Обработка SMS-сообщений с помощью GSM-модема Huawei e1550 и smstools на Debian 9 Stretch
В поисках решения организации SMS шлюза, посредством GSM-модема (прим. Huawei E1550), наткнулся на пакет «smstools», который прекрасно справляется со своими обязанностями (отправка\получение SMS).
Рассмотрим как развернуть пакет smstools
на Debian 9 Stretch и настроить его на GSM-модема Huawei e1550 (так же тестировал ниже описанное на e3372h с прошивкой stick).
Подготовка системы
Обновляем систему до актуального состояния:
apt-get update && apt-get upgrade
Устанавливаем необходимые для работы пакеты:
apt-get install gcc make recode usb-modeswitch minicom
Подключаем GSM-модем Huawei E1550, проверяем появились ли устройства ttyUSB*
:
ls -al /dev | grep ttyUSB
crw-rw---- 1 root dialout 188, 0 фев 27 11:34 ttyUSB0
crw-rw---- 1 root dialout 188, 1 фев 27 11:33 ttyUSB1
crw-rw---- 1 root dialout 188, 2 фев 27 12:37 ttyUSB2
Установка и настройка smstools
Скачиваем исходники smstools
, распаковываем их и переходим в распакованный каталог:
cd /opt
wget http://smstools3.kekekasvi.com/packages/smstools3-3.1.21.tar.gz
tar -zxvf smstools3-3.1.21.tar.gz
cd smstools3
Компилируем исходники и выполняем установку пакета:
make
make install
После установки, сразу создадим необходимые каталоги:
mkdir -p /var/spool/sms/{sent,failed}
mkdir -p /var/log/sms
Конфигурация smstools производится в файле /etc/smsd.conf
. Моя типовая конфигурация выглядит так:
devices = GSM1
outgoing = /var/spool/sms/outgoing
checked = /var/spool/sms/checked
incoming = /var/spool/sms/incoming
failed = /var/spool/sms/failed
sent = /var/spool/sms/sent
logfile = /var/log/smsd.log
loglevel = 5
checkhandler = /usr/local/sbin/sms_smshandler.sh
[GSM1]
device = /dev/ttyUSB2
incoming = high
check_memory_method = 31
ussd_convert = 1
eventhandler = /usr/local/sbin/sms_smshandler.sh
eventhandler_ussd = /usr/local/sbin/sms_smshandler.sh
regular_run_cmd = AT+CUSD=1,"AA180C3602",15;
regular_run_interval = 86400
regular_run_logfile = /var/log/sms/regular_run.log
Файл конфигурации разделен на две части. Сначала идут глобальные опции, а потом секция (прим. [GSM1]) с опциями для GSM-модема. Описание всех опций файла конфигурации можно найти на официальном сайте пакета smstools
.
Заострю внимание на опциях checkhandler, eventhandler, eventhandler_ussd
:
- В строке
checkhandler
задается обработчик исходящих SMS-сообщений. - В строке
eventhandler
задается обработчик входящих SMS-сообщений. - В строке
eventhandler_ussd
задается обработчик ответов на USSD-запросы.
В моем случае я использую это один и тот же скрипт sms_smshandler.sh
, в котором описывается обработка тех или иных событий.
Теперь можно запустить демон smstools:
/etc/init.d/sms3 start
Отправка SMS-сообщений
Для отправки используется скрипт sendsms, который идущий в комплекте пакета smstools.
sendsms 79999999999 'This is a test message!'
sendsms 79999999999 'Это тестовое сообщение!'
smstools 3.1.21
, сообщения нормально отправляются на кириллице, перекодировка реализована на уровне скрипта sendsms.Команда sendsms
формирует текстовый файл в каталоге «outgoing
«, который затем будет автоматически обработан сервисом smsd
и отправлен, после чего перемещен в каталог «sent
«.
Прием SMS-сообщений
Входящие SMS попадают в каталог «incoming
«. В случае если сообщение на кириллице, то оно будет закодировано в UCS2 формат
, чтобы его прочесть, требуется перекодировать его (прим. в формат UFT-8).
Рассмотрим скрипт sms_smshandler.sh
, указанный в файле конфигурации /etc/smsd.conf
в опциях eventhandle
, eventhandler_ussd
, который будет обрабатывать события.
В скрипте обрабатывается два переданных параметра ($1, $2
):
$1
— это тип события, возможные значения —CALL, RECEIVED, USSD, SENT, FAILED, REPORT
.$2
— это имя файла с SMS-сообщением.
Создаем файл скрипта:
nano /usr/local/sbin/sms_smshandler.sh
Добавим в него следующие содержание:
#!/bin/bash
case "$1" in
# События при поступлении SMS-сообщения.
RECEIVED)
# Проверка кодировки тела входящего SMS-сообщения.
# Если кодировка UCS2, то перекодируем в UTF-8
if grep "Alphabet: UCS2" $2 > /dev/null; then
head -5 "$2" | grep -e "^From: " -e "^Received: " >> /var/log/sms/incoming.txt
sed -e '1,/^$/ d' $2 | recode UCS-2..utf8 >> /var/log/sms/incoming.txt
echo "========================================" >> /var/log/sms/incoming.txt
else
head -5 "$2" | grep -e "^From: " -e "^Received: " >> /var/log/sms/incoming.txt
sed -e '1,/^$/ d' $2 >> /var/log/sms/incoming.txt
echo "========================================" >> /var/log/sms/incoming.txt
fi
;;
# События при исходящих SMS-сообщениях.
SENT)
# Проверяем кодировку тела исходящего SMS-сообщения.
# Если кодировка UCS, то перекодируем в UTF-8
if grep "Alphabet: UCS" $2 > /dev/null; then
sed -e '1,/^$/ d' $2 | recode UCS-2..utf8 >> /var/log/sms/send.txt
echo "========================================" >> /var/log/sms/send.txt
else
sed -e '1,/^$/ d' $2 >> /var/log/sms/send.txt
echo "========================================" >> /var/log/sms/send.txt
fi
;;
# События при получении ответа на USSD-запрос.
USSD)
;;
esac
Делаем скрипт исполняемым:
chmod +x /usr/local/sbin/sms_smshandler.sh
В скрипте для примера показано, как можно обрабатывать события и как перекодировать SMS-сообщение в читаемый вид, с последующей записью в файл.
Дальше только полет вашей фантазии, как вы будите использовать smstools. Лично я вижу в этом хороший инструмент для удаленного управления сервером, путем посыла SMS-сообщений с определенными командами. Так же можно заставить систему мониторинга (прим. Zabbix) отправлять уведомления в SMS-сообщении, что как мне кажется будет более надежным способом оповещения.
Дополнительно (возможные проблемы)
Опишу ситуации с которыми я столкнулся в ходе тестирования smstools.
Момент #1
На GSM-модеме Huawei e1550, smstools не получал входящие SMS-сообщения. Проблема оказалась в том, что smstools обращался по-умолчанию к памяти на SIM-карте (SM), а в параметрах GSM-модема было указано использование внутренней памяти (ME).
Посмотреть текущую настройку GSM-модема, можно командой (AT+CPMS=?
) выполненной в терминальном подключении к GSM-модема.
AT+CPMS=?
+CPMS: ("ME","SM"),("ME","SM"),("ME","SM")
Для решения данной проблемы, можно указать в файле конфигурации /etc/smsd.conf
, в секции описания GSM-модема (прим. [GSM1]), какой тип памяти использовать:
init = AT+CPMS="ME","ME","ME"
/etc/init.d/sms3 restart
)Так же рекомендую, найти какой нибудь старый телефон, который точно не будет подключатся к сети оператора и изменить IMEI GSM-модема на IMEI телефона. Теперь оператор будет видеть, что SMS-сообщения будут ходить через IMEI телефона.
Момент #2
Так же в логах smstools заметил что сыпется много сообщений вида:
2019-05-30 16:55:05,3, GSM1: Unexpected input: ^BOOT:43967939,0,0,0,20
2019-05-30 16:55:38,3, GSM1: Unexpected input: ^BOOT:43967939,0,0,0,20
2019-05-30 16:56:01,3, GSM1: Unexpected input: ^BOOT:43967939,0,0,0,20
2019-05-30 16:56:34,3, GSM1: Unexpected input: ^BOOT:43967939,0,0,0,20
2019-05-30 16:57:07,3, GSM1: Unexpected input: ^BOOT:43967939,0,0,0,20
2019-05-30 16:57:41,3, GSM1: Unexpected input: ^BOOT:43967939,0,0,0,20
2019-05-30 16:58:03,3, GSM1: Unexpected input: ^BOOT:43967939,0,0,0,20
На работу GSM-модема это никак не влияло, SMS успешно отправлялись и принимались, но не нравилось что лог-файл засоряется этими сообщениями. Решил данную проблему путем отключения вывода «boot
» сообщений.
В файле конфигурации /etc/smsd.conf
, в секции описания GSM-модема (прим. [GSM1]), указываем параметр:
init2 = AT^BOOT=0,0
Пользовательские комментарии
От пользователя Вася решение чтобы полученные СМС хранились в нормальной кодировке UTF-8, а не UCS.
В конфиге (обычно /etc/smsd.conf
) в основной секции добавить.
eventhandler=/usr/local/bin/smstools-eventhandler
Создаем исполняемый файл с именем /usr/local/bin/smstools-eventhandler
со следующим содержанием.
ConvertUCS2UTF(){
if sed -e ‘/^$/ q’ /dev/null; then
TMPFILE=`mktemp /tmp/smsd_XXXXXX`
sed -e ‘/^$/ q’ $TMPFILE
sed -e ‘1,/^$/ d’ > $TMPFILE
mv -f $TMPFILE $2
fi
}
case $1 in
SENT)
ConvertUCS2UTF «UCS» $2
;;
RECEIVED)
ConvertUCS2UTF «UCS2» $2
;;
FAILED)
# TODO: Action when failed to send message
;;
*)
# When unknown status is received, terminate the script with exit code 1
exit 1
;;
esac
exit 0
ПОНРАВИЛАСЬ ИЛИ ОКАЗАЛАСЬ ПОЛЕЗНОЙ СТАТЬЯ, ПОДДЕРЖИ АВТОРА ДОНАТОМ
Может кому пригодится такое решение:
В конфиге (обычно /etc/smsd.conf) в основной секции добавить
eventhandler=/usr/local/bin/smstools-eventhandler
Собственно, по указанному пути /usr/local/bin/ (или любому своему) создать исполняемый файл с именем smstools-eventhandler
А в него я вписал следующее, чтобы и отправленные и полученные СМС хранились в нормальной кодировке UTF-8, а не UCS
ConvertUCS2UTF(){
if sed -e ‘/^$/ q’ /dev/null; then
TMPFILE=`mktemp /tmp/smsd_XXXXXX`
sed -e ‘/^$/ q’ $TMPFILE
sed -e ‘1,/^$/ d’ > $TMPFILE
mv -f $TMPFILE $2
fi
}
case $1 in
SENT)
ConvertUCS2UTF «UCS» $2
;;
RECEIVED)
ConvertUCS2UTF «UCS2» $2
;;
FAILED)
# TODO: Action when failed to send message
;;
*)
# When unknown status is received, terminate the script with exit code 1
exit 1
;;
esac
exit 0
Спасибо, внесу ваше решение в статью, чтобы не потелялось!
Не могу читать входящие смс на кириллице. В incoming файлы с кодировкой ISO
Для истории оставлю тут правки:
1. вместо
init = AT+CPMS=»ME»,»ME»,»ME»
можно указать настройку
memory_start = 0
2. у меня модем спамит сообщениями типа
Unexpected input: +CREG: 1, 189D, 1CFDB33 +CGREG: 0
Unexpected input: ^RSSI:16
Чтоб это отключить надо в настройки добавить
init = AT^CURC=0
Спасибо, за дополнения 🙂
Спасибо, самый дружелюбный и полезный контент по теме.
Вместе со скриптом https://github.com/Shumaher/huawei-ussd
получилось самое комфортное решение.
Рад что помог!