/* Includes ------------------------------------------------------------------*/
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/tcp.h"
#include "lwip/tcp_impl.h"
#include "lwip/udp.h"
#include "netif/etharp.h"
#include "lwip/dhcp.h"
#include "lwip/ip_addr.h"
#include "ethernetif.h"
#include "main.h"
#include "netconf.h"
#include "common_config.h"
#include "settings_api.h"
#include "tinystdio.h"
#include "lwip/timers.h"
#include "lwip/init.h"

/* Private typedef -----------------------------------------------------------*/
#define MAX_DHCP_TRIES        4

/* Private define ------------------------------------------------------------*/
typedef enum 
{ 
  DHCP_START=0,
  DHCP_WAIT_ADDRESS,
  DHCP_ADDRESS_ASSIGNED,
  DHCP_TIMEOUT
} 
DHCP_State_TypeDef;
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
struct netif netif;
uint32_t TCPTimer = 0;
uint32_t ARPTimer = 0;
uint32_t DHCPfineTimer = 0;
uint32_t DHCPcoarseTimer = 0;
DHCP_State_TypeDef DHCP_state = DHCP_START;


/**
  * @brief  Общая структура настроек
  */
extern SETTINGS_t sSettings;

/* Private functions ---------------------------------------------------------*/
void LwIP_DHCP_Process_Handle(void);
/**
  * @brief  Initializes the lwIP stack
  * @param  None
  * @retval None
  */
void LwIP_Init(void)
{
  struct ip_addr ipaddr;
  struct ip_addr netmask;
  struct ip_addr gw;
  char str[20];

  lwip_init();

//  /* Initializes the dynamic memory heap defined by MEM_SIZE.*/
//  mem_init();
//
//  /* Initializes the memory pools defined by MEMP_NUM_x.*/
//  memp_init();

  if (sSettings.sWebParams.dhcpEnable)
  {	
    ipaddr.addr = 0;
    netmask.addr = 0;
    gw.addr = 0;
  }
  else
  {	
	sprintf(str, " %s\n\r", sSettings.sWebTempParams.ip);
    PRINT_USART("\n\rStatic IP address   \n\r");
    PRINT_USART(str);
	  
	ipaddr.addr = ipaddr_addr(sSettings.sWebParams.ip);
	netmask.addr = ipaddr_addr(sSettings.sWebParams.mask);
	gw.addr = ipaddr_addr(sSettings.sWebParams.gate);
  }	

  netif_add(&netif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input);
  netif_set_default(&netif);
  netif_set_up(&netif);
}

/**
  * @brief  Called when a frame is received
  * @param  None
  * @retval None
  */
void LwIP_Pkt_Handle(void)
{
  /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */
  ethernetif_input(&netif);
}

///**
//  * @brief  LwIP periodic tasks
//  * @param  localtime the current LocalTime value
//  * @retval None
//  */
//void LwIP_Periodic_Handle(__IO uint32_t localtime)
//{
//#if LWIP_TCP
//  /* TCP periodic process every 250 ms */
//  if (localtime - TCPTimer >= TCP_TMR_INTERVAL) {
//    TCPTimer =  localtime;
//    tcp_tmr();
//  }
//#endif
//
//  /* ARP periodic process every 5s */
//  if ((localtime - ARPTimer) >= ARP_TMR_INTERVAL) {
//    ARPTimer =  localtime;
//    etharp_tmr();
//  }
//
//  if (sSettings.sWebParams.dhcpEnable)
//  {
//    /* Fine DHCP periodic process every 500ms */
//    if (localtime - DHCPfineTimer >= DHCP_FINE_TIMER_MSECS) {
//      DHCPfineTimer =  localtime;
//      dhcp_fine_tmr();
//      if ((DHCP_state != DHCP_ADDRESS_ASSIGNED)&&(DHCP_state != DHCP_TIMEOUT)) {
//        /* process DHCP state machine */
//        LwIP_DHCP_Process_Handle();
//      }
//    }
//
//    /* DHCP Coarse periodic process every 60s */
//    if (localtime - DHCPcoarseTimer >= DHCP_COARSE_TIMER_MSECS) {
//      DHCPcoarseTimer =  localtime;
//      dhcp_coarse_tmr();
//    }
//  }
//
//}

/**
  * @brief  LwIP periodic tasks
  * @param  localtime the current LocalTime value
  * @retval None
  */
void LwIP_Periodic_Handle(__IO uint32_t localtime)
{
  if (sSettings.sWebParams.dhcpEnable)
  {
    /* Fine DHCP periodic process every 500ms */

      if ((DHCP_state != DHCP_ADDRESS_ASSIGNED)&&(DHCP_state != DHCP_TIMEOUT)) {
        /* process DHCP state machine */
        LwIP_DHCP_Process_Handle();    
      }
  }

  sys_check_timeouts();
}

/**
  * @brief  LwIP_DHCP_Process_Handle
  * @param  None
  * @retval None
  */
void LwIP_DHCP_Process_Handle()
{
  struct ip_addr ipaddr;
  struct ip_addr netmask;
  struct ip_addr gw;

  switch (DHCP_state)
  {
    case DHCP_START:
    {
      dhcp_start(&netif);
      DHCP_state = DHCP_WAIT_ADDRESS;
	  PRINT_USART("\n\rLooking for DHCP server please wait...\n\r");
    }
    break;

    case DHCP_WAIT_ADDRESS:
    {
	  ipaddr = netif.ip_addr;
      netmask = netif.netmask;
      gw = netif.gw;
	  
      if (ipaddr.addr != 0) 
	  {
        DHCP_state = DHCP_ADDRESS_ASSIGNED;	

        /* Stop DHCP */
        dhcp_stop(&netif);
    
        PRINT_USART("Parameters assigned by a DHCP server:\n\r     IP:   ");
        PRINT_USART(ipaddr_ntoa(&ipaddr));
		PRINT_USART("\n\r");
          
		PRINT_USART("Netmask:   ");
		PRINT_USART(ipaddr_ntoa(&netmask));
		PRINT_USART("\n\r");
		  
		PRINT_USART("Gateway:   ");
		PRINT_USART(ipaddr_ntoa(&gw));
		PRINT_USART("\n\r");

      } else {
        /* DHCP timeout */
        if (netif.dhcp->tries > MAX_DHCP_TRIES) 
		{
          DHCP_state = DHCP_TIMEOUT;

          /* Stop DHCP */
          dhcp_stop(&netif);

//		  ipaddr.addr = ipaddr_addr(sSettings.sWebTempParams.ip);
//	      netmask.addr = ipaddr_addr(sSettings.sWebTempParams.mask);
//	      gw.addr = ipaddr_addr(sSettings.sWebTempParams.gate);
          
          ipaddr.addr = ipaddr_addr("192.168.14.48");
          netmask.addr = ipaddr_addr("255.255.255.0");
          gw.addr = ipaddr_addr("192.168.14.1");

          netif_set_addr(&netif, &ipaddr , &netmask, &gw);
		  
		  PRINT_USART("DHCP timeout\n\r");
          PRINT_USART("\n\rStatic IP address\n\r");
	      PRINT_USART(ipaddr_ntoa(&ipaddr));
		  PRINT_USART("\n\r");
        }
      }
    }
    break;
    default: break;
  }
}     

/*********** Portions COPYRIGHT 2012 Embest Tech. Co., Ltd.*****END OF FILE****/
