]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
blinking lights for xmas presence
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 18 Dec 2007 01:12:50 +0000 (01:12 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 18 Dec 2007 01:12:50 +0000 (01:12 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6849 d0543943-73ff-0310-b7d9-9358b9ac24b2

conf/autoload_configs/conference.conf.xml
conf/dialplan/default.xml
src/mod/applications/mod_conference/mod_conference.c
src/mod/applications/mod_limit/mod_limit.c
src/mod/applications/mod_voicemail/mod_voicemail.c
src/mod/endpoints/mod_dingaling/mod_dingaling.c
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_sofia/sofia_presence.c
src/switch_core_db.c

index e6a830f96919a990777212351d9189dc9dca20db..430b095b9a68a73dd6f35a23899a67752cd336b6 100644 (file)
@@ -3,7 +3,7 @@
 <configuration name="conference.conf" description="Audio Conference">
   <!-- Advertise certain presence on startup . -->
   <advertise>
-    <room name="888@$${server_name}" status="FreeSWITCH"/>
+    <room name="3001@$${domain}" status="FreeSWITCH"/>
   </advertise>
 
   <!-- These are the default keys that map when you do not specify a caller control group -->  
@@ -30,7 +30,7 @@
     <!--If no profile is specified it will default to "default"-->
     <profile name="default">
       <!-- Domain (for presence) -->
-      <param name="domain" value="$${server_name}"/>
+      <param name="domain" value="$${domain}"/>
       <!-- Sample Rate-->
       <param name="rate" value="8000"/>
       <!-- Number of milliseconds per frame -->
index c8ebf9588dbba8abb64dbb8c499941e45c38b232..e319b5d75805bc58901a759fb36b1cc33e8eceb4 100644 (file)
        <action application="answer"/>
        <action application="sleep" data="1000"/>
        <action application="voicemail" data="check default $${domain} ${dialed_ext}"/>
-       <anti-action application="set" data="call_timeout=30"/>
+       <anti-action application="set" data="call_timeout=130"/>
        <anti-action application="set" data="hangup_after_bridge=true"/>
        <anti-action application="set" data="continue_on_fail=true"/>
        <anti-action application="db" data="insert/call_return/${dialed_ext}/${caller_id_number}"/>
index 1b964a10f62cd470282b7332464840737b0c7665..fba600254947874054abfa3e42191bbe9a9144d9 100644 (file)
@@ -40,6 +40,7 @@ SWITCH_MODULE_DEFINITION(mod_conference, mod_conference_load, mod_conference_shu
 static const char global_app_name[] = "conference";
 static char *global_cf_name = "conference.conf";
 static char *api_syntax;
+static int EC = 0;
 
 /* Size to allocate for audio buffers */
 #define CONF_BUFFER_SIZE 1024 * 128
@@ -542,6 +543,11 @@ static switch_status_t conference_add_member(conference_obj_t * conference, conf
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", conference->name, conference->domain);
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Active (%d caller%s)", conference->count, conference->count == 1 ? "" : "s");
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "unique-id", "%s", conference->name);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-state", "%s", "CS_RING");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "answer-state", "%s", "confirmed");
                        switch_event_fire(&event);
                }
 
@@ -670,6 +676,11 @@ static switch_status_t conference_del_member(conference_obj_t * conference, conf
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", conference->name, conference->domain);
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Active (%d caller%s)", conference->count, conference->count == 1 ? "" : "s");
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "unique-id", "%s", conference->name);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-state", "%s", "CS_RING");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "answer-state", "%s", "confirmed");
                        switch_event_fire(&event);
                }
 
@@ -957,7 +968,11 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t * thread,
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Inactive");
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "idle");
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
-
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "unique-id", "%s", conference->name);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-state", "%s", "CS_HANGUP");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "answer-state", "%s", "terminated");
                switch_event_fire(&event);
        }
 
@@ -4866,6 +4881,11 @@ static void pres_event_handler(switch_event_t *event)
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", conference->name, conference->domain);
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Active (%d caller%s)", conference->count, conference->count == 1 ? "" : "s");
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "unique-id", "%s", conf_name);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-state", "%s", "CS_RING");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "answer-state", "%s", "confirmed");
                        switch_event_fire(&event);
                }
        } else if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
@@ -4875,6 +4895,11 @@ static void pres_event_handler(switch_event_t *event)
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Idle");
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "idle");
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "unique-id", "%s", conf_name);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-state", "%s", "CS_HANGUP");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "answer-state", "%s", "terminated");
                switch_event_fire(&event);
        }
 
index 2793a32a4e9f1fed3afe92a53f028aa64ddf100b..3e4ff9372cfb031c656b3078a7ae78d1470e98da 100644 (file)
@@ -105,7 +105,7 @@ static switch_status_t limit_execute_sql(char *sql, switch_mutex_t *mutex)
                        goto end;
                }
 
-               status = switch_core_db_persistant_execute(db, sql, 25);
+               status = switch_core_db_persistant_execute(db, sql, 1);
                switch_core_db_close(db);
 
 #ifdef SWITCH_HAVE_ODBC
index 325b6c48709fd0591300ff7f870590ce2c4a9be9..91be7136351b8d44099960490b114f1d62cdddba 100644 (file)
@@ -129,7 +129,7 @@ static switch_status_t vm_execute_sql(vm_profile_t *profile, char *sql, switch_m
             status = SWITCH_STATUS_FALSE;
                        goto end;
                }
-               status = switch_core_db_persistant_execute(db, sql, 25);
+               status = switch_core_db_persistant_execute(db, sql, 1);
                switch_core_db_close(db);
     }
 
index ade3a92f7c0afc14c80e43024d991667d2c88194..3bd376793fd9bd825da15a38ff504d79d937de78 100644 (file)
@@ -284,7 +284,7 @@ static void mdl_execute_sql(mdl_profile_t *profile, char *sql, switch_mutex_t *m
                        goto end;
                }
 
-               switch_core_db_persistant_execute(db, sql, 25);
+               switch_core_db_persistant_execute(db, sql, 1);
                switch_core_db_close(db);
 
 #ifdef SWITCH_HAVE_ODBC
index 3e356b9c1a8a703c4edfab936befc4af816f5cba..9808c243eb71905f94d238a4bf772d02f092c58c 100644 (file)
@@ -214,6 +214,15 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
                switch_core_hash_delete(tech_pvt->profile->chat_hash, tech_pvt->hash_key);
        }
 
+       if (session) {
+               const char *call_id = tech_pvt->call_id;
+               char *sql;
+               sql = switch_mprintf("delete from sip_dialogs where call_id='%q'", call_id);
+               switch_assert(sql);
+        sofia_glue_execute_sql(tech_pvt->profile, SWITCH_FALSE, sql, tech_pvt->profile->ireg_mutex);
+               free(sql);
+       }
+
        if (tech_pvt->kick && (a_session = switch_core_session_locate(tech_pvt->kick))) {
                switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
                switch_channel_hangup(a_channel, switch_channel_get_cause(channel));
@@ -1593,6 +1602,9 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
 
        if (tech_pvt->local_url) {
                switch_channel_set_variable(nchannel, "sip_local_url", tech_pvt->local_url);
+               if (sofia_test_pflag(profile, PFLAG_PRESENCE)) {
+                       switch_channel_set_variable(nchannel, "presence_id", tech_pvt->local_url);
+               }
        }
        switch_channel_set_variable(nchannel, "sip_destination_url", tech_pvt->dest);
        
@@ -1605,6 +1617,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
        tech_pvt->caller_profile = caller_profile;
        *new_session = nsession;
        cause = SWITCH_CAUSE_SUCCESS;
+
        if (session) {
                switch_ivr_transfer_variable(session, nsession, SOFIA_REPLACES_HEADER);
                switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_HEADER_PREFIX_T);
index 026276f43a02386fb2f1e9f1e18cd853471500ae..67045ee7c52cb8e5cfd677a41138be3d81240a9a 100644 (file)
@@ -54,6 +54,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                         char const *phrase,
                                                                         nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
 
+static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status,
+                                                                        char const *phrase,
+                                                                         nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]);
 void sofia_handle_sip_r_notify(switch_core_session_t *session, int status,
                                                           char const *phrase,
                                                           nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
@@ -210,6 +213,8 @@ void sofia_event_callback(nua_event_t event,
                break;
 
        case nua_r_invite:
+               sofia_handle_sip_r_invite(session, status, phrase, nua, profile, nh, sofia_private, sip, tags);
+               break;
        case nua_r_get_params:
        case nua_r_unregister:
        case nua_r_options:
@@ -261,882 +266,931 @@ void sofia_event_callback(nua_event_t event,
                sofia_handle_sip_i_info(nua, profile, nh, session, sip, tags);
                break;
        case nua_r_refer:
-               break;
-       case nua_i_refer:
-               if (session) {
-                       sofia_handle_sip_i_refer(nua, profile, nh, session, sip, tags);
-               }
-               break;
-       case nua_r_subscribe:
-               sofia_presence_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
-               break;
-       case nua_i_subscribe:
-               sofia_presence_handle_sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
-               break;
-       default:
-               if (status > 100) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: unknown event %d: %03d %s\n", nua_event_name(event), event, status, phrase);
-               } else {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: unknown event %d\n", nua_event_name(event), event);
-               }
-               break;
-       }
-
-  done:
-
-       if (gateway) {
-               sofia_reg_release_gateway(gateway);
-       }
-
-       if (session) {
-               switch_core_session_rwunlock(session);
-
-       }
-}
-
-
-void event_handler(switch_event_t *event)
-{
-       char *subclass, *sql;
-
-       if ((subclass = switch_event_get_header(event, "orig-event-subclass")) && !strcasecmp(subclass, MY_EVENT_REGISTER)) {
-               char *from_user = switch_event_get_header(event, "orig-from-user");
-               char *from_host = switch_event_get_header(event, "orig-from-host");
-               char *contact_str = switch_event_get_header(event, "orig-contact");
-               char *exp_str = switch_event_get_header(event, "orig-expires");
-               char *rpid = switch_event_get_header(event, "orig-rpid");
-               char *call_id = switch_event_get_header(event, "orig-call-id");
-               char *user_agent = switch_event_get_header(event, "user-agent");
-               long expires = (long) time(NULL) + atol(exp_str);
-               char *profile_name = switch_event_get_header(event, "orig-profile-name");
-               sofia_profile_t *profile = NULL;
-               
-               if (!rpid) {
-                       rpid = "unknown";
-               }
-
-               if (!profile_name || !(profile = sofia_glue_find_profile(profile_name))) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
-                       return;
-               }
-               if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
-                       sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
-               } else {
-                       sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_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','%q','Registered', '%q', %ld, '%q')",
-                                                        call_id, from_user, from_host, contact_str, rpid, expires, user_agent);
-
-               if (sql) {
-                       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);
-               }
-       }
-}
-
-
-
-void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj)
-{
-       sofia_profile_t *profile = (sofia_profile_t *) obj;
-       switch_memory_pool_t *pool;
-       sip_alias_node_t *node;
-       uint32_t ireg_loops = 0;
-       uint32_t gateway_loops = 0;
-       switch_event_t *s_event;
-       int tportlog = 0;
-       
-       switch_mutex_lock(mod_sofia_globals.mutex);
-       mod_sofia_globals.threads++;
-       switch_mutex_unlock(mod_sofia_globals.mutex);
-
-       profile->s_root = su_root_create(NULL);
-       profile->home = su_home_new(sizeof(*profile->home));
-
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating agent for %s\n", profile->name);
-
-       if (!sofia_glue_init_sql(profile)) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database [%s]!\n", profile->name);
-               sofia_glue_del_profile(profile);
-               goto end;
-       }
-
-       if (switch_test_flag(profile, TFLAG_TPORT_LOG)) {
-               tportlog = 1;
-       }
-
-       profile->nua = nua_create(profile->s_root,      /* Event loop */
-                                                         sofia_event_callback, /* Callback for processing events */
-                                                         profile,      /* Additional data to pass to callback */
-                                                         NUTAG_URL(profile->bindurl), NTATAG_UDP_MTU(65536), TAG_IF(tportlog,TPTAG_LOG(1)), TAG_END());        /* Last tag should always finish the sequence */
-
-       if (!profile->nua) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s\n", profile->name);
-               sofia_glue_del_profile(profile);
-               goto end;
-       }
-
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created agent for %s\n", profile->name);
-
-       nua_set_params(profile->nua,
-                                  NUTAG_APPL_METHOD("OPTIONS"),
-                                  NUTAG_APPL_METHOD("NOTIFY"),
-                                  NUTAG_APPL_METHOD("INFO"),
-                                  NUTAG_AUTOANSWER(0),
-                                  NUTAG_AUTOALERT(0),
-                                  NUTAG_ALLOW("REGISTER"),
-                                  NUTAG_ALLOW("REFER"),
-                                  NUTAG_ALLOW("INFO"),
-                                  NUTAG_ALLOW("NOTIFY"),
-                                  NUTAG_ALLOW_EVENTS("talk"),
-                                  NUTAG_SESSION_TIMER(profile->session_timeout),
-                                  NTATAG_MAX_PROCEEDING(profile->max_proceeding),
-                                  TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW("PUBLISH")),
-                                  TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW("SUBSCRIBE")),
-                                  TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ENABLEMESSAGE(1)),
-                                  TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW_EVENTS("presence")),
-                                  TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW_EVENTS("dialog")),
-                                  TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW_EVENTS("call-info")),
-                                  TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW_EVENTS("presence.winfo")),
-                                  TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW_EVENTS("message-summary")),
-                                  SIPTAG_SUPPORTED_STR("100rel, precondition, timer"), SIPTAG_USER_AGENT_STR(profile->user_agent), TAG_END());
-
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set params for %s\n", profile->name);
-
-       for (node = profile->aliases; node; node = node->next) {
-               node->nua = nua_create(profile->s_root, /* Event loop */
+                break;
+        case nua_i_refer:
+                if (session) {
+                        sofia_handle_sip_i_refer(nua, profile, nh, session, sip, tags);
+                }
+                break;
+        case nua_r_subscribe:
+                sofia_presence_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+                break;
+        case nua_i_subscribe:
+                sofia_presence_handle_sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+                break;
+        default:
+                if (status > 100) {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: unknown event %d: %03d %s\n", nua_event_name(event), event, status, phrase);
+                } else {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: unknown event %d\n", nua_event_name(event), event);
+                }
+                break;
+        }
+
+   done:
+
+        if (gateway) {
+                sofia_reg_release_gateway(gateway);
+        }
+
+        if (session) {
+                switch_core_session_rwunlock(session);
+
+        }
+ }
+
+
+ void event_handler(switch_event_t *event)
+ {
+        char *subclass, *sql;
+
+        if ((subclass = switch_event_get_header(event, "orig-event-subclass")) && !strcasecmp(subclass, MY_EVENT_REGISTER)) {
+                char *from_user = switch_event_get_header(event, "orig-from-user");
+                char *from_host = switch_event_get_header(event, "orig-from-host");
+                char *contact_str = switch_event_get_header(event, "orig-contact");
+                char *exp_str = switch_event_get_header(event, "orig-expires");
+                char *rpid = switch_event_get_header(event, "orig-rpid");
+                char *call_id = switch_event_get_header(event, "orig-call-id");
+                char *user_agent = switch_event_get_header(event, "user-agent");
+                long expires = (long) time(NULL) + atol(exp_str);
+                char *profile_name = switch_event_get_header(event, "orig-profile-name");
+                sofia_profile_t *profile = NULL;
+
+                if (!rpid) {
+                        rpid = "unknown";
+                }
+
+                if (!profile_name || !(profile = sofia_glue_find_profile(profile_name))) {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
+                        return;
+                }
+                if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
+                        sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
+                } else {
+                        sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_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','%q','Registered', '%q', %ld, '%q')",
+                                                         call_id, from_user, from_host, contact_str, rpid, expires, user_agent);
+
+                if (sql) {
+                        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);
+                }
+        }
+ }
+
+
+
+ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj)
+ {
+        sofia_profile_t *profile = (sofia_profile_t *) obj;
+        switch_memory_pool_t *pool;
+        sip_alias_node_t *node;
+        uint32_t ireg_loops = 0;
+        uint32_t gateway_loops = 0;
+        switch_event_t *s_event;
+        int tportlog = 0;
+
+        switch_mutex_lock(mod_sofia_globals.mutex);
+        mod_sofia_globals.threads++;
+        switch_mutex_unlock(mod_sofia_globals.mutex);
+
+        profile->s_root = su_root_create(NULL);
+        profile->home = su_home_new(sizeof(*profile->home));
+
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating agent for %s\n", profile->name);
+
+        if (!sofia_glue_init_sql(profile)) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database [%s]!\n", profile->name);
+                sofia_glue_del_profile(profile);
+                goto end;
+        }
+
+        if (switch_test_flag(profile, TFLAG_TPORT_LOG)) {
+                tportlog = 1;
+        }
+
+        profile->nua = nua_create(profile->s_root,     /* Event loop */
                                                           sofia_event_callback,        /* Callback for processing events */
                                                           profile,     /* Additional data to pass to callback */
-                                                          NUTAG_URL(node->url), TAG_END());    /* Last tag should always finish the sequence */
-
-               nua_set_params(node->nua,
-                                          NUTAG_APPL_METHOD("OPTIONS"),
-                                          NUTAG_EARLY_MEDIA(1),
-                                          NUTAG_AUTOANSWER(0),
-                                          NUTAG_AUTOALERT(0),
-                                          NUTAG_ALLOW("REGISTER"),
-                                          NUTAG_ALLOW("REFER"),
-                                          NUTAG_ALLOW("INFO"),
-                                          TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW("PUBLISH")),
-                                          TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ENABLEMESSAGE(1)),
-                                          SIPTAG_SUPPORTED_STR("100rel, precondition"), SIPTAG_USER_AGENT_STR(profile->user_agent), TAG_END());
-
-       }
-
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "activated db for %s\n", profile->name);
-
-       switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
-       switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED, profile->pool);
-
-       ireg_loops = IREG_SECONDS;
-       gateway_loops = GATEWAY_SECONDS;
-
-       if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH) == SWITCH_STATUS_SUCCESS) {
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp");
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "module_name", "%s", "mod_sofia");
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile_name", "%s", profile->name);
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile_uri", "%s", profile->url);
-               switch_event_fire(&s_event);
-       }
-
-       sofia_glue_add_profile(profile->name, profile);
-
-       if (profile->pflags & PFLAG_PRESENCE) {
-               sofia_presence_establish_presence(profile);
-       }
-
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting thread for %s\n", profile->name);
-
-       profile->started = time(NULL);
-       switch_yield(1000000);
-
-       sofia_set_pflag_locked(profile, PFLAG_RUNNING);
-       
-       while (mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING)) {
-               if (++ireg_loops >= IREG_SECONDS) {
-                       sofia_reg_check_expire(profile, time(NULL));
-                       ireg_loops = 0;
-               }
-
-               if (++gateway_loops >= GATEWAY_SECONDS) {
-                       sofia_reg_check_gateway(profile, time(NULL));
-                       gateway_loops = 0;
-               }
-
-               su_root_step(profile->s_root, 1000);
-       }
-
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock %s\n", profile->name);
-       switch_thread_rwlock_wrlock(profile->rwlock);
-       sofia_reg_unregister(profile);
-       nua_shutdown(profile->nua);
-
-       su_root_run(profile->s_root);
-       nua_destroy(profile->nua);
-
-       switch_mutex_lock(profile->ireg_mutex);
-       switch_mutex_unlock(profile->ireg_mutex);
-
-       if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH) == SWITCH_STATUS_SUCCESS) {
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp");
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "module_name", "%s", "mod_sofia");
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile_name", "%s", profile->name);
-               switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile_uri", "%s", profile->url);
-               switch_event_fire(&s_event);
-       }
-
-       sofia_glue_sql_close(profile);
-       su_home_unref(profile->home);
-       su_root_destroy(profile->s_root);
-       pool = profile->pool;
-
-       sofia_glue_del_profile(profile);
-       switch_core_hash_destroy(&profile->chat_hash);
-       switch_core_hash_destroy(&profile->sub_hash);
-
-       switch_thread_rwlock_unlock(profile->rwlock);
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write unlock %s\n", profile->name);
-
-       if (sofia_test_pflag(profile, PFLAG_RESPAWN)) {
-               config_sofia(1, profile->name);
-       }
-       
-       switch_core_destroy_memory_pool(&pool);
-
- end:
-       switch_mutex_lock(mod_sofia_globals.mutex);
-       mod_sofia_globals.threads--;
-       switch_mutex_unlock(mod_sofia_globals.mutex);
-
-       return NULL;
-}
-
-void launch_sofia_profile_thread(sofia_profile_t *profile)
-{
-       switch_thread_t *thread;
-       switch_threadattr_t *thd_attr = NULL;
-
-       switch_threadattr_create(&thd_attr, profile->pool);
-       switch_threadattr_detach_set(thd_attr, 1);
-       switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
-       switch_thread_create(&thread, thd_attr, sofia_profile_thread_run, profile, profile->pool);
-}
-
-static void logger(void *logarg, char const *fmt, va_list ap)
-{
-       char *data = NULL;
-
-       if (fmt) {
-#ifdef HAVE_VASPRINTF
-               int ret;
-               ret = vasprintf(&data, fmt, ap);
-               if ((ret == -1) || !data) {
-                       return;
-               }
-#else
-               data = (char *) malloc(2048);
-               if (data) {
-                       vsnprintf(data, 2048, fmt, ap);
-               } else {
-                       return;
-               }
-#endif
-       }
-       if (data) {
-               switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, (char *) "%s", data);
-               free(data);
-       }
-}
-
-
-static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
-{
-       switch_xml_t gateway_tag, param;
-       sofia_gateway_t *gp;
-
-       for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) {
-               char *name = (char *) switch_xml_attr_soft(gateway_tag, "name");
-               sofia_gateway_t *gateway;
-
-               if (switch_strlen_zero(name)) {
-                       name = "anonymous";
-               }
-
-               if ((gateway = switch_core_alloc(profile->pool, sizeof(*gateway)))) {
-                       char *register_str = "true", *scheme = "Digest",
-                               *realm = NULL,
-                               *username = NULL,
-                               *password = NULL,
-                               *caller_id_in_from = "false",
-                               *extension = NULL,
-                               *proxy = NULL,
-                               *context = "default",
-                               *expire_seconds = "3600",
-                               *retry_seconds = "30",
-                               *from_user = "",
-                               *from_domain = "",
-                               *register_proxy = NULL,
-                               *contact_params = NULL,
-                               *params = NULL,
-                               *register_transport = "udp";
-                       
-                       gateway->pool = profile->pool;
-                       gateway->profile = profile;
-                       gateway->name = switch_core_strdup(gateway->pool, name);
-                       gateway->freq = 0;
-                       gateway->next = NULL;
-
-                       for (param = switch_xml_child(gateway_tag, "param"); param; param = param->next) {
-                               char *var = (char *) switch_xml_attr_soft(param, "name");
-                               char *val = (char *) switch_xml_attr_soft(param, "value");
-
-                               if (!strcmp(var, "register")) {
-                                       register_str = val;
-                               } else if (!strcmp(var, "scheme")) {
-                                       scheme = val;
-                               } else if (!strcmp(var, "realm")) {
-                                       realm = val;
-                               } else if (!strcmp(var, "username")) {
-                                       username = val;
-                               } else if (!strcmp(var, "password")) {
-                                       password = val;
-                               } else if (!strcmp(var, "caller-id-in-from")) {
-                                       caller_id_in_from = val;
-                               } else if (!strcmp(var, "extension")) {
-                                       extension = val;
-                               } else if (!strcmp(var, "proxy")) {
-                                       proxy = val;
-                               } else if (!strcmp(var, "context")) {
-                                       context = val;
-                               } else if (!strcmp(var, "expire-seconds")) {
-                                       expire_seconds = val;
-                               } else if (!strcmp(var, "retry-seconds")) {
-                                       retry_seconds = val;
-                               } else if (!strcmp(var, "from-user")) {
-                                       from_user = val;
-                               } else if (!strcmp(var, "from-domain")) {
-                                       from_domain = val;
-                               } else if (!strcmp(var, "register-proxy")) {
-                                       register_proxy = val;
-                               } else if (!strcmp(var, "contact-params")) {
-                                       contact_params = val;
-                               } else if (!strcmp(var, "register-transport")) {
-                                       if (!strcasecmp(val, "udp") || !strcasecmp(val, "tcp")) {
-                                               register_transport = val;
-                                       } else {
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: unsupported transport\n");
-                                               goto skip;
-                                       }
-                               }
-                       }
-                       
-                       if (switch_strlen_zero(realm)) {
-                               realm = name;
-                       }
-
-                       if (switch_strlen_zero(username)) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: username param is REQUIRED!\n");
-                               goto skip;
-                       }
-
-                       if (switch_strlen_zero(password)) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: password param is REQUIRED!\n");
-                               goto skip;
-                       }
-
-                       if (switch_strlen_zero(from_user)) {
-                               from_user = username;
-                       }
-
-                       if (switch_strlen_zero(extension)) {
-                               extension = username;
-                       }
-                       
-                       if (switch_strlen_zero(proxy)) {
-                               proxy = realm;
-                       }
-
-                       if (!switch_true(register_str)) {
-                               gateway->state = REG_STATE_NOREG;
-                       }
-
-                       if (switch_strlen_zero(from_domain)) {
-                               from_domain = realm;
-                       }
-
-                       if (switch_strlen_zero(register_proxy)) {
-                               register_proxy = proxy;
-                       }
-
-                       gateway->retry_seconds = atoi(retry_seconds);
-                       if (gateway->retry_seconds < 10) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "INVALID: retry_seconds correcting the value to 30\n");
-                               gateway->retry_seconds = 30;
-                       }
-                       gateway->register_scheme = switch_core_strdup(gateway->pool, scheme);
-                       gateway->register_context = switch_core_strdup(gateway->pool, context);
-                       gateway->register_realm = switch_core_strdup(gateway->pool, realm);
-                       gateway->register_username = switch_core_strdup(gateway->pool, username);
-                       gateway->register_password = switch_core_strdup(gateway->pool, password);
-                       if (switch_true(caller_id_in_from)) {
-                               switch_set_flag(gateway, REG_FLAG_CALLERID);
-                       }
-                       if (contact_params) {
-                               if (*contact_params == ';') {
-                                       params = switch_core_sprintf(gateway->pool, "%s&transport=%s", contact_params, register_transport);
-                               } else {
-                                       params = switch_core_sprintf(gateway->pool, ";%s&transport=%s", contact_params, register_transport);
-                               }
-                       } else {
-                               params = switch_core_sprintf(gateway->pool, ";transport=%s", register_transport);
-                       }
-                       
-                       gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s;transport=%s", register_proxy,register_transport);
-                       gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s;transport=%s>", from_user, from_domain, register_transport);
-                       gateway->register_contact = switch_core_sprintf(gateway->pool, "<sip:%s@%s:%d%s>", extension,
-                                                                                                                       profile->extsipip ? profile->extsipip : profile->sipip, profile->sip_port, params);
-
-                       if (!strncasecmp(proxy, "sip:", 4)) {
-                gateway->register_proxy = switch_core_strdup(gateway->pool, proxy);
-                gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy + 4);
-            } else {
-                gateway->register_proxy = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
-                gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy);
-            }
-
-                       gateway->expires_str = switch_core_strdup(gateway->pool, expire_seconds);
-
-                       if ((gateway->freq = atoi(gateway->expires_str)) < 5) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
-                                                                 "Invalid Freq: %d.  Setting Register-Frequency to 3600\n", gateway->freq);
-                               gateway->freq = 3600;
-                       }
-                       gateway->freq -= 2;
-
-                       if ((gp = sofia_reg_find_gateway(gateway->name))) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", gateway->name);
-                               sofia_reg_release_gateway(gp);
-                       } else {
-                               gateway->next = profile->gateways;
-                               profile->gateways = gateway;
-                               sofia_reg_add_gateway(gateway->name, gateway);
-                       }
-               }
-
-       skip:
-               switch_assert(gateway_tag);
-       }
-
-}
-
-switch_status_t config_sofia(int reload, char *profile_name)
-{
-       char *cf = "sofia.conf";
-       switch_xml_t cfg, xml = NULL, xprofile, param, settings, profiles, gateways_tag, domain_tag, domains_tag;
-       switch_status_t status = SWITCH_STATUS_SUCCESS;
-       sofia_profile_t *profile = NULL;
-       char url[512] = "";
-       int profile_found = 0;
-
-       if (!reload) {
-               su_init();
-               if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) {
-                       su_deinit();
-                       return SWITCH_STATUS_FALSE;
-               }
-
-               su_log_redirect(NULL, logger, NULL);
-               su_log_redirect(tport_log, logger, NULL);
-       }
-
-       if (!switch_strlen_zero(profile_name) && (profile = sofia_glue_find_profile(profile_name))) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile [%s] Already exists.\n", switch_str_nil(profile_name));
-               status = SWITCH_STATUS_FALSE;
-               sofia_glue_release_profile(profile);
-               return status;
-       }
-
-       switch_snprintf(url, sizeof(url), "profile=%s", switch_str_nil(profile_name));
-
-       if (!(xml = switch_xml_open_cfg(cf, &cfg, url))) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
-               status = SWITCH_STATUS_FALSE;
-               goto done;
-       }
-
-       if ((settings = switch_xml_child(cfg, "global_settings"))) {
-               for (param = switch_xml_child(settings, "param"); param; param = param->next) {
-                       char *var = (char *) switch_xml_attr_soft(param, "name");
-                       char *val = (char *) switch_xml_attr_soft(param, "value");
-                       if (!strcasecmp(var, "log-level")) {
-                               su_log_set_level(NULL, atoi(val));
-                       }
-               }
-       }
-
-       if ((profiles = switch_xml_child(cfg, "profiles"))) {
-               for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
-                       if (!(settings = switch_xml_child(xprofile, "settings"))) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Settings, check the new config!\n");
-                       } else {
-                               char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name");
-                               switch_memory_pool_t *pool = NULL;
-
-                               if (!xprofilename) {
-                                       xprofilename = "unnamed";
-                               }
-                               
-                               if (profile_name) {
-                                       if (strcasecmp(profile_name, xprofilename)) {
-                                               continue;
-                                       } else {
-                                               profile_found = 1;
-                                       }
-                               }
-                               
-                               /* Setup the pool */
-                               if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
-                                       goto done;
-                               }
-
-                               if (!(profile = (sofia_profile_t *) switch_core_alloc(pool, sizeof(*profile)))) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
-                                       goto done;
-                               }
-
-                               profile->pool = pool;
-                               profile->user_agent = SOFIA_USER_AGENT;
-
-                               profile->name = switch_core_strdup(profile->pool, xprofilename);
-                               switch_snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename);
-                               
-                               profile->dbname = switch_core_strdup(profile->pool, url);
-                               switch_core_hash_init(&profile->chat_hash, profile->pool);
-                               switch_core_hash_init(&profile->sub_hash, profile->pool);
-                               switch_thread_rwlock_create(&profile->rwlock, profile->pool);
-                               switch_mutex_init(&profile->flag_mutex, SWITCH_MUTEX_NESTED, profile->pool);
-                               profile->dtmf_duration = 100;
-
-                               for (param = switch_xml_child(settings, "param"); param; param = param->next) {
-                                       char *var = (char *) switch_xml_attr_soft(param, "name");
-                                       char *val = (char *) switch_xml_attr_soft(param, "value");
-
-                                       if (!strcasecmp(var, "debug")) {
-                                               profile->debug = atoi(val);
-                                       } else if (!strcasecmp(var, "use-rtp-timer") && switch_true(val)) {
-                                               switch_set_flag(profile, TFLAG_TIMER);
-                                       } else if (!strcasecmp(var, "sip-trace") && switch_true(val)) {
-                                               switch_set_flag(profile, TFLAG_TPORT_LOG);
-                                       } else if (!strcasecmp(var, "odbc-dsn") && !switch_strlen_zero(val)) {
-#ifdef SWITCH_HAVE_ODBC
-                                               profile->odbc_dsn = switch_core_strdup(profile->pool, val);
-                                               if ((profile->odbc_user = strchr(profile->odbc_dsn, ':'))) {
-                                                       *profile->odbc_user++ = '\0';
-                                                       if ((profile->odbc_pass = strchr(profile->odbc_user, ':'))) {
-                                                               *profile->odbc_pass++ = '\0';
-                                                       }
-                                               }
-                               
-#else
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
-#endif
-                                               
-                                       } else if (!strcasecmp(var, "user-agent-string")) {
-                                               profile->user_agent = switch_core_strdup(profile->pool, val);;
-                                       } else if (!strcasecmp(var, "inbound-no-media") && switch_true(val)) {
-                                               switch_set_flag(profile, TFLAG_INB_NOMEDIA);
-                                       } else if (!strcasecmp(var, "inbound-late-negotiation") && switch_true(val)) {
-                                               switch_set_flag(profile, TFLAG_LATE_NEGOTIATION);
-                                       } else if (!strcasecmp(var, "rfc2833-pt")) {
-                                               profile->te = (switch_payload_t) atoi(val);
-                                       } else if (!strcasecmp(var, "cng-pt")) {
-                                               profile->cng_pt = (switch_payload_t) atoi(val);
-                                       } else if (!strcasecmp(var, "sip-port")) {
-                                               profile->sip_port = atoi(val);
-                                       } else if (!strcasecmp(var, "vad")) {
-                                               if (!strcasecmp(val, "in")) {
-                                                       switch_set_flag(profile, TFLAG_VAD_IN);
-                                               } else if (!strcasecmp(val, "out")) {
-                                                       switch_set_flag(profile, TFLAG_VAD_OUT);
-                                               } else if (!strcasecmp(val, "both")) {
-                                                       switch_set_flag(profile, TFLAG_VAD_IN);
-                                                       switch_set_flag(profile, TFLAG_VAD_OUT);
-                                               } else {
-                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invald option %s for VAD\n", val);
-                                               }
-                                       } else if (!strcasecmp(var, "ext-rtp-ip")) {
-                                               profile->extrtpip = switch_core_strdup(profile->pool, strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip);
-                                       } else if (!strcasecmp(var, "rtp-ip")) {
-                                               profile->rtpip = switch_core_strdup(profile->pool, strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip);
-                                       } else if (!strcasecmp(var, "sip-ip")) {
-                                               profile->sipip = switch_core_strdup(profile->pool, strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip);
-                                       } else if (!strcasecmp(var, "ext-sip-ip")) {
-                                               if (!strcasecmp(val, "auto")) {
-                                                       profile->extsipip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
-                                               } else {
-                                                       char *ip = mod_sofia_globals.guess_ip;
-                                                       switch_port_t port = 0;
-                                                       if (sofia_glue_ext_address_lookup(&ip, &port, val, profile->pool) == SWITCH_STATUS_SUCCESS) {
-
-                                                               if (ip) {
-                                                                       profile->extsipip = switch_core_strdup(profile->pool, ip);
-                                                               }
-                                                       }
-                                               }
-                                       } else if (!strcasecmp(var, "force-register-domain")) {
-                                               profile->reg_domain = switch_core_strdup(profile->pool, val);
-                                       } else if (!strcasecmp(var, "bind-params")) {
-                                               profile->bind_params = switch_core_strdup(profile->pool, val);
-                                       } else if (!strcasecmp(var, "sip-domain")) {
-                                               profile->sipdomain = switch_core_strdup(profile->pool, val);
-                                       } else if (!strcasecmp(var, "rtp-timer-name")) {
-                                               profile->timer_name = switch_core_strdup(profile->pool, val);
-                                       } else if (!strcasecmp(var, "hold-music")) {
-                                               profile->hold_music = switch_core_strdup(profile->pool, val);
-                                       } else if (!strcasecmp(var, "session-timeout")) {
-                                               int v_session_timeout = atoi(val);
-                                               if (v_session_timeout >= 0) {
-                                                       profile->session_timeout = v_session_timeout;
-                                               }
-                                       } else if (!strcasecmp(var, "max-proceeding")) {
-                                               int v_max_proceeding = atoi(val);
-                                               if (v_max_proceeding >= 0) {
-                                                       profile->max_proceeding = v_max_proceeding;
-                                               }
-                                       } else if (!strcasecmp(var, "rtp-timeout-sec")) {
-                                               int v = atoi(val);
-                                               if (v >= 0) {
-                                                       profile->rtp_timeout_sec = v;
-                                               }
-                                       } else if (!strcasecmp(var, "manage-presence")) {
-                                               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, "supress-cng")) {
-                                               if (switch_true(val)) {
-                                                       profile->pflags |= PFLAG_SUPRESS_CNG;
-                                               }
-                                       } else if (!strcasecmp(var, "NDLB-to-in-200-contact")) {
-                                               if (switch_true(val)) {
-                                                       profile->ndlb |= PFLAG_NDLB_TO_IN_200_CONTACT;
-                                               }
-                                       } else if (!strcasecmp(var, "NDLB-broken-auth-hash")) {
-                                               if (switch_true(val)) {
-                                                       profile->ndlb |= PFLAG_NDLB_BROKEN_AUTH_HASH;
-                                               }
-                                       } else if (!strcasecmp(var, "pass-rfc2833")) {
-                                               if (switch_true(val)) {
-                                                       profile->pflags |= PFLAG_PASS_RFC2833;
-                                               }
-                                       } else if (!strcasecmp(var, "inbound-codec-negotiation")) {
-                                               if (!strcasecmp(val, "greedy")) {
-                                                       profile->pflags |= PFLAG_GREEDY;
-                                               }
-                                       } else if (!strcasecmp(var, "disable-transcoding")) {
-                                               if (switch_true(val)) {
-                                                       profile->pflags |= PFLAG_DISABLE_TRANSCODING;
-                                               }
-                                       } else if (!strcasecmp(var, "rtp-rewrite-timestamps")) {
-                                               if (switch_true(val)) {
-                                                       profile->pflags |= PFLAG_REWRITE_TIMESTAMPS;
-                                               }
-                                       } else if (!strcasecmp(var, "auth-calls")) {
-                                               if (switch_true(val)) {
-                                                       profile->pflags |= PFLAG_AUTH_CALLS;
-                                               }
-                                       } else if (!strcasecmp(var, "nonce-ttl")) {
-                                               profile->nonce_ttl = atoi(val);
-                                       } else if (!strcasecmp(var, "accept-blind-reg")) {
-                                               if (switch_true(val)) {
-                                                       profile->pflags |= PFLAG_BLIND_REG;
-                                               }
-                                       } else if (!strcasecmp(var, "auth-all-packets")) {
-                                               if (switch_true(val)) {
-                                                       profile->pflags |= PFLAG_AUTH_ALL;
-                                               }
-                                       } else if (!strcasecmp(var, "full-id-in-dialplan")) {
-                                               if (switch_true(val)) {
-                                                       profile->pflags |= PFLAG_FULL_ID;
-                                               }
-                                       } else if (!strcasecmp(var, "bitpacking")) {
-                                               if (!strcasecmp(val, "aal2")) {
-                                                       profile->codec_flags = SWITCH_CODEC_FLAG_AAL2;
-                                               }
-                                       } else if (!strcasecmp(var, "username")) {
-                                               profile->username = switch_core_strdup(profile->pool, val);
-                                       } else if (!strcasecmp(var, "context")) {
-                                               profile->context = switch_core_strdup(profile->pool, val);
-                                       } else if (!strcasecmp(var, "alias")) {
-                                               sip_alias_node_t *node;
-                                               if ((node = switch_core_alloc(profile->pool, sizeof(*node)))) {
-                                                       if ((node->url = switch_core_strdup(profile->pool, val))) {
-                                                               node->next = profile->aliases;
-                                                               profile->aliases = node;
-                                                       }
-                                               }
-                                       } else if (!strcasecmp(var, "dialplan")) {
-                                               profile->dialplan = switch_core_strdup(profile->pool, val);
-                                       } else if (!strcasecmp(var, "max-calls")) {
-                                               profile->max_calls = atoi(val);
-                                       } else if (!strcasecmp(var, "codec-prefs")) {
-                                               profile->codec_string = switch_core_strdup(profile->pool, val);
-                                       } else if (!strcasecmp(var, "dtmf-duration")) {
-                                               int dur = atoi(val);
-                                               if (dur > 10 && dur < 8000) {
-                                                       profile->dtmf_duration = dur;
-                                               } else {
-                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Duration out of bounds!\n");
-                                               }
-                                       }
-                               }
-
-                               if (!profile->cng_pt) {
-                                       profile->cng_pt = SWITCH_RTP_CNG_PAYLOAD;
-                               }
-
-                               if (!profile->sipip) {
-                                       profile->sipip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
-                               }
-
-                               if (!profile->rtpip) {
-                                       profile->rtpip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
-                               }
-
-                               if (profile->nonce_ttl < 60) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting nonce TTL to 60 seconds\n");
-                                       profile->nonce_ttl = 60;
-                               }
-
-                               if (switch_test_flag(profile, TFLAG_TIMER) && !profile->timer_name) {
-                                       profile->timer_name = switch_core_strdup(profile->pool, "soft");
-                               }
-
-                               if (!profile->username) {
-                                       profile->username = switch_core_strdup(profile->pool, "FreeSWITCH");
-                               }
-
-                               if (!profile->rtpip) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Setting ip to '127.0.0.1'\n");
-                                       profile->rtpip = switch_core_strdup(profile->pool, "127.0.0.1");
-                               }
-
-                               if (!profile->sip_port) {
-                                       profile->sip_port = atoi(SOFIA_DEFAULT_PORT);
-                               }
-
-                               if (!profile->dialplan) {
-                                       profile->dialplan = switch_core_strdup(profile->pool, "XML");
-                               }
-
-                               if (!profile->sipdomain) {
-                                       profile->sipdomain = switch_core_strdup(profile->pool, profile->sipip);
-                               }
-                               if (profile->extsipip) {
-                                       profile->url = switch_core_sprintf(profile->pool, "sip:mod_sofia@%s:%d", profile->extsipip, profile->sip_port);
-                                       profile->bindurl = switch_core_sprintf(profile->pool, "%s;maddr=%s", profile->url, profile->sipip);
-                               } else {
-                                       profile->url = switch_core_sprintf(profile->pool, "sip:mod_sofia@%s:%d", profile->sipip, profile->sip_port);
-                                       profile->bindurl = profile->url;
-                               }
-
-                               if (profile->bind_params) {
-                                       char *bindurl = profile->bindurl;
-                                       profile->bindurl = switch_core_sprintf(profile->pool, "%s;%s", bindurl, profile->bind_params);
-                               }
-                               
-                       }
-                       if (profile) {
-                               switch_xml_t aliases_tag, alias_tag;
-
-                               if ((gateways_tag = switch_xml_child(xprofile, "registrations"))) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
-                                                                         "The <registrations> syntax has been discontinued, please see the new syntax in the default configuration examples\n");
-                               } else if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
-                                       parse_gateways(profile, gateways_tag);
-                               }
-
-                               if ((domains_tag = switch_xml_child(xprofile, "domains"))) {
-                                       for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) {
-                                               switch_xml_t droot, actual_domain_tag, ut;
-                                               char *dname = (char *) switch_xml_attr_soft(domain_tag, "name");
-                                               char *parse = (char *) switch_xml_attr_soft(domain_tag, "parse");
-
-                                               if (!switch_strlen_zero(dname)) { 
-                                                       if (switch_true(parse)) {
-                                                               if (switch_xml_locate_domain(dname, NULL, &droot, &actual_domain_tag) == SWITCH_STATUS_SUCCESS) {
-                                                                       for (ut = switch_xml_child(actual_domain_tag, "user"); ut; ut = ut->next) {
-                                                                               if (((gateways_tag = switch_xml_child(ut, "gateways")))) {
-                                                                                       parse_gateways(profile, gateways_tag);
-                                                                               }
-                                                                       }
-                                                                       switch_xml_free(droot);
-                                                               }
-                                                       }
-                                                       sofia_glue_add_profile(switch_core_strdup(profile->pool, dname), profile);
-                                               }
-                                       }
-                               }
-                               
-                               if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) {
-                                       for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) {
-                                               char *aname = (char *) switch_xml_attr_soft(alias_tag, "name");
-                                               if (!switch_strlen_zero(aname)) {
-
-                                                       if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname), profile) == SWITCH_STATUS_SUCCESS) {
-                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name);
-                                                       } else {
-                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Adding Alias [%s] for profile [%s] (name in use)\n", 
-                                                                                                 aname, profile->name);
-                                                       }
-                                               }
-                                       }
-                               }
-
-                               if (profile->sipip) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Started Profile %s [%s]\n", profile->name, url);
-                                       launch_sofia_profile_thread(profile);
-                               } else {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Unable to start Profile %s due to no configured sip-ip\n", profile->name);
-                               }
-                               profile = NULL;
-                       }
-                       if (profile_found) {
-                               break;
-                       }
+                                                          NUTAG_URL(profile->bindurl), NTATAG_UDP_MTU(65536), TAG_IF(tportlog,TPTAG_LOG(1)), TAG_END());       /* Last tag should always finish the sequence */
+
+        if (!profile->nua) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s\n", profile->name);
+                sofia_glue_del_profile(profile);
+                goto end;
+        }
+
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created agent for %s\n", profile->name);
+
+        nua_set_params(profile->nua,
+                                       NUTAG_APPL_METHOD("OPTIONS"),
+                                       NUTAG_APPL_METHOD("NOTIFY"),
+                                       NUTAG_APPL_METHOD("INFO"),
+                                       NUTAG_AUTOANSWER(0),
+                                       NUTAG_AUTOALERT(0),
+                                       NUTAG_ALLOW("REGISTER"),
+                                       NUTAG_ALLOW("REFER"),
+                                       NUTAG_ALLOW("INFO"),
+                                       NUTAG_ALLOW("NOTIFY"),
+                                       NUTAG_ALLOW_EVENTS("talk"),
+                                       NUTAG_SESSION_TIMER(profile->session_timeout),
+                                       NTATAG_MAX_PROCEEDING(profile->max_proceeding),
+                                       TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW("PUBLISH")),
+                                       TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW("SUBSCRIBE")),
+                                       TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ENABLEMESSAGE(1)),
+                                       TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW_EVENTS("presence")),
+                                       TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW_EVENTS("dialog")),
+                                       TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW_EVENTS("call-info")),
+                                       TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW_EVENTS("presence.winfo")),
+                                       TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW_EVENTS("message-summary")),
+                                       SIPTAG_SUPPORTED_STR("100rel, precondition, timer"), SIPTAG_USER_AGENT_STR(profile->user_agent), TAG_END());
+
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set params for %s\n", profile->name);
+
+        for (node = profile->aliases; node; node = node->next) {
+                node->nua = nua_create(profile->s_root,        /* Event loop */
+                                                               sofia_event_callback,   /* Callback for processing events */
+                                                               profile,        /* Additional data to pass to callback */
+                                                               NUTAG_URL(node->url), TAG_END());       /* Last tag should always finish the sequence */
+
+                nua_set_params(node->nua,
+                                               NUTAG_APPL_METHOD("OPTIONS"),
+                                               NUTAG_EARLY_MEDIA(1),
+                                               NUTAG_AUTOANSWER(0),
+                                               NUTAG_AUTOALERT(0),
+                                               NUTAG_ALLOW("REGISTER"),
+                                               NUTAG_ALLOW("REFER"),
+                                               NUTAG_ALLOW("INFO"),
+                                               TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW("PUBLISH")),
+                                               TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ENABLEMESSAGE(1)),
+                                               SIPTAG_SUPPORTED_STR("100rel, precondition"), SIPTAG_USER_AGENT_STR(profile->user_agent), TAG_END());
+
+        }
+
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "activated db for %s\n", profile->name);
+
+        switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
+        switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED, profile->pool);
+
+        ireg_loops = IREG_SECONDS;
+        gateway_loops = GATEWAY_SECONDS;
+
+        if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH) == SWITCH_STATUS_SUCCESS) {
+                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp");
+                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
+                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "module_name", "%s", "mod_sofia");
+                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile_name", "%s", profile->name);
+                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile_uri", "%s", profile->url);
+                switch_event_fire(&s_event);
+        }
+
+        sofia_glue_add_profile(profile->name, profile);
+
+        if (profile->pflags & PFLAG_PRESENCE) {
+                sofia_presence_establish_presence(profile);
+        }
+
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting thread for %s\n", profile->name);
+
+        profile->started = time(NULL);
+        switch_yield(1000000);
+
+        sofia_set_pflag_locked(profile, PFLAG_RUNNING);
+
+        while (mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING)) {
+                if (++ireg_loops >= IREG_SECONDS) {
+                        sofia_reg_check_expire(profile, time(NULL));
+                        ireg_loops = 0;
+                }
+
+                if (++gateway_loops >= GATEWAY_SECONDS) {
+                        sofia_reg_check_gateway(profile, time(NULL));
+                        gateway_loops = 0;
+                }
+
+                su_root_step(profile->s_root, 1000);
+        }
+
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock %s\n", profile->name);
+        switch_thread_rwlock_wrlock(profile->rwlock);
+        sofia_reg_unregister(profile);
+        nua_shutdown(profile->nua);
+
+        su_root_run(profile->s_root);
+        nua_destroy(profile->nua);
+
+        switch_mutex_lock(profile->ireg_mutex);
+        switch_mutex_unlock(profile->ireg_mutex);
+
+        if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH) == SWITCH_STATUS_SUCCESS) {
+                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp");
+                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
+                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "module_name", "%s", "mod_sofia");
+                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile_name", "%s", profile->name);
+                switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile_uri", "%s", profile->url);
+                switch_event_fire(&s_event);
+        }
+
+        sofia_glue_sql_close(profile);
+        su_home_unref(profile->home);
+        su_root_destroy(profile->s_root);
+        pool = profile->pool;
+
+        sofia_glue_del_profile(profile);
+        switch_core_hash_destroy(&profile->chat_hash);
+        switch_core_hash_destroy(&profile->sub_hash);
+
+        switch_thread_rwlock_unlock(profile->rwlock);
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write unlock %s\n", profile->name);
+
+        if (sofia_test_pflag(profile, PFLAG_RESPAWN)) {
+                config_sofia(1, profile->name);
+        }
+
+        switch_core_destroy_memory_pool(&pool);
+
+  end:
+        switch_mutex_lock(mod_sofia_globals.mutex);
+        mod_sofia_globals.threads--;
+        switch_mutex_unlock(mod_sofia_globals.mutex);
+
+        return NULL;
+ }
+
+ void launch_sofia_profile_thread(sofia_profile_t *profile)
+ {
+        switch_thread_t *thread;
+        switch_threadattr_t *thd_attr = NULL;
+
+        switch_threadattr_create(&thd_attr, profile->pool);
+        switch_threadattr_detach_set(thd_attr, 1);
+        switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+        switch_thread_create(&thread, thd_attr, sofia_profile_thread_run, profile, profile->pool);
+ }
+
+ static void logger(void *logarg, char const *fmt, va_list ap)
+ {
+        char *data = NULL;
+
+        if (fmt) {
+ #ifdef HAVE_VASPRINTF
+                int ret;
+                ret = vasprintf(&data, fmt, ap);
+                if ((ret == -1) || !data) {
+                        return;
+                }
+ #else
+                data = (char *) malloc(2048);
+                if (data) {
+                        vsnprintf(data, 2048, fmt, ap);
+                } else {
+                        return;
+                }
+ #endif
+        }
+        if (data) {
+                switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, (char *) "%s", data);
+                free(data);
+        }
+ }
+
+
+ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
+ {
+        switch_xml_t gateway_tag, param;
+        sofia_gateway_t *gp;
+
+        for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) {
+                char *name = (char *) switch_xml_attr_soft(gateway_tag, "name");
+                sofia_gateway_t *gateway;
+
+                if (switch_strlen_zero(name)) {
+                        name = "anonymous";
+                }
+
+                if ((gateway = switch_core_alloc(profile->pool, sizeof(*gateway)))) {
+                        char *register_str = "true", *scheme = "Digest",
+                                *realm = NULL,
+                                *username = NULL,
+                                *password = NULL,
+                                *caller_id_in_from = "false",
+                                *extension = NULL,
+                                *proxy = NULL,
+                                *context = "default",
+                                *expire_seconds = "3600",
+                                *retry_seconds = "30",
+                                *from_user = "",
+                                *from_domain = "",
+                                *register_proxy = NULL,
+                                *contact_params = NULL,
+                                *params = NULL,
+                                *register_transport = "udp";
+
+                        gateway->pool = profile->pool;
+                        gateway->profile = profile;
+                        gateway->name = switch_core_strdup(gateway->pool, name);
+                        gateway->freq = 0;
+                        gateway->next = NULL;
+
+                        for (param = switch_xml_child(gateway_tag, "param"); param; param = param->next) {
+                                char *var = (char *) switch_xml_attr_soft(param, "name");
+                                char *val = (char *) switch_xml_attr_soft(param, "value");
+
+                                if (!strcmp(var, "register")) {
+                                        register_str = val;
+                                } else if (!strcmp(var, "scheme")) {
+                                        scheme = val;
+                                } else if (!strcmp(var, "realm")) {
+                                        realm = val;
+                                } else if (!strcmp(var, "username")) {
+                                        username = val;
+                                } else if (!strcmp(var, "password")) {
+                                        password = val;
+                                } else if (!strcmp(var, "caller-id-in-from")) {
+                                        caller_id_in_from = val;
+                                } else if (!strcmp(var, "extension")) {
+                                        extension = val;
+                                } else if (!strcmp(var, "proxy")) {
+                                        proxy = val;
+                                } else if (!strcmp(var, "context")) {
+                                        context = val;
+                                } else if (!strcmp(var, "expire-seconds")) {
+                                        expire_seconds = val;
+                                } else if (!strcmp(var, "retry-seconds")) {
+                                        retry_seconds = val;
+                                } else if (!strcmp(var, "from-user")) {
+                                        from_user = val;
+                                } else if (!strcmp(var, "from-domain")) {
+                                        from_domain = val;
+                                } else if (!strcmp(var, "register-proxy")) {
+                                        register_proxy = val;
+                                } else if (!strcmp(var, "contact-params")) {
+                                        contact_params = val;
+                                } else if (!strcmp(var, "register-transport")) {
+                                        if (!strcasecmp(val, "udp") || !strcasecmp(val, "tcp")) {
+                                                register_transport = val;
+                                        } else {
+                                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: unsupported transport\n");
+                                                goto skip;
+                                        }
+                                }
+                        }
+
+                        if (switch_strlen_zero(realm)) {
+                                realm = name;
+                        }
+
+                        if (switch_strlen_zero(username)) {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: username param is REQUIRED!\n");
+                                goto skip;
+                        }
+
+                        if (switch_strlen_zero(password)) {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: password param is REQUIRED!\n");
+                                goto skip;
+                        }
+
+                        if (switch_strlen_zero(from_user)) {
+                                from_user = username;
+                        }
+
+                        if (switch_strlen_zero(extension)) {
+                                extension = username;
+                        }
+
+                        if (switch_strlen_zero(proxy)) {
+                                proxy = realm;
+                        }
+
+                        if (!switch_true(register_str)) {
+                                gateway->state = REG_STATE_NOREG;
+                        }
+
+                        if (switch_strlen_zero(from_domain)) {
+                                from_domain = realm;
+                        }
+
+                        if (switch_strlen_zero(register_proxy)) {
+                                register_proxy = proxy;
+                        }
+
+                        gateway->retry_seconds = atoi(retry_seconds);
+                        if (gateway->retry_seconds < 10) {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "INVALID: retry_seconds correcting the value to 30\n");
+                                gateway->retry_seconds = 30;
+                        }
+                        gateway->register_scheme = switch_core_strdup(gateway->pool, scheme);
+                        gateway->register_context = switch_core_strdup(gateway->pool, context);
+                        gateway->register_realm = switch_core_strdup(gateway->pool, realm);
+                        gateway->register_username = switch_core_strdup(gateway->pool, username);
+                        gateway->register_password = switch_core_strdup(gateway->pool, password);
+                        if (switch_true(caller_id_in_from)) {
+                                switch_set_flag(gateway, REG_FLAG_CALLERID);
+                        }
+                        if (contact_params) {
+                                if (*contact_params == ';') {
+                                        params = switch_core_sprintf(gateway->pool, "%s&transport=%s", contact_params, register_transport);
+                                } else {
+                                        params = switch_core_sprintf(gateway->pool, ";%s&transport=%s", contact_params, register_transport);
+                                }
+                        } else {
+                                params = switch_core_sprintf(gateway->pool, ";transport=%s", register_transport);
+                        }
+
+                        gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s;transport=%s", register_proxy,register_transport);
+                        gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s;transport=%s>", from_user, from_domain, register_transport);
+                        gateway->register_contact = switch_core_sprintf(gateway->pool, "<sip:%s@%s:%d%s>", extension,
+                                                                                                                        profile->extsipip ? profile->extsipip : profile->sipip, profile->sip_port, params);
+
+                        if (!strncasecmp(proxy, "sip:", 4)) {
+                                gateway->register_proxy = switch_core_strdup(gateway->pool, proxy);
+                                gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy + 4);
+                        } else {
+                                gateway->register_proxy = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
+                                gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy);
+                        }
+
+                        gateway->expires_str = switch_core_strdup(gateway->pool, expire_seconds);
+
+                        if ((gateway->freq = atoi(gateway->expires_str)) < 5) {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
+                                                                  "Invalid Freq: %d.  Setting Register-Frequency to 3600\n", gateway->freq);
+                                gateway->freq = 3600;
+                        }
+                        gateway->freq -= 2;
+
+                        if ((gp = sofia_reg_find_gateway(gateway->name))) {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", gateway->name);
+                                sofia_reg_release_gateway(gp);
+                        } else {
+                                gateway->next = profile->gateways;
+                                profile->gateways = gateway;
+                                sofia_reg_add_gateway(gateway->name, gateway);
+                        }
+                }
+
+        skip:
+                switch_assert(gateway_tag);
+        }
+
+ }
+
+ switch_status_t config_sofia(int reload, char *profile_name)
+ {
+        char *cf = "sofia.conf";
+        switch_xml_t cfg, xml = NULL, xprofile, param, settings, profiles, gateways_tag, domain_tag, domains_tag;
+        switch_status_t status = SWITCH_STATUS_SUCCESS;
+        sofia_profile_t *profile = NULL;
+        char url[512] = "";
+        int profile_found = 0;
+
+        if (!reload) {
+                su_init();
+                if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) {
+                        su_deinit();
+                        return SWITCH_STATUS_FALSE;
+                }
+
+                su_log_redirect(NULL, logger, NULL);
+                su_log_redirect(tport_log, logger, NULL);
+        }
+
+        if (!switch_strlen_zero(profile_name) && (profile = sofia_glue_find_profile(profile_name))) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile [%s] Already exists.\n", switch_str_nil(profile_name));
+                status = SWITCH_STATUS_FALSE;
+                sofia_glue_release_profile(profile);
+                return status;
+        }
+
+        switch_snprintf(url, sizeof(url), "profile=%s", switch_str_nil(profile_name));
+
+        if (!(xml = switch_xml_open_cfg(cf, &cfg, url))) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
+                status = SWITCH_STATUS_FALSE;
+                goto done;
+        }
+
+        if ((settings = switch_xml_child(cfg, "global_settings"))) {
+                for (param = switch_xml_child(settings, "param"); param; param = param->next) {
+                        char *var = (char *) switch_xml_attr_soft(param, "name");
+                        char *val = (char *) switch_xml_attr_soft(param, "value");
+                        if (!strcasecmp(var, "log-level")) {
+                                su_log_set_level(NULL, atoi(val));
+                        }
+                }
+        }
+
+        if ((profiles = switch_xml_child(cfg, "profiles"))) {
+                for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
+                        if (!(settings = switch_xml_child(xprofile, "settings"))) {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Settings, check the new config!\n");
+                        } else {
+                                char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name");
+                                switch_memory_pool_t *pool = NULL;
+
+                                if (!xprofilename) {
+                                        xprofilename = "unnamed";
+                                }
+
+                                if (profile_name) {
+                                        if (strcasecmp(profile_name, xprofilename)) {
+                                                continue;
+                                        } else {
+                                                profile_found = 1;
+                                        }
+                                }
+
+                                /* Setup the pool */
+                                if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+                                        goto done;
+                                }
+
+                                if (!(profile = (sofia_profile_t *) switch_core_alloc(pool, sizeof(*profile)))) {
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
+                                        goto done;
+                                }
+
+                                profile->pool = pool;
+                                profile->user_agent = SOFIA_USER_AGENT;
+
+                                profile->name = switch_core_strdup(profile->pool, xprofilename);
+                                switch_snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename);
+
+                                profile->dbname = switch_core_strdup(profile->pool, url);
+                                switch_core_hash_init(&profile->chat_hash, profile->pool);
+                                switch_core_hash_init(&profile->sub_hash, profile->pool);
+                                switch_thread_rwlock_create(&profile->rwlock, profile->pool);
+                                switch_mutex_init(&profile->flag_mutex, SWITCH_MUTEX_NESTED, profile->pool);
+                                profile->dtmf_duration = 100;
+
+                                for (param = switch_xml_child(settings, "param"); param; param = param->next) {
+                                        char *var = (char *) switch_xml_attr_soft(param, "name");
+                                        char *val = (char *) switch_xml_attr_soft(param, "value");
+
+                                        if (!strcasecmp(var, "debug")) {
+                                                profile->debug = atoi(val);
+                                        } else if (!strcasecmp(var, "use-rtp-timer") && switch_true(val)) {
+                                                switch_set_flag(profile, TFLAG_TIMER);
+                                        } else if (!strcasecmp(var, "sip-trace") && switch_true(val)) {
+                                                switch_set_flag(profile, TFLAG_TPORT_LOG);
+                                        } else if (!strcasecmp(var, "odbc-dsn") && !switch_strlen_zero(val)) {
+ #ifdef SWITCH_HAVE_ODBC
+                                                profile->odbc_dsn = switch_core_strdup(profile->pool, val);
+                                                if ((profile->odbc_user = strchr(profile->odbc_dsn, ':'))) {
+                                                        *profile->odbc_user++ = '\0';
+                                                        if ((profile->odbc_pass = strchr(profile->odbc_user, ':'))) {
+                                                                *profile->odbc_pass++ = '\0';
+                                                        }
+                                                }
+
+ #else
+                                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
+ #endif
+
+                                        } else if (!strcasecmp(var, "user-agent-string")) {
+                                                profile->user_agent = switch_core_strdup(profile->pool, val);;
+                                        } else if (!strcasecmp(var, "inbound-no-media") && switch_true(val)) {
+                                                switch_set_flag(profile, TFLAG_INB_NOMEDIA);
+                                        } else if (!strcasecmp(var, "inbound-late-negotiation") && switch_true(val)) {
+                                                switch_set_flag(profile, TFLAG_LATE_NEGOTIATION);
+                                        } else if (!strcasecmp(var, "rfc2833-pt")) {
+                                                profile->te = (switch_payload_t) atoi(val);
+                                        } else if (!strcasecmp(var, "cng-pt")) {
+                                                profile->cng_pt = (switch_payload_t) atoi(val);
+                                        } else if (!strcasecmp(var, "sip-port")) {
+                                                profile->sip_port = atoi(val);
+                                        } else if (!strcasecmp(var, "vad")) {
+                                                if (!strcasecmp(val, "in")) {
+                                                        switch_set_flag(profile, TFLAG_VAD_IN);
+                                                } else if (!strcasecmp(val, "out")) {
+                                                        switch_set_flag(profile, TFLAG_VAD_OUT);
+                                                } else if (!strcasecmp(val, "both")) {
+                                                        switch_set_flag(profile, TFLAG_VAD_IN);
+                                                        switch_set_flag(profile, TFLAG_VAD_OUT);
+                                                } else {
+                                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invald option %s for VAD\n", val);
+                                                }
+                                        } else if (!strcasecmp(var, "ext-rtp-ip")) {
+                                                profile->extrtpip = switch_core_strdup(profile->pool, strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip);
+                                        } else if (!strcasecmp(var, "rtp-ip")) {
+                                                profile->rtpip = switch_core_strdup(profile->pool, strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip);
+                                        } else if (!strcasecmp(var, "sip-ip")) {
+                                                profile->sipip = switch_core_strdup(profile->pool, strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip);
+                                        } else if (!strcasecmp(var, "ext-sip-ip")) {
+                                                if (!strcasecmp(val, "auto")) {
+                                                        profile->extsipip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
+                                                } else {
+                                                        char *ip = mod_sofia_globals.guess_ip;
+                                                        switch_port_t port = 0;
+                                                        if (sofia_glue_ext_address_lookup(&ip, &port, val, profile->pool) == SWITCH_STATUS_SUCCESS) {
+
+                                                                if (ip) {
+                                                                        profile->extsipip = switch_core_strdup(profile->pool, ip);
+                                                                }
+                                                        }
+                                                }
+                                        } else if (!strcasecmp(var, "force-register-domain")) {
+                                                profile->reg_domain = switch_core_strdup(profile->pool, val);
+                                        } else if (!strcasecmp(var, "bind-params")) {
+                                                profile->bind_params = switch_core_strdup(profile->pool, val);
+                                        } else if (!strcasecmp(var, "sip-domain")) {
+                                                profile->sipdomain = switch_core_strdup(profile->pool, val);
+                                        } else if (!strcasecmp(var, "rtp-timer-name")) {
+                                                profile->timer_name = switch_core_strdup(profile->pool, val);
+                                        } else if (!strcasecmp(var, "hold-music")) {
+                                                profile->hold_music = switch_core_strdup(profile->pool, val);
+                                        } else if (!strcasecmp(var, "session-timeout")) {
+                                                int v_session_timeout = atoi(val);
+                                                if (v_session_timeout >= 0) {
+                                                        profile->session_timeout = v_session_timeout;
+                                                }
+                                        } else if (!strcasecmp(var, "max-proceeding")) {
+                                                int v_max_proceeding = atoi(val);
+                                                if (v_max_proceeding >= 0) {
+                                                        profile->max_proceeding = v_max_proceeding;
+                                                }
+                                        } else if (!strcasecmp(var, "rtp-timeout-sec")) {
+                                                int v = atoi(val);
+                                                if (v >= 0) {
+                                                        profile->rtp_timeout_sec = v;
+                                                }
+                                        } else if (!strcasecmp(var, "manage-presence")) {
+                                                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, "supress-cng")) {
+                                                if (switch_true(val)) {
+                                                        profile->pflags |= PFLAG_SUPRESS_CNG;
+                                                }
+                                        } else if (!strcasecmp(var, "NDLB-to-in-200-contact")) {
+                                                if (switch_true(val)) {
+                                                        profile->ndlb |= PFLAG_NDLB_TO_IN_200_CONTACT;
+                                                }
+                                        } else if (!strcasecmp(var, "NDLB-broken-auth-hash")) {
+                                                if (switch_true(val)) {
+                                                        profile->ndlb |= PFLAG_NDLB_BROKEN_AUTH_HASH;
+                                                }
+                                        } else if (!strcasecmp(var, "pass-rfc2833")) {
+                                                if (switch_true(val)) {
+                                                        profile->pflags |= PFLAG_PASS_RFC2833;
+                                                }
+                                        } else if (!strcasecmp(var, "inbound-codec-negotiation")) {
+                                                if (!strcasecmp(val, "greedy")) {
+                                                        profile->pflags |= PFLAG_GREEDY;
+                                                }
+                                        } else if (!strcasecmp(var, "disable-transcoding")) {
+                                                if (switch_true(val)) {
+                                                        profile->pflags |= PFLAG_DISABLE_TRANSCODING;
+                                                }
+                                        } else if (!strcasecmp(var, "rtp-rewrite-timestamps")) {
+                                                if (switch_true(val)) {
+                                                        profile->pflags |= PFLAG_REWRITE_TIMESTAMPS;
+                                                }
+                                        } else if (!strcasecmp(var, "auth-calls")) {
+                                                if (switch_true(val)) {
+                                                        profile->pflags |= PFLAG_AUTH_CALLS;
+                                                }
+                                        } else if (!strcasecmp(var, "nonce-ttl")) {
+                                                profile->nonce_ttl = atoi(val);
+                                        } else if (!strcasecmp(var, "accept-blind-reg")) {
+                                                if (switch_true(val)) {
+                                                        profile->pflags |= PFLAG_BLIND_REG;
+                                                }
+                                        } else if (!strcasecmp(var, "auth-all-packets")) {
+                                                if (switch_true(val)) {
+                                                        profile->pflags |= PFLAG_AUTH_ALL;
+                                                }
+                                        } else if (!strcasecmp(var, "full-id-in-dialplan")) {
+                                                if (switch_true(val)) {
+                                                        profile->pflags |= PFLAG_FULL_ID;
+                                                }
+                                        } else if (!strcasecmp(var, "bitpacking")) {
+                                                if (!strcasecmp(val, "aal2")) {
+                                                        profile->codec_flags = SWITCH_CODEC_FLAG_AAL2;
+                                                }
+                                        } else if (!strcasecmp(var, "username")) {
+                                                profile->username = switch_core_strdup(profile->pool, val);
+                                        } else if (!strcasecmp(var, "context")) {
+                                                profile->context = switch_core_strdup(profile->pool, val);
+                                        } else if (!strcasecmp(var, "alias")) {
+                                                sip_alias_node_t *node;
+                                                if ((node = switch_core_alloc(profile->pool, sizeof(*node)))) {
+                                                        if ((node->url = switch_core_strdup(profile->pool, val))) {
+                                                                node->next = profile->aliases;
+                                                                profile->aliases = node;
+                                                        }
+                                                }
+                                        } else if (!strcasecmp(var, "dialplan")) {
+                                                profile->dialplan = switch_core_strdup(profile->pool, val);
+                                        } else if (!strcasecmp(var, "max-calls")) {
+                                                profile->max_calls = atoi(val);
+                                        } else if (!strcasecmp(var, "codec-prefs")) {
+                                                profile->codec_string = switch_core_strdup(profile->pool, val);
+                                        } else if (!strcasecmp(var, "dtmf-duration")) {
+                                                int dur = atoi(val);
+                                                if (dur > 10 && dur < 8000) {
+                                                        profile->dtmf_duration = dur;
+                                                } else {
+                                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Duration out of bounds!\n");
+                                                }
+                                        }
+                                }
+
+                                if (!profile->cng_pt) {
+                                        profile->cng_pt = SWITCH_RTP_CNG_PAYLOAD;
+                                }
+
+                                if (!profile->sipip) {
+                                        profile->sipip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
+                                }
+
+                                if (!profile->rtpip) {
+                                        profile->rtpip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
+                                }
+
+                                if (profile->nonce_ttl < 60) {
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting nonce TTL to 60 seconds\n");
+                                        profile->nonce_ttl = 60;
+                                }
+
+                                if (switch_test_flag(profile, TFLAG_TIMER) && !profile->timer_name) {
+                                        profile->timer_name = switch_core_strdup(profile->pool, "soft");
+                                }
+
+                                if (!profile->username) {
+                                        profile->username = switch_core_strdup(profile->pool, "FreeSWITCH");
+                                }
+
+                                if (!profile->rtpip) {
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Setting ip to '127.0.0.1'\n");
+                                        profile->rtpip = switch_core_strdup(profile->pool, "127.0.0.1");
+                                }
+
+                                if (!profile->sip_port) {
+                                        profile->sip_port = atoi(SOFIA_DEFAULT_PORT);
+                                }
+
+                                if (!profile->dialplan) {
+                                        profile->dialplan = switch_core_strdup(profile->pool, "XML");
+                                }
+
+                                if (!profile->sipdomain) {
+                                        profile->sipdomain = switch_core_strdup(profile->pool, profile->sipip);
+                                }
+                                if (profile->extsipip) {
+                                        profile->url = switch_core_sprintf(profile->pool, "sip:mod_sofia@%s:%d", profile->extsipip, profile->sip_port);
+                                        profile->bindurl = switch_core_sprintf(profile->pool, "%s;maddr=%s", profile->url, profile->sipip);
+                                } else {
+                                        profile->url = switch_core_sprintf(profile->pool, "sip:mod_sofia@%s:%d", profile->sipip, profile->sip_port);
+                                        profile->bindurl = profile->url;
+                                }
+
+                                if (profile->bind_params) {
+                                        char *bindurl = profile->bindurl;
+                                        profile->bindurl = switch_core_sprintf(profile->pool, "%s;%s", bindurl, profile->bind_params);
+                                }
+
+                        }
+                        if (profile) {
+                                switch_xml_t aliases_tag, alias_tag;
+
+                                if ((gateways_tag = switch_xml_child(xprofile, "registrations"))) {
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
+                                                                          "The <registrations> syntax has been discontinued, please see the new syntax in the default configuration examples\n");
+                                } else if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
+                                        parse_gateways(profile, gateways_tag);
+                                }
+
+                                if ((domains_tag = switch_xml_child(xprofile, "domains"))) {
+                                        for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) {
+                                                switch_xml_t droot, actual_domain_tag, ut;
+                                                char *dname = (char *) switch_xml_attr_soft(domain_tag, "name");
+                                                char *parse = (char *) switch_xml_attr_soft(domain_tag, "parse");
+
+                                                if (!switch_strlen_zero(dname)) { 
+                                                        if (switch_true(parse)) {
+                                                                if (switch_xml_locate_domain(dname, NULL, &droot, &actual_domain_tag) == SWITCH_STATUS_SUCCESS) {
+                                                                        for (ut = switch_xml_child(actual_domain_tag, "user"); ut; ut = ut->next) {
+                                                                                if (((gateways_tag = switch_xml_child(ut, "gateways")))) {
+                                                                                        parse_gateways(profile, gateways_tag);
+                                                                                }
+                                                                        }
+                                                                        switch_xml_free(droot);
+                                                                }
+                                                        }
+                                                        sofia_glue_add_profile(switch_core_strdup(profile->pool, dname), profile);
+                                                }
+                                        }
+                                }
+
+                                if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) {
+                                        for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) {
+                                                char *aname = (char *) switch_xml_attr_soft(alias_tag, "name");
+                                                if (!switch_strlen_zero(aname)) {
+
+                                                        if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname), profile) == SWITCH_STATUS_SUCCESS) {
+                                                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name);
+                                                        } else {
+                                                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Adding Alias [%s] for profile [%s] (name in use)\n", 
+                                                                                                  aname, profile->name);
+                                                        }
+                                                }
+                                        }
+                                }
+
+                                if (profile->sipip) {
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Started Profile %s [%s]\n", profile->name, url);
+                                        launch_sofia_profile_thread(profile);
+                                } else {
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Unable to start Profile %s due to no configured sip-ip\n", profile->name);
+                                }
+                                profile = NULL;
+                        }
+                        if (profile_found) {
+                                break;
+                        }
+                }
+        }
+   done:
+        if (xml) {
+                switch_xml_free(xml);
+        }
+
+        if (profile_name && !profile_found) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No Such Profile '%s'\n", profile_name);
+                status = SWITCH_STATUS_FALSE;
+        }
+
+        return status;
+
+ }
+
+ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status,
+                                                                         char const *phrase,
+                                                                         nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
+ {
+
+
+        if (session && (status == 180 || status == 183 || status == 200)) {
+                switch_channel_t *channel = switch_core_session_get_channel(session);
+                const char *astate = "early";
+
+                if (status == 200) {
+                        astate = "confirmed";
+                }
+
+                if (!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_ANSWERED) && 
+                        !switch_channel_test_flag(channel, CF_RING_READY)) {
+                        const char *to_user = switch_str_nil(sip->sip_to->a_url->url_user);
+                        const char *to_host = switch_str_nil(sip->sip_to->a_url->url_host);
+                        const char *from_user = switch_str_nil(sip->sip_from->a_url->url_user);
+                        const char *from_host = switch_str_nil(sip->sip_from->a_url->url_host);
+                        const char *contact_user = switch_str_nil(sip->sip_contact->m_url->url_user);
+                        const char *contact_host = switch_str_nil(sip->sip_contact->m_url->url_host);
+                        const char *user_agent = switch_str_nil(sip->sip_user_agent->g_string);
+                        const char *call_id = switch_str_nil(sip->sip_call_id->i_id);
+                        char *sql = NULL;
+
+                       sql = switch_mprintf(
+                                                                "insert into sip_dialogs values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q')",
+                                                                call_id,
+                                                                switch_core_session_get_uuid(session),
+                                                                to_user,
+                                                                to_host,
+                                                                from_user,
+                                                                from_host,
+                                                                contact_user,
+                                                                contact_host,
+                                                                astate,
+                                                                "outbound",
+                                                                user_agent
+                                                                );
+
+                       switch_assert(sql);
+
+                       sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+                       free(sql);
                }
        }
-  done:
-       if (xml) {
-               switch_xml_free(xml);
-       }
-
-       if (profile_name && !profile_found) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No Such Profile '%s'\n", profile_name);
-               status = SWITCH_STATUS_FALSE;
-       }
-
-       return status;
-
 }
 
 static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
@@ -2107,14 +2161,15 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
                su_free(profile->home, tmp);
        }
 
-#if 0
        if (sofia_test_pflag(profile, PFLAG_PRESENCE)) {
-               char *tmp = switch_mprintf("%s@%s", switch_str_nil(switch_channel_get_variable(channel, "sip_to_user")), switch_str_nil(switch_channel_get_variable(channel, "sip_to_host")));
+               const char *user = switch_str_nil(sip->sip_from->a_url->url_user);
+               const char *host = switch_str_nil(sip->sip_from->a_url->url_host);
+
+               char *tmp = switch_mprintf("%s@%s", user, host);
                switch_assert(tmp);
                switch_channel_set_variable(channel, "presence_id", tmp);
                free(tmp);
        }
-#endif
 
        check_decode(displayname, session);
        tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
@@ -2188,6 +2243,35 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
        tech_pvt->nh = nh;
 
        if (switch_core_session_thread_launch(session) == SWITCH_STATUS_SUCCESS) {
+               const char *to_user = switch_str_nil(sip->sip_to->a_url->url_user);
+               const char *to_host = switch_str_nil(sip->sip_to->a_url->url_host);
+               const char *from_user = switch_str_nil(sip->sip_from->a_url->url_user);
+               const char *from_host = switch_str_nil(sip->sip_from->a_url->url_host);
+               const char *contact_user = switch_str_nil(sip->sip_contact->m_url->url_user);
+               const char *contact_host = switch_str_nil(sip->sip_contact->m_url->url_host);
+               const char *user_agent = switch_str_nil(sip->sip_user_agent->g_string);
+               const char *call_id = switch_str_nil(sip->sip_call_id->i_id);
+               char *sql = NULL;
+
+               sql = switch_mprintf(
+                                                        "insert into sip_dialogs values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q')",
+                                                        call_id,
+                                                        tech_pvt->sofia_private->uuid,
+                                                        to_user,
+                                                        to_host,
+                                                        from_user,
+                                                        from_host,
+                                                        contact_user,
+                                                        contact_host,
+                                                        "confirmed",
+                                                        "inbound",
+                                                        user_agent
+                                                        );
+
+               switch_assert(sql);
+
+               sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+               free(sql);
                return;
        }
 
index 23c65e57254de50608ad73f44b67f5341d97a4a9..0449527b3bf0922afd2c5cc08c91733f14619f29 100644 (file)
@@ -1696,6 +1696,21 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                "   user_agent      VARCHAR(255)\n"
                ");\n";
 
+       char dialog_sql[] =
+               "CREATE TABLE sip_dialogs (\n"
+               "   call_id         VARCHAR(255),\n"
+               "   uuid            VARCHAR(255),\n"
+               "   sip_to_user     VARCHAR(255),\n"
+               "   sip_to_host     VARCHAR(255),\n"
+               "   sip_from_user   VARCHAR(255),\n"
+               "   sip_from_host   VARCHAR(255),\n"
+               "   contact_user    VARCHAR(255),\n" 
+               "   contact_host    VARCHAR(255),\n" 
+               "   state           VARCHAR(255),\n" 
+               "   direction       VARCHAR(255),\n" 
+               "   user_agent      VARCHAR(255)\n"
+               ");\n";
+
        char sub_sql[] =
                "CREATE TABLE sip_subscriptions (\n"
                "   proto           VARCHAR(255),\n"
@@ -1742,6 +1757,11 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                        switch_odbc_handle_exec(profile->master_odbc, sub_sql, NULL);
                }
 
+               if (switch_odbc_handle_exec(profile->master_odbc, "delete from sip_dialogs", NULL) != SWITCH_ODBC_SUCCESS) {
+                       switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_dialogs", NULL);
+                       switch_odbc_handle_exec(profile->master_odbc, dialog_sql, NULL);
+               }
+
                if (switch_odbc_handle_exec(profile->master_odbc, "select nonce from sip_authentication", NULL) != SWITCH_ODBC_SUCCESS) {
                        switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_authentication", NULL);
                        switch_odbc_handle_exec(profile->master_odbc, auth_sql, NULL);
@@ -1756,6 +1776,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
 
                switch_core_db_test_reactive(profile->master_db, "select sip_user,user_agent from sip_registrations", "DROP TABLE sip_registrations", reg_sql);
                switch_core_db_test_reactive(profile->master_db, "delete from sip_subscriptions where sip_user != '' or accept != ''", "DROP TABLE sip_subscriptions", sub_sql);
+               switch_core_db_test_reactive(profile->master_db, "delete from sip_dialogs", "DROP TABLE sip_dialogs", dialog_sql);
                switch_core_db_test_reactive(profile->master_db, "select * from sip_authentication", "DROP TABLE sip_authentication", auth_sql);
 
        }
@@ -1813,7 +1834,8 @@ void sofia_glue_execute_sql(sofia_profile_t *profile, switch_bool_t master, char
                                goto end;
                        }
                }
-               switch_core_db_persistant_execute(db, sql, 25);
+               switch_core_db_persistant_execute(db, sql, 1);
+
                if (!master) {
                        switch_core_db_close(db);
                }
index 77fe0e365d40b0bebce04af91f73b88eaee8f3e9..986e3dc54f6ad7ab975408f4228a1fd840458d2b 100644 (file)
@@ -43,6 +43,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
 struct presence_helper {
        sofia_profile_t *profile;
        switch_event_t *event;
+       switch_stream_handle_t stream;
 };
 
 switch_status_t sofia_presence_chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint)
@@ -122,7 +123,7 @@ void sofia_presence_cancel(void)
        sofia_profile_t *profile;
        switch_hash_index_t *hi;
        void *val;
-       struct presence_helper helper;
+       struct presence_helper helper = { 0 };
        
        if ((sql = switch_mprintf("select *,-1,'unavailable','unavailable' from sip_subscriptions where event='presence'"))) {
                switch_mutex_lock(mod_sofia_globals.hash_mutex);
@@ -317,7 +318,7 @@ void sofia_presence_event_handler(switch_event_t *event)
        }
 
        if (event->event_id == SWITCH_EVENT_ROSTER) {
-               struct presence_helper helper;
+               struct presence_helper helper = { 0 };
                
                if (from) {
                        sql = switch_mprintf("select *,1,'%q','%q' from sip_subscriptions where event='presence' and full_from like '%%%q%%'", status, rpid, from);
@@ -393,10 +394,17 @@ void sofia_presence_event_handler(switch_event_t *event)
                                probe_euser = (p + 1);
                        }
 
-                       if (probe_euser && probe_host &&
-                               (sql = switch_mprintf("select sip_user,sip_host,status,rpid,'' from sip_registrations where sip_user='%q' and sip_host='%q'",
-                                                                         probe_euser, probe_host)) && (profile = sofia_glue_find_profile(probe_host))) {
-                               
+                       if (probe_euser && probe_host && (profile = sofia_glue_find_profile(probe_host))) {
+                               sql = switch_mprintf("select sip_registrations.sip_user, sip_registrations.sip_host, sip_registrations.status, "
+                                                                        "sip_registrations.rpid,'', sip_dialogs.uuid, sip_dialogs.state, sip_dialogs.direction "
+                                                                        "from sip_registrations left join sip_dialogs on "
+                                                                        "(sip_dialogs.contact_user = sip_registrations.sip_user or "
+                                                                        "sip_dialogs.sip_from_user = sip_registrations.sip_user or "
+                                                                        "sip_dialogs.sip_to_user = sip_registrations.sip_user) "
+                                                                        "and sip_dialogs.sip_to_host = sip_registrations.sip_host "
+                                                                        "where sip_registrations.sip_user='%q' and sip_registrations.sip_host='%q'",
+                                                                        probe_euser, probe_host);
+                               switch_assert(sql);
                                sofia_glue_execute_sql_callback(profile,
                                                                                                SWITCH_FALSE,
                                                                                                profile->ireg_mutex,
@@ -407,6 +415,7 @@ void sofia_presence_event_handler(switch_event_t *event)
                                sofia_glue_release_profile(profile);
                                switch_safe_free(sql);
                        }
+
                        switch_safe_free(user);
                }
                return;
@@ -435,16 +444,23 @@ void sofia_presence_event_handler(switch_event_t *event)
                }
 
                if (sql) {
-                       struct presence_helper helper;
+                       struct presence_helper helper = { 0 };
 
                        helper.profile = profile;
             helper.event = event;
+                       SWITCH_STANDARD_STREAM(helper.stream);
                        sofia_glue_execute_sql_callback(profile,
                                                                                        SWITCH_FALSE,
                                                                                        profile->ireg_mutex,
                                                                                        sql,
                                                                                        sofia_presence_sub_callback,
                                                                                        &helper);
+                       
+
+                       if (!switch_strlen_zero((char *)helper.stream.data)) {
+                               sofia_glue_execute_sql(profile, SWITCH_FALSE, helper.stream.data, profile->ireg_mutex);
+                       }
+                       switch_safe_free(helper.stream.data);
                }
        }
        switch_mutex_unlock(mod_sofia_globals.hash_mutex);
@@ -495,8 +511,17 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char
        char *status = argv[2];
        char *rpid = argv[3];
        char *proto = argv[4];
+       char *uuid = NULL;
+       char *state = NULL;
+       char *direction = NULL;
        switch_event_t *event;
 
+       if (argc > 5) {
+               uuid = switch_str_nil(argv[5]);
+               state = switch_str_nil(argv[6]);
+               direction = switch_str_nil(argv[7]);
+       }
+
        if (switch_strlen_zero(proto)) {
                proto = NULL;
        }
@@ -508,11 +533,20 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", status);
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
-               //switch_event_add_header(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
-               //switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", 0);
-               //switch_event_add_header(event, SWITCH_STACK_BOTTOM, "unique-id", "%s", SOFIA_CHAT_PROTO);
-               //switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-state", "%s", "CS_HANGUP");
-               //switch_event_add_header(event, SWITCH_STACK_BOTTOM, "answer-state", "%s", "void");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", 0);
+
+
+               if (switch_strlen_zero(state)) {
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "unique-id", "%s", SOFIA_CHAT_PROTO);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-state", "%s", "CS_HANGUP");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "answer-state", "%s", "terminated");
+               } else {
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-state", "%s", "CS_RING");
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "unique-id", "%s", uuid);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "answer-state", "%s", state);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "call-direction", "%s", direction);
+               }
                
                switch_event_fire(&event);
        }
@@ -556,8 +590,8 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
 {
        struct presence_helper *helper = (struct presence_helper *) pArg;
        sofia_profile_t *profile = helper->profile;
-       char *pl;
-       char *clean_id = NULL, *id = NULL, *note;
+       char *pl = NULL;
+       char *clean_id = NULL, *id = NULL, *note = NULL;
        uint32_t in = atoi(argv[13]);
        char *status = argv[14];
        char *rpid = argv[15];
@@ -570,7 +604,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
        char *event = argv[5];
        char *call_id = argv[7];
        nua_handle_t *nh;
-       char *to;
+       char *to = NULL;
        char *open;
        char *prpid;
        int done = 0;
@@ -601,7 +635,11 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
                open = "closed";
        }
 
-       clean_id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
+       if (!strcasecmp(proto, SOFIA_CHAT_PROTO)) {
+               clean_id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
+       } else {
+               clean_id = switch_mprintf("sip:%s+%s@%s", proto, sub_to_user, sub_to_host);
+       }
 
        if (!strcasecmp(sub_to_host, host)) {
                /* same host */
@@ -617,34 +655,40 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
        
        if (!strcmp(event, "dialog") && helper->event) {
                switch_stream_handle_t stream = { 0 };
-               //const char *direction = switch_str_nil(switch_event_get_header(helper->event, "call-direction"));
+               const char *direction = switch_str_nil(switch_event_get_header(helper->event, "call-direction"));
                const char *uuid = switch_str_nil(switch_event_get_header(helper->event, "unique-id"));
                const char *state = switch_str_nil(switch_event_get_header(helper->event, "channel-state"));
                const char *event_status = switch_str_nil(switch_event_get_header(helper->event, "status"));
                const char *astate = switch_str_nil(switch_event_get_header(helper->event, "answer-state"));
-
+               const char *dft_state;
+               
                SWITCH_STANDARD_STREAM(stream);
                
-               if (!strcasecmp(state, "cs_hangup")) {
+               if (!strcasecmp(direction, "outbound")) {
+                       direction = "recipient";
+                       dft_state = "early";
+               } else {
+                       direction = "initiator";
+                       dft_state = "confirmed";
+               }
+
+               if (!strcasecmp(state, "cs_execute")) {
+                       goto end;
+               } if (!strcasecmp(state, "cs_hangup")) {
                        astate = "terminated";
                } else if (!strcasecmp(astate, "answered")) {
                        astate = "confirmed";
-               } else if (!strcasecmp(astate, "ringing")) {
-                       astate = "early";
+               } else {
+                       astate = dft_state;
                }
-                                                         
+               
                stream.write_function(&stream, 
                                                          "<?xml version=\"1.0\"?>\n"
                                                          "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" "
                                                          "version=\"%s\" state=\"full\" entity=\"%s\">\n", 
                                                          switch_str_nil(switch_event_get_header(helper->event, "event_count")), clean_id);
-               
-               if (!strcasecmp(state, "RING")) {
-                       stream.write_function(&stream, "<dialog id=\"%s\" direction=\"recipient\">\n", uuid);
-               } else {
-                       stream.write_function(&stream, "<dialog id=\"%s\">\n", uuid);
-               }
-               
+               /* astate of aleg/outbound should start @ confirmed not early. direction is recipient or initiator */
+               stream.write_function(&stream, "<dialog id=\"%s\" direction=\"%s\">\n", uuid, direction);
 
                stream.write_function(&stream, "<state>%s</state>\n", astate);
 
@@ -656,7 +700,11 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
                stream.write_function(&stream, "</dialog>\n</dialog-info>\n");
                pl = stream.data;
                ct = "application/dialog-info+xml";
-               //printf("%s\n", pl);
+               
+               if (astate && uuid && helper->stream.data) {
+                       stream.write_function(&helper->stream, "update sip_dialogs set state='%s' where uuid='%s';\n", astate, uuid);
+               }
+
        } else {
                pl = switch_mprintf("<?xml version='1.0' encoding='UTF-8'?>\r\n"
                                                        "<presence xmlns='urn:ietf:params:xml:ns:pidf'\r\n"
@@ -696,6 +744,8 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
                switch_core_hash_delete(profile->sub_hash, call_id);
        }
 
+ end:
+
        switch_safe_free(id);
        switch_safe_free(clean_id);
        switch_safe_free(note);
index 0a74d1871ccc445aca6c211a7e96b4d5d7530dea..1a90b3d8bfa605c7f361df52a0af1588891af45b 100644 (file)
@@ -84,11 +84,12 @@ SWITCH_DECLARE(int) switch_core_db_exec(switch_core_db_t *db, const char *sql, s
 
        while(--sane > 0) {
                ret = sqlite3_exec(db, sql, callback, data, errmsg);
-
                if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
-                       switch_safe_free(*errmsg);
-                       switch_yield(1000);
-                       continue;
+                       if (sane > 1) {
+                               switch_safe_free(*errmsg);
+                               switch_yield(1000);
+                               continue;
+                       }
                } else {
                        break;
                }