GSM bridge using two freepbx servers, please help (reward in icecream!)

Hello all,

I’m trying to setup a GSM gateway just like described in this non-technical post – http://www.raspberrypi.org/raspberry-pi-gsm-gateway/

What I have is:

  • Two fully functional raspbx servers one in Brazil(dongle1/server1) and another in Germany(dongle2/server2).
  • Both servers are configured with different local gsm dongles and are able to make and receive calls.
  • Both servers are visible to each other through a properly configured VPN.

What I want:

  • To call the dongle1, route the call from server1 to server2, exit on dongle2 and call a specific number. Basically, if someone calls my number in Brazil (dongle1), the call will be routed to server2 and it will call my mobile using dongle2 as exit point.

What I don’t know:

  • How to connect both servers together.
  • And properly route the call in order to behave like described above.

Any help is welcome :smile:
(and will be very well rewarded with ice cream)

1 Like

http://wiki.freepbx.org/pages/viewpage.action?pageId=4161588

1 Like

Nice, so with that guide I was able to create an IAX2 channel between my servers but I can’t really route inbound GSM to an IAX2 trunk. Here is the log when I try to call my dongle:

(I replaced my actual dongle1 number by XXXX)

    -- Executing [XXXXXXXXXXXXXX@from-trunk-dongle:1] Set("Dongle/dongle1-0100000000", "CALLERID(name)=") in new stack
    -- Executing [XXXXXXXXXXXXXX@from-trunk-dongle:2] Goto("Dongle/dongle1-0100000000", "from-trunk,XXXXXXXXXXXXXX,1") in new stack
    -- Goto (from-trunk,XXXXXXXXXXXXXX,1)
    -- Executing [XXXXXXXXXXXXXX@from-trunk:1] Set("Dongle/dongle1-0100000000", "__FROM_DID=XXXXXXXXXXXXXX") in new stack
    -- Executing [XXXXXXXXXXXXXX@from-trunk:2] Gosub("Dongle/dongle1-0100000000", "app-blacklist-check,s,1()") in new stack
    -- Executing [s@app-blacklist-check:1] GotoIf("Dongle/dongle1-0100000000", "0?blacklisted") in new stack
    -- Executing [s@app-blacklist-check:2] Set("Dongle/dongle1-0100000000", "CALLED_BLACKLIST=1") in new stack
    -- Executing [s@app-blacklist-check:3] Return("Dongle/dongle1-0100000000", "") in new stack
    -- Executing [XXXXXXXXXXXXXX@from-trunk:3] Set("Dongle/dongle1-0100000000", "CDR(did)=XXXXXXXXXXXXXX") in new stack
    -- Executing [XXXXXXXXXXXXXX@from-trunk:4] ExecIf("Dongle/dongle1-0100000000", "1 ?Set(CALLERID(name)=)") in new stack
    -- Executing [XXXXXXXXXXXXXX@from-trunk:5] Set("Dongle/dongle1-0100000000", "CHANNEL(musicclass)=default") in new stack
    -- Executing [XXXXXXXXXXXXXX@from-trunk:6] Set("Dongle/dongle1-0100000000", "__MOHCLASS=default") in new stack
[2014-11-11 12:10:35] WARNING[18256][C-00000000]: func_callerid.c:910 callerpres_read: CALLERPRES is deprecated.  Use CALLERID(name-pres) or CALLERID(num-pres) instead.
    -- Executing [XXXXXXXXXXXXXX@from-trunk:7] Set("Dongle/dongle1-0100000000", "__CALLINGPRES_SV=allowed_not_screened") in new stack
    -- Executing [XXXXXXXXXXXXXX@from-trunk:8] Set("Dongle/dongle1-0100000000", "CALLERPRES()=allowed_not_screened") in new stack
    -- Executing [XXXXXXXXXXXXXX@from-trunk:9] Goto("Dongle/dongle1-0100000000", "ext-trunk,4,1") in new stack
    -- Goto (ext-trunk,4,1)
    -- Executing [4@ext-trunk:1] Set("Dongle/dongle1-0100000000", "TDIAL_STRING=IAX2/casa-berlim") in new stack
    -- Executing [4@ext-trunk:2] Set("Dongle/dongle1-0100000000", "DIAL_TRUNK=4") in new stack
    -- Executing [4@ext-trunk:3] Goto("Dongle/dongle1-0100000000", "ext-trunk,tdial,1") in new stack
    -- Goto (ext-trunk,tdial,1)
    -- Executing [tdial@ext-trunk:1] Set("Dongle/dongle1-0100000000", "OUTBOUND_GROUP=OUT_4") in new stack
    -- Executing [tdial@ext-trunk:2] GotoIf("Dongle/dongle1-0100000000", "1?nomax") in new stack
    -- Goto (ext-trunk,tdial,4)
    -- Executing [tdial@ext-trunk:4] ExecIf("Dongle/dongle1-0100000000", "1?Set(CALLERPRES()=allowed_not_screened)") in new stack
    -- Executing [tdial@ext-trunk:5] Set("Dongle/dongle1-0100000000", "DIAL_NUMBER=XXXXXXXXXXXXXX") in new stack
    -- Executing [tdial@ext-trunk:6] GosubIf("Dongle/dongle1-0100000000", "1?sub-flp-4,s,1()") in new stack
    -- Executing [s@sub-flp-4:1] ExecIf("Dongle/dongle1-0100000000", "1?Return()") in new stack
    -- Executing [tdial@ext-trunk:7] Set("Dongle/dongle1-0100000000", "OUTNUM=XXXXXXXXXXXXXX") in new stack
    -- Executing [tdial@ext-trunk:8] Set("Dongle/dongle1-0100000000", "DIAL_TRUNK_OPTIONS=") in new stack
    -- Executing [tdial@ext-trunk:9] Dial("Dongle/dongle1-0100000000", "IAX2/casa-berlim/XXXXXXXXXXXXXX,300,") in new stack
    -- Called IAX2/casa-berlim/XXXXXXXXXXXXXX
[2014-11-11 12:10:37] WARNING[18256][C-00000000]: channel.c:1002 channel_indicate: [Dongle/dongle1-0100000000] Don't know how to indicate condition 33
    -- Hungup 'IAX2/casa-berlim-17725'
  == Everyone is busy/congested at this time (1:0/0/1)
    -- Executing [tdial@ext-trunk:10] Set("Dongle/dongle1-0100000000", "CALLERID(number)=") in new stack
    -- Executing [tdial@ext-trunk:11] Set("Dongle/dongle1-0100000000", "CALLERID(name)=") in new stack
    -- Executing [tdial@ext-trunk:12] Hangup("Dongle/dongle1-0100000000", "") in new stack
  == Spawn extension (ext-trunk, tdial, 12) exited non-zero on 'Dongle/dongle1-0100000000'

OK, so I managed to solve it myself :slight_smile: Here is the full explanation on how everything works. But if you want to leave a comment on the original blog post I wrote, here is the link – http://bit.ly/gsm-bridge

Description of the environment: The server1 is placed on the Brazilian side. It’s a Raspberry Pi model B that runs an asterisk-modded-for-raspberry-pi distro called raspbx. Attached to it there’s an USB GSM dongle with a SIM card for the local Brazilian operator. In the same network of my server1 there’s a Cisco PAP2t Internet Phone Adapter and, attached to it, a regular land line telephone. The same setup is duplicated on the German side, except that the Raspberry Pi is model B+.



What it does: As I said, this is just for fun and proof of concept. So all the functionalities are both awesome but kind of useless (given the amount of voip options we have). This being said, this is the list of features that this project performs right now:

  1. Someone in Brazil calls my Brazilian number, the dongle1 answers the call, redirects to an IAX2 trunk directly to server2. The server2 takes this incoming call and uses the dongle2 to place a new call to my german cellphone. The other way is still pinned to a single phone -- like, call my dongle2 to reach a single number in Brazilian side -- but improvements are coming.
  2. Someone uses phone1 on Brazilian side to call extension phone2 on German side (and vice-versa) like a regular landline phone.
  3. Someone uses phone1 or phone2 to reach my german cellphone.

I'm gonna skip the PAP2t configuration because I think it's too much. This is only needed if you want to use land line telephones, it's not required for the GSM bridge. If anyone is interested in doing that, please leave a comment and I'll write a new post only for that configuration.

Important note: All the configuration explained from now on is identical on both servers.
  1. Install raspbx on your RPi's SD card. Also take a time to read through the raspbx documentation, which is very useful)
  2. Use the script install-dongle (built-in inside raspbx) to install your dongle on your RPi. Important notes regarding problems I got:
    1. There's a list of GSM dongles that are tested with voice, SMS and USSD. I bought the Huawei E160.
    2. Plug your dongle and only after that plug your RPi power. If you try to plug your dongle while the RPi turned on, you may experience your RPi to reboot due to power consumption failures
    3. If your RPi starts rebooting it's because it can't handle the gsm dongle power consumption, in this case, use a proper powered USB hub. I bought the D-Link Dub-H7
    4. Find out the IMEI and the IMSI code of your dongle and set the correct values under /etc/asterisk/dongle.conf because /dev/ttyUSB1 or /dev/ttyUSB2 may change.
  3. Before you start configuring raspbx itself, it's important that you have both sides with network configured properly with static IPs and (in my case) DynDNS. I didn't want to open too many ports on the routers on both sides so I just setup an OpenVPN
  4. Setup a new custom trunk for your dongle under Connectivity  Trunks  Add Custom Trunk and set these values:

    Trunk Name: to-my-cellphone
    Outbound CallerID: Your SIM card number with country code (with a plus sign at the beginning)
    Custom Dial String: dongle/dongle0/

    Note: This is the trunk that will actually place the inbound calls to your personal telephone.

  5. Setup a new IAX2 trunk under Connectivity  Trunks  Add IAX2 Trunk and set these values:

    General Settings:
    Trunk Name: Something that would remember the incoming connection from the other server
    Outbound CallerID: Your personal phone number

    Outgoing Settings:
    Trunk Name: (same as above, I also used the same name and it's ok)

    host=static IP under vpn
    username=any username
    secret=any password
    type=friend
    trunk=yes
    qualify=yes
    qualifyfreqok=25000
    tos=0x18

    Note: The IAX2 trunk is responsible for redirecting calls from this server to the other.
  6. Setup a new inbound route under Connectivity  Inbound Routes → Add Incoming Route:

    DID Number: Your SIM card number with country code (with a plus sign at the beginning)
    CallerID Number: Your personal cell phone number
    Set Destinations: Trunk and your recently created IAX2 trunk.

    Note: This is the route responsible to redirect an inbound call on your local dongle over the IAX2 trunk and then to your remote server.
If you noticed any omitted fields in the above configurations, it's because I didn't fill with anything or it's not important. I also did some extra work on Claning the SIM card memory for SMS every once in a while, I set a static IP for the OpenVPN so each server can always see each other, an additional service to check my credit balance every month and so and so forth. If you also want details like that please let me know in the comments :-) 
That's it! You did it! If you need more help setting up anything else please let me know in the comments of this post. Good luck and have fun! :-)