]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
BOUNTY-20
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 18 Aug 2010 19:58:14 +0000 (14:58 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Wed, 18 Aug 2010 20:01:32 +0000 (15:01 -0500)
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_sofia/sofia_presence.c
src/mod/endpoints/mod_sofia/sofia_reg.c
src/switch_ivr_bridge.c

index 2791692cab28e58bc5fa0b5712de25d2346ca7dd..6e07a1c963ab69f8ff735975e8626277abfb019e 100644 (file)
@@ -3783,7 +3783,12 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
                }
 
                if (!strncasecmp(dest, "sip:", 4) || !strncasecmp(dest, "sips:", 5)) {
+                       char *c;
                        tech_pvt->dest = switch_core_session_strdup(nsession, dest);
+                       if ((c = strchr(tech_pvt->dest, ':'))) {
+                               c++;
+                               tech_pvt->e_dest = switch_core_session_strdup(nsession, c);
+                       }
                } else if ((host = strchr(dest, '%'))) {
                        char buf[1024];
                        *host = '@';
@@ -3812,6 +3817,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
                } else {
                        host++;
                        tech_pvt->dest = switch_core_session_alloc(nsession, strlen(dest) + 5);
+                       tech_pvt->e_dest = switch_core_session_strdup(nsession, dest);
                        switch_snprintf(tech_pvt->dest, strlen(dest) + 5, "sip:%s", dest);
                }
        }
@@ -4173,40 +4179,45 @@ static void general_event_handler(switch_event_t *event)
                        const char *body = switch_event_get_body(event);
                        sofia_profile_t *profile;
                        nua_handle_t *nh;
-
+                       
                        if (profile_name && ct && user && host) {
                                char *id = NULL;
                                char *contact, *p;
-                               char buf[512] = "";
-
+                               switch_console_callback_match_t *list = NULL;
+                               switch_console_callback_match_node_t *m;
+                               
                                if (!(profile = sofia_glue_find_profile(profile_name))) {
                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find profile %s\n", profile_name);
                                        return;
                                }
-
-
-                               if (!sofia_reg_find_reg_url(profile, user, host, buf, sizeof(buf))) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find user %s@%s\n", user, host);
+                               
+                               if (!(list = sofia_reg_find_reg_url_multi(profile, user, host))) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find registered user %s@%s\n", user, host);
                                        return;
                                }
 
                                id = switch_mprintf("sip:%s@%s", user, host);
 
                                switch_assert(id);
-                               contact = sofia_glue_get_url_from_contact(buf, 0);
 
-                               if ((p = strstr(contact, ";fs_"))) {
-                                       *p = '\0';
-                               }
+                               for (m = list->head; m; m = m->next) {
+                                       contact = sofia_glue_get_url_from_contact(m->val, 0);
 
-                               nh = nua_handle(profile->nua,
-                                                               NULL, NUTAG_URL(contact), SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id), SIPTAG_CONTACT_STR(profile->url), TAG_END());
+                                       if ((p = strstr(contact, ";fs_"))) {
+                                               *p = '\0';
+                                       }
+
+                                       nh = nua_handle(profile->nua,
+                                                                       NULL, NUTAG_URL(contact), SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id), SIPTAG_CONTACT_STR(profile->url), TAG_END());
 
-                               nua_message(nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR(ct),
-                                                       TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_IF(!zstr(subject), SIPTAG_SUBJECT_STR(subject)), TAG_END());
+                                       nua_message(nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR(ct),
+                                                               TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_IF(!zstr(subject), SIPTAG_SUBJECT_STR(subject)), TAG_END());
 
 
-                               free(id);
+                                       free(id);
+                               }
+                               switch_console_free_matches(&list);
+
                                sofia_glue_release_profile(profile);
                        }
 
index 98ea11935909fccaf4379a6ea73de523e0536c40..78db36e8d5ccb227533ddb3ed132c6d247d18948 100644 (file)
@@ -216,6 +216,7 @@ typedef enum {
        PFLAG_EXTENDED_INFO_PARSING,
        PFLAG_T38_PASSTHRU,
        PFLAG_CID_IN_1XX,
+       PFLAG_IN_DIALOG_CHAT,
        /* No new flags below this line */
        PFLAG_MAX
 } PFLAGS;
@@ -698,6 +699,7 @@ struct private_object {
 struct callback_t {
        char *val;
        switch_size_t len;
+       switch_console_callback_match_t *list;
        int matches;
 };
 
@@ -1003,3 +1005,4 @@ void sofia_glue_copy_t38_options(switch_t38_options_t *t38_options, switch_core_
 switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *session, const char *r_sdp);
 char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type);
 void sofia_glue_tech_simplify(private_object_t *tech_pvt);
+switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host);
index b9ff9e35a89b3808fec50c7e23a9a13a9011a952..0a0c641365a222128802f6103f005d47ba183940 100644 (file)
@@ -2211,6 +2211,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
                                                } else {
                                                        sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID);
                                                }
+                                       } else if (!strcasecmp(var, "in-dialog-chat")) {
+                                               if (switch_true(val)) {
+                                                       sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT);
+                                               } else {
+                                                       sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT);
+                                               }
                                        } else if (!strcasecmp(var, "disable-hold")) {
                                                if (switch_true(val)) {
                                                        sofia_set_pflag(profile, PFLAG_DISABLE_HOLD);
@@ -2865,6 +2871,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                                } else {
                                                        sofia_clear_pflag(profile, PFLAG_LOG_AUTH_FAIL);
                                                }
+                                       } else if (!strcasecmp(var, "in-dialog-chat")) {
+                                               if (switch_true(val)) {
+                                                       sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT);
+                                               } else {
+                                                       sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT);
+                                               }
                                        } else if (!strcasecmp(var, "t38-passthru")) {
                                                if (switch_true(val)) {
                                                        sofia_set_pflag(profile, PFLAG_T38_PASSTHRU);
@@ -6748,7 +6760,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
        sofia_private->is_call++;
        tech_pvt->sofia_private = sofia_private;
 
-       if ((profile->pres_type)) {
+       if (profile->pres_type && sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)) {
                sofia_presence_set_chat_hash(tech_pvt, sip);
        }
        switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
index d78e690797118ebf2119da8d4d6a4f75f31c07a6..580b5e70b69ab155b58ce158efd973f25594ebea 100644 (file)
@@ -1968,7 +1968,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                nua_handle_bind(tech_pvt->nh, tech_pvt->sofia_private);
        }
 
-       if (tech_pvt->e_dest) {
+       if (tech_pvt->e_dest && sofia_test_pflag(tech_pvt->profile, PFLAG_IN_DIALOG_CHAT)) {
                char *user = NULL, *host = NULL;
                char hash_key[256] = "";
 
index 845fb6058358d78863668373adabcc6939cb6656..c6c0ccaa2377d38fcc64c61708c3c5bb804fc7f0 100644 (file)
@@ -73,7 +73,6 @@ struct presence_helper {
 switch_status_t sofia_presence_chat_send(const char *proto, const char *from, const char *to, const char *subject,
                                                                                 const char *body, const char *type, const char *hint)
 {
-       char buf[256];
        char *prof = NULL, *user = NULL, *host = NULL;
        sofia_profile_t *profile = NULL;
        char *ffrom = NULL;
@@ -84,6 +83,8 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
        const char *ct = "text/html";
        sofia_destination_t *dst = NULL;
        char *to_uri = NULL;
+       switch_console_callback_match_t *list = NULL;
+       switch_console_callback_match_node_t *m;
 
        if (!to) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n");
@@ -133,17 +134,19 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
                        host = prof;
                }
        }
-       
-       if (!to_uri && !sofia_reg_find_reg_url(profile, user, host, buf, sizeof(buf))) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find user. [%s][%s]\n", user, host);
+
+       if (to_uri) {
+               switch_console_push_match(&list, to_uri);
+       }  else if (!(list = sofia_reg_find_reg_url_multi(profile, user, host))) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find registered user %s@%s\n", user, host);
                goto end;
        }
-
+       
        if (!strcasecmp(proto, SOFIA_CHAT_PROTO)) {
                from = hint;
        } else {
                char *fp, *p = NULL;
-
+               
                fp = strdup(from);
 
                if (!fp) {
@@ -168,23 +171,28 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
                switch_safe_free(fp);
        }
 
-       if (!(dst = sofia_glue_get_destination(to_uri ? to_uri : buf))) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
-               goto end;
-       }
-
-       /* sofia_glue is running sofia_overcome_sip_uri_weakness we do not, not sure if it matters */
-
-       status = SWITCH_STATUS_SUCCESS;
-       /* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */
-       msg_nh = nua_handle(profile->nua, NULL, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
-                                               SIPTAG_FROM_STR(from), TAG_IF(contact, NUTAG_URL(contact)), SIPTAG_TO_STR(dst->to), SIPTAG_CONTACT_STR(profile->url), TAG_END());
-       nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private);
-       nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body), TAG_END());
+       for (m = list->head; m; m = m->next) {
 
+               if (!(dst = sofia_glue_get_destination(m->val))) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+                       break;
+               }
+       
+               /* sofia_glue is running sofia_overcome_sip_uri_weakness we do not, not sure if it matters */
+
+               status = SWITCH_STATUS_SUCCESS;
+               /* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */
+               msg_nh = nua_handle(profile->nua, NULL, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
+                                                       SIPTAG_FROM_STR(from), TAG_IF(contact, NUTAG_URL(contact)), SIPTAG_TO_STR(dst->to), SIPTAG_CONTACT_STR(profile->url), TAG_END());
+               nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private);
+               nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body), TAG_END());
+               sofia_glue_free_destination(dst);
+       }               
+       
+       switch_console_free_matches(&list);
 
   end:
-       sofia_glue_free_destination(dst);
+       
        switch_safe_free(contact);
        switch_safe_free(ffrom);
        switch_safe_free(dup);
@@ -2597,8 +2605,11 @@ void sofia_presence_handle_sip_i_message(int status,
 
                        from_addr = switch_mprintf("%s@%s", from_user, from_host);
 
-                       sofia_presence_set_hash_key(hash_key, sizeof(hash_key), sip);
-                       if ((tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) {
+                       if (sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)) {
+                               sofia_presence_set_hash_key(hash_key, sizeof(hash_key), sip);
+                       }
+
+                       if (sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT) && (tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) {
                                channel = switch_core_session_get_channel(tech_pvt->session);
                                if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
index be6041ff4f1368fdb5dcea1620b715d403cf1b1d..33f26e98dcc73f45819344753717bcaac18d4e2f 100644 (file)
@@ -417,9 +417,15 @@ int sofia_reg_find_callback(void *pArg, int argc, char **argv, char **columnName
 {
        struct callback_t *cbt = (struct callback_t *) pArg;
 
+       if (!cbt->len) {
+               switch_console_push_match(&cbt->list, argv[0]);
+               cbt->matches++;
+               return 0;
+       }
+
        switch_copy_string(cbt->val, argv[0], cbt->len);
        cbt->matches++;
-       return 0;
+       return cbt->matches == 1 ? 0 : 1;
 }
 
 int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames)
@@ -709,6 +715,30 @@ char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const c
 }
 
 
+switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host)
+{
+       struct callback_t cbt = { 0 };
+       char sql[512] = "";
+
+       if (!user) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Called with null user!\n");
+               return NULL;
+       }
+
+       if (host) {
+               switch_snprintf(sql, sizeof(sql), "select contact from sip_registrations where sip_user='%s' and (sip_host='%s' or presence_hosts like '%%%s%%')",
+                                               user, host, host);
+       } else {
+               switch_snprintf(sql, sizeof(sql), "select contact from sip_registrations where sip_user='%s'", user);
+       }
+
+
+       sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_find_callback, &cbt);
+
+       return cbt.list;
+}
+
+
 void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_regtype_t regtype, const char *realm, int stale)
 {
        switch_uuid_t uuid;
index b32a61f1a287ac950bc95153f544611028acca2a..b9a2feafbb1d4a69b7048e38b36545271a9cb641 100644 (file)
@@ -379,7 +379,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
                                status = input_callback(session_a, event, SWITCH_INPUT_TYPE_EVENT, user_data, 0);
                        }
 
-                       if (event->event_id != SWITCH_EVENT_COMMAND || switch_core_session_receive_event(session_b, &event) != SWITCH_STATUS_SUCCESS) {
+                       if ((event->event_id != SWITCH_EVENT_COMMAND && event->event_id != SWITCH_EVENT_MESSAGE)
+                               || switch_core_session_receive_event(session_b, &event) != SWITCH_STATUS_SUCCESS) {
                                switch_event_destroy(&event);
                        }