add justinu's patch
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2670 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
56827bc9ec
commit
387fdc5311
|
@ -80,7 +80,8 @@ typedef enum {
|
||||||
CFLAG_DYNAMIC = (1 << 1),
|
CFLAG_DYNAMIC = (1 << 1),
|
||||||
CFLAG_ENFORCE_MIN = (1 << 2),
|
CFLAG_ENFORCE_MIN = (1 << 2),
|
||||||
CFLAG_DESTRUCT = (1 << 3),
|
CFLAG_DESTRUCT = (1 << 3),
|
||||||
CFLAG_LOCKED = (1 << 4)
|
CFLAG_LOCKED = (1 << 4),
|
||||||
|
CFLAG_ANSWERED = (1 << 5)
|
||||||
} conf_flag_t;
|
} conf_flag_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -127,6 +128,7 @@ struct conference_obj {
|
||||||
char *bad_pin_sound;
|
char *bad_pin_sound;
|
||||||
char *profile_name;
|
char *profile_name;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
switch_call_cause_t bridge_hangup_cause;
|
||||||
switch_mutex_t *flag_mutex;
|
switch_mutex_t *flag_mutex;
|
||||||
uint32_t rate;
|
uint32_t rate;
|
||||||
uint32_t interval;
|
uint32_t interval;
|
||||||
|
@ -645,7 +647,13 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
|
||||||
|
|
||||||
for(imember = conference->members; imember; imember = imember->next) {
|
for(imember = conference->members; imember; imember = imember->next) {
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(imember->session);
|
switch_channel_t *channel = switch_core_session_get_channel(imember->session);
|
||||||
|
// add this little bit to preserve the bridge cause code in case of an early media call that
|
||||||
|
// never answers
|
||||||
|
if (switch_test_flag(conference, CFLAG_ANSWERED))
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||||
|
else
|
||||||
|
// put actual cause code from outbound channel hangup here
|
||||||
|
switch_channel_hangup(channel, conference->bridge_hangup_cause);
|
||||||
switch_clear_flag_locked(imember, MFLAG_RUNNING);
|
switch_clear_flag_locked(imember, MFLAG_RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,12 +706,6 @@ static void conference_loop(conference_member_t *member)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
|
||||||
/* Answer the channel */
|
|
||||||
switch_channel_answer(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare the write frame */
|
|
||||||
write_frame.data = data;
|
write_frame.data = data;
|
||||||
write_frame.buflen = sizeof(data);
|
write_frame.buflen = sizeof(data);
|
||||||
write_frame.codec = &member->write_codec;
|
write_frame.codec = &member->write_codec;
|
||||||
|
@ -723,7 +725,20 @@ static void conference_loop(conference_member_t *member)
|
||||||
if (switch_core_session_dequeue_event(member->session, &event) == SWITCH_STATUS_SUCCESS) {
|
if (switch_core_session_dequeue_event(member->session, &event) == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_event_destroy(&event);
|
switch_event_destroy(&event);
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||||
|
// test to see if outbound channel has answered
|
||||||
|
if (switch_channel_test_flag(channel, CF_ANSWERED) && !switch_test_flag(member->conference, CFLAG_ANSWERED)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Outbound conference channel answered, setting CFLAG_ANSWERED");
|
||||||
|
switch_set_flag(member->conference, CFLAG_ANSWERED);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (switch_test_flag(member->conference, CFLAG_ANSWERED) && !switch_channel_test_flag(channel, CF_ANSWERED)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CLFAG_ANSWERED set, answering inbound channel\n");
|
||||||
|
switch_channel_answer(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (switch_channel_has_dtmf(channel)) {
|
if (switch_channel_has_dtmf(channel)) {
|
||||||
switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
|
switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
|
||||||
|
|
||||||
|
@ -946,6 +961,15 @@ static void conference_loop(conference_member_t *member)
|
||||||
switch_clear_flag_locked(member, MFLAG_RUNNING);
|
switch_clear_flag_locked(member, MFLAG_RUNNING);
|
||||||
switch_core_timer_destroy(&timer);
|
switch_core_timer_destroy(&timer);
|
||||||
|
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Channel leaving conference, cause: %s\n",
|
||||||
|
switch_channel_cause2str(switch_channel_get_cause(channel)));
|
||||||
|
|
||||||
|
// if it's an outbound channel, store the release cause in the conference struct, we might need it
|
||||||
|
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||||
|
member->conference->bridge_hangup_cause = switch_channel_get_cause(channel);
|
||||||
|
}
|
||||||
|
|
||||||
/* Wait for the input thead to end */
|
/* Wait for the input thead to end */
|
||||||
while(switch_test_flag(member, MFLAG_ITHREAD)) {
|
while(switch_test_flag(member, MFLAG_ITHREAD)) {
|
||||||
switch_yield(1000);
|
switch_yield(1000);
|
||||||
|
@ -2055,7 +2079,8 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
|
||||||
cid_name,
|
cid_name,
|
||||||
cid_num,
|
cid_num,
|
||||||
NULL) != SWITCH_STATUS_SUCCESS) {
|
NULL) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create outgoing channel, cause: %s\n",
|
||||||
|
switch_channel_cause2str(cause));
|
||||||
if (session) {
|
if (session) {
|
||||||
caller_channel = switch_core_session_get_channel(session);
|
caller_channel = switch_core_session_get_channel(session);
|
||||||
switch_channel_hangup(caller_channel, cause);
|
switch_channel_hangup(caller_channel, cause);
|
||||||
|
@ -2319,7 +2344,9 @@ static void conference_function(switch_core_session_t *session, char *data)
|
||||||
if (conference_outcall(conference, session, bridgeto, 60, NULL, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
|
if (conference_outcall(conference, session, bridgeto, 60, NULL, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
} //else
|
||||||
|
// if we're not using "bridge:" set the conference answered flag
|
||||||
|
//switch_set_flag(conference, CFLAG_ANSWERED);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -532,14 +532,69 @@ static switch_status_t sofia_on_execute(switch_core_session_t *session)
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// map QSIG cause codes to SIP ala RFC4497
|
||||||
|
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_CALL_REJECTED:
|
||||||
|
return 603;
|
||||||
|
case SWITCH_CAUSE_NUMBER_CHANGED:
|
||||||
|
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:
|
||||||
|
return 501;
|
||||||
|
case SWITCH_CAUSE_INCOMPATIBLE_DESTINATION:
|
||||||
|
return 503;
|
||||||
|
case SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE:
|
||||||
|
return 504;
|
||||||
|
default:
|
||||||
|
return 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
static switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
||||||
{
|
{
|
||||||
private_object_t *tech_pvt;
|
private_object_t *tech_pvt;
|
||||||
switch_channel_t *channel = NULL;
|
switch_channel_t *channel = NULL;
|
||||||
|
switch_call_cause_t cause;
|
||||||
|
int sip_cause;
|
||||||
|
|
||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
assert(channel != NULL);
|
assert(channel != NULL);
|
||||||
|
|
||||||
|
cause = switch_channel_get_cause(channel);
|
||||||
|
sip_cause = hangup_cause_to_sip(cause);
|
||||||
|
|
||||||
tech_pvt = (private_object_t *) switch_core_session_get_private(session);
|
tech_pvt = (private_object_t *) switch_core_session_get_private(session);
|
||||||
assert(tech_pvt != NULL);
|
assert(tech_pvt != NULL);
|
||||||
|
|
||||||
|
@ -547,13 +602,17 @@ static switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
||||||
|
|
||||||
su_home_deinit(tech_pvt->home);
|
su_home_deinit(tech_pvt->home);
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Channel %s hanging up, cause: %s, SIP response: %d\n",
|
||||||
|
switch_channel_get_name(channel), switch_channel_cause2str(cause), sip_cause);
|
||||||
|
|
||||||
if (tech_pvt->nh) {
|
if (tech_pvt->nh) {
|
||||||
if (!switch_test_flag(tech_pvt, TFLAG_BYE)) {
|
if (!switch_test_flag(tech_pvt, TFLAG_BYE)) {
|
||||||
if (switch_test_flag(tech_pvt, TFLAG_ANS)) {
|
if (switch_test_flag(tech_pvt, TFLAG_ANS)) {
|
||||||
nua_bye(tech_pvt->nh, TAG_END());
|
nua_bye(tech_pvt->nh, TAG_END());
|
||||||
} else {
|
} else {
|
||||||
|
if (switch_test_flag(tech_pvt, TFLAG_INBOUND))
|
||||||
|
nua_respond(tech_pvt->nh, sip_cause, NULL, TAG_END());
|
||||||
|
else
|
||||||
nua_cancel(tech_pvt->nh, TAG_END());
|
nua_cancel(tech_pvt->nh, TAG_END());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -565,8 +624,6 @@ static switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
||||||
switch_set_flag_locked(tech_pvt, TFLAG_BYE);
|
switch_set_flag_locked(tech_pvt, TFLAG_BYE);
|
||||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SOFIA HANGUP\n");
|
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1198,6 +1255,57 @@ static uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t *sdp)
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// map sip responses to QSIG cause codes ala RFC4497
|
||||||
|
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;
|
||||||
|
default:
|
||||||
|
return SWITCH_CAUSE_NORMAL_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void sip_i_state(int status,
|
static void sip_i_state(int status,
|
||||||
char const *phrase,
|
char const *phrase,
|
||||||
nua_t *nua,
|
nua_t *nua,
|
||||||
|
@ -1362,7 +1470,7 @@ static void sip_i_state(int status,
|
||||||
case nua_callstate_terminated:
|
case nua_callstate_terminated:
|
||||||
if (session) {
|
if (session) {
|
||||||
switch_set_flag_locked(tech_pvt, TFLAG_BYE);
|
switch_set_flag_locked(tech_pvt, TFLAG_BYE);
|
||||||
terminate_session(&session, SWITCH_CAUSE_NORMAL_CLEARING, __LINE__);
|
terminate_session(&session, sip_cause_to_freeswitch(status), __LINE__);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1445,8 +1553,8 @@ static void event_callback(nua_event_t event,
|
||||||
tagi_t tags[])
|
tagi_t tags[])
|
||||||
{
|
{
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d] [%s]\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "channel [%s] event [%s] status [%d] [%s]\n",
|
||||||
nua_event_name (event), status, phrase);
|
session ? switch_channel_get_name(switch_core_session_get_channel(session)) : "null",nua_event_name (event), status, phrase);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case nua_r_shutdown:
|
case nua_r_shutdown:
|
||||||
|
|
|
@ -2372,7 +2372,7 @@ static void switch_core_standard_on_init(switch_core_session_t *session)
|
||||||
static void switch_core_standard_on_hangup(switch_core_session_t *session)
|
static void switch_core_standard_on_hangup(switch_core_session_t *session)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Standard HANGUP %s\n", switch_channel_get_name(session->channel));
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Standard HANGUP %s, cause: %s\n", switch_channel_get_name(session->channel),switch_channel_cause2str(switch_channel_get_cause(session->channel)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue