/*  Minimal DTLS client.
 *  (Meant to be used with config-threadnet.h)
 *
 *  Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
 *
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  This file is part of mbed TLS (https://tls.mbed.org)
 */

#include <zephyr.h>
#include <stdio.h>
#include <errno.h>
#include <misc/printk.h>

#if !defined(CONFIG_MBEDTLS_CFG_FILE)
#include "mbedtls/config.h"
#else
#include CONFIG_MBEDTLS_CFG_FILE
#endif

#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_time_t       time_t
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
#endif

#include <string.h>
#include <net/net_context.h>
#include <net/net_if.h>
#include "udp.h"
#include "udp_cfg.h"

#include "mbedtls/net.h"
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"

#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#include "mbedtls/memory_buffer_alloc.h"
static unsigned char heap[20480];
#endif

#define DEBUG_THRESHOLD 0
/*
 * Hardcoded values for server host and port
 */
#define HOSTNAME "localhost"	/* for cert verification if enabled */

#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"

const char *pers = "mini_client";

#if defined(CONFIG_NET_IPV6)
static struct in6_addr mcast_addr = MCAST_IP_ADDR;
#endif

#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#define ECJPAKE_PW_SIZE 6
const unsigned char ecjpake_pw[ECJPAKE_PW_SIZE] = "passwd";
#endif

enum exit_codes {
	exit_ok = 0,
	ctr_drbg_seed_failed,
	ssl_config_defaults_failed,
	ssl_setup_failed,
	hostname_failed,
	socket_failed,
	connect_failed,
	x509_crt_parse_failed,
	ssl_handshake_failed,
	ssl_write_failed,
};

struct dtls_timing_context {
	uint32_t snapshot;
	uint32_t int_ms;
	uint32_t fin_ms;
};

static void my_debug(void *ctx, int level,
		     const char *file, int line, const char *str)
{
	const char *p, *basename;

	/* Extract basename from file */
	for (p = basename = file; *p != '\0'; p++) {
		if (*p == '/' || *p == '\\') {
			basename = p + 1;
		}
	}

	mbedtls_printf("%s:%04d: |%d| %s", basename, line, level, str);
}

void dtls_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms)
{
	struct dtls_timing_context *ctx = (struct dtls_timing_context *)data;

	ctx->int_ms = int_ms;
	ctx->fin_ms = fin_ms;

	if (fin_ms != 0) {
		ctx->snapshot = k_uptime_get_32();
	}
}

int dtls_timing_get_delay(void *data)
{
	struct dtls_timing_context *ctx = (struct dtls_timing_context *)data;
	unsigned long elapsed_ms;

	if (ctx->fin_ms == 0) {
		return -1;
	}

	elapsed_ms = k_uptime_get_32() - ctx->snapshot;

	if (elapsed_ms >= ctx->fin_ms)
		return 2;

	if (elapsed_ms >= ctx->int_ms)
		return 1;
	return 0;
}

static int entropy_source(void *data, unsigned char *output, size_t len,
			  size_t *olen)
{
	uint32_t seed;

	seed = sys_rand32_get();
	if (len > sizeof(seed)) {
		len = sizeof(seed);
	}

	memcpy(output, &seed, len);

	*olen = len;
	return 0;
}

void dtls_client(void)
{
	int ret = exit_ok;
	struct udp_context ctx;
	struct dtls_timing_context timer;

	mbedtls_entropy_context entropy;
	mbedtls_ctr_drbg_context ctr_drbg;
	mbedtls_ssl_context ssl;
	mbedtls_ssl_config conf;

	mbedtls_ctr_drbg_init(&ctr_drbg);

	mbedtls_platform_set_printf(printk);

	/*
	 * 0. Initialize and setup stuff
	 */
	mbedtls_ssl_init(&ssl);
	mbedtls_ssl_config_init(&conf);

	mbedtls_printf("\n  . Seeding the random number generator...");
	mbedtls_entropy_init(&entropy);
	mbedtls_entropy_add_source(&entropy, entropy_source, NULL,
				   MBEDTLS_ENTROPY_MAX_GATHER,
				   MBEDTLS_ENTROPY_SOURCE_STRONG);

	if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
				  (const unsigned char *)pers,
				  strlen(pers)) != 0) {
		ret = ctr_drbg_seed_failed;
		mbedtls_printf
		    (" failed\n  ! mbedtls_ctr_drbg_seed returned 0x%x\n", ret);
		goto exit;
	}

	mbedtls_printf(" ok\n");

	mbedtls_printf("  . Setting up the DTLS structure...");
	ret = mbedtls_ssl_config_defaults(&conf,
					  MBEDTLS_SSL_IS_CLIENT,
					  MBEDTLS_SSL_TRANSPORT_DATAGRAM,
					  MBEDTLS_SSL_PRESET_DEFAULT);
	if (ret != 0) {
		ret = ssl_config_defaults_failed;
		mbedtls_printf(" failed! returned 0x%x\n\n", ret);
		goto exit;
	}

/* Modify this to change the default timeouts for the DTLS handshake */
/*        mbedtls_ssl_conf_handshake_timeout( &conf, min, max ); */

#if defined(MBEDTLS_DEBUG_C)
	mbedtls_debug_set_threshold(DEBUG_THRESHOLD);
#endif

	mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
	mbedtls_ssl_conf_dbg(&conf, my_debug, NULL);

#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
	mbedtls_memory_buffer_alloc_init(heap, sizeof(heap));
#endif

	if (mbedtls_ssl_setup(&ssl, &conf) != 0) {
		ret = ssl_setup_failed;
		mbedtls_printf
		    (" failed\n  ! mbedtls_ssl_setup returned 0x%x\n\n", ret);
		goto exit;
	}

	mbedtls_printf(" ok\n");

	/*
	 * 1. Start the connection
	 */

	mbedtls_printf("  . Connecting to server ...");

	if (udp_init(&ctx) != 0) {
		ret = connect_failed;
		mbedtls_printf(" failed\n  ! udp_init returned 0x%x\n\n", ret);
		goto exit;
	}

	mbedtls_printf(" ok\n");

#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
	mbedtls_printf("  . Setting up ecjpake password ...");
	if (mbedtls_ssl_set_hs_ecjpake_password
	    (&ssl, ecjpake_pw, ECJPAKE_PW_SIZE) != 0) {
		mbedtls_printf(" failed! set ecjpake password returned %d\n\n",
			       ssl_setup_failed);
		goto exit;
	}
#endif

	mbedtls_printf(" ok\n");

	mbedtls_ssl_set_timer_cb(&ssl, &timer, dtls_timing_set_delay,
				 dtls_timing_get_delay);

	mbedtls_ssl_set_bio(&ssl, &ctx, udp_tx, udp_rx, NULL);

	mbedtls_printf("  . Performing the SSL/TLS handshake...");
	ret = mbedtls_ssl_handshake(&ssl);
	if (ret != 0) {
		ret = ssl_handshake_failed;
		mbedtls_printf
		    (" failed\n  ! mbedtls_ssl_handshake returned 0x%x\n", ret);
		goto exit;
	}

	mbedtls_printf(" ok\n");

	/*
	 * 2. Write the GET request and close the connection
	 */
	mbedtls_printf("  > Write to server:");
	if (mbedtls_ssl_write(&ssl, (const unsigned char *)GET_REQUEST,
			      sizeof(GET_REQUEST) - 1) <= 0) {
		ret = ssl_write_failed;
		mbedtls_printf
		    (" failed\n  ! mbedtls_ssl_write returned 0x%x\n\n", ret);
		goto exit;
	}

	mbedtls_printf(" ok\n");

	mbedtls_printf("  . Closing the connection...");
	mbedtls_ssl_close_notify(&ssl);
	mbedtls_printf(" done\n");
exit:

	mbedtls_ssl_free(&ssl);
	mbedtls_ssl_config_free(&conf);
	mbedtls_ctr_drbg_free(&ctr_drbg);
	mbedtls_entropy_free(&entropy);
}

#define STACK_SIZE		8192
uint8_t stack[STACK_SIZE];

static inline int init_app(void)
{
#if defined(CONFIG_NET_IPV6)
#if defined(CONFIG_NET_SAMPLES_MY_IPV6_ADDR)
	if (net_addr_pton(AF_INET6,
			  CONFIG_NET_SAMPLES_MY_IPV6_ADDR,
			  &client_addr) < 0) {
		mbedtls_printf("Invalid IPv6 address %s",
			       CONFIG_NET_SAMPLES_MY_IPV6_ADDR);
	}
#endif
	if (!net_if_ipv6_addr_add(net_if_get_default(), &client_addr,
				  NET_ADDR_MANUAL, 0)) {
		return -EIO;
	}

	net_if_ipv6_maddr_add(net_if_get_default(), &mcast_addr);
#else
#if defined(CONFIG_NET_SAMPLES_MY_IPV4_ADDR)
	if (net_addr_pton(AF_INET, CONFIG_NET_SAMPLES_MY_IPV4_ADDR,
			  &client_addr) < 0) {
		mbedtls_printf("Invalid IPv4 address %s",
			       CONFIG_NET_SAMPLES_MY_IPV4_ADDR);
	}
#endif

	if (!net_if_ipv4_addr_add(net_if_get_default(), &client_addr,
				  NET_ADDR_MANUAL, 0)) {
		return -EIO;
	}
#endif

	return 0;
}

void main(void)
{
	if (init_app() != 0) {
		printf("Cannot initialize network\n");
		return;
	}

	k_thread_spawn(stack, STACK_SIZE, (k_thread_entry_t) dtls_client,
		       NULL, NULL, NULL, K_PRIO_COOP(7), 0, 0);

}
