<html>
<head>
<base href="https://wiki.asterisk.org/wiki">
<link rel="stylesheet" href="/wiki/s/en/2176/25/9/_/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/Asterisk+12+API+Improvements">Asterisk 12 API Improvements</a></h2>
<h4>Page <b>added</b> by <a href="https://wiki.asterisk.org/wiki/display/~dlee">David M. Lee</a>
</h4>
<br/>
<div class="notificationGreySide">
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>This page is under development; expect missing and incomplete information. Still, feel free to discuss on <a href="http://lists.digium.com/mailman/listinfo/asterisk-dev" class="external-link" rel="nofollow">asterisk-dev</a>.</td></tr></table></div>
<div>
<ul>
<li><a href='#Asterisk12APIImprovements-ProjectOverview'>Project Overview</a></li>
<li><a href='#Asterisk12APIImprovements-RequirementsandSpecification'>Requirements and Specification</a></li>
<ul>
<li><a href='#Asterisk12APIImprovements-StasisRequirements'>Stasis Requirements</a></li>
<li><a href='#Asterisk12APIImprovements-InternalImprovements'>Internal Improvements</a></li>
<li><a href='#Asterisk12APIImprovements-UseCases'>Use Cases</a></li>
<ul>
<li><a href='#Asterisk12APIImprovements-SummaryLevel'>Summary Level</a></li>
<li><a href='#Asterisk12APIImprovements-UserLevel'>User Level</a></li>
<li><a href='#Asterisk12APIImprovements-SubfunctionLevel'>Sub-function Level</a></li>
</ul>
<li><a href='#Asterisk12APIImprovements-Guidelines'>Guidelines</a></li>
<ul>
<li><a href='#Asterisk12APIImprovements-PBXvs.Toolkit'>PBX vs. Toolkit</a></li>
<li><a href='#Asterisk12APIImprovements-ConventionoverConfiguration'>Convention over Configuration</a></li>
</ul>
<li><a href='#Asterisk12APIImprovements-Configuration'>Configuration</a></li>
<ul>
<li><a href='#Asterisk12APIImprovements-project.conf'>project.conf</a></li>
<li><a href='#Asterisk12APIImprovements-RealTimeschemas'>RealTime schemas</a></li>
</ul>
<li><a href='#Asterisk12APIImprovements-APIs'>APIs</a></li>
</ul>
<li><a href='#Asterisk12APIImprovements-Design'>Design</a></li>
<li><a href='#Asterisk12APIImprovements-TestPlan'>Test Plan</a></li>
<ul>
<li><a href='#Asterisk12APIImprovements-TestsforUseCase%3ABobcallsAlice'>Tests for Use Case: Bob calls Alice</a></li>
</ul>
<li><a href='#Asterisk12APIImprovements-ProjectPlanning'>Project Planning</a></li>
<ul>
<li><a href='#Asterisk12APIImprovements-JIRAIssues'>JIRA Issues</a></li>
<li><a href='#Asterisk12APIImprovements-Contributors'>Contributors</a></li>
</ul>
<li><a href='#Asterisk12APIImprovements-ReferenceInformation'>Reference Information</a></li>
<li><a href='#Asterisk12APIImprovements-Footnotes'>Footnotes</a></li>
</ul></div>
<h1><a name="Asterisk12APIImprovements-ProjectOverview"></a>Project Overview</h1>
<p>While Asterisk has a number of interfaces one could use for building telephony applications, they suffer from several significant problems.</p>
<ul>
        <li>Channels identifiers are not stable. Some operations (like <a href="/wiki/display/AST/Asterisk+11+ManagerEvent_Masquerade" title="Asterisk 11 ManagerEvent_Masquerade">masquerades</a>) will change the id out from under you.</li>
        <li>The protocols (AMI and AGI) are non-standard and poorly documented, making them difficult to work with.</li>
        <li>AMI's message format is restricted to simple name/value pairs. Commands that need to pass back lists or structured data are very hackish.</li>
        <li>AMI event filtering is very course grained, and established in configuration instead of at runtime. This has lead to some creative solutions to dealing with the flood of events (most of which are not of interest).</li>
        <li>AGI is a synchronous interface, which really hinders making truly interactive applications.
        <ul>
                <li>While AsyncAGI attempts to address this issue, it is an asynchronous wrapper around a synchronous implementation. Commands queue up after one another, and are not interruptible, leading to many of the same problems with AGI or FastAGI.</li>
        </ul>
        </li>
        <li>Internally, AMI events are formatted into strings at the time they are created. This makes it very difficult to do anything with the events, except send them out AMI connections. This also makes using different protocol formats difficult.</li>
        <li>Different interfaces tend to implement the same logical command in different ways.</li>
</ul>
<p>We're going to start with fixing one of the most glaring problems with the current APIs: <a href="https://issues.asterisk.org/jira/browse/ASTERISK-20725" class="external-link" rel="nofollow">add a stable identifier to channels</a>, and use that identifier consistently throughout AMI. This solves a big problem for current AMI+AGI based applications.</p>
<p>Unfortunately, solving some of the larger problems would be very intrusive with the current API's, and introduce a host of breaking changes. Some are so fundamental, we would essentially be rewriting the interface. That's not acceptable; the current API's aren't going anywhere anytime soon.</p>
<p>This leads us down the path of adding a new interface to Asterisk. We've got some time to put some though into this, so let's do it right. Since things are easier to talk about when they have a name, the new API work has the working title <a href="#Asterisk12APIImprovements-badname">Stasis</a>.</p>
<p>We want the API to be familiar and approachable to developers. We don't want to force them to use C. In fact, we don't want to force them to use any particular programming language; the API should be accessible from the language and platform of their choice.</p>
<p>The API should be relatively high level, and not get stuck down in the details of what's happening inside of Asterisk. Asterisk may go through all sorts of shenanigans to do what it needs to do, but the API should provide a nice, clean abstraction.</p>
<p>In building out the new API, we don't want to repeat past mistakes by re-implement the same functionality several times in slightly different ways. There should be a single core implementation, that all of the API's use. This would improve consistency between the API's and reduce code duplication.</p>
<p>To accomplish this, Stasis will be a set of new modules for providing control and management interfaces into Asterisk. While Stasis will initially be focused on third party call control and monitoring, it should be extensible enough to provide configuration and provisioning API's in the future.</p>
<p>Internally to Asterisk, <tt>stasis-core</tt> will provide a message bus for interfacing with Asterisk objects. The <tt>stasis-http</tt> component will be built upon this message bus to expose a RESTful API, also utilizing WebSockets for asynchronous communication to the external applications.</p>
<p>The split between <tt>stasis-core</tt> and <tt>stasis-http</tt> should allow for other protocol bindings to be added in the future. This could even go so far as replacing the existing API's with Stasis implementations.</p>
<p>The selection of HTTP as the first binding for Stasis allows for very broad appeal, ease of use, and simplicity for writing client libraries to make it easier to write applications to the API.</p>
<h1><a name="Asterisk12APIImprovements-RequirementsandSpecification"></a>Requirements and Specification</h1>
<h2><a name="Asterisk12APIImprovements-StasisRequirements"></a>Stasis Requirements</h2>
<ul>
        <li><b>Asynchronous Everything</b> - Most applications need to be able to interrupt activities, and receive events as they happen. Blocking operations are the devil.</li>
        <li><b>Version Stability</b> - This is important. Like, really important. The current mechanisms may change dramatically between releases, which causes developers/integrators/etc. to keep running on older versions of Asterisk than anyone would like.</li>
        <li><b>Interoperability</b> - Stasis must work in a variety of environments, detailed below.
        <ul>
                <li><b>Programming Language</b> - Stasis applications should be able to be easily written in a variety of languages.</li>
        </ul>
        </li>
        <li><b>Security</b> - Reasonable security measures should be taken.
        <ul>
                <li>Encryption: Not needed immediately, and way down on the priority list. Even if connections are plain text, reasonable precautions should be taken with sensitive information (i.e. use challenge handshakes for authentication instead of passing plaintext passwords over the wire).</li>
                <li>Authentication: Client only authentication is sufficient. Should not be any more complicated than passwords/pre-shared secrets.</li>
                <li>Authorization: No immediate need for multiple levels or granular permissions inside the api.</li>
        </ul>
        </li>
</ul>
<h2><a name="Asterisk12APIImprovements-InternalImprovements"></a>Internal Improvements</h2>
<ul>
        <li><b>Stable channel identifier</b> - this is necessary for a reasonable Stasis API. Since so much of the world still depends on AMI, it should be updated to allow the stable id to be used in place of the current channel id</li>
        <li><b>AMI Event Structure</b> - AMI events should be generated into a key/value object pair instead of the <tt>printf</tt>-style string formatting currently used. This would allow Stasis to reuse the existing events.</li>
        <li><b>Improved implementation consistency</b> - While not something we would address in the initial Stasis work, existing disparate implementations could be reworked to use a single, consistent <tt>stasis-core</tt> implementation.</li>
</ul>
<h2><a name="Asterisk12APIImprovements-UseCases"></a>Use Cases</h2>
<h3><a name="Asterisk12APIImprovements-SummaryLevel"></a>Summary Level</h3>
<p>Highest level use cases; more or less applications that could be build on top of Stasis.</p>
<ul>
        <li><b>Standard two party call</b> - Very standard use case for Asterisk.</li>
        <li><b>Conference</b> - Multi-participant calls, in which media from one endpoint may be sent to two or more endpoints.
        <ul>
                <li>Some participants may control the conference via DTMF key presses</li>
                <li>Some participants may be muted</li>
        </ul>
        </li>
        <li><b>IVR</b> - Interactive Voice Response.
        <ul>
                <li>Plays media to caller</li>
                <li>Detects DTMF key presses from caller</li>
                <li>Record media from caller</li>
        </ul>
        </li>
        <li><b>Queue</b> - Call dispatch queue.
        <ul>
                <li>Get presence information from queue agents</li>
                <li>Originate calls to agents as needed</li>
                <li>When agent answers, bridge to most appropriate call from queue</li>
                <li>May add supervisor to agent/caller conversation</li>
        </ul>
        </li>
        <li><b>Voicemail</b>
        <ul>
                <li>Record audio from caller</li>
                <li>Playback recorded audio</li>
                <li>Detect DTMF for media control (fast forward, skip, delete)</li>
        </ul>
        </li>
</ul>
<h3><a name="Asterisk12APIImprovements-UserLevel"></a>User Level</h3>
<ul>
        <li><b>Originate</b> - An application may originate a new channel.</li>
        <li><b>DTMF Detection</b> - DTMF, and other channel events.</li>
        <li><b>Bridge</b> - Two or more channels may be bridged together, so that media from any channel may be mixed and sent to the others</li>
        <li><b>Play</b> - An application may specify media to be played on a channel.</li>
        <li><b>Presence</b> - An application may query the presence state of endpoints, and subscribe to presence updates.</li>
        <li><b>Record</b> - An application may record the media from a channel/bridge.</li>
</ul>
<h3><a name="Asterisk12APIImprovements-SubfunctionLevel"></a>Sub-function Level</h3>
<ul>
        <li><b>Media Control</b> - During the playback of media, the application may issue fine-grained media control commands. (fast forward, pause, stop, etc.)</li>
        <li><b>Mute participant</b> - Within a bridge, an application may (un)mute individual channels, controlling which media streams are mixed and sent to other participants.</li>
</ul>
<h2><a name="Asterisk12APIImprovements-Guidelines"></a>Guidelines</h2>
<h3><a name="Asterisk12APIImprovements-PBXvs.Toolkit"></a>PBX vs. Toolkit</h3>
<p>From the README in trunk: "Asterisk is an Open Source PBX and telephony toolkit." However, whether or not we are PBX-centric has implications for the API.</p>
<p>Currently, Asterisk leans more toward being a toolkit than a PBX. There is a very loose coupling between extensions and endpoints, as is typically defined by dialplan code in the extensions.conf file. There is no concept of 'inside' versus 'outside', unless you put it in the dialplan yourself. There is no standard definition of a 'call', or a 'user'. All of these vary depending upon your application, and being able to be applied to a variety of applications is what has made Asterisk so successful.</p>
<p>However, the primary application Asterisk is applied to is being a PBX. It is important that developers writing PBX applications aren't bogged down with general telephony toolkit details.</p>
<p>So while the PBX use cases are important, they should not undermine the general purpose toolkit use cases. Largely, this will influence default values and conventions of the API.</p>
<h3><a name="Asterisk12APIImprovements-ConventionoverConfiguration"></a>Convention over Configuration</h3>
<p>Continuing on with the theme of PBX vs. Toolkit, the API should adopt an approach of convention over configuration: reasonable defaults should be used wherever possible. Configuration should be possible, allowing users to specify their own values in place of these defaults.</p>
<h2><a name="Asterisk12APIImprovements-Configuration"></a>Configuration</h2>
<h3><a name="Asterisk12APIImprovements-project.conf"></a>project.conf</h3>
<h4><a name="Asterisk12APIImprovements-%5Cgeneral%5C"></a>[general]</h4>
<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Parameter </th>
<th class='confluenceTh'> Description </th>
<th class='confluenceTh'> Type </th>
<th class='confluenceTh'> Default Value </th>
</tr>
<tr>
<td class='confluenceTd'> foo </td>
<td class='confluenceTd'> Turns feature foo on or off </td>
<td class='confluenceTd'> Boolean </td>
<td class='confluenceTd'> True </td>
</tr>
<tr>
<td class='confluenceTd'> bar </td>
<td class='confluenceTd'> A comma delineated list of bar items (pun intended?) </td>
<td class='confluenceTd'> String </td>
<td class='confluenceTd'> </td>
</tr>
</tbody></table>
</div>
<h3><a name="Asterisk12APIImprovements-RealTimeschemas"></a>RealTime schemas</h3>
<h2><a name="Asterisk12APIImprovements-APIs"></a>APIs</h2>
<p>Add an entry for each Application, Function, AMI command, AMI event, AGI command, CLI command, or other external way of interacting with the features provided by the project. Different APIs require different sets of documentation; in general, sufficient documentation should be provided to create the standard XML documentation for that particular item.</p>
<h1><a name="Asterisk12APIImprovements-Design"></a>Design</h1>
<p>For sufficiently complex projects, a high level design may be needed to illustrate how the project plugs into the overall Asterisk architecture. Sufficiently detailed design of the project should be provided such that newcomers to the Asterisk project are provided a conceptual view of the construction of the implementation.</p>
<p>Note that the design should be independent of the implementation, i.e., if the code is not drastically changed, it should not require updates to this section.</p>
<h1><a name="Asterisk12APIImprovements-TestPlan"></a>Test Plan</h1>
<p>Project should include automated testing, using either the Asterisk Unit Test Framework or the Asterisk Test Suite. Automated testing not only helps collaborators and reviewers verify functionality, but also helps to future proof new functionality against breaking changes in the future. A test plan maps Use Cases, User Stories, or specific APIs to tests that exercise that functionality. Test plans should be broken up by specific pieces of functionality, and should enumerate the tests for each function.</p>
<p>Each test description should provide, at a minimum, the name of the test, the test level (Unit, Integration, or System), and a description of what the test covers. For System level tests (which implies manual testing), a detailed description should be provided such that the test is reproducible by any third party.</p>
<h2><a name="Asterisk12APIImprovements-TestsforUseCase%3ABobcallsAlice"></a>Tests for Use Case: Bob calls Alice</h2>
<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Test </th>
<th class='confluenceTh'> Level </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> sip_basic_call </td>
<td class='confluenceTd'> Integration </td>
<td class='confluenceTd'> Test a basic call scenario between two SIP UAs and Asterisk </td>
</tr>
<tr>
<td class='confluenceTd'> sip_uri_parse_nominal </td>
<td class='confluenceTd'> Unit </td>
<td class='confluenceTd'> Nominal parsing of SIP URIs </td>
</tr>
<tr>
<td class='confluenceTd'> sip_uri_parse_off_nominal </td>
<td class='confluenceTd'> Unit </td>
<td class='confluenceTd'> Tests that ensure that off nominal SIP URIs are handled properly </td>
</tr>
<tr>
<td class='confluenceTd'> sip_invite_request_test_nominal </td>
<td class='confluenceTd'> Unit </td>
<td class='confluenceTd'> Test INVITE request handling </td>
</tr>
</tbody></table>
</div>
<h1><a name="Asterisk12APIImprovements-ProjectPlanning"></a>Project Planning</h1>
<p>Provide links to the appropriate JIRA issues tracking work related to the project using the {jiraissues} macro (for more information on its usage, see <a href="https://confluence.atlassian.com/display/DOC/JIRA+Issues+Macro" class="external-link" rel="nofollow">JIRA Issues Macro</a>). The sample below uses a public Triage filter - you will need to set up a JIRA issue filter for the macro to pull issues from that is shared with the <b>Public</b> group.</p>
<h2><a name="Asterisk12APIImprovements-JIRAIssues"></a>JIRA Issues</h2>
<p>
<div>
<p>Errors were reported by the JIRA trusted connection.</p>
<ul>
<li>PERMISSION_DENIED;        Permission Denied;        []</li>
</ul>
</div>
<table cellspacing="0" class="grid" style="width: 100%">
<tr>
<th colspan="11" style="text-align: left; ">
<a rel="nofollow" href="https://issues.asterisk.org/jira/secure/IssueNavigator.jspa?requestId=11821&tempMax=1000">JIRA Issues</a> (0 issues) </th>
</tr>
<tr>
<th style="text-align: left; text-transform: capitalize;">Type</th>
<th style="text-align: left; text-transform: capitalize;">Key</th>
<th style="text-align: left; text-transform: capitalize;">Summary</th>
<th style="text-align: left; text-transform: capitalize;">Assignee</th>
<th style="text-align: left; text-transform: capitalize;">Reporter</th>
<th style="text-align: left; text-transform: capitalize;">Priority</th>
<th style="text-align: left; text-transform: capitalize;">Status</th>
<th style="text-align: left; text-transform: capitalize;">Resolution</th>
<th style="text-align: left; text-transform: capitalize;">Created</th>
<th style="text-align: left; text-transform: capitalize;">Updated</th>
<th style="text-align: left; text-transform: capitalize;">Due</th>
</tr>
</table>
</p>
<h2><a name="Asterisk12APIImprovements-Contributors"></a>Contributors</h2>
<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Name </th>
<th class='confluenceTh'> E-mail Address </th>
</tr>
<tr>
<td class='confluenceTd'> <a href="/wiki/display/~mjordan" class="confluence-userlink" data-username="mjordan" >Matt Jordan</a> </td>
<td class='confluenceTd'> mjordan@digium.com </td>
</tr>
</tbody></table>
</div>
<h1><a name="Asterisk12APIImprovements-ReferenceInformation"></a>Reference Information</h1>
<p>Include links to code reviews, asterisk-dev mailing list discussions, and any other related information.</p>
<h1><a name="Asterisk12APIImprovements-Footnotes"></a>Footnotes</h1>
<ul>
        <li><a name="Asterisk12APIImprovements-badname"></a> While it may stand for "Some Thought Actually Spent In Specification", suggestions for a better name are welcome.</li>
</ul>
</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/Asterisk+12+API+Improvements">View Online</a>
|
<a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+12+API+Improvements?showComments=true&showCommentArea=true#addcomment">Add Comment</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>