оригинал: Сам себе сотовый роуминг. Создание GSM гейта на asterisk + донгл от сотового оператора / Хабрахабр:
rasterisk -x "dongle discovery"
rasterisk -x "dongle show device state dongle0" | egrep "State|IMEI"
asterisk -vvvvr
CLI> dongle show devices
CLI> sip show peers
Создание GSM гейта на asterisk + донгл от сотового оператора
asterisk -vvvvvvvvvr
service asterisk restart
rasterisk -x reloadservice asterisk restart
rasterisk -x "dongle discovery"
rasterisk -x "dongle show device state dongle0" | egrep "State|IMEI"
CLI> dongle show devices
CLI> sip show peers
CLI> sip show registry
CLI> core set debug 4
покажет всё что пишется и читается из модема
оба архива www.draisberghof.de/usb_modeswitch/usb-modeswitch-1.2.5.tar.bz2 и www.draisberghof.de/usb_modeswitch/usb-modeswitch-data-20121109.tar.bz2
У вас есть линукс, у вас есть донгл.
Втыкаете, делаете lsusb.
Находите там строку похожую на
12d1 это вендор (huawey)
1446 это устройство (E173 в моем случае)
Но не все так просто.
Эти чрезвычайно юзер-френдли модемы устроены так, что после того как их втыкаешь в usb это флешка. С чем нам поможет справится usb_modeswitch.
Устанавливаем usb_modeswitch
так:
или так:
yum install asterisk-devel
wget http://asterisk-chan-dongle.googlecode.com/files/chan_dongle-1.1.r10.tgz
tar -xzvf chan_dongle-1.1.r10.tgz
cd chan_dongle-1.1.r10/
./configure
make
Качаем пропатченный исходник https://github.com/jstasiak/asterisk-chan-dongle/archive/asterisk11.zip
2. Ставим autoconf и automake
3. Разархивируем исходник, переходим в его папку и выполняем одну за другой команды:
aclocal
покажет всё что пишется и читается из модема
cat /dev/ttyUSB2 # для получения диагностики
для ввода команд
для ввода команд
stty -iutf8 hupcl -icrnl -opost -onlcr -isig -icanon -echo -echoe -echok -F /dev/ttyUSB2
echo -e "AT+ZCDRUN=8\r\n" > /dev/ttyUSB2 # отключаем автоподключение USB CD-ROM
echo -e "AT+ZCDRUN=E\r\n" > /dev/ttyUSB2 # только модем, отключить кардридер и автозагрузку USB CD-ROM
Открываем порты которые использует астериск и на которые нужно делать проброс: udp 5000-31000.
проверить порты yum install nmap
nmap -sU -O localhost
Поднимаем сервер на линукс http://www.elastix.org/index.php/en/необходимый софт:
— usb-modeswitch: www.draisberghof.de/usb_modeswitch/#downloadоба архива www.draisberghof.de/usb_modeswitch/usb-modeswitch-1.2.5.tar.bz2 и www.draisberghof.de/usb_modeswitch/usb-modeswitch-data-20121109.tar.bz2
Итак.
У вас есть линукс, у вас есть донгл.
Втыкаете, делаете lsusb.
Находите там строку похожую на
Bus 001 Device 004: ID 12d1:1446 Huawei Technologies Co., Ltd.
12d1 это вендор (huawey)
1446 это устройство (E173 в моем случае)
Но не все так просто.
Эти чрезвычайно юзер-френдли модемы устроены так, что после того как их втыкаешь в usb это флешка. С чем нам поможет справится usb_modeswitch.
Устанавливаем usb_modeswitch
так:
wget http://www.draisberghof.de/usb_modeswitch/usb-modeswitch-2.2.1.tar.bz2
wget http://www.draisberghof.de/usb_modeswitch/usb-modeswitch-data-20150115.tar.bz2
yum install libusb libusb-devel minicom wvdial
wget http://pkgs.repoforge.org/usb_modeswitch/usb_modeswitch-1.2.3-1.el6.rf.x86_64.rpm
wget http://pkgs.repoforge.org/usb_modeswitch-data/usb_modeswitch-data-20120120-1.el6.rf.noarch.rpm
yum -y --nogpgcheck install usb_modeswitch-1.1.5-1.el5.rf.x86_64.rpm usb_modeswitch-data-20120120-1.el5.rf.noarch.rpm
wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el5.rf.x86_64.rpm
rpm -ivh rpmforge-release-0.5.3-1.el5.rf.x86_64.rpm
yum install usb_modeswitch
yum install usb_modeswitch-data
nano /etc/usb-modeswitch.conf
DefaultVendor = 0x12d1
DefaultProduct = 0x1f01
MessageEndPoint = "0x01"
MessageContent =
"55534243000000000000000000000011060000000000000000000000000000"
Для каждого модема: usb_modeswitch -v 0x12d1 -p 0x1446 -H -s 5 -M 55534243000000000000000000000011060000000000000000000000000000
не забудьте поменять 12d1 и 1446 на свои цифры из lsusb!
Запускаете lsusb снова и вы увидите там примерно тоже самое что и раньше, но вторая 4-ка цифр вашего донгла будет другой.
Это значит что все прошло успешно и теперь ваш модем это модем.
[root@localhost asterisk]# ls /dev | grep USB
ttyUSB0
ttyUSB1
ttyUSB2
ttyUSB3
ttyUSB4
[root@localhost ~]# dmesg | grep tty
console [tty0] enabled
usb 1-1: GSM modem (1-port) converter now attached to ttyUSB0
usb 1-1: GSM modem (1-port) converter now attached to ttyUSB1
usb 1-1: GSM modem (1-port) converter now attached to ttyUSB2
usb 1-1: GSM modem (1-port) converter now attached to ttyUSB3
[root@localhost asterisk]# ls /dev | grep USB
ttyUSB0
ttyUSB1
ttyUSB2
ttyUSB3
ttyUSB4
[root@localhost ~]# dmesg | grep tty
console [tty0] enabled
usb 1-1: GSM modem (1-port) converter now attached to ttyUSB0
usb 1-1: GSM modem (1-port) converter now attached to ttyUSB1
usb 1-1: GSM modem (1-port) converter now attached to ttyUSB2
usb 1-1: GSM modem (1-port) converter now attached to ttyUSB3
Вот тут-то и должна отработать та самая опция про USB Serial Driver ядра и в /dev должны появится несколько устройств /dev/ttyUSB0 /dev/ttyUSB1 и т.д.
Это интерфейсы к модему, какие-то звуковые, какие-то управления, насколько я понял какой из них какой зависит от модема.
Треть дела сделана, цифровой интерфейс к сотовой сети у нас есть, переходим к астериску.
Не буду описывать его установку, будем считать что он поставлен (не настроен, просто установлен). Если из исходников, то хорошо. Если пакет — понадобится еще и -dev, потому что мы будем собирать chan_ модуль к нему.
А именно тот самый chan_dongle.
tar -xzvf chan_dongle-1.1.r10.tgz
cd chan_dongle-1.1.r10/
./configure
make
Если видим
usr/include/asterisk/module.h:458:5: note: expected 'int (*)(struct ast_channel *, const char *)' but argument is of type 'int (*)(struct ast_channel *, void *)'Качаем пропатченный исходник https://github.com/jstasiak/asterisk-chan-dongle/archive/asterisk11.zip
2. Ставим autoconf и automake
3. Разархивируем исходник, переходим в его папку и выполняем одну за другой команды:
autoconf
automake -a
automake -a
и снова
DESTDIR="/usr/lib64/asterisk/modules" ./configure //если 64
./configure //если 32
make
make install
chown :asterisk /var/lock/;
make
make install
chown :asterisk /var/lock/;
chmod g+w /var/lock/;
Копируем дефолтный конфиг из /etc/chan_dongle.conf в папку с конфигом астериска.
make install
ls /usr/lib64/asterisk/modules
cp etc/dongle.conf /etc/asterisk/
nano /etc/asterisk/dongle.conf
cp etc/dongle.conf /etc/asterisk/
nano /etc/asterisk/dongle.conf
Запускаем asterisk прямо без настройки.
Запускаем asterisk -rv и попадаем в консоль.
Пишем module load chan_dongle.so.
Модуль загрузится и скорее всего о чем-нибудь начнет ругаться.
Но по выполнении команды dongle show devices покажет что-то вроде
ID Group State RSSI Mode Submode Provider Name Model Firmware IMEI IMSI Number
dc_4823_7851 0 Free 11 0 0 MegaFon RUS E173 11.126.15.00.209 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxx
выходим
Открываем на редактирование файл /etc/asterisk/dongle.conf и в самом низу, где описывается устройство [dongle0]
комментируем все кроме строки imei, куда вписываем imei вашего модема из строки которую показал dongle show devices
и дописываем
[dongle0]
imei=xxxxxxxxxxxxxxxx
context=dongle-incoming; контекст
group=0
rxgain=3; увеличение громкости
txgain=3; увеличение громкости
resetdongle=yes; сбрасывать карту при инициализации
u2diag=-1
usecallingpres=yes
callingpres=allowed_passed_screen
Теперь модуль chan_dongle можно вписать в /etc/asterisk/modules.conf в виде строки load => chan_dongle.so
чтобы он подргужался сам при запуске asterisk.
Перезапускаем asterisk.
Вот теперь, по правильному imei, chan_dongle должен сам все правильно найти — и какие из устройств являются командными, и какие аудио, и так далее.
Запускаем asterisk -rv, выполняем dongle show devices и видим свой модем. Все в порядке.
echo 'KERNEL=="ttyUSB*", OWNER="asterisk", GROUP="dialout"' > /etc/udev/rules.d/10-modem.rulesТеперь к настройке астериска.
Все что нам нужно находится в файлах sip.conf и extensions.conf
Начнем с sip.conf
Находим секцию [general] и дописываем:
[general]
externip=х.х.х.х; внешний айпишник астериска, не важно его или гейта который прокидывает к нему порты, это внешний айпишник, адрес которого будут содержать пакеты идущие к астериску и он будет считать их своими
externaddr=х.х.х.х; тоже самое
localnet=192.168.0.0/255.255.0.0; сеть, которую астериск будет считать внутренней и не устраивать сложные танцы с маскарадом для нее
nat=force_rport,comedia; необходимый режим работы если астериск за натом и к нему прокидываются порты
context=public; контекст, в который приходят звонки по умолчанию. важно чтобы тут был какой-то контекст в котором будет совершенно не определен план звонков, чтобы все звонки по умолчанию никуда не попадали! в интернете полно ботов которые сканят день и ночь на предмет плохо настроеных астерисков чтобы звонить через них на халяву
allowguest=no; не принимать звонки неизвестно от кого.
С настройкой по умолчанию закончено, теперь в этом же файле описываем одного клиента (наш софтовый телефон)
[me]
type=friend
host=dynamic
secret=пароль
context=default
canreinvite=yes
dtmfmode=rfc2833
permit=0.0.0.0/0.0.0.0
qualify=yes
me — это будет логин, пароль где задать понятно.
Записываем sip.conf. Тут все.
Открываем extensions.conf — это план звонков, описание того куда и как передаются звонки.
То что нам нужно, так это описать два контекста: [dongle-incoming] — то, что делать со звонками поступающими в модем и [default] — то, что делать со звонками поступающими с софт. телефона.
Начинаем с простого:
[default]
exten => _7X.,1,Dial(Dongle/dongle0/holdother:+${FILTER(0-9,${EXTEN})})
exten => _+7X.,1,Dial(Dongle/dongle0/holdother:+${FILTER(0-9,${EXTEN})})
exten => _8X.,1,Dial(Dongle/dongle0/holdother:+7${FILTER(0-9,${EXTEN:1})})
exten => _007X.,1,Dial(Dongle/dongle0/holdother:+7${FILTER(0-9,${EXTEN:3})})
exten => h,1,Hangup()
Это фактически 4-ре строки которые делают одно и то же, только первая когда телефон назначения подходит под шаблон 7цифры, вторая когда +7цифры, третья 8цифры и 4-я 007цифры (во многих софтовых телефонах стоит опция передавать “+” как “00”).
И делает каждая строка одно и то же — передает звонок в канал dongle0 (наш модем) в виде +7цифры.
Ну и последняя строка вызовется при событии “трубка положена” и просто кладет трубку. Впрочем ее можно даже не писать, это формальность.
Чтобы было доходчиво как это работает — любой поступивший звонок с телефона зарегистрировавшегося на астериске под аккаунтом me будет обрабатываться в контексте [default], как указано в опции context для [me]. В контексте [default] номер назначения будет сверен с шаблоном и, если попадет под один из шаблонов, то будет исполнено действие “Dial(Dongle...)”. Кстати если номер назначения в шаблон не попадет, звонок будет сброшен как неизвестно куда направляемый, можете попробовать позвонить куда-нибудь типа +4..., если интересно. Тоже какой-никакой способ защититься от телефонных мошенников, хоть не в Уганду звонить будут, если как-то проберутся.
Теперь контекст [dongle-incoming], для звонков поступающих на сотовый номер:
[dongle-incoming-sms]
exten => sms,1,Noop(Incoming SMS from ${CALLERID(num)} ${BASE64_DECODE(${SMS_BASE64})})
exten => sms,n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} — ${DONGLENAME} — ${CALLERID(num)}: ${BASE64_DECODE(${SMS_BASE64})}' >> /var/log/asterisk/sms.txt)
exten => sms,n,Hangup()
[dongle-incoming-ussd]
exten => ussd,1,Noop(Incoming USSD: ${BASE64_DECODE(${USSD_BASE64})})
exten => ussd,n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} — ${DONGLENAME}: ${BASE64_DECODE(${USSD_BASE64})}' >> /var/log/asterisk/ussd.txt)
exten => ussd,n,Hangup()
[dongle-incoming]
include => dongle-incoming-sms
include => dongle-incoming-ussd
exten => _X.,1,Dial(SIP/me)
exten => h,1,Hangup()
Тут все еще проще — любой входящий звонок передается как звонок для клиента [me].
Верхние два раздела включенные как include => dongle-incoming-sms принимают sms и ussd соответственно, и записывают их в обычные текстовые файлы /var/log/asterisk/sms.txt и /var/log/asterisk/ussd.txt где их можно потом прочитать (кодировка UTF-8).
Эпилог
Вот вкратце и все. Но это только самая основа, если кому-то реально интересно как, или не получится у самого (все-таки те кто может все это повторить я уверен на 95% могут все это сделать и сами, без инструкции, и даже дополнить всем чего тут не хватает), я могу продолжить развив эту тему — как настроить sms чтобы они принимались и отправлялись на софт-клиент так же как звонки; как изменить dialplan таким образом чтобы номер был занят когда SIP клиент не подключен, либо звонящий попадал в Voicemail.
PS. В результате всего одного дня настройки я получил свой собственный телефонный номер за границей на котором так и не смог потратить 200 рублей денег положенных перед отъездом, хоть и пользовался им постоянно, и родственникам звонил и принимал звонки. Несравнимый опыт использования с роумингом где деньги можно было кидать как в топку тепловоза.
PPS. WARNING, DISCLAIMER: поступила информация:
«Дело в том, что использование любых шлюзов прямо запрещено всеми сотовыми операторами. Вот „Условия оказания услуг связи МТС“:
Пункт 1.3 Услуги связи МТС не могут быть использованы Абонентом без дополнительного письменного согласования с Оператором для… установки шлюзов для доступа к сети
электросвязи и Интернет-телефонии…
Такие же пункты есть в условиях других операторов сотовой связи, ибо маржа на роуминге зашкаливающая, и отказываться от такого навара операторы не будут. За использование подобного шлюза могут просто заблокировать сим-карту.»
Возможные проблемы:
at_response.c:384 at_response_error: [dongle] Error checking subscriber phone number
Модем заблокирован. В DC-Unlocker для e1550 команда DC-AT^CARDLOCK="65441898" с кодом Flasheo
Возможные проблемы:
at_response.c:384 at_response_error: [dongle] Error checking subscriber phone number
Модем заблокирован. В DC-Unlocker для e1550 команда DC-AT^CARDLOCK="65441898" с кодом Flasheo