在树莓派上搭建GSM语音网关:FreePBX + Quectel EC20 实战踩坑笔记
系统环境:Raspberry Pi 5 + RasPBX + FreePBX 17 + Asterisk 22.3.0 + Quectel EC20
一、项目背景
本项目旨在通过树莓派搭建一个可以处理 GSM 语音 + 短信 + USSD 的本地语音网关。依托 FreePBX 提供友好的 Web GUI 配置界面,结合 chan_quectel
驱动对 Quectel EC20 进行底层接入,实现灵活的电话进出、短信接收记录、USSD 执行等功能。
二、基础环境搭建
1. 系统准备
- 使用树莓派 5,安装 RasPBX 镜像(集成 FreePBX + Asterisk)
- 更新系统、安装基础开发工具:
sudo apt update && sudo apt install build-essential git asterisk-dev libsqlite3-dev autotools-dev
三、驱动与模块安装
1. 编译 chan_quectel
遇到如下问题:
aclocal not found
、autoconf not found
等:需提前安装autotools
sqlite3 library missing
:需安装libsqlite3-dev
snd_pcm_open failed
:系统未正确识别 USB 音频设备- 需使用
aplay -l
查看 alsa 音频设备编号,正确配置alsadev=hw:2,0
最终 chan_quectel.conf
设置如下:
[quectel0]
audio=/dev/ttyUSB1
data=/dev/quectel-at
quec_uac=1
alsadev=hw:2,0
context=from-trunk
四、FreePBX 配置流程
1. 创建 Trunk
- 类型:
Add Custom Trunk
- Trunk 名:
Quectel_GSM
- Dial String:
Quectel/quectel0/$OUTNUM$
- 注意:由于为自定义 Trunk,请在
/etc/asterisk/chan_quectel.conf
手动设置context=from-trunk
2. 出站设置(Outbound Route)
- Route 名:
To-GSM
- Dial Pattern:填
X.
或具体模式(如9|.
) - Trunk Sequence:选择
Quectel_GSM
3. 分机(Extensions)
- 依次添加
PJSIP
分机(如 1001,1002) - 使用 Zoiper 等软电话绑定测试
五、Ring Group 设置
- Ring Group 编号:如
700
- 添加成员:如
1001
,1002
,1003
- 策略:
ringall
,谁先接谁接通
将 Trunk 呼入的 Default Destination 设为 700
,实现全员同时振铃。
六、短信和 USSD 支持
1. 自定义 Dialplan 配置
位于 /etc/asterisk/extensions_custom.conf
:
[from-trunk-custom]
exten => sms,1,Verbose(Incoming SMS from ${CALLERID(num)}: ${BASE64_DECODE(${SMS_BASE64})})
same => n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${CALLERID(num)}: ${BASE64_DECODE(${SMS_BASE64})}' >> /var/log/asterisk/sms.txt)
same => n,Hangup()
exten => ussd,1,Verbose(Incoming USSD: ${BASE64_DECODE(${USSD_BASE64})})
same => n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - USSD: ${BASE64_DECODE(${USSD_BASE64})}' >> /var/log/asterisk/ussd/ussd.txt)
same => n,Hangup()
并确保 chan_quectel.conf
中的 context=from-trunk-custom
。
七、常见问题与解决方案
1. 短信乱码
- 确保日志文件用 UTF-8 编码,在 Windows 中打开建议使用 Notepad++ 或 VSCode。
- Linux 下使用
iconv
检查编码。
2. 短信被误识别为来电
- 通常是 context 配置不一致,应分离短信和语音处理逻辑。
- 在
extensions_custom.conf
中 不要定义_X.
或s
的处理逻辑,否则可能误转语音路径。
3. 呼叫提示通话中
- 出现
invalid extension
通常为context
错误或extensions_custom.conf
中未处理来电。 - 确保 GUI 接管语音逻辑,将通话逻辑放置在 GUI Trunk Routing 中。
八、最终系统逻辑
功能 | 托管方式 | 配置入口 |
---|---|---|
出/入语音 | FreePBX GUI | Trunks / Routes / RingGroup |
短信记录 | extensions_custom.conf | from-trunk-custom |
USSD 执行 | extensions_custom.conf | from-trunk-custom |
九、后续建议
- 使用 mailx 或 sendmail 实现短信转邮箱功能
- 使用 SQLite 或 Web 前端可视化短信内容
- 多端扩展使用 Gammu SMSD 或其他 API 平台对接
十、附录:日志路径
/var/log/asterisk/sms.txt
/var/log/asterisk/unread_sms/
/var/log/asterisk/ussd/
感谢阅读,若有问题欢迎评论交流。