RTS API Documentation  1.10.11
Data Structures | Macros | Typedefs | Functions | Variables
switch_loadable_module.c File Reference
#include <switch.h>
#include "private/switch_core_pvt.h"
#include <fspr_strings.h>
#include <fspr_env.h>
#include <fspr_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_database_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_database_node_s switch_database_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 (const char *dir, const char *fname, switch_bool_t runtime, switch_bool_t global, const char **err, switch_loadable_module_type_t type, switch_hash_t *event_hash)
 
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, switch_hash_t *event_hash)
 
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 (const char *dir, const 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_protect (const char *mod)
 Protect module from beeing unloaded. More...
 
switch_status_t switch_loadable_module_unload_module (const char *dir, const 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_database_interface_tswitch_loadable_module_get_database_interface (const char *name, const char *modname)
 Retrieve the database 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, char **fmtp)
 
int switch_loadable_module_get_codecs_sorted (const switch_codec_implementation_t **array, char fmtp_array[SWITCH_MAX_CODECS][MAX_FMTP_LEN], int arraylen, char **prefs, int preflen)
 Retrieve the list of loaded codecs into an array based on another array showing the sorted order. 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

◆ ALLOC_INTERFACE

#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; }
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684

Definition at line 3047 of file switch_loadable_module.c.

Referenced by switch_loadable_module_create_interface().

◆ CHAT_MAX_MSG_QUEUE

#define CHAT_MAX_MSG_QUEUE   101

Definition at line 764 of file switch_loadable_module.c.

Referenced by chat_queue_message(), and chat_thread_start().

◆ CHAT_QUEUE_SIZE

#define CHAT_QUEUE_SIZE   5000

Definition at line 765 of file switch_loadable_module.c.

Referenced by chat_thread_start().

◆ HASH_FUNC

#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; \
PROTECT_INTERFACE(i); \
} \
return i; \
}
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
#define SWITCH_DECLARE(type)
const char *const name
Definition: switch_cJSON.h:250

Definition at line 2574 of file switch_loadable_module.c.

Typedef Documentation

◆ switch_codec_node_t

◆ switch_database_node_t

◆ switch_file_node_t

Function Documentation

◆ chat_process_event()

static switch_status_t chat_process_event ( switch_event_t **  eventp)
static

Definition at line 888 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().

889 {
890  switch_event_t *event;
891  switch_status_t status;
892 
893  switch_assert(eventp);
894 
895  event = *eventp;
896  *eventp = NULL;
897 
898  status = do_chat_send(event);
899  switch_event_destroy(&event);
900 
901  return status;
902 }
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)

◆ chat_queue_message()

static void chat_queue_message ( switch_event_t **  eventp)
static

Definition at line 959 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().

960 {
961  int idx = 0;
962  switch_event_t *event;
963 
964  switch_assert(eventp);
965 
966  event = *eventp;
967  *eventp = NULL;
968 
969  if (chat_globals.running == 0) {
970  chat_process_event(&event);
971  return;
972  }
973 
974  again:
975 
977  idx = IDX;
978  IDX++;
979  if (IDX >= chat_globals.msg_queue_len) IDX = 0;
981 
982  chat_thread_start(idx);
983 
984  if (switch_queue_trypush(chat_globals.msg_queue[idx], event) != SWITCH_STATUS_SUCCESS) {
985  if (chat_globals.msg_queue_len < CHAT_MAX_MSG_QUEUE) {
986  chat_thread_start(idx + 1);
987  goto again;
988  } else {
989  switch_queue_push(chat_globals.msg_queue[idx], event);
990  }
991  }
992 }
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:313
#define CHAT_MAX_MSG_QUEUE
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_status_t switch_queue_trypush(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1279
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1253
static void chat_thread_start(int idx)
static struct @6 chat_globals
#define switch_assert(expr)

◆ chat_thread_run()

void* SWITCH_THREAD_FUNC chat_thread_run ( switch_thread_t thread,
void *  obj 
)

Definition at line 905 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().

906 {
907  void *pop;
908  switch_queue_t *q = (switch_queue_t *) obj;
909 
910  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Chat Thread Started\n");
911 
912 
913  while(switch_queue_pop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
914  switch_event_t *event = (switch_event_t *) pop;
915  chat_process_event(&event);
917  }
918 
919  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Chat Thread Ended\n");
920 
921  return NULL;
922 }
#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:1243
static switch_status_t chat_process_event(switch_event_t **eventp)
void switch_cond_next(void)
Definition: switch_time.c:658
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.

◆ chat_thread_start()

static void chat_thread_start ( int  idx)
static

Definition at line 925 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().

926 {
927 
928  if (idx >= CHAT_MAX_MSG_QUEUE || (idx < chat_globals.msg_queue_len && chat_globals.msg_queue_thread[idx])) {
929  return;
930  }
931 
933 
934  if (idx >= chat_globals.msg_queue_len) {
935  int i;
936  chat_globals.msg_queue_len = idx + 1;
937 
938  for (i = 0; i < chat_globals.msg_queue_len; i++) {
939  if (!chat_globals.msg_queue[i]) {
940  switch_threadattr_t *thd_attr = NULL;
941 
943 
944  switch_threadattr_create(&thd_attr, chat_globals.pool);
946  switch_thread_create(&chat_globals.msg_queue_thread[i],
947  thd_attr,
949  chat_globals.msg_queue[i],
950  chat_globals.pool);
951  }
952  }
953  }
954 
956 }
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:683
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:313
#define CHAT_MAX_MSG_QUEUE
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:588
#define CHAT_QUEUE_SIZE
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:665
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:698
switch_status_t switch_queue_create(switch_queue_t **queue, unsigned int queue_capacity, switch_memory_pool_t *pool)
Definition: switch_apr.c:1233
static struct @6 chat_globals

◆ do_chat_send()

static switch_status_t do_chat_send ( switch_event_t message_event)
static

Definition at line 779 of file switch_loadable_module.c.

References switch_loadable_module_container::chat_hash, switch_loadable_module_container::chat_rwlock, switch_chat_interface::chat_send, switch_chat_interface::interface_name, loadable_modules, 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_safe_free, SWITCH_STACK_BOTTOM, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_stristr(), switch_thread_rwlock_rdlock(), switch_thread_rwlock_unlock(), switch_true(), and UNPROTECT_INTERFACE.

Referenced by chat_process_event().

781 {
785  switch_event_t *dup = NULL;
786  const void *var;
787  void *val;
788  const char *proto;
789  const char *replying;
790  const char *dest_proto;
791  int do_skip = 0;
792 
793  /*
794 
795  const char *from;
796  const char *to;
797  const char *subject;
798  const char *body;
799  const char *type;
800  const char *hint;
801  */
802 
803  dest_proto = switch_event_get_header(message_event, "dest_proto");
804 
805  if (!dest_proto) {
806  return SWITCH_STATUS_FALSE;
807  }
808 
809  /*
810 
811  from = switch_event_get_header(message_event, "from");
812  to = switch_event_get_header(message_event, "to");
813  subject = switch_event_get_header(message_event, "subject");
814  body = switch_event_get_body(message_event);
815  type = switch_event_get_header(message_event, "type");
816  hint = switch_event_get_header(message_event, "hint");
817  */
818 
819  if (!(proto = switch_event_get_header(message_event, "proto"))) {
820  proto = "global";
821  switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto);
822  }
823 
824  replying = switch_event_get_header(message_event, "replying");
825 
826  if (!switch_true(replying) && !switch_stristr("global", proto) && !switch_true(switch_event_get_header(message_event, "skip_global_process"))) {
829  switch_core_hash_this(hi, &var, NULL, &val);
830 
831  if ((ci = (switch_chat_interface_t *) val)) {
832  if (ci->chat_send && !strncasecmp(ci->interface_name, "GLOBAL_", 7)) {
833  status = ci->chat_send(message_event);
834 
835  if (status == SWITCH_STATUS_SUCCESS) {
836  if (switch_true(switch_event_get_header(message_event, "final_delivery"))) {
837  /* The event was handled by an extension in the chatplan,
838  * so the event will be duplicated, modified and queued again,
839  * but it won't be processed by the chatplan again.
840  * So this copy of the event can be destroyed by the caller.
841  */
842  do_skip = 1;
843  }
844  } else if (status == SWITCH_STATUS_BREAK) {
845  /* The event went through the chatplan, but no extension matched
846  * to handle the sms messsage. It'll be attempted to be delivered
847  * directly, and unless that works the sms delivery will have failed.
848  */
849  } else {
850  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Chat Interface Error [%s]!\n", dest_proto);
851  break;
852  }
853  }
854  }
855  }
856  switch_safe_free(hi);
858  }
859 
860 
861  if (!do_skip && !switch_stristr("GLOBAL", dest_proto)) {
862  if ((ci = switch_loadable_module_get_chat_interface(dest_proto)) && ci->chat_send) {
863  status = ci->chat_send(message_event);
865  } else {
866  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid chat interface [%s]!\n", dest_proto);
867  status = SWITCH_STATUS_FALSE;
868  }
869  }
870 
871 
872  switch_event_dup(&dup, message_event);
873 
874  if ( switch_true(switch_event_get_header(message_event, "blocking")) ) {
875  if (status == SWITCH_STATUS_SUCCESS) {
876  switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "false");
877  } else {
878  switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "true");
879  }
880  } else {
881  switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Nonblocking-Delivery", "true");
882  }
883 
884  switch_event_fire(&dup);
885  return status;
886 }
static struct switch_loadable_module_container loadable_modules
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:286
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#define SWITCH_CHANNEL_LOG
Representation of an event.
Definition: switch_event.h:80
switch_status_t(* chat_send)(switch_event_t *message_event)
Abstract interface to a chat module.
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
switch_status_t switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:250
#define UNPROTECT_INTERFACE(_it)
switch_chat_interface_t * switch_loadable_module_get_chat_interface(const char *name)
Retrieve the chat interface by it&#39;s registered name.
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:885
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:1592

◆ do_shutdown()

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 2335 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().

2337 {
2338  int32_t flags = switch_core_flags();
2339  switch_assert(module != NULL);
2340 
2342  if (err) {
2343  *err = "Module in use.";
2344  }
2345  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Module %s is in use, cannot unload.\n", module->module_interface->module_name);
2346  return SWITCH_STATUS_FALSE;
2347  }
2348 
2349  module->shutting_down = SWITCH_TRUE;
2350 
2351  if (shutdown) {
2353  if (module->switch_module_shutdown) {
2355  module->status = module->switch_module_shutdown();
2356  } else {
2357  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s has no shutdown routine\n", module->module_interface->module_name);
2358  }
2359  }
2360 
2361  if (fail_if_busy && module->module_interface->rwlock) {
2363  }
2364 
2365  if (unload && module->status != SWITCH_STATUS_NOUNLOAD && !(flags & SCF_VG)) {
2367  switch_status_t st;
2368 
2369  if (module->thread) {
2370  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s stopping runtime thread.\n", module->module_interface->module_name);
2371  switch_thread_join(&st, module->thread);
2372  }
2373 
2375  switch_dso_destroy(&module->lib);
2376  if ((pool = module->pool)) {
2377  module = NULL;
2379  }
2380  }
2381 
2382  return SWITCH_STATUS_SUCCESS;
2383 
2384 }
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:286
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:642
switch_memory_pool_t * pool
switch_core_flag_t switch_core_flags(void)
return core flags
Definition: switch_core.c:2988
void switch_dso_destroy(switch_dso_lib_t *lib)
Definition: switch_dso.c:91
static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t *old_module)
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1379
switch_status_t
Common return values.
switch_loadable_module_interface_t * module_interface
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.
struct fspr_pool_t switch_memory_pool_t
#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:265

◆ do_swap()

static void do_swap ( const switch_codec_implementation_t **  array,
int  a,
int  b 
)
static

Definition at line 2620 of file switch_loadable_module.c.

References b.

Referenced by switch_loadable_module_sort_codecs().

2621 {
2622  const switch_codec_implementation_t *tmp = array[b];
2623  array[b] = array[a];
2624  array[a] = tmp;
2625 }
const cJSON *const b
Definition: switch_cJSON.h:243
A table of settings and callbacks that define a paticular implementation of a codec.

◆ switch_core_get_secondary_recover_callback()

switch_core_recover_callback_t switch_core_get_secondary_recover_callback ( const char *  key)

Definition at line 3216 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(), and switch_core_codec_ready().

3217 {
3219 
3223 
3224  return cb;
3225 }
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:313
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
int(* switch_core_recover_callback_t)(switch_core_session_t *session)
char * key
Definition: switch_msrp.c:64

◆ switch_core_register_secondary_recover_callback()

switch_status_t switch_core_register_secondary_recover_callback ( const char *  key,
switch_core_recover_callback_t  cb 
)

Definition at line 3228 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.

Referenced by switch_core_codec_ready().

3229 {
3231 
3232  switch_assert(cb);
3233 
3236  status = SWITCH_STATUS_FALSE;
3237  } else {
3239  }
3241 
3242  return status;
3243 }
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:313
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_status_t
Common return values.
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1479
char * key
Definition: switch_msrp.c:64
#define switch_assert(expr)

◆ switch_core_unregister_secondary_recover_callback()

void switch_core_unregister_secondary_recover_callback ( const char *  key)

Definition at line 3246 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().

Referenced by switch_core_codec_ready().

3247 {
3251 }
static struct switch_loadable_module_container loadable_modules
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
void * switch_core_hash_delete(_In_ switch_hash_t *hash, _In_z_ const char *key)
Delete data from a hash based on desired key.
char * key
Definition: switch_msrp.c:64

◆ switch_loadable_module_exec()

static void* SWITCH_THREAD_FUNC switch_loadable_module_exec ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 111 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().

112 {
113 
114 
117  switch_loadable_module_t *module = ts->objs[0];
118 
119  switch_assert(thread != NULL);
120  switch_assert(module != NULL);
121 
122  while (status != SWITCH_STATUS_TERM && !module->shutting_down) {
123  status = module->switch_module_runtime();
124  }
126 
127  if (ts->pool) {
129  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Destroying Pool for %s\n", module->module_interface->module_name);
131  }
133  return NULL;
134 }
#define SWITCH_CHANNEL_LOG
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
static switch_thread_t * thread
Definition: switch_log.c:486
switch_memory_pool_t * pool
Definition: switch_core.h:225
switch_memory_pool_t * pool
void * objs[SWITCH_MAX_CORE_THREAD_SESSION_OBJS]
Definition: switch_core.h:222
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&#39;s session object to allow mutiple arguements and a pool...
Definition: switch_core.h:216
switch_status_t switch_thread_exit(switch_thread_t *thd, switch_status_t retval)
Definition: switch_apr.c:1369
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
struct fspr_pool_t switch_memory_pool_t
#define switch_assert(expr)

◆ switch_loadable_module_load_file()

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 1636 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().

1637 {
1638  switch_loadable_module_t *module = NULL;
1639  switch_dso_lib_t dso = NULL;
1640  fspr_status_t status = SWITCH_STATUS_SUCCESS;
1641  switch_loadable_module_function_table_t *interface_struct_handle = NULL;
1642  switch_loadable_module_function_table_t *mod_interface_functions = NULL;
1643  char *struct_name = NULL;
1644  switch_module_load_t load_func_ptr = NULL;
1645  int loading = 1;
1646  switch_loadable_module_interface_t *module_interface = NULL;
1647  char *derr = NULL;
1648  const char *err = NULL;
1649  switch_memory_pool_t *pool = NULL;
1650  switch_bool_t load_global = global;
1651 
1652  switch_assert(path != NULL);
1653 
1655  *new_module = NULL;
1656 
1657  struct_name = switch_core_sprintf(pool, "%s_module_interface", filename);
1658 
1659 #ifdef WIN32
1660  dso = switch_dso_open("FreeSwitch.dll", load_global, &derr);
1661 #elif defined (MACOSX) || defined(DARWIN)
1662  {
1663  char *lib_path = switch_mprintf("%s/libfreeswitch.dylib", SWITCH_GLOBAL_dirs.lib_dir);
1664  dso = switch_dso_open(lib_path, load_global, &derr);
1665  switch_safe_free(lib_path);
1666  }
1667 #else
1668  dso = switch_dso_open(NULL, load_global, &derr);
1669 #endif
1670  if (!derr && dso) {
1671  interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
1672  }
1673 
1674  switch_safe_free(derr);
1675 
1676  if (!interface_struct_handle) {
1677  if (dso) switch_dso_destroy(&dso);
1678  dso = switch_dso_open(path, load_global, &derr);
1679  }
1680 
1681  while (loading) {
1682  if (derr) {
1683  err = derr;
1684  break;
1685  }
1686 
1687  if (!interface_struct_handle) {
1688  interface_struct_handle = switch_dso_data_sym(dso, struct_name, &derr);
1689  }
1690 
1691  if (derr) {
1692  err = derr;
1693  break;
1694  }
1695 
1696  if (interface_struct_handle && interface_struct_handle->switch_api_version != SWITCH_API_VERSION) {
1697  err = "Trying to load an out of date module, please rebuild the module.";
1698  break;
1699  }
1700 
1701  if (!load_global && interface_struct_handle && switch_test_flag(interface_struct_handle, SMODF_GLOBAL_SYMBOLS)) {
1702  load_global = SWITCH_TRUE;
1703  switch_dso_destroy(&dso);
1704  interface_struct_handle = NULL;
1705  dso = switch_dso_open(path, load_global, &derr);
1706  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading module with global namespace at request of module\n");
1707  continue;
1708  }
1709 
1710  if (interface_struct_handle) {
1711  mod_interface_functions = interface_struct_handle;
1712  load_func_ptr = mod_interface_functions->load;
1713  }
1714 
1715  if (load_func_ptr == NULL) {
1716  err = "Cannot locate symbol 'switch_module_load' please make sure this is a valid module.";
1717  break;
1718  }
1719 
1720  status = load_func_ptr(&module_interface, pool);
1721 
1722  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_NOUNLOAD) {
1723  err = "Module load routine returned an error";
1724  module_interface = NULL;
1725  break;
1726  }
1727 
1728  if (!module_interface) {
1729  err = "Module failed to initialize its module_interface. Is this a valid module?";
1730  break;
1731  }
1732 
1733  if ((module = switch_core_alloc(pool, sizeof(switch_loadable_module_t))) == 0) {
1734  abort();
1735  }
1736 
1737  if (status == SWITCH_STATUS_NOUNLOAD) {
1738  module->perm++;
1739  }
1740 
1741  loading = 0;
1742  }
1743 
1744 
1745  if (err) {
1746 
1747  if (dso) {
1748  switch_dso_destroy(&dso);
1749  }
1750 
1751  if (pool) {
1753  }
1754  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Loading module %s\n**%s**\n", path, err);
1755  switch_safe_free(derr);
1756  return SWITCH_STATUS_GENERR;
1757  }
1758 
1759  module->pool = pool;
1760  module->filename = switch_core_strdup(module->pool, path);
1761  module->module_interface = module_interface;
1762  module->switch_module_load = load_func_ptr;
1763 
1764  if (mod_interface_functions) {
1765  module->switch_module_shutdown = mod_interface_functions->shutdown;
1766  module->switch_module_runtime = mod_interface_functions->runtime;
1767  }
1768 
1769  module->lib = dso;
1770 
1771  *new_module = module;
1772  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
1773 
1775 
1776  return SWITCH_STATUS_SUCCESS;
1777 
1778 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
switch_module_load_t switch_module_load
switch_memory_pool_t * pool
#define SWITCH_CHANNEL_LOG
switch_bool_t
Definition: switch_types.h:441
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
#define SWITCH_API_VERSION
switch_memory_pool_t * pool
void switch_dso_destroy(switch_dso_lib_t *lib)
Definition: switch_dso.c:91
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
switch_dso_lib_t switch_dso_open(const char *path, int global, char **err)
Definition: switch_dso.c:101
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:82
const char *const const char *const path
switch_loadable_module_interface_t * module_interface
const char * filename
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:132
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
switch_module_shutdown_t shutdown
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
struct fspr_pool_t switch_memory_pool_t
void switch_core_set_signal_handlers(void)
Definition: switch_core.c:2579
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.

◆ switch_loadable_module_load_module_ex()

static switch_status_t switch_loadable_module_load_module_ex ( const char *  dir,
const char *  fname,
switch_bool_t  runtime,
switch_bool_t  global,
const char **  err,
switch_loadable_module_type_t  type,
switch_hash_t event_hash 
)
static

Definition at line 1784 of file switch_loadable_module.c.

References loadable_modules, switch_loadable_module_container::module_hash, switch_loadable_module_container::mutex, path, 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, switch_str_nil, switch_loadable_module::thread, and switch_loadable_module::type.

Referenced by switch_loadable_module_init(), and switch_loadable_module_load_module().

1785 {
1786  switch_size_t len = 0;
1787  char *path;
1788  char *file, *dot;
1789  switch_loadable_module_t *new_module = NULL;
1791 
1792 #ifdef WIN32
1793  const char *ext = ".dll";
1794 #else
1795  const char *ext = ".so";
1796 #endif
1797 
1798  *err = "";
1799 
1800  if ((file = switch_core_strdup(loadable_modules.pool, fname)) == 0) {
1801  *err = "allocation error";
1802  return SWITCH_STATUS_FALSE;
1803  }
1804 
1805  if (switch_is_file_path(file)) {
1807  file = (char *) switch_cut_path(file);
1808  if ((dot = strchr(file, '.'))) {
1809  *dot = '\0';
1810  }
1811  } else {
1812  if ((dot = strchr(file, '.'))) {
1813  *dot = '\0';
1814  }
1815  len = strlen(switch_str_nil(dir));
1816  len += strlen(file);
1817  len += 8;
1818  path = (char *) switch_core_alloc(loadable_modules.pool, len);
1819  switch_snprintf(path, len, "%s%s%s%s", switch_str_nil(dir), SWITCH_PATH_SEPARATOR, file, ext);
1820  }
1821 
1822 
1824  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Module %s Already Loaded!\n", file);
1825  *err = "Module already loaded";
1826  status = SWITCH_STATUS_FALSE;
1827  } else if ((status = switch_loadable_module_load_file(path, file, global, &new_module)) == SWITCH_STATUS_SUCCESS) {
1828  new_module->type = type;
1829 
1830  if ((status = switch_loadable_module_process(file, new_module, event_hash)) == SWITCH_STATUS_SUCCESS && runtime) {
1831  if (new_module->switch_module_runtime) {
1832  new_module->thread = switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool);
1833  }
1834  } else if (status != SWITCH_STATUS_SUCCESS) {
1835  *err = "module load routine returned an error";
1836  }
1837  } else {
1838  *err = "module load file routine returned an error";
1839  }
1840 
1841 
1842  return status;
1843 
1844 }
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:733
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
struct switch_runtime runtime
Definition: switch_core.c:86
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:124
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:684
uintptr_t switch_size_t
switch_loadable_module_type_t type
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:993
switch_status_t
Common return values.
const char *const const char *const path
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)
static switch_status_t switch_loadable_module_process(char *key, switch_loadable_module_t *new_module, switch_hash_t *event_hash)
switch_module_runtime_t switch_module_runtime
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_cut_path(const char *in)
Create a pointer to the file name in a given file path eliminating the directory name.

◆ switch_loadable_module_process()

static switch_status_t switch_loadable_module_process ( char *  key,
switch_loadable_module_t new_module,
switch_hash_t event_hash 
)
static

Definition at line 156 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::chat_rwlock, switch_loadable_module_container::codec_hash, switch_loadable_module_interface::codec_interface, switch_loadable_module_container::database_hash, switch_loadable_module_interface::database_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_database_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_database_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_database_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_database_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_codec_implementation::number_of_channels, switch_loadable_module::pool, switch_database_interface::prefixes, switch_file_node_s::ptr, switch_database_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_hash_insert_pointer(), 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_thread_rwlock_unlock(), switch_thread_rwlock_wrlock(), 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().

157 {
158  switch_event_t *event;
159  int added = 0;
160 
161  new_module->key = switch_core_strdup(new_module->pool, key);
162 
165 
166  if (new_module->module_interface->endpoint_interface) {
167  const switch_endpoint_interface_t *ptr;
168  for (ptr = new_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
169  if (!ptr->interface_name) {
170  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load endpoint interface from %s due to no interface name.\n", key);
171  } else {
172  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Endpoint '%s'\n", ptr->interface_name);
175  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "endpoint");
177  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
178  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
179 
180  if (!event_hash) {
181  switch_event_fire(&event);
182  } else {
183  switch_core_hash_insert_pointer(event_hash, (const void*)event);
184  }
185 
186  added++;
187  }
188  }
189  }
190  }
191 
192  if (new_module->module_interface->codec_interface) {
193  const switch_codec_implementation_t *impl;
194  const switch_codec_interface_t *ptr;
195 
196  for (ptr = new_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
197  if (!ptr->interface_name) {
198  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load codec interface from %s due to no interface name.\n", key);
199  } else {
200  unsigned load_interface = 1;
201  switch_codec_node_t *node, *head;
202 
203  for (impl = ptr->implementations; impl; impl = impl->next) {
204  if (!impl->iananame) {
205  load_interface = 0;
207  "Failed to load codec interface %s from %s due to no iana name in an implementation.\n", ptr->interface_name,
208  key);
209  break;
210  }
212  load_interface = 0;
214  "Failed to load codec interface %s from %s due to bytes per frame %d exceeding buffer size %d.\n",
215  ptr->interface_name,
217  break;
218  }
219  }
220  if (load_interface) {
221  for (impl = ptr->implementations; impl; impl = impl->next) {
222  if (impl->bits_per_second) {
224  "Adding Codec %s %d %s %dhz %dms %dch %dbps\n",
225  impl->iananame, impl->ianacode,
227  impl->microseconds_per_packet / 1000, impl->number_of_channels, impl->bits_per_second);
228  } else {
230  "Adding Codec %s %d %s %dhz %dms %dch (VBR)\n",
231  impl->iananame, impl->ianacode,
233  }
234 
235  node = switch_core_alloc(new_module->pool, sizeof(*node));
236  node->ptr = ptr;
237  node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name);
239  node->next = head;
240  }
241 
242  switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) node);
243  }
244 
246  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "codec");
248  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
249  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
251 
252  if (!event_hash) {
253  switch_event_fire(&event);
254  }
255  else {
256  switch_core_hash_insert_pointer(event_hash, (const void*)event);
257  }
258 
259  added++;
260  }
261  }
262  }
263  }
264  }
265 
266  if (new_module->module_interface->dialplan_interface) {
267  const switch_dialplan_interface_t *ptr;
268 
269  for (ptr = new_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) {
270  if (!ptr->interface_name) {
271  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load dialplan interface from %s due to no interface name.\n", key);
272  } else {
273  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Dialplan '%s'\n", ptr->interface_name);
275  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "dialplan");
277  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
278  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
279 
280  if (!event_hash) {
281  switch_event_fire(&event);
282  }
283  else {
284  switch_core_hash_insert_pointer(event_hash, (const void*)event);
285  }
286 
287  added++;
288  }
290  }
291  }
292  }
293 
294  if (new_module->module_interface->timer_interface) {
295  const switch_timer_interface_t *ptr;
296 
297  for (ptr = new_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
298  if (!ptr->interface_name) {
299  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load timer interface from %s due to no interface name.\n", key);
300  } else {
303  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "timer");
305  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
306  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
307 
308  if (!event_hash) {
309  switch_event_fire(&event);
310  }
311  else {
312  switch_core_hash_insert_pointer(event_hash, (const void*)event);
313  }
314 
315  added++;
316  }
318  }
319  }
320  }
321 
322  if (new_module->module_interface->application_interface) {
324 
325  for (ptr = new_module->module_interface->application_interface; ptr; ptr = ptr->next) {
326  if (!ptr->interface_name) {
327  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key);
328  } else {
329  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Application '%s'\n", ptr->interface_name);
331  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
335  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
336  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
337 
338  if (!event_hash) {
339  switch_event_fire(&event);
340  }
341  else {
342  switch_core_hash_insert_pointer(event_hash, (const void*)event);
343  }
344 
345  added++;
346  }
348  }
349  }
350  }
351 
352  if (new_module->module_interface->chat_application_interface) {
354 
355  for (ptr = new_module->module_interface->chat_application_interface; ptr; ptr = ptr->next) {
356  if (!ptr->interface_name) {
357  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load application interface from %s due to no interface name.\n", key);
358  } else {
359  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Chat Application '%s'\n", ptr->interface_name);
361  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
365  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
366  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
367 
368  if (!event_hash) {
369  switch_event_fire(&event);
370  }
371  else {
372  switch_core_hash_insert_pointer(event_hash, (const void*)event);
373  }
374 
375  added++;
376  }
378  }
379  }
380  }
381 
382  if (new_module->module_interface->api_interface) {
383  const switch_api_interface_t *ptr;
384 
385  for (ptr = new_module->module_interface->api_interface; ptr; ptr = ptr->next) {
386  if (!ptr->interface_name) {
387  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load api interface from %s due to no interface name.\n", key);
388  } else {
389  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding API Function '%s'\n", ptr->interface_name);
395  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
396  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
397 
398  if (!event_hash) {
399  switch_event_fire(&event);
400  }
401  else {
402  switch_core_hash_insert_pointer(event_hash, (const void*)event);
403  }
404 
405  added++;
406  }
408  }
409  }
410  }
411 
412  if (new_module->module_interface->json_api_interface) {
413  const switch_json_api_interface_t *ptr;
414 
415  for (ptr = new_module->module_interface->json_api_interface; ptr; ptr = ptr->next) {
416  if (!ptr->interface_name) {
417  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load JSON api interface from %s due to no interface name.\n", key);
418  } else {
419  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding JSON API Function '%s'\n", ptr->interface_name);
421  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "json_api");
425  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
426  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
427 
428  if (!event_hash) {
429  switch_event_fire(&event);
430  }
431  else {
432  switch_core_hash_insert_pointer(event_hash, (const void*)event);
433  }
434 
435  added++;
436  }
438  }
439  }
440  }
441 
442  if (new_module->module_interface->file_interface) {
443  const switch_file_interface_t *ptr;
444 
445  for (ptr = new_module->module_interface->file_interface; ptr; ptr = ptr->next) {
446  if (!ptr->interface_name) {
447  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no interface name.\n", key);
448  } else if (!ptr->extens) {
449  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load file interface from %s due to no file extensions.\n", key);
450  } else {
451  int i;
452  switch_file_node_t *node, *head;
453 
454  for (i = 0; ptr->extens[i]; i++) {
455  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding File Format '%s'\n", ptr->extens[i]);
457  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "file");
459  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
460  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
462 
463  if (!event_hash) {
464  switch_event_fire(&event);
465  }
466  else {
467  switch_core_hash_insert_pointer(event_hash, (const void*)event);
468  }
469 
470  added++;
471  }
472  node = switch_core_alloc(new_module->pool, sizeof(*node));
473  node->ptr = ptr;
474  node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name);
475  if ((head = switch_core_hash_find(loadable_modules.file_hash, ptr->extens[i]))) {
476  node->next = head;
477  }
478 
479  switch_core_hash_insert(loadable_modules.file_hash, ptr->extens[i], (const void *) node);
480  }
481  }
482  }
483  }
484 
485  if (new_module->module_interface->database_interface) {
486  const switch_database_interface_t *ptr;
487 
488  for (ptr = new_module->module_interface->database_interface; ptr; ptr = ptr->next) {
489  if (!ptr->interface_name) {
490  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load database interface from %s due to no interface name.\n", key);
491  }
492  else if (!ptr->prefixes) {
493  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load database interface from %s due to no prefixes.\n", key);
494  }
495  else {
496  int i;
497  switch_database_node_t *node, *head;
498 
499  for (i = 0; ptr->prefixes[i]; i++) {
500  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding dsn prefix '%s'\n", ptr->prefixes[i]);
502  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "database");
504  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
505  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
507 
508  if (!event_hash) {
509  switch_event_fire(&event);
510  }
511  else {
512  switch_core_hash_insert_pointer(event_hash, (const void*)event);
513  }
514 
515  added++;
516  }
517  node = switch_core_alloc(new_module->pool, sizeof(*node));
518  node->ptr = ptr;
519  node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name);
521  node->next = head;
522  }
523 
524  switch_core_hash_insert(loadable_modules.database_hash, ptr->prefixes[i], (const void *)node);
525  }
526  }
527  }
528  }
529 
530  if (new_module->module_interface->speech_interface) {
531  const switch_speech_interface_t *ptr;
532 
533  for (ptr = new_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
534  if (!ptr->interface_name) {
535  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load speech interface from %s due to no interface name.\n", key);
536  } else {
537  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Speech interface '%s'\n", ptr->interface_name);
539  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
541  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
542  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
543 
544  if (!event_hash) {
545  switch_event_fire(&event);
546  }
547  else {
548  switch_core_hash_insert_pointer(event_hash, (const void*)event);
549  }
550 
551  added++;
552  }
554  }
555  }
556  }
557 
558  if (new_module->module_interface->asr_interface) {
559  const switch_asr_interface_t *ptr;
560 
561  for (ptr = new_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
562  if (!ptr->interface_name) {
563  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load asr interface from %s due to no interface name.\n", key);
564  } else {
565  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding ASR interface '%s'\n", ptr->interface_name);
569  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
570  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
571 
572  if (!event_hash) {
573  switch_event_fire(&event);
574  }
575  else {
576  switch_core_hash_insert_pointer(event_hash, (const void*)event);
577  }
578 
579  added++;
580  }
582  }
583  }
584  }
585 
586  if (new_module->module_interface->directory_interface) {
587  const switch_directory_interface_t *ptr;
588 
589  for (ptr = new_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
590  if (!ptr->interface_name) {
591  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load directory interface from %s due to no interface name.\n", key);
592  } else {
593  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Directory interface '%s'\n", ptr->interface_name);
595  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
597  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
598  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
599 
600  if (!event_hash) {
601  switch_event_fire(&event);
602  }
603  else {
604  switch_core_hash_insert_pointer(event_hash, (const void*)event);
605  }
606 
607  added++;
608  }
610  }
611  }
612  }
613 
614  if (new_module->module_interface->chat_interface) {
615  const switch_chat_interface_t *ptr;
616 
617  for (ptr = new_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
618  if (!ptr->interface_name) {
619  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load chat interface from %s due to no interface name.\n", key);
620  } else {
621  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Chat interface '%s'\n", ptr->interface_name);
623  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
625  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
626  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
627 
628  if (!event_hash) {
629  switch_event_fire(&event);
630  }
631  else {
632  switch_core_hash_insert_pointer(event_hash, (const void*)event);
633  }
634 
635  added++;
636  }
640  }
641  }
642  }
643 
644  if (new_module->module_interface->say_interface) {
645  const switch_say_interface_t *ptr;
646 
647  for (ptr = new_module->module_interface->say_interface; ptr; ptr = ptr->next) {
648  if (!ptr->interface_name) {
649  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load say interface from %s due to no interface name.\n", key);
650  } else {
651  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Say interface '%s'\n", ptr->interface_name);
655  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
656  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
657 
658  if (!event_hash) {
659  switch_event_fire(&event);
660  }
661  else {
662  switch_core_hash_insert_pointer(event_hash, (const void*)event);
663  }
664 
665  added++;
666  }
668  }
669  }
670  }
671 
672  if (new_module->module_interface->management_interface) {
674 
675  for (ptr = new_module->module_interface->management_interface; ptr; ptr = ptr->next) {
676  if (!ptr->relative_oid) {
677  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load management interface from %s due to no interface name.\n", key);
678  } else {
681  "Failed to load management interface %s. OID %s already exists\n", key, ptr->relative_oid);
682  } else {
684  "Adding Management interface '%s' OID[%s.%s]\n", key, FREESWITCH_OID_PREFIX, ptr->relative_oid);
687  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "management");
689  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
690  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
691 
692  if (!event_hash) {
693  switch_event_fire(&event);
694  }
695  else {
696  switch_core_hash_insert_pointer(event_hash, (const void*)event);
697  }
698 
699  added++;
700  }
701  }
702 
703  }
704  }
705  }
706  if (new_module->module_interface->limit_interface) {
707  const switch_limit_interface_t *ptr;
708 
709  for (ptr = new_module->module_interface->limit_interface; ptr; ptr = ptr->next) {
710  if (!ptr->interface_name) {
711  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load limit interface from %s due to no interface name.\n", key);
712  } else {
715  "Failed to load limit interface %s. Name %s already exists\n", key, ptr->interface_name);
716  } else {
718  "Adding Limit interface '%s'\n", ptr->interface_name);
721  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "limit");
723  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
724  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
725 
726  if (!event_hash) {
727  switch_event_fire(&event);
728  }
729  else {
730  switch_core_hash_insert_pointer(event_hash, (const void*)event);
731  }
732 
733  added++;
734  }
735  }
736 
737  }
738  }
739  }
740 
741  if (!added) {
743  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "generic");
744  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", new_module->key);
745  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
746  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
747 
748  if (!event_hash) {
749  switch_event_fire(&event);
750  }
751  else {
752  switch_core_hash_insert_pointer(event_hash, (const void*)event);
753  }
754 
755  added++;
756  }
757  }
758 
760  return SWITCH_STATUS_SUCCESS;
761 
762 }
struct switch_database_interface * next
static struct switch_loadable_module_container loadable_modules
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
A module interface to implement an application.
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:286
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:594
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
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_database_interface_t * database_interface
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:313
struct switch_timer_interface * next
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:260
switch_timer_interface_t * timer_interface
Abstract interface to a speech module.
A module interface to implement an api function.
const switch_database_interface_t * ptr
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:308
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
Abstract interface to a management module.
switch_chat_interface_t * chat_interface
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:993
switch_status_t switch_core_hash_insert_pointer(switch_hash_t *hash, const void *data)
Insert data into a hash with an auto-generated key based on the data pointer.
switch_management_interface_t * management_interface
struct switch_database_node_s * next
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:1479
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
struct switch_say_interface * next
struct switch_codec_implementation * next
char * key
Definition: switch_msrp.c:64
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 database module.
Abstract interface to a directory module.
struct switch_asr_interface * next

◆ switch_loadable_module_runtime()

static void switch_loadable_module_runtime ( void  )
static

Definition at line 137 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().

138 {
140  void *val;
141  switch_loadable_module_t *module;
142 
145  switch_core_hash_this(hi, NULL, NULL, &val);
146  module = (switch_loadable_module_t *) val;
147 
148  if (module->switch_module_runtime) {
149  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Starting runtime thread for %s\n", module->module_interface->module_name);
151  }
152  }
154 }
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:313
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
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:1592

◆ switch_loadable_module_sort_codecs()

static void switch_loadable_module_sort_codecs ( const switch_codec_implementation_t **  array,
int  arraylen 
)
static

Definition at line 2627 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().

2628 {
2629  int i = 0, sorted_ptime = 0;
2630 
2631 #ifdef DEBUG_CODEC_SORTING
2633  do_print(array, arraylen);
2635 #endif
2636 
2637  for (i = 0; i < arraylen; i++) {
2638  int this_ptime;
2639 
2640  if (!array[i]) {
2641  continue;
2642  }
2643 
2644  this_ptime = array[i]->microseconds_per_packet / 1000;
2645 
2646  if (!strcasecmp(array[i]->iananame, "ilbc")) {
2647  this_ptime = 20;
2648  }
2649 
2650  if (!sorted_ptime) {
2651  sorted_ptime = this_ptime;
2652 #ifdef DEBUG_CODEC_SORTING
2653  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sorted1 = %d\n", sorted_ptime);
2654 #endif
2655  }
2656 
2657  if (i > 0 && array[i-1] && strcasecmp(array[i]->iananame, array[i-1]->iananame) && this_ptime != sorted_ptime) {
2658  int j;
2659  int swapped = 0;
2660 
2661 #ifdef DEBUG_CODEC_SORTING
2662  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%d != %d\n", this_ptime, sorted_ptime);
2663 #endif
2664  for(j = i; j < arraylen; j++) {
2665  int check_ptime = array[j]->microseconds_per_packet / 1000;
2666 
2667  if (!strcasecmp(array[i]->iananame, "ilbc")) {
2668  check_ptime = 20;
2669  }
2670 
2671  if (check_ptime == sorted_ptime) {
2672 #ifdef DEBUG_CODEC_SORTING
2673  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "swap %d %d ptime %d\n", i, j, check_ptime);
2674 #endif
2675  do_swap(array, i, j);
2676  swapped = 1;
2677  break;
2678  }
2679  }
2680 
2681  if (!swapped) {
2682  sorted_ptime = this_ptime;
2683 #ifdef DEBUG_CODEC_SORTING
2684  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sorted2 = %d\n", sorted_ptime);
2685 #endif
2686  }
2687  }
2688  }
2689 
2690 #ifdef DEBUG_CODEC_SORTING
2692  do_print(array, arraylen);
2694 #endif
2695 
2696 }
#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.

◆ switch_loadable_module_unprocess()

static switch_status_t switch_loadable_module_unprocess ( switch_loadable_module_t old_module)
static

Definition at line 1103 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::chat_rwlock, switch_loadable_module_container::codec_hash, switch_loadable_module_interface::codec_interface, switch_loadable_module_container::database_hash, switch_loadable_module_interface::database_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, 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_database_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_database_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_database_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_database_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_database_interface::prefixes, switch_file_node_s::ptr, 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_database_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_cache_db_database_interface_flush_handles(), 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_thread_rwlock_wrlock(), 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().

1104 {
1105  switch_event_t *event;
1106  int removed = 0;
1107 
1109 
1110  if (old_module->module_interface->endpoint_interface) {
1111  const switch_endpoint_interface_t *ptr;
1112 
1113  for (ptr = old_module->module_interface->endpoint_interface; ptr; ptr = ptr->next) {
1114  if (ptr->interface_name) {
1115 
1117  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1118  ptr->interface_name);
1121  } else {
1122  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1123  }
1124 
1125  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Endpoint '%s'\n", ptr->interface_name);
1127  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "endpoint");
1129  switch_event_fire(&event);
1130  removed++;
1131  }
1133  }
1134  }
1135  }
1136 
1137  if (old_module->module_interface->codec_interface) {
1138  const switch_codec_implementation_t *impl;
1139  const switch_codec_interface_t *ptr;
1140  switch_codec_node_t *node, *head, *last = NULL;
1141 
1142  for (ptr = old_module->module_interface->codec_interface; ptr; ptr = ptr->next) {
1143  if (ptr->interface_name) {
1144  unsigned load_interface = 1;
1145  for (impl = ptr->implementations; impl; impl = impl->next) {
1146  if (!impl->iananame) {
1147  load_interface = 0;
1148  break;
1149  }
1150  }
1151  if (load_interface) {
1152  for (impl = ptr->implementations; impl; impl = impl->next) {
1154  "Deleting Codec %s %d %s %dhz %dms\n",
1155  impl->iananame, impl->ianacode,
1159 
1161  for(node = head; node; node = node->next) {
1162  if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
1163  if (node == head) {
1164  if ((node = node->next)) {
1165  switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) node);
1166  } else {
1168  }
1169  } else {
1170  if (last) {
1171  last->next = node->next;
1172  }
1173  }
1174  break;
1175  }
1176  last = node;
1177  }
1178  }
1179  }
1181  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "codec");
1184  switch_event_fire(&event);
1185  removed++;
1186  }
1187  }
1188  }
1189  }
1190  }
1191 
1192  if (old_module->module_interface->dialplan_interface) {
1193  const switch_dialplan_interface_t *ptr;
1194 
1195  for (ptr = old_module->module_interface->dialplan_interface; ptr; ptr = ptr->next) {
1196  if (ptr->interface_name) {
1197  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Dialplan '%s'\n", ptr->interface_name);
1199  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "dialplan");
1201  switch_event_fire(&event);
1202  removed++;
1203  }
1205  }
1206  }
1207  }
1208 
1209  if (old_module->module_interface->timer_interface) {
1210  const switch_timer_interface_t *ptr;
1211 
1212  for (ptr = old_module->module_interface->timer_interface; ptr; ptr = ptr->next) {
1213  if (ptr->interface_name) {
1214  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Timer '%s'\n", ptr->interface_name);
1216  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "timer");
1218  switch_event_fire(&event);
1219  removed++;
1220  }
1222  }
1223  }
1224  }
1225 
1226  if (old_module->module_interface->application_interface) {
1227  const switch_application_interface_t *ptr;
1228  for (ptr = old_module->module_interface->application_interface; ptr; ptr = ptr->next) {
1229  if (ptr->interface_name) {
1230  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
1232  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1233  ptr->interface_name);
1236  } else {
1237  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1238  }
1239 
1241  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
1245  switch_event_fire(&event);
1246  removed++;
1247  }
1249  }
1250  }
1251  }
1252 
1253  if (old_module->module_interface->chat_application_interface) {
1255  for (ptr = old_module->module_interface->chat_application_interface; ptr; ptr = ptr->next) {
1256  if (ptr->interface_name) {
1257  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name);
1259  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1260  ptr->interface_name);
1263  } else {
1264  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1265  }
1266 
1268  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application");
1272  switch_event_fire(&event);
1273  removed++;
1274  }
1276  }
1277  }
1278  }
1279 
1280  if (old_module->module_interface->api_interface) {
1281  const switch_api_interface_t *ptr;
1282 
1283  for (ptr = old_module->module_interface->api_interface; ptr; ptr = ptr->next) {
1284  if (ptr->interface_name) {
1285  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
1286 
1287  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1288  ptr->interface_name);
1289 
1292  } else {
1293  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1294  }
1295 
1296 
1298  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");
1302  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", old_module->key);
1303  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", old_module->filename);
1304  switch_event_fire(&event);
1305  removed++;
1306  }
1308  }
1309  }
1310  }
1311 
1312  if (old_module->module_interface->json_api_interface) {
1313  const switch_json_api_interface_t *ptr;
1314 
1315  for (ptr = old_module->module_interface->json_api_interface; ptr; ptr = ptr->next) {
1316  if (ptr->interface_name) {
1317  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name);
1318 
1319  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1320  ptr->interface_name);
1321 
1324  } else {
1325  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1326  }
1327 
1328 
1330  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "json_api");
1334  switch_event_fire(&event);
1335  removed++;
1336  }
1338  }
1339  }
1340  }
1341 
1342  if (old_module->module_interface->file_interface) {
1343  const switch_file_interface_t *ptr;
1344  switch_file_node_t *node, *head, *last = NULL;
1345 
1346  for (ptr = old_module->module_interface->file_interface; ptr; ptr = ptr->next) {
1347  if (ptr->interface_name) {
1348  int i;
1349 
1350  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1351  ptr->interface_name);
1352 
1355  } else {
1356  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1357  }
1358 
1359  for (i = 0; ptr->extens[i]; i++) {
1360  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting File Format '%s'\n", ptr->extens[i]);
1362  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "file");
1365  switch_event_fire(&event);
1366  removed++;
1367  }
1368 
1369  if ((head = switch_core_hash_find(loadable_modules.file_hash, ptr->extens[i]))) {
1370  for(node = head; node; node = node->next) {
1371  if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
1372  if (node == head) {
1373  if ((node = node->next)) {
1374  switch_core_hash_insert(loadable_modules.file_hash, ptr->extens[i], (const void *) node);
1375  } else {
1377  }
1378  } else {
1379  if (last) {
1380  last->next = node->next;
1381  }
1382  }
1383  break;
1384  }
1385  last = node;
1386  }
1387  }
1388  }
1389  }
1390  }
1391  }
1392 
1393  if (old_module->module_interface->database_interface) {
1394  const switch_database_interface_t *ptr;
1395  switch_database_node_t *node, *head, *last = NULL;
1396 
1397  for (ptr = old_module->module_interface->database_interface; ptr; ptr = ptr->next) {
1398  if (ptr->interface_name) {
1399  int i;
1400 
1401  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1402  ptr->interface_name);
1403 
1406  }
1407  else {
1408  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1409  }
1410 
1411  for (i = 0; ptr->prefixes[i]; i++) {
1412  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting dsn prefix '%s'\n", ptr->prefixes[i]);
1414  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "database");
1417  switch_event_fire(&event);
1418  removed++;
1419  }
1420 
1422  for (node = head; node; node = node->next) {
1423  if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
1424  if (node == head) {
1425  if ((node = node->next)) {
1426  switch_core_hash_insert(loadable_modules.database_hash, ptr->prefixes[i], (const void *)node);
1427  }
1428  else {
1430  }
1431  }
1432  else {
1433  if (last) {
1434  last->next = node->next;
1435  }
1436  }
1437  break;
1438  }
1439  last = node;
1440  }
1441  }
1442  }
1443 
1445  }
1446  }
1447  }
1448 
1449  if (old_module->module_interface->speech_interface) {
1450  const switch_speech_interface_t *ptr;
1451 
1452  for (ptr = old_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
1453 
1454  if (ptr->interface_name) {
1455 
1456  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1457  ptr->interface_name);
1458 
1461  } else {
1462  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1463  }
1464 
1465  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Speech interface '%s'\n", ptr->interface_name);
1467  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
1469  switch_event_fire(&event);
1470  removed++;
1471  }
1473  }
1474  }
1475  }
1476 
1477  if (old_module->module_interface->asr_interface) {
1478  const switch_asr_interface_t *ptr;
1479 
1480  for (ptr = old_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
1481  if (ptr->interface_name) {
1482 
1483  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1484  ptr->interface_name);
1485 
1488  } else {
1489  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1490  }
1491 
1492  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Asr interface '%s'\n", ptr->interface_name);
1494  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "asr");
1496  switch_event_fire(&event);
1497  removed++;
1498  }
1500  }
1501  }
1502  }
1503 
1504  if (old_module->module_interface->directory_interface) {
1505  const switch_directory_interface_t *ptr;
1506 
1507  for (ptr = old_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
1508  if (ptr->interface_name) {
1509 
1510  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1511  ptr->interface_name);
1512 
1515  } else {
1516  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1517  }
1518 
1519  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Directory interface '%s'\n", ptr->interface_name);
1521  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
1523  switch_event_fire(&event);
1524  removed++;
1525  }
1527  }
1528  }
1529  }
1530 
1531 
1532  if (old_module->module_interface->chat_interface) {
1533  const switch_chat_interface_t *ptr;
1534 
1535  for (ptr = old_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
1536  if (ptr->interface_name) {
1537  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1538  ptr->interface_name);
1539 
1542  } else {
1543  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1544  }
1545 
1546  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Chat interface '%s'\n", ptr->interface_name);
1548  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
1550  switch_event_fire(&event);
1551  removed++;
1552  }
1556  }
1557  }
1558  }
1559 
1560  if (old_module->module_interface->say_interface) {
1561  const switch_say_interface_t *ptr;
1562 
1563  for (ptr = old_module->module_interface->say_interface; ptr; ptr = ptr->next) {
1564  if (ptr->interface_name) {
1565  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
1566  ptr->interface_name);
1567 
1570  } else {
1571  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
1572  }
1573  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Say interface '%s'\n", ptr->interface_name);
1575  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "say");
1577  switch_event_fire(&event);
1578  removed++;
1579  }
1581  }
1582  }
1583  }
1584 
1585  if (old_module->module_interface->management_interface) {
1586  const switch_management_interface_t *ptr;
1587 
1588  for (ptr = old_module->module_interface->management_interface; ptr; ptr = ptr->next) {
1589  if (ptr->relative_oid) {
1591  "Deleting Management interface '%s' OID[%s.%s]\n", old_module->key, FREESWITCH_OID_PREFIX, ptr->relative_oid);
1594  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "management");
1596  switch_event_fire(&event);
1597  removed++;
1598  }
1599  }
1600  }
1601  }
1602 
1603  if (old_module->module_interface->limit_interface) {
1604  const switch_limit_interface_t *ptr;
1605 
1606  for (ptr = old_module->module_interface->limit_interface; ptr; ptr = ptr->next) {
1607  if (ptr->interface_name) {
1609  "Deleting Limit interface '%s'\n", ptr->interface_name);
1612  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "limit");
1614  switch_event_fire(&event);
1615  removed++;
1616  }
1617  }
1618  }
1619  }
1620 
1621  if (!removed) {
1623  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "generic");
1624  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", old_module->key);
1625  switch_event_fire(&event);
1626  removed++;
1627  }
1628  }
1630 
1631  return SWITCH_STATUS_SUCCESS;
1632 
1633 }
struct switch_database_interface * next
static struct switch_loadable_module_container loadable_modules
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
A module interface to implement an application.
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:286
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:1000
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_database_interface_t * database_interface
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:313
struct switch_timer_interface * next
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:260
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:308
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:993
switch_management_interface_t * management_interface
struct switch_database_node_s * next
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:1479
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
struct switch_say_interface * next
switch_thread_rwlock_t * rwlock
void switch_core_session_hupall_endpoint(const switch_endpoint_interface_t *endpoint_interface, switch_call_cause_t cause)
Hangup all sessions that belong to an endpoint.
struct switch_codec_implementation * next
switch_thread_rwlock_t * rwlock
struct switch_application_interface * next
void switch_cache_db_database_interface_flush_handles(switch_database_interface_t *database_interface)
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:142
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:270
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 database module.
switch_thread_rwlock_t * rwlock
Abstract interface to a directory module.
struct switch_asr_interface * next

◆ switch_say_file()

void switch_say_file ( switch_say_file_handle_t sh,
const char *  fmt,
  ... 
)

Definition at line 3196 of file switch_loadable_module.c.

References buf, switch_say_file_handle::cnt, switch_say_file_handle::ext, switch_say_file_handle::stream, switch_vsnprintf(), and switch_stream_handle::write_function.

3197 {
3198  char buf[256] = "";
3199  va_list ap;
3200 
3201  va_start(ap, fmt);
3202 
3203  if (switch_vsnprintf(buf, sizeof(buf), fmt, ap) > 0) {
3204  if (!sh->cnt++) {
3205  sh->stream.write_function(&sh->stream, "file_string://%s.%s", buf, sh->ext);
3206  } else if (strstr(buf, "://")) {
3207  sh->stream.write_function(&sh->stream, "!%s", buf);
3208  } else {
3209  sh->stream.write_function(&sh->stream, "!%s.%s", buf, sh->ext);
3210  }
3211  }
3212 
3213  va_end(ap);
3214 }
struct switch_stream_handle stream
int cJSON_bool fmt
Definition: switch_cJSON.h:150
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:217

◆ switch_say_file_handle_create()

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 3173 of file switch_loadable_module.c.

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

3174 {
3175  switch_assert(sh);
3176 
3177  if (zstr(ext)) {
3178  ext = "wav";
3179  }
3180 
3181  *sh = malloc(sizeof(**sh));
3182  memset(*sh, 0, sizeof(**sh));
3183 
3184  SWITCH_STANDARD_STREAM((*sh)->stream);
3185 
3186  if (var_event) {
3187  (*sh)->param_event = *var_event;
3188  *var_event = NULL;
3189  }
3190 
3191  (*sh)->ext = strdup(ext);
3192 
3193  return SWITCH_STATUS_SUCCESS;
3194 }
#define zstr(x)
Definition: switch_utils.h:314
#define SWITCH_STANDARD_STREAM(s)
#define switch_assert(expr)
memset(buf, 0, buflen)

◆ switch_say_file_handle_destroy()

void switch_say_file_handle_destroy ( switch_say_file_handle_t **  sh)

Definition at line 3159 of file switch_loadable_module.c.

References switch_assert, switch_event_destroy(), and switch_safe_free.

3160 {
3161  switch_assert(sh);
3162 
3163  switch_safe_free((*sh)->stream.data);
3164  switch_safe_free((*sh)->ext);
3165 
3166  if ((*sh)->param_event) {
3167  switch_event_destroy(&(*sh)->param_event);
3168  }
3169  free(*sh);
3170  *sh = NULL;
3171 }
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)

◆ switch_say_file_handle_detach_path()

char* switch_say_file_handle_detach_path ( switch_say_file_handle_t sh)

Definition at line 3148 of file switch_loadable_module.c.

References switch_stream_handle::data, path, switch_say_file_handle::stream, and switch_assert.

3149 {
3150  char *path;
3151 
3152  switch_assert(sh);
3153  path = (char *) sh->stream.data;
3154  sh->stream.data = NULL;
3155  return path;
3156 }
struct switch_stream_handle stream
const char *const const char *const path
#define switch_assert(expr)

◆ switch_say_file_handle_get_path()

char* switch_say_file_handle_get_path ( switch_say_file_handle_t sh)

Definition at line 3143 of file switch_loadable_module.c.

References switch_stream_handle::data, and switch_say_file_handle::stream.

3144 {
3145  return (char *) sh->stream.data;
3146 }
struct switch_stream_handle stream

◆ switch_say_file_handle_get_variable()

char* switch_say_file_handle_get_variable ( switch_say_file_handle_t sh,
const char *  var 
)

Definition at line 3131 of file switch_loadable_module.c.

References switch_say_file_handle::param_event, and switch_event_get_header.

3132 {
3133  char *ret = NULL;
3134 
3135  if (sh->param_event) {
3136  ret = switch_event_get_header(sh->param_event, var);
3137  }
3138 
3139  return ret;
3140 
3141 }
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172

Variable Documentation

◆ chat_globals

struct { ... } chat_globals

◆ IDX

int IDX = 0
static

Definition at line 776 of file switch_loadable_module.c.

Referenced by chat_queue_message().

◆ loadable_modules

struct switch_loadable_module_container loadable_modules
static

◆ msg_queue

Definition at line 768 of file switch_loadable_module.c.

◆ msg_queue_len

int msg_queue_len

Definition at line 770 of file switch_loadable_module.c.

◆ msg_queue_thread

switch_thread_t* msg_queue_thread[CHAT_MAX_MSG_QUEUE]

Definition at line 769 of file switch_loadable_module.c.

◆ mutex

◆ pool

◆ running

int running

Definition at line 773 of file switch_loadable_module.c.