Detecting if a channel is on hold

I’m constructing “pickup from hold” feature. I have it mostly build using some channel parsing via AMI (with CoreShowChannels) followed by an AMI Bridge command. I would like to add a restriction where you can only bridge a channel that is on hold (to prevent someone from accidentally pulling a live call where people are talking).

However, there seems to be no way to tell whether a channel is on hold or not. Viewing the channel status of the held call always yields “AST_STATE_UP”, which is indistinguishable from a non-held channel.

How can I determine which channels are on hold? Thanks.

How do you define on hold?

What channel technology are you using.

Either it can’t be done without source code changes, or it can only be done by running asterisk -rx to issue a CLI command and analysing the result.

You can look at the peers (not the channels).

Issue the “ExtensionState” in the AMI. Something like:

Action: ExtensionState Exten: 100 Context: local-extensions

You get a state code back (among other things):
-1 = Extension not found
0 = Idle
1 = In Use
2 = Busy
4 = Unavailable
8 = Ringing
16 = On Hold <- Here we go!

All meanings fo on hold that Asterisk knows about relate to channels, not devices.

DEVICE_STATE reports on AST_DEVICE values, defined in devicestate.h, but the ones the OP is interested in are the AST_STATE values in channelstate.h.

For SIP, although an AST_DEVICE_ONHOLD status can be retured, it actually reflects a channel status (in the private data structure, so it is specific to SIP). This reflects the p->onhold value, which indicates that the device attached to the channel has requested a hold. There is no equivalent status where Asterisk is issuing a hold, and for SIP, Asterisk doesn’t physically issue the hold, but only generates music on hold.

It is possible that ONHOLD is an AST_DEVICE_ value, because many dahdi channels are generate (one Asterisk channel for each device channel). That is not the case for SIP.