/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-2014  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/timex.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <netdb.h>

#include <glib.h>

#include "connman.h"

struct ntp_short {
	uint16_t seconds;
	uint16_t fraction;
} __attribute__ ((packed));

struct ntp_time {
	uint32_t seconds;
	uint32_t fraction;
} __attribute__ ((packed));

struct ntp_msg {
	uint8_t flags;			/* Mode, version and leap indicator */
	uint8_t stratum;		/* Stratum details */
	int8_t poll;			/* Maximum interval in log2 seconds */
	int8_t precision;		/* Clock precision in log2 seconds */
	struct ntp_short rootdelay;	/* Root delay */
	struct ntp_short rootdisp;	/* Root dispersion */
	uint32_t refid;			/* Reference ID */
	struct ntp_time reftime;	/* Reference timestamp */
	struct ntp_time orgtime;	/* Origin timestamp */
	struct ntp_time rectime;	/* Receive timestamp */
	struct ntp_time xmttime;	/* Transmit timestamp */
} __attribute__ ((packed));

#define OFFSET_1900_1970  2208988800UL	/* 1970 - 1900 in seconds */

#define STEPTIME_MIN_OFFSET  0.4

#define LOGTOD(a)  ((a) < 0 ? 1. / (1L << -(a)) : 1L << (int)(a))
#define NSEC_PER_SEC  ((uint64_t)1000000000ULL)
#ifndef ADJ_SETOFFSET
#define ADJ_SETOFFSET		0x0100  /* add 'time' to current time */
#endif

#define NTP_SEND_TIMEOUT       2
#define NTP_SEND_RETRIES       3

#define NTP_FLAG_LI_SHIFT      6
#define NTP_FLAG_LI_MASK       0x3
#define NTP_FLAG_LI_NOWARNING  0x0
#define NTP_FLAG_LI_ADDSECOND  0x1
#define NTP_FLAG_LI_DELSECOND  0x2
#define NTP_FLAG_LI_NOTINSYNC  0x3

#define NTP_FLAG_VN_SHIFT      3
#define NTP_FLAG_VN_MASK       0x7

#define NTP_FLAG_MD_SHIFT      0
#define NTP_FLAG_MD_MASK       0x7
#define NTP_FLAG_MD_UNSPEC     0
#define NTP_FLAG_MD_ACTIVE     1
#define NTP_FLAG_MD_PASSIVE    2
#define NTP_FLAG_MD_CLIENT     3
#define NTP_FLAG_MD_SERVER     4
#define NTP_FLAG_MD_BROADCAST  5
#define NTP_FLAG_MD_CONTROL    6
#define NTP_FLAG_MD_PRIVATE    7

#define NTP_FLAG_VN_VER3       3
#define NTP_FLAG_VN_VER4       4

#define NTP_FLAGS_ENCODE(li, vn, md)  ((uint8_t)( \
                      (((li) & NTP_FLAG_LI_MASK) << NTP_FLAG_LI_SHIFT) | \
                      (((vn) & NTP_FLAG_VN_MASK) << NTP_FLAG_VN_SHIFT) | \
                      (((md) & NTP_FLAG_MD_MASK) << NTP_FLAG_MD_SHIFT)))

#define NTP_FLAGS_LI_DECODE(flags)    ((uint8_t)(((flags) >> NTP_FLAG_LI_SHIFT) & NTP_FLAG_LI_MASK))
#define NTP_FLAGS_VN_DECODE(flags)    ((uint8_t)(((flags) >> NTP_FLAG_VN_SHIFT) & NTP_FLAG_VN_MASK))
#define NTP_FLAGS_MD_DECODE(flags)    ((uint8_t)(((flags) >> NTP_FLAG_MD_SHIFT) & NTP_FLAG_MD_MASK))

#define NTP_PRECISION_S    0
#define NTP_PRECISION_DS   -3
#define NTP_PRECISION_CS   -6
#define NTP_PRECISION_MS   -9
#define NTP_PRECISION_US   -19
#define NTP_PRECISION_NS   -29

static guint channel_watch = 0;
static struct timespec mtx_time;
static int transmit_fd = 0;

static char *timeserver = NULL;
static struct sockaddr_in6 timeserver_addr;
static gint poll_id = 0;
static gint timeout_id = 0;
static guint retries = 0;

static void send_packet(int fd, struct sockaddr *server, uint32_t timeout);

static void next_server(void)
{
	if (timeserver) {
		g_free(timeserver);
		timeserver = NULL;
	}

	__connman_timeserver_sync_next();
}

static gboolean send_timeout(gpointer user_data)
{
	uint32_t timeout = GPOINTER_TO_UINT(user_data);

	DBG("send timeout %u (retries %d)", timeout, retries);

	if (retries++ == NTP_SEND_RETRIES)
		next_server();
	else
		send_packet(transmit_fd, (struct sockaddr *)&timeserver_addr, timeout << 1);

	return FALSE;
}

static void send_packet(int fd, struct sockaddr *server, uint32_t timeout)
{
	struct ntp_msg msg;
	struct timeval transmit_timeval;
	ssize_t len;
	void * addr;
	int size;
	char ipaddrstring[INET6_ADDRSTRLEN + 1];

	/*
	 * At some point, we could specify the actual system precision with:
	 *
	 *   clock_getres(CLOCK_REALTIME, &ts);
	 *   msg.precision = (int)log2(ts.tv_sec + (ts.tv_nsec * 1.0e-9));
	 */
	memset(&msg, 0, sizeof(msg));
	msg.flags = NTP_FLAGS_ENCODE(NTP_FLAG_LI_NOTINSYNC, NTP_FLAG_VN_VER4,
	    NTP_FLAG_MD_CLIENT);
	msg.poll = 4;	// min
	msg.poll = 10;	// max
	msg.precision = NTP_PRECISION_S;

	if (server->sa_family == AF_INET) {
		size = sizeof(struct sockaddr_in);
		addr = (void *)&(((struct sockaddr_in *)&timeserver_addr)->sin_addr);
	} else if (server->sa_family == AF_INET6) {
		size = sizeof(struct sockaddr_in6);
		addr = (void *)&timeserver_addr.sin6_addr;
	} else {
		connman_error("Family is neither ipv4 nor ipv6");
		return;
	}

	gettimeofday(&transmit_timeval, NULL);
	clock_gettime(CLOCK_MONOTONIC, &mtx_time);

	msg.xmttime.seconds = htonl(transmit_timeval.tv_sec + OFFSET_1900_1970);
	msg.xmttime.fraction = htonl(transmit_timeval.tv_usec * 1000);

	len = sendto(fd, &msg, sizeof(msg), MSG_DONTWAIT,
						server, size);

	if (len < 0) {
		connman_error("Time request for server %s failed (%d/%s)",
			inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)),
			errno, strerror(errno));

		if (errno == ENETUNREACH)
			__connman_timeserver_sync_next();

		return;
	}

	if (len != sizeof(msg)) {
		connman_error("Broken time request for server %s",
			inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)));
		return;
	}

	/*
	 * Add an exponential retry timeout to retry the existing
	 * request. After a set number of retries, we'll fallback to
	 * trying another server.
	 */

	timeout_id = g_timeout_add_seconds(timeout, send_timeout,
					GUINT_TO_POINTER(timeout));
}

static gboolean next_poll(gpointer user_data)
{
	poll_id = 0;

	if (!timeserver || transmit_fd == 0)
		return FALSE;

	send_packet(transmit_fd, (struct sockaddr *)&timeserver_addr, NTP_SEND_TIMEOUT);

	return FALSE;
}

static void reset_timeout(void)
{
	if (timeout_id > 0) {
		g_source_remove(timeout_id);
		timeout_id = 0;
	}

	retries = 0;
}

static void decode_msg(void *base, size_t len, struct timeval *tv,
		struct timespec *mrx_time)
{
	struct ntp_msg *msg = base;
	double m_delta, org, rec, xmt, dst;
	double delay, offset;
	static guint transmit_delay;
	struct timex tmx = {};

	if (len < sizeof(*msg)) {
		connman_error("Invalid response from time server");
		return;
	}

	if (!tv) {
		connman_error("Invalid packet timestamp from time server");
		return;
	}

	DBG("flags      : 0x%02x", msg->flags);
	DBG("stratum    : %u", msg->stratum);
	DBG("poll       : %f seconds (%d)",
				LOGTOD(msg->poll), msg->poll);
	DBG("precision  : %f seconds (%d)",
				LOGTOD(msg->precision), msg->precision);
	DBG("root delay : %u seconds (fraction %u)",
			msg->rootdelay.seconds, msg->rootdelay.fraction);
	DBG("root disp. : %u seconds (fraction %u)",
			msg->rootdisp.seconds, msg->rootdisp.fraction);
	DBG("reference  : 0x%04x", msg->refid);

	if (!msg->stratum) {
		/* RFC 4330 ch 8 Kiss-of-Death packet */
		uint32_t code = ntohl(msg->refid);

		connman_info("Skipping server %s KoD code %c%c%c%c",
			timeserver, code >> 24, code >> 16 & 0xff,
			code >> 8 & 0xff, code & 0xff);
		next_server();
		return;
	}

	transmit_delay = LOGTOD(msg->poll);

	if (NTP_FLAGS_LI_DECODE(msg->flags) == NTP_FLAG_LI_NOTINSYNC) {
		DBG("ignoring unsynchronized peer");
		return;
	}


	if (NTP_FLAGS_VN_DECODE(msg->flags) != NTP_FLAG_VN_VER4) {
		if (NTP_FLAGS_VN_DECODE(msg->flags) == NTP_FLAG_VN_VER3) {
			DBG("requested version %d, accepting version %d",
				NTP_FLAG_VN_VER4, NTP_FLAGS_VN_DECODE(msg->flags));
		} else {
			DBG("unsupported version %d", NTP_FLAGS_VN_DECODE(msg->flags));
			return;
		}
	}

	if (NTP_FLAGS_MD_DECODE(msg->flags) != NTP_FLAG_MD_SERVER) {
		DBG("unsupported mode %d", NTP_FLAGS_MD_DECODE(msg->flags));
		return;
	}

	m_delta = mrx_time->tv_sec - mtx_time.tv_sec +
		1.0e-9 * (mrx_time->tv_nsec - mtx_time.tv_nsec);

	org = tv->tv_sec + (1.0e-6 * tv->tv_usec) - m_delta + OFFSET_1900_1970;
	rec = ntohl(msg->rectime.seconds) +
			((double) ntohl(msg->rectime.fraction) / UINT_MAX);
	xmt = ntohl(msg->xmttime.seconds) +
			((double) ntohl(msg->xmttime.fraction) / UINT_MAX);
	dst = tv->tv_sec + (1.0e-6 * tv->tv_usec) + OFFSET_1900_1970;

	DBG("org=%f rec=%f xmt=%f dst=%f", org, rec, xmt, dst);

	offset = ((rec - org) + (xmt - dst)) / 2;
	delay = (dst - org) - (xmt - rec);

	DBG("offset=%f delay=%f", offset, delay);

	/* Remove the timeout, as timeserver has responded */

	reset_timeout();

	/*
	 * Now poll the server every transmit_delay seconds
	 * for time correction.
	 */
	if (poll_id > 0)
		g_source_remove(poll_id);

	DBG("Timeserver %s, next sync in %d seconds", timeserver, transmit_delay);

	poll_id = g_timeout_add_seconds(transmit_delay, next_poll, NULL);

	if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) {
		tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
		tmx.status = STA_PLL;
		tmx.offset = offset * NSEC_PER_SEC;
		tmx.constant = msg->poll - 4;
		tmx.maxerror = 0;
		tmx.esterror = 0;

		connman_info("ntp: adjust (slew): %+.6f sec", offset);
	} else {
		tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET;

		/* ADJ_NANO uses nanoseconds in the microseconds field */
		tmx.time.tv_sec = (long)offset;
		tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;

		/* the kernel expects -0.3s as {-1, 7000.000.000} */
		if (tmx.time.tv_usec < 0) {
			tmx.time.tv_sec  -= 1;
			tmx.time.tv_usec += NSEC_PER_SEC;
		}

		connman_info("ntp: adjust (jump): %+.6f sec", offset);
	}

	if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_ADDSECOND)
		tmx.status |= STA_INS;
	else if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_DELSECOND)
		tmx.status |= STA_DEL;

	if (adjtimex(&tmx) < 0) {
		connman_error("Failed to adjust time");
		return;
	}

	DBG("interval/delta/delay/drift %fs/%+.3fs/%.3fs/%+ldppm",
		LOGTOD(msg->poll), offset, delay, tmx.freq / 65536);
}

static gboolean received_data(GIOChannel *channel, GIOCondition condition,
							gpointer user_data)
{
	unsigned char buf[128];
	struct sockaddr_in6 sender_addr;
	struct msghdr msg;
	struct iovec iov;
	struct cmsghdr *cmsg;
	struct timeval *tv;
	struct timespec mrx_time;
	char aux[128];
	ssize_t len;
	int fd;
	int size;
	void * addr_ptr;
	void * src_ptr;

	if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
		connman_error("Problem with timer server channel");
		channel_watch = 0;
		return FALSE;
	}

	fd = g_io_channel_unix_get_fd(channel);

	iov.iov_base = buf;
	iov.iov_len = sizeof(buf);

	memset(&msg, 0, sizeof(msg));
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = aux;
	msg.msg_controllen = sizeof(aux);
	msg.msg_name = &sender_addr;
	msg.msg_namelen = sizeof(sender_addr);

	len = recvmsg(fd, &msg, MSG_DONTWAIT);
	if (len < 0)
		return TRUE;

	if (sender_addr.sin6_family == AF_INET) {
		size = 4;
		addr_ptr = &((struct sockaddr_in *)&timeserver_addr)->sin_addr;
		src_ptr = &((struct sockaddr_in *)&sender_addr)->sin_addr;
	} else if (sender_addr.sin6_family == AF_INET6) {
		size = 16;
		addr_ptr = &((struct sockaddr_in6 *)&timeserver_addr)->sin6_addr;
		src_ptr = &((struct sockaddr_in6 *)&sender_addr)->sin6_addr;
	} else {
		connman_error("Not a valid family type");
		return TRUE;
	}

	if(memcmp(addr_ptr, src_ptr, size) != 0)
		return TRUE;

	tv = NULL;
	clock_gettime(CLOCK_MONOTONIC, &mrx_time);

	for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
		if (cmsg->cmsg_level != SOL_SOCKET)
			continue;

		switch (cmsg->cmsg_type) {
		case SCM_TIMESTAMP:
			tv = (struct timeval *) CMSG_DATA(cmsg);
			break;
		}
	}

	decode_msg(iov.iov_base, iov.iov_len, tv, &mrx_time);

	return TRUE;
}

static void start_ntp(char *server)
{
	GIOChannel *channel;
	struct addrinfo hint;
	struct addrinfo *info;
	struct sockaddr * addr;
	struct sockaddr_in  * in4addr;
	struct sockaddr_in6 in6addr;
	int size;
	int family;
	int tos = IPTOS_LOWDELAY, timestamp = 1;
	int ret;

	if (!server)
		return;

	memset(&hint, 0, sizeof(hint));
	hint.ai_family = AF_UNSPEC;
	hint.ai_socktype = SOCK_DGRAM;
	hint.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
	ret = getaddrinfo(server, NULL, &hint, &info);

	if (ret) {
		connman_error("cannot get server info");
		return;
	}

	family = info->ai_family;

	memcpy(&timeserver_addr, info->ai_addr, info->ai_addrlen);
	freeaddrinfo(info);
	memset(&in6addr, 0, sizeof(in6addr));

	if (family == AF_INET) {
		((struct sockaddr_in *)&timeserver_addr)->sin_port = htons(123);
		in4addr = (struct sockaddr_in *)&in6addr;
		in4addr->sin_family = family;
		addr = (struct sockaddr *)in4addr;
		size = sizeof(struct sockaddr_in);
	} else if (family == AF_INET6) {
		timeserver_addr.sin6_port = htons(123);
		in6addr.sin6_family = family;
		addr = (struct sockaddr *)&in6addr;
		size = sizeof(in6addr);
	} else {
		connman_error("Family is neither ipv4 nor ipv6");
		return;
	}

	DBG("server %s family %d", server, family);

	if (channel_watch > 0)
		goto send;

	transmit_fd = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);

	if (transmit_fd <= 0) {
                connman_error("Failed to open time server socket");
                return;
	}

	if (bind(transmit_fd, (struct sockaddr *) addr, size) < 0) {
		connman_error("Failed to bind time server socket");
		close(transmit_fd);
		return;
	}

	if (family == AF_INET) {
		if (setsockopt(transmit_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
			connman_error("Failed to set type of service option");
			close(transmit_fd);
			return;
		}
	}

	if (setsockopt(transmit_fd, SOL_SOCKET, SO_TIMESTAMP, &timestamp,
						sizeof(timestamp)) < 0) {
		connman_error("Failed to enable timestamp support");
		close(transmit_fd);
		return;
	}

	channel = g_io_channel_unix_new(transmit_fd);
	if (!channel) {
		close(transmit_fd);
		return;
	}

	g_io_channel_set_encoding(channel, NULL, NULL);
	g_io_channel_set_buffered(channel, FALSE);

	g_io_channel_set_close_on_unref(channel, TRUE);

	channel_watch = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT,
				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
				received_data, NULL, NULL);

	g_io_channel_unref(channel);

send:
	send_packet(transmit_fd, (struct sockaddr*)&timeserver_addr, NTP_SEND_TIMEOUT);
}

int __connman_ntp_start(char *server)
{
	DBG("%s", server);

	if (!server)
		return -EINVAL;

	if (timeserver)
		g_free(timeserver);

	timeserver = g_strdup(server);

	start_ntp(timeserver);

	return 0;
}

void __connman_ntp_stop()
{
	DBG("");

	if (poll_id > 0) {
		g_source_remove(poll_id);
		poll_id = 0;
	}

	reset_timeout();

	if (channel_watch > 0) {
		g_source_remove(channel_watch);
		channel_watch = 0;
		transmit_fd = 0;
	}

	if (timeserver) {
		g_free(timeserver);
		timeserver = NULL;
	}
}
