МиниАТС у себя дома

У меня есть стационарный телефон от Укртелекома. И все бы хорошо, если бы не воровали телефонный кабель. И вот оставшись очередной раз без городской связи, я решил заняться поиском альтернатив. Интернет у меня идет по оптике. Узнав что Укртелеком предоставляет услуги SIP телефонии я уже обрадовался решению проблемы малой кровью. Однако оказалось, что номер при этом у меня изменится. А ведь старый номер это единственное, что меня останавливало от ухода с Укртелекома. Ну раз потери номера мне было не избежать, тогда я решил более плотно заняться вопросом обеспечения себя связью.

Сразу первой же альтернативой видится трубка CDMA, однако у меня в доме 6 трубок заведенные по 3 трубки на 2 базы (4 трубки в доме, 1 в летней кухне, 1 в гараже), это очень удобно, когда телефонная трубка всегда под рукой и не приходится носить ее с собою. Про CDMA терминал Huawei-1201 я тогда не знал, а если бы знал, тогда бы не было сейчас этой статьи. По этому я видел свое решение в мире SIP телефонии.

Выяснил, что для того чтобы подключить аналоговые телефоны к SIP-линии, необходим VOIP шлюз. Ну а раз телефония будет цифровая, то почему бы и не сделать «пульт управления» к ней?

На тот момент, о SIP телефонии я только читал на Хабре заголовки про Asterisk, пропуская их, думая что:

1) это очень сложно для меня.

2) мне это не пригодится.

В обоих пунктах я ошибался.

Когда-то давно я посмотрел видео Дмитрия Бачило, об установке OpenWrt на роутер TP-Link TL-WR842, где он сообщил, между прочего, что устанавливал Asterisk на подобные устройства. Спасибо Дмитрию за его видео. И когда я выбирал себе роутер, то решил что куплю роутер, на который Дмитрий ставил OpenWRT, чтобы не было потом неожиданностью, что в случае покупки другого роутера, он не поддерживает OpenWRT, плюсом было также то, что в нем был USB порт. Установив почти сразу же после покупки OpenWRT 15.05.1 на роутер и вставив в него USB флешку сделав его таким образом его домашней файлопомойкой. Было это около 10-12 месяцев назад. Скажу честно, с OpenWRT я не имел дело до этого и о многих технологиях я узнал благодаря видео Дмитрия.

Также я находил статьи о прикручивании GSM модемов к Asterisk. Поскольку usb порт в роутере у меня имелся, решил осуществить и эту задачу, правда даже не зная с какой стороны начинать ее решать.

Найдя пошаговое руководство о установке Asterisk 11 на OpenWrt я принялся его выполнять, следуя каждому шагу. Однако в конце меня ждало разочарование, при попытке запуска Asterisk 11 в OpenWRT 15 я видел ошибку Segmentation fault. Первый вопрос который возникнет у незнающего читателя: почему именно Asterisk 11? Потому что именно под эту версию есть пакет chan_dongle, который позволяет прикрутить к Астериску GSM модемы Huawei. Поискав в интернете причину Segmentation fault, я не нашел ничего внятного, кроме как «OpenWRT 15 — плохо, OpenWRT 14 — хорошо». По скольку опыта в этом вопросе не было у меня, пришлось «написанному верить». Установив 14-ю версию OpenWRT я все таки смог установить и запустить Астериск. Но ведь этого мало, его нужно еще настроить. Снова поискав в интернете, наткнулся на такого SIP-провайдера как Zadarma, у которого внутренние номера бесплатные. Для теста самое то! Зарегистрировав два аккаунта я попробовал позвонить с компьютера на смартфон. Звонок прошел. Значит я все параметры настроил правильно. На сайте есть инструкция по подключению к Астериск, однако, там не хватает одной строки, которую нужно прописать в файле sip. conf

Прописав настройки номера 101 на своем смартфоне я начал снова названивать с компьютера. Наигравшись и убедившись в жизнеспособности идеи я принялся за поиски VOIP шлюза. Перебрав кучу вариантов на OLX я решил все же заказать шлюз в Китае. Заказав Linksys pap2t, я принялся за поиски подходящего GSM модема, все на той же площадке бесплатных объявлений. Самым распространенным модемом поддерживающим передачу голоса был Huawei e1550, его я и купил. Однако по скольку USB хаба на тот момент у меня не было, я пытался установить OpenWRT на карту памяти вставленную в модем. К сожалению безуспешно. Карта памяти инициализировалась после примонтирования корневой файловой системы. Но я не оставлял попыток это сделать и даже решив попробовать полностью пересобрать OpenWRT из исходников (а вдруг поможет?). Неустанно компилируя по вечерам разные версии OpenWRT я пытался добится загрузки с карты памяти модема, но я добился совсем другого результата. Оказывается Asterisk 11 под OpenWRT 15 — работает. Если и прошивку и пакет компилировать вместе. Все же сдавшись я приобрел USB хаб, установил OpenWRT на флешку, вставив модем в соседний порт я принялся настраивать chan_dongle. Однако по скольку я уже компилирую прошивку самостоятельно, то и chan_dongle решил собрать из исходников.

В ожидании шлюза из Китая, я решил узнать, что я могу выжать из моей АТС, и первым делом написал на Bash скрипт, который формирует из номера звонящего голосовой файл, и затем при звонке с моего второго номера Zadarma мне проигрывался этот файл и я мог узнать номер последнего звонящего мне человека домой, даже если я находился не дома. Bash скрипт я тоже писал впервые и многое мне было не очевидным. В результате проведя эксперименты, при подключении к медленному каналу интернета и позвонив домой на номер Zadarma многие цифры было не возможно разобрать. Да и Bash скрипт был не лишен ошибок, по этому его я тут выкладывать не буду, скажу лишь, что пока пытался разобраться с вызовом скрипта наткнулся на такую замечательную вещь как AGI. Которая позволяет использовать в качестве обработчика PHP, Perl или CGI сценарии.

Параллельно написанию скриптов я названивал своим друзьям и знакомым через разные софтфоны со смартфона. Маршрут звонка был следующий: SoftFon (разные SIP клиенты) => Asterisk => GSM modem => GSM телефон. И все без исключения мне говорили о ужасном качестве моего голоса, при этом я всех слышал прекрасно. Это подвело меня к тому, что на каждый канал мне пришлось прописать разрешенные кодеки. Попробовав кодек G722, я понял, что мощностей моего роутера явно будет недостаточно для кодирования голоса и работы в качестве основного шлюза моего интернета. По этому для Астериска я решил приобрести отдельный роутер. Однако самыми оптимальными по качеству звука выявились кодеки G711(alaw/ulaw). На них и остановился, хотя качеством своего голоса я был явно недоволен.

Следующим шагом для меня стала детализация звонков, и их запись. Обе эти задачи можно решить внутренними средствами Астериска, 1 — CDR, 2 — MixMonitor. CDR — служит для детализации звонков, и записывать их может от CSV файла до базы данных MySQL, которую я и планировал использовать в качестве БД. Но позже вычитав, что MySQL для роутера будет слишком прожорливая, я сместил свой выбор в пользу SqLite3. Вот так выглядит мой файл cdr_sqlite3_custom. conf

А обернув вызов в MixMonitor я делаю запись звонка, но запись идет в wav файл, а этот формат любит много места, по этому я установил пакет lame и после записи, я конвертирую файл в mp3.

Тем временем мне уже приехал мой Linksys pap2t и я уже мог подключить вместо смартфона для теста обычный стационарный телефон. И каково же было мое удивление, когда при звонке через этот шлюз, пропала проблема с качеством исходящего голоса. Т. е. меня уже слышали также хорошо, как и я слышал собеседника.

В поисках роутера который будет выделен только под АТС (искать решил на Али), мой выбор пал на OYE-0001. потому как в нем уже имелся встроенный кард ридер для карточек MicroSD и OpenWRT стояла из коробки. Сделав заказ снова сел за написание скриптов. Пока писал скрипты, выяснилось, что модем Huawei E1550 имеют свойство уходит в астрал, и помогает от этого только полный сброс по питанию. Т. е. вытаскивание и установка модема обратно. (Забегая вперед скажу, эта проблема у меня пока так и не решена, хотя предполагаемое решение имеется.)

Получив китайский роутер снова начал пытаться установить прошивку на внешний носитель, но на этот раз на карту памяти, вставленную в кард-ридер. На стоковой прошивке у меня получилось это сделать, однако на ней не работали необходимые мне пакеты из репозитория OpenWRT. По этому попытался снова скомпилировать прошивку самостоятельно. Пробовал собирать именно 15-ю версию. Но перепробовав разные преднастройки от подобных роутеров, на процессоре MT7620, у меня постоянно что-то, да не работало так как надо. Но поскольку опыта мало, то и решить проблему я не мог. Однако выяснилось, что 16-я (trunk, тестовая) версия OpenWRT поддерживает мой роутер из коробки и на сайте есть даже прошивка, которую я поспешил загрузить. И в данной прошивке мне удалось сделать все что я задумывал, т. е. установить OpenWRT на карту памяти, настроить сеть и установить нужные мне пакеты. Если кто будет ставить себе 16, транковую, версию OpenWRT, в ней отсутствует пакет Luci. Т. е. графический Web-интерфейс. И настройки сети необходимо будет вносить через консоль в файл /etc/config/network.

Заключительный этап — подключение городского номера.

В качестве провайдера для городского номера я выбрал себе Интертелеком. Это CDMA оператор, который предоставляет услуги SIP телефонии. Я себе видел свою домашнюю АТС следующим образом: 2-GSM модема и SIP канал от Интертелекома, т. к. chan_dongle не умел работать с CDMA модемами. Но снова собирая информацию я наткнулся на chan_cdma. Эта библиотека позволяет работать с CDMA модемом ZTE AC8710. Спасибо огромное Олегу Жабко, за написание модуля для работы с этим модемом. Но она написана под Астериск 1.8, а у меня использовался 11. Далее среди объявлений я наткнулся на модем ZTE AC8700 (он внешне 1 в 1 АС8710), за 35 грн. (это шара). По этому решил вложится в этот эксперимент и приобрел данный модем. Позже выяснил, что chan_cdma написан на основе chan_dongle. По этому для того, чтобы заставить работать модем под 11 Астериск, потребуется нудная копипаста кода с одного проекта в другой. Но проделав тщательнейшую копипасту, перенося в проект chan_dongle только участки отвечающие за работу с CDMA, но особо в смысл кода я не вникал. Завести работать модем и позвонить оператору мне увы не удалось. Тогда пришлось приложить усилий и все же начал вникать в код постоянно вставляя отладочные сообщения. Начал замечать, что в коде есть места проверки данных, которые закоментированы, а вместо них вставлены заглушки «if(1) <. >». Тогда я подобрался к коду который отвечает за проверку регистрации в сети и тоже его также «заглушил». И «о чудо!», я смог сделать вызов оператору, но поскольку назначения данных проверок я не знаю, то я лишь добавил в «пропускающие» число которое возвращал мой модем.

С библиотекой chan_cdma я мучался около 2-х недель, и за это время как раз наткнулся на CDMA терминал Huawei-1201 и поскольку в оптимистичный финал с модемом я не верил. Тогда я решил точно не зависеть от проводов, оптический кабель тоже ведь могут украсть. По этому решил организовать «план Б». Приобрести Voip шлюз с FXO портом, приобрести Huawei-1201, посадить на этот порт терминал и это все будет идти через мой Астериск сервер. Снова посмотрел объявления на сайте я наткнулся на TP-Link TD-VG3631. Почитав в интернете описания, я понял, что это именно то, что мне нужно. 2FXS порта и 1 FXO. Да еще и в моем городе продается, я незамедлительно решил купить. Но после покупки, покопавшись в настройках я был сильно разочарован. Т. к. во-первых звонить на «FXO» можно было только со внутренних телефонов, а во вторых, для этого нужно было использовать «префикс». А это уже «костыль» в моей системе, т. к. тогда звонок будет идти в обход моей АТС и не все дома запомнят, что для звонка «теперь нужно набирать дополнительные цифры». По этому до покупки терминала дело так и не дошло. Еще одним разочарованием стало то, что Tp-Link TD-VG3631 не признавал SIP номера, короче 3-х цифр. До этого мои внутренние номера были 11 и 22 соответственно. К тому моменту мне уже отремонтировали линию Укртелекома и по этому пока я решил оставить Tp-Link TD-VG3631, благо входящий вызов на FXO порт он мог перенаправлять на SIP номер.

К тому моменту у меня уже сформировался AGI скрипт обработки входящих звонков, алгоритм его работы был следующий. Если номер звонит впервые, тогда проверяем пропускаем звонок в любом случае и записываем номер в телефонную книгу, если же этот номер есть у нас в телефонной книге и он не в черном списке — пропускаем звонок, иначе сбрасываем. Файл БД телефонной книги решил разместить там же где и находится файл детализации звонков в /var/log/asterisk. Но тут снова ждало разочарование. После перезагрузки эта папка очищается. Пришлось в исходниках Астериска в файле cdr_sqlite3_custom. c изменить путь к расположению файла master. db на /www/. Также скажу, что пакет res_agi. ipk из коробки не работает и для работы требует res_speech. so. Тут я попробовал вручную подсунуть этот файл из папки сборки OpenWRT в каталог /var/lib/asterisk/modules и все заработало.

Следующим изменением файла обработки входящих звонков, номер проверялся и если он соответствовал моему второму задармашнему номеру, тогда первым делом на него высылался список из последних 5 входящих, с временем когда они звонили, а лишь затем шел звонок на внутренние номера. Вот собственно сам код.

in. php

RECDIR=/var/spool/asterisk/monitor

SAVEMP3DIR=/www/light/monitor

[dongle-incoming-sms]

exten => sms,1,Noop(Incoming SMS from $ $)> — $)

exten => sms, n, Set(CDR(call_num)=sms_ussd)

exten => sms, n,AGI(sms. php, $, $)

include => dongle-incoming-sms

exten => _X. 2, Set(CDR(userfield)=$);

exten => _X. 3, Set(CDR(call_num)=$)

exten => _X. 4, Set(CDR(dist)=in)

exten => _X. 5, MixMonitor($.wav)

exten => _X. 6, AGI(in. php); направлены на внутренний номер

exten => _X. 7, Hangup()

exten => _X. 8, StopMixMonitor()

exten => _+X. 2, Set(CDR(userfield)=$);

exten => _+X. 3, Set(CDR(call_num)=$)

exten => _+X. 4, Set(CDR(dist)=in)

exten => _+X. 5, MixMonitor($.wav)

exten => _+X. 6, AGI(in. php); направлены на внутренний номер

exten => _+X. 7, Hangup()

exten => _+X. 8, StopMixMonitor()

exten => h,1,System(/usr/bin/lame — b 16 — silent $/$.wav $/$.mp3 > /var/log/asterisk/wav_2_mp3.log)

exten => h, n,System(/bin/rm — r $/$.wav)

Ну а для вывода статистики, по звонкам набросал на скорую руку Web-интерфейс. Вот так вот он выглядит. И положил его в папку /www/light/.

Makefile для компиляции в последней версии OpenWRT (необходимо заменить родной Makefile в папке /package/feeds/telephony/asterisk-11.x-chan-dongle, все патчи оставить как есть).

PKG_LICENSE:=GPL-2.0

PKG_LICENSE_FILES:=COPYRIGHT. txt LICENSE. txt

PKG_MAINTAINER:=Jiri Slachta <jiri@slachta. eu>

include $(INCLUDE_DIR)/package. mk

define Package/asterisk11-chan-dongle

CATEGORY:=Network

URL:=https://code. google. com/p/asterisk-chan-dongle/

DEPENDS:= asterisk11 +libiconv-full +kmod-usb-acm +kmod-usb-serial +kmod-usb-serial-option +libusb-1.0 +usb-modeswitch

TITLE:=Huawei UMTS 3G dongle support

endef

define Package/asterisk11-chan-dongle/description

Asterisk channel driver for Huawei UMTS 3G dongle.

endef

MAKE_ARGS:= \

CC=»$(TARGET_CC)» \

LD=»$(TARGET_CC)» \

CFLAGS=»$(TARGET_CFLAGS) — DASTERISK_VERSION_NUM=110000 — DLOW_MEMORY — D_GNU_SOURCE — D_XOPEN_SOURCE=600 $(TARGET_CPPFLAGS) — I$(STAGING_DIR)/usr/lib/libiconv-full/include — I$(STAGING_DIR)/usr/include/asterisk-11/include — DHAVE_CONFIG_H — I. — fPIC» \

$(call Build/Configure/Default, \

—with-asterisk=$(STAGING_DIR)/usr/include/asterisk-11/include \

$(MAKE) — C «$(PKG_BUILD_DIR)» $(MAKE_ARGS) all install

endef

define Package/asterisk11-chan-dongle/conffiles

/etc/asterisk/dongle. conf

endef

define Package/asterisk11-chan-dongle/install

$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/asterisk/modules/chan_dongle. so $(1)/usr/lib/asterisk/modules/

Закладка Постоянная ссылка.

Комментарии запрещены.