adding transfer part 1
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2962 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
965f8b50d5
commit
513d5dbbdd
|
@ -129,7 +129,8 @@ typedef enum {
|
||||||
TFLAG_VAD = ( 1 << 13),
|
TFLAG_VAD = ( 1 << 13),
|
||||||
TFLAG_TIMER = (1 << 14),
|
TFLAG_TIMER = (1 << 14),
|
||||||
TFLAG_READY = (1 << 15),
|
TFLAG_READY = (1 << 15),
|
||||||
TFLAG_REINVITE = (1 << 16)
|
TFLAG_REINVITE = (1 << 16),
|
||||||
|
TFLAG_REFER = (1 << 17)
|
||||||
} TFLAGS;
|
} TFLAGS;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
@ -311,6 +312,14 @@ static void sip_i_state(int status,
|
||||||
sip_t const *sip,
|
sip_t const *sip,
|
||||||
tagi_t tags[]);
|
tagi_t tags[]);
|
||||||
|
|
||||||
|
|
||||||
|
static void sip_i_refer(nua_t *nua,
|
||||||
|
sofia_profile_t *profile,
|
||||||
|
nua_handle_t *nh,
|
||||||
|
sofia_private_t *sofia_private,
|
||||||
|
sip_t const *sip,
|
||||||
|
tagi_t tags[]);
|
||||||
|
|
||||||
static void sip_i_invite(nua_t *nua,
|
static void sip_i_invite(nua_t *nua,
|
||||||
sofia_profile_t *profile,
|
sofia_profile_t *profile,
|
||||||
nua_handle_t *nh,
|
nua_handle_t *nh,
|
||||||
|
@ -1794,11 +1803,24 @@ static void sip_i_state(int status,
|
||||||
break;
|
break;
|
||||||
case nua_callstate_completed:
|
case nua_callstate_completed:
|
||||||
if (tech_pvt && r_sdp) {
|
if (tech_pvt && r_sdp) {
|
||||||
|
sdp_parser_t *parser = sdp_parse(tech_pvt->home, r_sdp, (int)strlen(r_sdp), 0);
|
||||||
|
sdp_session_t *sdp;
|
||||||
|
uint8_t match = 0;
|
||||||
|
|
||||||
|
if (tech_pvt->num_codecs) {
|
||||||
|
if ((sdp = sdp_session(parser))) {
|
||||||
|
match = negotiate_sdp(session, sdp);
|
||||||
|
}
|
||||||
|
}
|
||||||
tech_choose_port(tech_pvt);
|
tech_choose_port(tech_pvt);
|
||||||
set_local_sdp(tech_pvt);
|
set_local_sdp(tech_pvt);
|
||||||
tech_set_codec(tech_pvt);
|
tech_set_codec(tech_pvt);
|
||||||
switch_set_flag_locked(tech_pvt, TFLAG_REINVITE);
|
switch_set_flag_locked(tech_pvt, TFLAG_REINVITE);
|
||||||
|
activate_rtp(tech_pvt);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Processing Reinvite\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Processing Reinvite\n");
|
||||||
|
if (parser) {
|
||||||
|
sdp_parser_free(parser);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case nua_callstate_ready:
|
case nua_callstate_ready:
|
||||||
|
@ -2130,6 +2152,107 @@ static uint8_t handle_register(nua_t *nua,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------*/
|
||||||
|
static void sip_i_refer(nua_t *nua,
|
||||||
|
sofia_profile_t *profile,
|
||||||
|
nua_handle_t *nh,
|
||||||
|
sofia_private_t *sofia_private,
|
||||||
|
sip_t const *sip,
|
||||||
|
tagi_t tags[])
|
||||||
|
{
|
||||||
|
/* Incoming refer */
|
||||||
|
sip_from_t const *from;
|
||||||
|
sip_to_t const *to;
|
||||||
|
sip_refer_to_t const *refer_to;
|
||||||
|
char *refer_to_str;
|
||||||
|
switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
private_object_t *tech_pvt = NULL;
|
||||||
|
#ifdef this_was_done
|
||||||
|
char *dest;
|
||||||
|
private_object_t *ntech_pvt;
|
||||||
|
switch_core_session_t *nsession;
|
||||||
|
switch_channel_t *channel, *nchannel;
|
||||||
|
switch_caller_profile_t *caller_profile = NULL, *outbound_profile = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
|
from = sip->sip_from;
|
||||||
|
to = sip->sip_to;
|
||||||
|
refer_to = sip->sip_refer_to;
|
||||||
|
|
||||||
|
|
||||||
|
if ((refer_to_str = sip_header_as_string(tech_pvt->home, (sip_header_t*)refer_to))) {
|
||||||
|
char *exten = switch_core_session_strdup(session, refer_to_str);
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if ((p = strchr(exten, ':'))) {
|
||||||
|
*p++ = '\0';
|
||||||
|
exten = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((p = strchr(exten, '@'))) {
|
||||||
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
|
char *br;
|
||||||
|
|
||||||
|
*p = '\0';
|
||||||
|
if ((br = switch_channel_get_variable(channel, "BRIDGETO"))) {
|
||||||
|
switch_core_session_t *bsession;
|
||||||
|
|
||||||
|
if ((bsession = switch_core_session_locate(br))) {
|
||||||
|
switch_ivr_session_transfer(bsession, exten, profile->dialplan, profile->context);
|
||||||
|
switch_core_session_rwunlock(bsession);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "refer to " URL_PRINT_FORMAT " from %s%s" URL_PRINT_FORMAT " to %s\n",
|
||||||
|
URL_PRINT_ARGS(from->a_url),
|
||||||
|
from->a_display ? from->a_display : "", from->a_display ? " " : "",
|
||||||
|
URL_PRINT_ARGS(from->a_url),
|
||||||
|
refer_to_str
|
||||||
|
);
|
||||||
|
|
||||||
|
su_free(tech_pvt->home, refer_to_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef this_was_done
|
||||||
|
if (!(nsession = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ntech_pvt = (struct private_object *) switch_core_session_alloc(nsession, sizeof(*ntech_pvt)))) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n");
|
||||||
|
terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
ntech_pvt->dest = switch_core_session_strdup(nsession, refer_to_str);
|
||||||
|
dest = ntech_pvt->dest + 4;
|
||||||
|
channel = switch_core_session_get_channel(session);
|
||||||
|
outbound_profile = switch_channel_get_caller_profile(channel);
|
||||||
|
nchannel = switch_core_session_get_channel(nsession);
|
||||||
|
attach_private(nsession, profile, ntech_pvt, dest);
|
||||||
|
caller_profile = switch_caller_profile_clone(nsession, outbound_profile);
|
||||||
|
caller_profile->destination_number = switch_core_session_strdup(nsession, dest);
|
||||||
|
switch_channel_set_caller_profile(nchannel, caller_profile);
|
||||||
|
switch_channel_set_flag(nchannel, CF_OUTBOUND);
|
||||||
|
switch_set_flag_locked(ntech_pvt, TFLAG_OUTBOUND);
|
||||||
|
switch_set_flag_locked(ntech_pvt, TFLAG_REFER);
|
||||||
|
switch_channel_set_state(nchannel, CS_INIT);
|
||||||
|
switch_channel_set_variable(channel, "endpoint_disposition", "OUTBOUND_REFER");
|
||||||
|
switch_core_session_thread_launch(nsession);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//done:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void sip_i_invite(nua_t *nua,
|
static void sip_i_invite(nua_t *nua,
|
||||||
sofia_profile_t *profile,
|
sofia_profile_t *profile,
|
||||||
nua_handle_t *nh,
|
nua_handle_t *nh,
|
||||||
|
@ -2138,6 +2261,7 @@ static void sip_i_invite(nua_t *nua,
|
||||||
tagi_t tags[])
|
tagi_t tags[])
|
||||||
{
|
{
|
||||||
switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
|
switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
|
||||||
|
//refer_handle_t *refer = sofia_private ? sofia_private->refer : NULL;
|
||||||
char key[128] = "";
|
char key[128] = "";
|
||||||
|
|
||||||
if (!session) {
|
if (!session) {
|
||||||
|
@ -2155,7 +2279,7 @@ static void sip_i_invite(nua_t *nua,
|
||||||
sip_to_t const *to = sip->sip_to;
|
sip_to_t const *to = sip->sip_to;
|
||||||
char *displayname;
|
char *displayname;
|
||||||
char username[256];
|
char username[256];
|
||||||
|
char *url_user = (char *) from->a_url->url_user;
|
||||||
|
|
||||||
if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
|
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");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
|
||||||
|
@ -2167,6 +2291,11 @@ static void sip_i_invite(nua_t *nua,
|
||||||
tech_pvt->key = switch_core_session_strdup(session, key);
|
tech_pvt->key = switch_core_session_strdup(session, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
displayname = switch_core_session_strdup(session, (char *) from->a_display);
|
||||||
if (*displayname == '"') {
|
if (*displayname == '"') {
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -2176,8 +2305,11 @@ static void sip_i_invite(nua_t *nua,
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
displayname = url_user;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(username, sizeof(username), "%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
|
snprintf(username, sizeof(username), "%s@%s", url_user, (char *) from->a_url->url_host);
|
||||||
attach_private(session, profile, tech_pvt, username);
|
attach_private(session, profile, tech_pvt, username);
|
||||||
|
|
||||||
snprintf(username, sizeof(username), "sip:%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
|
snprintf(username, sizeof(username), "sip:%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
|
||||||
|
@ -2231,6 +2363,7 @@ static void sip_r_register(int status,
|
||||||
{
|
{
|
||||||
outbound_reg_t *oreg = NULL;
|
outbound_reg_t *oreg = NULL;
|
||||||
sip_www_authenticate_t const *authenticate = NULL;
|
sip_www_authenticate_t const *authenticate = NULL;
|
||||||
|
switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
|
||||||
|
|
||||||
if (sofia_private) {
|
if (sofia_private) {
|
||||||
if (sofia_private->oreg) {
|
if (sofia_private->oreg) {
|
||||||
|
@ -2244,6 +2377,19 @@ static void sip_r_register(int status,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
private_object_t *tech_pvt;
|
||||||
|
if ((tech_pvt = switch_core_session_get_private(session)) && switch_test_flag(tech_pvt, TFLAG_REFER)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "received reply from refer\n");
|
||||||
|
|
||||||
|
if (status == 200) {
|
||||||
|
//crap
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!oreg) {
|
if (!oreg) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No authentication available!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No authentication available!\n");
|
||||||
if (sofia_private->oreg) {
|
if (sofia_private->oreg) {
|
||||||
|
@ -2304,6 +2450,7 @@ static void event_callback(nua_event_t event,
|
||||||
auth_res_t auth_res = AUTH_FORBIDDEN;
|
auth_res_t auth_res = AUTH_FORBIDDEN;
|
||||||
switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
|
switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
|
||||||
|
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
|
if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
|
||||||
/* too late */
|
/* too late */
|
||||||
|
@ -2312,10 +2459,9 @@ static void event_callback(nua_event_t event,
|
||||||
tech_pvt = switch_core_session_get_private(session);
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d][%s] session: %s\n",
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d][%s] %s\n",
|
|
||||||
nua_event_name (event), status, phrase,
|
nua_event_name (event), status, phrase,
|
||||||
session ? switch_channel_get_name(switch_core_session_get_channel(session)) : "no session"
|
session ? switch_channel_get_name(switch_core_session_get_channel(session)) : "n/a"
|
||||||
);
|
);
|
||||||
|
|
||||||
if ((profile->pflags & PFLAG_AUTH_ALL) && tech_pvt && tech_pvt->key && sip) {
|
if ((profile->pflags & PFLAG_AUTH_ALL) && tech_pvt && tech_pvt->key && sip) {
|
||||||
|
@ -2410,7 +2556,7 @@ static void event_callback(nua_event_t event,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nua_i_refer:
|
case nua_i_refer:
|
||||||
//sip_i_refer(nua, profile, nh, sofia_private, sip, tags);
|
sip_i_refer(nua, profile, nh, sofia_private, sip, tags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nua_r_subscribe:
|
case nua_r_subscribe:
|
||||||
|
@ -2539,6 +2685,7 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
|
||||||
NUTAG_AUTOALERT(0),
|
NUTAG_AUTOALERT(0),
|
||||||
//NUTAG_AUTOTRYING(0),
|
//NUTAG_AUTOTRYING(0),
|
||||||
NUTAG_ALLOW("REGISTER"),
|
NUTAG_ALLOW("REGISTER"),
|
||||||
|
NUTAG_ALLOW("REFER"),
|
||||||
SIPTAG_SUPPORTED_STR("100rel, precondition"),
|
SIPTAG_SUPPORTED_STR("100rel, precondition"),
|
||||||
TAG_END());
|
TAG_END());
|
||||||
|
|
||||||
|
@ -2770,7 +2917,7 @@ static switch_status_t config_sofia(int reload)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!profile->dialplan) {
|
if (!profile->dialplan) {
|
||||||
profile->dialplan = switch_core_strdup(profile->pool, "default");
|
profile->dialplan = switch_core_strdup(profile->pool, "XML");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!profile->sipdomain) {
|
if (!profile->sipdomain) {
|
||||||
|
|
|
@ -1372,6 +1372,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
||||||
msg.from = __FILE__;
|
msg.from = __FILE__;
|
||||||
switch_core_session_receive_message(session_a, &msg);
|
switch_core_session_receive_message(session_a, &msg);
|
||||||
|
|
||||||
|
switch_channel_set_variable(chan_a, "BRIDGETO", NULL);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a));
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a));
|
||||||
|
|
||||||
switch_channel_clear_flag(chan_a, CF_BRIDGED);
|
switch_channel_clear_flag(chan_a, CF_BRIDGED);
|
||||||
|
@ -2110,6 +2111,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
|
||||||
switch_core_session_receive_message(session, &msg);
|
switch_core_session_receive_message(session, &msg);
|
||||||
|
|
||||||
if (switch_core_session_read_lock(peer_session) == SWITCH_STATUS_SUCCESS) {
|
if (switch_core_session_read_lock(peer_session) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_channel_set_variable(caller_channel, "BRIDGETO", switch_core_session_get_uuid(peer_session));
|
||||||
|
switch_channel_set_variable(peer_channel, "BRIDGETO", switch_core_session_get_uuid(session));
|
||||||
|
|
||||||
switch_channel_set_private(peer_channel, "_bridge_", other_audio_thread);
|
switch_channel_set_private(peer_channel, "_bridge_", other_audio_thread);
|
||||||
switch_channel_set_state(peer_channel, CS_LOOPBACK);
|
switch_channel_set_state(peer_channel, CS_LOOPBACK);
|
||||||
audio_bridge_thread(NULL, (void *) this_audio_thread);
|
audio_bridge_thread(NULL, (void *) this_audio_thread);
|
||||||
|
|
Loading…
Reference in New Issue