From a7ab24ef4c0ff88b2d671af62f35bbaca3eaff9f Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Wed, 18 Sep 2013 16:00:03 -0400 Subject: [PATCH] FS-2731 refactor a bit to make this actually usable and more cross-endpoint compatible --- src/mod/endpoints/mod_sofia/mod_sofia.c | 313 +++++----- src/mod/endpoints/mod_sofia/sofia_presence.c | 626 ++++++++++--------- 2 files changed, 503 insertions(+), 436 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 2bc0476da7..e99fbc4b1b 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1,4 +1,4 @@ -/* +/* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * Copyright (C) 2005-2012, Anthony Minessale II * @@ -22,7 +22,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * + * * Anthony Minessale II * Ken Rice * Paul D. Tinsley @@ -65,8 +65,8 @@ static switch_status_t sofia_kill_channel(switch_core_session_t *session, int si /* BODY OF THE MODULE */ /*************************************************************************************************************************************************************/ -/* - State methods they get called when the state changes to the specific state +/* + State methods they get called when the state changes to the specific state returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. */ @@ -375,7 +375,7 @@ switch_status_t sofia_on_destroy(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SOFIA DESTROY\n", switch_channel_get_name(channel)); if (tech_pvt) { - + if (tech_pvt->respond_phrase) { switch_yield(100000); } @@ -402,7 +402,7 @@ switch_status_t sofia_on_destroy(switch_core_session_t *session) sofia_profile_destroy(tech_pvt->profile); } } - + return SWITCH_STATUS_SUCCESS; } @@ -552,18 +552,18 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) case 401: case 407: { - const char *to_host = switch_channel_get_variable(channel, "sip_challenge_realm"); + const char *to_host = switch_channel_get_variable(channel, "sip_challenge_realm"); if (zstr(to_host)) { - to_host = switch_channel_get_variable(channel, "sip_to_host"); + to_host = switch_channel_get_variable(channel, "sip_to_host"); } - + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Challenging call\n"); - sofia_reg_auth_challenge(tech_pvt->profile, tech_pvt->nh, NULL, REG_INVITE, to_host, 0, 0); + sofia_reg_auth_challenge(tech_pvt->profile, tech_pvt->nh, NULL, REG_INVITE, to_host, 0, 0); *reason = '\0'; } break; - + case 484: { const char *to = switch_channel_get_variable(channel, "sip_to_uri"); @@ -575,13 +575,13 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) if ((p = strstr(to_uri, ":5060"))) { *p = '\0'; } - + tech_pvt->respond_dest = to_uri; - + } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Overlap Dial with %d %s\n", sip_cause, phrase); - + } break; @@ -590,7 +590,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) } } - + if (tech_pvt->respond_dest && !sofia_test_pflag(tech_pvt->profile, PFLAG_MANUAL_REDIRECT)) { added_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX); } @@ -611,12 +611,12 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) nua_respond(tech_pvt->nh, sip_cause, phrase, TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)), - TAG_IF(cid, SIPTAG_HEADER_STR(cid)), - TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), - TAG_IF(!zstr(resp_headers), SIPTAG_HEADER_STR(resp_headers)), - TAG_IF(!zstr(added_headers), SIPTAG_HEADER_STR(added_headers)), + TAG_IF(cid, SIPTAG_HEADER_STR(cid)), + TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), + TAG_IF(!zstr(resp_headers), SIPTAG_HEADER_STR(resp_headers)), + TAG_IF(!zstr(added_headers), SIPTAG_HEADER_STR(added_headers)), TAG_IF(tech_pvt->respond_dest, SIPTAG_CONTACT_STR(tech_pvt->respond_dest)), - TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)), + TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)), TAG_END()); switch_safe_free(resp_headers); @@ -663,7 +663,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) int is_3pcc = 0; char *sticky = NULL; const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full"); - + if (switch_channel_test_flag(channel, CF_CONFERENCE)) { tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s;isfocus", tech_pvt->reply_contact); } @@ -671,7 +671,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) //switch_core_media_set_local_sdp if(sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE)) { // SNARK: complete hack to get final ack sent when a 3pcc invite has been passed from the other leg in bypass_media mode. - // This code handles the pass_indication sent after the 3pcc ack is received by the other leg in the is_3pcc && is_proxy case below. + // This code handles the pass_indication sent after the 3pcc ack is received by the other leg in the is_3pcc && is_proxy case below. // Is there a better place to hang this...? b_sdp = switch_channel_get_variable(channel, SWITCH_B_SDP_VARIABLE); switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE); @@ -818,7 +818,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } - + if (tech_pvt->nh) { if (tech_pvt->mparams.local_sdp_str) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Local SDP %s:\n%s\n", switch_channel_get_name(channel), @@ -853,14 +853,14 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->mparams.early_sdp) { char *a, *b; - + /* start at the s= line to avoid some devices who update the o= between messages */ a = strstr(tech_pvt->mparams.early_sdp, "s="); b = strstr(tech_pvt->mparams.local_sdp_str, "s="); if (!a || !b || strcmp(a, b)) { - /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless + /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless we do so in this case we will abandon the SOA rules and go rogue. */ sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); @@ -873,7 +873,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) tech_pvt->session_refresher = nua_no_refresher; } - + if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, @@ -928,7 +928,7 @@ static switch_status_t sofia_read_video_frame(switch_core_session_t *session, sw #if 0 while (!(tech_pvt->video_read_codec.implementation && switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_VIDEO) && !switch_channel_test_flag(channel, CF_REQ_MEDIA))) { switch_ivr_parse_all_messages(tech_pvt->session); - + if (--sanity && switch_channel_ready(channel)) { switch_yield(10000); } else { @@ -1110,7 +1110,7 @@ static switch_status_t sofia_send_dtmf(switch_core_session_t *session, const swi dtmf_type = tech_pvt->mparams.dtmf_type; /* We only can send INFO when we have no media */ - if (!switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) || + if (!switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) || !switch_channel_media_ready(tech_pvt->channel) || switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE)) { dtmf_type = DTMF_INFO; } @@ -1187,7 +1187,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi break; case SWITCH_MESSAGE_INDICATE_BRIDGE: switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, NULL); - + if (switch_true(switch_channel_get_variable(channel, "sip_auto_simplify"))) { sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY); } @@ -1269,8 +1269,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } - if (((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) || - (var = switch_channel_get_variable(channel, "rtp_secure_media"))) && + if (((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) || + (var = switch_channel_get_variable(channel, "rtp_secure_media"))) && (switch_true(var) || !strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_32) || !strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_80))) { switch_channel_set_flag(tech_pvt->channel, CF_SECURE); } @@ -1306,10 +1306,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (!zstr(msg->string_arg)) { pl = msg->string_arg; } - + nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END()); } - + } break; case SWITCH_MESSAGE_INDICATE_BROADCAST: @@ -1353,9 +1353,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if(zstr(tech_pvt->mparams.local_sdp_str)) { sofia_set_flag(tech_pvt, TFLAG_3PCC_INVITE); } - + sofia_set_flag_locked(tech_pvt, TFLAG_SENT_UPDATE); - + if (!switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { switch_channel_set_flag(channel, CF_REQ_MEDIA); } @@ -1416,7 +1416,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_channel_set_variable(channel, "sip_require_timer", "false"); sofia_glue_do_invite(session); } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Request to send IMAGE on channel with not t38 options.\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Request to send IMAGE on channel with not t38 options.\n", switch_channel_get_name(channel)); } } @@ -1477,9 +1477,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } if (!switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Operation not permitted on an inbound non-answered call leg!\n"); - } else { + } else { nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_SUBSCRIPTION_STATE_STR("active"), SIPTAG_EVENT_STR(event), TAG_END()); } @@ -1546,23 +1546,23 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi "fs_send_unspported_info is deprecated in favor of correctly spelled fs_send_unsupported_info\n"); ok = 1; } - + if (switch_true(switch_channel_get_variable(channel, "fs_send_unsupported_info"))) { ok = 1; } - + if (ok) { char *headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_INFO_HEADER_PREFIX); const char *pl = NULL; - + if (!zstr(msg->string_array_arg[2])) { pl = msg->string_array_arg[2]; } - + nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(headers), SIPTAG_HEADER_STR(headers)), - TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_IF(pl, SIPTAG_PAYLOAD_STR(pl)), TAG_END()); @@ -1623,19 +1623,19 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi { const char *name = msg->string_array_arg[0], *number = msg->string_array_arg[1]; const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full"); - + if (!zstr(name)) { char message[256] = ""; const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent"); switch_event_t *event; - + check_decode(name, tech_pvt->session); if (zstr(number)) { number = tech_pvt->caller_profile->destination_number; } - + switch_ivr_eavesdrop_update_display(session, name, number); if (!sofia_test_flag(tech_pvt, TFLAG_UPDATING_DISPLAY) && switch_channel_test_flag(channel, CF_ANSWERED)) { @@ -1660,7 +1660,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)), TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); } else if (ua && switch_stristr("snom", ua)) { - const char *ver_str = NULL; + const char *ver_str = NULL; int version = 0; ver_str = switch_stristr( "/", ua); @@ -1744,7 +1744,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi tech_pvt->last_sent_callee_id_name = switch_core_session_strdup(tech_pvt->session, name); tech_pvt->last_sent_callee_id_number = switch_core_session_strdup(tech_pvt->session, number); - + if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) { const char *uuid = switch_channel_get_partner_uuid(channel); @@ -1784,7 +1784,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (!zstr(msg->string_arg)) { char message[256] = ""; const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent"); - + if (ua && switch_stristr("snom", ua)) { snprintf(message, sizeof(message), "From:\r\nTo: \"%s\" %s\r\n", msg->string_arg, tech_pvt->caller_profile->destination_number); nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"), @@ -1853,9 +1853,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Redirecting to %s\n", dest); - + tech_pvt->respond_dest = dest; - + if (argc > 1) { tech_pvt->respond_code = 300; tech_pvt->respond_phrase = "Multiple Choices"; @@ -1997,7 +1997,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi /* Regain lock on sofia */ switch_mutex_lock(tech_pvt->sofia_mutex); - + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Done waiting for ACK\n"); sofia_clear_flag(tech_pvt, TFLAG_3PCC); sofia_clear_flag(tech_pvt, TFLAG_3PCC_HAS_ACK); @@ -2102,7 +2102,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } } } else { - if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || + if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_core_media_codec_chosen(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) != SWITCH_STATUS_SUCCESS) { sofia_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION); if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { @@ -2150,11 +2150,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi char *cid = NULL; cid = generate_pai_str(tech_pvt); - + if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->mparams.early_sdp && strcmp(tech_pvt->mparams.early_sdp, tech_pvt->mparams.local_sdp_str)) { - /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless + /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless we do so in this case we will abandon the SOA rules and go rogue. */ sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); @@ -2202,7 +2202,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_UDPTL_MODE: { switch_t38_options_t *t38_options = switch_channel_get_private(channel, "t38_options"); - + if (!t38_options) { nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); } @@ -3082,7 +3082,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t goto done; } - + if (!strcasecmp(argv[1], "recover")) { if (argv[2] && !strcasecmp(argv[2], "flush")) { sofia_glue_profile_recover(profile, SWITCH_TRUE); @@ -3199,16 +3199,16 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t goto done; } - if (!strcasecmp(argv[1], "capture")) { - if (argc > 2) { - int value = switch_true(argv[2]); - nua_set_params(profile->nua, TPTAG_CAPT(value ? mod_sofia_globals.capture_server : NULL), TAG_END()); - stream->write_function(stream, "%s sip capturing on %s", value ? "Enabled" : "Disabled", profile->name); - } else { - stream->write_function(stream, "Usage: sofia profile capture \n"); - } - goto done; - } + if (!strcasecmp(argv[1], "capture")) { + if (argc > 2) { + int value = switch_true(argv[2]); + nua_set_params(profile->nua, TPTAG_CAPT(value ? mod_sofia_globals.capture_server : NULL), TAG_END()); + stream->write_function(stream, "%s sip capturing on %s", value ? "Enabled" : "Disabled", profile->name); + } else { + stream->write_function(stream, "Usage: sofia profile capture \n"); + } + goto done; + } if (!strcasecmp(argv[1], "watchdog")) { if (argc > 2) { @@ -3224,7 +3224,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t if (!strcasecmp(argv[1], "gwlist")) { int up = 1; - + if (argc > 2) { if (!strcasecmp(argv[2], "down")) { up = 0; @@ -3250,13 +3250,13 @@ static int contact_callback(void *pArg, int argc, char **argv, char **columnName { struct cb_helper *cb = (struct cb_helper *) pArg; char *contact; - + cb->row_process++; - + if (!zstr(argv[0]) && (contact = sofia_glue_get_url_from_contact(argv[0], 1))) { if (cb->dedup) { char *tmp = switch_mprintf("%ssofia/%s/sip:%s", argv[2], argv[1], sofia_glue_strip_proto(contact)); - + if (!strstr((char *)cb->stream->data, tmp)) { cb->stream->write_function(cb->stream, "%s,", tmp); } @@ -3463,17 +3463,17 @@ SWITCH_STANDARD_API(sofia_username_of_function) return SWITCH_STATUS_SUCCESS; } -static void select_from_profile(sofia_profile_t *profile, +static void select_from_profile(sofia_profile_t *profile, const char *user, const char *domain, const char *concat, - const char *exclude_contact, + const char *exclude_contact, switch_stream_handle_t *stream, switch_bool_t dedup) { struct cb_helper cb; char *sql; - + cb.row_process = 0; cb.profile = profile; @@ -3552,7 +3552,7 @@ SWITCH_STANDARD_API(sofia_contact_function) if (!zstr(profile_name)) { profile = sofia_glue_find_profile(profile_name); } - + if (!profile && !zstr(domain)) { profile = sofia_glue_find_profile(domain); } @@ -3571,32 +3571,32 @@ SWITCH_STANDARD_API(sofia_contact_function) if (!zstr(profile->domain_name) && !zstr(profile_name) && !strcmp(profile_name, profile->name)) { domain = profile->domain_name; } - + select_from_profile(profile, user, domain, concat, exclude_contact, &mystream, SWITCH_FALSE); sofia_glue_release_profile(profile); - + } else if (!zstr(domain)) { switch_mutex_lock(mod_sofia_globals.hash_mutex); if (mod_sofia_globals.profile_hash) { switch_hash_index_t *hi; const void *var; void *val; - + for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); if ((profile = (sofia_profile_t *) val) && !strcmp((char *)var, profile->name)) { - select_from_profile(profile, user, domain, concat, exclude_contact, &mystream, SWITCH_TRUE); + select_from_profile(profile, user, domain, concat, exclude_contact, &mystream, SWITCH_TRUE); profile = NULL; } } } switch_mutex_unlock(mod_sofia_globals.hash_mutex); - } - + } + reply = (char *) mystream.data; end: - + if (zstr(reply)) { reply = "error/user_not_registered"; } else if (end_of(reply) == ',') { @@ -3606,7 +3606,7 @@ SWITCH_STANDARD_API(sofia_contact_function) stream->write_function(stream, "%s", reply); reply = NULL; - switch_safe_free(mystream.data); + switch_safe_free(mystream.data); switch_safe_free(data); switch_safe_free(dup_domain); @@ -3933,12 +3933,12 @@ SWITCH_STANDARD_API(sofia_function) mod_sofia_globals.debug_presence = 10; stream->write_function(stream, "+OK Debugging presence\n"); } - + if (strstr(argv[2], "sla")) { mod_sofia_globals.debug_sla = 10; stream->write_function(stream, "+OK Debugging sla\n"); } - + if (strstr(argv[2], "none")) { stream->write_function(stream, "+OK Debugging nothing\n"); mod_sofia_globals.debug_presence = 0; @@ -3946,13 +3946,13 @@ SWITCH_STANDARD_API(sofia_function) } } - stream->write_function(stream, "+OK Debugging summary: presence: %s sla: %s\n", + stream->write_function(stream, "+OK Debugging summary: presence: %s sla: %s\n", mod_sofia_globals.debug_presence ? "on" : "off", mod_sofia_globals.debug_sla ? "on" : "off"); - + goto done; } - + if (!strcasecmp(argv[1], "siptrace")) { if (argc > 2) { ston = switch_true(argv[2]); @@ -3966,10 +3966,10 @@ SWITCH_STANDARD_API(sofia_function) } if (!strcasecmp(argv[1], "capture")) { - if (argc > 2) { - cton = switch_true(argv[2]); - } - } + if (argc > 2) { + cton = switch_true(argv[2]); + } + } if (!strcasecmp(argv[1], "watchdog")) { if (argc > 2) { @@ -3993,7 +3993,7 @@ SWITCH_STANDARD_API(sofia_function) } else { stream->write_function(stream, "-ERR Usage: siptrace |capture |watchdog |debug gateway_name = switch_core_session_strdup(nsession, gateway_ptr->name); switch_channel_set_variable(nchannel, "sip_gateway_name", gateway_ptr->name); @@ -4217,7 +4217,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session dest_to = NULL; } } - + if (params) { tech_pvt->invite_contact = switch_core_session_sprintf(nsession, "%s;%s", gateway_ptr->register_contact, params); tech_pvt->dest = switch_core_session_sprintf(nsession, "%s;%s", tech_pvt->dest, params); @@ -4228,10 +4228,10 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session gateway_ptr->ob_calls++; if (!zstr(gateway_ptr->from_domain) && !switch_channel_get_variable(nchannel, "sip_invite_domain")) { - + if (!strcasecmp(gateway_ptr->from_domain, "auto-aleg-full")) { const char *sip_full_from = switch_channel_get_variable(o_channel, "sip_full_from"); - + if (!zstr(sip_full_from)) { switch_channel_set_variable(nchannel, "sip_force_full_from", sip_full_from); } @@ -4309,7 +4309,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session } } else { host++; - + if (!strchr(host, '.') || switch_true(switch_event_get_header(var_event, "sip_gethostbyname"))) { struct sockaddr_in sa; struct hostent *he = gethostbyname(host); @@ -4318,7 +4318,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session if (he) { memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); ip = inet_ntoa(sa.sin_addr); - + tmp = switch_string_replace(dest, host, ip); //host = switch_core_session_strdup(nsession, ip); //dest = switch_core_session_strdup(nsession, tmp); @@ -4339,7 +4339,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session if (switch_stristr("fs_path", tech_pvt->dest)) { char *remote_host = NULL; const char *s; - + if ((s = switch_stristr("fs_path=", tech_pvt->dest))) { s += 8; } @@ -4351,7 +4351,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session if (!zstr(remote_host)) { switch_split_user_domain(remote_host, NULL, &tech_pvt->mparams.remote_ip); } - } + } if (zstr(tech_pvt->mparams.remote_ip)) { switch_split_user_domain(switch_core_session_strdup(nsession, tech_pvt->dest), NULL, &tech_pvt->mparams.remote_ip); @@ -4373,7 +4373,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_channel_set_variable(nchannel, "rtp_secure_media", SWITCH_RTP_CRYPTO_KEY_80); } - if ((hval = switch_event_get_header(var_event, SOFIA_SECURE_MEDIA_VARIABLE)) || + if ((hval = switch_event_get_header(var_event, SOFIA_SECURE_MEDIA_VARIABLE)) || (hval = switch_event_get_header(var_event, "rtp_secure_media"))) { switch_channel_set_variable(nchannel, "rtp_secure_media", hval); @@ -4384,7 +4384,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_channel_set_variable(nchannel, "media_webrtc", "true"); switch_core_session_set_ice(nsession); } - + sofia_glue_attach_private(nsession, profile, tech_pvt, dest); @@ -4518,7 +4518,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session } if (switch_core_session_compare(session, nsession)) { - /* It's another sofia channel! so lets cache what they use as a pt for telephone event so + /* It's another sofia channel! so lets cache what they use as a pt for telephone event so we can keep it the same */ private_object_t *ctech_pvt; @@ -4680,19 +4680,19 @@ static int notify_callback(void *pArg, int argc, char **argv, char **columnNames dst = sofia_glue_get_destination((char *) contact); - + if (dst->route_uri) { route_uri = sofia_glue_strip_uri(dst->route_uri); } nh = nua_handle(profile->nua, NULL, NUTAG_URL(dst->contact), SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id), SIPTAG_CONTACT_STR(profile->url), TAG_END()); - + nua_handle_bind(nh, &mod_sofia_globals.destroy_private); nua_notify(nh, NUTAG_NEWSUB(1), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), SIPTAG_EVENT_STR(es), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_END()); - + switch_safe_free(route_uri); sofia_glue_free_destination(dst); @@ -4809,32 +4809,32 @@ static void general_event_handler(switch_event_t *event) char *route_uri = NULL; dst = sofia_glue_get_destination((char *) to_uri); - + if (dst->route_uri) { route_uri = sofia_glue_strip_uri(dst->route_uri); } - - + + nh = nua_handle(profile->nua, NULL, - NUTAG_URL(to_uri), + NUTAG_URL(to_uri), SIPTAG_FROM_STR(from_uri), SIPTAG_TO_STR(to_uri), SIPTAG_CONTACT_STR(profile->url), TAG_END()); nua_handle_bind(nh, &mod_sofia_globals.destroy_private); - + nua_notify(nh, NUTAG_NEWSUB(1), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), SIPTAG_EVENT_STR(es), TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END()); - + switch_safe_free(route_uri); sofia_glue_free_destination(dst); - + sofia_glue_release_profile(profile); } @@ -4891,7 +4891,7 @@ static void general_event_handler(switch_event_t *event) const char *user = switch_event_get_header(event, "user"); const char *host = switch_event_get_header(event, "host"); const char *call_id = switch_event_get_header(event, "call-id"); - const char *csta_event = switch_event_get_header(event, "csta-event"); + const char *csta_event = switch_event_get_header(event, "Feature-Event"); char *ct = "application/x-as-feature-event+xml"; @@ -4948,8 +4948,19 @@ static void general_event_handler(switch_event_t *event) ct = switch_mprintf("multipart/mixed; boundary=\"%s\"", boundary_string); } else { + char *fwd_type = NULL; + char *header_name = NULL; + + if ((header_name = switch_event_get_header(event, "forward_immediate"))) { + fwd_type = "forwardImmediate"; + } else if ((header_name = switch_event_get_header(event, "forward_busy"))) { + fwd_type = "forwardBusy"; + } else if ((header_name = switch_event_get_header(event, "forward_no_answer"))) { + fwd_type = "forwardNoAns"; + } + // this will need some work to handle the different types of forwarding events - write_csta_xml_chunk(event, stream, csta_event, NULL); + write_csta_xml_chunk(event, stream, csta_event, fwd_type); } } @@ -4998,7 +5009,7 @@ static void general_event_handler(switch_event_t *event) char *contact, *p; switch_console_callback_match_t *list = NULL; switch_console_callback_match_node_t *m; - + if (!(list = sofia_reg_find_reg_url_multi(profile, user, host))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find registered user %s@%s\n", user, host); return; @@ -5150,7 +5161,7 @@ static void general_event_handler(switch_event_t *event) if (!strcmp(cond, "network-external-address-change") && mod_sofia_globals.auto_restart) { const char *old_ip4 = switch_event_get_header_nil(event, "network-external-address-previous-v4"); const char *new_ip4 = switch_event_get_header_nil(event, "network-external-address-change-v4"); - + switch_mutex_lock(mod_sofia_globals.hash_mutex); if (mod_sofia_globals.profile_hash && !zstr(old_ip4) && !zstr(new_ip4)) { for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { @@ -5168,7 +5179,7 @@ static void general_event_handler(switch_event_t *event) } } switch_mutex_unlock(mod_sofia_globals.hash_mutex); - sofia_glue_restart_all_profiles(); + sofia_glue_restart_all_profiles(); } else if (!strcmp(cond, "network-address-change") && mod_sofia_globals.auto_restart) { const char *old_ip4 = switch_event_get_header_nil(event, "network-address-previous-v4"); const char *new_ip4 = switch_event_get_header_nil(event, "network-address-change-v4"); @@ -5248,30 +5259,35 @@ void write_csta_xml_chunk(switch_event_t *event, switch_stream_handle_t stream, stream.write_function(&stream, " %s\n", dndstatus); } } else if(!strcmp(csta_event, "ForwardingEvent")) { - const char *fwdstatus = switch_event_get_header(event, "forwardStatus"); + const char *fwdstatus = NULL; const char *fwdto = NULL; const char *ringcount = NULL; - if (strcmp("forwardImmediate", fwdtype)) { - fwdto = switch_event_get_header(event, "forward_immediate"); - } else if (strcmp("forwardBusy", fwdtype)) { - fwdto = switch_event_get_header(event, "forward_busy"); - } else if (strcmp("fowardNoAns", fwdtype)) { - fwdto = switch_event_get_header(event, "forward_no_answer"); - ringcount = switch_event_get_header(event, "ringCount"); - } + if (fwdtype && !zstr(fwdtype)) { + if (!strcmp("forwardImmediate", fwdtype)) { + fwdto = switch_event_get_header(event, "forward_immediate"); + fwdstatus = switch_event_get_header(event, "forward_immediate_enabled"); + } else if (!strcmp("forwardBusy", fwdtype)) { + fwdto = switch_event_get_header(event, "forward_busy"); + fwdstatus = switch_event_get_header(event, "forward_busy_enabled"); + } else if (!strcmp("forwardNoAns", fwdtype)) { + fwdto = switch_event_get_header(event, "forward_no_answer"); + fwdstatus = switch_event_get_header(event, "forward_no_answer_enabled"); + ringcount = switch_event_get_header(event, "ringCount"); + } - if (fwdtype) { - stream.write_function(&stream, " %s\n", fwdtype); - } - if (fwdstatus) { - stream.write_function(&stream, " %s\n", fwdstatus); - } - if (fwdto) { - stream.write_function(&stream, " %s\n", fwdto); - } - if (ringcount) { - stream.write_function(&stream, " %s\n", ringcount); + if (fwdtype) { + stream.write_function(&stream, " %s\n", fwdtype); + } + if (fwdstatus) { + stream.write_function(&stream, " %s\n", fwdstatus); + } + if (fwdto) { + stream.write_function(&stream, " %s\n", fwdto); + } + if (ringcount) { + stream.write_function(&stream, " %s\n", ringcount); + } } } @@ -5403,7 +5419,7 @@ SWITCH_STANDARD_APP(sofia_sla_function) } switch_channel_answer(channel); - + if ((bargee_session = switch_core_session_locate((char *)data))) { if (bargee_session == session) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "BARGE: %s (cannot barge on myself)\n", (char *) data); @@ -5415,12 +5431,12 @@ SWITCH_STANDARD_APP(sofia_sla_function) switch_channel_set_flag(tech_pvt->channel, CF_SLA_BARGE); switch_ivr_transfer_variable(bargee_session, session, SWITCH_SIGNAL_BOND_VARIABLE); } - + if (switch_core_session_check_interface(session, sofia_endpoint_interface)) { tech_pvt = switch_core_session_get_private(session); switch_channel_set_flag(tech_pvt->channel, CF_SLA_BARGING); } - + switch_channel_set_variable(channel, "sip_barging_uuid", (char *)data); } @@ -5428,7 +5444,7 @@ SWITCH_STANDARD_APP(sofia_sla_function) } switch_channel_execute_on(channel, "execute_on_sip_barge"); - + switch_ivr_eavesdrop_session(session, data, NULL, ED_MUX_READ | ED_MUX_WRITE | ED_COPY_DISPLAY); } @@ -5482,12 +5498,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) /* start one message thread */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting initial message thread.\n"); sofia_msg_thread_start(0); - + if (sofia_init() != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_GENERR; } - + if (config_sofia(SOFIA_CONFIG_LOAD, NULL) != SWITCH_STATUS_SUCCESS) { mod_sofia_globals.running = 0; return SWITCH_STATUS_GENERR; @@ -5573,7 +5589,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) management_interface->relative_oid = "1001"; management_interface->management_function = sofia_manage; - SWITCH_ADD_APP(app_interface, "sofia_sla", "private sofia sla function", + SWITCH_ADD_APP(app_interface, "sofia_sla", "private sofia sla function", "private sofia sla function", sofia_sla_function, "", SAF_NONE); @@ -5597,7 +5613,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) switch_console_set_complete("add sofia profile"); switch_console_set_complete("add sofia profile restart all"); - + switch_console_set_complete("add sofia profile ::sofia::list_profiles start"); switch_console_set_complete("add sofia profile ::sofia::list_profiles stop wait"); switch_console_set_complete("add sofia profile ::sofia::list_profiles rescan"); @@ -5709,4 +5725,3 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) * For VIM: * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: */ - diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 27e9c6d669..f8cd9a6ede 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1,4 +1,4 @@ -/* +/* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * Copyright (C) 2005-2012, Anthony Minessale II * @@ -22,14 +22,14 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * + * * Anthony Minessale II * Ken Rice * Paul D. Tinsley * Bret McDanel * Raymond Chandler * William King - * Emmanuel Schmidbauer + * Emmanuel Schmidbauer * * sofia_presence.c -- SOFIA SIP Endpoint (presence code) * @@ -98,7 +98,7 @@ struct presence_helper { }; switch_status_t sofia_presence_chat_send(switch_event_t *message_event) - + { char *prof = NULL, *user = NULL, *host = NULL; sofia_profile_t *profile = NULL; @@ -119,7 +119,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) char *p = NULL; char *remote_host = NULL; const char *proto; - const char *from; + const char *from; const char *to; //const char *subject; const char *body; @@ -179,14 +179,14 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) if (!prof) { prof = switch_event_get_header(message_event, "sip_profile"); } - + if (!strncasecmp(user, "sip:", 4)) { to_uri = user; } if ((host = strchr(user, '@'))) { if (!to_uri) { - *host++ = '\0'; + *host++ = '\0'; } else { host++; } @@ -228,12 +228,12 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) } } - + if (!strcasecmp(proto, SOFIA_CHAT_PROTO)) { from = from_full; } else { char *fp, *p = NULL; - + fp = strdup(from); switch_assert(fp); @@ -291,7 +291,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); break; } - + /* sofia_glue is running sofia_overcome_sip_uri_weakness we do not, not sure if it matters */ if (dst->route_uri) { @@ -331,7 +331,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) if (dup_dest && (p = strstr(dup_dest, ";fs_"))) { *p = '\0'; } - + /* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */ //printf("DEBUG To: [%s] From: [%s] Contact: [%s] RURI [%s] ip [%s] port [%s]\n", to, from, contact, dst->route_uri, network_ip, network_port); @@ -346,17 +346,17 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) TAG_END()); nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private); - + switch_snprintf(header, sizeof(header), "X-FS-Sending-Message: %s", switch_core_get_uuid()); switch_uuid_str(uuid_str, sizeof(uuid_str)); - + if (is_blocking) { switch_mutex_lock(profile->flag_mutex); switch_core_hash_insert(profile->chat_hash, uuid_str, &mstatus); switch_mutex_unlock(profile->flag_mutex); } - + nua_message(msg_nh, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(route_uri, NUTAG_PROXY(route_uri)), @@ -371,7 +371,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) SIPTAG_HEADER_STR(header), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END()); - + if (is_blocking) { sanity = 200; @@ -379,7 +379,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) while(!mstatus && --sanity && !msg_nh->nh_destroyed) { switch_yield(100000); } - + if (!(mstatus > 199 && mstatus < 300)) { status = SWITCH_STATUS_FALSE; } @@ -394,7 +394,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) sofia_glue_free_destination(dst); switch_safe_free(dup_dest); switch_safe_free(remote_host); - } + } end: @@ -425,23 +425,23 @@ void sofia_presence_cancel(void) if (!mod_sofia_globals.profile_hash) { return; } - + if (list_profiles_full(NULL, NULL, &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { switch_console_callback_match_node_t *m; - + for (m = matches->head; m; m = m->next) { if ((profile = sofia_glue_find_profile(m->val))) { if (profile->pres_type == PRES_TYPE_FULL) { helper.profile = profile; helper.event = NULL; - + sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from," "full_via,expires,user_agent,accept,profile_name,network_ip" ",-1,'unavailable','unavailable' from sip_subscriptions where " "event='presence' and hostname='%q' and profile_name='%q'", mod_sofia_globals.hostname, profile->name); - + r = sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_sub_callback, &helper); switch_safe_free(sql); @@ -453,7 +453,7 @@ void sofia_presence_cancel(void) sofia_glue_release_profile(profile); } } - + switch_console_free_matches(&matches); } @@ -528,16 +528,16 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event) if ((pname = switch_event_get_header(event, "sofia-profile"))) { profile = sofia_glue_find_profile(pname); } - + if (!profile) { if (!host || !(profile = sofia_glue_find_profile(host))) { char *sql; char buf[512] = ""; switch_console_callback_match_t *matches; - sql = switch_mprintf("select profile_name from sip_registrations where hostname='%q' and (sip_host='%s' or mwi_host='%s')", + sql = switch_mprintf("select profile_name from sip_registrations where hostname='%q' and (sip_host='%s' or mwi_host='%s')", mod_sofia_globals.hostname, host, host); - + if (list_profiles_full(NULL, NULL, &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { switch_console_callback_match_node_t *m; @@ -597,7 +597,7 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event) "full_via,expires,user_agent,accept,profile_name,network_ip" ",'%q',full_to,network_ip,network_port from sip_subscriptions " "where hostname='%q' and event='message-summary' " - "and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')", + "and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')", stream.data, mod_sofia_globals.hostname, user, host, host); } else if (sub_call_id) { sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from," @@ -618,11 +618,11 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event) if (for_everyone) { sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',call_id " - "from sip_registrations where hostname='%q' and mwi_user='%q' and mwi_host='%q'", + "from sip_registrations where hostname='%q' and mwi_user='%q' and mwi_host='%q'", stream.data, mod_sofia_globals.hostname, user, host); } else if (call_id) { sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',call_id " - "from sip_registrations where hostname='%q' and call_id='%q'", + "from sip_registrations where hostname='%q' and call_id='%q'", stream.data, mod_sofia_globals.hostname, call_id); } @@ -654,7 +654,7 @@ static int sofia_presence_dialog_callback(void *pArg, int argc, char **argv, cha } if (mod_sofia_globals.debug_presence > 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "CHECK DIALOG state[%s] status[%s] rpid[%s] pres[%s] uuid[%s]\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "CHECK DIALOG state[%s] status[%s] rpid[%s] pres[%s] uuid[%s]\n", argv[0], argv[1], argv[2], argv[3], argv[4]); } @@ -683,7 +683,7 @@ static void do_normal_probe(switch_event_t *event) sofia_profile_t *profile; //DUMP_EVENT(event); - + if (!proto || strcasecmp(proto, SOFIA_CHAT_PROTO) != 0) { return; } @@ -703,10 +703,10 @@ 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,uuid from sip_dialogs " "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", + "((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); - - + + sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_dialog_callback, &dh); h.profile = profile; @@ -736,7 +736,7 @@ static void do_normal_probe(switch_event_t *event) "sip_dialogs.presence_id = sip_registrations.sip_user %q '@' %q sip_registrations.sub_host " "or (sip_dialogs.sip_from_user = sip_registrations.sip_user " "and sip_dialogs.sip_from_host = sip_registrations.sip_host)) " - + "left join sip_presence on " "sip_presence.hostname=sip_registrations.hostname and " "(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_server_host=sip_presence.sip_host and " @@ -748,11 +748,11 @@ static void do_normal_probe(switch_event_t *event) dh.status, dh.rpid, switch_str_nil(sub_call_id), switch_sql_concat(), switch_sql_concat(), mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, probe_euser, probe_host, probe_host); - - + + switch_assert(sql); - + if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s START_PRESENCE_PROBE_SQL\n", profile->name); } @@ -762,19 +762,19 @@ static void do_normal_probe(switch_event_t *event) } sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_resub_callback, &h); - switch_safe_free(sql); + switch_safe_free(sql); if (!h.rowcount) { h.noreg++; - + /* find ones with presence_id defined that are not registred */ sql = switch_mprintf("select sip_from_user, sip_from_host, 'Registered', '', '', " "uuid, state, direction, " "sip_to_user, sip_to_host," "'%q','%q',presence_id, '','','' " - + "from sip_dialogs " - + "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, @@ -790,7 +790,7 @@ static void do_normal_probe(switch_event_t *event) sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_resub_callback, &h); switch_safe_free(sql); - + 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); } @@ -804,13 +804,13 @@ static void do_normal_probe(switch_event_t *event) switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", probe_euser, probe_host); switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "status", "Unregistered"); switch_event_fire(&sevent); - } + } } sofia_glue_release_profile(profile); } - + switch_safe_free(probe_user); } @@ -935,7 +935,7 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event const char *body = switch_event_get_body(event); const char *type = "application/conference-info+xml"; const char *final = switch_event_get_header(event, "final"); - + if (!event_str) { event_str = "conference"; } @@ -962,36 +962,36 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event if (call_id) { if (switch_true(final)) { - sql = switch_mprintf("update sip_subscriptions set expires=%ld where " - "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' " - "and call_id = '%q' ", - (long)0, - mod_sofia_globals.hostname, profile->name, - from_user, from_host, event_str, call_id); + sql = switch_mprintf("update sip_subscriptions set expires=%ld where " + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' " + "and call_id = '%q' ", + (long)0, + mod_sofia_globals.hostname, profile->name, + from_user, from_host, event_str, call_id); - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, " "'%q' as ct,'%q' as pt " " from sip_subscriptions where " "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' " - "and call_id = '%q' ", + "and call_id = '%q' ", switch_sql_concat(), type, switch_str_nil(body), mod_sofia_globals.hostname, profile->name, from_user, from_host, event_str, call_id); } else { - if (switch_true(final)) { - sql = switch_mprintf("update sip_subscriptions set expires=%ld where " - "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'", - (long)0, - mod_sofia_globals.hostname, profile->name, - from_user, from_host, event_str); + if (switch_true(final)) { + sql = switch_mprintf("update sip_subscriptions set expires=%ld where " + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'", + (long)0, + mod_sofia_globals.hostname, profile->name, + from_user, from_host, event_str); - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - } + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, " "'%q' as ct,'%q' as pt " @@ -1014,7 +1014,7 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event "and call_id = '%q' ", mod_sofia_globals.hostname, profile->name, from_user, from_host, event_str, call_id); - + } else { sql = switch_mprintf("delete from sip_subscriptions where " "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'", @@ -1045,7 +1045,7 @@ static void conference_data_event_handler(switch_event_t *event) if ((pname = switch_event_get_header(event, "sofia-profile"))) { profile = sofia_glue_find_profile(pname); } - + if (host && !profile) { profile = sofia_glue_find_profile(host); } @@ -1055,17 +1055,17 @@ static void conference_data_event_handler(switch_event_t *event) sofia_glue_release_profile(profile); } else { switch_console_callback_match_t *matches; - + if (list_profiles_full(NULL, NULL, &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { switch_console_callback_match_node_t *m; - + for (m = matches->head; m; m = m->next) { if ((profile = sofia_glue_find_profile(m->val))) { send_conference_data(profile, event); sofia_glue_release_profile(profile); } } - + switch_console_free_matches(&matches); } } @@ -1091,7 +1091,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event char *call_info_state = switch_event_get_header(event, "presence-call-info-state"); const char *uuid = switch_event_get_header(event, "unique-id"); switch_console_callback_match_t *matches = NULL; - struct presence_helper helper = { 0 }; + struct presence_helper helper = { 0 }; int hup = 0; switch_event_t *s_event = NULL; @@ -1135,25 +1135,25 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event if ((profile = sofia_glue_find_profile(m->val))) { if (profile->pres_type != PRES_TYPE_FULL) { - + if (!mod_sofia_globals.profile_hash) { switch_console_free_matches(&matches); goto done; } - + if (from) { - + sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and " "sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'", mod_sofia_globals.hostname, profile->name, from); - + if (mod_sofia_globals.debug_presence > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql); } - + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - - + + sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host," "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event," "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from," @@ -1173,13 +1173,13 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and " "sip_subscriptions.event='presence'", mod_sofia_globals.hostname, profile->name); - + if (mod_sofia_globals.debug_presence > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql); } - + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - + sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host," "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event," "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from," @@ -1196,9 +1196,9 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event "sip_subscriptions.event='presence'", switch_str_nil(status), switch_str_nil(rpid), mod_sofia_globals.hostname, profile->name); } - + switch_assert(sql != NULL); - + if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s is passive, skipping\n", (char *) profile->name); @@ -1216,7 +1216,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event } switch_console_free_matches(&matches); } - + switch_safe_free(sql); goto done; } @@ -1258,10 +1258,10 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event { char *probe_type = switch_event_get_header(event, "probe-type"); - if (!probe_type || strcasecmp(probe_type, "dialog")) { + if (!probe_type || strcasecmp(probe_type, "dialog")) { /* NORMAL PROBE */ do_normal_probe(event); - } else { + } else { /* DIALOG PROBE */ do_dialog_probe(event); } @@ -1270,7 +1270,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event default: break; - } + } if (!mod_sofia_globals.profile_hash) { goto done; @@ -1299,8 +1299,8 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CHECK CALL_INFO [%s]\n", switch_str_nil(call_info)); } - if (call_info) { - + if (call_info) { + if (uuid) { sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' where " "hostname='%q' and profile_name='%q' and uuid='%q'", @@ -1308,25 +1308,25 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event } else { sql = switch_mprintf("update sip_dialogs set call_info='%q', call_info_state='%q' where hostname='%q' and profile_name='%q' and " "((sip_dialogs.sip_from_user='%q' and sip_dialogs.sip_from_host='%q') or presence_id='%q@%q') and call_info='%q'", - + call_info, call_info_state, mod_sofia_globals.hostname, profile->name, euser, host, euser, host, call_info); - + } - + if (mod_sofia_globals.debug_sla > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STATE SQL %s\n", sql); } 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, "PROCESS PRESENCE EVENT\n"); } - + sync_sla(profile, euser, host, SWITCH_TRUE, SWITCH_TRUE, call_id); } - + if (!strcmp(proto, "dp")) { sql = switch_mprintf("update sip_presence set rpid='%q',status='%q' where hostname='%q' and profile_name='%q' and " "sip_user='%q' and sip_host='%q'", @@ -1336,20 +1336,20 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event } if (zstr(uuid)) { - + sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs " "where call_info_state != 'seized' and hostname='%q' and profile_name='%q' and " - "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc", + "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc", mod_sofia_globals.hostname, profile->name, euser, host, euser, host); } else { sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs " "where uuid != '%q' and call_info_state != 'seized' and hostname='%q' and profile_name='%q' and " - "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc", + "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc", uuid, mod_sofia_globals.hostname, profile->name, euser, host, euser, host); } sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_dialog_callback, &dh); - + if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "CHECK SQL: %s@%s [%s]\nhits: %d\n", euser, host, sql, dh.hits); } @@ -1366,29 +1366,29 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event if (rpid) { rpid = sofia_presence_translate_rpid(rpid, status); } - + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "early"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", status); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", "EARLY"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "early"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "early"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "early"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "early"); } else { status = "CS_EXECUTE"; if (rpid) { rpid = sofia_presence_translate_rpid(rpid, status); } - + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "answered"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", status); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", "ACTIVE"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "confirmed"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "confirmed"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "confirmed"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "confirmed"); } } - + if (zstr(call_id) && (dh.hits && presence_source && (!strcasecmp(presence_source, "register") || switch_stristr("register", status)))) { goto done; @@ -1401,11 +1401,11 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event "and sip_subscriptions.proto='%q' and (event='%q' or event='%q') and sub_to_user='%q' and " "(sub_to_host='%q' or sub_to_host='%q' or sub_to_host='%q' or " "presence_hosts like '%%%q%%') and " - "(sip_subscriptions.profile_name = '%q' or presence_hosts like '%%%q%%')", + "(sip_subscriptions.profile_name = '%q' or presence_hosts like '%%%q%%')", mod_sofia_globals.hostname, profile->name, proto, event_type, alt_event_type, euser, host, profile->sipip, profile->extsipip ? profile->extsipip : "N/A", host, profile->name, host); - + if (mod_sofia_globals.debug_presence > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql); @@ -1414,7 +1414,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - + sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host," "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event," "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from," @@ -1427,23 +1427,23 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event "left join sip_presence on " "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and " "sip_subscriptions.profile_name=sip_presence.profile_name and sip_subscriptions.hostname=sip_presence.hostname) " - + "where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and " "sip_subscriptions.event != 'line-seize' and " "sip_subscriptions.proto='%q' and " "(event='%q' or event='%q') and sub_to_user='%q' " "and (sub_to_host='%q' or sub_to_host='%q' or sub_to_host='%q' or presence_hosts like '%%%q%%') ", - - + + switch_str_nil(status), switch_str_nil(rpid), host, dh.status,dh.rpid,dh.presence_id, mod_sofia_globals.hostname, profile->name, proto, - event_type, alt_event_type, euser, host, profile->sipip, + event_type, alt_event_type, euser, host, profile->sipip, profile->extsipip ? profile->extsipip : "N/A", host); } else { sql = switch_mprintf("update sip_subscriptions set version=version+1 where sip_subscriptions.event != 'line-seize' and " "sip_subscriptions.call_id='%q'", call_id); - + if (mod_sofia_globals.debug_presence > 1) { @@ -1465,23 +1465,23 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event "left join sip_presence on " "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and " "sip_subscriptions.profile_name=sip_presence.profile_name and sip_subscriptions.hostname=sip_presence.hostname) " - + "where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and " "sip_subscriptions.event != 'line-seize' and " "sip_subscriptions.call_id='%q'", - + switch_str_nil(status), switch_str_nil(rpid), host, dh.status,dh.rpid,dh.presence_id, mod_sofia_globals.hostname, profile->name, call_id); } - + helper.hup = hup; helper.calls_up = dh.hits; helper.profile = profile; helper.event = event; SWITCH_STANDARD_STREAM(helper.stream); switch_assert(helper.stream.data); - + if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s START_PRESENCE_SQL (%s)\n", event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name); @@ -1501,14 +1501,14 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_sub_callback, &helper); switch_safe_free(sql); - + if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_SQL (%s)\n", event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name); } #if 0 - if (hup && dh.hits < 1) { + if (hup && dh.hits < 1) { /* so many phones get confused when whe hangup we have to reprobe to get them all to reset to absolute states so the lights stay correct */ if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); @@ -1520,13 +1520,13 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event sofia_event_fire(profile, &s_event); } } -#endif - +#endif + if (!zstr((char *) helper.stream.data)) { char *this_sql = (char *) helper.stream.data; char *next = NULL; char *last = NULL; - + do { if ((next = strchr(this_sql, ';'))) { *next++ = '\0'; @@ -1534,7 +1534,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event *next++ = '\0'; } } - + if (!zstr(this_sql) && (!last || strcmp(last, this_sql))) { sofia_glue_execute_sql(profile, &this_sql, SWITCH_FALSE); last = this_sql; @@ -1544,7 +1544,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event } switch_safe_free(helper.stream.data); helper.stream.data = NULL; - + sofia_glue_release_profile(profile); } } @@ -2017,7 +2017,7 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char * else if (proto && !strcasecmp(proto, "conf")) { local_user = to_user; local_user_param = switch_mprintf(";proto=%s", proto); - if (skip_proto) { + if (skip_proto) { buf_to_free = switch_mprintf("sip:%s@%s", to_user, host); } else { buf_to_free = switch_mprintf("sip:conf+%s@%s", to_user, host); @@ -2082,9 +2082,9 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char * #define send_presence_notify(_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l) \ _send_presence_notify(_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,__FILE__, __SWITCH_FUNC__, __LINE__) -static void _send_presence_notify(sofia_profile_t *profile, - const char *full_to, - const char *full_from, +static void _send_presence_notify(sofia_profile_t *profile, + const char *full_to, + const char *full_from, const char *o_contact, const char *expires, const char *call_id, @@ -2141,10 +2141,10 @@ static void _send_presence_notify(sofia_profile_t *profile, our_contact = our_contact_dup; } - + if (!zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) { char *ptr = NULL; - + if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) { sofia_transport_t transport = sofia_glue_str2transport(ptr); @@ -2168,22 +2168,22 @@ static void _send_presence_notify(sofia_profile_t *profile, } else { contact_str = our_contact; } - - + + if ((to_uri = sofia_glue_get_url_from_contact((char *)full_to, 1))) { char *p; - + if ((p = strstr(to_uri, "sip:"))) { char *q; - + p += 4; if ((q = strchr(p, '@'))) { *q++ = '\0'; - + if ((dcs = switch_string_replace(contact_str, "mod_sofia", p))) { contact_str = dcs; } - + } } @@ -2198,7 +2198,7 @@ static void _send_presence_notify(sofia_profile_t *profile, } else { contact = strdup(o_contact); } - + if (dst->route_uri) { route_uri = sofia_glue_strip_uri(dst->route_uri); } else { @@ -2209,7 +2209,7 @@ static void _send_presence_notify(sofia_profile_t *profile, if (expires) { long ltmp = atol(expires); - + if (ltmp > 0) { exptime = (ltmp - now); } else { @@ -2248,14 +2248,14 @@ static void _send_presence_notify(sofia_profile_t *profile, ); } - + switch_mutex_lock(profile->ireg_mutex); if (!profile->cseq_base) { profile->cseq_base = (now - 1312693200) * 10; } callsequence = ++profile->cseq_base; switch_mutex_unlock(profile->ireg_mutex); - + if (cparams) { send_contact = switch_mprintf("%s;%s", contact_str, cparams); contact_str = send_contact; @@ -2270,25 +2270,25 @@ static void _send_presence_notify(sofia_profile_t *profile, nua_notify(nh, NUTAG_NEWSUB(1), - TAG_IF(route_uri, NUTAG_PROXY(route_uri)), + TAG_IF(route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_IF(user_via, SIPTAG_VIA_STR(user_via)), TAG_IF(path, SIPTAG_RECORD_ROUTE_STR(path)), - + SIPTAG_FROM_STR(full_to), SIPTAG_TO_STR(full_from), - + SIPTAG_CALL_ID_STR(call_id), TAG_IF(*expires_str, SIPTAG_EXPIRES_STR(expires_str)), - SIPTAG_SUBSCRIPTION_STATE_STR(sstr), - SIPTAG_EVENT_STR(event), + SIPTAG_SUBSCRIPTION_STATE_STR(sstr), + SIPTAG_EVENT_STR(event), TAG_IF(!zstr(ct), SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)), TAG_IF(!zstr(call_info), SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!exptime, SIPTAG_EXPIRES_STR("0")), SIPTAG_CSEQ(cseq), TAG_END()); - + switch_safe_free(route_uri); switch_safe_free(dcs); @@ -2320,20 +2320,20 @@ static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv, char *contact = argv[9]; char *remote_ip = argv[10]; char *remote_port = argv[11]; - + switch_stream_handle_t stream = { 0 }; char *to; const char *pl = NULL; const char *ct = "application/dialog-info+xml"; if (mod_sofia_globals.debug_presence > 0) { - int i; + int i; for(i = 0; i < argc; i++) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]); } } - + if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "SEND DIALOG\nTo: \t%s@%s\nFrom: \t%s@%s\nCall-ID: \t%s\n", @@ -2372,9 +2372,9 @@ static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv, } - send_presence_notify(sh->profile, - full_to, - full_from, + send_presence_notify(sh->profile, + full_to, + full_from, contact, expires, call_id, @@ -2460,13 +2460,13 @@ static char *gen_pidf(char *user_agent, char *id, char *url, char *open, char *r " \n" "
\n" " \n" - " \n" - "
\n" - "
\n" + " \n" + " \n" + " \n" "\n", status, id, id, url, open, prpid); } else { char *xml_rpid = NULL; - + *ct = "application/pidf+xml"; if (!strcasecmp(open, "closed")) { @@ -2477,7 +2477,7 @@ static char *gen_pidf(char *user_agent, char *id, char *url, char *open, char *r if (!strncasecmp(status, "Registered", 10)) { status = "Available"; } - + if (!strcasecmp(status, "Available")) { prpid = NULL; } @@ -2497,7 +2497,7 @@ static char *gen_pidf(char *user_agent, char *id, char *url, char *open, char *r status = "Available"; prpid = NULL; } - + if (prpid) { xml_rpid = switch_mprintf(" \r\n" " \n" @@ -2517,9 +2517,9 @@ static char *gen_pidf(char *user_agent, char *id, char *url, char *open, char *r " \n" "%s" " %s\n" - " \n" + " \n" "", id, open, switch_str_nil(xml_rpid), status); - + switch_safe_free(xml_rpid); } @@ -2582,7 +2582,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (mod_sofia_globals.debug_presence > 0) { - int i; + int i; for(i = 0; i < argc; i++) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]); } @@ -2613,7 +2613,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (!zstr(presence_id) && strchr(presence_id, '@')) { char *p; - + free_me = strdup(presence_id); if ((p = strchr(free_me, '@'))) { @@ -2622,7 +2622,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * user = free_me; } - + if (!zstr(orig_proto) && !strcmp(orig_proto, SOFIA_CHAT_PROTO)) { skip_proto = 1; @@ -2668,7 +2668,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (!rpid) { rpid = "unknown"; } - + // if (!strcasecmp(proto, SOFIA_CHAT_PROTO) || skip_proto) { // clean_id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host); //} else { @@ -2736,7 +2736,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * //if (user_agent && switch_stristr("snom", user_agent) && uuid) { // default_dialog = "full" ; //} - + if (call_state && !strcasecmp(call_state, "cs_hangup")) { astate = "hangup"; holding = 0; @@ -2758,7 +2758,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (!strcasecmp(direction, "inbound")) { from_id = switch_str_nil(switch_event_get_header(helper->event, "Caller-Destination-Number")); - + } else { from_id = switch_str_nil(switch_event_get_header(helper->event, "Caller-Caller-ID-Number")); from_name = switch_event_get_header(helper->event, "Caller-Caller-ID-Name"); @@ -2770,7 +2770,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (zstr(from_name)) { from_name = switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Name"); } - + } #if 0 @@ -2784,7 +2784,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (is_dialog) { SWITCH_STANDARD_STREAM(stream); } - + if (is_dialog) { // Usually we report the dialogs FROM the probed user. The exception is when the monitored endpoint is internal, // and its presence_id is set in the dialplan. Reverse the direction if this is not a registered entity. @@ -2815,14 +2815,14 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * "\n" "\n", version, default_dialog, clean_id); - + } if (!zstr(uuid)) { if (!zstr(answer_state)) { astate = answer_state; } - + if (zstr(astate)) { if (is_dialog) { astate = dft_state; @@ -2834,8 +2834,8 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (!strcasecmp(astate, "answered")) { astate = "confirmed"; } - - + + if (is_dialog) { if (!strcasecmp(astate, "ringing")) { @@ -2860,7 +2860,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (!strcasecmp(astate, "hangup")) { astate = "terminated"; } - + stream.write_function(&stream, "\n", uuid, direction); stream.write_function(&stream, "%s\n", astate); } else { @@ -2870,12 +2870,12 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * } - if ((sofia_test_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY) || switch_true(disable_early)) && + if ((sofia_test_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY) || switch_true(disable_early)) && ((!zstr(astate) && (!strcasecmp(astate, "early") || !strcasecmp(astate, "ringing") || (!strcasecmp(astate, "terminated") && !answered))))) { switch_safe_free(stream.data); goto end; } - + if (!strcasecmp(astate, "early") || !strcasecmp(astate, "confirmed")) { clean_to_user = switch_mprintf("%s", sub_to_user ? sub_to_user : to_user); @@ -2886,12 +2886,12 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * stream.write_function(&stream, "\nsip:%s@%s\n", clean_to_user, clean_to_user, host); stream.write_function(&stream, "\n", clean_to_user, host); stream.write_function(&stream, "\n", holding ? "no" : "yes"); - + stream.write_function(&stream, "\n\n"); if (switch_true(switch_event_get_header(helper->event, "Presence-Privacy"))) { stream.write_function(&stream, "\nsip:anonymous@anonymous.invalid\n"); } else { - stream.write_function(&stream, "\nsip:%s@%s\n", + stream.write_function(&stream, "\nsip:%s@%s\n", from_name ? from_name : clean_from_user, clean_from_user, host); } @@ -2938,7 +2938,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * } else if (!strcasecmp(proto, "conf")) { stream.write_function(&stream, "\nsip:%s@%s;proto=conference\n", !zstr(clean_to_user) ? clean_to_user : "unknown", host); - stream.write_function(&stream, "\n", + stream.write_function(&stream, "\n", !zstr(clean_to_user) ? clean_to_user : "unknown", host); stream.write_function(&stream, "\n\n\n"); stream.write_function(&stream, "\nsip:%s@%s\n", uuid, host); @@ -2965,9 +2965,9 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * ct = "application/dialog-info+xml"; } - if (!zstr(astate) && !zstr(uuid) && + if (!zstr(astate) && !zstr(uuid) && helper && helper->stream.data && strcmp(helper->last_uuid, uuid) && strcasecmp(astate, "terminated") && strchr(uuid, '-')) { - helper->stream.write_function(&helper->stream, "update sip_dialogs set state='%s' where hostname='%q' and profile_name='%q' and uuid='%s';", + helper->stream.write_function(&helper->stream, "update sip_dialogs set state='%s' where hostname='%q' and profile_name='%q' and uuid='%s';", astate, mod_sofia_globals.hostname, profile->name, uuid); switch_copy_string(helper->last_uuid, uuid, sizeof(helper->last_uuid)); } @@ -2983,7 +2983,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (switch_false(resub)) { const char *direction = switch_event_get_header(helper->event, "Caller-Direction"); const char *op, *what = "Ring"; - + if (direction && !strcasecmp(direction, "outbound")) { op = switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Number"); } else { @@ -3031,7 +3031,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * //force_event_status = "Available"; term = 1; } - + if (!term && !strcmp(status, "hold")) { rpid = "on-the-phone"; if (!zstr(op)) { @@ -3051,7 +3051,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (!zstr(open_closed)) { open = open_closed; } - + prpid = translate_rpid(rpid); if (!zstr(dialog_status) && !force_status) { @@ -3065,11 +3065,11 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * switch_set_string(status_line, force_event_status); } - + if (!zstr(dialog_rpid)) { prpid = rpid = dialog_rpid; } - + pl = gen_pidf(user_agent, clean_id, profile->url, open, rpid, prpid, status_line, &ct); } @@ -3089,22 +3089,22 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (!zstr(dialog_status)) { status = dialog_status; } - + if (!zstr(dialog_rpid)) { prpid = rpid = dialog_rpid; } - + pl = gen_pidf(user_agent, clean_id, profile->url, open, rpid, prpid, status, &ct); } - if (!is_dialog && helper->event && !switch_stristr("registered", status_line)){ + if (!is_dialog && helper->event && !switch_stristr("registered", status_line)){ const char *uuid = switch_event_get_header_nil(helper->event, "unique-id"); const char *register_source = switch_event_get_header_nil(helper->event, "register-source"); - + if (!zstr(uuid) && strchr(uuid, '-') && !zstr(status_line) && !zstr(rpid) && (zstr(register_source) || strcasecmp(register_source, "register"))) { - char *sql = switch_mprintf("update sip_dialogs set rpid='%q',status='%q' where hostname='%q' and profile_name='%q' and uuid='%q'", + char *sql = switch_mprintf("update sip_dialogs set rpid='%q',status='%q' where hostname='%q' and profile_name='%q' and uuid='%q'", rpid, status_line, mod_sofia_globals.hostname, profile->name, uuid); sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); @@ -3144,13 +3144,13 @@ static int sofia_presence_mwi_callback(void *pArg, int argc, char **argv, char * char *full_to = argv[16]; char *remote_ip = argv[17]; char *remote_port = argv[18]; - + struct mwi_helper *h = (struct mwi_helper *) pArg; sofia_profile_t *ext_profile = NULL, *profile = h->profile; if (mod_sofia_globals.debug_presence > 0) { - int i; + int i; for(i = 0; i < argc; i++) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]); } @@ -3162,9 +3162,9 @@ static int sofia_presence_mwi_callback(void *pArg, int argc, char **argv, char * } } - send_presence_notify(profile, - full_to, - full_from, + send_presence_notify(profile, + full_to, + full_from, contact, expires, call_id, @@ -3241,14 +3241,14 @@ static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char switch_snprintf(key, sizeof(key), "%s%s", user, host); data = switch_core_hash_find(sh->hash, key); - + if (data) { tmp = switch_core_sprintf(sh->pool, "%s,;appearance-index=*;appearance-state=idle", data, host); } else { tmp = switch_core_sprintf(sh->pool, ";appearance-index=*;appearance-state=idle", host); } - + if (!strcasecmp(event, "line-seize")) { char *hack; @@ -3260,13 +3260,13 @@ static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char if (mod_sofia_globals.debug_sla > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DB PRES NOTIFY: [%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n", argv[5], argv[6], argv[7], argv[8], call_id, event, argv[9], argv[10], tmp); - + } - + send_presence_notify(sh->profile, argv[5], argv[6], argv[7], argv[8], call_id, event, argv[9], argv[10], NULL, NULL, tmp); sh->total++; - + return 0; } @@ -3305,7 +3305,7 @@ static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv if (strcasecmp(state, "idle") && uuid && (session = switch_core_session_locate(uuid))) { switch_channel_t *channel = switch_core_session_get_channel(session); - if (switch_channel_test_flag(channel, CF_ORIGINATOR) || switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR) || + if (switch_channel_test_flag(channel, CF_ORIGINATOR) || switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR) || switch_channel_inbound_display(channel) || switch_channel_test_flag(channel, CF_SLA_BARGING)) { callee_name = switch_channel_get_variable(channel, "callee_id_name"); callee_number = switch_channel_get_variable(channel, "callee_id_number"); @@ -3313,7 +3313,7 @@ static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv if (zstr(callee_number)) { callee_number = switch_channel_get_variable(channel, "destination_number"); } - + } else { callee_name = switch_channel_get_variable(channel, "caller_id_name"); callee_number = switch_channel_get_variable(channel, "caller_id_number"); @@ -3350,7 +3350,7 @@ static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv if (zstr(callee_name)) { callee_name = "unknown"; } - + if (data) { tmp = switch_core_sprintf(sh->pool, "%s,;%s;appearance-state=%s;appearance-uri=\"\\\"%s\\\" \"", @@ -3391,20 +3391,20 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t "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->dbh_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); @@ -3415,27 +3415,27 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t 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 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->dbh_mutex, sql, sofia_presence_send_sql, &cb); if (mod_sofia_globals.debug_sla > 1) { @@ -3467,7 +3467,7 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t sql = switch_mprintf("select sip_from_user,sip_from_host,call_info,call_info_state,uuid from sip_dialogs " "where call_info_state is not null and call_info_state != '' and call_info_state != 'idle' and hostname='%q' and profile_name='%q' " "and ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') " - "and profile_name='%q'", + "and profile_name='%q'", mod_sofia_globals.hostname, profile->name, to_user, to_host, to_user, to_host, profile->name); @@ -3483,7 +3483,7 @@ 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' " - "and (event='call-info' or event='line-seize')", + "and (event='call-info' or event='line-seize')", call_id, mod_sofia_globals.hostname, profile->name); } else { @@ -3499,14 +3499,14 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t "from sip_subscriptions " "where hostname='%q' and profile_name='%q' " "and sub_to_user='%q' and sub_to_host='%q' " - "and (event='call-info' or event='line-seize') and (profile_name='%q' or presence_hosts like '%%%q%%')", + "and (event='call-info' or event='line-seize') and (profile_name='%q' or presence_hosts like '%%%q%%')", mod_sofia_globals.hostname, profile->name, to_user, to_host, profile->name, to_host); } 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 hostname='%q' and profile_name='%q' " "and sub_to_user='%q' and sub_to_host='%q' " "and (event='call-info') and " - "(profile_name='%q' or presence_hosts like '%%%q%%')", + "(profile_name='%q' or presence_hosts like '%%%q%%')", mod_sofia_globals.hostname, profile->name, to_user, to_host, profile->name, to_host); } } @@ -3524,7 +3524,7 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t - + return total; @@ -3731,9 +3731,9 @@ void sofia_presence_handle_sip_i_subscribe(int status, orig_proto = proto; proto = alt_proto; } - + if ((sub_state != nua_substate_terminated)) { - sql = switch_mprintf("select count(*) from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q'", + sql = switch_mprintf("select count(*) from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q'", call_id, mod_sofia_globals.hostname, profile->name); sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf)); @@ -3747,13 +3747,13 @@ void sofia_presence_handle_sip_i_subscribe(int status, if ((subbed = atoi(buf)) > 0) { sub_state = nua_substate_active; - } + } } if (sub_state == nua_substate_active) { - + sstr = switch_mprintf("active;expires=%ld", exp_delta); - + sql = switch_mprintf("update sip_subscriptions " "set expires=%ld " "where hostname='%q' and profile_name='%q' and call_id='%q' and profile_name='%q'", @@ -3764,19 +3764,19 @@ void sofia_presence_handle_sip_i_subscribe(int status, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "re-subscribe event %s, sql: %s\n", event, sql); } - + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } else { if (sub_state == nua_substate_terminated) { - sql = switch_mprintf("delete from sip_subscriptions where call_id='%q' and profile_name='%q' and hostname='%q'", + sql = switch_mprintf("delete from sip_subscriptions where call_id='%q' and profile_name='%q' and hostname='%q'", call_id, profile->name, mod_sofia_globals.hostname); - + if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "sub del sql: %s\n", sql); + "sub del sql: %s\n", sql); } - + switch_assert(sql != NULL); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); sstr = switch_mprintf("terminated;reason=noresource"); @@ -3786,12 +3786,12 @@ void sofia_presence_handle_sip_i_subscribe(int status, char accept[256] = ""; sub_state = nua_substate_active; - + while (ap) { switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : ""); ap = ap->ac_next; } - + sql = switch_mprintf("insert into sip_subscriptions " "(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from," "full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip,version,orig_proto, full_to) " @@ -3799,11 +3799,11 @@ void sofia_presence_handle_sip_i_subscribe(int status, proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : "", event, contact_str, call_id, full_from, full_via, (long) switch_epoch_time_now(NULL) + exp_delta, - full_agent, accept, profile->name, mod_sofia_globals.hostname, + full_agent, accept, profile->name, mod_sofia_globals.hostname, np.network_port, np.network_ip, orig_proto, full_to, use_to_tag); switch_assert(sql != NULL); - + if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s SUBSCRIBE %s@%s %s@%s\n%s\n", @@ -3814,9 +3814,9 @@ void sofia_presence_handle_sip_i_subscribe(int status, sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); sstr = switch_mprintf("active;expires=%ld", exp_delta); } - + } - + if ( sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "ua-profile") && contact_host ) { char *uri = NULL; char *ct = "application/url"; @@ -3827,15 +3827,15 @@ void sofia_presence_handle_sip_i_subscribe(int status, } else { uri = switch_mprintf("sip:%s", contact_host); } - - if ( uri ) { + + if ( uri ) { switch_event_t *params = NULL; - /* Grandstream REALLY uses a header called Message Body */ - extra_headers = switch_mprintf("MessageBody: %s\r\n", profile->pnp_prov_url); - + /* Grandstream REALLY uses a header called Message Body */ + extra_headers = switch_mprintf("MessageBody: %s\r\n", profile->pnp_prov_url); + nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sending pnp NOTIFY for %s to provision to %s\n", uri, profile->pnp_prov_url); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sending pnp NOTIFY for %s to provision to %s\n", uri, profile->pnp_prov_url); switch_event_create(¶ms, SWITCH_EVENT_NOTIFY); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile->name); @@ -3846,19 +3846,19 @@ void sofia_presence_handle_sip_i_subscribe(int status, switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "content-type", ct); switch_event_add_body(params, "%s", profile->pnp_prov_url); switch_event_fire(¶ms); - + switch_safe_free(uri); - switch_safe_free(extra_headers); - + switch_safe_free(extra_headers); + goto end; - } + } } - + if (status < 200) { char *sticky = NULL; char *contactstr = profile->url, *cs = NULL; char *p = NULL, *new_contactstr = NULL; - + if (np.is_nat) { char params[128] = ""; @@ -3875,7 +3875,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, contactstr = profile->url; } - + if (switch_stristr("port=tcp", contact->m_url->url_params)) { if (np.is_auto_nat) { cs = profile->tcp_public_contact; @@ -3894,7 +3894,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, contactstr = cs; } - + if (nh && nh->nh_ds && nh->nh_ds->ds_usage) { /* nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta + SUB_OVERLAP, exp_delta + SUB_OVERLAP); */ nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta, exp_delta); @@ -3907,9 +3907,9 @@ void sofia_presence_handle_sip_i_subscribe(int status, new_contactstr = switch_mprintf("", to_user, p); } } - + sip_to_tag(nh->nh_home, sip->sip_to, use_to_tag); - + if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Responding to SUBSCRIBE with 202 Accepted\n"); } @@ -3918,10 +3918,10 @@ void sofia_presence_handle_sip_i_subscribe(int status, TAG_IF(new_contactstr, SIPTAG_CONTACT_STR(new_contactstr)), NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EXPIRES_STR(exp_delta_str), TAG_IF(sticky, NUTAG_PROXY(sticky)), TAG_END()); - + switch_safe_free(new_contactstr); switch_safe_free(sticky); - + if (sub_state == nua_substate_terminated) { if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending NOTIFY with Expires [0] and State [%s]\n", sstr); @@ -3977,7 +3977,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, su_free(nh->nh_home, full_call_info); } - + } else { if (!strcasecmp(event, "line-seize")) { char *full_call_info = NULL; @@ -3997,7 +3997,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 " @@ -4014,7 +4014,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, now = switch_epoch_time_now(NULL); sql = switch_mprintf("insert into sip_dialogs (sip_from_user,sip_from_host,call_info,call_info_state,hostname,expires,rcd,profile_name) " "values ('%q','%q','%q','seized','%q',%"TIME_T_FMT",%ld,'%q')", - to_user, to_host, switch_str_nil(p), mod_sofia_globals.hostname, + to_user, to_host, switch_str_nil(p), mod_sofia_globals.hostname, switch_epoch_time_now(NULL) + exp_delta, (long)now, profile->name); if (mod_sofia_globals.debug_sla > 1) { @@ -4037,6 +4037,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, if (!strcasecmp(event, "as-feature-event")) { switch_event_t *event; char sip_cseq[40] = ""; + switch_snprintf(sip_cseq, sizeof(sip_cseq), "%d", sip->sip_cseq->cs_seq); switch_event_create(&event, SWITCH_EVENT_PHONE_FEATURE_SUBSCRIBE); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user", from_user); @@ -4047,8 +4048,59 @@ void sofia_presence_handle_sip_i_subscribe(int status, switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "cseq", sip_cseq); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "profile_name", profile->name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hostname", mod_sofia_globals.hostname); + if (sip->sip_payload) { - switch_event_add_body(event, "%s", sip->sip_payload->pl_data); + switch_xml_t xml = NULL; + char *pd_dup = NULL; + + pd_dup = strdup(sip->sip_payload->pl_data); + + if ((xml = switch_xml_parse_str(pd_dup, strlen(pd_dup)))) { + switch_xml_t device = NULL; + + if ((device = switch_xml_child(xml, "device"))) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "device", device->txt); + } + + if (!strcmp(xml->name, "SetDoNotDisturb")) { + switch_xml_t action = NULL; + + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Action", "SetDoNotDisturb"); + if ((action = switch_xml_child(xml, "doNotDisturbOn"))) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Enabled", action->txt); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Name", action->name); + } + } + + if (!strcmp(xml->name, "SetForwarding")) { + switch_xml_t cfwd_type, cfwd_enable, cfwd_target; + + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Action", "SetCallForward"); + if ((cfwd_type = switch_xml_child(xml, "forwardingType")) + && (cfwd_enable = switch_xml_child(xml, "activateForward")) + && (cfwd_target = switch_xml_child(xml, "forwardDN"))) { + + if (!strcmp(cfwd_type->txt, "forwardImmediate")) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Enabled", cfwd_enable->txt); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Name", "forward_immediate"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Value", cfwd_target->txt); + } else if (!strcmp(cfwd_type->txt, "forwardBusy")) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Enabled", cfwd_enable->txt); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Name", "forward_busy"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Value", cfwd_target->txt); + } else if (!strcmp(cfwd_type->txt, "forwardNoAns")) { + switch_xml_t rc; + + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Enabled", cfwd_enable->txt); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Name", "forward_no_answer"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Value", cfwd_target->txt); + if ((rc = switch_xml_child(xml, "ringCount"))) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ringCount", rc->txt); + } + } + } + } + } } switch_event_fire(&event); } else if (!strcasecmp(event, "message-summary")) { @@ -4056,13 +4108,13 @@ void sofia_presence_handle_sip_i_subscribe(int status, "full_via,expires,user_agent,accept,profile_name,network_ip" " from sip_subscriptions where hostname='%q' and profile_name='%q' and " "event='message-summary' and sub_to_user='%q' " - "and (sip_host='%q' or presence_hosts like '%%%q%%')", + "and (sip_host='%q' or presence_hosts like '%%%q%%')", to_host, mod_sofia_globals.hostname, profile->name, to_user, to_host, to_host))) { if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "SUBSCRIBE MWI SQL: %s\n", sql); + "SUBSCRIBE MWI SQL: %s\n", sql); } @@ -4122,7 +4174,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str); switch_event_fire(&sevent); - + } } else { @@ -4154,7 +4206,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "status", "Registered"); switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sub-call-id", call_id); switch_event_fire(&sevent); - } + } } } } @@ -4189,7 +4241,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, if (!sofia_private || !sofia_private->is_call) { nua_handle_destroy(nh); } - + } @@ -4273,10 +4325,10 @@ void sofia_presence_handle_sip_r_subscribe(int status, static int sofia_presence_send_sql(void *pArg, int argc, char **argv, char **columnNames) { struct pres_sql_cb *cb = (struct pres_sql_cb *) pArg; - + if (mod_sofia_globals.debug_presence > 0) { - int i; + int i; for(i = 0; i < argc; i++) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]); } @@ -4293,20 +4345,20 @@ uint32_t sofia_presence_contact_count(sofia_profile_t *profile, const char *cont { char buf[32] = ""; char *sql; - - sql = switch_mprintf("select count(*) from sip_subscriptions where hostname='%q' and profile_name='%q' and contact='%q'", + + sql = switch_mprintf("select count(*) from sip_subscriptions where hostname='%q' and profile_name='%q' and contact='%q'", mod_sofia_globals.hostname, profile->name, contact_str); - + sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf)); switch_safe_free(sql); - return atoi(buf); + return atoi(buf); } void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, sofia_dispatch_event_t *de, tagi_t tags[]) { - + sip_from_t const *from; char *from_user = NULL; char *from_host = NULL; @@ -4335,7 +4387,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n from_user = (char *) from->a_url->url_user; from_host = (char *) from->a_url->url_host; } - + exp_delta = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600); if ((profile->force_publish_expires > 0) && (profile->force_publish_expires < (uint32_t)exp_delta)) { exp_delta = profile->force_publish_expires; @@ -4356,7 +4408,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n int network_port = 0; sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port); - + pd_dup = strdup(payload->pl_data); if ((xml = switch_xml_parse_str(pd_dup, strlen(pd_dup)))) { @@ -4411,20 +4463,20 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n if (count) { if ((sql = switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' " - " and profile_name='%q' and hostname='%q'", + " and profile_name='%q' and hostname='%q'", from_user, from_host, profile->name, mod_sofia_globals.hostname))) { sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } - + if (sub_count > 0 && (sql = switch_mprintf("insert into sip_presence (sip_user, sip_host, status, rpid, expires, user_agent," " profile_name, hostname, open_closed, network_ip, network_port) " "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%q','%d')", - from_user, from_host, note_txt, rpid, exp, full_agent, profile->name, + from_user, from_host, note_txt, rpid, exp, full_agent, profile->name, mod_sofia_globals.hostname, open_closed, network_ip, network_port))) { - + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } - + } else if (contact_str) { struct pres_sql_cb cb = {profile, 0}; @@ -4432,12 +4484,12 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n "'application/pidf+xml' as ct,'%q' as pt " " from sip_subscriptions where " "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'" - "and contact = '%q' ", - - switch_str_nil(payload->pl_data), + "and contact = '%q' ", + + switch_str_nil(payload->pl_data), mod_sofia_globals.hostname, profile->name, from_user, from_host, event_type, contact_str); - + sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_send_sql, &cb); switch_safe_free(sql); } @@ -4494,7 +4546,7 @@ void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip) void sofia_presence_handle_sip_i_message(int status, char const *phrase, - nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, + nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sofia_private_t *sofia_private, sip_t const *sip, sofia_dispatch_event_t *de, @@ -4643,7 +4695,7 @@ void sofia_presence_handle_sip_i_message(int status, switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to", to_addr); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "context", profile->context); - + if (sip->sip_content_type && sip->sip_content_type->c_subtype) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", sip->sip_content_type->c_type); } else { @@ -4652,7 +4704,7 @@ void sofia_presence_handle_sip_i_message(int status, switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_full", full_from); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_profile", profile->name); - + if (msg) { switch_event_add_body(event, "%s", msg); } @@ -4662,7 +4714,7 @@ void sofia_presence_handle_sip_i_message(int status, } - if (sofia_test_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS)) { + if (sofia_test_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS)) { if (switch_event_dup(&event_dup, event) == SWITCH_STATUS_SUCCESS) { event_dup->event_id = SWITCH_EVENT_RECV_MESSAGE; event_dup->flags |= EF_UNIQ_HEADERS; @@ -4676,12 +4728,12 @@ void sofia_presence_handle_sip_i_message(int status, switch_core_session_queue_event(session, &event_dup); } } - + } else { abort(); } - + if (sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT) && (tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) { switch_core_session_queue_event(tech_pvt->session, &event); } else { @@ -4734,7 +4786,7 @@ void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip) } -void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now) +void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now) { char *sql; @@ -4749,7 +4801,7 @@ void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now) } sql = switch_mprintf("update sip_subscriptions set version=version+1 where " - "((expires > 0 and expires <= %ld)) and profile_name='%q' and hostname='%q'", + "((expires > 0 and expires <= %ld)) and profile_name='%q' and hostname='%q'", (long) now, profile->name, mod_sofia_globals.hostname); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); @@ -4770,7 +4822,7 @@ void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now) if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "sub del sql: %s\n", sql); + "sub del sql: %s\n", sql); } sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);