FS-11557: [mod_sofia] add support for RFC 7989 Session-ID header

(enable with sofia profile param rfc-7989=true)

FS-11557 [mod_sofia, mod_conference, core] Add support for re-INVITE when setting Session-ID in conference after call has been answered.

FS-11557 [mod_conference] Missed a spot where APP_SESSION_ID needed to be set.

FS-11557: set session id for outbound (initial requests)

FS-11557: [mod_sofia] rename vars and functions "session id" -> "session uuid" to reflect the real meaning for rfc7989.

FS-11557: fix bug - colliding chan var names (session_id)

FS-11557: check nil session uuid

FS-11557 : replace CS_NEW with CS_INIT for when originating calls, generate new uuid.

FS-11557: handle inbound (UAS mode, one leg)

FS-11557: generic param handling and filter via new sip profile option "rfc-7989-filter", eg:
<param name="rfc-7989-filter" value="logme, sec-agree, privacy" />

FS-11557: renamed chan vars (reflect meaning only for RFC7989)

FS-11557: fallback to RFC7329 - "old" Session-ID

FS-11557: distinguish between request and replies when we read the header
(to provide compatibility with old RFC7329 - section 11 of RFC7989)
FS-11557: change more vars/consts names

FS-11557: move compat flag on the channel.

FS-11557: add Session-ID header in REFER

FS-11557: needs extra condition on received initial request

FS-11557: handle NOTIFY

FS-11557: support answer() in dialplan - it was sending back a 200 OK with Session-ID invalid, eg: A=NIL;B=X

FS-11557: add Session-ID for NOTIFY (more cases)

FS-11557: handle reply to SIP INFO (add Session-ID header)

FS-11557: handle case of BYE after REFER, when the channel is destroyed already (save the uuid on sofia_private)

FS-11557: handle more SIP reply cases (eg: 202 Accepted , more negative replies)

FS-11557: handle ACK (UAS role)

FS-11557: added "rfc-7989-force-old" profile param - to enforce old rfc7329 for the UAC role. default off.
enabled with "<param name="rfc-7989-force-old" value="true" />".

FS-11557: fallback to rfc7329 fixes.

FS-11557: set flag CF_RFC7329_COMPAT on partner channel where needed

FS-11557: fix crash (mod_conference)
This commit is contained in:
Mike Jerris 2018-12-06 02:58:25 +04:00 committed by Andrey Volk
parent 0c13b704fc
commit a9e634b664
6 changed files with 701 additions and 113 deletions

View File

@ -225,6 +225,10 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE "exec_after_bridge_app"
#define SWITCH_EXEC_AFTER_BRIDGE_ARG_VARIABLE "exec_after_bridge_arg"
#define SWITCH_MAX_FORWARDS_VARIABLE "max_forwards"
#define SWITCH_RFC7989_SESSION_ID_VARIABLE "session_uuid"
#define SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE "remote_session_uuid"
#define SWITCH_RFC7989_APP_SESSION_ID_VARIABLE "app_session_uuid"
#define SWITCH_RFC7989_GENERIC_PARAM_VARIABLE "generic_param_session_uuid"
#define SWITCH_MAX_SESSION_TRANSFERS_VARIABLE "max_session_transfers"
#define SWITCH_DISABLE_APP_LOG_VARIABLE "disable_app_log"
#define SWITCH_SPEECH_KEY "speech"
@ -1159,6 +1163,7 @@ typedef enum {
SWITCH_MESSAGE_RING_EVENT,
SWITCH_MESSAGE_RESAMPLE_EVENT,
SWITCH_MESSAGE_HEARTBEAT_EVENT,
SWITCH_MESSAGE_INDICATE_SESSION_ID,
SWITCH_MESSAGE_INVALID
} switch_core_session_message_types_t;
@ -1607,6 +1612,7 @@ typedef enum {
CF_ARRANGED_BRIDGE,
CF_STATE_REPEAT,
CF_WANT_DTLSv1_2,
CF_RFC7329_COMPAT,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
CF_FLAG_MAX

View File

@ -1911,8 +1911,8 @@ SWITCH_STANDARD_APP(conference_function)
switch_channel_set_flag(channel, CF_CONFERENCE);
if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Channel answer failed.\n");
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Channel pre answer failed.\n");
goto end;
}
@ -2060,6 +2060,7 @@ SWITCH_STANDARD_APP(conference_function)
locked = 0;
switch_channel_set_variable(channel, "conference_name", conference->name);
switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, conference->uuid_str);
/* Set the minimum number of members (once you go above it you cannot go below it) */
conference->min = 2;
@ -2144,6 +2145,7 @@ SWITCH_STANDARD_APP(conference_function)
}
switch_channel_set_variable(channel, "conference_name", conference->name);
switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, conference->uuid_str);
/* Set MOH from variable if not set */
if (zstr(conference->moh_sound)) {
@ -2210,6 +2212,7 @@ SWITCH_STANDARD_APP(conference_function)
switch_channel_api_on(channel, "api_on_conference_create");
} else { /* setup user variable */
switch_channel_set_variable(channel, "conference_name", conference->name);
switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, conference->uuid_str);
rl++;
}
@ -2223,6 +2226,12 @@ SWITCH_STANDARD_APP(conference_function)
mdpin = conference->mpin;
}
/* Tell the channel we have a new Session-ID */
msg.from = __FILE__;
msg.message_id = SWITCH_MESSAGE_INDICATE_SESSION_ID;
switch_core_session_receive_message(session, &msg);
switch_channel_answer(channel);
/* if this is not an outbound call, deal with conference pins */
if (enforce_security && (!zstr(dpin) || !zstr(mdpin))) {
@ -2233,9 +2242,6 @@ SWITCH_STANDARD_APP(conference_function)
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *supplied_pin_value;
/* Answer the channel */
switch_channel_answer(channel);
/* look for PIN in channel variable first. If not present or invalid revert to prompting user */
supplied_pin_value = switch_core_strdup(conference->pool, switch_channel_get_variable(channel, "supplied_pin"));
if (!zstr(supplied_pin_value)) {

View File

@ -484,6 +484,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
const char *val = NULL;
const char *max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE);
const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
val = switch_channel_get_variable(tech_pvt->channel, "disable_q850_reason");
@ -518,7 +519,9 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)),
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_END());
TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
} else {
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
@ -532,7 +535,9 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
nua_cancel(tech_pvt->nh,
SIPTAG_CONTACT(SIP_NONE),
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)), TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_END());
TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)), TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
} else {
char *resp_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX);
@ -618,6 +623,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
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(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
switch_safe_free(resp_headers);
@ -667,9 +673,10 @@ static switch_status_t sofia_on_soft_execute(switch_core_session_t *session)
static switch_status_t sofia_acknowledge_call(switch_core_session_t *session)
{
struct private_object *tech_pvt = switch_core_session_get_private(session);
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
if (!tech_pvt->sent_100) {
nua_respond(tech_pvt->nh, SIP_100_TRYING, TAG_END());
nua_respond(tech_pvt->nh, SIP_100_TRYING, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
tech_pvt->sent_100 = 1;
return SWITCH_STATUS_SUCCESS;
}
@ -690,6 +697,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");
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
if(sofia_acknowledge_call(session) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Dialplan did not acknowledge_call; sent 100 Trying");
@ -726,6 +734,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
SOATAG_RTP_SELECT(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_ack(tech_pvt->nh,
@ -734,6 +743,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_END());
}
@ -811,6 +821,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
SOATAG_RTP_SELECT(1),
SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
} else {
@ -821,6 +832,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
}
@ -950,13 +962,13 @@ 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,
NUTAG_AUTOANSWER(0),
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher),
@ -977,6 +989,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher),
@ -1399,10 +1412,12 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
char *xdest;
if (msg->string_arg) {
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),
SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
SIPTAG_PAYLOAD_STR(msg->string_arg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
SIPTAG_EVENT_STR("refer"), TAG_END());
goto end;
}
@ -1412,6 +1427,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (event && uuid) {
char payload_str[255] = "SIP/2.0 403 Forbidden\r\n";
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
if (msg->numeric_arg) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"%s Completing blind transfer with success\n", switch_channel_get_name(channel));
@ -1437,6 +1453,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
NUTAG_SUBSTATE(nua_substate_terminated),
SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
SIPTAG_PAYLOAD_STR(payload_str),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
SIPTAG_EVENT_STR(event), TAG_END());
@ -1508,6 +1525,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
char ref_to[1024] = "";
const char *var;
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
if (!strcasecmp(msg->string_arg, "sip:")) {
const char *format = strchr(tech_pvt->profile->sipip, ':') ? "sip:%s@[%s]" : "sip:%s@%s";
@ -1519,6 +1537,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
nua_refer(tech_pvt->nh, SIPTAG_REFER_TO_STR(ref_to), SIPTAG_REFERRED_BY_STR(tech_pvt->contact_url),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
if (msg->string_array_arg[0]) {
@ -1570,18 +1589,23 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, SIP_200_OK,
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
switch_channel_mark_answered(channel);
}
@ -1629,9 +1653,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
case SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION:
{
switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options");
const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
if (!t38_options) {
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto end_lock;
}
@ -1650,7 +1675,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
SOATAG_REUSE_REJECTED(1),
SOATAG_ORDERED_USER(1),
SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_AUTOANSWER(0),
@ -1658,7 +1685,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
switch_safe_free(extra_headers);
sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
@ -1688,6 +1718,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
case SWITCH_MESSAGE_INDICATE_3P_NOMEDIA:
{
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
switch_channel_clear_flag(tech_pvt->channel, CF_MEDIA_ACK);
switch_channel_set_flag(tech_pvt->channel, CF_REQ_MEDIA);
@ -1698,7 +1729,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
NUTAG_MEDIA_ENABLE(0),
TAG_IF(msg->string_arg, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
SIPTAG_PAYLOAD_STR(msg->string_arg),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
switch_safe_free(extra_headers);
}
@ -1706,6 +1739,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
case SWITCH_MESSAGE_INDICATE_3P_MEDIA:
{
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
@ -1716,7 +1750,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
sofia_glue_clear_soa(session, SWITCH_TRUE);
nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), SIPTAG_PAYLOAD_STR(""),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
switch_safe_free(extra_headers);
}
@ -1785,10 +1821,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"Operation not permitted on an inbound non-answered call leg!\n");
} else {
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
full_to = switch_str_nil(switch_channel_get_variable(channel, "sip_full_to"));
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active),
TAG_IF((full_to), SIPTAG_TO_STR(full_to)),SIPTAG_SUBSCRIPTION_STATE_STR("active"),
SIPTAG_EVENT_STR(event), TAG_END());
SIPTAG_EVENT_STR(event),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
@ -1797,6 +1836,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
{
char ct[256] = "text/plain";
int ok = 0;
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
if (!zstr(msg->string_array_arg[3]) && !strcmp(msg->string_array_arg[3], tech_pvt->caller_profile->uuid)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Not sending message back to sender\n");
@ -1823,10 +1863,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
nua_message(tech_pvt->nh,
SIPTAG_CONTENT_TYPE_STR(ct),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(pl, SIPTAG_PAYLOAD_STR(pl)),
TAG_END());
SIPTAG_CONTENT_TYPE_STR(ct),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(pl, SIPTAG_PAYLOAD_STR(pl)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"%s send_message is not supported.\n", switch_channel_get_name(channel));
@ -1837,6 +1878,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
{
char ct[256] = "freeswitch/data";
int ok = 0;
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
if (switch_stristr("send_info", tech_pvt->x_freeswitch_support_remote)) {
ok = 1;
@ -1863,6 +1905,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
TAG_IF(!zstr(headers), SIPTAG_HEADER_STR(headers)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(pl, SIPTAG_PAYLOAD_STR(pl)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
switch_safe_free(headers);
@ -1905,6 +1948,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (to_user && to_host && from_user && from_host && call_id && to_tag && from_tag) {
char in[512] = "", out[1536] = "";
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
switch_snprintf(in, sizeof(in), "%s;to-tag=%s;from-tag=%s", call_id, to_tag, from_tag);
switch_url_encode(in, out, sizeof(out));
@ -1912,7 +1956,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
ref_to = switch_mprintf("<sip:%s@%s?Replaces=%s>", to_user, to_host, out);
ref_by = switch_mprintf("<sip:%s@%s>", from_user, from_host);
nua_refer(tech_pvt->nh, SIPTAG_REFER_TO_STR(ref_to), SIPTAG_REFERRED_BY_STR(ref_by), TAG_END());
nua_refer(tech_pvt->nh, SIPTAG_REFER_TO_STR(ref_to), SIPTAG_REFERRED_BY_STR(ref_by),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
switch_safe_free(ref_to);
switch_safe_free(ref_by);
}
@ -1937,6 +1983,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
const char *allow = switch_channel_get_variable(tech_pvt->channel, "sip_allow");
switch_event_t *event;
int update_allowed = 0;
const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
check_decode(name, tech_pvt->session);
@ -1970,7 +2017,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/update_display"),
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());
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else if (ua && switch_stristr("snom", ua)) {
const char *ver_str = NULL;
int version = 0;
@ -2025,7 +2074,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
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());
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
tech_pvt->last_sent_callee_id_name = switch_core_session_strdup(tech_pvt->session, name);
@ -2070,11 +2121,15 @@ 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");
const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
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"),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_PAYLOAD_STR(message), TAG_END());
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
SIPTAG_PAYLOAD_STR(message),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else if (ua && switch_stristr("polycom", ua)) {
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", msg->string_arg, tech_pvt->caller_profile->destination_number);
nua_update(tech_pvt->nh,
@ -2083,7 +2138,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
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());
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
}
@ -2183,6 +2240,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
break;
case SWITCH_MESSAGE_INDICATE_RESPOND:
{
const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
if (switch_channel_test_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE)) {
switch_channel_clear_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE);
@ -2195,12 +2253,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
@ -2245,8 +2308,12 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (tech_pvt->proxy_refer_uuid) {
if (tech_pvt->proxy_refer_msg) {
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_EXPIRES_STR("60"), NUTAG_WITH_THIS_MSG(tech_pvt->proxy_refer_msg), TAG_END());
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_EXPIRES_STR("60"),
NUTAG_WITH_THIS_MSG(tech_pvt->proxy_refer_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
msg_ref_destroy(tech_pvt->proxy_refer_msg);
tech_pvt->proxy_refer_msg = NULL;
}
@ -2296,13 +2363,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
if (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC)) {
@ -2336,8 +2407,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot respond.\n");
}
} else {
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
@ -2353,13 +2427,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
char *extra_header = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
char *cid = generate_pai_str(tech_pvt);
const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
nua_respond(tech_pvt->nh, SIP_180_RINGING,
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(!zstr(extra_header), SIPTAG_HEADER_STR(extra_header)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
break;
case SWITCH_MESSAGE_INDICATE_ACKNOWLEDGE_CALL:
@ -2378,6 +2456,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
char *extra_header = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
char *cid = generate_pai_str(tech_pvt);
const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
/* Set sip_to_tag to local tag for inbound channels. */
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
@ -2398,7 +2477,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(!zstr(extra_header), SIPTAG_HEADER_STR(extra_header)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
break;
case SWITCH_RING_READY_RINGING:
@ -2410,7 +2491,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(!zstr(extra_header), SIPTAG_HEADER_STR(extra_header)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
break;
}
@ -2528,6 +2611,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
char *extra_header = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
char *cid = NULL;
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
cid = generate_pai_str(tech_pvt);
@ -2556,7 +2640,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(!zstr(extra_header), SIPTAG_HEADER_STR(extra_header)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh,
send_sip_code, p_send_sip_msg,
@ -2570,7 +2656,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(!zstr(extra_header), SIPTAG_HEADER_STR(extra_header)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
switch_safe_free(extra_header);
}
@ -2583,7 +2671,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
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());
const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
}
}
break;
case SWITCH_MESSAGE_INDICATE_SESSION_ID:
{
if (sofia_test_pflag(tech_pvt->profile, PFLAG_RFC7989_SESSION_ID) && switch_channel_test_flag(channel, CF_ANSWERED)) {
sofia_glue_do_invite(session);
}
}
break;
@ -5198,7 +5296,8 @@ static int notify_csta_callback(void *pArg, int argc, char **argv, char **column
nua_notify(nh, NUTAG_NEWSUB(1),
TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
SIPTAG_EVENT_STR("as-feature-event"), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), SIPTAG_CSEQ(cseq), TAG_END());
SIPTAG_EVENT_STR("as-feature-event"), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), SIPTAG_CSEQ(cseq),
TAG_END());
@ -5346,7 +5445,8 @@ void general_event_handler(switch_event_t *event)
NUTAG_NEWSUB(1), TAG_IF(sip_sub_st, SIPTAG_SUBSCRIPTION_STATE_STR(sip_sub_st)),
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
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());
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_END());
switch_safe_free(route_uri);
sofia_glue_free_destination(dst);
@ -5399,7 +5499,8 @@ void general_event_handler(switch_event_t *event)
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());
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_END());
switch_safe_free(route_uri);
@ -5417,9 +5518,12 @@ void general_event_handler(switch_event_t *event)
if ((session = switch_core_session_locate(uuid))) {
if ((tech_pvt = switch_core_session_get_private(session))) {
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
nua_notify(tech_pvt->nh,
NUTAG_NEWSUB(1), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
SIPTAG_EVENT_STR(es), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_END());
SIPTAG_EVENT_STR(es), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
switch_core_session_rwunlock(session);
}
@ -5614,9 +5718,13 @@ void general_event_handler(switch_event_t *event)
if ((session = switch_core_session_locate(uuid))) {
if ((tech_pvt = switch_core_session_get_private(session))) {
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
nua_message(tech_pvt->nh,
SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body),
TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_IF(!zstr(subject), SIPTAG_SUBJECT_STR(subject)), TAG_END());
TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_IF(!zstr(subject), SIPTAG_SUBJECT_STR(subject)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
switch_core_session_rwunlock(session);
}

View File

@ -192,6 +192,7 @@ struct sofia_private {
int is_call;
int is_static;
switch_time_t ping_sent;
char *rfc7989_uuid;
};
#define set_param(ptr,val) if (ptr) {free(ptr) ; ptr = NULL;} if (val) {ptr = strdup(val);}
@ -310,6 +311,8 @@ typedef enum {
PFLAG_FIRE_BYE_RESPONSE_EVENTS,
PFLAG_AUTO_INVITE_100,
PFLAG_UPDATE_REFRESHER,
PFLAG_RFC7989_SESSION_ID,
PFLAG_RFC7989_FORCE_OLD,
PFLAG_AUTH_REQUIRE_USER,
PFLAG_AUTH_CALLS_ACL_ONLY,
PFLAG_USE_PORT_FOR_ACL_CHECK,
@ -790,6 +793,7 @@ struct sofia_profile {
int bind_attempt_interval;
char *proxy_notify_events;
char *proxy_info_content_types;
char *rfc7989_filter;
char *acl_inbound_x_token_header;
char *acl_proxy_x_token_header;
};
@ -989,6 +993,13 @@ void launch_sofia_profile_thread(sofia_profile_t *profile);
switch_status_t sofia_presence_chat_send(switch_event_t *message_event);
#define RFC7989_SESSION_UUID_LEN 32
#define RFC7989_SESSION_UUID_NULL "00000000000000000000000000000000"
int sofia_glue_is_valid_session_id(const char *session_id);
void sofia_glue_store_session_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t is_reply);
char *sofia_glue_session_id_header(switch_core_session_t *session, sofia_profile_t *profile);
/*
* \brief Sets the "ep_codec_string" channel variable, parsing r_sdp and taing codec_string in consideration
* \param channel Current channel

View File

@ -610,6 +610,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
sofia_gateway_subscription_t *gw_sub_ptr;
int sub_state;
sofia_gateway_t *gateway = NULL;
const char *session_id_header = sofia_glue_session_id_header(session, profile);
tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
@ -621,7 +622,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
/* Automatically return a 200 OK for Event: keep-alive */
if (!strcasecmp(sip->sip_event->o_type, "keep-alive")) {
/* XXX MTK - is this right? in this case isn't sofia is already sending a 200 itself also? */
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto end;
}
@ -717,7 +718,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
}
}
}
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
}
/* if no session, assume it could be an incoming notify from a gateway subscription */
@ -738,11 +739,14 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
nua_notify(other_tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active),
TAG_IF((full_to), SIPTAG_TO_STR(full_to)), SIPTAG_SUBSCRIPTION_STATE_STR("active"),
SIPTAG_EVENT_STR(sip->sip_event->o_type), TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown)),
TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)), TAG_END());
TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
switch_safe_free(unknown);
switch_core_session_rwunlock(other_session);
}
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto end;
}
/* make sure we have a proper "talk" event */
@ -754,7 +758,8 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
switch_channel_answer(channel);
switch_channel_set_variable(channel, "auto_answer_destination", switch_channel_get_variable(channel, "destination_number"));
switch_ivr_session_transfer(session, "auto_answer", NULL, NULL);
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto end;
}
}
@ -841,7 +846,8 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
if (sip && sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "message-summary")) {
/* unsolicited mwi, just say ok */
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
if (sofia_test_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)) {
const char *mwi_status = NULL;
@ -890,7 +896,8 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
}
} else {
nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
}
end:
@ -942,6 +949,7 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
char *extra_headers;
const char *call_info = NULL;
const char *vval = NULL;
const char *session_id_header = sofia_glue_session_id_header(session, profile);
#ifdef MANUAL_BYE
int cause;
char st[80] = "";
@ -1078,7 +1086,8 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
switch_channel_hangup(channel, cause);
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
switch_safe_free(extra_headers);
@ -1385,6 +1394,7 @@ static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt, const ch
const char *invite_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_from");
const char *invite_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_to");
int soa = sofia_use_soa(tech_pvt);
const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
if (sofia_test_pflag(tech_pvt->profile, PFLAG_TRACK_CALLS)) {
const char *invite_full_via = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_via");
@ -1402,6 +1412,7 @@ static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt, const ch
TAG_IF(r_sdp && !soa, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
TAG_IF(r_sdp && !soa, SIPTAG_PAYLOAD_STR(r_sdp)),
TAG_IF(r_sdp && !soa, NUTAG_MEDIA_ENABLE(0)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_ack(nh,
@ -1414,6 +1425,7 @@ static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt, const ch
TAG_IF(r_sdp && !soa, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
TAG_IF(r_sdp && !soa, SIPTAG_PAYLOAD_STR(r_sdp)),
TAG_IF(r_sdp && !soa, NUTAG_MEDIA_ENABLE(0)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
@ -1671,6 +1683,7 @@ static void our_sofia_event_callback(nua_event_t event,
{
if (channel && sip) {
const char *r_sdp = NULL;
sofia_glue_store_session_id(session, profile, sip, 0);
if (sip->sip_payload && sip->sip_payload->pl_data) {
if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)) {
@ -5299,6 +5312,20 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_UPDATE_REFRESHER);
}
} else if (!strcasecmp(var, "rfc-7989")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_RFC7989_SESSION_ID);
} else {
sofia_clear_pflag(profile, PFLAG_RFC7989_SESSION_ID);
}
} else if (!strcasecmp(var, "rfc-7989-filter")) {
profile->rfc7989_filter = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "rfc-7989-force-old")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_RFC7989_FORCE_OLD);
} else {
sofia_clear_pflag(profile, PFLAG_RFC7989_FORCE_OLD);
}
} else if (!strcasecmp(var, "manage-shared-appearance")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE);
@ -6616,6 +6643,8 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
switch_channel_set_flag(channel, CF_MEDIA_ACK);
sofia_glue_store_session_id(session, profile, sip, 1);
if ((x_freeswitch_support = sofia_glue_get_unknown_header(sip, "X-FS-Support"))) {
tech_pvt->x_freeswitch_support_remote = switch_core_session_strdup(session, x_freeswitch_support);
}
@ -7222,6 +7251,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_event_t *s_event = NULL;
char *p;
char *patched_sdp = NULL;
const char *session_id_header = sofia_glue_session_id_header(session, profile);
tl_gets(tags,
NUTAG_CALLSTATE_REF(ss_state),
@ -7389,6 +7419,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
TAG_IF((full_to), SIPTAG_TO_STR(full_to)),
SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
SIPTAG_EVENT_STR("talk"),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
@ -7501,7 +7532,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA");
switch_core_media_patch_sdp(tech_pvt->session);
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
nua_respond(nh, SIP_488_NOT_ACCEPTABLE,
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
} else{
switch_channel_mark_pre_answered(channel);
@ -7510,7 +7542,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
} else {
if (sofia_media_tech_media(tech_pvt, (char *) r_sdp) != SWITCH_STATUS_SUCCESS) {
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
nua_respond(nh, SIP_488_NOT_ACCEPTABLE,
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END());
switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
}
}
@ -7543,7 +7576,6 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED)) {
if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED_BLEG)) {
switch_core_session_t *other_session;
@ -7565,6 +7597,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
SOATAG_RTP_SELECT(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(other_tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_ack(other_tech_pvt->nh,
@ -7574,12 +7607,14 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
TAG_IF(r_sdp, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
TAG_IF(r_sdp, SIPTAG_PAYLOAD_STR(r_sdp)),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
nua_ack(tech_pvt->nh,
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
@ -7606,7 +7641,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (!match) {
if (switch_channel_get_state(channel) != CS_NEW) {
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE,
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END());
}
} else {
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
@ -7632,6 +7668,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
SOATAG_RTP_SELECT(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_ack(tech_pvt->nh,
@ -7641,6 +7678,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
@ -7698,7 +7736,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Other leg already handling a reinvite, so responding with 491\n");
nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING, TAG_END());
nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING,
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
sofia_glue_do_invite(session);
goto done;
}
@ -7747,7 +7786,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (switch_channel_get_state(channel) == CS_NEW) {
switch_channel_set_state(channel, CS_INIT);
} else {
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
}
sofia_set_flag(tech_pvt, TFLAG_SDP);
if (replaces_str) {
@ -7825,12 +7864,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
} else if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
@ -7897,12 +7940,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
@ -7945,11 +7992,12 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (r_sdp) {
const char *var;
uint8_t match = 0, is_ok = 1, is_t38 = 0;
tech_pvt->mparams.hold_laps = 0;
if ((var = switch_channel_get_variable(channel, "sip_ignore_reinvites")) && switch_true(var)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ignoring Re-invite\n");
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto done;
}
@ -7962,7 +8010,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if ((sofia_test_media_flag(profile, SCMF_DISABLE_HOLD)
|| ((var = switch_channel_get_variable(channel, "rtp_disable_hold")) && switch_true(var)))
&& ((switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) || tech_pvt->mparams.hold_laps)) {
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
if (tech_pvt->mparams.hold_laps) {
tech_pvt->mparams.hold_laps = 0;
@ -8024,12 +8072,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
switch_channel_set_flag(channel, CF_PROXY_MODE);
@ -8046,7 +8098,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_core_media_proxy_remote_addr(session, r_sdp);
if ((tech_pvt->profile->mndlb & SM_NDLB_NEVER_PATCH_REINVITE)) {
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NOT proxying re-invite.\n");
switch_core_session_rwunlock(other_session);
goto done;
@ -8058,7 +8110,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)) {
/* The other leg won the reinvite race */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Other leg already handling reinvite, so responding with 491\n");
nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING, TAG_END());
nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING,
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
switch_core_session_rwunlock(other_session);
goto done;
}
@ -8127,7 +8180,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (!match) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE,
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
switch_core_session_rwunlock(other_session);
goto done;
}
@ -8176,12 +8231,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
switch_core_session_rwunlock(other_session);
goto done;
@ -8198,12 +8257,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
goto done;
}
@ -8216,7 +8279,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto done;
}
@ -8240,7 +8303,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
} else {
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto done;
}
@ -8264,12 +8327,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
@ -8278,7 +8345,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
switch_event_fire(&s_event);
}
} else {
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE,
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
break;
@ -8371,7 +8440,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
if (!is_ok) {
nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
}
}
@ -8553,6 +8622,7 @@ typedef struct {
char *bridge_to_uuid;
switch_event_t *vars;
switch_memory_pool_t *pool;
sofia_profile_t *profile;
} nightmare_xfer_helper_t;
void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void *obj)
@ -8571,6 +8641,7 @@ void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void
if ((session = switch_core_session_locate(nhelper->reply_uuid))) {
private_object_t *tech_pvt = switch_core_session_get_private(session);
switch_channel_t *channel_a = switch_core_session_get_channel(session);
const char *session_id_header = sofia_glue_session_id_header(session, nhelper->profile);
if ((status = switch_ivr_originate(NULL, &tsession, &cause, nhelper->exten_with_params, timeout, NULL, NULL, NULL,
switch_channel_get_caller_profile(channel_a), nhelper->vars, SOF_NONE, NULL, NULL)) == SWITCH_STATUS_SUCCESS) {
@ -8602,7 +8673,9 @@ void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
SIPTAG_PAYLOAD_STR(status == SWITCH_STATUS_SUCCESS ? "SIP/2.0 200 OK\r\n" :
"SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(nhelper->event), TAG_END());
"SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(nhelper->event),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
switch_core_session_rwunlock(session);
}
@ -8727,6 +8800,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
nightmare_xfer_helper_t *nightmare_xfer_helper;
switch_memory_pool_t *npool;
switch_event_t *event = NULL;
const char *session_id_header = sofia_glue_session_id_header(session, profile);
if (!(profile->mflags & MFLAG_REFER)) {
nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
@ -8760,7 +8834,8 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
from = sip->sip_from;
//to = sip->sip_to;
nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"), TAG_END());
nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
switch_channel_set_variable(tech_pvt->channel, SOFIA_REPLACES_HEADER, NULL);
@ -8889,6 +8964,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
} else if (switch_channel_test_flag(channel_b, CF_ORIGINATOR)) {
@ -8982,6 +9058,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
if (b_tech_pvt && !sofia_test_flag(b_tech_pvt, TFLAG_BYE)) {
@ -8996,13 +9073,17 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
nua_bye(b_tech_pvt->nh,
SIPTAG_CONTACT(SIP_NONE),
TAG_IF(!zstr(q850), SIPTAG_REASON_STR(q850)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
} else {
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
} else if (br_a && br_b) {
@ -9081,6 +9162,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_channel_set_variable(channel_b, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER");
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
sofia_clear_flag_locked(b_tech_pvt, TFLAG_SIP_HOLD);
@ -9096,7 +9178,9 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
"Cannot transfer channels that are not in a bridge.\n");
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"),
SIPTAG_EVENT_STR(etmp), TAG_END());
SIPTAG_EVENT_STR(etmp),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
switch_core_session_t *t_session, *hup_session;
switch_channel_t *hup_channel;
@ -9162,14 +9246,18 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
NUTAG_NEWSUB(1),
SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
switch_core_session_rwunlock(t_session);
switch_channel_hangup(hup_channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session to transfer to not found.\n");
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
}
@ -9346,6 +9434,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Refer-For", br_a);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Good Luck, you'll need it......\n");
nightmare_xfer_helper->profile = profile;
launch_nightmare_xfer(nightmare_xfer_helper);
switch_core_session_rwunlock(a_session);
@ -9360,6 +9449,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_channel_set_variable(channel_a, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR");
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
@ -9413,7 +9503,9 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),
SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
if (refer_to->r_url->url_params) {
@ -9450,7 +9542,9 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
NUTAG_SUBSTATE(nua_substate_terminated),
SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
@ -9533,6 +9627,7 @@ switch_status_t sofia_proxy_sip_i_message(nua_t *nua, sofia_profile_t *profile,
sofia_dispatch_event_t *de, tagi_t tags[])
{
switch_core_session_t *other_session = NULL;
const char *session_id_header = sofia_glue_session_id_header(session, profile);
if (session && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
if (switch_core_session_compare(session, other_session)) {
@ -9552,15 +9647,18 @@ switch_status_t sofia_proxy_sip_i_message(nua_t *nua, sofia_profile_t *profile,
}
nua_message(other_tech_pvt->nh,
TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(su_strdup(other_tech_pvt->nh->nh_home, ct))),
TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
TAG_IF(pl, SIPTAG_PAYLOAD_STR(su_strdup(other_tech_pvt->nh->nh_home, pl))),
TAG_END());
TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(su_strdup(other_tech_pvt->nh->nh_home, ct))),
TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
TAG_IF(pl, SIPTAG_PAYLOAD_STR(su_strdup(other_tech_pvt->nh->nh_home, pl))),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
switch_core_session_rwunlock(other_session);
nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
return SWITCH_STATUS_SUCCESS;
}
@ -9572,6 +9670,7 @@ switch_status_t sofia_proxy_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua
sofia_dispatch_event_t *de, tagi_t tags[])
{
switch_core_session_t *other_session = NULL;
const char *session_id_header = sofia_glue_session_id_header(session, profile);
if (session && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
if (switch_core_session_compare(session, other_session)) {
@ -9601,12 +9700,13 @@ switch_status_t sofia_proxy_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua
TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(su_strdup(other_tech_pvt->nh->nh_home, ct))),
TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
TAG_IF(pl, SIPTAG_PAYLOAD_STR(su_strdup(other_tech_pvt->nh->nh_home, pl))),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
switch_core_session_rwunlock(other_session);
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
return SWITCH_STATUS_SUCCESS;
}
@ -9626,6 +9726,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_event_t *event;
private_object_t *tech_pvt = NULL;
switch_channel_t *channel = NULL;
const char *session_id_header = sofia_glue_session_id_header(session, profile);
if (session) {
tech_pvt = (private_object_t *) switch_core_session_get_private(session);
@ -9640,21 +9741,28 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
if (!strcasecmp(sip->sip_content_type->c_subtype, "session-event")) {
if (session) {
if (create_info_event(sip, nh, &event) == SWITCH_STATUS_SUCCESS) {
if (switch_core_session_queue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "queued freeswitch event for INFO\n");
nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
SIPTAG_PAYLOAD_STR("+OK MESSAGE QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
SIPTAG_PAYLOAD_STR("+OK MESSAGE QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
switch_event_destroy(&event);
nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
SIPTAG_PAYLOAD_STR("-ERR MESSAGE NOT QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
SIPTAG_PAYLOAD_STR("-ERR MESSAGE NOT QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
} else {
nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
SIPTAG_PAYLOAD_STR("-ERR INVALID SESSION"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
SIPTAG_PAYLOAD_STR("-ERR INVALID SESSION"), NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
@ -9675,10 +9783,15 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
if ((status = switch_api_execute(cmd, arg, NULL, &stream)) == SWITCH_STATUS_SUCCESS) {
nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response"),
SIPTAG_PAYLOAD_STR(stream.data), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
SIPTAG_PAYLOAD_STR(stream.data), NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response"),
SIPTAG_PAYLOAD_STR("-ERR INVALID COMMAND"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
SIPTAG_PAYLOAD_STR("-ERR INVALID COMMAND"), NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
switch_safe_free(stream.data);
@ -9686,7 +9799,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
return;
}
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
return;
}
@ -9724,6 +9839,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown)),
TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)),
TAG_END());
switch_safe_free(extra_headers);
@ -9869,7 +9985,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
}
/* Send 200 OK response */
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
"IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit);
@ -9882,7 +10000,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
if (!zstr(clientcode_header)) {
switch_channel_set_variable(channel, "call_clientcode", clientcode_header);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Setting CMC to %s\n", clientcode_header);
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
goto end;
}
@ -9890,14 +10010,17 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
if ((rec_header = sofia_glue_get_unknown_header(sip, "record"))) {
if (zstr(profile->record_template)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Record attempted but no template defined.\n");
nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
if (!strcasecmp(rec_header, "on")) {
char *file = NULL, *tmp = NULL;
if (switch_true(switch_channel_get_variable(channel, "sip_disable_recording"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Record attempted but is disabled by sip_disable_recording variable.\n");
nua_respond(nh, 488, "Recording disabled for this channel", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, 488, "Recording disabled for this channel", NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
} else {
tmp = switch_mprintf("%s%s%s", profile->record_path ? profile->record_path : "${recordings_dir}",
@ -9908,7 +10031,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Recording %s to %s\n", switch_channel_get_name(channel),
file);
switch_safe_free(tmp);
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
if (file != profile->record_template) {
free(file);
file = NULL;
@ -9921,9 +10046,13 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Done recording %s to %s\n",
switch_channel_get_name(channel), file);
switch_ivr_stop_record_session(session, file);
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else {
nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
}
}
}
@ -9940,7 +10069,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "dispatched freeswitch event for INFO\n");
}
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
return;
@ -9975,6 +10106,8 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
char via_space[2048];
char branch[16] = "";
sofia_glue_store_session_id(session, profile, sip, 0);
sofia_clear_flag(tech_pvt, TFLAG_GOT_ACK);
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
@ -10115,6 +10248,10 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
const char *req_uri = NULL;
char *req_user = NULL;
switch_time_t sip_invite_time;
const char *session_id_header;
sofia_glue_store_session_id(session, profile, sip, 0);
session_id_header = sofia_glue_session_id_header(session, profile);
if (sip && sip->sip_contact && sip->sip_contact->m_url->url_params) {
uparams = sip->sip_contact->m_url->url_params;
@ -10138,7 +10275,8 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
}
if (!session || (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING))) {
nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto fail;
}
@ -10148,13 +10286,15 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
if (!sip || !sip->sip_request || !sip->sip_request->rq_method_name) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received an invalid packet!\n");
nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE, TAG_END());
nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE,
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto fail;
}
if (!(sip->sip_contact)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT!\n");
nua_respond(nh, 400, "Missing Contact Header", TAG_END());
nua_respond(nh, 400, "Missing Contact Header",
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto fail;
}
@ -10372,7 +10512,8 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", x_auth_ip, switch_str_nil(last_acl));
if (!acl_context) {
nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
nua_respond(nh, SIP_403_FORBIDDEN,
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto fail;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
@ -10387,7 +10528,8 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
if (!is_auth && sofia_test_pflag(profile, PFLAG_AUTH_CALLS) && sofia_test_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP/Port %s %i Rejected by acls and auth-calls-acl-only flag is set, rejecting call\n",
network_ip, network_port);
nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
nua_respond(nh, SIP_403_FORBIDDEN,
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
goto fail;
}

View File

@ -338,6 +338,316 @@ enum tport_tls_verify_policy sofia_glue_str2tls_verify_policy(const char * str){
return ret;
}
/* create "local-uuid" */
int sofia_glue_is_valid_session_uuid(const char *session_uuid)
{
int i;
if (zstr(session_uuid) || strlen(session_uuid) != RFC7989_SESSION_UUID_LEN) {
return 0;
}
for (i = 0; i < RFC7989_SESSION_UUID_LEN; i++) {
char c = session_uuid[i];
if ((c < '0' || c > '9') && (c < 'a' || c > 'f')) {
return 0;
}
}
return 1;
}
/* NIL session-uuid: 00000000000000000000000000000000 */
int sofia_glue_is_nil_session_uuid(const char *session_uuid)
{
if (zstr(session_uuid)) {
return 0;
}
if (!memcmp(session_uuid, RFC7989_SESSION_UUID_NULL, RFC7989_SESSION_UUID_LEN)) {
return 1;
}
return 0;
}
const char *sofia_glue_uuid_to_session_uuid(switch_memory_pool_t *pool, const char *uuid)
{
char *session_uuid = NULL; /*"local-uuid", per rfc7989*/
if (zstr(uuid) || strlen(uuid) != 36) return NULL;
session_uuid = switch_core_alloc(pool, RFC7989_SESSION_UUID_LEN + 1);
memcpy(session_uuid, uuid, 8);
memcpy(session_uuid + 8, uuid + 9, 4);
memcpy(session_uuid + 12, uuid + 14, 4);
memcpy(session_uuid + 16, uuid + 19, 4);
memcpy(session_uuid + 20, uuid + 24, 12);
if (!sofia_glue_is_valid_session_uuid(session_uuid)) return NULL;
return session_uuid;
}
/* rfc7989 generic params, return 0 if param is disabled from config or invalid. ALL params allowed by default. */
/* save updated generic params list in chan var. */
int sofia_glue_check_filter_generic_params(switch_core_session_t *session, sofia_profile_t *profile, char *param)
{
char *tmp = NULL;
switch_channel_t *channel = switch_core_session_get_channel(session);
if (zstr(param)) {
return 0;
}
if (profile->rfc7989_filter) {
char *found = NULL; char *end = NULL;
char *token_array[100] = { 0 };
int tokens = switch_separate_string(profile->rfc7989_filter, ',', token_array, (sizeof(token_array) / sizeof(token_array[0])));
tmp = switch_core_session_strdup(session, param);
if (tokens) {
int i;
for (i = 0; i < tokens && token_array[i]; i++) {
while ((found = strstr(tmp, token_array[i]))) {
end = strchr(found, ';');
if (!end) end = strchr(found, '\0');
*found = '\0';
strcat(tmp, found + (end - found));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
"Session-ID: Dropped generic param: %s\n", token_array[i]);
}
}
}
}
if (tmp) {
switch_channel_set_variable(channel, SWITCH_RFC7989_GENERIC_PARAM_VARIABLE, tmp);
} else {
switch_channel_set_variable(channel, SWITCH_RFC7989_GENERIC_PARAM_VARIABLE, param);
}
return 1;
}
/* check and store Session-ID header. */
/* retrieve "local-uuid" and "remote-uuid" of the remote party. */
void sofia_glue_store_session_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t is_reply)
{
char *a_id, *b_id, *duped, *p, *remote_param;
const char *header = sofia_glue_get_unknown_header(sip, "Session-ID");
switch_channel_t *channel = switch_core_session_get_channel(session);
if (!sofia_test_pflag(profile, PFLAG_RFC7989_SESSION_ID)) return;
if (!header) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Session-ID: missing header.");
return;
}
duped = switch_core_session_strdup(session, header);
if (zstr(duped)) return;
a_id = switch_strip_whitespace(duped);
if (zstr(a_id)) return;
p = strchr(a_id, ';');
if (p) *p = '\0';
if (!sofia_glue_is_valid_session_uuid(a_id)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Session-ID: Ignoring \"%s\" parsed as \"%s\"\n", header, a_id);
return;
}
/* RFC7329 compatibility */
if (is_reply) {
const char *temp_id = switch_channel_get_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE);
if (!zstr(temp_id) && !memcmp(a_id, temp_id, RFC7989_SESSION_UUID_LEN) ) {
/* 'If a SIP response only contains the "local-uuid" that was sent
* originally, this comes from a pre-standard implementation and MUST
* NOT be discarded for removing the nil "remote-uuid". In this
* case, all future transactions within this dialog MUST contain only
* the UUID received in the first SIP response" */
switch_channel_set_flag(channel, CF_RFC7329_COMPAT);
switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
}
}
/* "local-uuid" field retrieved from remote party will become
* SWITCH_RFC7989_APP_SESSION_ID_VARIABLE in a b2bua role. */
if (!zstr(a_id)) {
struct private_object *tech_pvt = switch_core_session_get_private(session);
switch_channel_set_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE, a_id);
if (tech_pvt && tech_pvt->sofia_private && !tech_pvt->sofia_private->rfc7989_uuid) {
tech_pvt->sofia_private->rfc7989_uuid = su_strdup(tech_pvt->nh->nh_home, a_id);
}
}
if (!p) {
switch_channel_set_flag(channel, CF_RFC7329_COMPAT);
switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
return;
}
p++;
remote_param = strstr(p, "remote=");
if (!remote_param) {
switch_channel_set_flag(channel, CF_RFC7329_COMPAT);
switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
sofia_glue_check_filter_generic_params(session, profile, p);
return;
}
b_id = remote_param + 7;
if (!zstr(b_id) && strlen(b_id) == RFC7989_SESSION_UUID_LEN /*32*/) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session-ID: Set remote-uuid: %s\n", b_id);
/*using chan var as placeholder only when UAS or when answer() was called in the dialplan */
switch_channel_set_variable(channel, SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE, b_id);
switch_channel_set_variable_partner(channel, SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE, b_id);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Session-ID: invalid uuid, ignored.\n");
}
}
/* add "Session-ID:" header */
char *sofia_glue_session_id_header(switch_core_session_t *session, sofia_profile_t *profile)
{
switch_channel_t *channel;
const char *b_id = NULL;
const char *a_id = NULL;
const char *temp_id = NULL;
const char *generic = NULL;
if (!session) return NULL;
if (!profile) return NULL;
if (!sofia_test_pflag(profile, PFLAG_RFC7989_SESSION_ID)) return NULL;
channel = switch_core_session_get_channel(session);
a_id = switch_channel_get_variable_partner(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE);
if (zstr(a_id)) {
a_id = switch_channel_get_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE);
if (!zstr(a_id) && strlen(a_id) == 36) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Reformatting app Session-ID: %s\n", a_id);
a_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), a_id);
if (!zstr(a_id)) {
struct private_object *tech_pvt = switch_core_session_get_private(session);
switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id);
if (tech_pvt && tech_pvt->sofia_private && !tech_pvt->sofia_private->rfc7989_uuid) {
tech_pvt->sofia_private->rfc7989_uuid = su_strdup(tech_pvt->nh->nh_home, a_id);
}
}
}
}
if (zstr(a_id)) {
const char *partner_uuid = switch_channel_get_partner_uuid(channel);
if (!zstr(partner_uuid)) {
const char *partner_session_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), partner_uuid);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Setting \"Session-ID: %s\" from partner leg\n", partner_session_id);
switch_channel_set_variable_partner(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE, partner_session_id);
a_id = partner_session_id;
}
}
if (((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) && zstr(a_id) &&
switch_channel_get_state(channel) == CS_INIT) && switch_channel_test_flag(channel, CF_ORIGINATING)) {
/*outbound initial request*/
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
switch_uuid_str(uuid_str, sizeof(uuid_str));
a_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), uuid_str);
if (!zstr(a_id)) {
struct private_object *tech_pvt = switch_core_session_get_private(session);
switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id);
if (tech_pvt && tech_pvt->sofia_private && !tech_pvt->sofia_private->rfc7989_uuid) {
tech_pvt->sofia_private->rfc7989_uuid = su_strdup(tech_pvt->nh->nh_home, a_id);
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Session-ID: Outbound initial request. local-uuid: %s", a_id);
if (sofia_test_pflag(profile, PFLAG_RFC7989_FORCE_OLD)) {
/*for old (and obsolete) Session-ID RFC7329 */
return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
}
b_id = RFC7989_SESSION_UUID_NULL;
return switch_core_session_sprintf(session, "Session-ID: %s;remote=%s", a_id, b_id);
}
temp_id = switch_channel_get_variable(channel, SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE);
if ((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) &&
((switch_channel_get_state(channel) == CS_INIT) || (switch_channel_get_state(channel) == CS_EXECUTE)) &&
zstr(temp_id)) {
/* fallback to RFC7329 - "old". */
/* inbound initial request, no "remote" param. section 11 of RFC7989. */
a_id = switch_channel_get_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE);
if (zstr(a_id)) {
a_id = RFC7989_SESSION_UUID_NULL;
} else {
switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Session-ID: Fallback to RFC7329");
switch_channel_set_flag(channel, CF_RFC7329_COMPAT);
return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
}
if ((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) &&
((switch_channel_get_state(channel) == CS_INIT) || (switch_channel_get_state(channel) == CS_EXECUTE)) &&
sofia_glue_is_nil_session_uuid(temp_id)) {
/*inbound initial request*/
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
switch_uuid_str(uuid_str, sizeof(uuid_str));
a_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), uuid_str);
if (!zstr(a_id)) {
struct private_object *tech_pvt = switch_core_session_get_private(session);
switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id);
if (tech_pvt && tech_pvt->sofia_private) {
tech_pvt->sofia_private->rfc7989_uuid = su_strdup(tech_pvt->nh->nh_home, a_id);
}
}
b_id = switch_channel_get_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE);
if (zstr(b_id)) {
b_id = RFC7989_SESSION_UUID_NULL;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Session-ID: Inbound initial request. local-uuid: %s", a_id);
return switch_core_session_sprintf(session, "Session-ID: %s;remote=%s", a_id, b_id);
}
if (zstr(a_id)) {
struct private_object *tech_pvt = switch_core_session_get_private(session);
/* setting NIL local-uuid should never happen,
* but in case we don't get to set it properly by here, just set it to NIL */
if (tech_pvt && tech_pvt->sofia_private && tech_pvt->sofia_private->rfc7989_uuid) {
/* handle BYE after REFER or other cases where the channel is destroyed already and we can't get the chan var */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session-ID: retrieved local-uuid ");
a_id = tech_pvt->sofia_private->rfc7989_uuid;
} else {
a_id = RFC7989_SESSION_UUID_NULL;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session-ID: NIL local-uuid ");
}
}
b_id = switch_channel_get_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE);
if (zstr(b_id) && switch_channel_test_flag(channel, CF_RFC7329_COMPAT)) {
/* fallback to RFC7329 , only one uuid*/
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING ,"Session-ID: Fallback to RFC7329, use one uuid");
return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
} else if (zstr(b_id)) {
b_id = RFC7989_SESSION_UUID_NULL;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session-ID: set NIL remote-uuid");
}
/* B2B: handle generic params*/
generic = switch_channel_get_variable_partner(channel, SWITCH_RFC7989_GENERIC_PARAM_VARIABLE);
if (!zstr(generic)) {
/* copy generic param (name and val) */
return switch_core_session_sprintf(session, "Session-ID: %s;%s", a_id, generic);
}
if (switch_channel_test_flag(channel, CF_RFC7329_COMPAT)) {
return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
}
return switch_core_session_sprintf(session, "Session-ID: %s;remote=%s", a_id, b_id);
}
char *sofia_glue_find_parameter_value(switch_core_session_t *session, const char *str, const char *param)
{
const char *param_ptr;
@ -757,6 +1067,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
int require_timer = 1;
uint8_t is_t38 = 0;
const char *hold_char = "*";
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD_INACTIVE) ||
switch_true(switch_channel_get_variable_dup(tech_pvt->channel, "sofia_hold_inactive", SWITCH_FALSE, -1))) {
@ -1326,6 +1638,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
is_t38 = 1;
}
if (sofia_use_soa(tech_pvt)) {
nua_invite(tech_pvt->nh,
NUTAG_AUTOANSWER(0),
@ -1336,6 +1649,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
@ -1373,6 +1687,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),