Отправка SMS через консоль N900 | автор: Luca | 28 апреля 2010
Категория: GNU/Linux
Итак, постановка задачи. Хочу отправлять короткие сообщения на русском языке из командной строки (на кой хрен??! прим. Luca). Не хочу ограничивать себя размером сообщения, то есть если моя мысль не уложилась в одно сообщение, автоматически должно быть отправлено два или три или сколько там нужно сообщений, а на стороне получателя все должно выглядеть прилично.
Уважаемый товарищ Гугл в ответ на этот вопрос нам отвечает всего одной темой на форуме talk.maemo.org где помещена ссылка на творчество некоего pende которое (творчество) не работает, но нам очень помогает. Помимо этого, на вики для разработчиков maemo приведен пример кода на питоне, как нужно отправлять смс. Вот он:
Все вроде бы просто(да п#здец просто! прим. Luca), но, как обычно, дьявол кроется в мелочах. В нашем случае, это подготовка текста сообщения в так называемом формате PDU (Protoсol Data Unit). Огромной помощью в разбирательствах с этим форматом оказался труд Алексея Печерского «Формат PDU или как сформировать и распаковать SMS», найденный мною в сети. Большое спасибо этому человеку!
Основная проблема крылась в подготовке номера получателя. Важно что бы он содержал четное количество цифр. Поэтому, при необходимости, номер с конца дополняется символом «F». Приведу пример преобразования номера. Цитирую Алексея Печерского (справедливости для отмечу, с исправлением опечаток):
номер +37212345678 последовательно превращается:
1. 37212345678 — убрали +;
2. 37212345678 — определили длину адреса Length('37212345678') =11d(десятичное) или 0Bh (шестнадцатеричное);
3. 37212345678F — добавили в конец F, так как длина нечетная;
4. 7312325476F8 — переставили тетрады;
5. 917312325476F8 — добавили интернациональный тип номера 91h;
6. 0B917312325476F8 — добавили длину — и вот вам результат, то есть номер +37212345678 превратился в 0B917312325476F8
Ниже приведен текст функции, написанной pende и доработанной мною для российских условий. Мы устанавливаем, что номер получателя в интернациональном формате, время доставки сообщения 24 часа, текст сообщения в кодировке Unicode (2 байт на символ):
Собственно говоря и все. В случае, когда у нас возникает желание отправить длинное СМС (а точнее, серию сообщений) применяется непосредственно в теле сообщения специальный заголовок UDH, в котором указывается номер сообщения в серии и общее количество сообщений в этой серии. Поэтому функция подготовки сообщения претерпела изменения:
Ну и теперь нам осталось в самом начале понять, отправляем мы одно сообщение или несколько и выбрать каким способом формируется PDU.
Полный текст скрипта находится здесь.
источник с Хабра удален
Везде где появляется linux появляются ректальные методы работы с устройствами!
Прочитано 5459 раз и оставлено 117 комментариев.
Итак, постановка задачи. Хочу отправлять короткие сообщения на русском языке из командной строки (на кой хрен??! прим. Luca). Не хочу ограничивать себя размером сообщения, то есть если моя мысль не уложилась в одно сообщение, автоматически должно быть отправлено два или три или сколько там нужно сообщений, а на стороне получателя все должно выглядеть прилично.
Уважаемый товарищ Гугл в ответ на этот вопрос нам отвечает всего одной темой на форуме talk.maemo.org где помещена ссылка на творчество некоего pende которое (творчество) не работает, но нам очень помогает. Помимо этого, на вики для разработчиков maemo приведен пример кода на питоне, как нужно отправлять смс. Вот он:
import dbus
bus = dbus.SystemBus()
smsobject = bus.get_object('com.nokia.phone.SMS', '/com/nokia/phone/SMS/ba212ae1')
smsiface = dbus.Interface(smsobject, 'com.nokia.csd.SMS.Outgoing')
arr = dbus.Array(pdu_array)
msg = dbus.Array([arr])
smsiface.Send(msg,)
Все вроде бы просто(да п#здец просто! прим. Luca), но, как обычно, дьявол кроется в мелочах. В нашем случае, это подготовка текста сообщения в так называемом формате PDU (Protoсol Data Unit). Огромной помощью в разбирательствах с этим форматом оказался труд Алексея Печерского «Формат PDU или как сформировать и распаковать SMS», найденный мною в сети. Большое спасибо этому человеку!
Основная проблема крылась в подготовке номера получателя. Важно что бы он содержал четное количество цифр. Поэтому, при необходимости, номер с конца дополняется символом «F». Приведу пример преобразования номера. Цитирую Алексея Печерского (справедливости для отмечу, с исправлением опечаток):
номер +37212345678 последовательно превращается:
1. 37212345678 — убрали +;
2. 37212345678 — определили длину адреса Length('37212345678') =11d(десятичное) или 0Bh (шестнадцатеричное);
3. 37212345678F — добавили в конец F, так как длина нечетная;
4. 7312325476F8 — переставили тетрады;
5. 917312325476F8 — добавили интернациональный тип номера 91h;
6. 0B917312325476F8 — добавили длину — и вот вам результат, то есть номер +37212345678 превратился в 0B917312325476F8
Ниже приведен текст функции, написанной pende и доработанной мною для российских условий. Мы устанавливаем, что номер получателя в интернациональном формате, время доставки сообщения 24 часа, текст сообщения в кодировке Unicode (2 байт на символ):
def createPDUmessage(number, msg):
'''
Returns a list of bytes to represent a valid PDU message
'''
numlength = len(number)
number_length = len(number)
if (numlength % 2) == 0:
rangelength = numlength
else:
number = number + 'F'
rangelength = len(number)
octifiednumber = [ semi_octify(number[i:i+2]) for i in range(0,rangelength,2) ]
# octifiedmsg = octify(msg) теперь сообщение в unicode не будем его октифицировать
msg_length = len(msg)*2 # два байта на символ
PDU_TYPE = 0x11
MR = 0
ADDR_TYPE = 0x91 #international format
pdu_message = [PDU_TYPE, MR, number_length, ADDR_TYPE]
pdu_message.extend(octifiednumber)
pdu_message.append(0) #PID
pdu_message.append(8) #DCS
pdu_message.append(167) #VP 24 hours
pdu_message.append(msg_length)
# добвляем САМО сообщение а не октифицированную его версию!
# pdu_message.extend(msg)
for i in xrange (len(msg)) :
digit = ord(msg[i])
h_digit = digit >> 8
l_digit = digit & 0xFF
pdu_message.append(h_digit)
pdu_message.append(l_digit)
return pdu_message
Собственно говоря и все. В случае, когда у нас возникает желание отправить длинное СМС (а точнее, серию сообщений) применяется непосредственно в теле сообщения специальный заголовок UDH, в котором указывается номер сообщения в серии и общее количество сообщений в этой серии. Поэтому функция подготовки сообщения претерпела изменения:
def createPDUmessage_parted(number, msg, number_of_serie, part_number, number_of_parts):
'''
Returns a list of bytes to represent a valid PDU message
'''
numlength = len(number)
number_length = len(number)
# добавим к номеру в конце буковку F если длина номера нечетная
if (numlength % 2) == 0:
rangelength = numlength
else:
number = number + 'F'
rangelength = len(number)
# преобразуем номер получателя в принятый в заголовке формат
octifiednumber = [ semi_octify(number[i:i+2]) for i in range(0,rangelength,2) ]
msg_length = len(msg)*2 + 6 # два байта на символ плюс 6 байт на заголовок в сообщении что это длинное смс
PDU_TYPE = 0x51 # добавили бит что перед телом сообщения будет заголовок где информация о склейке
MR = 0
ADDR_TYPE = 0x91 #international format
pdu_message = [PDU_TYPE, MR, number_length, ADDR_TYPE]
pdu_message.extend(octifiednumber)
pdu_message.append(0) #PID
pdu_message.append(8) #DCS
pdu_message.append(167) #VP 24 hours
pdu_message.append(msg_length)
# добавим заголовок о том что у нас часть большого сообщения всего 6 байт
pdu_message.append(5)
pdu_message.append(0)
pdu_message.append(3) # это всегда так
pdu_message.append(number_of_serie) # уникальный для данной группы смс номер. хрен его знает как брать. будет пока 13
pdu_message.append(number_of_parts) # количество смс для склейки
pdu_message.append(part_number) # порядковый номер смс
# добвляем САМО сообщение а не октифицированную его версию!
for i in xrange (len(msg)) :
digit = ord(msg[i])
h_digit = digit >> 8
l_digit = digit & 0xFF
pdu_message.append(h_digit)
pdu_message.append(l_digit)
return pdu_message
Ну и теперь нам осталось в самом начале понять, отправляем мы одно сообщение или несколько и выбрать каким способом формируется PDU.
Полный текст скрипта находится здесь.
источник с Хабра удален
Везде где появляется linux появляются ректальные методы работы с устройствами!
ВНИМАНИЕ !
Возможно что-то уже неактуально. Обращайте внимание на даты !
Эта статья опубликована 28 апреля 2010-го года !
Прочитано 5459 раз и оставлено 117 комментариев.
#1.wr224