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