Turning your OBi200 and OBi202 into a SIP-to-Google-Voice Bridge

Robert Stampfli — r5519@cboh.org — Published June, 2018; last updated Saturday, 08 December 2018

I have successfully programmed many OBi devices to perform the SIP/GVsip bridge function described in these notes. In addition, I have exchanged emails with perhaps a dozen other individuals who have successfully implemented their own bridges. However, I have unfortunately not kept up with the evolution of the Asterisk server, and as such these notes may well have become dated. Feel free to make use of them within your own VoIP system, with the caveat that they have not been tested personally on systems beyond Asterisk 13. I believe they should continue to work fine, perhaps with some minor tweaks. Let me know if you are successful (or not), along with any alterations you had to make, and I'll include your results here for the benefit of others in the community. Finally, feel free to critique these notes if you see areas where changes are needed or they can be improved.


Many VoIP hobbyists and experimenters have come to rely on Google Voice for their trunking needs. While it's certainly not a perfect fit, it can be made to work reasonably well and free offsets a multitude of sins. In mid-2018, Google shut down its XMPP servers — the protocol the Asterisk PBX used to access GV. Polycom (neé OBiHAI) makes the only non-Google devices which currently have access to the new GV network with Google's blessing, and this got me thinking: The OBi 200 and 202 devices are themselves a feature-rich ATA — some might even say a mini-PBX in themselves — capable of handling four trunks and/or endpoint devices. Could they be pressed into service to provide a SIP-to-GV bridge? Think of this as a small localized version of Bill Simon's Google Voice Gateway. After some experimentation I came to the conclusion that, yes, they can.

I was able to interface an OBi202 to an Asterisk 13 server such that (1) outgoing calls from Asterisk would flow into the 202 using the SIP protocol, where they would be bridged to a corresponding GV line to complete the call. And (2) incoming GV calls would be automatically translated into SIP and delivered to Asterisk. In essence, the OBi200 or 202 ATA look like an ITSP to the Asterisk server and make it possible for Asterisk to continue to support up to three GV lines per OBi.

The OBi200 can be had for around $50 and as low as $35 on sale. The 202 costs a bit more. However, many of us already use these OBi units as ATAs in which case the additional functionality can often be added without any additional hardware costs.

What follows is a description of how to configure Asterisk and the OBi device to accomplish this task. Every configuration option described herein is based on publicly available published documentation. I will address two scenarios: The first, and simpler, implementation presumes that the Asterisk server and OBi device are on the same local LAN. The second, more involved, approach will work with an Asterisk server with a static IP address on the Internet interfacing with an OBI sitting behind a firewall that has a dynamic IP. (Think Asterisk on a VPS here.)

These notes presume the reader is familiar with programming the FreePBX Asterisk server, including how to add a trunk and make it functional. My personal testing was performed on a FreePBX 13 system running Asterisk 13. A Debian 8 system supported the first implementation and a CentOS 6 system the second.

There are two ways to make the changes we will be making below. One way is through the obitalk.com website using their Expert interface. The other is via the OBi's built-in web server (but only if Auto Provisioning is disabled first, or they will fight each other). Unfortunately, the Expert interface lacks the ability to enable X_EarlyICEEnableIn, and without this feature being enabled unanswered outbound calls will generate an error 503 after approximately 22 seconds of unanswered ringing, effectively denying access to most voicemail systems and answering machines. Because of this, I recommend disabling Auto Provisioning and using the built-in web server to configure your OBi. However, if you still prefer the online Expert interface, X_EarlyICEEnableIn may be enabled via the built-in web server and the rest configured via obitalk.com.

One shortcoming of using an OBi for Google Voice access is that you must have a physical location and network in which to place your OBi device, and this makes interfacing your OBi to a remoted Virtual Private Server (VPS) problematic when compared to a software-only solution.


Verify your OBi firmware is current:
You must be on a firmware load that supports the new GVsip protocol or GV will not work. The firmware ("Software Version") can be found under Product Information on the status page, from either the device's internal server or the OBiTalk.com website. The version must be 3.2.2 Build 5859EX or later.
Program the GV service(s) into your OBi:
This is normally done using the OBiTalk.com interface. Refer to the instructions on the website.

Make a note of the site-specific data you'll need:

Method 1: Your OBi and Asterisk are on the same LAN

If your Asterisk server and OBi are located on the same LAN and both have static IP addresses, then this method should work and is the simplest way to proceed. No registrations or authentications are needed; instead, the IP addresses themselves provide the necessary authentication. For the OBi, a static IP address can either be assigned manually, or by setting up your DHCP server to always serve the same IP address when presented with the OBi's MAC address. The latter is often the easier way to make this happen.

The OBi20X boxes have support for four Voice Services, named SP1 - SP4. It also has provisions for handling four Service Provider ITSP Profiles. By convention, SP1 is linked to ITSP Profile A, SP2 to Profile B, etc., but this is not a requirement.

In addition to the GV Service(s) you already have programmed (via OBiTalk.com), you'll need at least one unencumbered Voice Service for the SIP-side interface.

Now, before we begin, raise your right hand and repeat after me: "I will NOT change any parameter under any Google Voice Service or its ITSP Profile except for X_InboundCallRoute". If you do accidentally change a GV parameter it may break your GV or cause odd problems which are hard to diagnose.

On the OBi, here are the changes I made to the default settings, or in the case of SPgv, the settings OBiTALK made when setting up the Google Voice Service:

*** Changes to the OBi SIP-side service:

Using the ITSP profile you previously assigned to your SIP Voice Service:
Service Providers > ITSP Profile X > SIP > ProxyServer             [Set to the IP-addr of your Asterisk Server]
Service Providers > ITSP Profile X > SIP > ProxyServerPort         [Set to the listening SIP port on your Asterisk server (typically 5060 or 5160)]
Service Providers > ITSP Profile X > SIP > X_SpoofCallerID         (check)
Service Providers > ITSP Profile X > General > X_EarlyICEEnableIn  (check) ¹

Voice Services > SPx Service > X_ServProvProfile                   [The ITSP profile you selected and modified above]
Voice Services > SPx Service > X_InboundCallRoute                  {SPgv}
Voice Services > SPx Service > X_RegisterEnable                    (uncheck)
Voice Services > SPx Service > AuthUserName                        OBi202 ²
Voice Services > SPx Service > X_EnforceRequestUserID              (must be unchecked)
¹ – Must be enabled via the OBi's built-in web server.  Thanks to maxm from dslreports.com for finding this fix for the truncated-ring problem.
² – AuthUserName can be anything, but it must match username below.

*** Changes to the OBi GV-side service:

(This will be the only change you should make to the GV Service.)
Voice Services > SPgv Service > X_InboundCallRoute                 {SPx(6145551212)} ¹
¹ – Substitute your GV DID for 6145551212.

A word about the choice of a DID number above: Any number will work here as long as it does not conflict with another number on your server, but your GV DID is a good choice because it is logical as well as unique. You can prepend a leading '1' to it or not; just make sure it matches the DID you code in the Inbound Route below.

*** Changes on your Asterisk/FreePBX server:

Create a SIP trunk:
Creation is straightforward and left as an exercise for the reader. I set Maximum Channels to '2' to avoid abusing GV. The Incoming SIP Settings should all be left blank. The Outgoing Peer Details should contain something like:
host= ¹
port=5060 ²
username=OBi202 ³
allow=ulaw,opus ⁴
¹ – Substitute the IP address of your OBi.
² – Substitute the value of your OBi's X_UserAgentPort associated with the above SPx.
³ – Substitute whatever you set AuthUserName to above.
⁴ – Remove ,opus if your server does not support this codec.
Create an Outbound Route
No special configurations are required here.
Create an Inbound Route
No special configurations are required here. Use your GV number, the one you substituted for 6145551212 above, as the DID.

Method 2: You have an exposed Asterisk server with an OBi behind a firewall

Notice that the above implementation was done without any registrations. Registrations exist (1) to inform the far end of an endpoint's IP address when it is dynamic, and (2) to circumvent NAT issues. On local LANs, neither is typically a problem and thus registrations are rarely required or desired — you can just code the applicable IPs and Port numbers directly. However, VPSes don't have local LANs — at least not LANs that can do us any good. So, can we use our OBis to provide GV access to VPS PBXes? The answer is again yes, we just need to situate the OBi at a convenient spot on the Internet that we control, and hopefully one "close" (in Internet terms) to the VPS to avoid latency issues.

Here's the tricky part: If the convenient spot of choice is served by a dynamic IP address or located behind a firewall then you'll probably have to resort to using registrations. Normally, we are familiar with registrations in two contexts: (1) registering extensions (our VoIP phones), and (2) registering with ITSPs to gain access to trunks. In this case, however, we are dealing with something rarely encountered — here it's the OBi box (the ITSP) that has the labile IP address, so it needs to register with Asterisk (the client) as opposed to the other way around. Let's see how we can make this happen.

To be honest, I never could make this happen with SIP. I could get as far as answering a ringing phone, but never could get the audio. Hence, I abandoned SIP on the Asterisk server and went with PJsip.

*** Changes to the OBi SIP-side service

Service Providers > ITSP Profile X > SIP > ProxyServer             [Set to the IP addr of your Asterisk server]
Service Providers > ITSP Profile X > SIP > ProxyServerPort         [Set to the PJsip listening port of above server]
Service Providers > ITSP Profile X > SIP > RegistrationPeriod      (not less than 120) ¹
Service Providers > ITSP Profile X > SIP > X_SpoofCallerID         (verify UNchecked, for now)
Service Providers > ITSP Profile X > SIP > X_NoNonceAuth           (check) ¹
Service Providers > ITSP Profile X > General > X_EarlyICEEnableIn  (check) ²

Voice Services > SPx Service > X_ServProvProfile                   [The ITSP profile selected above]
Voice Services > SPx Service > X_InboundCallRoute                  {SPgv}
Voice Services > SPx Service > X_AcceptsSipFromRegistrarOnly       (check) ¹
Voice Services > SPx Service > X_NoRegNoCall                       (check) ¹
Voice Services > SPx Service > AuthUserName                        OBi200 ³
Voice Services > SPx Service > AuthPassword                        (set passwd)
Voice Services > SPx Service > X_EnforceRequestUserID              (verify unchecked)
¹ – Not required, but this setting suggested for additional security and/or efficiency.
² – Must be enabled via the OBi's built-in web server.  Thanks to maxm from dslreports.com for finding this fix for the truncated-ring problem.
³ – Select AuthUserName at your discretion, but it must match Trunk name below.

*** Changes to the OBi GV-side service:

Voice Services > SPgv Service > X_InboundCallRoute                 SPx(6145551212) ¹
¹ – Substitute your GV number for 6145551212.

*** Changes on the Asterisk/FreePBX server:

Note: If you are replacing a Motif trunk on your server, we recommend removing the trunk and Motif entry before adding the PJsip trunk below. Otherwise, unless you are careful, the Motif removal may also remove the newly added PJsip trunk.

Create a PJsip trunk:
Under Connectivity > Trunks > Add Trunk > chan_pjsip
General > Trunk Name                                              [same as AuthUserName above]
General > Outbound CallerID                                       [The Google Voice Number above]
PJsip Settings > General > Secret                                 [same as AuthPassword above]
PJsip Settings > General > Authentication                         (select Inbound)
PJsip Settings > General > Registration                           (select Receive)
PJsip Settings> Codecs                                            ulaw (+ opus if you have it)
Create an Inbound and Outbound route:
(Refer to the Inbound/Outbound documentation above.)


If everything to this point has gone according to plan, you should now be able to call in and out on your new trunk. But, what do you do if your setup doesn't work? Here are some pointers:

Have your Cake and Eat It Too: Passing Inbound CallerID (Method 2):

If you've played around with your new trunk at all, you've probably noticed that it does not pass the proper CallerID. Instead, it substitutes the name of the trunk. This is because we did not set X_SpoofCallerID above. But, unfortunately, our hands are tied, as PJsip relies on the trunk name being passed to match the incoming call to the proper trunk. If we spoof the CallerID, we get a PJsip error and the call never completes. Fortunately, though, there is a way to work around this, and I'm sure you want to know who's calling, so lets make it happen!

It turns out PJsip implements several algorithms for matching an incoming call to a PJsip trunk, but only two (three if you count Anonymous) are activated by default. The first uses the SIP INVITE's IP address, but this doesn't work for us because (among other reasons) our address is dynamic. The second uses the first part of the FROM field of INVITE, the same as what we need to spoof, so this won't work either. However, there is a third option that uses the AUTHENTICATE field of the INVITE, and since we always authenticate our incoming GV calls, this looks like an excellent alternative for us. But, since tha AUTHENTICATE option is not active by default we need to activate it via a PJsip configuration change. Unfortunately, it seems to be beyond the capabilities of FreePBX to accomplish this, so we'll have to modify the Asterisk config files directly.

Insert the following line at the very top of /etc/asterisk/pjsip_custom_post.conf, which up to this point is likely an empty file:
Next, add the following to /etc/asterisk/pjsip.endpoint_custom_post.conf
where the OBi200 above is whatever you named your trunk. Finally, reload PJsip to allow the above changes to take effect:
asterisk -rx "module reload res_pjsip.so"

Don't be surprised if the above reload command produces a few errors from the pjsip.conf file concerning an identify object; they come from the code FreePBX generates and are apparently benign. Now you should be able to go back to your OBi and check X_SpoofCallerID on the SIP-side SPx to allow the original CallerID to be passed to Asterisk.

Optional Enhancements:

One Google Voice Line, Multiple Endpoints

There is no reason why multiple endpoints cannot use the same GV line. Provided you have a remaining unassigned Voice Service, it can be pressed into service as a second SIP-side interface. Just configure it as described above, as if it were the sole user of the GV trunk. In this case it would be prudent to set Maximum Channels so as to avoid overloading the GV channel should both endpoints attempt to use the GV line at the same time.

Of course, incoming calls will be routed according to the GV channel's X_InboundCallRoute (which, incidentally, does not need to be set to one of the outgoing endpoints). Typically, these calls will be routed to only one destination, but here is an example of an X_InboundCallRoute which will ring two endpoints simultaneously and dispatch the call to the first one answered:
X_InboundCallRoute                              {sp3(6145551212),sp4(6145551212)}

Multiple Google Voice Lines, one Asterisk Trunk

In a similar vein, one Asterisk trunk can be made to control all the GV lines assigned to an OBi. You can direct a call to a specific GV line based on several criteria such as the called number, a prefix code, or even the passed CallerID. (Since GV will not pass CallerID, opting instead to always use its own number, this makes the passed CallerID a good candidate for selecting between GV lines.) This post from dslreports, https://www.dslreports.com/forum/r31956002-, describes in greater detail how this is done.
The following route will direct a call to SP1 if the passed CallerID matches 6145551212, else the call will go to SP2:
X_InboundCallRoute                              {6145551212:sp1},{:sp2}

A word about how to configure this in FreePBX: Create the trunk, but make sure that CID Options is set to "Allow Any CID". Then create two or more Outbound Routes, one for each Google Voice instance. Code the applicable GV number in the Route CID field of each Outbound Route, and the check Override Extension "Yes". Now each Outbound Route will pass its CID to the OBi, which will in turn direct the call the the proper GV instance.

Installing the Opus Codec on Asterisk

GVsip uses two codecs, ulaw and opus. While theoretically only ulaw is needed on the SIP side, it's handy to have to have the opus codec on Asterisk so no transcoding is necessary. Unfortunately, all my systems already had opus installed, so these instructions have never been tested in a opus-free environment.

I believe opus is installed by default in Asterisk 14, but must be explicitly built into Asterisk 13. There are two ways to accomplish this: The preferred method is to build and install opus as part of the Asterisk build. However, there is a quick and dirty alternative for Intel-based servers which involves downloading the libraries from Digicom and manually copying them into the Asterisk directories. This latter method worked fine for me. I used the notes from https://gist.github.com/worldadventurer/757bf4b10af2356d83d57a8a6bb3e4e8 to do the install on my system. Just make sure when you are done that you perform an " asterisk -rx 'core show translation' " to verify the codec is indeed loaded and usable.

Other Alternatives:

Although the OBi solution has worked well for me, it is only one of several options available to Asterisk users. With the announced impending demise of Bill Simon's excellent Google Voice Gateway, which was essentially a similar implementation done on a grander scale using commercial hardware, I see the following as potential alternatives:

Final Thoughts and Observations:

The OBi solution for adding Google Voice lines as trunks on an Asterisk system is viable and if OBi20x boxes are already in use as ATAs the additional functionality can often be added to them at no additional hardware cost. The implementation appears robust and, especially if everything resides on the same LAN, adds only minimal latency compared to the existing XMPP solution.

These instructions are designed for and were tested with a FreePBX/Asterisk server. However, they no doubt could be updated to apply to any VoIP PBX, or even providing Google Voice support for the older OBi100 series of devices.

One final caveat: Understand that it was never Google's intent for Google Voice to sub as a provider of free PBX trunks. As we alluded to in the first paragraph, these notes are mainly directed towards hobbyists and experimenters, not professionals running call centers. The OBis may be the equivalent of a Swiss army knife for VoIP interconnections, but that doesn't alter the fact that if you run afoul Google's Terms of Service (aka "The Gospel According to Google, available to only a select few", to paraphrase a recent Bill Simon post), don't be surprised if you find your Google Voice service suspended.