diff --git a/src/include/switch_core.h b/src/include/switch_core.h index f37280f3e7..007f6a85ad 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2153,7 +2153,7 @@ SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t SWITCH_DECLARE(void) switch_cond_yield(switch_interval_time_t t); SWITCH_DECLARE(void) switch_cond_next(void); SWITCH_DECLARE(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); + const char *subject, const char *body, const char *type, const char *hint, switch_bool_t blocking); SWITCH_DECLARE(switch_status_t) switch_core_chat_send(const char *dest_proto, switch_event_t *message_event); SWITCH_DECLARE(switch_status_t) switch_core_chat_deliver(const char *dest_proto, switch_event_t **message_event); diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index e527b22b31..779feb393d 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -7764,7 +7764,7 @@ static switch_status_t chat_send(switch_event_t *message_event) } if (!(conference = conference_find(name, NULL))) { - switch_core_chat_send_args(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "", "Conference not active.", NULL, NULL); + switch_core_chat_send_args(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "", "Conference not active.", NULL, NULL, SWITCH_FALSE); return SWITCH_STATUS_FALSE; } @@ -7782,7 +7782,7 @@ static switch_status_t chat_send(switch_event_t *message_event) switch_safe_free(lbuf); - switch_core_chat_send_args(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "", stream.data, NULL, NULL); + switch_core_chat_send_args(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "", stream.data, NULL, NULL, SWITCH_FALSE); switch_safe_free(stream.data); switch_thread_rwlock_unlock(conference->rwlock); diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 02f988f6cf..7abd30a6bb 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1720,7 +1720,7 @@ SWITCH_STANDARD_API(chat_api_function) if (!zstr(cmd) && (lbuf = strdup(cmd)) && (argc = switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0])))) >= 4) { - if (switch_core_chat_send_args(argv[0], "global", argv[1], argv[2], "", argv[3], !zstr(argv[4]) ? argv[4] : NULL, "") == SWITCH_STATUS_SUCCESS) { + if (switch_core_chat_send_args(argv[0], "global", argv[1], argv[2], "", argv[3], !zstr(argv[4]) ? argv[4] : NULL, "", SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { stream->write_function(stream, "Sent"); } else { stream->write_function(stream, "Error! Message Not Sent"); @@ -4105,7 +4105,7 @@ static switch_status_t api_chat_send(switch_event_t *message_event) switch_api_execute(cmd, arg, NULL, &stream); if (proto) { - switch_core_chat_send_args(proto, "api", to, hint && strchr(hint, '/') ? hint : from, !zstr(type) ? type : NULL, (char *) stream.data, NULL, NULL); + switch_core_chat_send_args(proto, "api", to, hint && strchr(hint, '/') ? hint : from, !zstr(type) ? type : NULL, (char *) stream.data, NULL, NULL, SWITCH_TRUE); } switch_safe_free(stream.data); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index d7758e7371..11a5c8d0fc 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -745,6 +745,24 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status, void sofia_handle_sip_r_message(int status, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip) { + const char *call_id; + int *mstatus; + + if (!sip && sip->sip_call_id) { + return; + } + + call_id = sip->sip_call_id->i_id; + + + switch_mutex_lock(profile->flag_mutex); + mstatus = switch_core_hash_find(profile->chat_hash, call_id); + switch_mutex_unlock(profile->flag_mutex); + + if (mstatus) { + *mstatus = status; + } + } void sofia_wait_for_reply(struct private_object *tech_pvt, nua_event_t event, uint32_t timeout) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 8a6b1297bc..594cb4c61e 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -128,6 +128,9 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) char *route_uri = NULL; const char *network_ip = NULL, *network_port = NULL, *from_proto; char *extra_headers = NULL; + char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; + int mstatus = 0, sanity = 0; + proto = switch_event_get_header(message_event, "proto"); from_proto = switch_event_get_header(message_event, "from_proto"); @@ -324,6 +327,12 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) switch_snprintf(header, sizeof(header), "X-FS-Sending-Message: %s", switch_core_get_uuid()); + switch_uuid_str(uuid_str, sizeof(uuid_str)); + + switch_mutex_lock(profile->flag_mutex); + switch_core_hash_insert(profile->chat_hash, uuid_str, &mstatus); + switch_mutex_unlock(profile->flag_mutex); + nua_message(msg_nh, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(route_uri, NUTAG_PROXY(route_uri)), @@ -331,7 +340,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) SIPTAG_FROM_STR(from), TAG_IF(contact, NUTAG_URL(contact)), SIPTAG_TO_STR(dup_dest), - + SIPTAG_CALL_ID_STR(uuid_str), TAG_IF(user_via, SIPTAG_VIA_STR(user_via)), SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body), @@ -339,6 +348,20 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END()); + + sanity = 200; + while(!mstatus && --sanity) { + switch_yield(100000); + } + + if (!(mstatus > 199 && mstatus < 300)) { + status = SWITCH_STATUS_FALSE; + } + + switch_mutex_lock(profile->flag_mutex); + switch_core_hash_delete(profile->chat_hash, uuid_str); + switch_mutex_unlock(profile->flag_mutex); + sofia_glue_free_destination(dst); switch_safe_free(dup_dest); switch_safe_free(remote_host); diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 537e1a2550..045733dfa5 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -580,7 +580,6 @@ static switch_status_t do_chat_send(switch_event_t *message_event) if (!do_skip && !switch_stristr("GLOBAL", dest_proto)) { if ((ci = switch_loadable_module_get_chat_interface(dest_proto)) && ci->chat_send) { status = ci->chat_send(message_event); - UNPROTECT_INTERFACE(ci); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid chat interface [%s]!\n", dest_proto); @@ -599,17 +598,20 @@ static switch_status_t do_chat_send(switch_event_t *message_event) return status; } -static void chat_process_event(switch_event_t **eventp) +static switch_status_t chat_process_event(switch_event_t **eventp) { switch_event_t *event; + switch_status_t status; switch_assert(eventp); event = *eventp; *eventp = NULL; - do_chat_send(event); + status = do_chat_send(event); switch_event_destroy(&event); + + return status; } @@ -743,7 +745,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_execute_chat_app(switch_event_t *mes SWITCH_DECLARE(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) + const char *subject, const char *body, const char *type, const char *hint, switch_bool_t blocking) { switch_event_t *message_event; switch_status_t status; @@ -768,8 +770,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_chat_send_args(const char *dest_prot switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "dest_proto", dest_proto); } - chat_queue_message(&message_event); - status = SWITCH_STATUS_SUCCESS; + + if (blocking) { + status = chat_process_event(&message_event); + } else { + chat_queue_message(&message_event); + status = SWITCH_STATUS_SUCCESS; + } return status;