text: /*
   * FreeRTOS Kernel V10.3.1
   * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy of
   * this software and associated documentation files (the "Software"), to deal in
   * the Software without restriction, including without limitation the rights to
   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
   * the Software, and to permit persons to whom the Software is furnished to do so,
   * subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in all
   * copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
   * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
   * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
   * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   *
   * http://www.FreeRTOS.org
   * http://aws.amazon.com/freertos
   *
   * 1 tab == 4 spaces!
   */
  
  /* 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 "timer.h"
  #include "clock-arch.h"
  #include "timer.h"
  
  /* Demo includes. */
  #include "FEC.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.
   */
  clock_time_t clock_time( void );
  
  /*-----------------------------------------------------------*/
  
  /* The semaphore used by the ISR to wake the uIP task. */
  extern SemaphoreHandle_t xFECSemaphore;
  
  /*-----------------------------------------------------------*/
  
  clock_time_t clock_time( void )
  {
  	return xTaskGetTickCount();
  }
  
  
  void vuIP_Task( void *pvParameters )
  {
  portBASE_TYPE i;
  uip_ipaddr_t xIPAddr;
  struct timer periodic_timer, arp_timer;
  extern void ( vEMAC_ISR )( void );
  
  	/* Just to get rid of the compiler warning. */
  	( void ) pvParameters;
  
  	/* Enable/Reset the Ethernet Controller */
  
  	/* Create the semaphore used by the ISR to wake this task. */
  	vSemaphoreCreateBinary( xFECSemaphore );
  	
  	/* 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 );
  	uip_ipaddr( xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );
  	uip_setnetmask( xIPAddr );		
  	httpd_init();
  
  	vInitFEC();
  
  	for( ;; )
  	{
  		/* Is there received data ready to be processed? */
  		uip_len = ( unsigned short ) ulFECRx();
  		
  		if( ( uip_len > 0 ) && ( uip_buf != NULL ) )
  		{
  			/* 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();
  					vFECTx();
  				}
  			}
  			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 )
  				{
  					vFECTx();
  				}
  			}			
  		}
  		else
  		{
  			if( ( timer_expired( &periodic_timer ) ) && ( uip_buf != NULL ) )
  			{
  				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();
  						vFECTx();
  					}
  				}	
  	
  				/* 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 / 2 );			
  			}
  		}
  	}
  }
  /*-----------------------------------------------------------*/
  
  void vApplicationProcessFormInput( char *pcInputString, portBASE_TYPE xInputLength )
  {
  char *c;
  
  	/* Just to get rid of the compiler warning - other ports/demos use the parameter. */
  	( void ) xInputLength;
  
  	/* Process the form input sent by the IO page of the served HTML. */
  
  	c = strstr( pcInputString, "?" );
  
      if( c )
      {
  		/* Turn LED's on or off in accordance with the check box status. */
  		if( strstr( c, "LED3=1" ) != NULL )
  		{
  			/* Turn LED 3 on. */
  			vParTestSetLED( 3, 1 );
  		}
  		else
  		{
  			/* Turn LED 3 off. */
  			vParTestSetLED( 3, 0 );
  		}		
      }
  }
  
  