add some defensive code to allow support for yealink in SCA mode even when its broken

This commit is contained in:
Anthony Minessale 2012-03-02 16:42:05 -06:00
parent 8e7f6b71a1
commit 17cb6a22b3
3 changed files with 164 additions and 31 deletions

View 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) {

View 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),

View 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)
{