Отправка коротких сообщений (SMS) через сотовый телефон, подключенный к компьютеру
Недавно я приобрел телефон Ericsson
R320s. В комплекте поставлялось стандартное программное обеспечение,
которое, как выяснилось, не было приспособлено для отправки русскоязычных
коротких сообщений (SMS). И я решил написать программу отправки сообщений
в кодировке UCS-2 (кириллические сообщения отправляются именно в нем).
Кодировка сообщения описана в стандарте ETSI GSM 03.38, а структура
в ETSI GSM 03.40, хотя большую часть информации я получил из руководства
разработчика, написанного Siemens для владельцев S-серии телефонов "sms_pdumode.pdf".
Существует 2 типа сообщений: текстовые и PDU (Protocol Data Unit).
В общем, это одно и то же, просто в режиме отправки текстовых сообщений
Вы не сможете передавать русские буквы и, вообще, буквы не английского
алфавита (греческие и др.), поскольку программное обеспечение телефона
не будет их преобразовывать в формат PDU. Поэтому сразу начнем рассмотрение
передачи сообщений в режиме PDU.
Будем различать принятые и исходящие сообщения.
Формат принятого сообщения:
|
1-12 байт
|
1 байт
|
2-12 байт
|
1 байт
|
1 байт
|
7 байт
|
1 байт
|
0-140 байт
|
|
SCA
|
PDU-type
|
OA
|
PID
|
DCS
|
SCTS
|
UDL
|
UD
|
Биты поля PDU-type называются так:
|
|
RP
|
UDHI
|
SRI
|
|
|
MMS
|
MTI
|
|
биты
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
Поле MTI должно быть таким: бит 0 = 0, бит 1 = 0.
Формат исходящего сообщения:
|
1-12 байт
|
1 байт
|
1 байт
|
2-12 байт
|
1 байт
|
1 байт
|
0, 1 или 7 байт
|
1 байт
|
0-140 бай
|
|
SCA
|
PDU-type
|
MR
|
DA
|
PID
|
DCS
|
VP
|
UDL
|
UD
|
Биты поля PDU-type называются так:
|
|
RP
|
UDHI
|
SRR
|
VPF
|
RD
|
MTI
|
|
биты
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
MTI должно быть таким: бит 0 = 1, бит 1 = 0.
Все неиспользуемые биты нужно установить в 0.
Названия и назначение полей:
| SCA |
номер SMSC (СМС-сервером) |
| PDU-type |
поле данных протокола |
| MR |
количество успешно переданых (0..255) сообщений с телефона |
| OA |
телефон отправителя |
| DA |
телефон получателя |
| PID |
идентификатор протокола: указывает SMSC, как обрабатывать сообщение |
| DCS |
схема кодирования данных в поле данных |
| SCTS |
время получения сообщения SMS-сервером |
| VP |
время действия сообщения (если сообщение не будет получено абонентом
в течение этого времени, SMSC его не будет передавать) |
| UDL |
длина поля данных |
| UD |
поле данных |
| RP |
указывает на наличие поля ответа |
| UDHI |
указывает на наличие заголовка в поле UD |
| SRI |
требование принимающегополучить статус сообщения |
| SRR |
требование отправителя получить статус сообщения |
| VPF |
флаг наличия поля VP |
| MMS |
количество неотправленных сообщений в SMSC |
| RD |
удалить дубликаты |
| MTI |
тип сообщения: если 00 - входящее, 01 - исходящее |
Важно!
Все поля подразумевают то, что они шестнадцатиричные (кроме битовых).
Но в телефон они отправляются в виде символов. Т.е. если поле имеет
значение 41H, то передаются два символа: 34H ("4") и 31H ("1").
SCA
| Длина поля - 1 байт |
Тип номера - 1 байт |
Номер от 0 до 6 байт |
- Длина содержит байт, указывающий длину номера SMSC + 1 байт типа
этого номера.
- Тип номера может быть или 81H - национальный, или 91H - международный.
Но лучше использовать 91H с нашими Московскими операторами.
- Поле номера кодируется следующим образом: каждая пара цифр меняется
местами. Если количество цифр нечетно, тогда в конец номера дописывается
0xF.
Например, для Московского БИЛАЙН'а номер SMSC: +790173100 Поле SCA
будет выглядеть так: 069197103701F0
Если параметр длина поля = 0, тогда телефон должен взять номер SMS
из своих настроек. А поскольку уверенным в правильности этого номера
быть нельзя, как, впрочем, и в том, что Ваша модель телефона сработает
именно так, лучше всегда здесь указывать номер SMSC.
PDU
- RP: установим его в 0
- UDHI: установим его в 0
- SRI: (устанавливаетя в SMSC)
- SRR:=Установим в 0
- VPF: Установим в 00
- MMS: (устанавливается в SMSC)
- RD: Установим=в 0
- MTI: Описано выше
Поле MR формируется в SMSC, но нужно что-либо там хранить, например
0x0.
OA и DA
Формируются аналогично полю SCA.
Пример:
Если нужно записать национальный номер (в Москве сообщение по такому
номеру не дойдет), 1234567 преобразуется в 0781214365F7.
PID
Сообщает транспортному уровню, какой протокол высшего уровня должен
обрабатывать это сообщение.
Некоторые возможности:
- 00H: обычное сообщение
- 41H: замещать сообщение типа 1
- 42H: замещать сообщение типа 2
- 43H: замещать сообщение типа 3
- ......
- 47H: замещать сообщение типа 7
DCS
Фактически нужны только два варианта поля+флажок вывода на экран:
- 80H: кодировка UCS2 (70 знаков);
- 00H: кодировка 7-бит (160 знаков, но не кириллическая).
Если при этом указать, что старший полубайт равен FH, то сообщение
будет выводиться сразу на экран, как в старой системе БИ+GSM (т.н. Flash-SMS).
Причем сообщение будет отображаться на экране независимо от кодировки,
если Ваш аппарат поддерживает UCS2 (например, Нокия Логоменеджер не
умеет отправлять Flash-SMS на русском языке).
Т.е. для Flash-SMS:
- F8H: кодировка UCS2 (70 знаков);
- F0H: кодировка 7-бит (160 знаков, но не кириллическая).
UDL
Длина поля данных в байтах. Собственно, если сообщение состоит из одного
символа UCS2, то его длина - 2 байта, а если из одного символа в 7-битной
кодировке - один байт.
UD
Начнем с UCS2. Сама кодировка повторяет Unicode. Т.е. для английских
символов просто однобайтовой кодировки добавляется байт 00H. Для русских
(те, что начинаются с C0H в Windows-кодировке) можно создать такое правило:
Из байта вычитается C0H и прибавляется 410H (кроме букв "ё"
и "Ё", которые в Unicode имеют коды 0451H и 0401H соответственно).
Точное описание кодировок можно увидеть здесь: http://www.webclub.ru/content/markup_refs/article-40.html
7-битная кодировка. Английские буквы этой кодировки по кодам не отличаются
от восьмибитной. Русских букв нет.
Упаковка 160 символов в 140 байт производится следующим образом.
Первый байт записывается так:
старший бит берется из младшего бита 2-го байта, 7 остальных бит -
биты первого символа.
Второй байт записывается так:
два старших бита берутся из младших разрядов 3-го байта, а шесть младших
- из оставшихся битов второго символа и т.д.
Пример: кодирование слова hellohello
Семибитная запись 10 букв:
|
h
|
e
|
l
|
l
|
o
|
h
|
e
|
l
|
l
|
o
|
|
68
|
65
|
68
|
68
|
6F
|
68
|
65
|
68
|
68
|
6F
|
|
1101000
|
1100101
|
1101100
|
1101100
|
1101111
|
1101000
|
1100101
|
1101100
|
1101100
|
1101111
|
Девять восьмибитных байтов со словом hellohello:
|
1
1101000
|
00
110010
|
100
11011
|
1111
1101
|
01000
110
|
100101
11
|
1101100
1
|
1
1101100
|
110111
|
|
E8
|
32
|
9B
|
FD
|
46
|
97
|
D9
|
EC
|
37
|
В следующей таблице представлена псевдорусская кодировка, которую я
предлагаю для телефонов, не поддерживающих кириллицу.
|
А
|
Б
|
В
|
Г
|
Д
|
Е
|
Ё
|
Ж
|
З
|
и
|
й
|
К
|
Л
|
М
|
Н
|
О
|
П
|
Р
|
С
|
Т
|
У
|
Ф
|
Х
|
Ц
|
Ч
|
Ш
|
Щ
|
Ъ
|
Ы
|
Ь
|
Э
|
Ю
|
Я
|
|
A
|
6
|
B
|
G
|
D
|
E
|
Й
|
*
|
З
|
u
|
щ
|
K
|
L
|
M
|
H
|
O
|
P
|
P
|
C
|
T
|
Y
|
F
|
X
|
_
|
_
|
W
|
_
|
_
|
Ы
|
Ь
|
_
|
_
|
_
|
|
41
|
36
|
42
|
05
|
06
|
45
|
C9
|
2A
|
33
|
75
|
F9
|
4B
|
08
|
4D
|
48
|
4F
|
0B
|
50
|
43
|
54
|
59
|
0F
|
58
|
|
|
|
57
|
|
626C
|
62
|
|
|
|
Такая кодировка позволяет отображать на экранах аппаратов Motorola,
Siemens (модели младше S25) и других, не понимающих формат UCS2, почти
русские сообщения. К сожалению, не все символы русского языка можно
передать таким кодом.
Как передать или принять сообщение через телефон
Для этого Ваш телефон должен поддерживать AT+C команды. Описание практически
всех команд Вы можете просмотреть в руководстве Siemens для владельцев
S-серии телефонов
, я же приведу только те из них, которые нужны для отправки и приема
сообщений.
Передача сообщения:
В COM-порт, к которому подключен телефон, нужно отправить строчку:
"AT+CMGS", дождаться отклика в виде символа ">"
и передать сформированное сообщение в COM-порт. Если передача информации
в телефон происходит успешно, то телефон откликнется строкой "OK".
Второй вариант: используем команды передачи сообщения из памяти телефона.
Т.е. выбираем в качестве памяти хранения SIM, записываем в память сообщение,
получаем номер этого сообщения в памяти, передаем сообщение с этим номером
в эфир и стираем его из памяти. Этот вариант я использовал при отладке
своей программы и до сих пор применяю для отправки сообщений не UCS2
(может быть, именно поэтому такие сообщения передаются неустойчиво).
Каждая строчка, переданная в телефон, должна оканчиваться символом
26H.
Описание команд Вы можете найти здесь.
Пример формирования сообщения.
- 069197103701F001000B919710276338F60008020410:
- 06=05 для номера SMSC + 1 байт интернациональности SMSC
- 91=интернациональность SMSC
- 97103701F0=+790173100 плюс признак окончания номера F
- 01=PDU Type:
- 00=MR - параметр, который устанавливается в SMSC
- 0B=длина номера получателя-1 (10 знаков в номере)
- 91=интернациональность получателя
- 9710276338F6=+79017236836 - номер получателя
- 00=PID идентификатор номера протокола, если не равен 0, то должен
быть равен 41..47 для того, чтобы замещать сообщения с теми же номерами
протокола (как в БИ+!!!)
- 08=DCS схема кодирования данных: кириллическое сообщение
- 02=длина сообщения
- 0410=сообщение: "А"
Передаем его на телефон в терминальной программе:
- AT+CMGS
- Ш 069197103701F001000B919710276338F60008020410
- OK
|