<html>
<head>
    <base href="https://wiki.asterisk.org/wiki">
            <link rel="stylesheet" href="/wiki/s/2030/1/7/_/styles/combined.css?spaceKey=AST&amp;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/Distributed+Device+State+with+AIS">Distributed Device State with AIS</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://wiki.asterisk.org/wiki/display/~russell">Russell Bryant</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" >For more information about OpenAIS, visit their web site [http://www.openais.org/]. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h5. Install Dependencies <br> <br>* Ubuntu <br>** libnss3-dev <br>* Fedora <br>** nss-devel <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h5. Download <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        

<div>
<ul>
    <li><a href='#DistributedDeviceStatewithAIS-Introduction'>1. Introduction</a></li>
    <li><a href='#DistributedDeviceStatewithAIS-OpenAISInstallation'>2. OpenAIS Installation</a></li>
<ul>
    <li><a href='#DistributedDeviceStatewithAIS-Description'>Description</a></li>
    <li><a href='#DistributedDeviceStatewithAIS-InstallDependencies'>Install Dependencies</a></li>
    <li><a href='#DistributedDeviceStatewithAIS-Download'>Download</a></li>
    <li><a href='#DistributedDeviceStatewithAIS-CompileandInstall'>Compile and Install</a></li>
</ul>
    <li><a href='#DistributedDeviceStatewithAIS-OpenAISConfiguration'>3. OpenAIS Configuration</a></li>
    <li><a href='#DistributedDeviceStatewithAIS-RunningOpenAIS'>4. Running OpenAIS</a></li>
    <li><a href='#DistributedDeviceStatewithAIS-InstallingAsterisk'>5. Installing Asterisk</a></li>
    <li><a href='#DistributedDeviceStatewithAIS-ConfiguringAsterisk'>6. Configuring Asterisk</a></li>
    <li><a href='#DistributedDeviceStatewithAIS-BasicTestingofAsteriskwithOpenAIS'>7. Basic Testing of Asterisk with OpenAIS</a></li>
    <li><a href='#DistributedDeviceStatewithAIS-TestingDistributedDeviceState'>8. Testing Distributed Device State</a></li>
</ul></div>

<h1><a name="DistributedDeviceStatewithAIS-Introduction"></a>1. Introduction</h1>

<p>Various changes have been made related to "event handling" in Asterisk.  One of the most important things included in these changes is the ability to share certain events between servers.  The two types of events that can currently be shared between servers are:</p>

<ol>
        <li>MWI - Message Waiting Indication - This gives you a high performance option for letting servers in a cluster be aware of changes in the state of a mailbox.  Instead of having each server have to poll an ODBC database, this lets the server that actually made the change to the mailbox generate an event which will get distributed to the other servers that have subscribed to this information.</li>
        <li>Device State - This lets servers in a local cluster inform each other about changes in the state of a device on that particular server.  When the state of a device changes on any server, the overall state of that device across the cluster will get recalculated.  So, any subscriptions to the state of a device, such as hints in the dialplan or an application like Queue() which reads device state, will then reflect the state of a device across a cluster.</li>
</ol>


<h1><a name="DistributedDeviceStatewithAIS-OpenAISInstallation"></a>2. OpenAIS Installation</h1>

<h5><a name="DistributedDeviceStatewithAIS-Description"></a>Description</h5>

<p>The current solution for providing distributed events with Asterisk is done by using the AIS (Application Interface Specification), which provides an API for a distributed event service.  While this API is standardized, this code has been developed exclusively against the open source implementation of AIS called OpenAIS.</p>

<p>For more information about OpenAIS, visit their web site <a href="http://www.openais.org/" class="external-link" rel="nofollow">http://www.openais.org/</a>.</p>

<h5><a name="DistributedDeviceStatewithAIS-InstallDependencies"></a>Install Dependencies</h5>

<ul>
        <li>Ubuntu
        <ul>
                <li>libnss3-dev</li>
        </ul>
        </li>
        <li>Fedora
        <ul>
                <li>nss-devel</li>
        </ul>
        </li>
</ul>


<h5><a name="DistributedDeviceStatewithAIS-Download"></a>Download</h5>

<p>Download the latest versions of Corosync and OpenAIS from <a href="http://www.corosync.org/" class="external-link" rel="nofollow">http://www.corosync.org/</a> and <a href="http://www.openais.org/" class="external-link" rel="nofollow">http://www.openais.org/</a>.</p>

<h5><a name="DistributedDeviceStatewithAIS-CompileandInstall"></a>Compile and Install</h5>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ tar xvzf corosync-1.2.8.tar.gz
$ cd corosync-1.2.8
$ ./configure
$ make
$ sudo make install
</pre>
</div></div>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ tar xvzf openais-1.1.4.tar.gz
$ cd openais-1.1.4
$ ./configure
$ make
$ sudo make install
</pre>
</div></div>

<h1><a name="DistributedDeviceStatewithAIS-OpenAISConfiguration"></a>3. OpenAIS Configuration</h1>

<p>Basic OpenAIS configuration to get this working is actually pretty easy.  Start by copying in a sample configuration file for Corosync and OpenAIS.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ sudo mkdir -p /etc/ais
$ cd openais-1.1.4
$ sudo cp conf/openais.conf.sample /etc/ais/openais.conf
</pre>
</div></div>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ sudo mkdir -p /etc/corosync
$ cd corosync-1.2.8
$ sudo cp conf/corosync.conf.sample /etc/corosync/corosync.conf
</pre>
</div></div>

<p>Now, edit openais.conf using the editor of your choice.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ ${EDITOR:-vim} /etc/ais/openais.conf
</pre>
</div></div>

<p>The only section that you should need to change is the totem - interface section.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>totem {
    ...
    interface {
    interface {
        ringnumber: 0
        bindnetaddr: 10.19.0.0
        mcastaddr: 226.94.1.1
        mcastport: 5405
    }
}
</pre>
</div></div>

<p>The default mcastaddr and mcastport is probably fine.  You need to change the bindnetaddr to match the network address that the nodes of your cluster will communicate on.</p>

<p>Now, edit /etc/corosync/corosync.conf, as well.  The same change will need to be made to the totem-interface section in that file, as well.</p>

<h1><a name="DistributedDeviceStatewithAIS-RunningOpenAIS"></a>4. Running OpenAIS</h1>

<p>While testing, I recommend starting the aisexec application in the foreground so that you can see debug messages that verify that the nodes have discovered each other and joined the cluster.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ sudo aisexec -f
</pre>
</div></div>

<h1><a name="DistributedDeviceStatewithAIS-InstallingAsterisk"></a>5. Installing Asterisk</h1>

<p>Install Asterisk as usual.  Just make sure that you run the configure script after OpenAIS gets installed.  That way, it will find the AIS header files and will let you build the res_ais module.  Check menuselect to make sure that res_ais is going to get compiled and installed.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ cd asterisk-source
$ ./configure

$ make menuselect
  ---&gt; Resource Modules
</pre>
</div></div>

<p>If you have existing configuration on the system being used for testing, just be sure to install the addition configuration file needed for res_ais.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ sudo cp configs/ais.conf.sample /etc/asterisk/ais.conf
</pre>
</div></div>

<h1><a name="DistributedDeviceStatewithAIS-ConfiguringAsterisk"></a>6. Configuring Asterisk</h1>

<p>First, ensure that you have a unique "entity ID" set for each server.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>*CLI&gt; core show settings
   ...
   Entity ID:                   01:23:45:67:89:ab
</pre>
</div></div>

<p>The code will attempt to generate a unique entity ID for you by reading MAC addresses off of a network interface.  However, you can also set it manually in the [options] section of asterisk.conf.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ sudo ${EDITOR:-vim} /etc/asterisk/asterisk.conf

[options]
...
entity_id=01:23:45:67:89:ab
</pre>
</div></div>


<p>Edit the Asterisk ais.conf to enable distributed events.  For example, if you would like to enable distributed device state, you should add the following section to the file:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ sudo ${EDITOR:-vim} /etc/asterisk/ais.conf

[device_state]
type=event_channel
publish_event=device_state
subscribe_event=device_state
</pre>
</div></div>

<p>For more information on the contents and available options in this configuration file, please see the sample configuration file:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>$ cd asterisk-source
$ less configs/ais.conf.sample
</pre>
</div></div>

<h1><a name="DistributedDeviceStatewithAIS-BasicTestingofAsteriskwithOpenAIS"></a>7. Basic Testing of Asterisk with OpenAIS</h1>

<p>If you have OpenAIS successfully installed and running, as well as Asterisk with OpenAIS support successfully installed, configured, and running, then you are ready to test out some of the AIS functionality in Asterisk.</p>

<p>The first thing to test is to verify that all of the nodes that you think should be in your cluster are actually there.  There is an Asterisk CLI command which will list the current cluster members using the AIS Cluster Membership Service<br/>
(CLM).</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>*CLI&gt; ais clm show members

=== Cluster Members =========================================
=============================================================
===
=== ---------------------------------------------------------
=== Node Name: 10.19.2.255
=== ==&gt; ID: 0xa1302ff
=== ==&gt; Address: 10.19.2.255
=== ==&gt; Member: Yes
=== ---------------------------------------------------------
===
=== ---------------------------------------------------------
=== Node Name: 10.19.6.187
=== ==&gt; ID: 0xa1306bb
=== ==&gt; Address: 10.19.6.187
=== ==&gt; Member: Yes
=== ---------------------------------------------------------
===
=============================================================
</pre>
</div></div>

<p>The next thing to do is to verify that you have successfully configured some event channels in the Asterisk ais.conf file.  This command is related to the event service (EVT), so like the previous command, uses the syntax: <tt>ais &lt;service name&gt; &lt;command&gt;</tt>.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>*CLI&gt; ais evt show event channels 

=============================================================
=== Event Channels ==========================================
=============================================================
===
=== ---------------------------------------------------------
=== Event Channel Name: mwi
=== ==&gt; Publishing Event Type: mwi
=== ==&gt; Subscribing to Event Type: mwi
=== ---------------------------------------------------------
===
=== ---------------------------------------------------------
=== Event Channel Name: device_state
=== ==&gt; Publishing Event Type: device_state
=== ==&gt; Subscribing to Event Type: device_state
=== ---------------------------------------------------------
===
=============================================================
</pre>
</div></div>


<h1><a name="DistributedDeviceStatewithAIS-TestingDistributedDeviceState"></a>8. Testing Distributed Device State</h1>

<p>The easiest way to test distributed device state is to use the DEVICE_STATE() diaplan function.  For example, you could have the following piece of dialplan on every server:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>[devstate_test]

exten =&gt; 1234,hint,Custom:mystate

exten =&gt; set_inuse,1,Set(DEVICE_STATE(Custom:mystate)=INUSE)
exten =&gt; set_not_inuse,1,Set(DEVICE_STATE(Custom:mystate)=NOT_INUSE)

exten =&gt; check,1,NoOp(Custom:mystate is ${DEVICE_STATE(Custom:mystate)})
</pre>
</div></div>

<p>Now, you can test that the cluster-wide state of "Custom:mystate" is what you would expect after going to the CLI of each server and adjusting the state.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>server1*CLI&gt; console dial set_inuse@devstate_test
   ...

server2*CLI&gt; console dial check@devstate_test
    -- Executing [check@devstate_test:1] NoOp("OSS/dsp", "Custom:mystate is INUSE") in new stack
</pre>
</div></div>

<p>Various combinations of setting and checking the state on different servers can be used to verify that it works as expected.  Also, you can see the status of the hint on each server, as well, to see how extension state would reflect the<br/>
state change with distributed device state:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>server2*CLI&gt; core show hints
    -= Registered Asterisk Dial Plan Hints =-
                   1234@devstate_test       : Custom:mystate        State:InUse           Watchers  0
</pre>
</div></div>

<p>One other helpful thing here during testing and debugging is to enable debug logging.  To do so, enable debug on the console in /etc/asterisk/logger.conf.  Also, enable debug at the Asterisk CLI.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>*CLI&gt; core set debug 1
</pre>
</div></div>

<p>When you have this debug enabled, you will see output during the processing of every device state change.  The important thing to look for is where the known state of the device for each server is added together to determine the overall<br/>
state.</p>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://wiki.asterisk.org/wiki/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://wiki.asterisk.org/wiki/display/AST/Distributed+Device+State+with+AIS">View Online</a>
        |
        <a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=4259996&revisedVersion=12&originalVersion=11">View Changes</a>
                |
        <a href="https://wiki.asterisk.org/wiki/display/AST/Distributed+Device+State+with+AIS?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>