Чтение смс at командами

Чтение смс at командами

Отправляем СМС-сообщение. а) Посылаем «AT+CMGS=»+79XXXXXXXXX»\r», получаем в ответ приглашение набрать текст сообщения — символ ‘>’. б) Отправляем текст. По окончании нужно отправить код комбинации клавиш Ctrl+Z (код 0x1A), только тогда модуль поймет, что текст набран и можно посылать сообщение адресату. в)Получаем «OK» — поздравляю, сообщение улетело.

Ниже пример функции отправки:

Общение с модулем при работе с СМС построено на индексах.
Каждому сообщению присваивается индекс, по нему мы указываем, какое сообщение прочитать/удалить.
При получении нового сообщения модуль уведомит отправкой в UART «+CMTI: «SM»,INDEX\r».
Значит в программе МК надо постоянно проверять приемный буфер на наличие данного сообщения, находить INDEX и сохранять его.

Можно упростить код разбора принятого сообщения с выделением его индекса если использовать библиотечную sscanf. Но дело в том, что sscanf и printf объемны и не всегда уместны во встраиваемых системах.

Зная индекс принятого сообщения, прочитать и удалить его не составит труда. Прочитать одно сообщение — «AT+CMGR=INDEX,0\r», второй параметр: 0 — обычный режим (по умолчанию) 1 — не изменять состояние сообщения. Получим ответ вида: «+CMGR: “REC UNREAD”,“+79XXXXXXXXX”, «» ,”DATE,TIME”\r\nMessage text\r\n\r\nOK» REC UNREAD — группа сообщений (см. ниже), DATE – дата формата YY/MM/DD, TIME – время в формате hh:mm:ss±hh.

Удалить одно сообщение по индексу — «AT+CMGD=INDEX\r».

Удалить сообщения по критерию — «AT+CMGD=INDEX,FLAG\r», где FLAG: 0 — удалить сообщение по индексу (по умолчанию) 1 — удалить все прочитанные сообщения 2 — удалить прочитанные и отправленные сообщения 3 — удалить прочитанные, отправленные и не отправленные сообщения 4 — удалить все сообщения. Исходя из вышеуказанного, удалить все сообщения — «AT+CMGD=1,4\r».

Прочитать группу сообщений — «AT+CMGL=”GROUP”\r», где параметр GROUP имеет следующие значения, числовое/текстовое: 0/REC UNREAD — все непрочитанные сообщения; 1/REC READ — прочитанные сообщения, 2/STO UNSENT — все не отправленные, 3/STO SENT — все отправленные, 4/ALL – все сообщения.

Отправляем СМС-сообщение. а) Посылаем «AT+CMGS=»+79XXXXXXXXX»\r», получаем в ответ приглашение набрать текст сообщения — символ ‘>’. б) Отправляем текст. По окончании нужно отправить код комбинации клавиш Ctrl+Z (код 0x1A), только тогда модуль поймет, что текст набран и можно посылать сообщение адресату. в)Получаем «OK» — поздравляю, сообщение улетело.

Ниже пример функции отправки:

Общение с модулем при работе с СМС построено на индексах.
Каждому сообщению присваивается индекс, по нему мы указываем, какое сообщение прочитать/удалить.
При получении нового сообщения модуль уведомит отправкой в UART «+CMTI: «SM»,INDEX\r».
Значит в программе МК надо постоянно проверять приемный буфер на наличие данного сообщения, находить INDEX и сохранять его.

Можно упростить код разбора принятого сообщения с выделением его индекса если использовать библиотечную sscanf. Но дело в том, что sscanf и printf объемны и не всегда уместны во встраиваемых системах.

Зная индекс принятого сообщения, прочитать и удалить его не составит труда. Прочитать одно сообщение — «AT+CMGR=INDEX,0\r», второй параметр: 0 — обычный режим (по умолчанию) 1 — не изменять состояние сообщения. Получим ответ вида: «+CMGR: “REC UNREAD”,“+79XXXXXXXXX”, «» ,”DATE,TIME”\r\nMessage text\r\n\r\nOK» REC UNREAD — группа сообщений (см. ниже), DATE – дата формата YY/MM/DD, TIME – время в формате hh:mm:ss±hh.

Удалить одно сообщение по индексу — «AT+CMGD=INDEX\r».

Удалить сообщения по критерию — «AT+CMGD=INDEX,FLAG\r», где FLAG: 0 — удалить сообщение по индексу (по умолчанию) 1 — удалить все прочитанные сообщения 2 — удалить прочитанные и отправленные сообщения 3 — удалить прочитанные, отправленные и не отправленные сообщения 4 — удалить все сообщения. Исходя из вышеуказанного, удалить все сообщения — «AT+CMGD=1,4\r».

Прочитать группу сообщений — «AT+CMGL=”GROUP”\r», где параметр GROUP имеет следующие значения, числовое/текстовое: 0/REC UNREAD — все непрочитанные сообщения; 1/REC READ — прочитанные сообщения, 2/STO UNSENT — все не отправленные, 3/STO SENT — все отправленные, 4/ALL – все сообщения.

В предыдущих статьях я рассказывал о формате PDU и отправке SMS-сообщений в этом формате. Тогда передо мной стояла задача именно отправлять SMS. Однако на днях задача стала обратной: принять сообщение, декодировать его и отправить на другой номер. Эдакая переадресация SMS. Программа была написана и успешно работает (подробнее об программе SMS-переадресации здесь: http://hardisoft.ru/news/programma-dlya-pereadresacii-sms-soobshhenij/)

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

Теория

Теоретическую часть о формате PDU, а так же ответы на «Главный вопрос жизни, вселенной и всего такого» можно посмотреть в предыдущих статьях цикла:

В этой же статье я не буду останавливаться на общей теории и перейду сразу к приему и декодированию результатов.

Работа с модемом

Прием SMS начинается с модема (в сотовом телефоне тоже есть модем). Модем управляется AT-командами. Рассмотрим кратко устройство модема и возможности получения оттуда SMS.

Режим PDU. Рекомендую перевести модем в PDU-режим перед всеми операциями командой AT+CMGF=0

Читайте также:  Ремонт холодильника тошиба gr l40r

Память. У GSM-модемов есть несколько видов памяти, в которых могут храниться SMS-сообщения. Честно говоря, зачем их столько я так и не выяснил, но раз уж есть – будем ковырять.

Память модема делится на три логических секции: первая для просмотра, чтения и удаления сообщений, вторая для сохранения и отправки исходящих сообщений и третья для только что полученных сообщений. В общем, тут все несколько запутано, но вторая и третья секции, в принципе, нас не интересуют. Обычно модем хранит полученные сообщения в первой секции.

Кроме логического деления на секции у модема еще есть несколько видов физической памяти: память SIM-карты, внутренняя память модема и прочее. Каждая физическая память назначается определенной логической секции. Таким образом можно назначить память SIM-карты для чтения и удаления сообщений, а память модема для написания и отправки. В общем, тут логика не совсем прослеживается, если кто-нибудь сможет объяснить такой зверинец более подробно – буду признателен.

Каждая область физической памяти имеет свое имя, для того, чтобы ей можно было оперировать в командах модема. Вот несколько возможных имен областей:

  • SM – Память SIM-карты
  • ME – Память модема/телефона
  • MT – Это общая память SIM-карты и модема, т.е. MT = SM+ME
  • BM – Память для широковещательных сообщений сети
  • SR – Память для отчетов (о доставке и т.п.)

Для чтения сообщений нам понадобится только SM и ME память, либо MT, которая включает в себя и SM и ME.

Учтите, любое чтение идет только из памяти, назначенной для первой секции. Это важно.

Для настройки памяти модема существует специальная AT-команда: AT+CPMS

Формат команды: AT+CPMS=message_storage1[,message_storage2[,message_storage3]]

Как видно из формата, вторую и третью секции памяти указывать не обязательно (они в квадратных скобках). Поэтому мы их указывать и не будем.

Итак. Нам нужно настроить первую секцию памяти (для чтения и удаления) и назначить ей соответствующую физическую область памяти. Делается это так:

AT+CPMS=”SM”, либо AT+CPMS=”ME”, либо AT+CPMS=”MT”.

Первый вариант указывает на то, что читать будем из SIM карты, второй – из памяти модема, третий – сразу из обоих. Рекомендую воспользоваться именно третьим вариантом.

В ответ на эту команду модем выдаст нечто вроде (ответ модема выделен жирным шрифтом):

+CPMS: 6,100,6,100,0,20

Цифры означают количество сообщений в памяти (например 6) и максимально допустимое количество сообщений (например 100) в каждой секции.

Узнать, какая область назначена для какой секции можно командой AT+CPMS?:

+CPMS: «MT»,6,100,»ME»,6,100,»SM»,0,20

Самое главное для чтения входящих сообщений – это первая секция, на остальные внимания не обращаем .

Чтение. Теперь, когда область памяти установлена, можно приступить к чтению сообщения.

Для чтения сообщений существует 2 команды: AT+CMGL и AT+CMGR. Разница их в том, что первая команда выдает сразу все сохраненные в памяти сообщения, а вторая – только одно сообщение, индекс которого передается ей в параметрах. Индекс начинается с нуля.

AT+CMGL

Синтаксис: AT+CMGL= , где – статус сообщения в памяти. Возможные статусы:

в текстовом режиме
в режиме PDU Пояснение
«REC UNREAD» Полученные непрочитанные сообщения
«REC READ» 1 Полученные прочитанные сообщения
«STO UNSENT» 2 Сохраненные неотправленные сообщения
«STO SENT» 3 Сохраненные отправленные сообщения
«ALL» 4 Все сообщения

AT+CMGR

Синтаксис: AT+CMGR= , где – индекс сохраненного сообщения.

Какой вариант выбрать? Решать вам. Я опишу лишь разницу: AT+CMGL позволят получить сразу все сообщения, причем можно выбрать по статусу — какие именно сообщения нас интересуют. AT+CMGR просто выдает нам указанное сообщение, не взирая на статус. Но нужно знать индекс сообщения.

В общем, в примере ниже, я использовал AT+CMGL=4 чтобы получить все сообщения, AT+CMGL=0 чтобы получить только непрочитанные и AT+CMGR=2 чтобы получить сообщение с индексом 2:

Пояснения к примеру:

AT+CMGF=0 – переходим в PDU режим

AT+CPMS=”MT” – Переключаем память SIM и модема на чтение сообщений

AT+CMGL=4 – Читаем все сообщения. Модем возвращает нам все содержимое памяти МТ. Формат такой: каждое сообщение начинается строкой +CMGL с параметрами:

Со следующей строки начинается, собственно, само сообщение в PDU формате. На рисунке терминал, для удобства, вывел его в несколько строк, хотя на самом деле модем передает его одной строкой. Вот это самое сообщение мы и будем декодировать. Следующее сообщение опять начинается строкой +CMGL и т.п. Идем далее.

AT+CMGL=0 – Читаем сообщение со статусом «REC UNREAD», т.е. не прочтенные. Здесь модем вернул просто ОК – это значит что непрочтенных сообщений нет. Если бы были – он бы их вывел в том же формате, что и до этого.

AT+CMGR=2 – Получение одного сообщения с индексом 2. Ответ начинается с +CMGR и параметров:

И со следующей строки опять-таки идет PDU.

Примечание: указанные параметры команд и ответов на команды справедливы только если включен PDU-режим командой AT+CMGF=0. Если модем работает в текстовом режиме, то параметры команд и возвращаемый ими результат отличаются от вышесказанного. Учтите этот нюанс. Мы работаем в режиме PDU, желающих разобраться с текстовым режимом отсылаю к литературе. От себя скажу, что преимуществ у текстового режима нет никаких.

Читайте также:  Как на айпаде обрезать видео

Как видим, сложного ничего нет, приступаем к декодированию текста сообщения.

Ковыряем PDU

Итак, читать из модема сообщения научились, теперь будем их декодировать. Начнем с простого. Возьмем для примера такое сообщение:

Что в переводе на русский язык означает “Hello World!” 🙂

Разберем его по косточкам:

TP-SCA (Service Centre address) – Адрес сервис-центра, отправившего сообщение.

Нам оно без надобности, но для проформы разберем: первый байт (07) – длина номера, в данном случае длина равна 7 байт. Следующий байт (91) – Тип номера, в данном случае 91 – международный, Следующие 6 байт – сам номер СЦ, дополненный до четности символом F и переставленными местами парами цифр. Подробнее об этом я писал в статье про отправку SMS, там это детально разжевано.

TP-MTI & Co (Message Type indicator и компания) – важный байт, состоящий из различных флагов, разберем его состав подробнее:

Биты
Описание
0
1
Message Type indicator (TP-MTI)
2 More messages to send (TP-MMS)
3
4
5 Status report indication (TP-SRI)
6 User data header information (TP-UDHI)
7 Reply path (TP-RP)

TP-MTI – Эти два бита определяют тип SMS. Причем трактовка этих битов зависит от “направления” SMS, т.е. от того, отправляется она или принимается. Вот табличка, описывающая доступные типы сообщения

Бит 1
Бит 0 СЦ –> модем Модем –> СЦ
SMS-DELIVER SMS-DELIVER REPORT
1 SMS-STATUS REPORT SMS-COMMAND
1 SMS-SUBMIT REPORT SMS-SUBMIT
1 1 RESERVED RESERVED

TP-MMS (More Messages to Send) — Этот бит информирует принимающую сторону, есть ли еще сообщения, ожидающие в сервис центре. Если бит равен нулю — значит в СЦ еще есть сообщения для доставки. Если 1 — значит в СЦ больше сообщений нет. В нашем случае этот бит равен 1, значит в СЦ больше нет сообщений для нашей SIM-карты

TP-SRI (Status Report Indication) — Этот бит показывает, будет ли отправлен отчет о состоянии отправителю. 0 — не будет, 1 — будет. Этот бит относится к биту TP-SRR (Status Report Request) в байте SMS-SUBMIT при отправке. Для чтения сообщения он не пригодится.

TP-UDHI (User Data header Indicator) — Этот бит показывает, что содержит блок TP-UD (User Data). Если бит равен 1 — то блок User Data содержит еще и блок User Data Header, в добавок к сообщению. Если ноль — то блок User Data содержит только сообщение. Для нас это важный бит, поскольку дополнительный блок User Data Header применяется для длинных SMS, в нем содержится информация о количестве частей в SMS и номер текущей части .

TP-RP (Reply Path) — Путь для ответа. Это бит говорит, что от принимающего запрашивается ответ. Если путь ответа запрашивается, отвечающее мобильное устройство может попытаться использовать тот же СЦ, что и отправитель, для более надежной доставки ответа. 1 — запрашивается, 0 — не запрашивается

Возвращаясь к нашему примеру и учитывая вышесказанное, анализ байта TP-MTI & Co (04) говорит нам о том, что это принятое SMS (TP-MTI=0,0 — SMS-DELIVER), что на станции больше нет для нас сообщений (TP-MMS=1) и что это одиночная SMS, а не часть длинной (TP-UDHI=0)

TP-OA (THE Originating Address) – Адрес отправителя сообщения. Это поле составное:

  • 1 байт (в нашем случае 0B) – длина номера отправителя
  • 1 байт (в нашем случае 91) – Формат номера
  • n байт – непосредственно сам номер

Длина номера: указывается количество цифр в номере, если это обычный номер телефона или количество полубайт, если это текстовый формат номера в 7-битной кодировке.

Формат номера . Тут тоже не все так просто:

Бит
Значение
0
1
2
3
Идентификатор плана нумерации
4
5
6
Тип номера
7 Всегда = 1

Рассмотрим тип номера:

Биты
6 5 4
Значение
0 0 0 Неизвестно. Сотовая сеть не знает, что за формат у номера
0 0 1 Международный формат номера
0 1 0 Внутренний номер страны. Префиксы страны у номера отсутствуют
0 1 1 Служебный номер сети. Сервисный, другими словами. Используется оператором.
1 0 0 Номер подписчика. Используется, когда определенное представление короткого номера сохранено в одном или нескольких СЦ как часть более высокоуровневого приложения
1 0 1 Буквенно-цифровой, закодированный в 7-битной кодировке
1 1 0 Сокращенный номер
1 1 1 Зарезервировано

Нас интересует всего 2 типа номера: 001 и 101 , остальное непонятно 🙂 и либо не применяется, либо применяется редко, либо ведет к ожирению 🙂

Далее — идентификатор плана нумерации. Применяется для типов номеров 000, 001, 010 и 101. Нет смысла рассматривать все, так как в сотовых сетях применяется всего 2 плана:

1) для типа номера 101 (буквенно-цифровой) идентификатор плана нумерации всегда 0000

2) для остальных типов идентификатор плана нумерации всегда 0001

Непосредственно сам номер — может быть двух видов, либо набор цифр, например “79101234567”, либо текст, например “InternetSMS”. На вид указывает тип номера из предыдущего байта.

Читайте также:  Kingston hyperx genesis khx1600c9d3k2 8g

Цифровой номер кодируется по стандартной схеме кодирования номеров, о ней можно прочитать в первой части (Отправка SMS-сообщений в формате PDU, теория с примерами на C#, часть 1).

Текстовый номер – просто строка текста, сжатая в 7-битную кодировку.

Как уже говорилось, длина номера – это либо количество цифр, либо количество полубайт . Т.е. для номера 79101234567 длина будет равна 11 (0B, как в примере), а для номера “InternetSMS” – 20 (14H). Почему 20? Потому, что «InternetSMS» (без пробела) это 11 символов. В 7-битной кодировке они упакуются в 11*0.875 = 9.625 байт. Умножаем на 2 чтобы получить полубайты, получаем 19.25. Округляем в большую сторону, т.е. в 20 полубайт.

Для ясности, разберем еще один пример с текстовым номером: 09D0D432BB2C03. Здесь 09 — длина(9 полубайт), D0 — формат номера. А дальше — сам номер (длиной 5 байт, т.е. 10 полубайт!) По нормальному это «Tele2». 5 символов. При кодировании получается 5*0.875 = 4.375. Умножаем на 2 чтобы получить полубайты, получаем 8.75. Округляем в большую сторону — 9 полубайт. Но полубайтами мы не оперируем, поэтому номер в действительности не 9, а 10 полубайт, т.е. 5 байт. Маразм, но с этим ничего не поделаешь 🙂

Итак, вернемся к нашему примеру: у нас поле TP-OA = “0B 91 9701119905F8”. 0B – в номере 11 цифр или символов, 91 — международный формат номера, цифры то есть. Далее – 9701119905F8 – непосредственно сам номер. Пары переставлены местами, до четности дополнен символом F, все по схеме кодирования номера. Получается, номер отправителя 7-910-119-95-08.

TP-PID (Protocol identifier) – Идентификатор протокола. В случае отправки SMS с телефона/модема на телефон/модем данный байт всегда будет равен 00. Для тех кому интересно, что же это поле означает, могу ответить, что оно описывает высокоуровневые протоколы или сетевые устройства, куда должна быть отправлена, или откуда пришла SMS. Другими словами, Сервисный Центр оператора сотовой связи может поддерживать дополнительные услуги, такие как конвертирование SMS в e-mail, отправка SMS на пейджер, телекс. В этом случае данное поле указывает на что-то типа шлюза, через который пойдет SMS дальше и превратится уже не в SMS а в тыкву… В общем, нам это поле не нужно.

У нас TP-PID как и положено равен 00

TP-DCS (Data coding scheme) – Схема кодирования данных. Описывает, как закодирована наша SMS, т.е. поле TP-UD. Для тех кто не хочет заморачиваться, опишу только то, что нам пригодится: 00 — 7-битная сжатая кодировка, 08 — UCS2, 10 и 18 — то же, только сообщение класса 0, т.е. Flash. Желающим узнать про это поле подробнее, могу персонально объяснить из чего оно состоит.

TP-DCS в нашем примере = 00, что означает простое сообщение в 7-битной кодировке.

TP-SCTS (The service centre time stamp) – Штамп времени сервисного центра. Проще говоря, это время, когда СЦ получил SMS, т.е. время отправки. Данное поле составляет 7 байт, которые означают следующее:

Причем в каждом байте цифры переставлены местами, как и в номерах СЦ и отправителя. Видимо разработчики пережили в детстве тяжелую психологическую травму …

Применительно к нам данное поле можно декодировать так: 21106232015061 = Год: 12, Месяц: 01, День: 26, Час: 32, Минута: 01, Секунда: 05, Временная зона: 16.

TP-UDL (User Data Length) — длина пользовательских данных, включая User Data header, если он есть. Если SMS закодирована 7-битной кодировкой, то данное поле указывает количество символов в сообщении. Если кодировка UCS2 – то поле указывает количество байт в сообщении.

В нашем примере TP-UDL = 0C, т.е. 12 в десятичном счислении. Поскольку TP-DCS в нашем примере = 00, что означает простое сообщение в 7-битной кодировке, значит сообщение содержит 12 символов. Так и есть, в сообщении “Hello World!” 12 символов. Однако, если посчитать количество байт сообщения (поле TP-UD), то их будет 11 а не 12, сказывается сжатие при 7-битной кодировке. Этот момент важно учитывать.

TP-UD (User Data) – Поле пользовательских данных. Здесь находится сам текст сообщения. В случае, если SMS длинная, т.е. разбита на несколько сообщений, данное поле начинается с заголовка TP-UDH. На наличие этого заголовка указывает бит TP-UDHI поля TP-MTI & Co. По поводу поля TP-UDH я подробно писал здесь: http://hardisoft.ru/soft/otpravka-dlinnyx-sms-soobshhenij-v-formate-pdu/ , пункт “2. Теория поля UDH”, так что здесь повторяться не буду.

У нас TP-UD = “C8329BFD065DDF72363904”, что после декодирования 7-битной кодировки дает нам искомое “Hello World!”

The Конец

Вот, в принципе, вся премудрость. Особо сложного ничего нет, если въехать до конца, то процесс получения SMS достаточно прост. Получение длинных SMS тоже достаточно просто, нужно только дополнительно учитывать поле TP-UDH.

С удовольствием отвечу на вопросы по данной теме, если она кому-то интересна.

«>

Ссылка на основную публикацию
Чем открыть файл html на компьютере
Автор: Юрий Белоусов · 21.11.2018 Каждый вебмастер знает, что такое HTML: это – язык гипертекстовой разметки, с помощью которой создается...
Фотоаппарат сони dsc h50
Название объектива : Carl Zeiss Vario-Tessar Количество групп оптических элементов : 8 Количество оптических элементов : 13 Цифровой Zoom :...
Фотоаппараты до 10000 рублей рейтинг
На российском рынке представлено настолько много фотоаппаратов и камер, что найдется модель на любой вкус. В том числе есть действительно...
Чем открыть файл mtf тесты
�������� (����.): ���� ����� MyTest �������� (���.): ���� ����� MyTest ��������: MTF ��� ���� ����� MyTest ������������ ����� ������ �����,...
Adblock detector