You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sems/doc/dsm/dsm_syntax.txt

553 lines
16 KiB

DSM quick reference
===================
Syntax
======
-- comment
#include "script.dsm"
#include "/path/to/anotherscript.dsm"
import(mod_name);
[initial] state name
[ enter {
<actions>
} ]
[ exit {
<actions>
} ]
;
transition name s1 - [ { [not] condition; [not] condition; ... } ] [/ { <actions>} ] -> s2;
or
transition name (s1a, s1b[, s1c, ...]) - [ { [not] condition; [not] condition; ... } ] [/ { <actions> } ] -> s2;
or (exception transition)
transition name s1 - exception [ { [not] condition; ... } ] [/ { <actions>} ] -> s2;
function func_name() {
<actions>
};
<actions> ::=
action;
action(param, param, ...);
if condition; condition; {
<actions>
} else {
<actions>
}
func_name();
...
Variables, event parameters, selects
====================================
#paramname uses the event parameter 'paramname' (from current event)
$varname uses the variable varname (from session's variable)
@selectname uses the "select" 'selectname' (from the session's dialog)
use ## for # (e.g. set($hash=##); )
$$ for $ (e.g. set($dol=$$); )
@@ for @ (e.g. set($at=@@); )
Variable arrays:
$myarray[0]
$myarray[1]
...
Variable structs:
$mystruct.member1
$mystruct.member2
Core actions
============
DSM flow
--------
-- call/jump/return sub-FSM
jumpFSM(name)
callFSM(name) - note that actions after callFSM may have the event & event params of the sub-FSM
returnFSM()
stop(<send bye>)
e.g. stop(false), stop(true)
-- reprocess the current event after transition:
repost()
Variable manipulation
---------------------
set($var=value)
e.g. set($var="text"); set($var=$var2); set($var=#key)
sets($var=value)
e.g. sets($var="text and some $variable and some #param");
var($dstvar=srcvarname)
e.g. var($dstvar=$var_counter)
param($dstvar=srcparamname)
e.g. param($dstvar=$myparam) (like: #($myparam) )
eval($var=value)
evaluate expression (only simple binary + and - supported)
e.g. set($var=1+5); set($var=$var2); set($var=#key)
append($var, value)
e.g. append($var, "text"); append($var, #key);
append($var, @select); append($var, $var2);
substr($var, pos)
e.g. substr($myvar, 5);
size($arrayname, $dst);
set variable $dst to size of array
(e.g. $arrayname[0], $arrayname[1] set, $dst set to 2)
inc($var)
clear($var)
clearArray($var)
clears all var.* variables
Playing prompts and file I/O
----------------------------
playPrompt(param)
from promptCollection, e.g. playPrompt("hello");
if $prompts.default_fallback=yes, default prompt set is tried if
prompt not found in current prompt set
Throws "prompt" exeption with #name if prompt not found.
playPromptFront(param) - play a prompt at first item in the playlist
playPromptLooped(param)
setPromptSet(name)
select active prompt set if more prompt sets are loaded
Throws "prompt" exeption with #name if prompt set not found
playFile(filename [, loop=true])
e.g. playFile($myfile, true); will play the file looped.
Throws "file" exeption with #path if file can not be opened
playFileFront(filename [, loop=true])
e.g. playFileFront($myfile, true); will play the file at first
position in the playlist, and looped.
Throws "file" exeption with #path if file can not be opened
playSilence(millisec) - play silence for millisec ms
playSilenceFront(millisec) - play silence for millisec ms at first position in playlist
recordFile(filename)
Throws "file" exeption with #path if file can not be opened for recording
stopRecord()
getRecordLength([dst_varname]) -- only while recording! default dst var: record_length
getRecordDataSize([dst_varname]) -- only while recording! default dst var: record_data_size
flushPlaylist()
setInOutPlaylist()
set playlist as input and output
setInputPlaylist()
set playlist as input (output untouched)
setOutputPlaylist()
set playlist as output (input untouched)
addSeparator(id [, bool front])
fires event when playlist hits it ; front=[true|false]
connectMedia() - set playlist as input and output of session,
and start processing of RTP and audio
(connect to mediaprocessor)
disconnectMedia() - stop processing of RTP and audio (disconnect from mediaprocessor)
enableReceiving() - enable processing of received RTP
disableReceiving() - disable processing of received RTP
enableForceDTMFReceiving() - enable/disable RTP DTMF packets processing even
disableForceDTMFReceiving() if received RTP is not processed, e.g. after
disableReceiving() or in passive mode
(only for RFC2833/4733 DTMF, *no* in-band)
monitorRTPTimeout(enabled=false)
set call to monitor RTP timeout (enabled="true" or "false")
mute() - set RTP stream to muted (don't send RTP packets)
unmute() - set RTP stream to unmuted (do send RTP packets)
DTMF
----
enableDTMFDetection()
disableDTMFDetection()
sendDTMF(key [, duration_ms])
send a DTMF event (RFC4733 event)
duration_ms defaults to 500ms
sendDTMFSequence(sequence [, duration_ms])
send a sequence of DTMF events (RFC4733 event), e.g. 123#45*1
duration_ms defaults to 500ms
B2B call control
----------------
B2B.connectCallee(remote_party, remote_uri)
connect second leg of B2B session (see AmB2BSession)
R-URI = remote_uri
To = remote_party
From = $b2b_local_party
auth = ($b2b_auth_user, $b2b_auth_pwd)
Call-ID = $b2b_callid
$b2b_relayed_invite=[true|false] : use relayed INVITE mode
B2B.terminateOtherLeg
disconnect second leg of B2B session (see AmB2BSession),
e.g. to connect to a new destination
note: don't use this when receiving BYE in an established
B2BUA call, as the BYE is sent end-to-end
B2B.sendReinvite(generate_sdp [, string extra_headers])
send a reinvite in caller leg (first leg), e.g. to
reconnect first leg after B2B.otherBye received.
generate_sdp can be 'true' or 'false'
(B2B.sendReinvite(true) recommended)
B2B.clearHeaders()
clear the headers used for outgoing INVITE on B leg
B2B.enableEarlyMediaRelay(enable=[true|false])
enable or disable relaying of early media SDP (180-183) as re-Invite in the first leg
B2B.addHeader(string header)
add a header for outgoing INVITE on B leg
B2B.removeHeader(string header_name)
remove a header for outgoing INVITE on B leg
B2B.setHeaders(string headers [, replace_crlf=true|false])
set headers for outgoing INVITE on B leg
replace_crlf=true for replacing \r\n with CRLF
e.g.
B2B.setHeaders("P-One: value\r\nP-Two: anothervalue", true)
B2B.relayEvent(variable_name;variable_name;...)
relay B2Bevent to related B2B session; variables copied as event parameters
e.g. B2B.relayEvent(var1;var2;var3) relay event with var1, var2, var3
B2B.relayEvent("var")
relay B2Bevent to related B2B session with all variables of current DSM session
Logging
-------
log(level, text)
e.g. log(1, $var1)
-- log all variables:
logVars(level)
-- log all selects:
logSelects(level)
-- log all Params (only in actions of a transition):
logParams(level)
-- log everything:
logAll(level)
Timers
------
setTimer(timer_id, timeout)
e.g. setTimer(1, $timeout)
* sets $errno (arg,config)
removeTimer(timer_id)
* sets $errno (arg,config)
removeTimers()
* sets $errno (config)
DI functions
------------
DI(factory, function [, params...])
execute DI function
e.g. DI(factory, function, $var_param, (int)int_param, "str param", @select_par, (array)arrayname, (struct)structname, (json)json_object...)
DI(monitoring, set, "mytable", @local_tag, (int)1);
set($sweets.candy="nice");
set($sweets.fruit="superb");
set($sweets.cake.tahini="great");
DI(myfactory, myfunc, (struct)sweets);
set($bi[0]="ba");
set($bi[1]="butzki");
DI(myfactory, myfunc, (array)bi);
set($js="{"x":"y", "a": 1}");
DI(myfactory, myfunc, (json)$js);
* sets $errno (arg,config)
DIgetResult(factory, function, param,...)
saves result from DI call to DI_res or DI_res0, DI_res1, ...
* sets $errno (arg,config)
Exception handling
------------------
throw(<type>[,arg1=val1;arg2=val2;...])
e.g. throw(bad_command), throw(bad_command,cmd=help;reason=whynot)
throwOnError()
Events
------
postEvent(sess_id[, variable_name;variable_name;...])
post dsm event to session sess_id; variables copied as event parameters
e.g. postEvent(@local_tag, PAI) : post event to ourselves
postEvent($some_call, var1;var2;var3) post event with var1, var2, var3
* sets $errno (arg)
postEvent(sess_id, var)
all local variables copied as event variables
* sets $errno (arg)
registerEventQueue(queue_name)
register session to receive events under the name queue_name
WARNING: make sure to unregister the event queue before ending the session!
unregisterEventQueue(queue_name)
unregister events queue queue_name
Object memory management/Garbage collector:
freeObject(varname) - free object referenced with varname immediately
trackObject(varname) - track object referenced with varname, i.e. enable garbage
collection with the current call/systemDSM
releaseObject(varname) - release object referenced with varname from garbage collector
Conditions
==========
Conditions are combined as AND, i.e. a transition is executed if all conditions match.
Generic conditions (regardless of the type of the event):
test(#key == 1)
test(#key == prefix*)
test(#key != 1)
test(#key < 1)
test(#key > 1)
test($var == 1)
test($var == prefix*)
test($var != 1)
test($var < 1)
test($var < 1)
test(len($var) < len(#key))
test(len($var) < len(@user))
Other conditions only match on the type of event and when the expression expr in the
brackets match.
start
start of a session (onStart). This event is processed before any other.
hangup
bye/cancel received
parameters:
#headers - headers of the BYE/CANCEL request
key(expr) or keyTest(expr)
parameters:
#key - Key pressed (0 - 11, * is 10, # is 11)
#duration - duration of key press
timer(expr) or timerTest(expr)
parameters:
#id - Timer ID
noAudio(expr) or noAudioTest(expr)
parameters:
#type - "cleared" (audio cleared) or "noAudio" (playlist empty)
separator(expr) or separatorTest(expr)
parameters:
#id - Separator ID
e.g. separatorTest(#id == 5)
event(expr) or eventTest(expr)
generic event, e.g. passed from DI or another call with postEvent
parameters depend on the DI call/the ones passed with postEvent
B2Bevent(expr)
generic event from B2B related call leg
parameters depend on the ones passed with B2B.relayEvent
keyPress(key)
alias to key(#key==key)
remoteDisappeared(expr)
remote end in an established call is unreachable (408/481 received)
parameters: see sipReply (below), except #old_dlg_status
set #processed="true" if you don't want default behaviour (clear call)
sessionTimeout(expr)
session expired (SST)
parameters: none
set #processed="true" if you don't want default behaviour (clear call)
rtpTimeout(expr)
RTP timeout detected
#type - "rtp_timeout"
#timeout_value - RTP timeout value (as configured)
set #processed="true" if you don't want default behaviour (clear call)
invite
invite received/sent (only with run_invite_event):
parameters: none
ringing
outgoing call: ringing reply, 180 (only with run_invite_event):
parameters:
#code - SIP response code, e.g. 180
#reason - SIP reason string, e.g. "Ringing"
#has_body - "true" or "false"
early
outgoing call: early session, 183 (only with run_invite_event):
parameters: none
failed
outgoing call failed (only with run_invite_event):
parameters:
#code - SIP response code, e.g. 404
#reason - SIP reason string, e.g. "Not found"
sessionStart
start of session (with run_invite_event):
parameters: none
startup
startup of a system DSM
parameters: none
reload
reload (system DSM)
system
system event - shutdown or SIGNAL sent (kill <pid>)
parameters:
#type - system event type, e.g. ServerShutdown, User1, User2
B2B.otherRequest (only sbc)
Request on other B2B leg received
parameters:
#method, #r_uri, #from, #to, #hdrs - from request
B2B.otherReply
Reply on other B2B leg received
parameters:
#code - reply code
#reason - reply reason
#hdrs - headers
#trans_method - transaction method (only sbc)
B2B.otherBye
BYE on other leg received
#hdrs - headers
sipRequest
SIP request received - only executed if enable_request_events=="true"
parameters:
#method - SIP method
#r_uri - request URI
#from - From
#to - To
#hdrs - Headers (apart from dialog-IDs)
#content_type - Content-Type
#body - body of message
#cseq - CSeq
sipReply
SIP reply received - only executed if enable_reply_events=="true"
parameters:
#code - response code
#reason - reason string
#hdrs - Headers (apart from dialog-IDs)
#content_type - Content-Type
#body - body of message
#cseq - CSeq
#dlg_status - SIP dialog status (Disconnected, Trying, ...)
#old_dlg_status - old SIP dialog status (before this reply)
jsonRpcRequest - json-rpc request received
parameters:
#ev_type - JsonRpcRequest
#method - RPC method
#is_notify - "true" or "false"
#id - request ID (if present)
#params.* - parameters array
subscription - SIP subscription status
#status - status: "active", "pending", "failed", "terminated", "timeout"
#code - SIP response code (if failed)
#reason - SIP response reason (if failed)
NOTIFY body in avar[DSM_AVAR_SIPSUBSCRIPTION_BODY] (if #status=="active")
jsonRpcResponse - json-rpc response received
#ev_type - JsonRpcResponse
#id - response ID
#is_error - "true" or "false"
#udata - user data that was saved when sending the request
#result.* or #error.* - response data array (or error data)
conference events:
generic events with
#type - "conference_event"
#id - event ID
Selects
=======
selects :
@local_tag
@user
@domain
@remote_tag
@callid
@local_party
@local_uri
@remote_uri
@remote_party
Importing modules
=================
module imported with import(mod_name); loads mod_name.so in
module load path. modules provide conditions and actions.
modules' actions/conditions-factory is checked first
(modules can override core conditions/actions)
Variables controlling call flow
===============================
special variables:
connect_session "0" -> after the start event (initial transition):
do not connect session to
media processor on start
-> after the invite event:
do not reply with 200 OK and do not
connect session to media processor on start
enable_request_events "true" - run events on receiving a request
"false" - don't run events on receiveing request
b2b_local_party - From in outgoing B2B call
b2b_local_uri - URI of From for B2B call, for application internal use
b2b_auth_user - SIP auth user for 2nd leg of B2B call
b2b_auth_pwd - SIP auth pwd for 2nd leg of B2B call
=============================
errors:
actions set $errno
#define DSM_ERRNO_OK ""
#define DSM_ERRNO_FILE "1"
#define DSM_ERRNO_UNKNOWN_ARG "2"
#define DSM_ERRNO_GENERAL "99"
...