]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
experimental multiple registrations
authorAnthony Minessale <anthony.minessale@gmail.com>
Thu, 18 Oct 2007 01:02:01 +0000 (01:02 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Thu, 18 Oct 2007 01:02:01 +0000 (01:02 +0000)
in sofia conf
<param name="multiple-registrations" value="true"/>

in dialplan

<action application="bridge" data="$sofia_contact(mysofia_profile_name/user@regtodomain.com)"/>
or
<action application="bridge" data="$sofia_contact(mysofia_profile_name_same_as_regto_domain.com/user)"/>
or
<action application="bridge" data="$sofia_contact(user@mysofia_profile_name_same_as_regto_domain.com)"/>

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5956 d0543943-73ff-0310-b7d9-9358b9ac24b2

conf/sofia.conf.xml
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_reg.c

index 2effd5a8d07770c8e323ed3b543ef303a00f5c35..362416a34ba6ac5f785be95b8e27ce6ddb0cb7c8 100644 (file)
@@ -54,6 +54,7 @@
        <param name="sip-ip" value="$${local_ip_v4}"/>
        <!--enable to use presense and mwi -->
        <param name="manage-presence" value="true"/>
+       <!--<param name="multiple-registrations" value="true"/>-->
        <!--set to 'greedy' if you want your codec list to take precedence -->
        <param name="inbound-codec-negotiation" value="generous"/>
        <!-- if you want to send any special bind params of your own -->
index 092b37451ea0bcdc9f08b015e4a6c7e9f83e326d..c11c31dbb4bf8ab6d914564d9a1dc4fb07090115 100644 (file)
@@ -1248,6 +1248,96 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
        return SWITCH_STATUS_SUCCESS;
 }
 
+static int contact_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+       struct cb_helper *cb = (struct cb_helper *) pArg;
+       char *contact;
+
+       if (!switch_strlen_zero(argv[0]) && (contact = sofia_glue_get_url_from_contact(argv[0], 1))) {
+               cb->stream->write_function(cb->stream, "sofia/%s/%s,", cb->profile->name, contact + 4);
+               free(contact);
+       }
+
+       return 0;
+}
+
+SWITCH_STANDARD_API(sofia_contact_function)
+{
+       char *data;
+       char *user = NULL;
+       char *domain = NULL;
+       char *profile_name = NULL;
+       char *p;
+
+       if (!cmd) {
+               stream->write_function(stream, "%s", "");
+               return SWITCH_STATUS_SUCCESS;
+       }
+
+       data = strdup(cmd);
+       assert(data);
+
+       if ((p = strchr(data, '/'))) {
+               profile_name = data;
+               *p++ = '\0';
+               user = p;
+       } else {
+               user = data;
+       }
+
+       if ((domain = strchr(user, '@'))) {
+               *domain++ = '\0';
+       }
+       
+       if (!profile_name && domain) {
+               profile_name = domain;
+       }
+
+       if (user && profile_name) {
+               char *sql;
+               sofia_profile_t *profile;
+               
+               if (!(profile = sofia_glue_find_profile(profile_name))) {
+                       profile_name = domain;
+                       domain = NULL;
+               }
+
+               if (!profile && profile_name) {
+                       profile = sofia_glue_find_profile(profile_name);
+               }
+
+               if (profile) {
+                       struct cb_helper cb;
+                       switch_stream_handle_t mystream = { 0 };
+                       if (!domain || !strchr(domain, '.')) {
+                               domain = profile->name;
+                       }
+
+                       SWITCH_STANDARD_STREAM(mystream);
+                       cb.profile = profile;
+                       cb.stream = &mystream;
+                       
+                       sql = switch_mprintf("select contact from sip_registrations where user='%q' and host='%q'", user, domain);
+                       assert(sql);
+                       sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, contact_callback, &cb);
+                       switch_safe_free(sql);
+                       if (mystream.data) {
+                               char *str = mystream.data;
+                               *(str + (strlen(str) - 1)) = '\0';
+                       }
+                       stream->write_function(stream, "%s", mystream.data);
+                       switch_safe_free(mystream.data);
+                       goto end;
+               }
+       }
+       
+       stream->write_function(stream, "%s", "");
+ end:
+
+       switch_safe_free(data);
+       return SWITCH_STATUS_SUCCESS;
+}
+
 SWITCH_STANDARD_API(sofia_function)
 {
        char *argv[1024] = { 0 };
@@ -1589,6 +1679,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
        management_interface->management_function = sofia_manage;
 
        SWITCH_ADD_API(api_interface, "sofia", "Sofia Controls", sofia_function, "<cmd> <args>");
+       SWITCH_ADD_API(api_interface, "sofia_contact", "Sofia Contacts", sofia_contact_function, "[profile/]<user>@<domain>");
        SWITCH_ADD_CHAT(chat_interface, SOFIA_CHAT_PROTO, sofia_presence_chat_send);
 
        /* indicate that the module should continue to be loaded */
index 06d9a2e2bbf74549ab06369af4c7352a4d2bfd0c..a8829930727fc5aefef42a7bcd0ba276621b3d8a 100644 (file)
@@ -112,7 +112,8 @@ typedef enum {
        PFLAG_REWRITE_TIMESTAMPS = (1 << 7),
        PFLAG_RUNNING = (1 << 8),
        PFLAG_RESPAWN = (1 << 9),
-       PFLAG_GREEDY = (1 << 10)
+       PFLAG_GREEDY = (1 << 10),
+       PFLAG_MULTIREG = (1 << 11)
 } PFLAGS;
 
 
index 6f06750f1a0f2e25adf76469720924d9c0a9a2c0..c46bd0cb825aa348fa16605ce0dd14e06c04ad58 100644 (file)
@@ -260,7 +260,8 @@ void event_handler(switch_event_t *event)
                long expires = (long) time(NULL) + atol(exp_str);
                char *profile_name = switch_event_get_header(event, "orig-profile-name");
                sofia_profile_t *profile = NULL;
-               char buf[512];
+               char *icontact = NULL, *p;
+
 
                if (!rpid) {
                        rpid = "unknown";
@@ -270,26 +271,33 @@ void event_handler(switch_event_t *event)
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
                        return;
                }
-
-
-               if (!sofia_reg_find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
-                       sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Regestered', '%q', %ld)",
-                                                                from_user, from_host, contact_str, rpid, expires);
+               if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
+                       icontact = sofia_glue_get_url_from_contact(contact_str, 1);
+                       
+                       if ((p = strchr(icontact, ';'))) {
+                               *p = '\0';
+                       }
+                       sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q' and contact like '%%%q%%'", from_user, from_host, icontact);
+                       switch_safe_free(icontact);
                } else {
-                       sql =
-                               switch_mprintf
-                               ("update sip_registrations set contact='%q', rpid='%q', expires=%ld where user='%q' and host='%q'",
-                                contact_str, rpid, expires, from_user, from_host);
-
+                       sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q'", from_user, from_host);
                }
 
+               switch_mutex_lock(profile->ireg_mutex);
+               sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
+               switch_safe_free(sql);
+               
+               sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Regestered', '%q', %ld)",
+                                                        from_user, from_host, contact_str, rpid, expires);
+
                if (sql) {
-                       sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+                       sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
                        switch_safe_free(sql);
                        sql = NULL;
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s\n", from_user, from_host, contact_str);
-
                }
+               switch_mutex_unlock(profile->ireg_mutex);
+               
 
                if (profile) {
                        sofia_glue_release_profile(profile);
@@ -844,6 +852,10 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                                if (switch_true(val)) {
                                                        profile->pflags |= PFLAG_PRESENCE;
                                                }
+                                       } else if (!strcasecmp(var, "multiple-registrations")) {
+                                               if (switch_true(val)) {
+                                                       profile->pflags |= PFLAG_MULTIREG;
+                                               }
                                        } else if (!strcasecmp(var, "NDLB-to-in-200-contact")) {
                                                if (switch_true(val)) {
                                                        profile->ndlb |= PFLAG_NDLB_TO_IN_200_CONTACT;
index 734a1603306421194c6d8030fb41223723a5fcc6..3071a0ee1bec6e8330ee7f612890dd00c377880a 100644 (file)
@@ -329,7 +329,7 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
        const char *to_user = NULL;
        const char *to_host = NULL;
        char contact_str[1024] = "";
-       char buf[512];
+       //char buf[512];
        uint8_t stale = 0, forbidden = 0;
        auth_res_t auth_res;
        long exptime = 60;
@@ -461,16 +461,32 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
        }
        
        if (exptime) {
-               if (!sofia_reg_find_reg_url(profile, to_user, to_host, buf, sizeof(buf))) {
-                       sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','%q', '%q', %ld)",
-                                                                to_user, to_host, contact_str, cd ? "Registered(NATHACK)" : "Registered", rpid, (long) time(NULL) + (long) exptime * 2);
+       
+               if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
+                       char *icontact, *p;
+                       icontact = sofia_glue_get_url_from_contact(contact_str, 1);
+                       if ((p = strchr(icontact, ';'))) {
+                               *p = '\0';
+                       }
+                       
+                       sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q' and contact like '%%%q%%'", to_user, to_host, icontact);
+                       switch_safe_free(icontact);
                } else {
-                       sql =
-                               switch_mprintf
-                               ("update sip_registrations set contact='%q', expires=%ld, rpid='%q' where user='%q' and host='%q'",
-                                contact_str, (long) time(NULL) + (long) exptime * 2, rpid, to_user, to_host);
+                       sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q'", to_user, to_host);
+               }
+               switch_mutex_lock(profile->ireg_mutex);
+               sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
+               switch_safe_free(sql);
+               sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','%q', '%q', %ld)",
+                                                        to_user, to_host, contact_str, cd ? "Registered(NATHACK)" : "Registered", rpid, (long) time(NULL) + (long) exptime * 2);
 
+               
+               if (sql) {
+                       sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
+                       switch_safe_free(sql);
+                       sql = NULL;
                }
+               switch_mutex_unlock(profile->ireg_mutex);
 
                if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {
                        switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
@@ -482,11 +498,7 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
                        switch_event_fire(&s_event);
                }
 
-               if (sql) {
-                       sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
-                       switch_safe_free(sql);
-                       sql = NULL;
-               }
+               
 
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
                                                  "Register:\nFrom:    [%s@%s]\nContact: [%s]\nExpires: [%ld]\n", to_user, to_host, contact_str, (long) exptime);
@@ -503,15 +515,36 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
                        switch_event_fire(&event);
                }
        } else {
-               if ((sql = switch_mprintf("delete from sip_subscriptions where user='%q' and host='%q'", to_user, to_host))) {
-                       sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
-                       switch_safe_free(sql);
-                       sql = NULL;
-               }
-               if ((sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q'", to_user, to_host))) {
-                       sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
-                       switch_safe_free(sql);
-                       sql = NULL;
+               if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
+                       char *icontact, *p;
+                       icontact = sofia_glue_get_url_from_contact(contact_str, 1);
+                       if ((p = strchr(icontact, ';'))) {
+                               *p = '\0';
+                       }
+                       if ((sql = switch_mprintf("delete from sip_subscriptions where user='%q' and host='%q' and contact like '%%%q%%'", to_user, to_host, icontact))) {
+                               sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+                               switch_safe_free(sql);
+                               sql = NULL;
+                       }
+                       
+                       if ((sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q' and contact like '%%%q%%'", to_user, to_host, icontact))) {
+                               sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+                               switch_safe_free(sql);
+                               sql = NULL;
+                       }
+                       switch_safe_free(icontact);
+               } else {
+                       if ((sql = switch_mprintf("delete from sip_subscriptions where user='%q' and host='%q'", to_user, to_host))) {
+                               sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+                               switch_safe_free(sql);
+                               sql = NULL;
+                       }
+                       
+                       if ((sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q'", to_user, to_host))) {
+                               sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+                               switch_safe_free(sql);
+                               sql = NULL;
+                       }
                }
                if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");