<html>
<head>
<base href="https://wiki.asterisk.org/wiki">
<link rel="stylesheet" href="/wiki/s/en/2160/1/7/_/styles/combined.css?spaceKey=AST&forWysiwyg=true" type="text/css">
</head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
<h2><a href="https://wiki.asterisk.org/wiki/display/AST/Advanced+Topics">Advanced Topics</a></h2>
<h4>Page <b>edited</b> by <a href="https://wiki.asterisk.org/wiki/display/~mnicholson">Matthew Nicholson</a>
</h4>
<br/>
<h4>Changes (1)</h4>
<div id="page-diffs">
<table class="diff" cellpadding="0" cellspacing="0">
<tr><td class="diff-snipped" >...<br></td></tr>
<tr><td class="diff-unchanged" > <br>The same lua state is used for the lifetime of the Asterisk channel it is running on, so effectively, the script has the lifetime of the channel. This means you can set global variables in the lua state and retrieve them later from a different extension if necessary. <br></td></tr>
<tr><td class="diff-added-lines" style="background-color: #dfd;"> <br>h2. Apps, Functions, and Variables <br> <br>_Details on accessing dialplan applications and functions and channel variables can be found in the [Interacting with Asterisk (apps, variables, and functions)] page._ <br> <br> When accessing a dialplan application or function or a channel variable, a placeholder object is generated that provides the {{:get()}} and {{:set()}} methods. <br> <br>{code:title=channel variable: var is the placeholder object} <br>var = channel.my_variable <br>var:set("my value") <br>value = var:get("my value") <br>{code} <br> <br>{code:title=dialplan function: fax_modems is the placeholder object} <br>fax_modems = channel.FAXOPT("module") <br> <br>-- the function arguments are stored in the placeholder <br> <br>fax_modems:set("v17") <br>value = fax_modems:get() <br>{code} <br> <br>{code:title=dialplan application: dial is the placeholder object} <br>dial = app.dial <br> <br>-- the only thing we can do with it is execute it <br>dial("SIP/100") <br>{code} <br> <br>There is a small cost in creating the placeholder objects so storing frequently used placeholder objects can be used as a micro optimization. This should never be necessary though and only provides benefits if you are running micro benchmarks. <br></td></tr>
</table>
</div> <h4>Full Content</h4>
<div class="notificationGreySide">
<p>Behind the scenes, a number of things happen to make the integration of lua into Asterisk as seamless as possible. Some details of how this integration works can be found below.</p>
<h2><a name="AdvancedTopics-%7B%7Bextensions.lua%7D%7DLoadProcess"></a><tt>extensions.lua</tt> Load Process</h2>
<p>The <tt>extensions.lua</tt> file is loaded into memory once when the pbx_lua module is loaded or reloaded. The file is then read from memory and executed once for each channel that looks up or executes a lua based extension. Since the file is executed once for each channel, it may not be wise to do things like connect to external services directly from the main script or build your extensions table from a webservice or database.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>This is probably a bad idea.</b></div><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false">-- my fancy extensions.lua
extensions = {}
extensions.default = {}
-- might be a bad idea, this will run each time a channel is created
data = query_webservice_for_extensions_list("site1")
for _, e in ipairs(data) do
extensions.default[e.exten] = function()
app.dial("SIP/" .. e.sip_peer, e.dial_timeout)
end
end</pre>
</div></div>
<h2><a name="AdvancedTopics-The%7B%7Bextensions%7D%7DTable"></a>The <tt>extensions</tt> Table</h2>
<p>The <tt>extensions</tt> table is a standard lua table and can be defined however you like. The pbx_lua module loads and sorts the table when it is needed.</p>
<h2><a name="AdvancedTopics-Wheredidtheprioritiesgo%3F"></a>Where did the priorities go?</h2>
<p>There are no priorities. Asterisk uses priorities to define the order in which dialplan operations occur. The pbx_lua module uses functions to define extensions and execution occurs within the lua interpreter, priorities don't make sense in this context. To Asterisk, each pbx_lua extension appears as an extension with one priority. Lua extensions can be referenced using the context name, extension, and priority 1, e.g. <tt>Goto(default,1234,1)</tt>. You would only reference extensions this way from outside of pbx_lua (i.e. from <tt>extensions.conf</tt> or <tt>extensions.ael</tt>). From with in pbx_lua you can just execute that extension's function. <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false">extensions.default["1234"]("default", "1234")</pre>
</div></div></p>
<h2><a name="AdvancedTopics-LuaScriptLifetime"></a>Lua Script Lifetime</h2>
<p>The same lua state is used for the lifetime of the Asterisk channel it is running on, so effectively, the script has the lifetime of the channel. This means you can set global variables in the lua state and retrieve them later from a different extension if necessary.</p>
<h2><a name="AdvancedTopics-Apps%2CFunctions%2CandVariables"></a>Apps, Functions, and Variables</h2>
<p><em>Details on accessing dialplan applications and functions and channel variables can be found in the <a href="/wiki/display/AST/Interacting+with+Asterisk+%28apps%2C+variables%2C+and+functions%29" title="Interacting with Asterisk (apps, variables, and functions)">Interacting with Asterisk (apps, variables, and functions)</a> page.</em></p>
<p> When accessing a dialplan application or function or a channel variable, a placeholder object is generated that provides the <tt>:get()</tt> and <tt>:set()</tt> methods.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>channel variable: var is the placeholder object</b></div><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false">var = channel.my_variable
var:set("my value")
value = var:get("my value")</pre>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>dialplan function: fax_modems is the placeholder object</b></div><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false">fax_modems = channel.FAXOPT("module")
-- the function arguments are stored in the placeholder
fax_modems:set("v17")
value = fax_modems:get()</pre>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>dialplan application: dial is the placeholder object</b></div><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false">dial = app.dial
-- the only thing we can do with it is execute it
dial("SIP/100")</pre>
</div></div>
<p>There is a small cost in creating the placeholder objects so storing frequently used placeholder objects can be used as a micro optimization. This should never be necessary though and only provides benefits if you are running micro benchmarks.</p>
</div>
<div id="commentsSection" class="wiki-content pageSection">
<div style="float: right;" class="grey">
<a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=AST">Stop watching space</a>
<span style="padding: 0px 5px;">|</span>
<a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action">Change email notification preferences</a>
</div>
<a href="https://wiki.asterisk.org/wiki/display/AST/Advanced+Topics">View Online</a>
|
<a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=16548044&revisedVersion=3&originalVersion=2">View Changes</a>
|
<a href="https://wiki.asterisk.org/wiki/display/AST/Advanced+Topics?showComments=true&showCommentArea=true#addcomment">Add Comment</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>