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__) #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, SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel_t *channel,
const char *file, const char *file,

View File

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

View File

@ -34,6 +34,15 @@
static const char modname[] = "mod_dptools"; 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) static void transfer_function(switch_core_session_t *session, char *data)
{ {
int argc; int argc;
@ -253,13 +262,24 @@ static switch_api_interface_t presence_api_interface = {
/*.next */ &dptools_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 = { static const switch_application_interface_t set_application_interface = {
/*.interface_name */ "set", /*.interface_name */ "set",
/*.application_function */ set_function, /*.application_function */ set_function,
/* long_desc */ "Set a channel varaible for the channel calling the application.", /* long_desc */ "Set a channel varaible for the channel calling the application.",
/* short_desc */ "Set a channel varaible", /* short_desc */ "Set a channel varaible",
/* syntax */ "<varname>=[<value>|_UNDEF_]", /* syntax */ "<varname>=[<value>|_UNDEF_]",
/*.next */ NULL /*.next */ &ringback_application_interface
}; };
static const switch_application_interface_t answer_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 // map QSIG cause codes to SIP from RFC4497 section 8.4.1
static int hangup_cause_to_sip(switch_call_cause_t cause) { static int hangup_cause_to_sip(switch_call_cause_t cause) {
switch (cause) { switch (cause) {
case SWITCH_CAUSE_UNALLOCATED: case SWITCH_CAUSE_UNALLOCATED:
case SWITCH_CAUSE_NO_ROUTE_TRANSIT_NET: case SWITCH_CAUSE_NO_ROUTE_TRANSIT_NET:
case SWITCH_CAUSE_NO_ROUTE_DESTINATION: case SWITCH_CAUSE_NO_ROUTE_DESTINATION:
return 404; return 404;
case SWITCH_CAUSE_USER_BUSY: case SWITCH_CAUSE_USER_BUSY:
return 486; return 486;
case SWITCH_CAUSE_NO_USER_RESPONSE: case SWITCH_CAUSE_NO_USER_RESPONSE:
return 408; return 408;
case SWITCH_CAUSE_NO_ANSWER: case SWITCH_CAUSE_NO_ANSWER:
return 480; return 480;
case SWITCH_CAUSE_SUBSCRIBER_ABSENT: case SWITCH_CAUSE_SUBSCRIBER_ABSENT:
return 480; return 480;
case SWITCH_CAUSE_CALL_REJECTED: case SWITCH_CAUSE_CALL_REJECTED:
return 603; return 603;
case SWITCH_CAUSE_NUMBER_CHANGED: case SWITCH_CAUSE_NUMBER_CHANGED:
case SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION: case SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION:
return 410; return 410;
case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER: case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER:
return 502; return 502;
case SWITCH_CAUSE_INVALID_NUMBER_FORMAT: case SWITCH_CAUSE_INVALID_NUMBER_FORMAT:
return 484; return 484;
case SWITCH_CAUSE_FACILITY_REJECTED: case SWITCH_CAUSE_FACILITY_REJECTED:
return 501; return 501;
case SWITCH_CAUSE_NORMAL_UNSPECIFIED: case SWITCH_CAUSE_NORMAL_UNSPECIFIED:
return 480; return 480;
case SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION: case SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION:
case SWITCH_CAUSE_NETWORK_OUT_OF_ORDER: case SWITCH_CAUSE_NETWORK_OUT_OF_ORDER:
case SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE: case SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE:
case SWITCH_CAUSE_SWITCH_CONGESTION: case SWITCH_CAUSE_SWITCH_CONGESTION:
return 503; return 503;
case SWITCH_CAUSE_OUTGOING_CALL_BARRED: case SWITCH_CAUSE_OUTGOING_CALL_BARRED:
case SWITCH_CAUSE_INCOMING_CALL_BARRED: case SWITCH_CAUSE_INCOMING_CALL_BARRED:
case SWITCH_CAUSE_BEARERCAPABILITY_NOTAUTH: case SWITCH_CAUSE_BEARERCAPABILITY_NOTAUTH:
return 403; return 403;
case SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL: case SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL:
return 503; return 503;
case SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL: case SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL:
return 488; return 488;
case SWITCH_CAUSE_FACILITY_NOT_IMPLEMENTED: case SWITCH_CAUSE_FACILITY_NOT_IMPLEMENTED:
case SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED: case SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED:
return 501; return 501;
case SWITCH_CAUSE_INCOMPATIBLE_DESTINATION: case SWITCH_CAUSE_INCOMPATIBLE_DESTINATION:
return 503; return 503;
case SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE: case SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE:
return 504; return 504;
default: case SWITCH_CAUSE_ORIGINATOR_CANCEL:
return 500; 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 // map sip responses to QSIG cause codes ala RFC4497 section 8.4.4
static switch_call_cause_t sip_cause_to_freeswitch(int status) { static switch_call_cause_t sip_cause_to_freeswitch(int status) {
switch (status) { switch (status) {
case 200: case 200:
return SWITCH_CAUSE_NORMAL_CLEARING; return SWITCH_CAUSE_NORMAL_CLEARING;
case 401: case 401:
case 402: case 402:
case 403: case 403:
case 407: case 407:
case 603: case 603:
return SWITCH_CAUSE_CALL_REJECTED; return SWITCH_CAUSE_CALL_REJECTED;
case 404: case 404:
case 485: case 485:
case 604: case 604:
return SWITCH_CAUSE_UNALLOCATED; return SWITCH_CAUSE_UNALLOCATED;
case 408: case 408:
case 504: case 504:
return SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE; return SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
case 410: case 410:
return SWITCH_CAUSE_NUMBER_CHANGED; return SWITCH_CAUSE_NUMBER_CHANGED;
case 413: case 413:
case 414: case 414:
case 416: case 416:
case 420: case 420:
case 421: case 421:
case 423: case 423:
case 505: case 505:
case 513: case 513:
return SWITCH_CAUSE_INTERWORKING; return SWITCH_CAUSE_INTERWORKING;
case 480: case 480:
return SWITCH_CAUSE_NO_USER_RESPONSE; return SWITCH_CAUSE_NO_USER_RESPONSE;
case 400: case 400:
case 481: case 481:
case 500: case 500:
case 503: case 503:
return SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE; return SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE;
case 486: case 486:
case 600: case 600:
return SWITCH_CAUSE_USER_BUSY; return SWITCH_CAUSE_USER_BUSY;
case 484: case 484:
return SWITCH_CAUSE_INVALID_NUMBER_FORMAT; return SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
case 488: case 488:
case 606: case 606:
return SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL; return SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL;
case 502: case 502:
return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER; return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
case 405: case 405:
return SWITCH_CAUSE_SERVICE_UNAVAILABLE; return SWITCH_CAUSE_SERVICE_UNAVAILABLE;
case 406: case 406:
case 415: case 415:
case 501: case 501:
return SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED; return SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED;
case 482: case 482:
case 483: case 483:
return SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR; return SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR;
default: case 487:
return SWITCH_CAUSE_NORMAL_UNSPECIFIED; return SWITCH_CAUSE_ORIGINATOR_CANCEL;
default:
return SWITCH_CAUSE_NORMAL_UNSPECIFIED;
} }
} }
@ -2280,6 +2286,8 @@ static void sip_i_state(int status,
char *uuid; char *uuid;
switch_core_session_t *other_session = NULL; switch_core_session_t *other_session = NULL;
switch_channel_t *other_channel = NULL; switch_channel_t *other_channel = NULL;
char st[80] = "";
tl_gets(tags, tl_gets(tags,
NUTAG_CALLSTATE_REF(ss_state), NUTAG_CALLSTATE_REF(ss_state),
@ -2560,6 +2568,8 @@ static void sip_i_state(int status,
nua_handle_destroy(tech_pvt->nh); nua_handle_destroy(tech_pvt->nh);
tech_pvt->nh = NULL; tech_pvt->nh = NULL;
} else { } 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__); 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 }, { "MANDATORY_IE_LENGTH_ERROR", SWITCH_CAUSE_MANDATORY_IE_LENGTH_ERROR },
{ "PROTOCOL_ERROR", SWITCH_CAUSE_PROTOCOL_ERROR }, { "PROTOCOL_ERROR", SWITCH_CAUSE_PROTOCOL_ERROR },
{ "INTERWORKING", SWITCH_CAUSE_INTERWORKING }, { "INTERWORKING", SWITCH_CAUSE_INTERWORKING },
{ "ORIGINATOR_CANCEL", SWITCH_CAUSE_ORIGINATOR_CANCEL },
{ "CRASH", SWITCH_CAUSE_CRASH }, { "CRASH", SWITCH_CAUSE_CRASH },
{ "SYSTEM_SHUTDOWN", SWITCH_CAUSE_SYSTEM_SHUTDOWN }, { "SYSTEM_SHUTDOWN", SWITCH_CAUSE_SYSTEM_SHUTDOWN },
{ "LOSE_RACE", SWITCH_CAUSE_LOSE_RACE }, { "LOSE_RACE", SWITCH_CAUSE_LOSE_RACE },
@ -1018,6 +1019,40 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel
return status; 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, SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *channel,
const char *file, const char *file,
const char *func, const char *func,

View File

@ -34,6 +34,11 @@
static const switch_state_handler_table_t audio_bridge_peer_state_handlers; 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_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, uint32_t ms)
{ {
switch_channel_t *channel; 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_frame_t *read_frame = NULL;
switch_memory_pool_t *pool = NULL; switch_memory_pool_t *pool = NULL;
int r = 0, i, and_argc = 0, or_argc = 0; 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_codec_t write_codec = {0};
switch_frame_t write_frame = {0}; switch_frame_t write_frame = {0};
uint8_t err = 0, fdata[1024], pass = 0; uint8_t err = 0, fdata[1024], pass = 0;
char *file = NULL, *key = NULL, *odata, *var; char *file = NULL, *key = NULL, *odata, *var;
switch_call_cause_t reason = SWITCH_CAUSE_UNALLOCATED;
uint8_t to = 0;
write_frame.data = fdata; write_frame.data = fdata;
*bleg = NULL; *bleg = NULL;
@ -1785,6 +1791,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
file = NULL; file = NULL;
key = NULL; key = NULL;
var = NULL; var = NULL;
to = 0;
and_argc = switch_separate_string(pipe_names[r], '&', peer_names, (sizeof(peer_names) / sizeof(peer_names[0]))); and_argc = switch_separate_string(pipe_names[r], '&', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
@ -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) { if ((time(NULL) - start) > (time_t)timelimit_sec) {
to++;
break; break;
} }
switch_yield(1000); switch_yield(1000);
@ -1967,7 +1975,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
} }
while ((!caller_channel || switch_channel_ready(caller_channel)) && 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 */ 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; 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)) { if (!switch_channel_ready(caller_channel)) {
idx = -2; idx = IDX_CANCEL;
} }
if (session && !switch_channel_test_flag(caller_channel, CF_NOMEDIA)) { 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; continue;
} }
if (i != idx) { 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_session = peer_sessions[idx];
peer_channel = peer_channels[idx]; peer_channel = peer_channels[idx];
} else { } else {
@ -2068,13 +2092,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
} }
if (caller_channel) { if (caller_channel) {
if (idx == -2) { if (idx == IDX_CANCEL) {
*cause = switch_channel_get_cause(caller_channel); *cause = switch_channel_get_cause(caller_channel);
} }
switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause)); 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", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Cancelled by originator termination Cause: %d [%s]\n",
*cause, switch_channel_cause2str(*cause)); *cause, switch_channel_cause2str(*cause));
} else { } else {