[Freeswitch-svn] [commit] r2670 - in freeswitch/trunk/src: . mod/applications/mod_conference mod/endpoints/mod_sofia
Freeswitch SVN
anthm at freeswitch.org
Tue Sep 12 18:24:40 EDT 2006
Author: anthm
Date: Tue Sep 12 18:24:39 2006
New Revision: 2670
Modified:
freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
freeswitch/trunk/src/switch_core.c
Log:
add justinu's patch
Modified: freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c Tue Sep 12 18:24:39 2006
@@ -80,7 +80,8 @@
CFLAG_DYNAMIC = (1 << 1),
CFLAG_ENFORCE_MIN = (1 << 2),
CFLAG_DESTRUCT = (1 << 3),
- CFLAG_LOCKED = (1 << 4)
+ CFLAG_LOCKED = (1 << 4),
+ CFLAG_ANSWERED = (1 << 5)
} conf_flag_t;
typedef enum {
@@ -127,6 +128,7 @@
char *bad_pin_sound;
char *profile_name;
uint32_t flags;
+ switch_call_cause_t bridge_hangup_cause;
switch_mutex_t *flag_mutex;
uint32_t rate;
uint32_t interval;
@@ -645,7 +647,13 @@
for(imember = conference->members; imember; imember = imember->next) {
switch_channel_t *channel = switch_core_session_get_channel(imember->session);
- switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+ // 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);
+ 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);
}
@@ -698,12 +706,6 @@
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.buflen = sizeof(data);
write_frame.codec = &member->write_codec;
@@ -723,7 +725,20 @@
if (switch_core_session_dequeue_event(member->session, &event) == SWITCH_STATUS_SUCCESS) {
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)) {
switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
@@ -946,6 +961,15 @@
switch_clear_flag_locked(member, MFLAG_RUNNING);
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 */
while(switch_test_flag(member, MFLAG_ITHREAD)) {
switch_yield(1000);
@@ -2055,7 +2079,8 @@
cid_name,
cid_num,
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) {
caller_channel = switch_core_session_get_channel(session);
switch_channel_hangup(caller_channel, cause);
@@ -2319,7 +2344,9 @@
if (conference_outcall(conference, session, bridgeto, 60, NULL, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
goto done;
}
- }
+ } //else
+ // if we're not using "bridge:" set the conference answered flag
+ //switch_set_flag(conference, CFLAG_ANSWERED);
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Tue Sep 12 18:24:39 2006
@@ -532,14 +532,69 @@
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)
{
private_object_t *tech_pvt;
switch_channel_t *channel = NULL;
+ switch_call_cause_t cause;
+ int sip_cause;
channel = switch_core_session_get_channel(session);
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);
assert(tech_pvt != NULL);
@@ -547,14 +602,18 @@
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 (!switch_test_flag(tech_pvt, TFLAG_BYE)) {
if (switch_test_flag(tech_pvt, TFLAG_ANS)) {
nua_bye(tech_pvt->nh, TAG_END());
} else {
- nua_cancel(tech_pvt->nh, TAG_END());
+ 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_handle_bind(tech_pvt->nh, NULL);
@@ -565,8 +624,6 @@
switch_set_flag_locked(tech_pvt, TFLAG_BYE);
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SOFIA HANGUP\n");
-
return SWITCH_STATUS_SUCCESS;
}
@@ -1198,6 +1255,57 @@
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,
char const *phrase,
nua_t *nua,
@@ -1362,7 +1470,7 @@
case nua_callstate_terminated:
if (session) {
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;
}
@@ -1445,8 +1553,8 @@
tagi_t tags[])
{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d] [%s]\n",
- nua_event_name (event), status, phrase);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "channel [%s] event [%s] status [%d] [%s]\n",
+ session ? switch_channel_get_name(switch_core_session_get_channel(session)) : "null",nua_event_name (event), status, phrase);
switch (event) {
case nua_r_shutdown:
Modified: freeswitch/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c (original)
+++ freeswitch/trunk/src/switch_core.c Tue Sep 12 18:24:39 2006
@@ -2372,7 +2372,7 @@
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)));
}
More information about the Freeswitch-svn
mailing list