]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add some defensive code to allow support for yealink in SCA mode even when its broken
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 2 Mar 2012 22:42:05 +0000 (16:42 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 2 Mar 2012 22:42:05 +0000 (16:42 -0600)
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_sofia/sofia_presence.c

index b84cc00f4acbc3452e206f14efb3e036d8ae59b3..1ebddbc87d0573223c45f19e49ad49f2092c11a2 100644 (file)
@@ -4806,6 +4806,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
                        if (channel && sip->sip_call_info) {
                                char *p;
                                call_info = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_call_info);
+
                                if (switch_stristr("appearance", call_info)) {
                                        switch_channel_set_variable(channel, "presence_call_info_full", call_info);
                                        if ((p = strchr(call_info, ';'))) {
@@ -4842,10 +4843,15 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
                                                if (mod_sofia_globals.debug_sla > 1) {
                                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
                                                }
-
+                                               
                                                sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+
+                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n", 
+                                                                                 sip->sip_from->a_url->url_host, buf);
+                                               switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
+                                               switch_channel_set_variable(channel, "presence_call_info", buf);
                                        }
-                               }
+                               } 
                        }
                }
 
@@ -8021,12 +8027,67 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
 
        if ((call_info = sip_call_info(sip))) {
                call_info_str = sip_header_as_string(nh->nh_home, (void *) call_info);
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WTF %s\n", call_info_str);
+               
+               if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE) && switch_stristr("appearance", call_info_str)) {
+                       char *p;
+
+                       switch_channel_set_variable(channel, "presence_call_info_full", call_info_str);
+                       if ((p = strchr(call_info_str, ';'))) {
+                               p++;
+                               switch_channel_set_variable(channel, "presence_call_info", p);
+                       }
+               }
+               
                if (call_info->ci_params && (msg_params_find(call_info->ci_params, "answer-after=0"))) {
                        switch_channel_set_variable(channel, "sip_auto_answer_detected", "true");
                }
                switch_channel_set_variable(channel, "sip_call_info", call_info_str);
+       } else if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
+               char buf[128] = "";
+               char *sql;
+               char *state = "progressing";
+               
+               if (sip &&
+                       sip->sip_from && sip->sip_from->a_url && sip->sip_from->a_url->url_user && sip->sip_from->a_url->url_host &&
+                       sip->sip_to && sip->sip_to->a_url && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
+                       sql =
+                               switch_mprintf("select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
+                                                          "sub_to_user='%q' and sub_to_host='%q'", mod_sofia_globals.hostname, sip->sip_to->a_url->url_user,
+                                                          sip->sip_from->a_url->url_host);
+                       sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf));
+                       
+                       if (mod_sofia_globals.debug_sla > 1) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "QUERY SQL %s [%s]\n", sql, buf);
+                       }
+                       free(sql);
+                       
+                       if (!zstr(buf)) {
+                               sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' "
+                                                                        "where uuid='%q'", buf, state, switch_core_session_get_uuid(session));
+
+                               if (mod_sofia_globals.debug_sla > 1) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
+                               }
+                               
+                               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+
+
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n", 
+                                                                 sip->sip_from->a_url->url_host, buf);
+
+                               switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
+                               switch_channel_set_variable(channel, "presence_call_info", buf);
+                               call_info_str = switch_core_session_sprintf(session, "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
+                       }
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WTF FAIL IF\n");
+
+
+               }               
        }
 
+
        if (profile->pres_type) {
                const char *presence_id = switch_channel_get_variable(channel, "presence_id");
                if (zstr(presence_id)) {
@@ -8145,7 +8206,8 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
 
                        free(sql);
                }
-       }
+       } 
+
 
        check_decode(displayname, session);
        tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
@@ -8197,7 +8259,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
 
 
                                if (app && data && !strcasecmp(app, "conference")) {
-                                       tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,conference:%s", data);
+                                       tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,conference:%s+flags{dist-dtmf}", data);
                                        tech_pvt->caller_profile->dialplan = "inline";
                                } else {
                                        if (switch_core_session_check_interface(b_session, sofia_endpoint_interface)) {
@@ -8233,7 +8295,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
                                                        if (!one_leg &&
                                                                (!b_tech_pvt || !sofia_test_flag(b_tech_pvt, TFLAG_SIP_HOLD)) &&
                                                                (!c_tech_pvt || !sofia_test_flag(c_tech_pvt, TFLAG_SIP_HOLD))) {
-                                                               char *ext = switch_core_session_sprintf(session, "answer,conference:%s@sla+flags{mintwo}", uuid);
+                                                               char *ext = switch_core_session_sprintf(session, "answer,conference:%s@sla+flags{mintwo|dist-dtmf}", uuid);
 
                                                                switch_channel_set_flag(c_channel, CF_REDIRECT);
                                                                switch_ivr_session_transfer(b_session, ext, "inline", NULL);
@@ -8246,7 +8308,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
 
                                                if (do_conf) {
                                                        tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, 
-                                                                                                                                                                                          "answer,conference:%s@sla+flags{mintwo}", uuid);
+                                                                                                                                                                                          "answer,conference:%s@sla+flags{mintwo|dist-dtmf}", uuid);
                                                } else {
                                                        if (one_leg && c_app) {
                                                                if (c_data) {
index 4b31e760e1a64116d5dd898efb257ff9dc40416e..ad0f25300b3efd7b6ae5ad376bb096cbd7fc7c93 100644 (file)
@@ -2362,7 +2362,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                        
                        switch_channel_set_variable(channel, "presence_id", from);
                }
-               
+
                if (!(tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL,
                                                                                NUTAG_URL(url_str),
                                                                                TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
@@ -2575,7 +2575,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
        } else {
                tech_pvt->session_refresher = nua_no_refresher;
        }
-       
+
        if (sofia_use_soa(tech_pvt)) {
                nua_invite(tech_pvt->nh,
                                   NUTAG_AUTOANSWER(0),
index 7700674243c382a974d4994db71a7e3f776ac37a..1dfa7188cdf9f537e23dc833cfad61a363ca2c8a 100644 (file)
@@ -55,6 +55,13 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t
 static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char **columnNames);
 static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv, char **columnNames);
 
+struct pres_sql_cb {
+       sofia_profile_t *profile;
+       int ttl;
+};
+
+static int sofia_presence_send_sql(void *pArg, int argc, char **argv, char **columnNames);
+
 struct dialog_helper {
        char state[128];
        char status[512];
@@ -627,7 +634,7 @@ static void do_normal_probe(switch_event_t *event)
 
        if (probe_euser && probe_host && (profile = sofia_glue_find_profile(probe_host))) {
                sql = switch_mprintf("select state,status,rpid,presence_id from sip_dialogs "
-                                                        "where hostname='%q' and profile_name='%q' and "
+                                                        "where hostname='%q' and profile_name='%q' and call_info_state != 'seized' and "
                                                         "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc", 
                                                         mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, probe_euser, probe_host);
                
@@ -701,7 +708,7 @@ static void do_normal_probe(switch_event_t *event)
                                                                                 
                                                                 "from sip_dialogs "
                                                                                 
-                                                                "where hostname='%q' and profile_name='%q' and (presence_id='%q@%q' or "
+                                                                "where call_info_state != 'seized' and hostname='%q' and profile_name='%q' and (presence_id='%q@%q' or "
                                                                 "(sip_from_user='%q' and (sip_from_host='%q' or sip_to_host='%q')))",
                                                                 mod_sofia_globals.hostname, profile->name,
                                                                 dh.status, dh.rpid, probe_euser, probe_host,  probe_euser, probe_host, probe_host);
@@ -1938,15 +1945,13 @@ static void _send_presence_notify(sofia_profile_t *profile,
                }
        }
 
-
-       
        if (exptime <= 0) {
                switch_snprintf(sstr, sizeof(sstr), "terminated;reason=noresource");
        } else {
                switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", (unsigned) exptime);
        }
 
-       if (mod_sofia_globals.debug_presence > 1) {
+       if (mod_sofia_globals.debug_presence > 1 || mod_sofia_globals.debug_sla > 1) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SEND PRES NOTIFY:\n"
                                                  "file[%s]\nfunc[%s]\nline[%d]\n"
                                                  "profile[%s]\nvia[%s]\nip[%s]\nport[%s]\nroute[%s]\ncontact[%s]\nto[%s]\nfrom[%s]\nurl[%s]\ncall_id[%s]\nexpires_str[%s]\n"
@@ -2007,7 +2012,6 @@ static void _send_presence_notify(sofia_profile_t *profile,
                           TAG_END());
        
 
-       
        switch_safe_free(route_uri);
        switch_safe_free(dcs);
        switch_safe_free(contact);
@@ -3018,6 +3022,85 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t
        char *sql;
        int total = 0;
 
+
+       if (clear) {
+               struct pres_sql_cb cb = {profile, 0};
+
+
+               if (call_id) {
+
+                       sql = switch_mprintf("update sip_subscriptions set version=version+1,expires=%ld where "
+                                                                "call_id='%q' "
+                                                                "and event='line-seize'", (long) switch_epoch_time_now(NULL),
+                                                                call_id);
+                       
+                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+                       
+                       if (mod_sofia_globals.debug_sla > 1) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
+                       }
+                       switch_safe_free(sql);
+                       
+                       sql = switch_mprintf("select full_to, full_from, contact, -1, call_id, event, network_ip, network_port, "
+                                                                "NULL as ct, NULL as pt "
+                                                                " from sip_subscriptions where call_id='%q' "
+                                                                
+                                                                "and event='line-seize'", call_id);
+                       
+                       sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_send_sql, &cb);
+                       if (mod_sofia_globals.debug_sla > 1) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
+                       }
+                       switch_safe_free(sql);
+               } else {
+
+                       sql = switch_mprintf("update sip_subscriptions set version=version+1,expires=%ld where "
+                                                                "hostname='%q' and profile_name='%q' "
+                                                                "and sub_to_user='%q' and sub_to_host='%q' "
+                                                                
+                                                                "and event='line-seize'", (long) switch_epoch_time_now(NULL),
+                                                                mod_sofia_globals.hostname, profile->name, to_user, to_host
+                                                                );
+                       
+                       if (mod_sofia_globals.debug_sla > 1) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
+                       }
+
+                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+                       
+                       
+                       sql = switch_mprintf("select full_to, full_from, contact, -1, call_id, event, network_ip, network_port, "
+                                                                "NULL as ct, NULL as pt "
+                                                                " from sip_subscriptions where "
+                                                                "hostname='%q' and profile_name='%q' "
+                                                                "and sub_to_user='%q' and sub_to_host='%q' "                                                            
+                                                                "and event='line-seized'",
+                                                                mod_sofia_globals.hostname, profile->name, to_user, to_host
+                                                                );
+                       
+                       sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_send_sql, &cb);
+
+                       if (mod_sofia_globals.debug_sla > 1) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
+                       }
+
+                       switch_safe_free(sql);
+               }
+
+
+               sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and profile_name='%q' and "
+                                                        "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
+                                                        "and call_info_state='seized'", mod_sofia_globals.hostname, profile->name, to_user, to_host, to_user, to_host);
+
+
+               if (mod_sofia_globals.debug_sla > 1) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
+               }
+               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+               switch_safe_free(sql);
+       }
+
+
        switch_core_new_memory_pool(&pool);
        sh = switch_core_alloc(pool, sizeof(*sh));
        sh->pool = pool;
@@ -3041,12 +3124,13 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t
 
                if (unseize) {
                        sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port "
-                                                                "from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q')", 
+                                                                "from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q' "
+                                                                "and (event='call-info' or event='line-seize')", 
                                                                 call_id, mod_sofia_globals.hostname, profile->name);
 
                } else {
                        sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port "
-                                                                "from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q'",
+                                                                "from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q' and event='call-info'",
                                                                 call_id, mod_sofia_globals.hostname, profile->name);
                }
 
@@ -3082,17 +3166,7 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t
 
 
 
-       if (clear) {
-               sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and profile_name='%q' and "
-                                                        "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
-                                                        "and call_info_state='seized'", mod_sofia_globals.hostname, profile->name, to_user, to_host, to_user, to_host);
-
-
-               if (mod_sofia_globals.debug_sla > 1) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
-               }
-               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-       }
+       
 
        return total;
 
@@ -3452,6 +3526,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                                                   SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
                                                   SIPTAG_EVENT_STR("line-seize"), TAG_IF(full_call_info, SIPTAG_CALL_INFO_STR(full_call_info)), TAG_END());
 
+                       
 
 
                                sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and profile_name='%q' and "
@@ -3687,10 +3762,6 @@ void sofia_presence_handle_sip_r_subscribe(int status,
        }
 }
 
-struct pres_sql_cb {
-       sofia_profile_t *profile;
-       int ttl;
-};
 
 static int sofia_presence_send_sql(void *pArg, int argc, char **argv, char **columnNames)
 {