|
Отправка СМС через USB-модем или сотовый телефон | ☑ | ||
---|---|---|---|---|
0
Cube
21.10.13
✎
10:32
|
Хотел подредактировать статью в КЗ http://kb.mista.ru/article.php?id=77 , но, оказалось, что туда могут писать только избранные, поэтому излагаю здесь.
Заголовок абзаца: Отправка СМС через USB-модем или сотовый телефон (подключенный по USB и определившийся как COM-порт). Текст: Ну а теперь вашему вниманию предлагается готовый код для отправки СМС, длиной более 70 символов (можете и менее, я не против) в PDU формате: Функция ОтправитьСМС(НомерТелефона, ТекстСообщения) COMПорт = "\\.\Com4"; НомерТелефонаДляКодирования = СтрЗаменить(НомерТелефона, "+", ""); Если СтрДлина(НомерТелефонаДляКодирования) = 10 ИЛИ СтрДлина(НомерТелефонаДляКодирования) = 11 Тогда НомерТелефонаДляКодирования = "7" + Прав(НомерТелефонаДляКодирования, 10) + "F"; Иначе Возврат "Не верная длина номера телефона"; КонецЕсли; НомерТелефонаСтр = ""; Для НомерСимвола = 2 По 12 Цикл Если НомерСимвола % 2 = 0 Тогда НомерТелефонаСтр = НомерТелефонаСтр + Сред(НомерТелефонаДляКодирования, НомерСимвола, 1) + Сред(НомерТелефонаДляКодирования, НомерСимвола - 1, 1); КонецЕсли; КонецЦикла; МассивСообщений = Новый Массив; ТекстСообщенияСтр = ""; ДлинаСообщения = СтрДлина(ТекстСообщения); Для НомерСимвола = 1 По ДлинаСообщения Цикл Если НомерСимвола > 67 И НомерСимвола % 67 = 1 Тогда МассивСообщений.Добавить(ТекстСообщенияСтр); ТекстСообщенияСтр = ""; КонецЕсли; КодСимволаСтр = ""; КодСимвола = КодСимвола(Сред(ТекстСообщения, НомерСимвола, 1)); Пока КодСимвола <> 0 Цикл Остаток = КодСимвола % 16; КодСимволаСтр = "" + ?(Остаток <= 9, Остаток, ?(Остаток = 10, "A", ?(Остаток = 11, "B", ?(Остаток = 12, "C", ?(Остаток = 13, "D", ?(Остаток = 14, "E", "F")))))) + КодСимволаСтр; КодСимвола = (КодСимвола - Остаток) / 16; КонецЦикла; Пока СтрДлина(КодСимволаСтр) < 4 Цикл КодСимволаСтр = "0" + КодСимволаСтр; КонецЦикла; ТекстСообщенияСтр = ТекстСообщенияСтр + КодСимволаСтр; КонецЦикла; МассивСообщений.Добавить(ТекстСообщенияСтр); ЧислоСМС = МассивСообщений.Количество(); ГСЧ = Новый ГенераторСлучайныхЧисел; СлучайноеЧисло = ГСЧ.СлучайноеЧисло(1, 255); УникальныйНомерСМС = ""; Пока СлучайноеЧисло <> 0 Цикл Остаток = СлучайноеЧисло % 16; УникальныйНомерСМС = "" + ?(Остаток <= 9, Остаток, ?(Остаток = 10, "A", ?(Остаток = 11, "B", ?(Остаток = 12, "C", ?(Остаток = 13, "D", ?(Остаток = 14, "E", "F")))))) + УникальныйНомерСМС; СлучайноеЧисло = (СлучайноеЧисло - Остаток) / 16; КонецЦикла; Пока СтрДлина(УникальныйНомерСМС) < 2 Цикл УникальныйНомерСМС = "0" + УникальныйНомерСМС; КонецЦикла; Для НомерСМС = 1 По ЧислоСМС Цикл //Вставим задержку, чтобы модем не захлебнулся. Если задержку не делать или сделать маленькой, то модем ничего не отправит (причина, как мне кажется, в том, что модем не успевает отправить предыдущую часть, а ему уже суют следующую). Такой вывод сделан чисто интуитивно, поэтому, возможно, я где-то не прав. Если НомерСМС > 1 Тогда ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах(); Пока ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала < 5000 Цикл КонецЦикла; КонецЕсли; Текст = "00"; //Длина и номер SMS центра. 0 - означает, что будет использоваться дефолтный номер. 07919731899699F0 = номер SMS центра МТС. Текст = Текст + "51"; //Тип PDU. 11 = у сообщения нет заголовка, 51 = у сообщения есть заголовок. Текст = Текст + "00"; //Поле предназначено для хранения количества переданных SMS. Не понятно, нафиг оно нужно. Текст = Текст + "0B"; //Длина номера получателя. Текст = Текст + "91"; //Тип-адреса. (91 указывает международный формат телефонного номера, 81 - местный формат). Текст = Текст + НомерТелефонаСтр; //Телефонный номер получателя в международном формате (закодированный). Текст = Текст + "00"; //Идентификатор протокола. Текст = Текст + "08"; //Старший полубайт означает сохранять SMS у получателя или нет (Flash SMS), Младший полубайт - кодировка(0-латиница 8-кирилица). Текст = Текст + "0B"; //Срок доставки сообщения. 0B = 1 час, 17 = 2 часа, С1 = 1 неделя. ЗаголовокСообщения = "05"; //Длина заголовка сообщения. ЗаголовокСообщения = ЗаголовокСообщения + "00"; //Длина поля "Уникальный номер длинного сообщения". 00 = 8-ми битная кодировка (1 октет, 255 значений поля), 08 = 16-битная кодировка (2 октета, 65535 значений поля). ЗаголовокСообщения = ЗаголовокСообщения + "03"; //Длина заголовка сообщения, исключая первые два поля. ЗаголовокСообщения = ЗаголовокСообщения + УникальныйНомерСМС; //Уникальный номер длинного сообщения. ЗаголовокСообщения = ЗаголовокСообщения + Формат(ЧислоСМС, "ЧЦ=2; ЧН=; ЧВН="); //Общее число сегментов составного СМС. ЗаголовокСообщения = ЗаголовокСообщения + Формат(НомерСМС, "ЧЦ=2; ЧН=; ЧВН="); //Номер текущего сегмента составного СМС. ДлинаСообщенияСтр = ""; ДлинаСообщенияДляКодирования = (СтрДлина(МассивСообщений[НомерСМС - 1]) + СтрДлина(ЗаголовокСообщения)) / 2; //Делим на 4 (т.к. уже закодировано) и умножаем на 2. Пока ДлинаСообщенияДляКодирования <> 0 Цикл Остаток = ДлинаСообщенияДляКодирования % 16; ДлинаСообщенияСтр = "" + ?(Остаток <= 9, Остаток, ?(Остаток = 10, "A", ?(Остаток = 11, "B", ?(Остаток = 12, "C", ?(Остаток = 13, "D", ?(Остаток = 14, "E", "F")))))) + ДлинаСообщенияСтр; ДлинаСообщенияДляКодирования = (ДлинаСообщенияДляКодирования - Остаток) / 16; КонецЦикла; Пока СтрДлина(ДлинаСообщенияСтр) < 2 Цикл ДлинаСообщенияСтр = "0" + ДлинаСообщенияСтр; КонецЦикла; ТекстСМС = Текст + ДлинаСообщенияСтр + ЗаголовокСообщения + МассивСообщений[НомерСМС - 1]; //Отправка на модем ЗаписьТекста = Новый ЗаписьТекста(COMПорт, КодировкаТекста.ANSI); ЗаписьТекста.ЗаписатьСтроку("AT+CMGF=0"); ЗаписьТекста.ЗаписатьСтроку("AT+CMGS=" + Окр((СтрДлина(ТекстСМС) - 2) / 2)); //Длина байтов сообщения (по 2 цифры), без учета длины и номера SMS центра. ЗаписьТекста.ЗаписатьСтроку(ТекстСМС + Символ(26)); ЗаписьТекста.Закрыть(); КонецЦикла; КонецФункции //ОтправитьСМС() Код для 1Cv8, но портировать на 1Cv77 не сложно. Код тестировался на модеме Huawei E303. Подводные камни: - На некоторых модемах нужно устанавливать кодировку сообщения принудительно ("AT+CSCS=""UCS2"""). - Другая модель (точно не помню какая) модема Huawei вообще зависала при установке типа PDU в значение 51 или 41. Поэтому на ней отправлять можно было только одиночные СМС. - На некоторых модемах не получалось писать все AT-команды в одной ЗаписьТекста. Приходилось каждую AT-команду писать в отдельной ЗаписьТекста и вместо метода ЗаписатьСтроку() пользоваться методом Записать(). - Если паузу между частями длинной СМС не делать или сделать маленькой, то на телефон вообще ничего не приходит. |
|||
1
Cube
21.10.13
✎
10:38
|
Сам бился над СМС-ками около месяца (оказалось, модем корявый - купил другой и заработало), поэтому решил выложить код, чтобы другим было проще.
Используемая литература: http://mobiletidings.com/2009/02/18/combining-sms-messages/ http://en.wikipedia.org/wiki/Concatenated_SMS http://huh-muh.blogspot.ru/2010/07/sms_31.html http://www.twit88.com/home/utility/sms-pdu-encode-decode http://ganatol2000.narod.ru/otap.htm http://www.sql.ru/forum/822234/pdu-i-dlinnye-sms http://www.gsm-modem.de/sms-pdu-mode.html http://www.sql.ru/forum/855618/biblioteka-gsm-library-shhob-snyat-voprosy-po-priemu-otpravke-sms-cherez-modemy-gsm http://habrahabr.ru/post/133085/ http://www.sql.ru/forum/660795-2/otpravka-sms-cherez-grps-modem http://kb.mista.ru/article.php?id=77 Так же был ещё мануал в PDF в инете. Найду ссылку - докину. |
|||
2
Cube
21.10.13
✎
10:45
|
Нашел: http://www.microchip.ua/simcom/SIM900x/AppNotes%20-%20raznoe/SMS%20in%20Pdu%20mode.pdf
И вот ещё: http://hardisoft.ru/soft/otpravka-sms-soobshhenij-v-formate-pdu-teoriya-s-primerami-na-c-chast-1/ http://hardisoft.ru/soft/otpravka-sms-soobshhenij-v-formate-pdu-teoriya-s-primerami-na-c-chast-2/ http://hardisoft.ru/soft/otpravka-dlinnyx-sms-soobshhenij-v-formate-pdu/ |
|||
3
Cube
21.10.13
✎
13:30
|
Ну так что, в статью кто-нить добавит или как?
|
|||
4
Nexux
21.10.13
✎
13:57
|
круто, обязательно заюзаю секнс
|
|||
5
oleg_km
21.10.13
✎
15:31
|
Читать ответы модема наверное тоже надо
|
|||
6
Sereja
21.10.13
✎
15:32
|
Гений 1с рассылку давно выкладывал. Нормуль было сделано
|
|||
7
Sereja
21.10.13
✎
15:33
|
+(6) У него все в готовенькой обработочке выложено
|
|||
8
Cube
22.10.13
✎
04:52
|
(5) Вообще - желательно, но тогда лучше внешнюю компоненту делать, а мне лень :)
Но не обязательно. |
|||
9
Cube
22.10.13
✎
04:53
|
(6) Я много и упорно искал. Не нашел. На мисте нашел только в КЗ, остальное на мисте шлак... Если есть ссылка - буду благодарен.
|
|||
10
Bumer
22.10.13
✎
08:37
|
||||
11
oleg_km
22.10.13
✎
09:42
|
(8) Я имел ввиду, порт правильно на невычитку ответов реагирует? Может будет виснуть и неустойчиво работать?
|
|||
12
Cube
24.10.13
✎
05:38
|
(10) Спасибо за ссылку. Программы для отправки я как-то даже не рассматривал, поэтому, видимо, и не нашел этой ссылки.
|
|||
13
Cube
24.10.13
✎
05:42
|
(11) ХЗ, посмотрим. Этот код в бою недавно. Из косяков, пока, только замечено, что 5 сек на таймаут не всегда хватает. Мы у себя поставили 10 сек, пока что.
|
|||
14
Cube
24.10.13
✎
05:45
|
Всё-таки над чтением ответа надо подумать, ведь это позволит убрать таймауты и код сам будет определять, когда можно слать следующую часть СМС на модем...
|
|||
15
IamAlexy
24.10.13
✎
06:56
|
(0) а почему не через смс порталы ?
|
|||
16
oleg_km
24.10.13
✎
09:24
|
(15) Ну у нас например всего лишь прием СМС с банк-клиента и отправка при отключении питания, т.е. штук 100 в мес вход и 8 штук выход. И ради этого заключать договор с смс порталом?
|
|||
17
Cube
25.10.13
✎
04:37
|
(15) Нам так удобнее. К тому же, такой СМС-центр можно поднять прямо у себя дома (даже взяв свою старую нокию) и добавить функциональности своему "умному дому" :)
На мисту вывалил не с целью кого-то переубеждать делать только так, а с целью пополнения инфы о работе с модемами. В инете инфы не много, а миста на хорошем счету у поисковиков. Ну куда, если не на мисту? :) |
|||
18
monsterZE
08.11.13
✎
14:17
|
спасибо тс за статью! =)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |