EC20模块使用asterisk及freepbx实现短信转发和网络电话
侧边栏壁纸
  • 累计撰写 85 篇文章
  • 累计收到 2 条评论

EC20模块使用asterisk及freepbx实现短信转发和网络电话

记忆の风
2025-06-23 / 0 评论 / 288 阅读 / 正在检测是否收录...
前提

EC20型号:EC20CEFAG-512-SGNS(mini-pcie接口)

额外配件:
1、4G模块转接板Mini PCIE转USB的卡座,卡座上有插SIM的地方
2、若干根IPEX转SMA转接线
3、SMA接口的4G天线

服务器:最好是虚拟机系统,如:exsi或者PVE。
1、部署ubuntu18.04虚拟机
2、安装Asterisk 16.23
3、安装Freepbx 16或者17

正题

1、PVE系统下检查EC20模块

1、打开PVE系统,使用shell进入。
关闭SIM卡的PIN,插入卡座,把EC20接上天线并通电,使用以下命令,查询EC20模块的usb端口

ls /dev/ttyUSB*
ttyUSB0
ttyUSB1 PCM语音,GPS信号
ttyUSB2 控制命令
ttyUSB3

安装picocom或者minicom软件与EC20模块进行通信

apt install picocom

或者

apt install minicom

命令如下

picocom -b 115200 /dev/ttyUSB2
或者
minicom -D /dev/ttyUSB2

输入ATI看一下EC20的版本号:

ATI
Quectel
EC20F
Revision: EC20CEFAGR08A03M4G

非必要:如果一切正常的话,可以先重置一遍EC20,以防上一个用户在卡内设置了错误的配置(但不要经常重置EC20,重置操作对dongle的闪存有损耗)。

重置模块

at+qprtpara=3

重启

AT+CFUN=1,1

重置并重启完后,可以通过以下命令检查一下SIM卡是否已经注册成功了(下面的例子是联通的,其他运营商同理):

AT+COPS? 
+COPS: 0,0,"CHN-UNICOM",7

AT+QNWINFO
+QNWINFO: "FDD LTE","46001","LTE BAND 3",1650

AT+QENG="servingcell"
+QENG: "servingcell","CONNECT","LTE","FDD",460,01

注:电信3g已拆除,只有打开4g volte才能查看到楼上数据,so电信卡需要先配置VOLET,不然是没信号的。

配置VoLTE

打开ims AT+QCFG="ims",1

查看dongle内的mbn文件 AT+QMBNCFG="List"
+QMBNCFG: "List",0,1,1,"ROW_Generic_3GPP",0x05010824,201806201
+QMBNCFG: "List",1,0,0,"OpenMkt-Commercial-CU",0x05011510,201911151
+QMBNCFG: "List",2,0,0,"OpenMkt-Commercial-CT",0x0501131C,201911141
+QMBNCFG: "List",3,0,0,"Volte_OpenMkt-Commercial-CMCC",0x05012011,201904261

# 尽管这里列出了移动联通电信的VoLTE配置文件,但使用默认的自动选择CU/CT/CMCC并不能注册VoLTE,需要强制选择ROW_Generic_3GPP才能成功注册VoLTE。

关闭自动选择mbn文件 AT+QMBNCFG="AutoSel",0
反激活当前的mbn at+qmbncfg="deactivate"

强制选择3gpp AT+QMBNCFG="select","ROW_Generic_3GPP"
重启 AT+CFUN=1,1

可以再确认一下mbn的选择状态,如果ROW_Generic_3GPP的第二位和第三位都是1的话,说明dongle目前选择了这个配置 AT+QMBNCFG="List"
+QMBNCFG: "List",0,1,1,"ROW_Generic_3GPP",0x05010824,201806201
+QMBNCFG: "List",1,0,0,"OpenMkt-Commercial-CU",0x05011510,201911151
+QMBNCFG: "List",2,0,0,"OpenMkt-Commercial-CT",0x0501131C,201911141
+QMBNCFG: "List",3,0,0,"Volte_OpenMkt-Commercial-CMCC",0x05012011,201904261

重启完后检查ims的状态 AT+QCFG="ims"

如果返回的是 +QCFG: "ims",1,1 即为激活,如果是+QCFG: "ims",1,0 说明没有激活

可选(激活UAC数字音频),最好打开

在模块上启用 UAC,这是一个一次性设置,将在重启后继续有效

AT+QCFG="USBCFG"

如果未启用 UAC,将收到响应
“+QCFG:“usbcfg”,0x2C7C,0x0125,1,1,1,1,1,0,0”

请注意,产品代码后应有 7 位数字,可以是 1 或 0。最后一位是 UAC 参数,如果参数少于 7 位,则表示设备不支持 UAC。现在复制整个字符串,并将最后一位改为 1,然后发出新的命令。

AT+QCFG="USBCFG",0x2C7C,0x0125,1,1,1,1,1,0,1

现在 UAC 将启用。然后(按下 Ctrl-A,然后按 X,选择 Yes 退出 minicom)

在ubuntu终端下输入

aplay -L

应该会向您显示一个新的声音设备,如

hw:CARD=Android,DEV=0
Android, USB Audio

使用新的 quectel.conf 文件,取消注释并设置 quec_uac=1,同时取消注释 alsadevice 行(以下步骤会复制/uac/quectel.conf过去,所以这步可以跳过)

2、安装asterisk虚拟机

安装asterisk和一些依赖

首先更新系统并安装必要的依赖包:

apt update && apt upgrade -y
apt install -y wget build-essential subversion libedit-dev libjansson-dev libssl-dev libxml2-dev libncurses5-dev uuid-dev

(1)下载并安装稳定的 Asterisk 16

wget https://github.com/asterisk/asterisk/archive/refs/heads/16.23.zip
unzip 16.23.zip
cd asterisk-16.23

(2)运行 Asterisk 提供的依赖安装脚本:

contrib/scripts/install_prereq install

(以下命令时,它可能会提示输入国家电话代码,您可以提供您想要的内容。此脚本会自动安装缺失的依赖项,如 libpjproject)

(3)配置与编译

./configure

错误提示

Downloading https://raw.githubusercontent.com/asterisk/third-party/master/pjproject/2.10/pjproject-2.10.tar.bz2 to /tmp/pjproject-2.10.tar.bz2

目前没有直接从githubusercontent下载,可以搜索githubusercontent加速,把raw.githubusercontent.com进行替换。替换后先进行下载

手动下载 pjproject

进入到/tmp(读取是在这个文件夹)

cd /tmp

wget https://加速站替换地址/asterisk/third-party/master/pjproject/2.10/pjproject-2.10.tar.bz2 to /tmp/pjproject-2.10.tar.bz2

然后重新运行 configure

./configure --with-pjproject=/tmp/pjproject-2.10.tar.bz2

验证安装

成功配置后你应该能看到:

checking for PJPROJECT... yes

接着再进行编译

make
make install
make config
cp configs/samples/. /etc/asterisk
cd /etc/asterisk
find . -name "*.sample" -exec sh -c 'mv "$1" "${1%.sample}"' _ {} \;

设置 chan_quectel

cd
wget https://github.com/IchthysMaranatha/asterisk-chan-quectel/archive/refs/heads/master.zip
unzip master.zip
cd asterisk-chan-quectel-master
./bootstrap
./configure --with-astversion=16.23
make
make install

现在使用 将 quectel.conf 复制到 /etc/asterisk

cp uar/quectel.conf /etc/asterisk

确保在 quectel.conf 中为您的设备正确设置了音频端口(前面已经进行设置了)

重启asterisk

systemctl restart asterisk

进入asterisk的cli界面

asterisk -rvvv

输入

quectel show devices

即可看到识别到的dongle了,也能看到dongle的imei和SIM卡的imsi:

# asterisk -rvvv
Asterisk 16.16.1~dfsg-1+deb11u1, Copyright (C) 1999 - 2018, Digium, Inc. and others.
Created by Mark Spencer <[email protected]>
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 16.16.1~dfsg-1+deb11u1 currently running on debian-asterisk (pid = 1403)
debian-asterisk*CLI> quectel show devices
ID           Group State      RSSI Mode Submode Provider Name  Model      Firmware          IMEI             IMSI             Number        
quectel0     0     Free       27   0    0       CHN-UNICOM     EC20F      EC20CEFAGR06A15M4 86XXXXX  46XXXXX  Unknown       
debian-asterisk*CLI> 

配置dialplan

直接参考驱动作者写的帖子,下载帖子里的sipext.zip,解压后放到/etc/asterisk下,同时修改一下/etc/asterisk/extensions.conf和sip.conf (请不要直接照抄!根据自己的实际情况和驱动作者的帖子修改)。
在 sip.conf 文件中,[70] 部分下,将主机 IP 地址更改为您 PC/笔记本电脑在家庭网络中的 IP 地址。然后将两个文件复制到 /etc/asterisk。
以下为本人使用的配置(IP段为192.168.1.0/24,freepbxip192.168.1.111),可以直接在/etc/asterisk进行修改。里面这2个文件其实都有的。

extensions.conf

[incoming-mobile]
#exten => _.,1,Dial(SIP/70/100)
#same => n,Hangup()

#exten => s,1,Set(CALLERID(name)=${CALLERID(num)})
#same => n,Dial(SIP/70)


; 来电处理
exten => s,1,NoOp(== 来电:${CALLERID(num)} ==)
 same => n,Set(CALLERID(name)=${CALLERID(num)})
 same => n,Dial(SIP/70,50)         ; 尝试拨打 SIP 分机 70,最多 50 秒
 same => n,Playback(vm-goodbye)    ; 播放语音提示(可选)
 same => n,Hangup()

;  短信处理
exten => sms,1,Verbose(SMS from ${CALLERID(num)})
 same => n,System(/usr/local/bin/sms2bark.sh '${CALLERID(num)}' '${SMS_BASE64}')
 same => n,Hangup()

;  USSD 处理(如果你用 AT+CUSD 发 USSD 查询)
exten => ussd,1,Verbose(Incoming USSD: ${BASE64_DECODE(${USSD_BASE64})})
 same => n,System(echo '${STRFTIME(${EPOCH},,%F %T)} - USSD: ${BASE64_DECODE(${$
 same => n,Hangup()




[Outbound-1001]
exten => _.,1,Dial(Quectel/quectel0/${EXTEN})
same => n,Hangup()

sip.conf

[general]
context=sip-default
udpbindaddr=0.0.0.0:46000
tcpbindaddr=0.0.0.0:47000
tlsbindaddr=0.0.0.0:5063
tlscipher=ALL
tlsclientmethod=tlsv1
accept_outofcall_message=yes
allow=!all,slin,ulaw,alaw
allowguest=no
allowtransfer=yes
alwaysauthreject=yes
authfailureevents=no
autoframing=no
defaultexpiry=120
dumphistory=no
dynamic_exclude_static=no
faxdetect=no
g726nonstandard=no
jbenabled=no
jbforce=no
jbimpl=fixed
language=en
maxcallbitrate=384
maxexpiry=3600
minexpiry=60
notifycid=no
notifyhold=no
notifyringing=yes
preferred_codec_only=no
recordhistory=no
rtpholdtimeout=300
rtptimeout=30
sipdebug=no
srvlookup=no
tonezone=us
tos_audio=ef
tos_sip=cs3
tos_video=af41
videosupport=no
nat=force_rport,comedia
websocket_enabled=false
autodomain=no
allowexternaldomains=yes
tcpenable=yesy
tlsenable=no
tlsdontverifyserver=no
localnet=192.168.1.0/255.255.255.0
useragent=VitalPBX
callcounter=yes
tos_text=af41
cos_sip=3
cos_audio=5
cos_video=4
cos_text=3
recordonfeature=one_touch_rec
recordofffeature=one_touch_rec
vmexten=*97
outofcall_message_context=messages
auth_message_requests=no
transport=udp
[70]
context=Outbound-1001
description=ext70
dtmfmode=rfc2833
allow=!all,slin,alaw,ulaw
nat=force_rport,comedia
host=192.168.1.111
port=5060
insecure=port,invite
type=friend
qualify=no

修改完后再重启一次asterisk。

systemctl restart asterisk

设置BARK短信转发
在extensions.conf设置中其实已经把bark转发的一点点配置加入进去了。现在我们需要做个bark转发脚本。
在/usr/local/bin下面创建sms2bark.sh

cd /usr/local/bin
nano sms2bark.sh

sms2bark.sh

#!/bin/bash

# 来电号码(对方号码)
SENDER="$1"

# 短信内容(base64 编码)
MESSAGE_BASE64="$2"

# 你的手机号,用于标注“来自 xxx”
MY_NUMBER="199xxxxxxxx"

# Bark 推送地址(替换为你自己的推送 key)
BARK_URL="https://api.day.app/你自己的推送key"

# 解码短信内容
DECODED=$(echo "$MESSAGE_BASE64" | base64 -d 2>/dev/null)

# 最终短信内容 + 你自己的标记
FINAL_MSG="$DECODED

来自 $MY_NUMBER"

# 发起推送(title 是发信号码)
curl -s -G \
  --data-urlencode "title=$SENDER" \
  --data-urlencode "body=$FINAL_MSG" \
  "$BARK_URL" >/dev/null

现在发条短信给你的ec20手机号码测试看看。。。不出意外,应该是可以成功收到。

Freepxb部分

去freepbx官网上下载freepbx的iso镜像(看起来是一个CentOS7):https://www.freepbx.org/downloads/。使用镜像安装系统,安装时选择freepbx 16 with asterisk 18。安装完后用浏览器访问虚拟机的IP,设置初始的管理员密码(最开始可以暂不打开防火墙,方便配置)。

添加分机号
在 Applications-Extensions 里,点击add extension- SIP extension,加一个200的extension(号码随意,只要不和asterisk虚拟机里的号码撞上了就行):
1750643217821.png
剩下部分保持默认,点submit,并点击一下右上角的apply config。

添加中继
添加之前,先按照前面的帖子的指引,修改asterisk虚拟机里的/etc/asterisk/sip.conf,把最底下70分机的host=192.168.x.x改成freepbx虚拟机的IP,重启asterisk。

在freepbx的中继里添加一个SIP(chan_pjsip)中继,配置如下,其他默认:
1750643302699.png

名字随意,outbound CallerID改成asterisk虚拟机那边设置的数值(70)
1750643328044.png
SIP server要改成asterisk虚拟机的IP,也就是将图片上10.16.X.X改成ubuntu18虚拟机的ip地址

路由
在出局线路里,新建路由,将出方向的路由都转发给前一步创建的SIP中继:
1750643664127.png

在入局线路里,新建路由,将入方向的路由都转发给分机上面设置的分机号:
1750643708217.png

如果未来连接了多个分机或者多个dongle,需要根据用户进行分流的话,可以详细配置上面的DID和CallerID来进行过滤。

测试通话

下载portsip uc,ios可以常驻后台
配置很简单的。不解释了。

其他

使用模块上网(未设置验证)
如果使用的手机卡包含流量,我们也可以一并配置模块的上网功能,以便在机器的有线/无线网络挂掉后,还能正常的转发短信和通话。

首先,在连上串口后输入

AT+QCFG="usbnet",1,

设置usbnet模式为ECM(1是ECM,2是NDIS,3是RNDIS)

接着,用

AT+CFUN=1,1

重启一下模块,随后查看ip a,应该能看到一个类似enxe2eeabcd123的接口,在这个接口上直接运行dhclient即可获取v4或v6地址。如果怕interface的名字经常变化,可以参考这个问题,把interface的名字根据MAC地址重命名成quectel-usbX这样方便管理的名字。

3: quectel-usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether ff:ff:ff:ff:ff:ff brd ff:ff:ff:ff:ff:ff
    inet 192.168.225.41/24 brd 192.168.225.255 scope global dynamic quectel-usb0
       valid_lft 28802sec preferred_lft 28802sec
    inet6 2408::/64 scope global dynamic mngtmpaddr 
       valid_lft forever preferred_lft forever
    inet6 fe80::/64 scope link 
       valid_lft forever preferred_lft forever

该教程参考 使用EC20模块配合asterisk及freepbx实现短信转发和网络电话 ,感谢作者。

Ubuntu 24系统下参考:https://myth.cx/p/asterisk-ec20/

具体修改下以下部分。

安装 Asterisk 和依赖

sudo apt install asterisk asterisk-dev adb git autoconf automake libsqlite3-dev build-essential libasound2-dev alsa-utils

编译安装 asterisk-chan-quectel 模块

git clone https://github.com/IchthysMaranatha/asterisk-chan-quectel
cd asterisk-chan-quectel

笔者这里按照另一篇文章的说明,修改了 pdu.c 文件中 663 行左右的代码:

原代码:

int i = 0;
int sca_digits = (pdu[i++] - 1) * 2;
int field_len = pdu_parse_number(pdu + i, pdu_length - i, sca_digits, sca, sca_len);

修改为:

int i = 0;
int sca_digits = (pdu[i++] - 1) * 2;
if (pdu[i-1] == 0) {
    return i;
}
int field_len = pdu_parse_number(pdu + i, pdu_length - i, sca_digits, sca, sca_len);

之后运行 asterisk -V,查看 Asterisk 版本号:

Asterisk 20.6.0~dfsg+~cs6.13.40431414-2build5

然后以下命令,编译安装 asterisk-chan-quectel 模块:

./bootstrap
./configure DESTDIR=/usr/lib/x86_64-linux-gnu/asterisk/modules --with-astversion=20.6.0
make
sudo make install

之后,将 quectel.conf 复制到 /etc/asterisk/ 目录下。如果你之前激活了 UAC 数字音频,将配置文件末尾部分中的两行取消注释:

cp quectel.conf /etc/asterisk/
[quectel0]
audio=/dev/ttyUSB1                 ; tty port for Audio, set as ttyUSB4 for Simcom if no other dev present
data=/dev/ttyUSB2                 ; tty port for AT commands;         no default value
quec_uac=1                              ; Uncomment line if using UAC mode
alsadev=hw:CARD=Android,DEV=0           ; Uncomment if using UAC, set device name or index as reqd

最后,运行命令重启 Asterisk 服务。

sudo systemctl restart asterisk

设置权限

Ubuntu 安装的 Asterisk 默认使用 asterisk 用户运行,该用户无权访问 /dev/ttyUSB 设备。需要将该用户添加到 dialout 组:

sudo usermod -aG dialout asterisk

另外,Ubuntu 上默认安装的 modemmanager 也会干扰 EC20 模块的使用,将其禁用:

sudo systemctl stop ModemManager
sudo systemctl disable ModemManager

之后重启系统。

检查 EC20 模块状态
重启后,运行 sudo asterisk -rvvv进入 Asterisk CLI,输入 quectel show device state quectel0检查模块状态:

-------------- Status -------------
  Device                  : quectel0
  State                   : Free
  Audio                   : /dev/ttyUSB1
  Data                    : /dev/ttyUSB2
  Voice                   : Yes
  SMS                     : Yes
  Manufacturer            : Quectel
  Model                   : EC20F
  Firmware                : EC20CEFAGR08A03M4G
  IMEI                    : XXXXXX
  IMSI                    : XXXXXX
  GSM Registration Status : Registered, home network
  RSSI                    : 27, -59 dBm
  Mode                    : No Service
  Submode                 : No service
  Provider Name           : CHN-CT
  Location area code      : XXXXXX
  Cell ID                 : XXXXXX
  Subscriber Number       : Unknown
  SMS Service Center      : XXXXXX
  Use UCS-2 encoding      : Yes
  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

以上内容说明已经成功注册到中国电信网络,并且 Asterisk 能够正常访问 EC20 模块。由于是电信卡,我们可以向 10000 发送一条免费短信进行测试:

quectel sms quectel0 10000 "cxll"

看到Successfully sent SMS message即表示发送成功。如果不出意外,几秒钟后可以在终端里看到运营商的回复短信。

配置短信转发和语音通话

同上面配置dialplan一样,主要修改/etc/asterisk/extensions.conf和sip.conf,还有配置bark转发脚本

0

评论 (0)

取消