1 /*! 2 * \file ast111.h 3 * \brief SCCP PBX Asterisk Header 4 * \author Marcello Ceshia 5 * \author Diederik de Groot <ddegroot [at] users.sourceforge.net> 6 * \note This program is free software and may be modified and distributed under the terms of the GNU Public License. 7 * See the LICENSE file at the top of the source tree. 8 */ 9 #pragma once 10 11 #include "config.h" 12 13 #undef pbx_channel_ref 14 #define pbx_channel_ref ast_channel_ref 15 #undef pbx_channel_unref 16 #define pbx_channel_unref ast_channel_unref 17 #define sccp_sched_context_destroy sched_context_destroy 18 19 #define PBX_ENDPOINT_TYPE void 20 #define PBX_EVENT_SUBSCRIPTION struct ast_event_sub 21 22 typedef struct ast_format_cap ast_format_t; 23 int skinny_codecs2pbx_codec_pref(const skinny_codec_t * const codecs, struct ast_codec_pref *astCodecPref); 24 int sccp_wrapper_asterisk_set_rtp_peer(PBX_CHANNEL_TYPE * ast, PBX_RTP_TYPE * rtp, PBX_RTP_TYPE * vrtp, PBX_RTP_TYPE * trtp, int codecs, int nat_active); 25 const char *pbx_getformatname(const struct ast_format *format); 26 char *pbx_getformatname_multiple(char *buf, size_t size, struct ast_format_cap *format); 27 28 /* Redefinitions for asterisk-trunk, need to be sorted */ 29 #define pbx_channel_name(x) ast_channel_name(x) 30 31 #undef pbx_channel_uniqueid 32 #undef pbx_channel_flags 33 #undef pbx_channel_call_forward 34 #undef pbx_channel_appl 35 #undef pbx_channel_state 36 #undef pbx_channel_pbx 37 #undef pbx_channel_hangupcause 38 #undef pbx_channel_set_hangupcause 39 #undef pbx_channel_softhangup 40 #undef pbx_channel_context 41 #undef pbx_channel_nativeformats 42 #undef pbx_channel_exten 43 #undef pbx_channel_priority 44 #undef pbx_channel_macroexten 45 #undef pbx_channel_macrocontext 46 #undef pbx_channel_dialcontext 47 #undef pbx_channel_callgroup 48 #undef pbx_channel_masq 49 #undef pbx_channel_setwhentohangup_tv 50 #undef pbx_channel_blocker 51 #undef pbx_channel_blockproc 52 #undef pbx_channel_tech 53 #undef pbx_channel_bridge 54 #undef pbx_channel_set_bridge 55 #undef pbx_channel_language 56 #undef pbx_channel_cdr 57 #undef pbx_channel_call_forward_set 58 #undef pbx_channel_varshead 59 #undef pbx_channel_redirecting_effective_from 60 #undef pbx_channel_redirecting_effective_to 61 #undef pbx_channel_redirecting_effective_orig 62 #undef pbx_channel_connected_id 63 #undef pbx_channel_connected_source 64 #undef pbx_channel_monitor 65 66 #define pbx_channel_uniqueid(_a) ast_channel_uniqueid(_a) 67 #define pbx_channel_flags(_a) ast_channel_flags(_a) 68 #define pbx_channel_call_forward(_a) ast_channel_call_forward(_a) 69 #define pbx_channel_appl(_a) ast_channel_appl(_a) 70 #define pbx_channel_state(_a) ast_channel_state(_a) 71 #define pbx_channel_pbx(_a) ast_channel_pbx(_a) 72 #define pbx_channel_hangupcause(_a) ast_channel_hangupcause(_a) 73 #define pbx_channel_set_hangupcause(_a, _b) ast_channel_hangupcause_set(_a, _b) 74 #define pbx_channel_softhangup(_a) ast_channel_softhangup_internal_flag(_a) 75 #define pbx_channel_set_hangupcause(_a, _b) ast_channel_hangupcause_set(_a, _b) 76 #define pbx_channel_context(_a) ast_channel_context(_a) 77 #define pbx_channel_nativeformats(_a) ast_channel_nativeformats(_a) 78 #define pbx_channel_exten(_a) ast_channel_exten(_a) 79 #define pbx_channel_priority(_a) ast_channel_priority(_a) 80 #define pbx_channel_macroexten(_a) ast_channel_macroexten(_a) 81 #define pbx_channel_macrocontext(_a) ast_channel_macrocontext(_a) 82 #define pbx_channel_dialcontext(_a) ast_channel_dialcontext(_a) 83 #define pbx_channel_callgroup(_a) ast_channel_callgroup(_a) 84 #define pbx_channel_masq(_a) ast_channel_masq(_a) 85 #define pbx_channel_setwhentohangup_tv(_a, _b) ast_channel_setwhentohangup_tv(_a, _b) 86 #define pbx_channel_blocker(_a) ast_channel_blocker(_a) 87 #define pbx_channel_blockproc(_a) ast_channel_blockproc(_a) 88 #define pbx_channel_tech(_a) ast_channel_tech(_a) 89 #define pbx_channel_bridge(_a) ast_channel_bridge(_a) 90 #define pbx_channel_set_bridge(_a, _b) ast_channel_internal_bridge_set(_a, _b) 91 #define pbx_channel_language(_a) ast_channel_language(_a) 92 #define pbx_channel_cdr(_a) ast_channel_cdr(_a) 93 #define pbx_channel_call_forward_set ast_channel_call_forward_set 94 #define pbx_channel_varshead(_a) ast_channel_varshead(_a) 95 #define pbx_channel_redirecting_effective_from(_a) ast_channel_redirecting_effective_from(_a) 96 #define pbx_channel_redirecting_effective_to(_a) ast_channel_redirecting_effective_to(_a) 97 #define pbx_channel_redirecting_effective_orig(_a) ast_channel_redirecting_effective_orig(_a) 98 #define pbx_channel_connected_id(_a) ast_channel_connected(_a)->id 99 #define pbx_channel_connected_source(_a) ast_channel_connected(_a)->source 100 #define pbx_channel_monitor(_a) ast_channel_monitor(_a) 101 102 int pbx_manager_register(const char *action, int authority, int (*func) (struct mansession * s, const struct message * m), const char *synopsis, const char *description); 103 104 #undef CS_AST_CHANNEL_PVT 105 #undef CS_AST_CHANNEL_PVT_TYPE 106 #undef CS_AST_CHANNEL_PVT_CMP_TYPE 107 108 #define CS_AST_CHANNEL_PVT(_a) ((sccp_channel_t*)ast_channel_tech_pvt(_a)) 109 #define CS_AST_CHANNEL_PVT_TYPE(_a) ast_channel_tech(_a)->type 110 #define CS_AST_CHANNEL_PVT_CMP_TYPE(_a,_b) !strncasecmp(CS_AST_CHANNEL_PVT_TYPE(_a), _b, strlen(_b)) 111 112 #define NEWCONST const // old functions used without const 113 #define OLDCONST // new function used with const 114 115 #if CS_TEST_FRAMEWORK 116 #undef pbx_test_validate_cleanup 117 #define pbx_test_validate_cleanup(test, condition, rc_variable, cleanup_label) ({ \ 118 if (!(condition)) { \ 119 pbx_test_status_update((test), "%s: %s\n", "Condition failed", #condition); \ 120 rc_variable = (enum ast_test_result_state) 2 /*AST_TEST_FAIL*/; \ 121 goto cleanup_label; \ 122 } \ 123 }) 124 #endif 125 126 #ifndef DOXYGEN_SHOULD_SKIP_THIS 127 # define CLI_AMI_OUTPUT(fd, s, ...) \ 128 ({ \ 129 if (NULL != (s)) { \ 130 astman_append ((s), __VA_ARGS__); \ 131 local_line_total++; \ 132 } else { \ 133 ast_cli ((fd), __VA_ARGS__); \ 134 } \ 135 }) 136 137 # define CLI_AMI_CAMEL_PARAM(param, camelParam) \ 138 ({ \ 139 char * current = (param); \ 140 char * ptr = (camelParam); \ 141 int CapsNext = 0; \ 142 while (*current) { \ 143 if ((*current >= 48 && *current <= 57 /*num*/) || (*current >= 65 && *current <= 90 /*A-Z*/) || (*current >= 97 && *current <= 122 /*a-z*/)) { \ 144 if (CapsNext) \ 145 *ptr++ = toupper (*current++); \ 146 else \ 147 *ptr++ = *current++; \ 148 CapsNext = 0; \ 149 } else { \ 150 CapsNext = 1; \ 151 current++; \ 152 } \ 153 } \ 154 *ptr = '\0'; \ 155 }) 156 157 # define CLI_AMI_OUTPUT_PARAM(param, width, fmt, ...) \ 158 ({ \ 159 if (NULL != (s)) { \ 160 char camelParam[width + 1]; \ 161 CLI_AMI_CAMEL_PARAM ((param), (camelParam)); \ 162 astman_append ((s), "%s: " fmt "\r\n", (camelParam), __VA_ARGS__); \ 163 local_line_total++; \ 164 } else { \ 165 ast_cli ((fd), "%-*.*s %s " fmt "\n", (width), (width), (param), ":", __VA_ARGS__); \ 166 } \ 167 }) 168 169 # define CLI_AMI_OUTPUT_BOOL(param, width, value) \ 170 ({ \ 171 if (NULL != (s)) { \ 172 char camelParam[width + 1]; \ 173 CLI_AMI_CAMEL_PARAM ((param), (camelParam)); \ 174 astman_append ((s), "%s: %s\r\n", (camelParam), ((value) ? "on" : "off")); \ 175 local_line_total++; \ 176 } else { \ 177 ast_cli ((fd), "%-*.*s %s %s\n", (width), (width), (param), ":", ((value) ? "on" : "off")); \ 178 } \ 179 }) 180 181 # define CLI_AMI_OUTPUT_YES_NO(param, width, value) \ 182 ({ \ 183 if (NULL != (s)) { \ 184 char camelParam[width + 1]; \ 185 CLI_AMI_CAMEL_PARAM ((param), (camelParam)); \ 186 astman_append ((s), "%s: %s\r\n", (camelParam), ((value) ? "yes" : "no")); \ 187 local_line_total++; \ 188 } else { \ 189 ast_cli ((fd), "%-*.*s %s %s\n", (width), (width), (param), ":", ((value) ? "yes" : "no")); \ 190 } \ 191 }) 192 193 # define _CLI_AMI_RETURN_ERROR(fd, s, m, line, fmt, ...) \ 194 ({ \ 195 if (NULL != (s)) { \ 196 char tmp_##line[101]; \ 197 snprintf (tmp_##line, sizeof (tmp_##line), (fmt), __VA_ARGS__); \ 198 astman_send_error ((s), (m), tmp_##line); \ 199 local_line_total++; \ 200 } else { \ 201 ast_cli ((fd), "SCCP CLI ERROR: " fmt, __VA_ARGS__); \ 202 } \ 203 return RESULT_FAILURE; \ 204 }) 205 # define CLI_AMI_RETURN_ERROR(fd, s, m, fmt, ...) _CLI_AMI_RETURN_ERROR ((fd), (s), (m), __LINE__, fmt, __VA_ARGS__) 206 207 // CLI_ENTRY 208 // param1=registration_name 209 // param2=function to execute when called 210 // param3=cli string to be types as array of strings 211 // param4=registration description 212 // param5=usage string 213 #define CLI_AMI_ENTRY(_FUNCTION_NAME,_CALLED_FUNCTION,_DESCR,_USAGE, _COMPLETER_REPEAT, _EVENTLIST) \ 214 static int manager_ ## _FUNCTION_NAME(struct mansession *s, const struct message *m) \ 215 { \ 216 const char *id = astman_get_header(m, "ActionID"); \ 217 static char *cli_ami_params[] = { CLI_COMMAND, CLI_AMI_PARAMS }; \ 218 static char *arguments[ARRAY_LEN(cli_ami_params)]; \ 219 uint8_t x = 0, i = 0; \ 220 for (x=0; x < ARRAY_LEN(cli_ami_params); x++) { \ 221 if(NULL != cli_ami_params[x] && strlen(cli_ami_params[x]) > 0){ \ 222 arguments[i++]=(char *)astman_get_header(m, cli_ami_params[x]); \ 223 } \ 224 } \ 225 char idtext[256] = ""; \ 226 /*int total = 0; */ \ 227 sccp_cli_totals_t totals = {0}; \ 228 if (!pbx_strlen_zero(id)) { \ 229 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); \ 230 } \ 231 if (_EVENTLIST == TRUE) { \ 232 astman_send_listack(s, m, AMI_COMMAND " list will follow", "start"); \ 233 } \ 234 if (RESULT_SUCCESS==_CALLED_FUNCTION(-1, &totals, s, m, ARRAY_LEN(arguments), arguments)) { \ 235 if (_EVENTLIST == TRUE) { \ 236 astman_append(s, \ 237 "Event: " AMI_COMMAND "Complete\r\n" \ 238 "EventList: Complete\r\n" \ 239 "ListItems: %d\r\n" \ 240 "ListTableItems: %d\r\n" \ 241 "%s" \ 242 "\r\n", totals.lines, totals.tables, idtext); \ 243 } else { \ 244 astman_append(s, "\r\n"); \ 245 } \ 246 } else { \ 247 astman_send_error(s, m, "Execution Failed\n"); \ 248 } \ 249 return 0; \ 250 } \ 251 \ 252 static char * cli_ ## _FUNCTION_NAME(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { \ 253 const char *cli_command[] = { CLI_COMMAND, NULL }; \ 254 static sccp_cli_completer_t cli_complete[] = { CLI_COMPLETE }; \ 255 static char command[80]=""; \ 256 if (cmd == CLI_INIT) { \ 257 ast_join(command, sizeof(command), cli_command); \ 258 e->command = command; \ 259 e->usage = _USAGE; \ 260 return NULL; \ 261 } \ 262 if (cmd == CLI_GENERATE) { \ 263 uint8_t completer; \ 264 for (completer=0; completer<ARRAY_LEN(cli_complete); completer++) { \ 265 if ((unsigned)a->pos == (completer + ARRAY_LEN(cli_command) - 1) || _COMPLETER_REPEAT ) {\ 266 return sccp_exec_completer(cli_complete[completer], (char *)a->line, (char *)a->word, a->pos, a->n);\ 267 } \ 268 } \ 269 return NULL; \ 270 } \ 271 if (a->argc < (int)(ARRAY_LEN(cli_command)-1)) { \ 272 return CLI_SHOWUSAGE; \ 273 } \ 274 static char *cli_ami_params[] = { CLI_COMMAND, CLI_AMI_PARAMS }; \ 275 struct message m = { 0 }; \ 276 size_t hdrlen; \ 277 for (int x = 0; x < (int)ARRAY_LEN(cli_ami_params) && x < a->argc; x++) { \ 278 hdrlen = strlen(cli_ami_params[x]) + 2 + strlen(a->argv[x]) + 1; \ 279 m.headers[m.hdrcount] = (const char *)sccp_malloc(hdrlen); \ 280 snprintf((char *) m.headers[m.hdrcount], hdrlen, "%s: %s", cli_ami_params[x], a->argv[x]); \ 281 m.hdrcount++; \ 282 } \ 283 int result = (_CALLED_FUNCTION)(a->fd, NULL, NULL, &m, a->argc, (char **) a->argv); \ 284 for (int x = 0; x < (int)ARRAY_LEN(cli_ami_params) && x < a->argc; x++) { \ 285 sccp_free(m.headers[x]); \ 286 } \ 287 switch (result) { \ 288 case RESULT_SUCCESS: return CLI_SUCCESS; \ 289 case RESULT_FAILURE: return CLI_FAILURE; \ 290 case RESULT_SHOWUSAGE: return CLI_SHOWUSAGE; \ 291 default: return CLI_FAILURE; \ 292 } \ 293 }; 294 #define CLI_ENTRY(_FUNCTION_NAME,_CALLED_FUNCTION,_DESCR,_USAGE, _COMPLETER_REPEAT) \ 295 static char *_FUNCTION_NAME(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { \ 296 const char *cli_command[] = { CLI_COMMAND, NULL }; \ 297 static sccp_cli_completer_t cli_complete[] = { CLI_COMPLETE }; \ 298 static char command[80]=""; \ 299 if (cmd == CLI_INIT) { \ 300 ast_join(command, sizeof(command), cli_command); \ 301 e->command = command; \ 302 e->usage = _USAGE; \ 303 return NULL; \ 304 } \ 305 if (cmd == CLI_GENERATE) { \ 306 uint8_t completer; \ 307 for (completer=0; completer<ARRAY_LEN(cli_complete); completer++) { \ 308 if ((unsigned)a->pos == (completer + ARRAY_LEN(cli_command) -1) || _COMPLETER_REPEAT ) {\ 309 return sccp_exec_completer(cli_complete[completer], (char *)a->line, (char *)a->word, a->pos, a->n);\ 310 } \ 311 } \ 312 return NULL; \ 313 } \ 314 if (a->argc < (int)(ARRAY_LEN(cli_command)-1)) { \ 315 return CLI_SHOWUSAGE; \ 316 } \ 317 switch (_CALLED_FUNCTION(a->fd, a->argc, (char **) a->argv)) { \ 318 case RESULT_SUCCESS: return CLI_SUCCESS; \ 319 case RESULT_FAILURE: return CLI_FAILURE; \ 320 case RESULT_SHOWUSAGE: return CLI_SHOWUSAGE; \ 321 default: return CLI_FAILURE; \ 322 } \ 323 }; 324 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 325 // kate: indent-width 8; replace-tabs off; indent-mode cstyle; auto-insert-doxygen on; line-numbers on; tab-indents on; keep-extra-spaces off; auto-brackets off; 326