Do you want to know how to use a custom device state to control the lamp on a programmable key of an IP phone? In this article I explain how to set up the hints and make any number of IP phones subscribe to a custom device state and how to switch the custom status from within the Asterisk dial plan.
In later articles I plan to show how this can be put to a practical use. I will explain how to switch the state from an external script and use this to provide a shared voicemail box linked to a programmable key on several extension phones.
Does your version of Asterisk support custom device states?
The first step is to make sure Asterisk supports custom device states. Version 1.2 and all earlier versions did not support this feature. Version 1.6 does support it. If you have version 1.4 then it might or might not support the feature – it did not come as standard, but was available as a kind of after-sales upgrade. The module we are looking for is func_devstate.so and you should check that it is available on your Asterisk server before proceeding.
You can check if the module is present by typing the command “module show like devstate” at the Asterisk CLI (Command Line Interface). If the module is installed, you should see the following output:
Module Description Use Count func_devstate.so Gets or sets a device state in the dialp 0 1 modules loaded
A further check is to look for the Asterisk function that is exported by the devstate module. The function we are looking for is DEVICE_STATE. You can search for installed functions using a CLI command. To check for any function containing the word “STATE”, the command would be “core show functions like STATE”. You should see the following output:
Matching Custom Functions: ------------------------------------------------------------------------------- DEVICE_STATE DEVICE_STATE(device) Get or Set a device state EXTENSION_STATE EXTENSION_STATE(extension[@context] Get an extension's state 2 matching custom functions installed.
Using the DEVICE_STATE function
Custom devices are dynamically created when the dial plan assigns a value to one of them using the Set command. Each new custom device takes whatever name you choose when assigning the value – there is no pre-existing master list of custom devices and no list has to be explicitly created or maintained. This has advantages (simplicity) and disadvantages (typing errors in device names will not be trapped). Note, however, that there is a pre-defined list of states that can be assigned to a device – see below.
From the Asterisk CLI, you can view information about the DEVICE_STATE function by typing the command “core show function DEVICE_STATE”. This shows you how to set a state for a custom device called “lamp1” and it also shows a list of all the permitted state values that you may assign to a device. Depending on the make of IP phone you are using, different states will typically cause the lamp to go on continuously, to flash fast or slow or potentially even to change colour where that is an option. You should experiment to see what happens for different values, but remember what happens on a Snom may not be the same on a Grandstream, etc. The states available are:
UNKNOWN, NOT_INUSE, INUSE, BUSY, INVALID, UNAVAILABLE, RINGING, RINGINUSE, ONHOLD
For example, to assign the INUSE value to a custom device called OnLeave:
exten => _X.,n,Set(DEVICE_STATE(Custom:OnLeave)=INUSE)
Linking a device state to an Asterisk hint
Remote SIP devices, such as IP phones, use a subscribe-notify mechanism to monitor the status of a device on Asterisk. To do this they send a SUBSCRIBE request to Asterisk with an identification tag that must match an Asterisk hint. In other words, custom device states (and any other device state) can only be seen by using a hint in the dialplan. Hints are explained in more detail in my article here.
Adding the following to your dial plan would link the subscribe tag 6123 to the state of the custom device called OnLeave:
exten => 6123,hint,Custom:OnLeave
To be sure that the hint can be found, it is best to add it to the context that is normally used by the subscribing phone. This may be the “default” context or, if using Trixbox or FreePBX, it would usually be the “from-internal” context. To add a hint for your Trixbox or FreePBX extensions, you will have to edit the file /etc/asterisk/extensions_custom.conf and add a context called ext-local-custom and put the hint in that. It would look like this:
[ext-local-custom] ; Add hint to link to the Custom Device State exten => 6123,hint,Custom:OnLeave
The “tag” value of 6123 that was used for the example above is, in part, an arbitrary number. It must be unique, at least so no two hints use the same number in the same context. It must match the value you set on the subscribing device (usually that means the number assigned to the BLF programmable key on your IP phone). However, for reasons that should become apparent as you read on, your choice for this number may be influenced by your wish to not only activate a lamp on your IP phone, but to also make the key next to that lamp do something relevant and useful.
Setting up the BLF programmable key on the IP phone
BLF stands for Busy Lamp Field and the terminology is inherited from older phone systems where the operator could view the status of every extension and trunk on a display board. The board would be populated with an array of lamps, each representing one extension or one trunk line on the telephone system. The manufacturers of modern IP phones use BLF to describe the option that is available on programmable keys to make them subscribe (via SIP) to monitor the status of other extensions or other devices. This is the how you can link a programmable key and its associated lamp to a device state in Asterisk.
Setting up the IP phone should be very straightforward provided your phone has a spare programmable BLF key. Not all phones have directly programmable keys – for example the Linksys SPA942 has four line keys, but they cannot be re-assigned using the web interface. One of my favourite budget IP phones for use as an Asterisk extension is the Aastra 6731i – it has a total of 8 programmable keys although two of these are pre-assigned and harder to change, but that still leaves 6. Snom refer to them as Function Keys, but they are the same thing.
Each make of phone is different, but generally it should be straightforward to use the web interface of your phone, find the page where programmable keys are set and choose the key you want to set. Set the type as BLF and set the number (or value) to match the tag number used in the hint – 6123 in the examples above. There is often another field for each key where you can select the account or line. In almost all cases you should set this to be the account that is used to register the phone with Asterisk. Don’t forget to save the new settings and reboot the phone if needed (it is not usually necessary).
That should be sufficient. The phone will send a SUBSCRIBE request to Asterisk. Asterisk will match it to the hint which in turn links it to the custom state. You can check what subscriptions are active at the Asterisk command line interface using the command “sip show subscriptions”. It is also possible to see a list of all the hints – i.e. what you can subscribe to – using the CLI command “core show hints”. The last column in the output from this command is a column showing how many “Watchers” are subscribed to this hint. It is perfectly acceptable for more than one IP phone to subscribe to the same hint at the same time.
If you press the button on a BLF programmed key, it will place a call to the number that you assigned to the key. Since there is considerable flexibility in your choice for this number and further flexibility in the Asterisk dial plans to respond to a dialled number, you should be able to configure the system so the action of the key is sensibly linked to the activation of the lamp. One example is for the lamp to show that there are messages waiting in a shared voicemail box and the key is used to access the messages in the box. Details of how to do this are now available in a 2-part article on this site – click here for part 1.