VoIP-GSM шлюз USB Huawei E1550 Asterisk & FreePBX Distro на CentOS 6

Опубликовано в Asterisk

VoIP-GSM шлюз USB Huawei E1550 Asterisk & FreePBX Distro на CentOS 6

В период кризиса и девальвации национальной валюты, идет резкое удорожание разнотипного VoIP оборудования. Не всегда малый бизнес готов сразу выкинуть несколько миллионов за систему IP-телефонии. А такие сервисы как запись разговоров, статистика и собственно сама IP-телефония, бывают критически необходимы. Поэтому приходиться прибегать к бюджетным решениям, одно из таких использование 3G модемов в качестве VoIP-GSM шлюза. Нельзя назвать, это решение стабильным и надежным, тем не менее когда нет денег, заказчик готов закрыть глаза на всякого рода “отваливания” модемов. В этой статье попробуем расcмотреть, как к уже готовому дистрибутиву FreePBX Distro подключить 3G модемы через USB хаб.

Исходные данные дистрибутив FreePBX Distro 2.11 64 bit, c Asterisk 11 на борту. Первым делом качаем пропатченный канальный драйвер chan_dongle с нашего сайта. И ставим необходимые зависимости:

yum -y install asterisk11-devel minicom
cd /usr/src
wget http://voiplab.by/download/dongle-asterisk-11-patched.tar.gz
tar xvzf dongle-asterisk-11-patched.tar.gz
cd dongle-asterisk-11-patched
aclocal
autoconf 
automake –a
./configure
make
make install
cp chan_dongle.so /usr/lib64/asterisk/modules
cp etc/dongle.conf /etc/asterisk/

C помощью minicom отключаем CardReader и виртуальный CD-ROM в модеме.

minicom –s

Выбираем настройку последовательного порта, нажимаем А и редактируем порт — /dev/ttyUSB0 после этого жмем два раза Enter и нажимаем Выход. После подключения вводим AT команду AT^U2DIAG=0 и выходим нажав Ctrl-A а потом Q

AT^U2DIAG=0 (девайс в режиме только модем)
AT^U2DIAG=1 (девайс в режиме модем + CD-ROM)
AT^U2DIAG=255 (девайс в режиме модем + CD-ROM + Card Reader)
AT^U2DIAG=256 (девайс в режиме модем + Card Reader)

Идем дальше и разбираемся с конфигурацией модемов.

nano /etc/asterisk/dongle.conf
... 
context=from-gsm
... 
rxgain=+3 
txgain=-3 
... 
[Huawei01] 
audio=/dev/ttyUSB1 
data=/dev/ttyUSB2 
 
[Huawei02] 
audio=/dev/ttyUSB4 
data=/dev/ttyUSB5 
...

Проверяем порты модемов:

ls /dev | grep USB

Добавляем нужный контекст для работы модемов:

nano /etc/asterisk/extensions_custom.conf
[from-gsm]
exten => s,1,Set(CALLERID(all)=${CALLERID(num)})
exten => s,n,Set(CALLERID(num)=${CALLERID(num)})
exten => s,n,goto(from-trunk,${DONGLEIMEI},1)
 
exten => sms,1,Verbose(Incoming SMS from ${CALLERID(num)} ${SMS})
exten => sms,n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLENAME} - ${CALLERID(num)}: ${SMS}' >> /var/log/asterisk/sms.txt)
exten => sms,n,Hangup()
 
exten => ussd,1,Verbose(Incoming USSD: ${USSD})
exten => ussd,n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLENAME}: ${USSD}' >> /var/log/asterisk/ussd.txt)
exten => ussd,n,Hangup()

Во FreePBX создаем кастомный транк, где указываем imei модема:

dongle/i:861976002997608/$OUTNUM$

После всех продлённых операций можно увидеть наши модемы:

asterisk -rvvvvvv
dongle show devices

Видим в консоли следующее:

chan_dongle.c: unable to open /dev/ttyUSB1: Permission denied

Создадаем правило udev для разрешения прав:

nano /etc/udev/rules.d/e1550.rules
KERNEL=="ttyUSB*", OWNER="asterisk", GROUP="asterisk", MODE="0660"
# /sbin/start_udev
# ls =la /dev | grep ttyUSB
crw-rw--   1 asterisk asterisk   4,  64 Сен 23 15:25 ttyUSB0
crw-rw--   1 asterisk asterisk   4,  65 Сен 23 15:25 ttyUSB1
crw-rw--   1 asterisk asterisk   4,  66 Сен 23 15:25 ttyUSB2
crw-rw--   1 asterisk asterisk   4,  64 Сен 23 15:25 ttyUSB3
crw-rw--   1 asterisk asterisk   4,  65 Сен 23 15:25 ttyUSB4
crw-rw--   1 asterisk asterisk   4,  66 Сен 23 15:25 ttyUSB5

Для экономии питания переводим модемы в 2G режим, это очень важный нюанс, потому как из-за нехватки тока питания USB модемы начинают отваливаться.

dongle cmd Huawei24 AT^SYSCFG=13,1,3FFFFFFF,2,4

Если есть желание, то можно задать номер телефона для сим-карт с номером Unknown:

dongle cmd Huawei01 AT+CPBS=\"ON\"
dongle cmd Huawei01 AT+CPBW=1,\"+375253XXXXX\",145

Следующим этапом создаем скрипт чистки лишних смс сообщения с симок модемов:

mkdir /home/mybin
nano /home/mybin/sms.sh
#! /bin/bash
asterisk -rx "dongle cmd Huawei01 AT+CMGD=1,4"
asterisk -rx "dongle cmd Huawei02 AT+CMGD=1,4"

Прописываем этот скрипт на выполнения в cron:

chmod +x /home/mybin/sms.sh 
nano /etc/crontab
00 */12 * * * root /home/mybin/sms.sh

И конечно скрипт, который на уровне Linux передернет ваш модем в случае его зависания:

nano /home/mybin/dongle_restart.sh
chmod +x /home/mybin/dongle_restart.sh
#!/bin/sh
#---------------Variables-------------------
config_file=/etc/asterisk/dongle.conf
#-------------End variables-----------------
 
#---------------Functions-------------------
 
# Function of read data value of datacard in dongle.conf
read_ini(){
  file=$1
  block=$2
  key=$3
  # Define ttyUSB
  usb_port=$(sed -n 's/#.*//;/[^[:space:]]/p' $file | awk -F = "BEGIN{found=0} {if(found) {if(/\[.+\]/){exit}else{if(\$1=/$key/){print \$2}}} else{if(/\[$block\]/){found=1}}}")
  usb_port=$(echo $usb_port | sed 's|.*/||')
}
 
# Function to reload modem
reload_modem(){
  if [ -z "$sys_num" ] # If system identifier is NULL then skiped, because it not connect to server
     then
    echo "$cur_error dont connect to server! Skip reload..."
    echo [$(date +%d.%m.%Y\ %H:%M:%S)]: "$cur_error dont connect to server! Skip reload..." >> /var/log/asterisk/dongle_reloads.txt
     else
    sh -c "echo 0 > /sys/bus/usb/devices/$sys_num/authorized" # Disable modem
    sleep 2
    sh -c "echo 1 > /sys/bus/usb/devices/$sys_num/authorized" # Enable modem
    echo "Reloading $cur_error done..."
    echo [$(date +%d.%m.%Y\ %H:%M:%S)]: "$sys_num reloaded..." >> /var/log/asterisk/dongle_reloads.txt
  fi
}
 
#-------------End functions-----------------
 
#-------------------Main--------------------
 
error_count=$(asterisk -rx 'dongle show devices' | egrep "Not|GSM" | wc | awk '{print($1);}';) # Count of fail modem
i=1
 
while [ $i -le $error_count ]; do # Repeat to all fail modem
  cur_error=$(asterisk -rx 'dongle show devices' | egrep "Not|GSM" | sed -n "$i"p | awk '{print($1);}';) # Find number of fail datacard
  echo "$cur_error not connect! Try to restart..."
  read_ini $config_file $cur_error "data" # Find number ttyUSB of fail datacard
  sys_num=$(dmesg | grep "$usb_port$" | grep "attached" | awk '{print($4);}' | sed 's|.*]||' | sed -n "1"p | sed 's/.$//') # Find system identifier of fail datacard
  reload_modem # Reload him
        i=$(($i + 1)) # Go to next fail datacard
done
 
#-----------------End Main------------------
 
exit 0

Коментарии: