Bläddra i källkod

【修改】完善 ntp 代码

zylx 7 år sedan
förälder
incheckning
06cdfc462c
1 ändrade filer med 61 tillägg och 48 borttagningar
  1. 61 48
      ntp/ntp.c

+ 61 - 48
ntp/ntp.c

@@ -39,8 +39,8 @@
 #define NTP_TIMEZONE                   NETUTILS_NTP_TIMEZONE
 #endif
 
-#ifdef NETUTILS_NTP_HOSTNAME1
-#define NTP_HOSTNAME1                   NETUTILS_NTP_HOSTNAME1
+#ifdef NETUTILS_NTP_HOSTNAME
+#define NTP_HOSTNAME1                   NETUTILS_NTP_HOSTNAME
 #else
 #define NTP_HOSTNAME1                   NULL
 #endif
@@ -68,9 +68,6 @@
 #define VN(packet)   (uint8_t) ((packet.li_vn_mode & 0x38) >> 3) // (vn   & 00 111 000) >> 3
 #define MODE(packet) (uint8_t) ((packet.li_vn_mode & 0x07) >> 0) // (mode & 00 000 111) >> 0
 
-#define HOST_NAME_LEN                  16
-#define RECV_TIME_DELAY                10
-
 // Structure that defines the 48 byte NTP packet protocol.
 typedef struct {
 
@@ -103,6 +100,38 @@ typedef struct {
 
 static ntp_packet packet = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
+static void sendto_ntp_server(int *sockfd, const char *host_name, struct sockaddr_in *serv_addr, int *server_num)
+{
+    struct hostent *server;
+    socklen_t addr_len = sizeof(struct sockaddr_in);
+    /* NTP UDP port number. */
+    int portno = 123;
+    
+    server = gethostbyname(host_name);
+    if (server == NULL)
+    {
+        LOG_W("no such host(%s)", host_name);
+    }
+    else
+    {
+        /* Zero out the server address structure. */
+        memset((char *)serv_addr, 0, addr_len);
+
+        serv_addr->sin_family = AF_INET;
+
+        /* Convert the port number integer to network big-endian style and save it to the server address structure. */
+        serv_addr->sin_port = htons(portno);
+
+        /* Copy the server's IP address to the server address structure. */
+        memcpy(&serv_addr->sin_addr.s_addr, (char *) server->h_addr, server->h_length);
+
+        sendto(*sockfd, (char *) &packet, sizeof(ntp_packet), 0, (const struct sockaddr *)serv_addr, addr_len);
+
+        *server_num += 1;
+    }
+}
+
+
 /**
  * Get the UTC time from NTP server
  *
@@ -115,24 +144,20 @@ static ntp_packet packet = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  */
 time_t ntp_get_time(const char *host_name)
 {
-    int sockfd, n;
+/* the delay between two receive */
+#define RECV_TIME_DELAY                10
+/* number of NTP servers */
+#define NTP_SERVER_NUM                 3
 
-    struct hostent *server;
-    struct sockaddr_in serv_addr[3];
+    int sockfd, n;
+    struct sockaddr_in serv_addr[NTP_SERVER_NUM];
 
-    /* NTP UDP port number. */
-    int portno = 123;
+    int i = 0;
     int server_num = 0;
     rt_tick_t start = 0;
     time_t new_time = 0;
     socklen_t addr_len = sizeof(struct sockaddr_in);
-    const char host_name_buf[3][HOST_NAME_LEN] = {NTP_HOSTNAME1, NTP_HOSTNAME2, NTP_HOSTNAME3};
-
-    /* Using default host name when host_name is NULL */
-    if (host_name != NULL)
-    {
-        memcpy((void *)&host_name_buf[0], host_name, HOST_NAME_LEN);
-    }
+    const char *const host_name_buf[NTP_SERVER_NUM] = {NTP_HOSTNAME1, NTP_HOSTNAME2, NTP_HOSTNAME3};
 
     /* Create and zero out the packet. All 48 bytes worth. */
     memset(&packet, 0, sizeof(ntp_packet));
@@ -140,45 +165,33 @@ time_t ntp_get_time(const char *host_name)
     /* Set the first byte's bits to 00,011,011 for li = 0, vn = 3, and mode = 3. The rest will be left set to zero.
        Represents 27 in base 10 or 00011011 in base 2. */
     *((char *) &packet + 0) = 0x1b;
-    
+
     /* Create a UDP socket. */
-    sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  
+    sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
     if (sockfd < 0)
     {
         LOG_E("create socket failed");
         return 0;
     }
 
-    for(int i = 0; i < 3; i++)
+    if (host_name)
     {
-        if(strlen(host_name_buf[i]) == 0)
-            continue;
-
-        server = gethostbyname((const char *)&host_name_buf[i]);
-        if (server == NULL)
-        {
-            LOG_W("no such host(%s)", host_name);
-        }
-        else
+        /* access the incoming host_name server */
+        sendto_ntp_server(&sockfd, host_name, serv_addr, &server_num);
+    }
+    else
+    {
+        /* use the default NTP server */
+        for (i = 0; i < NTP_SERVER_NUM; i++)
         {
-            server_num++;
-            
-            /* Zero out the server address structure. */
-            memset((char *)&serv_addr[server_num-1], 0, addr_len);
-            
-            serv_addr[server_num-1].sin_family = AF_INET;
-            
-            /* Convert the port number integer to network big-endian style and save it to the server address structure. */
-            serv_addr[server_num-1].sin_port = htons(portno);
-            
-            /* Copy the server's IP address to the server address structure. */
-            memcpy(&serv_addr[server_num-1].sin_addr.s_addr, (char *) server->h_addr, server->h_length);
-            
-            sendto(sockfd, (char *) &packet, sizeof(ntp_packet), 0, (const struct sockaddr *)&serv_addr[server_num - 1], addr_len);
+            if (host_name_buf[i] == NULL || strlen(host_name_buf[i]) == 0)
+                continue;
+
+            sendto_ntp_server(&sockfd, host_name_buf[i], &serv_addr[server_num], &server_num);
         }
     }
 
-    if(server_num <= 0)
+    if (server_num <= 0)
     {
         goto __exit;
     }
@@ -199,16 +212,16 @@ time_t ntp_get_time(const char *host_name)
                 break;
             }
         }
-        
-        if(n > 0)
+
+        if (n > 0)
         {
             break;
         }
-        
+
         rt_thread_mdelay(RECV_TIME_DELAY);
     }
 
-    if(rt_tick_get() <= start + NTP_GET_TIMEOUT * RT_TICK_PER_SECOND)
+    if (rt_tick_get() <= start + NTP_GET_TIMEOUT * RT_TICK_PER_SECOND)
     {
         /* These two fields contain the time-stamp seconds as the packet left the NTP server.
            The number of seconds correspond to the seconds passed since 1900.