diff --git a/src/include/switch_loadable_module.h b/src/include/switch_loadable_module.h index e0347d20c2..2cfbeb4b11 100644 --- a/src/include/switch_loadable_module.h +++ b/src/include/switch_loadable_module.h @@ -73,6 +73,8 @@ struct switch_loadable_module_interface { const switch_speech_interface_t *speech_interface; /*! the table of directory interfaces the module has implmented */ const switch_directory_interface_t *directory_interface; + /*! the table of chat interfaces the module has implmented */ + const switch_chat_interface_t *chat_interface; }; /*! @@ -163,6 +165,13 @@ SWITCH_DECLARE(switch_speech_interface_t *) switch_loadable_module_get_speech_in */ SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_directory_interface(char *name); +/*! + \brief Retrieve the chat interface by it's registered name + \param name the name of the chat interface + \return the desired chat interface + */ +SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(char *name); + /*! \brief Retrieve the list of loaded codecs into an array diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 46a86a5599..18c3d092ee 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -366,6 +366,14 @@ struct switch_speech_handle { }; +/*! \brief Abstract interface to a chat module */ +struct switch_chat_interface { + /*! the name of the interface */ + const char *interface_name; + /*! function to open the directory interface */ + switch_status_t (*chat_send)(char *from, char *to, char *subject, char *body, char *hint); + const struct switch_chat_interface *next; +}; /*! \brief Abstract interface to a directory module */ struct switch_directory_interface { diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 8a6c862ab0..1be4403a74 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -780,6 +780,7 @@ typedef struct switch_api_interface switch_api_interface_t; typedef struct switch_file_interface switch_file_interface_t; typedef struct switch_speech_interface switch_speech_interface_t; typedef struct switch_directory_interface switch_directory_interface_t; +typedef struct switch_chat_interface switch_chat_interface_t; typedef struct switch_core_port_allocator switch_core_port_allocator_t; typedef struct switch_media_bug switch_media_bug_t; typedef void (*switch_media_bug_callback_t)(switch_media_bug_t *, void *, switch_abc_type_t); diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 57aa3d089c..119d38c0c3 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -34,11 +34,11 @@ #define DL_CAND_WAIT 10000000 #define DL_CAND_INITIAL_WAIT 2000000 -#define JINGLE_KEY 1 #define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success" #define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure" #define DL_EVENT_CONNECTED "dingaling::connected" +#define MDL_CHAT_NAME "jingle" static const char modname[] = "mod_dingaling"; @@ -235,9 +235,6 @@ static void pres_event_handler(switch_event_t *event) switch_core_db_t *db; char *p; - if (event->key == JINGLE_KEY) { - return; - } if (status && !strcasecmp(status, "n/a")) { status = show; @@ -295,11 +292,8 @@ static void pres_event_handler(switch_event_t *event) switch_safe_free(sql); } -static void chat_event_handler(switch_event_t *event) +static switch_status_t chat_send(char *from, char *to, char *subject, char *body, char *hint) { - char *from = switch_event_get_header(event, "from"); - char *to = switch_event_get_header(event, "to"); - char *body = switch_event_get_body(event); char *user, *host, *f_user, *f_host = NULL; struct mdl_profile *profile = NULL; @@ -318,13 +312,14 @@ static void chat_event_handler(switch_event_t *event) ldl_handle_send_msg(profile->handle, from, to, NULL, body); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile %s\n", f_host ? f_host : "NULL"); - return; + return SWITCH_STATUS_FALSE; } switch_safe_free(f_host); free(user); } + return SWITCH_STATUS_SUCCESS; } @@ -339,9 +334,6 @@ static void roster_event_handler(switch_event_t *event) char *sql; switch_core_db_t *db; - if (event->key == JINGLE_KEY) { - return; - } if (status && !strcasecmp(status, "n/a")) { status = show; @@ -1252,7 +1244,10 @@ static switch_api_interface_t login_api_interface = { /*.next */ &logout_api_interface }; - +static const switch_chat_interface_t channel_chat_interface = { + /*.name */ MDL_CHAT_NAME, + /*.chat_send */ chat_send, +}; static const switch_loadable_module_interface_t channel_module_interface = { /*.module_name */ modname, @@ -1261,7 +1256,12 @@ static const switch_loadable_module_interface_t channel_module_interface = { /*.dialplan_interface */ NULL, /*.codec_interface */ NULL, /*.application_interface */ NULL, - /*.api_interface */ &login_api_interface + /*.api_interface */ &login_api_interface, + /*.file_interface */ NULL, + /*.speech_interface */ NULL, + /*.directory_interface */ NULL, + /*.chat_interface */ &channel_chat_interface + }; @@ -1427,11 +1427,6 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod return SWITCH_STATUS_GENERR; } - if (switch_event_bind((char *) modname, SWITCH_EVENT_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, chat_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); - return SWITCH_STATUS_GENERR; - } - /* connect my internal structure to the blank pointer passed to me */ *module_interface = &channel_module_interface; @@ -1828,50 +1823,55 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi break; case LDL_SIGNAL_ROSTER: if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "jingle"); - //event->key = JINGLE_KEY; + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from); switch_event_fire(&event); } break; case LDL_SIGNAL_PRESENCE_IN: if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "jingle"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", subject); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "%s", msg); - //event->key = JINGLE_KEY; switch_event_fire(&event); } break; case LDL_SIGNAL_PRESENCE_OUT: if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "jingle"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from); - //event->key = JINGLE_KEY; switch_event_fire(&event); } break; - case LDL_SIGNAL_MSG: - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "jingle"); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", "%s", subject); - event->key = JINGLE_KEY; - if (msg) { - switch_event_add_body(event, msg); - } + case LDL_SIGNAL_MSG: { + switch_chat_interface_t *ci; + char *proto = MDL_CHAT_NAME; + char *pproto = NULL; - if (profile->auto_reply) { - ldl_handle_send_msg(handle, (profile->user_flags & LDL_FLAG_COMPONENT) ? to : profile->login, from, "", profile->auto_reply); - } - - switch_event_fire(&event); + if (profile->auto_reply) { + ldl_handle_send_msg(handle, (profile->user_flags & LDL_FLAG_COMPONENT) ? to : profile->login, from, "", profile->auto_reply); } + + if (strchr(to, '+')) { + pproto = strdup(to); + if ((to = strchr(pproto, '+'))) { + *to++ = '\0'; + } + proto = pproto; + } + + if ((ci = switch_loadable_module_get_chat_interface(proto))) { + ci->chat_send(from, to, subject, msg, ""); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invaid Chat Interface [%s]!\n", proto); + } + + switch_safe_free(pproto); + } break; case LDL_SIGNAL_LOGIN_SUCCESS: if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_LOGIN_SUCCESS) == SWITCH_STATUS_SUCCESS) { @@ -1971,7 +1971,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi } if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "jingle"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 4e8d4e295f..c037d05ad2 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -67,7 +67,7 @@ typedef struct private_object private_object_t; #define MULTICAST_EVENT "multicast::event" #define SOFIA_REPLACES_HEADER "_sofia_replaces_" #define SOFIA_USER_AGENT "FreeSWITCH(mod_sofia)" -#define SIP_KEY 2 +#define SOFIA_CHAT_NAME "sip" #include #include @@ -407,6 +407,7 @@ static void launch_profile_thread(sofia_profile_t *profile); static switch_status_t config_sofia(int reload); +static switch_status_t chat_send(char *from, char *to, char *subject, char *body, char *hint); /* BODY OF THE MODULE */ /*************************************************************************************************************************************************************/ @@ -853,7 +854,7 @@ char *encode_name(char *s) char *at, *resource; char *user; - if (!strchr(s, '/') && !strchr(s, '@')) { + if (!strchr(s, '/')) { return NULL; } @@ -1820,7 +1821,6 @@ static switch_status_t sofia_receive_event(switch_core_session_t *session, switc SIPTAG_CONTACT_STR(tech_pvt->profile->url), TAG_END()); - nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR("text/html"), SIPTAG_PAYLOAD_STR(body), @@ -1860,13 +1860,24 @@ static const switch_endpoint_interface_t sofia_endpoint_interface = { /*.next */ NULL }; +static const switch_chat_interface_t sofia_chat_interface = { + /*.name */ SOFIA_CHAT_NAME, + /*.chat_send */ chat_send, + +}; + static const switch_loadable_module_interface_t sofia_module_interface = { /*.module_name */ modname, /*.endpoint_interface */ &sofia_endpoint_interface, /*.timer_interface */ NULL, /*.dialplan_interface */ NULL, /*.codec_interface */ NULL, - /*.application_interface */ NULL + /*.application_interface */ NULL, + /*.api_interface */ NULL, + /*.file_interface */ NULL, + /*.speech_interface */ NULL, + /*.directory_interface */ NULL, + /*.chat_interface */ &sofia_chat_interface }; @@ -2197,10 +2208,17 @@ static void sip_i_message(int status, char *to_addr; char *from_addr; char *p; + char *full_from; + char proto[512] = SOFIA_CHAT_NAME; + + full_from = sip_header_as_string(profile->home, (void *)sip->sip_from); if ((p=strchr(to_user, '+'))) { + switch_copy_string(proto, to_user, sizeof(proto)); + p = strchr(proto, '+'); + *p++ = '\0'; - if ((to_addr = strdup(++p))) { + if ((to_addr = strdup(p))) { p = strchr(to_addr, '+'); *p = '@'; } @@ -2209,7 +2227,7 @@ static void sip_i_message(int status, to_addr = switch_core_db_mprintf("%s@%s", to_user, to_host); } - from_addr = switch_core_db_mprintf("%s@%s", from_user, from_host); + from_addr = switch_core_db_mprintf("%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host); set_hash_key(hash_key, sizeof(hash_key), sip); if ((tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) { @@ -2220,7 +2238,6 @@ static void sip_i_message(int status, switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", tech_pvt->hash_key); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to_addr); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE"); - event->key = SIP_KEY; if (msg) { switch_event_add_body(event, msg); } @@ -2230,25 +2247,20 @@ static void sip_i_message(int status, } } } else { - - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip"); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from_addr); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to_addr); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE"); - event->key = SIP_KEY; - if (msg) { - switch_event_add_body(event, msg); - } - - switch_event_fire(&event); - + switch_chat_interface_t *ci; + + if ((ci = switch_loadable_module_get_chat_interface(proto))) { + ci->chat_send(from_addr, to_addr, "", msg, full_from); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invaid Chat Interface [%s]!\n", proto); } - + } switch_safe_free(to_addr); switch_safe_free(from_addr); + if (full_from) { + su_free(profile->home, full_from); + } } } @@ -2843,7 +2855,7 @@ static uint8_t handle_register(nua_t *nua, if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip"); - event->key = SIP_KEY; + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); switch_event_fire(&event); } @@ -2851,8 +2863,8 @@ static uint8_t handle_register(nua_t *nua, if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); - + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Registered"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "Registered"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); @@ -2862,7 +2874,7 @@ static uint8_t handle_register(nua_t *nua, if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "unavailable"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "unavailable"); @@ -3345,7 +3357,7 @@ static void sip_i_publish(nua_t *nua, if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", note_txt); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "%s", status_txt); @@ -3356,7 +3368,7 @@ static void sip_i_publish(nua_t *nua, if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "%s", event_type); switch_event_fire(&event); @@ -4452,38 +4464,46 @@ static int sub_callback(void *pArg, int argc, char **argv, char **columnNames){ return 0; } -static void chat_event_handler(switch_event_t *event) +static switch_status_t chat_send(char *from, char *to, char *subject, char *body, char *hint) { - char *from = switch_event_get_header(event, "from"); - char *to = switch_event_get_header(event, "to"); - char *body = switch_event_get_body(event); char buf[256]; char *user, *host; sofia_profile_t *profile; - char *from_p = NULL, *from_pp = NULL; - - if (event->key == SIP_KEY) { - return; - } - + char *from_p = NULL, *from_pp = NULL, *from_ppp = NULL; + if (to && (user = strdup(to))) { if ((host = strchr(user, '@'))) { *host++ = '\0'; } - + if (!host || !(profile = (sofia_profile_t *) switch_core_hash_find(globals.profile_hash, host))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile %s\n", host ? host : "NULL"); - return; + return SWITCH_STATUS_FALSE; } if (find_reg_url(profile, user, host, buf, sizeof(buf))) { nua_handle_t *msg_nh; - + if ((from_p = encode_name(from))) { - from_pp = switch_core_db_mprintf("\"%s\" ", from, from_p, host); + char *p, *q = NULL; + + from_ppp = strdup(from_p); + if ((p = strchr(from_ppp, '+'))) { + *p++ = '\0'; + if ((q = strchr(p, '+'))) { + *q = '@'; + } + } + if (!p) { + p = from; + } + from_pp = switch_core_db_mprintf("\"%s\" ", p, from_p, host); from = from_pp; + } else { + from = hint; } + msg_nh = nua_handle(profile->nua, NULL, SIPTAG_FROM_STR(from), NUTAG_URL(buf), @@ -4491,19 +4511,22 @@ static void chat_event_handler(switch_event_t *event) SIPTAG_CONTACT_STR(profile->url), TAG_END()); - nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR("text/html"), SIPTAG_PAYLOAD_STR(body), TAG_END()); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid chat dest"); } + switch_safe_free(from_p); switch_safe_free(from_pp); + switch_safe_free(from_ppp); free(user); } - + return SWITCH_STATUS_SUCCESS; } static void pres_event_handler(switch_event_t *event) @@ -4521,9 +4544,6 @@ static void pres_event_handler(switch_event_t *event) char *resource; switch_core_db_t *db; - if (event->key == SIP_KEY) { - return; - } if (event->event_id == SWITCH_EVENT_ROSTER) { sql = switch_core_db_mprintf("select 1,'%q',* from sip_subscriptions where event='presence'", status ? status : "Available"); @@ -4654,10 +4674,6 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod config_sofia(0); - if (switch_event_bind((char *) modname, SWITCH_EVENT_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, chat_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); - return SWITCH_STATUS_GENERR; - } if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); diff --git a/src/switch_core.c b/src/switch_core.c index 828cbce5d4..71bb371960 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1375,11 +1375,31 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_outgoing_channel(switch_core } if (channel && peer_channel) { + char *propagate_vars; + /* A comma (,) separated list of variable names that should ne propagated from originator to originatee */ + if ((propagate_vars = switch_channel_get_variable(channel, "propagate_vars"))) { + char *cptmp = switch_core_session_strdup(session, propagate_vars); + int argc; + char *argv[256]; + + if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { + int x; + + for (x = 0; x < argc; x++) { + char *val; + if ((val = switch_channel_get_variable(channel, argv[x]))) { + switch_channel_set_variable(peer_channel, argv[x], val); + } + } + } + } + if (profile) { if ((cloned_profile = switch_caller_profile_clone(*new_session, profile)) != 0) { switch_channel_set_originator_caller_profile(peer_channel, cloned_profile); } } + if (peer_profile) { if (session && (cloned_profile = switch_caller_profile_clone(session, peer_profile)) != 0) { switch_channel_set_originatee_caller_profile(channel, cloned_profile); diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index c97483d1f9..338b37576d 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -52,6 +52,7 @@ struct switch_loadable_module_container { switch_hash_t *file_hash; switch_hash_t *speech_hash; switch_hash_t *directory_hash; + switch_hash_t *chat_hash; switch_memory_pool_t *pool; }; @@ -230,6 +231,20 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_core_hash_insert(loadable_modules.directory_hash, (char *) ptr->interface_name, (void *) ptr); } } + + if (new_module->module_interface->chat_interface) { + const switch_chat_interface_t *ptr; + + for (ptr = new_module->module_interface->chat_interface; ptr; ptr = ptr->next) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Chat interface '%s'\n", ptr->interface_name); + if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "chat"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name); + switch_event_fire(&event); + } + switch_core_hash_insert(loadable_modules.chat_hash, (char *) ptr->interface_name, (void *) ptr); + } + } return SWITCH_STATUS_SUCCESS; @@ -476,6 +491,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init() switch_core_hash_init(&loadable_modules.file_hash, loadable_modules.pool); switch_core_hash_init(&loadable_modules.speech_hash, loadable_modules.pool); switch_core_hash_init(&loadable_modules.directory_hash, loadable_modules.pool); + switch_core_hash_init(&loadable_modules.chat_hash, loadable_modules.pool); switch_core_hash_init(&loadable_modules.dialplan_hash, loadable_modules.pool); if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) { @@ -637,6 +653,11 @@ SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_direct return switch_core_hash_find(loadable_modules.directory_hash, name); } +SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(char *name) +{ + return switch_core_hash_find(loadable_modules.chat_hash, name); +} + SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array, int arraylen) {