mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-06-08 05:54:45 +00:00
fix sofia (part 2) you'd better 'make sure'
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3860 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
905a48c85f
commit
968f4fccc3
@ -599,7 +599,8 @@ static int nua_notify_usage_shutdown(nua_handle_t *nh,
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ typedef struct sofia_profile sofia_profile_t;
|
||||
#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 @@ typedef enum {
|
||||
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 sofia_profile {
|
||||
|
||||
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_state(int status,
|
||||
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 @@ static void do_invite(switch_core_session_t *session)
|
||||
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 @@ static void do_xfer_invite(switch_core_session_t *session)
|
||||
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 int hangup_cause_to_sip(switch_call_cause_t cause) {
|
||||
|
||||
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 @@ static switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
||||
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 @@ static switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
||||
}
|
||||
|
||||
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 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
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,7 +2494,7 @@ static void sip_i_state(int status,
|
||||
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;
|
||||
@ -2513,6 +2502,16 @@ static void sip_i_state(int status,
|
||||
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),
|
||||
NUTAG_OFFER_RECV_REF(offer_recv),
|
||||
@ -2549,7 +2548,7 @@ static void sip_i_state(int status,
|
||||
}
|
||||
|
||||
if (status == 988) {
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch ((enum nua_callstate)ss_state) {
|
||||
@ -2591,7 +2590,7 @@ static void sip_i_state(int status,
|
||||
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 @@ static void sip_i_state(int status,
|
||||
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 @@ static void sip_i_state(int status,
|
||||
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 @@ static void sip_i_state(int status,
|
||||
|
||||
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 @@ static void sip_i_state(int status,
|
||||
}
|
||||
nua_handle_unref(bnh);
|
||||
}
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_channel_set_variable(channel, "endpoint_disposition", "NO CODECS");
|
||||
@ -2706,7 +2705,7 @@ static void sip_i_state(int status,
|
||||
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 @@ static void sip_i_state(int status,
|
||||
tech_pvt->nh2 = NULL;
|
||||
tech_choose_port(tech_pvt);
|
||||
activate_rtp(tech_pvt);
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (channel) {
|
||||
@ -2752,7 +2751,7 @@ static void sip_i_state(int status,
|
||||
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 @@ static void sip_i_state(int status,
|
||||
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 @@ static void sip_i_state(int status,
|
||||
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,10 +2793,6 @@ static void sip_i_state(int status,
|
||||
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);
|
||||
@ -2812,18 +2807,25 @@ static void sip_i_state(int status,
|
||||
|
||||
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_r_subscribe(int status,
|
||||
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,9 +3542,6 @@ static void sip_i_refer(nua_t *nua,
|
||||
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;
|
||||
@ -3550,7 +3549,6 @@ static void sip_i_refer(nua_t *nua,
|
||||
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;
|
||||
@ -3598,31 +3596,27 @@ static void sip_i_refer(nua_t *nua,
|
||||
}
|
||||
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;
|
||||
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))) {
|
||||
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 (!(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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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),
|
||||
@ -3631,35 +3625,33 @@ static void sip_i_refer(nua_t *nua,
|
||||
} 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));
|
||||
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 *bsession;
|
||||
switch_core_session_t *br_b_session;
|
||||
|
||||
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);
|
||||
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_core_session_get_uuid(b_private->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_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, bp_tech_pvt->local_sdp_audio_ip);
|
||||
tech_pvt->local_sdp_audio_port = bp_tech_pvt->local_sdp_audio_port;
|
||||
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, b_tech_pvt->remote_sdp_audio_ip);
|
||||
tech_pvt->remote_sdp_audio_port = b_tech_pvt->remote_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_core_session_rwunlock(br_b_session);
|
||||
}
|
||||
|
||||
switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER);
|
||||
@ -3671,20 +3663,23 @@ static void sip_i_refer(nua_t *nua,
|
||||
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 *asession;
|
||||
switch_core_session_t *a_session;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
if ((asession = switch_core_session_locate(br_a))) {
|
||||
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(asession);
|
||||
channel = switch_core_session_get_channel(a_session);
|
||||
|
||||
exten = switch_mprintf("sofia/%s/%s@%s:%s",
|
||||
profile->name,
|
||||
@ -3695,7 +3690,7 @@ static void sip_i_refer(nua_t *nua,
|
||||
|
||||
switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, rep);
|
||||
|
||||
if (switch_ivr_originate(asession,
|
||||
if (switch_ivr_originate(a_session,
|
||||
&tsession,
|
||||
&cause,
|
||||
exten,
|
||||
@ -3712,15 +3707,11 @@ static void sip_i_refer(nua_t *nua,
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_core_session_rwunlock(asession);
|
||||
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);
|
||||
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),
|
||||
@ -3754,12 +3745,12 @@ static void sip_i_refer(nua_t *nua,
|
||||
char *br;
|
||||
|
||||
if ((br = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE))) {
|
||||
switch_core_session_t *bsession;
|
||||
switch_core_session_t *b_session;
|
||||
|
||||
if ((bsession = switch_core_session_locate(br))) {
|
||||
if ((b_session = 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);
|
||||
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");
|
||||
@ -3770,10 +3761,6 @@ static void sip_i_refer(nua_t *nua,
|
||||
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,
|
||||
@ -3790,10 +3777,6 @@ static void sip_i_refer(nua_t *nua,
|
||||
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);
|
||||
|
||||
}
|
||||
@ -3806,7 +3789,7 @@ static void sip_i_refer(nua_t *nua,
|
||||
if (etmp) {
|
||||
switch_safe_free(etmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -3977,20 +3960,9 @@ static void sip_i_invite(nua_t *nua,
|
||||
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;
|
||||
|
||||
|
||||
if (!session) {
|
||||
|
||||
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;
|
||||
@ -4005,6 +3977,18 @@ static void sip_i_invite(nua_t *nua,
|
||||
char *from_port;
|
||||
char uri[1024];
|
||||
|
||||
|
||||
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))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session Alloc Failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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__);
|
||||
@ -4069,8 +4053,6 @@ static void sip_i_invite(nua_t *nua,
|
||||
}
|
||||
|
||||
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);
|
||||
@ -4218,10 +4200,9 @@ static void sip_i_invite(nua_t *nua,
|
||||
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(nh, tech_pvt->sofia_private);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void sip_i_register(nua_t *nua,
|
||||
@ -4277,13 +4258,12 @@ static void sip_r_challenge(int status,
|
||||
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[])
|
||||
{
|
||||
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,15 +4366,18 @@ static void event_callback(nua_event_t event,
|
||||
{
|
||||
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) {
|
||||
if ((session = switch_core_session_locate(sofia_private->uuid))) {
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
} else {
|
||||
/* too late */
|
||||
return;
|
||||
}
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
}
|
||||
}
|
||||
|
||||
if (status != 100 && status != 200) {
|
||||
@ -4432,122 +4415,73 @@ static void event_callback(nua_event_t event,
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
case nua_r_options:
|
||||
//sip_r_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
||||
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:
|
||||
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_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:
|
||||
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_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:
|
||||
|
@ -68,9 +68,15 @@ struct switch_media_bug {
|
||||
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(char *) switch_core_get_variable(char *varname)
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_hupall(switch_call_cause_t cause)
|
||||
@ -3232,6 +3236,14 @@ SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session
|
||||
|
||||
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 @@ SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session
|
||||
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 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t *thre
|
||||
{
|
||||
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 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t *thre
|
||||
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_DECLARE(switch_core_session_t *) switch_core_session_request(const switch
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -3308,12 +3308,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user