Hi,

if you are insterested in, here is a rewritten contrib socket sntp
client example to use netconn api.

I have test it against WinXP with lwip 1.3.1 on LM3S9b92. You have to
define SNTP_SERVER_ADDRESS variable and  LWIP_SO_RCVTIMEO to enable
UDP timeout.

A piece of customization(e.g. remove calling syslog function, improve
english) should be done.

Martin
#ifndef __SNTP_H__
#define __SNTP_H__


/**
 * SNTP_DEBUG: Enable debugging for SNTP.
 */
#ifndef SNTP_DEBUG
#define SNTP_DEBUG                  LWIP_DBG_ON
#endif

/** SNTP server port */
#ifndef SNTP_PORT
#define SNTP_PORT                   123
#endif

/** SNTP server address as IPv4 address in "u32_t" format */
#ifndef SNTP_SERVER_ADDRESS
#define SNTP_SERVER_ADDRESS         inet_addr("") /* your ntp server */
#endif

/** SNTP receive timeout - in milliseconds */
#ifndef SNTP_RECV_TIMEOUT
#define SNTP_RECV_TIMEOUT           3000
#endif

/** SNTP update delay - in milliseconds */
#ifndef SNTP_UPDATE_DELAY
#define SNTP_UPDATE_DELAY           60000
#endif

/** SNTP macro to change system time and/or the update the RTC clock */
#ifndef SNTP_SYSTEM_TIME
#define SNTP_SYSTEM_TIME(t)
#endif

/* SNTP protocol defines */
#define SNTP_MAX_DATA_LEN           48
#define SNTP_RCV_TIME_OFS           32
#define SNTP_LI_NO_WARNING          0x00
#define SNTP_VERSION               (4/* NTP Version 4*/<<3)
#define SNTP_MODE_CLIENT            0x03
#define SNTP_MODE_SERVER            0x04
#define SNTP_MODE_BROADCAST         0x05
#define SNTP_MODE_MASK              0x07

/* number of seconds between 1900 and 1970 */
#define DIFF_SEC_1900_1970         (2208988800)

time_t sntp_request(void);

#endif /* __SNTP_H__ */
#include <time.h>
#include <string.h>

#include "lwip/api.h"


#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */

/** This is an example of a "SNTP" client (with netconn API).
 *
 * For a list of some public NTP servers, see this link :
 * http://support.ntp.org/bin/view/Servers/NTPPoolServers
 *
 */


#include "sntp_netconn.h"

/**
 * SNTP request
 */
time_t sntp_request(void)
{
	unsigned char * sntp_request;
	unsigned char * sntp_response;
	struct ip_addr sntp_server_address;
	time_t timestamp = 0;

	struct netconn * sendUDPNetConn;
	struct netbuf * sendUDPNetBuf;
	struct netbuf * receiveUDPNetBuf;

	u16_t dataLen;

	err_t errLWIP;

	/* initialize SNTP server address */
	sntp_server_address.addr = SNTP_SERVER_ADDRESS;

	/* if we got a valid SNTP server address... */
	if (sntp_server_address.addr != 0)
	{
		/* create new socket */
		sendUDPNetConn = netconn_new( NETCONN_UDP );
		sendUDPNetBuf = netbuf_new();
		// Create data space for netbuf, if we can.
		sntp_request = (unsigned char *) netbuf_alloc(sendUDPNetBuf, SNTP_MAX_DATA_LEN);

		if ((NULL != sendUDPNetConn) && (NULL != sendUDPNetBuf) && (NULL != sntp_request))
		{
			errLWIP = netconn_connect(sendUDPNetConn, &sntp_server_address, SNTP_PORT);
			if(ERR_OK == errLWIP)
			{
				/* prepare SNTP request */
				memset(sntp_request, 0, SNTP_MAX_DATA_LEN);
				sntp_request[0] = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;

				errLWIP = netconn_send(sendUDPNetConn, sendUDPNetBuf);
				// Send SNTP request to server.
				if (ERR_OK == errLWIP)
				{
					// Set recv timeout.
					sendUDPNetConn->recv_timeout = SNTP_RECV_TIMEOUT;
					// Receive SNTP server response.
					receiveUDPNetBuf = netconn_recv(sendUDPNetConn);

					if (NULL != receiveUDPNetBuf)
					{
						// Get pointer to response data.
						netbuf_data(receiveUDPNetBuf, (void **) &sntp_response,(u16_t *) &dataLen);

						// If the response size is good.
						if (dataLen == SNTP_MAX_DATA_LEN)
						{
							// If this is a SNTP response...
							if (((sntp_response[0] & SNTP_MODE_MASK) == SNTP_MODE_SERVER) || ((sntp_response[0]
									& SNTP_MODE_MASK) == SNTP_MODE_BROADCAST))
							{
								/* extract GMT time from response */
								memcpy(&timestamp, (sntp_response + SNTP_RCV_TIME_OFS), sizeof(timestamp));
								timestamp = (ntohl(timestamp) - DIFF_SEC_1900_1970);

								syslog(LOG_DEBUG | LOG_USER, "Received timestamp %u", timestamp);
							}
							else
							{
								syslog(LOG_INFO | LOG_USER, "Received data did not match frame code");
							}
						}
						else
						{
							syslog(LOG_NOTICE | LOG_USER, "Length of data did not match SNTP_MAX_DATA_LEN, received len %u", dataLen);
						}
					}
					else
					{
						syslog(LOG_WARNING | LOG_USER, "Netconn receive failed with %d", netconn_err(sendUDPNetConn));
					}
				} // netconn_send(sendUDPNetConn, sendUDPNetBuf);
				else
				{
					syslog(LOG_WARNING | LOG_USER, "Netconn sendto failed with %d", errLWIP);
				}
			} //netconn_connect(sendUDPNetConn, &sntp_server_address, SNTP_PORT);
			else
			{
				syslog(LOG_WARNING | LOG_USER, "Netconn connect to server %X, port %u failed with %d", sntp_server_address.addr, SNTP_PORT, errLWIP);
			}
		} // if ((NULL != sendUDPNetConn) && (NULL != sendUDPNetBuf) && (NULL != sntp_request))
		else
		{
			syslog(LOG_ERR | LOG_USER, "Netconn or netbuf or data allocation failed.");
		}
	} //if (sntp_server_address != 0)
	else
	{
		syslog(LOG_WARNING | LOG_USER, "Invalid NTP server address %X", SNTP_SERVER_ADDRESS);
	}

	netbuf_delete(sendUDPNetBuf);
	netbuf_delete(receiveUDPNetBuf);
	netconn_delete(sendUDPNetConn);

	return timestamp;
}

#endif /* LWIP_SOCKET */
_______________________________________________
lwip-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to