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:
parent
1f2d19e28e
commit
08442ff2c4
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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__);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue