GSM модемы многих производителей обладают возможностью синхронизации времени как с сетью GSM оператора, так и с серверами точного времени по протоколу NTP. В этой статье поговорим о том, как это реализовано в модемах Quectel на примере модема M66 (в других моделях это работает аналогичным образом, лишь немного отличается в 3G модемах Quectel, где можно указывать какой часовой пояс тебя интересует).
Материал из Википедии
NTP (Network Time Protocol) — сетевой протокол для синхронизации внутренних часов компьютера с использованием с переменной латентностью.
Чтобы лучше понять, как данный функционал реализован в OpenCPU, а если быть точным в RIL (Radio Interface Layer), сперва немного окунемся в то, как это реализовано путем AT команд.
Команда:
AT+QNTP="<server>"[,<port>]
позволяет синхронизировать локальное время через NTP. Где,
<server> — адрес сервера точного времени в виде строки. Может быть именем домена или IP адресом.
<port> — соответственно, порт сервера точного времени, обычно 123.
В ответ получаем:
OK +QNTP: <result>
где,
<result> — результат запроса времени:
0 Время синхронизировано
1 Ошибка синхронизации локального времени по неизвестной причине
2 Ошибка получения ответа сервера
3 TCP/IP стек в данный момент занят другим запросом
4 Не найден сервер NTP
5 Ошибка активации PDP context
или
ERROR
По умолчанию документация предлагает использовать китайский сервер для синхронизации, но он конечно не доступен у нас, я обычно использую time1.google.com, вы можете использовать любой другой. Выглядит просто и, если вы работаете с модемом путем ввода AT команд, то это то, что вам нужно, чтобы получить точное время из интернета.
Ну ок, а что там с OpenCPU? В текущей версии SDK, а это к слову уже 2.4, есть два файла ril_ntp.c и ril_ntp.h. Именно в них присутствует необходимая функция запроса:
s32 RIL_NTP_START(u8 *server_addr, u16 server_port, CB_NTPCMD cb_NTPCMD_hdl);
С параметрами все просто, адрес сервера, порт сервера, а вот последний это адрес callback-функции, которая вызывается после получения ответа на AT команду, запрос которой осуществляется внутри функции вот так:
Ql_sprintf(strAT, "AT+QNTP=\"%s\",%d\r\n", server_addr, server_port); ret = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0);
Callback-функцию следует определить в своем приложении и передать ее адрес при запросе RIL_NTP_START
. Внутри своей callback-функции надо проверять ответ вида +QNTP: <result>, примерно так:
void callbackNtpHandler(const char* strURC, void* reserved) { if (*(strURC + 9) == '0') { ST_Time time = getLocalTime(); Ql_Debug_Trace("[ INFO ] Local time successfuly determined: %i.%i.%i %i:%i:%i timezone=%i\r\n", time.day, time.month, time.year, time.hour, time.minute, time.second, time.timezone); } else if (*(strURC + 9) == '1') { Ql_Debug_Trace("[ FAIL ] Failed to synchronize the local time because of unknown reason\r\n"); } else if .... // и так далее }
Делать запрос к NTP серверу следует после регистрации в сети GPRS и активации соединения, но заметил один нюанс, если активировать соединение командой Ql_GPRS_Activate
или Ql_GPRS_ActivateEx
, то команда AT+QNTP возвращает всякий раз ошибку RIL_AT_FAILED
. Побороть это можно активируя GPRS соединение в следующем порядке:
s32 pdpContextId = Ql_GPRS_GetPDPContextId(); RIL_NW_SetGPRSContext(pdpContextId); s32 ret = Ql_GPRS_Config(pdpContextId, &gprsConfig); // Не вызываем Ql_GPRS_Activate(pdpContextId); if (ret == GPRS_PDP_SUCCESS) { RIL_NTP_START(NTP_SERVER, NTP_PORT, Callback_NTP_Handler); }
На этом все, других возможностей для работы с NTP OpenCPU RIL не предоставляет, можно также рассмотреть работу с Time API OpenCPU, но оставлю это на одну из следующих статей. А пока подписывайтесь на мой ВК, Твиттер и заходите в наш чат Telegram.
Также, если вас интересует какая-то тема, касательно работы с Quectel OpenCPU и вы хотели бы видеть статью о ней у меня в блоге, пишите в комментариях или чате, и я обязательно учту ваши пожелания.
Классная статья. Спасибо. Где взять крайнюю прошивку с OpenCPU для M66?
Привет, спасибо за оценку моего скромного труда. Прошивки можно получить у региональных представителей Quectel, я беру отсюда http://auroramobile.ru/ У меня крайняя M66FAR02A03BT, могу скинуть на почту, если нужно, но наверное уже есть новее.
Спасибо, такая у меня есть. Буду искать.