321 lines
16 KiB
HTML
321 lines
16 KiB
HTML
<html>
|
|
<head>
|
|
<title>YATE - External module</title>
|
|
</head>
|
|
<body>
|
|
The work on this document is still in progress.
|
|
Please do not use it as reference, the specifications are likely to change.
|
|
|
|
<h1>External module command flow</h1>
|
|
|
|
<h2>File handles used</h2>
|
|
The external user application or script comunicates with the module trough
|
|
several file descriptors:<br />
|
|
0 (stdin) - Carries commands and notifications from engine to application<br />
|
|
1 (stdout) - Carries commands and answers from application to the engine<br />
|
|
2 (stderr) - Has the usual meaning of reporting errors and is directed to the engine's stderr or logfile<br />
|
|
3 (optional) - Transports audio data from the engine to the application<br />
|
|
4 (optional) - Transports audio data from the application to the engine<br />
|
|
|
|
File descriptors 3 and 4 are open only for audio capable applications.<br />
|
|
|
|
<h2>Socket operation</h2>
|
|
Yate can start one or more socket listeners and wait for external programs to
|
|
connect to them. Depending on the platform, TCP and UNIX sockets may be available.<br />
|
|
Once connected, an external program uses this single socket to send commands and
|
|
receive answers from the engine.<br />
|
|
For reporting errors it is recommended to use the <b>%%>output</b> keyword.<br />
|
|
Each listener can have a single role or the connecting program will have to
|
|
use the <b>%%>connect</b> command first to esablish a role.<br />
|
|
|
|
<h2>Format of commands and notifications</h2>
|
|
|
|
<p>
|
|
Words enclosed in <angle brackets> must be replaced with the proper value.<br />
|
|
|
|
Elements in [square brackets] are optional. An ellipsis ... denotes optional
|
|
repetition of the last element.<br />
|
|
|
|
Every command is sent on its own newline (\n, ^J, decimal 10) delimited line.<br />
|
|
|
|
Any value that contains special characters (ASCII code lower than 32) MUST have
|
|
them converted to %<upcode> where <upcode> is the character with a
|
|
numeric value equal with 64 + original ASCII code. The % character itself MUST
|
|
be converted to a special %% representation. Characters with codes higher than 32
|
|
(except %) SHOULD not be escaped but may be so. A %-escaped code may be received
|
|
instead of an unescaped character anywhere except in the initial keyword or the
|
|
delimiting colon (:) characters. Anywhere in the line except the initial keyword
|
|
a % character not followed by a character with a numeric value higher than 64
|
|
(40H, 0x40, '@') or another % is an error.<br />
|
|
</p>
|
|
|
|
<p><b>Special Keyword: Error in</b><br />
|
|
Error in:<original><br />
|
|
<b>Direction: Engine to application</b><br />
|
|
The engine sends this notification as answer to a syntactically incorrect line
|
|
it received from the application.<br />
|
|
<original> - the original line exactly as received (not escaped or something)<br />
|
|
The external module SHOULD NOT send anything back to Yate in response to such a
|
|
notification as it can result in an infinite loop.<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%>message</b><br />
|
|
%%>message:<id>:<time>:<name>:<retvalue>[:<key>=<value>...]<br />
|
|
<b>Direction: Engine to application</b><br />
|
|
This line is sent by the engine to the application) to ask it to process a message.
|
|
The Yate thread that dispatches the message will block until an answer is
|
|
received (see below).<br />
|
|
<id> - obscure unique message ID string generated by Yate<br />
|
|
<time> - time (in seconds) the message was initially created<br />
|
|
<name> - name of the message<br />
|
|
<retvalue> - default textual return value of the message<br />
|
|
<key>=<value> - enumeration of the key-value pairs of the message<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%<message</b><br />
|
|
%%<message:<id>:<processed>:[<name>]:<retvalue>[:<key>=<value>...]<br />
|
|
<b>Direction: Application to engine</b><br />
|
|
One such answer is required for every received message (%%>message). When
|
|
the engine gets a line in this format it modifies the provided values back into
|
|
the message and let it continue or stop dispatching.<br />
|
|
<id> - same message ID string received trough %%>message<br />
|
|
<processed> - boolean ("true" or "false") indication
|
|
if the message has been processed or it should be passed to the next handler<br />
|
|
<name> - new name of the message, if empty keep unchanged<br />
|
|
<retvalue> - new textual return value of the message<br />
|
|
<key>=<value> - new key-value pairs to set in the message; to delete
|
|
the key-value pair provide just a key name with no equal sign or value<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%>message</b><br />
|
|
%%>message:<id>:<time>:<name>:<retvalue>[:<key>=<value>...]<br />
|
|
<b>Direction: Application to engine</b><br />
|
|
This line is sent by the application to the engine to ask it to process a message.
|
|
The answer to such a message is delivered asynchronously (see below).<br />
|
|
<id> - obscure unique message ID string generated by the application<br />
|
|
<time> - time (in seconds) the message was initially created<br />
|
|
<name> - name of the message<br />
|
|
<retvalue> - default textual return value of the message<br />
|
|
<key>=<value> - enumeration of the key-value pairs of the message<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%<message</b><br />
|
|
%%<message:<id>:<processed>:[<name>]:<retvalue>[:<key>=<value>...]<br />
|
|
<b>Direction: Engine to application</b><br />
|
|
One such answer is required for every message (%%>message) the application
|
|
sent to the engine. It contains the message's return values and parameters.<br />
|
|
<id> - same message ID string received trough %%>message<br />
|
|
<processed> - boolean ("true" or "false") indication
|
|
if the message has been declared processed by one of the handlers<br />
|
|
<name> - name of the message, possibly changed<br />
|
|
<retvalue> - textual return value of the message<br />
|
|
<key>=<value> - key-value pairs of parameters to the message.<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%>install</b><br />
|
|
%%>install:[<priority>]:<name>[:<filter-name>[:<filter-value>]]<br />
|
|
<b>Direction: Application to engine</b><br />
|
|
Always from the application to the engine, requests the installing of a message
|
|
handler for the application that requested it<br />
|
|
The answer to the install request is delivered asynchronously (see below).<br />
|
|
<priority> - priority in chain, use default (100) if missing<br />
|
|
<name> - name of the messages for that a handler should be installed<br />
|
|
<filter-name> - name of a variable the handler will filter<br />
|
|
<filter-value> - matching value for the filtered variable<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%<install</b><br />
|
|
%%<install:<priority>:<name>:<success><br />
|
|
<b>Direction: Engine to application</b><br />
|
|
Confirmation from engine to the application that the handler has been installed
|
|
properly or not.<br />
|
|
<priority> - priority of the installed handler<br />
|
|
<name> - name of the messages asked to handle<br />
|
|
<success> - boolean ("true" or "false") success of operation<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%>uninstall</b><br />
|
|
%%>uninstall:<name><br />
|
|
<b>Direction: Application to engine</b><br />
|
|
Always from the application to the engine, requests uninstalling a previously
|
|
installed message handler<br />
|
|
The answer to the uninstall request is delivered asynchronously (see below).<br />
|
|
<name> - name of the message handler thst should be uninstalled<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%<uninstall</b><br />
|
|
%%<uninstall:<priority>:<name>:<success><br />
|
|
<b>Direction: Engine to application</b><br />
|
|
Confirmation from engine to the application that the handler has been uninstalled
|
|
properly or not.<br />
|
|
<priority> - priority of the previously installed handler<br />
|
|
<name> - name of the message handler asked to uninstall<br />
|
|
<success> - boolean ("true" or "false") success of operation<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%>watch</b><br />
|
|
%%>watch:<name><br />
|
|
<b>Direction: Application to engine</b><br />
|
|
Always from the application to the engine, requests the installing of a message
|
|
watcher (post-dispatching notifier) for the application that requested it<br />
|
|
The answer to the watch request is delivered asynchronously (see below).<br />
|
|
<name> - name of the messages for that a watcher should be installed<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%<watch</b><br />
|
|
%%<watch:<name>:<success><br />
|
|
<b>Direction: Engine to application</b><br />
|
|
Confirmation from engine to the application that the watcher has been installed
|
|
properly or not.<br />
|
|
<name> - name of the messages asked to watch<br />
|
|
<success> - boolean ("true" or "false") success of operation<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%>unwatch</b><br />
|
|
%%>unwatch:<name><br />
|
|
<b>Direction: Application to engine</b><br />
|
|
Always from the application to the engine, requests uninstalling a previously
|
|
installed message watcher<br />
|
|
The answer to the unwatch request is delivered asynchronously (see below).<br />
|
|
<name> - name of the message watcher thst should be uninstalled<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%<unwatch</b><br />
|
|
%%<unwatch:<name>:<success><br />
|
|
<b>Direction: Engine to application</b><br />
|
|
Confirmation from engine to the application that the watcher has been uninstalled
|
|
properly or not.<br />
|
|
<name> - name of the message watcher asked to uninstall<br />
|
|
<success> - boolean ("true" or "false") success of operation<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%>setlocal</b><br />
|
|
%%>setlocal:<name>:<value><br />
|
|
<b>Direction: Application to engine</b><br />
|
|
Always from the application to the engine, requests the change of a local
|
|
parameter<br />
|
|
The answer to the change request is delivered asynchronously (see below).<br />
|
|
<name> - name of the parameter to modify, must not be empty<br />
|
|
<value> - new value to set in the local module instance, empty to just query<br />
|
|
For read-only parameters you must provide an empty value.<br />
|
|
<b>Currently supported parameters:</b><br />
|
|
id (string) - Identifier of the associated channel, if any<br />
|
|
disconnected (bool) - Enable or disable sending "chan.disconnected" messages<br />
|
|
reason (string) - Set the disconnect reason that gets received by the peer channel<br />
|
|
timeout (int) - Timeout in milliseconds for answering to messages<br />
|
|
timebomb (bool) - Terminate this module instance if a timeout occured<br />
|
|
setdata (bool) - Attach channel pointer as user data to generated messages<br />
|
|
reenter (bool) - If this module is allowed to handle messages generated by itself<br />
|
|
selfwatch (bool) - If this module is allowed to watch messages generated by itself<br />
|
|
restart (bool) - Restart this global module if it terminates unexpectedly. Must be turned off to allow normal termination<br />
|
|
<b>Engine read-only run parameters:</b><br />
|
|
engine.version (string,readonly) - Version of the engine, like "2.0.1"<br />
|
|
engine.release (string,readonly) - Release type and number, like "beta2"<br />
|
|
engine.nodename (string,readonly) - Server's node name as known by the engine<br />
|
|
engine.runid (int,readonly) - Engine's run identifier<br />
|
|
engine.configname (string,readonly) - Name of the master configuration<br />
|
|
engine.sharedpath (string,readonly) - Path to the shared directory<br />
|
|
engine.configpath (string,readonly) - Path to the program config files directory<br />
|
|
engine.cfgsuffix (string,readonly) - Suffix of the config files names, normally ".conf"<br />
|
|
engine.modulepath (string,readonly) - Path to the main modules directory<br />
|
|
engine.modsuffix (string,readonly) - Suffix of the loadable modules, normally ".yate"<br />
|
|
engine.logfile (string,readonly) - Name of the log file if in use, empty if not logging<br />
|
|
engine.clientmode (bool,readonly) - Check if running as a client<br />
|
|
engine.supervised (bool,readonly) - Check if running under supervisor <br />
|
|
engine.maxworkers (int,readonly) - Maximum number of message worker threads<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%<setlocal</b><br />
|
|
%%<setlocal:<name>:<value>:<success><br />
|
|
<b>Direction: Engine to application</b><br />
|
|
Confirmation from engine to the application that the local parameter has been
|
|
changed successfully or not.<br />
|
|
<name> - name of the modified parameter<br />
|
|
<value> - new value of the local parameter<br />
|
|
<success> - boolean ("true" or "false") success of operation<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%>output</b><br />
|
|
%%>output:arbitrary unescaped string<br />
|
|
<b>Direction: Application to engine</b><br />
|
|
The "output" keyword is used to relay arbitrary output messages to
|
|
engine's logging output.<br />
|
|
This is the proper way of logging messages for programs that connect to the
|
|
socket interface as they may not have the standard error redirected.<br />
|
|
</p>
|
|
|
|
<p><b>Keyword: %%>connect</b><br />
|
|
%%>connect:<role>[:<id>][:<type>]<br />
|
|
<b>Direction: Application to engine</b><br />
|
|
The "connect" keyword is used only by external modules that attach to
|
|
the socket interface. As the conection is initiated from the external module the
|
|
engine must be informed on the role of the connection.<br />
|
|
This must be the first request sent over a newly established socket connection.
|
|
The role and direction of the connection is established and then this keyword
|
|
cannot be used again on the same connection.<br />
|
|
There is no answer to this request - if it fails the engine will slam the
|
|
connection shut.<br />
|
|
Connections with a role of play, record or playrec are data connections and must
|
|
be attached to a valid control channel. Any existing data endpoint with the same
|
|
type and direction is closed.<br />
|
|
<role> - role of this connection: global, channel, play, record, playrec<br />
|
|
<id> - channel id to connect this socket to<br />
|
|
<type> - type of data channel, assuming audio if missing<br />
|
|
</p>
|
|
|
|
<h2>Example</h2>
|
|
<p>
|
|
In the example below the lines sent from application to engine are prefixed with
|
|
A: while lines sent from engine to application are prefixed with E:<br />
|
|
Comments are indented<br />
|
|
</p>
|
|
|
|
<pre>
|
|
|
|
Application installs a handler for a "test" handler with priority 50
|
|
A: %%>install:50:test
|
|
|
|
Engine installs the handler and acknowledges it
|
|
E: %%<install:50:test:true
|
|
|
|
Application installs a handler for the "engine.timer" handler with default priority
|
|
A: %%>install::engine.timer
|
|
|
|
Engine installs the handler and acknowledges it
|
|
E: %%<install:100:engine.timer:true
|
|
|
|
Application emits a private "app.job" message; notice how the '%' and ':' characters were escaped
|
|
A: %%>message:myapp55251:1095112794:app.job::job=cleanup:done=75%%:path=/bin%Z/usr/bin
|
|
|
|
Engine just dispatched an "engine.timer" message
|
|
E: %%>message:234479208:1095112795:engine.timer::time=1095112795
|
|
|
|
Engine gets back the answer to the "app.job" message with a "Restart required" returned text value
|
|
E: %%<message:myapp55251:true:app.job:Restart required:path=/bin%Z/usr/bin%Z/usr/local/bin
|
|
|
|
Application ignores the timer message
|
|
A: %%<message:234479208:false:engine.timer::time=1095112795
|
|
|
|
Application uninstalls the "test" handler
|
|
A: %%>uninstall:test
|
|
|
|
Engine removes the handler and acknowledges it
|
|
E: %%<uninstall:50:test:true
|
|
|
|
Engine just dispatched another "engine.timer" message
|
|
E: %%>message:234479288:1095112796:engine.timer::time=1095112796
|
|
|
|
Application modifies the timer message but lets it flow further
|
|
A: %%<message:234479288:false:engine.timer::time=1095112796:extra=yes
|
|
|
|
Engine just dispatched another "engine.timer" message
|
|
E: %%>message:234479244:1095112797:engine.timer::time=1095112797
|
|
|
|
Application suddenly exits without acknowledging previous message.
|
|
The engine releases the message 234479244 (as if "false" was returned) and
|
|
uninstalls the remaining "engine.timer" handler
|
|
</pre>
|
|
|
|
</body>
|
|
</html>
|