The Apple Geek

Чему ты научился сегодня?

Переадресация SMS с помощью SMSTools

Интернет на iPhone - неблагодарная вещь. Захочешь не обращать внимание на трафик на iPhone и возьмёшь большой пакетный тариф (1 GB) - потратишь деньги, а израсходуешь 70 MB. Захочешь сэкономить и возьмёшь пакетный тариф поменьше (Киевстар, 100 MB) - и окажется, что в этом месяце чаще находишься “в поле” и трафик заканчивается 10-го числа. Именно это у случилось в прошлом месяце.

Пришлось “изголяться” и ставить в iPhone служебную карточку, чего я делать не люблю - предпочитаю разделять рабочее и личное использование мобильной связи.

Всё было бы неплохо - Интернет на новой карточке есть, голосовые вызовы я перенаправил. Но вот SMS… На мой номер приходят уведомления о транзакциях по 4-м дебитовым картам, на него же пишут SMS друзья и коллеги. И если внутри сети Киевстар есть возможность переадресации SMS, то на другого оператора включить её невозможно.

Пытался раз в день переставлять SIM-карту, но это быстро надоело. И тут родилась идея. Smstools. Я подумал, что можно настроить UMTS-модем как SMS-шлюз на приём сообщений.

Была лёгкая сложность - в iPhone 4 стоит MicroSIM, а в модем ставится обычная miniSIM. Сначала думал купить специальный адаптер, но потом прошёлся по радиорынку и там нашлось отличное решение. Продавцы, торгующие iPhone 4 и iPad 3G, не вырезают microSIM вручную, а обычно пользуются специальными резаками под названием “SIM Card Cutter”:

Эти резаки вырезают MicroSIM, а внешняя часть остаётся нетронутой. И вот в эту внешнюю часть, остающуюся после обрезки miniSIM, можно поставить MicroSIM:

и вставить эту конструкцию в модем

С этим разобрался. Модем у меня хороший - USB Novatel Wireless Ovation MC930D. Правда iPhone 4 мне использовать гораздо удобнее в качестве модема.

Подключил модем к ноутбуку, убедился, что мой “miniSIM-бутерброд” работает.

Дальше из исходников компилирую SMSTools (в Homebrew его нет, а ставить MacPorts не хочу из-за повышенного количества хлама).

$ mkdir ~/tmp
$ cd ~/tmp
$ curl http://smstools3.kekekasvi.com/packages/smstools3-3.1.14.tar.gz -o smstools3-3.1.14.tar.gz
$ tar xvfz smstools3-3.1.14.tar.gz 
$ cd smstools3
$ make
$ sudo make install
Installing binary program files
  /usr/local/bin/smsd
Installing some scripts
  /usr/local/bin/sendsms
  /usr/local/bin/sms2html
  /usr/local/bin/sms2unicode
  /usr/local/bin/unicode2sms
Installing config file
  /etc/smsd.conf
Creating minimum spool directories
  Skipped /var/spool, directory already exists
  Creating directory /var/spool/sms
  Creating directory /var/spool/sms/incoming
  Creating directory /var/spool/sms/outgoing
  Creating directory /var/spool/sms/checked
Installing start-script
  I do not know where to copy scripts/sms3. Please find out yourself.

$ sudo mkdir /var/spool/sms/{failed,sent}

Настраиваю:

$ sudo vim /etc/smsd.conf 
devices = Kyivstar
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 = 7
receive_before_send = no
autosplit = 3
#eventhandler = /etc/smsd/trsms.sh

[Kyivstar]
device = /dev/cu.wwanCMD
incoming = yes
rtscts = no
cs_convert = no
baudrate = 115200
init = AT+CPMS="SM","SM","SM"
check_memory_method = 31
smsc = 380672021111
baudrate = 115200

[Utel]
device = /dev/cu.wwanCMD
incoming = yes
rtscts = no
cs_convert = no
baudrate = 115200
init = AT+CPMS="SM","SM","SM"
check_memory_method = 31
smsc = 380910440601

Пока eventhandler я закомментировал. Обратите внимание на параметры init и check_memory_method.

Всё работало и с дефолтовыми параметрами, но в один момент я перестал получать сообщения. При разборке оказалось, что используются не те области памяти для SMS, а кроме того когда эти области заполняются, то сообщения не принимаются и об этом никаких сообщений нет. Решение было найдено.

Для моего модема используется Message Storage Area SM (внутренняя), и это я описал в init. Чтобы узнать это, я подключился к модему через screen (процесс я описывал раньше) и выполнил команду:

$ screen /dev/cu.wwanCMD
AT+CPMS=?
+CPMS: ("SM","SR"),("SM","SR"),("SM","SR")

Поэтому в init я прописал AT+CPMS=”SM”,”SM”,”SM”. Выход из screen: ‘Ctrl+a’, потом нажать букву ‘k’ и ответить ‘y’.

С check_memory_method было всё неочевидно. В принципе предыдущий шаг не нужен при значении 31, но я оставил init как есть. Как только я поставил 31, то сообщения стали приходить нормально.

Запускаю smsd:

$ sudo /usr/local/bin/smsd 
$ ps ax | grep smsd
 6469   ??  Ss     0:00.00 /usr/local/bin/smsd
 6470   ??  R      0:00.25 /usr/local/bin/smsd

Как остановить процесс:

$ sudo killall smsd

Смотрю лог:

$ sudo cat /var/log/smsd.log 

Смотрю на входящие сообщения:

$ sudo cat /var/log/smsd.log | grep incoming
2011-03-13 21:03:59,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.Duxzib
2011-03-13 21:04:00,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.FDdP9O
2011-03-13 21:04:01,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.BLXri0
2011-03-13 21:04:02,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.4gEyCi
2011-03-13 21:04:03,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.5OfeoH
2011-03-13 21:04:06,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.u5C6WN
2011-03-13 21:04:07,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.6KlTu8
2011-03-13 21:04:08,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.mxmpEX
2011-03-13 21:04:09,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.j564Hx
2011-03-13 21:04:10,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.26sbI4
2011-03-13 21:04:11,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.14HjjV
2011-03-13 21:04:12,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.XfmL6l

Отравляю себе сообщение:

$ sudo sendsms +38067xxxxxxx "Test"; sudo tail -f /var/log/smsd.log 
2011-03-13 21:06:56,7, GSM1: -> AT+CMGS=18
2011-03-13 21:06:56,7, GSM1: Command is sent, waiting for the answer
2011-03-13 21:06:56,7, GSM1: <- >
2011-03-13 21:06:56,7, GSM1: -> 0011000C918390117112660000FF04D4F29C0E
2011-03-13 21:06:56,7, GSM1: Command is sent, waiting for the answer
2011-03-13 21:07:00,7, GSM1: <- +CMGS: 58 OK
2011-03-13 21:07:00,5, GSM1: SMS sent, Message_id: 58, To: 380911172166, sending time 8 sec.
2011-03-13 21:07:00,6, GSM1: Moved file /var/spool/sms/checked/send_QgKq9h to /var/spool/sms/sent/send_QgKq9h

Тут я привёл не совсем правильный лог - он был сгенерирован при дефолтовом init. Но суть от этого не меняется.

Сообщение пришло:

$ sudo tail -f /var/log/smsd.log | grep "incoming message file"
2011-03-13 21:16:46,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.zp0Y32

Содержимое SMS:

$ cat /var/spool/sms/incoming/GSM1.zp0Y32
From: 38067xxxxxxx
From_TOA: 67 international, ISDN/telephone
From_SMSC: 380672021111
Sent: 11-03-13 21:16:13
Received: 11-03-13 21:16:46
Subject: GSM1
Modem: GSM1
IMSI: 255xxxxxxxxx
Report: no
Alphabet: GSM
Length: 8

Test

Это был английский текст. С русским похуже:

$ cat /var/spool/sms/incoming/GSM1.KW5aeu
From: 380xxxxxxxxx
From_TOA: 67 international, ISDN/telephone
From_SMSC: 380672021111
Sent: 11-03-13 21:15:02
Received: 11-03-13 21:15:17
Subject: GSM1
Modem: GSM1
IMSI: 255xxxxxxxxx
Report: no
Alphabet: UCS2
Length: 8

@>25@:0

”@>25@:0” - это текст на русском в кодировке UCS2. Кодировка? Значит iconv.

Текст начинается с 13-й строки, его я и передаю на вход iconv, преобразовывая в UTF-8:

$ tail +13 /var/spool/sms/incoming/GSM1.z1B8nr | iconv -f UCS-2 -t UTF-8
Проверка

Всё, SMS готов к обработке. Я решил записывать их в файл с помощью “eventhandler = /etc/smsd/trsms.sh”. Раскомментариваю эту строку в /etc/smsd.conf, создаю скрипт:

$ sudo mkdir /etc/smsd
$ sudo vim /etc/smsd/trsms.sh
#!/bin/bash
status="$1"
file="$2"

case "$1" in
  RECEIVED)
    FILE=`mktemp /tmp/smsd_XXXXXX`

    head -12 $file | grep -e "^From: " -e "^Sent: " -e "^Received: " >> /var/tmp/sms.log
    if grep "Alphabet: UCS2" $file >/dev/null; then
       tail +13 $file | iconv -f UCS-2 -t UTF-8 >> /var/tmp/sms.log
    else
       tail +13 $file >> /var/tmp/sms.log
    fi
    echo >> /var/tmp/sms.log
    echo >> /var/tmp/sms.log
    ;;
esac

Не забываю сделать скрипт исполняемым:

$ sudo chmod +x /etc/smsd/trsms.sh

Перезапускаю демона, слежу за логом:

$ sudo killall smsd
$ sudo /usr/local/bin/smsd
$ sudo tail -f /var/log/smsd.log

Кстати, если вы выдернули модем и потом вставили его обратно, то нужно перезапустить процесс, программа не подхватывает сама подключаемый модем.

Отправляю пару сообщений, одно с английским текстом, другое - с русским. Вуаля - сообщения в моём файле:

From: 38067xxxxxxx
Sent: 11-03-13 22:18:28
Received: 11-03-13 22:19:05
Проведенный тест

From: 38067xxxxxxx
Sent: 11-03-13 22:19:12
Received: 11-03-13 22:19:26
Test

Задача решена, входящие SMS пишутся в лог.

Но вот незадача - ноутбук я не всегда ношу с собой, модем держать постоянно воткнутым неудобно. Поэтому я сделал следующий шаг. Перенёс всё на постоянно включённую рабочую станцию под Ubuntu 10.10 и добавил очень удобную функцию - кроме записи в лог теперь SMS отсылаются мне на почту.

Установка проще:

$ sudo aptitude install smstools

Конфиг тот же. А eventhandler /etc/smsd/trsms.sh я усовершенствовал. Кстати, под Ubuntu не работает конструкция “tail +13”, вместо неё нужно писать “tail -n +13”.

#!/bin/bash
status="$1"
file="$2"

case "$1" in
  RECEIVED)
    FILE=`mktemp /tmp/smsd_XXXXXX`

    header=`head -12 $file | grep -e "^From: " -e "^Sent: " -e "^Received: "`
    from=`head -12 $file | grep -e "^From: " | awk '{print $2}'`

    if grep "Alphabet: UCS2" $file > /dev/null > /dev/null; then
                message=`tail -n +13 $file | iconv -f UCS-2BE -t UTF-8`
        else
                message=`tail -n +13 $file`
        fi
        echo -e "$message" | mail -s "Incoming SMS from +$from" email@gmail.com
        echo -e "$header\n$message\n" >> /var/log/sms.log
    ;;
esac

SMS отослан, SMS получен и практически мгновенно оно появляется в моём почтовом ящике. Суперудобно. В таком режиме система у меня проработала 20 дней без замечаний.

Следующим шагом я настроил мониторинг работы модема через Zabbix, там тоже было несколько интересных приёмов. Но писать уже лень, хватит.

Засим разрешите откланяться.

P.S. Эта статья была написана благодаря i-Store.ru. Если она вам оказалась полезна, то зайдите на магазина.

Comments