<?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>feisley &#187; asterisk</title>
	<atom:link href="http://feisley.com/tag/asterisk/feed/" rel="self" type="application/rss+xml" />
	<link>http://feisley.com</link>
	<description>programming with a side of life</description>
	<lastBuildDate>Thu, 15 Apr 2010 07:33:58 +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>Google Voice and Asterisk</title>
		<link>http://feisley.com/2009/07/29/google-voice-and-asterisk/</link>
		<comments>http://feisley.com/2009/07/29/google-voice-and-asterisk/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 17:27:56 +0000</pubDate>
		<dc:creator>Jacob Feisley</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[asterisk]]></category>
		<category><![CDATA[Gizmo5]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[SIP]]></category>
		<category><![CDATA[voip]]></category>

		<guid isPermaLink="false">http://feisley.com/?p=3436</guid>
		<description><![CDATA[Many months back Paul Marks and I looked into how to integrate Google Voice and Asterisk. Inbound calling was simple as you direct your Google Voice account to a Gizmo5 number and Asterisk integrates with the open SIP standard that Gizmo5 uses.
However, our task was to be able to make outbound calls without the need [...]]]></description>
			<content:encoded><![CDATA[<p>Many months back <a href="http://pmarks.net">Paul Marks</a> and I looked into how to integrate Google Voice and Asterisk. Inbound calling was simple as you direct your Google Voice account to a Gizmo5 number and Asterisk integrates with the open SIP standard that Gizmo5 uses.</p>
<p>However, our task was to be able to make outbound calls without the need to use the web interface to place the call. What essentially had to happen is when you dialed a number on your SIP phone, Asterisk would have to talk to the Google Voice site and handle the call setup for you.</p>
<p><span id="more-3436"></span></p>
<p><strong>***UPDATE***: I worked with Ward Mundy of <a href="http://nerdvittles.com/">Nerd Vittles</a> who put togeather a complete solution for both Asterisk 1.4 and 1.6. Additionally we are now using<a href="http://code.google.com/p/pygooglevoice/"> pyGoogleVoice</a> which is a more complete library than Paul&#8217;s script below. For the full write up, check out: <a href="http://nerdvittles.com/?p=635">http://nerdvittles.com/?p=635</a></strong></p>
<p>Paul then created a Python AGI (Asterisk Gateway Interface) script. It integrates into your dial plan and allows for the call to be made. The logic flow is as follows:</p>
<ol>
<li>You pick up your SIP phone and make a call.</li>
<li>Asterisk receives your call and the google-voice-dialout.agi script is called.</li>
<li>The script contacts Google Voice and initiates a call based on the number passed to asterisk.</li>
<li>Google Voice then dials your Gizmo5 number which rings into Asterisk.</li>
<li>Asterisk identifies this call by its caller id and the script binds your outbound call and the incoming call from Google</li>
<li>Google proceeds to call out to your destination.</li>
<li>Call is connected!</li>
</ol>
<p>Now a few caveats to this approach. As Paul&#8217;s script is essentially<span style="text-decoration: line-through;"> screen scraping</span> using unpublished API&#8217;s to the Google Voice application, any changes made to their web API could break this script. (As he notes in the script comments) At any rate, at the time of writing it works and the script is available for download here, <a href="http://feisley.com/wp-content/uploads/2009/07/google-voice-dialout.agi">google-voice-dialout.agi</a>, or shown below for reference.</p>
<p>When I get some more time, I will post details how to integrate this into an Asterisk dialplan and other features.</p>
<p><br class="spacer_" /></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># google-voice-dialout.agi</span>
<span style="color: #808080; font-style: italic;"># Paul Marks (http://pmarks.net)</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># This is an Asterisk 1.6 script to place outgoing calls through Google Voice.</span>
<span style="color: #808080; font-style: italic;"># It will automatically sign into the web interface, and submit a click2call</span>
<span style="color: #808080; font-style: italic;"># request through your registered Gizmo number.  Asterisk can then answer</span>
<span style="color: #808080; font-style: italic;"># the incoming call, and Bridge() it into your original outgoing call.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># I deduced the click2call sequence by using the &quot;Live HTTP Headers&quot; Firefox</span>
<span style="color: #808080; font-style: italic;"># plugin.  If the website changes too much, this script will probably stop</span>
<span style="color: #808080; font-style: italic;"># working, so don't use it for anything too important.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># This assumes you've already configured Asterisk to receive Gizmo calls.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># This rule will redirect outbound calls to this script:</span>
<span style="color: #808080; font-style: italic;">#   exten =&gt; _1NXXNXXXXXX,1,AGI(google-voice-dialout.agi)</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># This rule will connect the inbound GV/Gizmo calls:</span>
<span style="color: #808080; font-style: italic;">#   exten =&gt; s/6502650000,1,Bridge(${DB_DELETE(gv_dialout/channel)}, p)</span>
<span style="color: #808080; font-style: italic;">#              ^-- Put your 10-digit Google Voice number here.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># To test this script from the command line without Asterisk, type the</span>
<span style="color: #808080; font-style: italic;"># following.  Be sure to type a few linefeeds at the end:</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#   $ ./google-voice-dialout.agi</span>
<span style="color: #808080; font-style: italic;">#   agi_channel:</span>
<span style="color: #808080; font-style: italic;">#   agi_dnid: 18004664411</span>
<span style="color: #808080; font-style: italic;">#</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Put your Google login and Gizmo number here:</span>
USERNAME = <span style="color: #483d8b;">&quot;username@gmail.com&quot;</span>
PASSWORD = <span style="color: #483d8b;">&quot;password&quot;</span>
GIZMO_NUMBER = <span style="color: #483d8b;">&quot;17475555555&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">httplib</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Error<span style="color: black;">&#40;</span><span style="color: #008000;">Exception</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> ReadAgiEnvironment<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    env = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
        line = <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdin</span>.<span style="color: #dc143c;">readline</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> line:
            <span style="color: #ff7700;font-weight:bold;">break</span>
        key, data = line.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">':'</span><span style="color: black;">&#41;</span>
        env<span style="color: black;">&#91;</span>key.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span> = data.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> env
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> SendAgi<span style="color: black;">&#40;</span><span style="color: #dc143c;">cmd</span><span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">cmd</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdin</span>.<span style="color: #dc143c;">readline</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SimpleCookieJar<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    cookie_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(?i)set-cookie: (<span style="color: #000099; font-weight: bold;">\w</span>+)=([^;]+).*&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">cookies</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> addCookies<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, response<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> header <span style="color: #ff7700;font-weight:bold;">in</span> response.<span style="color: black;">msg</span>.<span style="color: black;">headers</span>:
            m = <span style="color: #008000;">self</span>.<span style="color: black;">cookie_re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>header<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> m:
                <span style="color: #ff7700;font-weight:bold;">continue</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">cookies</span><span style="color: black;">&#91;</span>m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span> = m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;; &quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;%s=%s&quot;</span> <span style="color: #66cc66;">%</span> kv <span style="color: #ff7700;font-weight:bold;">for</span> kv <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">cookies</span>.<span style="color: black;">iteritems</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> GVClickToCall<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    USER_AGENT = <span style="color: #483d8b;">&quot;google-voice-dialout.agi/1.1&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, username, password, via, dial<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">username</span> = username
        <span style="color: #008000;">self</span>.<span style="color: black;">password</span> = password
        <span style="color: #008000;">self</span>.<span style="color: black;">via</span> = via
        <span style="color: #008000;">self</span>.<span style="color: black;">dial</span> = dial
        <span style="color: #008000;">self</span>.<span style="color: black;">cj</span> = SimpleCookieJar<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">h</span> = <span style="color: #dc143c;">httplib</span>.<span style="color: black;">HTTPSConnection</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;www.google.com&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">login</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">placeCall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">logout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> login<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #66cc66;">&gt;&gt;</span>sys.<span style="color: black;">stderr</span>, <span style="color: #483d8b;">&quot;Logging in.&quot;</span>
        postdata = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span> <span style="color: #483d8b;">&quot;Email&quot;</span>: <span style="color: #008000;">self</span>.<span style="color: black;">username</span>,
                                      <span style="color: #483d8b;">&quot;Passwd&quot;</span>: <span style="color: #008000;">self</span>.<span style="color: black;">password</span> <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">doRequest</span><span style="color: black;">&#40;</span>
            method=<span style="color: #483d8b;">&quot;POST&quot;</span>, url=<span style="color: #483d8b;">&quot;/accounts/ServiceLoginAuth&quot;</span>,
            body=postdata,
            headers=<span style="color: black;">&#123;</span> <span style="color: #483d8b;">&quot;Content-Type&quot;</span>: <span style="color: #483d8b;">&quot;application/x-www-form-urlencoded&quot;</span> <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Start at https://www.google.com/voice, and collect cookies as we</span>
        <span style="color: #808080; font-style: italic;"># follow all the redirects.</span>
        PREFIX = <span style="color: #483d8b;">&quot;https://www.google.com/&quot;</span>
        location = <span style="color: #483d8b;">&quot;/voice&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>:
            response, html = <span style="color: #008000;">self</span>.<span style="color: black;">doRequest</span><span style="color: black;">&#40;</span>
                method=<span style="color: #483d8b;">&quot;GET&quot;</span>, url=location,
                headers=<span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
&nbsp;
            location = response.<span style="color: black;">getheader</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;location&quot;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> location:
                <span style="color: #808080; font-style: italic;"># No more redirects, yay!</span>
                <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
            <span style="color: #808080; font-style: italic;"># All redirects should fall within the same domain.</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> location.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span>PREFIX<span style="color: black;">&#41;</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> Error<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Unexpected redirect: %s&quot;</span> <span style="color: #66cc66;">%</span> location<span style="color: black;">&#41;</span>
            location = location<span style="color: black;">&#91;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>PREFIX<span style="color: black;">&#41;</span>-<span style="color: #ff4500;">1</span>:<span style="color: black;">&#93;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Scrape magic _rnr_se value from the HTML.</span>
        m = <span style="color: #dc143c;">re</span>.<span style="color: black;">search</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'name=&quot;_rnr_se&quot; type=&quot;hidden&quot; value=&quot;([^&quot;]+)&quot;'</span>, html<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> m:
            <span style="color: #ff7700;font-weight:bold;">raise</span> Error<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Can't find _rnr_se.  Not logged in?&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">magic_rnr_se</span> = m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> placeCall<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #66cc66;">&gt;&gt;</span>sys.<span style="color: black;">stderr</span>, <span style="color: #483d8b;">&quot;Calling %s via %s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">dial</span>, <span style="color: #008000;">self</span>.<span style="color: black;">via</span><span style="color: black;">&#41;</span>
        postdata = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span> <span style="color: #483d8b;">&quot;outgoingNumber&quot;</span>: <span style="color: #008000;">self</span>.<span style="color: black;">dial</span>,
                                      <span style="color: #483d8b;">&quot;forwardingNumber&quot;</span>: <span style="color: #008000;">self</span>.<span style="color: black;">via</span>,
                                      <span style="color: #483d8b;">&quot;_rnr_se&quot;</span>: <span style="color: #008000;">self</span>.<span style="color: black;">magic_rnr_se</span> <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
        response, http = <span style="color: #008000;">self</span>.<span style="color: black;">doRequest</span><span style="color: black;">&#40;</span>
            method=<span style="color: #483d8b;">&quot;POST&quot;</span>, url=<span style="color: #483d8b;">&quot;/voice/call/connect&quot;</span>,
            body=postdata,
            headers=<span style="color: black;">&#123;</span> <span style="color: #483d8b;">&quot;Content-Type&quot;</span>: <span style="color: #483d8b;">&quot;application/x-www-form-urlencoded&quot;</span> <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #66cc66;">&gt;&gt;</span>sys.<span style="color: black;">stderr</span>, <span style="color: #483d8b;">&quot;Dial response:&quot;</span>, http
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> logout<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">doRequest</span><span style="color: black;">&#40;</span>
            method=<span style="color: #483d8b;">&quot;GET&quot;</span>, url=<span style="color: #483d8b;">&quot;/accounts/Logout&quot;</span>,
            headers=<span style="color: black;">&#123;</span> <span style="color: #483d8b;">&quot;Connection&quot;</span>: <span style="color: #483d8b;">&quot;close&quot;</span> <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #66cc66;">&gt;&gt;</span>sys.<span style="color: black;">stderr</span>, <span style="color: #483d8b;">&quot;Logged out.&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> doRequest<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, headers, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>:
        headers<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;User-agent&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">self</span>.<span style="color: black;">USER_AGENT</span>
        headers<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Cookie&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">self</span>.<span style="color: black;">cj</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">h</span>.<span style="color: black;">request</span><span style="color: black;">&#40;</span>headers=headers, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>
        response = <span style="color: #008000;">self</span>.<span style="color: black;">h</span>.<span style="color: black;">getresponse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">cj</span>.<span style="color: black;">addCookies</span><span style="color: black;">&#40;</span>response<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> response, response.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    env = ReadAgiEnvironment<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #66cc66;">&gt;&gt;</span>sys.<span style="color: black;">stderr</span>, env
&nbsp;
    agi_channel = env<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;agi_channel&quot;</span><span style="color: black;">&#93;</span>
    agi_dnid = env<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;agi_dnid&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Write the channel ID to Asterisk's database, so it can be accessed</span>
    <span style="color: #808080; font-style: italic;"># by the incoming call when it arrives.</span>
    SendAgi<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;database put gv_dialout channel %s&quot;</span> <span style="color: #66cc66;">%</span> agi_channel<span style="color: black;">&#41;</span>
&nbsp;
    SendAgi<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;answer&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        GVClickToCall<span style="color: black;">&#40;</span>username=USERNAME, password=PASSWORD,
                      dial=agi_dnid, via=GIZMO_NUMBER<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Asterisk should patch in the incoming call while we're asleep.</span>
        <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">finally</span>:
        SendAgi<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;hangup&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://feisley.com/2009/07/29/google-voice-and-asterisk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cisco 7970G + Asterisk</title>
		<link>http://feisley.com/2008/03/20/cisco-7970g-asterisk/</link>
		<comments>http://feisley.com/2008/03/20/cisco-7970g-asterisk/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 21:34:21 +0000</pubDate>
		<dc:creator>Jacob Feisley</dc:creator>
				<category><![CDATA[Cisco]]></category>
		<category><![CDATA[Dark Horse Networks]]></category>
		<category><![CDATA[asterisk]]></category>
		<category><![CDATA[NAT]]></category>
		<category><![CDATA[router]]></category>
		<category><![CDATA[SIP]]></category>
		<category><![CDATA[VPN]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://feisley.com/2008/03/20/cisco-7970g-asterisk/</guid>
		<description><![CDATA[
The Cisco 7970G IP Phone is by far one of the nicest VoIP Phones i have ever used. However, getting it to work outside the standard Cisco Call Manager environment with Asterisk can be a challenge. After weeks of testing various configurations and tweaking settings on both the phone and Asterisk, i was able to [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-thumbnail wp-image-24" title="Cisco 7970g" src="http://feisley.com/wp-content/uploads/2008/03/7970g-150x120.jpg" alt="" width="150" height="120" /></p>
<p>The Cisco 7970G IP Phone is by far one of the nicest VoIP Phones i have ever used. However, getting it to work outside the standard Cisco Call Manager environment with Asterisk can be a challenge. After weeks of testing various configurations and tweaking settings on both the phone and Asterisk, i was able to finally get a working configuration that works for both local network connections and NAT as well.</p>
<p><span id="more-13"></span></p>
<p>As with any setup there are some prerequisites that must be met to perform this setup. It is possible that other configurations and software versions will work, however this is what I have currently working. You are welcome to let me know if you have other setups that work.</p>
<p><strong>My Configuration &amp; Setup</strong></p>
<ol>
<li>Asterisk 1.4.18</li>
<li>Cisco 7970G (firmware:  SIP70.8-3-4SR1S)</li>
<li>2  Cisco 1811  routers (IOS: 12.4(15)T1)</li>
</ol>
<p>I successfully tested the following configurations with the phone:</p>
<p><strong>The NAT Setup*</strong></p>
<p>7970G &lt;&#8211;&gt; 1811 (w/ NAT) &lt;&#8211;&gt; Internet &lt;&#8211;&gt; 1811 (w/ NAT) &lt;&#8211;&gt; Asterisk</p>
<p><strong>The DMVPN Setup (Same as a local network)</strong></p>
<p>7970G &lt;&#8211;&gt; 1811 &lt;&#8211;&gt; Internet (VPN) &lt;&#8211;&gt; 1811 &lt;&#8211;&gt; Asterisk</p>
<p>The DMVPN setup was the most trivial as it was essentially a local network with the Asterisk server. The NAT setup was the harder one to get working, however, once I got a configuration file that worked with NAT, the same configuration worked for the DMVPN or local setup as well.</p>
<p>*I believe that one of the keys to getting the 7970G working over NAT was the fact that it was behind a Cisco router (the 1811). Because this router&#8217;s NAT implementation is SIP aware, it is able to properly handle SIP messages over NAT from the 7970G. This being said, the 7970G may not function properly over NAT on other routers.</p>
<p><strong>XML Configuration File</strong></p>
<p>Below you will find the link to my XML configuration file (with passwords and IP&#8217;s of my private network removed of course)</p>
<p><a title="Cisco 7970 Configuration XML" href="http://feisley.com/wp-content/uploads/2008/03/sepmaccnf.xml">Cisco 7970 Configuration XML</a></p>
<p>NOTE: The file should be in the form &#8220;SEP<strong>mac_address</strong>.cnf.xml&#8221; when you place it on your TFTP server. where <strong>mac_address</strong> is the MAC address of your Cisco IP phone.</p>
<p><strong>Asterisk Configuration</strong></p>
<p>In order to get the Cisco 7970G to register to asterisk (either over NAT or VPN) the <strong>NAT </strong>flag in your <em>sip.conf</em> (or in FreePBX) must be set to &#8220;never&#8221; and <strong>qualify </strong>must be set to &#8220;yes&#8221;. I know it seems counter intuitive to keep NAT turned off when you are behind it but for some reason Asterisk&#8217;s NAT implementation breaks Cisco phone connections. Qualify is needed because it keeps the NAT translation open between the Cisco phone and the Asterisk server. Should the translation be allowed to close, Asterisk will not be able to reach the Cisco phone.</p>
<p><strong>MWI Fixes </strong></p>
<p>The second part to this was making sure that MWI worked on the phone. This has become somewhat of an issue due to a couple reasons:</p>
<ol>
<li>Asterisk adds some extra (and seemingly unneeded information) to the voice mail notices</li>
<li>Cisco decided not to follow the RFC on the SIP protocol and thus it ignores these notices with extra information.</li>
</ol>
<p>Cisco firmware version 8.0.2SR1 is able to handle the extra information and thus this is the firmware that many people using this phone have stuck with despite the numerous newer releases that have come out. Any version after that must use one of the following methods to get MWI working again.</p>
<ol>
<li>Asterisk 1.4 introduced the &#8220;BUGGYMWI&#8221;  flag for the <em>sip.conf</em> file. When defining an extension simply add the line &#8220;BUGGYMWI = true&#8221; and it will make the proper adjustments to the notices for Cisco compatibility.</li>
<li>Before compiling the Asterisk source code you can modify a line in the &#8220;chan_sip.c&#8221; file to remove that extra information permanently.</li>
</ol>
<p>I opted for option #2 for two reasons. First, it just seemed cleaner to make the change once and not have to worry about it again (until i upgrade that is) and secondly,  FreePBX  does not provide an easy way to add the &#8220;BUGGYMWI&#8221;  flag into extensions.</p>
<p>In order to remove this from <em>chan_sip.c</em> permanently, go to your asterisk source code and then go to the &#8220;channels&#8221; folder. From there open up the <em>chan_sip.c</em> file and search for the following:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* Cisco has a bug in the SIP stack where it can't accept the
(0/0) notification. This can temporarily be disabled in
sip.conf with the &quot;buggymwi&quot; option */</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">ast_build_string<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>t<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>maxbytes<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Voice-Message: %d/%d%s<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> newmsgs<span style="color: #339933;">,</span> oldmsgs<span style="color: #339933;">,</span>
<span style="color: #009900;">&#40;</span>ast_test_flag<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>p<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>flags<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> SIP_PAGE2_BUGGY_MWI<span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #339933;">:</span> <span style="color: #ff0000;">&quot;(0/0)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now all you must do is simply replace the last line with this:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">ast_build_string<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>t<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>maxbytes<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Voice-Message: %d/%d<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> newmsgs<span style="color: #339933;">,</span> oldmsgs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And then compile Asterisk.</p>
<p><strong>Epilogue </strong></p>
<p>I hope this guide helps everyone that loves the Cisco 7970G phone to get it working with Asterisk. It can be a difficult task but is well worth the effort once it is working. Please feel free to leave comments with any suggestions to this article and let me know if you have gotten any other configurations working!</p>
]]></content:encoded>
			<wfw:commentRss>http://feisley.com/2008/03/20/cisco-7970g-asterisk/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

