device state: Update the core to report ONHOLD if a channel is on hold
authorMatthew Jordan <mjordan@digium.com>
Thu, 24 Jul 2014 15:20:58 +0000 (15:20 +0000)
committerMatthew Jordan <mjordan@digium.com>
Thu, 24 Jul 2014 15:20:58 +0000 (15:20 +0000)
In Asterisk, it is possible for a device to have a status of ONHOLD. This is
not typically an easy thing to determine, as a channel being on hold is not
a direct channel state. Typically, this has to be calculated outside of the
core independently in channel drivers, notably, chan_sip and chan_pjsip. Both
of these channel drivers already have to calculate device state in a fashion
more complex than the core can handle, as they aggregate all state of all
channels associated with a peer/endpoint; they also independently track
whether or not one of those channels is currently on hold and mark the device
state appropriately.

In 12+, we now have the ability to report an AST_DEVICE_ONHOLD state for all
channels that defer their device state to the core. This is due to channel hold
state actually now being tracked on the channel itself. If a channel driver
defers its device state to the core (which many, such as DAHDI, IAX2, and
others do in most situations), the device state core already goes out to get a
channel associated with the device. As such, it can now also factor the channel
hold state in its calculation.

This patch adds this logic to the device state core. It also uses an existing
mapping between device state and channel state to handle more channel states.
chan_pjsip has been updated slightly as well to make use of this (as it was,
for some reason, reporting a channel state of BUSY as a device state of INUSE,
which feels slightly wrong).

Review: https://reviewboard.asterisk.org/r/3771/

ASTERISK-24038 #close

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419358 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_pjsip.c
main/devicestate.c

index f638a1e..8911b93 100644 (file)
@@ -872,17 +872,14 @@ static int chan_pjsip_devicestate(const char *data)
 
                snapshot = stasis_message_data(msg);
 
-               if (snapshot->state == AST_STATE_DOWN) {
-                       ast_devstate_aggregate_add(&aggregate, AST_DEVICE_NOT_INUSE);
-               } else if (snapshot->state == AST_STATE_RINGING) {
-                       ast_devstate_aggregate_add(&aggregate, AST_DEVICE_RINGING);
-               } else if ((snapshot->state == AST_STATE_UP) || (snapshot->state == AST_STATE_RING) ||
+               if (chan_pjsip_get_hold(snapshot->uniqueid)) {
+                       ast_devstate_aggregate_add(&aggregate, AST_DEVICE_ONHOLD);
+               } else {
+                       ast_devstate_aggregate_add(&aggregate, ast_state_chan2dev(snapshot->state));
+               }
+
+               if ((snapshot->state == AST_STATE_UP) || (snapshot->state == AST_STATE_RING) ||
                        (snapshot->state == AST_STATE_BUSY)) {
-                       if (chan_pjsip_get_hold(snapshot->uniqueid)) {
-                               ast_devstate_aggregate_add(&aggregate, AST_DEVICE_ONHOLD);
-                       } else {
-                               ast_devstate_aggregate_add(&aggregate, AST_DEVICE_INUSE);
-                       }
                        inuse++;
                }
        }
index 3580b1a..c4a57dd 100644 (file)
@@ -304,9 +304,12 @@ enum ast_device_state ast_parse_device_state(const char *device)
                return AST_DEVICE_UNKNOWN;
        }
 
-       res = (ast_channel_state(chan) == AST_STATE_RINGING) ? AST_DEVICE_RINGING : AST_DEVICE_INUSE;
-
-       chan = ast_channel_unref(chan);
+       if (ast_channel_hold_state(chan) == AST_CONTROL_HOLD) {
+               res = AST_DEVICE_ONHOLD;
+       } else {
+               res = ast_state_chan2dev(ast_channel_state(chan));
+       }
+       ast_channel_unref(chan);
 
        return res;
 }