Отправка SMS с 3G/GSM модема
Рождение идеи
Всё началось с того, что в одной небольшой сети магазинов возникла необходимость ежедневно информировать начальство о выручке по каждому магазину за день. В центральном офисе скапливается информация о продажах, её то и нужно донести до начальника. Ген.дир. (заказчик) — человек очень занятой, и как директору ему необходимо своевременно получать данные о выручке магазинов, интернет порой недоступен, а мобильник всегда под рукой, вот и было решено отправлять ему на телефон SMS с данными о выручке по каждому магазину, в простом и читабельном виде.
Пример SMS:
08.11.2011
1.Магазин A, 123045 р.
2.Магазин B, 134520 р.
3.Магазин C, 215403 р.
. ;
Как выяснилось в последующем это ещё не всё что требуется, но об этом чуть позже.
Сначала было предложено отправлять SMS через гейт, коих сейчас великое множество. Но заказчик сразу же отверг это предложение из соображений безопасности, ибо данные о дневной выручке — вещь довольно конфиденциальная. Затем было решено отправлять SMS просто с телефона подключенного к компу по USB кабелю, а в итоге и вовсе вместо телефона был задействован USB модем который уже давненько валялся без дела.
С чего начать
С COM портом конечно работать приходилось, а вот общаться с модемом по средствам AT команд, до этого как то не доводилось. AT команд конечно довольно много, но всё оказалось гораздо проще чем я ожидал, т.к. для нашей цели потребовались всего 5 команд:
AT+CMGF — задаёт режим работы: 0-цифровой или 1-текстовый. Эта команда будет вызываться первой, от этого зависит формат последующих команд и ответов модема.
AT+CMGS — отправка сообщения, формат параметра сильно зависти от режима (т.е. от прошлой команды).
AT+CMGL — чтение сообщений с модема, в качестве параметра можно передать одно из пяти значений, стоит обратить внимание что в зависимости от режима (AT+CMGF) следует передавать цифровые или строковые значения:
AT+CMGD — удаление одного сообщения с модема, в качестве параметра передаём номер сообщения.
AT+CMGR — чтение одного сообщения с модема, так же передаём номер сообщения.
Первые результаты
После нескольких часов (проб/ошибок) выяснил, что отправить SMS сообщение с модема ненамного сложнее чем сделать это с обычного мобильного телефона. Как уже упоминалось выше, для отправки SMS следует использовать команду «AT+CMGS». И так, открыл hyperterm, подключился к модему (через COM порт), и настрочил в порт следующие команды:
Пример того же самого на Delphi:
Вуаля, и карманный девайс сообщил о ожидаемом событии.
Но увы положительные эмоции возникшие у меня в момент этого успеха продлились недолго, а если точнее до того момента когда было обнаружено что с русским текстом всё гораздо сложнее. Во первых для отправки сообщений на русском нужно переключить режим с текстового на цифровой (AT+CMGF=0), а во вторых само сообщение должно быть отправлено в кодировке UCS2. И если с первым проблем минимум, то со вторым пришлось повозиться.
Кодировка текста в UCS и обратно (опять таки на Delphi):
Не скажу что всё получилось сразу и легко, но всё же получилось. Если раньше я отправлял в модем:
то для того чтобы отправить сообщение на русском нужно будет отправить:
Сначала переключение режима (в цифровой), затем отправляется длинна сообщения (84), а последняя строка содержит: номер телефона, текст сообщения и различные настройки (такие как: номер SMS-центра, сохранять ли сообщение у получателя и др.).
Пример на Delphi:
Развитие идеи
Сказать что я был счастлив когда на мобилу пришёл долгожданные русский текст, вместо «кракозябр», значит не сказать ничего. На следующий день дописал основную часть программы, и вроде бы всё. Сообщения с данными о выручке отправляются на телефон заказчику, вроде бы и жизнь то удалась, но не тут то было. Где то через неделю заказчик попросил доработать приложение, а именно сделать так чтобы после того как ему пришло SMS с текстом:
08.11.2011
1.Магазин A, 123045 р.
2.Магазин B, 134520 р.
3.Магазин C, 215403 р.
.
он бы мог в ответ на это сообщении отправить номер магазина и пришло бы новое сообщение, но уже с более детальной информацией по указанному магазину.
Ну в общем то логика простая: программа должна хранить последней отправленный «отчёт» по всем магазинам и читать входящие сообщения, как только появляется сообщение с условным текстом (например «магазин=12»), вытаскивать от туда номер магазина, смотреть в последнем отправленном сообщении что было под этим номером и отправлять детальную информацию по этому магазину (к сожалению на данный момент заказчик так и не определился с форматом и содержанием «подробного отчёта», так что в качестве примера привести нечего). Для реализации вышеупомянутой логики от модема требуется: прочитать SMS из памяти, удалить SMS из памяти (чтобы не скапливались). Для чтения сообщений использовал команды AT+CMGR и AT+CMGL (их краткое описание приводилось ранее). Чтение всех сообщений будет выглядеть как:
Здесь всё проще чем было раньше. Каждое сообщение состоит из 2х строк, в первой содержатся данные о сообщении (такие как: от кого, когда, номер сообщения), а во второй сам текст сообщения (опять таки в кодировке UCS, функция UCSToAnsi приводилась выше). Чтение одного сообщение осуществляется как:
Аналогичным образом происходит и удаление сообщений. Если например в моём случае отправить команду AT+CMGD=7, то при следующем AT+CMGL=«ALL» я уже не увижу сообщение номер 7, т.к. оно будет удалено.
Заключение
И так, были разобраны основные команды для работы с SMS сообщениями через GSM модем, была рассмотрена отправка, чтение, удаление сообщений. На последок хотелось бы отметить что область применения такого использования SMS сообщений довольно широка (особенно потому что можно организовать двухстороннюю связь). Например так: пользователь отправляет SMS, модем принимает, наша программа считывает, выполняет какие то действия исходя из текста сообщения и отправляет пользователю результата. Или наоборот: на ПК происходит какое то событие, и программа отправляет пользователю сообщение об этом событии. Удачи вам в ваших экспериментах, спасибо!
Работа с СМС на роутерах R-серии
В роутерах R-серии есть несколько способов отправки смс для различных ситуаций. Рассмотрим три способа отправить смс с помощью роутера.
Способ №1: отправка смс из пункта меню Send SMS.
В данном способе все просто, перейдите в раздел Tools => Send SMS и заполняете поле Recipient Phone Number номером телефона получателя SMS, а в поле Message вписываете желаемый текст и нажимаете кнопку Send.
Одновременно можно отправить смс только на один номер телефона.
Способ №2: отправка смс по событию на GPIO порту.
В разделе меню Tools => GPIO есть возможность настроить цифровые порты ввода-вывода на реагирование изменения их состояния с отправкой смс на указанный номер. Реагировать роутер может либо только на появление напряжения на указанном порту, либо только на пропажу напряжения, либо на оба этих события. Регулируется данный выбор в столбце — Trigger.
Способ №3: отправка смс посредством web api роутера.
Как работает api роутера для отправки смс:
для отправки сообщения необходимо выполнить POST запрос по протоколу HTTP на адрес роутера к URI /api/sendsms и передать в теле запроса JSON объект вида:
,где:
«recipient» — номер получателя,
«message» — текст сообщение.
Данные необходимо передавать в кодировке utf-8.
В ответ роутер сообщит об отправке сообщения JSON-объектом вида:
«result» — результат отправки: ok или fail
пример работы через утилиту curl:
Для операционных систем семейства WINDOWS так же есть утилита curl*, но вот синтаксис команды выглядит по другому :
Принимаем и отправляем СМС при помощи GSM-модема
Содержание статьи
СМС — технология не новая, но она все еще широко распространена. При помощи копеечного GSM-модема можно принимать и отправлять сообщения в свое удовольствие. Нужно всего лишь изучить систему его команд или установить софт, который позволит обойтись без этого.
Давно обещанный «интернет вещей» не так далек, как может показаться. Правда, футуристические статьи, рисующие напичканную датчиками технику, редко касаются одного важного вопроса: каким образом информация с этих датчиков достигает сервера? Если они находятся в доме — это одно дело. А если датчики установлены, скажем, на грузовом автомобиле или вообще в чистом поле? Ответ есть: зачастую информацию с датчиков собирает специальный контроллер, который затем передает ее на сервер по СМС. Тут, впрочем, возникает другой вопрос: как построить сервер, способный взаимодействовать с такими устройствами?
СМС и набор команд Hayes
Современная мобильная связь только кажется вещью в себе. Если смотреть на нее с верной точки зрения, быстро выясняется, что у навороченных смартфонов немало общего со старенькими «Курьерами» и «Спортстерами». И те и другие поддерживают так называемый набор команд Hayes.
Ветераны индустрии помнят замысловатые инициализационные строки, которые приходилось скармливать модему перед подключением к BBS или узлу Фидо. Каждая такая строка — это примитивная программа, составленная из команд Hayes для настройки модема.

Хакер #195. Атаки на Oracle DB
Модемы, для которых была разработана первая версия набора команд Hayes, не отличались богатыми возможностями. Кроме настроечных команд, имелись команды, которые позволяли набирать телефонные номера, устанавливать соединение, а затем вешать трубку.
За прошедшие с тех пор тридцать пять лет многое поменялось. Расширенный набор команд, который используется сегодня, фактически можно рассматривать как своеобразный программный интерфейс (API), при помощи которого можно управлять мобильным телефоном.
Каким образом это сделать? Сначала необходимо подключить GSM-устройство к компьютеру. Для автоматического обмена СМС удобнее взять не смартфон, а сотовый модем: он не нуждается во взломе, дешевле стоит и не требует проводов. Подойдет обычный 3G-модем, купленный в ближайшем салоне связи за тысячу рублей.
Перед использованием модема или смартфона на компьютер должны быть установлены необходимые драйверы. А вот софт для выхода в интернет, который часто прилагается к модемам, для нашей задачи не только не потребуется, но даже вреден. Если он захватит доступ к устройству, мы не сможем до него достучаться. Вместо этого нам потребуется UNIX-совместимая ОС и минимальное умение работы с командной строкой.
Первым делом наш путь лежит в каталог /dev/. Где-то в его недрах прячется файл подключенного устройства. Говорящее имя поможет идентифицировать его если не напрямую, то методом исключения. 4G-модем «Мегафон M100-4», использованный автором для опытов, обнаружился на пути /dev/tty.HUAWEIMobile-Pcui. Попробуем связаться с ним при помощи утилиты screen.
Теперь можно узнать, что же мы нашли. Для получения информации об устройстве служит команда ATI. Ответ следует немедленно:
Ценным открытием, что под личиной модема «Мегафон М100-4» скрывается Huawei E3276, сыт не будешь. Пора обратиться к более интересным задачам. При помощи команд Hayes можно ввести пин-код (AT+CPIN=»0000″), выяснить силу сигнала (AT+CSQ) или набрать один из служебных номеров — например, узнать баланс (ATD102#, где 102# — это номер).
Большинство устройств принимают команды в одном из двух режимов. По умолчанию, как правило, включен режим PDU (Protocol Data Unit), который требует указывать аргументы в цифровой форме. Чтобы не разучивать еще один шифр, лучше перейти в текстовый режим. Для этого служит команда AT+CMGF=1 (нулевое значение вернет устройство в режим PDU).
Следующая настройка, о которой следует позаботиться, — это режим кодирования. Дело в том, что текстовые сообщения могут быть составлены только из цифр, латинских букв и знаков препинания. Символы, которые не входят в классическую семибитную таблицу ASCII, не поддерживаются.
Для пересылки сообщений, которые написаны на алфавитах, не уместившихся в ASCII, придуман обходной путь: текст переводят в кодировку UTF-16, а затем заменяют каждый символ четырехзначным шестнадцатеричным кодом.
Поддерживает ли наше устройство этот способ? Это можно проверить при помощи команды AT+CSCS=?
Ответ модема содержит список поддерживаемых режимов кодирования. Режим GSM здесь соответствует чистому семибитному ASCII. IRA нам тоже не поможет — это так называемый International Reference Alphabet, малоизвестная международная разновидность ASCII. А вот UCS2, один из ранних вариантов UTF-16, — это именно то, что нужно. Стоит заметить, что иногда подходящий вариант, подразумевающий замену символов Unicode шестнадцатеричными цифрами, называется HEX, — все зависит от модели и производителя.
Теперь следует активировать нужный режим:
В некоторых случаях для работы с кириллицей может понадобиться настройка DCS — схемы кодирования данных. Для этого служит команда AT+CSMP. Значение четвертого аргумента должно быть равно восьми:
Есть два основных способа отправки текстовых сообщений при помощи команд Hayes. Первый реализует команда AT+CMGS. Чтобы отправить сообщение, нужно дать ей телефонный номер адресата и нажать Enter. Все, что будет введено далее, рассматривается как текст сообщения. Закончить ввод текста можно при помощи сочетания клавиш Ctrl + z.
Перед отправкой сообщения на русском языке придется позаботиться о его перекодировании. Это можно сделать при помощи любого скриптового языка. Вот, например, вариант на Python:
Теперь можно отправлять:
Второй способ состоит из двух шагов. Первый шаг потребует команды AT+CMGW. Она очень похожа на AT+CMGS, но не отправляет сообщение, а сохраняет его в памяти SIM-карты. На втором шаге сохраненную СМС отправляет другая команда — AT+CMGS. Чтобы отправить сообщение, нужно знать его номер. К примеру, команда отправки сохраненного сообщения под номером 12 выглядит так:
Этот способ удобен в тех случаях, когда один и тот же текст нужно доставить нескольким адресатам. Вместо того чтобы каждый раз передавать его устройству, достаточно один раз сохранить сообщение в памяти, а затем указывать модему лишь его индекс и номер получателя.
Команда удаления сообщения тоже принимает на входе его номер:
Покончив с отправкой, займемся приемом. Устройство самостоятельно принимает и сохраняет текстовые сообщения, поэтому задача сводится к извлечению СМС из памяти SIM-карты.
Сообщения хранятся в нескольких папках с разным назначением. Полный список выдаст команда AT+CMGL=?
Смысл папок понятен по их названиям: одна из них содержит прочтенные СМС, другая — непрочтенные, две другие — отправленные и неотправленные. Наконец, последняя называется ALL и позволяет увидеть все сообщения без фильтрации по папкам. Этим тоже занимается команда AT+CMGL.
Шестнадцатеричными цифрами закодирован не только текст сообщения, но и имя отправителя. Попытаемся расшифровать первое сообщение. Здесь снова поможет Python:
Время от времени диалог с модемом прерывается сообщениями, которые представляют собой не ответы на введенные команды, а уведомления о внешних событиях. Модемы используют код +CMTI, чтобы сообщить о приеме нового сообщения, а код +CDSI уведомляет о статусе отправляемого СМС.
Gammu и Gammu SMS Daemon
До сих пор мы общались с модемом в интерактивном режиме при помощи терминала. На практике это взаимодействие должно быть полностью автоматизировано. Это не проблема: открыть файл /dev/tty.HUAWEIMobile-Pcui программно ничуть не труднее, чем любой другой. Трудность может состоять в другом. Если планируется поддерживать более одной модели модема, придется разбираться в особенностях и капризах каждой.
Непосредственное управление при помощи команд Hayes — это хороший вариант, когда модем один, его модель известна, тонкости никого не волнуют, а все взаимодействие можно описать парой-тройкой строк кода. Когда запросы выше, стоит обратить внимание на одно из готовых средств для работы с телефонами и модемами.
В этом случае может подойти набор утилит командной строки Gammu — развитие известного в прошлом проекта Gnokii, избавленного от, увы, устаревшей ориентации на продукцию Nokia. Список поддерживаемых Gammu телефонов и GSM-модемов не ограничивается устройствами одного производителя. В нем, впрочем, все же имеются пробелы, поэтому вопросами совместимости лучше озаботиться заранее.
Gammu позволяет извлекать списки принятых и инициированных звонков, открывать телефонные соединения и управлять ими, просматривать телефонные книги, изучать информацию о телефоне и сотовой сети и многое другое, вплоть до работы со встроенным FM-приемником. Разумеется, прием и отправка СМС и MMС тоже входит в список умений этой программы.
Для установки Gammu под OS X следует воспользоваться командой brew install gammu (требуется пакетный менеджер brew). Под Linux поможет apt-get install gammu gammu-smsd или ее эквивалент для другого пакетного менеджера. Пользователям Windows придется отыскать и скачать инсталлятор на сайте проекта.
Работа с Gammu начинается с настройки. Проще всего это сделать при помощи утилиты, которая запускается командой gammu-config. Она поинтересуется «портом» (в нашем случае сюда попадает уже знакомый путь /dev/tty.HUAWEIMobile-Pcui), типом и скоростью соединения, моделью (если ничего подходящего нет, стоит выбрать at — в этот тип входит любое устройство, поддерживающее набор команд Hayes) и запросит несколько менее интересных деталей. Введенная информация будет сохранена в настроечном файле
/.gammurc, который при необходимости можно отредактировать в любом текстовом редакторе.

Здесь тоже возможны проблемы с кодировками, но их решение проще и прямолинейнее. Чтобы русский язык не вызывал у Gammu паники, в системе должна быть верно настроена локаль и язык. Для этого в OS X и Linux стоит добавить в инициализационный файл (например,
/.bash_profile) следующие строки:
Дальше будет проще. Для отправки сообщения служит команда gammu sendsms TEXT . Сам текст сообщения нужно направить команде по механизму pipes. Это упрощает отправку по СМС текста, который является результатом работы другой программы.
В Gammu предусмотрено несколько способов чтения сообщений, но для того, чтобы рассмотреть их все, здесь просто нет места. Ограничимся одной, самой простой командой. Она выводит все СМС, хранящиеся в памяти устройства.
Нередко вместо выполнения команды Gammu жалуется на проблемы. Ошибка «Error opening device. Unknown, busy or no permissions» может свидетельствовать о том, что соединение с модемом захватила какая-то другая программа. Возможен и другой вариант: GSM-модемы, как оказалось, не отличаются крепкими нервами и под градом команд склонны виснуть. Чтобы привести их в чувство, устройство приходится вытаскивать из порта USB и затем втыкать снова.
Еще один важный компонент Gammu — это SMS Daemon, программа, которая одним махом решает три четверти задачи построения сервера для взаимодействия по СМС. SMS Daemon работает в фоне, поддерживает контакт с модемом и при получении сообщения выполняет заданные действия. К слову, с перезагрузкой подвисшего модема он тоже справляется.
Настройка SMS Daemon — относительно сложная задача, требующая ручного редактирования настроечного файла. В нем должен появиться блок [smsd], содержащий настройки сервиса хранения СМС и, если это необходимо, задающий путь к обработчику получаемых сообщений.
Сервис хранения СМС ценнее всего. SMS Daemon способен автоматически записывать полученные сообщения в базу данных (поддерживаются среди прочего SQLite, MySQL, PostgreSQL и MS SQL) или складывать в виде файлов в специальную папку.
Обработчик представляет собой программу или скрипт пользователя, автоматически запускаемый после приема сообщения. Информация передается обработчику через переменные окружения. Переменная SMS_MESSAGES содержит число полученных сообщений, значение SMS_1_NUMBER соответствует телефонному номеру отправителя, а SMS_1_TEXT — тексту сообщения.
SMS Daemon можно использовать и для отправки сообщений, хотя это несколько выбивается из круга его обязанностей. Это делается при помощи команды gammu-smsd-inject, действующей в точности как gammu send-sms.
Интернет-шлюзы СМС
Есть и другой, более радикальный способ избавиться от необходимости нянчиться с капризными железками, а именно: переложить все заботы на плечи специально обученных людей и платить им, чтобы они страдали за тебя. Крупнейший международный сервис такого рода называется Twillio. В России автоматизированный прием и передачу текстовых сообщений можно наладить при помощи сервиса «SMS-центр».
Для отправки сообщений через smsc.ru служит простой программный интерфейс в стиле REST. Все необходимые параметры передаются сервису в виде запроса по GET или POST, а тот возвращает результаты его обработки. Вот пример команды, требующей отправить по телефону 79299999994 текст «Привет», переданный в кодировке UTF-8, и сообщить о результатах в формате JSON (fmt=3).
Добавление к этому запросу аргумента cost=1 вынудит сервис подсчитать стоимость отправки такого сообщения (отправления при этом не произойдет). А аргумент flash=1 придает обычному текстовому сообщению зрелищности: оно будет продемонстрировано получателю немедленно, в каком бы приложении он ни находился и чем бы ни занимался.
Некоторые тонкости есть и тут. Во-первых, пароль. Чтобы не гонять его по интернету в открытую, лучше заменить пароль хешем MD5. «SMS-центр» допускает такой вариант. Во-вторых, Sender-ID. Операторы недоверчиво относятся к сообщениям безымянных отправителей и то и дело отказываются их доставлять. Эту проблему можно решить, воспользовавшись подписью Sender-ID, которая принадлежит «SMS-центру», либо зарегистрировав свою собственную.
Для приема СМС в сервисе предусмотрено два метода: Push и Pull. В первом случае пользователь может время от времени сам запрашивать пришедшие сообщения у сервиса. Принцип тот же, что и при отправке:
Чтобы не скачивать каждый раз все сообщения от начала времен, к запросу можно добавить аргумент after_id и передавать в нем идентификационный номер последнего полученного СМС.
Во втором случае можно поручить «SMS-центру» при получении сообщений самостоятельно уведомлять об этом веб-сервис пользователя. Для этого на нем должен быть реализован соответствующий обработчик информации. Выглядеть он может, к примеру, так:
Напоследок стоит упомянуть, что далеко не всякая автоматизированная рассылка СМС легальна. По закону, отправитель рекламных сообщений должен заручиться согласием получателя и быть готовым доказывать свою правоту. Абонент, не желающий получать СМС, должен быть немедленно исключен из списков рассылки. Кроме того, есть длинный список запретных тем. От порно, наркотиков, терроризма и других предсказуемых вещей лучше держаться подальше. В противном случае можно нарваться на блокировку телефонного номера, штрафы, а то и кое-что похуже. Тебе это надо?






