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