viakon 0 15 августа, 2012 Опубликовано 15 августа, 2012 · Жалоба Растолкуйте по простому SUBJ на уровне 1 посылаешь по 123 порту xxxxx 2 получаешь хххххх где xx часы xx минуты Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 15 августа, 2012 Опубликовано 15 августа, 2012 · Жалоба Гугл сломался? Вот моя реализация клиента SNTP, может быть что-то полезное почерпнёте: /** * @file sntp.c * @brief SNTP client / clock */ #include "sntp.h" #include "event.h" #include "systime.h" #include "mcf5223xif.h" #include "lwip/udp.h" #include "assert_static.h" #include <time.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #define SENDFAIL_TIMEOUT 5000 /* 5 seconds */ #define SENT_TIMEOUT 60000 /* 1 minute */ #define BADREPLY_TIMEOUT 60000 /* 1 minute */ #define VALID_TIMEOUT (8 * 3600000) /* 8 hours */ #define SECSPERMIN 60L #define MINSPERHOUR 60L #define HOURSPERDAY 24L #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) #define SECSPERDAY (SECSPERHOUR * HOURSPERDAY) #define DAYSPERWEEK 7 #define MONSPERYEAR 12 #define YEAR_BASE 1900 #define EPOCH_WDAY 1 #define EPOCH_YEARS_SINCE_LEAP 2 #define EPOCH_YEARS_SINCE_CENTURY 70 #define EPOCH_YEARS_SINCE_LEAP_CENTURY 370 #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) enum sntp_state { SNTP_INIT, SNTP_SENDFAIL, SNTP_SENT, SNTP_BADREPLY, SNTP_VALID }; struct sntp_packet { uint8_t status; uint8_t stratum; uint8_t ppoll; uint8_t precision; uint32_t distance; uint32_t dispersion; uint32_t refid; uint64_t reftime; uint64_t org; uint64_t rec; uint64_t xmt; }; static bool time_valid = false; static enum sntp_state state = SNTP_INIT; static int32_t last_time, link_time; static struct udp_pcb* upcb; static struct ip_addr server; static uint_fast16_t port = 123; static uint64_t startup_time; /* timestamp in UTC */ static int_fast16_t tz; static uint64_t ms2ts(uint64_t ms) { return ((ms / 1000) << 32) | (((ms % 1000) / 4) << 24); } static void recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { if (p->len == sizeof(struct sntp_packet)) { int i; struct sntp_packet *ptr; assert(p->len == p->tot_len); /* don't accept chained pbuf */ ptr = p->payload; i = (ptr->status >> 3) & 7; if ((i < 1) || (i > 4)) /* SNTP version 1..4 */ { goto out; } i = ptr->status & 7; if ((i != 4) && (i != 5)) /* mode 4 or 5: server or broadcast */ { goto out; } if (ptr->stratum == 0) { goto out; } if (ptr->xmt == 0) { goto out; } startup_time = ptr->xmt - ms2ts(systime_ms64()); if (!time_valid) { time_valid = true; event_trigger(EVENT_SNTPSYNC); } state = SNTP_VALID; last_time = systime_ms32(); } out: pbuf_free(p); } void sntp_enable(bool enable) { assert_static(BYTE_ORDER == BIG_ENDIAN); if (enable) { if (upcb == 0) { err_t ret; upcb = udp_new(); assert(upcb != 0); ret = udp_bind(upcb, IP_ADDR_ANY, port); if (ret != ERR_OK) { udp_remove(upcb); upcb = 0; } else { udp_recv(upcb, recv, 0); } state = SNTP_INIT; } } else if (upcb != 0) { udp_remove(upcb); upcb = 0; } } bool sntp_isenabled(void) { return upcb != 0; } void sntp_setserveraddr(const struct ip_addr *addr) { ip_addr_copy(server, *addr); } void sntp_getserveraddr(struct ip_addr *addr) { ip_addr_copy(*addr, server); } void sntp_setserverport(uint_fast16_t port_arg) { port = port_arg; if (sntp_isenabled()) { sntp_enable(false); sntp_enable(true); } } uint_fast16_t sntp_getserverport(void) { return port; } void sntp_settz(int_fast16_t tz_arg) { tz = tz_arg; } int_fast16_t sntp_gettz(void) { return tz; } static void send_request(void) { struct sntp_packet packet; struct pbuf* psend; memset(&packet, 0, sizeof(packet)); packet.status = (3 << 3) /* SNTP vesion 3 */ | (3 << 0); /* Mode: client */ psend = pbuf_alloc(PBUF_RAW, sizeof(packet), PBUF_REF); if (psend != 0) { psend->payload = &packet; state = (udp_sendto(upcb, psend, &server, port) == ERR_OK) ? SNTP_SENT : SNTP_SENDFAIL; pbuf_free(psend); } last_time = systime_ms32(); } void sntp_poll(void) { if (mcf5223xif_link() == false) { link_time = systime_ms32(); } else if (upcb != 0) { int32_t now, timeout; now = systime_ms32(); if (abs(now - link_time) > 2000) { switch (state) { case SNTP_INIT: send_request(); return; case SNTP_SENDFAIL: timeout = SENDFAIL_TIMEOUT; break; case SNTP_SENT: timeout = SENT_TIMEOUT; break; case SNTP_BADREPLY: timeout = BADREPLY_TIMEOUT; break; case SNTP_VALID: timeout = VALID_TIMEOUT; break; } if (now - last_time > timeout) { send_request(); } } } } bool sntp_valid(void) { return time_valid; } uint32_t sntp_timestamp(void) { return time_valid ? (startup_time + ms2ts(systime_ms64())) >> 32 : 0; } static const uint8_t mon_lengths[2][MONSPERYEAR] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} } ; static const int year_lengths[2] = { 365, 366 } ; void sntp_seconds2tm(uint32_t sec32, struct tm* res) { long days, rem; int y; int yleap; const uint8_t *ip; uint64_t sec; sec = sec32 + 60 * tz; if (((sec32 & 0x80000000UL) == 0) && (sec32 != 0)) { sec += ((uint64_t)1 << 32); } days = sec / SECSPERDAY; rem = sec % SECSPERDAY; /* compute hour, min, and sec */ res->tm_hour = (int) (rem / SECSPERHOUR); rem %= SECSPERHOUR; res->tm_min = (int) (rem / SECSPERMIN); res->tm_sec = (int) (rem % SECSPERMIN); /* compute day of week */ if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0) { res->tm_wday += DAYSPERWEEK; } /* compute year & day of year */ y = YEAR_BASE; if (days >= 40542) /* days in years 1900..2010 inclusive */ { days -= 40542; y += 111; } if (days >= 0) { for (;;) { yleap = isleap(y); if (days < year_lengths[yleap]) { break; } y++; days -= year_lengths[yleap]; } } else { do { --y; yleap = isleap(y); days += year_lengths[yleap]; } while (days < 0); } res->tm_year = y - YEAR_BASE; res->tm_yday = days; ip = mon_lengths[yleap]; for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon) { days -= ip[res->tm_mon]; } res->tm_mday = days + 1; } void sntp_gettimestr(uint32_t timestamp, char *str) { if (timestamp != 0) { struct tm time; sntp_seconds2tm(timestamp, &time); sprintf(str, "%02d.%02d.%d %02d:%02d:%02d", time.tm_mday, time.tm_mon + 1, time.tm_year + 1900, time.tm_hour, time.tm_min, time.tm_sec); } else { strcpy(str, "00.00.0000 00:00:00"); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
viakon 0 15 августа, 2012 Опубликовано 15 августа, 2012 · Жалоба гуглом все в порядке, просто выдаваемая им куча мусора огромна. спасибо за пример просветление в мозгах подступает:). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pridnya 0 12 декабря, 2016 Опубликовано 12 декабря, 2016 (изменено) · Жалоба Гугл сломался? Еще один "велосипед". Не очень понятно, почему вы вместо функции strftime() стандартной библиотеки time.h пишете свою, делающую то же самое. Или не знали о её существовании? Какой смысл? И за 4 года никто не спросил и не поправил. В предыдущем посте кто-то даже просветлился. А что еще написать на такую портянку, когда сразу не въехал. time_t rawtime = 1480685759; // Fri, 02 Dec 2016 13:35:59 GMT struct tm * timeinfo; timeinfo = (struct tm*)localtime(&rawtime); char buffer [80]; strftime (buffer,80,"%d.%m.%Y %X",timeinfo); puts (buffer); // 02.12.2016 13:35:59 Ладно бы вы использовали какой-нибудь R32C Renesas и их компилятор NC100 в котором стандартная библиотека time.h вообще не реализована, но вы же отвечаете в теме по ARM, а в ARMCC хорошая библиотека. PS: И UnixTime в структуру руками не нужно переписывать (у вас 70 строк кода???): void sntp_seconds2tm(uint32_t sec32, struct tm* res)... Из NTP timestamp вычитаем разницу в секундах между 1970-1900 годами и используем стандартную функцию. PPS: Дальше черпать неохота, т.к. почерпнуть нечего. Изменено 13 декабря, 2016 пользователем IgorKossak бездумное цитирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться