RTS API Documentation  1.10.11
switch_loadable_module.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  * Seven Du <dujinfang@gmail.com>
28  * Andrey Volk <andywolk@gmail.com>
29  *
30  * switch_loadable_module.c -- Loadable Modules
31  *
32  */
33 
34 #include <switch.h>
36 
37 /* for fspr_pstrcat */
38 #include <fspr_strings.h>
39 
40 /* for fspr_env_get and fspr_env_set */
41 #include <fspr_env.h>
42 
43 /* for fspr file and directory handling */
44 #include <fspr_file_io.h>
45 
46 typedef struct switch_file_node_s {
48  const char *interface_name;
51 
52 typedef struct switch_database_node_s {
54  const char *interface_name;
57 
58 typedef struct switch_codec_node_s {
60  const char *interface_name;
63 
64 
66  char *key;
67  char *filename;
68  int perm;
71  switch_module_load_t switch_module_load;
72  switch_module_runtime_t switch_module_runtime;
73  switch_module_shutdown_t switch_module_shutdown;
79 };
80 
104 };
105 
108  const char **err);
109 static switch_status_t switch_loadable_module_load_module_ex(const char *dir, const char *fname, switch_bool_t runtime, switch_bool_t global, const char **err, switch_loadable_module_type_t type, switch_hash_t *event_hash);
110 
112 {
113 
114 
117  switch_loadable_module_t *module = ts->objs[0];
118 
119  switch_assert(thread != NULL);
120  switch_assert(module != NULL);
121 
122  while (status != SWITCH_STATUS_TERM && !module->shutting_down) {
123  status = module->switch_module_runtime();
124  }
126 
127  if (ts->pool) {
129  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Destroying Pool for %s\n", module->module_interface->module_name);
131  }
132  switch_thread_exit(thread, 0);
133  return NULL;
134 }
135 
136 
138 {
140  void *val;
141  switch_loadable_module_t *module;
142 
145  switch_core_hash_this(hi, NULL, NULL, &val);
146  module = (switch_loadable_module_t *) val;
147 
148  if (module->switch_module_runtime) {
149  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Starting runtime thread for %s\n", module->module_interface->module_name);
151  }
152  }
154 }
155 
157 {
158  switch_event_t *event;
159  int added = 0;
160 
161  new_module->key = switch_core_strdup(new_module->pool, key);
162 
165 
166  if (new_module->module_interface->endpoint_interface) {
168  for (ptr = new_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
169  if (!ptr->interface_name) {
170  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load endpoint interface from %s due to no interface name.\n", key);
171  } else {
172  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Endpoint '%s'\n", ptr->interface_name);
175  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "endpoint");
176  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
177  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
178  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
179 
180  if (!event_hash) {
181  switch_event_fire(&event);
182  } else {
183  switch_core_hash_insert_pointer(event_hash, (const void*)event);
184  }
185 
186  added++;
187  }
188  }
189  }
190  }
191 
192  if (new_module->module_interface->codec_interface) {
193  const switch_codec_implementation_t *impl;
195 
196  for (ptr = new_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
197  if (!ptr->interface_name) {
198  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load codec interface from %s due to no interface name.\n", key);
199  } else {
200  unsigned load_interface = 1;
201  switch_codec_node_t *node, *head;
202 
203  for (impl = ptr->implementations; impl; impl = impl->next) {
204  if (!impl->iananame) {
205  load_interface = 0;
207  "Failed to load codec interface %s from %s due to no iana name in an implementation.\n", ptr->interface_name,
208  key);
209  break;
210  }
212  load_interface = 0;
214  "Failed to load codec interface %s from %s due to bytes per frame %d exceeding buffer size %d.\n",
215  ptr->interface_name,
217  break;
218  }
219  }
220  if (load_interface) {
221  for (impl = ptr->implementations; impl; impl = impl->next) {
222  if (impl->bits_per_second) {
224  "Adding Codec %s %d %s %dhz %dms %dch %dbps\n",
225  impl->iananame, impl->ianacode,
227  impl->microseconds_per_packet / 1000, impl->number_of_channels, impl->bits_per_second);
228  } else {
230  "Adding Codec %s %d %s %dhz %dms %dch (VBR)\n",
231  impl->iananame, impl->ianacode,
233  }
234 
235  node = switch_core_alloc(new_module->pool, sizeof(*node));
236  node->ptr = ptr;
237  node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name);
239  node->next = head;
240  }
241 
242  switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) node);
243  }
244 
246  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "codec");
248  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
249  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
251 
252  if (!event_hash) {
253  switch_event_fire(&event);
254  }
255  else {
256  switch_core_hash_insert_pointer(event_hash, (const void*)event);
257  }
258 
259  added++;
260  }
261  }
262  }
263  }
264  }
265 
266  if (new_module->module_interface->dialplan_interface) {
268 
269  for (ptr = new_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) {
270  if (!ptr->interface_name) {
271  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load dialplan interface from %s due to no interface name.\n", key);
272  } else {
273  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Dialplan '%s'\n", ptr->interface_name);
275  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "dialplan");
277  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
278  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
279 
280  if (!event_hash) {
281  switch_event_fire(&event);
282  }
283  else {
284  switch_core_hash_insert_pointer(event_hash, (const void*)event);
285  }
286 
287  added++;
288  }
290  }
291  }
292  }
293 
294  if (new_module->module_interface->timer_interface) {
296 
297  for (ptr = new_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
298  if (!ptr->interface_name) {
299  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load timer interface from %s due to no interface name.\n", key);
300  } else {
303  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "timer");
305  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
306  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
307 
308  if (!event_hash) {
309  switch_event_fire(&event);
310  }
311  else {
312  switch_core_hash_insert_pointer(event_hash, (const void*)event);
313  }
314 
315  added++;
316  }
318  }
319  }
320  }
321 
322  if (new_module->module_interface->application_interface) {
324 
325  for (ptr = new_module->module_interface->application_interface; ptr; ptr = ptr->next) {
326  if (!ptr->interface_name) {
327  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key);
328  } else {
329  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Application '%s'\n", ptr->interface_name);
331  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
335  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
336  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
337 
338  if (!event_hash) {
339  switch_event_fire(&event);
340  }
341  else {
342  switch_core_hash_insert_pointer(event_hash, (const void*)event);
343  }
344 
345  added++;
346  }
348  }
349  }
350  }
351 
352  if (new_module->module_interface->chat_application_interface) {
354 
355  for (ptr = new_module->module_interface->chat_application_interface; ptr; ptr = ptr->next) {
356  if (!ptr->interface_name) {
357  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key);
358  } else {
359  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Chat Application '%s'\n", ptr->interface_name);
361  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
365  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
366  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
367 
368  if (!event_hash) {
369  switch_event_fire(&event);
370  }
371  else {
372  switch_core_hash_insert_pointer(event_hash, (const void*)event);
373  }
374 
375  added++;
376  }
378  }
379  }
380  }
381 
382  if (new_module->module_interface->api_interface) {
384 
385  for (ptr = new_module->module_interface->api_interface; ptr; ptr = ptr->next) {
386  if (!ptr->interface_name) {
387  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load api interface from %s due to no interface name.\n", key);
388  } else {
389  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding API Function '%s'\n", ptr->interface_name);
395  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
396  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
397 
398  if (!event_hash) {
399  switch_event_fire(&event);
400  }
401  else {
402  switch_core_hash_insert_pointer(event_hash, (const void*)event);
403  }
404 
405  added++;
406  }
408  }
409  }
410  }
411 
412  if (new_module->module_interface->json_api_interface) {
414 
415  for (ptr = new_module->module_interface->json_api_interface; ptr; ptr = ptr->next) {
416  if (!ptr->interface_name) {
417  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load JSON api interface from %s due to no interface name.\n", key);
418  } else {
419  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding JSON API Function '%s'\n", ptr->interface_name);
421  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "json_api");
425  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
426  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
427 
428  if (!event_hash) {
429  switch_event_fire(&event);
430  }
431  else {
432  switch_core_hash_insert_pointer(event_hash, (const void*)event);
433  }
434 
435  added++;
436  }
438  }
439  }
440  }
441 
442  if (new_module->module_interface->file_interface) {
444 
445  for (ptr = new_module->module_interface->file_interface; ptr; ptr = ptr->next) {
446  if (!ptr->interface_name) {
447  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no interface name.\n", key);
448  } else if (!ptr->extens) {
449  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no file extensions.\n", key);
450  } else {
451  int i;
452  switch_file_node_t *node, *head;
453 
454  for (i = 0; ptr->extens[i]; i++) {
455  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding File Format '%s'\n", ptr->extens[i]);
457  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "file");
459  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
460  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
462 
463  if (!event_hash) {
464  switch_event_fire(&event);
465  }
466  else {
467  switch_core_hash_insert_pointer(event_hash, (const void*)event);
468  }
469 
470  added++;
471  }
472  node = switch_core_alloc(new_module->pool, sizeof(*node));
473  node->ptr = ptr;
474  node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name);
475  if ((head = switch_core_hash_find(loadable_modules.file_hash, ptr->extens[i]))) {
476  node->next = head;
477  }
478 
479  switch_core_hash_insert(loadable_modules.file_hash, ptr->extens[i], (const void *) node);
480  }
481  }
482  }
483  }
484 
485  if (new_module->module_interface->database_interface) {
487 
488  for (ptr = new_module->module_interface->database_interface; ptr; ptr = ptr->next) {
489  if (!ptr->interface_name) {
490  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load database interface from %s due to no interface name.\n", key);
491  }
492  else if (!ptr->prefixes) {
493  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load database interface from %s due to no prefixes.\n", key);
494  }
495  else {
496  int i;
497  switch_database_node_t *node, *head;
498 
499  for (i = 0; ptr->prefixes[i]; i++) {
500  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding dsn prefix '%s'\n", ptr->prefixes[i]);
502  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "database");
504  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
505  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
507 
508  if (!event_hash) {
509  switch_event_fire(&event);
510  }
511  else {
512  switch_core_hash_insert_pointer(event_hash, (const void*)event);
513  }
514 
515  added++;
516  }
517  node = switch_core_alloc(new_module->pool, sizeof(*node));
518  node->ptr = ptr;
519  node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name);
521  node->next = head;
522  }
523 
524  switch_core_hash_insert(loadable_modules.database_hash, ptr->prefixes[i], (const void *)node);
525  }
526  }
527  }
528  }
529 
530  if (new_module->module_interface->speech_interface) {
532 
533  for (ptr = new_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
534  if (!ptr->interface_name) {
535  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load speech interface from %s due to no interface name.\n", key);
536  } else {
537  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Speech interface '%s'\n", ptr->interface_name);
539  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
541  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
542  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
543 
544  if (!event_hash) {
545  switch_event_fire(&event);
546  }
547  else {
548  switch_core_hash_insert_pointer(event_hash, (const void*)event);
549  }
550 
551  added++;
552  }
554  }
555  }
556  }
557 
558  if (new_module->module_interface->asr_interface) {
560 
561  for (ptr = new_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
562  if (!ptr->interface_name) {
563  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load asr interface from %s due to no interface name.\n", key);
564  } else {
565  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding ASR interface '%s'\n", ptr->interface_name);
569  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
570  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
571 
572  if (!event_hash) {
573  switch_event_fire(&event);
574  }
575  else {
576  switch_core_hash_insert_pointer(event_hash, (const void*)event);
577  }
578 
579  added++;
580  }
582  }
583  }
584  }
585 
586  if (new_module->module_interface->directory_interface) {
588 
589  for (ptr = new_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
590  if (!ptr->interface_name) {
591  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load directory interface from %s due to no interface name.\n", key);
592  } else {
593  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Directory interface '%s'\n", ptr->interface_name);
595  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
597  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
598  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
599 
600  if (!event_hash) {
601  switch_event_fire(&event);
602  }
603  else {
604  switch_core_hash_insert_pointer(event_hash, (const void*)event);
605  }
606 
607  added++;
608  }
610  }
611  }
612  }
613 
614  if (new_module->module_interface->chat_interface) {
616 
617  for (ptr = new_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
618  if (!ptr->interface_name) {
619  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load chat interface from %s due to no interface name.\n", key);
620  } else {
621  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Chat interface '%s'\n", ptr->interface_name);
623  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
625  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
626  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
627 
628  if (!event_hash) {
629  switch_event_fire(&event);
630  }
631  else {
632  switch_core_hash_insert_pointer(event_hash, (const void*)event);
633  }
634 
635  added++;
636  }
640  }
641  }
642  }
643 
644  if (new_module->module_interface->say_interface) {
646 
647  for (ptr = new_module->module_interface->say_interface; ptr; ptr = ptr->next) {
648  if (!ptr->interface_name) {
649  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load say interface from %s due to no interface name.\n", key);
650  } else {
651  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Say interface '%s'\n", ptr->interface_name);
655  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
656  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
657 
658  if (!event_hash) {
659  switch_event_fire(&event);
660  }
661  else {
662  switch_core_hash_insert_pointer(event_hash, (const void*)event);
663  }
664 
665  added++;
666  }
668  }
669  }
670  }
671 
672  if (new_module->module_interface->management_interface) {
674 
675  for (ptr = new_module->module_interface->management_interface; ptr; ptr = ptr->next) {
676  if (!ptr->relative_oid) {
677  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load management interface from %s due to no interface name.\n", key);
678  } else {
681  "Failed to load management interface %s. OID %s already exists\n", key, ptr->relative_oid);
682  } else {
684  "Adding Management interface '%s' OID[%s.%s]\n", key, FREESWITCH_OID_PREFIX, ptr->relative_oid);
687  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "management");
688  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->relative_oid);
689  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
690  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
691 
692  if (!event_hash) {
693  switch_event_fire(&event);
694  }
695  else {
696  switch_core_hash_insert_pointer(event_hash, (const void*)event);
697  }
698 
699  added++;
700  }
701  }
702 
703  }
704  }
705  }
706  if (new_module->module_interface->limit_interface) {
708 
709  for (ptr = new_module->module_interface->limit_interface; ptr; ptr = ptr->next) {
710  if (!ptr->interface_name) {
711  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load limit interface from %s due to no interface name.\n", key);
712  } else {
715  "Failed to load limit interface %s. Name %s already exists\n", key, ptr->interface_name);
716  } else {
718  "Adding Limit interface '%s'\n", ptr->interface_name);
721  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "limit");
722  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
723  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
724  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
725 
726  if (!event_hash) {
727  switch_event_fire(&event);
728  }
729  else {
730  switch_core_hash_insert_pointer(event_hash, (const void*)event);
731  }
732 
733  added++;
734  }
735  }
736 
737  }
738  }
739  }
740 
741  if (!added) {
743  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "generic");
744  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", new_module->key);
745  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
746  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
747 
748  if (!event_hash) {
749  switch_event_fire(&event);
750  }
751  else {
752  switch_core_hash_insert_pointer(event_hash, (const void*)event);
753  }
754 
755  added++;
756  }
757  }
758 
760  return SWITCH_STATUS_SUCCESS;
761 
762 }
763 
764 #define CHAT_MAX_MSG_QUEUE 101
765 #define CHAT_QUEUE_SIZE 5000
766 
767 static struct {
773  int running;
774 } chat_globals;
775 
776 static int IDX = 0;
777 
778 
780 
781 {
785  switch_event_t *dup = NULL;
786  const void *var;
787  void *val;
788  const char *proto;
789  const char *replying;
790  const char *dest_proto;
791  int do_skip = 0;
792 
793  /*
794 
795  const char *from;
796  const char *to;
797  const char *subject;
798  const char *body;
799  const char *type;
800  const char *hint;
801  */
802 
803  dest_proto = switch_event_get_header(message_event, "dest_proto");
804 
805  if (!dest_proto) {
806  return SWITCH_STATUS_FALSE;
807  }
808 
809  /*
810 
811  from = switch_event_get_header(message_event, "from");
812  to = switch_event_get_header(message_event, "to");
813  subject = switch_event_get_header(message_event, "subject");
814  body = switch_event_get_body(message_event);
815  type = switch_event_get_header(message_event, "type");
816  hint = switch_event_get_header(message_event, "hint");
817  */
818 
819  if (!(proto = switch_event_get_header(message_event, "proto"))) {
820  proto = "global";
821  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto);
822  }
823 
824  replying = switch_event_get_header(message_event, "replying");
825 
826  if (!switch_true(replying) && !switch_stristr("global", proto) && !switch_true(switch_event_get_header(message_event, "skip_global_process"))) {
829  switch_core_hash_this(hi, &var, NULL, &val);
830 
831  if ((ci = (switch_chat_interface_t *) val)) {
832  if (ci->chat_send && !strncasecmp(ci->interface_name, "GLOBAL_", 7)) {
833  status = ci->chat_send(message_event);
834 
835  if (status == SWITCH_STATUS_SUCCESS) {
836  if (switch_true(switch_event_get_header(message_event, "final_delivery"))) {
837  /* The event was handled by an extension in the chatplan,
838  * so the event will be duplicated, modified and queued again,
839  * but it won't be processed by the chatplan again.
840  * So this copy of the event can be destroyed by the caller.
841  */
842  do_skip = 1;
843  }
844  } else if (status == SWITCH_STATUS_BREAK) {
845  /* The event went through the chatplan, but no extension matched
846  * to handle the sms messsage. It'll be attempted to be delivered
847  * directly, and unless that works the sms delivery will have failed.
848  */
849  } else {
850  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Chat Interface Error [%s]!\n", dest_proto);
851  break;
852  }
853  }
854  }
855  }
856  switch_safe_free(hi);
858  }
859 
860 
861  if (!do_skip && !switch_stristr("GLOBAL", dest_proto)) {
862  if ((ci = switch_loadable_module_get_chat_interface(dest_proto)) && ci->chat_send) {
863  status = ci->chat_send(message_event);
865  } else {
866  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid chat interface [%s]!\n", dest_proto);
867  status = SWITCH_STATUS_FALSE;
868  }
869  }
870 
871 
872  switch_event_dup(&dup, message_event);
873 
874  if ( switch_true(switch_event_get_header(message_event, "blocking")) ) {
875  if (status == SWITCH_STATUS_SUCCESS) {
876  switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "false");
877  } else {
878  switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "true");
879  }
880  } else {
881  switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Nonblocking-Delivery", "true");
882  }
883 
884  switch_event_fire(&dup);
885  return status;
886 }
887 
889 {
890  switch_event_t *event;
891  switch_status_t status;
892 
893  switch_assert(eventp);
894 
895  event = *eventp;
896  *eventp = NULL;
897 
898  status = do_chat_send(event);
899  switch_event_destroy(&event);
900 
901  return status;
902 }
903 
904 
906 {
907  void *pop;
908  switch_queue_t *q = (switch_queue_t *) obj;
909 
910  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Chat Thread Started\n");
911 
912 
913  while(switch_queue_pop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
914  switch_event_t *event = (switch_event_t *) pop;
915  chat_process_event(&event);
917  }
918 
919  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Chat Thread Ended\n");
920 
921  return NULL;
922 }
923 
924 
925 static void chat_thread_start(int idx)
926 {
927 
928  if (idx >= CHAT_MAX_MSG_QUEUE || (idx < chat_globals.msg_queue_len && chat_globals.msg_queue_thread[idx])) {
929  return;
930  }
931 
933 
934  if (idx >= chat_globals.msg_queue_len) {
935  int i;
936  chat_globals.msg_queue_len = idx + 1;
937 
938  for (i = 0; i < chat_globals.msg_queue_len; i++) {
939  if (!chat_globals.msg_queue[i]) {
940  switch_threadattr_t *thd_attr = NULL;
941 
943 
944  switch_threadattr_create(&thd_attr, chat_globals.pool);
946  switch_thread_create(&chat_globals.msg_queue_thread[i],
947  thd_attr,
949  chat_globals.msg_queue[i],
950  chat_globals.pool);
951  }
952  }
953  }
954 
956 }
957 
958 
959 static void chat_queue_message(switch_event_t **eventp)
960 {
961  int idx = 0;
962  switch_event_t *event;
963 
964  switch_assert(eventp);
965 
966  event = *eventp;
967  *eventp = NULL;
968 
969  if (chat_globals.running == 0) {
970  chat_process_event(&event);
971  return;
972  }
973 
974  again:
975 
977  idx = IDX;
978  IDX++;
979  if (IDX >= chat_globals.msg_queue_len) IDX = 0;
981 
982  chat_thread_start(idx);
983 
984  if (switch_queue_trypush(chat_globals.msg_queue[idx], event) != SWITCH_STATUS_SUCCESS) {
985  if (chat_globals.msg_queue_len < CHAT_MAX_MSG_QUEUE) {
986  chat_thread_start(idx + 1);
987  goto again;
988  } else {
989  switch_queue_push(chat_globals.msg_queue[idx], event);
990  }
991  }
992 }
993 
994 
995 SWITCH_DECLARE(switch_status_t) switch_core_execute_chat_app(switch_event_t *message, const char *app, const char *data)
996 {
999  char *expanded;
1000 
1002  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid chat application interface [%s]!\n", app);
1003  return SWITCH_STATUS_FALSE;
1004  }
1005 
1006  if (switch_test_flag(message, EF_NO_CHAT_EXEC)) {
1007  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Message is not allowed to execute apps\n");
1009  }
1010 
1011  if (data && !strcmp(data, "__undef")) {
1012  data = NULL;
1013  }
1014 
1015  expanded = switch_event_expand_headers(message, data);
1016 
1017  status = cai->chat_application_function(message, expanded);
1018 
1019  if (expanded != data) {
1020  free(expanded);
1021  }
1022 
1023  end:
1024 
1025  UNPROTECT_INTERFACE(cai);
1026 
1027  return status;
1028 
1029 }
1030 
1031 
1032 
1033 SWITCH_DECLARE(switch_status_t) switch_core_chat_send_args(const char *dest_proto, const char *proto, const char *from, const char *to,
1034  const char *subject, const char *body, const char *type, const char *hint, switch_bool_t blocking)
1035 {
1036  switch_event_t *message_event;
1037  switch_status_t status;
1038 
1040  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto);
1041  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "from", from);
1042  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "to", to);
1043  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "subject", subject);
1044  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "type", type);
1045  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "hint", hint);
1046  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "skip_global_process", "true");
1047  if (blocking) {
1048  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "blocking", "true");
1049  }
1050 
1051  if (body) {
1052  switch_event_add_body(message_event, "%s", body);
1053  }
1054  } else {
1055  abort();
1056  }
1057 
1058  if (dest_proto) {
1059  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "dest_proto", dest_proto);
1060  }
1061 
1062 
1063  if (blocking) {
1064  status = chat_process_event(&message_event);
1065  } else {
1066  chat_queue_message(&message_event);
1067  status = SWITCH_STATUS_SUCCESS;
1068  }
1069 
1070  return status;
1071 
1072 }
1073 
1074 
1075 SWITCH_DECLARE(switch_status_t) switch_core_chat_send(const char *dest_proto, switch_event_t *message_event)
1076 {
1077  switch_event_t *dup;
1078 
1079  switch_event_dup(&dup, message_event);
1080 
1081  if (dest_proto) {
1082  switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "dest_proto", dest_proto);
1083  }
1084 
1085  chat_queue_message(&dup);
1086  return SWITCH_STATUS_SUCCESS;
1087 }
1088 
1089 
1091 {
1092 
1093  if (dest_proto) {
1094  switch_event_add_header_string(*message_event, SWITCH_STACK_BOTTOM, "dest_proto", dest_proto);
1095  }
1096 
1097  chat_queue_message(message_event);
1098 
1099  return SWITCH_STATUS_SUCCESS;
1100 }
1101 
1102 
1104 {
1105  switch_event_t *event;
1106  int removed = 0;
1107 
1109 
1110  if (old_module->module_interface->endpoint_interface) {
1112 
1113  for (ptr = old_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
1114  if (ptr->interface_name) {
1115 
1117  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1118  ptr->interface_name);
1121  } else {
1122  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1123  }
1124 
1125  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Endpoint '%s'\n", ptr->interface_name);
1127  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "endpoint");
1129  switch_event_fire(&event);
1130  removed++;
1131  }
1133  }
1134  }
1135  }
1136 
1137  if (old_module->module_interface->codec_interface) {
1138  const switch_codec_implementation_t *impl;
1140  switch_codec_node_t *node, *head, *last = NULL;
1141 
1142  for (ptr = old_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
1143  if (ptr->interface_name) {
1144  unsigned load_interface = 1;
1145  for (impl = ptr->implementations; impl; impl = impl->next) {
1146  if (!impl->iananame) {
1147  load_interface = 0;
1148  break;
1149  }
1150  }
1151  if (load_interface) {
1152  for (impl = ptr->implementations; impl; impl = impl->next) {
1154  "Deleting Codec %s %d %s %dhz %dms\n",
1155  impl->iananame, impl->ianacode,
1159 
1161  for(node = head; node; node = node->next) {
1162  if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
1163  if (node == head) {
1164  if ((node = node->next)) {
1165  switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) node);
1166  } else {
1168  }
1169  } else {
1170  if (last) {
1171  last->next = node->next;
1172  }
1173  }
1174  break;
1175  }
1176  last = node;
1177  }
1178  }
1179  }
1181  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "codec");
1184  switch_event_fire(&event);
1185  removed++;
1186  }
1187  }
1188  }
1189  }
1190  }
1191 
1192  if (old_module->module_interface->dialplan_interface) {
1194 
1195  for (ptr = old_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) {
1196  if (ptr->interface_name) {
1197  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Dialplan '%s'\n", ptr->interface_name);
1199  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "dialplan");
1201  switch_event_fire(&event);
1202  removed++;
1203  }
1205  }
1206  }
1207  }
1208 
1209  if (old_module->module_interface->timer_interface) {
1211 
1212  for (ptr = old_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
1213  if (ptr->interface_name) {
1214  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Timer '%s'\n", ptr->interface_name);
1216  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "timer");
1218  switch_event_fire(&event);
1219  removed++;
1220  }
1222  }
1223  }
1224  }
1225 
1226  if (old_module->module_interface->application_interface) {
1228  for (ptr = old_module->module_interface->application_interface; ptr; ptr = ptr->next) {
1229  if (ptr->interface_name) {
1230  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
1232  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1233  ptr->interface_name);
1236  } else {
1237  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1238  }
1239 
1241  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
1245  switch_event_fire(&event);
1246  removed++;
1247  }
1249  }
1250  }
1251  }
1252 
1253  if (old_module->module_interface->chat_application_interface) {
1255  for (ptr = old_module->module_interface->chat_application_interface; ptr; ptr = ptr->next) {
1256  if (ptr->interface_name) {
1257  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
1259  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1260  ptr->interface_name);
1263  } else {
1264  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1265  }
1266 
1268  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
1272  switch_event_fire(&event);
1273  removed++;
1274  }
1276  }
1277  }
1278  }
1279 
1280  if (old_module->module_interface->api_interface) {
1281  const switch_api_interface_t *ptr;
1282 
1283  for (ptr = old_module->module_interface->api_interface; ptr; ptr = ptr->next) {
1284  if (ptr->interface_name) {
1285  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
1286 
1287  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1288  ptr->interface_name);
1289 
1292  } else {
1293  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1294  }
1295 
1296 
1298  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");
1302  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", old_module->key);
1303  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", old_module->filename);
1304  switch_event_fire(&event);
1305  removed++;
1306  }
1308  }
1309  }
1310  }
1311 
1312  if (old_module->module_interface->json_api_interface) {
1314 
1315  for (ptr = old_module->module_interface->json_api_interface; ptr; ptr = ptr->next) {
1316  if (ptr->interface_name) {
1317  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
1318 
1319  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1320  ptr->interface_name);
1321 
1324  } else {
1325  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1326  }
1327 
1328 
1330  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "json_api");
1334  switch_event_fire(&event);
1335  removed++;
1336  }
1338  }
1339  }
1340  }
1341 
1342  if (old_module->module_interface->file_interface) {
1344  switch_file_node_t *node, *head, *last = NULL;
1345 
1346  for (ptr = old_module->module_interface->file_interface; ptr; ptr = ptr->next) {
1347  if (ptr->interface_name) {
1348  int i;
1349 
1350  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1351  ptr->interface_name);
1352 
1355  } else {
1356  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1357  }
1358 
1359  for (i = 0; ptr->extens[i]; i++) {
1360  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting File Format '%s'\n", ptr->extens[i]);
1362  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "file");
1365  switch_event_fire(&event);
1366  removed++;
1367  }
1368 
1369  if ((head = switch_core_hash_find(loadable_modules.file_hash, ptr->extens[i]))) {
1370  for(node = head; node; node = node->next) {
1371  if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
1372  if (node == head) {
1373  if ((node = node->next)) {
1374  switch_core_hash_insert(loadable_modules.file_hash, ptr->extens[i], (const void *) node);
1375  } else {
1377  }
1378  } else {
1379  if (last) {
1380  last->next = node->next;
1381  }
1382  }
1383  break;
1384  }
1385  last = node;
1386  }
1387  }
1388  }
1389  }
1390  }
1391  }
1392 
1393  if (old_module->module_interface->database_interface) {
1395  switch_database_node_t *node, *head, *last = NULL;
1396 
1397  for (ptr = old_module->module_interface->database_interface; ptr; ptr = ptr->next) {
1398  if (ptr->interface_name) {
1399  int i;
1400 
1401  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1402  ptr->interface_name);
1403 
1406  }
1407  else {
1408  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1409  }
1410 
1411  for (i = 0; ptr->prefixes[i]; i++) {
1412  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting dsn prefix '%s'\n", ptr->prefixes[i]);
1414  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "database");
1417  switch_event_fire(&event);
1418  removed++;
1419  }
1420 
1422  for (node = head; node; node = node->next) {
1423  if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
1424  if (node == head) {
1425  if ((node = node->next)) {
1426  switch_core_hash_insert(loadable_modules.database_hash, ptr->prefixes[i], (const void *)node);
1427  }
1428  else {
1430  }
1431  }
1432  else {
1433  if (last) {
1434  last->next = node->next;
1435  }
1436  }
1437  break;
1438  }
1439  last = node;
1440  }
1441  }
1442  }
1443 
1445  }
1446  }
1447  }
1448 
1449  if (old_module->module_interface->speech_interface) {
1451 
1452  for (ptr = old_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
1453 
1454  if (ptr->interface_name) {
1455 
1456  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1457  ptr->interface_name);
1458 
1461  } else {
1462  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1463  }
1464 
1465  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Speech interface '%s'\n", ptr->interface_name);
1467  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
1469  switch_event_fire(&event);
1470  removed++;
1471  }
1473  }
1474  }
1475  }
1476 
1477  if (old_module->module_interface->asr_interface) {
1478  const switch_asr_interface_t *ptr;
1479 
1480  for (ptr = old_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
1481  if (ptr->interface_name) {
1482 
1483  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1484  ptr->interface_name);
1485 
1488  } else {
1489  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1490  }
1491 
1492  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Asr interface '%s'\n", ptr->interface_name);
1494  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "asr");
1496  switch_event_fire(&event);
1497  removed++;
1498  }
1500  }
1501  }
1502  }
1503 
1504  if (old_module->module_interface->directory_interface) {
1506 
1507  for (ptr = old_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
1508  if (ptr->interface_name) {
1509 
1510  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1511  ptr->interface_name);
1512 
1515  } else {
1516  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1517  }
1518 
1519  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Directory interface '%s'\n", ptr->interface_name);
1521  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
1523  switch_event_fire(&event);
1524  removed++;
1525  }
1527  }
1528  }
1529  }
1530 
1531 
1532  if (old_module->module_interface->chat_interface) {
1534 
1535  for (ptr = old_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
1536  if (ptr->interface_name) {
1537  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1538  ptr->interface_name);
1539 
1542  } else {
1543  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1544  }
1545 
1546  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Chat interface '%s'\n", ptr->interface_name);
1548  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
1550  switch_event_fire(&event);
1551  removed++;
1552  }
1556  }
1557  }
1558  }
1559 
1560  if (old_module->module_interface->say_interface) {
1561  const switch_say_interface_t *ptr;
1562 
1563  for (ptr = old_module->module_interface->say_interface; ptr; ptr = ptr->next) {
1564  if (ptr->interface_name) {
1565  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1566  ptr->interface_name);
1567 
1570  } else {
1571  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1572  }
1573  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Say interface '%s'\n", ptr->interface_name);
1575  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "say");
1577  switch_event_fire(&event);
1578  removed++;
1579  }
1581  }
1582  }
1583  }
1584 
1585  if (old_module->module_interface->management_interface) {
1587 
1588  for (ptr = old_module->module_interface->management_interface; ptr; ptr = ptr->next) {
1589  if (ptr->relative_oid) {
1591  "Deleting Management interface '%s' OID[%s.%s]\n", old_module->key, FREESWITCH_OID_PREFIX, ptr->relative_oid);
1594  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "management");
1596  switch_event_fire(&event);
1597  removed++;
1598  }
1599  }
1600  }
1601  }
1602 
1603  if (old_module->module_interface->limit_interface) {
1605 
1606  for (ptr = old_module->module_interface->limit_interface; ptr; ptr = ptr->next) {
1607  if (ptr->interface_name) {
1609  "Deleting Limit interface '%s'\n", ptr->interface_name);
1612  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "limit");
1614  switch_event_fire(&event);
1615  removed++;
1616  }
1617  }
1618  }
1619  }
1620 
1621  if (!removed) {
1623  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "generic");
1624  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", old_module->key);
1625  switch_event_fire(&event);
1626  removed++;
1627  }
1628  }
1630 
1631  return SWITCH_STATUS_SUCCESS;
1632 
1633 }
1634 
1635 
1637 {
1638  switch_loadable_module_t *module = NULL;
1639  switch_dso_lib_t dso = NULL;
1640  fspr_status_t status = SWITCH_STATUS_SUCCESS;
1641  switch_loadable_module_function_table_t *interface_struct_handle = NULL;
1642  switch_loadable_module_function_table_t *mod_interface_functions = NULL;
1643  char *struct_name = NULL;
1644  switch_module_load_t load_func_ptr = NULL;
1645  int loading = 1;
1646  switch_loadable_module_interface_t *module_interface = NULL;
1647  char *derr = NULL;
1648  const char *err = NULL;
1649  switch_memory_pool_t *pool = NULL;
1650  switch_bool_t load_global = global;
1651 
1652  switch_assert(path != NULL);
1653 
1655  *new_module = NULL;
1656 
1657  struct_name = switch_core_sprintf(pool, "%s_module_interface", filename);
1658 
1659 #ifdef WIN32
1660  dso = switch_dso_open("FreeSwitch.dll", load_global, &derr);
1661 #elif defined (MACOSX) || defined(DARWIN)
1662  {
1663  char *lib_path = switch_mprintf("%s/libfreeswitch.dylib", SWITCH_GLOBAL_dirs.lib_dir);
1664  dso = switch_dso_open(lib_path, load_global, &derr);
1665  switch_safe_free(lib_path);
1666  }
1667 #else
1668  dso = switch_dso_open(NULL, load_global, &derr);
1669 #endif
1670  if (!derr && dso) {
1671  interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
1672  }
1673 
1674  switch_safe_free(derr);
1675 
1676  if (!interface_struct_handle) {
1677  if (dso) switch_dso_destroy(&dso);
1678  dso = switch_dso_open(path, load_global, &derr);
1679  }
1680 
1681  while (loading) {
1682  if (derr) {
1683  err = derr;
1684  break;
1685  }
1686 
1687  if (!interface_struct_handle) {
1688  interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
1689  }
1690 
1691  if (derr) {
1692  err = derr;
1693  break;
1694  }
1695 
1696  if (interface_struct_handle && interface_struct_handle->switch_api_version != SWITCH_API_VERSION) {
1697  err = "Trying to load an out of date module, please rebuild the module.";
1698  break;
1699  }
1700 
1701  if (!load_global && interface_struct_handle && switch_test_flag(interface_struct_handle, SMODF_GLOBAL_SYMBOLS)) {
1702  load_global = SWITCH_TRUE;
1703  switch_dso_destroy(&dso);
1704  interface_struct_handle = NULL;
1705  dso = switch_dso_open(path, load_global, &derr);
1706  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading module with global namespace at request of module\n");
1707  continue;
1708  }
1709 
1710  if (interface_struct_handle) {
1711  mod_interface_functions = interface_struct_handle;
1712  load_func_ptr = mod_interface_functions->load;
1713  }
1714 
1715  if (load_func_ptr == NULL) {
1716  err = "Cannot locate symbol 'switch_module_load' please make sure this is a valid module.";
1717  break;
1718  }
1719 
1720  status = load_func_ptr(&module_interface, pool);
1721 
1722  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_NOUNLOAD) {
1723  err = "Module load routine returned an error";
1724  module_interface = NULL;
1725  break;
1726  }
1727 
1728  if (!module_interface) {
1729  err = "Module failed to initialize its module_interface. Is this a valid module?";
1730  break;
1731  }
1732 
1733  if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))) == 0) {
1734  abort();
1735  }
1736 
1737  if (status == SWITCH_STATUS_NOUNLOAD) {
1738  module->perm++;
1739  }
1740 
1741  loading = 0;
1742  }
1743 
1744 
1745  if (err) {
1746 
1747  if (dso) {
1748  switch_dso_destroy(&dso);
1749  }
1750 
1751  if (pool) {
1753  }
1754  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Loading module %s\n**%s**\n", path, err);
1755  switch_safe_free(derr);
1756  return SWITCH_STATUS_GENERR;
1757  }
1758 
1759  module->pool = pool;
1760  module->filename = switch_core_strdup(module->pool, path);
1761  module->module_interface = module_interface;
1762  module->switch_module_load = load_func_ptr;
1763 
1764  if (mod_interface_functions) {
1765  module->switch_module_shutdown = mod_interface_functions->shutdown;
1766  module->switch_module_runtime = mod_interface_functions->runtime;
1767  }
1768 
1769  module->lib = dso;
1770 
1771  *new_module = module;
1772  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
1773 
1775 
1776  return SWITCH_STATUS_SUCCESS;
1777 
1778 }
1779 SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(const char *dir, const char *fname, switch_bool_t runtime, const char **err)
1780 {
1782 }
1783 
1784 static switch_status_t switch_loadable_module_load_module_ex(const char *dir, const char *fname, switch_bool_t runtime, switch_bool_t global, const char **err, switch_loadable_module_type_t type, switch_hash_t *event_hash)
1785 {
1786  switch_size_t len = 0;
1787  char *path;
1788  char *file, *dot;
1789  switch_loadable_module_t *new_module = NULL;
1791 
1792 #ifdef WIN32
1793  const char *ext = ".dll";
1794 #else
1795  const char *ext = ".so";
1796 #endif
1797 
1798  *err = "";
1799 
1800  if ((file = switch_core_strdup(loadable_modules.pool, fname)) == 0) {
1801  *err = "allocation error";
1802  return SWITCH_STATUS_FALSE;
1803  }
1804 
1805  if (switch_is_file_path(file)) {
1807  file = (char *) switch_cut_path(file);
1808  if ((dot = strchr(file, '.'))) {
1809  *dot = '\0';
1810  }
1811  } else {
1812  if ((dot = strchr(file, '.'))) {
1813  *dot = '\0';
1814  }
1815  len = strlen(switch_str_nil(dir));
1816  len += strlen(file);
1817  len += 8;
1818  path = (char *) switch_core_alloc(loadable_modules.pool, len);
1819  switch_snprintf(path, len, "%s%s%s%s", switch_str_nil(dir), SWITCH_PATH_SEPARATOR, file, ext);
1820  }
1821 
1822 
1824  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Module %s Already Loaded!\n", file);
1825  *err = "Module already loaded";
1826  status = SWITCH_STATUS_FALSE;
1827  } else if ((status = switch_loadable_module_load_file(path, file, global, &new_module)) == SWITCH_STATUS_SUCCESS) {
1828  new_module->type = type;
1829 
1830  if ((status = switch_loadable_module_process(file, new_module, event_hash)) == SWITCH_STATUS_SUCCESS && runtime) {
1831  if (new_module->switch_module_runtime) {
1832  new_module->thread = switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool);
1833  }
1834  } else if (status != SWITCH_STATUS_SUCCESS) {
1835  *err = "module load routine returned an error";
1836  }
1837  } else {
1838  *err = "module load file routine returned an error";
1839  }
1840 
1841 
1842  return status;
1843 
1844 }
1845 
1847 {
1848  switch_status_t status;
1849 
1850  if (zstr(mod)) {
1851  return SWITCH_STATUS_FALSE;
1852  }
1853 
1856  status = SWITCH_STATUS_SUCCESS;
1857  } else {
1858  status = SWITCH_STATUS_FALSE;
1859  }
1861 
1862  return status;
1863 }
1864 
1866 {
1867  switch_loadable_module_t *module = NULL;
1869 
1870  if (zstr(mod)) {
1871  return SWITCH_STATUS_FALSE;
1872  }
1873 
1875  if ((module = switch_core_hash_find(loadable_modules.module_hash, mod))) {
1876  if (!module->perm) {
1877  module->perm++;
1878  }
1879  status = SWITCH_STATUS_SUCCESS;
1880  }
1881  else {
1882  status = SWITCH_STATUS_FALSE;
1883  }
1885 
1886  return status;
1887 }
1888 
1889 SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(const char *dir, const char *fname, switch_bool_t force, const char **err)
1890 {
1891  switch_loadable_module_t *module = NULL;
1893 
1894  if (force) {
1895  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Spin the barrel and pull the trigger.......!\n");
1896  }
1897 
1899  if ((module = switch_core_hash_find(loadable_modules.module_hash, fname))) {
1900  if (module->perm) {
1901  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Module is not unloadable.\n");
1902  *err = "Module is not unloadable";
1903  status = SWITCH_STATUS_NOUNLOAD;
1904  goto unlock;
1905  } else {
1906  /* Prevent anything from using the module while it's shutting down */
1909  if ((status = do_shutdown(module, SWITCH_TRUE, SWITCH_TRUE, !force, err)) != SWITCH_STATUS_SUCCESS) {
1910  /* Something went wrong in the module's shutdown function, add it again */
1912  }
1913  goto end;
1914  }
1915  } else {
1916  *err = "No such module!";
1917  status = SWITCH_STATUS_FALSE;
1918  }
1919 unlock:
1921  end:
1922  if (force) {
1923  switch_yield(1000000);
1925  }
1926 
1927  return status;
1928 
1929 }
1930 
1932 {
1933  switch_dir_t *dir = NULL;
1934  switch_status_t status;
1935  char buffer[256];
1936  const char *fname;
1937  const char *fname_ext;
1938  char *fname_base;
1939 
1940 #ifdef WIN32
1941  const char *ext = ".dll";
1942 #else
1943  const char *ext = ".so";
1944 #endif
1945 
1946  if ((status = switch_dir_open(&dir, dir_path, loadable_modules.pool)) != SWITCH_STATUS_SUCCESS) {
1947  return status;
1948  }
1949 
1950  while((fname = switch_dir_next_file(dir, buffer, sizeof(buffer)))) {
1951  if ((fname_ext = strrchr(fname, '.'))) {
1952  if (!strcmp(fname_ext, ext)) {
1953  if (!(fname_base = switch_mprintf("%.*s", (int)(fname_ext-fname), fname))) {
1954  status = SWITCH_STATUS_GENERR;
1955  goto end;
1956  }
1957  callback(user_data, fname_base);
1958  switch_safe_free(fname_base)
1959  }
1960  }
1961  }
1962 
1963 
1964  end:
1965  switch_dir_close(dir);
1966  return status;
1967 }
1968 
1970 {
1971  switch_hash_index_t *hi;
1972  void *val;
1973  switch_loadable_module_t *module;
1974 
1977  switch_core_hash_this(hi, NULL, NULL, &val);
1978  module = (switch_loadable_module_t *) val;
1979 
1980  callback(user_data, module->module_interface->module_name);
1981  }
1983 
1984  return SWITCH_STATUS_SUCCESS;
1985 }
1986 
1988  switch_module_load_t switch_module_load,
1989  switch_module_runtime_t switch_module_runtime,
1990  switch_module_shutdown_t switch_module_shutdown, switch_bool_t runtime)
1991 {
1992  switch_loadable_module_t *module = NULL;
1993  switch_module_load_t load_func_ptr = NULL;
1994  int loading = 1;
1995  const char *err = NULL;
1996  switch_loadable_module_interface_t *module_interface = NULL;
1998 
1999 
2002  abort();
2003  }
2004 
2005  if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))) == 0) {
2006  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Couldn't allocate memory\n");
2007  abort();
2008  }
2009 
2010 
2011 
2012  while (loading) {
2013  switch_status_t status;
2014  load_func_ptr = (switch_module_load_t) switch_module_load;
2015 
2016  if (load_func_ptr == NULL) {
2017  err = "Cannot Load";
2018  break;
2019  }
2020 
2021  status = load_func_ptr(&module_interface, pool);
2022 
2023  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_NOUNLOAD) {
2024  err = "Module load routine returned an error";
2025  module_interface = NULL;
2026  break;
2027  }
2028 
2029  if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))) == 0) {
2030  abort();
2031  }
2032 
2033  if (status == SWITCH_STATUS_NOUNLOAD) {
2034  module->perm++;
2035  }
2036 
2037  loading = 0;
2038  }
2039 
2040  if (err) {
2042  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error Loading module %s\n**%s**\n", filename, err);
2043  return SWITCH_STATUS_GENERR;
2044  }
2045 
2046  module->pool = pool;
2047  module->filename = switch_core_strdup(module->pool, filename);
2048  module->module_interface = module_interface;
2049  module->switch_module_load = load_func_ptr;
2050 
2051  if (switch_module_shutdown) {
2052  module->switch_module_shutdown = switch_module_shutdown;
2053  }
2054  if (switch_module_runtime) {
2055  module->switch_module_runtime = switch_module_runtime;
2056  }
2057  if (runtime && module->switch_module_runtime) {
2059  }
2060  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
2061  return switch_loadable_module_process((char *) module->filename, module, NULL);
2062 }
2063 
2064 #ifdef WIN32
2065 static void switch_loadable_module_path_init()
2066 {
2067  char *path = NULL, *working = NULL;
2068  fspr_dir_t *perl_dir_handle = NULL;
2069 
2070  fspr_env_get(&path, "path", loadable_modules.pool);
2071  fspr_filepath_get(&working, APR_FILEPATH_NATIVE, loadable_modules.pool);
2072 
2073  if (fspr_dir_open(&perl_dir_handle, ".\\perl", loadable_modules.pool) == APR_SUCCESS) {
2074  fspr_dir_close(perl_dir_handle);
2075  fspr_env_set("path", fspr_pstrcat(loadable_modules.pool, path, ";", working, "\\perl", NULL), loadable_modules.pool);
2076  }
2077 }
2078 #endif
2079 
2081 {
2082 
2083  fspr_finfo_t finfo = { 0 };
2084  fspr_dir_t *module_dir_handle = NULL;
2085  fspr_int32_t finfo_flags = APR_FINFO_DIRENT | APR_FINFO_TYPE | APR_FINFO_NAME;
2086  char *precf = "pre_load_modules.conf";
2087  char *cf = "modules.conf";
2088  char *pcf = "post_load_modules.conf";
2089  switch_xml_t cfg, xml;
2090  unsigned char all = 0;
2091  unsigned int count = 0;
2092  const char *err;
2093  switch_hash_t *event_hash;
2094  switch_hash_index_t *hi;
2095  void *hash_val;
2096  switch_event_t *event;
2097 
2098 
2099 #ifdef WIN32
2100  const char *ext = ".dll";
2101  const char *EXT = ".DLL";
2102 #elif defined (MACOSX) || defined (DARWIN)
2103  const char *ext = ".dylib";
2104  const char *EXT = ".DYLIB";
2105 #else
2106  const char *ext = ".so";
2107  const char *EXT = ".SO";
2108 #endif
2109 
2112 
2113 
2114 #ifdef WIN32
2115  switch_loadable_module_path_init();
2116 #endif
2117 
2139 
2140  if (!autoload) return SWITCH_STATUS_SUCCESS;
2141 
2142  /*
2143  switch_core_sqldb_init() is not yet ready and is executed after starting modules from pre_load_modules.conf
2144  Modules loading procedure generates events used by sqldb.
2145  This is why we should hold those events (storing in the event_hash) not firing them until sqldb is ready.
2146  */
2147  switch_core_hash_init(&event_hash);
2148 
2149  /*
2150  Pre-load core modules.
2151  Do not pre-load modules which may use databases,
2152  use appropriate section.
2153  */
2157 
2158  /*
2159  Loading pre-load modules.
2160  Database modules must be loaded here.
2161  */
2162  if ((xml = switch_xml_open_cfg(precf, &cfg, NULL))) {
2163  switch_xml_t mods, ld;
2164  if ((mods = switch_xml_child(cfg, "modules"))) {
2165  for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
2166  switch_bool_t global = SWITCH_FALSE;
2167  const char *val = switch_xml_attr_soft(ld, "module");
2168  const char *path = switch_xml_attr_soft(ld, "path");
2169  const char *critical = switch_xml_attr_soft(ld, "critical");
2170  const char *sglobal = switch_xml_attr_soft(ld, "global");
2171 
2172  if (zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
2173  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
2174  continue;
2175  }
2176  global = switch_true(sglobal);
2177 
2178  if (path && zstr(path)) {
2179  path = SWITCH_GLOBAL_dirs.mod_dir;
2180  }
2181  if (switch_loadable_module_load_module_ex((char *)path, (char *)val, SWITCH_FALSE, global, &err, SWITCH_LOADABLE_MODULE_TYPE_PRELOAD, event_hash) == SWITCH_STATUS_GENERR) {
2182  if (critical && switch_true(critical)) {
2183  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val);
2184  switch_core_hash_destroy(&event_hash);
2185 
2186  abort();
2187  }
2188  }
2189  count++;
2190  }
2191  }
2192  switch_xml_free(xml);
2193 
2194  }
2195  else {
2196  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "open of %s failed\n", precf);
2197  }
2198 
2200  {
2201  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Loading modules interrupted. [Error: %s]\n", err);
2202  switch_core_hash_destroy(&event_hash);
2203  return SWITCH_STATUS_GENERR;
2204  }
2205 
2206  /* sqldb is ready. Fire holding events! */
2207  for (hi = switch_core_hash_first(event_hash); hi; hi = switch_core_hash_next(&hi)) {
2208  switch_core_hash_this(hi, NULL, NULL, &hash_val);
2209  event = (switch_event_t *)hash_val;
2210  switch_event_fire(&event);
2211  }
2212 
2213  switch_core_hash_destroy(&event_hash);
2214 
2215  /*
2216  To perevent locking.
2217  Core modules which may use databases should be pre-loaded here
2218  (databases are loaded already).
2219  */
2220 #ifdef SWITCH_HAVE_YUV
2221 #ifdef SWITCH_HAVE_VPX
2222  switch_loadable_module_load_module("", "CORE_VPX_MODULE", SWITCH_FALSE, &err);
2223 #endif
2224 #endif
2225 
2226  /* Loading common modules */
2227  if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
2228  switch_xml_t mods, ld;
2229  if ((mods = switch_xml_child(cfg, "modules"))) {
2230  for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
2231  switch_bool_t global = SWITCH_FALSE;
2232  const char *val = switch_xml_attr_soft(ld, "module");
2233  const char *path = switch_xml_attr_soft(ld, "path");
2234  const char *critical = switch_xml_attr_soft(ld, "critical");
2235  const char *sglobal = switch_xml_attr_soft(ld, "global");
2236  if (zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
2237  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
2238  continue;
2239  }
2240  global = switch_true(sglobal);
2241 
2242  if (path && zstr(path)) {
2243  path = SWITCH_GLOBAL_dirs.mod_dir;
2244  }
2246  if (critical && switch_true(critical)) {
2247  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val);
2248  abort();
2249  }
2250  }
2251  count++;
2252  }
2253  }
2254  switch_xml_free(xml);
2255 
2256  } else {
2257  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "open of %s failed\n", cf);
2258  }
2259 
2260  if ((xml = switch_xml_open_cfg(pcf, &cfg, NULL))) {
2261  switch_xml_t mods, ld;
2262 
2263  if ((mods = switch_xml_child(cfg, "modules"))) {
2264  for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
2265  switch_bool_t global = SWITCH_FALSE;
2266  const char *val = switch_xml_attr_soft(ld, "module");
2267  const char *path = switch_xml_attr_soft(ld, "path");
2268  const char *sglobal = switch_xml_attr_soft(ld, "global");
2269  if (zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
2270  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
2271  continue;
2272  }
2273  global = switch_true(sglobal);
2274 
2275  if (path && zstr(path)) {
2276  path = SWITCH_GLOBAL_dirs.mod_dir;
2277  }
2279  count++;
2280  }
2281  }
2282  switch_xml_free(xml);
2283 
2284  } else {
2285  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "open of %s failed\n", pcf);
2286  }
2287 
2288  if (!count) {
2289  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "No modules loaded, assuming 'load all'\n");
2290  all = 1;
2291  }
2292 
2293  if (all) {
2294  if (fspr_dir_open(&module_dir_handle, SWITCH_GLOBAL_dirs.mod_dir, loadable_modules.pool) != APR_SUCCESS) {
2296  return SWITCH_STATUS_GENERR;
2297  }
2298 
2299  while (fspr_dir_read(&finfo, finfo_flags, module_dir_handle) == APR_SUCCESS) {
2300  const char *fname = finfo.fname;
2301 
2302  if (finfo.filetype != APR_REG) {
2303  continue;
2304  }
2305 
2306  if (!fname) {
2307  fname = finfo.name;
2308  }
2309 
2310  if (!fname) {
2311  continue;
2312  }
2313 
2314  if (zstr(fname) || (!strstr(fname, ext) && !strstr(fname, EXT))) {
2315  continue;
2316  }
2317 
2319  }
2320  fspr_dir_close(module_dir_handle);
2321  }
2322 
2324 
2325  memset(&chat_globals, 0, sizeof(chat_globals));
2326  chat_globals.running = 1;
2329 
2330  chat_thread_start(1);
2331 
2332  return SWITCH_STATUS_SUCCESS;
2333 }
2334 
2336  const char **err)
2337 {
2338  int32_t flags = switch_core_flags();
2339  switch_assert(module != NULL);
2340 
2342  if (err) {
2343  *err = "Module in use.";
2344  }
2345  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Module %s is in use, cannot unload.\n", module->module_interface->module_name);
2346  return SWITCH_STATUS_FALSE;
2347  }
2348 
2349  module->shutting_down = SWITCH_TRUE;
2350 
2351  if (shutdown) {
2353  if (module->switch_module_shutdown) {
2355  module->status = module->switch_module_shutdown();
2356  } else {
2357  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s has no shutdown routine\n", module->module_interface->module_name);
2358  }
2359  }
2360 
2361  if (fail_if_busy && module->module_interface->rwlock) {
2363  }
2364 
2365  if (unload && module->status != SWITCH_STATUS_NOUNLOAD && !(flags & SCF_VG)) {
2367  switch_status_t st;
2368 
2369  if (module->thread) {
2370  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s stopping runtime thread.\n", module->module_interface->module_name);
2371  switch_thread_join(&st, module->thread);
2372  }
2373 
2375  switch_dso_destroy(&module->lib);
2376  if ((pool = module->pool)) {
2377  module = NULL;
2379  }
2380  }
2381 
2382  return SWITCH_STATUS_SUCCESS;
2383 
2384 }
2385 
2387 {
2388  switch_hash_index_t *hi;
2389  void *val;
2390  const void *key;
2391  switch_loadable_module_t *module;
2392  int i;
2393 
2395  return;
2396  }
2397 
2398  chat_globals.running = 0;
2399 
2400  for (i = 0; i < chat_globals.msg_queue_len; i++) {
2401  switch_queue_push(chat_globals.msg_queue[i], NULL);
2402  }
2403 
2404  for (i = 0; i < chat_globals.msg_queue_len; i++) {
2405  switch_status_t st;
2406  switch_thread_join(&st, chat_globals.msg_queue_thread[i]);
2407  }
2408 
2409 
2411  switch_core_hash_this(hi, NULL, NULL, &val);
2412  module = (switch_loadable_module_t *)val;
2413  if (module->type != SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
2415  }
2416  }
2417 
2418  switch_yield(1000000);
2419 
2421  switch_core_hash_this(hi, &key, NULL, &val);
2422  module = (switch_loadable_module_t *)val;
2423 
2424  hi = switch_core_hash_next(&hi);
2425 
2426  if (module->type != SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
2428  {
2430  }
2431  }
2432  }
2433 
2435 
2437  switch_core_hash_this(hi, NULL, NULL, &val);
2438  if ((module = (switch_loadable_module_t *)val)) {
2439  if (module->type == SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
2441  }
2442  }
2443  }
2444 
2445  switch_yield(1000000);
2446 
2448  switch_core_hash_this(hi, NULL, NULL, &val);
2449  if ((module = (switch_loadable_module_t *)val)) {
2450  if (module->type == SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
2452  }
2453  }
2454  }
2455 
2475 
2477 }
2478 
2480 {
2482 
2485  PROTECT_INTERFACE(ptr);
2487 
2488 
2489  return ptr;
2490 }
2491 
2493 {
2494  switch_file_interface_t *i = NULL;
2495  switch_file_node_t *node, *head;
2496 
2498 
2499  if ((head = switch_core_hash_find(loadable_modules.file_hash, name))) {
2500  if (modname) {
2501  for (node = head; node; node = node->next) {
2502  if (!strcasecmp(node->interface_name, modname)) {
2503  i = (switch_file_interface_t *) node->ptr;
2504  break;
2505  }
2506  }
2507  } else {
2508  i = (switch_file_interface_t *) head->ptr;
2509  }
2510  }
2511 
2513 
2514  if (i) PROTECT_INTERFACE(i);
2515 
2516  return i;
2517 }
2518 
2520 {
2521  switch_database_interface_t *i = NULL;
2522  switch_database_node_t *node, *head;
2523 
2525 
2527  if (modname) {
2528  for (node = head; node; node = node->next) {
2529  if (!strcasecmp(node->interface_name, modname)) {
2530  i = (switch_database_interface_t *)node->ptr;
2531  break;
2532  }
2533  }
2534  }
2535  else {
2536  i = (switch_database_interface_t *)head->ptr;
2537  }
2538  }
2539 
2541 
2542  if (i) PROTECT_INTERFACE(i);
2543 
2544  return i;
2545 }
2546 
2548 {
2549  switch_codec_interface_t *codec = NULL;
2550  switch_codec_node_t *node, *head;
2551 
2553 
2554  if ((head = switch_core_hash_find(loadable_modules.codec_hash, name))) {
2555  if (modname) {
2556  for (node = head; node; node = node->next) {
2557  if (!strcasecmp(node->interface_name, modname)) {
2558  codec = (switch_codec_interface_t *) node->ptr;
2559  break;
2560  }
2561  }
2562  } else {
2563  codec = (switch_codec_interface_t *) head->ptr;
2564  }
2565  }
2566 
2568 
2569  PROTECT_INTERFACE(codec);
2570 
2571  return codec;
2572 }
2573 
2574 #define HASH_FUNC(_kind_) SWITCH_DECLARE(switch_##_kind_##_interface_t *) switch_loadable_module_get_##_kind_##_interface(const char *name) \
2575  { \
2576  switch_##_kind_##_interface_t *i = NULL; \
2577  if (loadable_modules._kind_##_hash && (i = switch_core_hash_find_locked(loadable_modules._kind_##_hash, name, loadable_modules.mutex))) { \
2578  PROTECT_INTERFACE(i); \
2579  } \
2580  return i; \
2581  }
2582 
2583 HASH_FUNC(dialplan)
2584 HASH_FUNC(timer)
2585 HASH_FUNC(application)
2586 HASH_FUNC(chat_application)
2587 HASH_FUNC(api)
2588 HASH_FUNC(json_api)
2589 HASH_FUNC(speech)
2590 HASH_FUNC(asr)
2591 HASH_FUNC(directory)
2592 HASH_FUNC(chat)
2593 HASH_FUNC(limit)
2594 
2595 
2597 {
2599 }
2600 
2602 {
2604 }
2605 
2606 #ifdef DEBUG_CODEC_SORTING
2607 static void do_print(const switch_codec_implementation_t **array, int arraylen)
2608 {
2609  int i;
2610 
2611  for(i = 0; i < arraylen; i++) {
2613  "DEBUG %d %s:%d %d\n", i, array[i]->iananame, array[i]->ianacode, array[i]->microseconds_per_packet / 1000);
2614  }
2615 
2616 }
2617 #endif
2618 
2619 /* helper only -- bounds checking enforced by caller */
2620 static void do_swap(const switch_codec_implementation_t **array, int a, int b)
2621 {
2622  const switch_codec_implementation_t *tmp = array[b];
2623  array[b] = array[a];
2624  array[a] = tmp;
2625 }
2626 
2628 {
2629  int i = 0, sorted_ptime = 0;
2630 
2631 #ifdef DEBUG_CODEC_SORTING
2633  do_print(array, arraylen);
2635 #endif
2636 
2637  for (i = 0; i < arraylen; i++) {
2638  int this_ptime;
2639 
2640  if (!array[i]) {
2641  continue;
2642  }
2643 
2644  this_ptime = array[i]->microseconds_per_packet / 1000;
2645 
2646  if (!strcasecmp(array[i]->iananame, "ilbc")) {
2647  this_ptime = 20;
2648  }
2649 
2650  if (!sorted_ptime) {
2651  sorted_ptime = this_ptime;
2652 #ifdef DEBUG_CODEC_SORTING
2653  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sorted1 = %d\n", sorted_ptime);
2654 #endif
2655  }
2656 
2657  if (i > 0 && array[i-1] && strcasecmp(array[i]->iananame, array[i-1]->iananame) && this_ptime != sorted_ptime) {
2658  int j;
2659  int swapped = 0;
2660 
2661 #ifdef DEBUG_CODEC_SORTING
2662  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%d != %d\n", this_ptime, sorted_ptime);
2663 #endif
2664  for(j = i; j < arraylen; j++) {
2665  int check_ptime = array[j]->microseconds_per_packet / 1000;
2666 
2667  if (!strcasecmp(array[i]->iananame, "ilbc")) {
2668  check_ptime = 20;
2669  }
2670 
2671  if (check_ptime == sorted_ptime) {
2672 #ifdef DEBUG_CODEC_SORTING
2673  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "swap %d %d ptime %d\n", i, j, check_ptime);
2674 #endif
2675  do_swap(array, i, j);
2676  swapped = 1;
2677  break;
2678  }
2679  }
2680 
2681  if (!swapped) {
2682  sorted_ptime = this_ptime;
2683 #ifdef DEBUG_CODEC_SORTING
2684  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sorted2 = %d\n", sorted_ptime);
2685 #endif
2686  }
2687  }
2688  }
2689 
2690 #ifdef DEBUG_CODEC_SORTING
2692  do_print(array, arraylen);
2694 #endif
2695 
2696 }
2697 
2698 
2700 {
2701  switch_hash_index_t *hi;
2702  void *val;
2703  switch_codec_interface_t *codec_interface;
2704  int i = 0;
2705  const switch_codec_implementation_t *imp;
2706  switch_codec_node_t *node, *head;
2707 
2710  switch_core_hash_this(hi, NULL, NULL, &val);
2711  head = (switch_codec_node_t *) val;
2712 
2713  for (node = head; node; node = node->next) {
2714  codec_interface = (switch_codec_interface_t *) node->ptr;
2715 
2716  /* Look for the default ptime of the codec because it's the safest choice */
2717  for (imp = codec_interface->implementations; imp; imp = imp->next) {
2718  uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode);
2719 
2720  if (imp->microseconds_per_packet / 1000 == (int)default_ptime) {
2721  array[i++] = imp;
2722  goto found;
2723  }
2724  }
2725  /* oh well we will use what we have */
2726  array[i++] = codec_interface->implementations;
2727  }
2728 
2729  found:
2730 
2731  if (i > arraylen) {
2732  break;
2733  }
2734 
2735  }
2736  switch_safe_free(hi);
2737 
2739 
2741 
2742  return i;
2743 
2744 }
2745 
2746 SWITCH_DECLARE(char *) switch_parse_codec_buf(char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit, uint32_t *channels, char **modname, char **fmtp)
2747 {
2748  char *cur, *next = NULL, *name, *p;
2749 
2750  name = next = cur = buf;
2751 
2752  *channels = 1;
2753 
2754  for (;;) {
2755  if (!next) {
2756  break;
2757  }
2758 
2759  if ((p = strchr(next, '@'))) {
2760  *p++ = '\0';
2761  }
2762  next = p;
2763 
2764  if (cur != name) {
2765  if (strchr(cur, 'i')) {
2766  *interval = atoi(cur);
2767  } else if ((strchr(cur, 'k') || strchr(cur, 'h'))) {
2768  *rate = atoi(cur);
2769  } else if (strchr(cur, 'b')) {
2770  *bit = atoi(cur);
2771  } else if (strchr(cur, 'c')) {
2772  *channels = atoi(cur);
2773  } else {
2774  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad syntax for codec string. Missing qualifier [h|k|i|b|c] for part [%s]!\n", cur);
2775  }
2776  }
2777  cur = next;
2778  }
2779 
2780  if ((p = strchr(name, '.'))) {
2781  *p++ = '\0';
2782  *modname = name;
2783  name = p;
2784  }
2785 
2786  if ((p = strchr(name, '~'))) {
2787  *p++ = '\0';
2788  if (fmtp) {
2789  *fmtp = p;
2790  }
2791  }
2792 
2793  return name;
2794 }
2795 
2796 SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, char fmtp_array[SWITCH_MAX_CODECS][MAX_FMTP_LEN], int arraylen, char **prefs, int preflen)
2797 {
2798  int x, i = 0, j = 0;
2799  switch_codec_interface_t *codec_interface;
2800  const switch_codec_implementation_t *imp;
2801 
2803 
2804  for (x = 0; x < preflen; x++) {
2805  char *name, buf[256], jbuf[256], *modname = NULL, *fmtp = NULL;
2806  uint32_t interval = 0, rate = 0, bit = 0, channels = 1;
2807 
2808  switch_copy_string(buf, prefs[x], sizeof(buf));
2809  name = switch_parse_codec_buf(buf, &interval, &rate, &bit, &channels, &modname, &fmtp);
2810 
2811  for(j = 0; j < x; j++) {
2812  char *jname, *jmodname = NULL, *jfmtp = NULL;
2813  uint32_t jinterval = 0, jrate = 0, jbit = 0, jchannels = 1;
2814  uint32_t ointerval = interval, orate = rate, ochannels = channels;
2815 
2816  if (ointerval == 0) {
2817  ointerval = switch_default_ptime(name, 0);
2818  }
2819 
2820  if (orate == 0) {
2821  orate = switch_default_rate(name, 0);
2822  }
2823 
2824  if (ochannels == 0) {
2825  ochannels = 1;
2826  }
2827 
2828  switch_copy_string(jbuf, prefs[j], sizeof(jbuf));
2829  jname = switch_parse_codec_buf(jbuf, &jinterval, &jrate, &jbit, &jchannels, &jmodname, &jfmtp);
2830 
2831  if (jinterval == 0) {
2832  jinterval = switch_default_ptime(jname, 0);
2833  }
2834 
2835  if (jrate == 0) {
2836  jrate = switch_default_rate(jname, 0);
2837  }
2838 
2839  if (jchannels == 0) {
2840  jchannels = 1;
2841  }
2842 
2843  if (!strcasecmp(name, jname) && ointerval == jinterval && orate == jrate && ochannels == jchannels &&
2844  !strcasecmp(switch_str_nil(fmtp), switch_str_nil(jfmtp))) {
2845  goto next_x;
2846  }
2847  }
2848 
2849  if ((codec_interface = switch_loadable_module_get_codec_interface(name, modname)) != 0) {
2850  /* If no specific codec interval is requested opt for the default above all else because lots of stuff assumes it */
2851  for (imp = codec_interface->implementations; imp; imp = imp->next) {
2852  uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode);
2853  uint32_t default_rate = switch_default_rate(imp->iananame, imp->ianacode);
2854 
2855  if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
2856  uint32_t crate = !strcasecmp(imp->iananame, "g722") ? imp->samples_per_second : imp->actual_samples_per_second;
2857 
2858  if ((!interval && (uint32_t) (imp->microseconds_per_packet / 1000) != default_ptime) ||
2859  (interval && (uint32_t) (imp->microseconds_per_packet / 1000) != interval)) {
2860  continue;
2861  }
2862 
2863  if (((!rate && crate != default_rate) || (rate && (uint32_t) imp->actual_samples_per_second != rate))) {
2864  continue;
2865  }
2866 
2867  if (bit && (uint32_t) imp->bits_per_second != bit) {
2868  continue;
2869  }
2870 
2871  if (channels && imp->number_of_channels != channels) {
2872  continue;
2873  }
2874  }
2875 
2876  if (!zstr(fmtp)) {
2877  switch_set_string(fmtp_array[i], fmtp);
2878  }
2879  array[i++] = imp;
2880  goto found;
2881 
2882  }
2883 
2884  /* Either looking for a specific interval or there was no interval specified and there wasn't one at the default ptime available */
2885  for (imp = codec_interface->implementations; imp; imp = imp->next) {
2886  if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
2887  uint32_t crate = !strcasecmp(imp->iananame, "g722") ? imp->samples_per_second : imp->actual_samples_per_second;
2888 
2889  if (interval && (uint32_t) (imp->microseconds_per_packet / 1000) != interval) {
2890  continue;
2891  }
2892 
2893  if (rate && (uint32_t) crate != rate) {
2894  continue;
2895  }
2896 
2897  if (bit && (uint32_t) imp->bits_per_second != bit) {
2898  continue;
2899  }
2900 
2901  if (channels && imp->number_of_channels != channels) {
2902  continue;
2903  }
2904  }
2905 
2906  array[i++] = imp;
2907  goto found;
2908 
2909  }
2910 
2911  found:
2912 
2913  UNPROTECT_INTERFACE(codec_interface);
2914 
2915  if (i > arraylen) {
2916  break;
2917  }
2918 
2919  }
2920 
2921  next_x:
2922 
2923  continue;
2924  }
2925 
2927 
2929 
2930  return i;
2931 }
2932 
2934 {
2936  switch_status_t status;
2937  char *arg_used;
2938  char *cmd_used;
2939 
2940  switch_assert(stream != NULL);
2941  switch_assert(stream->data != NULL);
2942  switch_assert(stream->write_function != NULL);
2943 
2944  if (strcasecmp(cmd, "console_complete")) {
2945  cmd_used = switch_strip_whitespace(cmd);
2946  arg_used = switch_strip_whitespace(arg);
2947  } else {
2948  cmd_used = (char *) cmd;
2949  arg_used = (char *) arg;
2950  }
2951 
2952 
2953  if (!stream->param_event) {
2955  }
2956 
2957  if (stream->param_event) {
2958  if (cmd_used && *cmd_used) {
2959  switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command", cmd_used);
2960  }
2961  if (arg_used && *arg_used) {
2962  switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command-Argument", arg_used);
2963  }
2964  }
2965 
2966 
2967  if (cmd_used && (api = switch_loadable_module_get_api_interface(cmd_used)) != 0) {
2968  if ((status = api->function(arg_used, session, stream)) != SWITCH_STATUS_SUCCESS) {
2969  stream->write_function(stream, "COMMAND RETURNED ERROR!\n");
2970  }
2971  UNPROTECT_INTERFACE(api);
2972  } else {
2973  status = SWITCH_STATUS_FALSE;
2974  stream->write_function(stream, "INVALID COMMAND!\n");
2975  }
2976 
2977  if (stream->param_event) {
2978  switch_event_fire(&stream->param_event);
2979  }
2980 
2981  if (cmd_used != cmd) {
2982  switch_safe_free(cmd_used);
2983  }
2984 
2985  if (arg_used != arg) {
2986  switch_safe_free(arg_used);
2987  }
2988 
2989  return status;
2990 }
2991 
2993 {
2994  switch_json_api_interface_t *json_api;
2995  switch_status_t status;
2996  cJSON *function, *json_reply = NULL;
2997 
2998  switch_assert(json);
2999 
3000  function = cJSON_GetObjectItem(json, "command");
3001 
3002  if (function && function->valuestring
3003  && cJSON_GetObjectItem(json, "data") && (json_api = switch_loadable_module_get_json_api_interface(function->valuestring)) != 0) {
3004  if ((status = json_api->function(json, session, &json_reply)) != SWITCH_STATUS_SUCCESS) {
3005  cJSON_AddItemToObject(json, "status", cJSON_CreateString("error"));
3006  cJSON_AddItemToObject(json, "message", cJSON_CreateString("The command returned an error"));
3007  } else {
3008  cJSON_AddItemToObject(json, "status", cJSON_CreateString("success"));
3009  }
3010 
3011  if (!json_reply) {
3012  json_reply = cJSON_CreateNull();
3013  }
3014 
3015  if (retval) {
3016  *retval = json_reply;
3017  } else {
3018  cJSON_AddItemToObject(json, "response", json_reply);
3019  }
3020 
3021  UNPROTECT_INTERFACE(json_api);
3022  } else {
3023  status = SWITCH_STATUS_FALSE;
3024  cJSON_AddItemToObject(json, "status", cJSON_CreateString("error"));
3025  cJSON_AddItemToObject(json, "message", cJSON_CreateString("Invalid request or non-existant command"));
3026  cJSON_AddItemToObject(json, "response", cJSON_CreateNull());
3027  }
3028 
3029  return status;
3030 }
3031 
3032 
3034 {
3036 
3038  switch_assert(mod != NULL);
3039 
3040  mod->pool = pool;
3041 
3042  mod->module_name = switch_core_strdup(mod->pool, name);
3044  return mod;
3045 }
3046 
3047 #define ALLOC_INTERFACE(_TYPE_) { \
3048  switch_##_TYPE_##_interface_t *i, *ptr; \
3049  i = switch_core_alloc(mod->pool, sizeof(switch_##_TYPE_##_interface_t)); \
3050  switch_assert(i != NULL); \
3051  for (ptr = mod->_TYPE_##_interface; ptr && ptr->next; ptr = ptr->next); \
3052  if (ptr) { \
3053  ptr->next = i; \
3054  } else { \
3055  mod->_TYPE_##_interface = i; \
3056  } \
3057  switch_thread_rwlock_create(&i->rwlock, mod->pool); \
3058  switch_mutex_init(&i->reflock, SWITCH_MUTEX_NESTED, mod->pool); \
3059  i->parent = mod; \
3060  return i; }
3061 
3062 
3064 {
3065 
3066  switch (iname) {
3068  ALLOC_INTERFACE(endpoint)
3069 
3071  ALLOC_INTERFACE(timer)
3072 
3074  ALLOC_INTERFACE(dialplan)
3075 
3077  ALLOC_INTERFACE(codec)
3078 
3080  ALLOC_INTERFACE(application)
3081 
3083  ALLOC_INTERFACE(chat_application)
3084 
3085  case SWITCH_API_INTERFACE:
3086  ALLOC_INTERFACE(api)
3087 
3089  ALLOC_INTERFACE(json_api)
3090 
3091  case SWITCH_FILE_INTERFACE:
3092  ALLOC_INTERFACE(file)
3093 
3095  ALLOC_INTERFACE(speech)
3096 
3098  ALLOC_INTERFACE(directory)
3099 
3100  case SWITCH_CHAT_INTERFACE:
3101  ALLOC_INTERFACE(chat)
3102 
3103  case SWITCH_SAY_INTERFACE:
3104  ALLOC_INTERFACE(say)
3105 
3106  case SWITCH_ASR_INTERFACE:
3107  ALLOC_INTERFACE(asr)
3108 
3110  ALLOC_INTERFACE(management)
3111 
3113  ALLOC_INTERFACE(limit)
3114 
3116  ALLOC_INTERFACE(database)
3117 
3118  default:
3119  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Module Type!\n");
3120  return NULL;
3121  }
3122 }
3123 
3125  char *ext;
3126  int cnt;
3127  struct switch_stream_handle stream;
3129 };
3130 
3132 {
3133  char *ret = NULL;
3134 
3135  if (sh->param_event) {
3136  ret = switch_event_get_header(sh->param_event, var);
3137  }
3138 
3139  return ret;
3140 
3141 }
3142 
3144 {
3145  return (char *) sh->stream.data;
3146 }
3147 
3149 {
3150  char *path;
3151 
3152  switch_assert(sh);
3153  path = (char *) sh->stream.data;
3154  sh->stream.data = NULL;
3155  return path;
3156 }
3157 
3158 
3160 {
3161  switch_assert(sh);
3162 
3163  switch_safe_free((*sh)->stream.data);
3164  switch_safe_free((*sh)->ext);
3165 
3166  if ((*sh)->param_event) {
3167  switch_event_destroy(&(*sh)->param_event);
3168  }
3169  free(*sh);
3170  *sh = NULL;
3171 }
3172 
3174 {
3175  switch_assert(sh);
3176 
3177  if (zstr(ext)) {
3178  ext = "wav";
3179  }
3180 
3181  *sh = malloc(sizeof(**sh));
3182  memset(*sh, 0, sizeof(**sh));
3183 
3184  SWITCH_STANDARD_STREAM((*sh)->stream);
3185 
3186  if (var_event) {
3187  (*sh)->param_event = *var_event;
3188  *var_event = NULL;
3189  }
3190 
3191  (*sh)->ext = strdup(ext);
3192 
3193  return SWITCH_STATUS_SUCCESS;
3194 }
3195 
3197 {
3198  char buf[256] = "";
3199  va_list ap;
3200 
3201  va_start(ap, fmt);
3202 
3203  if (switch_vsnprintf(buf, sizeof(buf), fmt, ap) > 0) {
3204  if (!sh->cnt++) {
3205  sh->stream.write_function(&sh->stream, "file_string://%s.%s", buf, sh->ext);
3206  } else if (strstr(buf, "://")) {
3207  sh->stream.write_function(&sh->stream, "!%s", buf);
3208  } else {
3209  sh->stream.write_function(&sh->stream, "!%s.%s", buf, sh->ext);
3210  }
3211  }
3212 
3213  va_end(ap);
3214 }
3215 
3217 {
3219 
3223 
3224  return cb;
3225 }
3226 
3227 
3229 {
3231 
3232  switch_assert(cb);
3233 
3236  status = SWITCH_STATUS_FALSE;
3237  } else {
3239  }
3241 
3242  return status;
3243 }
3244 
3245 
3247 {
3251 }
3252 
3253 
3254 /* For Emacs:
3255  * Local Variables:
3256  * mode:c
3257  * indent-tabs-mode:t
3258  * tab-width:4
3259  * c-basic-offset:4
3260  * End:
3261  * For VIM:
3262  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3263  */
#define SWITCH_MAX_CODECS
Definition: switch_types.h:591
struct switch_database_interface * next
void * switch_core_hash_find_locked(_In_ switch_hash_t *hash, _In_z_ const char *key, _In_ switch_mutex_t *mutex)
Retrieve data from a given hash.
switch_loadable_module_type_t
List of loadable module types.
char * switch_say_file_handle_get_variable(switch_say_file_handle_t *sh, const char *var)
static struct switch_loadable_module_container loadable_modules
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
void switch_say_file(switch_say_file_handle_t *sh, const char *fmt,...)
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
A module interface to implement an application.
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:286
const char * switch_xml_attr_soft(_In_ switch_xml_t xml, _In_z_ const char *attr)
returns the value of the requested tag attribute, or "" if not found
switch_module_load_t switch_module_load
switch_memory_pool_t * pool
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
struct switch_directory_interface * next
#define switch_event_expand_headers(_event, _in)
Definition: switch_event.h:355
#define ALLOC_INTERFACE(_TYPE_)
#define SWITCH_THREAD_FUNC
Abstract interface to a limit module.
static int IDX
#define SWITCH_CHANNEL_LOG
static void chat_queue_message(switch_event_t **eventp)
switch_status_t switch_core_hash_destroy(_Inout_ switch_hash_t **hash)
Destroy an existing hash table.
switch_api_function_t function
switch_thread_rwlock_t * rwlock
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
switch_dialplan_interface_t * dialplan_interface
switch_json_api_interface_t * switch_loadable_module_get_json_api_interface(const char *name)
Retrieve the JSON API interface by it&#39;s registered name.
Abstraction of an module endpoint interface This is the glue between the abstract idea of a "channel"...
struct switch_database_node_s switch_database_node_t
switch_directory_interface_t * directory_interface
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1431
const switch_codec_interface_t * ptr
struct switch_management_interface * next
int switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, char fmtp_array[SWITCH_MAX_CODECS][MAX_FMTP_LEN], int arraylen, char **prefs, int preflen)
Retrieve the list of loaded codecs into an array based on another array showing the sorted order...
switch_thread_rwlock_t * rwlock
#define switch_core_session_hupall_matching_var(_vn, _vv, _c)
Definition: switch_core.h:1000
switch_core_recover_callback_t switch_core_get_secondary_recover_callback(const char *key)
switch_status_t switch_loadable_module_enumerate_available(const char *dir_path, switch_modulename_callback_func_t callback, void *user_data)
Enumerates a list of all modules discovered in a directory.
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
switch_status_t switch_loadable_module_build_dynamic(char *filename, switch_module_load_t switch_module_load, switch_module_runtime_t switch_module_runtime, switch_module_shutdown_t switch_module_shutdown, switch_bool_t runtime)
build a dynamic module object and register it (for use in double embeded modules) ...
cJSON *const to
switch_bool_t
Definition: switch_types.h:437
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
const cJSON *const b
Definition: switch_cJSON.h:243
switch_chat_application_function_t chat_application_function
switch_status_t switch_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream)
Execute a registered API command.
switch_codec_interface_t * codec_interface
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:683
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
struct switch_stream_handle stream
Representation of an event.
Definition: switch_event.h:80
A module interface to implement a chat application.
switch_codec_implementation_t * implementations
switch_status_t switch_event_add_body(switch_event_t *event, const char *fmt,...) PRINTF_FUNCTION(2
Add a body to an event.
struct switch_endpoint_interface * next
switch_status_t(* chat_send)(switch_event_t *message_event)
#define FREESWITCH_OID_PREFIX
Definition: switch.h:53
int msg_queue_len
switch_management_interface_t * switch_loadable_module_get_management_interface(const char *relative_oid)
Retrieve the management interface by it&#39;s registered name.
Abstract interface to a chat module.
char * switch_strip_whitespace(const char *str)
static void switch_loadable_module_sort_codecs(const switch_codec_implementation_t **array, int arraylen)
A representation of an XML tree.
Definition: switch_xml.h:79
Abstract interface to a dialplan module.
switch_status_t switch_queue_pop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1243
switch_status_t switch_json_api_execute(cJSON *json, switch_core_session_t *session, cJSON **retval)
Execute a registered JSON API command.
struct switch_speech_interface * next
A table of functions that a timer module implements.
void *SWITCH_THREAD_FUNC chat_thread_run(switch_thread_t *thread, void *obj)
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
switch_database_interface_t * database_interface
#define SWITCH_API_VERSION
pack cur
static switch_thread_t * thread
Definition: switch_log.c:486
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
struct switch_runtime runtime
Definition: switch_core.c:86
char * switch_parse_codec_buf(char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit, uint32_t *channels, char **modname, char **fmtp)
switch_status_t switch_loadable_module_protect(const char *mod)
Protect module from beeing unloaded.
switch_thread_rwlock_t * rwlock
Abstract interface to an asr module.
switch_thread_rwlock_t * rwlock
void switch_loadable_module_shutdown(void)
Shutdown the module backend and call the shutdown routine in all loaded modules.
switch_api_interface_t * switch_loadable_module_get_api_interface(const char *name)
Retrieve the API interface by it&#39;s registered name.
Abstract interface to a file format module.
switch_memory_pool_t * pool
Definition: switch_core.h:225
#define zstr(x)
Definition: switch_utils.h:314
static switch_status_t chat_process_event(switch_event_t **eventp)
int cJSON_bool fmt
Definition: switch_cJSON.h:150
struct switch_codec_node_s switch_codec_node_t
switch_memory_pool_t * pool
struct switch_json_api_interface * next
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_thread_t * msg_queue_thread[CHAT_MAX_MSG_QUEUE]
switch_status_t switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:250
struct switch_timer_interface * next
#define UNPROTECT_INTERFACE(_it)
switch_status_t switch_core_chat_send(const char *dest_proto, switch_event_t *message_event)
#define HASH_FUNC(_kind_)
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
void switch_core_unregister_secondary_recover_callback(const char *key)
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:260
switch_timer_interface_t * timer_interface
switch_status_t switch_loadable_module_unload_module(const char *dir, const char *fname, switch_bool_t force, const char **err)
Unoad a module.
switch_thread_rwlock_t * rwlock
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:124
switch_xml_t next
Definition: switch_xml.h:91
switch_chat_interface_t * switch_loadable_module_get_chat_interface(const char *name)
Retrieve the chat interface by it&#39;s registered name.
Abstract interface to a speech module.
switch_database_interface_t * switch_loadable_module_get_database_interface(const char *name, const char *modname)
Retrieve the database interface by it&#39;s registered name.
switch_byte_t switch_byte_t * buf
static switch_status_t switch_loadable_module_load_file(char *path, char *filename, switch_bool_t global, switch_loadable_module_t **new_module)
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
A module interface to implement an api function.
static void switch_loadable_module_runtime(void)
switch_status_t switch_core_hash_insert_locked(_In_ switch_hash_t *hash, _In_z_ const char *key, _In_opt_ const void *data, _In_opt_ switch_mutex_t *mutex)
Insert data into a hash.
#define CHAT_MAX_MSG_QUEUE
const switch_database_interface_t * ptr
struct switch_dialplan_interface * next
Abstract interface to a say module.
switch_status_t switch_say_file_handle_create(switch_say_file_handle_t **sh, const char *ext, switch_event_t **var_event)
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_core_flag_t switch_core_flags(void)
return core flags
Definition: switch_core.c:2988
void switch_dso_destroy(switch_dso_lib_t *lib)
Definition: switch_dso.c:91
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
Abstract interface to a management module.
switch_chat_interface_t * chat_interface
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:584
switch_speech_interface_t * speech_interface
#define CHAT_QUEUE_SIZE
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
struct switch_api_interface * next
switch_file_interface_t * switch_loadable_module_get_file_interface(const char *name, const char *modname)
Retrieve the file format interface by it&#39;s registered name.
static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t *old_module)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
Top level module interface to implement a series of codec implementations.
switch_endpoint_interface_t * endpoint_interface
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1379
int switch_loadable_module_get_codecs(const switch_codec_implementation_t **array, int arraylen)
Retrieve the list of loaded codecs into an array.
switch_status_t switch_loadable_module_exists(const char *mod)
Check if a module is loaded.
void switch_core_hash_this(_In_ switch_hash_index_t *hi, _Out_opt_ptrdiff_cap_(klen) const void **key, _Out_opt_ switch_ssize_t *klen, _Out_ void **val)
Gets the key and value of the current hash element.
switch_module_interface_name_t
Definition: switch_types.h:397
uintptr_t switch_size_t
struct switch_codec_interface * next
struct switch_chat_interface * next
switch_hash_index_t * switch_core_hash_next(_In_ switch_hash_index_t **hi)
Gets the next element of a hashtable.
uint32_t switch_default_ptime(const char *name, uint32_t number)
Definition: switch_core.c:2022
char * switch_say_file_handle_detach_path(switch_say_file_handle_t *sh)
switch_status_t switch_dir_open(switch_dir_t **new_dir, const char *dirname, switch_memory_pool_t *pool)
Definition: switch_apr.c:561
struct switch_chat_application_interface * next
struct switch_codec_node_s * next
void switch_cond_next(void)
Definition: switch_time.c:658
switch_queue_t * msg_queue[CHAT_MAX_MSG_QUEUE]
#define SWITCH_STANDARD_STREAM(s)
int(* switch_modulename_callback_func_t)(void *user_data, const char *module_name)
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
switch_thread_rwlock_t * rwlock
switch_dso_lib_t switch_dso_open(const char *path, int global, char **err)
Definition: switch_dso.c:101
void * objs[SWITCH_MAX_CORE_THREAD_SESSION_OBJS]
Definition: switch_core.h:222
switch_file_interface_t * file_interface
void * switch_core_hash_delete(_In_ switch_hash_t *hash, _In_z_ const char *key)
Delete data from a hash based on desired key.
switch_application_interface_t * application_interface
const char * switch_dir_next_file(switch_dir_t *thedir, char *buf, switch_size_t len)
Definition: switch_apr.c:618
switch_codec_interface_t * switch_loadable_module_get_codec_interface(const char *name, const char *modname)
Retrieve the codec interface by it&#39;s registered name.
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:82
switch_mutex_t * mutex
switch_limit_interface_t * limit_interface
switch_loadable_module_type_t type
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:993
switch_status_t switch_core_hash_insert_pointer(switch_hash_t *hash, const void *data)
Insert data into a hash with an auto-generated key based on the data pointer.
struct fspr_thread_mutex_t switch_mutex_t
Definition: switch_apr.h:314
switch_management_interface_t * management_interface
switch_status_t switch_loadable_module_load_module(const char *dir, const char *fname, switch_bool_t runtime, const char **err)
Load a module.
struct switch_database_node_s * next
switch_stream_handle_write_function_t write_function
switch_status_t
Common return values.
switch_chat_application_interface_t * switch_loadable_module_get_chat_application_interface(const char *name)
Retrieve the chat application interface by it&#39;s registered name.
const char *const const char *const path
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:287
switch_loadable_module_interface_t * module_interface
switch_endpoint_interface_t * switch_loadable_module_get_endpoint_interface(const char *name)
Retrieve the endpoint interface by it&#39;s registered name.
switch_say_interface_t * switch_loadable_module_get_say_interface(const char *name)
Retrieve the say interface by it&#39;s registered name.
switch_xml_t switch_xml_open_cfg(_In_z_ const char *file_path, _Out_ switch_xml_t *node, _In_opt_ switch_event_t *params)
open a config in the core registry
char * switch_say_file_handle_get_path(switch_say_file_handle_t *sh)
static switch_status_t do_chat_send(switch_event_t *message_event)
switch_thread_rwlock_t * rwlock
struct switch_file_node_s * next
switch_thread_t * switch_core_launch_thread(void *(SWITCH_THREAD_FUNC *func)(switch_thread_t *, void *), void *obj, switch_memory_pool_t *pool)
Launch a thread.
switch_status_t switch_core_chat_send_args(const char *dest_proto, const char *proto, const char *from, const char *to, const char *subject, const char *body, const char *type, const char *hint, switch_bool_t blocking)
switch_loadable_module_interface_t * switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name)
switch_json_api_interface_t * json_api_interface
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1479
Main Library Header.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
static switch_bool_t switch_is_file_path(const char *file)
int(* switch_core_recover_callback_t)(switch_core_session_t *session)
switch_status_t switch_core_register_secondary_recover_callback(const char *key, switch_core_recover_callback_t cb)
#define SWITCH_DECLARE(type)
const char * filename
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
static void *SWITCH_THREAD_FUNC switch_loadable_module_exec(switch_thread_t *thread, void *obj)
switch_status_t switch_loadable_module_enumerate_loaded(switch_modulename_callback_func_t callback, void *user_data)
Enumerates a list of all currently loaded modules.
static void do_swap(const switch_codec_implementation_t **array, int a, int b)
#define switch_set_string(_dst, _src)
Definition: switch_utils.h:734
switch_status_t switch_core_execute_chat_app(switch_event_t *message, const char *app, const char *data)
switch_status_t switch_queue_trypush(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1279
struct switch_say_interface * next
switch_thread_rwlock_t * rwlock
void switch_core_session_hupall_endpoint(const switch_endpoint_interface_t *endpoint_interface, switch_call_cause_t cause)
Hangup all sessions that belong to an endpoint.
char * buffer
Definition: switch_cJSON.h:153
struct switch_codec_implementation * next
static switch_status_t switch_loadable_module_process(char *key, switch_loadable_module_t *new_module, switch_hash_t *event_hash)
switch_module_runtime_t switch_module_runtime
switch_thread_rwlock_t * rwlock
char * key
Definition: switch_msrp.c:64
switch_status_t switch_loadable_module_init(switch_bool_t autoload)
Initilize the module backend and load all the modules.
A generic object to pass as a thread&#39;s session object to allow mutiple arguements and a pool...
Definition: switch_core.h:216
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1253
switch_status_t switch_core_chat_deliver(const char *dest_proto, switch_event_t **message_event)
void * switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err)
Definition: switch_dso.c:132
static void chat_thread_start(int idx)
struct switch_application_interface * next
void switch_cache_db_database_interface_flush_handles(switch_database_interface_t *database_interface)
switch_status_t switch_thread_rwlock_create(switch_thread_rwlock_t **rwlock, switch_memory_pool_t *pool)
Definition: switch_apr.c:235
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
switch_module_shutdown_t shutdown
#define MAX_FMTP_LEN
Definition: switch_types.h:245
switch_status_t switch_thread_exit(switch_thread_t *thd, switch_status_t retval)
Definition: switch_apr.c:1369
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char * switch_stristr(const char *instr, const char *str)
#define SWITCH_CURRENT_APPLICATION_VARIABLE
Definition: switch_types.h:142
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:665
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:698
A table of settings and callbacks that define a paticular implementation of a codec.
#define PROTECT_INTERFACE(_it)
A module interface to implement a json api function.
void * switch_dso_lib_t
Definition: switch_dso.h:30
const switch_file_interface_t * ptr
void switch_say_file_handle_destroy(switch_say_file_handle_t **sh)
struct switch_limit_interface * next
int count
Definition: switch_cJSON.h:204
struct fspr_pool_t switch_memory_pool_t
switch_api_interface_t * api_interface
const char *const name
Definition: switch_cJSON.h:250
switch_status_t switch_thread_rwlock_trywrlock_timeout(switch_thread_rwlock_t *rwlock, int timeout)
Definition: switch_apr.c:270
switch_status_t switch_queue_create(switch_queue_t **queue, unsigned int queue_capacity, switch_memory_pool_t *pool)
Definition: switch_apr.c:1233
void switch_core_set_signal_handlers(void)
Definition: switch_core.c:2579
void switch_event_destroy(switch_event_t **event)
Destroy an event.
switch_json_api_function_t function
static struct @6 chat_globals
int switch_vsnprintf(char *buf, switch_size_t len, const char *format, va_list ap)
Definition: switch_apr.c:217
switch_asr_interface_t * asr_interface
char * switch_core_sprintf(_In_ switch_memory_pool_t *pool, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the pool ...
#define switch_assert(expr)
struct fspr_thread_t switch_thread_t
Definition: switch_apr.h:941
const char * switch_cut_path(const char *in)
Create a pointer to the file name in a given file path eliminating the directory name.
switch_say_interface_t * say_interface
switch_module_shutdown_t switch_module_shutdown
switch_chat_application_interface_t * chat_application_interface
struct fspr_thread_rwlock_t switch_thread_rwlock_t
Definition: switch_apr.h:436
struct switch_file_interface * next
Abstract interface to a database module.
#define switch_core_hash_first(_h)
Definition: switch_core.h:1592
switch_thread_rwlock_t * rwlock
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
uint32_t switch_default_rate(const char *name, uint32_t number)
Definition: switch_core.c:2033
memset(buf, 0, buflen)
switch_status_t switch_core_sqldb_init(const char **err)
Definition: switch_core.c:2428
#define switch_core_hash_init_nocase(_hash)
Definition: switch_core.h:1432
static switch_status_t switch_loadable_module_load_module_ex(const char *dir, const char *fname, switch_bool_t runtime, switch_bool_t global, const char **err, switch_loadable_module_type_t type, switch_hash_t *event_hash)
The abstraction of a loadable module.
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, const char **err)
void * switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, switch_module_interface_name_t iname)
Abstract interface to a directory module.
struct switch_asr_interface * next
switch_status_t switch_thread_rwlock_trywrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:265
void switch_core_sqldb_destroy(void)
Definition: switch_core.c:3013
switch_status_t switch_dir_close(switch_dir_t *thedir)
Definition: switch_apr.c:582
struct switch_file_node_s switch_file_node_t