首页 > Linux > Raspberry Pi上搭建和配置RasPBX实现VoIP GSM网关

Raspberry Pi上搭建和配置RasPBX实现VoIP GSM网关

2014年10月2日 LTNS     访问次数 936 发表评论 阅读评论

Raspberry Pi (RPI) 是一款信用卡尺寸大小的、基于 ARM架构的迷你电脑,由英国树莓派基金会组织开发,这里贴二张 B型(售价35美元)的网上图片

RPi-B-CN-set-up

基金会的初衷是以低价硬件和自由软件推动在中小学的基础计算机学科教育,但是自2012年推出以来,却很快得到了全球 Maker们的青睐,基于 RPI开发了各种各样的,如WEB服务器、NAS服务器、多媒体中心、路由器、GPS跟踪器、智能家居控制、GSM基站服务器、咖啡机控制器,等等的应用。

网上介绍过一个开源的 VoIP PBX软件 RasPBX,基于 Raspbian 整合了 Asterisk 和相应的GUI管理界面 FreePBX,可以把 RPI变成一个小型的网络电话交换机,配合 chan_dongle(华为3G U棒的驱动)可实现 GSM VoIP应用,这两天抽空尝试了一下,在此作个记录。

 
准备条件:

1. B型 RPI一块,主要参数如下

CPU: ARM1176JZF-S核心(ARM11系列)700MHz
RAM: 512MB (早期的256MB版本也可以安装 RasPBX)
USB: usb 2.0 数量2个(支持USB hub扩展)
网络接口: 10/100 以太网接口(RJ45接口)
板载存储: SD / MMC / SDIO卡插槽
详见 维基页面


2. Micro-USB接口的电源(RPI随机不带电源),我用5V 1A规格的,网上也有人建议电流至少1.5A;
3. 至少4GB容量的SD卡一张,用作 RPI的存储介质;
4. 兼容 SIP协议的 IP电话机,可用安装了 SIP SoftPhone软件(如 ZoiperCSipSimple等)的智能手机替代;
5. 3G U棒,兼容的型号请参考 RasPBX官网,我用的是华为 E173u-1,按这里的 wiki页面 的说法该型号U棒的芯片是高通的 MSM6290。
aa另外,某宝上卖的 3G U棒一般都是已解锁的,如下图所示,如未解锁可用 DC-unlocker 这款软件,具体用法和注意事项(解锁有风险)请自行网上搜索。
e173_dc-unlocker

网络连接示意图如下
raspbx topology structure

 
烧录 RasPBX启动盘

下载 raspbx镜像文件,目前最新版本 raspbx-31-07-2014.zip(已集成了 Asterisk 11.11.0FreePBX 2.11.0.38),通过烧录工具(如 Win32 Disk Imager)将解压得到的 .img文件写入 SD卡,完成后将 SD卡插入 RPI,用网线连接到路由器,最后插上电源启动。(图片中 RPI的透明塑料外壳是另购的)
RPI_e173-dongle

 
升级 RasPBX系统

这里先要指出一下,因为 RasPBX官网 已被WALL,所以得先想办法比如让路由器能翻WALL上网(具体请自行网上搜索),才能进行后面的操作。

Putty 登录 RPI(默认用户名和密码分别是 rootraspberry),升级系统并安装 chan_dongle

apt-get update
raspbx-upgrade
install-dongle
apt-get install ussd-webpage   #如有需要可安装发送USSD的web页面
#安装完成后关机
shutdown -h now

注:运行 install-dongle的过程中,会遇到如下几个提问:
Please enter the phone number of your SIM card (defaults to +1234567890 if left blank):
输入U棒里的 sim卡手机号码,直接回车则默认为 +1234567890
Send incoming SMS to email address (leave empty to disable SMS forwarding):
设置邮箱,以便将U棒收到的短信内容转发过去,直接回车可取消该功能
Forward incoming SMS to mobile phone number (via dongle0) (leave empty to disable):
设置一个手机号码,以便将U棒收到的短信通过 dongle0 转发至该号码,直接回车可取消该功能
Would you like to install a webpage for sending SMS with chan_dongle? (http://raspbx/sms/) [y/N]
是否安装发送短信的web页面,可回答 y 并按提示设置一个登录密码。

在 U棒里塞入 sim卡,插入 RPI,然后通电启动,顺利的话可在 Asterisk CLI界面(CLI命令用法可参考 这里)读取到相应的参数,下面的示例是从 E173+我的移动2G卡 读取的

root@raspbx:~# asterisk -r   #或者 asterisk -rvvvv 进入调试模式
Asterisk 11.6.0, Copyright (C) 1999 - 2013 Digium, Inc. and others.
Created by Mark Spencer 
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk 11.6.0 currently running on raspbx (pid = 3370)
 
raspbx*CLI> dongle show device state dongle0
-------------- Status -------------
  Device                  : dongle0
  State                   : Free
  Audio                   : /dev/ttyUSB1
  Data                    : /dev/ttyUSB2
  Voice                   : Yes
  SMS                     : Yes
  Manufacturer            : huawei
  Model                   : E173
  Firmware                : 11.126.16.04.00
  IMEI                    : 8*************8
  IMSI                    : 4*************9
  GSM Registration Status : Registered, home network
  RSSI                    : 19, -75 dBm
  Mode                    : GSM/GPRS
  Submode                 : EDGE
  Provider Name           : 139********
  Location area code      : 188A
  Cell ID                 : 6BE1
  Subscriber Number       : +86139********
  SMS Service Center      : +8613800210500
  Use UCS-2 encoding      : Yes
  USSD use 7 bit encoding : Yes
  USSD use UCS-2 decoding : No
  Tasks in queue          : 0
  Commands in queue       : 0
  Call Waiting            : Disabled
  Current device state    : start
  Desired device state    : start
  When change state       : now
  Calls/Channels          : 0
    Active                : 0
    Held                  : 0
    Dialing               : 0
    Alerting              : 0
    Incoming              : 0
    Waiting               : 0
    Releasing             : 0
    Initializing          : 0
 
raspbx*CLI> exit
Asterisk cleanly ending (0).
Executing last minute cleanups

 
FreePBX的设置

接下来在浏览器访问 http://raspbxhttp://RPI的ip地址,点击左侧的“FreePBX Administration”图标(默认用户名和密码都是 admin),进入 FreePBX管理页面
FreePBX_System_Status

点击菜单 Applications > ExtensionsSubmit “Generic SIP Device”,添加 SIP设备211和212(分机号可自定义)
Generic_SIP_Device
注:1. 移动鼠标至各设定项右边的问号会提示相应的设置说明;
aaa2. 提交设置后记得要点击右上角的“Apply Config”按钮以使设置生效;

在智能手机上的 SIP SoftPhone软件里添加 SIP帐号,然后在无线路由器内网的 wifi环境里,SIP分机201和202相互之间就可以拨号通话了。
SIP_account

然后点击菜单 Connectivity > TrunksAdd Custom Trunk,添加自定义的 Trunk,Custom Dial String框中填入“dongle/dongle0/$OUTNUM$
custom_Trunk

添加 Outbound Route,完成后就可以在 SIP分机上拨号“9+外线号码”,即可从 3G U棒里的手机号码拨打出去
Outbound_Routes

添加 Inbound Route生效后,当3G U棒里的手机号码有来电时指定的 SIP分机就会响铃
Inbound_Routes
注:如有第二个 3G U棒,可在 DID Number框中填入 sim卡的手机号码以示区分,号码必须以“+86”开头。

点击菜单 Settings > Asterisk SIP Settings,一般家庭宽带分配的是动态ip,所以还要申请一个动态域名(免费的二级域名如 3322.org花生壳等)
Asterisk_SIP_Settings

还要在路由器上设置一下端口映射
router_RasPBX_NAT

端口映射完成后 SIP分机就可以从路由器的外网连接到 RasPBX的 SIP服务端了,SIP帐号的服务器地址需改成路由器外网ip的动态域名(如xxx.3322.org)。我的路由器使用第三方的 Tomato固件,内置了 3322的DDNS,自动更新外网的动态ip,其他平台请自行参考动态域名服务商的官网(比如 noip.com的免费二级域名,可按照 官网教程 在RPI上安装客户端以自动更新ip)。

 
其他

在 Asterisk CLI界面会自动提示 3G U棒收到的短信内容(存放在 /var/log/asterisk/sms.txt,供事后查阅),中文显示正常,长短信会被自动拆分(不过跨运营商之间的,比如移动发联通,似乎只能收到拆分后的最后一条)。还可以发送短信,不过不支持中文,注意短信接收人的号码必须以“+86”开头(类似10010之类的客服号码则不必)。

root@raspbx:~# asterisk -r
raspbx*CLI> core show help dongle   #显示 dongle命令的帮助说明
raspbx*CLI> dongle sms dongle0 +8618699999999 Hello from RasPBX!
raspbx*CLI> exit
root@raspbx:~# cat /var/log/asterisk/sms.txt

如果在前面升级 RasPBX的过程中安装了web页面,在浏览器中访问 http://raspbx/sms 可进入短信发送页面(http://raspbx/ussd 为USSD发送页面),发送中文短信会乱码。

注:修改 /var/www/html/sms/index.php文件,把其中的编码 ISO-8859-1改成 utf-8,重启后发送中文短信就正常了。

如果在前面升级 RasPBX的过程中还设置过接收的短信自动转发邮件的话,则短信内容存放在 /tmp/sms.txt文件中(不过只有最近的一条)。另外,还设置过接收的短信自动转发另一个手机号码的话,对方手机倒是能正常显示中文字符,不过有个bug,即,截止到第一个半角字符后面的内容会丢失。

顺便贴出 /etc/asterisk/extensions_custom.conf文件里的 dialplan,供参考

[from-trunk-dongle]
exten => sms,1,Verbose(Incoming SMS from ${CALLERID(num)} ${BASE64_DECODE(${SMS_BASE64})})
exten => sms,n,System(echo "To: xxx@gmail.com\nSubject: Incoming SMS from ${CALLERID(num)} to ${OUTCID_1}\n\n${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLENAME} - ${CALLERID(num)}: " > /tmp/sms.txt)
exten => sms,n,Set(FILE(/tmp/sms.txt,,,a)=${BASE64_DECODE(${SMS_BASE64})})
exten => sms,n,System(sendmail -t < /tmp/sms.txt)
;exten => sms,n,DongleSendSMS(dongle0,+8618699999999,${BASE64_DECODE(${SMS_BASE64})} - from ${CALLERID(num)})
exten => sms,n,Hangup()
exten => _.,1,Set(CALLERID(name)=${CALLERID(num)})
exten => _.,n,Goto(from-trunk,${EXTEN},1)

注:如经常更换 3G U棒里的 sim卡,可像如上 dialplan那样在邮件标题中添加 OUTCID_*变量(对应 Trunks设置里的手机号码,具体变量名可在 /etc/asterisk/extensions_additional.conf 文件里查看),以便得知收到的短信是发给哪个号码的。

 
最后,完工后建议用烧录工具(如 Win32 Disk Imager)备份一下 SD卡,或者按照 RasPBX官网教程 实时备份和更新 SD卡系统的镜像文件(还需要一个不小于4G容量的U盘)。因为SD卡这类存储介质还是比较脆弱的,不正常关机(比如意外停电)可能导致SD卡无法引导启动 PRI。

 
可能会遇到的问题

问题1:在 FreePBX管理页面的右下角的 Server Status区域可能会显示 Asterisk ERROR 或 Web Server ERROR
一般多是系统时间出错导致的问题(请用 date命令检查一下是否日期变成了 1970年的),用 WinSCP登录 RPI,把 /usr/local/sbin/amportal_delaye文件中的如下四行注释掉

#while [ `/bin/date +%s` -lt $MIN_START_TIME ]
#do
#  sleep 10
#done

重启 RPI后如果还没有效果,则修改一下 /etc/ntp.conf这个配置文件,替换掉其中的 ntp server

#server 0.debian.pool.ntp.org iburst
server ntp服务器地址 iburst

修改完成后重启一下 RPI的 ntp服务

service ntp restart

 
问题2:第一次使用正常(之后重启也正常),但RPI重新上电后,3G U棒的连接会丢失

正常情形下应该会有三个 ttyUSB*文件

root@pbx:~ $ ls /dev/ttyUSB*
/dev/ttyUSB0  /dev/ttyUSB1  /dev/ttyUSB2

但实际上找不到 ttyUSB*,同时在 Asterisk CLI界面会不断提示出错“chan_dongle.c:218 opentty: unable to open /dev/ttyUSB2: No such file or directory”,这时候如果插拔U棒一到二次就能恢复正常。

经网上搜索,找到一篇 文章,得知 3G U棒有两种工作模式,cdrom和modem,默认是前者(所以U棒插入Win系统电脑时会自动安装3G上网软件),解决办法就是在每次 RPI启动时用 usb_modeswitch(RasPBX已内置了该软件)修改一下 3G U棒的工作模式。

新建一个 E173的配置文件 /etc/usb_modeswitch.d/e173.conf,内容如下

########################################################
# Huawei, newer modems

DefaultVendor= 0x12d1
DefaultProduct=0x1446

TargetVendor=  0x12d1
TargetProduct= 0x1436

CheckSuccess=20

MessageContent="55534243123456780000000000000011062000000100000000000000000000"

注:其他型号的 3G U棒的配置文件可参考 USB_ModeSwitch官网 的device_reference.txt文件内容。

修改 E173的工作模式

root@raspbx:~# usb_modeswitch -I -W -c /etc/usb_modeswitch.d/e173.conf

注:这时 E173应该就自动接通了,然后把这一行添加到 /etc/rc.local文件中,exit 0的那一行之前即可。

另外,用 usb-deviceslsusb命令可以看到修改前后的变化

#修改模式之前
root@raspbx:~# usb-devices
T:  Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#=  4 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=12d1 ProdID=1446 Rev=00.00
S:  Manufacturer=HUAWEI Technology
S:  Product=HUAWEI Mobile
C:  #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none)
I:  If#= 1 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
 
root@raspbx:~# apt-get install usbutils   #安装 lsusb
root@raspbx:~# lsusb
Bus 001 Device 005: ID 12d1:1446 Huawei Technologies Co., Ltd.
 
#之后
root@raspbx:~# usb-devices
T:  Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#=  5 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=12d1 ProdID=1436 Rev=00.00
S:  Manufacturer=HUAWEI Technology
S:  Product=HUAWEI Mobile
C:  #Ifs= 7 Cfg#= 1 Atr=e0 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 1 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=ff Driver=cdc_ether
I:  If#= 2 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether
I:  If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 5 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
I:  If#= 6 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
 
root@raspbx:~# lsusb
Bus 001 Device 005: ID 12d1:1436 Huawei Technologies Co., Ltd.

这里 还有一个更简单的方法,即,用Putty 连接 3G U棒的串口,然后用 AT命令把U棒默认的 cdrom模式改为modem模式(相关的 AT命令也可参考 这里,建议修改前先记下 AT^U2DIAG? 命令反馈的数字,以便将来可能改回cdrom模式,另外,输入的AT命令默认在屏幕上不显示,请小心键入命令!),不过平时经常要把3G U棒插到电脑上网用的话不推荐这个方法。

 
补充1:
有篇文章 提及 RPI的usb接口可能供电不足导致3G U棒工作不正常,需要把 U棒改接到有独立供电的 USB HUB
cambodia_raspbx_setup
注:不过我还没遇到过这个问题,按照 这里 的说法,RPI的usb供电能力跟版本有关,我的RPI revision number是 000f。

另外,这篇文章用了两套 RasPBX,利用互联网实现了两个国家的移动运营商之间的GSM VoIP应用,任何一个运营商手机号码接收到的来电,同时会从另一个运营商的手机号码那里拨打出去,这样打电话给你的人并不知道其实你已经身在异国,而且你也不需要在手机上安装 SIP SoftPhone软件(以便通过移动互联网连接到另一国的 RasPBX),适合你在异国手机无法上网的情形。
architecture_01

 

补充2:
据说 SIP分机使用 TCP端口比 UDP更省电,另外,Asterisk 的专用协议 IAX通话效果好于 SIP,详见 Asterisk修改SIP端口为TCP以及设置IAX分机

顺便提一下,RPI通电未开机时的电流小于0.2A@5VDC,运行时不到0.5A,E173打电话时 RPI的峰值约0.8A。

 
 

参考文章
1. http://www.raspberry-asterisk.org/documentation/
2. http://sourceforge.net/p/raspbx/discussion/tutorials/thread/6a57b991/
3. http://www.framboise314.fr/decouvrez-la-framboise314-allo-un-pabx-asterisk-dans-votre-raspberry-pi-partie-1/
 

  1. 有问题请教
    2015年5月12日16:34 | #1

    你好,我想问一下,有的家里本身就是内网nat网络接入的,花生壳是映射不到的,怎么解决呢?还有根据这个教程做了两套以后需要联通,怎么设置呢?

  2. LTNS
    2015年5月13日23:34 | #2

    @有问题请教
    可以购买花生棒,其实就是通过花生壳公司提供的公网服务器中转,不过有流量和端口数量的限制(当然可以花钱升级);或者购买带有公网ip的VPS然后自己搭建相关转发服务应该也可以。

    另,两套VoIP GSM网关相互之间需要联通,可参考这篇文章
    http://blog.ltns.info/linux/two_gsm_voip_gateway_voice_roaming/

  3. jht
    2015年6月13日16:22 | #3

    大大你好,我正需要这方面的技术,很幸运看到您写的文章,我还有一些问题想请教您,可否通过邮件联系您?

  4. LTNS
    2015年6月22日10:01 | #4

    @jht
    可以,info(a)ltns.info。不过最好还是留言,这样可能对其他人也有帮助

  5. 2015年7月15日21:35 | #5

    我的安装后两个SIP软件,局域网和手机3G流量通话,音质有类似播放VCD光盘脏了那种卡顿声和哇哇的轻微变声,还像有些播放器播放不匹配码率的MP3歌曲一样,有哇音、卡卡的。
    这是什么原因?编码方式不匹配?
    请问如何解决?谢谢!

  6. 2015年7月15日21:37 | #6

    esun :
    我的安装后两个SIP软件,局域网和手机3G流量通话,音质有类似播放VCD光盘脏了那种卡顿声和哇哇的轻微变声,还像有些播放器播放不匹配码率的MP3歌曲一样,有哇音、卡卡的。
    这是什么原因?编码方式不匹配?
    请问如何解决?谢谢!

    映射了3322.net,局域网--局域网、局域网--联通3G流量之间通话都同样存在这种声音问题

  7. andy
    2015年12月22日05:29 | #7

    你好,请问raspbx支不支持两条3G棒同时用?
    我在dongle.conf文件里添加了dongle1
    [dongle1]
    audio=/dev/ttyUSB5 ; tty port for audio connection; no default value
    data=/dev/ttyUSB4 ; tty port for AT commands; no default value
    data端口4是测试过可以用它来上网的。
    但是在控制台看到就是不能用
    root@raspbx:~# asterisk -r
    Asterisk 11.20.0, Copyright (C) 1999 - 2013 Digium, Inc. and others.
    Created by Mark Spencer
    Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
    This is free software, with components licensed under the GNU General Public
    License version 2 and other licenses; you are welcome to redistribute it under
    certain conditions. Type 'core show license' for details.
    =========================================================================
    Connected to Asterisk 11.20.0 currently running on raspbx (pid = 8845)
    [2015-12-22 13:16:55] ERROR[12335]: chan_dongle.c:436 do_monitor_phone: [dongle1] timedout while waiting 'OK' in response to 'AT'
    raspbx*CLI> dongle show devices
    ID Group State RSSI Mode Submode Provider Name Model Firmware IMEI IMSI Number
    dongle0 0 Free 21 0 0 FFFFFFFFFFFFFF K3715 11.104.05.00.00 353435024650013 460019672224390 Unknown
    dongle1 0 Not connec 0 0 0 NONE Unknown
    [2015-12-22 13:17:10] ERROR[12362]: chan_dongle.c:436 do_monitor_phone: [dongle1] timedout while waiting 'OK' in response to 'AT'
    raspbx*CLI>
    请问是什么原因?

  8. LTNS
    2015年12月22日12:43 | #8

    @andy
    没试过两个3G U棒同时用,按理应该可行,不过可能RPI usb供电不够,请外接独立供电的usb hub再试试

  9. 2016年1月13日14:36 | #9

    Hi 博主, 请问这个对树莓派的版本有限制吗? 比如说现在的二代B+,能支持吗?

  10. 2016年1月14日02:25 | #10

    好文章,我弄了一个放在VPS上的FreePBX。加上上级落地电话的SIP服务。每分钟2分钱也是蛮划算的。

  11. allankliu
    2016年1月19日08:34 | #11

    现在有个项目,从手机蓝牙HFP取出双向语音,并保持与远程服务器的双向通讯。不知道使用Asterisk可以完成此目的么?

    从手机HFP->音频输入->SW?->TCP->SW->音频输出放大
    手机HFP<-音频输出<-SW?<-TCP<-SW<-音频输入

    可以看到这个需求只有TCP通道可能采用PCM编码,但是我倒是不清楚Asterisk是否可以用于此目的?

  12. LTNS
    2016年2月2日13:52 | #12

    @Richie

    http://www.raspberry-asterisk.org/downloads/

    Since the last image posted on 31/07/2014 these fixes and improvements have been made:
    Including support for Pi 2, B+, B and A models
    ...

  13. LTNS
    2016年2月2日14:03 | #13

    @esun

    换个sip软件试试

  14. 2016年6月14日10:50 | #14

    亲,FreePBX已经13版了,设置方面跟此文有很多不同,能不能劳烦一下,做一个最新的设置使用教程啊!
    我已经跟据你的方法,安装好系统了,但是进入网页不会设置使用O!O

  15. LTNS
    2016年7月20日16:55 | #15

    @bozhi
    抱歉,手上的RPI很久没用了,3G U棒也不在手边,而且最近很忙,等过段时间再折腾了。

  16. hero
    2017年5月13日01:20 | #16

    apt-get update被墙了,无法做raspbx-upgrade , install-dongle 这2部,我该怎么做,烦了我几天了

  1. 2014年10月7日21:46 | #1
30 - 6 = (必填)