yate/docs/extmodule.html

201 lines
9.2 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>Format of commands and notifications</h2>
<p>
Words enclosed in &lt;angle brackets&gt; 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 %&lt;upcode&gt; where &lt;upcode&gt; 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:&lt;original&gt;<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 />
&lt;original&gt; - 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: %%&gt;message</b><br />
%%&gt;message:&lt;id&gt;:&lt;time&gt;:&lt;name&gt;:&lt;retvalue&gt;[:&lt;key&gt;=&lt;value&gt;...]<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 />
&lt;id&gt; - obscure unique message ID string generated by Yate<br />
&lt;time&gt; - time (in seconds) the message was initially created<br />
&lt;name&gt; - name of the message<br />
&lt;retvalue&gt; - default textual return value of the message<br />
&lt;key&gt;=&lt;value&gt; - enumeration of the key-value pairs of the message<br />
</p>
<p><b>Keyword: %%&lt;message</b><br />
%%&lt;message:&lt;id&gt;:&lt;processed&gt;:[&lt;name&gt;]:&lt;retvalue&gt;[:&lt;key&gt;=&lt;value&gt;...]<br />
<b>Direction: Application to engine</b><br />
One such answer is required for every received message (%%&gt;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 />
&lt;id&gt; - same message ID string received trough %%&gt;message<br />
&lt;processed&gt; - boolean (&quot;true&quot; or &quot;false&quot;) indication
if the message has been processed or it should be passed to the next handler<br />
&lt;name&gt; - new name of the message, if empty keep unchanged<br />
&lt;retvalue&gt; - new textual return value of the message<br />
&lt;key&gt;=&lt;value&gt; - 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: %%&gt;message</b><br />
%%&gt;message:&lt;id&gt;:&lt;time&gt;:&lt;name&gt;:&lt;retvalue&gt;[:&lt;key&gt;=&lt;value&gt;...]<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 />
&lt;id&gt; - obscure unique message ID string generated by the application<br />
&lt;time&gt; - time (in seconds) the message was initially created<br />
&lt;name&gt; - name of the message<br />
&lt;retvalue&gt; - default textual return value of the message<br />
&lt;key&gt;=&lt;value&gt; - enumeration of the key-value pairs of the message<br />
</p>
<p><b>Keyword: %%&lt;message</b><br />
%%&lt;message:&lt;id&gt;:&lt;processed&gt;:[&lt;name&gt;]:&lt;retvalue&gt;[:&lt;key&gt;=&lt;value&gt;...]<br />
<b>Direction: Engine to application</b><br />
One such answer is required for every message (%%&gt;message) the application
sent to the engine. It contains the message's return values and parameters.<br />
&lt;id&gt; - same message ID string received trough %%&gt;message<br />
&lt;processed&gt; - boolean (&quot;true&quot; or &quot;false&quot;) indication
if the message has been declared processed by one of the handlers<br />
&lt;name&gt; - name of the message, possibly changed<br />
&lt;retvalue&gt; - textual return value of the message<br />
&lt;key&gt;=&lt;value&gt; - key-value pairs of parameters to the message.<br />
</p>
<p><b>Keyword: %%&gt;install</b><br />
%%&gt;install:[&lt;priority&gt;]:&lt;name&gt;<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 />
&lt;priority&gt; - priority in chain, use default (100) if missing<br />
&lt;name&gt; - name of the messages for that a handler should be installed<br />
</p>
<p><b>Keyword: %%&lt;install</b><br />
%%&lt;install:&lt;priority&gt;:&lt;name&gt;:&lt;success&gt;<br />
<b>Direction: Engine to application</b><br />
Confirmation from engine to the application that the handler has been installed
properly or not.<br />
&lt;priority&gt; - priority of the installed handler<br />
&lt;name&gt; - name of the messages asked to handle<br />
&lt;success&gt; - boolean (&quot;true&quot; or &quot;false&quot;) success of operation<br />
</p>
<p><b>Keyword: %%&gt;uninstall</b><br />
%%&gt;install:&lt;name&gt;<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 />
&lt;name&gt; - name of the message handler thst should be uninstalled<br />
</p>
<p><b>Keyword: %%&lt;uninstall</b><br />
%%&lt;install:&lt;priority&gt;:&lt;name&gt;:&lt;success&gt;<br />
<b>Direction: Engine to application</b><br />
Confirmation from engine to the application that the handler has been uninstalled
properly or not.<br />
&lt;priority&gt; - priority of the previously installed handler<br />
&lt;name&gt; - name of the message handler asked to uninstall<br />
&lt;success&gt; - boolean (&quot;true&quot; or &quot;false&quot;) success of operation<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: %%&gt;install:50:test
Engine installs the handler and acknowledges it
E: %%&lt;install:50:test:true
Application installs a handler for the "engine.timer" handler with default priority
A: %%&gt;install::engine.timer
Engine installs the handler and acknowledges it
E: %%&lt;install:100:engine.timer:true
Application emits a private "app.job" message; notice how the '%' and ':' characters were escaped
A: %%&gt;message:myapp55251:1095112794:app.job::job=cleanup:done=75%%:path=/bin%Z/usr/bin
Engine just dispatched an "engine.timer" message
E: %%&gt;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: %%&lt;message:myapp55251:true:app.job:Restart required:path=/bin%Z/usr/bin%Z/usr/local/bin
Application ignores the timer message
A: %%&lt;message:234479208:false:engine.timer::time=1095112795
Application uninstalls the "test" handler
A: %%&gt;uninstall:test
Engine removes the handler and acknowledges it
E: %%&lt;uninstall:50:test:true
Engine just dispatched another "engine.timer" message
E: %%&gt;message:234479288:1095112796:engine.timer::time=1095112796
Application modifies the timer message but lets it flow further
A: %%&lt;message:234479288:false:engine.timer::time=1095112796:extra=yes
Engine just dispatched another "engine.timer" message
E: %%&gt;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>