[svn-commits] rmudgett: branch 1.4 r2170 - in /branches/1.4: pri_internal.h q931.c
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Mon Dec 20 23:12:15 UTC 2010
Author: rmudgett
Date: Mon Dec 20 17:12:10 2010
New Revision: 2170
URL: http://svnview.digium.com/svn/libpri?view=rev&rev=2170
Log:
Better HOLD/RETRIEVE collision handling.
The upper layer is now initiating HOLD/RETRIEVE signaling. These changes
are needed to help preserve the correct channel id after a collision.
Modified:
branches/1.4/pri_internal.h
branches/1.4/q931.c
Modified: branches/1.4/pri_internal.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_internal.h?view=diff&rev=2170&r1=2169&r2=2170
==============================================================================
--- branches/1.4/pri_internal.h (original)
+++ branches/1.4/pri_internal.h Mon Dec 20 17:12:10 2010
@@ -532,9 +532,9 @@
/*! \brief Incoming call transfer state. */
enum INCOMING_CT_STATE incoming_ct_state;
- /*! Call hold supplementary state. */
+ /*! Call hold supplementary state. Valid on master call record only. */
enum Q931_HOLD_STATE hold_state;
- /*! Call hold event timer */
+ /*! Call hold event timer. Valid on master call record only. */
int hold_timer;
int deflection_in_progress; /*!< CallDeflection for NT PTMP in progress. */
Modified: branches/1.4/q931.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/q931.c?view=diff&rev=2170&r1=2169&r2=2170
==============================================================================
--- branches/1.4/q931.c (original)
+++ branches/1.4/q931.c Mon Dec 20 17:12:10 2010
@@ -5572,6 +5572,7 @@
static void q931_hold_timeout(void *data)
{
struct q931_call *call = data;
+ struct q931_call *master = call->master_call;
struct pri *ctrl = call->pri;
if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
@@ -5579,16 +5580,23 @@
}
/* Ensure that the timer is deleted. */
- pri_schedule_del(ctrl, call->hold_timer);
- call->hold_timer = 0;
-
- UPDATE_HOLD_STATE(ctrl, call, Q931_HOLD_STATE_IDLE);
+ pri_schedule_del(ctrl, master->hold_timer);
+ master->hold_timer = 0;
+
+ /* Don't change the hold state if there was HOLD a collision. */
+ switch (master->hold_state) {
+ case Q931_HOLD_STATE_HOLD_REQ:
+ UPDATE_HOLD_STATE(ctrl, master, Q931_HOLD_STATE_IDLE);
+ break;
+ default:
+ break;
+ }
q931_clr_subcommands(ctrl);
ctrl->schedev = 1;
ctrl->ev.e = PRI_EVENT_HOLD_REJ;
ctrl->ev.hold_rej.channel = q931_encode_channel(call);
- ctrl->ev.hold_rej.call = call;
+ ctrl->ev.hold_rej.call = master;
ctrl->ev.hold_rej.cause = PRI_CAUSE_MESSAGE_TYPE_NONEXIST;
ctrl->ev.hold_rej.subcmds = &ctrl->subcmds;
}
@@ -5662,8 +5670,8 @@
}
pri_schedule_del(ctrl, call->hold_timer);
call->hold_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T_HOLD],
- q931_hold_timeout, call);
- if (send_message(ctrl, winner, Q931_HOLD, hold_ies)) {
+ q931_hold_timeout, winner);
+ if (!call->hold_timer || send_message(ctrl, winner, Q931_HOLD, hold_ies)) {
pri_schedule_del(ctrl, call->hold_timer);
call->hold_timer = 0;
return -1;
@@ -5764,33 +5772,38 @@
static void q931_retrieve_timeout(void *data)
{
struct q931_call *call = data;
+ struct q931_call *master = call->master_call;
struct pri *ctrl = call->pri;
- struct q931_call *winner;
if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
pri_message(ctrl, "Time-out waiting for RETRIEVE response\n");
}
/* Ensure that the timer is deleted. */
- pri_schedule_del(ctrl, call->hold_timer);
- call->hold_timer = 0;
-
- UPDATE_HOLD_STATE(ctrl, call, Q931_HOLD_STATE_CALL_HELD);
-
- winner = q931_find_winning_call(call);
- if (winner) {
+ pri_schedule_del(ctrl, master->hold_timer);
+ master->hold_timer = 0;
+
+ /* Don't change the hold state if there was RETRIEVE a collision. */
+ switch (master->hold_state) {
+ case Q931_HOLD_STATE_CALL_HELD:
+ case Q931_HOLD_STATE_RETRIEVE_REQ:
+ UPDATE_HOLD_STATE(ctrl, master, Q931_HOLD_STATE_CALL_HELD);
+
/* Call is still on hold so forget the channel. */
- winner->channelno = 0;/* No channel */
- winner->ds1no = 0;
- winner->ds1explicit = 0;
- winner->chanflags = 0;
+ call->channelno = 0;/* No channel */
+ call->ds1no = 0;
+ call->ds1explicit = 0;
+ call->chanflags = 0;
+ break;
+ default:
+ break;
}
q931_clr_subcommands(ctrl);
ctrl->schedev = 1;
ctrl->ev.e = PRI_EVENT_RETRIEVE_REJ;
ctrl->ev.retrieve_rej.channel = q931_encode_channel(call);
- ctrl->ev.retrieve_rej.call = call;
+ ctrl->ev.retrieve_rej.call = master;
ctrl->ev.retrieve_rej.cause = PRI_CAUSE_MESSAGE_TYPE_NONEXIST;
ctrl->ev.retrieve_rej.subcmds = &ctrl->subcmds;
}
@@ -5869,7 +5882,7 @@
winner->ds1no = (channel & 0xff00) >> 8;
winner->ds1explicit = (channel & 0x10000) >> 16;
winner->channelno = channel & 0xff;
- if (ctrl->localtype == PRI_NETWORK) {
+ if (ctrl->localtype == PRI_NETWORK && winner->channelno != 0xFF) {
winner->chanflags = FLAG_EXCLUSIVE;
} else {
winner->chanflags = FLAG_PREFERRED;
@@ -5881,8 +5894,8 @@
pri_schedule_del(ctrl, call->hold_timer);
call->hold_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T_RETRIEVE],
- q931_retrieve_timeout, call);
- if (send_message(ctrl, winner, Q931_RETRIEVE, retrieve_ies)) {
+ q931_retrieve_timeout, winner);
+ if (!call->hold_timer || send_message(ctrl, winner, Q931_RETRIEVE, retrieve_ies)) {
pri_schedule_del(ctrl, call->hold_timer);
call->hold_timer = 0;
@@ -8211,6 +8224,9 @@
master_call = c->master_call;
switch (master_call->hold_state) {
case Q931_HOLD_STATE_HOLD_REQ:
+ if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
+ pri_message(ctrl, "HOLD collision\n");
+ }
if (ctrl->localtype == PRI_NETWORK) {
/* The network ignores HOLD request on a hold collision. */
break;
@@ -8224,10 +8240,6 @@
res = Q931_RES_HAVEEVENT;
UPDATE_HOLD_STATE(ctrl, master_call, Q931_HOLD_STATE_HOLD_IND);
-
- /* Stop any T-HOLD timer from possible hold collision. */
- pri_schedule_del(ctrl, master_call->hold_timer);
- master_call->hold_timer = 0;
break;
default:
q931_send_hold_rej_msg(ctrl, c, PRI_CAUSE_WRONG_CALL_STATE);
@@ -8324,6 +8336,9 @@
master_call = c->master_call;
switch (master_call->hold_state) {
case Q931_HOLD_STATE_RETRIEVE_REQ:
+ if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
+ pri_message(ctrl, "RETRIEVE collision\n");
+ }
if (ctrl->localtype == PRI_NETWORK) {
/* The network ignores RETRIEVE request on a retrieve collision. */
break;
@@ -8338,10 +8353,6 @@
res = Q931_RES_HAVEEVENT;
UPDATE_HOLD_STATE(ctrl, master_call, Q931_HOLD_STATE_RETRIEVE_IND);
-
- /* Stop any T-RETRIEVE timer from possible retrieve collision. */
- pri_schedule_del(ctrl, master_call->hold_timer);
- master_call->hold_timer = 0;
break;
default:
q931_send_retrieve_rej_msg(ctrl, c, PRI_CAUSE_WRONG_CALL_STATE);
@@ -8383,6 +8394,8 @@
res = 0;
master_call = c->master_call;
switch (master_call->hold_state) {
+ case Q931_HOLD_STATE_CALL_HELD:
+ /* In this state likely because of a RETRIEVE collision. */
case Q931_HOLD_STATE_RETRIEVE_REQ:
UPDATE_HOLD_STATE(ctrl, master_call, Q931_HOLD_STATE_CALL_HELD);
More information about the svn-commits
mailing list