/*
 * Modified from an original work that is Copyright (c) 2001-2003, Adam Dunkels.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This file is part of the uIP TCP/IP stack.
 *
 * $Id: main.c,v 1.10.2.4 2003/10/21 21:27:51 adam Exp $
 *
 */

/* Standard includes. */
#include <stdlib.h>
#include <string.h>
#include <stdio.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 "timer.h"
#include "clock-arch.h"

/* Demo includes. */

#include "SAM7_EMAC.h"
#include "partest.h"
#include "memory.h"


extern unsigned char logged;

/* How long to wait before attempting to connect the MAC again. */
#define uipINIT_WAIT    ( 100 / portTICK_RATE_MS )

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

/* The semaphore used by the ISR to wake the uIP task. */
static xSemaphoreHandle xEMACSemaphore;

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

void vuIP_Task( void *pvParameters )
{
	portBASE_TYPE i;
	uip_ipaddr_t xIPAddr;
	struct timer periodic_timer, arp_timer;
	unsigned char NetSetting[8];


/* Initialise the uIP stack. */
	timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );
	timer_set( &arp_timer, configTICK_RATE_HZ * 10 );
	uip_init();
/* Get IP Address and Mask*/
	at45db_read( 0x00, 0x00, 0x00, NetSetting, 8);

	uip_ipaddr( xIPAddr, NetSetting[0], NetSetting[1], NetSetting[2], NetSetting[3] );
	uip_sethostaddr( xIPAddr );

	uip_ipaddr( xIPAddr, NetSetting[4], NetSetting[5], NetSetting[6], NetSetting[7] );
	uip_setnetmask( xIPAddr );


	httpd_init();

	/* Initialise the MAC. */
	do
    {
		vTaskDelay( uipINIT_WAIT );
		xEMACSemaphore = xEMACInit();
    } while( xEMACSemaphore == NULL );

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

		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();
					lEMACSend();
				}
			}
			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 )
				{
					lEMACSend();
				}
			}
		}
		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();
						lEMACSend();
					}
				}

				/* 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( xEMACSemaphore, configTICK_RATE_HZ / 2 );
			}
		}
	}
}
/*-----------------------------------------------------------------------------------*/

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

clock_time_t clock_time( void )
{
	return xTaskGetTickCount();
}
/*-----------------------------------------------------------*/

void vProcessInput( char *pcInput )
{
    char *c, *pass, *change_pass;
	uip_ipaddr_t xIPAddr;
	int a0, a1, a2, a3;
	int lenght_password;
	int lenght_change_pass;
	unsigned char NetSetting[8], chng_pass [10];


	/* Turn the Outputs on or off depending on the checkbox status. */

	if( strstr( pcInput, "update" ) != NULL )
	{
		if( strstr( pcInput, "LED0=1" ) != NULL )
		{
			vParTestSetLED( 3, 0 );
		}
		else
		{
			vParTestSetLED( 3, 1 );
		}
		if( strstr( pcInput, "LED1=1" ) != NULL )
		{
			vParTestSetLED( 2, 0 );
		}
		else
		{
			vParTestSetLED( 2, 1 );
		}
		if( strstr( pcInput, "LED2=1" ) != NULL )
				{
					vParTestSetLED( 1, 0 );
				}
				else
				{
					vParTestSetLED( 1, 1 );
				}
	}
	/* Button Reboot */
	if( strstr( pcInput, "Reboot" ) != NULL )
	{
		/* SW Reset */
		AT91C_BASE_RSTC->RSTC_RCR  = (0xA5 << 24) | AT91C_RSTC_PROCRST;

	}
	/* Button Set IP Parameters */
	if( strstr( pcInput, "storeIP" ) != NULL )
	{
		NetSetting[0] = atoi(strstr( pcInput, "A0=" ) + 3);
		NetSetting[1]  = atoi(strstr( pcInput, "A1=" ) + 3);
		NetSetting[2]  = atoi(strstr( pcInput, "A2=" ) + 3);
		NetSetting[3]  = atoi(strstr( pcInput, "A3=" ) + 3);


		NetSetting[4]  = atoi(strstr( pcInput, "M0=" ) + 3);
		NetSetting[5]  = atoi(strstr( pcInput, "M1=" ) + 3);
		NetSetting[6]  = atoi(strstr( pcInput, "M2=" ) + 3);
		NetSetting[7]  = atoi(strstr( pcInput, "M3=" ) + 3);
		/* Write new IP adrress and Mask */
		at45db_write( 0x00, 0x00, 0x00, NetSetting, 8);

	}
	/* Button Login */
	if( strstr( pcInput, "Password=" ) != NULL )
	  {
		at45db_read( 0x00, 0x10, 0x00, chng_pass, 11);

		pass = strstr( pcInput, "Password=" ) + 9;

		if (strncmp(pass, chng_pass, 10))
		  {
			logged = 0;
		  }
		else
		  {
			logged = 1;
          }

	    }
	/* Button Submit, change password */
	if( strstr( pcInput, "Change=" ) != NULL )
		{

		   change_pass =  (strstr( pcInput, "Change" ) + 7);

           at45db_write( 0x00, 0x10, 0x00, change_pass, strlen (change_pass));
         }
	/* Button Logout */
	if( strstr( pcInput, "Logout" ) != NULL )
		{
			vUSBDebug(3, "Logout\n");
			logged = 0;

		}

}





