Process USSD Lua Service
Introduction
The ProcessUssdLuaService is a service for initiating Lua scripts running within the LogicApp.
The ProcessUssdLuaService receives a ProcessUnstructuredSSRequest
operation contained in a TCAP-RECV
message from an instance of the
SigtranApp which is
configured to receive TCAP messages from an external client.
During the transaction, the ProcessUssdLuaService communicates with the SigtranApp using the
TCAP-SEND
and TCAP-RECV
messages. See the definition of the
TCAP-… messages.
Configuring ProcessUssdLuaService
The ProcessUssdLuaService is configured within a LogicApp.
<?xml version="1.0" encoding="utf-8"?>
<n2svcd>
...
<applications>
...
<application name="Logic" module="LogicApp">
<include>
<lib>../apps/logic/lib</lib>
</include>
<parameters>
...
</parameters>
<config>
<services>
<service module="SigtranApp::ProcessUssdLuaService" libs="/usr/share/n2ttg/apps/sigtran/lib/" script_dir="/var/lib/n2svcd/logic/ussd_gw">
<menu_timeout>10</menu_timeout>
<error_message>Custom Error String</error_message>
<triggers>
<trigger dest_ssn="120" ussd_string_prefix="*123#" script_key="123"/>
<trigger dest_ssn="120" destination="333" script_key="333"/>
<trigger dest_ssn="120" ussd_string_prefix="*444#" script_key="444"/>
<trigger dest_ssn="120" ussd_string_prefix="*666#" script_key="666"/>
<trigger dest_ssn="120" destination="777" script_key="777"/>
</triggers>
</service>
</services>
<agents>
...
</agents>
</config>
</application>
...
</application>
...
</n2svcd>
In addition to the Common LogicApp Service Configuration, note the following specific attribute notes, and service-specific attributes.
Under normal installation, the following service
attributes apply:
Parameter Name | Type | XML Type | Description |
---|---|---|---|
module
|
String | Attribute |
[Required] The module name containing the Lua Service code: SigtranApp::ProcessUssdLuaService
|
libs
|
String | Element |
Location of the module for ProcessUssdLuaService.(Default: ../apps/sigtran/lib )
|
script_dir
|
String | Attribute | [Required] The directory containing scripts used by this service. |
dcs_language
|
Integer | Element |
The default ussdDataCodingScheme_language .If not present, a codec-specified default is applied. |
menu_timeout
|
Integer | Element | The default duration (in seconds) after which the script will resume if no result/error is received. |
notify_timeout
|
Integer | Element | The default duration (in seconds) after which the script will assume a notify has failed if no result/error is received. |
error_message
|
String | Element |
The message which will be returned to the subscriber if an unhandled error occurs in then Lua script. The internal script error will be written to the application log, but will not be sent to the subscriber. |
.triggers
|
Array | Element |
Array of trigger elements specifying Lua scripts to run for Process USSD Inbound Transactions.
|
.trigger
|
Object | Element | Provisions a Lua script to run for a Process USSD Inbound Transaction for received ProcessUnstructuredSSRequest operations. |
Script Trigger Rules
Each Process USSD Inbound trigger rule defines the name of a script which is ready to handle an inbound ProcessUnstructuredSSRequest Transaction.
Note that destination and origination addresses may contain hex digits A-F, and the
matching is for destination_prefix
and origination_prefix
is case-insensitive.
However, the string matching for ussd_string_prefix
is case-sensitive.
Each trigger
Object in the config
.triggers
Array is configured as follows.
Parameter Name | Type | XML Type | Description |
---|---|---|---|
ssn
|
1 -255
|
Attribute |
This trigger applies for only USSD ProcessUnstructuredSSRequest to this exact SCCP subsystem number. (Default = Trigger applies to all SCCP subsystem numbers). |
ussd_string_prefix
|
String | Attribute |
This trigger applies for only USSD ProcessUnstructuredSSRequest with content beginning with this sub-string. (Default = Trigger applies to all ProcessUnstructuredSSRequest). |
destination
|
Hex Digits | Attribute |
This trigger applies for only USSD ProcessUnstructuredSSRequest to this exact destination reference digits (in MAP Open). (Default = Trigger applies to all ProcessUnstructuredSSRequest). |
destination_prefix
|
Hex Digits | Attribute |
This trigger applies for only USSD ProcessUnstructuredSSRequest to destination reference digits (in MAP Open) with this prefix. (Default = Trigger applies to all ProcessUnstructuredSSRequest). |
origination
|
Hex Digits | Attribute |
This trigger applies for only USSD ProcessUnstructuredSSRequest from this exact origination reference digits (in MAP Open). (Default = Trigger applies to all ProcessUnstructuredSSRequest). |
origination_prefix
|
Integer | Attribute |
This trigger applies for only USSD ProcessUnstructuredSSRequest from origination reference digits (in MAP Open) with this prefix. (Default = Trigger applies to all ProcessUnstructuredSSRequest). |
script_key
|
String | Attribute |
The name for the Lua script to load (excluding the ".lua" or ".lc" suffix). The script should reside in the configured script_dir directory.
|
Script Selection (USSD Transaction Request)
The Lua script selection to execute for a USSD ProcessUnstructuredSSRequest takes into consideration the received content of the inbound TCAP_BEGIN transaction and/or the MAP content and/or the SCCP addressing information.
The destination address for matching is:
- The MAP_OPEN Destination Reference Digits.
The origination address for matching is:
- The MAP_OPEN Origination Reference Digits.
The Process USSD Lua Service will iterate the configured trigger
entries in the sequence
in which they are configured and find the first trigger which matches the parameters of the
received message.
Refer to the LogicApp configuration for more information on directories, library paths, and script caching parameters.
Script Global Variables
Scripts run with this service have access to the Common LUA Service Global Variables.
There are no service-specific global variables.
Script Entry Parameters (USSD Request)
The Lua script defines the service processing steps, such as the following:
local n2svcd = require "n2.n2svcd"
local ussd = require "n2.n2svcd.process_ussd_service"
-- The args contain the content of the ProcessUnstructuredSSRequest sent by the HLR.
local args = ...
-- This sends UnstructuredSSRequest and expects a UnstructuredSSRequest / ReturnResult.
local input = ussd.menu ("1. Add-ons\n2. Packages\n3. Account Services\n4. Other Services", 2)
if (type (input) == "nil") then
return "No input provided. Session over."
end
-- This sends UnstructuredSSNotify within the session. No response is required, do not wait for possible error.
ussd.notify ("You chose option " .. input .. " thanks.")
-- This closes the session by sending ProcessUnstructuredSSRequest / ReturnResult.
return "We'll send an SMS with your usage details."
The service script will be executed with an args
entry parameter which is an object with the
following attributes:
Attribute | Type | Description |
---|---|---|
.remote_sccp
|
SCCP Address Object | The far-end SCCP address, as per the TCAP-RECV Message. |
.local_sccp
|
SCCP Address Object | The near-end SCCP address, as per the TCAP-RECV Message. |
.text
|
String |
The ussdString_text decoded message text copied from .process_ussd.ussdString_text .
|
.process_ussd
|
Object |
The decoded attributes of the ProcessUnstructuredSSRequest operation. Some of these
attributes may be optional. Site-specific protocol variants may add additional parameters
not documented here.
|
.ussdString
|
Binary | The raw encoded bytes of the USSD message content. |
.ussdString_text
|
String |
The decoded text of the ussdString in ASCII or Unicode.
|
.msisdn
|
Binary | The MSISDN (raw bytes) encoded as MAP Address String. |
.msisdn_digits
|
HEX String |
The decoded digits of the MSISDN address.
|
.msisdn_noa
|
Integer |
The decoded Nature Of Address of the MSISDN address.
|
.msisdn_npi
|
Integer |
The decoded Numbering Plan Indicator of the MSISDN address.
|
.ussdDataCodingScheme
|
Binary | The USSD Data Coding Scheme (raw bytes) encoded as USSD Call Broadcast Data Scheme. |
.ussdDataCodingScheme_encoding
|
Integer |
The decoded encoding of the ussdDataCodingScheme compound field.
|
.ussdDataCodingScheme_group
|
Integer |
The decoded group of the ussdDataCodingScheme compound field.
|
.ussdDataCodingScheme_is_compressed
|
0 /1
|
The decoded is_compressed of the ussdDataCodingScheme compound field.
|
.ussdDataCodingScheme_language
|
Integer |
The decoded language of the ussdDataCodingScheme compound field.
|
.map_open
|
Table | The decoded attributes of the MAP-Open element within the TCAP's MAP Dialogue PDU. Some of these attributes may be optional. Site-specific protocol variants may add additional parameters not documented here. |
.destination_reference
|
Binary | The Destination Reference (raw bytes) encoded as MAP Address String. |
.destination_reference_digits
|
HEX String | The decoded digits of the Destination Reference address. |
.destination_reference_noa
|
Integer | The decoded Nature Of Address of the Destination Reference address. |
.destination_reference_npi
|
Integer | The decoded Numbering Plan Indicator of the Origination Reference address. |
.origination_reference
|
Binary | The Origination Reference (raw bytes) encoded as MAP Address String. |
.origination_reference_digits
|
HEX String | The decoded digits of the Origination Reference address. |
.origination_reference_noa
|
Integer | The decoded Nature Of Address of the Origination Reference address. |
.origination_reference_npi
|
Integer | The decoded Numbering Plan Indicator of the Origination Reference address. |
Script Return Parameters (USSD Response)
The Lua script is responsible for determing the contents of the ReturnResult
for the
ProcessUnstructuredSSRequest
operation, which will be sent back to the subscriber and
conclude the session.
The simplest way to do this is by the return value given back to the service at the end of script execution.
For full control over the USSD response, the script return value may be a response
object with the following attributes:
Field | Type | Description |
---|---|---|
response
|
Table | Container for the USSD response parameters we are to send. |
.ussdString
|
Binary |
The encoded bytes for the USSD String content. You will generally not specify this value, the service will encode it for you. |
.ussdString_text
|
String |
The user string in ASCII for Unicode that you wish to be encoded. (Default = None) |
.ussdDataCodingScheme_group
|
Integer |
The encoding group associated with the string encoding. (Default = 0 )
|
.ussdDataCodingScheme_language
|
Integer |
The encoding language associated with the string encoding. (Default = service dcs_language or codec-determined default)
|
.ussdDataCodingScheme_is_compressed
|
Integer |
The compression flag associated with the string encoding. (Default = 0 )
|
.ussdDataCodingScheme_message_class
|
Integer |
The encoding message class associated with the string encoding. (Default = 0 )
|
.ussdDataCodingScheme_encoding
|
Integer |
The encoding type associated with the string encoding. (Default = 0 )
|
Alternatively, the script may return a string. This is the same as specifying .ussdString_text
=
(the given simple string) with all other attributes not specified.
Alternatively, the script may return nil
in which case the USSD transaction will be closed
by sending Empty TCAP END. The subscriber behaviour here may vary according to handset.
Example (returning a Table USSD Response):
local n2svcd = require "n2.n2svcd"
local args = ...
return ({ ussdString_text = "Bienvenue a la service", ussdDataCodingScheme_language = 3 })
Alternatively, a script may return a simple string instead of a Table.
Example (returning a String USSD Response):
local n2svcd = require "n2.n2svcd"
local args = ...
return "Welcome to the service"
This is a shorthand for ussdString_text
= (Text Message) with all other values set to defaults.
Alternatively, a script may return nil
.
Example (returning nothing):
local n2svcd = require "n2.n2svcd"
local args = ...
return nil
In this case, the session will be closed with an Empty TCAP END to the subscriber handset.
The ProcessUssdLuaService API
The Process USSD Service API can be loaded as follows.
local ussd = require "n2.n2svcd.ussd"
It is not necessary to load the Process USSD Service API if you are only using the simple response mechanism described above. It is only required if you wish to use any of the extended features described below, or any of the constants.
.response [Synchronous]
When a Lua script needs to perform extended processing, it may wish to send an early USSD
response before the script completes. This can be done with the response
method on the
USSD Service API.
This method will send a ReturnResult
for the ProcessUnstructuredSSRequest
operation,
within a TCAP_END. The USSD transaction is over. Subsequent calls to response
, decline
,
notify
, or menu
are not permitted, and will generate a runtime script error.
The response
method takes a single response
parameter.
Parameter | Type | Description |
---|---|---|
response
|
Table or String | A simple "text/plain" string, or an Table with the same structure as the returned object described under "Script Return Parameters". |
After the response
method, the USSD transaction is no longer in progress.
The response
method returns the following object structure:
Parameter | Type | Description |
---|---|---|
controlled
|
false
|
This field is always false to indicate that the session is no longer under control.
|
reason
|
Response / Abandon
|
Response - The ReturnResult was successfully sent to the SigtranApp.Abandon - The user abandoned with TCAP ABORT or TCAP Empty END prior to the response attempt.
|
[Fragment] Example Early Response specifying Language:
...
ussd.response ({ ussdString_text = "Bienvenue a la service", ussdDataCodingScheme_language = 3 })
[post-processing logic after USSD transaction is ended]
...
[Fragment] Example Early Response with default Language:
...
ussd.response ("Welcome to the service")
[post-processing logic after USSD transaction is ended]
...
.decline [Synchronous]
If the Lua service logic script does not wish to handle the request, it can indicate error
processing by sending a ReturnError
for the ProcessUnstructuredSSRequest
operation,
within a TCAP_END.
The USSD transaction is over. Subsequent calls to response
, decline
, notify
,
or menu
are not permitted, and will generate a runtime script error.
The decline
method takes a single error_code
parameter.
Parameter | Type | Description |
---|---|---|
error_code
|
Integer |
An optional custom error code. (Default = System Failure - Error Code 34) |
After the decline
method, the USSD transaction is no longer in progress.
The decline
method returns the following object structure:
Parameter | Type | Description |
---|---|---|
controlled
|
false
|
This field is always false to indicate that the session is no longer under control.
|
reason
|
Decline / Abandon
|
Decline - The ReturnError was successfully sent to the SigtranApp.Abandon - The user abandoned with TCAP ABORT or TCAP Empty END prior to the decline attempt.
|
[Fragment] Decline request using custom error code:
...
ussd.decline (ussd.ERROR_ILLEGAL_EQUIPMENT)
return nil
.notify [Asychronous]
As part of the interaction, the Lua script may wish to send intermediate UnstructuredSSNotify
messages to the subscriber. There is no response or confirmation for these messages.
The notify
method on the USSD API will perform this function.
The script may only use notify
while the USSD subscriber session is controlled.
i.e. At the start of the script, or after a previous call to notify
or menu
has returned
controlled
= true
. Invoking notify
after a previous call to notify
or menu
has returned
controlled
= false
is not permitted and will raise a Lua error.
The notify
method has two different forms. The “full form” supports the following single parameter:
Parameter | Type | Description |
---|---|---|
ussd
|
Table | Container for the USSD request parameters we are to send. |
.ussdString
|
Binary |
The encoded bytes for the USSD String content. You will generally not specify this value, the service will encode it for you. |
.ussdString_text
|
String |
The user string in ASCII for Unicode that you wish to be encoded. (Default = None) |
.msisdn
|
Binary |
The MSISDN (raw bytes) encoded as MAP Address String. This is not typically required when a Notify occurs with the context of an established dialog. |
.msisdn_digits
|
HEX String |
The digits of the MSISDN address.This is not typically required when a Notify occurs with the context of an established dialog. |
.msisdn_noa
|
Integer |
The Nature Of Address of the MSISDN address.This is not typically required when a Notify occurs with the context of an established dialog. |
.msisdn_npi
|
Integer |
The Numbering Plan Indicator of the MSISDN address.This is not typically required when a Notify occurs with the context of an established dialog. |
.ussdDataCodingScheme_group
|
Integer |
The encoding group associated with the string encoding. (Default = 0 )
|
.ussdDataCodingScheme_language
|
Integer |
The encoding language associated with the string encoding. (Default = service dcs_language or codec-determined default)
|
.ussdDataCodingScheme_is_compressed
|
Integer |
The compression flag associated with the string encoding. (Default = 0 )
|
.ussdDataCodingScheme_message_class
|
Integer |
The encoding message class associated with the string encoding. (Default = 0 )
|
.ussdDataCodingScheme_encoding
|
Integer |
The encoding type associated with the string encoding. (Default = 0 )
|
seconds
|
Number |
The timeout in seconds for the script to wait for an ReturnResult/ReturnError response from the network. (Default = Service configured notify_timeout value).
|
The “simplified form” accepts a simple text argument, which is sufficient for most purposes:
Parameter | Type | Description |
---|---|---|
text
|
String |
A simple "text/plain" string which will be the ussdString_text in the request.
|
seconds
|
Number |
The timeout in seconds for the script to wait for an ReturnResult/ReturnError response from the network. (Default = Service configured notify_timeout value).
|
After the notify
method, the USSD transaction may or may not be in progress.
The result.controlled
field will indicate if the USSD interaction is still under
our control.
The notify
method returns the following object structure:
Parameter | Type | Description |
---|---|---|
controlled
|
Boolean |
This attribute is true if the USSD session is still proceeding.It will be always true in the case of reason Notify .It will be always false in the case of reason Abandon .
|
reason
|
Notify / Error / Abandon / Timeout
|
Notify - Acknowledgement was received. controlled may be true or false .Error - A user/network error code was received within the timeout window. controlled may be true or false .Abandon - The user/network abandoned with TCAP ABORT or TCAP Empty END. controlled = false .Timeout - The handset did not acknowledge the notify within the timer. controlled = true .
|
error_code
|
Integer |
Present if and only if reason = Error .The user/network-provided error code number. |
[Fragment] Example Notification specifying Language:
...
ussd.notify ({ ussdString_text = "En cours. Patientez SVP.", ussdDataCodingScheme_language = 3 })
...
[additional logic including further USSD interactions]
...
[Fragment] Example Notification with default Language, wait for possible error:
...
-- Wait up to 1.5 seconds to see if an error is returned from the handset.
ussd.notify ("Working... please wait.", 1.5)
...
[additional logic including further USSD interactions]
...
.menu [Asynchronous]
As part of the interaction, the Lua script may wish to send intermediate UnstructuredSSRequest
messages to the subscriber. This is effectively a “menu prompt”. The subscriber will be
shown a text, and prompted to enter additional input which is returned to the service in a
ReturnResult
component for the UnstructuredSSRequest
operation.
The script may only use menu
while the USSD subscriber session is controlled.
i.e. At the start of the script, or after a previous call to notify
or menu
has returned
controlled
= true
. Invoking menu
after a previous call to notify
or menu
has returned
controlled
= false
is not permitted and will raise a Lua error.
The script will suspend until the subscriber input is received, or until the configurable time value expires.
The request
method has two different forms. The “full form” supports the following two parameters:
Parameter | Type | Description |
---|---|---|
ussd
|
Table |
Container for the USSD request parameters we are to send. This is the same as for the notify method.
|
seconds
|
Number |
The timeout in seconds before the script resumes processing without input. (Default = Service configured menu_timeout value).
|
The “simplified form” accepts a simple text argument, which is sufficient for most purposes:
Parameter | Type | Description |
---|---|---|
text
|
String |
A simple "text/plain" string which will be the ussdString_text in the request.
|
seconds
|
Integer |
The timeout in seconds before the script resumes processing without input. (Default = Service configured menu_timeout value).
|
In either case, the menu
method returns the following object structure:
Parameter | Type | Description |
---|---|---|
controlled
|
Boolean |
This attribute is true if the USSD session is still proceeding.It will be always false in the case of reason Abandon .
|
reason
|
Input / Error / Abandon / Timeout
|
Input - A user input string was received. controlled may be true or false .Error - A user/network error code was received. controlled may be true or false .Abandon - The user/network abandoned with TCAP ABORT or TCAP Empty END. controlled = false .Timeout - The handset did not respond within the timer. controlled = true .
|
error_code
|
Integer |
Present if and only if reason = Error .The user/network-provided error code number. |
text
|
String |
A simple "text/plain" string which will be the ussdString_text from the response.This is present only when supplied by the subscriber, i.e. only when result.reason = ussd.REASON_INPUT .
|
ussd
|
Table |
Container for the USSD request result parameters we received. In the case of timeout or user abandon, this field will be `nil`. |
.ussdString
|
Binary |
The encoded bytes for the USSD String content. You will generally not specify this value, the service will encode it for you. |
.ussdString_text
|
String |
The user string in ASCII for Unicode that you wish to be encoded. (Default = None) |
.ussdDataCodingScheme_group
|
Integer |
The encoding group associated with the string encoding. (Default = 0 )
|
.ussdDataCodingScheme_language
|
Integer |
The encoding language associated with the string encoding. (Default = service dcs_language or codec-determined default)
|
.ussdDataCodingScheme_is_compressed
|
Integer |
The compression flag associated with the string encoding. (Default = 0 )
|
.ussdDataCodingScheme_message_class
|
Integer |
The encoding message class associated with the string encoding. (Default = 0 )
|
.ussdDataCodingScheme_encoding
|
Integer |
The encoding type associated with the string encoding. (Default = 0 )
|
After the menu
method, the USSD transaction may or may not be in progress.
The result.controlled
field will indicate if the USSD interaction is still under
our control.
[Fragment] Full form with custom Timeout:
...
local result = ussd.request ({ ussdString_text = "1. Account Balance\n2. My Usage\n3. Recharge History\n4. Recharge\n0. Back" }, 20)
-- Check for anything other than successful result.
if (result.reason ~= ussd.REASON_INPUT) then
return "Session terminated because of " .. result.reason
end
-- Now we can access the response text.
if (result.ussd.ussdString_text == "1") then
...
end
...
[Fragment] Simplified form Menu with custom Timeout:
...
local result = ussd.menu ("1. Account Balance\n2. My Usage\n3. Recharge History\n4. Recharge\n0. Back", 20)
if (not result.controlled) then return nil end
if (not result.text) then return "No input received to menu. Session terminated." end
if (result.text == "1") then
...
end
...
.close [Synchronous]
The service logic may use this method to conclude the subscriber interaction without sending
back a final response message. This has the same effect as returning nil
from the service
script.
However, calling close
causes the USSD session (and associated TCAP transaction) to be
closed immediately. In general, service logic should call close
as soon as possible.
This will free the transaction resources, and (for some handsets) may be necessary before
the handset can perform another function.
The close
method takes no parameters.
The close
method returns nil
.
[Fragment] Example close session using empty TCAP END:
...
-- Session is no longer required and we have no response.
ussd.close ()
...
Constants
The following USSD constants are defined on the returned ussd
object.
USSD Reason Constants
The following constants are used to indicate the reason that a USSD interaction succeed or failed.
-- USSD Reason Constants.
ussd.REASON_RESPONSE = 'Response'
ussd.REASON_DECLINE = 'Decline'
ussd.REASON_NOTIFY = 'Notify'
ussd.REASON_INPUT = 'Input'
ussd.REASON_ABANDON = 'Abandon'
ussd.REASON_TIMEOUT = 'Timeout'
USSD Error Constants
The following constants are error code values for ReturnError
as passed into the decline
method.
-- USSD Error Constants.
ussd.ERROR_SYSTEM_FAILURE = 34
ussd.ERROR_DATA_MISSING = 35
ussd.ERROR_UNEXPECTED_DATA_VALUE = 36
ussd.ERROR_UNKNOWN_ALPHABET = 71
ussd.ERROR_CALL_BARRED = 13
ussd.ERROR_ABSENT_SUBSCRIBER = 27
ussd.ERROR_ROAMING_NOT_ALLOWED = 8
ussd.ERROR_ILLEGAL_SUBSCRIBER = 9
ussd.ERROR_ILLEGAL_EQUIPMENT = 12
ussd.ERROR_BUSY_SUBSCRIBER = 45
ussd.ERROR_UNKNOWN_SUBSCRIBER = 1
ussd.ERROR_USSD_BUSY = 72