Commit 49514ec4444959b2c8ac62190abf344bd95f9076

Authored by Emilio Soca Herrera
1 parent eb82fd70

--no commit message

Project/applications/smartcities/include/ntp.h
@@ -8,19 +8,6 @@ @@ -8,19 +8,6 @@
8 #include "lwip/sys.h" 8 #include "lwip/sys.h"
9 #include "lwip/api.h" 9 #include "lwip/api.h"
10 #include "ch.h" 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 typedef struct { 12 typedef struct {
26 int second; 13 int second;
@@ -31,24 +18,54 @@ typedef struct { @@ -31,24 +18,54 @@ typedef struct {
31 int year; 18 int year;
32 }Date; 19 }Date;
33 20
  21 +unsigned long getSecsSince1900(void);
  22 +Date getDate(unsigned long);
  23 +void udpNtp_test(void);
  24 +
34 #define LEAP_YEAR(Y) (((1970+Y)>0) && !((1970+Y)%4) && (((1970+Y)%100) || !((1970+Y)%400))) 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 #endif 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 unsigned long daysPerMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 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 int second = epoch % 60; 17 int second = epoch % 60;
238 epoch /= 60; 18 epoch /= 60;
239 int minute = epoch % 60; 19 int minute = epoch % 60;
240 epoch /= 60; 20 epoch /= 60;
241 - int hour = ((epoch % 24) + timeZone) % 24; 21 + int hour = ((epoch % 24) + TIME_ZONE) % 24;
242 epoch /= 24; 22 epoch /= 24;
243 int year = 0; 23 int year = 0;
244 unsigned long days = 0; 24 unsigned long days = 0;
@@ -281,60 +61,126 @@ Date getDate(){ @@ -281,60 +61,126 @@ Date getDate(){
281 return date; 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 \ No newline at end of file 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 \ No newline at end of file 188 \ No newline at end of file