signalling refactoring for media etc

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3192 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-10-25 04:28:49 +00:00
parent 1f2d19e28e
commit 08442ff2c4
6 changed files with 213 additions and 112 deletions

View File

@ -281,6 +281,17 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *
#define switch_channel_answer(channel) switch_channel_perform_answer(channel, __FILE__, __FUNCTION__, __LINE__)
SWITCH_DECLARE(switch_status_t) switch_channel_perform_ringback(switch_channel_t *channel,
const char *file,
const char *func,
int line);
/*!
\brief Send Ringing message to a channel
\param channel channel to ring
\return SWITCH_STATUS_SUCCESS if successful
*/
#define switch_channel_ringback(channel) switch_channel_perform_ringback(channel, __FILE__, __FUNCTION__, __LINE__)
SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel_t *channel,
const char *file,

View File

@ -720,6 +720,7 @@ typedef enum {
SWITCH_CAUSE_MANDATORY_IE_LENGTH_ERROR = 103,
SWITCH_CAUSE_PROTOCOL_ERROR = 111,
SWITCH_CAUSE_INTERWORKING = 127,
SWITCH_CAUSE_ORIGINATOR_CANCEL = 487,
SWITCH_CAUSE_CRASH = 500,
SWITCH_CAUSE_SYSTEM_SHUTDOWN = 501,
SWITCH_CAUSE_LOSE_RACE = 502,

View File

@ -34,6 +34,15 @@
static const char modname[] = "mod_dptools";
static void ringback_function(switch_core_session_t *session, char *data)
{
switch_channel_t *channel;
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
switch_channel_ringback(channel);
}
static void transfer_function(switch_core_session_t *session, char *data)
{
int argc;
@ -253,13 +262,24 @@ static switch_api_interface_t presence_api_interface = {
/*.next */ &dptools_api_interface
};
static const switch_application_interface_t ringback_application_interface = {
/*.interface_name */ "ringback",
/*.application_function */ ringback_function,
/* long_desc */ "Indicate Ringback on a channel.",
/* short_desc */ "Indicate Ringback",
/* syntax */ "",
/*.next */ NULL
};
static const switch_application_interface_t set_application_interface = {
/*.interface_name */ "set",
/*.application_function */ set_function,
/* long_desc */ "Set a channel varaible for the channel calling the application.",
/* short_desc */ "Set a channel varaible",
/* syntax */ "<varname>=[<value>|_UNDEF_]",
/*.next */ NULL
/*.next */ &ringback_application_interface
};
static const switch_application_interface_t answer_application_interface = {

View File

@ -1078,53 +1078,55 @@ static switch_status_t sofia_on_execute(switch_core_session_t *session)
// map QSIG cause codes to SIP from RFC4497 section 8.4.1
static int hangup_cause_to_sip(switch_call_cause_t cause) {
switch (cause) {
case SWITCH_CAUSE_UNALLOCATED:
case SWITCH_CAUSE_NO_ROUTE_TRANSIT_NET:
case SWITCH_CAUSE_NO_ROUTE_DESTINATION:
return 404;
case SWITCH_CAUSE_USER_BUSY:
return 486;
case SWITCH_CAUSE_NO_USER_RESPONSE:
return 408;
case SWITCH_CAUSE_NO_ANSWER:
return 480;
case SWITCH_CAUSE_SUBSCRIBER_ABSENT:
return 480;
case SWITCH_CAUSE_CALL_REJECTED:
return 603;
case SWITCH_CAUSE_NUMBER_CHANGED:
case SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION:
return 410;
case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER:
return 502;
case SWITCH_CAUSE_INVALID_NUMBER_FORMAT:
return 484;
case SWITCH_CAUSE_FACILITY_REJECTED:
return 501;
case SWITCH_CAUSE_NORMAL_UNSPECIFIED:
return 480;
case SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION:
case SWITCH_CAUSE_NETWORK_OUT_OF_ORDER:
case SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE:
case SWITCH_CAUSE_SWITCH_CONGESTION:
return 503;
case SWITCH_CAUSE_OUTGOING_CALL_BARRED:
case SWITCH_CAUSE_INCOMING_CALL_BARRED:
case SWITCH_CAUSE_BEARERCAPABILITY_NOTAUTH:
return 403;
case SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL:
return 503;
case SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL:
return 488;
case SWITCH_CAUSE_FACILITY_NOT_IMPLEMENTED:
case SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED:
return 501;
case SWITCH_CAUSE_INCOMPATIBLE_DESTINATION:
return 503;
case SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE:
return 504;
default:
return 500;
case SWITCH_CAUSE_UNALLOCATED:
case SWITCH_CAUSE_NO_ROUTE_TRANSIT_NET:
case SWITCH_CAUSE_NO_ROUTE_DESTINATION:
return 404;
case SWITCH_CAUSE_USER_BUSY:
return 486;
case SWITCH_CAUSE_NO_USER_RESPONSE:
return 408;
case SWITCH_CAUSE_NO_ANSWER:
return 480;
case SWITCH_CAUSE_SUBSCRIBER_ABSENT:
return 480;
case SWITCH_CAUSE_CALL_REJECTED:
return 603;
case SWITCH_CAUSE_NUMBER_CHANGED:
case SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION:
return 410;
case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER:
return 502;
case SWITCH_CAUSE_INVALID_NUMBER_FORMAT:
return 484;
case SWITCH_CAUSE_FACILITY_REJECTED:
return 501;
case SWITCH_CAUSE_NORMAL_UNSPECIFIED:
return 480;
case SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION:
case SWITCH_CAUSE_NETWORK_OUT_OF_ORDER:
case SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE:
case SWITCH_CAUSE_SWITCH_CONGESTION:
return 503;
case SWITCH_CAUSE_OUTGOING_CALL_BARRED:
case SWITCH_CAUSE_INCOMING_CALL_BARRED:
case SWITCH_CAUSE_BEARERCAPABILITY_NOTAUTH:
return 403;
case SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL:
return 503;
case SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL:
return 488;
case SWITCH_CAUSE_FACILITY_NOT_IMPLEMENTED:
case SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED:
return 501;
case SWITCH_CAUSE_INCOMPATIBLE_DESTINATION:
return 503;
case SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE:
return 504;
case SWITCH_CAUSE_ORIGINATOR_CANCEL:
return 487;
default:
return 500;
}
}
@ -2033,60 +2035,64 @@ static uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t *sdp)
// map sip responses to QSIG cause codes ala RFC4497 section 8.4.4
static switch_call_cause_t sip_cause_to_freeswitch(int status) {
switch (status) {
case 200:
return SWITCH_CAUSE_NORMAL_CLEARING;
case 401:
case 402:
case 403:
case 407:
case 603:
return SWITCH_CAUSE_CALL_REJECTED;
case 404:
case 485:
case 604:
return SWITCH_CAUSE_UNALLOCATED;
case 408:
case 504:
return SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
case 410:
return SWITCH_CAUSE_NUMBER_CHANGED;
case 413:
case 414:
case 416:
case 420:
case 421:
case 423:
case 505:
case 513:
return SWITCH_CAUSE_INTERWORKING;
case 480:
return SWITCH_CAUSE_NO_USER_RESPONSE;
case 400:
case 481:
case 500:
case 503:
return SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE;
case 486:
case 600:
return SWITCH_CAUSE_USER_BUSY;
case 484:
return SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
case 488:
case 606:
return SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL;
case 502:
return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
case 405:
return SWITCH_CAUSE_SERVICE_UNAVAILABLE;
case 406:
case 415:
case 501:
return SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED;
case 482:
case 483:
return SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR;
default:
return SWITCH_CAUSE_NORMAL_UNSPECIFIED;
case 200:
return SWITCH_CAUSE_NORMAL_CLEARING;
case 401:
case 402:
case 403:
case 407:
case 603:
return SWITCH_CAUSE_CALL_REJECTED;
case 404:
case 485:
case 604:
return SWITCH_CAUSE_UNALLOCATED;
case 408:
case 504:
return SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
case 410:
return SWITCH_CAUSE_NUMBER_CHANGED;
case 413:
case 414:
case 416:
case 420:
case 421:
case 423:
case 505:
case 513:
return SWITCH_CAUSE_INTERWORKING;
case 480:
return SWITCH_CAUSE_NO_USER_RESPONSE;
case 400:
case 481:
case 500:
case 503:
return SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE;
case 486:
case 600:
return SWITCH_CAUSE_USER_BUSY;
case 484:
return SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
case 488:
case 606:
return SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL;
case 502:
return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
case 405:
return SWITCH_CAUSE_SERVICE_UNAVAILABLE;
case 406:
case 415:
case 501:
return SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED;
case 482:
case 483:
return SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR;
case 487:
return SWITCH_CAUSE_ORIGINATOR_CANCEL;
default:
return SWITCH_CAUSE_NORMAL_UNSPECIFIED;
}
}
@ -2280,7 +2286,9 @@ static void sip_i_state(int status,
char *uuid;
switch_core_session_t *other_session = NULL;
switch_channel_t *other_channel = NULL;
char st[80] = "";
tl_gets(tags,
NUTAG_CALLSTATE_REF(ss_state),
NUTAG_OFFER_RECV_REF(offer_recv),
@ -2560,6 +2568,8 @@ static void sip_i_state(int status,
nua_handle_destroy(tech_pvt->nh);
tech_pvt->nh = NULL;
} else {
snprintf(st, sizeof(st), "%d", status);
switch_channel_set_variable(channel, "sip_term_status", st);
terminate_session(&session, sip_cause_to_freeswitch(status), __LINE__);
}
}

View File

@ -87,6 +87,7 @@ static struct switch_cause_table CAUSE_CHART[] = {
{ "MANDATORY_IE_LENGTH_ERROR", SWITCH_CAUSE_MANDATORY_IE_LENGTH_ERROR },
{ "PROTOCOL_ERROR", SWITCH_CAUSE_PROTOCOL_ERROR },
{ "INTERWORKING", SWITCH_CAUSE_INTERWORKING },
{ "ORIGINATOR_CANCEL", SWITCH_CAUSE_ORIGINATOR_CANCEL },
{ "CRASH", SWITCH_CAUSE_CRASH },
{ "SYSTEM_SHUTDOWN", SWITCH_CAUSE_SYSTEM_SHUTDOWN },
{ "LOSE_RACE", SWITCH_CAUSE_LOSE_RACE },
@ -1018,6 +1019,40 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel
return status;
}
SWITCH_DECLARE(switch_status_t) switch_channel_perform_ringback(switch_channel_t *channel,
const char *file,
const char *func,
int line)
{
switch_core_session_message_t msg;
char *uuid = switch_core_session_get_uuid(channel->session);
switch_status_t status;
assert(channel != NULL);
if (channel->state >= CS_HANGUP) {
return SWITCH_STATUS_FALSE;
}
if (switch_channel_test_flag(channel, CF_ANSWERED)) {
return SWITCH_STATUS_SUCCESS;
}
if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
return SWITCH_STATUS_SUCCESS;
}
msg.message_id = SWITCH_MESSAGE_INDICATE_RINGING;
msg.from = channel->name;
status = switch_core_session_message_send(uuid, &msg);
if (status == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_ID_LOG, (char *) file, func, line, SWITCH_LOG_NOTICE, "Ringback %s!\n", channel->name);
}
return status;
}
SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *channel,
const char *file,
const char *func,

View File

@ -34,6 +34,11 @@
static const switch_state_handler_table_t audio_bridge_peer_state_handlers;
typedef enum {
IDX_CANCEL = -2,
IDX_NADA = -1
} abort_t;
SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, uint32_t ms)
{
switch_channel_t *channel;
@ -1715,12 +1720,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
switch_frame_t *read_frame = NULL;
switch_memory_pool_t *pool = NULL;
int r = 0, i, and_argc = 0, or_argc = 0;
int32_t idx = -1;
int32_t idx = IDX_NADA;
switch_codec_t write_codec = {0};
switch_frame_t write_frame = {0};
uint8_t err = 0, fdata[1024], pass = 0;
char *file = NULL, *key = NULL, *odata, *var;
switch_call_cause_t reason = SWITCH_CAUSE_UNALLOCATED;
uint8_t to = 0;
write_frame.data = fdata;
*bleg = NULL;
@ -1785,7 +1791,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
file = NULL;
key = NULL;
var = NULL;
to = 0;
and_argc = switch_separate_string(pipe_names[r], '&', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
for (i = 0; i < and_argc; i++) {
@ -1924,6 +1931,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
}
if ((time(NULL) - start) > (time_t)timelimit_sec) {
to++;
break;
}
switch_yield(1000);
@ -1965,9 +1973,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
}
}
}
while ((!caller_channel || switch_channel_ready(caller_channel)) &&
check_channel_status(peer_channels, peer_sessions, and_argc, &idx, file, key) && ((time(NULL) - start) < (time_t)timelimit_sec)) {
check_channel_status(peer_channels, peer_sessions, and_argc, &idx, file, key)) {
if ((to = ((time(NULL) - start) >= (time_t)timelimit_sec))) {
break;
}
if (session && or_argc == 1 && and_argc == 1) { /* when there is only 1 channel to call and bridge */
switch_core_session_message_t *message = NULL;
@ -2000,7 +2012,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
}
if (!switch_channel_ready(caller_channel)) {
idx = -2;
idx = IDX_CANCEL;
}
if (session && !switch_channel_test_flag(caller_channel, CF_NOMEDIA)) {
@ -2012,12 +2024,24 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
continue;
}
if (i != idx) {
switch_channel_hangup(peer_channels[i], SWITCH_CAUSE_LOSE_RACE);
if (idx == IDX_CANCEL) {
reason = SWITCH_CAUSE_ORIGINATOR_CANCEL;
} else {
if (to) {
reason = SWITCH_CAUSE_NO_ANSWER;
} else if (and_argc > 1) {
reason = SWITCH_CAUSE_LOSE_RACE;
} else {
reason = SWITCH_CAUSE_NO_ANSWER;
}
}
switch_channel_hangup(peer_channels[i], reason);
}
}
if (idx > -1) {
if (idx > IDX_NADA) {
peer_session = peer_sessions[idx];
peer_channel = peer_channels[idx];
} else {
@ -2068,13 +2092,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
}
if (caller_channel) {
if (idx == -2) {
if (idx == IDX_CANCEL) {
*cause = switch_channel_get_cause(caller_channel);
}
switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause));
}
if (idx == -2) {
if (idx == IDX_CANCEL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Cancelled by originator termination Cause: %d [%s]\n",
*cause, switch_channel_cause2str(*cause));
} else {