Как послать flash-SMS?

    Flash-SMS – такая SMS, текст которой сразу выводится на экран телефона/смартфона пользователя вместо записи в память устройства. Пользователь её читает и решает, сохранять её в памяти или нет.

    Для отправки flash-SMS потребуется использовать так называемый режим PDU — Packet Data Unit. Это режим, который позволяет контролировать все секретные параметры SMS, описанные в ETSI GSM Technical Specification GSM 03.40.
    Для доступа к PDU рекомендуется использовать любой GSM-модем или модуль. Некоторые старые телефоны в режиме модема это тоже умели, а по поводу современных смартфонов ничего сказать не могу, ибо не знаю.
    Я использовал GSM-модуль Neoway M660, но для модемов/модулей других производителей это должно быть также справедливо.



    В режиме PDU SMS-сообщение представляет собой набор данных, передаваемых модему в виде символов ASCII.
    Давайте рассмотрим формат передаваемого SMS-сообщения, последовательность команд, подаваемых на GSM-модем, а также сформируем пакет PDU и пошлем flash-SMS «Привет, Хабр!» на гипотетический номер +70123456789.

    Формат передаваемого SMS-сообщения в режиме PDU



    изображен на картинке:

    Название поля PDU Длина, байт Краткое описание
    SCA, Service Center Address 1-12 Номер телефона Центра SMS (может не указываться)
    PDU Type Тип PDU
    MR, Message Reference 1 Порядковый номер сообщения, устанавливаемый самим модемом/модулем
    DA, Destination Address 2-12 Номер телефона получателя сообщения
    PID, Protocol Identifier 1 Идентификатор протокола
    DCS, Data Coding Scheme 1 Кодировка сообщения
    VP, Validity Period 0,1 или 7 Время жизни SMS
    UDL, User Data Length 1 Длина поля User Data в байтах
    UD, User Data 0-140 Сообщение

    Итак, рассмотрим назначение отдельных полей пакета PDU передаваемого сообщения.

    1. SCA (Service Center Address) — номер телефона Центра SMS (SMSC).
    Данное поле не является обязательным, так как номер SMSC хранится на SIM-карте и считывается GSM-модулями Neoway автоматически. Воспользуемся этой возможностью и не будем указывать номер Центра SMS в нашем примере, тем более, что в этом случае содержимое PDU не зависит от используемой SIM-карты. Если номер SMSC в PDU не указывается, поле SCA принимает значение 0x00.
    Но если вам всё же захочется считать номер Центра SMS из GSM-модуля, вы всегда можете это сделать с помощью команды AT+CSCA?..

    2. PDU Type – тип PDU



    2.1 RP (Reply Path)
    0 — путь для ответа не определен,
    1 – путь для ответа определен, используется тот же Центр SMS (SMSC).

    2.2 UDHI (User Data Header Included):
    0 – поле UD содержит только само сообщение,
    1- поле UD содержит сообщение и дополнительный заголовок.

    2.3 SRR (Status Report Request):
    0 – статус сообщения не запрашивается,
    1- статус сообщения запрашивается.

    2.4 VPF (Validity Period Format):
    00 – поле VP отсутствует,
    01 – зарезервировано,
    10 – поле VP содержит времянные данные в относительном формате,
    11 – поле VP содержит времянные данные в абсолютном формате.

    2.5 RD (Reject Duplicates):
    0 – SMSC следует переслать сообщение получателю в случае, если оно имеет те же значения полей MR и DA, что и предыдущее сообщение.
    1 — SMSC следует отклонить сообщение в случае, если оно имеет те же значения полей MR и DA, что и предыдущее сообщение.

    2.6 MTI (Message Type Indicator):
    00 – принимаемое сообщение (от SMSC к модулю) или подтверждение приема (от модуля к SMSC)
    01 – отправляемое сообщение (от модуля к SMSC) или подтверждение отправки (от SMSC к модулю),
    10 – отчет о доставке (от SMSC к модулю) или SMS-команда (от модуля к SMSC)
    11 – зарезервировано.

    С целью упрощения поле VP (время жизни SMS, см. п. 7) использовать не будем и установим биты VPF в нулевое значение. Также в нулевое значение установим биты RP, UDHI, SRR, RD. Биты MTI отправляемого сообщения необходимо установить в значение 01. Таким образом значение байта поля PDU Type принимаем равным 0x01.

    3. MR (Message Reference) – порядковый номер сообщения, определяется самим модулем. В PDU значение поля устанавливается равным 0x00.

    4. DA (Destination Address) – номер телефона получателя сообщения.
    Поле DA состоит из трёх частей и имеет следующий вид:
    Количество цифр в номере получателя Тип номера получателя Номер получателя
    1 байт 1 байт 0…6 байт

    4.1 Количество цифр в номере получателя подсчитывается без учета знака «+» и представляется в шестнадцатеричном формате.
    Например, для номера +70123456789 значение байта «Количество цифр в номере получателя» равняется 0x0B (11 в десятичной системе счисления).

    4.2 Тип номера получателя.
    В случае международного формата номера байт «Тип номера получателя» устанавливается равным 0x91, в случае местного формата – 0x81.

    4.3 Номер получателя.
    Поле «Номер получателя» формируется следующим образом:
    а) в случае международного формата номера знак «+» отбрасывается;
    б) если количество цифр в номере нечетное, в конце добавляется «F»;
    в) цифры номера попарно переставляются местами.

    Например, для номера +70123456789 поле «Номер получателя» будет иметь вид: 0721436587F9, а целиком поле DA – 0B910721436587F9.

    5. PID (Protocol Identifier) – идентификатор протокола.
    В нашем случае значение поля PID необходимо устанавливать в значение 0x00.
    Подробнее об особенностях данного поля можно прочитать в ETSI GSM 03.40, пункт 9.2.3.9.

    6. DCS (Data Coding Scheme) – кодировка сообщения.
    Вот это и есть то самое поле, которое нас больше всего сейчас интересует! Для отправки сообщений кириллическими символами необходимо использовать кодировку UCS2.
    Значение поля DCS в нашем случае следует установить равным 0x18 – это и есть секретная комбинация, позволяющая отправить flash-SMS кириллическими символами (0x08 – обычное SMS).

    7. VP (Validity Period) – время жизни сообщения.

    Время жизни сообщения – время, по истечении которого сообщение уничтожается (стирается из памяти Центра SMS), если не было доставлено адресату.
    Это поле связано с битами VPF поля PDU Type, существует три варианта их совместного использования.

    7.1 Поле VP не используется (помните, мы договаривались, что и не будем его использовать в нашем примере?).
    В этом случае длина поля VP — 0 байт, биты VPF должны быть установлены в значение 00 (как мы уже и сделали).

    7.2 Поле VP содержит данные о времени жизни в относительном формате.
    В этом случае длина поля VP — 1 байт, биты VPF должны быть установлены в значение 10 (в двоичной системе).
    Возможные значения поля VP в случае использования относительного формата времени и формулы для расчета соответствующего времени жизни сообщения приведены в следующей таблице:
    Значение VP шестнадцатеричное Значение VP десятичное Соответствующее значению VP время Максимальное время жизни
    1..8F 0… 143 (VP + 1) * 5 минут 12 часов
    90..A7 144… 167 12 часов + (VP – 143)*30 минут 24 часа
    A8..C4 168… 196 (VP – 166) * 1 день 30 дней
    C5..FF 197… 255 (VP – 192) * 1 неделю 63 недели

    7.3 Поле VP содержит данные о времени жизни в абсолютном формате.
    В этом случае длина поля VP — 7 байт, биты VPF должны быть установлены в значение 11(в двоичной системе).
    Назначение байт в поле VP при использовании абсолютного формата времени преведено в этой таблице:
    1-й байт 2-й байт 3-й байт 4-й байт 5-й байт 6-й байт 7-й байт
    Год Месяц День Час Минуты Секунды Часовой пояс

    При этом каждый байт содержит по два десятичных числа, переставленных местами. Например, байт 2 в случае месяца мая будет иметь значение 0x50.
    Год представлен последними двумя цифрами.
    Часовой пояс указывает разницу между местным временем и временем по Гринвичу (GMT), выраженную в четвертях часа. При этом первый бит указывает знак этой разницы: 0 – разница положительная, 1 – разница отрицательная. То есть байт 7 в случае часового пояса GMT+3 будет иметь значение 0x21.

    Так как мы решили не использовать поле VP и установили два бита VPF поля PDU Type в значение 00, то в пакете PDU нашего примера поле VP будет отсутствовать.

    8. UDL (User Data Length) – длина поля UD в байтах.
    В случае использования интересующей нас кодировки UCS2 значение поля UDL можно вычислить, умножив количество символов в передаваемом сообщении на 2 (каждый символ кодируется двумя байтами). Для сообщения «Привет, Хабр!» поле UDL равно 0x1A (26 в десятичной системе).

    9. UD (User Data) – сообщение
    Для отправки сообщения кириллицей необходимо использовать кодировку UCS2, в этой кодировке каждая буква или символ кодируется двумя байтами.
    Таблица кодировки UCS2 — тут
    Сообщение «Привет, Хабр!» в кодировке UCS2 будет выглядеть так:
    П: 041F
    р: 0440
    и: 0438
    в: 0432
    е: 0435
    т: 0442
    ,: 002C
    : 0020
    Х: 0425
    а: 0430
    б: 0431
    р: 0440
    !: 0021

    Привет, Хабр!: 041F04400438043204350442002C002004250430043104400021

    Процесс отправки SMS-сообщения


    Как только пакет PDU сформирован, процесс отправки SMS не представляет труда и состоит из двух простых шагов:

    1. Ввод команды отправки SMS с указанием количества байт в пакете PDU за исключением поля SCA. Звучит не очень дружелюбно, но если не используется номер Центра SMS, то поле SCA равно 0x00 (как у нас) и это число равно количеству байт в пакете PDU минус один. Для «Привет, Хабр!» эта величина — 39:

    AT+CMGS=39

    Важно, чтобы эта команда завершалась символом '\r' (0x0D), без добавок.
    После этого GSM-модем выдает приглашение '>' ввести данные пакета PDU.

    2. Ввод данных пакета PDU.
    В случае сообщения «Привет, Хабр!» пакет PDU выглядит так:
    0001000B91хххххххххххх00181A041F04400438043204350442002C002004250430043104400021 (в текстовом виде),

    где хххххххххххх – поле номера получателя, у которого переставлены местами цифры и добавлен символ «F» на конце в случае нечетного количества цифр в номере (как описано раньше).
    Для номера +79123456789 поле номера получателя будет иметь вид: 9721436587F9,
    а весь пакет PDU с сообщением «Привет, Хабр!», отправляемый на этот номер:
    0001000B919721436587F900181A041F04400438043204350442002C002004250430043104400021

    Ввод данных пакета PDU должен заканчиваться байтом 0x1A

    В случае успешной отправки SMS-сообщения модем ответит:

    +CMGS: Message_Reference
    OK


    где Message_Reference — порядковый номер сообщения, установленный модемом (см. описание поля MR пакета PDU).
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 23

      +7
      Ожидал скриншёт телефона с такой смс в конце поста…
        0
        Хорошая идея) Соберусь — сделаю!
        +3
        Когда занимались прошивкокопательством на старых сименсах, тоже делали подобную фишку. Но потом операторы начали резать такие смс, исправляя их на обычные. Это решение на каких операторах проверено?
          0
          Проверял на картах МТС, Мегафон — такого не заметил. А какие операторы SMS-ки таким образом резали?
            0
            Билайн резал точно, у меня их симка была. Про остальных не вспомню — врать не буду.
              0
              МТС, Билайн в 2008 или 2009 начал резать, когда появилось приложение для симбиана которое отправлялось такие смс. МегаФон принимал. Но с тех пор думал операторы закрыли данный метод доставки.
                +1
                у билайна есть этот их вонючий хамелеон, за который с превеликим удовольствием бы морду набил. Ибо нажатие на любую клавишу, отличную от отбоя трубки ведет (вело) к ответу, а следовательно к краже денег со счета.
                  +1
                  У меня в Nokia 3720 в списке типов отправляемых сообщений flash был штатно и это точно работало в Билайне еще в начале 2013, в Москве. Отправлял тоже на Билайн.
              0
              Из старых телефонов Ericsson R320 точно умел посылать такие SMS.
                0
                На МТС такие можно слать с помощью СМС-Экстра: меняете SMS-центр на +7 916 896 02 20, потом шлете ON на 147, и flash можно отправлять в формате
                *<пробел>текст

                Там еще некоторые печеньки есть, вроде отправки с защитой или по расписанию, но это уже не так актуально.
                Можно еще на андроиде приложением ZeroSMS такие сообщения слать, но у меня оно не работало.
                  0
                  Flash-SMS, было дело. Надо было написать SMS-шлюз, использовал эту библиотеку, в ней не было этой функции, помог добавить.
                    0
                    Для отправки сообщения кириллицей необходимо использовать кодировку UCS2, в этой кодировке каждая буква или символ кодируется двумя байтами.

                    На самом деле, можно отправить в кодировке koi8 или windows-1251, точно не помню. Помню, у оператора Golden Telecom был сайт, на котором можно было выбрать кодировку. Если выбиралась 8-битовая, то SMS кириллицей можно было писать 140 символов :)
                      0
                      Закономерный вопрос: и как его поймет телефон? Все таки родная кодировка для мобильников — юникод, причем без вариантов, поскольку только в него можно запихнуть все основные языки.
                        0
                        Про все телефоны не скажу, но, как минимум, Sony Ericsson J300, K750, K800, W580 — отлично понимали когда тестировал.
                      +1
                      Сейчас такие смс присылает Тинькофф с кодами верификации (допустим я недавно менял лимит по расходу и мне такая смс пришла).
                      Раньше можно было в смс написать: [текст смс] и приходила такая флешь смс.
                        +1
                        Это у вас его приложение стоит. Обычные смски он присылает.
                          0
                          Вот Сити раньше точно без всяких приложений flash SMS присылали, сейчас вроде на обычные перешли.
                        +6
                        4.3 Номер получателя.
                        Поле «Номер получателя» формируется следующим образом:
                        в) цифры номера попарно переставляются местами.
                        Каждый раз натыкаясь на что-нибудь подобное в спеках, я улыбаюсь. Прям так и вижу инженеров писавших стандарт: «А вот тут мы добавим немного сумасбродства, такой, легкий диссонанс, ведь спеки это же джаз!»
                          0
                          Во, у меня тож вопрос возник — в чем смысл такого преобразования?
                            0
                            Полагаю, какое-то наследие от big endian\little endian.
                              +1
                              Индианы это порядок байтов, а тут полубайты.
                              0
                              Это для упрощения обработки в железе.
                              Насколько я помню, какой то алгоритм преобразования из двоично-десятичного в двоичное дает обратный порядок нибблов. А если их заранее переставить, то преобразование становится проще.
                            +1
                            Как же забыли про такую чудесную программку PDUSpy www.nobbi.com/pduspy.html которая позволяет конструировать SMS в PDU-формате?

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                            Самое читаемое