/* network.c - Networking demo */

/*
 * 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.
 */

#include <zephyr.h>

#if defined(CONFIG_STDOUT_CONSOLE)
#include <stdio.h>
#define PRINT           printf
#else
#include <misc/printk.h>
#define PRINT           printk
#endif

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

#include <net_driver_loopback.h>

/* Longer packet sending works only if fragmentation is supported
 * by network stack.
 */
/* Generated by http://www.lipsum.com/
 * 2 paragraphs, 185 words, 1231 bytes of Lorem Ipsum
 * The main() will add one null byte at the end so the maximum
 * length for the data to send is 1232 bytes.
 */
static const char *lorem_ipsum =
	"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam "
	"congue non neque vel tempor. In id porta nibh, ut cursus tortor. "
	"Morbi eleifend tristique vehicula. Nunc vitae risus mauris. "
	"Praesent vel imperdiet dolor, et ultricies nibh. Aliquam erat "
	"volutpat. Maecenas pellentesque dolor vitae dictum tincidunt. "
	"Fusce vel nibh nec leo tristique auctor eu a massa. Nam et tellus "
	"ac tortor sollicitudin semper vitae nec tortor. Aliquam nec lacus "
	"velit. Maecenas ornare ullamcorper justo non auctor. Donec "
	"aliquam feugiat turpis, quis elementum sem rutrum ut. Sed eu "
	"ullamcorper libero, ut suscipit magna."
	"\n"
	"Donec vehicula magna ut varius aliquam. Ut vitae commodo nulla, "
	"quis ornare dolor. Nulla tortor sem, venenatis eu iaculis id, "
	"commodo ut massa. Sed est lorem, euismod vitae enim sed, "
	"hendrerit gravida felis. Donec eros lacus, auctor ut ultricies "
	"eget, lobortis quis nisl. Aliquam sit amet blandit eros. "
	"Interdum et malesuada fames ac ante ipsum primis in faucibus. "
	"Quisque egestas nisl leo, sed consectetur leo ornare eu. "
	"Suspendisse vitae urna vel purus maximus finibus. Proin sed "
	"sollicitudin turpis. Mauris interdum neque eu tellus "
	"pellentesque, id fringilla nisi fermentum. Suspendisse gravida "
	"pharetra sodales orci aliquam.";

/* specify delay between greetings (in ms); compute equivalent in ticks */

#define SLEEPTIME  1000
#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000)

#define STACKSIZE 2000

static char fiberReceiverStack[STACKSIZE];
static char fiberSenderStack[STACKSIZE];

const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;            /* ::  */
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;  /* ::1 */

static struct net_addr any_addr;
static struct net_addr loopback_addr;

static int sent;
static int received;

static nano_thread_id_t sender_id;
static nano_thread_id_t receiver_id;

static bool failure;
static int appdatalen;

/* How many packets to send/receive */
#if defined(CONFIG_NETWORK_LOOPBACK_TEST_COUNT)
#define TEST_COUNT CONFIG_NETWORK_LOOPBACK_TEST_COUNT
#else
#define TEST_COUNT 0
#endif
static unsigned long count = TEST_COUNT;

void fiber_receiver(void)
{
	struct nano_timer timer;
	uint32_t data[2] = {0, 0};
	struct net_context *ctx;
	struct net_buf *buf;

	ctx = net_context_get(IPPROTO_UDP,
			      &any_addr, 0,
			      &loopback_addr, 4242);
	if (!ctx) {
		PRINT("%s: Cannot get network context\n", __func__);
		return;
	}

	nano_timer_init(&timer, data);

	while (!failure) {
		buf = net_receive(ctx, TICKS_UNLIMITED);
		if (buf) {
			PRINT("%d: %s: received %d bytes\n", received++,
			      __func__, ip_buf_appdatalen(buf));

			if (appdatalen != ip_buf_appdatalen(buf)) {
				failure = true;
				PRINT("Received %d bytes but was sent "
				      "%d bytes\n",
				      ip_buf_appdatalen(buf), appdatalen);
			} else if (memcmp(lorem_ipsum, ip_buf_appdata(buf),
					  appdatalen - 1)) {
				failure = true;
				PRINT("Sent and received data do not match.\n");
				PRINT("    Sent: %.*s\n", appdatalen, lorem_ipsum);
				PRINT("Received: %.*s\n", appdatalen, ip_buf_appdata(buf));
			}
			ip_buf_unref(buf);
		}

		if (count && (count < received)) {
			break;
		}

		fiber_wakeup(sender_id);
		fiber_sleep(SLEEPTICKS);
	}
}

void fiber_sender(void)
{
	struct nano_timer timer;
	uint32_t data[2] = {0, 0};
	struct net_context *ctx;
	struct net_buf *buf;
	int len;
	int ipsum_len = strlen(lorem_ipsum);

	ctx = net_context_get(IPPROTO_UDP,
			      &loopback_addr, 4242,
			      &any_addr, 0);
	if (!ctx) {
		PRINT("Cannot get network context\n");
		return;
	}

	nano_timer_init(&timer, data);

	while (!failure) {
		buf = ip_buf_get_tx(ctx);
		if (buf) {
			uint8_t *ptr;
			uint16_t sent_len;

			len = sys_rand32_get() % ipsum_len;

			ptr = net_buf_add(buf, 0);
			memcpy(ptr, lorem_ipsum, len);
			ptr = net_buf_add(buf, len);
			ptr = net_buf_add(buf, 1); /* add \0 */
			*ptr = '\0';
			sent_len = buf->len;
			appdatalen = 0;

			if (net_send(buf) < 0) {
				PRINT("%s: sending %d bytes failed\n",
					__func__, len);
				ip_buf_unref(buf);
			} else {
				appdatalen = sent_len - ip_buf_reserve(buf);
				PRINT("%d: %s: sent %d bytes\n", sent++,
				      __func__, appdatalen);
			}
		}

		fiber_wakeup(receiver_id);
		fiber_sleep(SLEEPTICKS);

		if (sent != received) {
			failure = true;
		}

		if (count && (count < sent)) {
			break;
		}
	}

	if (failure) {
		PRINT("ERROR TEST FAILED\n");
	} else {
		PRINT("TEST PASSED\n");
	}
}

void main(void)
{
	/* Pretend to be ethernet with 6 byte mac */
	uint8_t mac[] = { 0x0a, 0xbe, 0xef, 0x15, 0xf0, 0x0d };

	PRINT("%s: run network loopback test\n", __func__);

	sys_rand32_init();

	net_init();
	net_driver_loopback_init();

	any_addr.in6_addr = in6addr_any;
	any_addr.family = AF_INET6;

	loopback_addr.in6_addr = in6addr_loopback;
	loopback_addr.family = AF_INET6;

	net_set_mac(mac, sizeof(mac));

	receiver_id = task_fiber_start(&fiberReceiverStack[0], STACKSIZE,
				       (nano_fiber_entry_t)fiber_receiver,
				       0, 0, 7, 0);

	sender_id = task_fiber_start(&fiberSenderStack[0], STACKSIZE,
				     (nano_fiber_entry_t)fiber_sender,
				     0, 0, 7, 0);
}
