| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 | #include "sntp_api.h"#include "rtc.h"#include "settings_api.h"#include "FreeRTOS.h"#include "task.h"#include "semphr.h"#include "tcpip.h"#include "udp.h"#include <string.h>#include <time.h>#ifdef PRINTF_STDLIB#include <stdio.h>#endif#ifdef PRINTF_CUSTOM#include "tinystdio.h"#endif#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 *//* number of seconds between 1900 and 1970 */#define DIFF_SEC_1900_1970         (2208988800UL)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 unsigned int timeout;static struct udp_pcb* upcb;static struct ip4_addr server;static int port = 123;extern bool ntpResult;extern uint32_t SNTP_Time;/**  * @brief  Отладочный таск. Выводим время в консоль.  * @retval   */void vTaskSntp(void *arg){  TM_RTC_t data;    for (;;)  {    vTaskDelay(1000);	TM_RTC_GetDateTime(&data, TM_RTC_Format_BIN);	printf("%d.%d.%d %d:%d:%d \n\r", data.date,data.month,data.year,data.hours,data.minutes,data.seconds);  }}static void recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, 				 struct ip_addr *addr, u16_t port){  time_t t;  //struct tm *time;  //struct tm *ptrTime = &time;    if (p->len == sizeof(struct sntp_packet))  {    int i;    struct sntp_packet aligned;    //myassert(p->len == p->tot_len); /* don't accept chained pbuf */    memcpy(&aligned, p->payload, sizeof(aligned));    i = (aligned.status >> 3) & 7;    	if ((i < 1) || (i > 4)) /* SNTP version 1..4 */      goto out;    i = aligned.status & 7;	if ((i != 4) && (i != 5)) /* mode 4 or 5: server or broadcast */      goto out;	if (aligned.xmt == 0)      goto out;		t = (ntohl(aligned.xmt) - 2208988800);		TM_RTC_SetDataTimeUnix((uint32_t)t);		//time = __localtime32(&t);		SNTP_Time = t;	ntpResult = true;		//printf("%s\r\n", asctime(time));	timeout = VALID_TIMEOUT;      }  out:    pbuf_free(p);}void SNTP_Enable(bool enable){  if (enable)  {    if (upcb == 0)    {      err_t ret;      upcb = udp_new();      if (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);        }        timeout = 0;	  }    }  }  else if (upcb != 0)  {    udp_remove(upcb);    upcb = 0;  }}bool SNTP_IsEnabled(void){  return upcb != 0;}void SNTP_SetServerAddr(char *addr){  server.addr = ipaddr_addr(addr);}int sntp_getserverport(void){  return port;}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;    timeout = (udp_sendto(upcb, psend, &server, port) == ERR_OK) ? SENT_TIMEOUT : SENDFAIL_TIMEOUT;    pbuf_free(psend);  }}void SNTP_Poll(void){  if (upcb)    send_request();}
 |