Синхронизация времени с NTP сервером в модемах Quectel M66 в приложениях с OpenCPU

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 и вы хотели бы видеть статью о ней у меня в блоге, пишите в комментариях или чате, и я обязательно учту ваши пожелания.

3 Ответов в “Синхронизация времени с NTP сервером в модемах Quectel M66 в приложениях с OpenCPU

  1. Классная статья. Спасибо. Где взять крайнюю прошивку с OpenCPU для M66?

    1. Привет, спасибо за оценку моего скромного труда. Прошивки можно получить у региональных представителей Quectel, я беру отсюда http://auroramobile.ru/ У меня крайняя M66FAR02A03BT, могу скинуть на почту, если нужно, но наверное уже есть новее.

      1. Спасибо, такая у меня есть. Буду искать.

Комментарии отключены.