[Freeswitch-svn] [commit] r3860 - in freeswitch/trunk: libs/sofia-sip/libsofia-sip-ua/nua src src/mod/endpoints/mod_sofia
Freeswitch SVN
anthm at freeswitch.org
Thu Dec 28 14:38:35 EST 2006
Author: anthm
Date: Thu Dec 28 14:38:35 2006
New Revision: 3860
Modified:
freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
freeswitch/trunk/src/switch_core.c
freeswitch/trunk/src/switch_ivr.c
Log:
fix sofia (part 2) you'd better 'make sure'
Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c (original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c Thu Dec 28 14:38:35 2006
@@ -599,7 +599,8 @@
if (!cr->cr_usage) {
/* Unnotify */
- nua_stack_notify2(nh->nh_nua, nh, nua_r_destroy, du, NULL);
+ /* Commenting this line out to supress an attended transfer bug (awaiting fix from pessi) */
+ //nua_stack_notify2(nh->nh_nua, nh, nua_r_destroy, du, NULL);
return cr->cr_usage != du;
}
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Thu Dec 28 14:38:35 2006
@@ -49,7 +49,7 @@
#define NUA_MAGIC_T sofia_profile_t
struct sofia_private {
- switch_core_session_t *session;
+ char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
outbound_reg_t *oreg;
};
@@ -167,8 +167,7 @@
TFLAG_XFER = (1 << 19),
TFLAG_NOMEDIA = (1 << 20),
TFLAG_BUGGY_2833 = (1 << 21),
- TFLAG_SIP_HOLD = (1 << 22),
- TFLAG_RWLOCK = (1 << 23)
+ TFLAG_SIP_HOLD = (1 << 22)
} TFLAGS;
static struct {
@@ -256,7 +255,6 @@
struct private_object {
sofia_private_t *sofia_private;
- sofia_private_t *sofia_private2;
uint32_t flags;
switch_payload_t agreed_pt;
switch_core_session_t *session;
@@ -374,7 +372,7 @@
static void sip_i_refer(nua_t *nua,
sofia_profile_t *profile,
nua_handle_t *nh,
- sofia_private_t *sofia_private,
+ switch_core_session_t *session,
sip_t const *sip,
tagi_t tags[]);
@@ -983,7 +981,7 @@
abort();
}
memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
- tech_pvt->sofia_private->session = session;
+ switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
nua_handle_bind(tech_pvt->nh, tech_pvt->sofia_private);
}
@@ -1057,14 +1055,7 @@
TAG_END());
- if (!(tech_pvt->sofia_private2 = malloc(sizeof(*tech_pvt->sofia_private2)))) {
- abort();
- }
- memset(tech_pvt->sofia_private2, 0, sizeof(*tech_pvt->sofia_private2));
- tech_pvt->sofia_private2->session = tech_pvt->sofia_private->session;
- nua_handle_bind(tech_pvt->nh2, tech_pvt->sofia_private2);
-
-
+ nua_handle_bind(tech_pvt->nh2, tech_pvt->sofia_private);
nua_invite(tech_pvt->nh2,
TAG_IF(rpid, SIPTAG_HEADER_STR(rpid)),
@@ -1237,7 +1228,7 @@
static switch_status_t sofia_on_hangup(switch_core_session_t *session)
{
- switch_core_session_t *asession;
+ switch_core_session_t *a_session;
private_object_t *tech_pvt;
switch_channel_t *channel = NULL;
switch_call_cause_t cause;
@@ -1261,10 +1252,10 @@
switch_core_hash_delete(tech_pvt->profile->chat_hash, tech_pvt->hash_key);
}
- if (tech_pvt->kick && (asession = switch_core_session_locate(tech_pvt->kick))) {
- switch_channel_t *a_channel = switch_core_session_get_channel(asession);
+ if (tech_pvt->kick && (a_session = switch_core_session_locate(tech_pvt->kick))) {
+ switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
switch_channel_hangup(a_channel, switch_channel_get_cause(channel));
- switch_core_session_rwunlock(asession);
+ switch_core_session_rwunlock(a_session);
}
if (tech_pvt->nh) {
@@ -1297,7 +1288,7 @@
}
if (tech_pvt->sofia_private) {
- tech_pvt->sofia_private->session = NULL;
+ *tech_pvt->sofia_private->uuid = '\0';
}
return SWITCH_STATUS_SUCCESS;
@@ -1862,23 +1853,21 @@
if (switch_test_flag(tech_pvt, TFLAG_XFER)) {
switch_clear_flag_locked(tech_pvt, TFLAG_XFER);
if (msg->pointer_arg) {
- switch_core_session_t *asession, *bsession = msg->pointer_arg;
+ switch_core_session_t *a_session, *b_session = msg->pointer_arg;
- if ((asession = switch_core_session_locate(tech_pvt->xferto))) {
- private_object_t *a_tech_pvt = switch_core_session_get_private(asession);
- private_object_t *b_tech_pvt = switch_core_session_get_private(bsession);
+ if ((a_session = switch_core_session_locate(tech_pvt->xferto))) {
+ private_object_t *a_tech_pvt = switch_core_session_get_private(a_session);
+ private_object_t *b_tech_pvt = switch_core_session_get_private(b_session);
switch_set_flag_locked(a_tech_pvt, TFLAG_REINVITE);
- a_tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(asession, b_tech_pvt->remote_sdp_audio_ip);
+ a_tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(a_session, b_tech_pvt->remote_sdp_audio_ip);
a_tech_pvt->remote_sdp_audio_port = b_tech_pvt->remote_sdp_audio_port;
- a_tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(asession, b_tech_pvt->local_sdp_audio_ip);
+ a_tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(a_session, b_tech_pvt->local_sdp_audio_ip);
a_tech_pvt->local_sdp_audio_port = b_tech_pvt->local_sdp_audio_port;
activate_rtp(a_tech_pvt);
- b_tech_pvt->kick = switch_core_session_strdup(bsession, tech_pvt->xferto);
-
-
- switch_core_session_rwunlock(asession);
+ b_tech_pvt->kick = switch_core_session_strdup(b_session, tech_pvt->xferto);
+ switch_core_session_rwunlock(a_session);
}
@@ -2505,13 +2494,23 @@
int ss_state = nua_callstate_init;
switch_channel_t *channel = NULL;
private_object_t *tech_pvt = NULL;
- switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
+ switch_core_session_t *session = NULL;
const char *replaces_str = NULL;
char *uuid;
switch_core_session_t *other_session = NULL;
switch_channel_t *other_channel = NULL;
char st[80] = "";
+
+ if (sofia_private) {
+ if (!switch_strlen_zero(sofia_private->uuid)) {
+ if (!(session = switch_core_session_locate(sofia_private->uuid))) {
+ /* too late */
+ return;
+ }
+ }
+ }
+
tl_gets(tags,
NUTAG_CALLSTATE_REF(ss_state),
@@ -2549,7 +2548,7 @@
}
if (status == 988) {
- return;
+ goto done;
}
switch ((enum nua_callstate)ss_state) {
@@ -2591,7 +2590,7 @@
switch_channel_pre_answer(other_channel);
switch_core_session_rwunlock(other_session);
}
- return;
+ goto done;
} else {
sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0);
sdp_session_t *sdp;
@@ -2628,7 +2627,7 @@
case nua_callstate_received:
if (session && switch_core_session_running(session)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Re-Entering Call State Received!\n");
- return;
+ goto done;
}
if (channel) {
@@ -2638,7 +2637,7 @@
switch_channel_set_state(channel, CS_INIT);
switch_set_flag_locked(tech_pvt, TFLAG_READY);
switch_core_session_thread_launch(session);
- return;
+ goto done;
} else {
sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0);
sdp_session_t *sdp;
@@ -2673,7 +2672,7 @@
if ((b_private = nua_handle_magic(bnh))) {
char *br_b = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE);
- char *br_a = switch_core_session_get_uuid(b_private->session);
+ char *br_a = b_private->uuid;
if (br_b) {
switch_ivr_uuid_bridge(br_a, br_b);
@@ -2689,7 +2688,7 @@
}
nua_handle_unref(bnh);
}
- return;
+ goto done;
}
switch_channel_set_variable(channel, "endpoint_disposition", "NO CODECS");
@@ -2706,7 +2705,7 @@
if (tech_pvt && r_sdp) {
if (r_sdp) {
if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) {
- return;
+ goto done;
} else {
sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0);
sdp_session_t *sdp;
@@ -2739,7 +2738,7 @@
tech_pvt->nh2 = NULL;
tech_choose_port(tech_pvt);
activate_rtp(tech_pvt);
- return;
+ goto done;
}
if (channel) {
@@ -2752,7 +2751,7 @@
switch_channel_answer(other_channel);
switch_core_session_rwunlock(other_session);
}
- return;
+ goto done;
} else {
sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0);
sdp_session_t *sdp;
@@ -2775,7 +2774,7 @@
tech_choose_port(tech_pvt);
activate_rtp(tech_pvt);
switch_channel_mark_answered(channel);
- return;
+ goto done;
}
switch_channel_set_variable(channel, "endpoint_disposition", "NO CODECS");
@@ -2785,7 +2784,7 @@
switch_set_flag_locked(tech_pvt, TFLAG_ANS);
switch_channel_set_variable(channel, "endpoint_disposition", "ANSWER");
switch_channel_mark_answered(channel);
- return;
+ goto done;
} //else probably an ack
}
@@ -2794,12 +2793,8 @@
break;
case nua_callstate_terminated:
if (session) {
- if (switch_test_flag(tech_pvt, TFLAG_RWLOCK)) {
- switch_core_session_rwunlock(session);
- switch_clear_flag_locked(tech_pvt, TFLAG_RWLOCK);
- }
if (!switch_test_flag(tech_pvt, TFLAG_BYE)) {
-
+
switch_set_flag_locked(tech_pvt, TFLAG_BYE);
if (switch_test_flag(tech_pvt, TFLAG_NOHUP)) {
switch_clear_flag_locked(tech_pvt, TFLAG_NOHUP);
@@ -2812,18 +2807,25 @@
if (tech_pvt->sofia_private) {
free(tech_pvt->sofia_private);
- nua_handle_bind(tech_pvt->nh, NULL);
tech_pvt->sofia_private = NULL;
}
tech_pvt->nh = NULL;
- }
+ } else if (sofia_private) {
+ free(sofia_private);
+ }
+
if (nh) {
+ nua_handle_bind(nh, NULL);
nua_handle_destroy(nh);
}
break;
}
-
+ done:
+
+ if (session) {
+ switch_core_session_rwunlock(session);
+ }
}
@@ -3532,7 +3534,7 @@
static void sip_i_refer(nua_t *nua,
sofia_profile_t *profile,
nua_handle_t *nh,
- sofia_private_t *sofia_private,
+ switch_core_session_t *session,
sip_t const *sip,
tagi_t tags[])
{
@@ -3540,273 +3542,254 @@
sip_from_t const *from;
sip_to_t const *to;
sip_refer_to_t const *refer_to;
- switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
-
- if (session) {
- private_object_t *tech_pvt = NULL;
- char *etmp = NULL, *exten = NULL;
- switch_channel_t *channel_a = NULL, *channel_b = NULL;
+ private_object_t *tech_pvt = NULL;
+ char *etmp = NULL, *exten = NULL;
+ switch_channel_t *channel_a = NULL, *channel_b = NULL;
- tech_pvt = switch_core_session_get_private(session);
- channel_a = switch_core_session_get_channel(session);
+ tech_pvt = switch_core_session_get_private(session);
+ channel_a = switch_core_session_get_channel(session);
-
- if (!sip->sip_cseq || !(etmp = switch_mprintf("refer;id=%u", sip->sip_cseq->cs_seq))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
- goto done;
- }
+ if (!sip->sip_cseq || !(etmp = switch_mprintf("refer;id=%u", sip->sip_cseq->cs_seq))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
+ goto done;
+ }
- if (switch_channel_test_flag(channel_a, CF_NOMEDIA)) {
- nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
- SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
- SIPTAG_EVENT_STR(etmp),
- TAG_END());
- goto done;
- }
+ if (switch_channel_test_flag(channel_a, CF_NOMEDIA)) {
+ nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+ SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
+ SIPTAG_EVENT_STR(etmp),
+ TAG_END());
+ goto done;
+ }
- from = sip->sip_from;
- to = sip->sip_to;
-
- if ((refer_to = sip->sip_refer_to)) {
- if (profile->pflags & PFLAG_FULL_ID) {
- exten = switch_mprintf("%s@%s", (char *) refer_to->r_url->url_user, (char *) refer_to->r_url->url_host);
- } else {
- exten = (char *) refer_to->r_url->url_user;
- }
+ from = sip->sip_from;
+ to = sip->sip_to;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Process REFER to [%s@%s]\n", exten, (char *) refer_to->r_url->url_host);
+ if ((refer_to = sip->sip_refer_to)) {
+ if (profile->pflags & PFLAG_FULL_ID) {
+ exten = switch_mprintf("%s@%s", (char *) refer_to->r_url->url_user, (char *) refer_to->r_url->url_host);
+ } else {
+ exten = (char *) refer_to->r_url->url_user;
+ }
- if (refer_to->r_url->url_headers) {
- sip_replaces_t *replaces;
- nua_handle_t *bnh;
- char *rep;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Process REFER to [%s@%s]\n", exten, (char *) refer_to->r_url->url_host);
- if ((rep = strchr(refer_to->r_url->url_headers, '='))) {
- char *br_a = NULL, *br_b = NULL;
- char *buf;
- rep++;
+ if (refer_to->r_url->url_headers) {
+ sip_replaces_t *replaces;
+ nua_handle_t *bnh;
+ char *rep;
+
+ if ((rep = strchr(refer_to->r_url->url_headers, '='))) {
+ char *br_a = NULL, *br_b = NULL;
+ char *buf;
+ rep++;
- if ((buf = switch_core_session_alloc(session, strlen(rep) + 1))) {
- rep = url_unescape(buf, (const char *) rep);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Replaces: [%s]\n", rep);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
- goto done;
- }
- if ((replaces = sip_replaces_make(tech_pvt->home, rep)) && (bnh = nua_handle_by_replaces(nua, replaces))) {
- sofia_private_t *b_private = NULL;
- private_object_t *tech_pvt_b = NULL;
- switch_channel_set_variable(channel_a, SOFIA_REPLACES_HEADER, rep);
- if ((b_private = nua_handle_magic(bnh))) {
- tech_pvt_b = (private_object_t *) switch_core_session_get_private(b_private->session);
- channel_b = switch_core_session_get_channel(b_private->session);
+ if ((buf = switch_core_session_alloc(session, strlen(rep) + 1))) {
+ rep = url_unescape(buf, (const char *) rep);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Replaces: [%s]\n", rep);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
+ goto done;
+ }
+ if ((replaces = sip_replaces_make(tech_pvt->home, rep)) && (bnh = nua_handle_by_replaces(nua, replaces))) {
+ sofia_private_t *b_private = NULL;
+ private_object_t *b_tech_pvt = NULL;
+ switch_core_session_t *b_session = NULL;
+
+ switch_channel_set_variable(channel_a, SOFIA_REPLACES_HEADER, rep);
+ if ((b_private = nua_handle_magic(bnh))) {
+ if (!(b_session = switch_core_session_locate(b_private->uuid))) {
+ goto done;
+ }
+ b_tech_pvt = (private_object_t *) switch_core_session_get_private(b_session);
+ channel_b = switch_core_session_get_channel(b_session);
- br_a = switch_channel_get_variable(channel_a, SWITCH_BRIDGE_VARIABLE);
- br_b = switch_channel_get_variable(channel_b, SWITCH_BRIDGE_VARIABLE);
+ br_a = switch_channel_get_variable(channel_a, SWITCH_BRIDGE_VARIABLE);
+ br_b = switch_channel_get_variable(channel_b, SWITCH_BRIDGE_VARIABLE);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Attended Transfer [%s][%s]\n", br_a, br_b);
-
- if (switch_test_flag(tech_pvt, TFLAG_RWLOCK)) {
- switch_core_session_rwunlock(tech_pvt->session);
- switch_clear_flag_locked(tech_pvt, TFLAG_RWLOCK);
- }
- if (switch_test_flag(tech_pvt_b, TFLAG_RWLOCK)) {
- switch_core_session_rwunlock(tech_pvt_b->session);
- switch_clear_flag_locked(tech_pvt_b, TFLAG_RWLOCK);
- }
-
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Attended Transfer [%s][%s]\n", br_a, br_b);
- if (br_a && br_b) {
- switch_ivr_uuid_bridge(br_a, br_b);
- switch_channel_set_variable(channel_b, "endpoint_disposition", "ATTENDED_TRANSFER");
- switch_set_flag_locked(tech_pvt, TFLAG_BYE);
- nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
- SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
- SIPTAG_EVENT_STR(etmp),
- TAG_END());
+ if (br_a && br_b) {
+ switch_ivr_uuid_bridge(br_a, br_b);
+ switch_channel_set_variable(channel_b, "endpoint_disposition", "ATTENDED_TRANSFER");
+ switch_set_flag_locked(tech_pvt, TFLAG_BYE);
+ switch_set_flag_locked(b_tech_pvt, TFLAG_BYE);
+ nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+ SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
+ SIPTAG_EVENT_STR(etmp),
+ TAG_END());
- } else {
- if (!br_a && !br_b) {
- switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
- switch_set_flag_locked(tech_pvt_b, TFLAG_XFER);
- tech_pvt_b->xferto = switch_core_session_strdup(b_private->session, switch_core_session_get_uuid(session));
- } else if (!br_a && br_b) {
- switch_core_session_t *bsession;
-
- if ((bsession = switch_core_session_locate(br_b))) {
- private_object_t *b_tech_pvt = switch_core_session_get_private(bsession);
- switch_channel_t *b_channel = switch_core_session_get_channel(bsession);
- private_object_t *bp_tech_pvt = switch_core_session_get_private(b_private->session);
-
- switch_core_session_get_uuid(b_private->session);
- switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
+ } else {
+ if (!br_a && !br_b) {
+ switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
+ switch_set_flag_locked(b_tech_pvt, TFLAG_XFER);
+ b_tech_pvt->xferto = switch_core_session_strdup(b_session, switch_core_session_get_uuid(session));
+ } else if (!br_a && br_b) {
+ switch_core_session_t *br_b_session;
+
+ if ((br_b_session = switch_core_session_locate(br_b))) {
+ private_object_t *br_b_tech_pvt = switch_core_session_get_private(br_b_session);
+ switch_channel_t *br_b_channel = switch_core_session_get_channel(br_b_session);
+
+ switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
- switch_channel_clear_state_handler(b_channel, NULL);
- switch_channel_set_state_flag(b_channel, CF_TRANSFER);
- switch_channel_set_state(b_channel, CS_TRANSMIT);
-
- switch_set_flag_locked(tech_pvt, TFLAG_REINVITE);
- tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(session, bp_tech_pvt->local_sdp_audio_ip);
- tech_pvt->local_sdp_audio_port = bp_tech_pvt->local_sdp_audio_port;
-
- tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(session, b_tech_pvt->remote_sdp_audio_ip);
- tech_pvt->remote_sdp_audio_port = b_tech_pvt->remote_sdp_audio_port;
- activate_rtp(tech_pvt);
+ switch_channel_clear_state_handler(br_b_channel, NULL);
+ switch_channel_set_state_flag(br_b_channel, CF_TRANSFER);
+ switch_channel_set_state(br_b_channel, CS_TRANSMIT);
+
+ switch_set_flag_locked(tech_pvt, TFLAG_REINVITE);
+ tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(session, b_tech_pvt->local_sdp_audio_ip);
+ tech_pvt->local_sdp_audio_port = b_tech_pvt->local_sdp_audio_port;
+
+ tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(session, br_b_tech_pvt->remote_sdp_audio_ip);
+ tech_pvt->remote_sdp_audio_port = br_b_tech_pvt->remote_sdp_audio_port;
+ activate_rtp(tech_pvt);
- b_tech_pvt->kick = switch_core_session_strdup(bsession, switch_core_session_get_uuid(session));
+ br_b_tech_pvt->kick = switch_core_session_strdup(br_b_session, switch_core_session_get_uuid(session));
- switch_core_session_rwunlock(bsession);
- }
-
- switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER);
- }
- switch_set_flag_locked(tech_pvt, TFLAG_BYE);
- nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
- SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
- SIPTAG_EVENT_STR(etmp),
- TAG_END());
+ switch_core_session_rwunlock(br_b_session);
+ }
- }
- }
- nua_handle_unref(bnh);
- } else { /* the other channel is on a different box, we have to go find them */
- if (exten && (br_a = switch_channel_get_variable(channel_a, SWITCH_BRIDGE_VARIABLE))) {
- switch_core_session_t *asession;
- switch_channel_t *channel = switch_core_session_get_channel(session);
+ switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER);
+ }
+ switch_set_flag_locked(tech_pvt, TFLAG_BYE);
+ nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+ SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
+ SIPTAG_EVENT_STR(etmp),
+ TAG_END());
+
+ }
+ if (b_session) {
+ switch_core_session_rwunlock(b_session);
+ }
+ }
+ nua_handle_unref(bnh);
+ } else { /* the other channel is on a different box, we have to go find them */
+ if (exten && (br_a = switch_channel_get_variable(channel_a, SWITCH_BRIDGE_VARIABLE))) {
+ switch_core_session_t *a_session;
+ switch_channel_t *channel = switch_core_session_get_channel(session);
- if ((asession = switch_core_session_locate(br_a))) {
- switch_core_session_t *tsession;
- switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
- uint32_t timeout = 60;
- char *tuuid_str;
-
- channel = switch_core_session_get_channel(asession);
-
- exten = switch_mprintf("sofia/%s/%s@%s:%s",
- profile->name,
- (char *) refer_to->r_url->url_user,
- (char *) refer_to->r_url->url_host,
- refer_to->r_url->url_port
- );
+ if ((a_session = switch_core_session_locate(br_a))) {
+ switch_core_session_t *tsession;
+ switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
+ uint32_t timeout = 60;
+ char *tuuid_str;
+
+ channel = switch_core_session_get_channel(a_session);
+
+ exten = switch_mprintf("sofia/%s/%s@%s:%s",
+ profile->name,
+ (char *) refer_to->r_url->url_user,
+ (char *) refer_to->r_url->url_host,
+ refer_to->r_url->url_port
+ );
- switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, rep);
+ switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, rep);
- if (switch_ivr_originate(asession,
- &tsession,
- &cause,
- exten,
- timeout,
- &noop_state_handler,
- NULL,
- NULL,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! [%s]\n", exten);
- nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
- SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
- SIPTAG_EVENT_STR(etmp),
- TAG_END());
- goto done;
- }
-
- switch_core_session_rwunlock(asession);
- tuuid_str = switch_core_session_get_uuid(tsession);
- switch_ivr_uuid_bridge(br_a, tuuid_str);
- switch_channel_set_variable(channel_a, "endpoint_disposition", "ATTENDED_TRANSFER");
- switch_set_flag_locked(tech_pvt, TFLAG_BYE);
- if (switch_test_flag(tech_pvt, TFLAG_RWLOCK)) {
- switch_core_session_rwunlock(tech_pvt->session);
- switch_clear_flag_locked(tech_pvt, TFLAG_RWLOCK);
- }
- nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
- SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
- SIPTAG_EVENT_STR(etmp),
- TAG_END());
- } else {
- goto error;
- }
-
- } else { error:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Transfer! [%s]\n", br_a);
- switch_channel_set_variable(channel_a, "endpoint_disposition", "ATTENDED_TRANSFER_ERROR");
- nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
- SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
- SIPTAG_EVENT_STR(etmp),
- TAG_END());
- }
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot parse Replaces!\n");
- }
- goto done;
- }
+ if (switch_ivr_originate(a_session,
+ &tsession,
+ &cause,
+ exten,
+ timeout,
+ &noop_state_handler,
+ NULL,
+ NULL,
+ NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! [%s]\n", exten);
+ nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+ SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
+ SIPTAG_EVENT_STR(etmp),
+ TAG_END());
+ goto done;
+ }
+
+ switch_core_session_rwunlock(a_session);
+ tuuid_str = switch_core_session_get_uuid(tsession);
+ switch_ivr_uuid_bridge(br_a, tuuid_str);
+ switch_channel_set_variable(channel_a, "endpoint_disposition", "ATTENDED_TRANSFER");
+ switch_set_flag_locked(tech_pvt, TFLAG_BYE);
+ nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+ SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
+ SIPTAG_EVENT_STR(etmp),
+ TAG_END());
+ } else {
+ goto error;
+ }
+
+ } else { error:
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Transfer! [%s]\n", br_a);
+ switch_channel_set_variable(channel_a, "endpoint_disposition", "ATTENDED_TRANSFER_ERROR");
+ nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+ SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden"),
+ SIPTAG_EVENT_STR(etmp),
+ TAG_END());
+ }
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot parse Replaces!\n");
+ }
+ goto done;
+ }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Refer-To\n");
- goto done;
- }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Refer-To\n");
+ goto done;
+ }
- if (exten) {
- switch_channel_t *channel = switch_core_session_get_channel(session);
- char *br;
+ if (exten) {
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ char *br;
- if ((br = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE))) {
- switch_core_session_t *bsession;
+ if ((br = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE))) {
+ switch_core_session_t *b_session;
- if ((bsession = switch_core_session_locate(br))) {
- switch_channel_set_variable(channel, "TRANSFER_FALLBACK", (char *) from->a_user);
- switch_ivr_session_transfer(bsession, exten, profile->dialplan, profile->context);
- switch_core_session_rwunlock(bsession);
- }
+ if ((b_session = switch_core_session_locate(br))) {
+ switch_channel_set_variable(channel, "TRANSFER_FALLBACK", (char *) from->a_user);
+ switch_ivr_session_transfer(b_session, exten, profile->dialplan, profile->context);
+ switch_core_session_rwunlock(b_session);
+ }
- switch_channel_set_variable(channel, "endpoint_disposition", "BLIND_TRANSFER");
+ switch_channel_set_variable(channel, "endpoint_disposition", "BLIND_TRANSFER");
- /*
- nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
- SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
- SIPTAG_EVENT_STR(etmp),
- TAG_END());
- */
- if (switch_test_flag(tech_pvt, TFLAG_RWLOCK)) {
- switch_core_session_rwunlock(tech_pvt->session);
- switch_clear_flag_locked(tech_pvt, TFLAG_RWLOCK);
- }
- } else {
- exten = switch_mprintf("sip:%s@%s:%s",
- (char *) refer_to->r_url->url_user,
- (char *) refer_to->r_url->url_host,
- refer_to->r_url->url_port);
- tech_pvt->dest = switch_core_session_strdup(session, exten);
+ /*
+ nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+ SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
+ SIPTAG_EVENT_STR(etmp),
+ TAG_END());
+ */
+ } else {
+ exten = switch_mprintf("sip:%s@%s:%s",
+ (char *) refer_to->r_url->url_user,
+ (char *) refer_to->r_url->url_host,
+ refer_to->r_url->url_port);
+ tech_pvt->dest = switch_core_session_strdup(session, exten);
- switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
+ switch_set_flag_locked(tech_pvt, TFLAG_NOHUP);
- /*
- nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
- SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
- SIPTAG_EVENT_STR(etmp),
- TAG_END());
- */
- if (switch_test_flag(tech_pvt, TFLAG_RWLOCK)) {
- switch_core_session_rwunlock(tech_pvt->session);
- switch_clear_flag_locked(tech_pvt, TFLAG_RWLOCK);
- }
- do_xfer_invite(session);
+ /*
+ nua_notify(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
+ SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK"),
+ SIPTAG_EVENT_STR(etmp),
+ TAG_END());
+ */
+ do_xfer_invite(session);
- }
- }
+ }
+ }
- done:
- if (exten && strchr(exten, '@')) {
- switch_safe_free(exten);
- }
- if (etmp) {
- switch_safe_free(etmp);
- }
- }
+ done:
+ if (exten && strchr(exten, '@')) {
+ switch_safe_free(exten);
+ }
+ if (etmp) {
+ switch_safe_free(etmp);
+ }
+
}
@@ -3977,251 +3960,249 @@
sip_t const *sip,
tagi_t tags[])
{
- switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
+ switch_core_session_t *session = NULL;
char key[128] = "";
sip_unknown_t *un;
+ private_object_t *tech_pvt = NULL;
+ switch_channel_t *channel = NULL;
+ sip_from_t const *from = sip->sip_from;
+ sip_to_t const *to = sip->sip_to;
+ char *displayname;
+ char *username, *to_username = NULL;
+ char *url_user = (char *) from->a_url->url_user;
+ char *to_user, *to_host, *to_port;
+ char *req_user, *req_host, *req_port;
+ char *contact_user, *contact_host, *contact_port;
+ char *via_rport, *via_host, *via_port;
+ char *from_port;
+ char uri[1024];
-
- if (!session) {
- if ((profile->pflags & PFLAG_AUTH_CALLS)) {
- if (handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key))) {
- return;
- }
- }
+ if ((profile->pflags & PFLAG_AUTH_CALLS)) {
+ if (handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key))) {
+ return;
+ }
+ }
- if ((session = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
- private_object_t *tech_pvt = NULL;
- switch_channel_t *channel = NULL;
- sip_from_t const *from = sip->sip_from;
- sip_to_t const *to = sip->sip_to;
- char *displayname;
- char *username, *to_username = NULL;
- char *url_user = (char *) from->a_url->url_user;
- char *to_user, *to_host, *to_port;
- char *req_user, *req_host, *req_port;
- char *contact_user, *contact_host, *contact_port;
- char *via_rport, *via_host, *via_port;
- char *from_port;
- char uri[1024];
-
- if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
- terminate_session(&session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
- return;
- }
+ if (!(session = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session Alloc Failed!\n");
+ return;
+ }
- if (!switch_strlen_zero(key)) {
- tech_pvt->key = switch_core_session_strdup(session, key);
- }
+ if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
+ terminate_session(&session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
+ return;
+ }
- to_user = (char *) to->a_url->url_user;
- to_host = (char *) to->a_url->url_host;
- if (!(to_port = (char *) to->a_url->url_port)) {
- to_port = "5060";
- }
+ if (!switch_strlen_zero(key)) {
+ tech_pvt->key = switch_core_session_strdup(session, key);
+ }
+
+ to_user = (char *) to->a_url->url_user;
+ to_host = (char *) to->a_url->url_host;
+ if (!(to_port = (char *) to->a_url->url_port)) {
+ to_port = "5060";
+ }
- if (switch_strlen_zero(to_user)) { /* if sofia doesnt parse the To: right, we'll have to do it */
- if ((to_user = sip_header_as_string(tech_pvt->home, (sip_header_t *) to))) {
- char *p;
- if (*to_user == '<') {
- to_user++;
- }
- if ((p = strchr((to_user += 4), '@'))) {
- *p++ = '\0';
- to_host = p;
- if ((p = strchr(to_host, '>'))) {
- *p = '\0';
- }
- }
- }
- }
+ if (switch_strlen_zero(to_user)) { /* if sofia doesnt parse the To: right, we'll have to do it */
+ if ((to_user = sip_header_as_string(tech_pvt->home, (sip_header_t *) to))) {
+ char *p;
+ if (*to_user == '<') {
+ to_user++;
+ }
+ if ((p = strchr((to_user += 4), '@'))) {
+ *p++ = '\0';
+ to_host = p;
+ if ((p = strchr(to_host, '>'))) {
+ *p = '\0';
+ }
+ }
+ }
+ }
- if (switch_strlen_zero(url_user)) {
- url_user = "service";
- }
+ if (switch_strlen_zero(url_user)) {
+ url_user = "service";
+ }
- if (!switch_strlen_zero(from->a_display)) {
- displayname = switch_core_session_strdup(session, (char *) from->a_display);
- if (*displayname == '"') {
- char *p;
+ if (!switch_strlen_zero(from->a_display)) {
+ displayname = switch_core_session_strdup(session, (char *) from->a_display);
+ if (*displayname == '"') {
+ char *p;
- displayname++;
- if ((p = strchr(displayname, '"'))) {
- *p = '\0';
- }
- }
- } else {
- displayname = url_user;
- }
+ displayname++;
+ if ((p = strchr(displayname, '"'))) {
+ *p = '\0';
+ }
+ }
+ } else {
+ displayname = url_user;
+ }
- if (!(username = switch_mprintf("%s@%s", url_user, (char *) from->a_url->url_host))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
- return;
- }
+ if (!(username = switch_mprintf("%s@%s", url_user, (char *) from->a_url->url_host))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+ return;
+ }
- if (profile->pflags & PFLAG_FULL_ID) {
- if (!(to_username = switch_mprintf("%s@%s:%s", (char *) to_user, (char *) to_host, to_port))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
- switch_safe_free(username);
- return;
- }
- }
+ if (profile->pflags & PFLAG_FULL_ID) {
+ if (!(to_username = switch_mprintf("%s@%s:%s", (char *) to_user, (char *) to_host, to_port))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+ switch_safe_free(username);
+ return;
+ }
+ }
- attach_private(session, profile, tech_pvt, username);
- switch_core_session_read_lock(session);
- switch_set_flag(tech_pvt, TFLAG_RWLOCK);
- channel = switch_core_session_get_channel(session);
- switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
- set_chat_hash(tech_pvt, sip);
+ attach_private(session, profile, tech_pvt, username);
+ channel = switch_core_session_get_channel(session);
+ switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
+ set_chat_hash(tech_pvt, sip);
- switch_channel_set_variable(channel, "sip_from_user", (char *) from->a_url->url_user);
- if (from->a_url->url_user && *from->a_url->url_user == '+') {
- switch_channel_set_variable(channel, "sip_from_user_stripped", (char *)(from->a_url->url_user+1));
- } else {
- switch_channel_set_variable(channel, "sip_from_user_stripped", (char *)from->a_url->url_user);
- }
- switch_channel_set_variable(channel, "sip_from_host", (char *) from->a_url->url_host);
+ switch_channel_set_variable(channel, "sip_from_user", (char *) from->a_url->url_user);
+ if (from->a_url->url_user && *from->a_url->url_user == '+') {
+ switch_channel_set_variable(channel, "sip_from_user_stripped", (char *)(from->a_url->url_user+1));
+ } else {
+ switch_channel_set_variable(channel, "sip_from_user_stripped", (char *)from->a_url->url_user);
+ }
+ switch_channel_set_variable(channel, "sip_from_host", (char *) from->a_url->url_host);
- if (!(from_port = (char *) from->a_url->url_port)) {
- from_port = "5060";
- }
+ if (!(from_port = (char *) from->a_url->url_port)) {
+ from_port = "5060";
+ }
- switch_channel_set_variable(channel, "sip_from_port", from_port);
+ switch_channel_set_variable(channel, "sip_from_port", from_port);
- snprintf(uri, sizeof(uri), "%s@%s:%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host, from_port);
- switch_channel_set_variable(channel, "sip_from_uri", uri);
+ snprintf(uri, sizeof(uri), "%s@%s:%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host, from_port);
+ switch_channel_set_variable(channel, "sip_from_uri", uri);
- switch_channel_set_variable(channel, "sip_to_user", to_user);
- switch_channel_set_variable(channel, "sip_to_host", to_host);
- switch_channel_set_variable(channel, "sip_to_port", to_port);
-
- snprintf(uri, sizeof(uri), "%s@%s:%s", to_user, to_host, to_port);
- switch_channel_set_variable(channel, "sip_to_uri", uri);
+ switch_channel_set_variable(channel, "sip_to_user", to_user);
+ switch_channel_set_variable(channel, "sip_to_host", to_host);
+ switch_channel_set_variable(channel, "sip_to_port", to_port);
+
+ snprintf(uri, sizeof(uri), "%s@%s:%s", to_user, to_host, to_port);
+ switch_channel_set_variable(channel, "sip_to_uri", uri);
- req_user = (char *) sip->sip_request->rq_url->url_user;
- req_host = (char *) sip->sip_request->rq_url->url_host;
- if (!(req_port = (char *) sip->sip_request->rq_url->url_port)) {
- req_port = "5060";
- }
+ req_user = (char *) sip->sip_request->rq_url->url_user;
+ req_host = (char *) sip->sip_request->rq_url->url_host;
+ if (!(req_port = (char *) sip->sip_request->rq_url->url_port)) {
+ req_port = "5060";
+ }
- switch_channel_set_variable(channel, "sip_req_user", req_user);
- switch_channel_set_variable(channel, "sip_req_host", req_host);
- switch_channel_set_variable(channel, "sip_req_port", req_port);
-
- contact_user = (char *) sip->sip_contact->m_url->url_user;
- contact_host = (char *) sip->sip_contact->m_url->url_host;
- if (!(contact_port = (char *) sip->sip_contact->m_url->url_port)) {
- contact_port = "5060";
- }
+ switch_channel_set_variable(channel, "sip_req_user", req_user);
+ switch_channel_set_variable(channel, "sip_req_host", req_host);
+ switch_channel_set_variable(channel, "sip_req_port", req_port);
+
+ contact_user = (char *) sip->sip_contact->m_url->url_user;
+ contact_host = (char *) sip->sip_contact->m_url->url_host;
+ if (!(contact_port = (char *) sip->sip_contact->m_url->url_port)) {
+ contact_port = "5060";
+ }
- switch_channel_set_variable(channel, "sip_contact_user", contact_user);
- switch_channel_set_variable(channel, "sip_contact_host", contact_host);
- switch_channel_set_variable(channel, "sip_contact_port", contact_port);
-
- via_host = (char *) sip->sip_via->v_host;
- if (!(via_port = (char *) sip->sip_via->v_port)) {
- via_port = "5060";
- }
- if (!(via_rport = (char *) sip->sip_via->v_rport)) {
- via_rport = "5060";
- }
+ switch_channel_set_variable(channel, "sip_contact_user", contact_user);
+ switch_channel_set_variable(channel, "sip_contact_host", contact_host);
+ switch_channel_set_variable(channel, "sip_contact_port", contact_port);
+
+ via_host = (char *) sip->sip_via->v_host;
+ if (!(via_port = (char *) sip->sip_via->v_port)) {
+ via_port = "5060";
+ }
+ if (!(via_rport = (char *) sip->sip_via->v_rport)) {
+ via_rport = "5060";
+ }
- switch_channel_set_variable(channel, "sip_via_host", via_host);
- switch_channel_set_variable(channel, "sip_via_port", via_port);
- switch_channel_set_variable(channel, "sip_via_rport", via_rport);
+ switch_channel_set_variable(channel, "sip_via_host", via_host);
+ switch_channel_set_variable(channel, "sip_via_port", via_port);
+ switch_channel_set_variable(channel, "sip_via_rport", via_rport);
- snprintf(uri, sizeof(uri), "%s@%s:%s", req_user, req_host, req_port);
- switch_channel_set_variable(channel, "sip_req_uri", uri);
+ snprintf(uri, sizeof(uri), "%s@%s:%s", req_user, req_host, req_port);
+ switch_channel_set_variable(channel, "sip_req_uri", uri);
- if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
- (char *) from->a_url->url_user,
- profile->dialplan,
- displayname,
- (char *) from->a_url->url_user,
- (char *) from->a_url->url_host,
- NULL,
- NULL,
- NULL,
- (char *)modname,
- (profile->context && !strcasecmp(profile->context, "_domain_")) ?
- (char *) from->a_url->url_host : profile->context,
- to_username ? to_username : (char *) to_user
- )) != 0) {
-
-
- for (un=sip->sip_unknown; un; un=un->un_next) {
- if (!strncasecmp(un->un_name, "Alert-Info", 10)) {
- if (!switch_strlen_zero(un->un_value)) {
- switch_channel_set_variable(channel, "alert_info", (char *)un->un_value);
- }
- // Loop thru Known Headers Here so we can do something with them
- } else if (!strncasecmp(un->un_name, "Remote-Party-ID", 15)) {
- int argc, x, screen = 1;
- char *mydata, *argv[10] = { 0 };
- if (!switch_strlen_zero(un->un_value)) {
- if ((mydata = strdup(un->un_value))) {
- argc = switch_separate_string(mydata, ';', argv, (sizeof(argv) / sizeof(argv[0])));
-
- // Do We really need this at this time
- // clid_uri = argv[0];
-
- for (x=1; x < argc && argv[x]; x++){
- // we dont need to do anything with party yet we should only be seeing party=calling here anyway
- // maybe thats a dangerous assumption bit oh well yell at me later
- // if (!strncasecmp(argv[x], "party", 5)) {
- // party = argv[x];
- // } else
- if (!strncasecmp(argv[x], "privacy=", 8)) {
- char *arg = argv[x] + 9;
-
- if (!strcasecmp(arg, "yes")) {
- switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
- } else if (!strcasecmp(arg, "full")) {
- switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
- } else if (!strcasecmp(arg, "name")) {
- switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
- } else if (!strcasecmp(arg, "number")) {
- switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
- } else {
- switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
- switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
- }
-
- } else if (!strncasecmp(argv[x], "screen=", 7) && screen > 0) {
- char *arg = argv[x] + 8;
- if (!strcasecmp(arg, "no")) {
- screen = 0;
- switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN);
- }
- }
- }
- free(mydata);
- }
- }
- break;
- }
- }
+ if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
+ (char *) from->a_url->url_user,
+ profile->dialplan,
+ displayname,
+ (char *) from->a_url->url_user,
+ (char *) from->a_url->url_host,
+ NULL,
+ NULL,
+ NULL,
+ (char *)modname,
+ (profile->context && !strcasecmp(profile->context, "_domain_")) ?
+ (char *) from->a_url->url_host : profile->context,
+ to_username ? to_username : (char *) to_user
+ )) != 0) {
- switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
- switch_safe_free(username);
- switch_safe_free(to_username);
- }
+
+ for (un=sip->sip_unknown; un; un=un->un_next) {
+ if (!strncasecmp(un->un_name, "Alert-Info", 10)) {
+ if (!switch_strlen_zero(un->un_value)) {
+ switch_channel_set_variable(channel, "alert_info", (char *)un->un_value);
+ }
+ // Loop thru Known Headers Here so we can do something with them
+ } else if (!strncasecmp(un->un_name, "Remote-Party-ID", 15)) {
+ int argc, x, screen = 1;
+ char *mydata, *argv[10] = { 0 };
+ if (!switch_strlen_zero(un->un_value)) {
+ if ((mydata = strdup(un->un_value))) {
+ argc = switch_separate_string(mydata, ';', argv, (sizeof(argv) / sizeof(argv[0])));
+
+ // Do We really need this at this time
+ // clid_uri = argv[0];
+
+ for (x=1; x < argc && argv[x]; x++){
+ // we dont need to do anything with party yet we should only be seeing party=calling here anyway
+ // maybe thats a dangerous assumption bit oh well yell at me later
+ // if (!strncasecmp(argv[x], "party", 5)) {
+ // party = argv[x];
+ // } else
+ if (!strncasecmp(argv[x], "privacy=", 8)) {
+ char *arg = argv[x] + 9;
+
+ if (!strcasecmp(arg, "yes")) {
+ switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
+ } else if (!strcasecmp(arg, "full")) {
+ switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
+ } else if (!strcasecmp(arg, "name")) {
+ switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
+ } else if (!strcasecmp(arg, "number")) {
+ switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
+ } else {
+ switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
+ switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
+ }
- if (!(tech_pvt->sofia_private = malloc(sizeof(*tech_pvt->sofia_private)))) {
- abort();
+ } else if (!strncasecmp(argv[x], "screen=", 7) && screen > 0) {
+ char *arg = argv[x] + 8;
+ if (!strcasecmp(arg, "no")) {
+ screen = 0;
+ switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN);
+ }
+ }
+ }
+ free(mydata);
+ }
+ }
+ break;
}
- memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
- tech_pvt->sofia_private->session = session;
- nua_handle_bind(nh, tech_pvt->sofia_private);
- }
- }
+ }
+
+ switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
+ switch_safe_free(username);
+ switch_safe_free(to_username);
+ }
+
+ if (!(tech_pvt->sofia_private = malloc(sizeof(*tech_pvt->sofia_private)))) {
+ abort();
+ }
+ memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
+ switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
+ nua_handle_bind(nh, tech_pvt->sofia_private);
+
}
static void sip_i_register(nua_t *nua,
@@ -4273,17 +4254,16 @@
}
static void sip_r_challenge(int status,
- char const *phrase,
- nua_t *nua,
- sofia_profile_t *profile,
- nua_handle_t *nh,
- sofia_private_t *sofia_private,
- sip_t const *sip,
- tagi_t tags[])
+ char const *phrase,
+ nua_t *nua,
+ sofia_profile_t *profile,
+ nua_handle_t *nh,
+ switch_core_session_t *session,
+ sip_t const *sip,
+ tagi_t tags[])
{
outbound_reg_t *oreg = NULL;
sip_www_authenticate_t const *authenticate = NULL;
- switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
char const *realm = NULL;
char *p = NULL, *duprealm = NULL, *qrealm = NULL;
char const *scheme = NULL;
@@ -4386,16 +4366,19 @@
{
struct private_object *tech_pvt = NULL;
auth_res_t auth_res = AUTH_FORBIDDEN;
- switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
+ switch_core_session_t *session = NULL;
+ if (sofia_private) {
+ if (!switch_strlen_zero(sofia_private->uuid)) {
- if (session) {
- if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
- /* too late */
- return;
- }
- tech_pvt = switch_core_session_get_private(session);
- }
+ if ((session = switch_core_session_locate(sofia_private->uuid))) {
+ tech_pvt = switch_core_session_get_private(session);
+ } else {
+ /* too late */
+ return;
+ }
+ }
+ }
if (status != 100 && status != 200) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d][%s] session: %s\n",
@@ -4432,122 +4415,73 @@
}
if (sip && (status == 401 || status == 407)) {
- sip_r_challenge(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ sip_r_challenge(status, phrase, nua, profile, nh, session, sip, tags);
goto done;
}
switch (event) {
case nua_r_shutdown:
- //sip_r_shutdown(status, phrase, nua, profile, nh, sofia_private, sip, tags);
- break;
-
case nua_r_get_params:
- //sip_r_get_params(status, phrase, nua, profile, nh, sofia_private, sip, tags);
- break;
-
case nua_r_invite:
- break;
-
+ break;
case nua_r_register:
sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
-
- case nua_r_unregister:
- //sip_r_unregister(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ case nua_r_unregister:
break;
-
- case nua_r_options:
- //sip_r_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
+ case nua_r_options:
break;
-
case nua_i_options:
sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
-
case nua_i_fork:
- //sip_i_fork(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
-
- case nua_i_invite:
- sip_i_invite(nua, profile, nh, sofia_private, sip, tags);
+ case nua_i_invite:
+ if (!session) {
+ sip_i_invite(nua, profile, nh, sofia_private, sip, tags);
+ }
break;
-
case nua_i_publish:
sip_i_publish(nua, profile, nh, sofia_private, sip, tags);
break;
-
case nua_i_register:
sip_i_register (nua, profile, nh, sofia_private, sip, tags);
break;
-
case nua_i_prack:
- //sip_i_prack(nua, profile, nh, sofia_private, sip, tags);
break;
-
case nua_i_state:
sip_i_state(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
-
- case nua_r_bye:
- //sip_r_bye(status, phrase, nua, profile, nh, sofia_private, sip, tags);
- break;
-
+ case nua_r_bye:
case nua_i_bye:
- //sip_i_bye(nua, profile, nh, sofia_private, sip, tags);
- break;
-
case nua_i_message:
sip_i_message(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
-
case nua_r_info:
- //sip_r_info(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
-
case nua_i_info:
sip_i_info(nua, profile, nh, session, sip, tags);
break;
-
case nua_r_refer:
- //sip_r_refer(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
-
case nua_i_refer:
- sip_i_refer(nua, profile, nh, sofia_private, sip, tags);
+ if (session) {
+ sip_i_refer(nua, profile, nh, session, sip, tags);
+ }
break;
-
-
- case nua_r_subscribe:
+ case nua_r_subscribe:
sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
-
case nua_i_subscribe:
sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
-
case nua_r_unsubscribe:
- //sip_r_unsubscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
- break;
-
case nua_r_publish:
- //sip_r_publish(status, phrase, nua, profile, nh, sofia_private, sip, tags);
- break;
case nua_r_message:
case nua_r_notify:
- break;
-
- case nua_i_notify:
- //sip_i_notify(nua, profile, nh, sofia_private, sip, tags);
- break;
-
+ case nua_i_notify:
case nua_i_cancel:
- //sip_i_cancel(nua, profile, nh, sofia_private, sip, tags);
- break;
-
case nua_i_error:
- //sip_i_error(nua, profile, nh, sofia_private, status, phrase, tags);
- break;
-
case nua_i_active:
case nua_i_ack:
case nua_i_terminated:
Modified: freeswitch/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c (original)
+++ freeswitch/trunk/src/switch_core.c Thu Dec 28 14:38:35 2006
@@ -67,10 +67,16 @@
uint32_t flags;
struct switch_media_bug *next;
};
-
+
+typedef enum {
+ SSF_NONE = 0,
+ SSF_DESTROYED = (1 << 0)
+} switch_session_flag_t;
+
struct switch_core_session {
uint32_t id;
char name[80];
+ switch_session_flag_t flags;
int thread_running;
switch_memory_pool_t *pool;
switch_channel_t *channel;
@@ -567,24 +573,22 @@
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_str)
{
- switch_core_session_t *session;
+ switch_core_session_t *session = NULL;
if (uuid_str) {
switch_mutex_lock(runtime.session_table_mutex);
if ((session = switch_core_hash_find(runtime.session_table, uuid_str))) {
/* Acquire a read lock on the session */
- if (switch_thread_rwlock_tryrdlock(session->rwlock) != SWITCH_STATUS_SUCCESS) {
+ if (switch_test_flag(session, SSF_DESTROYED) || switch_thread_rwlock_tryrdlock(session->rwlock) != SWITCH_STATUS_SUCCESS) {
/* not available, forget it */
session = NULL;
}
}
switch_mutex_unlock(runtime.session_table_mutex);
-
- /* if its not NULL, now it's up to you to rwunlock this */
- return session;
- } else {
- return NULL;
}
+
+ /* if its not NULL, now it's up to you to rwunlock this */
+ return session;
}
SWITCH_DECLARE(void) switch_core_session_hupall(switch_call_cause_t cause)
@@ -3232,6 +3236,14 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Close Channel %s\n", switch_channel_get_name((*session)->channel));
+ switch_mutex_lock(runtime.session_table_mutex);
+ switch_core_hash_delete(runtime.session_table, (*session)->uuid_str);
+ if (runtime.session_count) {
+ runtime.session_count--;
+ }
+ switch_set_flag((*session), SSF_DESTROYED);
+ switch_mutex_unlock(runtime.session_table_mutex);
+
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DESTROY) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data((*session)->channel, event);
switch_event_fire(&event);
@@ -3247,11 +3259,6 @@
apr_pool_destroy(pool);
pool = NULL;
- switch_mutex_lock(runtime.session_table_mutex);
- if (runtime.session_count) {
- runtime.session_count--;
- }
- switch_mutex_unlock(runtime.session_table_mutex);
}
SWITCH_DECLARE(switch_status_t) switch_core_hash_init(switch_hash_t **hash, switch_memory_pool_t *pool)
@@ -3342,11 +3349,8 @@
{
switch_core_session_t *session = obj;
session->thread = thread;
- snprintf(session->name, sizeof(session->name), "%u", session->id);
- switch_mutex_lock(runtime.session_table_mutex);
- session->id = runtime.session_id++;
- switch_core_hash_insert(runtime.session_table, session->uuid_str, session);
- switch_mutex_unlock(runtime.session_table_mutex);
+
+
switch_core_session_run(session);
switch_core_media_bug_remove_all(session);
@@ -3354,9 +3358,6 @@
switch_core_session_write_lock(session);
switch_core_session_rwunlock(session);
- switch_mutex_lock(runtime.session_table_mutex);
- switch_core_hash_delete(runtime.session_table, session->uuid_str);
- switch_mutex_unlock(runtime.session_table_mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Session %u (%s) Ended\n", session->id, switch_channel_get_name(session->channel));
switch_core_session_destroy(&session);
return NULL;
@@ -3479,9 +3480,13 @@
switch_thread_cond_create(&session->cond, session->pool);
switch_thread_rwlock_create(&session->rwlock, session->pool);
+ snprintf(session->name, sizeof(session->name), "%u", session->id);
switch_mutex_lock(runtime.session_table_mutex);
+ session->id = runtime.session_id++;
+ switch_core_hash_insert(runtime.session_table, session->uuid_str, session);
runtime.session_count++;
switch_mutex_unlock(runtime.session_table_mutex);
+
return session;
}
Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c (original)
+++ freeswitch/trunk/src/switch_ivr.c Thu Dec 28 14:38:35 2006
@@ -3308,12 +3308,12 @@
if (switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(peer_channel, CF_TRANSFER)) {
//switch_channel_hangup(peer_channel, SWITCH_CAUSE_NORMAL_CLEARING);
- switch_yield(2000000);
+ //switch_yield(2000000);
}
if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && switch_channel_test_flag(peer_channel, CF_TRANSFER)) {
//switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_CLEARING);
- switch_yield(2000000);
+ //switch_yield(2000000);
}
More information about the Freeswitch-svn
mailing list