| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 | 
							- #include "sntp.h"
 
- #include "rtc.h"
 
- #include "settings_api.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 ip_addr server;
 
- static int port = 123;
 
- /**
 
-   * @brief  Общая структура настроек
 
-   */
 
- extern SETTINGS_t sSettings;
 
- /**
 
-   * @brief  Разовая синхронизация времени при старте контроллера
 
-   */
 
- extern TaskHandle_t xHandleSntpOnceSinhro;
 
- /**
 
-   * @brief  Синхронизация времени единоразово при включении контроллера
 
-   * @retval 
 
-   */
 
- void vTaskOnceSynchro(void *arg)
 
- {
 
-   for (;;) 
 
-   {
 
- 	if (sSettings.sSNTP.sntpEnable)
 
- 	{  
 
-       vTaskDelay(7000);
 
-   	  SNTP_Poll();
 
- 	  //printf("Once time sinhro\n\r");
 
- 	  vTaskDelete(xHandleSntpOnceSinhro);
 
- 	}
 
- 	else
 
- 	  vTaskDelete(xHandleSntpOnceSinhro);
 
-   }
 
- }
 
- /**
 
-   * @brief  Периодическая синхронизация времени.
 
-   *         Выполняется раз в сутки с 0 часов.
 
-   * @retval 
 
-   */
 
- void vTaskPeriodicSynchro(void *arg)
 
- {
 
-   TM_RTC_t data;
 
-   
 
-   static uint8_t fSinhro = 0;
 
-   
 
-   for (;;) 
 
-   {
 
- 	vTaskDelay(10000);
 
- 	if (sSettings.sSNTP.sntpEnable)
 
- 	{
 
- 	  TM_RTC_GetDateTime(&data, TM_RTC_Format_BIN);
 
- 	  
 
- 	  /* Если пришло время синхронизации */
 
- 	  if ((data.hours == 0) && (fSinhro == 0))
 
- 	  {
 
- 		SNTP_Poll();
 
- 	    fSinhro = 1;
 
- 		//printf("Periodic time sinhro\n\r");
 
- 	  }
 
- 	  
 
- 	  if (data.hours > 1)
 
- 	    fSinhro = 0;
 
- 	}
 
-    	
 
-   }
 
- }
 
- /**
 
-   * @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);
 
-   }
 
- }
 
- /**
 
-   * @brief  Инициализация SNTP.
 
-   * @retval 
 
-   */
 
- void SNTP_Init(void)
 
- {
 
-   
 
-   
 
-   SNTP_SetServerAddr(sSettings.sSNTP.ip);
 
-   SNTP_Enable(sSettings.sSNTP.sntpEnable);
 
- }
 
- static void recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, 
 
- 				 struct ip_addr *addr, u16_t port)
 
- {
 
-   time_t t;
 
-   int utcSec = 0;
 
-   TM_RTC_t data;
 
-   
 
-   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;
 
- 	
 
- 	utcSec = (int)(3600.0*sSettings.sSNTP.timeZone);
 
- 	t = (ntohl(aligned.xmt) - 2208988800 + utcSec );
 
- 	
 
- 	TM_RTC_SetDataTimeUnix((uint32_t)t);
 
- 	
 
- 	/* Сохраним время последней синхронизации */
 
- 	TM_RTC_GetDateTime(&data, TM_RTC_Format_BIN);
 
- 		
 
- 	memset(sSettings.sSNTP.data, 0, sizeof(sSettings.sSNTP.data));
 
- 	
 
- 	sprintf(sSettings.sSNTP.data, "%02d.%02d.%02d %02d:%02d:%02d", 
 
- 			data.date, data.month, data.year,
 
- 			data.hours, data.minutes, data.seconds);
 
- 	
 
-     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();
 
- }
 
 
  |