Bug Summary

File:switch_loadable_module.c
Warning:line 792, column 2
Potential leak of memory pointed to by 'event_num'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name switch_loadable_module.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fno-trapping-math -ffp-contract=fast -ffast-math -ffinite-math-only -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -resource-dir /usr/lib/llvm-7/lib/clang/7.0.1 -D HAVE_CONFIG_H -I . -I ./src/include -I ./libs/esl/src/include -I ./libs/xmlrpc-c -I /drone/src/libs/libvpx -I /drone/src/src/include -I /drone/src/src/include -I /drone/src/libs/libteletone/src -D SWITCH_API_VISIBILITY=1 -D CJSON_API_VISIBILITY=1 -D HAVE_VISIBILITY=1 -D _REENTRANT -D _GNU_SOURCE -I /drone/src/libs/apr/include -I /drone/src/libs/apr-util/include -I /drone/src/libs/apr-util/xml/expat/lib -I /drone/src/libs/srtp/include -I /drone/src/libs/libyuv/include -D SWITCH_HAVE_YUV -I /drone/src/libs/srtp/crypto/include -I libs/srtp/crypto/include -D SWITCH_HAVE_VPX -D ENABLE_SRTP -D SWITCH_HAVE_ODBC -I /usr/include -D SWITCH_HAVE_PNG -I /usr/include/libpng16 -D SWITCH_HAVE_FREETYPE -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/x86_64-linux-gnu -I /usr/include/editline -D HAVE_OPENSSL -I /usr/include/sofia-sip-1.13 -I /usr/include/uuid -I /drone/src/src/include -I /drone/src/src/include -I /drone/src/libs/libteletone/src -D SWITCH_API_VISIBILITY=1 -D CJSON_API_VISIBILITY=1 -D HAVE_VISIBILITY=1 -D HAVE_OPENSSL -D PIC -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-result -Wno-misleading-indentation -std=c99 -fdebug-compilation-dir /drone/src -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -o /drone/src/scan-build/2021-10-18-184555-401-1 -x c src/switch_loadable_module.c -faddrsig
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 * Andrey Volk <andywolk@gmail.com>
29 *
30 * switch_loadable_module.c -- Loadable Modules
31 *
32 */
33
34#include <switch.h>
35#include "private/switch_core_pvt.h"
36
37/* for apr_pstrcat */
38#include <apr_strings.h>
39
40/* for apr_env_get and apr_env_set */
41#include <apr_env.h>
42
43/* for apr file and directory handling */
44#include <apr_file_io.h>
45
46typedef struct switch_file_node_s {
47 const switch_file_interface_t *ptr;
48 const char *interface_name;
49 struct switch_file_node_s *next;
50} switch_file_node_t;
51
52typedef struct switch_database_node_s {
53 const switch_database_interface_t *ptr;
54 const char *interface_name;
55 struct switch_database_node_s *next;
56} switch_database_node_t;
57
58typedef struct switch_codec_node_s {
59 const switch_codec_interface_t *ptr;
60 const char *interface_name;
61 struct switch_codec_node_s *next;
62} switch_codec_node_t;
63
64
65struct switch_loadable_module {
66 char *key;
67 char *filename;
68 int perm;
69 switch_loadable_module_interface_t *module_interface;
70 switch_dso_lib_t lib;
71 switch_module_load_t switch_module_load;
72 switch_module_runtime_t switch_module_runtime;
73 switch_module_shutdown_t switch_module_shutdown;
74 switch_memory_pool_t *pool;
75 switch_status_t status;
76 switch_thread_t *thread;
77 switch_bool_t shutting_down;
78 switch_loadable_module_type_t type;
79};
80
81struct switch_loadable_module_container {
82 switch_hash_t *module_hash;
83 switch_hash_t *endpoint_hash;
84 switch_hash_t *codec_hash;
85 switch_hash_t *dialplan_hash;
86 switch_hash_t *timer_hash;
87 switch_hash_t *application_hash;
88 switch_hash_t *chat_application_hash;
89 switch_hash_t *api_hash;
90 switch_hash_t *json_api_hash;
91 switch_hash_t *file_hash;
92 switch_hash_t *speech_hash;
93 switch_hash_t *asr_hash;
94 switch_hash_t *directory_hash;
95 switch_hash_t *chat_hash;
96 switch_hash_t *say_hash;
97 switch_hash_t *management_hash;
98 switch_hash_t *limit_hash;
99 switch_hash_t *database_hash;
100 switch_hash_t *secondary_recover_hash;
101 switch_mutex_t *mutex;
102 switch_memory_pool_t *pool;
103};
104
105static struct switch_loadable_module_container loadable_modules;
106static switch_status_t do_shutdown(switch_loadable_module_t *module, switch_bool_t shutdown, switch_bool_t unload, switch_bool_t fail_if_busy,
107 const char **err);
108static switch_status_t switch_loadable_module_load_module_ex(const char *dir, const char *fname, switch_bool_t runtime, switch_bool_t global, const char **err, switch_loadable_module_type_t type, switch_hash_t *event_hash);
109
110static void *SWITCH_THREAD_FUNC switch_loadable_module_exec(switch_thread_t *thread, void *obj)
111{
112
113
114 switch_status_t status = SWITCH_STATUS_SUCCESS;
115 switch_core_thread_session_t *ts = obj;
116 switch_loadable_module_t *module = ts->objs[0];
117 int restarts;
118
119 switch_assert(thread != NULL)((thread != ((void*)0)) ? (void) (0) : __assert_fail ("thread != ((void*)0)"
, "src/switch_loadable_module.c", 119, __extension__ __PRETTY_FUNCTION__
))
;
120 switch_assert(module != NULL)((module != ((void*)0)) ? (void) (0) : __assert_fail ("module != ((void*)0)"
, "src/switch_loadable_module.c", 120, __extension__ __PRETTY_FUNCTION__
))
;
121
122 for (restarts = 0; status != SWITCH_STATUS_TERM && !module->shutting_down; restarts++) {
123 status = module->switch_module_runtime();
124 }
125 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 125, ((void*)0)
, SWITCH_LOG_NOTICE, "Thread ended for %s\n", module->module_interface->module_name);
126
127 if (ts->pool) {
128 switch_memory_pool_t *pool = ts->pool;
129 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 129, ((void*)0)
, SWITCH_LOG_DEBUG, "Destroying Pool for %s\n", module->module_interface->module_name);
130 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 130)
;
131 }
132 switch_thread_exit(thread, 0);
133 return NULL((void*)0);
134}
135
136
137static void switch_loadable_module_runtime(void)
138{
139 switch_hash_index_t *hi;
140 void *val;
141 switch_loadable_module_t *module;
142
143 switch_mutex_lock(loadable_modules.mutex);
144 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)) {
145 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
146 module = (switch_loadable_module_t *) val;
147
148 if (module->switch_module_runtime) {
149 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 149, ((void*)0)
, SWITCH_LOG_CONSOLE, "Starting runtime thread for %s\n", module->module_interface->module_name);
150 module->thread = switch_core_launch_thread(switch_loadable_module_exec, module, loadable_modules.pool);
151 }
152 }
153 switch_mutex_unlock(loadable_modules.mutex);
154}
155
156static switch_status_t switch_loadable_module_process(char *key, switch_loadable_module_t *new_module, switch_hash_t *event_hash)
157{
158 switch_event_t *event;
159 int *event_num = NULL((void*)0);
160 char str_event_num[12];
161 void *val;
162 int added = 0;
163
164 if (event_hash) {
1
Assuming 'event_hash' is non-null
2
Taking true branch
165 if ((val = switch_core_hash_find(event_hash, "0"))) {
3
Assuming 'val' is null
4
Taking false branch
166 event_num = (int*)val;
167 } else {
168 if (!(event_num = malloc(sizeof(int)))) {
5
Memory is allocated
6
Assuming 'event_num' is not null
7
Taking false branch
169 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 169, ((void*)0)
, SWITCH_LOG_CRIT, "Allocation error.\n");
170 return SWITCH_STATUS_MEMERR;
171 }
172
173 *event_num = 0;
174 switch_core_hash_insert(event_hash, "0", (const void*)event_num)switch_core_hash_insert_destructor(event_hash, "0", (const void
*)event_num, ((void*)0))
;
175 }
176 }
177
178 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__, 178)
;
179
180 switch_mutex_lock(loadable_modules.mutex);
181 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))
;
182
183 if (new_module->module_interface->endpoint_interface) {
8
Assuming the condition is false
9
Taking false branch
184 const switch_endpoint_interface_t *ptr;
185 for (ptr = new_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
186 if (!ptr->interface_name) {
187 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 187, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load endpoint interface from %s due to no interface name.\n", key);
188 } else {
189 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 189, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Endpoint '%s'\n", ptr->interface_name);
190 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))
;
191 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 191, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
192 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "endpoint");
193 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
194 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
195 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
196
197 if (!event_hash) {
198 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 198, &event, ((void*)0))
;
199 } else {
200 sprintf(str_event_num, "%i", ++*event_num);
201 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
202 }
203
204 added++;
205 }
206 }
207 }
208 }
209
210 if (new_module->module_interface->codec_interface) {
10
Assuming the condition is false
11
Taking false branch
211 const switch_codec_implementation_t *impl;
212 const switch_codec_interface_t *ptr;
213
214 for (ptr = new_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
215 if (!ptr->interface_name) {
216 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 216, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load codec interface from %s due to no interface name.\n", key);
217 } else {
218 unsigned load_interface = 1;
219 switch_codec_node_t *node, *head;
220
221 for (impl = ptr->implementations; impl; impl = impl->next) {
222 if (!impl->iananame) {
223 load_interface = 0;
224 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 224, ((void*)0)
, SWITCH_LOG_CRIT,
225 "Failed to load codec interface %s from %s due to no iana name in an implementation.\n", ptr->interface_name,
226 key);
227 break;
228 }
229 if (impl->decoded_bytes_per_packet > SWITCH_RECOMMENDED_BUFFER_SIZE8192) {
230 load_interface = 0;
231 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 231, ((void*)0)
, SWITCH_LOG_CRIT,
232 "Failed to load codec interface %s from %s due to bytes per frame %d exceeding buffer size %d.\n",
233 ptr->interface_name,
234 key, impl->decoded_bytes_per_packet, SWITCH_RECOMMENDED_BUFFER_SIZE8192);
235 break;
236 }
237 }
238 if (load_interface) {
239 for (impl = ptr->implementations; impl; impl = impl->next) {
240 if (impl->bits_per_second) {
241 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 241, ((void*)0)
, SWITCH_LOG_NOTICE,
242 "Adding Codec %s %d %s %dhz %dms %dch %dbps\n",
243 impl->iananame, impl->ianacode,
244 ptr->interface_name, impl->actual_samples_per_second,
245 impl->microseconds_per_packet / 1000, impl->number_of_channels, impl->bits_per_second);
246 } else {
247 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 247, ((void*)0)
, SWITCH_LOG_NOTICE,
248 "Adding Codec %s %d %s %dhz %dms %dch (VBR)\n",
249 impl->iananame, impl->ianacode,
250 ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000, impl->number_of_channels);
251 }
252
253 node = switch_core_alloc(new_module->pool, sizeof(*node))switch_core_perform_alloc(new_module->pool, sizeof(*node),
"src/switch_loadable_module.c", (const char *)__func__, 253)
;
254 node->ptr = ptr;
255 node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name)switch_core_perform_strdup(new_module->pool, new_module->
module_interface->module_name, "src/switch_loadable_module.c"
, (const char *)__func__, 255)
;
256 if ((head = switch_core_hash_find(loadable_modules.codec_hash, impl->iananame))) {
257 node->next = head;
258 }
259
260 switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) node)switch_core_hash_insert_destructor(loadable_modules.codec_hash
, impl->iananame, (const void *) node, ((void*)0))
;
261 }
262
263 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 263, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
264 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "codec");
265 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
266 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
267 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
268 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", new_module->module_interface->module_name);
269
270 if (!event_hash) {
271 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 271, &event, ((void*)0))
;
272 }
273 else {
274 sprintf(str_event_num, "%i", ++*event_num);
275 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
276 }
277
278 added++;
279 }
280 }
281 }
282 }
283 }
284
285 if (new_module->module_interface->dialplan_interface) {
12
Assuming the condition is false
13
Taking false branch
286 const switch_dialplan_interface_t *ptr;
287
288 for (ptr = new_module->module_interface->dialplan_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 dialplan 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 Dialplan '%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", "dialplan");
295 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
296 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
297 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
298
299 if (!event_hash) {
300 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 300, &event, ((void*)0))
;
301 }
302 else {
303 sprintf(str_event_num, "%i", ++*event_num);
304 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
305 }
306
307 added++;
308 }
309 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))
;
310 }
311 }
312 }
313
314 if (new_module->module_interface->timer_interface) {
14
Assuming the condition is false
15
Taking false branch
315 const switch_timer_interface_t *ptr;
316
317 for (ptr = new_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
318 if (!ptr->interface_name) {
319 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 319, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load timer interface from %s due to no interface name.\n", key);
320 } else {
321 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 321, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Timer '%s'\n", ptr->interface_name);
322 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 322, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
323 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "timer");
324 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
325 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
326 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
327
328 if (!event_hash) {
329 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 329, &event, ((void*)0))
;
330 }
331 else {
332 sprintf(str_event_num, "%i", ++*event_num);
333 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
334 }
335
336 added++;
337 }
338 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))
;
339 }
340 }
341 }
342
343 if (new_module->module_interface->application_interface) {
16
Assuming the condition is false
17
Taking false branch
344 const switch_application_interface_t *ptr;
345
346 for (ptr = new_module->module_interface->application_interface; ptr; ptr = ptr->next) {
347 if (!ptr->interface_name) {
348 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 348, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key);
349 } else {
350 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 350, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Application '%s'\n", ptr->interface_name);
351 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 351, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
352 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
353 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
354 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->short_desc)(ptr->short_desc ? ptr->short_desc : ""));
355 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
356 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
357 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
358
359 if (!event_hash) {
360 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 360, &event, ((void*)0))
;
361 }
362 else {
363 sprintf(str_event_num, "%i", ++*event_num);
364 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
365 }
366
367 added++;
368 }
369 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))
;
370 }
371 }
372 }
373
374 if (new_module->module_interface->chat_application_interface) {
18
Assuming the condition is false
19
Taking false branch
375 const switch_chat_application_interface_t *ptr;
376
377 for (ptr = new_module->module_interface->chat_application_interface; ptr; ptr = ptr->next) {
378 if (!ptr->interface_name) {
379 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 379, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key);
380 } else {
381 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 381, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Chat Application '%s'\n", ptr->interface_name);
382 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 382, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
383 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
384 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
385 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->short_desc)(ptr->short_desc ? ptr->short_desc : ""));
386 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
387 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
388 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
389
390 if (!event_hash) {
391 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 391, &event, ((void*)0))
;
392 }
393 else {
394 sprintf(str_event_num, "%i", ++*event_num);
395 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
396 }
397
398 added++;
399 }
400 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))
;
401 }
402 }
403 }
404
405 if (new_module->module_interface->api_interface) {
20
Assuming the condition is false
21
Taking false branch
406 const switch_api_interface_t *ptr;
407
408 for (ptr = new_module->module_interface->api_interface; ptr; ptr = ptr->next) {
409 if (!ptr->interface_name) {
410 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 410, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load api interface from %s due to no interface name.\n", key);
411 } else {
412 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 412, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding API Function '%s'\n", ptr->interface_name);
413 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 413, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
414 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");
415 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
416 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->desc)(ptr->desc ? ptr->desc : ""));
417 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
418 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
419 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
420
421 if (!event_hash) {
422 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 422, &event, ((void*)0))
;
423 }
424 else {
425 sprintf(str_event_num, "%i", ++*event_num);
426 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
427 }
428
429 added++;
430 }
431 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))
;
432 }
433 }
434 }
435
436 if (new_module->module_interface->json_api_interface) {
22
Assuming the condition is false
23
Taking false branch
437 const switch_json_api_interface_t *ptr;
438
439 for (ptr = new_module->module_interface->json_api_interface; ptr; ptr = ptr->next) {
440 if (!ptr->interface_name) {
441 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 441, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load JSON api interface from %s due to no interface name.\n", key);
442 } else {
443 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 443, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding JSON API Function '%s'\n", ptr->interface_name);
444 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 444, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
445 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "json_api");
446 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
447 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->desc)(ptr->desc ? ptr->desc : ""));
448 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
449 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
450 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
451
452 if (!event_hash) {
453 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 453, &event, ((void*)0))
;
454 }
455 else {
456 sprintf(str_event_num, "%i", ++*event_num);
457 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
458 }
459
460 added++;
461 }
462 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))
;
463 }
464 }
465 }
466
467 if (new_module->module_interface->file_interface) {
24
Assuming the condition is false
25
Taking false branch
468 const switch_file_interface_t *ptr;
469
470 for (ptr = new_module->module_interface->file_interface; ptr; ptr = ptr->next) {
471 if (!ptr->interface_name) {
472 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 472, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no interface name.\n", key);
473 } else if (!ptr->extens) {
474 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 474, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no file extensions.\n", key);
475 } else {
476 int i;
477 switch_file_node_t *node, *head;
478
479 for (i = 0; ptr->extens[i]; i++) {
480 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 480, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding File Format '%s'\n", ptr->extens[i]);
481 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 481, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
482 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "file");
483 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->extens[i]);
484 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
485 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
486 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", new_module->module_interface->module_name);
487
488 if (!event_hash) {
489 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 489, &event, ((void*)0))
;
490 }
491 else {
492 sprintf(str_event_num, "%i", ++*event_num);
493 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
494 }
495
496 added++;
497 }
498 node = switch_core_alloc(new_module->pool, sizeof(*node))switch_core_perform_alloc(new_module->pool, sizeof(*node),
"src/switch_loadable_module.c", (const char *)__func__, 498)
;
499 node->ptr = ptr;
500 node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name)switch_core_perform_strdup(new_module->pool, new_module->
module_interface->module_name, "src/switch_loadable_module.c"
, (const char *)__func__, 500)
;
501 if ((head = switch_core_hash_find(loadable_modules.file_hash, ptr->extens[i]))) {
502 node->next = head;
503 }
504
505 switch_core_hash_insert(loadable_modules.file_hash, ptr->extens[i], (const void *) node)switch_core_hash_insert_destructor(loadable_modules.file_hash
, ptr->extens[i], (const void *) node, ((void*)0))
;
506 }
507 }
508 }
509 }
510
511 if (new_module->module_interface->database_interface) {
26
Assuming the condition is false
27
Taking false branch
512 const switch_database_interface_t *ptr;
513
514 for (ptr = new_module->module_interface->database_interface; ptr; ptr = ptr->next) {
515 if (!ptr->interface_name) {
516 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 516, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load database interface from %s due to no interface name.\n", key);
517 }
518 else if (!ptr->prefixes) {
519 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 519, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load database interface from %s due to no prefixes.\n", key);
520 }
521 else {
522 int i;
523 switch_database_node_t *node, *head;
524
525 for (i = 0; ptr->prefixes[i]; i++) {
526 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 526, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding dsn prefix '%s'\n", ptr->prefixes[i]);
527 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 527, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
528 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "database");
529 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->prefixes[i]);
530 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
531 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
532 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", new_module->module_interface->module_name);
533
534 if (!event_hash) {
535 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 535, &event, ((void*)0))
;
536 }
537 else {
538 sprintf(str_event_num, "%i", ++*event_num);
539 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
540 }
541
542 added++;
543 }
544 node = switch_core_alloc(new_module->pool, sizeof(*node))switch_core_perform_alloc(new_module->pool, sizeof(*node),
"src/switch_loadable_module.c", (const char *)__func__, 544)
;
545 node->ptr = ptr;
546 node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name)switch_core_perform_strdup(new_module->pool, new_module->
module_interface->module_name, "src/switch_loadable_module.c"
, (const char *)__func__, 546)
;
547 if ((head = switch_core_hash_find(loadable_modules.database_hash, ptr->prefixes[i]))) {
548 node->next = head;
549 }
550
551 switch_core_hash_insert(loadable_modules.database_hash, ptr->prefixes[i], (const void *)node)switch_core_hash_insert_destructor(loadable_modules.database_hash
, ptr->prefixes[i], (const void *)node, ((void*)0))
;
552 }
553 }
554 }
555 }
556
557 if (new_module->module_interface->speech_interface) {
28
Assuming the condition is false
29
Taking false branch
558 const switch_speech_interface_t *ptr;
559
560 for (ptr = new_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
561 if (!ptr->interface_name) {
562 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 562, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load speech interface from %s due to no interface name.\n", key);
563 } else {
564 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 564, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Speech interface '%s'\n", ptr->interface_name);
565 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 565, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
566 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
567 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
568 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
569 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
570
571 if (!event_hash) {
572 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 572, &event, ((void*)0))
;
573 }
574 else {
575 sprintf(str_event_num, "%i", ++*event_num);
576 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
577 }
578
579 added++;
580 }
581 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))
;
582 }
583 }
584 }
585
586 if (new_module->module_interface->asr_interface) {
30
Assuming the condition is false
31
Taking false branch
587 const switch_asr_interface_t *ptr;
588
589 for (ptr = new_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
590 if (!ptr->interface_name) {
591 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 591, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load asr interface from %s due to no interface name.\n", key);
592 } else {
593 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 593, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding ASR interface '%s'\n", ptr->interface_name);
594 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 594, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
595 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "asr");
596 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
597 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
598 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
599
600 if (!event_hash) {
601 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 601, &event, ((void*)0))
;
602 }
603 else {
604 sprintf(str_event_num, "%i", ++*event_num);
605 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
606 }
607
608 added++;
609 }
610 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))
;
611 }
612 }
613 }
614
615 if (new_module->module_interface->directory_interface) {
32
Assuming the condition is false
33
Taking false branch
616 const switch_directory_interface_t *ptr;
617
618 for (ptr = new_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
619 if (!ptr->interface_name) {
620 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 620, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load directory interface from %s due to no interface name.\n", key);
621 } else {
622 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 622, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Directory interface '%s'\n", ptr->interface_name);
623 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 623, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
624 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
625 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
626 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
627 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
628
629 if (!event_hash) {
630 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 630, &event, ((void*)0))
;
631 }
632 else {
633 sprintf(str_event_num, "%i", ++*event_num);
634 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
635 }
636
637 added++;
638 }
639 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))
;
640 }
641 }
642 }
643
644 if (new_module->module_interface->chat_interface) {
34
Assuming the condition is false
35
Taking false branch
645 const switch_chat_interface_t *ptr;
646
647 for (ptr = new_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
648 if (!ptr->interface_name) {
649 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 649, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load chat interface from %s due to no interface name.\n", key);
650 } else {
651 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 651, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Chat interface '%s'\n", ptr->interface_name);
652 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 652, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
653 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
654 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
655 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
656 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
657
658 if (!event_hash) {
659 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 659, &event, ((void*)0))
;
660 }
661 else {
662 sprintf(str_event_num, "%i", ++*event_num);
663 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
664 }
665
666 added++;
667 }
668 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))
;
669 }
670 }
671 }
672
673 if (new_module->module_interface->say_interface) {
36
Assuming the condition is false
37
Taking false branch
674 const switch_say_interface_t *ptr;
675
676 for (ptr = new_module->module_interface->say_interface; ptr; ptr = ptr->next) {
677 if (!ptr->interface_name) {
678 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 678, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load say interface from %s due to no interface name.\n", key);
679 } else {
680 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 680, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Say interface '%s'\n", ptr->interface_name);
681 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 681, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
682 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "say");
683 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
684 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
685 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
686
687 if (!event_hash) {
688 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 688, &event, ((void*)0))
;
689 }
690 else {
691 sprintf(str_event_num, "%i", ++*event_num);
692 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
693 }
694
695 added++;
696 }
697 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))
;
698 }
699 }
700 }
701
702 if (new_module->module_interface->management_interface) {
38
Assuming the condition is false
39
Taking false branch
703 const switch_management_interface_t *ptr;
704
705 for (ptr = new_module->module_interface->management_interface; ptr; ptr = ptr->next) {
706 if (!ptr->relative_oid) {
707 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 707, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load management interface from %s due to no interface name.\n", key);
708 } else {
709 if (switch_core_hash_find(loadable_modules.management_hash, ptr->relative_oid)) {
710 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 710, ((void*)0)
, SWITCH_LOG_CRIT,
711 "Failed to load management interface %s. OID %s already exists\n", key, ptr->relative_oid);
712 } else {
713 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 713, ((void*)0)
, SWITCH_LOG_NOTICE,
714 "Adding Management interface '%s' OID[%s.%s]\n", key, FREESWITCH_OID_PREFIX".1.3.6.1.4.1." "27880", ptr->relative_oid);
715 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))
;
716 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 716, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
717 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "management");
718 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->relative_oid);
719 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
720 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
721
722 if (!event_hash) {
723 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 723, &event, ((void*)0))
;
724 }
725 else {
726 sprintf(str_event_num, "%i", ++*event_num);
727 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
728 }
729
730 added++;
731 }
732 }
733
734 }
735 }
736 }
737 if (new_module->module_interface->limit_interface) {
40
Assuming the condition is false
41
Taking false branch
738 const switch_limit_interface_t *ptr;
739
740 for (ptr = new_module->module_interface->limit_interface; ptr; ptr = ptr->next) {
741 if (!ptr->interface_name) {
742 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 742, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load limit interface from %s due to no interface name.\n", key);
743 } else {
744 if (switch_core_hash_find(loadable_modules.limit_hash, ptr->interface_name)) {
745 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 745, ((void*)0)
, SWITCH_LOG_CRIT,
746 "Failed to load limit interface %s. Name %s already exists\n", key, ptr->interface_name);
747 } else {
748 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 748, ((void*)0)
, SWITCH_LOG_NOTICE,
749 "Adding Limit interface '%s'\n", ptr->interface_name);
750 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))
;
751 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 751, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
752 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "limit");
753 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
754 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
755 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
756
757 if (!event_hash) {
758 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 758, &event, ((void*)0))
;
759 }
760 else {
761 sprintf(str_event_num, "%i", ++*event_num);
762 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
763 }
764
765 added++;
766 }
767 }
768
769 }
770 }
771 }
772
773 if (!added) {
42
Taking true branch
774 if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 774, &event, SWITCH_EVENT_MODULE_LOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
43
Taking false branch
775 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "generic");
776 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", new_module->key);
777 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
778 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
779
780 if (!event_hash) {
781 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 781, &event, ((void*)0))
;
782 }
783 else {
784 sprintf(str_event_num, "%i", ++*event_num);
785 switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event)switch_core_hash_insert_destructor(event_hash, (const char*)str_event_num
, (const void*)event, ((void*)0))
;
786 }
787
788 added++;
789 }
790 }
791
792 switch_mutex_unlock(loadable_modules.mutex);
44
Potential leak of memory pointed to by 'event_num'
793 return SWITCH_STATUS_SUCCESS;
794
795}
796
797#define CHAT_MAX_MSG_QUEUE101 101
798#define CHAT_QUEUE_SIZE5000 5000
799
800static struct {
801 switch_queue_t *msg_queue[CHAT_MAX_MSG_QUEUE101];
802 switch_thread_t *msg_queue_thread[CHAT_MAX_MSG_QUEUE101];
803 int msg_queue_len;
804 switch_mutex_t *mutex;
805 switch_memory_pool_t *pool;
806 int running;
807} chat_globals;
808
809static int IDX = 0;
810
811
812static switch_status_t do_chat_send(switch_event_t *message_event)
813
814{
815 switch_chat_interface_t *ci;
816 switch_status_t status = SWITCH_STATUS_FALSE;
817 switch_hash_index_t *hi;
818 switch_event_t *dup = NULL((void*)0);
819 const void *var;
820 void *val;
821 const char *proto;
822 const char *replying;
823 const char *dest_proto;
824 int do_skip = 0;
825
826 /*
827
828 const char *from;
829 const char *to;
830 const char *subject;
831 const char *body;
832 const char *type;
833 const char *hint;
834 */
835
836 dest_proto = switch_event_get_header(message_event, "dest_proto")switch_event_get_header_idx(message_event, "dest_proto", -1);
837
838 if (!dest_proto) {
839 return SWITCH_STATUS_FALSE;
840 }
841
842 /*
843
844 from = switch_event_get_header(message_event, "from");
845 to = switch_event_get_header(message_event, "to");
846 subject = switch_event_get_header(message_event, "subject");
847 body = switch_event_get_body(message_event);
848 type = switch_event_get_header(message_event, "type");
849 hint = switch_event_get_header(message_event, "hint");
850 */
851
852 if (!(proto = switch_event_get_header(message_event, "proto")switch_event_get_header_idx(message_event, "proto", -1))) {
853 proto = "global";
854 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto);
855 }
856
857 replying = switch_event_get_header(message_event, "replying")switch_event_get_header_idx(message_event, "replying", -1);
858
859 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)
)) {
860 switch_mutex_lock(loadable_modules.mutex);
861 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)) {
862 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
863
864 if ((ci = (switch_chat_interface_t *) val)) {
865 if (ci->chat_send && !strncasecmp(ci->interface_name, "GLOBAL_", 7)) {
866 status = ci->chat_send(message_event);
867
868 if (status == SWITCH_STATUS_SUCCESS) {
869 if (switch_true(switch_event_get_header(message_event, "final_delivery")switch_event_get_header_idx(message_event, "final_delivery", -
1)
)) {
870 /* The event was handled by an extension in the chatplan,
871 * so the event will be duplicated, modified and queued again,
872 * but it won't be processed by the chatplan again.
873 * So this copy of the event can be destroyed by the caller.
874 */
875 do_skip = 1;
876 }
877 } else if (status == SWITCH_STATUS_BREAK) {
878 /* The event went through the chatplan, but no extension matched
879 * to handle the sms messsage. It'll be attempted to be delivered
880 * directly, and unless that works the sms delivery will have failed.
881 */
882 } else {
883 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 883, ((void*)0)
, SWITCH_LOG_ERROR, "Chat Interface Error [%s]!\n", dest_proto);
884 break;
885 }
886 }
887 }
888 }
889 switch_safe_free(hi)if (hi) {free(hi);hi=((void*)0);};
890 switch_mutex_unlock(loadable_modules.mutex);
891 }
892
893
894 if (!do_skip && !switch_stristr("GLOBAL", dest_proto)) {
895 if ((ci = switch_loadable_module_get_chat_interface(dest_proto)) && ci->chat_send) {
896 status = ci->chat_send(message_event);
897 UNPROTECT_INTERFACE(ci)if (ci) {switch_mutex_lock(ci->reflock); ci->refs--; ci
->parent->refs--; switch_mutex_unlock(ci->reflock); switch_thread_rwlock_unlock
(ci->rwlock); switch_thread_rwlock_unlock(ci->parent->
rwlock);}
;
898 } else {
899 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 899, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid chat interface [%s]!\n", dest_proto);
900 status = SWITCH_STATUS_FALSE;
901 }
902 }
903
904
905 switch_event_dup(&dup, message_event);
906
907 if ( switch_true(switch_event_get_header(message_event, "blocking")switch_event_get_header_idx(message_event, "blocking", -1)) ) {
908 if (status == SWITCH_STATUS_SUCCESS) {
909 switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "false");
910 } else {
911 switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "true");
912 }
913 } else {
914 switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Nonblocking-Delivery", "true");
915 }
916
917 switch_event_fire(&dup)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 917, &dup, ((void*)0))
;
918 return status;
919}
920
921static switch_status_t chat_process_event(switch_event_t **eventp)
922{
923 switch_event_t *event;
924 switch_status_t status;
925
926 switch_assert(eventp)((eventp) ? (void) (0) : __assert_fail ("eventp", "src/switch_loadable_module.c"
, 926, __extension__ __PRETTY_FUNCTION__))
;
927
928 event = *eventp;
929 *eventp = NULL((void*)0);
930
931 status = do_chat_send(event);
932 switch_event_destroy(&event);
933
934 return status;
935}
936
937
938void *SWITCH_THREAD_FUNC chat_thread_run(switch_thread_t *thread, void *obj)
939{
940 void *pop;
941 switch_queue_t *q = (switch_queue_t *) obj;
942
943 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 943, ((void*)0)
, SWITCH_LOG_DEBUG, "Chat Thread Started\n");
944
945
946 while(switch_queue_pop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
947 switch_event_t *event = (switch_event_t *) pop;
948 chat_process_event(&event);
949 switch_cond_next();
950 }
951
952 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 952, ((void*)0)
, SWITCH_LOG_DEBUG, "Chat Thread Ended\n");
953
954 return NULL((void*)0);
955}
956
957
958static void chat_thread_start(int idx)
959{
960
961 if (idx >= CHAT_MAX_MSG_QUEUE101 || (idx < chat_globals.msg_queue_len && chat_globals.msg_queue_thread[idx])) {
962 return;
963 }
964
965 switch_mutex_lock(chat_globals.mutex);
966
967 if (idx >= chat_globals.msg_queue_len) {
968 int i;
969 chat_globals.msg_queue_len = idx + 1;
970
971 for (i = 0; i < chat_globals.msg_queue_len; i++) {
972 if (!chat_globals.msg_queue[i]) {
973 switch_threadattr_t *thd_attr = NULL((void*)0);
974
975 switch_queue_create(&chat_globals.msg_queue[i], CHAT_QUEUE_SIZE5000, chat_globals.pool);
976
977 switch_threadattr_create(&thd_attr, chat_globals.pool);
978 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
979 switch_thread_create(&chat_globals.msg_queue_thread[i],
980 thd_attr,
981 chat_thread_run,
982 chat_globals.msg_queue[i],
983 chat_globals.pool);
984 }
985 }
986 }
987
988 switch_mutex_unlock(chat_globals.mutex);
989}
990
991
992static void chat_queue_message(switch_event_t **eventp)
993{
994 int idx = 0;
995 switch_event_t *event;
996
997 switch_assert(eventp)((eventp) ? (void) (0) : __assert_fail ("eventp", "src/switch_loadable_module.c"
, 997, __extension__ __PRETTY_FUNCTION__))
;
998
999 event = *eventp;
1000 *eventp = NULL((void*)0);
1001
1002 if (chat_globals.running == 0) {
1003 chat_process_event(&event);
1004 return;
1005 }
1006
1007 again:
1008
1009 switch_mutex_lock(chat_globals.mutex);
1010 idx = IDX;
1011 IDX++;
1012 if (IDX >= chat_globals.msg_queue_len) IDX = 0;
1013 switch_mutex_unlock(chat_globals.mutex);
1014
1015 chat_thread_start(idx);
1016
1017 if (switch_queue_trypush(chat_globals.msg_queue[idx], event) != SWITCH_STATUS_SUCCESS) {
1018 if (chat_globals.msg_queue_len < CHAT_MAX_MSG_QUEUE101) {
1019 chat_thread_start(idx + 1);
1020 goto again;
1021 } else {
1022 switch_queue_push(chat_globals.msg_queue[idx], event);
1023 }
1024 }
1025}
1026
1027
1028SWITCH_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)
1029{
1030 switch_chat_application_interface_t *cai;
1031 switch_status_t status = SWITCH_STATUS_SUCCESS;
1032 char *expanded;
1033
1034 if (!(cai = switch_loadable_module_get_chat_application_interface(app)) || !cai->chat_application_function) {
1035 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1035, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid chat application interface [%s]!\n", app);
1036 return SWITCH_STATUS_FALSE;
1037 }
1038
1039 if (switch_test_flag(message, EF_NO_CHAT_EXEC)((message)->flags & EF_NO_CHAT_EXEC)) {
1040 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1040, ((void*)0)
, SWITCH_LOG_DEBUG, "Message is not allowed to execute apps\n");
1041 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1042 }
1043
1044 if (data && !strcmp(data, "__undef")) {
1045 data = NULL((void*)0);
1046 }
1047
1048 expanded = switch_event_expand_headers(message, data)switch_event_expand_headers_check(message, data, ((void*)0), (
(void*)0), 0)
;
1049
1050 status = cai->chat_application_function(message, expanded);
1051
1052 if (expanded != data) {
1053 free(expanded);
1054 }
1055
1056 end:
1057
1058 UNPROTECT_INTERFACE(cai)if (cai) {switch_mutex_lock(cai->reflock); cai->refs--;
cai->parent->refs--; switch_mutex_unlock(cai->reflock
); switch_thread_rwlock_unlock(cai->rwlock); switch_thread_rwlock_unlock
(cai->parent->rwlock);}
;
1059
1060 return status;
1061
1062}
1063
1064
1065
1066SWITCH_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,
1067 const char *subject, const char *body, const char *type, const char *hint, switch_bool_t blocking)
1068{
1069 switch_event_t *message_event;
1070 switch_status_t status;
1071
1072 if (switch_event_create(&message_event, SWITCH_EVENT_MESSAGE)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1072, &message_event
, SWITCH_EVENT_MESSAGE, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1073 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto);
1074 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "from", from);
1075 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "to", to);
1076 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "subject", subject);
1077 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "type", type);
1078 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "hint", hint);
1079 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "skip_global_process", "true");
1080 if (blocking) {
1081 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "blocking", "true");
1082 }
1083
1084 if (body) {
1085 switch_event_add_body(message_event, "%s", body);
1086 }
1087 } else {
1088 abort();
1089 }
1090
1091 if (dest_proto) {
1092 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "dest_proto", dest_proto);
1093 }
1094
1095
1096 if (blocking) {
1097 status = chat_process_event(&message_event);
1098 } else {
1099 chat_queue_message(&message_event);
1100 status = SWITCH_STATUS_SUCCESS;
1101 }
1102
1103 return status;
1104
1105}
1106
1107
1108SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_chat_send(const char *dest_proto, switch_event_t *message_event)
1109{
1110 switch_event_t *dup;
1111
1112 switch_event_dup(&dup, message_event);
1113
1114 if (dest_proto) {
1115 switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "dest_proto", dest_proto);
1116 }
1117
1118 chat_queue_message(&dup);
1119 return SWITCH_STATUS_SUCCESS;
1120}
1121
1122
1123SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_chat_deliver(const char *dest_proto, switch_event_t **message_event)
1124{
1125
1126 if (dest_proto) {
1127 switch_event_add_header_string(*message_event, SWITCH_STACK_BOTTOM, "dest_proto", dest_proto);
1128 }
1129
1130 chat_queue_message(message_event);
1131
1132 return SWITCH_STATUS_SUCCESS;
1133}
1134
1135
1136static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t *old_module)
1137{
1138 switch_event_t *event;
1139 int removed = 0;
1140
1141 switch_mutex_lock(loadable_modules.mutex);
1142
1143 if (old_module->module_interface->endpoint_interface) {
1144 const switch_endpoint_interface_t *ptr;
1145
1146 for (ptr = old_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
1147 if (ptr->interface_name) {
1148
1149 switch_core_session_hupall_endpoint(ptr, SWITCH_CAUSE_MANAGER_REQUEST);
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 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1153 switch_thread_rwlock_unlock(ptr->rwlock);
1154 } else {
1155 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1155, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1156 }
1157
1158 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1158, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Endpoint '%s'\n", ptr->interface_name);
1159 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1159, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1160 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "endpoint");
1161 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1162 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1162, &event, ((void*)0)
)
;
1163 removed++;
1164 }
1165 switch_core_hash_delete(loadable_modules.endpoint_hash, ptr->interface_name);
1166 }
1167 }
1168 }
1169
1170 if (old_module->module_interface->codec_interface) {
1171 const switch_codec_implementation_t *impl;
1172 const switch_codec_interface_t *ptr;
1173 switch_codec_node_t *node, *head, *last = NULL((void*)0);
1174
1175 for (ptr = old_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
1176 if (ptr->interface_name) {
1177 unsigned load_interface = 1;
1178 for (impl = ptr->implementations; impl; impl = impl->next) {
1179 if (!impl->iananame) {
1180 load_interface = 0;
1181 break;
1182 }
1183 }
1184 if (load_interface) {
1185 for (impl = ptr->implementations; impl; impl = impl->next) {
1186 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1186, ((void*)0)
, SWITCH_LOG_NOTICE,
1187 "Deleting Codec %s %d %s %dhz %dms\n",
1188 impl->iananame, impl->ianacode,
1189 ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000);
1190 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)
;
1191 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)
;
1192
1193 if ((head = switch_core_hash_find(loadable_modules.codec_hash, impl->iananame))) {
1194 for(node = head; node; node = node->next) {
1195 if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
1196 if (node == head) {
1197 if ((node = node->next)) {
1198 switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) node)switch_core_hash_insert_destructor(loadable_modules.codec_hash
, impl->iananame, (const void *) node, ((void*)0))
;
1199 } else {
1200 switch_core_hash_delete(loadable_modules.codec_hash, impl->iananame);
1201 }
1202 } else {
1203 if (last) {
1204 last->next = node->next;
1205 }
1206 }
1207 break;
1208 }
1209 last = node;
1210 }
1211 }
1212 }
1213 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1213, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1214 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "codec");
1215 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1216 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", old_module->module_interface->module_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 }
1221 }
1222 }
1223 }
1224
1225 if (old_module->module_interface->dialplan_interface) {
1226 const switch_dialplan_interface_t *ptr;
1227
1228 for (ptr = old_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) {
1229 if (ptr->interface_name) {
1230 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1230, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Dialplan '%s'\n", ptr->interface_name);
1231 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1231, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1232 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "dialplan");
1233 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1234 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1234, &event, ((void*)0)
)
;
1235 removed++;
1236 }
1237 switch_core_hash_delete(loadable_modules.dialplan_hash, ptr->interface_name);
1238 }
1239 }
1240 }
1241
1242 if (old_module->module_interface->timer_interface) {
1243 const switch_timer_interface_t *ptr;
1244
1245 for (ptr = old_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
1246 if (ptr->interface_name) {
1247 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1247, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Timer '%s'\n", ptr->interface_name);
1248 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1248, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1249 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "timer");
1250 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1251 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1251, &event, ((void*)0)
)
;
1252 removed++;
1253 }
1254 switch_core_hash_delete(loadable_modules.timer_hash, ptr->interface_name);
1255 }
1256 }
1257 }
1258
1259 if (old_module->module_interface->application_interface) {
1260 const switch_application_interface_t *ptr;
1261 for (ptr = old_module->module_interface->application_interface; ptr; ptr = ptr->next) {
1262 if (ptr->interface_name) {
1263 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1263, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
1264 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)
;
1265 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1265, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1266 ptr->interface_name);
1267 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1268 switch_thread_rwlock_unlock(ptr->rwlock);
1269 } else {
1270 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1270, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1271 }
1272
1273 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1273, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1274 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
1275 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1276 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->short_desc)(ptr->short_desc ? ptr->short_desc : ""));
1277 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
1278 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1278, &event, ((void*)0)
)
;
1279 removed++;
1280 }
1281 switch_core_hash_delete(loadable_modules.application_hash, ptr->interface_name);
1282 }
1283 }
1284 }
1285
1286 if (old_module->module_interface->chat_application_interface) {
1287 const switch_chat_application_interface_t *ptr;
1288 for (ptr = old_module->module_interface->chat_application_interface; ptr; ptr = ptr->next) {
1289 if (ptr->interface_name) {
1290 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1290, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
1291 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)
;
1292 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1292, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1293 ptr->interface_name);
1294 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1295 switch_thread_rwlock_unlock(ptr->rwlock);
1296 } else {
1297 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1297, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1298 }
1299
1300 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1300, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1301 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
1302 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1303 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->short_desc)(ptr->short_desc ? ptr->short_desc : ""));
1304 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
1305 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1305, &event, ((void*)0)
)
;
1306 removed++;
1307 }
1308 switch_core_hash_delete(loadable_modules.chat_application_hash, ptr->interface_name);
1309 }
1310 }
1311 }
1312
1313 if (old_module->module_interface->api_interface) {
1314 const switch_api_interface_t *ptr;
1315
1316 for (ptr = old_module->module_interface->api_interface; ptr; ptr = ptr->next) {
1317 if (ptr->interface_name) {
1318 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1318, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
1319
1320 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1320, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1321 ptr->interface_name);
1322
1323 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1324 switch_thread_rwlock_unlock(ptr->rwlock);
1325 } else {
1326 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1326, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1327 }
1328
1329
1330 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1330, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1331 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");
1332 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1333 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->desc)(ptr->desc ? ptr->desc : ""));
1334 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
1335 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", old_module->key);
1336 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", old_module->filename);
1337 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1337, &event, ((void*)0)
)
;
1338 removed++;
1339 }
1340 switch_core_hash_delete(loadable_modules.api_hash, ptr->interface_name);
1341 }
1342 }
1343 }
1344
1345 if (old_module->module_interface->json_api_interface) {
1346 const switch_json_api_interface_t *ptr;
1347
1348 for (ptr = old_module->module_interface->json_api_interface; ptr; ptr = ptr->next) {
1349 if (ptr->interface_name) {
1350 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1350, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
1351
1352 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1352, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1353 ptr->interface_name);
1354
1355 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1356 switch_thread_rwlock_unlock(ptr->rwlock);
1357 } else {
1358 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1358, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1359 }
1360
1361
1362 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1362, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1363 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "json_api");
1364 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1365 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->desc)(ptr->desc ? ptr->desc : ""));
1366 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax)(ptr->syntax ? ptr->syntax : ""));
1367 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1367, &event, ((void*)0)
)
;
1368 removed++;
1369 }
1370 switch_core_hash_delete(loadable_modules.json_api_hash, ptr->interface_name);
1371 }
1372 }
1373 }
1374
1375 if (old_module->module_interface->file_interface) {
1376 const switch_file_interface_t *ptr;
1377 switch_file_node_t *node, *head, *last = NULL((void*)0);
1378
1379 for (ptr = old_module->module_interface->file_interface; ptr; ptr = ptr->next) {
1380 if (ptr->interface_name) {
1381 int i;
1382
1383 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1383, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1384 ptr->interface_name);
1385
1386 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1387 switch_thread_rwlock_unlock(ptr->rwlock);
1388 } else {
1389 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1389, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1390 }
1391
1392 for (i = 0; ptr->extens[i]; i++) {
1393 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1393, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting File Format '%s'\n", ptr->extens[i]);
1394 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1394, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1395 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "file");
1396 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->extens[i]);
1397 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", old_module->module_interface->module_name);
1398 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1398, &event, ((void*)0)
)
;
1399 removed++;
1400 }
1401
1402 if ((head = switch_core_hash_find(loadable_modules.file_hash, ptr->extens[i]))) {
1403 for(node = head; node; node = node->next) {
1404 if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
1405 if (node == head) {
1406 if ((node = node->next)) {
1407 switch_core_hash_insert(loadable_modules.file_hash, ptr->extens[i], (const void *) node)switch_core_hash_insert_destructor(loadable_modules.file_hash
, ptr->extens[i], (const void *) node, ((void*)0))
;
1408 } else {
1409 switch_core_hash_delete(loadable_modules.file_hash, ptr->extens[i]);
1410 }
1411 } else {
1412 if (last) {
1413 last->next = node->next;
1414 }
1415 }
1416 break;
1417 }
1418 last = node;
1419 }
1420 }
1421 }
1422 }
1423 }
1424 }
1425
1426 if (old_module->module_interface->database_interface) {
1427 const switch_database_interface_t *ptr;
1428 switch_database_node_t *node, *head, *last = NULL((void*)0);
1429
1430 for (ptr = old_module->module_interface->database_interface; ptr; ptr = ptr->next) {
1431 if (ptr->interface_name) {
1432 int i;
1433
1434 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1434, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1435 ptr->interface_name);
1436
1437 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1438 switch_thread_rwlock_unlock(ptr->rwlock);
1439 }
1440 else {
1441 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1441, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1442 }
1443
1444 for (i = 0; ptr->prefixes[i]; i++) {
1445 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1445, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting dsn prefix '%s'\n", ptr->prefixes[i]);
1446 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1446, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1447 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "database");
1448 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->prefixes[i]);
1449 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", old_module->module_interface->module_name);
1450 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1450, &event, ((void*)0)
)
;
1451 removed++;
1452 }
1453
1454 if ((head = switch_core_hash_find(loadable_modules.database_hash, ptr->prefixes[i]))) {
1455 for (node = head; node; node = node->next) {
1456 if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
1457 if (node == head) {
1458 if ((node = node->next)) {
1459 switch_core_hash_insert(loadable_modules.database_hash, ptr->prefixes[i], (const void *)node)switch_core_hash_insert_destructor(loadable_modules.database_hash
, ptr->prefixes[i], (const void *)node, ((void*)0))
;
1460 }
1461 else {
1462 switch_core_hash_delete(loadable_modules.database_hash, ptr->prefixes[i]);
1463 }
1464 }
1465 else {
1466 if (last) {
1467 last->next = node->next;
1468 }
1469 }
1470 break;
1471 }
1472 last = node;
1473 }
1474 }
1475 }
1476
1477 switch_cache_db_database_interface_flush_handles(old_module->module_interface->database_interface);
1478 }
1479 }
1480 }
1481
1482 if (old_module->module_interface->speech_interface) {
1483 const switch_speech_interface_t *ptr;
1484
1485 for (ptr = old_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
1486
1487 if (ptr->interface_name) {
1488
1489 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1489, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1490 ptr->interface_name);
1491
1492 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1493 switch_thread_rwlock_unlock(ptr->rwlock);
1494 } else {
1495 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1495, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1496 }
1497
1498 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1498, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Speech interface '%s'\n", ptr->interface_name);
1499 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1499, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1500 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
1501 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1502 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1502, &event, ((void*)0)
)
;
1503 removed++;
1504 }
1505 switch_core_hash_delete(loadable_modules.speech_hash, ptr->interface_name);
1506 }
1507 }
1508 }
1509
1510 if (old_module->module_interface->asr_interface) {
1511 const switch_asr_interface_t *ptr;
1512
1513 for (ptr = old_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
1514 if (ptr->interface_name) {
1515
1516 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1516, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1517 ptr->interface_name);
1518
1519 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1520 switch_thread_rwlock_unlock(ptr->rwlock);
1521 } else {
1522 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1522, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1523 }
1524
1525 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1525, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Asr interface '%s'\n", ptr->interface_name);
1526 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1526, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1527 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "asr");
1528 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1529 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1529, &event, ((void*)0)
)
;
1530 removed++;
1531 }
1532 switch_core_hash_delete(loadable_modules.asr_hash, ptr->interface_name);
1533 }
1534 }
1535 }
1536
1537 if (old_module->module_interface->directory_interface) {
1538 const switch_directory_interface_t *ptr;
1539
1540 for (ptr = old_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
1541 if (ptr->interface_name) {
1542
1543 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1543, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1544 ptr->interface_name);
1545
1546 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1547 switch_thread_rwlock_unlock(ptr->rwlock);
1548 } else {
1549 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1549, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1550 }
1551
1552 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1552, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Directory interface '%s'\n", ptr->interface_name);
1553 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1553, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1554 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
1555 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1556 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1556, &event, ((void*)0)
)
;
1557 removed++;
1558 }
1559 switch_core_hash_delete(loadable_modules.directory_hash, ptr->interface_name);
1560 }
1561 }
1562 }
1563
1564
1565 if (old_module->module_interface->chat_interface) {
1566 const switch_chat_interface_t *ptr;
1567
1568 for (ptr = old_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
1569 if (ptr->interface_name) {
1570 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1570, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1571 ptr->interface_name);
1572
1573 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1574 switch_thread_rwlock_unlock(ptr->rwlock);
1575 } else {
1576 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1576, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1577 }
1578
1579 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1579, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Chat interface '%s'\n", ptr->interface_name);
1580 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1580, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1581 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
1582 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1583 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1583, &event, ((void*)0)
)
;
1584 removed++;
1585 }
1586 switch_core_hash_delete(loadable_modules.chat_hash, ptr->interface_name);
1587 }
1588 }
1589 }
1590
1591 if (old_module->module_interface->say_interface) {
1592 const switch_say_interface_t *ptr;
1593
1594 for (ptr = old_module->module_interface->say_interface; ptr; ptr = ptr->next) {
1595 if (ptr->interface_name) {
1596 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1596, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1597 ptr->interface_name);
1598
1599 if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
1600 switch_thread_rwlock_unlock(ptr->rwlock);
1601 } else {
1602 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1602, ((void*)0)
, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1603 }
1604 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1604, ((void*)0)
, SWITCH_LOG_NOTICE, "Deleting Say interface '%s'\n", ptr->interface_name);
1605 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1605, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1606 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "say");
1607 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1608 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1608, &event, ((void*)0)
)
;
1609 removed++;
1610 }
1611 switch_core_hash_delete(loadable_modules.say_hash, ptr->interface_name);
1612 }
1613 }
1614 }
1615
1616 if (old_module->module_interface->management_interface) {
1617 const switch_management_interface_t *ptr;
1618
1619 for (ptr = old_module->module_interface->management_interface; ptr; ptr = ptr->next) {
1620 if (ptr->relative_oid) {
1621 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1621, ((void*)0)
, SWITCH_LOG_NOTICE,
1622 "Deleting Management interface '%s' OID[%s.%s]\n", old_module->key, FREESWITCH_OID_PREFIX".1.3.6.1.4.1." "27880", ptr->relative_oid);
1623 switch_core_hash_delete(loadable_modules.management_hash, ptr->relative_oid);
1624 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1624, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1625 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "management");
1626 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->relative_oid);
1627 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1627, &event, ((void*)0)
)
;
1628 removed++;
1629 }
1630 }
1631 }
1632 }
1633
1634 if (old_module->module_interface->limit_interface) {
1635 const switch_limit_interface_t *ptr;
1636
1637 for (ptr = old_module->module_interface->limit_interface; ptr; ptr = ptr->next) {
1638 if (ptr->interface_name) {
1639 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1639, ((void*)0)
, SWITCH_LOG_NOTICE,
1640 "Deleting Limit interface '%s'\n", ptr->interface_name);
1641 switch_core_hash_delete(loadable_modules.limit_hash, ptr->interface_name);
1642 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1642, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1643 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "limit");
1644 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
1645 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1645, &event, ((void*)0)
)
;
1646 removed++;
1647 }
1648 }
1649 }
1650 }
1651
1652 if (!removed) {
1653 if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 1653, &event, SWITCH_EVENT_MODULE_UNLOAD
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1654 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "generic");
1655 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", old_module->key);
1656 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 1656, &event, ((void*)0)
)
;
1657 removed++;
1658 }
1659 }
1660 switch_mutex_unlock(loadable_modules.mutex);
1661
1662 return SWITCH_STATUS_SUCCESS;
1663
1664}
1665
1666
1667static switch_status_t switch_loadable_module_load_file(char *path, char *filename, switch_bool_t global, switch_loadable_module_t **new_module)
1668{
1669 switch_loadable_module_t *module = NULL((void*)0);
1670 switch_dso_lib_t dso = NULL((void*)0);
1671 apr_status_t status = SWITCH_STATUS_SUCCESS;
1672 switch_loadable_module_function_table_t *interface_struct_handle = NULL((void*)0);
1673 switch_loadable_module_function_table_t *mod_interface_functions = NULL((void*)0);
1674 char *struct_name = NULL((void*)0);
1675 switch_module_load_t load_func_ptr = NULL((void*)0);
1676 int loading = 1;
1677 switch_loadable_module_interface_t *module_interface = NULL((void*)0);
1678 char *derr = NULL((void*)0);
1679 const char *err = NULL((void*)0);
1680 switch_memory_pool_t *pool = NULL((void*)0);
1681 switch_bool_t load_global = global;
1682
1683 switch_assert(path != NULL)((path != ((void*)0)) ? (void) (0) : __assert_fail ("path != ((void*)0)"
, "src/switch_loadable_module.c", 1683, __extension__ __PRETTY_FUNCTION__
))
;
1684
1685 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 1685)
;
1686 *new_module = NULL((void*)0);
1687
1688 struct_name = switch_core_sprintf(pool, "%s_module_interface", filename);
1689
1690#ifdef WIN32
1691 dso = switch_dso_open("FreeSwitch.dll", load_global, &derr);
1692#elif defined (MACOSX) || defined(DARWIN)
1693 {
1694 char *lib_path = switch_mprintf("%s/libfreeswitch.dylib", SWITCH_GLOBAL_dirs.lib_dir);
1695 dso = switch_dso_open(lib_path, load_global, &derr);
1696 switch_safe_free(lib_path)if (lib_path) {free(lib_path);lib_path=((void*)0);};
1697 }
1698#else
1699 dso = switch_dso_open(NULL((void*)0), load_global, &derr);
1700#endif
1701 if (!derr && dso) {
1702 interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
1703 }
1704
1705 switch_safe_free(derr)if (derr) {free(derr);derr=((void*)0);};
1706
1707 if (!interface_struct_handle) {
1708 if (dso) switch_dso_destroy(&dso);
1709 dso = switch_dso_open(path, load_global, &derr);
1710 }
1711
1712 while (loading) {
1713 if (derr) {
1714 err = derr;
1715 break;
1716 }
1717
1718 if (!interface_struct_handle) {
1719 interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
1720 }
1721
1722 if (derr) {
1723 err = derr;
1724 break;
1725 }
1726
1727 if (interface_struct_handle && interface_struct_handle->switch_api_version != SWITCH_API_VERSION5) {
1728 err = "Trying to load an out of date module, please rebuild the module.";
1729 break;
1730 }
1731
1732 if (!load_global && interface_struct_handle && switch_test_flag(interface_struct_handle, SMODF_GLOBAL_SYMBOLS)((interface_struct_handle)->flags & SMODF_GLOBAL_SYMBOLS
)
) {
1733 load_global = SWITCH_TRUE;
1734 switch_dso_destroy(&dso);
1735 interface_struct_handle = NULL((void*)0);
1736 dso = switch_dso_open(path, load_global, &derr);
1737 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1737, ((void*)0)
, SWITCH_LOG_DEBUG, "Loading module with global namespace at request of module\n");
1738 continue;
1739 }
1740
1741 if (interface_struct_handle) {
1742 mod_interface_functions = interface_struct_handle;
1743 load_func_ptr = mod_interface_functions->load;
1744 }
1745
1746 if (load_func_ptr == NULL((void*)0)) {
1747 err = "Cannot locate symbol 'switch_module_load' please make sure this is a valid module.";
1748 break;
1749 }
1750
1751 status = load_func_ptr(&module_interface, pool);
1752
1753 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_NOUNLOAD) {
1754 err = "Module load routine returned an error";
1755 module_interface = NULL((void*)0);
1756 break;
1757 }
1758
1759 if (!module_interface) {
1760 err = "Module failed to initialize its module_interface. Is this a valid module?";
1761 break;
1762 }
1763
1764 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__, 1764
)
) == 0) {
1765 abort();
1766 }
1767
1768 if (status == SWITCH_STATUS_NOUNLOAD) {
1769 module->perm++;
1770 }
1771
1772 loading = 0;
1773 }
1774
1775
1776 if (err) {
1777
1778 if (dso) {
1779 switch_dso_destroy(&dso);
1780 }
1781
1782 if (pool) {
1783 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 1783)
;
1784 }
1785 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1785, ((void*)0)
, SWITCH_LOG_CRIT, "Error Loading module %s\n**%s**\n", path, err);
1786 switch_safe_free(derr)if (derr) {free(derr);derr=((void*)0);};
1787 return SWITCH_STATUS_GENERR;
1788 }
1789
1790 module->pool = pool;
1791 module->filename = switch_core_strdup(module->pool, path)switch_core_perform_strdup(module->pool, path, "src/switch_loadable_module.c"
, (const char *)__func__, 1791)
;
1792 module->module_interface = module_interface;
1793 module->switch_module_load = load_func_ptr;
1794
1795 if (mod_interface_functions) {
1796 module->switch_module_shutdown = mod_interface_functions->shutdown;
1797 module->switch_module_runtime = mod_interface_functions->runtime;
1798 }
1799
1800 module->lib = dso;
1801
1802 *new_module = module;
1803 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1803, ((void*)0)
, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
1804
1805 switch_core_set_signal_handlers();
1806
1807 return SWITCH_STATUS_SUCCESS;
1808
1809}
1810SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_load_module(const char *dir, const char *fname, switch_bool_t runtime, const char **err)
1811{
1812 return switch_loadable_module_load_module_ex(dir, fname, runtime, SWITCH_FALSE, err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, NULL((void*)0));
1813}
1814
1815static switch_status_t switch_loadable_module_load_module_ex(const char *dir, const char *fname, switch_bool_t runtime, switch_bool_t global, const char **err, switch_loadable_module_type_t type, switch_hash_t *event_hash)
1816{
1817 switch_size_t len = 0;
1818 char *path;
1819 char *file, *dot;
1820 switch_loadable_module_t *new_module = NULL((void*)0);
1821 switch_status_t status = SWITCH_STATUS_SUCCESS;
1822
1823#ifdef WIN32
1824 const char *ext = ".dll";
1825#else
1826 const char *ext = ".so";
1827#endif
1828
1829 *err = "";
1830
1831 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__, 1831)
) == 0) {
1832 *err = "allocation error";
1833 return SWITCH_STATUS_FALSE;
1834 }
1835
1836 if (switch_is_file_path(file)) {
1837 path = switch_core_strdup(loadable_modules.pool, file)switch_core_perform_strdup(loadable_modules.pool, file, "src/switch_loadable_module.c"
, (const char *)__func__, 1837)
;
1838 file = (char *) switch_cut_path(file);
1839 if ((dot = strchr(file, '.'))) {
1840 *dot = '\0';
1841 }
1842 } else {
1843 if ((dot = strchr(file, '.'))) {
1844 *dot = '\0';
1845 }
1846 len = strlen(switch_str_nil(dir)(dir ? dir : ""));
1847 len += strlen(file);
1848 len += 8;
1849 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__, 1849)
;
1850 switch_snprintf(path, len, "%s%s%s%s", switch_str_nil(dir)(dir ? dir : ""), SWITCH_PATH_SEPARATOR"/", file, ext);
1851 }
1852
1853
1854 if (switch_core_hash_find_locked(loadable_modules.module_hash, file, loadable_modules.mutex)) {
1855 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1855, ((void*)0)
, SWITCH_LOG_WARNING, "Module %s Already Loaded!\n", file);
1856 *err = "Module already loaded";
1857 status = SWITCH_STATUS_FALSE;
1858 } else if ((status = switch_loadable_module_load_file(path, file, global, &new_module)) == SWITCH_STATUS_SUCCESS) {
1859 new_module->type = type;
1860
1861 if ((status = switch_loadable_module_process(file, new_module, event_hash)) == SWITCH_STATUS_SUCCESS && runtime) {
1862 if (new_module->switch_module_runtime) {
1863 new_module->thread = switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool);
1864 }
1865 } else if (status != SWITCH_STATUS_SUCCESS) {
1866 *err = "module load routine returned an error";
1867 }
1868 } else {
1869 *err = "module load file routine returned an error";
1870 }
1871
1872
1873 return status;
1874
1875}
1876
1877SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_exists(const char *mod)
1878{
1879 switch_status_t status;
1880
1881 if (zstr(mod)_zstr(mod)) {
1882 return SWITCH_STATUS_FALSE;
1883 }
1884
1885 switch_mutex_lock(loadable_modules.mutex);
1886 if (switch_core_hash_find(loadable_modules.module_hash, mod)) {
1887 status = SWITCH_STATUS_SUCCESS;
1888 } else {
1889 status = SWITCH_STATUS_FALSE;
1890 }
1891 switch_mutex_unlock(loadable_modules.mutex);
1892
1893 return status;
1894}
1895
1896SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_protect(const char *mod)
1897{
1898 switch_loadable_module_t *module = NULL((void*)0);
1899 switch_status_t status = SWITCH_STATUS_FALSE;
1900
1901 if (zstr(mod)_zstr(mod)) {
1902 return SWITCH_STATUS_FALSE;
1903 }
1904
1905 switch_mutex_lock(loadable_modules.mutex);
1906 if ((module = switch_core_hash_find(loadable_modules.module_hash, mod))) {
1907 if (!module->perm) {
1908 module->perm++;
1909 }
1910 status = SWITCH_STATUS_SUCCESS;
1911 }
1912 else {
1913 status = SWITCH_STATUS_FALSE;
1914 }
1915 switch_mutex_unlock(loadable_modules.mutex);
1916
1917 return status;
1918}
1919
1920SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_unload_module(const char *dir, const char *fname, switch_bool_t force, const char **err)
1921{
1922 switch_loadable_module_t *module = NULL((void*)0);
1923 switch_status_t status = SWITCH_STATUS_SUCCESS;
1924
1925 if (force) {
1926 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1926, ((void*)0)
, SWITCH_LOG_WARNING, "Spin the barrel and pull the trigger.......!\n");
1927 }
1928
1929 switch_mutex_lock(loadable_modules.mutex);
1930 if ((module = switch_core_hash_find(loadable_modules.module_hash, fname))) {
1931 if (module->perm) {
1932 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1932, ((void*)0)
, SWITCH_LOG_CRIT, "Module is not unloadable.\n");
1933 *err = "Module is not unloadable";
1934 status = SWITCH_STATUS_NOUNLOAD;
1935 goto unlock;
1936 } else {
1937 /* Prevent anything from using the module while it's shutting down */
1938 switch_core_hash_delete(loadable_modules.module_hash, fname);
1939 switch_mutex_unlock(loadable_modules.mutex);
1940 if ((status = do_shutdown(module, SWITCH_TRUE, SWITCH_TRUE, !force, err)) != SWITCH_STATUS_SUCCESS) {
1941 /* Something went wrong in the module's shutdown function, add it again */
1942 switch_core_hash_insert_locked(loadable_modules.module_hash, fname, module, loadable_modules.mutex);
1943 }
1944 goto end;
1945 }
1946 } else {
1947 *err = "No such module!";
1948 status = SWITCH_STATUS_FALSE;
1949 }
1950unlock:
1951 switch_mutex_unlock(loadable_modules.mutex);
1952 end:
1953 if (force) {
1954 switch_yield(1000000)switch_sleep(1000000);;
1955 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 1955, ((void*)0)
, SWITCH_LOG_WARNING, "PHEW!\n");
1956 }
1957
1958 return status;
1959
1960}
1961
1962SWITCH_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)
1963{
1964 switch_dir_t *dir = NULL((void*)0);
1965 switch_status_t status;
1966 char buffer[256];
1967 const char *fname;
1968 const char *fname_ext;
1969 char *fname_base;
1970
1971#ifdef WIN32
1972 const char *ext = ".dll";
1973#else
1974 const char *ext = ".so";
1975#endif
1976
1977 if ((status = switch_dir_open(&dir, dir_path, loadable_modules.pool)) != SWITCH_STATUS_SUCCESS) {
1978 return status;
1979 }
1980
1981 while((fname = switch_dir_next_file(dir, buffer, sizeof(buffer)))) {
1982 if ((fname_ext = strrchr(fname, '.'))) {
1983 if (!strcmp(fname_ext, ext)) {
1984 if (!(fname_base = switch_mprintf("%.*s", (int)(fname_ext-fname), fname))) {
1985 status = SWITCH_STATUS_GENERR;
1986 goto end;
1987 }
1988 callback(user_data, fname_base);
1989 switch_safe_free(fname_base)if (fname_base) {free(fname_base);fname_base=((void*)0);}
1990 }
1991 }
1992 }
1993
1994
1995 end:
1996 switch_dir_close(dir);
1997 return status;
1998}
1999
2000SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_enumerate_loaded(switch_modulename_callback_func_t callback, void *user_data)
2001{
2002 switch_hash_index_t *hi;
2003 void *val;
2004 switch_loadable_module_t *module;
2005
2006 switch_mutex_lock(loadable_modules.mutex);
2007 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)) {
2008 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
2009 module = (switch_loadable_module_t *) val;
2010
2011 callback(user_data, module->module_interface->module_name);
2012 }
2013 switch_mutex_unlock(loadable_modules.mutex);
2014
2015 return SWITCH_STATUS_SUCCESS;
2016}
2017
2018SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_build_dynamic(char *filename,
2019 switch_module_load_t switch_module_load,
2020 switch_module_runtime_t switch_module_runtime,
2021 switch_module_shutdown_t switch_module_shutdown, switch_bool_t runtime)
2022{
2023 switch_loadable_module_t *module = NULL((void*)0);
2024 switch_module_load_t load_func_ptr = NULL((void*)0);
2025 int loading = 1;
2026 const char *err = NULL((void*)0);
2027 switch_loadable_module_interface_t *module_interface = NULL((void*)0);
2028 switch_memory_pool_t *pool;
2029
2030
2031 if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 2031)
!= SWITCH_STATUS_SUCCESS) {
2032 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2032, ((void*)0)
, SWITCH_LOG_CRIT, "OH OH no pool\n");
2033 abort();
2034 }
2035
2036 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__, 2036
)
) == 0) {
2037 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2037, ((void*)0)
, SWITCH_LOG_CONSOLE, "Couldn't allocate memory\n");
2038 abort();
2039 }
2040
2041
2042
2043 while (loading) {
2044 switch_status_t status;
2045 load_func_ptr = (switch_module_load_t) switch_module_load;
2046
2047 if (load_func_ptr == NULL((void*)0)) {
2048 err = "Cannot Load";
2049 break;
2050 }
2051
2052 status = load_func_ptr(&module_interface, pool);
2053
2054 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_NOUNLOAD) {
2055 err = "Module load routine returned an error";
2056 module_interface = NULL((void*)0);
2057 break;
2058 }
2059
2060 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__, 2060
)
) == 0) {
2061 abort();
2062 }
2063
2064 if (status == SWITCH_STATUS_NOUNLOAD) {
2065 module->perm++;
2066 }
2067
2068 loading = 0;
2069 }
2070
2071 if (err) {
2072 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 2072)
;
2073 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2073, ((void*)0)
, SWITCH_LOG_CONSOLE, "Error Loading module %s\n**%s**\n", filename, err);
2074 return SWITCH_STATUS_GENERR;
2075 }
2076
2077 module->pool = pool;
2078 module->filename = switch_core_strdup(module->pool, filename)switch_core_perform_strdup(module->pool, filename, "src/switch_loadable_module.c"
, (const char *)__func__, 2078)
;
2079 module->module_interface = module_interface;
2080 module->switch_module_load = load_func_ptr;
2081
2082 if (switch_module_shutdown) {
2083 module->switch_module_shutdown = switch_module_shutdown;
2084 }
2085 if (switch_module_runtime) {
2086 module->switch_module_runtime = switch_module_runtime;
2087 }
2088 if (runtime && module->switch_module_runtime) {
2089 module->thread = switch_core_launch_thread(switch_loadable_module_exec, module, module->pool);
2090 }
2091 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2091, ((void*)0)
, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
2092 return switch_loadable_module_process((char *) module->filename, module, NULL((void*)0));
2093}
2094
2095#ifdef WIN32
2096static void switch_loadable_module_path_init()
2097{
2098 char *path = NULL((void*)0), *working = NULL((void*)0);
2099 apr_dir_t *perl_dir_handle = NULL((void*)0);
2100
2101 apr_env_get(&path, "path", loadable_modules.pool);
2102 apr_filepath_get(&working, APR_FILEPATH_NATIVE0x10, loadable_modules.pool);
2103
2104 if (apr_dir_open(&perl_dir_handle, ".\\perl", loadable_modules.pool) == APR_SUCCESS0) {
2105 apr_dir_close(perl_dir_handle);
2106 apr_env_set("path", apr_pstrcat(loadable_modules.pool, path, ";", working, "\\perl", NULL((void*)0)), loadable_modules.pool);
2107 }
2108}
2109#endif
2110
2111SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_loadable_module_init(switch_bool_t autoload)
2112{
2113
2114 apr_finfo_t finfo = { 0 };
2115 apr_dir_t *module_dir_handle = NULL((void*)0);
2116 apr_int32_t finfo_flags = APR_FINFO_DIRENT0x02000000 | APR_FINFO_TYPE0x00008000 | APR_FINFO_NAME0x02000000;
2117 char *precf = "pre_load_modules.conf";
2118 char *cf = "modules.conf";
2119 char *pcf = "post_load_modules.conf";
2120 switch_xml_t cfg, xml;
2121 unsigned char all = 0;
2122 unsigned int count = 0;
2123 const char *err;
2124 switch_hash_t *event_hash;
2125 switch_hash_index_t *hi;
2126 void *hash_val;
2127 switch_event_t *event;
2128
2129
2130#ifdef WIN32
2131 const char *ext = ".dll";
2132 const char *EXT = ".DLL";
2133#elif defined (MACOSX) || defined (DARWIN)
2134 const char *ext = ".dylib";
2135 const char *EXT = ".DYLIB";
2136#else
2137 const char *ext = ".so";
2138 const char *EXT = ".SO";
2139#endif
2140
2141 memset(&loadable_modules, 0, sizeof(loadable_modules));
2142 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__, 2142
)
;
2143
2144
2145#ifdef WIN32
2146 switch_loadable_module_path_init();
2147#endif
2148
2149 switch_core_hash_init(&loadable_modules.module_hash)switch_core_hash_init_case(&loadable_modules.module_hash,
SWITCH_TRUE)
;
2150 switch_core_hash_init_nocase(&loadable_modules.endpoint_hash)switch_core_hash_init_case(&loadable_modules.endpoint_hash
, SWITCH_FALSE)
;
2151 switch_core_hash_init_nocase(&loadable_modules.codec_hash)switch_core_hash_init_case(&loadable_modules.codec_hash, SWITCH_FALSE
)
;
2152 switch_core_hash_init_nocase(&loadable_modules.timer_hash)switch_core_hash_init_case(&loadable_modules.timer_hash, SWITCH_FALSE
)
;
2153 switch_core_hash_init_nocase(&loadable_modules.application_hash)switch_core_hash_init_case(&loadable_modules.application_hash
, SWITCH_FALSE)
;
2154 switch_core_hash_init_nocase(&loadable_modules.chat_application_hash)switch_core_hash_init_case(&loadable_modules.chat_application_hash
, SWITCH_FALSE)
;
2155 switch_core_hash_init_nocase(&loadable_modules.api_hash)switch_core_hash_init_case(&loadable_modules.api_hash, SWITCH_FALSE
)
;
2156 switch_core_hash_init_nocase(&loadable_modules.json_api_hash)switch_core_hash_init_case(&loadable_modules.json_api_hash
, SWITCH_FALSE)
;
2157 switch_core_hash_init(&loadable_modules.file_hash)switch_core_hash_init_case(&loadable_modules.file_hash, SWITCH_TRUE
)
;
2158 switch_core_hash_init_nocase(&loadable_modules.speech_hash)switch_core_hash_init_case(&loadable_modules.speech_hash,
SWITCH_FALSE)
;
2159 switch_core_hash_init_nocase(&loadable_modules.asr_hash)switch_core_hash_init_case(&loadable_modules.asr_hash, SWITCH_FALSE
)
;
2160 switch_core_hash_init_nocase(&loadable_modules.directory_hash)switch_core_hash_init_case(&loadable_modules.directory_hash
, SWITCH_FALSE)
;
2161 switch_core_hash_init_nocase(&loadable_modules.chat_hash)switch_core_hash_init_case(&loadable_modules.chat_hash, SWITCH_FALSE
)
;
2162 switch_core_hash_init_nocase(&loadable_modules.say_hash)switch_core_hash_init_case(&loadable_modules.say_hash, SWITCH_FALSE
)
;
2163 switch_core_hash_init_nocase(&loadable_modules.management_hash)switch_core_hash_init_case(&loadable_modules.management_hash
, SWITCH_FALSE)
;
2164 switch_core_hash_init_nocase(&loadable_modules.limit_hash)switch_core_hash_init_case(&loadable_modules.limit_hash, SWITCH_FALSE
)
;
2165 switch_core_hash_init_nocase(&loadable_modules.database_hash)switch_core_hash_init_case(&loadable_modules.database_hash
, SWITCH_FALSE)
;
2166 switch_core_hash_init_nocase(&loadable_modules.dialplan_hash)switch_core_hash_init_case(&loadable_modules.dialplan_hash
, SWITCH_FALSE)
;
2167 switch_core_hash_init(&loadable_modules.secondary_recover_hash)switch_core_hash_init_case(&loadable_modules.secondary_recover_hash
, SWITCH_TRUE)
;
2168 switch_mutex_init(&loadable_modules.mutex, SWITCH_MUTEX_NESTED0x1, loadable_modules.pool);
2169
2170 if (!autoload) return SWITCH_STATUS_SUCCESS;
2171
2172 /*
2173 switch_core_sqldb_init() is not yet ready and is executed after starting modules from pre_load_modules.conf
2174 Modules loading procedure generates events used by sqldb.
2175 This is why we should hold those events (storing in the event_hash) not firing them until sqldb is ready.
2176 */
2177 switch_core_hash_init(&event_hash)switch_core_hash_init_case(&event_hash, SWITCH_TRUE);
2178
2179 /*
2180 Pre-load core modules.
2181 Do not pre-load modules which may use databases,
2182 use appropriate section.
2183 */
2184 switch_loadable_module_load_module_ex("", "CORE_SOFTTIMER_MODULE", SWITCH_FALSE, SWITCH_FALSE, &err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, event_hash);
2185 switch_loadable_module_load_module_ex("", "CORE_PCM_MODULE", SWITCH_FALSE, SWITCH_FALSE, &err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, event_hash);
2186 switch_loadable_module_load_module_ex("", "CORE_SPEEX_MODULE", SWITCH_FALSE, SWITCH_FALSE, &err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, event_hash);
2187
2188 /*
2189 Loading pre-load modules.
2190 Database modules must be loaded here.
2191 */
2192 if ((xml = switch_xml_open_cfg(precf, &cfg, NULL((void*)0)))) {
2193 switch_xml_t mods, ld;
2194 if ((mods = switch_xml_child(cfg, "modules"))) {
2195 for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
2196 switch_bool_t global = SWITCH_FALSE;
2197 const char *val = switch_xml_attr_soft(ld, "module");
2198 const char *path = switch_xml_attr_soft(ld, "path");
2199 const char *critical = switch_xml_attr_soft(ld, "critical");
2200 const char *sglobal = switch_xml_attr_soft(ld, "global");
2201
2202 if (zstr(val)_zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
2203 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2203, ((void*)0)
, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
2204 continue;
2205 }
2206 global = switch_true(sglobal);
2207
2208 if (path && zstr(path)_zstr(path)) {
2209 path = SWITCH_GLOBAL_dirs.mod_dir;
2210 }
2211 if (switch_loadable_module_load_module_ex((char *)path, (char *)val, SWITCH_FALSE, global, &err, SWITCH_LOADABLE_MODULE_TYPE_PRELOAD, event_hash) == SWITCH_STATUS_GENERR) {
2212 if (critical && switch_true(critical)) {
2213 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2213, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val);
2214
2215 if ((hash_val = switch_core_hash_find(event_hash, "0"))) {
2216 switch_safe_free(hash_val)if (hash_val) {free(hash_val);hash_val=((void*)0);};
2217 }
2218 switch_core_hash_destroy(&event_hash);
2219
2220 abort();
2221 }
2222 }
2223 count++;
2224 }
2225 }
2226 switch_xml_free(xml);
2227
2228 }
2229 else {
2230 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2230, ((void*)0)
, SWITCH_LOG_CONSOLE, "open of %s failed\n", precf);
2231 }
2232
2233 if (switch_core_sqldb_init(&err) != SWITCH_STATUS_SUCCESS)
2234 {
2235 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2235, ((void*)0)
, SWITCH_LOG_CRIT, "Loading modules interrupted. [Error: %s]\n", err);
2236 if ((hash_val = switch_core_hash_find(event_hash, "0"))) {
2237 switch_safe_free(hash_val)if (hash_val) {free(hash_val);hash_val=((void*)0);};
2238 }
2239 switch_core_hash_destroy(&event_hash);
2240 return SWITCH_STATUS_GENERR;
2241 }
2242
2243 /* sqldb is ready. Fire holding events! */
2244 if ((hash_val = switch_core_hash_find(event_hash, "0"))) {
2245 switch_safe_free(hash_val)if (hash_val) {free(hash_val);hash_val=((void*)0);};
2246 switch_core_hash_delete(event_hash, "0");
2247 }
2248
2249 for (hi = switch_core_hash_first(event_hash)switch_core_hash_first_iter(event_hash, ((void*)0)); hi; hi = switch_core_hash_next(&hi)) {
2250 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &hash_val);
2251 event = (switch_event_t *)hash_val;
2252 switch_event_fire(&event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 2252, &event, ((void*)0)
)
;
2253 }
2254
2255 switch_core_hash_destroy(&event_hash);
2256
2257 /*
2258 To perevent locking.
2259 Core modules which may use databases should be pre-loaded here
2260 (databases are loaded already).
2261 */
2262#ifdef SWITCH_HAVE_YUV1
2263#ifdef SWITCH_HAVE_VPX1
2264 switch_loadable_module_load_module("", "CORE_VPX_MODULE", SWITCH_FALSE, &err);
2265#endif
2266#endif
2267
2268 /* Loading common modules */
2269 if ((xml = switch_xml_open_cfg(cf, &cfg, NULL((void*)0)))) {
2270 switch_xml_t mods, ld;
2271 if ((mods = switch_xml_child(cfg, "modules"))) {
2272 for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
2273 switch_bool_t global = SWITCH_FALSE;
2274 const char *val = switch_xml_attr_soft(ld, "module");
2275 const char *path = switch_xml_attr_soft(ld, "path");
2276 const char *critical = switch_xml_attr_soft(ld, "critical");
2277 const char *sglobal = switch_xml_attr_soft(ld, "global");
2278 if (zstr(val)_zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
2279 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2279, ((void*)0)
, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
2280 continue;
2281 }
2282 global = switch_true(sglobal);
2283
2284 if (path && zstr(path)_zstr(path)) {
2285 path = SWITCH_GLOBAL_dirs.mod_dir;
2286 }
2287 if (switch_loadable_module_load_module_ex(path, val, SWITCH_FALSE, global, &err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, NULL((void*)0)) == SWITCH_STATUS_GENERR) {
2288 if (critical && switch_true(critical)) {
2289 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2289, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val);
2290 abort();
2291 }
2292 }
2293 count++;
2294 }
2295 }
2296 switch_xml_free(xml);
2297
2298 } else {
2299 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2299, ((void*)0)
, SWITCH_LOG_CONSOLE, "open of %s failed\n", cf);
2300 }
2301
2302 if ((xml = switch_xml_open_cfg(pcf, &cfg, NULL((void*)0)))) {
2303 switch_xml_t mods, ld;
2304
2305 if ((mods = switch_xml_child(cfg, "modules"))) {
2306 for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
2307 switch_bool_t global = SWITCH_FALSE;
2308 const char *val = switch_xml_attr_soft(ld, "module");
2309 const char *path = switch_xml_attr_soft(ld, "path");
2310 const char *sglobal = switch_xml_attr_soft(ld, "global");
2311 if (zstr(val)_zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
2312 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2312, ((void*)0)
, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
2313 continue;
2314 }
2315 global = switch_true(sglobal);
2316
2317 if (path && zstr(path)_zstr(path)) {
2318 path = SWITCH_GLOBAL_dirs.mod_dir;
2319 }
2320 switch_loadable_module_load_module_ex(path, val, SWITCH_FALSE, global, &err, SWITCH_LOADABLE_MODULE_TYPE_POSTLOAD, NULL((void*)0));
2321 count++;
2322 }
2323 }
2324 switch_xml_free(xml);
2325
2326 } else {
2327 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2327, ((void*)0)
, SWITCH_LOG_CONSOLE, "open of %s failed\n", pcf);
2328 }
2329
2330 if (!count) {
2331 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2331, ((void*)0)
, SWITCH_LOG_CONSOLE, "No modules loaded, assuming 'load all'\n");
2332 all = 1;
2333 }
2334
2335 if (all) {
2336 if (apr_dir_open(&module_dir_handle, SWITCH_GLOBAL_dirs.mod_dir, loadable_modules.pool) != APR_SUCCESS0) {
2337 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2337, ((void*)0)
, SWITCH_LOG_CONSOLE, "Can't open directory: %s\n", SWITCH_GLOBAL_dirs.mod_dir);
2338 return SWITCH_STATUS_GENERR;
2339 }
2340
2341 while (apr_dir_read(&finfo, finfo_flags, module_dir_handle) == APR_SUCCESS0) {
2342 const char *fname = finfo.fname;
2343
2344 if (finfo.filetype != APR_REG) {
2345 continue;
2346 }
2347
2348 if (!fname) {
2349 fname = finfo.name;
2350 }
2351
2352 if (!fname) {
2353 continue;
2354 }
2355
2356 if (zstr(fname)_zstr(fname) || (!strstr(fname, ext) && !strstr(fname, EXT))) {
2357 continue;
2358 }
2359
2360 switch_loadable_module_load_module(SWITCH_GLOBAL_dirs.mod_dir, fname, SWITCH_FALSE, &err);
2361 }
2362 apr_dir_close(module_dir_handle);
2363 }
2364
2365 switch_loadable_module_runtime();
2366
2367 memset(&chat_globals, 0, sizeof(chat_globals));
2368 chat_globals.running = 1;
2369 chat_globals.pool = loadable_modules.pool;
2370 switch_mutex_init(&chat_globals.mutex, SWITCH_MUTEX_NESTED0x1, chat_globals.pool);
2371
2372 chat_thread_start(1);
2373
2374 return SWITCH_STATUS_SUCCESS;
2375}
2376
2377static switch_status_t do_shutdown(switch_loadable_module_t *module, switch_bool_t shutdown, switch_bool_t unload, switch_bool_t fail_if_busy,
2378 const char **err)
2379{
2380 int32_t flags = switch_core_flags();
2381 switch_assert(module != NULL)((module != ((void*)0)) ? (void) (0) : __assert_fail ("module != ((void*)0)"
, "src/switch_loadable_module.c", 2381, __extension__ __PRETTY_FUNCTION__
))
;
2382
2383 if (fail_if_busy && module->module_interface->rwlock && switch_thread_rwlock_trywrlock(module->module_interface->rwlock) != SWITCH_STATUS_SUCCESS) {
2384 if (err) {
2385 *err = "Module in use.";
2386 }
2387 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2387, ((void*)0)
, SWITCH_LOG_WARNING, "Module %s is in use, cannot unload.\n", module->module_interface->module_name);
2388 return SWITCH_STATUS_FALSE;
2389 }
2390
2391 module->shutting_down = SWITCH_TRUE;
2392
2393 if (shutdown) {
2394 switch_loadable_module_unprocess(module);
2395 if (module->switch_module_shutdown) {
2396 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2396, ((void*)0)
, SWITCH_LOG_CONSOLE, "Stopping: %s\n", module->module_interface->module_name);
2397 module->status = module->switch_module_shutdown();
2398 } else {
2399 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2399, ((void*)0)
, SWITCH_LOG_CONSOLE, "%s has no shutdown routine\n", module->module_interface->module_name);
2400 }
2401 }
2402
2403 if (fail_if_busy && module->module_interface->rwlock) {
2404 switch_thread_rwlock_unlock(module->module_interface->rwlock);
2405 }
2406
2407 if (unload && module->status != SWITCH_STATUS_NOUNLOAD && !(flags & SCF_VG)) {
2408 switch_memory_pool_t *pool;
2409 switch_status_t st;
2410
2411 if (module->thread) {
2412 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2412, ((void*)0)
, SWITCH_LOG_CONSOLE, "%s stopping runtime thread.\n", module->module_interface->module_name);
2413 switch_thread_join(&st, module->thread);
2414 }
2415
2416 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2416, ((void*)0)
, SWITCH_LOG_CONSOLE, "%s unloaded.\n", module->module_interface->module_name);
2417 switch_dso_destroy(&module->lib);
2418 if ((pool = module->pool)) {
2419 module = NULL((void*)0);
2420 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_loadable_module.c"
, (const char *)__func__, 2420)
;
2421 }
2422 }
2423
2424 return SWITCH_STATUS_SUCCESS;
2425
2426}
2427
2428SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_loadable_module_shutdown(void)
2429{
2430 switch_hash_index_t *hi;
2431 void *val;
2432 const void *key;
2433 switch_loadable_module_t *module;
2434 int i;
2435
2436 if (!loadable_modules.module_hash) {
2437 return;
2438 }
2439
2440 chat_globals.running = 0;
2441
2442 for (i = 0; i < chat_globals.msg_queue_len; i++) {
2443 switch_queue_push(chat_globals.msg_queue[i], NULL((void*)0));
2444 }
2445
2446 for (i = 0; i < chat_globals.msg_queue_len; i++) {
2447 switch_status_t st;
2448 switch_thread_join(&st, chat_globals.msg_queue_thread[i]);
2449 }
2450
2451
2452 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)) {
2453 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
2454 module = (switch_loadable_module_t *)val;
2455 if (module->type != SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
2456 do_shutdown(module, SWITCH_TRUE, SWITCH_FALSE, SWITCH_FALSE, NULL((void*)0));
2457 }
2458 }
2459
2460 switch_yield(1000000)switch_sleep(1000000);;
2461
2462 for (hi = switch_core_hash_first(loadable_modules.module_hash)switch_core_hash_first_iter(loadable_modules.module_hash, ((void
*)0))
; hi;) {
2463 switch_core_hash_this(hi, &key, NULL((void*)0), &val);
2464 module = (switch_loadable_module_t *)val;
2465
2466 hi = switch_core_hash_next(&hi);
2467
2468 if (module->type != SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
2469 if (do_shutdown(module, SWITCH_FALSE, SWITCH_TRUE, SWITCH_FALSE, NULL((void*)0)) == SWITCH_STATUS_SUCCESS)
2470 {
2471 switch_core_hash_delete(loadable_modules.module_hash, key);
2472 }
2473 }
2474 }
2475
2476 switch_core_sqldb_destroy();
2477
2478 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)) {
2479 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
2480 if ((module = (switch_loadable_module_t *)val)) {
2481 if (module->type == SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
2482 do_shutdown(module, SWITCH_TRUE, SWITCH_FALSE, SWITCH_FALSE, NULL((void*)0));
2483 }
2484 }
2485 }
2486
2487 switch_yield(1000000)switch_sleep(1000000);;
2488
2489 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)) {
2490 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
2491 if ((module = (switch_loadable_module_t *)val)) {
2492 if (module->type == SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
2493 do_shutdown(module, SWITCH_FALSE, SWITCH_TRUE, SWITCH_FALSE, NULL((void*)0));
2494 }
2495 }
2496 }
2497
2498 switch_core_hash_destroy(&loadable_modules.module_hash);
2499 switch_core_hash_destroy(&loadable_modules.endpoint_hash);
2500 switch_core_hash_destroy(&loadable_modules.codec_hash);
2501 switch_core_hash_destroy(&loadable_modules.timer_hash);
2502 switch_core_hash_destroy(&loadable_modules.application_hash);
2503 switch_core_hash_destroy(&loadable_modules.chat_application_hash);
2504 switch_core_hash_destroy(&loadable_modules.api_hash);
2505 switch_core_hash_destroy(&loadable_modules.json_api_hash);
2506 switch_core_hash_destroy(&loadable_modules.file_hash);
2507 switch_core_hash_destroy(&loadable_modules.speech_hash);
2508 switch_core_hash_destroy(&loadable_modules.asr_hash);
2509 switch_core_hash_destroy(&loadable_modules.directory_hash);
2510 switch_core_hash_destroy(&loadable_modules.chat_hash);
2511 switch_core_hash_destroy(&loadable_modules.say_hash);
2512 switch_core_hash_destroy(&loadable_modules.management_hash);
2513 switch_core_hash_destroy(&loadable_modules.limit_hash);
2514 switch_core_hash_destroy(&loadable_modules.database_hash);
2515 switch_core_hash_destroy(&loadable_modules.dialplan_hash);
2516 switch_core_hash_destroy(&loadable_modules.secondary_recover_hash);
2517
2518 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__
, 2518)
;
2519}
2520
2521SWITCH_DECLARE(switch_endpoint_interface_t *)__attribute__((visibility("default"))) switch_endpoint_interface_t
*
switch_loadable_module_get_endpoint_interface(const char *name)
2522{
2523 switch_endpoint_interface_t *ptr;
2524
2525 switch_mutex_lock(loadable_modules.mutex);
2526 ptr = switch_core_hash_find(loadable_modules.endpoint_hash, name);
2527 PROTECT_INTERFACE(ptr)if (ptr) {switch_thread_rwlock_rdlock(ptr->parent->rwlock
); switch_thread_rwlock_rdlock(ptr->rwlock); switch_mutex_lock
(ptr->reflock); ptr->refs++; ptr->parent->refs++;
switch_mutex_unlock(ptr->reflock);}
;
2528 switch_mutex_unlock(loadable_modules.mutex);
2529
2530
2531 return ptr;
2532}
2533
2534SWITCH_DECLARE(switch_file_interface_t *)__attribute__((visibility("default"))) switch_file_interface_t
*
switch_loadable_module_get_file_interface(const char *name, const char *modname)
2535{
2536 switch_file_interface_t *i = NULL((void*)0);
2537 switch_file_node_t *node, *head;
2538
2539 switch_mutex_lock(loadable_modules.mutex);
2540
2541 if ((head = switch_core_hash_find(loadable_modules.file_hash, name))) {
2542 if (modname) {
2543 for (node = head; node; node = node->next) {
2544 if (!strcasecmp(node->interface_name, modname)) {
2545 i = (switch_file_interface_t *) node->ptr;
2546 break;
2547 }
2548 }
2549 } else {
2550 i = (switch_file_interface_t *) head->ptr;
2551 }
2552 }
2553
2554 switch_mutex_unlock(loadable_modules.mutex);
2555
2556 if (i) PROTECT_INTERFACE(i)if (i) {switch_thread_rwlock_rdlock(i->parent->rwlock);
switch_thread_rwlock_rdlock(i->rwlock); switch_mutex_lock
(i->reflock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}
;
2557
2558 return i;
2559}
2560
2561SWITCH_DECLARE(switch_database_interface_t *)__attribute__((visibility("default"))) switch_database_interface_t
*
switch_loadable_module_get_database_interface(const char *name, const char *modname)
2562{
2563 switch_database_interface_t *i = NULL((void*)0);
2564 switch_database_node_t *node, *head;
2565
2566 switch_mutex_lock(loadable_modules.mutex);
2567
2568 if ((head = switch_core_hash_find(loadable_modules.database_hash, name))) {
2569 if (modname) {
2570 for (node = head; node; node = node->next) {
2571 if (!strcasecmp(node->interface_name, modname)) {
2572 i = (switch_database_interface_t *)node->ptr;
2573 break;
2574 }
2575 }
2576 }
2577 else {
2578 i = (switch_database_interface_t *)head->ptr;
2579 }
2580 }
2581
2582 switch_mutex_unlock(loadable_modules.mutex);
2583
2584 if (i) PROTECT_INTERFACE(i)if (i) {switch_thread_rwlock_rdlock(i->parent->rwlock);
switch_thread_rwlock_rdlock(i->rwlock); switch_mutex_lock
(i->reflock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}
;
2585
2586 return i;
2587}
2588
2589SWITCH_DECLARE(switch_codec_interface_t *)__attribute__((visibility("default"))) switch_codec_interface_t
*
switch_loadable_module_get_codec_interface(const char *name, const char *modname)
2590{
2591 switch_codec_interface_t *codec = NULL((void*)0);
2592 switch_codec_node_t *node, *head;
2593
2594 switch_mutex_lock(loadable_modules.mutex);
2595
2596 if ((head = switch_core_hash_find(loadable_modules.codec_hash, name))) {
2597 if (modname) {
2598 for (node = head; node; node = node->next) {
2599 if (!strcasecmp(node->interface_name, modname)) {
2600 codec = (switch_codec_interface_t *) node->ptr;
2601 break;
2602 }
2603 }
2604 } else {
2605 codec = (switch_codec_interface_t *) head->ptr;
2606 }
2607 }
2608
2609 switch_mutex_unlock(loadable_modules.mutex);
2610
2611 PROTECT_INTERFACE(codec)if (codec) {switch_thread_rwlock_rdlock(codec->parent->
rwlock); switch_thread_rwlock_rdlock(codec->rwlock); switch_mutex_lock
(codec->reflock); codec->refs++; codec->parent->refs
++; switch_mutex_unlock(codec->reflock);}
;
2612
2613 return codec;
2614}
2615
2616#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 = ((void*)0); if (loadable_modules
._kind__hash && (i = switch_core_hash_find_locked(loadable_modules
._kind__hash, name, loadable_modules.mutex))) { if (i) {switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); switch_mutex_lock(i->reflock); 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) \
2617 { \
2618 switch_##_kind_##_interface_t *i = NULL((void*)0); \
2619 if (loadable_modules._kind_##_hash && (i = switch_core_hash_find_locked(loadable_modules._kind_##_hash, name, loadable_modules.mutex))) { \
2620 PROTECT_INTERFACE(i)if (i) {switch_thread_rwlock_rdlock(i->parent->rwlock);
switch_thread_rwlock_rdlock(i->rwlock); switch_mutex_lock
(i->reflock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}
; \
2621 } \
2622 return i; \
2623 }
2624
2625HASH_FUNC(dialplan)__attribute__((visibility("default"))) switch_dialplan_interface_t
* switch_loadable_module_get_dialplan_interface(const char *
name) { switch_dialplan_interface_t *i = ((void*)0); if (loadable_modules
.dialplan_hash && (i = switch_core_hash_find_locked(loadable_modules
.dialplan_hash, name, loadable_modules.mutex))) { if (i) {switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); switch_mutex_lock(i->reflock); i->refs++; i->
parent->refs++; switch_mutex_unlock(i->reflock);}; } return
i; }
2626HASH_FUNC(timer)__attribute__((visibility("default"))) switch_timer_interface_t
* switch_loadable_module_get_timer_interface(const char *name
) { switch_timer_interface_t *i = ((void*)0); if (loadable_modules
.timer_hash && (i = switch_core_hash_find_locked(loadable_modules
.timer_hash, name, loadable_modules.mutex))) { if (i) {switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); switch_mutex_lock(i->reflock); i->refs++; i->
parent->refs++; switch_mutex_unlock(i->reflock);}; } return
i; }
2627HASH_FUNC(application)__attribute__((visibility("default"))) switch_application_interface_t
* switch_loadable_module_get_application_interface(const char
*name) { switch_application_interface_t *i = ((void*)0); if (
loadable_modules.application_hash && (i = switch_core_hash_find_locked
(loadable_modules.application_hash, name, loadable_modules.mutex
))) { if (i) {switch_thread_rwlock_rdlock(i->parent->rwlock
); switch_thread_rwlock_rdlock(i->rwlock); switch_mutex_lock
(i->reflock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2628HASH_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 = ((void
*)0); if (loadable_modules.chat_application_hash && (
i = switch_core_hash_find_locked(loadable_modules.chat_application_hash
, name, loadable_modules.mutex))) { if (i) {switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); switch_mutex_lock(i->reflock); i->refs++; i->
parent->refs++; switch_mutex_unlock(i->reflock);}; } return
i; }
2629HASH_FUNC(api)__attribute__((visibility("default"))) switch_api_interface_t
* switch_loadable_module_get_api_interface(const char *name)
{ switch_api_interface_t *i = ((void*)0); if (loadable_modules
.api_hash && (i = switch_core_hash_find_locked(loadable_modules
.api_hash, name, loadable_modules.mutex))) { if (i) {switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); switch_mutex_lock(i->reflock); i->refs++; i->
parent->refs++; switch_mutex_unlock(i->reflock);}; } return
i; }
2630HASH_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 = ((void*)0); if (loadable_modules
.json_api_hash && (i = switch_core_hash_find_locked(loadable_modules
.json_api_hash, name, loadable_modules.mutex))) { if (i) {switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); switch_mutex_lock(i->reflock); i->refs++; i->
parent->refs++; switch_mutex_unlock(i->reflock);}; } return
i; }
2631HASH_FUNC(speech)__attribute__((visibility("default"))) switch_speech_interface_t
* switch_loadable_module_get_speech_interface(const char *name
) { switch_speech_interface_t *i = ((void*)0); if (loadable_modules
.speech_hash && (i = switch_core_hash_find_locked(loadable_modules
.speech_hash, name, loadable_modules.mutex))) { if (i) {switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); switch_mutex_lock(i->reflock); i->refs++; i->
parent->refs++; switch_mutex_unlock(i->reflock);}; } return
i; }
2632HASH_FUNC(asr)__attribute__((visibility("default"))) switch_asr_interface_t
* switch_loadable_module_get_asr_interface(const char *name)
{ switch_asr_interface_t *i = ((void*)0); if (loadable_modules
.asr_hash && (i = switch_core_hash_find_locked(loadable_modules
.asr_hash, name, loadable_modules.mutex))) { if (i) {switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); switch_mutex_lock(i->reflock); i->refs++; i->
parent->refs++; switch_mutex_unlock(i->reflock);}; } return
i; }
2633HASH_FUNC(directory)__attribute__((visibility("default"))) switch_directory_interface_t
* switch_loadable_module_get_directory_interface(const char *
name) { switch_directory_interface_t *i = ((void*)0); if (loadable_modules
.directory_hash && (i = switch_core_hash_find_locked(
loadable_modules.directory_hash, name, loadable_modules.mutex
))) { if (i) {switch_thread_rwlock_rdlock(i->parent->rwlock
); switch_thread_rwlock_rdlock(i->rwlock); switch_mutex_lock
(i->reflock); i->refs++; i->parent->refs++; switch_mutex_unlock
(i->reflock);}; } return i; }
2634HASH_FUNC(chat)__attribute__((visibility("default"))) switch_chat_interface_t
* switch_loadable_module_get_chat_interface(const char *name
) { switch_chat_interface_t *i = ((void*)0); if (loadable_modules
.chat_hash && (i = switch_core_hash_find_locked(loadable_modules
.chat_hash, name, loadable_modules.mutex))) { if (i) {switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); switch_mutex_lock(i->reflock); i->refs++; i->
parent->refs++; switch_mutex_unlock(i->reflock);}; } return
i; }
2635HASH_FUNC(limit)__attribute__((visibility("default"))) switch_limit_interface_t
* switch_loadable_module_get_limit_interface(const char *name
) { switch_limit_interface_t *i = ((void*)0); if (loadable_modules
.limit_hash && (i = switch_core_hash_find_locked(loadable_modules
.limit_hash, name, loadable_modules.mutex))) { if (i) {switch_thread_rwlock_rdlock
(i->parent->rwlock); switch_thread_rwlock_rdlock(i->
rwlock); switch_mutex_lock(i->reflock); i->refs++; i->
parent->refs++; switch_mutex_unlock(i->reflock);}; } return
i; }
2636
2637
2638SWITCH_DECLARE(switch_say_interface_t *)__attribute__((visibility("default"))) switch_say_interface_t
*
switch_loadable_module_get_say_interface(const char *name)
2639{
2640 return switch_core_hash_find_locked(loadable_modules.say_hash, name, loadable_modules.mutex);
2641}
2642
2643SWITCH_DECLARE(switch_management_interface_t *)__attribute__((visibility("default"))) switch_management_interface_t
*
switch_loadable_module_get_management_interface(const char *relative_oid)
2644{
2645 return switch_core_hash_find_locked(loadable_modules.management_hash, relative_oid, loadable_modules.mutex);
2646}
2647
2648#ifdef DEBUG_CODEC_SORTING
2649static void do_print(const switch_codec_implementation_t **array, int arraylen)
2650{
2651 int i;
2652
2653 for(i = 0; i < arraylen; i++) {
2654 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2654, ((void*)0)
, SWITCH_LOG_ERROR,
2655 "DEBUG %d %s:%d %d\n", i, array[i]->iananame, array[i]->ianacode, array[i]->microseconds_per_packet / 1000);
2656 }
2657
2658}
2659#endif
2660
2661/* helper only -- bounds checking enforced by caller */
2662static void do_swap(const switch_codec_implementation_t **array, int a, int b)
2663{
2664 const switch_codec_implementation_t *tmp = array[b];
2665 array[b] = array[a];
2666 array[a] = tmp;
2667}
2668
2669static void switch_loadable_module_sort_codecs(const switch_codec_implementation_t **array, int arraylen)
2670{
2671 int i = 0, sorted_ptime = 0;
2672
2673#ifdef DEBUG_CODEC_SORTING
2674 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2674, ((void*)0)
, SWITCH_LOG_ERROR, "--BEFORE\n");
2675 do_print(array, arraylen);
2676 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2676, ((void*)0)
, SWITCH_LOG_ERROR, "--BEFORE\n");
2677#endif
2678
2679 for (i = 0; i < arraylen; i++) {
2680 int this_ptime;
2681
2682 if (!array[i]) {
2683 continue;
2684 }
2685
2686 this_ptime = array[i]->microseconds_per_packet / 1000;
2687
2688 if (!strcasecmp(array[i]->iananame, "ilbc")) {
2689 this_ptime = 20;
2690 }
2691
2692 if (!sorted_ptime) {
2693 sorted_ptime = this_ptime;
2694#ifdef DEBUG_CODEC_SORTING
2695 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2695, ((void*)0)
, SWITCH_LOG_ERROR, "sorted1 = %d\n", sorted_ptime);
2696#endif
2697 }
2698
2699 if (i > 0 && array[i-1] && strcasecmp(array[i]->iananame, array[i-1]->iananame) && this_ptime != sorted_ptime) {
2700 int j;
2701 int swapped = 0;
2702
2703#ifdef DEBUG_CODEC_SORTING
2704 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2704, ((void*)0)
, SWITCH_LOG_ERROR, "%d != %d\n", this_ptime, sorted_ptime);
2705#endif
2706 for(j = i; j < arraylen; j++) {
2707 int check_ptime = array[j]->microseconds_per_packet / 1000;
2708
2709 if (!strcasecmp(array[i]->iananame, "ilbc")) {
2710 check_ptime = 20;
2711 }
2712
2713 if (check_ptime == sorted_ptime) {
2714#ifdef DEBUG_CODEC_SORTING
2715 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2715, ((void*)0)
, SWITCH_LOG_ERROR, "swap %d %d ptime %d\n", i, j, check_ptime);
2716#endif
2717 do_swap(array, i, j);
2718 swapped = 1;
2719 break;
2720 }
2721 }
2722
2723 if (!swapped) {
2724 sorted_ptime = this_ptime;
2725#ifdef DEBUG_CODEC_SORTING
2726 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2726, ((void*)0)
, SWITCH_LOG_ERROR, "sorted2 = %d\n", sorted_ptime);
2727#endif
2728 }
2729 }
2730 }
2731
2732#ifdef DEBUG_CODEC_SORTING
2733 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2733, ((void*)0)
, SWITCH_LOG_ERROR, "--AFTER\n");
2734 do_print(array, arraylen);
2735 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2735, ((void*)0)
, SWITCH_LOG_ERROR, "--AFTER\n");
2736#endif
2737
2738}
2739
2740
2741SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_loadable_module_get_codecs(const switch_codec_implementation_t **array, int arraylen)
2742{
2743 switch_hash_index_t *hi;
2744 void *val;
2745 switch_codec_interface_t *codec_interface;
2746 int i = 0;
2747 const switch_codec_implementation_t *imp;
2748 switch_codec_node_t *node, *head;
2749
2750 switch_mutex_lock(loadable_modules.mutex);
2751 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)) {
2752 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
2753 head = (switch_codec_node_t *) val;
2754
2755 for (node = head; node; node = node->next) {
2756 codec_interface = (switch_codec_interface_t *) node->ptr;
2757
2758 /* Look for the default ptime of the codec because it's the safest choice */
2759 for (imp = codec_interface->implementations; imp; imp = imp->next) {
2760 uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode);
2761
2762 if (imp->microseconds_per_packet / 1000 == (int)default_ptime) {
2763 array[i++] = imp;
2764 goto found;
2765 }
2766 }
2767 /* oh well we will use what we have */
2768 array[i++] = codec_interface->implementations;
2769 }
2770
2771 found:
2772
2773 if (i > arraylen) {
2774 break;
2775 }
2776
2777 }
2778 switch_safe_free(hi)if (hi) {free(hi);hi=((void*)0);};
2779
2780 switch_mutex_unlock(loadable_modules.mutex);
2781
2782 switch_loadable_module_sort_codecs(array, i);
2783
2784 return i;
2785
2786}
2787
2788SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_parse_codec_buf(char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit, uint32_t *channels, char **modname, char **fmtp)
2789{
2790 char *cur, *next = NULL((void*)0), *name, *p;
2791
2792 name = next = cur = buf;
2793
2794 *channels = 1;
2795
2796 for (;;) {
2797 if (!next) {
2798 break;
2799 }
2800
2801 if ((p = strchr(next, '@'))) {
2802 *p++ = '\0';
2803 }
2804 next = p;
2805
2806 if (cur != name) {
2807 if (strchr(cur, 'i')) {
2808 *interval = atoi(cur);
2809 } else if ((strchr(cur, 'k') || strchr(cur, 'h'))) {
2810 *rate = atoi(cur);
2811 } else if (strchr(cur, 'b')) {
2812 *bit = atoi(cur);
2813 } else if (strchr(cur, 'c')) {
2814 *channels = atoi(cur);
2815 } else {
2816 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 2816, ((void*)0)
, SWITCH_LOG_ERROR, "Bad syntax for codec string. Missing qualifier [h|k|i|b|c] for part [%s]!\n", cur);
2817 }
2818 }
2819 cur = next;
2820 }
2821
2822 if ((p = strchr(name, '.'))) {
2823 *p++ = '\0';
2824 *modname = name;
2825 name = p;
2826 }
2827
2828 if ((p = strchr(name, '~'))) {
2829 *p++ = '\0';
2830 if (fmtp) {
2831 *fmtp = p;
2832 }
2833 }
2834
2835 return name;
2836}
2837
2838SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, char fmtp_array[SWITCH_MAX_CODECS50][MAX_FMTP_LEN256], int arraylen, char **prefs, int preflen)
2839{
2840 int x, i = 0, j = 0;
2841 switch_codec_interface_t *codec_interface;
2842 const switch_codec_implementation_t *imp;
2843
2844 switch_mutex_lock(loadable_modules.mutex);
2845
2846 for (x = 0; x < preflen; x++) {
2847 char *name, buf[256], jbuf[256], *modname = NULL((void*)0), *fmtp = NULL((void*)0);
2848 uint32_t interval = 0, rate = 0, bit = 0, channels = 1;
2849
2850 switch_copy_string(buf, prefs[x], sizeof(buf));
2851 name = switch_parse_codec_buf(buf, &interval, &rate, &bit, &channels, &modname, &fmtp);
2852
2853 for(j = 0; j < x; j++) {
2854 char *jname, *jmodname = NULL((void*)0), *jfmtp = NULL((void*)0);
2855 uint32_t jinterval = 0, jrate = 0, jbit = 0, jchannels = 1;
2856 uint32_t ointerval = interval, orate = rate, ochannels = channels;
2857
2858 if (ointerval == 0) {
2859 ointerval = switch_default_ptime(name, 0);
2860 }
2861
2862 if (orate == 0) {
2863 orate = switch_default_rate(name, 0);
2864 }
2865
2866 if (ochannels == 0) {
2867 ochannels = 1;
2868 }
2869
2870 switch_copy_string(jbuf, prefs[j], sizeof(jbuf));
2871 jname = switch_parse_codec_buf(jbuf, &jinterval, &jrate, &jbit, &jchannels, &jmodname, &jfmtp);
2872
2873 if (jinterval == 0) {
2874 jinterval = switch_default_ptime(jname, 0);
2875 }
2876
2877 if (jrate == 0) {
2878 jrate = switch_default_rate(jname, 0);
2879 }
2880
2881 if (jchannels == 0) {
2882 jchannels = 1;
2883 }
2884
2885 if (!strcasecmp(name, jname) && ointerval == jinterval && orate == jrate && ochannels == jchannels &&
2886 !strcasecmp(switch_str_nil(fmtp)(fmtp ? fmtp : ""), switch_str_nil(jfmtp)(jfmtp ? jfmtp : ""))) {
2887 goto next_x;
2888 }
2889 }
2890
2891 if ((codec_interface = switch_loadable_module_get_codec_interface(name, modname)) != 0) {
2892 /* If no specific codec interval is requested opt for the default above all else because lots of stuff assumes it */
2893 for (imp = codec_interface->implementations; imp; imp = imp->next) {
2894 uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode);
2895 uint32_t default_rate = switch_default_rate(imp->iananame, imp->ianacode);
2896
2897 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
2898 uint32_t crate = !strcasecmp(imp->iananame, "g722") ? imp->samples_per_second : imp->actual_samples_per_second;
2899
2900 if ((!interval && (uint32_t) (imp->microseconds_per_packet / 1000) != default_ptime) ||
2901 (interval && (uint32_t) (imp->microseconds_per_packet / 1000) != interval)) {
2902 continue;
2903 }
2904
2905 if (((!rate && crate != default_rate) || (rate && (uint32_t) imp->actual_samples_per_second != rate))) {
2906 continue;
2907 }
2908
2909 if (bit && (uint32_t) imp->bits_per_second != bit) {
2910 continue;
2911 }
2912
2913 if (channels && imp->number_of_channels != channels) {
2914 continue;
2915 }
2916 }
2917
2918 if (!zstr(fmtp)_zstr(fmtp)) {
2919 switch_set_string(fmtp_array[i], fmtp)switch_copy_string(fmtp_array[i], fmtp, sizeof(fmtp_array[i])
)
;
2920 }
2921 array[i++] = imp;
2922 goto found;
2923
2924 }
2925
2926 /* Either looking for a specific interval or there was no interval specified and there wasn't one at the default ptime available */
2927 for (imp = codec_interface->implementations; imp; imp = imp->next) {
2928 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
2929 uint32_t crate = !strcasecmp(imp->iananame, "g722") ? imp->samples_per_second : imp->actual_samples_per_second;
2930
2931 if (interval && (uint32_t) (imp->microseconds_per_packet / 1000) != interval) {
2932 continue;
2933 }
2934
2935 if (rate && (uint32_t) crate != rate) {
2936 continue;
2937 }
2938
2939 if (bit && (uint32_t) imp->bits_per_second != bit) {
2940 continue;
2941 }
2942
2943 if (channels && imp->number_of_channels != channels) {
2944 continue;
2945 }
2946 }
2947
2948 array[i++] = imp;
2949 goto found;
2950
2951 }
2952
2953 found:
2954
2955 UNPROTECT_INTERFACE(codec_interface)if (codec_interface) {switch_mutex_lock(codec_interface->reflock
); codec_interface->refs--; codec_interface->parent->
refs--; switch_mutex_unlock(codec_interface->reflock); switch_thread_rwlock_unlock
(codec_interface->rwlock); switch_thread_rwlock_unlock(codec_interface
->parent->rwlock);}
;
2956
2957 if (i > arraylen) {
2958 break;
2959 }
2960
2961 }
2962
2963 next_x:
2964
2965 continue;
2966 }
2967
2968 switch_mutex_unlock(loadable_modules.mutex);
2969
2970 switch_loadable_module_sort_codecs(array, i);
2971
2972 return i;
2973}
2974
2975SWITCH_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)
2976{
2977 switch_api_interface_t *api;
2978 switch_status_t status;
2979 char *arg_used;
2980 char *cmd_used;
2981
2982 switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)"
, "src/switch_loadable_module.c", 2982, __extension__ __PRETTY_FUNCTION__
))
;
2983 switch_assert(stream->data != NULL)((stream->data != ((void*)0)) ? (void) (0) : __assert_fail
("stream->data != ((void*)0)", "src/switch_loadable_module.c"
, 2983, __extension__ __PRETTY_FUNCTION__))
;
2984 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"
, 2984, __extension__ __PRETTY_FUNCTION__))
;
2985
2986 if (strcasecmp(cmd, "console_complete")) {
2987 cmd_used = switch_strip_whitespace(cmd);
2988 arg_used = switch_strip_whitespace(arg);
2989 } else {
2990 cmd_used = (char *) cmd;
2991 arg_used = (char *) arg;
2992 }
2993
2994
2995 if (!stream->param_event) {
2996 switch_event_create(&stream->param_event, SWITCH_EVENT_API)switch_event_create_subclass_detailed("src/switch_loadable_module.c"
, (const char * )(const char *)__func__, 2996, &stream->
param_event, SWITCH_EVENT_API, ((void*)0))
;
2997 }
2998
2999 if (stream->param_event) {
3000 if (cmd_used && *cmd_used) {
3001 switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command", cmd_used);
3002 }
3003 if (arg_used && *arg_used) {
3004 switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command-Argument", arg_used);
3005 }
3006 }
3007
3008
3009 if (cmd_used && (api = switch_loadable_module_get_api_interface(cmd_used)) != 0) {
3010 if ((status = api->function(arg_used, session, stream)) != SWITCH_STATUS_SUCCESS) {
3011 stream->write_function(stream, "COMMAND RETURNED ERROR!\n");
3012 }
3013 UNPROTECT_INTERFACE(api)if (api) {switch_mutex_lock(api->reflock); api->refs--;
api->parent->refs--; switch_mutex_unlock(api->reflock
); switch_thread_rwlock_unlock(api->rwlock); switch_thread_rwlock_unlock
(api->parent->rwlock);}
;
3014 } else {
3015 status = SWITCH_STATUS_FALSE;
3016 stream->write_function(stream, "INVALID COMMAND!\n");
3017 }
3018
3019 if (stream->param_event) {
3020 switch_event_fire(&stream->param_event)switch_event_fire_detailed("src/switch_loadable_module.c", (const
char * )(const char *)__func__, 3020, &stream->param_event
, ((void*)0))
;
3021 }
3022
3023 if (cmd_used != cmd) {
3024 switch_safe_free(cmd_used)if (cmd_used) {free(cmd_used);cmd_used=((void*)0);};
3025 }
3026
3027 if (arg_used != arg) {
3028 switch_safe_free(arg_used)if (arg_used) {free(arg_used);arg_used=((void*)0);};
3029 }
3030
3031 return status;
3032}
3033
3034SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_json_api_execute(cJSON *json, switch_core_session_t *session, cJSON **retval)
3035{
3036 switch_json_api_interface_t *json_api;
3037 switch_status_t status;
3038 cJSON *function, *json_reply = NULL((void*)0);
3039
3040 switch_assert(json)((json) ? (void) (0) : __assert_fail ("json", "src/switch_loadable_module.c"
, 3040, __extension__ __PRETTY_FUNCTION__))
;
3041
3042 function = cJSON_GetObjectItem(json, "command");
3043
3044 if (function && function->valuestring
3045 && cJSON_GetObjectItem(json, "data") && (json_api = switch_loadable_module_get_json_api_interface(function->valuestring)) != 0) {
3046 if ((status = json_api->function(json, session, &json_reply)) != SWITCH_STATUS_SUCCESS) {
3047 cJSON_AddItemToObject(json, "status", cJSON_CreateString("error"));
3048 cJSON_AddItemToObject(json, "message", cJSON_CreateString("The command returned an error"));
3049 } else {
3050 cJSON_AddItemToObject(json, "status", cJSON_CreateString("success"));
3051 }
3052
3053 if (!json_reply) {
3054 json_reply = cJSON_CreateNull();
3055 }
3056
3057 if (retval) {
3058 *retval = json_reply;
3059 } else {
3060 cJSON_AddItemToObject(json, "response", json_reply);
3061 }
3062
3063 UNPROTECT_INTERFACE(json_api)if (json_api) {switch_mutex_lock(json_api->reflock); json_api
->refs--; json_api->parent->refs--; switch_mutex_unlock
(json_api->reflock); switch_thread_rwlock_unlock(json_api->
rwlock); switch_thread_rwlock_unlock(json_api->parent->
rwlock);}
;
3064 } else {
3065 status = SWITCH_STATUS_FALSE;
3066 cJSON_AddItemToObject(json, "status", cJSON_CreateString("error"));
3067 cJSON_AddItemToObject(json, "message", cJSON_CreateString("Invalid request or non-existant command"));
3068 cJSON_AddItemToObject(json, "response", cJSON_CreateNull());
3069 }
3070
3071 return status;
3072}
3073
3074
3075SWITCH_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)
3076{
3077 switch_loadable_module_interface_t *mod;
3078
3079 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__, 3079
)
;
3080 switch_assert(mod != NULL)((mod != ((void*)0)) ? (void) (0) : __assert_fail ("mod != ((void*)0)"
, "src/switch_loadable_module.c", 3080, __extension__ __PRETTY_FUNCTION__
))
;
3081
3082 mod->pool = pool;
3083
3084 mod->module_name = switch_core_strdup(mod->pool, name)switch_core_perform_strdup(mod->pool, name, "src/switch_loadable_module.c"
, (const char *)__func__, 3084)
;
3085 switch_thread_rwlock_create(&mod->rwlock, mod->pool);
3086 return mod;
3087}
3088
3089#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__, 3089); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3089, __extension__ __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; }
{ \
3090 switch_##_TYPE_##_interface_t *i, *ptr; \
3091 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__, 3091)
; \
3092 switch_assert(i != NULL)((i != ((void*)0)) ? (void) (0) : __assert_fail ("i != ((void*)0)"
, "src/switch_loadable_module.c", 3092, __extension__ __PRETTY_FUNCTION__
))
; \
3093 for (ptr = mod->_TYPE_##_interface; ptr && ptr->next; ptr = ptr->next); \
3094 if (ptr) { \
3095 ptr->next = i; \
3096 } else { \
3097 mod->_TYPE_##_interface = i; \
3098 } \
3099 switch_thread_rwlock_create(&i->rwlock, mod->pool); \
3100 switch_mutex_init(&i->reflock, SWITCH_MUTEX_NESTED0x1, mod->pool); \
3101 i->parent = mod; \
3102 return i; }
3103
3104
3105SWITCH_DECLARE(void *)__attribute__((visibility("default"))) void * switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, switch_module_interface_name_t iname)
3106{
3107
3108 switch (iname) {
3109 case SWITCH_ENDPOINT_INTERFACE:
3110 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__, 3110); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3110, __extension__ __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; }
3111
3112 case SWITCH_TIMER_INTERFACE:
3113 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__, 3113); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3113, __extension__ __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; }
3114
3115 case SWITCH_DIALPLAN_INTERFACE:
3116 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__, 3116); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3116, __extension__ __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; }
3117
3118 case SWITCH_CODEC_INTERFACE:
3119 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__, 3119); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3119, __extension__ __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; }
3120
3121 case SWITCH_APPLICATION_INTERFACE:
3122 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__, 3122); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3122, __extension__ __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; }
3123
3124 case SWITCH_CHAT_APPLICATION_INTERFACE:
3125 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__, 3125); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3125, __extension__ __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; }
3126
3127 case SWITCH_API_INTERFACE:
3128 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__, 3128); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3128, __extension__ __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; }
3129
3130 case SWITCH_JSON_API_INTERFACE:
3131 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__, 3131); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3131, __extension__ __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; }
3132
3133 case SWITCH_FILE_INTERFACE:
3134 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__, 3134); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3134, __extension__ __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; }
3135
3136 case SWITCH_SPEECH_INTERFACE:
3137 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__, 3137); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3137, __extension__ __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; }
3138
3139 case SWITCH_DIRECTORY_INTERFACE:
3140 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__, 3140); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3140, __extension__ __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; }
3141
3142 case SWITCH_CHAT_INTERFACE:
3143 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__, 3143); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3143, __extension__ __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; }
3144
3145 case SWITCH_SAY_INTERFACE:
3146 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__, 3146); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3146, __extension__ __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; }
3147
3148 case SWITCH_ASR_INTERFACE:
3149 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__, 3149); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3149, __extension__ __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; }
3150
3151 case SWITCH_MANAGEMENT_INTERFACE:
3152 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__, 3152); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3152, __extension__ __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; }
3153
3154 case SWITCH_LIMIT_INTERFACE:
3155 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__, 3155); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3155, __extension__ __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; }
3156
3157 case SWITCH_DATABASE_INTERFACE:
3158 ALLOC_INTERFACE(database){ switch_database_interface_t *i, *ptr; i = switch_core_perform_alloc
(mod->pool, sizeof(switch_database_interface_t), "src/switch_loadable_module.c"
, (const char *)__func__, 3158); ((i != ((void*)0)) ? (void) (
0) : __assert_fail ("i != ((void*)0)", "src/switch_loadable_module.c"
, 3158, __extension__ __PRETTY_FUNCTION__)); for (ptr = mod->
database_interface; ptr && ptr->next; ptr = ptr->
next); if (ptr) { ptr->next = i; } else { mod->database_interface
= i; } switch_thread_rwlock_create(&i->rwlock, mod->
pool); switch_mutex_init(&i->reflock, 0x1, mod->pool
); i->parent = mod; return i; }
3159
3160 default:
3161 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_loadable_module.c", (const
char *)__func__, 3161, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid Module Type!\n");
3162 return NULL((void*)0);
3163 }
3164}
3165
3166struct switch_say_file_handle {
3167 char *ext;
3168 int cnt;
3169 struct switch_stream_handle stream;
3170 switch_event_t *param_event;
3171};
3172
3173SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_say_file_handle_get_variable(switch_say_file_handle_t *sh, const char *var)
3174{
3175 char *ret = NULL((void*)0);
3176
3177 if (sh->param_event) {
3178 ret = switch_event_get_header(sh->param_event, var)switch_event_get_header_idx(sh->param_event, var, -1);
3179 }
3180
3181 return ret;
3182
3183}
3184
3185SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_say_file_handle_get_path(switch_say_file_handle_t *sh)
3186{
3187 return (char *) sh->stream.data;
3188}
3189
3190SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_say_file_handle_detach_path(switch_say_file_handle_t *sh)
3191{
3192 char *path;
3193
3194 switch_assert(sh)((sh) ? (void) (0) : __assert_fail ("sh", "src/switch_loadable_module.c"
, 3194, __extension__ __PRETTY_FUNCTION__))
;
3195 path = (char *) sh->stream.data;
3196 sh->stream.data = NULL((void*)0);
3197 return path;
3198}
3199
3200
3201SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_say_file_handle_destroy(switch_say_file_handle_t **sh)
3202{
3203 switch_assert(sh)((sh) ? (void) (0) : __assert_fail ("sh", "src/switch_loadable_module.c"
, 3203, __extension__ __PRETTY_FUNCTION__))
;
3204
3205 switch_safe_free((*sh)->stream.data)if ((*sh)->stream.data) {free((*sh)->stream.data);(*sh)
->stream.data=((void*)0);}
;
3206 switch_safe_free((*sh)->ext)if ((*sh)->ext) {free((*sh)->ext);(*sh)->ext=((void*
)0);}
;
3207
3208 if ((*sh)->param_event) {
3209 switch_event_destroy(&(*sh)->param_event);
3210 }
3211 free(*sh);
3212 *sh = NULL((void*)0);
3213}
3214
3215SWITCH_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)
3216{
3217 switch_assert(sh)((sh) ? (void) (0) : __assert_fail ("sh", "src/switch_loadable_module.c"
, 3217, __extension__ __PRETTY_FUNCTION__))
;
3218
3219 if (zstr(ext)_zstr(ext)) {
3220 ext = "wav";
3221 }
3222
3223 *sh = malloc(sizeof(**sh));
3224 memset(*sh, 0, sizeof(**sh));
3225
3226 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"
, 3226, __extension__ __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
;
3227
3228 if (var_event) {
3229 (*sh)->param_event = *var_event;
3230 *var_event = NULL((void*)0);
3231 }
3232
3233 (*sh)->ext = strdup(ext);
3234
3235 return SWITCH_STATUS_SUCCESS;
3236}
3237
3238SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_say_file(switch_say_file_handle_t *sh, const char *fmt, ...)
3239{
3240 char buf[256] = "";
3241 int ret;
3242 va_list ap;
3243
3244 va_start(ap, fmt)__builtin_va_start(ap, fmt);
3245
3246 if ((ret = switch_vsnprintf(buf, sizeof(buf), fmt, ap)) > 0) {
3247 if (!sh->cnt++) {
3248 sh->stream.write_function(&sh->stream, "file_string://%s.%s", buf, sh->ext);
3249 } else if (strstr(buf, "://")) {
3250 sh->stream.write_function(&sh->stream, "!%s", buf);
3251 } else {
3252 sh->stream.write_function(&sh->stream, "!%s.%s", buf, sh->ext);
3253 }
3254
3255 }
3256
3257 va_end(ap)__builtin_va_end(ap);
3258}
3259
3260SWITCH_DECLARE(switch_core_recover_callback_t)__attribute__((visibility("default"))) switch_core_recover_callback_t switch_core_get_secondary_recover_callback(const char *key)
3261{
3262 switch_core_recover_callback_t cb;
3263
3264 switch_mutex_lock(loadable_modules.mutex);
3265 cb = (switch_core_recover_callback_t) (intptr_t) switch_core_hash_find(loadable_modules.secondary_recover_hash, key);
3266 switch_mutex_unlock(loadable_modules.mutex);
3267
3268 return cb;
3269}
3270
3271
3272SWITCH_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)
3273{
3274 switch_status_t status = SWITCH_STATUS_SUCCESS;
3275
3276 switch_assert(cb)((cb) ? (void) (0) : __assert_fail ("cb", "src/switch_loadable_module.c"
, 3276, __extension__ __PRETTY_FUNCTION__))
;
3277
3278 switch_mutex_lock(loadable_modules.mutex);
3279 if (switch_core_hash_find(loadable_modules.secondary_recover_hash, key)) {
3280 status = SWITCH_STATUS_FALSE;
3281 } else {
3282 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))
;
3283 }
3284 switch_mutex_unlock(loadable_modules.mutex);
3285
3286 return status;
3287}
3288
3289
3290SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_unregister_secondary_recover_callback(const char *key)
3291{
3292 switch_mutex_lock(loadable_modules.mutex);
3293 switch_core_hash_delete(loadable_modules.secondary_recover_hash, key);
3294 switch_mutex_unlock(loadable_modules.mutex);
3295}
3296
3297
3298/* For Emacs:
3299 * Local Variables:
3300 * mode:c
3301 * indent-tabs-mode:t
3302 * tab-width:4
3303 * c-basic-offset:4
3304 * End:
3305 * For VIM:
3306 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3307 */