Функция ОтправитьСМС(НомерТелефона="",ТекстСообщения="") Экспорт
Комментарий = "";
//Инициализация модема
СерверMSComm = Новый COMОбъект("MSCommLib.MSComm.1");
СерверMSComm.CommPort = КомПорт; //Задает или возвращает номер COM порта.
СерверMSComm.InBufferCount = 0; //Задает или возвращает число ожидающих символов в буфере приема.
СерверMSComm.PortOpen = Истина;
//Отправка СМС
Отправлено = Истина;
НомерТелефонаДляКодирования = СтрЗаменить(НомерТелефона, "+", "");
Если СтрДлина(НомерТелефонаДляКодирования) = 10 ИЛИ СтрДлина(НомерТелефонаДляКодирования) = 11 Тогда
НомерТелефонаДляКодирования = "9" + Прав(НомерТелефонаДляКодирования, 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 По ЧислоСМС Цикл
Текст = "00"; //Длина и номер SMS центра. 0 - означает, что будет использоваться дефолтный номер. 07919720990100F0 = ЕТК. 07919731899699F0 = МТС
Текст = Текст + "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];
//Отправка команды на модем
СерверMSComm.Output = "AT" + Символ(13) + Символ(10);
//Ожидание ответа от модема
Отправлено = Ложь;
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Пока ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала <= 10000 Цикл
Если СокрЛП(СерверMSComm.Input) = "OK" Тогда
Отправлено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ Отправлено Тогда
Комментарий = "Ошибка: Модем не отвечает (1)";
Прервать;
КонецЕсли;
//Отправка команды на модем
СерверMSComm.Output = "AT+CMGF=0" + Символ(13) + Символ(10);
//Ожидание ответа от модема
Отправлено = Ложь;
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Пока ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала <= 10000 Цикл
Если СокрЛП(СерверMSComm.Input) = "OK" Тогда
Отправлено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ Отправлено Тогда
Комментарий = "Ошибка: Модем не отвечает (2)";
Прервать;
КонецЕсли;
//Отправка команды на модем
СерверMSComm.Output = "AT+CMGS=" + Окр((СтрДлина(ТекстСМС) - 2) / 2) + Символ(13) + Символ(10); //Длина байтов сообщения (по 2 цифры), без учета длины и номера SMS центра.
//Ожидание ответа от модема
Отправлено = Ложь;
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Пока ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала <= 10000 Цикл
Если СокрЛП(СерверMSComm.Input) = ">" Тогда
Отправлено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ Отправлено Тогда
Комментарий = "Ошибка: Модем не отвечает (3)";
Прервать;
КонецЕсли;
//Отправка команды на модем
СерверMSComm.Output = ТекстСМС + Символ(26);
//Ожидание ответа от модема
Отправлено = Ложь;
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Пока ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала <= 10000 Цикл
Если Прав(СокрЛП(СерверMSComm.Input), 2) = "OK" Тогда
Отправлено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ Отправлено Тогда
Комментарий = "Ошибка: Модем не отвечает (4)";
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
//Освобождение модема
Сообщить(Комментарий);
СерверMSComm.PortOpen = Ложь;
Отправлено = Истина;
КонецФункции
Функция ПолучитьСМС(ТаблицаСообщений=Неопределено,ТекстСообщения=Неопределено) Экспорт
ТаблицаСообщений = Новый ТаблицаЗначений();
ТаблицаСообщений.Колонки.Добавить("Отправитель");
ТаблицаСообщений.Колонки.Добавить("ТекстСообщения");
ТаблицаСообщений.Колонки.Добавить("ДатаПолучения");
ТаблицаСообщений.Колонки.Добавить("Индекс");
ТаблицаСообщений.Колонки.Добавить("ТипСообщения");
Комментарий = "";
//Инициализация модема
СерверMSComm = Новый COMОбъект("MSCommLib.MSComm.1");
СерверMSComm.CommPort = КомПорт; //Задает или возвращает номер COM порта.
СерверMSComm.InBufferCount = 0; //Задает или возвращает число ожидающих символов в буфере приема.
СерверMSComm.PortOpen = Истина;
//Отправка СМС
Отправлено = Истина;
СерверMSComm.Output = "AT+CMGF=1" + Символ(13) + Символ(10);
//Ожидание ответа от модема
Отправлено = Ложь;
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Пока ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала <= 10000 Цикл
Ответ = СокрЛП(СерверMSComm.Input);
Сообщить(Ответ);
Если Найти(Ответ,"OK")>0 Тогда
Отправлено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ Отправлено Тогда
Комментарий = "Ошибка: Модем не отвечает (1)";
КонецЕсли;
//Отправка команды на модем
СерверMSComm.Output = "AT+CMGL=""ALL""" + Символ(13) + Символ(10);
//Ожидание ответа от модема
Отправлено = Ложь;
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Пока ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала <= 10000 Цикл
Ответ = СокрЛП(СерверMSComm.Input);
//Сообщить(Ответ);
Если Найти(Ответ,"OK")>0 Тогда
Отправлено = Истина;
Результат = "";
Для Сч=1 По СтрЧислоСтрок(Ответ) Цикл
строкаТекст1 = СтрПолучитьСтроку(Ответ,Сч);
Если Найти(строкаТекст1,"CMGL")>0 Тогда // строка получатель
мнСтрокаПолучатель = СтрЗаменить(строкаТекст1,",",Символы.ПС);
стрТСообщений = ТаблицаСообщений.Добавить();
стрТСообщений.Отправитель = СокрЛП(СтрПолучитьСтроку(мнСтрокаПолучатель,3));
стрТСообщений.Отправитель = СтрЗаменить(стрТСообщений.Отправитель,"""","");
ТекстДата = СокрЛП(СтрПолучитьСтроку(мнСтрокаПолучатель,5)) + СокрЛП(СтрПолучитьСтроку(мнСтрокаПолучатель,6));
ТекстДата = СтрЗаменить(ТекстДата,"""","");
ТекстДата = СтрЗаменить(ТекстДата,"/","");
ТекстДата = СтрЗаменить(ТекстДата,":","");
ТекстДата = Лев(ТекстДата,Найти(ТекстДата,"+")-1);
стрТСообщений.ДатаПолучения = ДАТА("20"+ТекстДата);
стрТСообщений.Индекс = СтрЗаменить(СокрЛП(СтрПолучитьСтроку(мнСтрокаПолучатель,1)),"+CMGL: ","");
стрТСообщений.Индекс = СтрЗаменить(стрТСообщений.Индекс,"""","");
стрТСообщений.ТипСообщения = СокрЛП(СтрПолучитьСтроку(мнСтрокаПолучатель,2));
стрТСообщений.ТипСообщения = СтрЗаменить(стрТСообщений.Индекс,"""","");
Результат = "";
ИначеЕсли СокрЛП(строкаТекст1)="" Тогда
Продолжить;
ИначеЕсли СокрЛП(строкаТекст1)="OK" Тогда
// ничего
Иначе
ДлиннаСтр = Цел(СтрДлина(строкаТекст1)/4);
Для Сч1=0 по ДлиннаСтр-1 Цикл
Результат = Результат + ПолучитьСимвол(Сред(строкаТекст1,Сч1*4+1,4));
КонецЦикла;
стрТСообщений.ТекстСообщения = Результат;
КонецЕсли;
КонецЦикла;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ Отправлено Тогда
Комментарий = "Ошибка: Модем не отвечает (2)";
КонецЕсли;
//Отправка команды на модем
#Если Клиент Тогда
Если Вопрос("Удалить сообщения",РежимДиалогаВопрос.ДаНет,5,КодВозвратаДиалога.Нет) = КодВозвратаДиалога.Да Тогда
Для Каждого СтрокаТ2 Из ТаблицаСообщений Цикл
СерверMSComm.Output = "AT+CMGD=" + СокрЛП(СтрокаТ2.Индекс) + Символ(13) + Символ(10);
//Ожидание ответа от модема
Отправлено = Ложь;
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Пока ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала <= 10000 Цикл
Ответ = СокрЛП(СерверMSComm.Input);
Сообщить(Ответ);
Если Найти(Ответ,"OK")>0 Тогда
Отправлено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ Отправлено Тогда
Комментарий = "Ошибка: Модем не отвечает (3)";
КонецЕсли;
//Отправка команды на модем
КонецЦикла;
КонецЕсли;
#КонецЕсли
Сообщить(Комментарий);
СерверMSComm.PortOpen = Ложь;
Отправлено = Истина;
КонецФункции
Функция ИзХСчислВЧисло(аф,Шаблон)
аф = ВРег(аф); // на всякий случай.
ДлинаШаблона = СтрДлина(Шаблон);
ДлинаСтроки = СтрДлина(аф);
Рез = 0;
Для ТекСимвол = 1 По ДлинаСтроки Цикл
ОбрабатываемыйСимвол = Сред(аф, ТекСимвол,1);
ПозицияВШаблоне = Найти(Шаблон,ОбрабатываемыйСимвол)-1;
Рез = Рез * ДлинаШаблона + ПозицияВШаблоне;
КонецЦикла;
Возврат(Рез);
КонецФункции
Функция ПолучитьСимвол(ИсхСтр)
КодСимв=ИзХСчислВЧисло(ИсхСтр,"0123456789ABCDEF");
ЧислоКодСивола=Число(КодСимв);
Возврат Символ(ЧислоКодСивола);
КонецФункции
Показать