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