Custom hints (DEVICE_STATE)

Hi,

I’d like to set custom device states such as the following regarding DND:

User wants to set DND on:

same => n,Set(DEVICE_STATE(Custom:DND${CALLERID(num)})=BUSY)

User wants to set DND off:

same => n,Set(DEVICE_STATE(Custom:DND${CALLERID(num)})=NOT_INUSE)

Now, if I define hints like so:

exten => _XXXX,hint,PJSIP/${EXTEN}&Custom:DND${EXTEN}

the DND/BUSY states will show up fine for all those endpoints that subscribe.

However, if an endpoint never registers and never enables/disables DND it can appear as IDLE/online instead of unavailable.

So, “core show hints” might show that EXTEN is in State:Unavailable if I DO NOT add Custom:DND${EXTEN} to “hint”, but it will show that EXTEN is in State:Idle if I do.
That means that any endpoint that subscribes to it will get an incorrect reading (online when it is not).

I really need to make sure the DND status is reflected in the device state (I don’t care for user presence/state). I read somewhere about PRESENCE_STATE and CustomPresence, but I might not need it (and I don’t necessarily have Digium devices).
All I need is that if a users sets DND on it’s device state should be set to BUSY, INUSE or ONHOLD or whichever the SIP/webrtc clients will see as “somewhat busy/unavailable”.

So it seems that if Custom:DND${EXTEN} is not explicitly set it will default to NOT_INUSE, correct?
I mean that if the hint is PJSIP/${EXTEN}&Custom:DND${EXTEN} and PJSIP/${EXTEN} is UNAVAILABLE or UNKNOWN and Custom:DND${EXTEN} is undefined then the overall hint will be NOT_INUSE and will show up as Idle with “core show hints”, correct?

In any case, how can one properly make use of custom hints as in my DND example?

Suppose I set this hint in the dialplan:

exten => _XXXX,hint,PJSIP/${EXTEN}&PJSIP/web${EXTEN}&PJSIP/webd${EXTEN}&Custom:DND${EXTEN}

Then I call a dialplan extension to print out the corresponding DEVICE_STATE values:

    -- Executing [devstatetest@default:3] NoOp("PJSIP/web1000-00000005", "7110: INVALID") in new stack
    -- Executing [devstatetest@default:4] NoOp("PJSIP/web1000-00000005", "web7110: INVALID") in new stack
    -- Executing [devstatetest@default:5] NoOp("PJSIP/web1000-00000005", "webd7110: INVALID") in new stack
    -- Executing [devstatetest@default:6] NoOp("PJSIP/web1000-00000005", "Custom7110: UNKNOWN") in new stack
    -- Executing [devstatetest@default:7] Hangup("PJSIP/web1000-00000005", "") in new stack

# asterisk -rx "core show hints" | grep 7110
shows that 7110’s state is:
State:Idle

Why is INVALID&INVALID&INVALID&UNKNOWN = Idle ?

Is it a bug or expected to be like this? Why?

Asterisk 18.10.0

I think it is actually a custom extension state and extension states don’t include UNKNOWN, presumably because there is no way of generating a SIP NOTIFY that reflects an UKNOWN state.

That’s presumably because it is the best available guess and translating it to, say, busy might result in a good device not being used.

INVALID gets translated to UNAVAILABLE, but you only need one available one to override that.

I don’t quite understand what you’re saying.
If I NoOp EXTENSION_STATE for 7110@default I DO get NOT_INUSE, but that’s because my default context has the hint I reported before:

exten => _XXXX,hint,PJSIP/${EXTEN}&PJSIP/web${EXTEN}&PJSIP/webd${EXTEN}&Custom:DND${EXTEN}

However, I am setting a custom DEVICE state with

same => n,Set(DEVICE_STATE(Custom:DND${CALLERID(num)})=$WHATEVER)

If it’s not explicitly set it defaults to UNKNOWN.
So that’s why I previously said that the hint line above should sort of “translate” to

exten => _XXXX,hint,INVALID&INVALID&INVALID&UNKNOWN

and that leads to NOT_INUSE…

This is only from a user’s point of view. I understand that from the source code you are deducing that when Custom: is UNKNOWN it is expected to translate to NOT_INUSE.

In any case, from an admin user’s point of view I’d like to know how to properly add a custom device state to hints.
I think my goal is pretty commonplace as all I want is for an endpoint to appear as “BUSY” when setting the custom device state appropriately. Otherwise the device state should be whatever the channel driver says (PJSIP in my case).

Obviously, the hint in my dialplan is “wrong”:

exten => _XXXX,hint,PJSIP/${EXTEN}&PJSIP/web${EXTEN}&PJSIP/webd${EXTEN}&Custom:DND${EXTEN}

So how would one go about “adding” the custom DND state so that whoever subscribes to an extension’s hint gets a “proper” reading – being that if DND then show as BUSY, otherwise check driver channel.

Am I making any sense, or am I dealing this the wrong way?

Thanks

The hint isn’t wrong, it just doesn’t work as you want it to and isn’t implemented to. It’s an over all aggregation of all device states. There is no “if DND is busy show as busy, otherwise use channel driver”.

Not according to this discussion. It’s not an aggregation of all device states because as shown in my previous posts the DEVICE_STATE of Custom: is UNKNOWN (so INVALID&UNKNOWN should not equate to NOT_INUSE). It is then somehow translated to an extension state of NOT_INUSE (that makes INVALID&NOT_INUSE equate to Idle in show core hints), but I find that to be confusing.

I guess I don’t understand why a default custom DEVICE STATE of UNKNOWN is actually treated as NOT_INUSE in a hint.

I’ll dwell on it, and see if I can use CustomPresence instead.

It is an aggregation. It’s an aggregation of the device state initially. The aggregation of “invalid and unknown” results in an aggregate value of unknown. This is because for one of the device states you can’t say if they’re in use, not in use, busy, etc. Invalid you know for sure is a no-go.

This aggregate value is then converted into extension state which has the following possible values:

not in use
in use
busy
unavailable
ringing

(And some combinations)

There is no unknown there explicitly, and since unknown means you don’t know the “safest” is to be not in use.

Is it true that NOTIFY presence events are not sent to UAs that are not Digium or Sangoma?

If so, why?

On the other hand, the wiki (Presence State - Asterisk Project - Asterisk Project Wiki) seems to state that:
“devices themselves (soft-phone or hardphone) could be modified to interpret the XML send out in the Presence State notification”

So does it mean that the presence state notification for CustomPresence is always sent out regardless of the Brand used?

I’m asking because I was hoping to use CustomPresence instead of Custom device states…

The information is not sent out in the NOTIFY to non-Digium/non-Sangoma. The code could be changed, but the endpoint would still have to be modified to parse the information and use it. It’s not sent because that is not defined in an RFC standard, so could cause problems for other endpoints if they don’t ignore it, and would be useless for anything not modified to support it.

I’m using mostly webrtc clients even though I do have some brands of hardphones.
A quick “hack” to force sending this type of notifications is to manually set the user agent string so it contains a substring of ‘digium’ or ‘sangoma’ (eg. ‘digium-compatible UA’).
The only thing it does is add a tuple in the presence tag:

 <tuple id="digium-presence">
  <status>
   <digium_presence type="available" />
  </status>
 </tuple>

If some endpoints/hardphones were incompatible I guess the only thing that could fail is the presence status on those endpoints only.