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