Bug Summary

File:src/switch_loadable_module.c
Location:line 1697, column 4
Description:Value stored to 'err' is never read

Annotated Source Code

1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 * Seven Du <dujinfang@gmail.com>
28 *
29 * switch_loadable_module.c -- Loadable Modules
30 *
31 */
32
33#include <switch.h>
34
35/* for apr_pstrcat */
36#include <apr_strings.h>
37
38/* for apr_env_get and apr_env_set */
39#include <apr_env.h>
40
41/* for apr file and directory handling */
42#include <apr_file_io.h>
43
44struct switch_loadable_module {
45 char *key;
46 char *filename;
47 int perm;
48 switch_loadable_module_interface_t *module_interface;
49 switch_dso_lib_t lib;
50 switch_module_load_t switch_module_load;
51 switch_module_runtime_t switch_module_runtime;
52 switch_module_shutdown_t switch_module_shutdown;
53 switch_memory_pool_t *pool;
54 switch_status_t status;
55 switch_thread_t *thread;
56 switch_bool_t shutting_down;
57};
58
59struct switch_loadable_module_container {
60 switch_hash_t *module_hash;
61 switch_hash_t *endpoint_hash;
62 switch_hash_t *codec_hash;
63 switch_hash_t *dialplan_hash;
64 switch_hash_t *timer_hash;
65 switch_hash_t *application_hash;
66 switch_hash_t *chat_application_hash;
67 switch_hash_t *api_hash;
68 switch_hash_t *json_api_hash;
69 switch_hash_t *file_hash;
70 switch_hash_t *speech_hash;
71 switch_hash_t *asr_hash;
72 switch_hash_t *directory_hash;
73 switch_hash_t *chat_hash;
74 switch_hash_t *say_hash;
75 switch_hash_t *management_hash;
76 switch_hash_t *limit_hash;
77 switch_hash_t *secondary_recover_hash;
78 switch_mutex_t *mutex;
79 switch_memory_pool_t *pool;
80};
81
82static struct switch_loadable_module_container loadable_modules;
83static switch_status_t do_shutdown(switch_loadable_module_t *module, switch_bool_t shutdown, switch_bool_t unload, switch_bool_t fail_if_busy,
84 const char **err);
85static switch_status_t switch_loadable_module_load_module_ex(char *dir, char *fname, switch_bool_t runtime, switch_bool_t global, const char **err);
86
87static void *SWITCH_THREAD_FUNC switch_loadable_module_exec(switch_thread_t *thread, void *obj)
88{
89
90
91 switch_status_t status = SWITCH_STATUS_SUCCESS;
92 switch_core_thread_session_t *ts = obj;
93 switch_loadable_module_t *module = ts->objs[0];
94 int restarts;
95
96 switch_assert(thread != NULL)((thread != ((void*)0)) ? (void) (0) : __assert_fail ("thread != ((void*)0)"
, "src/switch_loadable_module.c", 96, __PRETTY_FUNCTION__))
;
97 switch_assert(module != NULL)((module != ((void*)0)) ? (void) (0) : __assert_fail ("module != ((void*)0)"
, "src/switch_loadable_module.c", 97, __PRETTY_FUNCTION__))
;
98
99 for (restarts = 0; status != SWITCH_STATUS_TERM && !module->shutting_down; restarts++) {
100 status = module->switch_module_runtime();
101 }
102 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 102, ((void*)0)
, SWITCH_LOG_NOTICE, "Thread ended for %s\n", module->module_interface->module_name);
103
104 if (ts->pool) {
105 switch_memory_pool_t *pool = ts->pool;
106 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 106, ((void*)0)
, SWITCH_LOG_DEBUG, "Destroying Pool for %s\n", module->module_interface->module_name);
107 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 107)
;
108 }
109 switch_thread_exit(thread, 0);
110 return NULL((void*)0);
111}
112
113
114static void switch_loadable_module_runtime(void)
115{
116 switch_hash_index_t *hi;
117 void *val;
118 switch_loadable_module_t *module;
119
120 switch_mutex_lock(loadable_modules.mutex);
121 for (hi = switch_core_hash_first(loadable_modules.module_hash)switch_core_hash_first_iter(loadable_modules.module_hash, ((void
*)0))
; hi; hi = switch_core_hash_next(&hi)) {
122 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
123 module = (switch_loadable_module_t *) val;
124
125 if (module->switch_module_runtime) {
126 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 126, ((void*)0)
, SWITCH_LOG_CONSOLE, "Starting runtime thread for %s\n", module->module_interface->module_name);
127 module->thread = switch_core_launch_thread(switch_loadable_module_exec, module, loadable_modules.pool);
128 }
129 }
130 switch_mutex_unlock(loadable_modules.mutex);
131}
132
133static switch_status_t switch_loadable_module_process(char *key, switch_loadable_module_t *new_module)
134{
135 switch_event_t *event;
136 int added = 0;
137
138 new_module->key = switch_core_strdup(new_module->pool, key)switch_core_perform_strdup(new_module->pool, key, "src/switch_loadable_module.c"
, (const char *)__func__, 138)
;
139
140 switch_mutex_lock(loadable_modules.mutex);
141 switch_core_hash_insert(loadable_modules.module_hash, key, new_module)switch_core_hash_insert_destructor(loadable_modules.module_hash
, key, new_module, ((void*)0))
;
142
143 if (new_module->module_interface->endpoint_interface) {
144 const switch_endpoint_interface_t *ptr;
145 for (ptr = new_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
146 if (!ptr->interface_name) {
147 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 147, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load endpoint interface from %s due to no interface name.\n", key);
148 } else {
149 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 149, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Endpoint '%s'\n", ptr->interface_name);
150 switch_core_hash_insert(loadable_modules.endpoint_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.endpoint_hash
, ptr->interface_name, (const void *) ptr, ((void*)0))
;
151 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 151, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
152 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "endpoint");
153 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
154 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
155 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
156 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 156, &event, ((void*)0))
;
157 added++;
158 }
159 }
160 }
161 }
162
163 if (new_module->module_interface->codec_interface) {
164 const switch_codec_implementation_t *impl;
165 const switch_codec_interface_t *ptr;
166
167 for (ptr = new_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
168 if (!ptr->interface_name) {
169 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 169, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load codec interface from %s due to no interface name.\n", key);
170 } else {
171 unsigned load_interface = 1;
172 for (impl = ptr->implementations; impl; impl = impl->next) {
173 if (!impl->iananame) {
174 load_interface = 0;
175 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 175, ((void*)0)
, SWITCH_LOG_CRIT,
176 "Failed to load codec interface %s from %s due to no iana name in an implementation.\n", ptr->interface_name,
177 key);
178 break;
179 }
180 if (impl->decoded_bytes_per_packet > SWITCH_RECOMMENDED_BUFFER_SIZE8192) {
181 load_interface = 0;
182 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 182, ((void*)0)
, SWITCH_LOG_CRIT,
183 "Failed to load codec interface %s from %s due to bytes per frame %d exceeding buffer size %d.\n",
184 ptr->interface_name,
185 key, impl->decoded_bytes_per_packet, SWITCH_RECOMMENDED_BUFFER_SIZE8192);
186 break;
187 }
188 }
189 if (load_interface) {
190 for (impl = ptr->implementations; impl; impl = impl->next) {
191 if (impl->bits_per_second) {
192 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 192, ((void*)0)
, SWITCH_LOG_NOTICE,
193 "Adding Codec %s %d %s %dhz %dms %dbps\n",
194 impl->iananame, impl->ianacode,
195 ptr->interface_name, impl->actual_samples_per_second,
196 impl->microseconds_per_packet / 1000, impl->bits_per_second);
197 } else {
198 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 198, ((void*)0)
, SWITCH_LOG_NOTICE,
199 "Adding Codec %s %d %s %dhz %dms (VBR)\n",
200 impl->iananame, impl->ianacode,
201 ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000);
202 }
203 if (!switch_core_hash_find(loadable_modules.codec_hash, impl->iananame)) {
204 switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.codec_hash
, impl->iananame, (const void *) ptr, ((void*)0))
;
205 }
206 }
207 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 207, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
208 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "codec");
209 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
210 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
211 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
212 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 212, &event, ((void*)0))
;
213 added++;
214 }
215 }
216 }
217 }
218 }
219
220 if (new_module->module_interface->dialplan_interface) {
221 const switch_dialplan_interface_t *ptr;
222
223 for (ptr = new_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) {
224 if (!ptr->interface_name) {
225 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 225, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load dialplan interface from %s due to no interface name.\n", key);
226 } else {
227 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 227, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Dialplan '%s'\n", ptr->interface_name);
228 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 228, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
229 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "dialplan");
230 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
231 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
232 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
233 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 233, &event, ((void*)0))
;
234 added++;
235 }
236 switch_core_hash_insert(loadable_modules.dialplan_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.dialplan_hash
, ptr->interface_name, (const void *) ptr, ((void*)0))
;
237 }
238 }
239 }
240
241 if (new_module->module_interface->timer_interface) {
242 const switch_timer_interface_t *ptr;
243
244 for (ptr = new_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
245 if (!ptr->interface_name) {
246 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 246, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load timer interface from %s due to no interface name.\n", key);
247 } else {
248 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 248, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Timer '%s'\n", ptr->interface_name);
249 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 249, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
250 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "timer");
251 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
252 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
253 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
254 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 254, &event, ((void*)0))
;
255 added++;
256 }
257 switch_core_hash_insert(loadable_modules.timer_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.timer_hash
, ptr->interface_name, (const void *) ptr, ((void*)0))
;
258 }
259 }
260 }
261
262 if (new_module->module_interface->application_interface) {
263 const switch_application_interface_t *ptr;
264
265 for (ptr = new_module->module_interface->application_interface; ptr; ptr = ptr->next) {
266 if (!ptr->interface_name) {
267 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 267, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key);
268 } else {
269 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 269, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Application '%s'\n", ptr->interface_name);
270 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 270, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
271 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
272 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
273 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->short_desc)(ptr->short_desc ? ptr->short_desc : ""));
274 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
275 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
276 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
277 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 277, &event, ((void*)0))
;
278 added++;
279 }
280 switch_core_hash_insert(loadable_modules.application_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.application_hash
, ptr->interface_name, (const void *) ptr, ((void*)0))
;
281 }
282 }
283 }
284
285 if (new_module->module_interface->chat_application_interface) {
286 const switch_chat_application_interface_t *ptr;
287
288 for (ptr = new_module->module_interface->chat_application_interface; ptr; ptr = ptr->next) {
289 if (!ptr->interface_name) {
290 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 290, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key);
291 } else {
292 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 292, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Chat Application '%s'\n", ptr->interface_name);
293 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 293, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
294 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
295 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
296 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->short_desc)(ptr->short_desc ? ptr->short_desc : ""));
297 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
298 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
299 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
300 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 300, &event, ((void*)0))
;
301 added++;
302 }
303 switch_core_hash_insert(loadable_modules.chat_application_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.chat_application_hash
, ptr->interface_name, (const void *) ptr, ((void*)0))
;
304 }
305 }
306 }
307
308 if (new_module->module_interface->api_interface) {
309 const switch_api_interface_t *ptr;
310
311 for (ptr = new_module->module_interface->api_interface; ptr; ptr = ptr->next) {
312 if (!ptr->interface_name) {
313 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 313, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load api interface from %s due to no interface name.\n", key);
314 } else {
315 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 315, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding API Function '%s'\n", ptr->interface_name);
316 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 316, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
317 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");
318 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
319 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->desc)(ptr->desc ? ptr->desc : ""));
320 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
321 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
322 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
323 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 323, &event, ((void*)0))
;
324 added++;
325 }
326 switch_core_hash_insert(loadable_modules.api_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.api_hash,
ptr->interface_name, (const void *) ptr, ((void*)0))
;
327 }
328 }
329 }
330
331 if (new_module->module_interface->json_api_interface) {
332 const switch_json_api_interface_t *ptr;
333
334 for (ptr = new_module->module_interface->json_api_interface; ptr; ptr = ptr->next) {
335 if (!ptr->interface_name) {
336 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 336, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load JSON api interface from %s due to no interface name.\n", key);
337 } else {
338 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 338, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding JSON API Function '%s'\n", ptr->interface_name);
339 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 339, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
340 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "json_api");
341 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
342 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->desc)(ptr->desc ? ptr->desc : ""));
343 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
344 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
345 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
346 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 346, &event, ((void*)0))
;
347 added++;
348 }
349 switch_core_hash_insert(loadable_modules.json_api_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.json_api_hash
, ptr->interface_name, (const void *) ptr, ((void*)0))
;
350 }
351 }
352 }
353
354 if (new_module->module_interface->file_interface) {
355 const switch_file_interface_t *ptr;
356
357 for (ptr = new_module->module_interface->file_interface; ptr; ptr = ptr->next) {
358 if (!ptr->interface_name) {
359 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 359, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no interface name.\n", key);
360 } else if (!ptr->extens) {
361 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 361, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no file extensions.\n", key);
362 } else {
363 int i;
364 for (i = 0; ptr->extens[i]; i++) {
365 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 365, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding File Format '%s'\n", ptr->extens[i]);
366 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 366, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
367 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "file");
368 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->extens[i]);
369 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
370 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
371 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 371, &event, ((void*)0))
;
372 added++;
373 }
374 switch_core_hash_insert(loadable_modules.file_hash, ptr->extens[i], (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.file_hash
, ptr->extens[i], (const void *) ptr, ((void*)0))
;
375 }
376 }
377 }
378 }
379
380 if (new_module->module_interface->speech_interface) {
381 const switch_speech_interface_t *ptr;
382
383 for (ptr = new_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
384 if (!ptr->interface_name) {
385 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 385, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load speech interface from %s due to no interface name.\n", key);
386 } else {
387 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 387, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Speech interface '%s'\n", ptr->interface_name);
388 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 388, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
389 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
390 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
391 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
392 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
393 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 393, &event, ((void*)0))
;
394 added++;
395 }
396 switch_core_hash_insert(loadable_modules.speech_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.speech_hash
, ptr->interface_name, (const void *) ptr, ((void*)0))
;
397 }
398 }
399 }
400
401 if (new_module->module_interface->asr_interface) {
402 const switch_asr_interface_t *ptr;
403
404 for (ptr = new_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
405 if (!ptr->interface_name) {
406 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 406, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load asr interface from %s due to no interface name.\n", key);
407 } else {
408 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 408, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding ASR interface '%s'\n", ptr->interface_name);
409 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 409, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
410 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "asr");
411 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
412 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
413 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
414 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 414, &event, ((void*)0))
;
415 added++;
416 }
417 switch_core_hash_insert(loadable_modules.asr_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.asr_hash,
ptr->interface_name, (const void *) ptr, ((void*)0))
;
418 }
419 }
420 }
421
422 if (new_module->module_interface->directory_interface) {
423 const switch_directory_interface_t *ptr;
424
425 for (ptr = new_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
426 if (!ptr->interface_name) {
427 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 427, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load directory interface from %s due to no interface name.\n", key);
428 } else {
429 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 429, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Directory interface '%s'\n", ptr->interface_name);
430 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 430, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
431 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
432 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
433 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
434 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
435 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 435, &event, ((void*)0))
;
436 added++;
437 }
438 switch_core_hash_insert(loadable_modules.directory_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.directory_hash
, ptr->interface_name, (const void *) ptr, ((void*)0))
;
439 }
440 }
441 }
442
443 if (new_module->module_interface->chat_interface) {
444 const switch_chat_interface_t *ptr;
445
446 for (ptr = new_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
447 if (!ptr->interface_name) {
448 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 448, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load chat interface from %s due to no interface name.\n", key);
449 } else {
450 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 450, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Chat interface '%s'\n", ptr->interface_name);
451 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 451, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
452 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
453 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
454 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
455 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
456 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 456, &event, ((void*)0))
;
457 added++;
458 }
459 switch_core_hash_insert(loadable_modules.chat_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.chat_hash
, ptr->interface_name, (const void *) ptr, ((void*)0))
;
460 }
461 }
462 }
463
464 if (new_module->module_interface->say_interface) {
465 const switch_say_interface_t *ptr;
466
467 for (ptr = new_module->module_interface->say_interface; ptr; ptr = ptr->next) {
468 if (!ptr->interface_name) {
469 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 469, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load say interface from %s due to no interface name.\n", key);
470 } else {
471 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 471, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Say interface '%s'\n", ptr->interface_name);
472 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 472, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
473 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "say");
474 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
475 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
476 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
477 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 477, &event, ((void*)0))
;
478 added++;
479 }
480 switch_core_hash_insert(loadable_modules.say_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.say_hash,
ptr->interface_name, (const void *) ptr, ((void*)0))
;
481 }
482 }
483 }
484
485 if (new_module->module_interface->management_interface) {
486 const switch_management_interface_t *ptr;
487
488 for (ptr = new_module->module_interface->management_interface; ptr; ptr = ptr->next) {
489 if (!ptr->relative_oid) {
490 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 490, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load management interface from %s due to no interface name.\n", key);
491 } else {
492 if (switch_core_hash_find(loadable_modules.management_hash, ptr->relative_oid)) {
493 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 493, ((void*)0)
, SWITCH_LOG_CRIT,
494 "Failed to load management interface %s. OID %s already exists\n", key, ptr->relative_oid);
495 } else {
496 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 496, ((void*)0)
, SWITCH_LOG_NOTICE,
497 "Adding Management interface '%s' OID[%s.%s]\n", key, FREESWITCH_OID_PREFIX".1.3.6.1.4.1." "27880", ptr->relative_oid);
498 switch_core_hash_insert(loadable_modules.management_hash, ptr->relative_oid, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.management_hash
, ptr->relative_oid, (const void *) ptr, ((void*)0))
;
499 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 499, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
500 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "management");
501 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->relative_oid);
502 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
503 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
504 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 504, &event, ((void*)0))
;
505 added++;
506 }
507 }
508
509 }
510 }
511 }
512 if (new_module->module_interface->limit_interface) {
513 const switch_limit_interface_t *ptr;
514
515 for (ptr = new_module->module_interface->limit_interface; ptr; ptr = ptr->next) {
516 if (!ptr->interface_name) {
517 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 517, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load limit interface from %s due to no interface name.\n", key);
518 } else {
519 if (switch_core_hash_find(loadable_modules.limit_hash, ptr->interface_name)) {
520 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 520, ((void*)0)
, SWITCH_LOG_CRIT,
521 "Failed to load limit interface %s. Name %s already exists\n", key, ptr->interface_name);
522 } else {
523 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 523, ((void*)0)
, SWITCH_LOG_NOTICE,
524 "Adding Limit interface '%s'\n", ptr->interface_name);
525 switch_core_hash_insert(loadable_modules.limit_hash, ptr->interface_name, (const void *) ptr)switch_core_hash_insert_destructor(loadable_modules.limit_hash
, ptr->interface_name, (const void *) ptr, ((void*)0))
;
526 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 526, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
527 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "limit");
528 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
529 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
530 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
531 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 531, &event, ((void*)0))
;
532 added++;
533 }
534 }
535
536 }
537 }
538 }
539
540 if (!added) {
541 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 541, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
542 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "generic");
543 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", new_module->key);
544 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
545 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
546 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 546, &event, ((void*)0))
;
547 added++;
548 }
549 }
550
551 switch_mutex_unlock(loadable_modules.mutex);
552 return SWITCH_STATUS_SUCCESS;
553
554}
555
556#define CHAT_MAX_MSG_QUEUE101 101
557#define CHAT_QUEUE_SIZE5000 5000
558
559static struct {
560 switch_queue_t *msg_queue[CHAT_MAX_MSG_QUEUE101];
561 switch_thread_t *msg_queue_thread[CHAT_MAX_MSG_QUEUE101];
562 int msg_queue_len;
563 switch_mutex_t *mutex;
564 switch_memory_pool_t *pool;
565 int running;
566} chat_globals;
567
568static int IDX = 0;
569
570
571static switch_status_t do_chat_send(switch_event_t *message_event)
572
573{
574 switch_chat_interface_t *ci;
575 switch_status_t status = SWITCH_STATUS_FALSE;
576 switch_hash_index_t *hi;
577 switch_event_t *dup = NULL((void*)0);
578 const void *var;
579 void *val;
580 const char *proto;
581 const char *replying;
582 const char *dest_proto;
583 int do_skip = 0;
584
585 /*
586
587 const char *from;
588 const char *to;
589 const char *subject;
590 const char *body;
591 const char *type;
592 const char *hint;
593 */
594
595 dest_proto = switch_event_get_header(message_event, "dest_proto")switch_event_get_header_idx(message_event, "dest_proto", -1);
596
597 if (!dest_proto) {
598 return SWITCH_STATUS_FALSE;
599 }
600
601 /*
602
603 from = switch_event_get_header(message_event, "from");
604 to = switch_event_get_header(message_event, "to");
605 subject = switch_event_get_header(message_event, "subject");
606 body = switch_event_get_body(message_event);
607 type = switch_event_get_header(message_event, "type");
608 hint = switch_event_get_header(message_event, "hint");
609 */
610
611 if (!(proto = switch_event_get_header(message_event, "proto")switch_event_get_header_idx(message_event, "proto", -1))) {
612 proto = "global";
613 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto);
614 }
615
616 replying = switch_event_get_header(message_event, "replying")switch_event_get_header_idx(message_event, "replying", -1);
617
618 if (!switch_true(replying) && !switch_stristr("global", proto) && !switch_true(switch_event_get_header(message_event, "skip_global_process")switch_event_get_header_idx(message_event, "skip_global_process"
, -1)
)) {
619 switch_mutex_lock(loadable_modules.mutex);
620 for (hi = switch_core_hash_first(loadable_modules.chat_hash)switch_core_hash_first_iter(loadable_modules.chat_hash, ((void
*)0))
; hi; hi = switch_core_hash_next(&hi)) {
621 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
622
623 if ((ci = (switch_chat_interface_t *) val)) {
624 if (ci->chat_send && !strncasecmp(ci->interface_name, "GLOBAL_", 7)) {
625 status = ci->chat_send(message_event);
626
627 if (status == SWITCH_STATUS_SUCCESS) {
628 if (switch_true(switch_event_get_header(message_event, "final_delivery")switch_event_get_header_idx(message_event, "final_delivery", -
1)
)) {
629 /* The event was handled by an extension in the chatplan,
630 * so the event will be duplicated, modified and queued again,
631 * but it won't be processed by the chatplan again.
632 * So this copy of the event can be destroyed by the caller.
633 */
634 do_skip = 1;
635 }
636 } else if (status == SWITCH_STATUS_BREAK) {
637 /* The event went through the chatplan, but no extension matched
638 * to handle the sms messsage. It'll be attempted to be delivered
639 * directly, and unless that works the sms delivery will have failed.
640 */
641 } else {
642 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 642, ((void*)0)
, SWITCH_LOG_ERROR, "Chat Interface Error [%s]!\n", dest_proto);
643 break;
644 }
645 }
646 }
647 }
648 switch_safe_free(hi)if (hi) {free(hi);hi=((void*)0);};
649 switch_mutex_unlock(loadable_modules.mutex);
650 }
651
652
653 if (!do_skip && !switch_stristr("GLOBAL", dest_proto)) {
654 if ((ci = switch_loadable_module_get_chat_interface(dest_proto)) && ci->chat_send) {
655 status = ci->chat_send(message_event);
656 UNPROTECT_INTERFACE(ci)if (ci) {switch_mutex_lock(ci->reflock); switch_thread_rwlock_unlock
(ci->rwlock); switch_thread_rwlock_unlock(ci->parent->
rwlock); ci->refs--; ci->parent->refs--; switch_mutex_unlock
(ci->reflock);}
;
657 } else {
658 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 658, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid chat interface [%s]!\n", dest_proto);
659 status = SWITCH_STATUS_FALSE;
660 }
661 }
662
663
664 switch_event_dup(&dup, message_event);
665
666 if ( switch_true(switch_event_get_header(message_event, "blocking")switch_event_get_header_idx(message_event, "blocking", -1)) ) {
667 if (status == SWITCH_STATUS_SUCCESS) {
668 switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "false");
669 } else {
670 switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "true");
671 }
672 } else {
673 switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Nonblocking-Delivery", "true");
674 }
675
676 switch_event_fire(&dup)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 676, &dup, ((void*)0))
;
677 return status;
678}
679
680static switch_status_t chat_process_event(switch_event_t **eventp)
681{
682 switch_event_t *event;
683 switch_status_t status;
684
685 switch_assert(eventp)((eventp) ? (void) (0) : __assert_fail ("eventp", "src/switch_loadable_module.c"
, 685, __PRETTY_FUNCTION__))
;
686
687 event = *eventp;
688 *eventp = NULL((void*)0);
689
690 status = do_chat_send(event);
691 switch_event_destroy(&event);
692
693 return status;
694}
695
696
697void *SWITCH_THREAD_FUNC chat_thread_run(switch_thread_t *thread, void *obj)
698{
699 void *pop;
700 switch_queue_t *q = (switch_queue_t *) obj;
701
702 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 702, ((void*)0)
, SWITCH_LOG_DEBUG, "Chat Thread Started\n");
703
704
705 while(switch_queue_pop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
706 switch_event_t *event = (switch_event_t *) pop;
707 chat_process_event(&event);
708 switch_cond_next();
709 }
710
711 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 711, ((void*)0)
, SWITCH_LOG_DEBUG, "Chat Thread Ended\n");
712
713 return NULL((void*)0);
714}
715
716
717static void chat_thread_start(int idx)
718{
719
720 if (idx >= CHAT_MAX_MSG_QUEUE101 || (idx < chat_globals.msg_queue_len && chat_globals.msg_queue_thread[idx])) {
721 return;
722 }
723
724 switch_mutex_lock(chat_globals.mutex);
725
726 if (idx >= chat_globals.msg_queue_len) {
727 int i;
728 chat_globals.msg_queue_len = idx + 1;
729
730 for (i = 0; i < chat_globals.msg_queue_len; i++) {
731 if (!chat_globals.msg_queue[i]) {
732 switch_threadattr_t *thd_attr = NULL((void*)0);
733
734 switch_queue_create(&chat_globals.msg_queue[i], CHAT_QUEUE_SIZE5000, chat_globals.pool);
735
736 switch_threadattr_create(&thd_attr, chat_globals.pool);
737 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
738 switch_thread_create(&chat_globals.msg_queue_thread[i],
739 thd_attr,
740 chat_thread_run,
741 chat_globals.msg_queue[i],
742 chat_globals.pool);
743 }
744 }
745 }
746
747 switch_mutex_unlock(chat_globals.mutex);
748}
749
750
751static void chat_queue_message(switch_event_t **eventp)
752{
753 int idx = 0;
754 switch_event_t *event;
755
756 switch_assert(eventp)((eventp) ? (void) (0) : __assert_fail ("eventp", "src/switch_loadable_module.c"
, 756, __PRETTY_FUNCTION__))
;
757
758 event = *eventp;
759 *eventp = NULL((void*)0);
760
761 if (chat_globals.running == 0) {
762 chat_process_event(&event);
763 return;
764 }
765
766 again:
767
768 switch_mutex_lock(chat_globals.mutex);
769 idx = IDX;
770 IDX++;
771 if (IDX >= chat_globals.msg_queue_len) IDX = 0;
772 switch_mutex_unlock(chat_globals.mutex);
773
774 chat_thread_start(idx);
775
776 if (switch_queue_trypush(chat_globals.msg_queue[idx], event) != SWITCH_STATUS_SUCCESS) {
777 if (chat_globals.msg_queue_len < CHAT_MAX_MSG_QUEUE101) {
778 chat_thread_start(idx + 1);
779 goto again;
780 } else {
781 switch_queue_push(chat_globals.msg_queue[idx], event);
782 }
783 }
784}
785
786
787SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_execute_chat_app(switch_event_t *message, const char *app, const char *data)
788{
789 switch_chat_application_interface_t *cai;
790 switch_status_t status = SWITCH_STATUS_SUCCESS;
791 char *expanded;
792
793 if (!(cai = switch_loadable_module_get_chat_application_interface(app)) || !cai->chat_application_function) {
794 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 794, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid chat application interface [%s]!\n", app);
795 return SWITCH_STATUS_FALSE;
796 }
797
798 if (switch_test_flag(message, EF_NO_CHAT_EXEC)((message)->flags & EF_NO_CHAT_EXEC)) {
799 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 799, ((void*)0)
, SWITCH_LOG_DEBUG, "Message is not allowed to execute apps\n");
800 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
801 }
802
803 if (data && !strcmp(data, "__undef")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(data) && __builtin_constant_p ("__undef") &&
(__s1_len = __builtin_strlen (data), __s2_len = __builtin_strlen
("__undef"), (!((size_t)(const void *)((data) + 1) - (size_t
)(const void *)(data) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)(("__undef") + 1) - (size_t)(const void
*)("__undef") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(data, "__undef") : (__builtin_constant_p (data) && (
(size_t)(const void *)((data) + 1) - (size_t)(const void *)(data
) == 1) && (__s1_len = __builtin_strlen (data), __s1_len
< 4) ? (__builtin_constant_p ("__undef") && ((size_t
)(const void *)(("__undef") + 1) - (size_t)(const void *)("__undef"
) == 1) ? __builtin_strcmp (data, "__undef") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("__undef"); int __result = (((const unsigned char *
) (const char *) (data))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (data))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (data))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (data))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("__undef") && ((size_t)(const void *)(("__undef") +
1) - (size_t)(const void *)("__undef") == 1) && (__s2_len
= __builtin_strlen ("__undef"), __s2_len < 4) ? (__builtin_constant_p
(data) && ((size_t)(const void *)((data) + 1) - (size_t
)(const void *)(data) == 1) ? __builtin_strcmp (data, "__undef"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (data); int __result = (((const unsigned
char *) (const char *) ("__undef"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("__undef"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("__undef"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("__undef"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (data, "__undef")))); })
) {
804 data = NULL((void*)0);
805 }
806
807 expanded = switch_event_expand_headers(message, data)switch_event_expand_headers_check(message, data, ((void*)0), (
(void*)0), 0)
;
808
809 status = cai->chat_application_function(message, expanded);
810
811 if (expanded != data) {
812 free(expanded);
813 }
814
815 end:
816
817 UNPROTECT_INTERFACE(cai)if (cai) {switch_mutex_lock(cai->reflock); switch_thread_rwlock_unlock
(cai->rwlock); switch_thread_rwlock_unlock(cai->parent->
rwlock); cai->refs--; cai->parent->refs--; switch_mutex_unlock
(cai->reflock);}
;
818
819 return status;
820
821}
822
823
824
825SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_chat_send_args(const char *dest_proto, const char *proto, const char *from, const char *to,
826 const char *subject, const char *body, const char *type, const char *hint, switch_bool_t blocking)
827{
828 switch_event_t *message_event;
829 switch_status_t status;
830
831 if (switch_event_create(&message_event, SWITCH_EVENT_MESSAGE)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 831, &message_event
, SWITCH_EVENT_MESSAGE, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
832 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto);
833 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "from", from);
834 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "to", to);
835 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "subject", subject);
836 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "type", type);
837 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "hint", hint);
838 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "skip_global_process", "true");
839 if (blocking) {
840 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "blocking", "true");
841 }
842
843 if (body) {
844 switch_event_add_body(message_event, "%s", body);
845 }
846 } else {
847 abort();
848 }
849
850 if (dest_proto) {
851 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "dest_proto", dest_proto);
852 }
853
854
855 if (blocking) {
856 status = chat_process_event(&message_event);
857 } else {
858 chat_queue_message(&message_event);
859 status = SWITCH_STATUS_SUCCESS;
860 }
861
862 return status;
863
864}
865
866
867SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_chat_send(const char *dest_proto, switch_event_t *message_event)
868{
869 switch_event_t *dup;
870
871 switch_event_dup(&dup, message_event);
872
873 if (dest_proto) {
874 switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "dest_proto", dest_proto);
875 }
876
877 chat_queue_message(&dup);
878 return SWITCH_STATUS_SUCCESS;
879}
880
881
882SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_chat_deliver(const char *dest_proto, switch_event_t **message_event)
883{
884
885 if (dest_proto) {
886 switch_event_add_header_string(*message_event, SWITCH_STACK_BOTTOM, "dest_proto", dest_proto);
887 }
888
889 chat_queue_message(message_event);
890
891 return SWITCH_STATUS_SUCCESS;
892}
893
894
895static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t *old_module)
896{
897 switch_event_t *event;
898 int removed = 0;
899
900 switch_mutex_lock(loadable_modules.mutex);
901
902 if (old_module->module_interface->endpoint_interface) {
903 const switch_endpoint_interface_t *ptr;
904
905 for (ptr = old_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
906 if (ptr->interface_name) {
907
908 switch_core_session_hupall_endpoint(ptr, SWITCH_CAUSE_MANAGER_REQUEST);
909 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 909, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
910 ptr->interface_name);
911 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
912 switch_thread_rwlock_unlock(ptr->rwlock);
913 } else {
914 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 914, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
915 }
916
917 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 917, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Endpoint '%s'\n", ptr->interface_name);
918 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 918, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
919 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "endpoint");
920 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
921 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 921, &event, ((void*)0))
;
922 removed++;
923 }
924 switch_core_hash_delete(loadable_modules.endpoint_hash, ptr->interface_name);
925 }
926 }
927 }
928
929 if (old_module->module_interface->codec_interface) {
930 const switch_codec_implementation_t *impl;
931 const switch_codec_interface_t *ptr;
932
933 for (ptr = old_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
934 if (ptr->interface_name) {
935 unsigned load_interface = 1;
936 for (impl = ptr->implementations; impl; impl = impl->next) {
937 if (!impl->iananame) {
938 load_interface = 0;
939 break;
940 }
941 }
942 if (load_interface) {
943 for (impl = ptr->implementations; impl; impl = impl->next) {
944 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 944, ((void*)0)
, SWITCH_LOG_NOTICE,
945 "Deleting Codec %s %d %s %dhz %dms\n",
946 impl->iananame, impl->ianacode,
947 ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000);
948 switch_core_session_hupall_matching_var("read_codec", impl->iananame, SWITCH_CAUSE_MANAGER_REQUEST)switch_core_session_hupall_matching_var_ans("read_codec", impl
->iananame, SWITCH_CAUSE_MANAGER_REQUEST, SHT_UNANSWERED |
SHT_ANSWERED)
;
949 switch_core_session_hupall_matching_var("write_codec", impl->iananame, SWITCH_CAUSE_MANAGER_REQUEST)switch_core_session_hupall_matching_var_ans("write_codec", impl
->iananame, SWITCH_CAUSE_MANAGER_REQUEST, SHT_UNANSWERED |
SHT_ANSWERED)
;
950 if (switch_core_hash_find(loadable_modules.codec_hash, impl->iananame)) {
951 switch_core_hash_delete(loadable_modules.codec_hash, impl->iananame);
952 }
953 }
954 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 954, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
955 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "codec");
956 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
957 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 957, &event, ((void*)0))
;
958 removed++;
959 }
960 }
961 }
962 }
963 }
964
965 if (old_module->module_interface->dialplan_interface) {
966 const switch_dialplan_interface_t *ptr;
967
968 for (ptr = old_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) {
969 if (ptr->interface_name) {
970 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 970, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Dialplan '%s'\n", ptr->interface_name);
971 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 971, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
972 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "dialplan");
973 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
974 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 974, &event, ((void*)0))
;
975 removed++;
976 }
977 switch_core_hash_delete(loadable_modules.dialplan_hash, ptr->interface_name);
978 }
979 }
980 }
981
982 if (old_module->module_interface->timer_interface) {
983 const switch_timer_interface_t *ptr;
984
985 for (ptr = old_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
986 if (ptr->interface_name) {
987 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 987, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Timer '%s'\n", ptr->interface_name);
988 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 988, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
989 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "timer");
990 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
991 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 991, &event, ((void*)0))
;
992 removed++;
993 }
994 switch_core_hash_delete(loadable_modules.timer_hash, ptr->interface_name);
995 }
996 }
997 }
998
999 if (old_module->module_interface->application_interface) {
1000 const switch_application_interface_t *ptr;
1001 for (ptr = old_module->module_interface->application_interface; ptr; ptr = ptr->next) {
1002 if (ptr->interface_name) {
1003 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1003, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
1004 switch_core_session_hupall_matching_var(SWITCH_CURRENT_APPLICATION_VARIABLE, ptr->interface_name, SWITCH_CAUSE_MANAGER_REQUEST)switch_core_session_hupall_matching_var_ans("current_application"
, ptr->interface_name, SWITCH_CAUSE_MANAGER_REQUEST, SHT_UNANSWERED
| SHT_ANSWERED)
;
1005 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1005, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1006 ptr->interface_name);
1007 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1008 switch_thread_rwlock_unlock(ptr->rwlock);
1009 } else {
1010 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1010, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1011 }
1012
1013 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1013, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1014 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
1015 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1016 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->short_desc)(ptr->short_desc ? ptr->short_desc : ""));
1017 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
1018 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1018, &event, ((void*)0)
)
;
1019 removed++;
1020 }
1021 switch_core_hash_delete(loadable_modules.application_hash, ptr->interface_name);
1022 }
1023 }
1024 }
1025
1026 if (old_module->module_interface->chat_application_interface) {
1027 const switch_chat_application_interface_t *ptr;
1028 for (ptr = old_module->module_interface->chat_application_interface; ptr; ptr = ptr->next) {
1029 if (ptr->interface_name) {
1030 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1030, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
1031 switch_core_session_hupall_matching_var(SWITCH_CURRENT_APPLICATION_VARIABLE, ptr->interface_name, SWITCH_CAUSE_MANAGER_REQUEST)switch_core_session_hupall_matching_var_ans("current_application"
, ptr->interface_name, SWITCH_CAUSE_MANAGER_REQUEST, SHT_UNANSWERED
| SHT_ANSWERED)
;
1032 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1032, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1033 ptr->interface_name);
1034 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1035 switch_thread_rwlock_unlock(ptr->rwlock);
1036 } else {
1037 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1037, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1038 }
1039
1040 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1040, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1041 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
1042 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1043 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->short_desc)(ptr->short_desc ? ptr->short_desc : ""));
1044 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
1045 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1045, &event, ((void*)0)
)
;
1046 removed++;
1047 }
1048 switch_core_hash_delete(loadable_modules.chat_application_hash, ptr->interface_name);
1049 }
1050 }
1051 }
1052
1053 if (old_module->module_interface->api_interface) {
1054 const switch_api_interface_t *ptr;
1055
1056 for (ptr = old_module->module_interface->api_interface; ptr; ptr = ptr->next) {
1057 if (ptr->interface_name) {
1058 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1058, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
1059
1060 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1060, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1061 ptr->interface_name);
1062
1063 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1064 switch_thread_rwlock_unlock(ptr->rwlock);
1065 } else {
1066 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1066, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1067 }
1068
1069
1070 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1070, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1071 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");
1072 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1073 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->desc)(ptr->desc ? ptr->desc : ""));
1074 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
1075 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1075, &event, ((void*)0)
)
;
1076 removed++;
1077 }
1078 switch_core_hash_delete(loadable_modules.api_hash, ptr->interface_name);
1079 }
1080 }
1081 }
1082
1083 if (old_module->module_interface->json_api_interface) {
1084 const switch_json_api_interface_t *ptr;
1085
1086 for (ptr = old_module->module_interface->json_api_interface; ptr; ptr = ptr->next) {
1087 if (ptr->interface_name) {
1088 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1088, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
1089
1090 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1090, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1091 ptr->interface_name);
1092
1093 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1094 switch_thread_rwlock_unlock(ptr->rwlock);
1095 } else {
1096 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1096, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1097 }
1098
1099
1100 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1100, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1101 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");
1102 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1103 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->desc)(ptr->desc ? ptr->desc : ""));
1104 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
1105 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1105, &event, ((void*)0)
)
;
1106 removed++;
1107 }
1108 switch_core_hash_delete(loadable_modules.json_api_hash, ptr->interface_name);
1109 }
1110 }
1111 }
1112
1113 if (old_module->module_interface->file_interface) {
1114 const switch_file_interface_t *ptr;
1115
1116 for (ptr = old_module->module_interface->file_interface; ptr; ptr = ptr->next) {
1117 if (ptr->interface_name) {
1118 int i;
1119
1120 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1120, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1121 ptr->interface_name);
1122
1123 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1124 switch_thread_rwlock_unlock(ptr->rwlock);
1125 } else {
1126 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1126, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1127 }
1128
1129 for (i = 0; ptr->extens[i]; i++) {
1130 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1130, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting File Format '%s'\n", ptr->extens[i]);
1131 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1131, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1132 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "file");
1133 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->extens[i]);
1134 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1134, &event, ((void*)0)
)
;
1135 removed++;
1136 }
1137 switch_core_hash_delete(loadable_modules.file_hash, ptr->extens[i]);
1138 }
1139 }
1140 }
1141 }
1142
1143 if (old_module->module_interface->speech_interface) {
1144 const switch_speech_interface_t *ptr;
1145
1146 for (ptr = old_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
1147
1148 if (ptr->interface_name) {
1149
1150 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1150, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1151 ptr->interface_name);
1152
1153 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1154 switch_thread_rwlock_unlock(ptr->rwlock);
1155 } else {
1156 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1156, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1157 }
1158
1159 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1159, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Speech interface '%s'\n", ptr->interface_name);
1160 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1160, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1161 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
1162 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1163 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1163, &event, ((void*)0)
)
;
1164 removed++;
1165 }
1166 switch_core_hash_delete(loadable_modules.speech_hash, ptr->interface_name);
1167 }
1168 }
1169 }
1170
1171 if (old_module->module_interface->asr_interface) {
1172 const switch_asr_interface_t *ptr;
1173
1174 for (ptr = old_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
1175 if (ptr->interface_name) {
1176
1177 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1177, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1178 ptr->interface_name);
1179
1180 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1181 switch_thread_rwlock_unlock(ptr->rwlock);
1182 } else {
1183 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1183, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1184 }
1185
1186 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1186, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Asr interface '%s'\n", ptr->interface_name);
1187 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1187, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1188 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "asr");
1189 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1190 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1190, &event, ((void*)0)
)
;
1191 removed++;
1192 }
1193 switch_core_hash_delete(loadable_modules.asr_hash, ptr->interface_name);
1194 }
1195 }
1196 }
1197
1198 if (old_module->module_interface->directory_interface) {
1199 const switch_directory_interface_t *ptr;
1200
1201 for (ptr = old_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
1202 if (ptr->interface_name) {
1203
1204 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1204, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1205 ptr->interface_name);
1206
1207 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1208 switch_thread_rwlock_unlock(ptr->rwlock);
1209 } else {
1210 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1210, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1211 }
1212
1213 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1213, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Directory interface '%s'\n", ptr->interface_name);
1214 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1214, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1215 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
1216 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1217 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1217, &event, ((void*)0)
)
;
1218 removed++;
1219 }
1220 switch_core_hash_delete(loadable_modules.directory_hash, ptr->interface_name);
1221 }
1222 }
1223 }
1224
1225
1226 if (old_module->module_interface->chat_interface) {
1227 const switch_chat_interface_t *ptr;
1228
1229 for (ptr = old_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
1230 if (ptr->interface_name) {
1231 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1231, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1232 ptr->interface_name);
1233
1234 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1235 switch_thread_rwlock_unlock(ptr->rwlock);
1236 } else {
1237 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1237, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1238 }
1239
1240 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1240, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Chat interface '%s'\n", ptr->interface_name);
1241 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1241, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1242 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
1243 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1244 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1244, &event, ((void*)0)
)
;
1245 removed++;
1246 }
1247 switch_core_hash_delete(loadable_modules.chat_hash, ptr->interface_name);
1248 }
1249 }
1250 }
1251
1252 if (old_module->module_interface->say_interface) {
1253 const switch_say_interface_t *ptr;
1254
1255 for (ptr = old_module->module_interface->say_interface; ptr; ptr = ptr->next) {
1256 if (ptr->interface_name) {
1257 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1257, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1258 ptr->interface_name);
1259
1260 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1261 switch_thread_rwlock_unlock(ptr->rwlock);
1262 } else {
1263 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1263, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1264 }
1265 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1265, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Say interface '%s'\n", ptr->interface_name);
1266 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1266, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1267 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "say");
1268 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1269 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1269, &event, ((void*)0)
)
;
1270 removed++;
1271 }
1272 switch_core_hash_delete(loadable_modules.say_hash, ptr->interface_name);
1273 }
1274 }
1275 }
1276
1277 if (old_module->module_interface->management_interface) {
1278 const switch_management_interface_t *ptr;
1279
1280 for (ptr = old_module->module_interface->management_interface; ptr; ptr = ptr->next) {
1281 if (ptr->relative_oid) {
1282 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1282, ((void*)0)
, SWITCH_LOG_NOTICE,
1283 "Deleting Management interface '%s' OID[%s.%s]\n", old_module->key, FREESWITCH_OID_PREFIX".1.3.6.1.4.1." "27880", ptr->relative_oid);
1284 switch_core_hash_delete(loadable_modules.management_hash, ptr->relative_oid);
1285 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1285, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1286 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "management");
1287 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->relative_oid);
1288 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1288, &event, ((void*)0)
)
;
1289 removed++;
1290 }
1291 }
1292 }
1293 }
1294
1295 if (old_module->module_interface->limit_interface) {
1296 const switch_limit_interface_t *ptr;
1297
1298 for (ptr = old_module->module_interface->limit_interface; ptr; ptr = ptr->next) {
1299 if (ptr->interface_name) {
1300 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1300, ((void*)0)
, SWITCH_LOG_NOTICE,
1301 "Deleting Limit interface '%s'\n", ptr->interface_name);
1302 switch_core_hash_delete(loadable_modules.limit_hash, ptr->interface_name);
1303 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1303, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1304 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "limit");
1305 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1306 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1306, &event, ((void*)0)
)
;
1307 removed++;
1308 }
1309 }
1310 }
1311 }
1312
1313 if (!removed) {
1314 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1314, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1315 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "generic");
1316 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", old_module->key);
1317 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1317, &event, ((void*)0)
)
;
1318 removed++;
1319 }
1320 }
1321 switch_mutex_unlock(loadable_modules.mutex);
1322
1323 return SWITCH_STATUS_SUCCESS;
1324
1325}
1326
1327
1328static switch_status_t switch_loadable_module_load_file(char *path, char *filename, switch_bool_t global, switch_loadable_module_t **new_module)
1329{
1330 switch_loadable_module_t *module = NULL((void*)0);
1331 switch_dso_lib_t dso = NULL((void*)0);
1332 apr_status_t status = SWITCH_STATUS_SUCCESS;
1333 switch_loadable_module_function_table_t *interface_struct_handle = NULL((void*)0);
1334 switch_loadable_module_function_table_t *mod_interface_functions = NULL((void*)0);
1335 char *struct_name = NULL((void*)0);
1336 switch_module_load_t load_func_ptr = NULL((void*)0);
1337 int loading = 1;
1338 switch_loadable_module_interface_t *module_interface = NULL((void*)0);
1339 char *derr = NULL((void*)0);
1340 const char *err = NULL((void*)0);
1341 switch_memory_pool_t *pool = NULL((void*)0);
1342 switch_bool_t load_global = global;
1343
1344 switch_assert(path != NULL)((path != ((void*)0)) ? (void) (0) : __assert_fail ("path != ((void*)0)"
, "src/switch_loadable_module.c", 1344, __PRETTY_FUNCTION__))
;
1345
1346 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 1346)
;
1347 *new_module = NULL((void*)0);
1348
1349 struct_name = switch_core_sprintf(pool, "%s_module_interface", filename);
1350
1351#ifdef WIN32
1352 dso = switch_dso_open("FreeSwitch.dll", load_global, &derr);
1353#elif defined (MACOSX) || defined(DARWIN)
1354 {
1355 char *lib_path = switch_mprintf("%s/libfreeswitch.dylib", SWITCH_GLOBAL_dirs.lib_dir);
1356 dso = switch_dso_open(lib_path, load_global, &derr);
1357 switch_safe_free(lib_path)if (lib_path) {free(lib_path);lib_path=((void*)0);};
1358 }
1359#else
1360 dso = switch_dso_open(NULL((void*)0), load_global, &derr);
1361#endif
1362 if (!derr && dso) {
1363 interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
1364 }
1365
1366 switch_safe_free(derr)if (derr) {free(derr);derr=((void*)0);};
1367
1368 if (!interface_struct_handle) {
1369 if (dso) switch_dso_destroy(&dso);
1370 dso = switch_dso_open(path, load_global, &derr);
1371 }
1372
1373 while (loading) {
1374 if (derr) {
1375 err = derr;
1376 break;
1377 }
1378
1379 if (!interface_struct_handle) {
1380 interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
1381 }
1382
1383 if (derr) {
1384 err = derr;
1385 break;
1386 }
1387
1388 if (interface_struct_handle && interface_struct_handle->switch_api_version != SWITCH_API_VERSION5) {
1389 err = "Trying to load an out of date module, please rebuild the module.";
1390 break;
1391 }
1392
1393 if (!load_global && interface_struct_handle && switch_test_flag(interface_struct_handle, SMODF_GLOBAL_SYMBOLS)((interface_struct_handle)->flags & SMODF_GLOBAL_SYMBOLS
)
) {
1394 load_global = SWITCH_TRUE;
1395 switch_dso_destroy(&dso);
1396 interface_struct_handle = NULL((void*)0);
1397 dso = switch_dso_open(path, load_global, &derr);
1398 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1398, ((void*)0)
, SWITCH_LOG_DEBUG, "Loading module with global namespace at request of module\n");
1399 continue;
1400 }
1401
1402 if (interface_struct_handle) {
1403 mod_interface_functions = interface_struct_handle;
1404 load_func_ptr = mod_interface_functions->load;
1405 }
1406
1407 if (load_func_ptr == NULL((void*)0)) {
1408 err = "Cannot locate symbol 'switch_module_load' please make sure this is a valid module.";
1409 break;
1410 }
1411
1412 status = load_func_ptr(&module_interface, pool);
1413
1414 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_NOUNLOAD) {
1415 err = "Module load routine returned an error";
1416 module_interface = NULL((void*)0);
1417 break;
1418 }
1419
1420 if (!module_interface) {
1421 err = "Module failed to initialize its module_interface. Is this a valid module?";
1422 break;
1423 }
1424
1425 if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))switch_core_perform_alloc(pool, sizeof(switch_loadable_module_t
), "src/switch_loadable_module.c", (const char *)__func__, 1425
)
) == 0) {
1426 err = "Could not allocate memory\n";
1427 abort();
1428 }
1429
1430 if (status == SWITCH_STATUS_NOUNLOAD) {
1431 module->perm++;
1432 }
1433
1434 loading = 0;
1435 }
1436
1437
1438 if (err) {
1439
1440 if (dso) {
1441 switch_dso_destroy(&dso);
1442 }
1443
1444 if (pool) {
1445 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 1445)
;
1446 }
1447 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1447, ((void*)0)
, SWITCH_LOG_CRIT, "Error Loading module %s\n**%s**\n", path, err);
1448 switch_safe_free(derr)if (derr) {free(derr);derr=((void*)0);};
1449 return SWITCH_STATUS_GENERR;
1450 }
1451
1452 module->pool = pool;
1453 module->filename = switch_core_strdup(module->pool, path)switch_core_perform_strdup(module->pool, path, "src/switch_loadable_module.c"
, (const char *)__func__, 1453)
;
1454 module->module_interface = module_interface;
1455 module->switch_module_load = load_func_ptr;
1456
1457 if (mod_interface_functions) {
1458 module->switch_module_shutdown = mod_interface_functions->shutdown;
1459 module->switch_module_runtime = mod_interface_functions->runtime;
1460 }
1461
1462 module->lib = dso;
1463
1464 *new_module = module;
1465 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1465, ((void*)0)
, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
1466
1467 switch_core_set_signal_handlers();
1468
1469 return SWITCH_STATUS_SUCCESS;
1470
1471}
1472SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_load_module(char *dir, char *fname, switch_bool_t runtime, const char **err)
1473{
1474 return switch_loadable_module_load_module_ex(dir, fname, runtime, SWITCH_FALSE, err);
1475}
1476
1477static switch_status_t switch_loadable_module_load_module_ex(char *dir, char *fname, switch_bool_t runtime, switch_bool_t global, const char **err)
1478{
1479 switch_size_t len = 0;
1480 char *path;
1481 char *file, *dot;
1482 switch_loadable_module_t *new_module = NULL((void*)0);
1483 switch_status_t status = SWITCH_STATUS_SUCCESS;
1484
1485#ifdef WIN32
1486 const char *ext = ".dll";
1487#else
1488 const char *ext = ".so";
1489#endif
1490
1491 *err = "";
1492
1493 if ((file = switch_core_strdup(loadable_modules.pool, fname)switch_core_perform_strdup(loadable_modules.pool, fname, "src/switch_loadable_module.c"
, (const char *)__func__, 1493)
) == 0) {
1494 *err = "allocation error";
1495 return SWITCH_STATUS_FALSE;
1496 }
1497
1498 if (switch_is_file_path(file)) {
1499 path = switch_core_strdup(loadable_modules.pool, file)switch_core_perform_strdup(loadable_modules.pool, file, "src/switch_loadable_module.c"
, (const char *)__func__, 1499)
;
1500 file = (char *) switch_cut_path(file);
1501 if ((dot = strchr(file, '.')(__extension__ (__builtin_constant_p ('.') && !__builtin_constant_p
(file) && ('.') == '\0' ? (char *) __rawmemchr (file
, '.') : __builtin_strchr (file, '.')))
)) {
1502 *dot = '\0';
1503 }
1504 } else {
1505 if ((dot = strchr(file, '.')(__extension__ (__builtin_constant_p ('.') && !__builtin_constant_p
(file) && ('.') == '\0' ? (char *) __rawmemchr (file
, '.') : __builtin_strchr (file, '.')))
)) {
1506 *dot = '\0';
1507 }
1508 len = strlen(dir);
1509 len += strlen(file);
1510 len += 8;
1511 path = (char *) switch_core_alloc(loadable_modules.pool, len)switch_core_perform_alloc(loadable_modules.pool, len, "src/switch_loadable_module.c"
, (const char *)__func__, 1511)
;
1512 switch_snprintf(path, len, "%s%s%s%s", dir, SWITCH_PATH_SEPARATOR"/", file, ext);
1513 }
1514
1515
1516 if (switch_core_hash_find_locked(loadable_modules.module_hash, file, loadable_modules.mutex)) {
1517 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1517, ((void*)0)
, SWITCH_LOG_WARNING, "Module %s Already Loaded!\n", file);
1518 *err = "Module already loaded";
1519 status = SWITCH_STATUS_FALSE;
1520 } else if ((status = switch_loadable_module_load_file(path, file, global, &new_module)) == SWITCH_STATUS_SUCCESS) {
1521 if ((status = switch_loadable_module_process(file, new_module)) == SWITCH_STATUS_SUCCESS && runtime) {
1522 if (new_module->switch_module_runtime) {
1523 new_module->thread = switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool);
1524 }
1525 } else if (status != SWITCH_STATUS_SUCCESS) {
1526 *err = "module load routine returned an error";
1527 }
1528 } else {
1529 *err = "module load file routine returned an error";
1530 }
1531
1532
1533 return status;
1534
1535}
1536
1537SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_exists(const char *mod)
1538{
1539 switch_status_t status;
1540
1541 if (zstr(mod)_zstr(mod)) {
1542 return SWITCH_STATUS_FALSE;
1543 }
1544
1545 switch_mutex_lock(loadable_modules.mutex);
1546 if (switch_core_hash_find(loadable_modules.module_hash, mod)) {
1547 status = SWITCH_STATUS_SUCCESS;
1548 } else {
1549 status = SWITCH_STATUS_FALSE;
1550 }
1551 switch_mutex_unlock(loadable_modules.mutex);
1552
1553 return status;
1554}
1555
1556SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_unload_module(char *dir, char *fname, switch_bool_t force, const char **err)
1557{
1558 switch_loadable_module_t *module = NULL((void*)0);
1559 switch_status_t status = SWITCH_STATUS_SUCCESS;
1560
1561 if (force) {
1562 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1562, ((void*)0)
, SWITCH_LOG_WARNING, "Spin the barrel and pull the trigger.......!\n");
1563 }
1564
1565 switch_mutex_lock(loadable_modules.mutex);
1566 if ((module = switch_core_hash_find(loadable_modules.module_hash, fname))) {
1567 if (module->perm) {
1568 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1568, ((void*)0)
, SWITCH_LOG_CRIT, "Module is not unloadable.\n");
1569 *err = "Module is not unloadable";
1570 status = SWITCH_STATUS_NOUNLOAD;
1571 goto unlock;
1572 } else {
1573 /* Prevent anything from using the module while it's shutting down */
1574 switch_core_hash_delete(loadable_modules.module_hash, fname);
1575 switch_mutex_unlock(loadable_modules.mutex);
1576 if ((status = do_shutdown(module, SWITCH_TRUE, SWITCH_TRUE, !force, err)) != SWITCH_STATUS_SUCCESS) {
1577 /* Something went wrong in the module's shutdown function, add it again */
1578 switch_core_hash_insert_locked(loadable_modules.module_hash, fname, module, loadable_modules.mutex);
1579 }
1580 goto end;
1581 }
1582 } else {
1583 *err = "No such module!";
1584 status = SWITCH_STATUS_FALSE;
1585 }
1586unlock:
1587 switch_mutex_unlock(loadable_modules.mutex);
1588 end:
1589 if (force) {
1590 switch_yield(1000000)switch_sleep(1000000);;
1591 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1591, ((void*)0)
, SWITCH_LOG_WARNING, "PHEW!\n");
1592 }
1593
1594 return status;
1595
1596}
1597
1598SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_enumerate_available(const char *dir_path, switch_modulename_callback_func_t callback, void *user_data)
1599{
1600 switch_dir_t *dir = NULL((void*)0);
1601 switch_status_t status;
1602 char buffer[256];
1603 const char *fname;
1604 const char *fname_ext;
1605 char *fname_base;
1606
1607#ifdef WIN32
1608 const char *ext = ".dll";
1609#else
1610 const char *ext = ".so";
1611#endif
1612
1613 if ((status = switch_dir_open(&dir, dir_path, loadable_modules.pool)) != SWITCH_STATUS_SUCCESS) {
1614 return status;
1615 }
1616
1617 while((fname = switch_dir_next_file(dir, buffer, sizeof(buffer)))) {
1618 if ((fname_ext = strrchr(fname, '.'))) {
1619 if (!strcmp(fname_ext, ext)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(fname_ext) && __builtin_constant_p (ext) &&
(__s1_len = __builtin_strlen (fname_ext), __s2_len = __builtin_strlen
(ext), (!((size_t)(const void *)((fname_ext) + 1) - (size_t)
(const void *)(fname_ext) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((ext) + 1) - (size_t)(const void *
)(ext) == 1) || __s2_len >= 4)) ? __builtin_strcmp (fname_ext
, ext) : (__builtin_constant_p (fname_ext) && ((size_t
)(const void *)((fname_ext) + 1) - (size_t)(const void *)(fname_ext
) == 1) && (__s1_len = __builtin_strlen (fname_ext), __s1_len
< 4) ? (__builtin_constant_p (ext) && ((size_t)(const
void *)((ext) + 1) - (size_t)(const void *)(ext) == 1) ? __builtin_strcmp
(fname_ext, ext) : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (ext); int __result
= (((const unsigned char *) (const char *) (fname_ext))[0] -
__s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (fname_ext))[1] -
__s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (fname_ext))[2] -
__s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (fname_ext))[3] -
__s2[3]); } } __result; }))) : (__builtin_constant_p (ext) &&
((size_t)(const void *)((ext) + 1) - (size_t)(const void *)(
ext) == 1) && (__s2_len = __builtin_strlen (ext), __s2_len
< 4) ? (__builtin_constant_p (fname_ext) && ((size_t
)(const void *)((fname_ext) + 1) - (size_t)(const void *)(fname_ext
) == 1) ? __builtin_strcmp (fname_ext, ext) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (fname_ext); int __result = (((const unsigned char *
) (const char *) (ext))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (ext))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (ext))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (ext))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(fname_ext, ext)))); })
) {
1620 if (!(fname_base = switch_mprintf("%.*s", (int)(fname_ext-fname), fname))) {
1621 status = SWITCH_STATUS_GENERR;
1622 goto end;
1623 }
1624 callback(user_data, fname_base);
1625 switch_safe_free(fname_base)if (fname_base) {free(fname_base);fname_base=((void*)0);}
1626 }
1627 }
1628 }
1629
1630
1631 end:
1632 switch_dir_close(dir);
1633 return status;
1634}
1635
1636SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_enumerate_loaded(switch_modulename_callback_func_t callback, void *user_data)
1637{
1638 switch_hash_index_t *hi;
1639 void *val;
1640 switch_loadable_module_t *module;
1641
1642 switch_mutex_lock(loadable_modules.mutex);
1643 for (hi = switch_core_hash_first(loadable_modules.module_hash)switch_core_hash_first_iter(loadable_modules.module_hash, ((void
*)0))
; hi; hi = switch_core_hash_next(&hi)) {
1644 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
1645 module = (switch_loadable_module_t *) val;
1646
1647 callback(user_data, module->module_interface->module_name);
1648 }
1649 switch_mutex_unlock(loadable_modules.mutex);
1650
1651 return SWITCH_STATUS_SUCCESS;
1652}
1653
1654SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_build_dynamic(char *filename,
1655 switch_module_load_t switch_module_load,
1656 switch_module_runtime_t switch_module_runtime,
1657 switch_module_shutdown_t switch_module_shutdown, switch_bool_t runtime)
1658{
1659 switch_loadable_module_t *module = NULL((void*)0);
1660 switch_module_load_t load_func_ptr = NULL((void*)0);
1661 int loading = 1;
1662 const char *err = NULL((void*)0);
1663 switch_loadable_module_interface_t *module_interface = NULL((void*)0);
1664 switch_memory_pool_t *pool;
1665
1666
1667 if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 1667)
!= SWITCH_STATUS_SUCCESS) {
1668 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1668, ((void*)0)
, SWITCH_LOG_CRIT, "OH OH no pool\n");
1669 abort();
1670 }
1671
1672 if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))switch_core_perform_alloc(pool, sizeof(switch_loadable_module_t
), "src/switch_loadable_module.c", (const char *)__func__, 1672
)
) == 0) {
1673 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1673, ((void*)0)
, SWITCH_LOG_CONSOLE, "Couldn't allocate memory\n");
1674 abort();
1675 }
1676
1677
1678
1679 while (loading) {
1680 switch_status_t status;
1681 load_func_ptr = (switch_module_load_t) switch_module_load;
1682
1683 if (load_func_ptr == NULL((void*)0)) {
1684 err = "Cannot Load";
1685 break;
1686 }
1687
1688 status = load_func_ptr(&module_interface, pool);
1689
1690 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_NOUNLOAD) {
1691 err = "Module load routine returned an error";
1692 module_interface = NULL((void*)0);
1693 break;
1694 }
1695
1696 if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))switch_core_perform_alloc(pool, sizeof(switch_loadable_module_t
), "src/switch_loadable_module.c", (const char *)__func__, 1696
)
) == 0) {
1697 err = "Could not allocate memory\n";
Value stored to 'err' is never read
1698 abort();
1699 }
1700
1701 if (status == SWITCH_STATUS_NOUNLOAD) {
1702 module->perm++;
1703 }
1704
1705 loading = 0;
1706 }
1707
1708 if (err) {
1709 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 1709)
;
1710 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1710, ((void*)0)
, SWITCH_LOG_CONSOLE, "Error Loading module %s\n**%s**\n", filename, err);
1711 return SWITCH_STATUS_GENERR;
1712 }
1713
1714 module->pool = pool;
1715 module->filename = switch_core_strdup(module->pool, filename)switch_core_perform_strdup(module->pool, filename, "src/switch_loadable_module.c"
, (const char *)__func__, 1715)
;
1716 module->module_interface = module_interface;
1717 module->switch_module_load = load_func_ptr;
1718
1719 if (switch_module_shutdown) {
1720 module->switch_module_shutdown = switch_module_shutdown;
1721 }
1722 if (switch_module_runtime) {
1723 module->switch_module_runtime = switch_module_runtime;
1724 }
1725 if (runtime && module->switch_module_runtime) {
1726 module->thread = switch_core_launch_thread(switch_loadable_module_exec, module, module->pool);
1727 }
1728 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1728, ((void*)0)
, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
1729 return switch_loadable_module_process((char *) module->filename, module);
1730}
1731
1732#ifdef WIN32
1733static void switch_loadable_module_path_init()
1734{
1735 char *path = NULL((void*)0), *working = NULL((void*)0);
1736 apr_dir_t *perl_dir_handle = NULL((void*)0);
1737
1738 apr_env_get(&path, "path", loadable_modules.pool);
1739 apr_filepath_get(&working, APR_FILEPATH_NATIVE0x10, loadable_modules.pool);
1740
1741 if (apr_dir_open(&perl_dir_handle, ".\\perl", loadable_modules.pool) == APR_SUCCESS0) {
1742 apr_dir_close(perl_dir_handle);
1743 apr_env_set("path", apr_pstrcat(loadable_modules.pool, path, ";", working, "\\perl", NULL((void*)0)), loadable_modules.pool);
1744 }
1745}
1746#endif
1747
1748SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_init(switch_bool_t autoload)
1749{
1750
1751 apr_finfo_t finfo = { 0 };
1752 apr_dir_t *module_dir_handle = NULL((void*)0);
1753 apr_int32_t finfo_flags = APR_FINFO_DIRENT0x02000000 | APR_FINFO_TYPE0x00008000 | APR_FINFO_NAME0x02000000;
1754 char *cf = "modules.conf";
1755 char *pcf = "post_load_modules.conf";
1756 switch_xml_t cfg, xml;
1757 unsigned char all = 0;
1758 unsigned int count = 0;
1759 const char *err;
1760
1761
1762#ifdef WIN32
1763 const char *ext = ".dll";
1764 const char *EXT = ".DLL";
1765#elif defined (MACOSX) || defined (DARWIN)
1766 const char *ext = ".dylib";
1767 const char *EXT = ".DYLIB";
1768#else
1769 const char *ext = ".so";
1770 const char *EXT = ".SO";
1771#endif
1772
1773 memset(&loadable_modules, 0, sizeof(loadable_modules));
1774 switch_core_new_memory_pool(&loadable_modules.pool)switch_core_perform_new_memory_pool(&loadable_modules.pool
, "src/switch_loadable_module.c", (const char *)__func__, 1774
)
;
1775
1776
1777#ifdef WIN32
1778 switch_loadable_module_path_init();
1779#endif
1780
1781 switch_core_hash_init(&loadable_modules.module_hash)switch_core_hash_init_case(&loadable_modules.module_hash,
SWITCH_TRUE)
;
1782 switch_core_hash_init_nocase(&loadable_modules.endpoint_hash)switch_core_hash_init_case(&loadable_modules.endpoint_hash
, SWITCH_FALSE)
;
1783 switch_core_hash_init_nocase(&loadable_modules.codec_hash)switch_core_hash_init_case(&loadable_modules.codec_hash, SWITCH_FALSE
)
;
1784 switch_core_hash_init_nocase(&loadable_modules.timer_hash)switch_core_hash_init_case(&loadable_modules.timer_hash, SWITCH_FALSE
)
;
1785 switch_core_hash_init_nocase(&loadable_modules.application_hash)switch_core_hash_init_case(&loadable_modules.application_hash
, SWITCH_FALSE)
;
1786 switch_core_hash_init_nocase(&loadable_modules.chat_application_hash)switch_core_hash_init_case(&loadable_modules.chat_application_hash
, SWITCH_FALSE)
;
1787 switch_core_hash_init_nocase(&loadable_modules.api_hash)switch_core_hash_init_case(&loadable_modules.api_hash, SWITCH_FALSE
)
;
1788 switch_core_hash_init_nocase(&loadable_modules.json_api_hash)switch_core_hash_init_case(&loadable_modules.json_api_hash
, SWITCH_FALSE)
;
1789 switch_core_hash_init(&loadable_modules.file_hash)switch_core_hash_init_case(&loadable_modules.file_hash, SWITCH_TRUE
)
;
1790 switch_core_hash_init_nocase(&loadable_modules.speech_hash)switch_core_hash_init_case(&loadable_modules.speech_hash,
SWITCH_FALSE)
;
1791 switch_core_hash_init_nocase(&loadable_modules.asr_hash)switch_core_hash_init_case(&loadable_modules.asr_hash, SWITCH_FALSE
)
;
1792 switch_core_hash_init_nocase(&loadable_modules.directory_hash)switch_core_hash_init_case(&loadable_modules.directory_hash
, SWITCH_FALSE)
;
1793 switch_core_hash_init_nocase(&loadable_modules.chat_hash)switch_core_hash_init_case(&loadable_modules.chat_hash, SWITCH_FALSE
)
;
1794 switch_core_hash_init_nocase(&loadable_modules.say_hash)switch_core_hash_init_case(&loadable_modules.say_hash, SWITCH_FALSE
)
;
1795 switch_core_hash_init_nocase(&loadable_modules.management_hash)switch_core_hash_init_case(&loadable_modules.management_hash
, SWITCH_FALSE)
;
1796 switch_core_hash_init_nocase(&loadable_modules.limit_hash)switch_core_hash_init_case(&loadable_modules.limit_hash, SWITCH_FALSE
)
;
1797 switch_core_hash_init_nocase(&loadable_modules.dialplan_hash)switch_core_hash_init_case(&loadable_modules.dialplan_hash
, SWITCH_FALSE)
;
1798 switch_core_hash_init(&loadable_modules.secondary_recover_hash)switch_core_hash_init_case(&loadable_modules.secondary_recover_hash
, SWITCH_TRUE)
;
1799 switch_mutex_init(&loadable_modules.mutex, SWITCH_MUTEX_NESTED0x1, loadable_modules.pool);
1800
1801 if (!autoload) return SWITCH_STATUS_SUCCESS;
1802
1803 switch_loadable_module_load_module("", "CORE_SOFTTIMER_MODULE", SWITCH_FALSE, &err);
1804 switch_loadable_module_load_module("", "CORE_PCM_MODULE", SWITCH_FALSE, &err);
1805 switch_loadable_module_load_module("", "CORE_SPEEX_MODULE", SWITCH_FALSE, &err);
1806
1807
1808 if ((xml = switch_xml_open_cfg(cf, &cfg, NULL((void*)0)))) {
1809 switch_xml_t mods, ld;
1810 if ((mods = switch_xml_child(cfg, "modules"))) {
1811 for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
1812 switch_bool_t global = SWITCH_FALSE;
1813 const char *val = switch_xml_attr_soft(ld, "module");
1814 const char *path = switch_xml_attr_soft(ld, "path");
1815 const char *critical = switch_xml_attr_soft(ld, "critical");
1816 const char *sglobal = switch_xml_attr_soft(ld, "global");
1817 if (zstr(val)_zstr(val) || (strchr(val, '.')(__extension__ (__builtin_constant_p ('.') && !__builtin_constant_p
(val) && ('.') == '\0' ? (char *) __rawmemchr (val, '.'
) : __builtin_strchr (val, '.')))
&& !strstr(val, ext) && !strstr(val, EXT))) {
1818 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1818, ((void*)0)
, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
1819 continue;
1820 }
1821 global = switch_true(sglobal);
1822
1823 if (path && zstr(path)_zstr(path)) {
1824 path = SWITCH_GLOBAL_dirs.mod_dir;
1825 }
1826 if (switch_loadable_module_load_module_ex((char *) path, (char *) val, SWITCH_FALSE, global, &err) == SWITCH_STATUS_GENERR) {
1827 if (critical && switch_true(critical)) {
1828 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1828, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val);
1829 abort();
1830 }
1831 }
1832 count++;
1833 }
1834 }
1835 switch_xml_free(xml);
1836
1837 } else {
1838 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1838, ((void*)0)
, SWITCH_LOG_CONSOLE, "open of %s failed\n", cf);
1839 }
1840
1841 if ((xml = switch_xml_open_cfg(pcf, &cfg, NULL((void*)0)))) {
1842 switch_xml_t mods, ld;
1843
1844 if ((mods = switch_xml_child(cfg, "modules"))) {
1845 for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
1846 switch_bool_t global = SWITCH_FALSE;
1847 const char *val = switch_xml_attr_soft(ld, "module");
1848 const char *path = switch_xml_attr_soft(ld, "path");
1849 const char *sglobal = switch_xml_attr_soft(ld, "global");
1850 if (zstr(val)_zstr(val) || (strchr(val, '.')(__extension__ (__builtin_constant_p ('.') && !__builtin_constant_p
(val) && ('.') == '\0' ? (char *) __rawmemchr (val, '.'
) : __builtin_strchr (val, '.')))
&& !strstr(val, ext) && !strstr(val, EXT))) {
1851 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1851, ((void*)0)
, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
1852 continue;
1853 }
1854 global = switch_true(sglobal);
1855
1856 if (path && zstr(path)_zstr(path)) {
1857 path = SWITCH_GLOBAL_dirs.mod_dir;
1858 }
1859 switch_loadable_module_load_module_ex((char *) path, (char *) val, SWITCH_FALSE, global, &err);
1860 count++;
1861 }
1862 }
1863 switch_xml_free(xml);
1864
1865 } else {
1866 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1866, ((void*)0)
, SWITCH_LOG_CONSOLE, "open of %s failed\n", pcf);
1867 }
1868
1869 if (!count) {
1870 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1870, ((void*)0)
, SWITCH_LOG_CONSOLE, "No modules loaded, assuming 'load all'\n");
1871 all = 1;
1872 }
1873
1874 if (all) {
1875 if (apr_dir_open(&module_dir_handle, SWITCH_GLOBAL_dirs.mod_dir, loadable_modules.pool) != APR_SUCCESS0) {
1876 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1876, ((void*)0)
, SWITCH_LOG_CONSOLE, "Can't open directory: %s\n", SWITCH_GLOBAL_dirs.mod_dir);
1877 return SWITCH_STATUS_GENERR;
1878 }
1879
1880 while (apr_dir_read(&finfo, finfo_flags, module_dir_handle) == APR_SUCCESS0) {
1881 const char *fname = finfo.fname;
1882
1883 if (finfo.filetype != APR_REG) {
1884 continue;
1885 }
1886
1887 if (!fname) {
1888 fname = finfo.name;
1889 }
1890
1891 if (!fname) {
1892 continue;
1893 }
1894
1895 if (zstr(fname)_zstr(fname) || (!strstr(fname, ext) && !strstr(fname, EXT))) {
1896 continue;
1897 }
1898
1899 switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) fname, SWITCH_FALSE, &err);
1900 }
1901 apr_dir_close(module_dir_handle);
1902 }
1903
1904 switch_loadable_module_runtime();
1905
1906 memset(&chat_globals, 0, sizeof(chat_globals));
1907 chat_globals.running = 1;
1908 chat_globals.pool = loadable_modules.pool;
1909 switch_mutex_init(&chat_globals.mutex, SWITCH_MUTEX_NESTED0x1, chat_globals.pool);
1910
1911 chat_thread_start(1);
1912
1913 return SWITCH_STATUS_SUCCESS;
1914}
1915
1916static switch_status_t do_shutdown(switch_loadable_module_t *module, switch_bool_t shutdown, switch_bool_t unload, switch_bool_t fail_if_busy,
1917 const char **err)
1918{
1919 int32_t flags = switch_core_flags();
1920 switch_assert(module != NULL)((module != ((void*)0)) ? (void) (0) : __assert_fail ("module != ((void*)0)"
, "src/switch_loadable_module.c", 1920, __PRETTY_FUNCTION__))
;
1921
1922 if (fail_if_busy && module->module_interface->rwlock && switch_thread_rwlock_trywrlock(module->module_interface->rwlock) != SWITCH_STATUS_SUCCESS) {
1923 if (err) {
1924 *err = "Module in use.";
1925 }
1926 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1926, ((void*)0)
, SWITCH_LOG_WARNING, "Module %s is in use, cannot unload.\n", module->module_interface->module_name);
1927 return SWITCH_STATUS_FALSE;
1928 }
1929
1930 module->shutting_down = SWITCH_TRUE;
1931
1932 if (shutdown) {
1933 switch_loadable_module_unprocess(module);
1934 if (module->switch_module_shutdown) {
1935 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1935, ((void*)0)
, SWITCH_LOG_CONSOLE, "Stopping: %s\n", module->module_interface->module_name);
1936 module->status = module->switch_module_shutdown();
1937 } else {
1938 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1938, ((void*)0)
, SWITCH_LOG_CONSOLE, "%s has no shutdown routine\n", module->module_interface->module_name);
1939 }
1940 }
1941
1942 if (fail_if_busy && module->module_interface->rwlock) {
1943 switch_thread_rwlock_unlock(module->module_interface->rwlock);
1944 }
1945
1946 if (unload && module->status != SWITCH_STATUS_NOUNLOAD && !(flags & SCF_VG)) {
1947 switch_memory_pool_t *pool;
1948 switch_status_t st;
1949
1950 if (module->thread) {
1951 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1951, ((void*)0)
, SWITCH_LOG_CONSOLE, "%s stopping runtime thread.\n", module->module_interface->module_name);
1952 switch_thread_join(&st, module->thread);
1953 }
1954
1955 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1955, ((void*)0)
, SWITCH_LOG_CONSOLE, "%s unloaded.\n", module->module_interface->module_name);
1956 switch_dso_destroy(&module->lib);
1957 if ((pool = module->pool)) {
1958 module = NULL((void*)0);
1959 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 1959)
;
1960 }
1961 }
1962
1963 return SWITCH_STATUS_SUCCESS;
1964
1965}
1966
1967SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_loadable_module_shutdown(void)
1968{
1969 switch_hash_index_t *hi;
1970 void *val;
1971 switch_loadable_module_t *module;
1972 int i;
1973
1974 if (!loadable_modules.module_hash) {
1975 return;
1976 }
1977
1978 chat_globals.running = 0;
1979
1980 for (i = 0; i < chat_globals.msg_queue_len; i++) {
1981 switch_queue_push(chat_globals.msg_queue[i], NULL((void*)0));
1982 }
1983
1984 for (i = 0; i < chat_globals.msg_queue_len; i++) {
1985 switch_status_t st;
1986 switch_thread_join(&st, chat_globals.msg_queue_thread[i]);
1987 }
1988
1989
1990 for (hi = switch_core_hash_first(loadable_modules.module_hash)switch_core_hash_first_iter(loadable_modules.module_hash, ((void
*)0))
; hi; hi = switch_core_hash_next(&hi)) {
1991 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
1992 module = (switch_loadable_module_t *) val;
1993 if (!module->perm) {
1994 do_shutdown(module, SWITCH_TRUE, SWITCH_FALSE, SWITCH_FALSE, NULL((void*)0));
1995 }
1996 }
1997
1998 switch_yield(1000000)switch_sleep(1000000);;
1999
2000 for (hi = switch_core_hash_first(loadable_modules.module_hash)switch_core_hash_first_iter(loadable_modules.module_hash, ((void
*)0))
; hi; hi = switch_core_hash_next(&hi)) {
2001 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
2002 module = (switch_loadable_module_t *) val;
2003 if (!module->perm) {
2004 do_shutdown(module, SWITCH_FALSE, SWITCH_TRUE, SWITCH_FALSE, NULL((void*)0));
2005 }
2006 }
2007
2008 switch_core_hash_destroy(&loadable_modules.module_hash);
2009 switch_core_hash_destroy(&loadable_modules.endpoint_hash);
2010 switch_core_hash_destroy(&loadable_modules.codec_hash);
2011 switch_core_hash_destroy(&loadable_modules.timer_hash);
2012 switch_core_hash_destroy(&loadable_modules.application_hash);
2013 switch_core_hash_destroy(&loadable_modules.chat_application_hash);
2014 switch_core_hash_destroy(&loadable_modules.api_hash);
2015 switch_core_hash_destroy(&loadable_modules.json_api_hash);
2016 switch_core_hash_destroy(&loadable_modules.file_hash);
2017 switch_core_hash_destroy(&loadable_modules.speech_hash);
2018 switch_core_hash_destroy(&loadable_modules.asr_hash);
2019 switch_core_hash_destroy(&loadable_modules.directory_hash);
2020 switch_core_hash_destroy(&loadable_modules.chat_hash);
2021 switch_core_hash_destroy(&loadable_modules.say_hash);
2022 switch_core_hash_destroy(&loadable_modules.management_hash);
2023 switch_core_hash_destroy(&loadable_modules.limit_hash);
2024 switch_core_hash_destroy(&loadable_modules.dialplan_hash);
2025
2026 switch_core_destroy_memory_pool(&loadable_modules.pool)switch_core_perform_destroy_memory_pool(&loadable_modules
.pool, "src/switch_loadable_module.c", (const char *)__func__
, 2026)
;
2027}
2028
2029SWITCH_DECLARE(switch_endpoint_interface_t *)__attribute__((visibility("default"))) switch_endpoint_interface_t
*
switch_loadable_module_get_endpoint_interface(const char *name)
2030{
2031 switch_endpoint_interface_t *ptr;
2032
2033 switch_mutex_lock(loadable_modules.mutex);
2034 ptr = switch_core_hash_find(loadable_modules.endpoint_hash, name);
2035 if (ptr) {
2036 PROTECT_INTERFACE(ptr)if (ptr) {switch_mutex_lock(ptr->reflock); switch_thread_rwlock_rdlock
(ptr->parent->rwlock); switch_thread_rwlock_rdlock(ptr->
rwlock); ptr->refs++; ptr->parent->refs++; switch_mutex_unlock
(ptr->reflock);}
;
2037 }
2038 switch_mutex_unlock(loadable_modules.mutex);
2039
2040
2041 return ptr;
2042}
2043
2044SWITCH_DECLARE(switch_codec_interface_t *)__attribute__((visibility("default"))) switch_codec_interface_t
*
switch_loadable_module_get_codec_interface(const char *name)
2045{
2046 char altname[256] = "";
2047 switch_codec_interface_t *codec;
2048 switch_size_t x;
2049
2050 switch_mutex_lock(loadable_modules.mutex);
2051 if (!(codec = switch_core_hash_find(loadable_modules.codec_hash, name))) {
2052 for (x = 0; x < strlen(name); x++) {
2053 altname[x] = (char) toupper((int) name[x])(__extension__ ({ int __res; if (sizeof ((int) name[x]) > 1
) { if (__builtin_constant_p ((int) name[x])) { int __c = ((int
) name[x]); __res = __c < -128 || __c > 255 ? __c : (*__ctype_toupper_loc
())[__c]; } else __res = toupper ((int) name[x]); } else __res
= (*__ctype_toupper_loc ())[(int) ((int) name[x])]; __res; }
))
;
2054 }
2055 if (!(codec = switch_core_hash_find(loadable_modules.codec_hash, altname))) {
2056 for (x = 0; x < strlen(name); x++) {
2057 altname[x] = (char) tolower((int) name[x])(__extension__ ({ int __res; if (sizeof ((int) name[x]) > 1
) { if (__builtin_constant_p ((int) name[x])) { int __c = ((int
) name[x]); __res = __c < -128 || __c > 255 ? __c : (*__ctype_tolower_loc
())[__c]; } else __res = tolower ((int) name[x]); } else __res
= (*__ctype_tolower_loc ())[(int) ((int) name[x])]; __res; }
))
;
2058 }
2059 codec = switch_core_hash_find(loadable_modules.codec_hash, altname);
2060 }
2061 }
2062 switch_mutex_unlock(loadable_modules.mutex);
2063
2064 if (codec) {
2065 PROTECT_INTERFACE(codec)if (codec) {switch_mutex_lock(codec->reflock); switch_thread_rwlock_rdlock
(codec->parent->rwlock); switch_thread_rwlock_rdlock(codec
->rwlock); codec->refs++; codec->parent->refs++; switch_mutex_unlock
(codec->reflock);}
;
2066 }
2067
2068 return codec;
2069}
2070
2071#define HASH_FUNC(_kind_)__attribute__((visibility("default"))) switch__kind__interface_t
* switch_loadable_module_get__kind__interface(const char *name
) { switch__kind__interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules._kind__hash, name, loadable_modules.mutex))
) { if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
SWITCH_DECLARE(switch_##_kind_##_interface_t *)__attribute__((visibility("default"))) switch_##_kind_##_interface_t
*
switch_loadable_module_get_##_kind_##_interface(const char *name) \
2072 { \
2073 switch_##_kind_##_interface_t *i; \
2074 if ((i = switch_core_hash_find_locked(loadable_modules._kind_##_hash, name, loadable_modules.mutex))) { \
2075 PROTECT_INTERFACE(i)if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}
; \
2076 } \
2077 return i; \
2078 }
2079
2080HASH_FUNC(dialplan)__attribute__((visibility("default"))) switch_dialplan_interface_t
* switch_loadable_module_get_dialplan_interface(const char *
name) { switch_dialplan_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.dialplan_hash, name, loadable_modules.mutex
))) { if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2081HASH_FUNC(timer)__attribute__((visibility("default"))) switch_timer_interface_t
* switch_loadable_module_get_timer_interface(const char *name
) { switch_timer_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.timer_hash, name, loadable_modules.mutex)))
{ if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2082HASH_FUNC(application)__attribute__((visibility("default"))) switch_application_interface_t
* switch_loadable_module_get_application_interface(const char
*name) { switch_application_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.application_hash, name, loadable_modules.mutex
))) { if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2083HASH_FUNC(chat_application)__attribute__((visibility("default"))) switch_chat_application_interface_t
* switch_loadable_module_get_chat_application_interface(const
char *name) { switch_chat_application_interface_t *i; if ((i
= switch_core_hash_find_locked(loadable_modules.chat_application_hash
, name, loadable_modules.mutex))) { if (i) {switch_mutex_lock
(i->reflock); switch_thread_rwlock_rdlock(i->parent->
rwlock); switch_thread_rwlock_rdlock(i->rwlock); i->refs
++; i->parent->refs++; switch_mutex_unlock(i->reflock
);}; } return i; }
2084HASH_FUNC(api)__attribute__((visibility("default"))) switch_api_interface_t
* switch_loadable_module_get_api_interface(const char *name)
{ switch_api_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.api_hash, name, loadable_modules.mutex))) {
if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2085HASH_FUNC(json_api)__attribute__((visibility("default"))) switch_json_api_interface_t
* switch_loadable_module_get_json_api_interface(const char *
name) { switch_json_api_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.json_api_hash, name, loadable_modules.mutex
))) { if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2086HASH_FUNC(file)__attribute__((visibility("default"))) switch_file_interface_t
* switch_loadable_module_get_file_interface(const char *name
) { switch_file_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.file_hash, name, loadable_modules.mutex))) {
if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2087HASH_FUNC(speech)__attribute__((visibility("default"))) switch_speech_interface_t
* switch_loadable_module_get_speech_interface(const char *name
) { switch_speech_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.speech_hash, name, loadable_modules.mutex))
) { if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2088HASH_FUNC(asr)__attribute__((visibility("default"))) switch_asr_interface_t
* switch_loadable_module_get_asr_interface(const char *name)
{ switch_asr_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.asr_hash, name, loadable_modules.mutex))) {
if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2089HASH_FUNC(directory)__attribute__((visibility("default"))) switch_directory_interface_t
* switch_loadable_module_get_directory_interface(const char *
name) { switch_directory_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.directory_hash, name, loadable_modules.mutex
))) { if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2090HASH_FUNC(chat)__attribute__((visibility("default"))) switch_chat_interface_t
* switch_loadable_module_get_chat_interface(const char *name
) { switch_chat_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.chat_hash, name, loadable_modules.mutex))) {
if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2091HASH_FUNC(limit)__attribute__((visibility("default"))) switch_limit_interface_t
* switch_loadable_module_get_limit_interface(const char *name
) { switch_limit_interface_t *i; if ((i = switch_core_hash_find_locked
(loadable_modules.limit_hash, name, loadable_modules.mutex)))
{ if (i) {switch_mutex_lock(i->reflock); switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2092
2093
2094SWITCH_DECLARE(switch_say_interface_t *)__attribute__((visibility("default"))) switch_say_interface_t
*
switch_loadable_module_get_say_interface(const char *name)
2095{
2096 return switch_core_hash_find_locked(loadable_modules.say_hash, name, loadable_modules.mutex);
2097}
2098
2099SWITCH_DECLARE(switch_management_interface_t *)__attribute__((visibility("default"))) switch_management_interface_t
*
switch_loadable_module_get_management_interface(const char *relative_oid)
2100{
2101 return switch_core_hash_find_locked(loadable_modules.management_hash, relative_oid, loadable_modules.mutex);
2102}
2103
2104#ifdef DEBUG_CODEC_SORTING
2105static void do_print(const switch_codec_implementation_t **array, int arraylen)
2106{
2107 int i;
2108
2109 for(i = 0; i < arraylen; i++) {
2110 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2110, ((void*)0)
, SWITCH_LOG_ERROR,
2111 "DEBUG %d %s:%d %d\n", i, array[i]->iananame, array[i]->ianacode, array[i]->microseconds_per_packet / 1000);
2112 }
2113
2114}
2115#endif
2116
2117/* helper only -- bounds checking enforced by caller */
2118static void do_swap(const switch_codec_implementation_t **array, int a, int b)
2119{
2120 const switch_codec_implementation_t *tmp = array[b];
2121 array[b] = array[a];
2122 array[a] = tmp;
2123}
2124
2125static void switch_loadable_module_sort_codecs(const switch_codec_implementation_t **array, int arraylen)
2126{
2127 int i = 0, sorted_ptime = 0;
2128
2129#ifdef DEBUG_CODEC_SORTING
2130 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2130, ((void*)0)
, SWITCH_LOG_ERROR, "--BEFORE\n");
2131 do_print(array, arraylen);
2132 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2132, ((void*)0)
, SWITCH_LOG_ERROR, "--BEFORE\n");
2133#endif
2134
2135 for (i = 0; i < arraylen; i++) {
2136 int this_ptime = array[i]->microseconds_per_packet / 1000;
2137
2138 if (!strcasecmp(array[i]->iananame, "ilbc")) {
2139 this_ptime = 20;
2140 }
2141
2142 if (!sorted_ptime) {
2143 sorted_ptime = this_ptime;
2144#ifdef DEBUG_CODEC_SORTING
2145 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2145, ((void*)0)
, SWITCH_LOG_ERROR, "sorted1 = %d\n", sorted_ptime);
2146#endif
2147 }
2148
2149 if (i > 0 && strcasecmp(array[i]->iananame, array[i-1]->iananame) && this_ptime != sorted_ptime) {
2150 int j;
2151 int swapped = 0;
2152
2153#ifdef DEBUG_CODEC_SORTING
2154 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2154, ((void*)0)
, SWITCH_LOG_ERROR, "%d != %d\n", this_ptime, sorted_ptime);
2155#endif
2156 for(j = i; j < arraylen; j++) {
2157 int check_ptime = array[j]->microseconds_per_packet / 1000;
2158
2159 if (!strcasecmp(array[i]->iananame, "ilbc")) {
2160 check_ptime = 20;
2161 }
2162
2163 if (check_ptime == sorted_ptime) {
2164#ifdef DEBUG_CODEC_SORTING
2165 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2165, ((void*)0)
, SWITCH_LOG_ERROR, "swap %d %d ptime %d\n", i, j, check_ptime);
2166#endif
2167 do_swap(array, i, j);
2168 swapped = 1;
2169 break;
2170 }
2171 }
2172
2173 if (!swapped) {
2174 sorted_ptime = this_ptime;
2175#ifdef DEBUG_CODEC_SORTING
2176 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2176, ((void*)0)
, SWITCH_LOG_ERROR, "sorted2 = %d\n", sorted_ptime);
2177#endif
2178 }
2179 }
2180 }
2181
2182#ifdef DEBUG_CODEC_SORTING
2183 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2183, ((void*)0)
, SWITCH_LOG_ERROR, "--AFTER\n");
2184 do_print(array, arraylen);
2185 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2185, ((void*)0)
, SWITCH_LOG_ERROR, "--AFTER\n");
2186#endif
2187
2188}
2189
2190
2191SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_loadable_module_get_codecs(const switch_codec_implementation_t **array, int arraylen)
2192{
2193 switch_hash_index_t *hi;
2194 void *val;
2195 switch_codec_interface_t *codec_interface;
2196 int i = 0;
2197 const switch_codec_implementation_t *imp;
2198
2199 switch_mutex_lock(loadable_modules.mutex);
2200 for (hi = switch_core_hash_first(loadable_modules.codec_hash)switch_core_hash_first_iter(loadable_modules.codec_hash, ((void
*)0))
; hi; hi = switch_core_hash_next(&hi)) {
2201 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
2202 codec_interface = (switch_codec_interface_t *) val;
2203
2204 /* Look for the default ptime of the codec because it's the safest choice */
2205 for (imp = codec_interface->implementations; imp; imp = imp->next) {
2206 uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode);
2207
2208 if (imp->microseconds_per_packet / 1000 == (int)default_ptime) {
2209 array[i++] = imp;
2210 goto found;
2211 }
2212 }
2213 /* oh well we will use what we have */
2214 array[i++] = codec_interface->implementations;
2215
2216 found:
2217
2218 if (i > arraylen) {
2219 break;
2220 }
2221 }
2222 switch_safe_free(hi)if (hi) {free(hi);hi=((void*)0);};
2223
2224 switch_mutex_unlock(loadable_modules.mutex);
2225
2226 switch_loadable_module_sort_codecs(array, i);
2227
2228 return i;
2229
2230}
2231
2232SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_parse_codec_buf(char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit, uint32_t *channels)
2233{
2234 char *cur, *next = NULL((void*)0), *name, *p;
2235
2236 name = next = cur = buf;
2237
2238 *channels = 1;
2239
2240 for (;;) {
2241 if (!next) {
2242 break;
2243 }
2244
2245 if ((p = strchr(next, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(next) && ('@') == '\0' ? (char *) __rawmemchr (next
, '@') : __builtin_strchr (next, '@')))
)) {
2246 *p++ = '\0';
2247 }
2248 next = p;
2249
2250 if (cur != name) {
2251 if (strchr(cur, 'i')(__extension__ (__builtin_constant_p ('i') && !__builtin_constant_p
(cur) && ('i') == '\0' ? (char *) __rawmemchr (cur, 'i'
) : __builtin_strchr (cur, 'i')))
) {
2252 *interval = atoi(cur);
2253 } else if ((strchr(cur, 'k')(__extension__ (__builtin_constant_p ('k') && !__builtin_constant_p
(cur) && ('k') == '\0' ? (char *) __rawmemchr (cur, 'k'
) : __builtin_strchr (cur, 'k')))
|| strchr(cur, 'h')(__extension__ (__builtin_constant_p ('h') && !__builtin_constant_p
(cur) && ('h') == '\0' ? (char *) __rawmemchr (cur, 'h'
) : __builtin_strchr (cur, 'h')))
)) {
2254 *rate = atoi(cur);
2255 } else if (strchr(cur, 'b')(__extension__ (__builtin_constant_p ('b') && !__builtin_constant_p
(cur) && ('b') == '\0' ? (char *) __rawmemchr (cur, 'b'
) : __builtin_strchr (cur, 'b')))
) {
2256 *bit = atoi(cur);
2257 } else if (strchr(cur, 'c')(__extension__ (__builtin_constant_p ('c') && !__builtin_constant_p
(cur) && ('c') == '\0' ? (char *) __rawmemchr (cur, 'c'
) : __builtin_strchr (cur, 'c')))
) {
2258 *channels = atoi(cur);
2259 } else {
2260 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2260, ((void*)0)
, SWITCH_LOG_ERROR, "Bad syntax for codec string. Missing qualifier [h|k|i|b|c] for part [%s]!\n", cur);
2261 }
2262 }
2263 cur = next;
2264 }
2265
2266 return name;
2267}
2268
2269SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, int arraylen, char **prefs, int preflen)
2270{
2271 int x, i = 0, j = 0;
2272 switch_codec_interface_t *codec_interface;
2273 const switch_codec_implementation_t *imp;
2274
2275 switch_mutex_lock(loadable_modules.mutex);
2276
2277 for (x = 0; x < preflen; x++) {
2278 char *name, buf[256], jbuf[256];
2279 uint32_t interval = 0, rate = 0, bit = 0, channels = 1;
2280
2281 switch_copy_string(buf, prefs[x], sizeof(buf));
2282 name = switch_parse_codec_buf(buf, &interval, &rate, &bit, &channels);
2283
2284 for(j = 0; j < x; j++) {
2285 char *jname;
2286 uint32_t jinterval = 0, jrate = 0, jbit = 0, jchannels = 1;
2287 uint32_t ointerval = interval, orate = rate, ochannels = channels;
2288
2289 if (ointerval == 0) {
2290 ointerval = switch_default_ptime(name, 0);
2291 }
2292
2293 if (orate == 0) {
2294 orate = switch_default_rate(name, 0);
2295 }
2296
2297 if (ochannels == 0) {
2298 ochannels = 1;
2299 }
2300
2301 switch_copy_string(jbuf, prefs[j], sizeof(jbuf));
2302 jname = switch_parse_codec_buf(jbuf, &jinterval, &jrate, &jbit, &jchannels);
2303
2304 if (jinterval == 0) {
2305 jinterval = switch_default_ptime(jname, 0);
2306 }
2307
2308 if (jrate == 0) {
2309 jrate = switch_default_rate(jname, 0);
2310 }
2311
2312 if (jchannels == 0) {
2313 jchannels = 1;
2314 }
2315
2316 if (!strcasecmp(name, jname) && ointerval == jinterval && orate == jrate && ochannels == jchannels) {
2317 goto next_x;
2318 }
2319 }
2320
2321 if ((codec_interface = switch_loadable_module_get_codec_interface(name)) != 0) {
2322 /* If no specific codec interval is requested opt for the default above all else because lots of stuff assumes it */
2323 for (imp = codec_interface->implementations; imp; imp = imp->next) {
2324 uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode);
2325 uint32_t default_rate = switch_default_rate(imp->iananame, imp->ianacode);
2326
2327 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
2328 uint32_t crate = !strcasecmp(imp->iananame, "g722") ? imp->samples_per_second : imp->actual_samples_per_second;
2329
2330 if ((!interval && (uint32_t) (imp->microseconds_per_packet / 1000) != default_ptime) ||
2331 (interval && (uint32_t) (imp->microseconds_per_packet / 1000) != interval)) {
2332 continue;
2333 }
2334
2335 if (((!rate && crate != default_rate) || (rate && (uint32_t) imp->actual_samples_per_second != rate))) {
2336 continue;
2337 }
2338
2339 if (bit && (uint32_t) imp->bits_per_second != bit) {
2340 continue;
2341 }
2342
2343 if (channels && imp->number_of_channels != channels) {
2344 continue;
2345 }
2346 }
2347
2348
2349 array[i++] = imp;
2350 goto found;
2351
2352 }
2353
2354 /* Either looking for a specific interval or there was no interval specified and there wasn't one at the default ptime available */
2355 for (imp = codec_interface->implementations; imp; imp = imp->next) {
2356 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
2357 uint32_t crate = !strcasecmp(imp->iananame, "g722") ? imp->samples_per_second : imp->actual_samples_per_second;
2358
2359 if (interval && (uint32_t) (imp->microseconds_per_packet / 1000) != interval) {
2360 continue;
2361 }
2362
2363 if (rate && (uint32_t) crate != rate) {
2364 continue;
2365 }
2366
2367 if (bit && (uint32_t) imp->bits_per_second != bit) {
2368 continue;
2369 }
2370
2371 if (channels && imp->number_of_channels != channels) {
2372 continue;
2373 }
2374 }
2375
2376 array[i++] = imp;
2377 goto found;
2378
2379 }
2380
2381 found:
2382
2383 UNPROTECT_INTERFACE(codec_interface)if (codec_interface) {switch_mutex_lock(codec_interface->reflock
); switch_thread_rwlock_unlock(codec_interface->rwlock); switch_thread_rwlock_unlock
(codec_interface->parent->rwlock); codec_interface->
refs--; codec_interface->parent->refs--; switch_mutex_unlock
(codec_interface->reflock);}
;
2384
2385 if (i > arraylen) {
2386 break;
2387 }
2388
2389 }
2390
2391 next_x:
2392
2393 continue;
2394 }
2395
2396 switch_mutex_unlock(loadable_modules.mutex);
2397
2398 switch_loadable_module_sort_codecs(array, i);
2399
2400 return i;
2401}
2402
2403SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream)
2404{
2405 switch_api_interface_t *api;
2406 switch_status_t status;
2407 char *arg_used;
2408 char *cmd_used;
2409
2410 switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)"
, "src/switch_loadable_module.c", 2410, __PRETTY_FUNCTION__))
;
2411 switch_assert(stream->data != NULL)((stream->data != ((void*)0)) ? (void) (0) : __assert_fail
("stream->data != ((void*)0)", "src/switch_loadable_module.c"
, 2411, __PRETTY_FUNCTION__))
;
2412 switch_assert(stream->write_function != NULL)((stream->write_function != ((void*)0)) ? (void) (0) : __assert_fail
("stream->write_function != ((void*)0)", "src/switch_loadable_module.c"
, 2412, __PRETTY_FUNCTION__))
;
2413
2414 if (strcasecmp(cmd, "console_complete")) {
2415 cmd_used = switch_strip_whitespace(cmd);
2416 arg_used = switch_strip_whitespace(arg);
2417 } else {
2418 cmd_used = (char *) cmd;
2419 arg_used = (char *) arg;
2420 }
2421
2422
2423 if (!stream->param_event) {
2424 switch_event_create(&stream->param_event, SWITCH_EVENT_API)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 2424, &stream->
param_event, SWITCH_EVENT_API, ((void*)0))
;
2425 }
2426
2427 if (stream->param_event) {
2428 if (cmd_used && *cmd_used) {
2429 switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command", cmd_used);
2430 }
2431 if (arg_used && *arg_used) {
2432 switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command-Argument", arg_used);
2433 }
2434 }
2435
2436
2437 if (cmd_used && (api = switch_loadable_module_get_api_interface(cmd_used)) != 0) {
2438 if ((status = api->function(arg_used, session, stream)) != SWITCH_STATUS_SUCCESS) {
2439 stream->write_function(stream, "COMMAND RETURNED ERROR!\n");
2440 }
2441 UNPROTECT_INTERFACE(api)if (api) {switch_mutex_lock(api->reflock); switch_thread_rwlock_unlock
(api->rwlock); switch_thread_rwlock_unlock(api->parent->
rwlock); api->refs--; api->parent->refs--; switch_mutex_unlock
(api->reflock);}
;
2442 } else {
2443 status = SWITCH_STATUS_FALSE;
2444 stream->write_function(stream, "INVALID COMMAND!\n");
2445 }
2446
2447 if (stream->param_event) {
2448 switch_event_fire(&stream->param_event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 2448, &stream->param_event
, ((void*)0))
;
2449 }
2450
2451 if (cmd_used != cmd) {
2452 switch_safe_free(cmd_used)if (cmd_used) {free(cmd_used);cmd_used=((void*)0);};
2453 }
2454
2455 if (arg_used != arg) {
2456 switch_safe_free(arg_used)if (arg_used) {free(arg_used);arg_used=((void*)0);};
2457 }
2458
2459 return status;
2460}
2461
2462SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_json_api_execute(cJSON *json, switch_core_session_t *session, cJSON **retval)
2463{
2464 switch_json_api_interface_t *json_api;
2465 switch_status_t status;
2466 cJSON *function, *json_reply = NULL((void*)0);
2467
2468 switch_assert(json)((json) ? (void) (0) : __assert_fail ("json", "src/switch_loadable_module.c"
, 2468, __PRETTY_FUNCTION__))
;
2469
2470 function = cJSON_GetObjectItem(json, "command");
2471
2472 if (function && function->valuestring
2473 && cJSON_GetObjectItem(json, "data") && (json_api = switch_loadable_module_get_json_api_interface(function->valuestring)) != 0) {
2474 if ((status = json_api->function(json, session, &json_reply)) != SWITCH_STATUS_SUCCESS) {
2475 cJSON_AddItemToObject(json, "status", cJSON_CreateString("error"));
2476 cJSON_AddItemToObject(json, "message", cJSON_CreateString("The command returned an error"));
2477 } else {
2478 cJSON_AddItemToObject(json, "status", cJSON_CreateString("success"));
2479 }
2480
2481 if (!json_reply) {
2482 json_reply = cJSON_CreateNull();
2483 }
2484
2485 if (retval) {
2486 *retval = json_reply;
2487 } else {
2488 cJSON_AddItemToObject(json, "response", json_reply);
2489 }
2490
2491 UNPROTECT_INTERFACE(json_api)if (json_api) {switch_mutex_lock(json_api->reflock); switch_thread_rwlock_unlock
(json_api->rwlock); switch_thread_rwlock_unlock(json_api->
parent->rwlock); json_api->refs--; json_api->parent->
refs--; switch_mutex_unlock(json_api->reflock);}
;
2492 } else {
2493 status = SWITCH_STATUS_FALSE;
2494 cJSON_AddItemToObject(json, "status", cJSON_CreateString("error"));
2495 cJSON_AddItemToObject(json, "message", cJSON_CreateString("Invalid request or non-existant command"));
2496 cJSON_AddItemToObject(json, "response", cJSON_CreateNull());
2497 }
2498
2499 return status;
2500}
2501
2502
2503SWITCH_DECLARE(switch_loadable_module_interface_t *)__attribute__((visibility("default"))) switch_loadable_module_interface_t
*
switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name)
2504{
2505 switch_loadable_module_interface_t *mod;
2506
2507 mod = switch_core_alloc(pool, sizeof(switch_loadable_module_interface_t))switch_core_perform_alloc(pool, sizeof(switch_loadable_module_interface_t
), "src/switch_loadable_module.c", (const char *)__func__, 2507
)
;
2508 switch_assert(mod != NULL)((mod != ((void*)0)) ? (void) (0) : __assert_fail ("mod != ((void*)0)"
, "src/switch_loadable_module.c", 2508, __PRETTY_FUNCTION__))
;
2509
2510 mod->pool = pool;
2511
2512 mod->module_name = switch_core_strdup(mod->pool, name)switch_core_perform_strdup(mod->pool, name, "src/switch_loadable_module.c"
, (const char *)__func__, 2512)
;
2513 switch_thread_rwlock_create(&mod->rwlock, mod->pool);
2514 return mod;
2515}
2516
2517#define ALLOC_INTERFACE(_TYPE_){ switch__TYPE__interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch__TYPE__interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2517); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2517, __PRETTY_FUNCTION__)); for (ptr = mod->_TYPE__interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->_TYPE__interface = i; } switch_thread_rwlock_create
(&i->rwlock, mod->pool); switch_mutex_init(&i->
reflock, 0x1, mod->pool); i->parent = mod; return i; }
{ \
2518 switch_##_TYPE_##_interface_t *i, *ptr; \
2519 i = switch_core_alloc(mod->pool, sizeof(switch_##_TYPE_##_interface_t))switch_core_perform_alloc(mod->pool, sizeof(switch_##_TYPE_
##_interface_t), "src/switch_loadable_module.c", (const char *
)__func__, 2519)
; \
2520 switch_assert(i != NULL)((i != ((void*)0)) ? (void) (0) : __assert_fail ("i != ((void*)0)"
, "src/switch_loadable_module.c", 2520, __PRETTY_FUNCTION__))
; \
2521 for (ptr = mod->_TYPE_##_interface; ptr && ptr->next; ptr = ptr->next); \
2522 if (ptr) { \
2523 ptr->next = i; \
2524 } else { \
2525 mod->_TYPE_##_interface = i; \
2526 } \
2527 switch_thread_rwlock_create(&i->rwlock, mod->pool); \
2528 switch_mutex_init(&i->reflock, SWITCH_MUTEX_NESTED0x1, mod->pool); \
2529 i->parent = mod; \
2530 return i; }
2531
2532
2533SWITCH_DECLARE(void *)__attribute__((visibility("default"))) void * switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, switch_module_interface_name_t iname)
2534{
2535
2536 switch (iname) {
2537 case SWITCH_ENDPOINT_INTERFACE:
2538 ALLOC_INTERFACE(endpoint){ switch_endpoint_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_endpoint_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2538); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2538, __PRETTY_FUNCTION__)); for (ptr = mod->endpoint_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->endpoint_interface = i; }
switch_thread_rwlock_create(&i->rwlock, mod->pool)
; switch_mutex_init(&i->reflock, 0x1, mod->pool); i
->parent = mod; return i; }
2539
2540 case SWITCH_TIMER_INTERFACE:
2541 ALLOC_INTERFACE(timer){ switch_timer_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_timer_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2541); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2541, __PRETTY_FUNCTION__)); for (ptr = mod->timer_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->timer_interface = i; } switch_thread_rwlock_create
(&i->rwlock, mod->pool); switch_mutex_init(&i->
reflock, 0x1, mod->pool); i->parent = mod; return i; }
2542
2543 case SWITCH_DIALPLAN_INTERFACE:
2544 ALLOC_INTERFACE(dialplan){ switch_dialplan_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_dialplan_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2544); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2544, __PRETTY_FUNCTION__)); for (ptr = mod->dialplan_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->dialplan_interface = i; }
switch_thread_rwlock_create(&i->rwlock, mod->pool)
; switch_mutex_init(&i->reflock, 0x1, mod->pool); i
->parent = mod; return i; }
2545
2546 case SWITCH_CODEC_INTERFACE:
2547 ALLOC_INTERFACE(codec){ switch_codec_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_codec_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2547); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2547, __PRETTY_FUNCTION__)); for (ptr = mod->codec_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->codec_interface = i; } switch_thread_rwlock_create
(&i->rwlock, mod->pool); switch_mutex_init(&i->
reflock, 0x1, mod->pool); i->parent = mod; return i; }
2548
2549 case SWITCH_APPLICATION_INTERFACE:
2550 ALLOC_INTERFACE(application){ switch_application_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_application_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2550); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2550, __PRETTY_FUNCTION__)); for (ptr = mod->application_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->application_interface = i
; } switch_thread_rwlock_create(&i->rwlock, mod->pool
); switch_mutex_init(&i->reflock, 0x1, mod->pool); i
->parent = mod; return i; }
2551
2552 case SWITCH_CHAT_APPLICATION_INTERFACE:
2553 ALLOC_INTERFACE(chat_application){ switch_chat_application_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_chat_application_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2553); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2553, __PRETTY_FUNCTION__)); for (ptr = mod->chat_application_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->chat_application_interface
= i; } switch_thread_rwlock_create(&i->rwlock, mod->
pool); switch_mutex_init(&i->reflock, 0x1, mod->pool
); i->parent = mod; return i; }
2554
2555 case SWITCH_API_INTERFACE:
2556 ALLOC_INTERFACE(api){ switch_api_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_api_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2556); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2556, __PRETTY_FUNCTION__)); for (ptr = mod->api_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->api_interface = i; } switch_thread_rwlock_create
(&i->rwlock, mod->pool); switch_mutex_init(&i->
reflock, 0x1, mod->pool); i->parent = mod; return i; }
2557
2558 case SWITCH_JSON_API_INTERFACE:
2559 ALLOC_INTERFACE(json_api){ switch_json_api_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_json_api_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2559); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2559, __PRETTY_FUNCTION__)); for (ptr = mod->json_api_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->json_api_interface = i; }
switch_thread_rwlock_create(&i->rwlock, mod->pool)
; switch_mutex_init(&i->reflock, 0x1, mod->pool); i
->parent = mod; return i; }
2560
2561 case SWITCH_FILE_INTERFACE:
2562 ALLOC_INTERFACE(file){ switch_file_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_file_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2562); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2562, __PRETTY_FUNCTION__)); for (ptr = mod->file_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->file_interface = i; } switch_thread_rwlock_create
(&i->rwlock, mod->pool); switch_mutex_init(&i->
reflock, 0x1, mod->pool); i->parent = mod; return i; }
2563
2564 case SWITCH_SPEECH_INTERFACE:
2565 ALLOC_INTERFACE(speech){ switch_speech_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_speech_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2565); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2565, __PRETTY_FUNCTION__)); for (ptr = mod->speech_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->speech_interface = i; } switch_thread_rwlock_create
(&i->rwlock, mod->pool); switch_mutex_init(&i->
reflock, 0x1, mod->pool); i->parent = mod; return i; }
2566
2567 case SWITCH_DIRECTORY_INTERFACE:
2568 ALLOC_INTERFACE(directory){ switch_directory_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_directory_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2568); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2568, __PRETTY_FUNCTION__)); for (ptr = mod->directory_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->directory_interface = i; }
switch_thread_rwlock_create(&i->rwlock, mod->pool)
; switch_mutex_init(&i->reflock, 0x1, mod->pool); i
->parent = mod; return i; }
2569
2570 case SWITCH_CHAT_INTERFACE:
2571 ALLOC_INTERFACE(chat){ switch_chat_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_chat_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2571); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2571, __PRETTY_FUNCTION__)); for (ptr = mod->chat_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->chat_interface = i; } switch_thread_rwlock_create
(&i->rwlock, mod->pool); switch_mutex_init(&i->
reflock, 0x1, mod->pool); i->parent = mod; return i; }
2572
2573 case SWITCH_SAY_INTERFACE:
2574 ALLOC_INTERFACE(say){ switch_say_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_say_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2574); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2574, __PRETTY_FUNCTION__)); for (ptr = mod->say_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->say_interface = i; } switch_thread_rwlock_create
(&i->rwlock, mod->pool); switch_mutex_init(&i->
reflock, 0x1, mod->pool); i->parent = mod; return i; }
2575
2576 case SWITCH_ASR_INTERFACE:
2577 ALLOC_INTERFACE(asr){ switch_asr_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_asr_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2577); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2577, __PRETTY_FUNCTION__)); for (ptr = mod->asr_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->asr_interface = i; } switch_thread_rwlock_create
(&i->rwlock, mod->pool); switch_mutex_init(&i->
reflock, 0x1, mod->pool); i->parent = mod; return i; }
2578
2579 case SWITCH_MANAGEMENT_INTERFACE:
2580 ALLOC_INTERFACE(management){ switch_management_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_management_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2580); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2580, __PRETTY_FUNCTION__)); for (ptr = mod->management_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->management_interface = i;
} switch_thread_rwlock_create(&i->rwlock, mod->pool
); switch_mutex_init(&i->reflock, 0x1, mod->pool); i
->parent = mod; return i; }
2581
2582 case SWITCH_LIMIT_INTERFACE:
2583 ALLOC_INTERFACE(limit){ switch_limit_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_limit_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 2583); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 2583, __PRETTY_FUNCTION__)); for (ptr = mod->limit_interface
; ptr && ptr->next; ptr = ptr->next); if (ptr) {
ptr->next = i; } else { mod->limit_interface = i; } switch_thread_rwlock_create
(&i->rwlock, mod->pool); switch_mutex_init(&i->
reflock, 0x1, mod->pool); i->parent = mod; return i; }
2584
2585 default:
2586 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2586, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid Module Type!\n");
2587 return NULL((void*)0);
2588 }
2589}
2590
2591struct switch_say_file_handle {
2592 char *ext;
2593 int cnt;
2594 struct switch_stream_handle stream;
2595 switch_event_t *param_event;
2596};
2597
2598SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_say_file_handle_get_variable(switch_say_file_handle_t *sh, const char *var)
2599{
2600 char *ret = NULL((void*)0);
2601
2602 if (sh->param_event) {
2603 ret = switch_event_get_header(sh->param_event, var)switch_event_get_header_idx(sh->param_event, var, -1);
2604 }
2605
2606 return ret;
2607
2608}
2609
2610SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_say_file_handle_get_path(switch_say_file_handle_t *sh)
2611{
2612 return (char *) sh->stream.data;
2613}
2614
2615SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_say_file_handle_detach_path(switch_say_file_handle_t *sh)
2616{
2617 char *path;
2618
2619 switch_assert(sh)((sh) ? (void) (0) : __assert_fail ("sh", "src/switch_loadable_module.c"
, 2619, __PRETTY_FUNCTION__))
;
2620 path = (char *) sh->stream.data;
2621 sh->stream.data = NULL((void*)0);
2622 return path;
2623}
2624
2625
2626SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_say_file_handle_destroy(switch_say_file_handle_t **sh)
2627{
2628 switch_assert(sh)((sh) ? (void) (0) : __assert_fail ("sh", "src/switch_loadable_module.c"
, 2628, __PRETTY_FUNCTION__))
;
2629
2630 switch_safe_free((*sh)->stream.data)if ((*sh)->stream.data) {free((*sh)->stream.data);(*sh)
->stream.data=((void*)0);}
;
2631 switch_safe_free((*sh)->ext)if ((*sh)->ext) {free((*sh)->ext);(*sh)->ext=((void*
)0);}
;
2632
2633 if ((*sh)->param_event) {
2634 switch_event_destroy(&(*sh)->param_event);
2635 }
2636 free(*sh);
2637 *sh = NULL((void*)0);
2638}
2639
2640SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_say_file_handle_create(switch_say_file_handle_t **sh, const char *ext, switch_event_t **var_event)
2641{
2642 switch_assert(sh)((sh) ? (void) (0) : __assert_fail ("sh", "src/switch_loadable_module.c"
, 2642, __PRETTY_FUNCTION__))
;
2643
2644 if (zstr(ext)_zstr(ext)) {
2645 ext = "wav";
2646 }
2647
2648 *sh = malloc(sizeof(**sh));
2649 memset(*sh, 0, sizeof(**sh));
2650
2651 SWITCH_STANDARD_STREAM((*sh)->stream)memset(&(*sh)->stream, 0, sizeof((*sh)->stream)); (
*sh)->stream.data = malloc(1024); (((*sh)->stream.data)
? (void) (0) : __assert_fail ("(*sh)->stream.data", "src/switch_loadable_module.c"
, 2651, __PRETTY_FUNCTION__)); memset((*sh)->stream.data, 0
, 1024); (*sh)->stream.end = (*sh)->stream.data; (*sh)->
stream.data_size = 1024; (*sh)->stream.write_function = switch_console_stream_write
; (*sh)->stream.raw_write_function = switch_console_stream_raw_write
; (*sh)->stream.alloc_len = 1024; (*sh)->stream.alloc_chunk
= 1024
;
2652
2653 if (var_event) {
2654 (*sh)->param_event = *var_event;
2655 *var_event = NULL((void*)0);
2656 }
2657
2658 (*sh)->ext = strdup(ext)(__extension__ (__builtin_constant_p (ext) && ((size_t
)(const void *)((ext) + 1) - (size_t)(const void *)(ext) == 1
) ? (((const char *) (ext))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (ext) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, ext, __len); __retval
; })) : __strdup (ext)))
;
2659
2660 return SWITCH_STATUS_SUCCESS;
2661}
2662
2663SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_say_file(switch_say_file_handle_t *sh, const char *fmt, ...)
2664{
2665 char buf[256] = "";
2666 int ret;
2667 va_list ap;
2668
2669 va_start(ap, fmt)__builtin_va_start(ap, fmt);
2670
2671 if ((ret = switch_vsnprintf(buf, sizeof(buf), fmt, ap)) > 0) {
2672 if (!sh->cnt++) {
2673 sh->stream.write_function(&sh->stream, "file_string://%s.%s", buf, sh->ext);
2674 } else if (strstr(buf, "://")) {
2675 sh->stream.write_function(&sh->stream, "!%s", buf);
2676 } else {
2677 sh->stream.write_function(&sh->stream, "!%s.%s", buf, sh->ext);
2678 }
2679
2680 }
2681
2682 va_end(ap)__builtin_va_end(ap);
2683}
2684
2685SWITCH_DECLARE(switch_core_recover_callback_t)__attribute__((visibility("default"))) switch_core_recover_callback_t switch_core_get_secondary_recover_callback(const char *key)
2686{
2687 switch_core_recover_callback_t cb;
2688
2689 switch_mutex_lock(loadable_modules.mutex);
2690 cb = (switch_core_recover_callback_t) (intptr_t) switch_core_hash_find(loadable_modules.secondary_recover_hash, key);
2691 switch_mutex_unlock(loadable_modules.mutex);
2692
2693 return cb;
2694}
2695
2696
2697SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_register_secondary_recover_callback(const char *key, switch_core_recover_callback_t cb)
2698{
2699 switch_status_t status = SWITCH_STATUS_SUCCESS;
2700
2701 switch_assert(cb)((cb) ? (void) (0) : __assert_fail ("cb", "src/switch_loadable_module.c"
, 2701, __PRETTY_FUNCTION__))
;
2702
2703 switch_mutex_lock(loadable_modules.mutex);
2704 if (switch_core_hash_find(loadable_modules.secondary_recover_hash, key)) {
2705 status = SWITCH_STATUS_FALSE;
2706 } else {
2707 switch_core_hash_insert(loadable_modules.secondary_recover_hash, key, (void *)(intptr_t) cb)switch_core_hash_insert_destructor(loadable_modules.secondary_recover_hash
, key, (void *)(intptr_t) cb, ((void*)0))
;
2708 }
2709 switch_mutex_unlock(loadable_modules.mutex);
2710
2711 return status;
2712}
2713
2714
2715SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_unregister_secondary_recover_callback(const char *key)
2716{
2717 switch_mutex_lock(loadable_modules.mutex);
2718 switch_core_hash_delete(loadable_modules.secondary_recover_hash, key);
2719 switch_mutex_unlock(loadable_modules.mutex);
2720}
2721
2722
2723/* For Emacs:
2724 * Local Variables:
2725 * mode:c
2726 * indent-tabs-mode:t
2727 * tab-width:4
2728 * c-basic-offset:4
2729 * End:
2730 * For VIM:
2731 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
2732 */