реклама на сайте
подробности

 
 
> Протокол SNTP
Pridnya
сообщение Dec 12 2016, 05:53
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 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
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Pridnya
сообщение Dec 13 2016, 12:20
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 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[].
Берут не ту метку и заведомо ухудшают точность. И на этом нам предлагается учиться.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Dec 13 2016, 14:05
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Pridnya @ Dec 13 2016, 15:20) *
И еще одинаковые длинные имена используют внутри структуры и во временном массиве receive_timestamp[].
Берут не ту метку и заведомо ухудшают точность. И на этом нам предлагается учиться.

А что Вы хотите? "Дарёному коню..." Напишите своё - SNTP - простой протокол.
Go to the top of the page
 
+Quote Post
Ruslan1
сообщение Dec 13 2016, 15:05
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025



Эх, у меня исходники sntp только для Майкрочипа. А тут просят SNTP именно для АРМов (раз в этом разделе тему создали), значит мои сишные файлы не подойдут.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 19:33
Рейтинг@Mail.ru


Страница сгенерированна за 0.01377 секунд с 7
ELECTRONIX ©2004-2016