]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
solve problem from MODENDP-258 with an alternate approach, and make send-message...
authorAnthony Minessale <anthony.minessale@gmail.com>
Thu, 12 Nov 2009 03:52:07 +0000 (03:52 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Thu, 12 Nov 2009 03:52:07 +0000 (03:52 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15441 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_sofia/sofia_presence.c
src/mod/endpoints/mod_sofia/sofia_reg.c
src/mod/endpoints/mod_sofia/sofia_sla.c

index 770ae67ce598cc189cc9a9a43be2fc85cc316a0c..6c9f2a4310732546dec6f5c6129a180f0e2807e0 100644 (file)
@@ -2042,7 +2042,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
                                                                                 profile->name);
                                }
 
-                               sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, show_reg_callback, &cb);
+                               sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, show_reg_callback, &cb);
                                switch_safe_free(sql);
 
                                stream->write_function(stream, "%s\n", line);
@@ -2263,7 +2263,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
                                                                                 profile->name);
                                }
 
-                               sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, show_reg_callback_xml, &cb);
+                               sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, show_reg_callback_xml, &cb);
                                switch_safe_free(sql);
 
                                stream->write_function(stream, "  </registrations>\n");
@@ -2653,7 +2653,7 @@ SWITCH_STANDARD_API(sofia_contact_function)
                        }
 
                        switch_assert(sql);
-                       sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, contact_callback, &cb);
+                       sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, contact_callback, &cb);
                        switch_safe_free(sql);
                        reply = (char *) mystream.data;
                        if (!zstr(reply) && end_of(reply) == ',') {
@@ -3365,7 +3365,7 @@ static void general_event_handler(switch_event_t *event)
                                
 
                                switch_mutex_lock(profile->ireg_mutex);
-                               sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, notify_callback, profile);
+                               sofia_glue_execute_sql_callback(profile, NULL, sql, notify_callback, profile);
                                switch_mutex_unlock(profile->ireg_mutex);
                                sofia_glue_release_profile(profile);
 
index 03132cceb6ce2c25232dde672eab16ee5c1911b7..e6c5e958f84bef1f899560c0360ce443b49e6101 100644 (file)
@@ -475,7 +475,8 @@ struct sofia_profile {
        sofia_gateway_t *gateways;
        su_home_t *home;
        switch_hash_t *chat_hash;
-       switch_core_db_t *master_db;
+       switch_hash_t *db_hash;
+       //switch_core_db_t *master_db;
        switch_thread_rwlock_t *rwlock;
        switch_mutex_t *flag_mutex;
        uint32_t inuse;
@@ -670,6 +671,11 @@ typedef struct {
         char *route_uri;
 } sofia_destination_t;
 
+typedef struct {
+       switch_core_db_t *db;
+       time_t last_used;
+} sofia_cache_db_handle_t;
+
 #define sofia_test_pflag(obj, flag) ((obj)->pflags[flag] ? 1 : 0)
 #define sofia_set_pflag(obj, flag) (obj)->pflags[flag] = 1
 #define sofia_set_pflag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
@@ -747,7 +753,7 @@ switch_status_t config_sofia(int reload, char *profile_name);
 void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_regtype_t regtype, const char *realm, int stale);
 auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization, 
                                                                sip_t const *sip, const char *regstr, char *np, size_t nplen, char *ip, switch_event_t **v_event, 
-                                                               long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params);
+                                                               long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count);
                                                                
 
 void sofia_reg_handle_sip_r_challenge(int status,
@@ -773,7 +779,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                                         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_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic);
-void sofia_glue_actually_execute_sql(sofia_profile_t *profile, switch_bool_t master, char *sql, switch_mutex_t *mutex);
+void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex);
 void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot);
 void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now);
 void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now);
@@ -795,7 +801,6 @@ void sofia_glue_sql_close(sofia_profile_t *profile);
 int sofia_glue_init_sql(sofia_profile_t *profile);
 char *sofia_overcome_sip_uri_weakness(switch_core_session_t *session, const char *uri, const sofia_transport_t transport, switch_bool_t uri_only, const char *params);
 switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
-                                                                                         switch_bool_t master,
                                                                                          switch_mutex_t *mutex,
                                                                                          char *sql,
                                                                                          switch_core_db_callback_func_t callback,
@@ -925,3 +930,4 @@ void sofia_glue_set_extra_headers(switch_channel_t *channel, sip_t const *sip, c
 void sofia_info_send_sipfrag(switch_core_session_t *aleg, switch_core_session_t *bleg);
 void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t send);
 void sofia_send_callee_id(switch_core_session_t *session, const char *name, const char *number);
+int sofia_sla_supported(sip_t const *sip);
index 1645880e8411bc8b156158e6556086c02e37e6a6..ba08175299824089d507767efc5c164ae9f51fdc 100644 (file)
@@ -591,7 +591,7 @@ void sofia_event_callback(nua_event_t event,
                        sofia_glue_get_addr(nua_current_request(nua), network_ip,  sizeof(network_ip), NULL);
                        auth_res = sofia_reg_parse_auth(profile, authorization, sip,
                                                                                        (char *) sip->sip_request->rq_method_name, tech_pvt->key, strlen(tech_pvt->key), network_ip, NULL, 0,
-                                                                                       REG_INVITE, NULL, NULL);
+                                                                                       REG_INVITE, NULL, NULL, NULL);
                }
                
                if (auth_res != AUTH_OK) {
@@ -943,7 +943,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread
                                sprintf(sqlbuf + len, "commit;\n");
 
                                //printf("TRANS:\n%s\n", sqlbuf);
-                               sofia_glue_actually_execute_sql(profile, SWITCH_TRUE, sqlbuf, NULL);
+                               sofia_glue_actually_execute_sql(profile, sqlbuf, NULL);
                                switch_mutex_unlock(profile->ireg_mutex);
                                loop_count = 0;
                        }
@@ -951,7 +951,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread
                        if (qsize) {
                                switch_mutex_lock(profile->ireg_mutex);
                                while (switch_queue_trypop(profile->sql_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
-                                       sofia_glue_actually_execute_sql(profile, SWITCH_TRUE, (char *) pop, NULL);
+                                       sofia_glue_actually_execute_sql(profile, (char *) pop, NULL);
                                        free(pop);
                                }
                                switch_mutex_unlock(profile->ireg_mutex);
@@ -978,7 +978,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread
 
        switch_mutex_lock(profile->ireg_mutex);
        while (switch_queue_trypop(profile->sql_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
-               sofia_glue_actually_execute_sql(profile, SWITCH_TRUE, (char *) pop, NULL);
+               sofia_glue_actually_execute_sql(profile, (char *) pop, NULL);
                free(pop);
        }
        switch_mutex_unlock(profile->ireg_mutex);
@@ -1098,6 +1098,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
                                   NUTAG_APPL_METHOD("NOTIFY"),
                                   NUTAG_APPL_METHOD("INFO"),
                                   NUTAG_APPL_METHOD("ACK"),
+                                  NUTAG_APPL_METHOD("SUBSCRIBE"),
 #ifdef MANUAL_BYE
                                   NUTAG_APPL_METHOD("BYE"),
 #endif
@@ -1267,6 +1268,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
 
        sofia_glue_del_profile(profile);
        switch_core_hash_destroy(&profile->chat_hash);
+       switch_core_hash_destroy(&profile->db_hash);
 
        switch_thread_rwlock_unlock(profile->rwlock);
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write unlock %s\n", profile->name);
@@ -1864,6 +1866,7 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
                                                if (switch_true(val)) {
                                                        sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
                                                } else if (!strcasecmp(val, "first-only")) {
+                                                       sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
                                                        sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
                                                } else {
                                                        sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
@@ -2387,6 +2390,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
 
                                profile->dbname = switch_core_strdup(profile->pool, url);
                                switch_core_hash_init(&profile->chat_hash, profile->pool);
+                               switch_core_hash_init(&profile->db_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;
@@ -2397,10 +2401,11 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                sofia_set_pflag(profile, PFLAG_DISABLE_100REL);
                                profile->auto_restart = 1;
                                sofia_set_pflag(profile, PFLAG_AUTOFIX_TIMING);
-                               sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
                                sofia_set_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE);
                                profile->contact_user = SOFIA_DEFAULT_CONTACT_USER;
                                sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID);
+                               sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
+                               sofia_set_pflag(profile, PFLAG_SQL_IN_TRANS);
 
                                for (param = switch_xml_child(settings, "param"); param; param = param->next) {
                                        char *var = (char *) switch_xml_attr_soft(param, "name");
@@ -2479,6 +2484,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                                if (switch_true(val)) {
                                                        sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
                                                } else if (!strcasecmp(val, "first-only")) {
+                                                       sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
                                                        sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
                                                } else {
                                                        sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
@@ -2653,6 +2659,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                        } else if (!strcasecmp(var, "manage-shared-appearance")) {
                                                if (switch_true(val)) {
                                                        sofia_set_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE);
+                                                       profile->pres_type = PRES_TYPE_FULL;
                                                        profile->sla_contact = switch_core_sprintf(profile->pool, "sla-agent");
                                                }
                                        } else if (!strcasecmp(var, "disable-srv")) {
index 7e64e91b53dd9d91cf8078111d554d429d9b4673..d34272cdb363da92c7d87abc0dcbcd5ae1c9e958 100644 (file)
@@ -3609,6 +3609,7 @@ void sofia_glue_del_profile(sofia_profile_t *profile)
 int sofia_glue_init_sql(sofia_profile_t *profile)
 {
        char *test_sql = NULL;
+       switch_core_db_t *db = NULL;
 
        char reg_sql[] =
                "CREATE TABLE sip_registrations (\n"
@@ -3780,7 +3781,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                
                test_sql = switch_mprintf("delete from sip_registrations where (contact like '%%TCP%%' "
                                                                  "or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q' "
-                                                                 "and network_ip!='-1' and network_port!='-1' and sip_username != '-1' and mwi_user != '-1' and mwi_host != '-1'", 
+                                                                 "and network_ip like '%%' and network_port like '%%' and sip_username "
+                                                                 "like '%%' and mwi_user  like '%%' and mwi_host like '%%'", 
                                                                  mod_sofia_globals.hostname);
 
                if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
@@ -3790,7 +3792,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                free(test_sql);
 
 
-               test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and network_ip!='-1' and network_port!='-1'", mod_sofia_globals.hostname);
+               test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and network_ip like '%%' and network_port like '%%'", 
+                                                                 mod_sofia_globals.hostname);
 
                if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
                        switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_subscriptions", NULL);
@@ -3813,7 +3816,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                }
 
                free(test_sql);
-               test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' and last_nc >= 0", mod_sofia_globals.hostname);
+               test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' or last_nc >= 0", mod_sofia_globals.hostname);
 
                if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
                        switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_authentication", NULL);
@@ -3821,7 +3824,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                }
                free(test_sql);
 
-               test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str='' or hostname='%q' and network_ip!='-1'",
+               test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str='' or hostname='%q' and network_ip like '%%'",
                                                                  mod_sofia_globals.hostname);
                if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
                        switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_shared_appearance_subscriptions", NULL);
@@ -3830,7 +3833,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                free(test_sql);
 
 
-               test_sql = switch_mprintf("delete from sip_shared_appearance_dialogs where contact_str='' or hostname='%q' and network_ip!='-1'",
+               test_sql = switch_mprintf("delete from sip_shared_appearance_dialogs where contact_str='' or hostname='%q' and network_ip like '%%'",
                                                                  mod_sofia_globals.hostname);
                if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
                        switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_shared_appearance_dialogs", NULL);
@@ -3847,111 +3850,119 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
        } else if (profile->odbc_dsn) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
        } else {
-               if (!(profile->master_db = switch_core_db_open_file(profile->dbname))) {
+               if (!(db = switch_core_db_open_file(profile->dbname))) {
                        return 0;
                }
 
                test_sql = switch_mprintf("delete from sip_registrations where (contact like '%%TCP%%' "
                                                                  "or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q' "
-                                                                 "and network_ip!='-1' and network_port!='-1' and sip_username != '-1' and mwi_user != '-1' and mwi_host != '-1'",
+                                                                 "and network_ip like '%%' and network_port like '%%' and sip_username "
+                                                                 "like '%%' and mwi_user like '%%' and mwi_host like '%%'",
                                                                  mod_sofia_globals.hostname);
                
-               switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_registrations", reg_sql);
+               switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_registrations", reg_sql);
                free(test_sql);
 
-               test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and network_ip!='-1' and network_port!='-1'", mod_sofia_globals.hostname);
-               switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_subscriptions", sub_sql);
+               test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and network_ip like '%%' or network_port like '%%'", 
+                                                                 mod_sofia_globals.hostname);
+               switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_subscriptions", sub_sql);
                free(test_sql);
 
                test_sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and contact like '%%'", mod_sofia_globals.hostname);
-               switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_dialogs", dialog_sql);
+               switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_dialogs", dialog_sql);
                free(test_sql);
 
                test_sql = switch_mprintf("delete from sip_presence where hostname='%q'", mod_sofia_globals.hostname);
-               switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_presence", pres_sql);
+               switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_presence", pres_sql);
                free(test_sql);
 
-               test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' and last_nc >= 0", mod_sofia_globals.hostname);
-               switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_authentication", auth_sql);
+               test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' or last_nc >= 0", mod_sofia_globals.hostname);
+               switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_authentication", auth_sql);
                free(test_sql);
 
                
-               test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str = '' or hostname='%q' and network_ip!='-1'",
+               test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str = '' or hostname='%q' and network_ip like '%%'",
                                                                  mod_sofia_globals.hostname);
-               switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_shared_appearance_subscriptions", shared_appearance_sql);
+               switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_shared_appearance_subscriptions", shared_appearance_sql);
                free(test_sql);
 
                test_sql = switch_mprintf("delete from sip_shared_appearance_dialogs where contact_str = '' or hostname='%q'", mod_sofia_globals.hostname);
-               switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_shared_appearance_dialogs", shared_appearance_dialogs_sql);
+               switch_core_db_test_reactive(db, test_sql, "DROP TABLE sip_shared_appearance_dialogs", shared_appearance_dialogs_sql);
                free(test_sql);
                
-               switch_core_db_exec(profile->master_db, "create index if not exists ssa_hostname on sip_shared_appearance_subscriptions (hostname)", 
+               switch_core_db_exec(db, "create index if not exists ssa_hostname on sip_shared_appearance_subscriptions (hostname)", 
                                                        NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ssa_subscriber on sip_shared_appearance_subscriptions (subscriber)", 
+               switch_core_db_exec(db, "create index if not exists ssa_subscriber on sip_shared_appearance_subscriptions (subscriber)", 
                                                        NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ssa_profile_name on sip_shared_appearance_subscriptions (profile_name)", 
+               switch_core_db_exec(db, "create index if not exists ssa_profile_name on sip_shared_appearance_subscriptions (profile_name)", 
                                                        NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ssa_aor on sip_shared_appearance_subscriptions (aor)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists ssa_aor on sip_shared_appearance_subscriptions (aor)", NULL, NULL, NULL);
                
 
-               switch_core_db_exec(profile->master_db, "create index if not exists ssd_profile_name on sip_shared_appearance_dialogs (profile_name)", 
+               switch_core_db_exec(db, "create index if not exists ssd_profile_name on sip_shared_appearance_dialogs (profile_name)", 
                                                        NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ssd_hostname on sip_shared_appearance_dialogs (hostname)", 
+               switch_core_db_exec(db, "create index if not exists ssd_hostname on sip_shared_appearance_dialogs (hostname)", 
                                                        NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ssd_hostname on sip_shared_appearance_dialogs (network_ip)", 
+               switch_core_db_exec(db, "create index if not exists ssd_hostname on sip_shared_appearance_dialogs (network_ip)", 
                                                        NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ssd_contact_str on sip_shared_appearance_dialogs (contact_str)",  
+               switch_core_db_exec(db, "create index if not exists ssd_contact_str on sip_shared_appearance_dialogs (contact_str)",  
                                                        NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ssd_call_id on sip_shared_appearance_dialogs (call_id)",  
+               switch_core_db_exec(db, "create index if not exists ssd_call_id on sip_shared_appearance_dialogs (call_id)",  
                                                        NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ssd_expires on sip_shared_appearance_dialogs (expires)", 
+               switch_core_db_exec(db, "create index if not exists ssd_expires on sip_shared_appearance_dialogs (expires)", 
                                                        NULL, NULL, NULL);
                
 
 
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_call_id on sip_registrations (call_id)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_sip_user on sip_registrations (sip_user)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_sip_host on sip_registrations (sip_host)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_profile_name on sip_registrations (profile_name)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_presence_hosts on sip_registrations (presence_hosts)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_contact on sip_registrations (contact)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_expires on sip_registrations (expires)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_hostname on sip_registrations (hostname)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_status on sip_registrations (status)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_network_ip on sip_registrations (network_ip)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_network_port on sip_registrations (network_port)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_sip_username on sip_registrations (sip_username)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sr_sip_realm on sip_registrations (sip_realm)", NULL, NULL, NULL);
-
-
-               switch_core_db_exec(profile->master_db, "create index if not exists ss_call_id on sip_subscriptions (call_id)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ss_hostname on sip_subscriptions (hostname)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ss_hostname on sip_subscriptions (network_ip)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ss_sip_user on sip_subscriptions (sip_user)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ss_sip_host on sip_subscriptions (sip_host)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ss_presence_hosts on sip_subscriptions (presence_hosts)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ss_event on sip_subscriptions (event)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ss_proto on sip_subscriptions (proto)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ss_sub_to_user on sip_subscriptions (sub_to_user)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists ss_sub_to_host on sip_subscriptions (sub_to_host)", NULL, NULL, NULL);
-
-               switch_core_db_exec(profile->master_db, "create index if not exists sd_uuid on sip_dialogs (uuid)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sd_hostname on sip_dialogs (hostname)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sd_hostname on sip_dialogs (contact)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sd_hostname on sip_dialogs (presence_id)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sd_hostname on sip_dialogs (presence_data)", NULL, NULL, NULL);
-
-               switch_core_db_exec(profile->master_db, "create index if not exists sp_hostname on sip_presence (hostname)", NULL, NULL, NULL);
-
-               switch_core_db_exec(profile->master_db, "create index if not exists sa_nonce on sip_authentication (nonce)", NULL, NULL, NULL);
-               switch_core_db_exec(profile->master_db, "create index if not exists sa_hostname on sip_authentication (hostname)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_call_id on sip_registrations (call_id)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_sip_user on sip_registrations (sip_user)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_sip_host on sip_registrations (sip_host)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_profile_name on sip_registrations (profile_name)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_presence_hosts on sip_registrations (presence_hosts)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_contact on sip_registrations (contact)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_expires on sip_registrations (expires)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_hostname on sip_registrations (hostname)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_status on sip_registrations (status)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_network_ip on sip_registrations (network_ip)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_network_port on sip_registrations (network_port)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_sip_username on sip_registrations (sip_username)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sr_sip_realm on sip_registrations (sip_realm)", NULL, NULL, NULL);
+
+
+               switch_core_db_exec(db, "create index if not exists ss_call_id on sip_subscriptions (call_id)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists ss_hostname on sip_subscriptions (hostname)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists ss_hostname on sip_subscriptions (network_ip)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists ss_sip_user on sip_subscriptions (sip_user)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists ss_sip_host on sip_subscriptions (sip_host)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists ss_presence_hosts on sip_subscriptions (presence_hosts)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists ss_event on sip_subscriptions (event)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists ss_proto on sip_subscriptions (proto)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists ss_sub_to_user on sip_subscriptions (sub_to_user)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists ss_sub_to_host on sip_subscriptions (sub_to_host)", NULL, NULL, NULL);
+
+               switch_core_db_exec(db, "create index if not exists sd_uuid on sip_dialogs (uuid)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sd_hostname on sip_dialogs (hostname)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sd_hostname on sip_dialogs (contact)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sd_hostname on sip_dialogs (presence_id)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sd_hostname on sip_dialogs (presence_data)", NULL, NULL, NULL);
+
+               switch_core_db_exec(db, "create index if not exists sp_hostname on sip_presence (hostname)", NULL, NULL, NULL);
+
+               switch_core_db_exec(db, "create index if not exists sa_nonce on sip_authentication (nonce)", NULL, NULL, NULL);
+               switch_core_db_exec(db, "create index if not exists sa_hostname on sip_authentication (hostname)", NULL, NULL, NULL);
        }
 
        if (switch_odbc_available() && profile->odbc_dsn) {
                return profile->master_odbc ? 1 : 0;
        }
+       
+       if (db) {
+               switch_core_db_close(db);
+               return 1;
+       } else {
+               return 0;
+       }
 
-       return profile->master_db ? 1 : 0;
 }
 
 void sofia_glue_sql_close(sofia_profile_t *profile)
@@ -3959,8 +3970,25 @@ void sofia_glue_sql_close(sofia_profile_t *profile)
        if (switch_odbc_available() && profile->master_odbc) {
                switch_odbc_handle_destroy(&profile->master_odbc);
        } else {
-               switch_core_db_close(profile->master_db);
-               profile->master_db = NULL;
+               switch_hash_index_t *hi;
+               const void *var;
+               void *val;
+               sofia_cache_db_handle_t *dbh = NULL;
+
+               switch_mutex_lock(profile->ireg_mutex);
+       top:
+        for (hi = switch_hash_first(NULL, profile->db_hash); hi; hi = switch_hash_next(hi)) {
+                       switch_hash_this(hi, &var, NULL, &val);
+            if ((dbh = (sofia_cache_db_handle_t *) val)) {
+                               switch_core_db_close(dbh->db);
+                               dbh->db = NULL;
+                               switch_core_hash_delete(profile->db_hash, (char *)var);
+
+                               goto top;
+                       }
+               }
+               switch_mutex_unlock(profile->ireg_mutex);
+
        }
 }
 
@@ -3988,7 +4016,7 @@ void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t
        }
 
        if (status != SWITCH_STATUS_SUCCESS) {
-               sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+               sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex);
        }
 
        switch_safe_free(d_sql);
@@ -3998,7 +4026,33 @@ void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t
        }
 }
 
-void sofia_glue_actually_execute_sql(sofia_profile_t *profile, switch_bool_t master, char *sql, switch_mutex_t *mutex)
+switch_core_db_t *sofia_glue_get_db_handle(sofia_profile_t *profile)
+{
+       switch_thread_id_t self = switch_thread_self();
+       char thread_str[256] = "";
+       switch_core_db_t *db = NULL;
+       sofia_cache_db_handle_t *dbh = NULL;
+
+       snprintf(thread_str, sizeof(thread_str) - 1, "%lu", (unsigned long)(intptr_t)self);
+
+       switch_mutex_lock(profile->ireg_mutex);
+       if ((dbh = switch_core_hash_find(profile->db_hash, thread_str))) {
+               db = dbh->db;
+       } else {
+               dbh = switch_core_alloc(profile->pool, sizeof(*dbh));
+               dbh->db = switch_core_db_open_file(profile->dbname);
+               dbh->last_used = switch_epoch_time_now(NULL);
+               switch_core_hash_insert(profile->db_hash, thread_str, dbh);
+               db = dbh->db;
+       }
+       switch_mutex_unlock(profile->ireg_mutex);
+
+       return db;
+}
+
+
+
+void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex)
 {
        switch_core_db_t *db;
 
@@ -4022,24 +4076,18 @@ void sofia_glue_actually_execute_sql(sofia_profile_t *profile, switch_bool_t mas
        } else {
                char *errmsg;
 
-               if (master) {
-                       db = profile->master_db;
-               } else {
-                       if (!(db = switch_core_db_open_file(profile->dbname))) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
-                               goto end;
-                       }
+               
+               if (!(db = sofia_glue_get_db_handle(profile))) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
+                       goto end;
                }
 
                switch_core_db_exec(db, sql, NULL, NULL, &errmsg);
+
                if (errmsg) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n%s\n", errmsg, sql);
                        switch_core_db_free(errmsg);
                }
-
-               if (!master) {
-                       switch_core_db_close(db);
-               }
        }
 
   end:
@@ -4049,7 +4097,7 @@ void sofia_glue_actually_execute_sql(sofia_profile_t *profile, switch_bool_t mas
 }
 
 switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
-                                                                                         switch_bool_t master, switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata)
+                                                                                         switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata)
 {
        switch_bool_t ret = SWITCH_FALSE;
        switch_core_db_t *db;
@@ -4066,25 +4114,18 @@ switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
        } else {
 
-               if (master) {
-                       db = profile->master_db;
-               } else {
-                       if (!(db = switch_core_db_open_file(profile->dbname))) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
-                               goto end;
-                       }
+               if (!(db = sofia_glue_get_db_handle(profile))) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
+                       goto end;
                }
 
+
                switch_core_db_exec(db, sql, callback, pdata, &errmsg);
 
                if (errmsg) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg);
                        free(errmsg);
                }
-
-               if (!master && db) {
-                       switch_core_db_close(db);
-               }
        }
 
   end:
index 7502ad2768ff74bd3eec44009998954cf7667db5..31089305955e706a3cd9c99ca77a17467edfd9c9 100644 (file)
@@ -190,7 +190,7 @@ void sofia_presence_cancel(void)
                        }
                        helper.profile = profile;
                        helper.event = NULL;
-                       if (sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper) != SWITCH_TRUE) {
+                       if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper) != SWITCH_TRUE) {
                                continue;
                        }
                }
@@ -202,13 +202,13 @@ void sofia_presence_cancel(void)
 void sofia_presence_establish_presence(sofia_profile_t *profile)
 {
 
-       if (sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex,
+       if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex,
                                                                                "select sip_user,sip_host,'Registered','unknown','' from sip_registrations",
                                                                                sofia_presence_resub_callback, profile) != SWITCH_TRUE) {
                return;
        }
 
-       if (sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex,
+       if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex,
                                                                                "select sub_to_user,sub_to_host,'Online','unknown',proto from sip_subscriptions "
                                                                                "where proto='ext' or proto='user' or proto='conf'", sofia_presence_resub_callback, profile) != SWITCH_TRUE) {
                return;
@@ -337,7 +337,7 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
 
 
        if (sql) {
-               sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_mwi_callback, &h);
+               sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_mwi_callback, &h);
                free(sql);
                sql = NULL;
                
@@ -355,7 +355,7 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
 
        if (sql) {
                switch_assert(sql != NULL);
-               sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_mwi_callback2, &h);
+               sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_mwi_callback2, &h);
                free(sql);
                sql = NULL;
        }
@@ -456,7 +456,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
                        }
                        helper.profile = profile;
                        helper.event = NULL;
-                       sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper);
+                       sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper);
                }
                switch_mutex_unlock(mod_sofia_globals.hash_mutex);
                free(sql);
@@ -534,7 +534,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s DUMP PRESENCE_PROBE_SQL:\n%s\n", profile->name, sql);
                                }
 
-                               sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_resub_callback, profile);
+                               sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_resub_callback, profile);
                                if (mod_sofia_globals.debug_presence > 0) {
                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_PROBE_SQL\n\n", profile->name);
                                }
@@ -573,7 +573,6 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
                        }
                        continue;
                }
-               
 
                if ((sql = switch_mprintf(
                                                         
@@ -615,7 +614,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
                                free(buf);
                        }
 
-                       sofia_glue_execute_sql_callback(profile, SWITCH_FALSE,
+                       sofia_glue_execute_sql_callback(profile,
                                                                                        NULL, sql, sofia_presence_sub_callback, &helper);
 
                        if (mod_sofia_globals.debug_presence > 0) {
@@ -1764,7 +1763,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                                                                  "full_via,expires,user_agent,accept,profile_name,network_ip"
                                                                  " from sip_subscriptions where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", 
                                                                  to_host, to_user, to_host, to_host))) {
-                       sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_presence_sub_reg_callback, profile);
+                       sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_reg_callback, profile);
                        
                        switch_safe_free(sql);
                }
index 0c41a3919260b9ca2d9c277f4e8f95f96b6d5187..4d5c65252ad373f65ac66933cb4b624563d9f3b0 100644 (file)
@@ -521,7 +521,7 @@ void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int
        switch_safe_free(sqlextra);
        
        switch_mutex_lock(profile->ireg_mutex);
-       sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, sofia_reg_del_callback, profile);
+       sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile);
        switch_mutex_unlock(profile->ireg_mutex);
        switch_safe_free(sql);
        
@@ -543,11 +543,6 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
                        return;
                }
-       } else {
-               if (!profile->master_db) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
-                       return;
-               }
        }
 
        switch_mutex_lock(profile->ireg_mutex);
@@ -562,7 +557,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
                                                ",%d from sip_registrations where expires > 0", reboot);
        }
 
-       sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, sofia_reg_del_callback, profile);
+       sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile);
        if (now) {
                switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and expires <= %ld and hostname='%s'", 
                                                (long) now, mod_sofia_globals.hostname);
@@ -570,7 +565,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
                switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
        }
 
-       sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, NULL);
+       sofia_glue_actually_execute_sql(profile, sql, NULL);
 
 
 
@@ -579,12 +574,12 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
                                                "and profile_name='%s' and expires <= %ld", 
                                                mod_sofia_globals.hostname, profile->name, (long) now);
        
-               sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, sofia_sla_dialog_del_callback, profile);
+               sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_sla_dialog_del_callback, profile);
                switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%s' and expires <= %ld", 
                                                mod_sofia_globals.hostname, (long) now);
 
 
-               sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, NULL);
+               sofia_glue_actually_execute_sql(profile, sql, NULL);
        }
 
 
@@ -595,7 +590,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
                switch_snprintf(sql, sizeof(sql), "delete from sip_presence where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
        }
 
-       sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, NULL);
+       sofia_glue_actually_execute_sql(profile, sql, NULL);
 
        if (now) {
                switch_snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and expires <= %ld and hostname='%s'", 
@@ -604,7 +599,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
                switch_snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
        }
 
-       sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, NULL);
+       sofia_glue_actually_execute_sql(profile, sql, NULL);
 
 
 
@@ -615,7 +610,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
                switch_snprintf(sql, sizeof(sql), "select call_id from sip_subscriptions where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
        }
 
-       sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, sofia_sub_del_callback, profile);
+       sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_sub_del_callback, profile);
 
        if (now) {
                switch_snprintf(sql, sizeof(sql), "delete from sip_subscriptions where expires > 0 and expires <= %ld and hostname='%s'", 
@@ -624,7 +619,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
                switch_snprintf(sql, sizeof(sql), "delete from sip_subscriptions where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
        }
 
-       sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, NULL);
+       sofia_glue_actually_execute_sql(profile, sql, NULL);
 
 
        if (now && sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) {
@@ -633,7 +628,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
                                                " from sip_registrations where (status like '%%AUTO-NAT%%' "
                                                "or status like '%%UDP-NAT%%') and hostname='%s'", mod_sofia_globals.hostname);
 
-               sofia_glue_execute_sql_callback(profile, SWITCH_TRUE, NULL, sql, sofia_reg_nat_callback, profile);
+               sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nat_callback, profile);
        }
 
        switch_mutex_unlock(profile->ireg_mutex);
@@ -661,7 +656,7 @@ char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const c
        }
 
 
-       sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_reg_find_callback, &cbt);
+       sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_find_callback, &cbt);
 
 
        if (cbt.matches) {
@@ -686,9 +681,10 @@ void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                 switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : DEFAULT_NONCE_TTL), 
                                                 profile->name, mod_sofia_globals.hostname);
        switch_assert(sql != NULL);
-       sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+       sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex);
        switch_safe_free(sql);
 
+       //auth_str = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=MD5, qop=\"auth\"", realm, uuid_str, stale ? " stale=true," : "");
        auth_str = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=MD5, qop=\"auth\"", realm, uuid_str, stale ? " stale=\"true\"," : "");
 
        if (regtype == REG_REGISTER) {
@@ -741,6 +737,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
        char *path_val = NULL;
        switch_event_t *auth_params = NULL;
        int r = 0;
+       long reg_count = 0;
 
        /* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
        switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL);
@@ -896,7 +893,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
        if (authorization) {
                char *v_contact_str;
                if ((auth_res = sofia_reg_parse_auth(profile, authorization, sip, sip->sip_request->rq_method_name,
-                                                                                        key, keylen, network_ip, v_event, exptime, regtype, to_user, &auth_params)) == AUTH_STALE) {
+                                                                                        key, keylen, network_ip, v_event, exptime, regtype, to_user, &auth_params, &reg_count)) == AUTH_STALE) {
                        stale = 1;
                }
 
@@ -1131,16 +1128,21 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
                        switch_event_fire(&event);
                }
 #else
-               if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
-                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "sip");
-                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
-                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
-                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, reg_host);
-                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, reg_host);
-                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Registered");
-                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe");
-                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
-                       switch_event_fire(&event);
+
+               if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) || 
+                       (reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
+
+                       if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, reg_host);
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, reg_host);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Registered");
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe");
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+                               switch_event_fire(&event);
+                       }
                }
 #endif
 
@@ -1213,28 +1215,15 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
        if (regtype == REG_REGISTER) {
                char exp_param[128] = "";
                char date[80] = "";
-               long nc_long = 0;               
-               
+
                s_event = NULL;
 
                if (exptime) {
                        switch_snprintf(exp_param, sizeof(exp_param), "expires=%ld", exptime);
                        sip_contact_add_param(nua_handle_home(nh), sip->sip_contact, exp_param);
                        
-                       if (auth_params && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)) {
-                               const char *nc = NULL;
-
-                               if ((nc = switch_event_get_header(auth_params, "sip_auth_nc"))) {
-                                       nc_long = strtoul(nc, 0, 16);
-                               } else {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, 
-                                                                         "No nonce count, cannot determine if this was the first register, sending notify implicitly.\n");
-                                       nc_long = 1;
-                               }
-                       }
-                       
                        if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) || 
-                               (nc_long == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
+                               (reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
                                if (switch_event_create(&s_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) {
                                        switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host);
                                        switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name);
@@ -1263,13 +1252,9 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
                if (s_event) {
                        switch_event_fire(&s_event);
                }
-
-               if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
-                       char *full_contact = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_contact);
-                       if (full_contact && switch_stristr("SUBSCRIBE", full_contact)) {
-                               sofia_sla_handle_register(nua, profile, sip, exptime, full_contact);
-                               su_free(nua_handle_home(nh), full_contact);
-                       }
+               
+               if (contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE) && sofia_sla_supported(sip)) {
+                       sofia_sla_handle_register(nua, profile, sip, exptime, contact_str);
                }
 
                switch_goto_int(r, 1, end);
@@ -1594,6 +1579,20 @@ void sofia_reg_handle_sip_r_challenge(int status,
 
 }
 
+typedef struct {
+       char *nonce;
+       switch_size_t nplen;
+       int last_nc;
+} nonce_cb_t;
+
+static int sofia_reg_nonce_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+       nonce_cb_t *cb = (nonce_cb_t *) pArg;
+       switch_copy_string(cb->nonce, argv[0], cb->nplen);
+       cb->last_nc = zstr(argv[1]) ? 0 : atoi(argv[1]);
+       return 0;
+}
+
 auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, 
                                                                sip_authorization_t const *authorization, 
                                                                sip_t const *sip, 
@@ -1606,7 +1605,8 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
                                                                sofia_regtype_t 
                                                                regtype, 
                                                                const char *to_user,
-                                                               switch_event_t **auth_params)
+                                                               switch_event_t **auth_params,
+                                                               long *reg_count)
 {
        int indexnum;
        const char *cur;
@@ -1626,6 +1626,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
        char *domain_name = NULL;
        switch_event_t *params = NULL;
        const char *auth_acl = NULL;
+       long ncl = 0;
 
        username = realm = nonce = uri = qop = cnonce = nc = response = NULL;
 
@@ -1684,20 +1685,35 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
        }
 
        if (zstr(np)) {
+               nonce_cb_t cb = { 0 };
+               long nc_long = 0;
                first = 1;
+               
                if (nc) {
-                       sql = switch_mprintf("select nonce from sip_authentication where nonce='%q' and last_nc < %lu", nonce, strtoul(nc, 0, 16));
+                       nc_long = strtoul(nc, 0, 16);
+                       sql = switch_mprintf("select nonce,last_nc from sip_authentication where nonce='%q' and last_nc < %lu", nonce, nc_long);
                } else {
                        sql = switch_mprintf("select nonce from sip_authentication where nonce='%q'", nonce);
                }
 
+               cb.nonce = np;
+               cb.nplen = nplen;
+               
                switch_assert(sql != NULL);
-               if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) {
-                       free(sql);
+               sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nonce_callback, &cb);
+               free(sql);
+
+               //if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) {
+               if (zstr(np)) {
+                       sql = switch_mprintf("delete from sip_authentication where nonce='%q'", nonce);
+                       sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
                        ret = AUTH_STALE;
                        goto end;
                }
-               free(sql);
+
+               if (reg_count) {
+                       *reg_count = cb.last_nc + 1;
+               }
        }
 
        switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
@@ -2082,6 +2098,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
 
 
        if (nc && cnonce && qop) {
+               ncl = strtoul(nc, 0, 16);
 
 #if defined(_WIN32) && !defined(_WIN64)
 #define        LL_FMT "ll"
@@ -2089,10 +2106,10 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
 #define        LL_FMT "l"
 #endif
                sql = switch_mprintf("update sip_authentication set expires='%"LL_FMT"u',last_nc=%lu where nonce='%s'", 
-                                                        switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : exptime + 10), strtoul(nc, 0, 16), nonce);
+                                                        switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : exptime + 10), ncl, nonce);
 
                switch_assert(sql != NULL);
-               sofia_glue_actually_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
+               sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex);
                switch_safe_free(sql);
        }
 
@@ -2112,6 +2129,18 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
        switch_safe_free(nc);
        switch_safe_free(response);
 
+       if (reg_count && !*reg_count) {
+               if (ret == AUTH_OK) {
+                       if (ncl) {
+                               *reg_count = ncl;
+                       } else {
+                               *reg_count = 1;
+                       }
+               } else {
+                       *reg_count = 0;
+               }
+       }
+
        return ret;
 
 }
index 9ae56e10fc69eda861a3bd3d5ad14a180578ea66..afec5e5a12cb4be1ff016d0a11e450856845d12b 100644 (file)
@@ -49,6 +49,25 @@ static int get_call_id_callback(void *pArg, int argc, char **argv, char **column
        return 0;
 }
 
+int sofia_sla_supported(sip_t const *sip)
+{
+       if (sip && sip->sip_user_agent && sip->sip_user_agent->g_string) {
+               const char *ua = sip->sip_user_agent->g_string;
+
+               if (switch_stristr("polycom", ua)) {
+                       return 1;
+               }
+
+               if (switch_stristr("snom", ua)) {
+                       return 1;
+               }
+
+       }
+
+       return 0;
+}
+
+
 void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip, long exptime, const char *full_contact)
 {
        nua_handle_t *nh = NULL;
@@ -60,12 +79,15 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
        sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
        char network_ip[80];
        int network_port = 0;
+       sofia_destination_t *dst;
+       char *route_uri = NULL;
+       char port_str[25] = "";
 
        sofia_glue_get_addr(nua_current_request(nua), network_ip,  sizeof(network_ip), &network_port);
 
        sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'", 
                                                 mod_sofia_globals.hostname, profile->name, contact_str);
-       sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, get_call_id_callback, &sh);
+       sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, get_call_id_callback, &sh);
 
        free(sql);
        
@@ -85,21 +107,35 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
        nua_handle_bind(nh, &mod_sofia_globals.keep_private);
 
        switch_snprintf(exp_str, sizeof(exp_str), "%ld", exptime + 30);
+
+       switch_snprintf(port_str, sizeof(port_str), ":%ld", sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->sip_port);
+
        if (sofia_glue_check_nat(profile, network_ip)) { 
-               switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s;transport=%s>;expires=%s", profile->sla_contact, 
-                                               profile->extsipip, sofia_glue_transport2str(transport), exp_str);
+               switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s%s;transport=%s>;expires=%s", profile->sla_contact, 
+                                               profile->extsipip, port_str, sofia_glue_transport2str(transport), exp_str);
        } else {
-               switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s;transport=%s>;expires=%s", profile->sla_contact, 
-                                               profile->sipip, sofia_glue_transport2str(transport), exp_str);
+               switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s%s;transport=%s>;expires=%s", profile->sla_contact, 
+                                               profile->sipip, port_str, sofia_glue_transport2str(transport), exp_str);
        }
+
+       dst = sofia_glue_get_destination((char*) full_contact);
+
+       if(dst->route_uri) {
+               route_uri = sofia_glue_strip_uri(dst->route_uri);
+       }
+
        nua_subscribe(nh,
+                                 TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
                                  SIPTAG_TO(sip->sip_to),
                                  SIPTAG_FROM(sip->sip_to),
                                  SIPTAG_CONTACT_STR(my_contact),
                                  SIPTAG_EXPIRES_STR(exp_str),
-                                 SIPTAG_EVENT_STR("dialog;sla"),       /* some phones want ;include-session-description too? */
+                                 SIPTAG_EVENT_STR("dialog;sla;include-session-description"),
+                                 SIPTAG_ACCEPT_STR("application/dialog-info+xml"),
                                  TAG_NULL());
 
+       sofia_glue_free_destination(dst);
+
        free(contact_str);
 }
 
@@ -119,6 +155,7 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
        char network_ip[80];
        int network_port = 0;
        sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
+       char *pl;
 
        sofia_glue_get_addr(nua_current_request(nua), network_ip,  sizeof(network_ip), &network_port);
        /*
@@ -194,6 +231,21 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
                                /*  sofia_presence says something about needing TAG_IF(sticky, NUTAG_PROXY(sticky)) for NAT stuff? */
                                TAG_END());
 
+
+       
+       pl = switch_mprintf("<?xml version=\"1.0\"?>\n"
+                                               "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" "
+                                               "version=\"0\" state=\"full\" entity=\"%s\"></dialog-info>\n", aor);
+       
+       nua_notify(nh,
+                          SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* XXX MTK FIXME - this is totally fake calculation */
+                          TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
+                          SIPTAG_CONTENT_TYPE_STR("application/dialog-info+xml"),      /* could've just kept the type from the payload */
+                          SIPTAG_PAYLOAD_STR(pl),
+                          TAG_END());
+       
+       
+
        switch_safe_free(aor);
        switch_safe_free(subscriber);
        switch_safe_free(route_uri);
@@ -295,7 +347,7 @@ void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_han
                helper.payload = sip->sip_payload->pl_data;     /* could just send the WHOLE payload. you'd get the type that way. */
 
                /* which mutex if any is correct to hold in this callback? XXX MTK FIXME */
-               sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, sofia_sla_sub_callback, &helper);
+               sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sla_sub_callback, &helper);
 
                switch_safe_free(sql);
                switch_safe_free(aor);