N1盒子变废为宝:云通话armbian+Asterisk+freepbx+chan_dongle

最终达成的效果:在任何有网络的地方,以本地通话的方式 拨打电话(use-n1-call-as-local-when-aboard)。

瑕疵:无法接电话(软件无故重启,还没解决

主要用到的软件系列:armbian+Asterisk+freepbx+chan_dongle

硬件有:N1+Huawei E156G  3G上网卡

已经折腾过Raspberry的解决方案,无奈如今一派难求,3b的价格基本赶上4的价格了。正好手上有吃灰的N1,于是开启漫长的编译解决bug之路,本文记录一些坑。

首先N1盒子降级,刷armbian我就省略了,只记录一些我刷的版本:Armbian_5.77_Aml-s905_Debian_stretch_default_5.0.2_20190401.img

坑1: N1有线不能上网:需要编辑U盘根目录下的uEnv.ini文件,设置:dtb_name=/dtb/meson-gxl-s905d-phicomm-n1.dtb

N1安装Asterisk+freepbx:

参考文章:https://wiki.freepbx.org/pages/viewpage.action?pageId=171016249 我把文章内容复制过来,把坑填一填:

Step-by-step guide

All commands are to be run as the root user, either by directly logging in as root or by using sudo su - .

Start from a base Debian 10 installation. All necessary packages will be installed through the following commands.

Add the backports repo specifically so that the odbc-mariadb package is available. Then update the OS to current.

Install all the necessary packages

  • apt-get install -y build-essential linux-headers-`uname -r` openssh-server apache2 mariadb-server mariadb-client bison flex php php-curl php-cli php-pdo php-mysql php-pear php-gd php-mbstring php-intl php-bcmath curl sox libncurses5-dev libssl-dev mpg123 libxml2-dev libnewt-dev sqlite3 libsqlite3-dev pkg-config automake libtool autoconf git unixodbc-dev uuid uuid-dev libasound2-dev libogg-dev libvorbis-dev libicu-dev libcurl4-openssl-dev libical-dev libneon27-dev libsrtp2-dev libspandsp-dev sudo subversion libtool-bin python-dev unixodbc dirmngr sendmail-bin sendmail asterisk debhelper-compat cmake libmariadb-dev odbc-mariadb php-ldap

这里linux-headers-`uname -r`会出错:

使用apt search inux-headers 于是改为:

  • linux-headers-arm64
  • linux-headers-current-arm64

Install Node.js

Install this required Pear module

  • pear install Console_Getopt

Prepare Asterisk

  • systemctl stop asterisk
  • systemctl disable asterisk
  • cd /etc/asterisk
  • mkdir DIST
  • mv * DIST
  • cp DIST/asterisk.conf .
  • sed -i 's/(!)//' asterisk.conf 这句话不要执行,不然会遇到Checking if Asterisk is running and we can talk to it as the 'asterisk' user...Error!
  • touch modules.conf
  • touch cdr.conf

Configure Apache web server

  • sed -i 's/\(^upload_max_filesize = \).*/\120M/' /etc/php/7.3/apache2/php.ini
  • sed -i 's/\(^memory_limit = \).*/\1256M/' /etc/php/7.3/apache2/php.ini
  • sed -i 's/^\(User\|Group\).*/\1 asterisk/' /etc/apache2/apache2.conf
  • sed -i 's/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
  • a2enmod rewrite
  • service apache2 restart
  • rm /var/www/html/index.html

这里安装后不是7.3而是7.0 这些应该是增强php和apache的配置(可选)

Configure ODBC

  cd /usr/src
  git clone https://github.com/MariaDB/mariadb-connector-odbc.git
  cd mariadb-connector-odbc
  git checkout tags/3.1.15
  mkdir build
  cd build
  if [ "$(uname -m)" = "aarch64" ]; then
    DDM_DIR=/usr/lib/aarch64-linux-gnu
  else
    DDM_DIR=/usr/lib/arm-linux-gnueabihf
  fi
  cmake ../ -LH -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_SSL=OPENSSL\
 -DDM_DIR="${DDM_DIR}" -DCMAKE_C_FLAGS_RELEASE:STRING="-w"
  cmake --build . --config Release
  make install
  如有需要,安装下面的debhelper-compat # https://debian.pkgs.org/10/debian-main-arm64/debhelper_12.1.1_all.deb.html
    apt-get install debhelper
Install MariaDB ODBC Connector
  • cat <<EOF > /etc/odbc.ini
    [MySQL-asteriskcdrdb]
    Description = MySQL connection to 'asteriskcdrdb' database
    Driver = MySQL
    Server = localhost
    Database = asteriskcdrdb
    Port = 3306
    Socket = /var/run/mysqld/mysqld.sock
    Option = 3
    EOF

Download FFMPEG static build for sound file manipulation忽略不做!

这一个忽略不做!

Install FreePBX

Get the rest of the modules忽略不做!

Only a very basic system is installed at this point. You will probably want to install all the modules. Alternatively, you can skip this and pick-and-choose the individual modules you want later.

  • fwconsole ma installall

这一个执行好像出错了,忽略不做!

Uninstall digium_phones忽略不做!

Broken with PHP 7.3 (April 2020).

  • fwconsole ma uninstall digium_phones

Apply the current configuration

  • fwconsole reload
  • cd /usr/share/asterisk
  • mv sounds sounds-DIST
  • ln -s /var/lib/asterisk/sounds sounds

可以执行,但我看里面是空的,不影响使用

Perform a restart to load all Asterisk modules that had not yet been configured

  • fwconsole restart

Set up systemd (startup script)

  • cat <<EOF > /etc/systemd/system/freepbx.service
    [Unit]
    Description=FreePBX VoIP Server
    After=mariadb.service
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=/usr/sbin/fwconsole start -q
    ExecStop=/usr/sbin/fwconsole stop -q
    [Install]
    WantedBy=multi-user.target
    EOF
  • systemctl daemon-reload
  • systemctl enable freepbx

Asterisk and FreePBX 15 are installed! Go to the web interface at http://YOUR-IP to finish setup.


安装chan_dongle.so :  https://github.com/wdoekes/asterisk-chan-dongle

apt install asterisk-dev
cd /usr/local/src
git clone https://github.com/wdoekes/asterisk-chan-dongle.git
cd asterisk-chan-dongle
./bootstrap
./configure --with-astversion=13.14.1 
#注意版本且不需要添加 --with-asterisk=/usr/include/asterisk/ 否则会报 configure: error: sqlite3.h header file missing
make
make install
aml*CLI> module show like dongle
Module                         Description                              Use Count  Status      Support Level
chan_dongle.so                 Huawei 3G Dongle Channel Driver          0          Not Running      extended

[2022-05-28 08:27:33] ERROR[7696]: chan_dongle.c:1799 public_state_init: Errors reading config file dongle.conf, Not loading module
dongle.conf


touch /etc/asterisk/extensions_custom.conf
vi /etc/asterisk/extensions_custom.conf
[from-trunk-dongle]
exten => sms,1,Verbose(Incoming SMS from ${CALLERID(num)} ${BASE64_DECODE(${SMS_BASE64})})
exten => sms,n,System(wget -O/dev/null -q "https://api.day.app/xEKxxxxX5JUfS/${REPLACE(BASE64_DECODE(${SMS_BASE64}),'/', '-')}${CALLERID(num)}?sound=bell&group=voip2")
exten => sms,n,Set(FILE(/var/log/asterisk/sms.txt,,,a)=${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLENAME} - ${CALLERID(num)}: ${BASE64_DECODE(${SMS_BASE64})})
exten => sms,n,System(echo >> /var/log/asterisk/sms.txt)
exten => sms,n,Hangup()
exten => _.,1,Set(CALLERID(name)=${CALLERID(num)})
exten => _.,n,Goto(from-trunk,${EXTEN},1)


chan_dongle.c:229 opentty: unable to open /dev/ttyUSB2: Permission denied :
chmod 666 /dev/ttyUsb*


vi ./extensions_additional.conf
exten => s,n,System(wget -O/dev/null -q "https://api.day.app/xEKHDxxxxxfS/callFrom-${CALLERID(num)}?sound=bell&group=nus")

dongle 配置文件:从RasPBX复制过来的,只增加最后三行,正常运行的dongle会有3个Usb,比如0,1,2,插2个的话,就是3,4,5.

cat /etc/asterisk/dongle.conf
[general]

interval=15                     ; Number of seconds between trying to connect to devices

;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
;jbenable = yes                 ; Enables the use of a jitterbuffer on the receiving side of a
                                ; Dongle channel. Defaults to "no". An enabled jitterbuffer will
                                ; be used only if the sending side can create and the receiving
                                ; side can not accept jitter. The Dongle channel can't accept jitter,
                                ; thus an enabled jitterbuffer on the receive Dongle side will always
                                ; be used if the sending side can create jitter.

;jbforce = no                   ; Forces the use of a jitterbuffer on the receive side of a Dongle
                                ; channel. Defaults to "no".

;jbmaxsize = 200                ; Max length of the jitterbuffer in milliseconds.

;jbresyncthreshold = 1000       ; Jump in the frame timestamps over which the jitterbuffer is
                                ; resynchronized. Useful to improve the quality of the voice, with
                                ; big jumps in/broken timestamps, usually sent from exotic devices
                                ; and programs. Defaults to 1000.

;jbimpl = fixed                 ; Jitterbuffer implementation, used on the receiving side of a Dongle
                                ; channel. Two implementations are currently available - "fixed"
                                ; (with size always equals to jbmaxsize) and "adaptive" (with
                                ; variable size, actually the new jb of IAX2). Defaults to fixed.

;jbtargetextra = 40             ; This option only affects the jb when 'jbimpl = adaptive' is set.
                                ; The option represents the number of milliseconds by which the new jitter buffer
                                ; will pad its size. the default is 40, so without modification, the new
                                ; jitter buffer will set its size to the jitter value plus 40 milliseconds.
                                ; increasing this value may help if your network normally has low jitter,
                                ; but occasionally has spikes.

;jblog = no                     ; Enables jitterbuffer frame logging. Defaults to "no".
;-----------------------------------------------------------------------------------

[defaults]
; now you can set here any not required device settings as template
;   sure you can overwrite in any [device] section this default values

context=from-trunk-dongle       ; context for incoming calls
group=0                         ; calling group
rxgain=0                        ; increase the incoming volume; may be negative
txgain=0                        ; increase the outgoint volume; may be negative
autodeletesms=yes               ; auto delete incoming sms
resetdongle=yes                 ; reset dongle during initialization with ATZ command
u2diag=-1                       ; set ^U2DIAG parameter on device (0 = disable everything except modem function) ; -1 not use ^U2DIAG command
usecallingpres=yes              ; use the caller ID presentation or not
callingpres=allowed_passed_screen ; set caller ID presentation          by default use default network settings
disablesms=no                   ; disable of SMS reading from device when received
                                ;  chan_dongle has currently a bug with SMS reception. When a SMS gets in during a
                                ;  call chan_dongle might crash. Enable this option to disable sms reception.
                                ;  default = no

language=en                     ; set channel default language
smsaspdu=yes                    ; if 'yes' send SMS in PDU mode, feature implementation incomplete and we strongly recommend say 'yes'
mindtmfgap=45                   ; minimal interval from end of previews DTMF from begining of next in ms
mindtmfduration=80              ; minimal DTMF tone duration in ms
mindtmfinterval=200             ; minimal interval between ends of DTMF of same digits in ms

callwaiting=auto                ; if 'yes' allow incoming calls waiting; by default use network settings
                                ; if 'no' waiting calls just ignored
disable=no                      ; OBSOLETED by initstate: if 'yes' no load this device and just ignore this section

initstate=start                 ; specified initial state of device, must be one of 'stop' 'start' 'remote'
                                ;   'remove' same as 'disable=yes'

exten=+1234567890               ; exten for start incoming calls, only in case of Subscriber Number not available!, also set to CALLERID(ndid)

dtmf=relax                      ; control of incoming DTMF detection, possible values:
                                ;   off    - off DTMF tones detection, voice data passed to asterisk unaltered
                                ;              use this value for gateways or if not use DTMF for AVR or inside dialplan
                                ;   inband - do DTMF tones detection
                                ;   relax  - like inband but with relaxdtmf option
                                ;  default is 'relax' by compatibility reason

; dongle required settings
[dongle0]
audio=/dev/ttyUSB1              ; tty port for audio connection;        no default value
data=/dev/ttyUSB2               ; tty port for AT commands;             no default value

[dongle1]
audio=/dev/ttyUSB4              ; tty port for audio connection;        no default value
data=/dev/ttyUSB5               ; tty port for AT commands;             no default value

编译常见错误:

configure: error: Can't find "asterisk.h"
$ apt install asterisk-dev
find . -name "asterisk.*" -type f
ls /usr/local/src/asterisk-1.6.2.13/include/asterisk.h
ls /usr/include/asterisk/asterisk.h

find . -name "autoconfig.h" -type f

configure: error: sqlite3.h header file missing
$ apt install sqlite3 libsqlite3-dev 



vi /etc/default/asterisk
AST_USER="asterisk"
AST_GROUP="asterisk"

vi /etc/selinux/config
set SELINUX=disabled
reboot

常用命令

systemctl stop asterisk
systemctl enable asterisk
systemctl start asterisk # /usr/sbin/asterisk -g -f -U asterisk
systemctl status asterisk.service # /usr/sbin/asterisk -g -f -U asterisk
systemctl enable freepbx

find . -name "asterisk.*" -type f
find . -name "autoconfig.h" -type f

/etc/init.d/asterisk restart

$ which automake
$ automake --version
ls /usr/share/automake.1.11.1/config.guess
./configure --disable-xmldocs --build=aarch64-unknown-linux-gnu




asterisk -rx 'dongle show devices'
asterisk -rx 'dongle reload now'
asterisk -rvvv
core restart now
module show like dongle
asterisk -cvvvvv

crontab -l
@reboot sleep 90 &&  chmod 666 /dev/ttyUSB* && asterisk -rx 'dongle reload now' && date >> /tmp/tty.log
`

如何配置: https://www.mubucm.com/doc/kp2R9UOypa

忘记密码?

FreePBX - forgotten web admin password
At the failed login page, select all and you will see a session id that looks like this: 2nbkuaeta1t95pb5f8shd29rl5

From the CLI, fwconsole unlock <sessionid>  

关于U棒E156G: