/* dtls-client.c - dtls client */

/*
 * Copyright (c) 2015 Intel Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define SYS_LOG_LEVEL SYS_LOG_LEVEL_INFO
#include <misc/sys_log.h>

#if defined(CONFIG_TINYDTLS_DEBUG)
#define DEBUG DEBUG_FULL
#else
#define DEBUG DEBUG_SYS_LOG_INF
#endif
#include "contiki/ip/uip-debug.h"

#include <zephyr.h>

#include <drivers/rand32.h>

#include <errno.h>

#include <net/ip_buf.h>
#include <net/net_core.h>
#include <net/net_socket.h>

#include <net/tinydtls.h>

#if defined(CONFIG_NET_TESTING)
#include <net_testing.h>
#endif

/* Generated by http://www.lipsum.com/
 * 1202 bytes of Lorem Ipsum.
 *
 * This is the maximum we can send with encryption.
 */
static const char lorem_ipsum[] =
	"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin congue orci et lectus ultricies, sed elementum urna finibus. Nam bibendum, massa id sollicitudin finibus, massa ante pharetra lacus, nec semper felis metus eu massa. Curabitur gravida, neque a pulvinar suscipit, felis massa maximus neque, eu sagittis felis enim nec justo. Suspendisse sit amet sem a magna aliquam tincidunt. Mauris consequat ante in consequat auctor. Nam eu congue mauris, congue aliquet metus. Etiam elit ipsum, vehicula et lectus at, dignissim accumsan turpis. Sed magna nisl, tempor ut dolor sed, feugiat pharetra velit. Nulla sed purus at elit dapibus lobortis. In hac habitasse platea dictumst. Praesent quis libero id enim aliquet viverra eleifend non urna. Vivamus metus justo, dignissim eget libero molestie, tincidunt pellentesque purus. Quisque pulvinar, nisi sed egestas vestibulum, ante felis elementum justo, ut viverra nisl est sagittis leo. Curabitur pharetra eros at felis ultricies efficitur."
	"\n"
	"Ut rutrum urna vitae neque rhoncus, id dictum ex dictum. Suspendisse venenatis vel mauris sed maximus. Sed malesuada elit vel neque hendrerit, in accumsan odio sodales. Aliquam erat volutpat. Praesent non situ.\n";

struct data {
	bool fail;
	bool connected;
	int expecting;
	int ipsum_len;
	struct net_context *ctx;
};

static const unsigned char ecdsa_priv_key[] = {
			0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05,
			0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF,
			0xC7, 0xF1, 0xCD, 0x74, 0x83, 0x8F, 0x75, 0x70,
			0xC8, 0x07, 0x2D, 0x0A, 0x76, 0x26, 0x1B, 0xD4};

static const unsigned char ecdsa_pub_key_x[] = {
			0xD0, 0x55, 0xEE, 0x14, 0x08, 0x4D, 0x6E, 0x06,
			0x15, 0x59, 0x9D, 0xB5, 0x83, 0x91, 0x3E, 0x4A,
			0x3E, 0x45, 0x26, 0xA2, 0x70, 0x4D, 0x61, 0xF2,
			0x7A, 0x4C, 0xCF, 0xBA, 0x97, 0x58, 0xEF, 0x9A};

static const unsigned char ecdsa_pub_key_y[] = {
			0xB4, 0x18, 0xB6, 0x4A, 0xFE, 0x80, 0x30, 0xDA,
			0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31,
			0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D,
			0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70};

#ifdef CONFIG_NETWORKING_WITH_IPV6
/* The 2001:db8::/32 is the private address space for documentation RFC 3849 */
/* Define the peer IP address where to send messages */
#if !defined(CONFIG_NET_TESTING)
#define PEER_IPADDR { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }
#endif
#else /* ipv6 */
/* The 192.0.2.0/24 is the private address space for documentation RFC 5737 */
#if !defined(CONFIG_NET_TESTING)
#define PEER_IPADDR { { { 192, 0, 2, 1 } } }
#endif
#endif

#define MY_PORT 8484
#define PEER_PORT 4242

static inline void init_app(void)
{
	SYS_LOG_INF("%s: run dtls client", __func__);

#if defined(CONFIG_NET_TESTING)
	net_testing_setup();
#endif
}

static inline void reverse(unsigned char *buf, int len)
{
	int i, last = len - 1;

	for (i = 0; i < len / 2; i++) {
		unsigned char tmp = buf[i];
		buf[i] = buf[last - i];
		buf[last - i] = tmp;
	}
}

/* How many tics to wait for a network packet */
#define WAIT_TIME 5
#define WAIT_TICKS (WAIT_TIME * sys_clock_ticks_per_sec)

static inline void send_message(const char *name,
				dtls_context_t *ctx,
				session_t *session)
{
	struct data *user_data = (struct data *)dtls_get_app_data(ctx);
	struct net_buf *buf;

	buf = ip_buf_get_reserve_tx(UIP_IPUDPH_LEN);
	if (buf) {
		uint8_t *ptr;
		int pos = sys_rand32_get() % user_data->ipsum_len;

		user_data->expecting = user_data->ipsum_len - pos;

		ptr = net_buf_add(buf, user_data->expecting);
		memcpy(ptr, lorem_ipsum + pos, user_data->expecting);
		ip_buf_appdatalen(buf) = user_data->expecting;

		dtls_write(ctx, session,
			   ip_buf_appdata(buf), ip_buf_appdatalen(buf));

		/* The encrypted data to peer is actually sent by
		 * send_to_peer() so we need to release the buffer
		 * here.
		 */
		ip_buf_unref(buf);
	}
}

static inline bool wait_reply(const char *name,
			      struct dtls_context_t *dtls,
			      session_t *session)
{
	struct data *user_data = (struct data *)dtls_get_app_data(dtls);
	struct net_buf *buf;

	/* Wait for the answer */
	buf = net_receive(user_data->ctx, WAIT_TICKS);
	if (buf) {
		SYS_LOG_INF("Received data %p datalen %d",
		      ip_buf_appdata(buf), ip_buf_appdatalen(buf));

		dtls_handle_message(dtls, session, ip_buf_appdata(buf),
				    ip_buf_appdatalen(buf));

		ip_buf_unref(buf);
		return true;
	}

	return false;
}

#ifdef CONFIG_NETWORKING_WITH_IPV6
static const struct in6_addr in6addr_peer = PEER_IPADDR;
#else
static struct in_addr in4addr_peer = PEER_IPADDR;
#endif

static inline struct net_context *get_context(void)
{
	static struct net_addr peer_addr;
	static struct net_addr my_addr;
	struct net_context *ctx;

#ifdef CONFIG_NETWORKING_WITH_IPV6
	static struct in6_addr in6addr_my = IN6ADDR_ANY_INIT;

	peer_addr.in6_addr = in6addr_peer;
	peer_addr.family = AF_INET6;

	my_addr.in6_addr = in6addr_my;
	my_addr.family = AF_INET6;
#else
	static struct in_addr in4addr_my = { { { 0 } } };

	peer_addr.in_addr = in4addr_peer;
	peer_addr.family = AF_INET;

	my_addr.in_addr = in4addr_my;
	my_addr.family = AF_INET;
#endif

	ctx = net_context_get(IPPROTO_UDP,
			      &peer_addr, PEER_PORT,
			      &my_addr, MY_PORT);
	if (!ctx) {
		SYS_LOG_INF("%s: Cannot get network context", __func__);
		return NULL;
	}

	return ctx;
}

static int read_from_peer(struct dtls_context_t *ctx,
			  session_t *session,
			  uint8 *data, size_t len)
{
	struct data *user_data = (struct data *)dtls_get_app_data(ctx);
	int pos;

	SYS_LOG_INF("%s: read from peer %p len %d", __func__, data, len);

	if (user_data->expecting != len) {
		SYS_LOG_INF("%s: received %d bytes, expected %d",
		      __func__, len, user_data->expecting);
		user_data->fail = true;
		return 0;
	}

	/* In this test we reverse the received bytes.
	 * We could also just pass the data back as is.
	 */
	reverse(data, len);

	/* Did we get all the data back?
	 */
	pos = user_data->ipsum_len - user_data->expecting;

	if (memcmp(lorem_ipsum + pos, data, user_data->expecting)) {
		SYS_LOG_INF("%s: received data mismatch.", __func__);
		user_data->fail = true;
	}

	return 0;
}

static int send_to_peer(struct dtls_context_t *ctx,
			session_t *session,
			uint8 *data, size_t len)
{
	struct data *user_data = (struct data *)dtls_get_app_data(ctx);
	struct net_buf *buf;
	int max_data_len;
	uint8_t *ptr;

	buf = ip_buf_get_tx(user_data->ctx);
	if (!buf) {
		len = -ENOBUFS;
		goto out;
	}

	max_data_len = IP_BUF_MAX_DATA - UIP_IPUDPH_LEN;

	SYS_LOG_INF("%s: send to peer data %p len %d", __func__, data, len);

	if (len > max_data_len) {
		SYS_LOG_INF("%s: too much (%d bytes) data "
			    "to send (max %d bytes)",
			    __func__, len, max_data_len);
		ip_buf_unref(buf);
		len = -EINVAL;
		goto out;
	}

	ptr = net_buf_add(buf, len);
	memcpy(ptr, data, len);
	ip_buf_appdatalen(buf) = len;

	if (net_send(buf)) {
		ip_buf_unref(buf);
	}

out:
	return len;
}

#ifdef DTLS_PSK
/* This function is the "key store" for tinyDTLS. It is called to
 * retrieve a key for the given identity within this particular
 * session. */
static int get_psk_info(struct dtls_context_t *ctx,
			const session_t *session,
			dtls_credentials_type_t type,
			const unsigned char *id, size_t id_len,
			unsigned char *result, size_t result_length)
{
	struct keymap_t {
		unsigned char *id;
		size_t id_length;
		unsigned char *key;
		size_t key_length;
	} psk[3] = {
		{ (unsigned char *)"Client_identity", 15,
		  (unsigned char *)"secretPSK", 9 },
		{ (unsigned char *)"default identity", 16,
		  (unsigned char *)"\x11\x22\x33", 3 },
		{ (unsigned char *)"\0", 2,
		  (unsigned char *)"", 1 }
	};

	if (type != DTLS_PSK_KEY) {
		return 0;
	}

	if (id) {
		int i;
		for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) {
			if (id_len == psk[i].id_length &&
			    memcmp(id, psk[i].id, id_len) == 0) {
				if (result_length < psk[i].key_length) {
					dtls_warn("buffer too small for PSK");
					return dtls_alert_fatal_create(
						DTLS_ALERT_INTERNAL_ERROR);
				}

				memcpy(result, psk[i].key, psk[i].key_length);
				return psk[i].key_length;
			}
		}
	}

	return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR);
}
#endif /* DTLS_PSK */

#ifdef DTLS_ECC
static int get_ecdsa_key(struct dtls_context_t *ctx,
			 const session_t *session,
			 const dtls_ecdsa_key_t **result)
{
	static const dtls_ecdsa_key_t ecdsa_key = {
		.curve = DTLS_ECDH_CURVE_SECP256R1,
		.priv_key = ecdsa_priv_key,
		.pub_key_x = ecdsa_pub_key_x,
		.pub_key_y = ecdsa_pub_key_y
	};

	*result = &ecdsa_key;
	return 0;
}

static int verify_ecdsa_key(struct dtls_context_t *ctx,
			    const session_t *session,
			    const unsigned char *other_pub_x,
			    const unsigned char *other_pub_y,
			    size_t key_size)
{
	return 0;
}
#endif /* DTLS_ECC */

static int handle_event(struct dtls_context_t *ctx, session_t *session,
			dtls_alert_level_t level, unsigned short code)
{
	dtls_debug("event: level %d code %d\n", level, code);

	if (level > 0) {
		/* alert code, quit */
	} else if (level == 0) {
		/* internal event */
		if (code == DTLS_EVENT_CONNECTED) {
			struct data *user_data =
				(struct data *)dtls_get_app_data(ctx);

			SYS_LOG_INF("*** Connected ***");

			/* We can send data now */
			user_data->connected = true;
		}
	}

	return 0;
}

static void init_dtls(struct data *user_data, dtls_context_t **dtls)
{
	static dtls_handler_t cb = {
		.write = send_to_peer,
		.read  = read_from_peer,
		.event = handle_event,
#ifdef DTLS_PSK
		.get_psk_info = get_psk_info,
#endif /* DTLS_PSK */
#ifdef DTLS_ECC
		.get_ecdsa_key = get_ecdsa_key,
		.verify_ecdsa_key = verify_ecdsa_key
#endif /* DTLS_ECC */
	};

	SYS_LOG_INF("DTLS client started");

#ifdef CONFIG_TINYDTLS_DEBUG
	dtls_set_log_level(DTLS_LOG_DEBUG);
#endif

	*dtls = dtls_new_context(user_data);
	if (*dtls) {
		dtls_set_handler(*dtls, &cb);
	}
}

void startup(void)
{
	static dtls_context_t *dtls;
	static session_t session;
	static struct data user_data;

	user_data.ipsum_len = strlen(lorem_ipsum);

	net_init();

	dtls_init();

	init_app();

	user_data.ctx = get_context();
	if (!user_data.ctx) {
		SYS_LOG_INF("%s: Cannot get network context", __func__);
		return;
	}

	init_dtls(&user_data, &dtls);
	if (!dtls) {
		SYS_LOG_INF("%s: Cannot get DTLS context", __func__);
		return;
	}

	dtls_session_init(&session);

	uip_ipaddr_copy(&session.addr.ipaddr, (uip_ipaddr_t *)&in6addr_peer);
	session.addr.port = uip_htons(PEER_PORT);

	PRINT6ADDR(&session.addr.ipaddr);
	SYS_LOG_INF("Trying to connect to :%d",
		    uip_ntohs(session.addr.port));

	dtls_connect(dtls, &session);

	while (!user_data.fail) {
		if (user_data.connected) {
			send_message(__func__, dtls, &session);
		}
		if (!wait_reply(__func__, dtls, &session)) {
			if (user_data.connected) {
				break;
			}
		}
	}

	SYS_LOG_INF("ERROR: Did not receive reply, closing.");
	dtls_close(dtls, &session);
}

#ifdef CONFIG_NANOKERNEL

#define STACKSIZE 3000
char fiberStack[STACKSIZE];

void main(void)
{
	fiber_start(&fiberStack[0], STACKSIZE,
			(nano_fiber_entry_t)startup, 0, 0, 7, 0);
}

#endif /* CONFIG_NANOKERNEL */
