/*
 FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd.

 ***************************************************************************
 *                                                                         *
 * If you are:                                                             *
 *                                                                         *
 *    + New to FreeRTOS,                                                   *
 *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
 *    + Looking for basic training,                                        *
 *    + Wanting to improve your FreeRTOS skills and productivity           *
 *                                                                         *
 * then take a look at the FreeRTOS eBook                                  *
 *                                                                         *
 *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
 *                  http://www.FreeRTOS.org/Documentation                  *
 *                                                                         *
 * A pdf reference manual is also available.  Both are usually delivered   *
 * to your inbox within 20 minutes to two hours when purchased between 8am *
 * and 8pm GMT (although please allow up to 24 hours in case of            *
 * exceptional circumstances).  Thank you for your support!                *
 *                                                                         *
 ***************************************************************************

 This file is part of the FreeRTOS distribution.

 FreeRTOS 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 AND MODIFIED BY the FreeRTOS exception.
 ***NOTE*** The exception to the GPL is included to allow you to distribute
 a combined work that includes FreeRTOS without being obliged to provide the
 source code for proprietary components outside of the FreeRTOS kernel.
 FreeRTOS 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 and the FreeRTOS license exception along with FreeRTOS; if not it
 can be viewed here: http://www.freertos.org/a00114.html and also obtained
 by writing to Richard Barry, contact details for whom are available on the
 FreeRTOS WEB site.

 1 tab == 4 spaces!

 http://www.FreeRTOS.org - Documentation, latest information, license and
 contact details.

 http://www.SafeRTOS.com - A version that is certified for use in safety
 critical systems.

 http://www.OpenRTOS.com - Commercial support, development, porting,
 licensing and training services.
 */

/* Task that controls the uIP TCP/IP stack. */

/* Standard includes. */
#include <string.h>

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

/* uip includes. */
#include "uip.h"
#include "uip_arp.h"
#include "httpd.h"
#include "kom_modul.h"
#include "timer.h"
#include "clock-arch.h"

/* Demo includes. */
#include "FEC.h"
#include "uip-split.h"
#include "partest.h"

/*-----------------------------------------------------------*/

/* Shortcut to the header within the Rx buffer. */
#define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])

/*-----------------------------------------------------------*/

/*
 * Port functions required by the uIP stack.
 */
void clock_init(void);
clock_time_t clock_time(void);
extern void timer_set(struct timer *t, clock_time_t interval);
extern int timer_expired(struct timer *t);
extern void timer_reset(struct timer *t);

/*-----------------------------------------------------------*/

/* The semaphore used by the ISR to wake the uIP task. */
extern xSemaphoreHandle xFECSemaphore;

/*-----------------------------------------------------------*/

void clock_init(void) {
	/* This is done when the scheduler starts. */
}
/*-----------------------------------------------------------*/

/* Define clock functions here to avoid header file name clash between uIP
 and the Luminary Micro driver library. */
clock_time_t clock_time(void) {
	return xTaskGetTickCount();
}
/*-----------------------------------------------------------*/

void uIP_appcall(void) {
	switch (uip_conn->lport) {
	case HTONS(1000):
		hello_world_appcall();
		break;

	case HTONS(80):
		httpd_appcall();
		break;
	}
}

void vuIP_Task(void *pvParameters) {
	portBASE_TYPE i;
	uip_ipaddr_t xIPAddr;
	struct timer periodic_timer, arp_timer;

	/* To prevent compiler warnings. */
	(void) pvParameters;

	/* Initialise the uIP stack. */
	timer_set(&periodic_timer, configTICK_RATE_HZ / 2);
	timer_set(&arp_timer, configTICK_RATE_HZ * 10);
	uip_init();
	uip_ipaddr( xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
	uip_sethostaddr( xIPAddr );

	/* Initialise the WEB server. */
	httpd_init();
	hello_world_init();

	/* Initialise the Ethernet controller peripheral. */
	vFECInit();

	for (;;) {
		/* Is there received data ready to be processed? */
		uip_len = usFECGetRxedData();

		if (uip_len > 0) {
			/* Standard uIP loop taken from the uIP manual. */

			if (xHeader->type == htons(UIP_ETHTYPE_IP)) {
				uip_arp_ipin();
				uip_input();

				/* If the above function invocation resulted in data that
				 should be sent out on the network, the global variable
				 uip_len is set to a value > 0. */
				if (uip_len > 0) {
					uip_arp_out();
					vFECSendData();

				} else {
					/* If we are not sending data then let the FEC driver know
					 the buffer is no longer required. */
					vFECRxProcessingCompleted();
				}
			} else if (xHeader->type == htons(UIP_ETHTYPE_ARP)) {
				uip_arp_arpin();

				/* If the above function invocation resulted in data that
				 should be sent out on the network, the global variable
				 uip_len is set to a value > 0. */
				if (uip_len > 0) {
					vFECSendData();

				} else {
					/* If we are not sending data then let the FEC driver know
					 the buffer is no longer required. */
					vFECRxProcessingCompleted();
				}
			} else {
				/* If we are not sending data then let the FEC driver know
				 the buffer is no longer required. */
				vFECRxProcessingCompleted();
			}
		} else {
			if (timer_expired(&periodic_timer)) {
				timer_reset(&periodic_timer);
				for (i = 0; i < UIP_CONNS; i++) {
					uip_periodic( i );

					/* If the above function invocation resulted in data that
					 should be sent out on the network, the global variable
					 uip_len is set to a value > 0. */
					if (uip_len > 0) {
						uip_arp_out();
						vFECSendData();


					}
				}

				/* Call the ARP timer function every 10 seconds. */
				if (timer_expired(&arp_timer)) {
					timer_reset(&arp_timer);
					uip_arp_timer();
				}
			} else {
				/* We did not receive a packet, and there was no periodic
				 processing to perform.  Block for a fixed period.  If a packet
				 is received during this period we will be woken by the ISR
				 giving us the Semaphore. */
				xSemaphoreTake( xFECSemaphore, configTICK_RATE_HZ / 5 );
			}
		}
	}
}
/*-----------------------------------------------------------*/



