#include "lwip_comm.h" 
#include "netif/etharp.h"
#include "lwip/dhcp.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/init.h"
#include "ethernetif.h" 
#include "lwip/timers.h"
#include "lwip/tcp_impl.h"
#include "lwip/ip_frag.h"
#include "lwip/tcpip.h" 
#include "malloc.h"
#include "delay.h"
#include "usart.h"  
#include "udp_demo.h" 
#include <stdio.h>
  
__lwip_dev lwipdev;						//lwip控制结构体 
struct netif lwip_netif;				//定义一个全局的网络接口

extern u32 memp_get_memorysize(void);	//在memp.c里面定义
extern u8_t *memp_memory;				//在memp.c里面定义.
extern u8_t *ram_heap;					//在mem.c里面定义.

u32 TCPTimer=0;			//TCP查询计时器
u32 ARPTimer=0;			//ARP查询计时器
u32 lwip_localtime;		//lwip本地时间计数器,单位:ms
u32 DHCPfineTimer=0;	//DHCP精细处理计时器



//lwip中mem和memp的内存申请
//返回值:0,成功;
//    其他,失败
u8 lwip_comm_mem_malloc(void)
{
	u32 mempsize;
	u32 ramheapsize; 
	mempsize=memp_get_memorysize();			//得到memp_memory数组大小
	memp_memory=mymalloc(SRAMIN,mempsize);	//为memp_memory申请内存
	ramheapsize=LWIP_MEM_ALIGN_SIZE(MEM_SIZE)+2*LWIP_MEM_ALIGN_SIZE(4*3)+MEM_ALIGNMENT;//得到ram heap大小
	ram_heap=mymalloc(SRAMIN,ramheapsize);	//为ram_heap申请内存 
	if(!memp_memory||!ram_heap)//有申请失败的
	{
		lwip_comm_mem_free();
		return 1;
	}
	return 0;	
}
//lwip中mem和memp内存释放
void lwip_comm_mem_free(void)
{ 	
	myfree(SRAMIN,memp_memory);
	myfree(SRAMIN,ram_heap);
}
//lwip 默认IP设置
void lwip_comm_default_ip_set(__lwip_dev *lwipx)
{
	u32 sn0;
	u8 speed;
	sn0=*(vu32*)(0x1FFF7A10);//获取STM32的唯一ID的前24位作为MAC地址后三字节
	
	//MAC地址设置(高三字节固定为:2.0.0,低三字节用STM32唯一ID)
	//高三字节(IEEE称之为组织唯一ID,OUI)地址固定为:2.0.0
	//低三字节用STM32的唯一ID
	lwipx->mac[0]=2;
	lwipx->mac[1]=0;
	lwipx->mac[2]=0;
	lwipx->mac[3]=(sn0>>16)&0XFF;
	lwipx->mac[4]=(sn0>>8)&0XFFF;;
	lwipx->mac[5]=sn0&0XFF; 
	
	//默认本地IP为:192.168.1.30
	lwipx->ip[0]=10;	
	lwipx->ip[1]=13;
	lwipx->ip[2]=88;
	lwipx->ip[3]=50;

	//默认远端IP为:10.13.88.123
	lwipx->remoteip[0]=10;	
	lwipx->remoteip[1]=13;
	lwipx->remoteip[2]=88;
	lwipx->remoteip[3]=123;
	
	//默认子网掩码:255.255.255.0
	lwipx->netmask[0]=255;	
	lwipx->netmask[1]=255;
	lwipx->netmask[2]=255;
	lwipx->netmask[3]=0;
	
	//默认网关:192.168.1.1
	lwipx->gateway[0]=10;	
	lwipx->gateway[1]=13;
	lwipx->gateway[2]=88;
	lwipx->gateway[3]=1;
		
	IP4_ADDR(&(lwip_netif.ip_addr),lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);
	IP4_ADDR(&(lwip_netif.netmask),lwipdev.netmask[0],lwipdev.netmask[1],lwipdev.netmask[2],lwipdev.netmask[3]);
	IP4_ADDR(&(lwip_netif.gw),lwipdev.gateway[0],lwipdev.gateway[1],lwipdev.gateway[2],lwipdev.gateway[3]);
	printf("静态IP地址:\r\n");
	printf("MAC地址................%d.%d.%d.%d.%d.%d\r\n",lwipdev.mac[0],lwipdev.mac[1],lwipdev.mac[2],lwipdev.mac[3],lwipdev.mac[4],lwipdev.mac[5]);				
	printf("子网掩码...............%d.%d.%d.%d\r\n",lwipdev.netmask[0],lwipdev.netmask[1],lwipdev.netmask[2],lwipdev.netmask[3]);
	printf("默认网关...............%d.%d.%d.%d\r\n",lwipdev.gateway[0],lwipdev.gateway[1],lwipdev.gateway[2],lwipdev.gateway[3]);
	printf("本地IP.................%d.%d.%d.%d\r\n",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);
	printf("远端IP.................%d.%d.%d.%d\r\n",lwipdev.remoteip[0],lwipdev.remoteip[1],lwipdev.remoteip[2],lwipdev.remoteip[3]);//远端IP
	printf("端口号.................%d\r\n",UDP_DEMO_PORT);//客户端端口号
	speed=LAN8720_Get_Speed();
	if(speed==6)
	printf("网速...................100M\r\n");
	else printf("网速...................10M\r\n");
} 

//当接收到数据后调用 
void lwip_pkt_handle(void)
{
  //从网络缓冲区中读取接收到的数据包并将其发送给LWIP处理 
 ethernetif_input(&lwip_netif);
}

//LWIP轮询任务
void lwip_periodic_handle()
{
  //ARP每5s周期性调用一次
  if ((lwip_localtime - ARPTimer) >= ARP_TMR_INTERVAL)
  {
    ARPTimer =  lwip_localtime;
    etharp_tmr();
  }
}


//LWIP初始化
//返回值:0,成功
//       1,内存错误
//       2,LAN8720初始化失败
//       3,网卡添加失败
u8 lwip_comm_init(void)
{
	struct netif *Netif_Init_Flag;		 //调用netif_add()函数时的返回值,用于判断网络初始化是否成功
	struct ip_addr ipaddr;  			     //ip地址
	struct ip_addr netmask; 			     //子网掩码
	struct ip_addr gw;      			     //默认网关 
	printf("LWIP 初始化....\r\n");     //打印信息
	if(ETH_Mem_Malloc())return 1;		   //内存申请失败
	if(lwip_comm_mem_malloc())return 1;//内存申请失败
	if(LAN8720_Init())return 2;			   //初始化LAN8720失败
	lwip_init();						           //初始化LWIP内核
	lwip_comm_default_ip_set(&lwipdev);//设置默认IP等信息
	Netif_Init_Flag=netif_add(&lwip_netif,&ipaddr,&netmask,&gw,NULL,&ethernetif_init,&ethernet_input);//向网卡列表中添加一个网口
	if(Netif_Init_Flag==NULL)return 3; //网卡添加失败 
	else                               //网口添加成功后,设置netif为默认值,并且打开netif网口
	{
		netif_set_default(&lwip_netif);  //设置netif为默认网口
		netif_set_up(&lwip_netif);		   //打开netif网口
	}printf("LWIP 初始化成功\r\n\r\n");//打印信息
	return 0;                          //操作OK.
}
