<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IT.JDMetzger.com</title>
	<atom:link href="http://it.jdmetzger.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://it.jdmetzger.com</link>
	<description></description>
	<lastBuildDate>Thu, 30 Dec 2010 20:31:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SIP routing</title>
		<link>http://it.jdmetzger.com/2010/03/07/sip-routing/</link>
		<comments>http://it.jdmetzger.com/2010/03/07/sip-routing/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 14:53:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://it.jdmetzger.com/?p=41</guid>
		<description><![CDATA[Back when I was a bit newer with Asterisk, I was setting up a rather large office and had a number of issues getting things going.  To make a long story short, I learned that Asterisk is a terrible SIP router.  Many of you probably already know this &#8211; if you have an Asterisk server [...]]]></description>
			<content:encoded><![CDATA[<p>Back when I was a bit newer with Asterisk, I was setting up a rather large office and had a number of issues getting things going.  To make a long story short, I learned that Asterisk is a terrible SIP router.  Many of you probably already know this &#8211; if you have an Asterisk server that only hands off calls to other servers based on dialplan rules, you will eventually choke the server as if it was processing all the calls itself since it won&#8217;t route the SIP traffic without also processing the audio stream, which is taxing even when it&#8217;s just passthru.  How I wish for an option in SIP.CONF like &#8220;siprouter=yes&#8221; where you can use it as a SIP router.  This would save a lot of time &#8211; there is already code for dealing with a database, extensions.conf is creating in a language I know, and I would only be dealing with one piece of software.  How nice.  Anyone want to set that up for me?</p>
<p><span id="more-41"></span></p>
<p>Since that isn&#8217;t really an option, I have the need for a SIP routing package that is fairly powerful.  I&#8217;ve started to look at OpenSIPS, though the learning curve seems pretty steep and so far my other job functions (Linux admin, EMC CX3 SAN management) makes it hard to get to these other projects as quickly as I&#8217;d like.  Currently we&#8217;re using a windows-based SIP router that functions fine for large pattern-matching (555XXXX to one server, 666XXXX to another&#8230;), but I want more granularity and the ability to use a database so updates can be automated.  I&#8217;ll update regarding my progress as I go along and we&#8217;ll see what happens.</p>
]]></content:encoded>
			<wfw:commentRss>http://it.jdmetzger.com/2010/03/07/sip-routing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More fancy queues</title>
		<link>http://it.jdmetzger.com/2010/02/28/more-fancy-queues/</link>
		<comments>http://it.jdmetzger.com/2010/02/28/more-fancy-queues/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 18:17:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Asterisk]]></category>

		<guid isPermaLink="false">http://it.jdmetzger.com/?p=37</guid>
		<description><![CDATA[As mentioned in my previous post about queueing, I wanted to add some code that automatically adds an extension into the queue database table the first time they log in.  I finally got around to adding the three lines in extensions.conf as well as creating the extra func_odbc.conf entries.  Total time for the addition [...]]]></description>
			<content:encoded><![CDATA[<p>As mentioned in my previous post about queueing, I wanted to add some code that automatically adds an extension into the queue database table the first time they log in.  I finally got around to adding the three lines in extensions.conf as well as creating the extra func_odbc.conf entries.  Total time for the addition was only a few minutes.</p>
<p><span id="more-37"></span></p>
<p>First, extensions.conf:</p>
<pre>exten =&gt; *7,48,Set(EXIST=${ODBC_EXTENEXIST(${CALLERID(num)},queuenum)})
exten =&gt; *7,49,Gotoif($["${EXIST}" = "${CALLERID(num)}"]?51:43)
exten =&gt; *7,50,Set(ODBC_QUEUENUMC()=${CALLERID(num)}\,1234)
</pre>
<p>It&#8217;s pretty basic &#8211; set variable &#8220;exist&#8221; to the output from a select statement that tries to pull the extension from the &#8220;queuenum&#8221; table.  From there, compare &#8220;exist&#8221; to &#8220;queuenum&#8221;.  If it matches, go ahead and log the person in with the code in my previous post, otherwise create the entry with default information, then go ahead and log them in like everyone else.</p>
<p>Func_odbc entries:</p>
<pre>[EXTENEXIST]
dsn=asterisk
read=SELECT ${ARG1} FROM ${ARG2}  WHERE EXTEN = '${ARG1}'

[QUEUENUMC]
dsn=asterisk
write=insert queuenum (exten,queue) values ('${VAL1}','${VAL2}')</pre>
<p>And there you have it!</p>
]]></content:encoded>
			<wfw:commentRss>http://it.jdmetzger.com/2010/02/28/more-fancy-queues/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fancy Queues</title>
		<link>http://it.jdmetzger.com/2010/02/17/fancy-queues/</link>
		<comments>http://it.jdmetzger.com/2010/02/17/fancy-queues/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 16:15:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Asterisk]]></category>

		<guid isPermaLink="false">http://it.jdmetzger.com/?p=16</guid>
		<description><![CDATA[I always wonder if I&#8217;m missing some basic features of Asterisk that would allow me to do things in an easier way, but often I find it difficult or impossible to find good solutions online, meaning I end up creating my own solutions.
My office has a rather convoluted queue setup that was initially configured on [...]]]></description>
			<content:encoded><![CDATA[<p>I always wonder if I&#8217;m missing some basic features of Asterisk that would allow me to do things in an easier way, but often I find it difficult or impossible to find good solutions online, meaning I end up creating my own solutions.</p>
<p>My office has a rather convoluted queue setup that was initially configured on a Cisco CallManager system.  I had to find a smooth way of replicating this on Asterisk.  The basic setup is we have about 12 different queues.  Users need a simple way to login/logout of a queue (only one at a time).  That is the easy part.  The extra catch is each phone can be reached directly from the outside, and if they don&#8217;t answer the call should roll into their queue, as extensions do not have their own voicemail.   We frequently have new hires and people moved to different groups, so this saves me a lot of trouble with manual queue changes for each phone.</p>
<p><span id="more-16"></span></p>
<p>I&#8217;m still using the older style extension language as I haven&#8217;t had time to switch our many offices to anything newer (yet).  I could really use case statements, as you will see.  I am also accessing a MySQL database using func_odbc.  Back when I first set these systems up, I liked using that better than the mysql features, as it was part of the core Asterisk distribution and the mysql things were in asterisk-addons.  I wanted to stick with what I saw as the simpler setup.  First the easy stuff.</p>
<p>A basic queue config in queues.conf</p>
<pre><span style="color: #0000ff;">[5551212] ; queue 1212
musiconhold=default
strategy=rrmemory
timeout=12
ringinuse=yes</span></pre>
<p>Now for the dialplan.  Users login with *7 and logout with *9.  When dialing *7, they are logged out of any other queue (in case they forgot to log out), are prompted for their 4-digit queue number, then logged in.  We also update a database entry.  I&#8217;ll get to that in a moment.  Here is the extensions.conf:</p>
<pre><span style="color: #0000ff;">exten =&gt; *7,1,Answer()
exten =&gt; *7,2,Set(TRIES=0)
exten =&gt; *7,3,Set(ATTEMPT=0)
exten =&gt; *7,4,Wait(1)
exten =&gt; *7,5,Read(QNUM|enter-qnum|4)
exten =&gt; *7,6,GotoIf($["${QNUM}" = "1212"]?51:7)
exten =&gt; *7,7,GotoIf($["${QNUM}" = "1213"]?51:8)
exten =&gt; *7,8,GotoIf($["${QNUM}" = "1214"]?51:9)
exten =&gt; *7,9,GotoIf($["${QNUM}" = "1215"]?51:800)
exten =&gt; *7,51,Set(OLDQNUM=${ODBC_QUEUENUMR(queue,${CALLERID(num)})})
exten =&gt; *7,52,System(asterisk -rx "queue remove member SIP/${CALLERID(num)} from 555${OLDQNUM}")
exten =&gt; *7,53,Set(ODBC_QUEUENUMW()=${QNUM}\,${CALLERID(num)})
exten =&gt; *7,54,System(asterisk -rx "queue add member SIP/${CALLERID(num)} to 555${QNUM}")
exten =&gt; *7,55,Noop(Agent ${CALLERID(num)} added to queue 555${QNUM})
exten =&gt; *7,56,Playback(agent-loginok)
exten =&gt; *7,57,Hangup
exten =&gt; *7,800,Playback(invalid-qnum)
exten =&gt; *7,801,Wait(1)
exten =&gt; *7,802,Set(TRIES=$[${TRIES} + 1])
exten =&gt; *7,803,GoToIf($[${TRIES} &gt; 2]?*7,900:*7,5)
exten =&gt; *7,804,Hangup
exten =&gt; *7,900,Playback(goodbye-qnum)
exten =&gt; *7,901,Hangup
exten =&gt; *9,1,Answer()
exten =&gt; *9,2,Set(QNUM=${ODBC_QUEUENUMR(queue,${CALLERID(num)})})
exten =&gt; *9,3,System(asterisk -rx "queue remove member SIP/${CALLERID(num)} from 555${QNUM}")
exten =&gt;*9,4,Playback(agent-loggedoff)
exten =&gt; *9,5,Hangup()</span></pre>
<p>The call flow for the *7 login sets counters to zero, plays a recorded &#8220;Please enter your queue number&#8230;&#8221; message, then waits for input.  If they put in an invalid number, it tells them, updates the try counter, and re-prompts for the queue number.  After several failed attempts it plays a goodbye message and disconnects.  If they enter a valid number, it checks their last logged in queue (extension is grabbed from their callerid and their last queue number is pulled from the database), logs them out (just to make sure &#8211; I don&#8217;t check if they actually were logged out first, I just try to log them out.  It&#8217;s probably a bit lazy), then it updates the database information with the queue number they entered, logs them into that queue, and plays an &#8220;Agent logged in&#8221; message before disconnecting.  We use 7-digit queue numbers for some other office features, but to make things easy we only ask for the last 4 digits from the users, so I append the first three digits to the queue number (in this case, the first three are &#8220;555&#8243;).</p>
<p>The &#8220;*9&#8243; logout feature is much more simplistic.  It reads the queue they were logged into from the database, logs them out, and plays the &#8220;Agent logged off&#8221; message.</p>
<p>The database table structure we&#8217;re using is rather simple.  The table is called &#8220;queuenum&#8221; which contains three fields; id, exten, queue.  &#8220;Id&#8221; is just an auto-incremented field number.  &#8220;exten&#8221; is the extension number (table was pre-populated with all extensions), and &#8220;queue&#8221; is the queue they are logged into/last logged into.  Now for the function calls to read and write the queue info:</p>
<p>func_odbc.conf</p>
<pre><span style="color: #0000ff;">[QUEUENUMW]

dsn=asterisk

write=UPDATE queuenum SET queue='${VAL1}' WHERE EXTEN='${VAL2}'

[QUEUENUMR]

dsn=asterisk

read=SELECT ${ARG1} FROM queuenum WHERE EXTEN = '${ARG2}'</span></pre>
<p>Pretty basic &#8211; one read the queue number, one writes the queue number.</p>
<p>So that takes care of the queues.conf setup, all extensions are in agents.conf, we have a database table full of extension numbers, we have a way for users to log in/log out of their queues, and we have the func_odbc calls to read/write queue information to/from a database.  All that is left is the extensions.conf configuration for each phone so inbound calls roll to their queue (or the queue they were last logged in to):</p>
<p>extensions.conf (for the phone):</p>
<pre><span style="color: #0000ff;">exten =&gt; 5559999,1,Dial(SIP/5559999,20)

exten =&gt; 5559999,n,Goto(queue-routing,s,1)</span></pre>
<p>And here is the queue routing routine:</p>
<pre><span style="color: #0000ff;">[queue-routing]

exten =&gt; s,1,Set(QNUM=${ODBC_QUEUENUMR(queue,${CALLERID(num)})})

exten =&gt; s,2,Noop(loop routing from ${CALLERID(num)} to queue 555${QNUM})

exten =&gt; s,3,Goto(inboundqueues,555${QNUM},1)</span></pre>
<p>This pulls the queue number from the database and sends the call to the context (in this example, I called it &#8220;inboundqueues&#8221;) and the correct queue number.  There is also code to handle invalid entries (if they would happen) to send the calls to our front desk.</p>
<p>That&#8217;s it!  The only changes I want to make is to have it automatically create the extension entry in the database table so when adding new phones I don&#8217;t have to do it manually.  It will only be a few lines of code to check for the existence of the extension, and if it&#8217;s not there, create it (which would happen immediately after verifying the user puts in a valid queue number.  It&#8217;s worth noting that when I auto-generated the database table, I also put all extensions into a default queue so there is no code to handle a &#8220;NULL&#8221; queue situation.  Once I add the code to auto-populate the table, it will always be a non-issue.</p>
<p>Go ahead and critique or tell me there is a far easier way to handle this.  I enjoy finding better ways of doing things!</p>
]]></content:encoded>
			<wfw:commentRss>http://it.jdmetzger.com/2010/02/17/fancy-queues/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asterisk upgrade pains</title>
		<link>http://it.jdmetzger.com/2010/02/16/asterisk-upgrade-pains/</link>
		<comments>http://it.jdmetzger.com/2010/02/16/asterisk-upgrade-pains/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 04:31:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://it.jdmetzger.com/?p=13</guid>
		<description><![CDATA[We recently updated one of our sites to the newest 1.4 Asterisk release (1.4.29 as of the time of the upgrade).  So far things have been working fairly well.  We had a convoluted queues.conf setup in the past with all of the queue members (incorrectly) entered in that file.  Calls would ring to the correct [...]]]></description>
			<content:encoded><![CDATA[<p>We recently updated one of our sites to the newest 1.4 Asterisk release (1.4.29 as of the time of the upgrade).  So far things have been working fairly well.  We had a convoluted queues.conf setup in the past with all of the queue members (incorrectly) entered in that file.  Calls would ring to the correct phones, but there was no way for an unused phone to be logged out.  It also made management cumbersome.  With the new upgrade, calls would still route the same but users could not answer the call.  If they picked up the call they ended up with a &#8220;dead air&#8221; connection to nothing while on the caller side it continued acting like nobody picked up, and eventually the call would timeout and go to voicemail.  Very strange.  We switched to having an easier to manage dynamic setup where phones can log in and out to different call queues and I added some fancy (I think) features that I&#8217;ll outline in my next post, which handles our specific call routing needs.</p>
<p>Aside from that, we seem to be having mystery problems of voicemails suddenly not always saving.  Debugging is now activated and I hope I can track down the problem quickly.</p>
]]></content:encoded>
			<wfw:commentRss>http://it.jdmetzger.com/2010/02/16/asterisk-upgrade-pains/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mystery T1 issues</title>
		<link>http://it.jdmetzger.com/2010/01/13/hello-world/</link>
		<comments>http://it.jdmetzger.com/2010/01/13/hello-world/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 03:32:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Asterisk]]></category>

		<guid isPermaLink="false">http://it.jdmetzger.com/?p=1</guid>
		<description><![CDATA[As usual, a substantial amount of my work time is being taken up with Asterisk programming and issues.  There was a T1 attached to one of the servers that had a channel a bit out of whack.  Any call coming into the 5th channel would ring in and &#8220;hang&#8221;.  From the calling side, it was [...]]]></description>
			<content:encoded><![CDATA[<p>As usual, a substantial amount of my work time is being taken up with Asterisk programming and issues.  There was a T1 attached to one of the servers that had a channel a bit out of whack.  Any call coming into the 5th channel would ring in and &#8220;hang&#8221;.  From the calling side, it was dead silence.  From the servers point of view, a call came in without DNIS or CID.  It tried to play the &#8220;ss-noservice&#8221; message, but the audio would not be heard.  The carried claimed it was an &#8220;equipment issue&#8221; on our side (that restarts never solved), but after some testing (and a reset by Qwest), the problem suspiciously disappeared and has not returned.  Now, back to creating more custom IVR menus.</p>
]]></content:encoded>
			<wfw:commentRss>http://it.jdmetzger.com/2010/01/13/hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

