1 /*!
2 * \file ast106.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/astobj2.h>
13
14 #define ast_alloca(size) __builtin_alloca(size)
15
16 #define sccp_sched_context_destroy sched_context_destroy
17 //#warning "HERE"
18 #if ASTERISK_VERSION_NUMBER >= 10601
19 #define pbx_channel_unref(c) ({ ao2_ref(c, -1); (PBX_CHANNEL_TYPE *) (NULL); })
20 #define pbx_channel_ref(c) ({ ao2_ref(c, 1); (PBX_CHANNEL_TYPE *) c; })
21 #else
22 #define pbx_channel_unref(c) NULL
23 #define pbx_channel_ref(c) ({(PBX_CHANNEL_TYPE *) c;})
24 #endif
25 #define NEWCONST const // old functions used without const
26 #define OLDCONST // new function used with const
27
28 #define PBX_ENDPOINT_TYPE void
29 #define PBX_EVENT_SUBSCRIPTION struct ast_event_sub
30
31 #define pbx_manager_register ast_manager_register2
32
33 #undef pbx_channel_get_by_name
34 #define pbx_channel_get_by_name(_x) ast_get_channel_by_name_locked(_x)
35
36 #ifndef CONFIG_STATUS_FILEMISSING
37 #define CONFIG_STATUS_FILEMISSING (void *)-2
38 #endif
39
40 #ifndef CONFIG_STATUS_FILEINVALID
41 #define CONFIG_STATUS_FILEINVALID (void *)-2
42 #endif
43
__do_nothing(void)44 static inline void __do_nothing(void) {} // will be optimized out
45
46 #undef pbx_check_hangup_locked
47 #define pbx_check_hangup_locked(_x) ({int res##__LINE__; ast_channel_lock(_x); res##__LINE__ = ast_check_hangup(_x); ast_channel_unlock(_x); (res##__LINE__);})
48 #undef pbx_bridge_lock
49 #undef pbx_bridge_unlock
50 #define pbx_bridge_lock(x) __do_nothing()
51 #define pbx_bridge_unlock(x) __do_nothing()
52
53 enum AST_CONNECTED_LINE_UPDATE_SOURCE {
54 /*! Update for unknown reason (May be interpreted to mean from answer) */
55 AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN,
56 /*! Update from normal call answering */
57 AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER,
58 /*! Update from call diversion (Deprecated, use REDIRECTING updates instead.) */
59 AST_CONNECTED_LINE_UPDATE_SOURCE_DIVERSION,
60 /*! Update from call transfer(active) (Party has already answered) */
61 AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER,
62 /*! Update from call transfer(alerting) (Party has not answered yet) */
63 AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING
64 };
65
66 #include "pbx_impl/ast/ast.h"
67 typedef int ast_format_t;
68 typedef int64_t format_t;
69 int skinny_codecs2pbx_codec_pref(const skinny_codec_t * const codecs, struct ast_codec_pref *astCodecPref);
70 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);
71
72 //void *sccp_do_monitor(void *data);
73 //int sccp_restart_monitor(void);
74 char *pbx_getformatname(format_t format);
75 char *pbx_getformatname_multiple(char *buf, size_t size, format_t format);
76
77 #define pbx_channel_name(x) x->name
78
79 #ifndef DOXYGEN_SHOULD_SKIP_THIS
80 #define CLI_AMI_OUTPUT(fd, s, ...) \
81 if (NULL != s) { \
82 astman_append(s, __VA_ARGS__); \
83 local_line_total++; \
84 } else { \
85 ast_cli(fd, __VA_ARGS__); \
86 }
87
88 #define CLI_AMI_CAMEL_PARAM(param, camelParam) \
89 char *current = param; \
90 char *ptr = camelParam; \
91 int CapsNext = 0; \
92 while (*current) { \
93 if ((*current >= 48 && *current <= 57 /*num*/) || (*current >= 65 && *current <= 90 /*A-Z*/) || (*current >= 97 && *current <= 122 /*a-z*/)) { \
94 if (CapsNext) *ptr++ = toupper(*current++); \
95 else *ptr++ = *current++; \
96 CapsNext = 0; \
97 } else { \
98 CapsNext = 1; \
99 current++; \
100 } \
101 } \
102 *ptr='\0';
103
104 #define CLI_AMI_OUTPUT_PARAM(param, width, fmt, ...) \
105 if (NULL != s) { \
106 char *camelParam = pbx_strdupa(param); \
107 CLI_AMI_CAMEL_PARAM(param, camelParam); \
108 astman_append(s, "%s: " fmt "\r\n", camelParam, __VA_ARGS__); \
109 local_line_total++; \
110 } else { \
111 ast_cli(fd, "%-*.*s %s " fmt "\n", width, width, param, ":", __VA_ARGS__); \
112 }
113
114 #define CLI_AMI_OUTPUT_BOOL(param, width, value) \
115 if (NULL != s) { \
116 char *camelParam = pbx_strdupa(param); \
117 CLI_AMI_CAMEL_PARAM(param, camelParam); \
118 astman_append(s, "%s: %s\r\n", camelParam, ((value) ? "on" : "off")); \
119 local_line_total++; \
120 } else { \
121 ast_cli(fd, "%-*.*s %s %s\n", width, width, param, ":", ((value) ? "on" : "off")); \
122 }
123
124 #define CLI_AMI_OUTPUT_YES_NO(param, width, value) \
125 if (NULL != s) { \
126 char *camelParam = pbx_strdupa(param); \
127 CLI_AMI_CAMEL_PARAM(param, camelParam); \
128 astman_append(s, "%s: %s\r\n", camelParam, ((value) ? "yes" : "no")); \
129 local_line_total++; \
130 } else { \
131 ast_cli(fd, "%-*.*s %s %s\n", width, width, param, ":", ((value) ? "yes" : "no")); \
132 }
133
134 # define _CLI_AMI_RETURN_ERROR(fd, s, m, line, fmt, ...) \
135 /*pbx_log(LOG_WARNING, "SCCP CLI ERROR: " fmt, __VA_ARGS__);*/ \
136 if(NULL != s) { \
137 char tmp_##line[101]; \
138 snprintf(tmp_##line, sizeof(tmp_##line), fmt, __VA_ARGS__); \
139 astman_send_error(s, m, tmp_##line); \
140 local_line_total++; \
141 } else { \
142 ast_cli(fd, "SCCP CLI ERROR: " fmt, __VA_ARGS__); \
143 } \
144 return RESULT_FAILURE;
145 # define CLI_AMI_RETURN_ERROR(fd, s, m, fmt, ...) _CLI_AMI_RETURN_ERROR(fd, s, m, __LINE__, fmt, __VA_ARGS__)
146
147 // CLI_ENTRY
148 // param1=registration_name
149 // param2=function to execute when called
150 // param3=cli string to be types as array of strings
151 // param4=registration description
152 // param5=usage string
153 #define CLI_AMI_ENTRY(_FUNCTION_NAME,_CALLED_FUNCTION,_DESCR,_USAGE, _COMPLETER_REPEAT, _EVENTLIST) \
154 static int manager_ ## _FUNCTION_NAME(struct mansession *s, const struct message *m) \
155 { \
156 const char *id = astman_get_header(m, "ActionID"); \
157 static char *cli_ami_params[] = { CLI_COMMAND, CLI_AMI_PARAMS }; \
158 static char *arguments[ARRAY_LEN(cli_ami_params)]; \
159 uint8_t x = 0, i = 0; \
160 for (x=0; x<ARRAY_LEN(cli_ami_params); x++) { \
161 if(NULL != cli_ami_params[x] && strlen(cli_ami_params[x]) > 0){ \
162 arguments[i++]=(char *)astman_get_header(m, cli_ami_params[x]); \
163 } \
164 } \
165 char idtext[256] = ""; \
166 sccp_cli_totals_t totals = {0}; \
167 if (!pbx_strlen_zero(id)) { \
168 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); \
169 } \
170 if (_EVENTLIST == TRUE) { \
171 astman_send_listack(s, m, AMI_COMMAND " list will follow", "start"); \
172 } \
173 if (RESULT_SUCCESS==_CALLED_FUNCTION(-1, &totals, s, m, ARRAY_LEN(arguments), arguments)) { \
174 if (_EVENTLIST == TRUE) { \
175 astman_append(s, \
176 "Event: " AMI_COMMAND "Complete\r\n" \
177 "EventList: Complete\r\n" \
178 "ListItems: %d\r\n" \
179 "ListTableItems: %d\r\n" \
180 "%s" \
181 "\r\n", totals.lines, totals.tables, idtext); \
182 } else { \
183 astman_append(s, "\r\n"); \
184 } \
185 } else { \
186 astman_send_error(s, m, "Execution Failed\n"); \
187 } \
188 return 0; \
189 } \
190 \
191 static char * cli_ ## _FUNCTION_NAME(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { \
192 char *cli_command[] = { CLI_COMMAND, NULL }; \
193 static sccp_cli_completer_t cli_complete[] = { CLI_COMPLETE }; \
194 static char command[80]=""; \
195 if (cmd == CLI_INIT) { \
196 ast_join(command, sizeof(command), cli_command); \
197 e->command = command; \
198 e->usage = _USAGE; \
199 return NULL; \
200 } \
201 if (cmd == CLI_GENERATE) { \
202 uint8_t completer; \
203 for (completer=0; completer<ARRAY_LEN(cli_complete); completer++) { \
204 if ((unsigned)a->pos == (completer + ARRAY_LEN(cli_command) - 1) || _COMPLETER_REPEAT ) {\
205 return sccp_exec_completer(cli_complete[completer], (char *)a->line, (char *)a->word, a->pos, a->n);\
206 } \
207 } \
208 return NULL; \
209 } \
210 if (a->argc < (int)(ARRAY_LEN(cli_command)-1)) { \
211 return CLI_SHOWUSAGE; \
212 } \
213 static char *cli_ami_params[] = { CLI_COMMAND, CLI_AMI_PARAMS }; \
214 struct message m = { 0 }; \
215 size_t hdrlen; \
216 for (int x = 0; x < (int)ARRAY_LEN(cli_ami_params) && x < a->argc; x++) { \
217 hdrlen = strlen(cli_ami_params[x]) + 2 + strlen(a->argv[x]) + 1; \
218 m.headers[m.hdrcount] = (const char *)sccp_malloc(hdrlen); \
219 snprintf((char *) m.headers[m.hdrcount], hdrlen, "%s: %s", cli_ami_params[x], a->argv[x]); \
220 m.hdrcount++; \
221 } \
222 int result = (_CALLED_FUNCTION)(a->fd, NULL, NULL, &m, a->argc, (char **) a->argv); \
223 for (int x = 0; x < (int)ARRAY_LEN(cli_ami_params) && x < a->argc; x++) { \
224 sccp_free(m.headers[x]); \
225 } \
226 switch (result) { \
227 case RESULT_SUCCESS: return CLI_SUCCESS; \
228 case RESULT_FAILURE: return CLI_FAILURE; \
229 case RESULT_SHOWUSAGE: return CLI_SHOWUSAGE; \
230 default: return CLI_FAILURE; \
231 } \
232 };
233 #define CLI_ENTRY(_FUNCTION_NAME,_CALLED_FUNCTION,_DESCR,_USAGE, _COMPLETER_REPEAT) \
234 static char *_FUNCTION_NAME(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { \
235 char *cli_command[] = { CLI_COMMAND, NULL }; \
236 static sccp_cli_completer_t cli_complete[] = { CLI_COMPLETE }; \
237 static char command[80]=""; \
238 if (cmd == CLI_INIT) { \
239 ast_join(command, sizeof(command), cli_command); \
240 e->command = command; \
241 e->usage = _USAGE; \
242 return NULL; \
243 } \
244 if (cmd == CLI_GENERATE) { \
245 uint8_t completer; \
246 for (completer=0; completer<ARRAY_LEN(cli_complete); completer++) { \
247 if ((unsigned)a->pos == (completer + ARRAY_LEN(cli_command) -1) || _COMPLETER_REPEAT ) {\
248 return sccp_exec_completer(cli_complete[completer], (char *)a->line, (char *)a->word, a->pos, a->n);\
249 } \
250 } \
251 return NULL; \
252 } \
253 if (a->argc < (int)(ARRAY_LEN(cli_command)-1)) { \
254 return CLI_SHOWUSAGE; \
255 } \
256 switch (_CALLED_FUNCTION(a->fd, a->argc, (char **) a->argv)) { \
257 case RESULT_SUCCESS: return CLI_SUCCESS; \
258 case RESULT_FAILURE: return CLI_FAILURE; \
259 case RESULT_SHOWUSAGE: return CLI_SHOWUSAGE; \
260 default: return CLI_FAILURE; \
261 } \
262 };
263 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
264 // 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;
265