{"id":445,"date":"2012-08-31T01:00:00","date_gmt":"2012-08-30T23:00:00","guid":{"rendered":"https:\/\/www.fussylogic.co.uk\/blog\/?p=445"},"modified":"2013-06-26T11:53:55","modified_gmt":"2013-06-26T10:53:55","slug":"asterisk-for-a-small-business-iii","status":"publish","type":"post","link":"https:\/\/www.fussylogic.co.uk\/blog\/?p=445","title":{"rendered":"Asterisk For a Small Business (III)"},"content":{"rendered":"<p>Last time we left ourselves in the position of having two outgoing trunks available and four locally connected phone extensions. Let\u00e2\u20ac\u2122s remind ourselves of these endpoints.<\/p>\n<pre><code>$ asterisk -r\nhostname*cli&gt; sip show peers\nName\/username              Host           Dyn Forcerport ACL Port  Status     \nandyp\/andyp                192.168.1.82    D                       OK (100 ms)\nwife\/wife                  (Unspecified)   D   0                   UNKNOWN    \nhandytone1\/handytone1      192.168.1.10    D                 5060  OK (5 ms)\nhandytone2\/handytone2      192.168.1.10    D                 5062  OK (6 ms)\nvoiptalkOFFICE\/222222222   77.240.48.94        N             5060  Unmonitored\nvoiptalkRESIDENTIAL\/11111  77.240.48.94        N             5060  Unmonitored\n6 sip peers [Monitored: 3 online, 1 offline Unmonitored: 2 online, 0 offline]<\/code><\/pre>\n<p>Let\u00e2\u20ac\u2122s now start thinking about what we want our phone system to do (or rather, what I want mine to do, and hope that you want something similar).<\/p>\n<ul>\n<li><code>andyp<\/code>, <code>wife<\/code>, <code>handytone1<\/code> and <code>handytone2<\/code> should all be able to ring each other internally.<\/li>\n<li><code>andyp<\/code>, <code>wife<\/code>, and <code>handytone1<\/code> shall make outgoing calls on <code>voiptalkRESIDENTIAL<\/code> by default.<\/li>\n<li><code>handytone2<\/code> shall make outgoing calls on <code>voiptalkOFFICE<\/code> by default.<\/li>\n<li>Incoming calls to <code>voiptalkOFFICE<\/code> shall ring <code>andyp<\/code> and <code>handytone2<\/code><\/li>\n<li>Incoming calls to <code>voiptalkRESIDENTIAL<\/code> shall ring <code>andyp<\/code>, <code>wife<\/code>, and <code>handytone1<\/code>.<\/li>\n<\/ul>\n<p>That\u00e2\u20ac\u2122ll do us as a reasonable start. This time we\u00e2\u20ac\u2122ll deal with the first of these requirements.<\/p>\n<p>Recall one of our local SIP endpoint definitions:<\/p>\n<pre><code>[handytone1](user,ht386)\n    secret=handytonesecret1\n    callerid=&quot;Residential&quot; &lt;2102&gt;\n    context=internal-residential\n    mailbox=household@default<\/code><\/pre>\n<p>In particular note the \u00e2\u20ac\u0153<code>context<\/code>\u00e2\u20ac\u009d option. This tells Asterisk which extension context incoming calls from this endpoint should be \u00e2\u20ac\u0153run\u00e2\u20ac\u009d in. What does that mean? To understand that, we need to start looking in <code>\/etc\/asterisk\/extensions.conf<\/code>. This file creates what Asterisk refers to as its \u00e2\u20ac\u0153dialplan\u00e2\u20ac\u009d. Don\u00e2\u20ac\u2122t be confused when you see it referred to like that.<\/p>\n<p>My suggestion is to delete or comment out everything not in the \u00e2\u20ac\u0153<code>[general]<\/code>\u00e2\u20ac\u009d section, and even that is a lot of cruft. It\u00e2\u20ac\u2122s a thorough example configuration, but just causes us difficulties when we\u00e2\u20ac\u2122re making our own setup. In <code>[general]<\/code> I suggest making sure you have the following options set:<\/p>\n<pre><code>[general]\nstatic=yes\nwriteprotect=yes\nclearglobalvariables=no<\/code><\/pre>\n<p>With that out of the way, let\u00e2\u20ac\u2122s begin with defining the \u00e2\u20ac\u0153internal-residential\u00e2\u20ac\u009d context that we\u00e2\u20ac\u2122ve placed <code>andyp<\/code>, <code>wife<\/code> and <code>handytone1<\/code> in. While we\u00e2\u20ac\u2122re at it, we\u00e2\u20ac\u2122ll define \u00e2\u20ac\u0153internal-business\u00e2\u20ac\u009d for <code>handytone2<\/code>.<\/p>\n<pre><code>[internal-residential]\ninclude =&gt; internal-extensions\n[internal-business]    \ninclude =&gt; internal-extensions<\/code><\/pre>\n<p>To make these two contexts we\u00e2\u20ac\u2122ve simply included a third (as yet not defined) context, \u00e2\u20ac\u0153internal-extensions\u00e2\u20ac\u009d. We\u00e2\u20ac\u2122ll see why this is sensible later. Let\u00e2\u20ac\u2122s now define this common context, but we\u00e2\u20ac\u2122ll just write one extension for now:<\/p>\n<pre><code>[internal-extensions]\nexten =&gt; andyp,1,Dial(SIP\/andyp,20)\nexten =&gt; andyp,2,Verbose(1,No answer from SIP\/andyp)\nexten =&gt; andyp,3,Hangup<\/code><\/pre>\n<p>Extensions are like little programs, the form of the \u00e2\u20ac\u0153<code>exten<\/code>\u00e2\u20ac\u009d line is<\/p>\n<pre><code>DIALSTRING,PRIORITY,COMMAND<\/code><\/pre>\n<p>You can see then we\u00e2\u20ac\u2122re defining the <code>andyp<\/code> extension, i.e.\u00c2\u00a0this is what to do when someone calls the <code>andyp<\/code> extension in the <code>internal-extensions<\/code> context. Asterisk doesn\u00e2\u20ac\u2122t mind whether you use all numeric names or, as I have here, all alphabetic names in a dial string. When processing starts, the priority is at one, and is incremented after each command completes. So you can run multiple commands in response to a single DIALSTRING. In this case, we\u00e2\u20ac\u2122ve made it so that if someone dials the string \u00e2\u20ac\u0153andyp\u00e2\u20ac\u009d, Asterisk runs the <code>Dial()<\/code> function which rings an endpoint, in this case \u00e2\u20ac\u0153SIP\/andyp\u00e2\u20ac\u009d. Note that it didn\u00e2\u20ac\u2122t have to be \u00e2\u20ac\u0153SIP\/andyp\u00e2\u20ac\u009d there is nothing that stop us (except common sense) from having the \u00e2\u20ac\u0153andyp\u00e2\u20ac\u009d extension dial the \u00e2\u20ac\u0153SIP\/wife\u00e2\u20ac\u009d endpoint. If after 20 seconds, there has been no answer, then the next priority runs. That priority uses the <code>Verbose()<\/code> function to issue a message at verbosity level 1. The final priority, 3, hangs up.<\/p>\n<p>It can get tedious maintaining these priority numbers, so Asterisk offers a short cut in the form of the special, \u00e2\u20ac\u0153n\u00e2\u20ac\u009d priority.<\/p>\n<pre><code>[internal-extensions]\nexten =&gt; andyp,1,Dial(SIP\/andyp,20)\nexten =&gt; andyp,n,Verbose(1,No answer from SIP\/andyp)\nexten =&gt; andyp,n,Hangup<\/code><\/pre>\n<p>This simply means, \u00e2\u20ac\u0153one more than the previous\u00e2\u20ac\u009d. So this is identical in function to the first version.<\/p>\n<p>There are other special priorities, but one in particular is important to us here. The \u00e2\u20ac\u0153hint\u00e2\u20ac\u009d priority.<\/p>\n<pre><code>[internal-extensions]\nexten =&gt; andyp,1,Dial(SIP\/andyp,20)\nexten =&gt; andyp,n,Verbose(1,No answer from SIP\/andyp)\nexten =&gt; andyp,n,Hangup\nexten =&gt; andyp,hint,SIP\/andyp<\/code><\/pre>\n<p>With this in place run the asterisk command line again.<\/p>\n<pre><code>hostname*CLI&gt; reload\nhostname*CLI&gt; core show hints\n\n    -= Registered Asterisk Dial Plan Hints =-\n                  andyp@internal-extensions : SIP\/andyp State:Idle            Watchers  0\n----------------\n- 1 hints registered<\/code><\/pre>\n<p>Asterisk hints form a connection between an arbitrarily named extension and an endpoint. This connection allows use of the SIP SUBSCRIBE command. SIP phones can ask to be notified of the presence or absence of another extension. But extensions are not endpoints, so when, say, <code>SIP\/wife<\/code> sends a \u00e2\u20ac\u0153SUBSCRIBE andyp\u00e2\u20ac\u009d command, Asterisk (without the hint) has no way of knowing which endpoint\u00e2\u20ac\u2122s presence should be reported. The hint fixes that problem \u00e2\u20ac\u201c Asterisk will now know.<\/p>\n<p>Back to our <code>extensions.conf<\/code>. Do you notice that we wrote \u00e2\u20ac\u0153andyp\u00e2\u20ac\u009d a lot in that definition? If we ever renamed \u00e2\u20ac\u0153andyp\u00e2\u20ac\u009d it\u00e2\u20ac\u2122s a lot of work to change. It\u00e2\u20ac\u2122s also makes copy and pasting this entry to create others a lot more work. Let\u00e2\u20ac\u2122s address that.<\/p>\n<pre><code>[internal-extensions]\nexten =&gt; andyp,1,Dial(SIP\/${EXTEN},20)\nexten =&gt; andyp,n,Verbose(1,No answer from SIP\/${EXTEN})\nexten =&gt; andyp,n,Hangup\nexten =&gt; andyp,hint,SIP\/${EXTEN}<\/code><\/pre>\n<p>\u00e2\u20ac\u0153<code>${EXTEN}<\/code>\u00e2\u20ac\u009d is an Asterisk variable. It is expanded when processing the line. \u00e2\u20ac\u0153<code>${EXTEN}<\/code>\u00e2\u20ac\u009d in particular is a built-in variable and it expands to the name of the current extension. So now, provided we name our extensions the same as our SIP endpoints, we have made our extension handling generic.<\/p>\n<pre><code>[internal-extensions]\nexten =&gt; andyp,1,Dial(SIP\/${EXTEN},20)\nexten =&gt; andyp,n,Verbose(1,No answer from SIP\/${EXTEN})\nexten =&gt; andyp,n,Hangup\nexten =&gt; andyp,hint,SIP\/${EXTEN}\nexten =&gt; wife,1,Dial(SIP\/${EXTEN},20)\nexten =&gt; wife,n,Verbose(1,No answer from SIP\/${EXTEN})\nexten =&gt; wife,n,Hangup\nexten =&gt; wife,hint,SIP\/${EXTEN}<\/code><\/pre>\n<p>Our use of a variable has improved things, but this is still a lot of duplicated code. Further, if we add a new feature to the <code>andyp<\/code> extension, we have to remember to add it to the <code>wife<\/code> extension too. Wouldn\u00e2\u20ac\u2122t it be better if we just had one copy of the extension handling code? Yep.<\/p>\n<pre><code>[stdexten]\nexten =&gt; s,1,Verbose(1,Start stdexten ${ARG1},${ARG2})\nexten =&gt; s,n,Set(LOCAL(ext)=${ARG2})\nexten =&gt; s,n,Set(LOCAL(dev)=${ARG1})\nexten =&gt; s,n,Dial(${dev},20)\nexten =&gt; s,n,Goto(s-${DIALSTATUS},1)\nexten =&gt; s-NOANSWER,1,Verbose(1,No answer from ${ext})\nexten =&gt; s-NOANSWER,n,Return()\nexten =&gt; s-BUSY,n,Verbose(1,${ext} is busy)\nexten =&gt; s-BUSY,n,Return()\nexten =&gt; _s-.,1,Goto(s-NOANSWER,1)\n\n[internal-extensions]\nexten =&gt; andyp,1,Gosub(stdexten,s,1(SIP\/${EXTEN},${EXTEN}))\nexten =&gt; andyp,hint,SIP\/${EXTEN}\nexten =&gt; wife,1,Gosub(stdexten,s,1(SIP\/${EXTEN},${EXTEN}))\nexten =&gt; wife,hint,SIP\/${EXTEN}<\/code><\/pre>\n<p>Now we\u00e2\u20ac\u2122re cooking. We\u00e2\u20ac\u2122ve made a fairly large handler that behaves identically for both <code>andyp<\/code> and <code>wife<\/code> and yet doesn\u00e2\u20ac\u2122t duplicate any code. I won\u00e2\u20ac\u2122t go into exactly how <code>[stdexten]<\/code> works, the Asterisk documentation will tell you if you are interested (it\u00e2\u20ac\u2122s not rocket science though, you should be able to guess just by looking at it here).<\/p>\n<p>We can now add all of our endpoints to <code>internal-extensions<\/code> and have their hints set and have them callable. Should you have a genuine SIP phone which supports text extensions, you would then be able to call any of them. However, we need to cater for numeric keypads too. We can do that easily. Here\u00e2\u20ac\u2122s our completed <code>[internal-extensions]<\/code> with numeric aliases that match the <code>callerid<\/code> options we gave in <code>sip.conf<\/code>.<\/p>\n<pre><code>[internal-extensions]\n; Numeric aliases\nexten =&gt; 2100,1,Goto(andyp,1)\nexten =&gt; 2101,1,Goto(wife,1)\nexten =&gt; 2102,1,Goto(handytone1,1)\nexten =&gt; 2103,1,Goto(handytone2,1)\n; Named extensions\nexten =&gt; andyp,1,Gosub(stdexten,s,1(SIP\/${EXTEN},${EXTEN}))\nexten =&gt; andyp,hint,SIP\/${EXTEN}\nexten =&gt; wife,1,Gosub(stdexten,s,1(SIP\/${EXTEN},${EXTEN}))\nexten =&gt; wife,hint,SIP\/${EXTEN}\nexten =&gt; handytone1,1,Gosub(stdexten,s,1(SIP\/${EXTEN},${EXTEN}))\nexten =&gt; handytone1,hint,SIP\/${EXTEN}\nexten =&gt; handytone2,1,Gosub(stdexten,s,1(SIP\/${EXTEN},${EXTEN}))\nexten =&gt; handytone2,hint,SIP\/${EXTEN}<\/code><\/pre>\n<p>Reload from the command line interface and you should then be able to dial extensions from each other just like you would on a much more expensive PBX.<\/p>\n<p>Next time we\u00e2\u20ac\u2122ll look at making outgoing calls on different trunks for different extensions.<\/p>\n<p><a href=\"?p=441\">asterisk1<\/a> <a href=\"?p=443\">asterisk2<\/a> <a href=\"?p=445\">asterisk3<\/a> <a href=\"?p=447\">asterisk4<\/a> <a href=\"?p=449\">asterisk5<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last time we left ourselves in the position of having two outgoing trunks available and four locally connected phone extensions. Let\u00e2\u20ac\u2122s remind ourselves of these endpoints. $ asterisk -r hostname*cli&gt; sip show peers Name\/username Host Dyn Forcerport ACL Port Status andyp\/andyp 192.168.1.82 D OK (100 ms) wife\/wife (Unspecified) D 0 UNKNOWN handytone1\/handytone1 192.168.1.10 D 5060\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.fussylogic.co.uk\/blog\/?p=445\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[31,6],"_links":{"self":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/445"}],"collection":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=445"}],"version-history":[{"count":10,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/445\/revisions"}],"predecessor-version":[{"id":1088,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/445\/revisions\/1088"}],"wp:attachment":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=445"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=445"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}