Настольная книга по Linux/Вопросы по программной отправке SMS
отправка SMS программно через AT-команды под Линуксом
[править]инструкция предоставленная jackLucas-ом (из Новосибирска) для линуксойдов такова:
-подключаем сотовый (Motorola C650) к компьютеру через USB (в ядре должна быть включена поддержка CDC ACM модемов); - dmesg выдаёт, что обнаружено устройство /dev/ttyACM0 - запускаем minicom (аналог Telix'а, HyperTerminal'а) - настраиваем com порт на /dev/ttyACM0 - включаем ECHO - сохраняем настройки minicom'а - перезапускаем minicom - набираем ATZ, жмём Enter - получаем в ответ OK - набираем AT+CMGF=1, жмём Enter - получаем OK - набираем AT+CSCA="+79139869990" (+79139869990 - телефон СМС центра МТС (в Новосибирске, по крайней мере)), жмём Enter - получаем OK - набираем AT+CMGS="(номер телефона того, кому отправляем сообщение)", жмём Enter - получаем > - набираем текст сообщения, жмём Enter, жмём Ctrl+Z - через некоторое время получаем сообщение модема, что сообщение отправлено
отправка русских SMS программно через AT-команды под Линуксом
[править]инструкция предоставленная jackLucas-ом (из Новосибирска) для линуксойдов с использованием minicom такова:
- вводим ATZ, жмём Enter - получаем OK - вводим AT+CMGF=1 (переходим в ТЕКСТОВЫЙ режим передачи сообщений, лучше конечно использовать PDU режим (AT+CMGF=0), так как текстовый режим поддерживают не все сотовые, но я в этом режиме пока не разбираюсь ), жмём Enter - получаем OK - вводим AT+CSCA="+79139869990", жмём Enter - получаем OK - вводим AT+CSCS=?, жмём Enter - получаем список поддерживаемых кодировок - вводим AT+CSCS="UCS2", жмём Enter - получаем OK - вводим AT+CMGS="(тот номер, на который отправляем СМС)", жмём Enter - вводим текст сообщения, каждая буква представляется четырьмя шестнадцатиричными цифрами (кодом буквы в UCS2, русская А = 0410). Например, для слова Привет вводим: 041F04400438043204350442, жмём Ctrl+Z - вот тут самое интересное: я отправил два сообщения, оба дошли до абонентов, оба по-русски, но модем в первом случае сказал OK, во втором - ERROR. Но оба сообщения ДОШЛИ КОРРЕКТНО.
ну вот собственно и всё.
P.S. для программной реализации лучше конечно использовать PDU режим, изучением которого я и займусь. Но как-то там всё странно с кодированием сообщения
Подготовка PDU-сообщения для отправки SMS
[править]Как раз программную реализацию я недавно делал. Вот пример 100% рабочего кода на С. Пример иллюстрируется предельно простой, то есть нет поддержки различных кодировок, нет работы с режимами отправки, это просто отправная точка для тех, кому нужно разобраться. По этой же причине код не написан настолько компактно, насколько С это позволяет. PDU формируется для команды AT+CMGS. Работать с ней вот как: посылаете модему "AT+CMGS=<Длина PDU>" Модем Вам ответит символом ">" Вводите PDU и посылаете символ CTRL-Z (или жмете на клавиатуре) Если PDU сформирована верно модем отошлет СМС на нужный номер (он внутри PDU)
{
char tmp[255]; char* tmps=&tmp; char* st=" "; char* hex="0123456789ABCDEF"; char* msg="Sample message for PDU mode test" unsigned char i,j,x,n; tmps[0]=0; // Это заголовок. вкратце: "послать", "с моего номера", 0x0C=число цифр в номере, "СМС-центр - тот, что в телефоне" strcpy(tmps,"0011000B91"); // На какой номер отправлять. Номер в интернациональном стандарте должен быть представлен // без символа "+" и каждая пара цифр "развернута". // Пример: Для посылки СМС на номер "+70123456789" запись должна быть пополнена "F" // То есть исходный номер преобразуется в: "70123456789F". Теперь развернем каждую // пару цифр номера. Получим: "0721436587F9", итак: strcat(tmps,"0721436587F9"); strcat(tmps,"0000AA"); // Тоже служебные поля. // Тут должно быть в шестнадцатиричном виде проставлена длина некодированного сообщения. i=strlen(msg); // Получим длину сообщения st[0]=hex[(i >> 4)]; // Получим старшую часть байта в виде символа strcat(tmps,st); // Добавим к строке st[0]=hex[(i & 0x0F)]; // Младшую часть байта .. strcat(tmps,st); // ..Аналогично // Дальше начинается перекодирование ASCII в PDU формат. j=0; x=1; while (j<i) { n=msg[j] << 1; n=(n >> x) | (msg[j+1] << (8-x)); j++; x++; if (x==8) { x=1; j++; } st[0]=hex[(n >> 4)]; strcat(tmps,st); st[0]=hex[(n & 0x0F)]; strcat(tmps,st); } // Осталось только вычислить длину для AT+CMGS=? i=(strlen(tmps)-2)>>1; // Вот и все. Длина для команды - в переменной i // Готовое сообщение - в tmps.