A port and bug fix of Alix955/code/ntp-client. The socket would hang as it was defined both with a timeout and as blocking.

Committer:
sjalloq
Date:
Sun May 26 08:46:35 2019 +0100
Revision:
2:a3aec199dc7c
Parent:
1:099750f42b02
ntp-client : fork from Alix955/code/ntp-client

- sockets should not be setup as blocking if you want to use a timeout. This
resulted in the socket hanging when packets went missing.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Alix955 0:3c1170035e2b 1 #include "ntp-client/NTPClient.h"
Alix955 0:3c1170035e2b 2 #include "mbed.h"
Alix955 0:3c1170035e2b 3
sjalloq 2:a3aec199dc7c 4 NTPClient::NTPClient(NetworkInterface *iface) : iface(iface),
sjalloq 2:a3aec199dc7c 5 nist_server_address((char *)NTP_DEFULT_NIST_SERVER_ADDRESS),
sjalloq 2:a3aec199dc7c 6 nist_server_port(NTP_DEFULT_NIST_SERVER_PORT) {
Alix955 0:3c1170035e2b 7 }
Alix955 0:3c1170035e2b 8
sjalloq 2:a3aec199dc7c 9 void NTPClient::set_server(char* server, int port) {
Alix955 0:3c1170035e2b 10 nist_server_address = server;
sjalloq 2:a3aec199dc7c 11 nist_server_port = port;
Alix955 0:3c1170035e2b 12 }
Alix955 0:3c1170035e2b 13
sjalloq 2:a3aec199dc7c 14 /* The timeout value is in uS. A sensible positive value is >5K to
sjalloq 2:a3aec199dc7c 15 avoid the timeout firing on slow responses. Note that this is UDP
sjalloq 2:a3aec199dc7c 16 so there is the likely possibility that the packet will be lost.
sjalloq 2:a3aec199dc7c 17
sjalloq 2:a3aec199dc7c 18 A timeout value of 0 corresponds to set_blocking(false).
sjalloq 2:a3aec199dc7c 19 A timeout value of -1 corresponds to set_blocking(true).
sjalloq 2:a3aec199dc7c 20 */
Alix955 0:3c1170035e2b 21 time_t NTPClient::get_timestamp(int timeout) {
sjalloq 2:a3aec199dc7c 22 const time_t TIME1970 = (time_t)2208988800UL;
sjalloq 2:a3aec199dc7c 23 int ntp_send_values[12] = {0};
sjalloq 2:a3aec199dc7c 24 int ntp_recv_values[12] = {0};
Alix955 0:3c1170035e2b 25
sjalloq 2:a3aec199dc7c 26 SocketAddress nist;
sjalloq 2:a3aec199dc7c 27 UDPSocket sock;
sjalloq 2:a3aec199dc7c 28 SocketAddress source;
sjalloq 2:a3aec199dc7c 29
sjalloq 2:a3aec199dc7c 30 nsapi_size_or_error_t szerr;
Alix955 0:3c1170035e2b 31
sjalloq 2:a3aec199dc7c 32 int ret_gethostbyname = iface->gethostbyname(nist_server_address, &nist);
sjalloq 2:a3aec199dc7c 33 if (ret_gethostbyname < 0) {
sjalloq 2:a3aec199dc7c 34 // Network error on DNS lookup
sjalloq 2:a3aec199dc7c 35 printf("Error on DNS lookup : %d\n" , ret_gethostbyname);
sjalloq 2:a3aec199dc7c 36 return ret_gethostbyname;
sjalloq 2:a3aec199dc7c 37 }
sjalloq 2:a3aec199dc7c 38 nist.set_port(nist_server_port);
Alix955 0:3c1170035e2b 39
sjalloq 2:a3aec199dc7c 40 memset(ntp_recv_values, 0x00, sizeof(ntp_recv_values));
sjalloq 2:a3aec199dc7c 41 memset(ntp_send_values, 0x00, sizeof(ntp_send_values));
sjalloq 2:a3aec199dc7c 42 ntp_send_values[0] = '\x1b';
Alix955 0:3c1170035e2b 43
sjalloq 2:a3aec199dc7c 44 sock.open(iface);
sjalloq 2:a3aec199dc7c 45 sock.set_timeout(timeout);
sjalloq 2:a3aec199dc7c 46
sjalloq 2:a3aec199dc7c 47 szerr = sock.sendto(nist, (void*)ntp_send_values, sizeof(ntp_send_values));
sjalloq 2:a3aec199dc7c 48 if(szerr < 0) {
sjalloq 2:a3aec199dc7c 49 sock.close();
sjalloq 2:a3aec199dc7c 50 printf("sock.sendto() error code = %d\n\r", szerr);
sjalloq 2:a3aec199dc7c 51 return szerr;
sjalloq 2:a3aec199dc7c 52 }
Alix955 0:3c1170035e2b 53
sjalloq 2:a3aec199dc7c 54 szerr = sock.recvfrom(&source, (void*)ntp_recv_values, sizeof(ntp_recv_values));
sjalloq 2:a3aec199dc7c 55 if(szerr < 0) {
sjalloq 2:a3aec199dc7c 56 sock.close();
sjalloq 2:a3aec199dc7c 57 printf("sock.sendto() error code = %d\n\r", szerr);
sjalloq 2:a3aec199dc7c 58 return szerr;
sjalloq 2:a3aec199dc7c 59 }
Alix955 0:3c1170035e2b 60
sjalloq 2:a3aec199dc7c 61 if (szerr > 10) {
Alix955 0:3c1170035e2b 62 return ntohl(ntp_recv_values[10]) - TIME1970;
Alix955 0:3c1170035e2b 63 } else {
sjalloq 2:a3aec199dc7c 64 // No or partial data returned
sjalloq 2:a3aec199dc7c 65 printf("No or partial data returned: bytes=%d\n\r", szerr);
sjalloq 2:a3aec199dc7c 66 return -1;
sjalloq 2:a3aec199dc7c 67 }
Alix955 0:3c1170035e2b 68 }
Alix955 0:3c1170035e2b 69
Alix955 0:3c1170035e2b 70 uint32_t NTPClient::ntohl(uint32_t x) {
Alix955 0:3c1170035e2b 71 uint32_t ret = (x & 0xff) << 24;
Alix955 0:3c1170035e2b 72 ret |= (x & 0xff00) << 8;
Alix955 0:3c1170035e2b 73 ret |= (x & 0xff0000UL) >> 8;
Alix955 0:3c1170035e2b 74 ret |= (x & 0xff000000UL) >> 24;
Alix955 0:3c1170035e2b 75 return ret;
sjalloq 2:a3aec199dc7c 76 }