Commit 49514ec4444959b2c8ac62190abf344bd95f9076

Authored by Emilio Soca Herrera
1 parent eb82fd70

--no commit message

Project/applications/smartcities/include/ntp.h
... ... @@ -8,19 +8,6 @@
8 8 #include "lwip/sys.h"
9 9 #include "lwip/api.h"
10 10 #include "ch.h"
11   -#include <stdio.h>
12   -#include <time.h>
13   -#include <string.h>
14   -#include <stdlib.h>
15   -#include <unistd.h>
16   -#include <math.h>
17   -#include <sys/time.h>
18   -
19   -
20   -#define NTP_PACKET_LENGTH 48
21   -#define NTP_SERVER "81.184.154.182"
22   -//const uint16_t remotePort = 123;
23   -
24 11  
25 12 typedef struct {
26 13 int second;
... ... @@ -31,24 +18,54 @@ typedef struct {
31 18 int year;
32 19 }Date;
33 20  
  21 +unsigned long getSecsSince1900(void);
  22 +Date getDate(unsigned long);
  23 +void udpNtp_test(void);
  24 +
34 25 #define LEAP_YEAR(Y) (((1970+Y)>0) && !((1970+Y)%4) && (((1970+Y)%100) || !((1970+Y)%400)))
35   -//const unsigned long seventyYears = 2208988800UL;
36   -//const int timeZone = 2; //Time offset from GMT
37   -//unsigned long daysPerMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
38 26  
39   -void udpNTP_Setup(void);
40   -unsigned long getSecsSince1900(void);
41   -Date getDate(void);
  27 +#define NTP_PACKET_LENGTH 48
42 28  
43   -void udpNtp_test(void);
  29 +//cabecera de netconn api
  30 +#ifndef SNTP_PORT
  31 +#define SNTP_PORT 123
  32 +#endif
  33 +
  34 +/** SNTP server address as IPv4 address in "u32_t" format */
  35 +#ifndef SNTP_SERVER_ADDRESS
  36 +#define SNTP_SERVER_ADDRESS ipaddr_addr("81.184.154.182") /* your ntp server */
  37 +#endif
  38 +
  39 +/** SNTP receive timeout - in milliseconds */
  40 +#ifndef SNTP_RECV_TIMEOUT
  41 +#define SNTP_RECV_TIMEOUT 3000
  42 +#endif
  43 +
  44 +/** SNTP update delay - in milliseconds */
  45 +#ifndef SNTP_UPDATE_DELAY
  46 +#define SNTP_UPDATE_DELAY 60000
  47 +#endif
  48 +
  49 +/** SNTP macro to change system time and/or the update the RTC clock */
  50 +#ifndef SNTP_SYSTEM_TIME
  51 +#define SNTP_SYSTEM_TIME(t)
  52 +#endif
  53 +
  54 +/* SNTP protocol defines */
  55 +#define SNTP_MAX_DATA_LEN 48
  56 +#define SNTP_RCV_TIME_OFS 32
  57 +#define SNTP_LI_NO_WARNING 0x00
  58 +#define SNTP_VERSION (4/* NTP Version 4*/<<3)
  59 +#define SNTP_MODE_CLIENT 0x03
  60 +#define SNTP_MODE_SERVER 0x04
  61 +#define SNTP_MODE_BROADCAST 0x05
  62 +#define SNTP_MODE_MASK 0x07
  63 +
  64 +/* number of seconds between 1900 and 1970 */
  65 +#define DIFF_SEC_1900_1970 (2208988800)
44 66  
45   -void udpNtp_init(void);
46   -void udpNtp_send(void);
47   -void udpNtp_dataReceivedCb(void * arg, struct udp_pcb * upcb,struct pbuf * firstPbuf,struct ip_addr * addr, u16_t port);
48   -uint32_t udpNtp_setupConnection(void);
49   -uint32_t udpNtp_setupConnectionL(void);
50   -uint32_t read32(char* buffer, int offset);
51   -char* timestamp_data(char* value,Date time);
  67 +/*timezone from GMT*/
  68 +#define TIME_ZONE 2
52 69  
53 70  
54 71 #endif
... ...
Project/applications/smartcities/ntp.c
1   -#include "ntp.h"
2   -
3   -#define DBG(fmt,...) if(1){printf("[NTP] "fmt"\r\n", ##__VA_ARGS__);}else{({});}
4   -#define DBG_WARNING(fmt,...) if(1){printf("[NTP_WARNING] "fmt"\r\n", ##__VA_ARGS__);}else{({});}
5   -
6   -//define LEAP_YEAR(Y) (((1970+Y)>0) && !((1970+Y)%4) && (((1970+Y)%100) || !((1970+Y)%400)))
7   -//const unsigned long seventyYears = 2208988800UL;
8   -//const int timeZone = 2; //Time offset from GMT
9   -//unsigned long daysPerMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
10   -unsigned long secsSince1900=0;
11   -int flag=0;
12   -
13   -struct udp_pcb* udpConnectionHandler= NULL;
14   -uint8_t udpNtpOnline = 0;
15   -
16   -
17   -/*----------------------------------------------------------------------------------------------------------------------------------------
18   -INITIALIZATION/PROCESSING FUNCTIONS
19   ------------------------------------------------------------------------------------------------------------------------------------------*/
20   -void udpNtp_init(){
21   - udpConnectionHandler= NULL;
22   - udpNtpOnline = 0;
23   - secsSince1900=0;
24   - flag=0;
25   -}
26   -
27   -/*
28   -* Check if the connection handler has been initialized,
29   -* and if so send a new message
30   -*/
31   -void udpNtp_process(){
32   - while(udpNtpOnline==0){
33   - DBG("TX abandonned! [Not connected]\r\n");
34   - chThdSleepMilliseconds(500);
35   - }
36   - udpNtp_send();
37   -}
38   -
39   -/*----------------------------------------------------------------------------------------------------------------------------------------
40   -UDP TRANSMISSION HANDLING FUNCTIONS
41   ------------------------------------------------------------------------------------------------------------------------------------------*/
42   -/*
43   -* Sends a new message to the remote peer
44   -*/
45   -void udpNtp_send(){
46   - uint16_t remotePort = 123;
47   - char packetBuffer[NTP_PACKET_LENGTH];
48   - static uint32_t messageCount = 0;
49   - memset (packetBuffer,0,NTP_PACKET_LENGTH);
50   - packetBuffer[0] =0x1B;//0b11100011; // LI, Version, Mode
51   - packetBuffer[1] = 0; // Stratum, or type of clock
52   - packetBuffer[2] = 6; // Polling Interval
53   - packetBuffer[3] = 0xEC; // Peer Clock Precision
54   - // 8 bytes of zero for Root Delay & Root Dispersion
55   - packetBuffer[12] = 49;
56   - packetBuffer[13] = 0x4E;
57   - packetBuffer[14] = 49;
58   - packetBuffer[15] = 52;
59   - struct pbuf *pbuffer;
60   - ip_addr_t addr;
61   - uint32_t ipaddr;
62   -
63   - err_t err;
64   -
65   - //Convert the IP address from string to lwip format
66   - ipaddr = ipaddr_addr(NTP_SERVER);
67   - ip4_addr_set_u32((&addr), ipaddr);
68   -
69   - /*
70   - * Allocate a pbuf which we are going to fill with the transmitted data.
71   - * We use libwismart_LwIP_lock() here because we are making a LWIP call
72   - */
73   -libwismart_LwIP_lock();
74   - pbuffer = pbuf_alloc(PBUF_TRANSPORT, NTP_PACKET_LENGTH, PBUF_POOL);
75   -libwismart_LwIP_unlock();
76   - if(pbuffer == NULL){
77   - DBG_WARNING("pbuf_alloc() FAILED!\r\n");
78   - return;
79   - }
80   -
81   - /*
82   - * Fill the payload of the pbuf with the message to be transmitted
83   - * NOTE: Because pbuffer->payload has type (void*), we have to cast it (else we may have undefined behaviour)
84   - */
85   - memcpy((uint8_t*)pbuffer->payload, packetBuffer, NTP_PACKET_LENGTH);
86   -
87   - /*
88   - * Send the packet and release the allocated pbuf.
89   - * We use libwismart_LwIP_lock() here because we are making a LWIP call
90   - */
91   - libwismart_LwIP_lock();
92   - err = udp_sendto(udpConnectionHandler, pbuffer, &addr, remotePort);
93   - libwismart_LwIP_unlock();
94   -
95   - /*
96   - * Release the allocated pbuf
97   - * We use libwismart_LwIP_lock() here because we are making a LWIP call
98   - */
99   - libwismart_LwIP_lock();
100   - pbuf_free(pbuffer);
101   - libwismart_LwIP_unlock();
102   -
103   - if(err != ERR_OK){
104   - DBG_WARNING("udp_sendto() FAILED!");
105   - return;
106   - }
107   -
108   - DBG("Message #%u sent!",messageCount++);
109   -}
110   -
111   -/*----------------------------------------------------------------------------------------------------------------------------------------
112   -UDP RECEPTION HANDLING FUNCTIONS
113   ------------------------------------------------------------------------------------------------------------------------------------------*/
114   -void udpNtp_dataReceivedCb(void * arg, struct udp_pcb * upcb,struct pbuf * firstPbuf,struct ip_addr * addr, u16_t port){
115   - unsigned char *payload;
116   - unsigned int payloadLen;
117   - struct pbuf *currentPbuf;
118   -
119   - currentPbuf = firstPbuf;
120   - while(currentPbuf != NULL){
121   -
122   - /*
123   - * It is important to cast the pbufNow->payload because its type is (void*)
124   - */
125   - payload = (unsigned char *)currentPbuf->payload;
126   - payloadLen = currentPbuf->len;
127   -
128   - DBG("New message [%u bytes] received!\r\n", payloadLen);
129   -
130   - currentPbuf = currentPbuf->next;
131   - };
132   -
133   - uint32_t temp=read32(payload, 40);
134   - secsSince1900=(unsigned long) temp;
135   - flag=1;
136   -
137   - /*
138   - * Free the pbuf list.
139   - */
140   - pbuf_free(firstPbuf);
141   -
142   -}
143   -
144   -/*----------------------------------------------------------------------------------------------------------------------------------------
145   -UDP CONNECTION SETUP FUNCTIONS
146   ------------------------------------------------------------------------------------------------------------------------------------------*/
147   -/*
148   -* Setups a new udp connection handler
149   -*/
150   -uint32_t udpNtp_setupConnection(){
151   - uint32_t error;
152   -
153   -libwismart_LwIP_lock();
154   - error = udpNtp_setupConnectionL();
155   -libwismart_LwIP_unlock();
156   -
157   - return error;
158   -}
159   -
160   -/*
161   -* Setups a new udp connection handler (Locked version of udpNTP_setupConnection)
162   -*/
163   -uint32_t udpNtp_setupConnectionL(){
164   - uint16_t localPort = 5004;
165   - err_t err;
166   -
167   - /*
168   - * Create a new udp connection handler
169   - */
170   - udpConnectionHandler = udp_new();
171   - if(udpConnectionHandler == NULL){
172   - DBG_WARNING("udp_new() FAILED!\r\n");
173   - return 1;
174   - }
175   -
176   - /*
177   - * Bind the connection to a local port. By giving 0
178   - * as third argument(port), you can say to lwip to bind the connection
179   - * to any available port of our system.
180   - */
181   - err = udp_bind(udpConnectionHandler, IP_ADDR_ANY, localPort);
182   - if(err != ERR_OK){
183   - DBG_WARNING("udp_bind() FAILED!\r\n");
184   - udp_remove(udpConnectionHandler);
185   - return 2;
186   - }
187   - /*
188   - * Set the callback function when udp data are received.
189   - * Since we only transmit, we should set this to NULL(second argument).
190   - * For demonstration reasons only we provide a callback function
191   - * that will be called each time a packet is received at port 'localPort'
192   - */
193   - udp_recv(udpConnectionHandler, udpNtp_dataReceivedCb, NULL);
194   -
195   - udpNtpOnline = 1;
196   -
197   - return 0;
198   -}
199   -
200   -uint32_t read32(char* buffer, int offset) {
201   - char b0 = buffer[offset];
202   - char b1 = buffer[offset+1];
203   - char b2 = buffer[offset+2];
204   - char b3 = buffer[offset+3];
205   -
206   - // convert signed bytes to unsigned values
207   - uint32_t i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
208   - uint32_t i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
209   - uint32_t i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
210   - uint32_t i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);
211   -
212   - uint32_t v = (i0 << 24) + (i1 << 16) + (i2 << 8) + i3;
213   - return v;
214   -}
215   -
216   -unsigned long getSecsSince1900(){
217   - while(flag==0){
218   - DBG("in function getSecsSince1900: waiting for NTP procces\n");
219   - chThdSleepMilliseconds(500);
220   - }
221   - return secsSince1900;
222   -}
223   -
224   -Date getDate(){
225   - while(flag==0){
226   - DBG("in function getDate: waiting for NTP procces\n");
227   - chThdSleepMilliseconds(500);
228   - }
  1 +#include <stdio.h>
  2 +#include <time.h>
  3 +#include <string.h>
  4 +#include <stdlib.h>
  5 +#include <unistd.h>
  6 +#include <errno.h>
  7 +#include <math.h>
  8 +#include <sys/time.h>
229 9  
  10 +#include "ntp.h"
230 11  
231   - const unsigned long seventyYears = 2208988800UL;
232   - const int timeZone = 2; //Time offset from GMT
  12 +Date getDate(unsigned long secsSince1900){
233 13 unsigned long daysPerMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
234 14  
235   - unsigned long epoch = secsSince1900 - seventyYears;
  15 + unsigned long epoch = secsSince1900 - DIFF_SEC_1900_1970;
236 16  
237 17 int second = epoch % 60;
238 18 epoch /= 60;
239 19 int minute = epoch % 60;
240 20 epoch /= 60;
241   - int hour = ((epoch % 24) + timeZone) % 24;
  21 + int hour = ((epoch % 24) + TIME_ZONE) % 24;
242 22 epoch /= 24;
243 23 int year = 0;
244 24 unsigned long days = 0;
... ... @@ -281,60 +61,126 @@ Date getDate(){
281 61 return date;
282 62 }
283 63  
284   -void udpNTP_Setup(){
285   - DBG("start_init\r\n");
286   - udpNtp_init();
287   -
288   - DBG("start_Setup_Connection\r\n");
289   - udpNtp_setupConnectionL();
290   -
291   - DBG("start_Procces\r\n");
292   - udpNtp_process();
293   -}
294   -
295   -char* timestamp_data(char* value,Date time)
  64 +unsigned long getSecsSince1900 (void)
296 65 {
297   - uint8_t length = strlen(value) + strlen(",00/00/0000T00:00:00") + 1;
298   - char str_day[3],str_month[3],str_year[5],str_hour[3],str_minute[3],str_second[3];
299   - char* data = chHeapAlloc(NULL,length*sizeof(char));
  66 + unsigned char * sntp_request;
  67 + unsigned char * sntp_response;
  68 + struct ip_addr sntp_server_address;
  69 + time_t timestamp = 0;
  70 +
  71 + struct netconn * sendUDPNetConn;
  72 + struct netbuf * sendUDPNetBuf;
  73 + struct netbuf * receiveUDPNetBuf;
  74 +
  75 + u16_t dataLen;
  76 + err_t errLWIP;
  77 +
  78 + /* initialize SNTP server address */
  79 + sntp_server_address.addr = SNTP_SERVER_ADDRESS;
  80 +
  81 + /* if we got a valid SNTP server address... */
  82 + if (sntp_server_address.addr != 0)
  83 + {
  84 + /* create new socket */
  85 + sendUDPNetConn = netconn_new( NETCONN_UDP );
  86 + sendUDPNetBuf = netbuf_new();
  87 + // Create data space for netbuf, if we can.
  88 + sntp_request = (unsigned char *) netbuf_alloc(sendUDPNetBuf, SNTP_MAX_DATA_LEN);
  89 +
  90 + if ((NULL != sendUDPNetConn) && (NULL != sendUDPNetBuf) && (NULL != sntp_request))
  91 + {
  92 + errLWIP = netconn_connect(sendUDPNetConn, &sntp_server_address, SNTP_PORT);
  93 + if (ERR_OK == errLWIP)
  94 + {
  95 + /* prepare SNTP request */
  96 + memset(sntp_request, 0, SNTP_MAX_DATA_LEN);
  97 + sntp_request[0] = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
  98 +
  99 + errLWIP = netconn_send(sendUDPNetConn, sendUDPNetBuf);
  100 + // Send SNTP request to server.
  101 + if (ERR_OK == errLWIP)
  102 + {
  103 + // Set recv timeout.
  104 + sendUDPNetConn->recv_timeout = SNTP_RECV_TIMEOUT;
  105 + // Receive SNTP server response.
  106 + //receiveUDPNetBuf = netconn_recv(sendUDPNetConn);
  107 + errLWIP=netconn_recv(sendUDPNetConn, &receiveUDPNetBuf);
  108 +
  109 +
  110 + //if (NULL != receiveUDPNetBuf)
  111 + if(errLWIP==ERR_OK)
  112 + {
  113 + // Get pointer to response data.
  114 + netbuf_data(receiveUDPNetBuf, (void **) &sntp_response, (u16_t *) &dataLen);
  115 +
  116 +
  117 + // If the response size is good.
  118 + if (dataLen == SNTP_MAX_DATA_LEN)
  119 + {
  120 + // If this is a SNTP response...
  121 + if (((sntp_response[0] & SNTP_MODE_MASK) == SNTP_MODE_SERVER) || ((sntp_response[0] & SNTP_MODE_MASK) == SNTP_MODE_BROADCAST))
  122 + {
  123 + /* extract GMT time from response */
  124 + memcpy(&timestamp, (sntp_response + SNTP_RCV_TIME_OFS), sizeof(timestamp));
  125 + //timestamp = (ntohl(timestamp) - DIFF_SEC_1900_1970);
  126 + timestamp=(ntohl(timestamp));
  127 +
  128 + printf("Received timestamp %u\r\n", timestamp);
  129 + }
  130 + else
  131 + {
  132 + printf("Received data did not match frame code\r\n");
  133 + }
  134 + }
  135 + else
  136 + {
  137 + printf("Length of data did not match SNTP_MAX_DATA_LEN, received len %u\r\n", dataLen);
  138 + }
  139 + // Deallocate space hold for netbuf structure.
  140 + netbuf_delete(receiveUDPNetBuf);
  141 + }
  142 + else
  143 + {
  144 + //printf("Netconn receive failed with %d\r\n", netconn_err(sendUDPNetConn));
  145 + printf("Netconn receive failed with %d\r\n", netconn_err(sendUDPNetConn));
  146 + }
  147 + } // netconn_send(sendUDPNetConn, sendUDPNetBuf);
  148 + else
  149 + {
  150 + printf("Netconn sendto failed with %d\r\n", errLWIP);
  151 + }
  152 + } //netconn_connect(sendUDPNetConn, &sntp_server_address, SNTP_PORT);
  153 + else
  154 + {
  155 + printf("Netconn connect to server %X, port %u failed with %d\r\n", sntp_server_address.addr, SNTP_PORT, errLWIP);
  156 + }
  157 + } // if ((NULL != sendUDPNetConn) && (NULL != sendUDPNetBuf) && (NULL != sntp_request))
  158 + else
  159 + {
  160 + printf("Netconn or netbuf or data allocation failed.\r\n");
  161 + }
300 162  
301   - sprintf(str_day,"%d",time.day);
302   - sprintf(str_month,"%d",time.month);
303   - sprintf(str_year,"%d",time.year);
304   - sprintf(str_hour,"%d",time.hour);
305   - sprintf(str_minute,"%d",time.minute);
306   - sprintf(str_second,"%d",time.second);
  163 + // Deallocate space hold for netconn and netbuf structure.
  164 + netbuf_delete(sendUDPNetBuf);
  165 + netconn_delete(sendUDPNetConn);
  166 + } //if (sntp_server_address != 0)
  167 + else
  168 + {
  169 + printf("Invalid NTP server address %X\r\n", SNTP_SERVER_ADDRESS);
  170 + }
307 171  
308   - strcpy(data,value);
309   - strcat(data,",");
310   - strcat(data, str_day);
311   - strcat(data,"/");
312   - strcat(data, str_month);
313   - strcat(data,"/");
314   - strcat(data, str_year);
315   - strcat(data,"T");
316   - strcat(data, str_hour);
317   - strcat(data,":");
318   - strcat(data, str_minute);
319   - strcat(data,":");
320   - strcat(data, str_second);
321   - data[length-1] = '\0';
322   - return data;
  172 + return (unsigned long) timestamp;
323 173 }
324 174  
  175 +/*Funcion para testeo del resto de funciones relacionadas con NTP.
  176 + -) getSecsSince1900() solo devuelve los segundos desde 1900, esta función abre y cierra los sockets de forma que puede ser llamada de forma continuada
  177 + -) a getDate() se le deve pasar el resultado de la función anterior
  178 +*/
  179 +void udpNtp_test(){
325 180  
326   -/*Funcion para testeo del resto de funciones relacionadas con NTP. En el main() el orden de ejecución debe ser el siguiente.
327   -1ro: udpNTP_Setup
328   -2do: getSecsSince1900() o getDate()
329   -si se quiere actualizar la fecha actual, debemos llamar primeramente a UdpNTP_Setup.*/
330   -/*void udpNtp_test(){
331   -
332   - udpNTP_Setup();
333   - //unsigned long var1=getSecsSince1900();
334   - Date var2=getDate();
335   -
336   - //DBG("seconds since 1900: %lu\r\n", var1);
  181 + libwismart_EnableBsdSocketAPI();
  182 + Date var2=getDate(getSecsSince1900());
337 183  
338   - DBG("Hora:%i:%i:%i\r\n", var2.hour, var2.minute, var2.second);
339   - DBG("Fecha:%i|%i|%i\r\n", var2.day,var2.month,var2.year);
340   -}*/
341 184 \ No newline at end of file
  185 + printf("Hora:%i:%i:%i\r\n", var2.hour, var2.minute, var2.second);
  186 + printf("Fecha:%i|%i|%i\r\n", var2.day,var2.month,var2.year);
  187 +}
342 188 \ No newline at end of file
... ...