FreeSWITCH API Documentation  1.7.0
Data Structures | Macros | Typedefs | Functions | Variables
switch_loadable_module.c File Reference
#include <switch.h>
#include <apr_strings.h>
#include <apr_env.h>
#include <apr_file_io.h>
+ Include dependency graph for switch_loadable_module.c:

Go to the source code of this file.

Data Structures

struct  switch_file_node_s
 
struct  switch_codec_node_s
 
struct  switch_loadable_module
 
struct  switch_loadable_module_container
 
struct  switch_say_file_handle
 

Macros

#define CHAT_MAX_MSG_QUEUE   101
 
#define CHAT_QUEUE_SIZE   5000
 
#define HASH_FUNC(_kind_)
 
#define ALLOC_INTERFACE(_TYPE_)
 

Typedefs

typedef struct switch_file_node_s switch_file_node_t
 
typedef struct switch_codec_node_s switch_codec_node_t
 

Functions

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)
 
static switch_status_t switch_loadable_module_load_module_ex (char *dir, char *fname, switch_bool_t runtime, switch_bool_t global, const char **err)
 
static void *SWITCH_THREAD_FUNC switch_loadable_module_exec (switch_thread_t *thread, void *obj)
 
static void switch_loadable_module_runtime (void)
 
static switch_status_t switch_loadable_module_process (char *key, switch_loadable_module_t *new_module)
 
static switch_status_t do_chat_send (switch_event_t *message_event)
 
static switch_status_t chat_process_event (switch_event_t **eventp)
 
void *SWITCH_THREAD_FUNC chat_thread_run (switch_thread_t *thread, void *obj)
 
static void chat_thread_start (int idx)
 
static void chat_queue_message (switch_event_t **eventp)
 
switch_status_t switch_core_execute_chat_app (switch_event_t *message, const char *app, const char *data)
 
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_status_t switch_core_chat_send (const char *dest_proto, switch_event_t *message_event)
 
switch_status_t switch_core_chat_deliver (const char *dest_proto, switch_event_t **message_event)
 
static switch_status_t switch_loadable_module_unprocess (switch_loadable_module_t *old_module)
 
static switch_status_t switch_loadable_module_load_file (char *path, char *filename, switch_bool_t global, switch_loadable_module_t **new_module)
 
switch_status_t switch_loadable_module_load_module (char *dir, char *fname, switch_bool_t runtime, const char **err)
 Load a module. More...
 
switch_status_t switch_loadable_module_exists (const char *mod)
 Check if a module is loaded. More...
 
switch_status_t switch_loadable_module_unload_module (char *dir, char *fname, switch_bool_t force, const char **err)
 Unoad a module. More...
 
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. More...
 
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. More...
 
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) More...
 
switch_status_t switch_loadable_module_init (switch_bool_t autoload)
 Initilize the module backend and load all the modules. More...
 
void switch_loadable_module_shutdown (void)
 Shutdown the module backend and call the shutdown routine in all loaded modules. More...
 
switch_endpoint_interface_tswitch_loadable_module_get_endpoint_interface (const char *name)
 Retrieve the endpoint interface by it's registered name. More...
 
switch_file_interface_tswitch_loadable_module_get_file_interface (const char *name, const char *modname)
 Retrieve the file format interface by it's registered name. More...
 
switch_codec_interface_tswitch_loadable_module_get_codec_interface (const char *name, const char *modname)
 Retrieve the codec interface by it's registered name. More...
 
switch_say_interface_tswitch_loadable_module_get_say_interface (const char *name)
 Retrieve the say interface by it's registered name. More...
 
switch_management_interface_tswitch_loadable_module_get_management_interface (const char *relative_oid)
 Retrieve the management interface by it's registered name. More...
 
static void do_swap (const switch_codec_implementation_t **array, int a, int b)
 
static void switch_loadable_module_sort_codecs (const switch_codec_implementation_t **array, int arraylen)
 
int switch_loadable_module_get_codecs (const switch_codec_implementation_t **array, int arraylen)
 Retrieve the list of loaded codecs into an array. More...
 
char * switch_parse_codec_buf (char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit, uint32_t *channels, char **modname)
 
int switch_loadable_module_get_codecs_sorted (const switch_codec_implementation_t **array, int arraylen, char **prefs, int preflen)
 Retrieve the list of loaded codecs into an array based on another array showing the sorted order. More...
 
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. More...
 
switch_status_t switch_json_api_execute (cJSON *json, switch_core_session_t *session, cJSON **retval)
 Execute a registered JSON API command. More...
 
switch_loadable_module_interface_tswitch_loadable_module_create_module_interface (switch_memory_pool_t *pool, const char *name)
 
void * switch_loadable_module_create_interface (switch_loadable_module_interface_t *mod, switch_module_interface_name_t iname)
 
char * switch_say_file_handle_get_variable (switch_say_file_handle_t *sh, const char *var)
 
char * switch_say_file_handle_get_path (switch_say_file_handle_t *sh)
 
char * switch_say_file_handle_detach_path (switch_say_file_handle_t *sh)
 
void switch_say_file_handle_destroy (switch_say_file_handle_t **sh)
 
switch_status_t switch_say_file_handle_create (switch_say_file_handle_t **sh, const char *ext, switch_event_t **var_event)
 
void switch_say_file (switch_say_file_handle_t *sh, const char *fmt,...)
 
switch_core_recover_callback_t switch_core_get_secondary_recover_callback (const char *key)
 
switch_status_t switch_core_register_secondary_recover_callback (const char *key, switch_core_recover_callback_t cb)
 
void switch_core_unregister_secondary_recover_callback (const char *key)
 

Variables

static struct
switch_loadable_module_container 
loadable_modules
 
struct {
   switch_queue_t *   msg_queue [CHAT_MAX_MSG_QUEUE]
 
   switch_thread_t *   msg_queue_thread [CHAT_MAX_MSG_QUEUE]
 
   int   msg_queue_len
 
   switch_mutex_t *   mutex
 
   switch_memory_pool_t *   pool
 
   int   running
 
chat_globals
 
static int IDX = 0
 

Macro Definition Documentation

#define ALLOC_INTERFACE (   _TYPE_)
Value:
{ \
switch_##_TYPE_##_interface_t *i, *ptr; \
i = switch_core_alloc(mod->pool, sizeof(switch_##_TYPE_##_interface_t)); \
switch_assert(i != NULL); \
for (ptr = mod->_TYPE_##_interface; ptr && ptr->next; ptr = ptr->next); \
if (ptr) { \
ptr->next = i; \
} else { \
mod->_TYPE_##_interface = i; \
} \
switch_thread_rwlock_create(&i->rwlock, mod->pool); \
switch_mutex_init(&i->reflock, SWITCH_MUTEX_NESTED, mod->pool); \
i->parent = mod; \
return i; }
return
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
switch_status_t switch_thread_rwlock_create(switch_thread_rwlock_t **rwlock, switch_memory_pool_t *pool)
Definition: switch_apr.c:212
#define switch_assert(expr)

Definition at line 2634 of file switch_loadable_module.c.

Referenced by switch_loadable_module_create_interface().

#define CHAT_MAX_MSG_QUEUE   101

Definition at line 589 of file switch_loadable_module.c.

Referenced by chat_queue_message(), and chat_thread_start().

#define CHAT_QUEUE_SIZE   5000

Definition at line 590 of file switch_loadable_module.c.

Referenced by chat_thread_start().

#define HASH_FUNC (   _kind_)
Value:
SWITCH_DECLARE(switch_##_kind_##_interface_t *) switch_loadable_module_get_##_kind_##_interface(const char *name) \
{ \
switch_##_kind_##_interface_t *i = NULL; \
if (loadable_modules._kind_##_hash && (i = switch_core_hash_find_locked(loadable_modules._kind_##_hash, name, loadable_modules.mutex))) { \
PROTECT_INTERFACE(i); \
} \
return i; \
}
#define SWITCH_DECLARE(type)

Definition at line 2177 of file switch_loadable_module.c.

Typedef Documentation

Function Documentation

static switch_status_t chat_process_event ( switch_event_t **  eventp)
static

Definition at line 713 of file switch_loadable_module.c.

References do_chat_send(), switch_assert, and switch_event_destroy().

Referenced by chat_queue_message(), chat_thread_run(), and switch_core_chat_send_args().

714 {
715  switch_event_t *event;
716  switch_status_t status;
717 
718  switch_assert(eventp);
719 
720  event = *eventp;
721  *eventp = NULL;
722 
723  status = do_chat_send(event);
724  switch_event_destroy(&event);
725 
726  return status;
727 }
Representation of an event.
Definition: switch_event.h:80
switch_status_t
Common return values.
static switch_status_t do_chat_send(switch_event_t *message_event)
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)
static void chat_queue_message ( switch_event_t **  eventp)
static

Definition at line 784 of file switch_loadable_module.c.

References chat_globals, CHAT_MAX_MSG_QUEUE, chat_process_event(), chat_thread_start(), IDX, switch_assert, switch_mutex_lock(), switch_mutex_unlock(), switch_queue_push(), switch_queue_trypush(), and SWITCH_STATUS_SUCCESS.

Referenced by switch_core_chat_deliver(), switch_core_chat_send(), and switch_core_chat_send_args().

785 {
786  int idx = 0;
787  switch_event_t *event;
788 
789  switch_assert(eventp);
790 
791  event = *eventp;
792  *eventp = NULL;
793 
794  if (chat_globals.running == 0) {
795  chat_process_event(&event);
796  return;
797  }
798 
799  again:
800 
802  idx = IDX;
803  IDX++;
804  if (IDX >= chat_globals.msg_queue_len) IDX = 0;
806 
807  chat_thread_start(idx);
808 
809  if (switch_queue_trypush(chat_globals.msg_queue[idx], event) != SWITCH_STATUS_SUCCESS) {
810  if (chat_globals.msg_queue_len < CHAT_MAX_MSG_QUEUE) {
811  chat_thread_start(idx + 1);
812  goto again;
813  } else {
814  switch_queue_push(chat_globals.msg_queue[idx], event);
815  }
816  }
817 }
static int IDX
Representation of an event.
Definition: switch_event.h:80
static switch_status_t chat_process_event(switch_event_t **eventp)
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
#define CHAT_MAX_MSG_QUEUE
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
static struct @5 chat_globals
switch_status_t switch_queue_trypush(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1155
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1129
static void chat_thread_start(int idx)
#define switch_assert(expr)
void* SWITCH_THREAD_FUNC chat_thread_run ( switch_thread_t thread,
void *  obj 
)

Definition at line 730 of file switch_loadable_module.c.

References chat_process_event(), SWITCH_CHANNEL_LOG, switch_cond_next(), SWITCH_LOG_DEBUG, switch_log_printf(), switch_queue_pop(), and SWITCH_STATUS_SUCCESS.

Referenced by chat_thread_start().

731 {
732  void *pop;
733  switch_queue_t *q = (switch_queue_t *) obj;
734 
735  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Chat Thread Started\n");
736 
737 
738  while(switch_queue_pop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
739  switch_event_t *event = (switch_event_t *) pop;
740  chat_process_event(&event);
742  }
743 
744  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Chat Thread Ended\n");
745 
746  return NULL;
747 }
struct apr_queue_t switch_queue_t
Definition: switch_apr.h:590
#define SWITCH_CHANNEL_LOG
Representation of an event.
Definition: switch_event.h:80
switch_status_t switch_queue_pop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1119
static switch_status_t chat_process_event(switch_event_t **eventp)
void switch_cond_next(void)
Definition: switch_time.c:638
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.
static void chat_thread_start ( int  idx)
static

Definition at line 750 of file switch_loadable_module.c.

References chat_globals, CHAT_MAX_MSG_QUEUE, CHAT_QUEUE_SIZE, chat_thread_run(), switch_mutex_lock(), switch_mutex_unlock(), switch_queue_create(), switch_thread_create(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), and switch_threadattr_stacksize_set().

Referenced by chat_queue_message(), and switch_loadable_module_init().

751 {
752 
753  if (idx >= CHAT_MAX_MSG_QUEUE || (idx < chat_globals.msg_queue_len && chat_globals.msg_queue_thread[idx])) {
754  return;
755  }
756 
758 
759  if (idx >= chat_globals.msg_queue_len) {
760  int i;
761  chat_globals.msg_queue_len = idx + 1;
762 
763  for (i = 0; i < chat_globals.msg_queue_len; i++) {
764  if (!chat_globals.msg_queue[i]) {
765  switch_threadattr_t *thd_attr = NULL;
766 
768 
769  switch_threadattr_create(&thd_attr, chat_globals.pool);
771  switch_thread_create(&chat_globals.msg_queue_thread[i],
772  thd_attr,
774  chat_globals.msg_queue[i],
775  chat_globals.pool);
776  }
777  }
778  }
779 
781 }
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
void *SWITCH_THREAD_FUNC chat_thread_run(switch_thread_t *thread, void *obj)
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
#define CHAT_MAX_MSG_QUEUE
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
#define CHAT_QUEUE_SIZE
static struct @5 chat_globals
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:642
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:675
switch_status_t switch_queue_create(switch_queue_t **queue, unsigned int queue_capacity, switch_memory_pool_t *pool)
Definition: switch_apr.c:1109
static switch_status_t do_chat_send ( switch_event_t message_event)
static

Definition at line 604 of file switch_loadable_module.c.

References switch_loadable_module_container::chat_hash, switch_chat_interface::chat_send, switch_chat_interface::interface_name, loadable_modules, switch_loadable_module_container::mutex, SWITCH_CHANNEL_LOG, switch_core_hash_first, switch_core_hash_next(), switch_core_hash_this(), switch_event_add_header_string(), switch_event_dup(), switch_event_fire, switch_event_get_header, switch_loadable_module_get_chat_interface(), SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_safe_free, SWITCH_STACK_BOTTOM, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_stristr(), switch_true(), and UNPROTECT_INTERFACE.

Referenced by chat_process_event().

606 {
610  switch_event_t *dup = NULL;
611  const void *var;
612  void *val;
613  const char *proto;
614  const char *replying;
615  const char *dest_proto;
616  int do_skip = 0;
617 
618  /*
619 
620  const char *from;
621  const char *to;
622  const char *subject;
623  const char *body;
624  const char *type;
625  const char *hint;
626  */
627 
628  dest_proto = switch_event_get_header(message_event, "dest_proto");
629 
630  if (!dest_proto) {
631  return SWITCH_STATUS_FALSE;
632  }
633 
634  /*
635 
636  from = switch_event_get_header(message_event, "from");
637  to = switch_event_get_header(message_event, "to");
638  subject = switch_event_get_header(message_event, "subject");
639  body = switch_event_get_body(message_event);
640  type = switch_event_get_header(message_event, "type");
641  hint = switch_event_get_header(message_event, "hint");
642  */
643 
644  if (!(proto = switch_event_get_header(message_event, "proto"))) {
645  proto = "global";
646  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto);
647  }
648 
649  replying = switch_event_get_header(message_event, "replying");
650 
651  if (!switch_true(replying) && !switch_stristr("global", proto) && !switch_true(switch_event_get_header(message_event, "skip_global_process"))) {
654  switch_core_hash_this(hi, &var, NULL, &val);
655 
656  if ((ci = (switch_chat_interface_t *) val)) {
657  if (ci->chat_send && !strncasecmp(ci->interface_name, "GLOBAL_", 7)) {
658  status = ci->chat_send(message_event);
659 
660  if (status == SWITCH_STATUS_SUCCESS) {
661  if (switch_true(switch_event_get_header(message_event, "final_delivery"))) {
662  /* The event was handled by an extension in the chatplan,
663  * so the event will be duplicated, modified and queued again,
664  * but it won't be processed by the chatplan again.
665  * So this copy of the event can be destroyed by the caller.
666  */
667  do_skip = 1;
668  }
669  } else if (status == SWITCH_STATUS_BREAK) {
670  /* The event went through the chatplan, but no extension matched
671  * to handle the sms messsage. It'll be attempted to be delivered
672  * directly, and unless that works the sms delivery will have failed.
673  */
674  } else {
675  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Chat Interface Error [%s]!\n", dest_proto);
676  break;
677  }
678  }
679  }
680  }
681  switch_safe_free(hi);
683  }
684 
685 
686  if (!do_skip && !switch_stristr("GLOBAL", dest_proto)) {
687  if ((ci = switch_loadable_module_get_chat_interface(dest_proto)) && ci->chat_send) {
688  status = ci->chat_send(message_event);
690  } else {
691  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid chat interface [%s]!\n", dest_proto);
692  status = SWITCH_STATUS_FALSE;
693  }
694  }
695 
696 
697  switch_event_dup(&dup, message_event);
698 
699  if ( switch_true(switch_event_get_header(message_event, "blocking")) ) {
700  if (status == SWITCH_STATUS_SUCCESS) {
701  switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "false");
702  } else {
703  switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "true");
704  }
705  } else {
706  switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Nonblocking-Delivery", "true");
707  }
708 
709  switch_event_fire(&dup);
710  return status;
711 }
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:412
#define SWITCH_CHANNEL_LOG
switch_status_t(* chat_send)(switch_event_t *message_event)
Representation of an event.
Definition: switch_event.h:80
Abstract interface to a chat module.
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
#define UNPROTECT_INTERFACE(_it)
switch_chat_interface_t * switch_loadable_module_get_chat_interface(const char *name)
Retrieve the chat interface by it's registered name.
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
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.
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
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_hash_index_t * switch_core_hash_next(_In_ switch_hash_index_t **hi)
Gets the next element of a hashtable.
switch_status_t
Common return values.
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
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_core_hash_first(_h)
Definition: switch_core.h:1501
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 
)
static

Definition at line 1993 of file switch_loadable_module.c.

References switch_loadable_module::lib, switch_loadable_module::module_interface, switch_loadable_module_interface::module_name, switch_loadable_module::pool, pool, switch_loadable_module_interface::rwlock, SCF_VG, switch_loadable_module::shutting_down, switch_loadable_module::status, switch_assert, SWITCH_CHANNEL_LOG, switch_core_destroy_memory_pool, switch_core_flags(), switch_dso_destroy(), switch_loadable_module_unprocess(), SWITCH_LOG_CONSOLE, switch_log_printf(), SWITCH_LOG_WARNING, switch_loadable_module::switch_module_shutdown, SWITCH_STATUS_FALSE, SWITCH_STATUS_NOUNLOAD, SWITCH_STATUS_SUCCESS, switch_thread_join(), switch_thread_rwlock_trywrlock(), switch_thread_rwlock_unlock(), SWITCH_TRUE, and switch_loadable_module::thread.

Referenced by switch_loadable_module_shutdown(), and switch_loadable_module_unload_module().

1995 {
1996  int32_t flags = switch_core_flags();
1997  switch_assert(module != NULL);
1998 
2000  if (err) {
2001  *err = "Module in use.";
2002  }
2003  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Module %s is in use, cannot unload.\n", module->module_interface->module_name);
2004  return SWITCH_STATUS_FALSE;
2005  }
2006 
2007  module->shutting_down = SWITCH_TRUE;
2008 
2009  if (shutdown) {
2011  if (module->switch_module_shutdown) {
2013  module->status = module->switch_module_shutdown();
2014  } else {
2015  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s has no shutdown routine\n", module->module_interface->module_name);
2016  }
2017  }
2018 
2019  if (fail_if_busy && module->module_interface->rwlock) {
2021  }
2022 
2023  if (unload && module->status != SWITCH_STATUS_NOUNLOAD && !(flags & SCF_VG)) {
2025  switch_status_t st;
2026 
2027  if (module->thread) {
2028  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s stopping runtime thread.\n", module->module_interface->module_name);
2029  switch_thread_join(&st, module->thread);
2030  }
2031 
2033  switch_dso_destroy(&module->lib);
2034  if ((pool = module->pool)) {
2035  module = NULL;
2037  }
2038  }
2039 
2040  return SWITCH_STATUS_SUCCESS;
2041 
2042 }
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
switch_memory_pool_t * pool
#define SWITCH_CHANNEL_LOG
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1255
switch_core_flag_t switch_core_flags(void)
return core flags
Definition: switch_core.c:2852
void switch_dso_destroy(switch_dso_lib_t *lib)
Definition: switch_dso.c:87
static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t *old_module)
switch_status_t
Common return values.
switch_loadable_module_interface_t * module_interface
struct apr_pool_t switch_memory_pool_t
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.
#define switch_assert(expr)
switch_module_shutdown_t switch_module_shutdown
switch_status_t switch_thread_rwlock_trywrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:242
static void do_swap ( const switch_codec_implementation_t **  array,
int  a,
int  b 
)
static

Definition at line 2223 of file switch_loadable_module.c.

Referenced by switch_loadable_module_sort_codecs().

2224 {
2225  const switch_codec_implementation_t *tmp = array[b];
2226  array[b] = array[a];
2227  array[a] = tmp;
2228 }
A table of settings and callbacks that define a paticular implementation of a codec.
switch_core_recover_callback_t switch_core_get_secondary_recover_callback ( const char *  key)

Definition at line 2802 of file switch_loadable_module.c.

References loadable_modules, switch_loadable_module_container::mutex, switch_loadable_module_container::secondary_recover_hash, switch_core_hash_find(), switch_mutex_lock(), and switch_mutex_unlock().

Referenced by recover_callback().

2803 {
2805 
2809 
2810  return cb;
2811 }
static struct switch_loadable_module_container loadable_modules
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
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 
)

Definition at line 2814 of file switch_loadable_module.c.

References loadable_modules, switch_loadable_module_container::mutex, switch_loadable_module_container::secondary_recover_hash, switch_assert, switch_core_hash_find(), switch_core_hash_insert, switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

2815 {
2817 
2818  switch_assert(cb);
2819 
2822  status = SWITCH_STATUS_FALSE;
2823  } else {
2825  }
2827 
2828  return status;
2829 }
static struct switch_loadable_module_container loadable_modules
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_status_t
Common return values.
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1410
#define switch_assert(expr)
void switch_core_unregister_secondary_recover_callback ( const char *  key)

Definition at line 2832 of file switch_loadable_module.c.

References loadable_modules, switch_loadable_module_container::mutex, switch_loadable_module_container::secondary_recover_hash, switch_core_hash_delete(), switch_mutex_lock(), and switch_mutex_unlock().

2833 {
2837 }
static struct switch_loadable_module_container loadable_modules
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
void * switch_core_hash_delete(_In_ switch_hash_t *hash, _In_z_ const char *key)
Delete data from a hash based on desired key.
static void* SWITCH_THREAD_FUNC switch_loadable_module_exec ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 100 of file switch_loadable_module.c.

References switch_loadable_module::module_interface, switch_loadable_module_interface::module_name, switch_core_thread_session::objs, switch_core_thread_session::pool, pool, switch_loadable_module::shutting_down, switch_assert, SWITCH_CHANNEL_LOG, switch_core_destroy_memory_pool, SWITCH_LOG_DEBUG, SWITCH_LOG_NOTICE, switch_log_printf(), switch_loadable_module::switch_module_runtime, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TERM, and switch_thread_exit().

Referenced by switch_loadable_module_build_dynamic(), switch_loadable_module_load_module_ex(), and switch_loadable_module_runtime().

101 {
102 
103 
106  switch_loadable_module_t *module = ts->objs[0];
107  int restarts;
108 
109  switch_assert(thread != NULL);
110  switch_assert(module != NULL);
111 
112  for (restarts = 0; status != SWITCH_STATUS_TERM && !module->shutting_down; restarts++) {
113  status = module->switch_module_runtime();
114  }
116 
117  if (ts->pool) {
119  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Destroying Pool for %s\n", module->module_interface->module_name);
121  }
123  return NULL;
124 }
#define SWITCH_CHANNEL_LOG
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
static switch_thread_t * thread
Definition: switch_log.c:279
switch_memory_pool_t * pool
Definition: switch_core.h:223
switch_memory_pool_t * pool
switch_status_t switch_thread_exit(switch_thread_t *thd, switch_status_t retval)
Definition: switch_apr.c:1245
void * objs[SWITCH_MAX_CORE_THREAD_SESSION_OBJS]
Definition: switch_core.h:220
switch_status_t
Common return values.
switch_loadable_module_interface_t * module_interface
switch_module_runtime_t switch_module_runtime
A generic object to pass as a thread's session object to allow mutiple arguements and a pool...
Definition: switch_core.h:214
struct apr_pool_t switch_memory_pool_t
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.
#define switch_assert(expr)
static switch_status_t switch_loadable_module_load_file ( char *  path,
char *  filename,
switch_bool_t  global,
switch_loadable_module_t **  new_module 
)
static

Definition at line 1401 of file switch_loadable_module.c.

References switch_loadable_module::filename, switch_loadable_module::lib, switch_directories::lib_dir, switch_loadable_module_function_table::load, switch_loadable_module::module_interface, switch_loadable_module_interface::module_name, switch_loadable_module::perm, switch_loadable_module::pool, pool, switch_loadable_module_function_table::runtime, switch_loadable_module_function_table::shutdown, SMODF_GLOBAL_SYMBOLS, SWITCH_API_VERSION, switch_loadable_module_function_table::switch_api_version, switch_assert, SWITCH_CHANNEL_LOG, switch_core_alloc, switch_core_destroy_memory_pool, switch_core_new_memory_pool, switch_core_set_signal_handlers(), switch_core_sprintf(), switch_core_strdup, switch_dso_data_sym(), switch_dso_destroy(), switch_dso_open(), SWITCH_GLOBAL_dirs, SWITCH_LOG_CONSOLE, SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG, switch_log_printf(), switch_loadable_module::switch_module_load, switch_loadable_module::switch_module_runtime, switch_loadable_module::switch_module_shutdown, switch_mprintf(), switch_safe_free, SWITCH_STATUS_GENERR, SWITCH_STATUS_NOUNLOAD, SWITCH_STATUS_SUCCESS, switch_test_flag, and SWITCH_TRUE.

Referenced by switch_loadable_module_load_module_ex().

1402 {
1403  switch_loadable_module_t *module = NULL;
1404  switch_dso_lib_t dso = NULL;
1405  apr_status_t status = SWITCH_STATUS_SUCCESS;
1406  switch_loadable_module_function_table_t *interface_struct_handle = NULL;
1407  switch_loadable_module_function_table_t *mod_interface_functions = NULL;
1408  char *struct_name = NULL;
1409  switch_module_load_t load_func_ptr = NULL;
1410  int loading = 1;
1411  switch_loadable_module_interface_t *module_interface = NULL;
1412  char *derr = NULL;
1413  const char *err = NULL;
1414  switch_memory_pool_t *pool = NULL;
1415  switch_bool_t load_global = global;
1416 
1417  switch_assert(path != NULL);
1418 
1420  *new_module = NULL;
1421 
1422  struct_name = switch_core_sprintf(pool, "%s_module_interface", filename);
1423 
1424 #ifdef WIN32
1425  dso = switch_dso_open("FreeSwitch.dll", load_global, &derr);
1426 #elif defined (MACOSX) || defined(DARWIN)
1427  {
1428  char *lib_path = switch_mprintf("%s/libfreeswitch.dylib", SWITCH_GLOBAL_dirs.lib_dir);
1429  dso = switch_dso_open(lib_path, load_global, &derr);
1430  switch_safe_free(lib_path);
1431  }
1432 #else
1433  dso = switch_dso_open(NULL, load_global, &derr);
1434 #endif
1435  if (!derr && dso) {
1436  interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
1437  }
1438 
1439  switch_safe_free(derr);
1440 
1441  if (!interface_struct_handle) {
1442  if (dso) switch_dso_destroy(&dso);
1443  dso = switch_dso_open(path, load_global, &derr);
1444  }
1445 
1446  while (loading) {
1447  if (derr) {
1448  err = derr;
1449  break;
1450  }
1451 
1452  if (!interface_struct_handle) {
1453  interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
1454  }
1455 
1456  if (derr) {
1457  err = derr;
1458  break;
1459  }
1460 
1461  if (interface_struct_handle && interface_struct_handle->switch_api_version != SWITCH_API_VERSION) {
1462  err = "Trying to load an out of date module, please rebuild the module.";
1463  break;
1464  }
1465 
1466  if (!load_global && interface_struct_handle && switch_test_flag(interface_struct_handle, SMODF_GLOBAL_SYMBOLS)) {
1467  load_global = SWITCH_TRUE;
1468  switch_dso_destroy(&dso);
1469  interface_struct_handle = NULL;
1470  dso = switch_dso_open(path, load_global, &derr);
1471  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading module with global namespace at request of module\n");
1472  continue;
1473  }
1474 
1475  if (interface_struct_handle) {
1476  mod_interface_functions = interface_struct_handle;
1477  load_func_ptr = mod_interface_functions->load;
1478  }
1479 
1480  if (load_func_ptr == NULL) {
1481  err = "Cannot locate symbol 'switch_module_load' please make sure this is a valid module.";
1482  break;
1483  }
1484 
1485  status = load_func_ptr(&module_interface, pool);
1486 
1487  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_NOUNLOAD) {
1488  err = "Module load routine returned an error";
1489  module_interface = NULL;
1490  break;
1491  }
1492 
1493  if (!module_interface) {
1494  err = "Module failed to initialize its module_interface. Is this a valid module?";
1495  break;
1496  }
1497 
1498  if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))) == 0) {
1499  err = "Could not allocate memory\n";
1500  abort();
1501  }
1502 
1503  if (status == SWITCH_STATUS_NOUNLOAD) {
1504  module->perm++;
1505  }
1506 
1507  loading = 0;
1508  }
1509 
1510 
1511  if (err) {
1512 
1513  if (dso) {
1514  switch_dso_destroy(&dso);
1515  }
1516 
1517  if (pool) {
1519  }
1520  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Loading module %s\n**%s**\n", path, err);
1521  switch_safe_free(derr);
1522  return SWITCH_STATUS_GENERR;
1523  }
1524 
1525  module->pool = pool;
1526  module->filename = switch_core_strdup(module->pool, path);
1527  module->module_interface = module_interface;
1528  module->switch_module_load = load_func_ptr;
1529 
1530  if (mod_interface_functions) {
1531  module->switch_module_shutdown = mod_interface_functions->shutdown;
1532  module->switch_module_runtime = mod_interface_functions->runtime;
1533  }
1534 
1535  module->lib = dso;
1536 
1537  *new_module = module;
1538  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
1539 
1541 
1542  return SWITCH_STATUS_SUCCESS;
1543 
1544 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
switch_module_load_t switch_module_load
switch_memory_pool_t * pool
#define SWITCH_CHANNEL_LOG
switch_bool_t
Definition: switch_types.h:405
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
#define SWITCH_API_VERSION
switch_memory_pool_t * pool
void switch_dso_destroy(switch_dso_lib_t *lib)
Definition: switch_dso.c:87
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_dso_lib_t switch_dso_open(const char *path, int global, char **err)
Definition: switch_dso.c:95
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
switch_loadable_module_interface_t * module_interface
switch_module_runtime_t switch_module_runtime
void * switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err)
Definition: switch_dso.c:126
struct apr_pool_t switch_memory_pool_t
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
switch_module_shutdown_t shutdown
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.
void * switch_dso_lib_t
Definition: switch_dso.h:30
void switch_core_set_signal_handlers(void)
Definition: switch_core.c:2494
char * filename
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)
switch_module_shutdown_t switch_module_shutdown
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
The abstraction of a loadable module.
static switch_status_t switch_loadable_module_load_module_ex ( char *  dir,
char *  fname,
switch_bool_t  runtime,
switch_bool_t  global,
const char **  err 
)
static

Definition at line 1550 of file switch_loadable_module.c.

References loadable_modules, switch_loadable_module_container::module_hash, switch_loadable_module_container::mutex, switch_loadable_module::pool, switch_loadable_module_container::pool, SWITCH_CHANNEL_LOG, switch_core_alloc, switch_core_hash_find_locked(), switch_core_launch_thread(), switch_core_strdup, switch_cut_path(), switch_is_file_path(), switch_loadable_module_exec(), switch_loadable_module_load_file(), switch_loadable_module_process(), switch_log_printf(), SWITCH_LOG_WARNING, switch_loadable_module::switch_module_runtime, SWITCH_PATH_SEPARATOR, switch_snprintf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_loadable_module::thread.

Referenced by switch_loadable_module_init(), and switch_loadable_module_load_module().

1551 {
1552  switch_size_t len = 0;
1553  char *path;
1554  char *file, *dot;
1555  switch_loadable_module_t *new_module = NULL;
1557 
1558 #ifdef WIN32
1559  const char *ext = ".dll";
1560 #else
1561  const char *ext = ".so";
1562 #endif
1563 
1564  *err = "";
1565 
1566  if ((file = switch_core_strdup(loadable_modules.pool, fname)) == 0) {
1567  *err = "allocation error";
1568  return SWITCH_STATUS_FALSE;
1569  }
1570 
1571  if (switch_is_file_path(file)) {
1573  file = (char *) switch_cut_path(file);
1574  if ((dot = strchr(file, '.'))) {
1575  *dot = '\0';
1576  }
1577  } else {
1578  if ((dot = strchr(file, '.'))) {
1579  *dot = '\0';
1580  }
1581  len = strlen(dir);
1582  len += strlen(file);
1583  len += 8;
1584  path = (char *) switch_core_alloc(loadable_modules.pool, len);
1585  switch_snprintf(path, len, "%s%s%s%s", dir, SWITCH_PATH_SEPARATOR, file, ext);
1586  }
1587 
1588 
1590  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Module %s Already Loaded!\n", file);
1591  *err = "Module already loaded";
1592  status = SWITCH_STATUS_FALSE;
1593  } else if ((status = switch_loadable_module_load_file(path, file, global, &new_module)) == SWITCH_STATUS_SUCCESS) {
1594  if ((status = switch_loadable_module_process(file, new_module)) == SWITCH_STATUS_SUCCESS && runtime) {
1595  if (new_module->switch_module_runtime) {
1596  new_module->thread = switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool);
1597  }
1598  } else if (status != SWITCH_STATUS_SUCCESS) {
1599  *err = "module load routine returned an error";
1600  }
1601  } else {
1602  *err = "module load file routine returned an error";
1603  }
1604 
1605 
1606  return status;
1607 
1608 }
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.
static struct switch_loadable_module_container loadable_modules
switch_memory_pool_t * pool
#define SWITCH_CHANNEL_LOG
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
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:64
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
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_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
uintptr_t switch_size_t
switch_status_t
Common return values.
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.
static switch_bool_t switch_is_file_path(const char *file)
static void *SWITCH_THREAD_FUNC switch_loadable_module_exec(switch_thread_t *thread, void *obj)
switch_module_runtime_t switch_module_runtime
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.
static switch_status_t switch_loadable_module_process(char *key, switch_loadable_module_t *new_module)
const char * switch_cut_path(const char *in)
Create a pointer to the file name in a given file path eliminating the directory name.
static switch_status_t switch_loadable_module_process ( char *  key,
switch_loadable_module_t new_module 
)
static

Definition at line 146 of file switch_loadable_module.c.

References switch_codec_implementation::actual_samples_per_second, switch_loadable_module_container::api_hash, switch_loadable_module_interface::api_interface, switch_loadable_module_container::application_hash, switch_loadable_module_interface::application_interface, switch_loadable_module_container::asr_hash, switch_loadable_module_interface::asr_interface, switch_codec_implementation::bits_per_second, switch_loadable_module_container::chat_application_hash, switch_loadable_module_interface::chat_application_interface, switch_loadable_module_container::chat_hash, switch_loadable_module_interface::chat_interface, switch_loadable_module_container::codec_hash, switch_loadable_module_interface::codec_interface, switch_codec_implementation::decoded_bytes_per_packet, switch_api_interface::desc, switch_json_api_interface::desc, switch_loadable_module_container::dialplan_hash, switch_loadable_module_interface::dialplan_interface, switch_loadable_module_container::directory_hash, switch_loadable_module_interface::directory_interface, switch_loadable_module_container::endpoint_hash, switch_loadable_module_interface::endpoint_interface, switch_file_interface::extens, switch_loadable_module_container::file_hash, switch_loadable_module_interface::file_interface, switch_loadable_module::filename, FREESWITCH_OID_PREFIX, switch_codec_implementation::ianacode, switch_codec_implementation::iananame, switch_codec_interface::implementations, switch_file_node_s::interface_name, switch_codec_node_s::interface_name, switch_endpoint_interface::interface_name, switch_timer_interface::interface_name, switch_dialplan_interface::interface_name, switch_file_interface::interface_name, switch_asr_interface::interface_name, switch_speech_interface::interface_name, switch_say_interface::interface_name, switch_chat_interface::interface_name, switch_limit_interface::interface_name, switch_directory_interface::interface_name, switch_codec_interface::interface_name, switch_application_interface::interface_name, switch_chat_application_interface::interface_name, switch_api_interface::interface_name, switch_json_api_interface::interface_name, switch_loadable_module_container::json_api_hash, switch_loadable_module_interface::json_api_interface, switch_loadable_module::key, switch_loadable_module_container::limit_hash, switch_loadable_module_interface::limit_interface, loadable_modules, switch_loadable_module_container::management_hash, switch_loadable_module_interface::management_interface, switch_codec_implementation::microseconds_per_packet, switch_loadable_module_container::module_hash, switch_loadable_module::module_interface, switch_loadable_module_interface::module_name, switch_loadable_module_container::mutex, switch_file_node_s::next, switch_codec_node_s::next, switch_endpoint_interface::next, switch_timer_interface::next, switch_dialplan_interface::next, switch_file_interface::next, switch_asr_interface::next, switch_speech_interface::next, switch_say_interface::next, switch_chat_interface::next, switch_management_interface::next, switch_limit_interface::next, switch_directory_interface::next, switch_codec_implementation::next, switch_codec_interface::next, switch_application_interface::next, switch_chat_application_interface::next, switch_api_interface::next, switch_json_api_interface::next, switch_loadable_module::pool, switch_file_node_s::ptr, switch_codec_node_s::ptr, switch_management_interface::relative_oid, switch_loadable_module_container::say_hash, switch_loadable_module_interface::say_interface, switch_application_interface::short_desc, switch_chat_application_interface::short_desc, switch_loadable_module_container::speech_hash, switch_loadable_module_interface::speech_interface, SWITCH_CHANNEL_LOG, switch_core_alloc, switch_core_hash_find(), switch_core_hash_insert, switch_core_strdup, switch_event_add_header_string(), switch_event_create, switch_event_fire, SWITCH_EVENT_MODULE_LOAD, SWITCH_LOG_CRIT, SWITCH_LOG_NOTICE, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, switch_str_nil, switch_application_interface::syntax, switch_chat_application_interface::syntax, switch_api_interface::syntax, switch_json_api_interface::syntax, switch_loadable_module_container::timer_hash, and switch_loadable_module_interface::timer_interface.

Referenced by switch_loadable_module_build_dynamic(), and switch_loadable_module_load_module_ex().

147 {
148  switch_event_t *event;
149  int added = 0;
150 
151  new_module->key = switch_core_strdup(new_module->pool, key);
152 
155 
156  if (new_module->module_interface->endpoint_interface) {
157  const switch_endpoint_interface_t *ptr;
158  for (ptr = new_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
159  if (!ptr->interface_name) {
160  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load endpoint interface from %s due to no interface name.\n", key);
161  } else {
162  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Endpoint '%s'\n", ptr->interface_name);
165  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "endpoint");
167  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
168  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
169  switch_event_fire(&event);
170  added++;
171  }
172  }
173  }
174  }
175 
176  if (new_module->module_interface->codec_interface) {
177  const switch_codec_implementation_t *impl;
178  const switch_codec_interface_t *ptr;
179 
180  for (ptr = new_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
181  if (!ptr->interface_name) {
182  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load codec interface from %s due to no interface name.\n", key);
183  } else {
184  unsigned load_interface = 1;
185  switch_codec_node_t *node, *head;
186 
187  for (impl = ptr->implementations; impl; impl = impl->next) {
188  if (!impl->iananame) {
189  load_interface = 0;
191  "Failed to load codec interface %s from %s due to no iana name in an implementation.\n", ptr->interface_name,
192  key);
193  break;
194  }
196  load_interface = 0;
198  "Failed to load codec interface %s from %s due to bytes per frame %d exceeding buffer size %d.\n",
199  ptr->interface_name,
201  break;
202  }
203  }
204  if (load_interface) {
205  for (impl = ptr->implementations; impl; impl = impl->next) {
206  if (impl->bits_per_second) {
208  "Adding Codec %s %d %s %dhz %dms %dbps\n",
209  impl->iananame, impl->ianacode,
211  impl->microseconds_per_packet / 1000, impl->bits_per_second);
212  } else {
214  "Adding Codec %s %d %s %dhz %dms (VBR)\n",
215  impl->iananame, impl->ianacode,
217  }
218 
219  node = switch_core_alloc(new_module->pool, sizeof(*node));
220  node->ptr = ptr;
221  node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name);
223  node->next = head;
224  }
225 
226  switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) node);
227  }
228 
230  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "codec");
232  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
233  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
235  switch_event_fire(&event);
236  added++;
237  }
238  }
239  }
240  }
241  }
242 
243  if (new_module->module_interface->dialplan_interface) {
244  const switch_dialplan_interface_t *ptr;
245 
246  for (ptr = new_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) {
247  if (!ptr->interface_name) {
248  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load dialplan interface from %s due to no interface name.\n", key);
249  } else {
250  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Dialplan '%s'\n", ptr->interface_name);
252  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "dialplan");
254  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
255  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
256  switch_event_fire(&event);
257  added++;
258  }
260  }
261  }
262  }
263 
264  if (new_module->module_interface->timer_interface) {
265  const switch_timer_interface_t *ptr;
266 
267  for (ptr = new_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
268  if (!ptr->interface_name) {
269  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load timer interface from %s due to no interface name.\n", key);
270  } else {
273  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "timer");
275  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
276  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
277  switch_event_fire(&event);
278  added++;
279  }
281  }
282  }
283  }
284 
285  if (new_module->module_interface->application_interface) {
287 
288  for (ptr = new_module->module_interface->application_interface; ptr; ptr = ptr->next) {
289  if (!ptr->interface_name) {
290  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key);
291  } else {
292  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Application '%s'\n", ptr->interface_name);
294  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
298  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
299  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
300  switch_event_fire(&event);
301  added++;
302  }
304  }
305  }
306  }
307 
308  if (new_module->module_interface->chat_application_interface) {
310 
311  for (ptr = new_module->module_interface->chat_application_interface; ptr; ptr = ptr->next) {
312  if (!ptr->interface_name) {
313  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key);
314  } else {
315  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Chat Application '%s'\n", ptr->interface_name);
317  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
321  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
322  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
323  switch_event_fire(&event);
324  added++;
325  }
327  }
328  }
329  }
330 
331  if (new_module->module_interface->api_interface) {
332  const switch_api_interface_t *ptr;
333 
334  for (ptr = new_module->module_interface->api_interface; ptr; ptr = ptr->next) {
335  if (!ptr->interface_name) {
336  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load api interface from %s due to no interface name.\n", key);
337  } else {
338  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding API Function '%s'\n", ptr->interface_name);
344  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
345  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
346  switch_event_fire(&event);
347  added++;
348  }
350  }
351  }
352  }
353 
354  if (new_module->module_interface->json_api_interface) {
355  const switch_json_api_interface_t *ptr;
356 
357  for (ptr = new_module->module_interface->json_api_interface; ptr; ptr = ptr->next) {
358  if (!ptr->interface_name) {
359  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load JSON api interface from %s due to no interface name.\n", key);
360  } else {
361  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding JSON API Function '%s'\n", ptr->interface_name);
363  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "json_api");
367  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
368  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
369  switch_event_fire(&event);
370  added++;
371  }
373  }
374  }
375  }
376 
377  if (new_module->module_interface->file_interface) {
378  const switch_file_interface_t *ptr;
379 
380  for (ptr = new_module->module_interface->file_interface; ptr; ptr = ptr->next) {
381  if (!ptr->interface_name) {
382  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no interface name.\n", key);
383  } else if (!ptr->extens) {
384  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no file extensions.\n", key);
385  } else {
386  int i;
387  switch_file_node_t *node, *head;
388 
389  for (i = 0; ptr->extens[i]; i++) {
390  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding File Format '%s'\n", ptr->extens[i]);
392  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "file");
394  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
395  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
397  switch_event_fire(&event);
398  added++;
399  }
400  node = switch_core_alloc(new_module->pool, sizeof(*node));
401  node->ptr = ptr;
402  node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name);
403  if ((head = switch_core_hash_find(loadable_modules.file_hash, ptr->extens[i]))) {
404  node->next = head;
405  }
406 
407  switch_core_hash_insert(loadable_modules.file_hash, ptr->extens[i], (const void *) node);
408  }
409  }
410  }
411  }
412 
413  if (new_module->module_interface->speech_interface) {
414  const switch_speech_interface_t *ptr;
415 
416  for (ptr = new_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
417  if (!ptr->interface_name) {
418  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load speech interface from %s due to no interface name.\n", key);
419  } else {
420  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Speech interface '%s'\n", ptr->interface_name);
422  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
424  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
425  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
426  switch_event_fire(&event);
427  added++;
428  }
430  }
431  }
432  }
433 
434  if (new_module->module_interface->asr_interface) {
435  const switch_asr_interface_t *ptr;
436 
437  for (ptr = new_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
438  if (!ptr->interface_name) {
439  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load asr interface from %s due to no interface name.\n", key);
440  } else {
441  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding ASR interface '%s'\n", ptr->interface_name);
445  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
446  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
447  switch_event_fire(&event);
448  added++;
449  }
451  }
452  }
453  }
454 
455  if (new_module->module_interface->directory_interface) {
456  const switch_directory_interface_t *ptr;
457 
458  for (ptr = new_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
459  if (!ptr->interface_name) {
460  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load directory interface from %s due to no interface name.\n", key);
461  } else {
462  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Directory interface '%s'\n", ptr->interface_name);
464  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
466  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
467  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
468  switch_event_fire(&event);
469  added++;
470  }
472  }
473  }
474  }
475 
476  if (new_module->module_interface->chat_interface) {
477  const switch_chat_interface_t *ptr;
478 
479  for (ptr = new_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
480  if (!ptr->interface_name) {
481  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load chat interface from %s due to no interface name.\n", key);
482  } else {
483  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Chat interface '%s'\n", ptr->interface_name);
485  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
487  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
488  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
489  switch_event_fire(&event);
490  added++;
491  }
493  }
494  }
495  }
496 
497  if (new_module->module_interface->say_interface) {
498  const switch_say_interface_t *ptr;
499 
500  for (ptr = new_module->module_interface->say_interface; ptr; ptr = ptr->next) {
501  if (!ptr->interface_name) {
502  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load say interface from %s due to no interface name.\n", key);
503  } else {
504  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Say interface '%s'\n", ptr->interface_name);
508  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
509  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
510  switch_event_fire(&event);
511  added++;
512  }
514  }
515  }
516  }
517 
518  if (new_module->module_interface->management_interface) {
520 
521  for (ptr = new_module->module_interface->management_interface; ptr; ptr = ptr->next) {
522  if (!ptr->relative_oid) {
523  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load management interface from %s due to no interface name.\n", key);
524  } else {
527  "Failed to load management interface %s. OID %s already exists\n", key, ptr->relative_oid);
528  } else {
530  "Adding Management interface '%s' OID[%s.%s]\n", key, FREESWITCH_OID_PREFIX, ptr->relative_oid);
533  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "management");
535  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
536  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
537  switch_event_fire(&event);
538  added++;
539  }
540  }
541 
542  }
543  }
544  }
545  if (new_module->module_interface->limit_interface) {
546  const switch_limit_interface_t *ptr;
547 
548  for (ptr = new_module->module_interface->limit_interface; ptr; ptr = ptr->next) {
549  if (!ptr->interface_name) {
550  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load limit interface from %s due to no interface name.\n", key);
551  } else {
554  "Failed to load limit interface %s. Name %s already exists\n", key, ptr->interface_name);
555  } else {
557  "Adding Limit interface '%s'\n", ptr->interface_name);
560  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "limit");
562  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
563  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
564  switch_event_fire(&event);
565  added++;
566  }
567  }
568 
569  }
570  }
571  }
572 
573  if (!added) {
575  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "generic");
576  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", new_module->key);
577  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
578  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
579  switch_event_fire(&event);
580  added++;
581  }
582  }
583 
585  return SWITCH_STATUS_SUCCESS;
586 
587 }
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:412
A module interface to implement an application.
switch_memory_pool_t * pool
struct switch_directory_interface * next
Abstract interface to a limit module.
#define SWITCH_CHANNEL_LOG
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
Abstraction of an module endpoint interface This is the glue between the abstract idea of a "channel"...
switch_directory_interface_t * directory_interface
const switch_codec_interface_t * ptr
struct switch_management_interface * next
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
switch_codec_interface_t * codec_interface
Representation of an event.
Definition: switch_event.h:80
A module interface to implement a chat application.
switch_codec_implementation_t * implementations
struct switch_endpoint_interface * next
#define FREESWITCH_OID_PREFIX
Definition: switch.h:53
Abstract interface to a chat module.
Abstract interface to a dialplan module.
struct switch_speech_interface * next
A table of functions that a timer module implements.
Abstract interface to an asr module.
Abstract interface to a file format module.
struct switch_json_api_interface * next
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
struct switch_timer_interface * next
switch_timer_interface_t * timer_interface
Abstract interface to a speech module.
A module interface to implement an api function.
struct switch_dialplan_interface * next
Abstract interface to a say module.
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
Abstract interface to a management module.
switch_chat_interface_t * chat_interface
switch_speech_interface_t * speech_interface
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
Top level module interface to implement a series of codec implementations.
switch_endpoint_interface_t * endpoint_interface
struct switch_codec_interface * next
struct switch_chat_interface * next
struct switch_chat_application_interface * next
struct switch_codec_node_s * next
switch_file_interface_t * file_interface
switch_application_interface_t * application_interface
switch_limit_interface_t * limit_interface
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
switch_management_interface_t * management_interface
switch_loadable_module_interface_t * module_interface
struct switch_file_node_s * next
switch_json_api_interface_t * json_api_interface
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1410
#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:383
struct switch_say_interface * next
struct switch_codec_implementation * next
struct switch_application_interface * next
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.
A table of settings and callbacks that define a paticular implementation of a codec.
A module interface to implement a json api function.
const switch_file_interface_t * ptr
struct switch_limit_interface * next
switch_api_interface_t * api_interface
switch_asr_interface_t * asr_interface
switch_say_interface_t * say_interface
switch_chat_application_interface_t * chat_application_interface
struct switch_file_interface * next
Abstract interface to a directory module.
struct switch_asr_interface * next
static void switch_loadable_module_runtime ( void  )
static

Definition at line 127 of file switch_loadable_module.c.

References loadable_modules, switch_loadable_module_container::module_hash, switch_loadable_module::module_interface, switch_loadable_module_interface::module_name, switch_loadable_module_container::mutex, switch_loadable_module_container::pool, SWITCH_CHANNEL_LOG, switch_core_hash_first, switch_core_hash_next(), switch_core_hash_this(), switch_core_launch_thread(), switch_loadable_module_exec(), SWITCH_LOG_CONSOLE, switch_log_printf(), switch_loadable_module::switch_module_runtime, switch_mutex_lock(), switch_mutex_unlock(), and switch_loadable_module::thread.

Referenced by switch_loadable_module_init().

128 {
130  void *val;
131  switch_loadable_module_t *module;
132 
135  switch_core_hash_this(hi, NULL, NULL, &val);
136  module = (switch_loadable_module_t *) val;
137 
138  if (module->switch_module_runtime) {
139  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Starting runtime thread for %s\n", module->module_interface->module_name);
141  }
142  }
144 }
static struct switch_loadable_module_container loadable_modules
#define SWITCH_CHANNEL_LOG
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
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_hash_index_t * switch_core_hash_next(_In_ switch_hash_index_t **hi)
Gets the next element of a hashtable.
switch_loadable_module_interface_t * module_interface
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.
static void *SWITCH_THREAD_FUNC switch_loadable_module_exec(switch_thread_t *thread, void *obj)
switch_module_runtime_t switch_module_runtime
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.
#define switch_core_hash_first(_h)
Definition: switch_core.h:1501
static void switch_loadable_module_sort_codecs ( const switch_codec_implementation_t **  array,
int  arraylen 
)
static

Definition at line 2230 of file switch_loadable_module.c.

References do_swap(), switch_codec_implementation::microseconds_per_packet, SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, and switch_log_printf().

Referenced by switch_loadable_module_get_codecs(), and switch_loadable_module_get_codecs_sorted().

2231 {
2232  int i = 0, sorted_ptime = 0;
2233 
2234 #ifdef DEBUG_CODEC_SORTING
2236  do_print(array, arraylen);
2238 #endif
2239 
2240  for (i = 0; i < arraylen; i++) {
2241  int this_ptime = array[i]->microseconds_per_packet / 1000;
2242 
2243  if (!strcasecmp(array[i]->iananame, "ilbc")) {
2244  this_ptime = 20;
2245  }
2246 
2247  if (!sorted_ptime) {
2248  sorted_ptime = this_ptime;
2249 #ifdef DEBUG_CODEC_SORTING
2250  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sorted1 = %d\n", sorted_ptime);
2251 #endif
2252  }
2253 
2254  if (i > 0 && strcasecmp(array[i]->iananame, array[i-1]->iananame) && this_ptime != sorted_ptime) {
2255  int j;
2256  int swapped = 0;
2257 
2258 #ifdef DEBUG_CODEC_SORTING
2259  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%d != %d\n", this_ptime, sorted_ptime);
2260 #endif
2261  for(j = i; j < arraylen; j++) {
2262  int check_ptime = array[j]->microseconds_per_packet / 1000;
2263 
2264  if (!strcasecmp(array[i]->iananame, "ilbc")) {
2265  check_ptime = 20;
2266  }
2267 
2268  if (check_ptime == sorted_ptime) {
2269 #ifdef DEBUG_CODEC_SORTING
2270  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "swap %d %d ptime %d\n", i, j, check_ptime);
2271 #endif
2272  do_swap(array, i, j);
2273  swapped = 1;
2274  break;
2275  }
2276  }
2277 
2278  if (!swapped) {
2279  sorted_ptime = this_ptime;
2280 #ifdef DEBUG_CODEC_SORTING
2281  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sorted2 = %d\n", sorted_ptime);
2282 #endif
2283  }
2284  }
2285  }
2286 
2287 #ifdef DEBUG_CODEC_SORTING
2289  do_print(array, arraylen);
2291 #endif
2292 
2293 }
#define SWITCH_CHANNEL_LOG
static void do_swap(const switch_codec_implementation_t **array, int a, int b)
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.
static switch_status_t switch_loadable_module_unprocess ( switch_loadable_module_t old_module)
static

Definition at line 928 of file switch_loadable_module.c.

References switch_codec_implementation::actual_samples_per_second, switch_loadable_module_container::api_hash, switch_loadable_module_interface::api_interface, switch_loadable_module_container::application_hash, switch_loadable_module_interface::application_interface, switch_loadable_module_container::asr_hash, switch_loadable_module_interface::asr_interface, switch_loadable_module_container::chat_application_hash, switch_loadable_module_interface::chat_application_interface, switch_loadable_module_container::chat_hash, switch_loadable_module_interface::chat_interface, switch_loadable_module_container::codec_hash, switch_loadable_module_interface::codec_interface, switch_api_interface::desc, switch_json_api_interface::desc, switch_loadable_module_container::dialplan_hash, switch_loadable_module_interface::dialplan_interface, switch_loadable_module_container::directory_hash, switch_loadable_module_interface::directory_interface, switch_loadable_module_container::endpoint_hash, switch_loadable_module_interface::endpoint_interface, switch_file_interface::extens, switch_loadable_module_container::file_hash, switch_loadable_module_interface::file_interface, FREESWITCH_OID_PREFIX, switch_codec_implementation::ianacode, switch_codec_implementation::iananame, switch_codec_interface::implementations, switch_file_node_s::interface_name, switch_codec_node_s::interface_name, switch_endpoint_interface::interface_name, switch_timer_interface::interface_name, switch_dialplan_interface::interface_name, switch_file_interface::interface_name, switch_asr_interface::interface_name, switch_speech_interface::interface_name, switch_say_interface::interface_name, switch_chat_interface::interface_name, switch_limit_interface::interface_name, switch_directory_interface::interface_name, switch_codec_interface::interface_name, switch_application_interface::interface_name, switch_chat_application_interface::interface_name, switch_api_interface::interface_name, switch_json_api_interface::interface_name, switch_loadable_module_container::json_api_hash, switch_loadable_module_interface::json_api_interface, switch_loadable_module::key, switch_loadable_module_container::limit_hash, switch_loadable_module_interface::limit_interface, loadable_modules, switch_loadable_module_container::management_hash, switch_loadable_module_interface::management_interface, switch_codec_implementation::microseconds_per_packet, switch_loadable_module::module_interface, switch_loadable_module_interface::module_name, switch_loadable_module_container::mutex, switch_file_node_s::next, switch_codec_node_s::next, switch_endpoint_interface::next, switch_timer_interface::next, switch_dialplan_interface::next, switch_file_interface::next, switch_asr_interface::next, switch_speech_interface::next, switch_say_interface::next, switch_chat_interface::next, switch_management_interface::next, switch_limit_interface::next, switch_directory_interface::next, switch_codec_implementation::next, switch_codec_interface::next, switch_application_interface::next, switch_chat_application_interface::next, switch_api_interface::next, switch_json_api_interface::next, switch_management_interface::relative_oid, switch_endpoint_interface::rwlock, switch_file_interface::rwlock, switch_asr_interface::rwlock, switch_speech_interface::rwlock, switch_say_interface::rwlock, switch_chat_interface::rwlock, switch_directory_interface::rwlock, switch_application_interface::rwlock, switch_chat_application_interface::rwlock, switch_api_interface::rwlock, switch_json_api_interface::rwlock, switch_loadable_module_container::say_hash, switch_loadable_module_interface::say_interface, switch_application_interface::short_desc, switch_chat_application_interface::short_desc, switch_loadable_module_container::speech_hash, switch_loadable_module_interface::speech_interface, SWITCH_CAUSE_MANAGER_REQUEST, SWITCH_CHANNEL_LOG, switch_core_hash_delete(), switch_core_hash_find(), switch_core_hash_insert, switch_core_session_hupall_endpoint(), switch_core_session_hupall_matching_var, SWITCH_CURRENT_APPLICATION_VARIABLE, switch_event_add_header_string(), switch_event_create, switch_event_fire, SWITCH_EVENT_MODULE_UNLOAD, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, SWITCH_LOG_NOTICE, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, switch_str_nil, switch_thread_rwlock_trywrlock_timeout(), switch_thread_rwlock_unlock(), switch_application_interface::syntax, switch_chat_application_interface::syntax, switch_api_interface::syntax, switch_json_api_interface::syntax, switch_loadable_module_container::timer_hash, and switch_loadable_module_interface::timer_interface.

Referenced by do_shutdown().

929 {
930  switch_event_t *event;
931  int removed = 0;
932 
934 
935  if (old_module->module_interface->endpoint_interface) {
936  const switch_endpoint_interface_t *ptr;
937 
938  for (ptr = old_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
939  if (ptr->interface_name) {
940 
942  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
943  ptr->interface_name);
946  } else {
947  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
948  }
949 
950  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Endpoint '%s'\n", ptr->interface_name);
952  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "endpoint");
954  switch_event_fire(&event);
955  removed++;
956  }
958  }
959  }
960  }
961 
962  if (old_module->module_interface->codec_interface) {
963  const switch_codec_implementation_t *impl;
964  const switch_codec_interface_t *ptr;
965  switch_codec_node_t *node, *head, *last = NULL;
966 
967  for (ptr = old_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
968  if (ptr->interface_name) {
969  unsigned load_interface = 1;
970  for (impl = ptr->implementations; impl; impl = impl->next) {
971  if (!impl->iananame) {
972  load_interface = 0;
973  break;
974  }
975  }
976  if (load_interface) {
977  for (impl = ptr->implementations; impl; impl = impl->next) {
979  "Deleting Codec %s %d %s %dhz %dms\n",
980  impl->iananame, impl->ianacode,
984 
986  for(node = head; node; node = node->next) {
987  if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
988  if (node == head) {
989  if ((node = node->next)) {
990  switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) node);
991  } else {
993  }
994  } else {
995  if (last) {
996  last->next = node->next;
997  }
998  }
999  break;
1000  }
1001  last = node;
1002  }
1003  }
1004  }
1006  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "codec");
1009  switch_event_fire(&event);
1010  removed++;
1011  }
1012  }
1013  }
1014  }
1015  }
1016 
1017  if (old_module->module_interface->dialplan_interface) {
1018  const switch_dialplan_interface_t *ptr;
1019 
1020  for (ptr = old_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) {
1021  if (ptr->interface_name) {
1022  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Dialplan '%s'\n", ptr->interface_name);
1024  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "dialplan");
1026  switch_event_fire(&event);
1027  removed++;
1028  }
1030  }
1031  }
1032  }
1033 
1034  if (old_module->module_interface->timer_interface) {
1035  const switch_timer_interface_t *ptr;
1036 
1037  for (ptr = old_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
1038  if (ptr->interface_name) {
1039  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Timer '%s'\n", ptr->interface_name);
1041  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "timer");
1043  switch_event_fire(&event);
1044  removed++;
1045  }
1047  }
1048  }
1049  }
1050 
1051  if (old_module->module_interface->application_interface) {
1052  const switch_application_interface_t *ptr;
1053  for (ptr = old_module->module_interface->application_interface; ptr; ptr = ptr->next) {
1054  if (ptr->interface_name) {
1055  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
1057  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1058  ptr->interface_name);
1061  } else {
1062  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1063  }
1064 
1066  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
1070  switch_event_fire(&event);
1071  removed++;
1072  }
1074  }
1075  }
1076  }
1077 
1078  if (old_module->module_interface->chat_application_interface) {
1080  for (ptr = old_module->module_interface->chat_application_interface; ptr; ptr = ptr->next) {
1081  if (ptr->interface_name) {
1082  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
1084  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1085  ptr->interface_name);
1088  } else {
1089  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1090  }
1091 
1093  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
1097  switch_event_fire(&event);
1098  removed++;
1099  }
1101  }
1102  }
1103  }
1104 
1105  if (old_module->module_interface->api_interface) {
1106  const switch_api_interface_t *ptr;
1107 
1108  for (ptr = old_module->module_interface->api_interface; ptr; ptr = ptr->next) {
1109  if (ptr->interface_name) {
1110  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
1111 
1112  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1113  ptr->interface_name);
1114 
1117  } else {
1118  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1119  }
1120 
1121 
1123  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");
1127  switch_event_fire(&event);
1128  removed++;
1129  }
1131  }
1132  }
1133  }
1134 
1135  if (old_module->module_interface->json_api_interface) {
1136  const switch_json_api_interface_t *ptr;
1137 
1138  for (ptr = old_module->module_interface->json_api_interface; ptr; ptr = ptr->next) {
1139  if (ptr->interface_name) {
1140  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
1141 
1142  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1143  ptr->interface_name);
1144 
1147  } else {
1148  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1149  }
1150 
1151 
1153  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");
1157  switch_event_fire(&event);
1158  removed++;
1159  }
1161  }
1162  }
1163  }
1164 
1165  if (old_module->module_interface->file_interface) {
1166  const switch_file_interface_t *ptr;
1167  switch_file_node_t *node, *head, *last = NULL;
1168 
1169  for (ptr = old_module->module_interface->file_interface; ptr; ptr = ptr->next) {
1170  if (ptr->interface_name) {
1171  int i;
1172 
1173  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1174  ptr->interface_name);
1175 
1178  } else {
1179  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1180  }
1181 
1182  for (i = 0; ptr->extens[i]; i++) {
1183  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting File Format '%s'\n", ptr->extens[i]);
1185  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "file");
1188  switch_event_fire(&event);
1189  removed++;
1190  }
1191 
1192  if ((head = switch_core_hash_find(loadable_modules.file_hash, ptr->extens[i]))) {
1193  for(node = head; node; node = node->next) {
1194  if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
1195  if (node == head) {
1196  if ((node = node->next)) {
1197  switch_core_hash_insert(loadable_modules.file_hash, ptr->extens[i], (const void *) node);
1198  } else {
1200  }
1201  } else {
1202  if (last) {
1203  last->next = node->next;
1204  }
1205  }
1206  break;
1207  }
1208  last = node;
1209  }
1210  }
1211  }
1212  }
1213  }
1214  }
1215 
1216  if (old_module->module_interface->speech_interface) {
1217  const switch_speech_interface_t *ptr;
1218 
1219  for (ptr = old_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
1220 
1221  if (ptr->interface_name) {
1222 
1223  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1224  ptr->interface_name);
1225 
1228  } else {
1229  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1230  }
1231 
1232  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Speech interface '%s'\n", ptr->interface_name);
1234  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
1236  switch_event_fire(&event);
1237  removed++;
1238  }
1240  }
1241  }
1242  }
1243 
1244  if (old_module->module_interface->asr_interface) {
1245  const switch_asr_interface_t *ptr;
1246 
1247  for (ptr = old_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
1248  if (ptr->interface_name) {
1249 
1250  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1251  ptr->interface_name);
1252 
1255  } else {
1256  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1257  }
1258 
1259  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Asr interface '%s'\n", ptr->interface_name);
1261  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "asr");
1263  switch_event_fire(&event);
1264  removed++;
1265  }
1267  }
1268  }
1269  }
1270 
1271  if (old_module->module_interface->directory_interface) {
1272  const switch_directory_interface_t *ptr;
1273 
1274  for (ptr = old_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
1275  if (ptr->interface_name) {
1276 
1277  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1278  ptr->interface_name);
1279 
1282  } else {
1283  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1284  }
1285 
1286  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Directory interface '%s'\n", ptr->interface_name);
1288  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
1290  switch_event_fire(&event);
1291  removed++;
1292  }
1294  }
1295  }
1296  }
1297 
1298 
1299  if (old_module->module_interface->chat_interface) {
1300  const switch_chat_interface_t *ptr;
1301 
1302  for (ptr = old_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
1303  if (ptr->interface_name) {
1304  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1305  ptr->interface_name);
1306 
1309  } else {
1310  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1311  }
1312 
1313  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Chat interface '%s'\n", ptr->interface_name);
1315  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
1317  switch_event_fire(&event);
1318  removed++;
1319  }
1321  }
1322  }
1323  }
1324 
1325  if (old_module->module_interface->say_interface) {
1326  const switch_say_interface_t *ptr;
1327 
1328  for (ptr = old_module->module_interface->say_interface; ptr; ptr = ptr->next) {
1329  if (ptr->interface_name) {
1330  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1331  ptr->interface_name);
1332 
1335  } else {
1336  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1337  }
1338  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Say interface '%s'\n", ptr->interface_name);
1340  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "say");
1342  switch_event_fire(&event);
1343  removed++;
1344  }
1346  }
1347  }
1348  }
1349 
1350  if (old_module->module_interface->management_interface) {
1351  const switch_management_interface_t *ptr;
1352 
1353  for (ptr = old_module->module_interface->management_interface; ptr; ptr = ptr->next) {
1354  if (ptr->relative_oid) {
1356  "Deleting Management interface '%s' OID[%s.%s]\n", old_module->key, FREESWITCH_OID_PREFIX, ptr->relative_oid);
1359  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "management");
1361  switch_event_fire(&event);
1362  removed++;
1363  }
1364  }
1365  }
1366  }
1367 
1368  if (old_module->module_interface->limit_interface) {
1369  const switch_limit_interface_t *ptr;
1370 
1371  for (ptr = old_module->module_interface->limit_interface; ptr; ptr = ptr->next) {
1372  if (ptr->interface_name) {
1374  "Deleting Limit interface '%s'\n", ptr->interface_name);
1377  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "limit");
1379  switch_event_fire(&event);
1380  removed++;
1381  }
1382  }
1383  }
1384  }
1385 
1386  if (!removed) {
1388  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "generic");
1389  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", old_module->key);
1390  switch_event_fire(&event);
1391  removed++;
1392  }
1393  }
1395 
1396  return SWITCH_STATUS_SUCCESS;
1397 
1398 }
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:412
A module interface to implement an application.
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
struct switch_directory_interface * next
Abstract interface to a limit module.
#define SWITCH_CHANNEL_LOG
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
Abstraction of an module endpoint interface This is the glue between the abstract idea of a "channel"...
switch_directory_interface_t * directory_interface
struct switch_management_interface * next
switch_thread_rwlock_t * rwlock
#define switch_core_session_hupall_matching_var(_vn, _vv, _c)
Definition: switch_core.h:984
switch_codec_interface_t * codec_interface
Representation of an event.
Definition: switch_event.h:80
A module interface to implement a chat application.
switch_codec_implementation_t * implementations
struct switch_endpoint_interface * next
#define FREESWITCH_OID_PREFIX
Definition: switch.h:53
Abstract interface to a chat module.
Abstract interface to a dialplan module.
struct switch_speech_interface * next
A table of functions that a timer module implements.
switch_thread_rwlock_t * rwlock
Abstract interface to an asr module.
switch_thread_rwlock_t * rwlock
Abstract interface to a file format module.
struct switch_json_api_interface * next
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
struct switch_timer_interface * next
switch_timer_interface_t * timer_interface
switch_thread_rwlock_t * rwlock
Abstract interface to a speech module.
A module interface to implement an api function.
struct switch_dialplan_interface * next
Abstract interface to a say module.
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
Abstract interface to a management module.
switch_chat_interface_t * chat_interface
switch_speech_interface_t * speech_interface
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
Top level module interface to implement a series of codec implementations.
switch_endpoint_interface_t * endpoint_interface
struct switch_codec_interface * next
struct switch_chat_interface * next
struct switch_chat_application_interface * next
struct switch_codec_node_s * next
switch_thread_rwlock_t * rwlock
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
switch_limit_interface_t * limit_interface
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
switch_management_interface_t * management_interface
switch_loadable_module_interface_t * module_interface
switch_thread_rwlock_t * rwlock
struct switch_file_node_s * next
switch_json_api_interface_t * json_api_interface
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1410
#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:383
struct switch_say_interface * next
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.
struct switch_codec_implementation * next
switch_thread_rwlock_t * rwlock
struct switch_application_interface * next
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.
#define SWITCH_CURRENT_APPLICATION_VARIABLE
Definition: switch_types.h:140
A table of settings and callbacks that define a paticular implementation of a codec.
A module interface to implement a json api function.
struct switch_limit_interface * next
switch_api_interface_t * api_interface
switch_status_t switch_thread_rwlock_trywrlock_timeout(switch_thread_rwlock_t *rwlock, int timeout)
Definition: switch_apr.c:247
switch_asr_interface_t * asr_interface
switch_say_interface_t * say_interface
switch_chat_application_interface_t * chat_application_interface
struct switch_file_interface * next
switch_thread_rwlock_t * rwlock
Abstract interface to a directory module.
struct switch_asr_interface * next
void switch_say_file ( switch_say_file_handle_t sh,
const char *  fmt,
  ... 
)

Definition at line 2780 of file switch_loadable_module.c.

References buf, and switch_vsnprintf().

2781 {
2782  char buf[256] = "";
2783  int ret;
2784  va_list ap;
2785 
2786  va_start(ap, fmt);
2787 
2788  if ((ret = switch_vsnprintf(buf, sizeof(buf), fmt, ap)) > 0) {
2789  if (!sh->cnt++) {
2790  sh->stream.write_function(&sh->stream, "file_string://%s.%s", buf, sh->ext);
2791  } else if (strstr(buf, "://")) {
2792  sh->stream.write_function(&sh->stream, "!%s", buf);
2793  } else {
2794  sh->stream.write_function(&sh->stream, "!%s.%s", buf, sh->ext);
2795  }
2796 
2797  }
2798 
2799  va_end(ap);
2800 }
struct switch_stream_handle stream
switch_byte_t switch_byte_t * buf
switch_stream_handle_write_function_t write_function
int switch_vsnprintf(char *buf, switch_size_t len, const char *format, va_list ap)
Definition: switch_apr.c:194
switch_status_t switch_say_file_handle_create ( switch_say_file_handle_t **  sh,
const char *  ext,
switch_event_t **  var_event 
)

Definition at line 2757 of file switch_loadable_module.c.

References memset(), switch_assert, SWITCH_STANDARD_STREAM, SWITCH_STATUS_SUCCESS, and zstr.

2758 {
2759  switch_assert(sh);
2760 
2761  if (zstr(ext)) {
2762  ext = "wav";
2763  }
2764 
2765  *sh = malloc(sizeof(**sh));
2766  memset(*sh, 0, sizeof(**sh));
2767 
2768  SWITCH_STANDARD_STREAM((*sh)->stream);
2769 
2770  if (var_event) {
2771  (*sh)->param_event = *var_event;
2772  *var_event = NULL;
2773  }
2774 
2775  (*sh)->ext = strdup(ext);
2776 
2777  return SWITCH_STATUS_SUCCESS;
2778 }
#define zstr(x)
Definition: switch_utils.h:281
#define SWITCH_STANDARD_STREAM(s)
#define switch_assert(expr)
memset(buf, 0, buflen)
void switch_say_file_handle_destroy ( switch_say_file_handle_t **  sh)

Definition at line 2743 of file switch_loadable_module.c.

References switch_assert, switch_event_destroy(), and switch_safe_free.

2744 {
2745  switch_assert(sh);
2746 
2747  switch_safe_free((*sh)->stream.data);
2748  switch_safe_free((*sh)->ext);
2749 
2750  if ((*sh)->param_event) {
2751  switch_event_destroy(&(*sh)->param_event);
2752  }
2753  free(*sh);
2754  *sh = NULL;
2755 }
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)
char* switch_say_file_handle_detach_path ( switch_say_file_handle_t sh)

Definition at line 2732 of file switch_loadable_module.c.

References switch_assert.

2733 {
2734  char *path;
2735 
2736  switch_assert(sh);
2737  path = (char *) sh->stream.data;
2738  sh->stream.data = NULL;
2739  return path;
2740 }
struct switch_stream_handle stream
#define switch_assert(expr)
char* switch_say_file_handle_get_path ( switch_say_file_handle_t sh)

Definition at line 2727 of file switch_loadable_module.c.

2728 {
2729  return (char *) sh->stream.data;
2730 }
struct switch_stream_handle stream
char* switch_say_file_handle_get_variable ( switch_say_file_handle_t sh,
const char *  var 
)

Definition at line 2715 of file switch_loadable_module.c.

References switch_event_get_header.

2716 {
2717  char *ret = NULL;
2718 
2719  if (sh->param_event) {
2720  ret = switch_event_get_header(sh->param_event, var);
2721  }
2722 
2723  return ret;
2724 
2725 }
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172

Variable Documentation

struct { ... } chat_globals
int IDX = 0
static

Definition at line 601 of file switch_loadable_module.c.

Referenced by chat_queue_message().

struct switch_loadable_module_container loadable_modules
static

Definition at line 593 of file switch_loadable_module.c.

int msg_queue_len

Definition at line 595 of file switch_loadable_module.c.

switch_thread_t* msg_queue_thread[CHAT_MAX_MSG_QUEUE]

Definition at line 594 of file switch_loadable_module.c.

int running

Definition at line 598 of file switch_loadable_module.c.