|
|
  |
Протокол SNTP |
|
|
|
Dec 12 2016, 05:53
|
Частый гость
 
Группа: Свой
Сообщений: 142
Регистрация: 11-01-11
Из: Орел
Пользователь №: 62 159

|
Здравствуйте, товарищи! Использую стек lwIP 1.3.2, протокол SNTP (за основу взят sntp из архива contrib-1.4.1). Заполняю структуру sntp_msg, Код struct sntp_msg { PACK_STRUCT_FIELD(u8_t li_vn_mode); PACK_STRUCT_FIELD(u8_t stratum); PACK_STRUCT_FIELD(u8_t poll); PACK_STRUCT_FIELD(u8_t precision); PACK_STRUCT_FIELD(u32_t root_delay); PACK_STRUCT_FIELD(u32_t root_dispersion); PACK_STRUCT_FIELD(u32_t reference_identifier); PACK_STRUCT_FIELD(u32_t reference_timestamp[2]); PACK_STRUCT_FIELD(u32_t originate_timestamp[2]); PACK_STRUCT_FIELD(u32_t receive_timestamp[2]); PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]); }; вставляю в неё свою метку времени originate_timestamp[] и отправляю её NTP-серверу (служба времени Windows), в ответ получаю такую же структуру с четырьмя метками времени. В файле sntp.c (из архива contrib-1.4.1) есть функция Код /* SNTP processing of received timestamp */ static void sntp_process(u32_t *receive_timestamp) { /* convert SNTP time (1900-based) to unix GMT time (1970-based) * @todo: if MSB is 1, SNTP time is 2036-based! */ time_t t = (ntohl(receive_timestamp[0]) - DIFF_SEC_1900_1970);
#if SNTP_CALC_TIME_US u32_t us = ntohl(receive_timestamp[1]) / 4295; SNTP_SET_SYSTEM_TIME_US(t, us); /* display local time from GMT time */ LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&t), us));
#else /* SNTP_CALC_TIME_US */
/* change system time and/or the update the RTC clock */ SNTP_SET_SYSTEM_TIME(t); /* display local time from GMT time */ LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s", ctime(&t))); #endif /* SNTP_CALC_TIME_US */ } Из этого кода следует, что метка времени receive_timestamp[] (момент времени, когда NTP-сервер получил запрос клиента) переводится из NTP timestamp в UnixTime и далее используется клиентом как "время сервера" (эталонное), при этом никак не учитываются два параметра из протокола SNTP (RFC1769 SNTP v3) - циклическая задержка и смещение времени (см.скриншот). Это авторы кода так упростили себе задачу и почему они так сделали? И как учесть циклическую задержку и смещение?
Сообщение отредактировал Pridnya - Dec 12 2016, 06:22
Эскизы прикрепленных изображений
|
|
|
|
|
Dec 13 2016, 12:20
|
Частый гость
 
Группа: Свой
Сообщений: 142
Регистрация: 11-01-11
Из: Орел
Пользователь №: 62 159

|
Не ожидал такой лажи от создателей примеров lwIP contrib-1.4.1, sntp.c. Клиент получает структуру (ответ на запрос с метками времени): CODE #define SNTP_OFFSET_ORIGINATE_TIME 24 #define SNTP_OFFSET_RECEIVE_TIME 32 #define SNTP_OFFSET_TRANSMIT_TIME 40 ... struct sntp_msg { PACK_STRUCT_FIELD(u8_t li_vn_mode); PACK_STRUCT_FIELD(u8_t stratum); PACK_STRUCT_FIELD(u8_t poll); PACK_STRUCT_FIELD(u8_t precision); PACK_STRUCT_FIELD(u32_t root_delay); PACK_STRUCT_FIELD(u32_t root_dispersion); PACK_STRUCT_FIELD(u32_t reference_identifier); PACK_STRUCT_FIELD(u32_t reference_timestamp[2]); // Время синхронизации сервера. PACK_STRUCT_FIELD(u32_t originate_timestamp[2]); // Метка времени клиента (для проверки ответа на свой запрос) PACK_STRUCT_FIELD(u32_t receive_timestamp[2]); // Время получения запроса сервером PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]); // Время на момент отправки ответа сервером. }; ... static void sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) { ... // Создается новый массив для полученной эталонной метки времени. u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE]; ... /*И в новый массив копируется метка "Время получения запроса сервером", при этом сколько времени сервер потратил на обработку запроса никого не интересует. А другие SNTP-клиенты копируют "Время на момент отправки ответа сервером", в этом случае задержка сервера не имеет значения.*/ pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_RECEIVE_TIME);
// Далее следует установка времени. sntp_process(receive_timestamp);
И еще одинаковые длинные имена используют внутри структуры и во временном массиве receive_timestamp[]. Берут не ту метку и заведомо ухудшают точность. И на этом нам предлагается учиться.
|
|
|
|
|
Dec 14 2016, 05:52
|
Частый гость
 
Группа: Свой
Сообщений: 142
Регистрация: 11-01-11
Из: Орел
Пользователь №: 62 159

|
Цитата(jcxz @ Dec 13 2016, 17:05)  А что Вы хотите? "Дарёному коню..." Напишите своё - SNTP - простой протокол. Автор SNTP-клиента Цитата SNTP client module (contrib-1.4.1\apps\sntp) Author: Simon Goldschmidt (lwIP raw API part). он же является автором многочисленных правок LwIP-стека, его имя присутствует в файлах. И я ожидал, что это толковый товарищ, а оказывается за ним все нужно проверять. А вообще, я пишу свою реализацию, хочется учесть недостатки существующих SNTP-клиентов. Цитата(Ruslan1 @ Dec 13 2016, 18:05)  Эх, у меня исходники sntp только для Майкрочипа. А тут просят SNTP именно для АРМов (раз в этом разделе тему создали), значит мои сишные файлы не подойдут. Я вроде не просил. И с SNTP-клиентом знаком. В последней версии MLA Microchip дает исходники простенького такого клиента. Цитата mla\v2016_08_08\framework\tcpip\sntp.h mla\v2016_08_08\framework\tcpip\src\sntp.c Вот мое мнение по этому поводу. Меня интересует, а как в MPLAB Harmony c SNTP-клиентом дела? Цитата(jcxz @ Dec 14 2016, 02:36)  А что - есть SNTP для пиков, а есть - для ARM-ов??? Я думаю в IEEE этого ещё не знают. Надо им сообщить срочно. Пусть внесут правки в стандарт  SNTP-клиент - вещь абстрактная, он не знает о существовании микроконтроллеров, не знает на какой архитектуре запущен. Но SNTP-клиент для PIC-ов есть и выложен он в mla\v2016_08_08\framework\tcpip\src\sntp.c. Но он совсем простой, т.к. авторы предполагали, что он будет работать даже на PIC18. Но после PIC18 есть же еще PIC24, PIC32MX и PIC32MZ, и не совсем правильно для PIC32 использовать клиент со времен PIC18 (те же исходникик). Если архитектура микроконтроллера позволяет, то можно и улучшить SNTP-клиент, повысить точность. PS: Полно простых реализаций SNT-клиентов, которые не проверяют, когда последний раз синхронизировался сам сервер, не вставляют в запрос свою метку времени, не учитывают субсекунды (до секунд и хватит), не учитывают время задержки, а ведь SNTP позволяет получить точность 1-50 мс от сервера в Интернете и до 0,2 мс от сервера в локальной сети. И тоже называются SNTP-клиентами.
|
|
|
|
|
Dec 14 2016, 13:38
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
Мда, мой шутка был понят не всеми, разъясню что имел в виду: Тему создали в разделе "ARM", значит Топикстартеру нужно именно под АРМ. Я тоже не вижу разницы, но Топикстартеру виднее, раз именно тут спрошено.
Про "sntp для Майкрочип": я его писал уж наверное 7 лет как, тогда Майкрочип такого и не предлагал. Прочитал описание, посмотрел исходники из Линукса- и вперед на амбразуру. Но если сейчас предлагают, да еще и "простенький" (а что там сложного может быть в отсылке запроса-разборке принятого?) - то и отлично, можно посмотреть, а не писать с нуля.
|
|
|
|
|
Dec 15 2016, 05:40
|
Частый гость
 
Группа: Свой
Сообщений: 142
Регистрация: 11-01-11
Из: Орел
Пользователь №: 62 159

|
Цитата(Ruslan1 @ Dec 14 2016, 16:38)  Мда, мой шутка был понят не всеми, разъясню что имел в виду: Тему создали в разделе "ARM", значит Топикстартеру нужно именно под АРМ. Я тоже не вижу разницы, но Топикстартеру виднее, раз именно тут спрошено.
Про "sntp для Майкрочип": я его писал уж наверное 7 лет как, тогда Майкрочип такого и не предлагал. Прочитал описание, посмотрел исходники из Линукса- и вперед на амбразуру. Но если сейчас предлагают, да еще и "простенький" (а что там сложного может быть в отсылке запроса-разборке принятого?) - то и отлично, можно посмотреть, а не писать с нуля. Вы снова пошутили? Или я опять что-то не понял? В 2012-м году я использовал Microchip Solutions v2010-10-19\Microchip\TCPIP Stack\, эта библиотека у меня и сейчас установлена. Она содержит исходник SNTP-клиента на Си - файл sntp.c, в котором есть запись Цитата * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Darren Wenn 03/08/07 Original * Howard Schlunder 06/20/07 Modified for release ********************************************************************/ #define __SNTP_C Она означает, что SNTP-клиент в исходниках у Microchip есть с 2007-го года, т.е. почти 10 лет. Я вообще знаком с продукцией Microchip, с неё и начинал, а с STM32 последние несколько лет работаю. А сложности там есть и SNTP-клиенты бывают простые и посложнее, как и программисты. А вопрос попал в тему "ARM" из-за того, что SNTP-клиент для LwIP-стека может отличаться от SNTP-клиента для Microchip TCP/IP-стека и т.д. И чем выше производительность микроконтроллера, тем выше достоверность и точность установки времени (мне нужно не хуже 0,01 сек). Для меня есть разница. И мне такие ответы не интересны. Цитата(Ruslan1 @ Dec 13 2016, 18:05)  Эх, у меня исходники sntp только для Майкрочипа. А тут просят SNTP именно для АРМов (раз в этом разделе тему создали), значит мои сишные файлы не подойдут. В первом посте я немного ошибся: Цитата(Pridnya @ Dec 12 2016, 08:53)  Заполняю структуру sntp_msg, Код struct sntp_msg { ... PACK_STRUCT_FIELD(u32_t reference_timestamp[2]); PACK_STRUCT_FIELD(u32_t originate_timestamp[2]); PACK_STRUCT_FIELD(u32_t receive_timestamp[2]); PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]); }; вставляю в неё свою метку времени originate_timestamp[] и отправляю её NTP-серверу (служба времени Windows), в ответ получаю такую же структуру с четырьмя метками времени. SNTP-клиент вставляет свою метку времни в запрос в поле u32_t transmit_timestamp[2], а получает её обратно в поле u32_t originate_timestamp[2] (NTP-клиент Windows переставляет метку).
|
|
|
|
|
Dec 15 2016, 11:13
|
Частый гость
 
Группа: Свой
Сообщений: 142
Регистрация: 11-01-11
Из: Орел
Пользователь №: 62 159

|
Цитата(Ruslan1 @ Dec 15 2016, 14:01)  А, ну значит уже было, а я-то просто не искал тогда. Значит ошибся, извиняюсь. Да ладно! Цитата(Ruslan1 @ Dec 15 2016, 14:01)  Но sntp протокол действительно очень "simple" и совершенно не привязан к типу ядра микроконтроллера. Вот это "simple" каждый понимает по-своему, в меру разумения. Код клиента на Си не привязан к ядру (к системе команд), даже к периферии не привязан, зато привязан к конкретному TCP/IP-стеку, который портируется для конкретной архитектуры (и не всегда есть порт для конкретной архитектуры). Для того же LwIP есть несколько вариантов клиента (с использованием RTOS и без неё) и т.д. А у Microchip клиент за 10 лет практически не изменился, в последней версии microchip\mla\v2016_08_08\framework\tcpip\src\sntp.c практически тот же что и в 2007-м году файл, только нет строк об авторах и дате. Стыдно, наверное.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|