Smart BLF
Smart BLF encompasses the behaviors of Digium's Rapid Dial keys that are available beginning with the 1.4 phone firmware. Â Compared to the previous behavior of the Rapid Dial keys, Smart BLF provides an entirely new world of configuration possibilities. Â This page contains both a complete description of the BLF Items capabilities as well as practical examples of Smart BLF usage with Sangoma phones.
BLF Items
BLF Items defines the absolute key location of contacts, including assignment to a fixed page or the assignment of blank keys, as well as the behavior of the key, specifically the actions taken by the phone when the key is pressed, optionally depending on the press duration as well as the state of the phone and the status of a target phone. Â Further, BLF Items allows control over the LED indicators and local-ringtone playback.
BLF Items is contained in a separate XML sheet that is retrieved by the Sangoma phone by URL. Â
For DPMA users, it is defined using the blf_items phone option, e.g.:
[myphone]
type=phone
...
blf_items=myblfitems.xml
...
Where the XML sheet, myblfitems.xml is retrieved from the file_url_prefix according to the phone's current network.
For XML configurations, it is configured using the <smart_blf> node, e.g.:
BLF Items in XML Provisioning Example
<?xml version="1.0">
<config>
    <smart_blf>
        <blf_items url="http://server.example.com/myblfitems.xml" network_id="mynetwork" md5="abcd123" />
    </smart_blf>
</config>Â |
Â
If a Smart BLF sheet is loaded onto a phone, then each contact to be mapped to a Rapid Dial key must be explicitly defined in that sheet. If a contact is not explicitly mapped to a key, it will not show up on a key. This behavior differs from the older, pre 1.4.0 firmware behavior of automatically attaching, in order, listed contacts to Rapid Dial keys.
Â
BLF Items XML skeleton
Because Contacts, BLF Items and Display Rules are constructed in XML, and because Sangoma phones do not point out XML errors to you, it is very important to verify the syntax of your XML before sending it to the phone. If your syntax is invalid, the XML file will fail to load, and you might wonder why your Contacts don't show up, your BLF Items don't seem to work, or your Display Rules are ignored. So, you should use an XML editor or some other tool (Chrome, xmllint, etc.) to verify your syntax before sending XML to the phone.
A basic BLF Items XML structure is defined here:
BLF Items Structure example
<config>
    <smart_blf>
        <blf_items>
            <blf_item>
                <behaviors>
                    <behavior />
                </behaviors>
                <indicators>
                    <indicator />
                </indicators>
            </blf_item>
        </blf_items>
    </smart_blf>
</config> |
And, a more complete example looks like:
BLF Item Example
BLF Item Element
Option | Values | Description |
---|---|---|
location | main, side, expansion | Defines the display panel for the BLF Item. D40, D45, D60, D62, D65, and D80 phones display only on main. D50 and D70 phones can display on main or side. Accounts on the main screen take precedence over BLF item locations. D65 phones with an attached expansion module can display on the expansion location. |
index | integer | Sets the position key for the BLF Item, top-down, beginning with 0. For D65 and D70 phones, assigning more than one BLF item to the same index number will cause subsequent assignments to appear on additional pages in the correct index slot. BLF items located on the main screen must begin in location 1 because the first slot, 0, is occupied by the phone's primary line. |
node | integer, 0-5 | When laying out BLF Items onto an expansion module, the node parameter is required and is used to place an item onto a specific node, rather than following normal paging rules. |
paging | Boolean, 0, 1 | Defaults to 1. If disabled, the item will remain static across all pages. The paging element is not used for expansion modules. |
contact_id | string | Maps this item to a Contact as derived from the "id" field of a contact from the loaded contacts XML file |
app_id | string | The identifier should be either one of the phone's default applications (contacts, voicemail, parking, status, queues) or should be the identifier of a user-loaded custom application. Used instead of contact_id to dedicate this item to loading an application into the foreground. |
blank | Boolean, 0,1 | Defaults to 0. If present, blanks out the item so that an empty BLF is loaded into the slot. Note that blank type keys do not have any contact_id or additional attributes associated with them. |
arg | string | Allows passing of data to apps that can consume it, such as the mcastpage app, to which the arg id of a multicast page broadcast can be passed. NOTE for |
Behaviors: Child element of <blf_item>
Behavior: Child element of <behaviors>
A behavior exists to define the operation of the phone when a particular Rapid Dial Key is pressed. Â More than one behavior may be defined for a particular BLF Item. Â Behaviors are processed top-down; so, less-specific behaviors should precede more-specific behaviors.
Option | Values | Description |
---|---|---|
phone_state | A valid phone_state as defined in the Phone States section | Defines the state of the local phone that must be matched for this behavior to be in effect |
target_status | unknown, idle, on_hold, ringing, on_the_phone | Defines the status of the watched device that must be matched for this behavior to be in effect |
press_action | An action id from the loaded contacts file | Specifies the action to be invoked, when the key is pressed for less than 2 seconds, if the behavior is in effect. |
press_function | dial, info, show_app, transfer, send_dtmf, none | Specifies the function to be invoked if the behavior is in effect. "dial" executes a new calls to the action. "info" retrieves the contact's info screen. "show_app" loads an application if the action calls an application. "transfer" executes a transfer to the action. "send_dtmf" plays in-call DTMF down the active channel - only if an active channel is available. "none" is used to specify that no action is to take place. |
long_press_action | An action id from the loaded contacts file | Specifies the action to be invoked, when the key is pressed for more than 2 seconds, if the behavior is in effect. |
long_press_function | dial, info, show_app, transfer, send_dtmf, none | Specifies the function to be invoked if the behavior is in effect. "dial" executes a new calls to the action. "info" retrieves the contact's info screen. "show" loads an application if the action calls an application. "transfer" executes a transfer to the action. "send_dtmf" plays in-call DTMF down the active channel - only if an active channel is available. "none" is used to specify that no action is to take place. Defaults to "info" |
Phone States
There are a number of valid Phone States as used by BLF Items Behaviors. Â Valid states and descriptions are listed in the following table:
Phone State | Description |
---|---|
idle | The phone is at rest / idle. There is no call state in which the phone is operating |
hold | A call is on Hold, and that call is selected in the call field |
hold/transfer | A call is on Hold, and the phone is in the Transfer state, e.g. the user has Answered a call and then pressed the Transfer key or has pressed Hold followed by the Transfer key. |
hold/preconference | A call is on Hold, and the phone is in the Pre-Conference state, e.g. the user has Answered a call and then pressed the Conference key. |
hold/conference | A Conference call is on hold, e.g. the user, while conducting a phone-based conference call, presses the Hold key, putting both conferenced parties on hold |
incoming | The phone is receiving a call and that call is selected in the call field, but the call has not yet been answered. |
incoming/transfer | The phone is receiving a call and the user has pressed the Transfer key prior to answering the call |
connected | The phone has an active call and no other operations are taking place |
connected/conference | The phone is in an active Conference call |
calling | The phone has placed a call to the target (the server) and the target has not yet answered |
dial | The phone is off-hook, prepared to dial, but no digits have been entered |
dialing | The phone is off-hook and digits have been entered |
failed | The server has rejected the call as invalid |
all | The default; a wildcard state that matches any other state |
Indicators: Child element of <blf_item>
Indicator: Child element of <indicators>
Option | Values | Description |
---|---|---|
target_status | unknown, idle, on_hold, ringing, on_the_phone | Defines the status of the watched device that must be matched for this indicator to be in effect. If undefined, all target_states will be matched. |
ring | Boolean | If true, causes the local phone to ring when the behavior is met |
ringtone_id | Alarm, Chimes, Digium, GuitarStrum, Jingle, Office2, Office, RotaryPhone, SteelDrum, Techno, Theme, Tweedle, Twinkle, Vibe, or one of ids from a custom-loaded ringtone | Specifies the ringtone to be played when the indicator is in effect. If unspecified, the phone's default ringtone will be used |
led_color | amber, green, red | Specifies the color to be applied to the line key LED if the indicator is in effect. Amber is not supported on EXP150M expansion modules. |
led_state | off, on, slow, fast | Specifies the LED blink state of the line key LED if the indicator is in effect. |
line_label_fgcolor | Hex color value, defaults to #BDBDBD | Specifies a hex color value for the color of the label text when this indicator is active. The default color value for text in rapid dial keys is #BDBDBD. Firmware 2.6.0 and greater, D6x phones only. |
line_label_bgcolor | Hex color value, defaults to #212121 | Specifies a hex color value for the color of the label background when this indicator is active. The default color value for the label background is #212121. Firmware 2.6.0 and greater, D6x phones only. |
Behavior Considerations
When creating behaviors, the following points should be taken into consideration.
Top Down Processing
Behaviors are processed top-down. Â Where one has the following:
Top-Down Example Collapse source
and where two behaviors, both for the same phone_state are defined, only the first behavior will operate when the state is true. Â The second behavior, because it was not loaded first, will be discarded.
But if I have two behaviors. one of which is more specific than the first, such as:
Top-Down, Add Specificity Example Collapse source
then, where the phone is in a state other than dial, the press_action will be callb.  When the phone is in the dial state only, the press_action will be callc.
Default Behaviors
Default behaviors are driven by default actions. Â If there are no behaviors defined, e.g.:
No Defined Behavior Example Collapse source
or if there are only behaviors defined for states in which the phone does not currently find itself, e.g. where a phone is actually in the idle state not the dial state:
Not Current State Default Behavior Example Collapse source
and where only a single action is configured for the contact 101 like:
Only One Action Example Collapse source
then, when pressed, the Rapid Dial key will perform the only listed action, 101 as that action will be treated as the default action, since no other actions exist.
Selective Behavior Enabling
If you want to default no behavior for an item, and only explicitly define limited behavior, it is best to first define none functions for all states, such as:
Selective Behavior Enabling Example Collapse source
Thus, the only state in which any action will be possible is the dial state.
Long-Press Function Default
The default behavior for long_press_action is info, so the information about a contact will always be loaded when a key is long_pressed unless the long_press_function is otherwise defined.
Use Cases
Call Pickup
Traditionally, Call Pickup within Asterisk is generally performed using a separate extension handler that, rather than dialing the target phone directly using the Dial() application, instead uses the Pickup() or PickupChan() application with an extension prefix. Â And, Call Pickup is only performed when the target phone is ringing. Â Otherwise, the target phone is dialed normally. Â Assuming 3-digit extensions, dialplan for this might look like:
Pickup Dialplan Example Collapse source
First, we've defined a normal pattern match 1XX - one, followed by two digits 0-9. Â If matched, Asterisk performs a dial to that SIP device.
Next, we've defined an extern pattern match on **1XX - all dialed patterns beginning with two * characters, followed by 1, then two more digits 0-9. Â In the case that it's matched, Asterisk will perform a pickup against the ringing extension, stripping off the first two ** characters.
To affect this, our Sangoma phone needs a contact that is configured with two actions: one, called 103 to dial the contact normally, and another called pickup that dials using a prefix.  The contact configuration thus looks like:
Pickup Contacts Example Collapse source
Here, note that we've created the actions 103 and pickupcall.  For 103, only 103 is dialed.  For pickupcall, phone will dial the ** prefix first, and then 103.
Next, we need to configure the behavior of a Rapid Dial key to affect the actions. Â Configuration for this resembles:
Pickup BLF Items Example Collapse source
Here, notice that we have defined two behaviors.  Because behaviors are processed top-down, we first define a behavior with press_action of 103 and press_function of dial.  This will cause the phone for all phone_states and all target_states (the implied behavior when not explicitly defining them) to call the 103 action. Â
Next, we define a behavior where the target_status is ringing, we've set the press_action to pickupcall (which is the identifier of the pickup action that we created for the Contact), and the press_function is set to dial.  Because we defined a pickup_action within the contact itself, and because we have a ringing target_status behavior, this will cause the D80 model phone to display a pickup activity card in its activity stream, beginning with firmware 1.8.0.
Thus, when Mark Spencer's phone is ringing, based on a subscription NOTIFY from Asterisk, and someone presses this Rapid Dial key, the phone will dial **103 into Asterisk, which will in turn call the Pickup() application.  And, when Mark Spencer's phone isn't ringing, and someone presses this Rapid Dial key, the phone will dial 103 into Asterisk, which will call the Dial() application and ring the phone normally.
Intercom
In the following example, we assume that users want to call another party as the standard action of pressing a Rapid Dial key, but that when a Rapid Dial key is long-pressed (held down for 3 seconds or more) and the target is idle, that the user wants to Intercom the target. Â
Assuming 3-digit extensions, dialplan for this might look like:
Intercom Dialplan Example Collapse source
Here, we've defined an extern pattern match on 1XX - all 3-digit dialed patterns beginning with 1 followed by two more digits 0-9.  In the case that it's matched, Asterisk will first perform a GotoIf() depending on the presence of an X-Digium-Call-Feature matching feature_intercom.  Where feature_intercom is matched, the dialplan jumps to the intercomcall label where a Dial is performed using a pre-dial handler to utilize the PJSIP_HEADER dislplan function that will add an Alert-Info header to the outgoing SIP INVITE before performing the Dial.  Otherwise, when feature_intercom is not matched, the dialplan jumps to the notintercomcall label and performs a regular Dial() without adding any special headers.
To affect this, our Sangoma phone needs a contact that is configured with two actions: one, called 103 to dial the contact normally, and another called intercom that dials with a special header.  The contact configuration thus looks like:
Intercom Contacts Example Collapse source
Here, note that we've created the actions 103 and myintercom.  For 103, only 103 is dialed.  For myintercom, phone will also dial 103, but a header will be appended to the outgoing INVITE from the phone to Asterisk
Next, we need to configure the behavior of a Rapid Dial key to affect the actions. Â Configuration for this resembles:
Intercom BLF Items Example Collapse source
Here, notice that we have defined two behaviors.  Because behaviors are processed top-down, we first define a behavior with press_action of 103 and press_function of dial.  This will cause the phone for all phone_states and all target_states (the implied behavior when not explicitly defining them) to call the 103 action. Â
Next, we define a behavior where the target_status is idle, we've set the long_press_action to myintercom (which is the identifier of the pickup action that we created for the Contact), and the long_press_function is set to dial. Â
Thus, when Mark Spencer's phone is idle, based on a subscription NOTIFY from Asterisk, and someone performs a long press on this Rapid Dial key, the phone will dial 103 with a special X-Digium-Call-Feature header of feature_intercom into Asterisk, which will get handled by the dialplan to prepend an Alert-Info to the outgoing INVITE to Mark's phone.  And, when Mark Spencer's phone isn't idle, and someone presses this Rapid Dial key, the phone will dial 103 into Asterisk, which will call the Dial() application and ring the phone normally.
Call Monitor
Much like Call Pickup and Intercom, both within Asterisk are generally performed using a separate extension handler that rather than calling a direct Dial() to the phone, unless you've followed the above example and been more creative using X-headers. Â As before, this example for Call Monitor will make use of an arbitrary SIP header that we'll configure the Sangoma phone to attach. Â In this example, we assume that users want to call another party as the standard action of pressing a Rapid Dial key, that when the Rapid Dial key is long-pressed and the target is idle, that the user wants to Intercom the target, and that if the Rapid Dial key is long-pressed and the target is on the phone, that the user wants to Monitor the target.
Assuming 3-digit extensions, dialplan for this might look like:
Call Monitor Dialplan Example Collapse source
Here, we've defined an extern pattern match on 1XX - all 3-digit dialed patterns beginning with 1 followed by two more digits 0-9.  In the case that it's matched, Asterisk will first perform a GotoIf() depending on the presence of an X-Digium-Call-Feature matching feature_intercom.  Where feature_intercom is matched, the dialplan jumps to the intercomcall label where a pre-dial handler calls the PJSIP_HEADER dial plan function to add an Alert-Info header to the outgoing SIP INVITE before performing the Dial.  Otherwise, when feature_intercom is not matched, the dialplan jumps to the notintercomcall label.  The notintercomcall label performs another GotoIf check.  If the feature_monitor header is present, then the dialplan jumps to monitorcall to a ChanSpy() application to monitor the call.  If the feature_monitor header is not present, the dialplan jumps to donotmonitorcall to a normal Dial().
To affect this, our Sangoma phone needs a contact that is configured with three actions: one, called 103 to dial the contact normally, another called myintercom that dials with a special header, and a third called mymonitor also with a special header.  The contact configuration thus looks like:
Call Monitor Contacts Example Collapse source
Here, note that we've created the actions 103 and myintercom and mymonitor.  For 103, only 103 is dialed.  For myintercom, phone will also dial 103, but a header will be appended to the outgoing INVITE from the phone to Asterisk.  An,d for mymonitor, the phone will also dial 103, but a different header will be appended to the outgoing INVITE.
Next, we need to configure the behavior of a Rapid Dial key to affect the actions. Â Configuration for this resembles:
Call Monitor BLF Items Example Collapse source
Here, notice that we have defined three behaviors.  Because behaviors are processed top-down, we first define a behavior with press_action of 103 and press_function of dial.  This will cause the phone for all phone_states and all target_states (the implied behavior when not explicitly defining them) to call the 103 action. Â
Next, we define a behavior where the target_status is idle, we've set the long_press_action to myintercom (which is the identifier of the pickup action that we created for the Contact), and the long_press_function is set to dial. Â
Finally, we define a behavior when the target_status is on_the_phone, where we've set the long_press_action to mymonitor.
Thus, when Mark Spencer's phone is idle, based on a subscription NOTIFY from Asterisk, and someone performs a long press on this Rapid Dial key, the phone will dial 103 with a special X-Digium-Call-Feature header of feature_intercom into Asterisk, which will get handled by the dialplan to prepend an Alert-Info to the outgoing INVITE to Mark's phone.  When Mark's on the phone, the header of feature_monitor will be sent, and ChanSpy will be called to listen to Mark's conversation.  Otherwise, when someone presses this Rapid Dial key, the phone will dial 103 into Asterisk, which will call the Dial() application and ring the phone normally.
Call Parking
Sangoma phones include a built-in Parking application, visible in the Applications menu, and have a dedicated Park soft-key, visible on the main screen while a call is in-progress, that can be exposed when the phones are configured using DPMA. Â In addition to these features, it is also possible to configure a Rapid Dial key to serve both functions. Â For our example, pressing a rapid dial key while a call is connected will automatically transfer the caller to the parking lot. Â And, pressing the same rapid dial key while the phone is idle will load the parking application into the foreground, from which callers can be picked. Â To do this, we will take advantage of Asterisk's built-in res_parking.conf-based call parking along with its built in feature-code mapping in features.conf. Â First, call parking must be enabled in res_parking.conf, which looks like:
Call Parking res_parking.conf Example Collapse source
and then to handle in-call DTMF for parking, then in features.conf like:
Call Parking featues.conf Example Collapse source
Â
Here, we've setup the main parking extension as 700, we've setup 20 lots, numbered 701-720, and we've set the in-call feature sequence that parks calls as #72.
Wondering why you can't re-park a previously parked call? Or, wondering why you can't do DTMF-based transfers of previously parked calls? Take a look at the parkedcalltransfers and parkedcallreparking (and other) options in features.conf. They're disabled by default, so, to enable that capability, they'll need to be enabled.
Â
Next, we need to make sure our Dialplan is constructed to include the parkedcalls context like so:
Call Parking Dialplan Example Collapse source
Here, our sample context testing includes the necessary components, automatically generated by features.conf.  And, our Dial() application includes the k and K flags, which lets the called and calling parties park the other caller by dialing the proper DTMF sequence.
To affect this, our Sangoma phone needs a contact that is configured with two actions: one, called parkme to perform the actual parking of the caller, and another called showparking that loads the parking application into the foreground.  The contact configuration thus looks like:
Call Parking Contacts Example Collapse source
Here, note that we've created the actions parkme and showparking.  For parkme, #72 is dialed.  For showparking, the phone will load the parking built-in phone application.
Next, we need to configure the behavior of a Rapid Dial key to affect the actions. Â Configuration for this resembles:
Call Parking BLF Items Example Collapse source
Here, notice that we have defined two behaviors.  First, we define a behavior that acts when our phone is in the connected state.  In that state, when the rapid dial key is pressed, the parkme action is called with the press_function of send_dtmf, which sends in-call DTMF back to Asterisk.
Next, we define a behavior that acts when our phone is in the idle state.  In this state, when the rapid dial key is pressed, the showparking action is called, with the press_function show_app, which loads an application into the foreground.
Thus, when we're on call, we can press the rapid dial key to send DTMF to Asterisk that sends the caller to the parking lot. Â And, when we're idle, we can press the same rapid dial key to load the parking application into the foreground, so we can see who's parked.
Blind Transfer
Prior to the 1.4 phone firmware, blind transfers on Sangoma phones could only be affected on unanswered calls by pressing the Transfer hard key, followed by a Rapid Dial key for a contact, or during an in-progress call by pressing the Transfer hard key, followed by dialing the contact and pressing the Transfer soft key or by selecting the contact and pressing the Transfer soft key. Â In either case, performing a blind transfer prior to the 1.4 firmware requires use of the Transfer hard key to put the phone in a transfer-capable state.
With the capabilities of Smart BLF, it is possible to perform a blind transfer with the press of a single Rapid Dial key, and it can be done one of two ways. Â The first way performs a regular SIP transfer. Â In this scenario, let's assume that when our phone is idle, and we press the rapid dial key for a contact, that we call that contact. Â And, when our phone is receiving a call, or when our phone is on a call, or when our phone is actually in the transfer state (because someone has pressed the hard transfer key), that pressing that contact's rapid dial key will blind transfer the call that's active/highlighted in the call field to the target.
To begin, let's assume 3-digit extensions. Â Diaplan for this might look like:
Blind Transfer Dialplan Example Collapse source
Here, we've defined an extern pattern match on 1XX - all 3-digit dialed patterns beginning with 1 followed by two more digits 0-9. Â In the case that it's matched, Asterisk will dial the SIP extension.
To affect this, our Sangoma phone needs a contact that is configured with two actions: one, called 103 to dial the contact normally, and another called blindxfer that performs a transfer function.  The contact configuration thus looks like:
Bind Transfer Contacts Example Collapse source
Here, note that we've created the actions 103 and blindxfer.  For each, only 103 is dialed.Â
Next, we need to configure the behavior of a Rapid Dial key to affect the actions. Â Configuration for this resembles:
Blind Transfer BLF Items Example Collapse source
Here, notice that we have defined five behaviors.  Because behaviors are processed top-down, we first define a behavior with press_action of 103 and press_function of dial.  This will cause the phone for all phone_states and all target_states (the implied behavior when not explicitly defining them) to call the 103 action. Â
Next, we define behaviors for the phone states where we want the blindxfer action to be called.  The states we've chosen are incoming (for when a call rings us), connected (for when we're on a call and not doing anything else), incoming/transfer (for when a call is ringing us and we've pressed the Transfer hard key), and hold/transfer (for when we're on a call and we've pressed the Transfer hard key, which puts the caller on hold).
Thus, when we're idle, and we press the rapid dial key, the phone will dial 103.  And, in four phone states that we've defined, the phone will instead perform a blind transfer of any call that might be ringing or already connected to the phone.
The second method of performing a blind transfer using a single key press involves use of Asterisk's built-in DTMF-based transfer. Â To do this, we need to first make sure that features.conf is configured correctly. Â It should look something like:
Blind Transfer featues.conf Example Collapse source
Here, we've setup DTMF sequence to invoke blind transfer as #1.
Next, we need to make sure our Dialplan is constructed to include the feature map context like so:
Blind Transfer using features.conf Dialplan Example Collapse source
Here, our sample context testing includes the necessary components, automatically generated by features.conf.  And, our Dial() application includes the t and T flags, which lets the called and calling parties transfer the other caller by dialing the proper DTMF sequence.
In this example, in light of the previous example, we'll only configure one action, called blindfeaturetransfer to perform the parking of the caller.  In this case, we'll use the #1 feature code as the dialing prefix and the target extension as the dialed number.  The contact configuration thus looks like:
Blind Transfer using features.conf Contacts Example Collapse source
Here, note that we've created the action blindfeaturetransfer.  When the action is called, the phone will dial #1 followed by 103.
Next, we need to configure the behavior of a Rapid Dial key to affect the actions. Â Configuration for this resembles:
Blind Transfer using features.conf BLF Items Example Collapse source
Here, we define a behavior that acts when our phone is in any state.  It is probably prudent to narrow this down though to a more limited set of states.  Nevertheless, for this example, when the rapid dial key is pressed, the blindfeaturetransfer action is called with the press_function of send_dtmf, which sends in-call DTMF back to Asterisk.
Thus, when we're on call, we can press the rapid dial key to send DTMF to Asterisk that transfers the caller to extension 103. Â
Loading an Application
Applications, both custom as well as the phone's built-in applications, can be loaded into the foreground with the press of a rapid dial key. Â One might, for example, want a rapid dial key when pressed to dial an idle contact; but, when the contact is on the phone, load an application instead. Â To affect something like this, ignoring any dialplan, let's first look at a contact configuration to load a custom application:
Loading an Application Contacts Example Collapse source
Here, note that we've created the actions 103 and personisbusy.  For the first, 103 is dialed.  For the second, an application called personbusyapp is referenced.
Next, we need to configure the behavior of a Rapid Dial key to affect the actions. Â Configuration for this resembles:
Loading an Application BLF Items Example Collapse source
Here, notice that we have defined two behaviors.  Because behaviors are processed top-down, we first define a behavior with press_action of 103 and press_function of dial.  This will cause the phone for all phone_states and all target_states (the implied behavior when not explicitly defining them) to call the 103 action. Â
Next, we define a behavior that acts only when the target contact is on_the_phone.  In that case, and that case only, our press_function is to show_app.
Thus, whenever we press the key and the target isn't on the phone, we will dial 103.  And, whenever the target is on the telephone, we will load the application personbusyapp into the foreground.
Load an App without defining a Contact
If, instead of creating a contact that loads an application as part of action-defined behavior, you just want to dedicate a key to loading an application, a BLF Item can be constructed like:
Load an app with not contact reference
Note the use of the app_id parameter instead o the contact_id parameter. For this type of key, no presence subscription is made, nor are other actions possible. Rather, it's a quick way to drop an application onto a Rapid Dial key.
Â
LED and Ringtone Indication manipulation
By default, Sangoma phones, for an active subscription, blink fast green when a party is ringing, slow red when a party is on hold, and show solid green when a party is on a call.  Smart BLF provides customization of the LED states based upon the device state of the subscribed party.  You can configure red instead of green, amber instead of red, off instead of amber, etc., and you can manipulate the blinking rate.  Control over the LED state is managed by indicators that can be configured along with the configuration of each blf_item.  Let's look at a small example:
Small LED Indicator Example Collapse source
For this example, notice the indicator element.  It defines a target_status, an led_color and an led_state.  The target_status is set to ringing, the led_color is set to amber and the led_state is set to fast.  Thus, when the target of this blf_item, that's contact_id 103, is in the ringing status, the LED indicator for this rapid dial key will fast-blink amber.  Normally, without this definition, as noted above, the default behavior when a target is ringing is to blink fast green.
Besides just controlling LED color and state, indicators can also control the local playback of ringtones. Â So, if you want your phone to ring every time another phone rings, and maybe you want to use a special ringtone to indicate that, you can control that, too, using indicators. Â Here's an example:
Ringtone Indicator Example Collapse source
For this example, we've built slightly upon the first.  Now, we define ring="1" and we set ringtone_id to Digium.  Thus, when the watched party is ringing, our phone will playback the Sangoma ringtone.  ringtone_id is derived from the ids of the various ringtones loaded onto the phone - factory defaults or custom-added.
If more than one party is being watched and is in a particular state that requires ringtone playback, only one ringtone will be played back. More than one ringtone will not be interleaved or played back simultaneously. Rather than building a setup that requires one phone to simultaneously playback two other phone's ringing indications, it's better to have multiple phones base their playback of ringing on the status of just one phone.
Â
Send to VM
Digium's phones maintain a dedicated Send to VM button that appears in the phone application when an incoming call arrives into the phone. Â And, for phones that use the older contacts convention of has_voicemail, a "to vm" function is available when viewing the contact's information. Â It is also useful though to configure a rapid dial key for dialing a voicemail box or transferring a call directly into voicemail. Â To accomplish this, one must first create some dialplan magic. Â Within the dialplan, it is necessary to account for two cases:
A direct dial to voicemail, that can be handled using an X-call header
A call transferred into voicemail, that must be handled using a Diversion header
For this example, we want to craft a rapid dial key that when the target is idle calls the phone, when the target is on the phone or is ringing, does a normal press to dial into the target's voicemail box and does a long-press to transfer a call directly into the target's voicemail box.
So, our dialplan for this would look something like:
Assuming 3-digit extensions, dialplan for this might look like:
Send to VM Dialplan Example Collapse source
Here, we've defined an extern pattern match on 1XX - all 3-digit dialed patterns beginning with 1 followed by two more digits 0-9.  In the case that it's matched, Asterisk will first perform a GotoIf() depending on the presence of an X-Digium-Call-Feature matching feature_send_to_vm or of a Diversion header with a redirection reason of send_to_vm.  Where the voicemail checks are matched, the dialplan jumps to the vm label where the Voicemail() application is called.  Otherwise, when the voicemail checks are not not matched, the dialplan jumps to the notvm label and performs a regular Dial().
To affect this, our Sangoma phone needs a contact that is configured with two actions: one, called 103 to dial the contact normally, and another that dials with special headers.  The contact configuration thus looks like:
Send to VM Contacts Example Collapse source
Here, note that we've created the actions 103 and sendtovm.  For 103, only 103 is dialed.  For sendtovm, phone will also dial 103, but will add headers to the outgoing INVITE from the phone to Asterisk, that Asterisk will parse in its dial plan.
Next, we need to configure the behavior of a Rapid Dial key to affect the actions. Â Configuration for this resembles:
Send to VM BLF Items Example Collapse source
Here, notice that we have defined three behaviors.  Because behaviors are processed top-down, we first define a behavior with press_action of 103 and press_function of dial.  This will cause the phone for all phone_states and all target_states (the implied behavior when not explicitly defining them) to call the 103 action. Â
Next, we define a behavior where the target_status is on_the_phone, we've set the press_action to sendtovm (which is the identifier of the voicemail action that we created for the contact), the press_function to dial, the long_press_action also to sendtovm, and the long_press_function to transfer.
We define a third behavior with the same actions and functions as the second behavior, only it acts on a different target status -Â ringing.
Thus, when the rapid dial key is pressed and Mark is neither ringing or on the phone, and someone presses this rapid dial key, Mark's phone will be dialed normally. Â If Mark is on the phone or is ringing and someone presses the rapid dial key, Mark's voicemail box will be called. Â If Mark is on the phone or is ringing, and someone does a long-press on the rapid dial key, any caller that we're talking to will be transferred directly into Mark's voicemail box.
BLF Positioning and Pagination
For firmwares prior to 1.4, contacts were populated onto BLF keys as ordered top-down from a group_name as specified by the blf_contact_group configuration parameter.  This meant that explicit positioning of contacts onto a key or multiple keys on multiple pages wasn't possible.  Now, with Smart BLF, contacts may be mapped to an exact key on an exact page.  Mapping is accomplished using the location, index, and paging blf_item parameters.  Take the following example:
Â
One BLF Item Example Collapse source
For this example, the contact will be located on the side panel.  This means it's compatible with D50 and D70 phones, but not the D40, as the D40 only has a main location.  Now, on the side panel, the contact is located at index slot 1.  The index begins at 0, so this item, because its index is 1 will appear on the second rapid dial key from the top.  Further, paging is enabled.  When paging is enabled, a contact is mapped to a particular page.  Pages are only relevant to the D70 phone, which supports up to 10 pages.  Since this contact is mapped to a particular page, and because it is the first item on index 1, it will appear only on the first page of contacts.
Now, take this example:
Many BLF Items Example Collapse source
In this example, a total of 4 items are defined. Â
The first item is mapped to the main screen on index 3, so it will appear on the 4th line key on D50 and D70 phones (but wouldn'tappear on a D40 phone which only has a single index slot available to it). Â
The second item is mapped to the side screen on index 0 and paging is disabled.  So, it will appear on the first page screen in the first rapid dial key.Â
The third item is mapped to the side screen, also on index 0 and paging is disabled.  Because it is the second item to be mapped to index 0, and because blf items are processed top-down, this item will appear on the second page screen only, but not on the first.
The fourth item is mapped to the side screen on index 9 and paging is disabled.  So, it will appear on both the first and second pages on the 10th rapid dial key.