Работа с gsm android

Работа с gsm android

Попробую объяснить на примере:

Пусть у нас есть машина в которой установлена охранная GSM-сигнализация. Данная сигнализация позволяет управлять режимами охраны (вкл./откл.) и исполнительными устройствами (например включать/выключать сирену или предпусковой подогреватель, заводить/глушить двигатель и т.д.) через отправку на нее предопределенных sms-команд (смотрим в паспорте на сигнализацию).

Теперь настраиваем наш виртуальный брелок к этой сигнализации:Идем в настройки->настройка брелков->правка:
-задаем название для брелка (например Машина)
-вводим телефонный номер симки, вставленной в сигнализацию (например +79991234567)-
-в пункте sms-пароль введите (если нужно!) пароль, который будет добавлятся перед каждой sms-командой при отправке ее GSM-сигнализации. Этот пункт полезен, когда ваша сигнализация допускает управление ей с любого номера, если перед текстом сообщения добавлен предустановленный пароль, и ваш номер не являетя основным. Не знаю как это коротко объяснить, но думаю те, кто имел дело с настройкой GSM-сигнализаций понимают зачем он.
-настроте обработку входящих сообщений перехватывать/не перехватывать сообщения с номера сигнализации, звук уведомления, количество повторений и т.д.
-настройте формат отображения сообщений лога на дисплее виртуального брелка
-в пункте «Запросы» предполагается настройка sms команд для получения информации от сигнализации (например баланс денег на счете, напряжение АКБ, статус режима охраны и т.д.). Чтобы отправить предварительно настроенный запрос нужно нажать и удерживать дисплей брелка. Затем, в появившемся контекстном меню выбрать нужный запрос. (Например: имя запроса — баланс; смс-команда запроса — balance?; жмем на дисплей брелка, выбираем пункт «баланс»; на сигнализацию отправляется sms с текстм «balance?» и через несколько секунд нам приходит ответ от сигнализации, сколько денег осталось на ее счете)
-В пункте «Команды» настраиваются кнопки брелка, аналогично запросам, только sms команда будет оправлятся по нажатию на эту кнопку. Если для кнопки отмечен чекбокс «Использовать для исходящего вызова» то по нажатию на эту кнпку будет начинаться дозвон на номер сигнализации. (Например: сигнализация ставится на охрану по звонку, а снимается по sms-команде «guard off». Жмем «Добавить исполнительное устройство» -> в поле «Исполнительное устройство:» вводим: «Охрана»-> отмечаем чекбокс «Добавить левую кнопку» -> в поле «Название левой кнопки» — «Откл.», в поле sms-команда — «guard off» -> отмечаем чекбокс «Добавить правую кнопку» -> отмечаем под ней чекбокс «использовать для исходящего вызова» -> сохраняем. Теперь на корпусе брелка у нас появилось следущюее [кнопка «Откл.» ] Охрана [кнопка с изображение телефонной трубки]. Жмем на [кнопка с изображение телефонной трубки] — идет дозвон, сигнализация ставится на охрану. Жмем [кнопка «Откл.» ] — отправляется sms с текстом «guard off» на номер сигнализации, сигнализация снимается с охраны)

ps: подробней описать не могу так что пробуйте, сами все поймете.

pps: просьба к участникам форума написать какими GSM-устройствами они управляют с помощью этого приложения. спасибо.

Управляю Elita GSW Joker.
Спасибо за программу!
Просьба — сделать тест в окне более контрастным, между доставленым и не доствленным сообщениями:
Например, сообщение отправлено, но не доставлено — цвет текста красный.
Оправлено и доставлено — синий или как сейчас серый.

Сообщение отредактировал BanKhv — 22.11.12, 06:06

Источник

Работа с GSM-модулем на примере SIM900D

Не так давно друг предложил мне работу, связанную с созданием прошивки для микроконтроллера, который должен был связываться с сервером при помощи GSM-модуля SIM900D. Ранее я с программированием микроконтроллеров дела не имел, да и на C программировал последний раз в студенческие времена, но любопытство перевесило и я принялся за работу. Документация по данной железке присутствует в интернете, однако хороших примеров работы с TCP/IP в коде найти не удалось. Ничего не оставалось, кроме как обложиться документацией, запастись сигаретами и чаем и приступить к лавированию между граблями. А граблей оказалось немало. Собственно, поэтому я и написал эту статью — чтобы другим было легче.

Читайте также:  Камера для андроид samsung

Далее будет много AT-команд, не слишком много кода и очень много букв.

Что было нужно

Требовалось написать код, который мог бы инициализировать GSM-модуль, устанавливать подключение с сервером, получать и отправлять произвольные данные, проверять состояние подключения и работать без сбоев. А также быть достаточно компактным, чтобы уместиться в ограниченной памяти микроконтроллера и оставить место для основной функциональности и еще чуть-чуть про запас.

Что получилось в итоге

Получился код на C, который может все, что было нужно. Из-за требований компактности, разбирать ответы и генерировать строки пришлось при помощи своего кода, который даже стыдно показать честному народу. Поэтому рекомендую всем использовать для этих целей регулярные выражения. Свой код я тоже собираюсь перевести на легковесный движок регулярных выражений, но уже после создания полнофункциональной прошивки.

Код требует функций/макросов для работы с последовательным портом, а также наличия функций memset и memcpy. Так что его с относительной легкостью можно перенести на другую платформу, не зацепив по пути кучу библиотек.

И как оно выглядит?

Программирование и тестирование проводилось под Windows 7. Код, полученный в результате, стал основным материалом для этой статьи. Я не стану приводить код полностью и комментировать его, а вместо этого покажу алгоритм настройки и работы с GSM-модулем.

Функции, которые требуются коду:

  • uint16_t init_serial_port(char *port_name) Эта функция настраивает указанный последовательный порт. Под Windows.
  • uint16_t puts_serial(uint8_t *buffer, uint16_t size) А эта пишет строку байт в этот порт.
  • gets_serial(uint8_t *buffer, uint16_t size) Эта, соответственно, читает строку байт из последовательного порта.

Функции, которые код предоставляет:

  • init_gprs() & stop_gprs() Соответственно инициализируют и вырубают GSM-модуль.
  • uint16_t connect_gprs(uint8_t index, uint8_t mode, char *address, char *port) Устанавливает подключение с сервером. Стоит отметить, что модуль умеет работать с протоколами TCP и UDP как в качестве клиента, так и будучи клиентом. Поддерживается максимум 8 одновременных подключений.
  • uint16_t close_gprs(uint8_t index) Закрывает указанное подключение.
  • uint16_t send_gprs(uint8_t index, uint8_t *buffer, uint16_t size) Отправка сообщения через указанное подключение.
  • uint16_t recv_gprs(uint8_t index, uint8_t *buffer, uint16_t size) Получение сообщения. Неблокирующая функция, что значит она не будет ждать появления данных в потоке, а вернет управление, если получать нечего. Стоит отметить, что такое поведение реализовать проще, чем блокирующее.

Как работать с последовательным портом

Это достаточно просто. Под целевой микроконтроллер есть макросы для отправки/получения данных через USART, но так как отлаживать такой код проще со стационарного компьютера, мне была предоставлена связка из переходника USB USART и GSM-модуля. Оставалось только научиться работать с последовательным портом под Windows. Это оказалось просто. Вкратце, последовательный порт представляется в ОС обычным файлом, передача информации осуществляется функциями ReadFile и WriteFile. Нужно только установить кое-какие параметры при помощи функций SetCommTimeouts и SetCommState.

Читайте также:  Redpower 31151 ips dsp android 7

Вот как выглядит функция инициализации порта:

Как происходит общение с GSM-модулем

После того, как последовательный порт настроен, в него можно отправлять AT-команды. Первой командой должна быть последовательность «AT\r» , позволяющая модулю автоматически настроить скорость передачи по последовательному порту. Ответ, который можно получить после этого из порта, будет выглядеть как «AT\r\r\nOK\r\n» .

Команда является простой строкой из ASCII-символов. Чтобы команду воспринял модуль, в ее конце нужно поставить символ перевода каретки «\r» . В ответ модуль передаст строку символов, состоящую из двух частей — команды, на которую модуль отвечает и отделенным от нее символами «\r\r\n» ответом, заканчивающимся символами «\r\n» . Чтобы было удобнее разбирать ответы я создал макрос, который устанавливает указатель на начало ответа в принимающем буфере. Если хочется вывести ответ в консоль, нужно добавить нулевой символ в конец принятого сообщения.

Примерно так и выглядят вспомогательные функции для отправки команды и получения ответа.

Инициализация модуля

Самая большая функция в коде отвечает за настройку модуля. При инициализации отправляется много AT-команд. Я опишу их в порядке посылки модулю. Специально не расписываю аргументы и варианты ответов подробно, ибо их можно найти в документации.

  • «AT+CPIN=pin-code» Как несложно догадаться, эта команда разблокирует SIM-карту путем ввода пин-кода. Чтобы проверить, требуется ли пин-код, можно использовать команду «AT+CPIN?» .
  • «AT+CREG?» Эта команда возвращает статус регистрации модуля в сети. Нужно выполнять ее, пока модуль не ответит, что в сети он зарегистрирован.
  • «AT+CGATT=1» Заставляет модуль подключиться к GPRS. Проверить, подключен ли он, можно командой «AT+CGATT?» .
  • «AT+CIPRXGET=1» Включает получение данных, переданных через соединение, вручную. По умолчанию этот параметр отключен и данные передаются в последовательный порт сразу после получения. Это не слишком удобно, хотя и не критично — можно настроить модуль так, чтобы вместе с данными он передавал и заголовки IP, по которым можно определить, от кого был получен пакет. Я решил, что вручную данные получать проще и не ошибся. Как я понял, данная команда воспринимается только GSM-модулями SIM.COM.
  • «AT+CIPMUX=1» По умолчанию модуль может устанавливать только одно подключение. Этот параметр включает возможность создавать несколько подключений. Отправка и прием данных будут отличаться только на один параметр — индекс подключения.
  • «AT+CSTT=»internet»» APN — Access Point Name, имя точки доступа для GPRS. Для моего провайдера выглядит именно так.
  • «AT+CIICR» Устанавливает беспроводное подключение GPRS. Может занять некоторое время, так что ее нужно выполнять в цикле и проверять ответ.
  • «AT+CIFSR» Возвращает IP-адрес модуля. Я использую ее чтобы проверить, подключен ли модуль к интернету.
  • «AT+CDNSCFG=»8.8.8.8″,»8.8.4.4″» Этой командой устанавливаются сервера DNS, которые будет использовать модуль.
  • «AT+CIPSTATUS» Помимо данных о состоянии подключений эта команда дает информацию о том, готов ли модуль к установке соединений. Так что нужно проверить ее ответ.

После выполнения этих команд модуль будет готов к работе. Ну или не будет. Тут уж как повезет.

Установка и разрыв подключений

Создание подключения производится командой «AT+CIPSTART=index,»mode»,»address»,»port»» .

  • index указывает порядковый номер подключения, может принимать значения от 0 до 7.
  • mode определяет протокол, который будет использоваться соединением. Может быть «TCP» или «UDP».
  • address задает адрес сервера. Если при настройке были указаны DNS-сервера, то можно использовать как IP-адрес, так и доменное имя.
  • port задает порт сервера, с которым будет устанавливаться соединение.

Замечу, что при использовании протокола UDP по умолчанию датаграммы будут отсылаться и приниматься только с одного адреса. Для того, чтобы использовать UDP на полную катушку и отсылать/принимать данные с любых адресов, можно использовать так называемый расширенный режим UDP, настраиваемый командой «AT+CIPUDPMODE» . За подробностями отсылаю к документации.

Читайте также:  Форматирование поврежденной sd карты android

В ответ на команду можно получить несколько вариантов ответов. Если все хорошо, то после стандартного «OK» через небольшой промежуток времени можно получить один из трех ответов:

  • «index,ALREADY CONNECT» это значит, что подключение с заданным индексом уже установлено и стоит его поискать.
  • «index,CONNECT OK» тут все очевидно.
  • «index,CONNECT FAIL» означает, что возникли проблемы с установкой соединения.

Разорвать соединение можно командой «AT+CIPCLOSE=index» . Разорвать все соединения и деактивировать интерфейс GPRS можно командой «AT+CIPSHUT» .

Передача данных

Данные передаются командой «AT+CIPSEND=index,length» , где index указывает подключение, по которому нужно передать данные, а length задает длину пакета данных. Кстати, узнать MTU для каждого подключения можно при помощи команды «AT+CIPSEND=?» .

Если все хорошо, то модуль в ответ на команду выдаст приглашение «>» , после которого нужно переслать в последовательный порт данные. Как только модуль получит количество байт, равное length , он скажет что-то типа «index,SEND OK» . Вообще, можно не использовать параметр length , однако в таком случае окончание пакета данных должно быть указано явно при помощи символа 0x1A , в терминале сочетание Ctrl+Z. Для передачи произвольных данных такой вариант, очевидно, не подходит.

Как видите, передача данных — процесс не слишком сложный. Поэтому переходим к самому интересному — приему данных.

Прием данных

Как только GSM-модуль принимает данные, он сигнализирует об этом, посылая в последовательный порт строку вида «+CIPRXGET:1,index\r\n» . Я честно не знаю, что означает единица, ибо данная функция модуля документирована достаточно слабо, но у меня она фигурирует во всех сообщениях о приеме пакета.

Мне не доставляла радости мысль о том, что придется тем или иным образом отслеживать сообщения модуля. Однако, немного поигравшись с дебаггером, я выяснил, что никаких других асинхронных сообщений модуль не посылает, а также то, что после выполнения любой AT-команды это сообщение оказывается в начале буфера. Так как я составил макрос для отделения ответа от команды путем поиска подстроки «\r\r\n» , меня это никоим образом не задевало. Так что функция приема данных была реализована достаточно просто.

Так вот, принимать данные можно командой «AT+CIPRXGET=2,index,length» . Двойка означает режим приема, в данном случае байты просто высыпаются в последовательный порт. Можно также задать получение данных в виде HEX-текста, видимо, ради предотвращения конфликтов с программным управлением потоком. Мне это не потребовалось, ибо управление потоком я вообще не использую. Параметр length задает размер пакета данных, который мы желаем получить за один раз.

В ответ мы получим нечто вида «+CIPRXGET:2,index,received,excess\r\n__DATA__\r\nOK\r\n» . В поле received будет находиться количество байт, находящихся в пакете данных __DATA__ , а поле excess будет содержать количество байт, ожидающих своей очереди в буфере модуля. Так что если поле received равно нулю, можно с чистой совестью заявлять, что получать нечего. Собственно, пользуясь этим, я и реализовал неблокирующую функцию для приема данных.

В заключение

Настоятельно рекомендую перед написанием кода освоиться в AT-командах при помощи PuTTY, который прекрасно работает с последовательным портом.

Надеюсь, информация из этой статьи поможет кому-нибудь написать код для своего SIM900. Вполне возможно, что принципы работы с GSM-модулем, изложенные выше, можно применить и к модулям других моделей, а, возможно, и производителей.

Источник

Оцените статью