CASr1 scripting
This page explains how CASr1 script are implemented, so the reader can read, modify or create CASR1 scripts to adapt to different variants, or implement new variants.
Summary
Toolpack uses the LUA programming language to implement CAS scripts. The CAS scripts are interpreted by the TMG unit in order to handle calls.
A portion of the CAS state machine is implemented outside the script, in the CAS stack that runs on the TMG unit, although the script still offers a great level of flexibility to implement various CAS variants.
CASR1 vs CASR2 scripts
CASR1 variants and CASR2 variants both use LUA scripts stored in the same place in the Toolpack configuration Web Portal.
However, CASR1 and CASR2 scripts are quite different. They use different constants and function, and will have different "callback" functions called by the CAS stack on the TMG. The general architecture (state machine) of the scripts is also different.
In a few words:
CASR1 scripts need to:
- Handle incoming CAS bits changes
- Decide when to change sent CAS bits
- Decide when to detect/send ANI/DNIS tones
- Implement a state machine that follows the different call states, and report these states to the CAS stack
CASR2 scripts need to:
- Define forward and backward digits to use
- Map digits to various meanings
- Handle received digits and how to handle then
The current page explains CASR1 scripts. For more information about CASR2 scripts, please refer to the following page: Web_Portal_Tutorial_Guide_v2.6#CASR2
Set the script type to CASR1
A CAS script be identified as a CASR1 script when the following variable is set:
SCRIPT_TYPE="CASR1"
If this variable is missing, the script will be interpreted as "CASR2".
Overview
Per-timeslot context
The CASR1 scripts works on a "per timeslot" basis. It's informed of each timeslot that is under it's control through callback function HandleNewTimeslot.
A context is provided with each timeslot, so the script can store "per-timeslot" variables in order to implement the state machine.
Per-timeslot events
Once a timeslot has been created in the script, the CAS stack will inform the script of any event on that timeslot (CAS bits changes and others). To each received event, the script will take one ore more action.
Per-timeslot actions
The CAS script can perform various actions on a timeslot, while it handles timeslot events.
For example, it can
- change CAS bits (or send "wink")
- report call state to the CAS stack (seizure, call alerting, call answered, call terminating, timeslot remotely blocked, etc.).
- ask for ANI/DNIS detection
- ask for transmission of ANI/DNIS
- Start a timer
- And more...
Per-timeslot state machine
It's up to the script implementation to define it's own states for handling the calls. The script is thus very flexible in the way it implements the CASR1 variant call flow.
The current document does not describe how CASR1 call flows are implemented (what are CAS bits, when and why to they "change", how calling/called numbers are exchanged, what is the call flow etc.) The reader shall find that information in the specifications for CASR1 variants.
The current document provides general information on available timeslot events and actions that allow to actually implement CASR1 variants.
Script entry points
There are 2 functions that the script must provide, and that will be called by the stack when appropriate:
- HandleNewTimeslot( in_TimeslotCtx, in_InitialCasBits )
- HandleEvent( in_TimeslotCtx, in_EventType, ... )
(see documentation blow for detailed information)
Configurable global script constants
The script can define some constants required by the stack (though default values are provided if the script does not define these constants).
SCRIPT_TYPE
Defines the type of this sript. This constant is mandatory for CASR1 scripts.
SCRIPT_TYPE = "CASR1"
ABCD_PATTERN_MATCH_MASK
Mask to apply to CAS bits detected from remote equipment (for bits 0xABCD). A bit which mask is set to 0 will be ignored and always reported as zero (0) to this script. This is useful in some cases when unused bits have undefined (and even sometimes toggeling!) values.
Default: 0x1111
ABCD_PATTERN_MATCH_MASK = 0x1111
TONE_USE_DTMF
Indicates the type of tones must be used to send/receive AND/DNIS. Value of 1 stands for DTMF. Value of 0 defaults to MFR1.
Default: 1 (use DTMF)
TONE_USE_DTMF = 1
TONE_ON_TIME
Defines the "on time" (in ms) of tones used when sending ANI/DNIS.
Default: 60ms
TONE_ON_TIME = 60
TONE_OFF_TIME
Defines the "off time" (inter-digit delay)(in ms) of tones used when sending ANI/DNIS.
Default: 40ms
TONE_OFF_TIME = 50
TONE_LEVEL
Defines the audio power level (in DB) of tones used when sending ANI/DNIS, or dial tone.
Default: -10db
TONE_LEVEL = -10
TONE_VP_GROUP
Defines the type of tone detector/generator that will be used for CASR1 calls:
- Group 0: Use DSP resources (for TMG that have DSP resources)
- Group 1: Use VOIP resources (for TMG that have VOIP resources)
It may be required to change this value if using CASR1 scripts on TMG units that don't have either DSP or VOIP resources.
Default: 1 (VOIP resources)
TONE_VP_GROUP = 1
Tones mapping to ASCII characters
DTMF mapping
DTMF tones are represented, in the script, as ASCII characters. (these are used to define ANI/DNIS prefix/suffix, or to explicitly provide the ANI/DNIS for a call).
Please refer to the following table to know which ASCII character is used to represent each existing DTMF tone:
'0' -> DTMF Digit 0: 941Hz + 1336Hz '1' -> DTMF Digit 1: 697Hz + 1209Hz '2' -> DTMF Digit 2: 697Hz + 1336Hz '3' -> DTMF Digit 3: 697Hz + 1477Hz '4' -> DTMF Digit 4: 770Hz + 1209Hz '5' -> DTMF Digit 5: 770Hz + 1336Hz '6' -> DTMF Digit 6: 770Hz + 1477Hz '7' -> DTMF Digit 7: 852Hz + 1209Hz '8' -> DTMF Digit 8: 852Hz + 1336Hz '9' -> DTMF Digit 9: 852Hz + 1477Hz '*' -> DTMF Digit Star (*): 941Hz + 1209Hz '#' -> DTMF Digit Pound (#): 941Hz + 1477Hz 'A' -> DTMF Digit A: 697Hz + 1633Hz 'B' -> DTMF Digit B: 770Hz + 1633Hz 'C' -> DTMF Digit C: 852Hz + 1633Hz 'D' -> DTMF Digit D: 941Hz + 1633Hz Alternative values for * and #: 'E' -> DTMF Digit Star (*): 941Hz + 1209Hz 'F' -> DTMF Digit Pound (#): 941Hz + 1477Hz
MFR1 mapping
MFR1 tones are represented, in the script, as ASCII characters. (these are used to define ANI/DNIS prefix/suffix, or to explicitly provide the ANI/DNIS for a call).
Please refer to the following table to know which ASCII character is used to represent each existing MFR1 tone:
'0' -> MFR1 Digit 0: 1300Hz + 1500Hz '1' -> MFR1 Digit 1: 700Hz + 900Hz '2' -> MFR1 Digit 2: 700Hz + 1100Hz '3' -> MFR1 Digit 3: 900Hz + 1100Hz '4' -> MFR1 Digit 4: 700Hz + 1300Hz '5' -> MFR1 Digit 5: 900Hz + 1300Hz '6' -> MFR1 Digit 6: 1100Hz + 1300Hz '7' -> MFR1 Digit 7: 700Hz + 1500Hz '8' -> MFR1 Digit 8: 900Hz + 1500Hz '9' -> MFR1 Digit 9: 1100Hz + 1500Hz '*' -> MFR1 KP (Start of pulsing): 1100Hz + 1700Hz '#' -> MFR1 ST (End of pulsing): 1500Hz + 1700Hz 'A' -> MFR1 STI: 900Hz + 1700Hz 'B' -> MFR1 STII: 1300Hz + 1700Hz 'C' -> MFR1 STIII: 700Hz + 1700Hz 'D' -> Not supported in MFR1 Alternative characters: 'E' -> MFR1 KP (Start of pulsing): 1100Hz + 1700Hz 'F' -> MFR1 ST (End of pulsing): 1500Hz + 1700Hz
Static constants pushed by the stack, for usage in this script
Available actions for "StackAction" function: Commonly used actions:
ACTION_END_SIGNALING ACTION_SET_CAS_BITS ACTION_SEND_WINK ACTION_WAIT_WINK ACTION_SEND_ANI ACTION_SEND_DNIS ACTION_WAIT_ANI ACTION_WAIT_DNIS ACTION_REPORT_SEIZURE ACTION_REPORT_VALIDATE_CALL ACTION_REPORT_ACCEPTED ACTION_REPORT_ALERTED ACTION_REPORT_ANSWERED ACTION_REPORT_BLOCKED ACTION_REPORT_UNBLOCKED ACTION_START_TIMER ACTION_CANCEL_TIMER
Additional actions to implement special variants
ACTION_SEND_TONE ACTION_SET_ANI ACTION_SET_DNIS
Events received by this script on "HandleEvents" function: Commonly used events:
EVENT_CAS_BITS_CHANGED EVENT_WINK_DETECTED EVENT_WINK_COMPLETED EVENT_ANI_RECEIVED EVENT_DNIS_RECEIVED EVENT_ANI_SENT EVENT_DNIS_SENT EVENT_APP_FWD_MAKE_CALL EVENT_APP_BWD_MUST_ALERT EVENT_APP_BWD_MUST_ANSWER EVENT_APP_END_SIGNALING EVENT_APP_BLOCK_TIMESLOT EVENT_APP_UNBLOCK_TIMESLOT EVENT_TIMEOUT
Additional events to implement special variants
EVENT_TONE_RECEIVED EVENT_TONE_SENT
Result code that HandleNewTimeslot or HandleEvent funtions must return:
RESULT_OK RESULT_FAIL RESULT_MISMATCH RESULT_OUT_OF_RESOURCE RESULT_INVALID_PARAM RESULT_INVALID_STATE RESULT_NOT_SUPPORTED RESULT_TRUNK_RES_NOT_IDLE RESULT_BLOCKED_LOCALLY RESULT_BLOCKED_REMOTELY
Call release causes to use with ACTION_END_SIGNALING
CAUSE_FWD_SEIZURE_COLLISION CAUSE_FWD_SEIZURE_ACK_TIMEOUT CAUSE_FWD_TONE_TIMEOUT CAUSE_FWD_ANSWER_TIMEOUT CAUSE_FWD_CALL_REFUSED CAUSE_FWD_REJECT_CALL CAUSE_FWD_HANG_UP CAUSE_BWD_TONE_TIMEOUT CAUSE_BWD_REJECT_CALL CAUSE_BWD_CALL_REFUSED CAUSE_BWD_ALERT_TIMEOUT CAUSE_BWD_ANSWER_TIMEOUT CAUSE_BWD_HANG_UP
Trace levels (used with function StackLogTrace). Least verbose is TRACE_LEVEL_0 (almost never printed). Most verbose is TRACE_LEVEL_4 (generally printed)
TRACE_LEVEL_0 TRACE_LEVEL_1 TRACE_LEVEL_2 TRACE_LEVEL_3 TRACE_LEVEL_4 TRACE_LEVEL_ALWAYS TRACE_LEVEL_ERROR
Mandatory functions to implement in this script
The script must provide the following mandatory functions, that will be called by the CAS stack at appropriate moments.
HandleNewTimeslot( in_TimeslotCtx, in_InitialCasBits )
This function is called to prepare a new timeslot so it's ready to be used to receive events and eventually handle a CASR1 call.
When this function is called, the timeslot must be initially be considered "locally blocked (and CAS bits must be set to "off-hook" state). The stack will later send EVENT_APP_UNBLOCK_TIMESLOT when it's time to go "on-hook" and be ready to make calls.
in_TimeslotCtx
Context containing variables for this timeslot. This context is a LUA table. This table already contains two values:
- ["TrunkNumber"]
- ["TimeslotNumber"]
The script can store it's own LUA variables here (like the "call state"), which will be accessible for any event on this timeslot.
in_InitialCasBits
The initial states of CAS bits received from remote equipment (integer like 0x1111)
HandleEvent( in_TimeslotCtx, in_EventType, ... )
This function reports that an event occurred on a timeslot.
in_TimeslotCtx
Timeslot context used by the script to store any timeslot-related information, like the "call state".
This is the table that was passed to HandleNewTimeslot.
in_EventType
The type of the event that was just received
See below for list of events that can be received: CASR1 script events
...
Variable number of parameters, that depend on event type.
To access these parameters, the LUA syntax is as follows:
-- Create an array with the variable number of arguments: local args = {...} -- Accessing the first argument local first_argument_value = args[1]
Return value
This function must return RESULT_OK, or one of the return codes defined above.
This result code tells to the stack if the event was properly handled by the script. Upon non-OK code, the stack may decide to terminate the call, assuming the script is incomplete and did not expect the event.
Please note that RESULT_OK is normally returned even in case of events that make the call fail or be dropped. The purpose of this result code is not to indicate if the event cause a call to be dropped, but rather to indicate that the script really does not know what to do with the received event.
CASR1 script events
The CASR1 script will receive (and must handle) the following events (received in function HandleEvent
EVENT_CAS_BITS_CHANGED
Indicates that new CAS bits have been received from remote equipment.
Parameters:
- Arg[1]
Received CAS bits (integer like 0x1111)
Indicates that CAS bits values received by remote equipment have changed.
EVENT_WINK_DETECTED
Indicates that a "Wink" has been detected. This event can only follow ACTION_WAIT_WINK.
No specific parameter.
EVENT_WINK_COMPLETED
Indicates that a "Wink" has been sent successfully. This event can only follow ACTION_SEND_WINK.
No specific parameter.
EVENT_TONE_RECEIVED
Indicates that a tone was detected.
Not normally used in CASR1 standard variants, because most variants can rely on ACTION_WAIT_ANI or ACTION_WAIT_DNIS to collect calling/called numbers in one single action.
And thus this event will not report tones that are collected by the CAS stack as part of ACTION_WAIT_ANI or ACTION_WAIT_DNIS.
Parameters:
- Arg[1]
A one-character string that represents the received tone (digit).
See Tones mapping to ASCII characters for details about which ASCII character represents which tone.
EVENT_ANI_RECEIVED
Indicates that ANI (calling number) has been sent received (prefix/suffix detected). This event can only follow ACTION_WAIT_ANI.
Note: The received ANI/DNIS digits are not passed to the script as EVENT_TONE_RECEIVED. Instead, the stack stores them as the 'calling number' which will be reported to the application upon ACTION_REPORT_VALIDATE_CALL
No specific parameter.
EVENT_DNIS_RECEIVED
Same as EVENT_ANI_RECEIVED, but for DNIS (called number)
EVENT_TONE_SENT
Indicates that a tone (digit) as been sent successfully following ACTION_SEND_TONE. Not normally used in CASR1 standard variants.
No specific parameter.
EVENT_ANI_SENT
Indicates that ANI (calling number) has been sent successfully (all tones played). This event can only follow ACTION_SEND_ANI. No specific parameter.
EVENT_DNIS_SENT
Same as EVENT_ANI_SENT, but for DNIS (called number)
EVENT_APP_FWD_MAKE_CALL
Indicate that a new "forward" call must be made.
The script shall take appropriate actions to initiate a new call (most likely change the CAS bits to the "off hook" state).
No specific parameter.
EVENT_APP_BWD_MUST_ALERT
Indicates that this "backward" call must now be set to "alerted" state (meaning we have accepted the call, and received required information to proceed).
The decision of when to alert the call is made by the application, and at that moment the script receives this event so it can take appropriate actions to alert a "backward" call. (in most variants, there is nothing to do, on some variants, a "Wink" may be sent).
No specific parameter.
EVENT_APP_BWD_MUST_ANSWER
Indicates that this "backward" call must now be set to "answered" state.
The decision of when set the call "answered" is made by the application, and at that moment the script receives this event so it can take appropriate actions to answer. (in most variants, CAS bits must be set to "off hook" pattern).
No specific parameter.
EVENT_APP_END_SIGNALING
Indicates either that:
-
Application requests to terminate the call.
The script then take appropriate action, like sending CAS bits to "idle" state, wait for remote equipment to acknowledge, then at the end use ACTION_END_SIGNALING to confirm that termination is completed. -
Script had already previously called ACTION_END_SIGNALING, (after remote equipment set CAS bits to "idle" or after an error in the script), in which case this event confirms that the application is also ready to terminate the call.
The script generally returns to "idle" state after that event.
No specific parameter.
EVENT_APP_BLOCK_TIMESLOT
Indicates that the timeslot must be locally blocked, the next time it becomes "idle".
On most variants where this is supported, a timeslot is "blocked" by going "off-hook", but not sending ANI/DNIS and remaining in that state no matter remote state.
This is also the default state for a newly created timeslot.
When this event is received on a non-idle timeslot (in a call, or establishing a call), it does not drop the call. Timeslot will be blocked only once the timeslot is back to "idle".
This state can only be canceled by EVENT_APP_UNBLOCK_TIMESLOT
No specific parameter.
EVENT_APP_UNBLOCK_TIMESLOT
Cancels a previous EVENT_APP_BLOCK_TIMESLOT, which (in most variants) requires to set our CAS bits to "on hook" (unless still in a call).
No specific parameter.
EVENT_TIMEOUT
Indicates that the timer previously started with ACTION_START_TIMER has expired. It's up to the script to determine the meaning of the timeout and take appropriate action.
No specific parameter.
Stack functions that can be called by this script
The CAS stack provides a few functions that the script can call.
StackActionToString( in_Action )
Returns string value of an action type, generally used for printing debug traces.
In the following example the StackAction function is remapped so that the script will print the action name in a trace every time that "StackAction" is called.
----------------------------------------------------------------------- -- Wraps StackAction function calls with debug comments ----------------------------------------------------------------------- CasR1.StackAction = StackAction function StackAction(name, ...) StackLogTrace(TRACE_LEVEL_2, "Calling StackAction '%s'", StackActionToString(name) ) CasR1.StackAction(name, ...) end
StackEventToString( in_Event )
Returns string value of an event type, generally used for printing debug traces.
Example:
function HandleEvent( in_TimeslotCtx, in_EventType, ... ) StackLogTrace ( TRACE_LEVEL_3, "Event %s received", StackEventToString( in_EventType ) )
StackCauseToString( in_Cause )
Returns string value of a release cause.
Example: my_release_cause = CAUSE_FWD_SEIZURE_COLLISION StackCauseToString( my_release_cause ) will return the string "CAUSE_FWD_SEIZURE_COLLISION".
StackLogTrace( in_TraceLevel, in_Format, ... )
Asks the stack to print a trace (generally debug traces).
Traces will be sent to the "tblogtrace" application.
Parameters:
in_TraceLevel:
Level of the trace (see TRACE_LEVEL_* above)
in_Format:
String that contains the trace to print, plus refernences to other arguments ("printf" style format)
...:
Values for printf-style refernces of in_Format. Example: local cas_bits = 0x1100 StackLogTrace( TRACE_LEVEL_2, "Send CAS bits %08X", cas_bits ) will print "Send CAS bits 1100" to tblogtrace log.
StackAction( in_Action, ... )
This function executes the specified action (in some cases with the specified action-specific arguments). The action is done asynchronously, meaning that control will immediately return to the script. Events will be received later according to the actions taken. Upon an event, the script may perform multiple actions (like starting a timer, declarign the call "alerted" and sending CAS bits for example)
Parameters :
in_Action : The action to perform. (see constants ACTION_* documented below)
... : Variable number of action-specific arguments.
ACTION_END_SIGNALING
Parameter:
- The call release cause to report. See values "CAUSE_". Indicates either that:
- Application previously requested to terminate the call (with EVENT_APP_END_SIGNALING), in which case this action is used by the script to indicate that signaling is fully idle (local CAS bits set to "idle", remote equipment has acknowledged too with "idle" CAS bits).
- Script wants to terminate the call (after remote equipment set CAS bits to "idle" or after an error in the script). After sending ACTION_END_SIGNALING, the script must wait until EVENT_APP_END_SIGNALING is received, which confirms that application is ready to terminate the cally. Only at that moment the script shall set it's CAS bits to "idle" value.
ACTION_SET_CAS_BITS
Parameter:
- CAS bits to set (integer like 0x1111) Used to change the CAS bits that we are sending on current timeslot towawrd remote equipment.
ACTION_SEND_WINK
Parameters:
- CAS bits to set during the "Wink" (integer like 0x1111) - Duration of the "Wink" (in milliseconds) Used to send a "Wink", which is temporary change of the CAS bits for few milliseconds, then back to initial CAS bits value. EVENT_WINK_COMPLETED will be received by the script once Wink has completed (CAS bits are back to their initial value)
ACTION_WAIT_WINK
Parameters:
- Expected CAS bits during the "Wink" (integer like 0x1111) - Minimum duration of the "Wink" (in ms) - Maximum duration of the "Wink" (in ms) Used to request a "Wink" detection. Upon next CAS bits change from remote equipment, the stack will see if the bits match the Wink expected bits. EVENT_WINK_DETECTED will be reported if CAS bits received from remote equipment change to the expected pattern for a duration within specified range, then go back to original value. Any other CAS bits change not deteced as a "Wink" will be reported to the script by EVENT_CAS_BITS_CHANGED (which will probably want to drop the call because a Wink was expected)
ACTION_SEND_TONE
Parameters:
- Digit (tone) to send. (see "Digit format" below) Used to send one digit (tone) toward remote equipment. EVENT_TONE_SENT will be received once the tone has been successfully sent. Not normally used in CASR1 standard variants. Note: This action is not used to send ANI/DNIS (calling/called numbers), it's used to send other tones that may be used within the current CASR1 variant call flow.
ACTION_SEND_ANI
Parameters:
- Prefix to send before ANI. Can be empty. - Suffix to send after ANI. Can be empty. (see "Digit format" below) Used to send ANI (calling number) toward remote equipment, using tones. A prefix may be inserted before ANI. A suffix is mandatory. It's transmitted after ANI. Remote equipment expects that suffix to determine that the ANI has been entirely sent. EVENT_ANI_SENT will be received once transmission of prefix + ANI + suffix completed
ACTION_SEND_DNIS
Same as ACTION_SEND_ANI, but for sending DNIS (called number)
ACTION_WAIT_ANI
Parameters:
- Prefix to expect before ANI. Can be empty. - Suffix to expect after ANI. Can be empty only if next argument (nb expected digits) is set. (see "Digit format" below) - Number of expected digits. Optional. Only required if suffix is empty. Used to wait for ANI (calling number) from remote equipment, by detecting tones. A prefix may be expected before ANI. A suffix is mandatory. It's received after ANI to indicate that the ANI has been entirely transmitted. EVENT_ANI_RECEIVED will be received if a matching prefix + suffix are detected.
ACTION_WAIT_DNIS
Same as ACTION_WAIT_ANI, but for receiving DNIS (called number)
ACTION_SET_ANI
Parameters:
- ANI to set Used to replace the ANI detected by the stack with this ANI provided by the script. This action must be calld before action TBX_CASR2VMLIB_CASR1_ACTION_REPORT_VALIDATE_CALL (otherwise it's too late to set ANI) Not normally used in CASR1 standard variants.
ACTION_SET_DNIS
Same as ACTION_SET_ANI, but for DNIS (called number)
ACTION_REPORT_SEIZURE
No parameter.
Tell the application that seizure (off-hook) has been deteced on a timeslot.
ACTION_REPORT_VALIDATE_CALL
No parameter.
Tell the application that ANI and/or DNIS have been successfully received, and we now have the information required to process this incoming call.
ACTION_REPORT_ACCEPTED
No parameter.
Tell the application that a "forward" call has been accepted by remote equipment, often by detecting a "Wink".
ACTION_REPORT_ALERTED
No parameter.
Tell the application that a "forward" call has been alerted by remote equipment. On most variants, there is no specific indication from remote side, and this action must be taken upon EVENT_DNIS_SENT. On other variants, a "Wink" may be awaited before calling this action.
ACTION_REPORT_ANSWERED
No parameter.
Tell the application that a "forward" call has been answered by remote equipment, generally because "off-hook" CAS bits have been received.
ACTION_REPORT_BLOCKED
No parameter.
Tells the application that the script considers the timeslot as "remotely blocked". This is the case when remote side goes "off hook" and remains in that state for some duration after we've returned to "on hook" on our side.
ACTION_REPORT_UNBLOCKED
No parameter.
Tells the application that the timeslot is no more "remotely blocked", because remote equipment went "on hook" after we reported ACTION_REPORT_BLOCKED.
ACTION_START_TIMER
Parameter:
- Timer duration in milliseconds. Starts a timer. EVENT_TIMEOUT will be posted if the timer expires before ACTION_CANCEL_TIMER is called.
ACTION_CANCEL_TIMER
No parameter. Cancels a timer previously started with ACTION_START_TIMER.
Digit format:
The digit format (for sending tone or ANI/DNIS prefix/suffix) is represented by a string that contains up to 3 of the following characters: 0123456789ABCD*#
== Debugging the script ==