From 5d5be35633a8836afc234255b2fa6021b8bb744b Mon Sep 17 00:00:00 2001 From: Johny Mattsson Date: Mon, 12 Oct 2015 14:31:04 +1100 Subject: [PATCH] Upgraded LWIP to 1.4.0 released from Espressif. Plus directly provided patch for user_interface.h. --- app/include/lwip/app/dhcpserver.h | 5 +- app/include/lwip/app/espconn.h | 3 +- app/include/lwip/app/espconn_udp.h | 13 + app/include/lwip/mem.h | 25 +- app/include/lwip/netif.h | 5 +- app/include/lwip/sys.h | 4 +- app/include/lwipopts.h | 9 +- app/lwip/app/dhcpserver.c | 2138 +++++++++-------- app/lwip/app/espconn.c | 49 +- app/lwip/app/espconn_tcp.c | 23 +- app/lwip/app/espconn_udp.c | 161 +- app/lwip/app/netio.c | 8 +- app/lwip/app/ping.c | 4 + app/lwip/core/dhcp.c | 14 + app/lwip/core/dns.c | 4 + app/lwip/core/init.c | 2 +- app/lwip/core/ipv4/igmp.c | 4 + app/lwip/core/mdns.c | 37 +- app/lwip/core/pbuf.c | 43 + app/lwip/core/raw.c | 4 + app/lwip/core/tcp.c | 4 + app/lwip/core/tcp_in.c | 14 + app/lwip/core/tcp_out.c | 27 +- app/lwip/core/timers.c | 8 +- app/lwip/core/udp.c | 4 + app/lwip/netif/etharp.c | 4 + .../include/user_interface.h | 1 + 27 files changed, 1552 insertions(+), 1065 deletions(-) diff --git a/app/include/lwip/app/dhcpserver.h b/app/include/lwip/app/dhcpserver.h index 8e68e3e0..a4379a17 100644 --- a/app/include/lwip/app/dhcpserver.h +++ b/app/include/lwip/app/dhcpserver.h @@ -24,6 +24,7 @@ typedef struct dhcps_msg { #ifndef LWIP_OPEN_SRC struct dhcps_lease { + bool enable; struct ip_addr start_ip; struct ip_addr end_ip; }; @@ -46,7 +47,8 @@ typedef struct _list_node{ struct _list_node *pnext; }list_node; -#define DHCPS_LEASE_TIMER 0x05A0 +extern uint32 dhcps_lease_time; +#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0 #define DHCPS_MAX_LEASE 0x64 #define BOOTP_BROADCAST 0x8000 @@ -89,6 +91,7 @@ typedef struct _list_node{ #define DHCPS_STATE_ACK 3 #define DHCPS_STATE_NAK 4 #define DHCPS_STATE_IDLE 5 +#define DHCPS_STATE_RELEASE 6 #define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0) diff --git a/app/include/lwip/app/espconn.h b/app/include/lwip/app/espconn.h index 91304ed2..787d1458 100644 --- a/app/include/lwip/app/espconn.h +++ b/app/include/lwip/app/espconn.h @@ -30,6 +30,7 @@ typedef void (* espconn_reconnect_callback)(void *arg, sint8 err); #define ESPCONN_CONN -11 /* Not connected. */ #define ESPCONN_ARG -12 /* Illegal argument. */ +#define ESPCONN_IF -14 /* Low_level error */ #define ESPCONN_ISCONN -15 /* Already connected. */ #define ESPCONN_HANDSHAKE -28 /* ssl handshake failed */ @@ -168,7 +169,7 @@ typedef struct _espconn_msg{ struct espconn *pespconn; comon_pkt pcommon; uint8 count_opt; - sint16_t hs_status; //the status of the handshake + int16_t hs_status; //the status of the handshake void *preverse; void *pssl; struct _espconn_msg *pnext; diff --git a/app/include/lwip/app/espconn_udp.h b/app/include/lwip/app/espconn_udp.h index 2b724349..cdb312f7 100644 --- a/app/include/lwip/app/espconn_udp.h +++ b/app/include/lwip/app/espconn_udp.h @@ -45,6 +45,19 @@ extern sint8 espconn_udp_server(struct espconn *espconn); extern err_t espconn_udp_sent(void *arg, uint8 *psent, uint16 length); +/****************************************************************************** + * FunctionName : espconn_udp_sendto + * Description : sent data for UDP + * Parameters : void *arg -- UDP to send + * uint8* psent -- Data to send + * uint16 length -- Length of data to send + * Returns : return espconn error code. + * - ESPCONN_OK. Successful. No error occured. + * - ESPCONN_MEM. Out of memory. + * - ESPCONN_RTE. Could not find route to destination address. + * - More errors could be returned by lower protocol layers. +*******************************************************************************/ +extern err_t espconn_udp_sendto(void *arg, uint8 *psent, uint16 length); #endif /* __ESPCONN_UDP_H__ */ diff --git a/app/include/lwip/mem.h b/app/include/lwip/mem.h index 7a4febcc..af6e3609 100644 --- a/app/include/lwip/mem.h +++ b/app/include/lwip/mem.h @@ -33,7 +33,7 @@ #define __LWIP_MEM_H__ #include "lwip/opt.h" -#include "mem_manager.h" +//#include "mem_manager.h" #ifdef __cplusplus extern "C" { @@ -50,6 +50,7 @@ typedef size_t mem_size_t; /* in case C library malloc() needs extra protection, * allow these defines to be overridden. */ +#ifndef MEMLEAK_DEBUG #ifndef mem_free #define mem_free vPortFree #endif @@ -64,6 +65,28 @@ typedef size_t mem_size_t; #endif #ifndef mem_zalloc #define mem_zalloc pvPortZalloc +#endif +#else +#ifndef mem_free +#define mem_free(s) \ +do{\ + const char *file = mem_debug_file;\ + vPortFree(s, file, __LINE__);\ +}while(0) +#endif +#ifndef mem_malloc +#define mem_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__);}) +#endif +#ifndef mem_calloc +#define mem_calloc(s) ({const char *file = mem_debug_file; pvPortCalloc(s, file, __LINE__);}) +#endif +#ifndef mem_realloc +#define mem_realloc(p, s) ({const char *file = mem_debug_file; pvPortRealloc(p, s, file, __LINE__);}) +#endif +#ifndef mem_zalloc +#define mem_zalloc(s) ({const char *file = mem_debug_file; pvPortZalloc(s, file, __LINE__);}) +#endif + #endif #ifndef os_malloc diff --git a/app/include/lwip/netif.h b/app/include/lwip/netif.h index 4aad49f2..04e4f7a0 100644 --- a/app/include/lwip/netif.h +++ b/app/include/lwip/netif.h @@ -130,6 +130,9 @@ typedef void (*netif_status_callback_fn)(struct netif *netif); typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, ip_addr_t *group, u8_t action); +/*add DHCP event processing by LiuHan*/ +typedef void (*dhcp_event_fn)(void); + /** Generic data structure used for all lwIP network interfaces. * The following fields should be filled in by the initialization * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ @@ -170,7 +173,7 @@ struct netif { /** the DHCP client state information for this netif */ struct dhcp *dhcp; struct udp_pcb *dhcps_pcb; //dhcps - void *pad; + dhcp_event_fn dhcp_event; #endif /* LWIP_DHCP */ #if LWIP_AUTOIP /** the AutoIP client state information for this netif */ diff --git a/app/include/lwip/sys.h b/app/include/lwip/sys.h index 432d2de2..31a9dea7 100644 --- a/app/include/lwip/sys.h +++ b/app/include/lwip/sys.h @@ -281,8 +281,8 @@ void sys_arch_unprotect(sys_prot_t pval)ICACHE_FLASH_ATTR; #else #define SYS_ARCH_DECL_PROTECT(lev) -#define SYS_ARCH_PROTECT(lev) lev = ets_intr_lock() //fix by ives at 2014.3.24 -#define SYS_ARCH_UNPROTECT(lev) lev = ets_intr_unlock() +#define SYS_ARCH_PROTECT(lev) lev = os_intr_lock() //fix by ives at 2014.3.24 +#define SYS_ARCH_UNPROTECT(lev) lev = os_intr_unlock() #endif /* SYS_LIGHTWEIGHT_PROT */ diff --git a/app/include/lwipopts.h b/app/include/lwipopts.h index b39f8d76..eaa8dd6b 100644 --- a/app/include/lwipopts.h +++ b/app/include/lwipopts.h @@ -659,6 +659,13 @@ #define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) #endif +/** + * DHCP_MAXRTX: Maximum number of retries of current request. + */ +#ifndef DHCP_MAXRTX +#define DHCP_MAXRTX (*(volatile uint32*)0x600011E0) +#endif + /* ------------------------------------ ---------- AUTOIP options ---------- @@ -934,7 +941,7 @@ * Define to 0 if your device is low on memory. */ #ifndef TCP_QUEUE_OOSEQ -#define TCP_QUEUE_OOSEQ 0 +#define TCP_QUEUE_OOSEQ 1 #endif #if 1 diff --git a/app/lwip/app/dhcpserver.c b/app/lwip/app/dhcpserver.c index 0bf8eddc..ddb59845 100644 --- a/app/lwip/app/dhcpserver.c +++ b/app/lwip/app/dhcpserver.c @@ -1,996 +1,1146 @@ -#include "lwip/inet.h" +#include "lwip/inet.h" #include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/udp.h" -#include "lwip/mem.h" -//#include "crypto/common.h" -#include "osapi.h" -#include "lwip/app/dhcpserver.h" - -#ifndef LWIP_OPEN_SRC -#include "net80211/ieee80211_var.h" -#endif -//#include "netif/wlan_lwip_if.h" -#include "user_interface.h" - -//////////////////////////////////////////////////////////////////////////////////// -//static const uint8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; -//static u8_t old_xid[4] = {0}; -static const uint32 magic_cookie ICACHE_RODATA_ATTR = 0x63538263; -static struct udp_pcb *pcb_dhcps = NULL; -static struct ip_addr broadcast_dhcps; -static struct ip_addr server_address; -static struct ip_addr client_address;//added -static struct ip_addr client_address_plus; - -struct dhcps_state s; - -static struct dhcps_lease dhcps_lease; -static bool dhcps_lease_flag = true; -static list_node *plist = NULL; -static uint8 offer = 0xFF; -/****************************************************************************** - * FunctionName : node_insert_to_list - * Description : insert the node to the list - * Parameters : arg -- Additional argument to pass to the callback function - * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node* pinsert) +#include "lwip/pbuf.h" +#include "lwip/udp.h" +#include "lwip/mem.h" +//#include "crypto/common.h" +#include "osapi.h" +#include "lwip/app/dhcpserver.h" + +#ifndef LWIP_OPEN_SRC +#include "net80211/ieee80211_var.h" +#endif + +#include "user_interface.h" + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + +//////////////////////////////////////////////////////////////////////////////////// +//static const uint8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; +//static u8_t old_xid[4] = {0}; +static const uint32 magic_cookie ICACHE_RODATA_ATTR = 0x63538263; +static struct udp_pcb *pcb_dhcps = NULL; +static struct ip_addr broadcast_dhcps; +static struct ip_addr server_address; +static struct ip_addr client_address;//added +static struct ip_addr client_address_plus; + +static struct dhcps_lease dhcps_lease; +//static bool dhcps_lease_flag = true; +static list_node *plist = NULL; +static uint8 offer = 0xFF; +static bool renew = false; +#define DHCPS_LEASE_TIME_DEF (120) +uint32 dhcps_lease_time = DHCPS_LEASE_TIME_DEF; //minute +/****************************************************************************** + * FunctionName : node_insert_to_list + * Description : insert the node to the list + * Parameters : arg -- Additional argument to pass to the callback function + * Returns : none +*******************************************************************************/ +void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node* pinsert) +{ + list_node *plist = NULL; + struct dhcps_pool *pdhcps_pool = NULL; + struct dhcps_pool *pdhcps_node = NULL; + if (*phead == NULL) + *phead = pinsert; + else { + plist = *phead; + pdhcps_node = pinsert->pnode; + pdhcps_pool = plist->pnode; + + if(pdhcps_node->ip.addr < pdhcps_pool->ip.addr) { + pinsert->pnext = plist; + *phead = pinsert; + } else { + while (plist->pnext != NULL) { + pdhcps_pool = plist->pnext->pnode; + if (pdhcps_node->ip.addr < pdhcps_pool->ip.addr) { + pinsert->pnext = plist->pnext; + plist->pnext = pinsert; + break; + } + plist = plist->pnext; + } + + if(plist->pnext == NULL) { + plist->pnext = pinsert; + } + } + } +// pinsert->pnext = NULL; +} + +/****************************************************************************** + * FunctionName : node_delete_from_list + * Description : remove the node from list + * Parameters : arg -- Additional argument to pass to the callback function + * Returns : none +*******************************************************************************/ +void ICACHE_FLASH_ATTR node_remove_from_list(list_node **phead, list_node* pdelete) +{ + list_node *plist = NULL; + + plist = *phead; + if (plist == NULL){ + *phead = NULL; + } else { + if (plist == pdelete){ + *phead = plist->pnext; + } else { + while (plist != NULL) { + if (plist->pnext == pdelete){ + plist->pnext = pdelete->pnext; + } + plist = plist->pnext; + } + } + } +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ��DHCP msg��Ϣ�ṹ���������� + * + * @param optptr -- DHCP msg��Ϣλ�� + * @param type -- Ҫ��ӵ�����option + * + * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ + */ +/////////////////////////////////////////////////////////////////////////////////// +static uint8_t* ICACHE_FLASH_ATTR add_msg_type(uint8_t *optptr, uint8_t type) +{ + + *optptr++ = DHCP_OPTION_MSG_TYPE; + *optptr++ = 1; + *optptr++ = type; + return optptr; +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ��DHCP msg�ṹ������offerӦ������ + * + * @param optptr -- DHCP msg��Ϣλ�� + * + * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ + */ +/////////////////////////////////////////////////////////////////////////////////// +static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) +{ + struct ip_addr ipadd; + + ipadd.addr = *( (uint32_t *) &server_address); + +#ifdef USE_CLASS_B_NET + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = 4; //length + *optptr++ = 255; + *optptr++ = 240; + *optptr++ = 0; + *optptr++ = 0; +#else + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = 4; + *optptr++ = 255; + *optptr++ = 255; + *optptr++ = 255; + *optptr++ = 0; +#endif + + *optptr++ = DHCP_OPTION_LEASE_TIME; + *optptr++ = 4; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 24) & 0xFF; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 16) & 0xFF; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 8) & 0xFF; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 0) & 0xFF; + + *optptr++ = DHCP_OPTION_SERVER_ID; + *optptr++ = 4; + *optptr++ = ip4_addr1( &ipadd); + *optptr++ = ip4_addr2( &ipadd); + *optptr++ = ip4_addr3( &ipadd); + *optptr++ = ip4_addr4( &ipadd); + + if (dhcps_router_enabled(offer)){ + struct ip_info if_ip; + os_bzero(&if_ip, sizeof(struct ip_info)); + wifi_get_ip_info(SOFTAP_IF, &if_ip); + + *optptr++ = DHCP_OPTION_ROUTER; + *optptr++ = 4; + *optptr++ = ip4_addr1( &if_ip.gw); + *optptr++ = ip4_addr2( &if_ip.gw); + *optptr++ = ip4_addr3( &if_ip.gw); + *optptr++ = ip4_addr4( &if_ip.gw); + } + +#ifdef USE_DNS + *optptr++ = DHCP_OPTION_DNS_SERVER; + *optptr++ = 4; + *optptr++ = ip4_addr1( &ipadd); + *optptr++ = ip4_addr2( &ipadd); + *optptr++ = ip4_addr3( &ipadd); + *optptr++ = ip4_addr4( &ipadd); +#endif + +#ifdef CLASS_B_NET + *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; + *optptr++ = 4; + *optptr++ = ip4_addr1( &ipadd); + *optptr++ = 255; + *optptr++ = 255; + *optptr++ = 255; +#else + *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; + *optptr++ = 4; + *optptr++ = ip4_addr1( &ipadd); + *optptr++ = ip4_addr2( &ipadd); + *optptr++ = ip4_addr3( &ipadd); + *optptr++ = 255; +#endif + + *optptr++ = DHCP_OPTION_INTERFACE_MTU; + *optptr++ = 2; +#ifdef CLASS_B_NET + *optptr++ = 0x05; + *optptr++ = 0xdc; +#else + *optptr++ = 0x02; + *optptr++ = 0x40; +#endif + + *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY; + *optptr++ = 1; + *optptr++ = 0x00; + + *optptr++ = 43; + *optptr++ = 6; + + *optptr++ = 0x01; + *optptr++ = 4; + *optptr++ = 0x00; + *optptr++ = 0x00; + *optptr++ = 0x00; + *optptr++ = 0x02; + + return optptr; +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ��DHCP msg�ṹ����ӽ����־���� + * + * @param optptr -- DHCP msg��Ϣλ�� + * + * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ + */ +/////////////////////////////////////////////////////////////////////////////////// +static uint8_t* ICACHE_FLASH_ATTR add_end(uint8_t *optptr) +{ + + *optptr++ = DHCP_OPTION_END; + return optptr; +} +/////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR create_msg(struct dhcps_msg *m) +{ + struct ip_addr client; + + client.addr = *( (uint32_t *) &client_address); + + m->op = DHCP_REPLY; + m->htype = DHCP_HTYPE_ETHERNET; + m->hlen = 6; + m->hops = 0; +// os_memcpy((char *) xid, (char *) m->xid, sizeof(m->xid)); + m->secs = 0; + m->flags = htons(BOOTP_BROADCAST); + + os_memcpy((char *) m->yiaddr, (char *) &client.addr, sizeof(m->yiaddr)); + + os_memset((char *) m->ciaddr, 0, sizeof(m->ciaddr)); + os_memset((char *) m->siaddr, 0, sizeof(m->siaddr)); + os_memset((char *) m->giaddr, 0, sizeof(m->giaddr)); + os_memset((char *) m->sname, 0, sizeof(m->sname)); + os_memset((char *) m->file, 0, sizeof(m->file)); + + os_memset((char *) m->options, 0, sizeof(m->options)); + os_memcpy((char *) m->options, &magic_cookie, sizeof(magic_cookie)); +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ����һ��OFFER + * + * @param -- m ָ����Ҫ���͵�DHCP msg���� + */ +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m) +{ + uint8_t *end; + struct pbuf *p, *q; + u8_t *data; + u16_t cnt=0; + u16_t i; + err_t SendOffer_err_t; + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPOFFER); + end = add_offer_options(end); + end = add_end(end); + + p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); +#if DHCPS_DEBUG + os_printf("udhcp: send_offer>>p->ref = %d\n", p->ref); +#endif + if(p != NULL){ + +#if DHCPS_DEBUG + os_printf("dhcps: send_offer>>pbuf_alloc succeed\n"); + os_printf("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len); + os_printf("dhcps: send_offer>>p->len = %d\n", p->len); +#endif + q = p; + while(q != NULL){ + data = (u8_t *)q->payload; + for(i=0; ilen; i++) + { + data[i] = ((u8_t *) m)[cnt++]; +#if DHCPS_DEBUG + os_printf("%02x ",data[i]); + if((i+1)%16 == 0){ + os_printf("\n"); + } +#endif + } + + q = q->next; + } + }else{ + +#if DHCPS_DEBUG + os_printf("dhcps: send_offer>>pbuf_alloc failed\n"); +#endif + return; + } + SendOffer_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); +#if DHCPS_DEBUG + os_printf("dhcps: send_offer>>udp_sendto result %x\n",SendOffer_err_t); +#endif + if(p->ref != 0){ +#if DHCPS_DEBUG + os_printf("udhcp: send_offer>>free pbuf\n"); +#endif + pbuf_free(p); + } +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ����һ��NAK��Ϣ + * + * @param m ָ����Ҫ���͵�DHCP msg���� + */ +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR send_nak(struct dhcps_msg *m) +{ + + u8_t *end; + struct pbuf *p, *q; + u8_t *data; + u16_t cnt=0; + u16_t i; + err_t SendNak_err_t; + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPNAK); + end = add_end(end); + + p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); +#if DHCPS_DEBUG + os_printf("udhcp: send_nak>>p->ref = %d\n", p->ref); +#endif + if(p != NULL){ + +#if DHCPS_DEBUG + os_printf("dhcps: send_nak>>pbuf_alloc succeed\n"); + os_printf("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len); + os_printf("dhcps: send_nak>>p->len = %d\n", p->len); +#endif + q = p; + while(q != NULL){ + data = (u8_t *)q->payload; + for(i=0; ilen; i++) + { + data[i] = ((u8_t *) m)[cnt++]; +#if DHCPS_DEBUG + os_printf("%02x ",data[i]); + if((i+1)%16 == 0){ + os_printf("\n"); + } +#endif + } + + q = q->next; + } + }else{ + +#if DHCPS_DEBUG + os_printf("dhcps: send_nak>>pbuf_alloc failed\n"); +#endif + return; + } + SendNak_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); +#if DHCPS_DEBUG + os_printf("dhcps: send_nak>>udp_sendto result %x\n",SendNak_err_t); +#endif + if(p->ref != 0){ +#if DHCPS_DEBUG + os_printf("udhcp: send_nak>>free pbuf\n"); +#endif + pbuf_free(p); + } +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ����һ��ACK��DHCP�ͻ��� + * + * @param m ָ����Ҫ���͵�DHCP msg���� + */ +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR send_ack(struct dhcps_msg *m) +{ + + u8_t *end; + struct pbuf *p, *q; + u8_t *data; + u16_t cnt=0; + u16_t i; + err_t SendAck_err_t; + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPACK); + end = add_offer_options(end); + end = add_end(end); + + p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); +#if DHCPS_DEBUG + os_printf("udhcp: send_ack>>p->ref = %d\n", p->ref); +#endif + if(p != NULL){ + +#if DHCPS_DEBUG + os_printf("dhcps: send_ack>>pbuf_alloc succeed\n"); + os_printf("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len); + os_printf("dhcps: send_ack>>p->len = %d\n", p->len); +#endif + q = p; + while(q != NULL){ + data = (u8_t *)q->payload; + for(i=0; ilen; i++) + { + data[i] = ((u8_t *) m)[cnt++]; +#if DHCPS_DEBUG + os_printf("%02x ",data[i]); + if((i+1)%16 == 0){ + os_printf("\n"); + } +#endif + } + + q = q->next; + } + }else{ + +#if DHCPS_DEBUG + os_printf("dhcps: send_ack>>pbuf_alloc failed\n"); +#endif + return; + } + SendAck_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); +#if DHCPS_DEBUG + os_printf("dhcps: send_ack>>udp_sendto result %x\n",SendAck_err_t); +#endif + + if(p->ref != 0){ +#if DHCPS_DEBUG + os_printf("udhcp: send_ack>>free pbuf\n"); +#endif + pbuf_free(p); + } +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ����DHCP�ͻ��˷�����DHCP����������Ϣ�����Բ�ͬ��DHCP��������������Ӧ��Ӧ�� + * + * @param optptr DHCP msg�е��������� + * @param len ��������Ĵ��?(byte) + * + * @return uint8_t ���ش�����DHCP Server״ֵ̬ + */ +/////////////////////////////////////////////////////////////////////////////////// +static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len) +{ + struct ip_addr client; + bool is_dhcp_parse_end = false; + struct dhcps_state s; + + client.addr = *( (uint32_t *) &client_address);// Ҫ�����DHCP�ͻ��˵�IP + + u8_t *end = optptr + len; + u16_t type = 0; + + s.state = DHCPS_STATE_IDLE; + + while (optptr < end) { +#if DHCPS_DEBUG + os_printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr); +#endif + switch ((sint16_t) *optptr) { + + case DHCP_OPTION_MSG_TYPE: //53 + type = *(optptr + 2); + break; + + case DHCP_OPTION_REQ_IPADDR://50 + if( os_memcmp( (char *) &client.addr, (char *) optptr+2,4)==0 ) { +#if DHCPS_DEBUG + os_printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); +#endif + s.state = DHCPS_STATE_ACK; + }else { +#if DHCPS_DEBUG + os_printf("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n"); +#endif + s.state = DHCPS_STATE_NAK; + } + break; + case DHCP_OPTION_END: + { + is_dhcp_parse_end = true; + } + break; + } + + if(is_dhcp_parse_end){ + break; + } + + optptr += optptr[1] + 2; + } + + switch (type){ + + case DHCPDISCOVER://1 + s.state = DHCPS_STATE_OFFER; +#if DHCPS_DEBUG + os_printf("dhcps: DHCPD_STATE_OFFER\n"); +#endif + break; + + case DHCPREQUEST://3 + if ( !(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK) ) { + if(renew == true) { + s.state = DHCPS_STATE_ACK; + } else { + s.state = DHCPS_STATE_NAK; + } +#if DHCPS_DEBUG + os_printf("dhcps: DHCPD_STATE_NAK\n"); +#endif + } + break; + + case DHCPDECLINE://4 + s.state = DHCPS_STATE_IDLE; +#if DHCPS_DEBUG + os_printf("dhcps: DHCPD_STATE_IDLE\n"); +#endif + break; + + case DHCPRELEASE://7 + s.state = DHCPS_STATE_RELEASE; +#if DHCPS_DEBUG + os_printf("dhcps: DHCPD_STATE_IDLE\n"); +#endif + break; + } +#if DHCPS_DEBUG + os_printf("dhcps: return s.state = %d\n", s.state); +#endif + return s.state; +} +/////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////// +static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len) { - list_node *plist = NULL; - - if (*phead == NULL) - *phead = pinsert; - else { - plist = *phead; - while (plist->pnext != NULL) { - plist = plist->pnext; - } - plist->pnext = pinsert; - } - pinsert->pnext = NULL; -} - -/****************************************************************************** - * FunctionName : node_delete_from_list - * Description : remove the node from list - * Parameters : arg -- Additional argument to pass to the callback function - * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR node_remove_from_list(list_node **phead, list_node* pdelete) -{ - list_node *plist = NULL; - - plist = *phead; - if (plist == NULL){ - *phead = NULL; - } else { - if (plist == pdelete){ - *phead = plist->pnext; - } else { - while (plist != NULL) { - if (plist->pnext == pdelete){ - plist->pnext = pdelete->pnext; - } - plist = plist->pnext; - } - } - } -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ��DHCP msg��Ϣ�ṹ���������� - * - * @param optptr -- DHCP msg��Ϣλ�� - * @param type -- Ҫ��ӵ�����option - * - * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ - */ -/////////////////////////////////////////////////////////////////////////////////// -static uint8_t* ICACHE_FLASH_ATTR add_msg_type(uint8_t *optptr, uint8_t type) -{ - - *optptr++ = DHCP_OPTION_MSG_TYPE; - *optptr++ = 1; - *optptr++ = type; - return optptr; -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ��DHCP msg�ṹ������offerӦ������ - * - * @param optptr -- DHCP msg��Ϣλ�� - * - * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ - */ -/////////////////////////////////////////////////////////////////////////////////// -static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) -{ - struct ip_addr ipadd; - - ipadd.addr = *( (uint32_t *) &server_address); - -#ifdef USE_CLASS_B_NET - *optptr++ = DHCP_OPTION_SUBNET_MASK; - *optptr++ = 4; //length - *optptr++ = 255; - *optptr++ = 240; - *optptr++ = 0; - *optptr++ = 0; -#else - *optptr++ = DHCP_OPTION_SUBNET_MASK; - *optptr++ = 4; - *optptr++ = 255; - *optptr++ = 255; - *optptr++ = 255; - *optptr++ = 0; -#endif - - *optptr++ = DHCP_OPTION_LEASE_TIME; - *optptr++ = 4; - *optptr++ = 0x00; - *optptr++ = 0x01; - *optptr++ = 0x51; - *optptr++ = 0x80; - - *optptr++ = DHCP_OPTION_SERVER_ID; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd); - *optptr++ = ip4_addr2( &ipadd); - *optptr++ = ip4_addr3( &ipadd); - *optptr++ = ip4_addr4( &ipadd); - - if (dhcps_router_enabled(offer)){ - struct ip_info if_ip; - os_bzero(&if_ip, sizeof(struct ip_info)); - wifi_get_ip_info(SOFTAP_IF, &if_ip); - - *optptr++ = DHCP_OPTION_ROUTER; - *optptr++ = 4; - *optptr++ = ip4_addr1( &if_ip.gw); - *optptr++ = ip4_addr2( &if_ip.gw); - *optptr++ = ip4_addr3( &if_ip.gw); - *optptr++ = ip4_addr4( &if_ip.gw); - } - -#ifdef USE_DNS - *optptr++ = DHCP_OPTION_DNS_SERVER; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd); - *optptr++ = ip4_addr2( &ipadd); - *optptr++ = ip4_addr3( &ipadd); - *optptr++ = ip4_addr4( &ipadd); -#endif - -#ifdef CLASS_B_NET - *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd); - *optptr++ = 255; - *optptr++ = 255; - *optptr++ = 255; -#else - *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd); - *optptr++ = ip4_addr2( &ipadd); - *optptr++ = ip4_addr3( &ipadd); - *optptr++ = 255; -#endif - - *optptr++ = DHCP_OPTION_INTERFACE_MTU; - *optptr++ = 2; -#ifdef CLASS_B_NET - *optptr++ = 0x05; - *optptr++ = 0xdc; -#else - *optptr++ = 0x02; - *optptr++ = 0x40; -#endif - - *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY; - *optptr++ = 1; - *optptr++ = 0x00; - - *optptr++ = 43; - *optptr++ = 6; - - *optptr++ = 0x01; - *optptr++ = 4; - *optptr++ = 0x00; - *optptr++ = 0x00; - *optptr++ = 0x00; - *optptr++ = 0x02; - - return optptr; -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ��DHCP msg�ṹ����ӽ����־���� - * - * @param optptr -- DHCP msg��Ϣλ�� - * - * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ - */ -/////////////////////////////////////////////////////////////////////////////////// -static uint8_t* ICACHE_FLASH_ATTR add_end(uint8_t *optptr) -{ - - *optptr++ = DHCP_OPTION_END; - return optptr; -} -/////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR create_msg(struct dhcps_msg *m) -{ - struct ip_addr client; - - client.addr = *( (uint32_t *) &client_address); - - m->op = DHCP_REPLY; - m->htype = DHCP_HTYPE_ETHERNET; - m->hlen = 6; - m->hops = 0; -// os_memcpy((char *) xid, (char *) m->xid, sizeof(m->xid)); - m->secs = 0; - m->flags = htons(BOOTP_BROADCAST); - - os_memcpy((char *) m->yiaddr, (char *) &client.addr, sizeof(m->yiaddr)); - - os_memset((char *) m->ciaddr, 0, sizeof(m->ciaddr)); - os_memset((char *) m->siaddr, 0, sizeof(m->siaddr)); - os_memset((char *) m->giaddr, 0, sizeof(m->giaddr)); - os_memset((char *) m->sname, 0, sizeof(m->sname)); - os_memset((char *) m->file, 0, sizeof(m->file)); - - os_memset((char *) m->options, 0, sizeof(m->options)); - os_memcpy((char *) m->options, &magic_cookie, sizeof(magic_cookie)); -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����һ��OFFER - * - * @param -- m ָ����Ҫ���͵�DHCP msg���� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m) -{ - uint8_t *end; - struct pbuf *p, *q; - u8_t *data; - u16_t cnt=0; - u16_t i; - err_t SendOffer_err_t; - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPOFFER); - end = add_offer_options(end); - end = add_end(end); - - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); -#if DHCPS_DEBUG - os_printf("udhcp: send_offer>>p->ref = %d\n", p->ref); -#endif - if(p != NULL){ - -#if DHCPS_DEBUG - os_printf("dhcps: send_offer>>pbuf_alloc succeed\n"); - os_printf("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len); - os_printf("dhcps: send_offer>>p->len = %d\n", p->len); -#endif - q = p; - while(q != NULL){ - data = (u8_t *)q->payload; - for(i=0; ilen; i++) - { - data[i] = ((u8_t *) m)[cnt++]; -#if DHCPS_DEBUG - os_printf("%02x ",data[i]); - if((i+1)%16 == 0){ - os_printf("\n"); - } -#endif - } - - q = q->next; - } - }else{ - -#if DHCPS_DEBUG - os_printf("dhcps: send_offer>>pbuf_alloc failed\n"); -#endif - return; - } - SendOffer_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); -#if DHCPS_DEBUG - os_printf("dhcps: send_offer>>udp_sendto result %x\n",SendOffer_err_t); -#endif - if(p->ref != 0){ -#if DHCPS_DEBUG - os_printf("udhcp: send_offer>>free pbuf\n"); -#endif - pbuf_free(p); - } -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����һ��NAK��Ϣ - * - * @param m ָ����Ҫ���͵�DHCP msg���� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR send_nak(struct dhcps_msg *m) -{ - - u8_t *end; - struct pbuf *p, *q; - u8_t *data; - u16_t cnt=0; - u16_t i; - err_t SendNak_err_t; - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPNAK); - end = add_end(end); - - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); -#if DHCPS_DEBUG - os_printf("udhcp: send_nak>>p->ref = %d\n", p->ref); -#endif - if(p != NULL){ - -#if DHCPS_DEBUG - os_printf("dhcps: send_nak>>pbuf_alloc succeed\n"); - os_printf("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len); - os_printf("dhcps: send_nak>>p->len = %d\n", p->len); -#endif - q = p; - while(q != NULL){ - data = (u8_t *)q->payload; - for(i=0; ilen; i++) - { - data[i] = ((u8_t *) m)[cnt++]; -#if DHCPS_DEBUG - os_printf("%02x ",data[i]); - if((i+1)%16 == 0){ - os_printf("\n"); - } -#endif - } - - q = q->next; - } - }else{ - -#if DHCPS_DEBUG - os_printf("dhcps: send_nak>>pbuf_alloc failed\n"); -#endif - return; - } - SendNak_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); -#if DHCPS_DEBUG - os_printf("dhcps: send_nak>>udp_sendto result %x\n",SendNak_err_t); -#endif - if(p->ref != 0){ -#if DHCPS_DEBUG - os_printf("udhcp: send_nak>>free pbuf\n"); -#endif - pbuf_free(p); - } -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����һ��ACK��DHCP�ͻ��� - * - * @param m ָ����Ҫ���͵�DHCP msg���� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR send_ack(struct dhcps_msg *m) -{ - - u8_t *end; - struct pbuf *p, *q; - u8_t *data; - u16_t cnt=0; - u16_t i; - err_t SendAck_err_t; - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPACK); - end = add_offer_options(end); - end = add_end(end); - - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); -#if DHCPS_DEBUG - os_printf("udhcp: send_ack>>p->ref = %d\n", p->ref); -#endif - if(p != NULL){ - -#if DHCPS_DEBUG - os_printf("dhcps: send_ack>>pbuf_alloc succeed\n"); - os_printf("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len); - os_printf("dhcps: send_ack>>p->len = %d\n", p->len); -#endif - q = p; - while(q != NULL){ - data = (u8_t *)q->payload; - for(i=0; ilen; i++) - { - data[i] = ((u8_t *) m)[cnt++]; -#if DHCPS_DEBUG - os_printf("%02x ",data[i]); - if((i+1)%16 == 0){ - os_printf("\n"); - } -#endif - } - - q = q->next; - } - }else{ - -#if DHCPS_DEBUG - os_printf("dhcps: send_ack>>pbuf_alloc failed\n"); -#endif - return; - } - SendAck_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); -#if DHCPS_DEBUG - os_printf("dhcps: send_ack>>udp_sendto result %x\n",SendAck_err_t); -#endif - - if(p->ref != 0){ -#if DHCPS_DEBUG - os_printf("udhcp: send_ack>>free pbuf\n"); -#endif - pbuf_free(p); - } -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����DHCP�ͻ��˷�����DHCP����������Ϣ�����Բ�ͬ��DHCP��������������Ӧ��Ӧ�� - * - * @param optptr DHCP msg�е��������� - * @param len ��������Ĵ��?(byte) - * - * @return uint8_t ���ش�����DHCP Server״ֵ̬ - */ -/////////////////////////////////////////////////////////////////////////////////// -static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len) -{ - struct ip_addr client; - bool is_dhcp_parse_end = false; - - client.addr = *( (uint32_t *) &client_address);// Ҫ�����DHCP�ͻ��˵�IP - - u8_t *end = optptr + len; - u16_t type = 0; - - s.state = DHCPS_STATE_IDLE; - - while (optptr < end) { -#if DHCPS_DEBUG - os_printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr); -#endif - switch ((sint16_t) *optptr) { - - case DHCP_OPTION_MSG_TYPE: //53 - type = *(optptr + 2); - break; - - case DHCP_OPTION_REQ_IPADDR://50 - if( os_memcmp( (char *) &client.addr, (char *) optptr+2,4)==0 ) { -#if DHCPS_DEBUG - os_printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); -#endif - s.state = DHCPS_STATE_ACK; - }else { -#if DHCPS_DEBUG - os_printf("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n"); -#endif - s.state = DHCPS_STATE_NAK; - } - break; - case DHCP_OPTION_END: - { - is_dhcp_parse_end = true; - } - break; - } - - if(is_dhcp_parse_end){ - break; - } - - optptr += optptr[1] + 2; - } - - switch (type){ - - case DHCPDISCOVER://1 - s.state = DHCPS_STATE_OFFER; -#if DHCPS_DEBUG - os_printf("dhcps: DHCPD_STATE_OFFER\n"); -#endif - break; - - case DHCPREQUEST://3 - if ( !(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK) ) { - s.state = DHCPS_STATE_NAK; -#if DHCPS_DEBUG - os_printf("dhcps: DHCPD_STATE_NAK\n"); -#endif - } - break; - - case DHCPDECLINE://4 - s.state = DHCPS_STATE_IDLE; -#if DHCPS_DEBUG - os_printf("dhcps: DHCPD_STATE_IDLE\n"); -#endif - break; - - case DHCPRELEASE://7 - s.state = DHCPS_STATE_IDLE; -#if DHCPS_DEBUG - os_printf("dhcps: DHCPD_STATE_IDLE\n"); -#endif - break; - } -#if DHCPS_DEBUG - os_printf("dhcps: return s.state = %d\n", s.state); -#endif - return s.state; -} -/////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////// -static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len) -{ - if(os_memcmp((char *)m->options, - &magic_cookie, - sizeof(magic_cookie)) == 0){ -#if DHCPS_DEBUG - os_printf("dhcps: len = %d\n", len); -#endif - /* - * ��¼��ǰ��xid���ﴦ���? - * �˺�ΪDHCP�ͻ����������û�ͳһ��ȡIPʱ�� - */ -// if((old_xid[0] == 0) && -// (old_xid[1] == 0) && -// (old_xid[2] == 0) && -// (old_xid[3] == 0)){ -// /* -// * old_xidδ��¼�κ����? -// * �϶��ǵ�һ��ʹ�� -// */ -// os_memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); -// }else{ -// /* -// * ���δ����DHCP msg��Я���xid���ϴμ�¼�IJ�ͬ�� -// * �϶�Ϊ��ͬ��DHCP�ͻ��˷��ͣ���ʱ����Ҫ����Ŀͻ���IP -// * ���� 192.168.4.100(0x6404A8C0) <--> 192.168.4.200(0xC804A8C0) -// * -// */ -// if(os_memcmp((char *)old_xid, (char *)m->xid, sizeof(m->xid)) != 0){ - /* - * ��¼���ε�xid�ţ�ͬʱ�����IP���� - */ - struct ip_addr addr_tmp; -// os_memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); - - { - struct dhcps_pool *pdhcps_pool = NULL; - list_node *pnode = NULL; - list_node *pback_node = NULL; - - POOL_START: - client_address.addr = client_address_plus.addr; -// addr_tmp.addr = htonl(client_address_plus.addr); -// addr_tmp.addr++; -// client_address_plus.addr = htonl(addr_tmp.addr); - for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) { - pdhcps_pool = pback_node->pnode; - if (os_memcmp(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)) == 0){ -// os_printf("the same device request ip\n"); - client_address.addr = pdhcps_pool->ip.addr; - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; - goto POOL_CHECK; - } else if (pdhcps_pool->ip.addr == client_address_plus.addr){ -// client_address.addr = client_address_plus.addr; -// os_printf("the ip addr has been request\n"); - addr_tmp.addr = htonl(client_address_plus.addr); - addr_tmp.addr++; - client_address_plus.addr = htonl(addr_tmp.addr); - client_address.addr = client_address_plus.addr; - } - } - pdhcps_pool = (struct dhcps_pool *)os_zalloc(sizeof(struct dhcps_pool)); - pdhcps_pool->ip.addr = client_address.addr; - os_memcpy(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)); - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; - pnode = (list_node *)os_zalloc(sizeof(list_node )); - pnode->pnode = pdhcps_pool; - node_insert_to_list(&plist,pnode); - - POOL_CHECK: - if ((client_address_plus.addr > dhcps_lease.end_ip.addr) || (ip_addr_isany(&client_address))){ - os_printf("client_address_plus.addr %x %d\n", client_address_plus.addr, system_get_free_heap_size()); - node_remove_from_list(&plist,pnode); - os_free(pdhcps_pool); - pdhcps_pool = NULL; - os_free(pnode); - pnode = NULL; -// client_address_plus.addr = dhcps_lease.start_ip.addr; - return 4; - } - - if (wifi_softap_set_station_info(m->chaddr, &client_address) == false) { - return 0; - } - } - -#if DHCPS_DEBUG - os_printf("dhcps: xid changed\n"); - os_printf("dhcps: client_address.addr = %x\n", client_address.addr); -#endif - -// } - -// } - - return parse_options(&m->options[4], len); - } - return 0; -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * DHCP ��������ݰ���մ���ص�����˺�����LWIP UDPģ������ʱ������ - * ��Ҫ����udp_recv()������LWIP����ע��. - * - * @param arg - * @param pcb ���յ�UDP��Ŀ��ƿ�? - * @param p ���յ���UDP�е��������? - * @param addr ���ʹ�UDP���Դ�����IP��ַ - * @param port ���ʹ�UDP���Դ�����UDPͨ���˿ں� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR handle_dhcp(void *arg, - struct udp_pcb *pcb, - struct pbuf *p, - struct ip_addr *addr, - uint16_t port) -{ - struct dhcps_msg *pmsg_dhcps = NULL; - sint16_t tlen = 0; - u16_t i = 0; - u16_t dhcps_msg_cnt = 0; - u8_t *p_dhcps_msg = NULL; - u8_t *data = NULL; - -#if DHCPS_DEBUG - os_printf("dhcps: handle_dhcp-> receive a packet\n"); -#endif - if (p==NULL) return; - - pmsg_dhcps = (struct dhcps_msg *)os_zalloc(sizeof(struct dhcps_msg)); - if (NULL == pmsg_dhcps){ - pbuf_free(p); - return; - } - p_dhcps_msg = (u8_t *)pmsg_dhcps; - tlen = p->tot_len; - data = p->payload; - -#if DHCPS_DEBUG - os_printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen); - os_printf("dhcps: handle_dhcp-> p->len = %d\n", p->len); -#endif - - for(i=0; ilen; i++){ - p_dhcps_msg[dhcps_msg_cnt++] = data[i]; -#if DHCPS_DEBUG - os_printf("%02x ",data[i]); - if((i+1)%16 == 0){ - os_printf("\n"); - } -#endif - } - - if(p->next != NULL) { -#if DHCPS_DEBUG - os_printf("dhcps: handle_dhcp-> p->next != NULL\n"); - os_printf("dhcps: handle_dhcp-> p->next->tot_len = %d\n",p->next->tot_len); - os_printf("dhcps: handle_dhcp-> p->next->len = %d\n",p->next->len); -#endif - - data = p->next->payload; - for(i=0; inext->len; i++){ - p_dhcps_msg[dhcps_msg_cnt++] = data[i]; -#if DHCPS_DEBUG - os_printf("%02x ",data[i]); - if((i+1)%16 == 0){ - os_printf("\n"); - } -#endif - } - } - - /* - * DHCP �ͻ���������Ϣ���� - */ -#if DHCPS_DEBUG - os_printf("dhcps: handle_dhcp-> parse_msg(p)\n"); -#endif - - switch(parse_msg(pmsg_dhcps, tlen - 240)) { - - case DHCPS_STATE_OFFER://1 -#if DHCPS_DEBUG - os_printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); -#endif - send_offer(pmsg_dhcps); - break; - case DHCPS_STATE_ACK://3 -#if DHCPS_DEBUG - os_printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); -#endif - send_ack(pmsg_dhcps); - break; - case DHCPS_STATE_NAK://4 -#if DHCPS_DEBUG - os_printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); -#endif - send_nak(pmsg_dhcps); - break; - default : - break; - } -#if DHCPS_DEBUG - os_printf("dhcps: handle_dhcp-> pbuf_free(p)\n"); -#endif - pbuf_free(p); - os_free(pmsg_dhcps); - pmsg_dhcps = NULL; -} -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR wifi_softap_init_dhcps_lease(uint32 ip) -{ - uint32 softap_ip = 0,local_ip = 0; - - if (dhcps_lease_flag) { - local_ip = softap_ip = htonl(ip); - softap_ip &= 0xFFFFFF00; - local_ip &= 0xFF; - if (local_ip >= 0x80) - local_ip -= DHCPS_MAX_LEASE; - else - local_ip ++; - - os_bzero(&dhcps_lease, sizeof(dhcps_lease)); - dhcps_lease.start_ip.addr = softap_ip | local_ip; - dhcps_lease.end_ip.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE); - } - dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr); - dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr); -// os_printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip); -} -/////////////////////////////////////////////////////////////////////////////////// -void ICACHE_FLASH_ATTR dhcps_start(struct ip_info *info) -{ - struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); - - if(apnetif->dhcps_pcb != NULL) { - udp_remove(apnetif->dhcps_pcb); - } - - pcb_dhcps = udp_new(); - if (pcb_dhcps == NULL || info ==NULL) { - os_printf("dhcps_start(): could not obtain pcb\n"); - } - - apnetif->dhcps_pcb = pcb_dhcps; - - IP4_ADDR(&broadcast_dhcps, 255, 255, 255, 255); - - server_address = info->ip; - wifi_softap_init_dhcps_lease(server_address.addr); - client_address_plus.addr = dhcps_lease.start_ip.addr; - - udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT); - udp_recv(pcb_dhcps, handle_dhcp, NULL); -#if DHCPS_DEBUG - os_printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n"); -#endif - -} - -void ICACHE_FLASH_ATTR dhcps_stop(void) -{ - struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); - - udp_disconnect(pcb_dhcps); - dhcps_lease_flag = true; - if(apnetif->dhcps_pcb != NULL) { - udp_remove(apnetif->dhcps_pcb); - apnetif->dhcps_pcb = NULL; - } - - //udp_remove(pcb_dhcps); - list_node *pnode = NULL; - list_node *pback_node = NULL; - pnode = plist; - while (pnode != NULL) { - pback_node = pnode; - pnode = pback_node->pnext; - node_remove_from_list(&plist, pback_node); - os_free(pback_node->pnode); - pback_node->pnode = NULL; - os_free(pback_node); - pback_node = NULL; - } -} - -/****************************************************************************** - * FunctionName : wifi_softap_set_dhcps_lease - * Description : set the lease information of DHCP server - * Parameters : please -- Additional argument to set the lease information, - * Little-Endian. - * Returns : true or false -*******************************************************************************/ -bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease(struct dhcps_lease *please) -{ - struct ip_info info; - uint32 softap_ip = 0; - uint32 start_ip = 0; - uint32 end_ip = 0; - - uint8 opmode = wifi_get_opmode(); - - if (opmode == STATION_MODE || opmode == NULL_MODE) { - return false; - } - - if (please == NULL || wifi_softap_dhcps_status() == DHCP_STARTED) - return false; - - os_bzero(&info, sizeof(struct ip_info)); - wifi_get_ip_info(SOFTAP_IF, &info); - softap_ip = htonl(info.ip.addr); - start_ip = htonl(please->start_ip.addr); - end_ip = htonl(please->end_ip.addr); - - /*config ip information can't contain local ip*/ - if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) - return false; - - /*config ip information must be in the same segment as the local ip*/ - softap_ip >>= 8; - if ((start_ip >> 8 != softap_ip) - || (end_ip >> 8 != softap_ip)) { - return false; - } - - if (end_ip - start_ip > DHCPS_MAX_LEASE) - return false; - - os_bzero(&dhcps_lease, sizeof(dhcps_lease)); - dhcps_lease.start_ip.addr = start_ip; - dhcps_lease.end_ip.addr = end_ip; - dhcps_lease_flag = false; - return true; -} - -/****************************************************************************** - * FunctionName : wifi_softap_get_dhcps_lease - * Description : get the lease information of DHCP server - * Parameters : please -- Additional argument to get the lease information, - * Little-Endian. - * Returns : true or false -*******************************************************************************/ -bool ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease(struct dhcps_lease *please) -{ - uint8 opmode = wifi_get_opmode(); - - if (opmode == STATION_MODE || opmode == NULL_MODE) { - return false; - } - - if (NULL == please) - return false; - - if (dhcps_lease_flag){ - if (wifi_softap_dhcps_status() == DHCP_STOPPED) - return false; - } else { - os_bzero(please, sizeof(dhcps_lease)); - if (wifi_softap_dhcps_status() == DHCP_STOPPED){ - please->start_ip.addr = htonl(dhcps_lease.start_ip.addr); - please->end_ip.addr = htonl(dhcps_lease.end_ip.addr); - } - } - - if (wifi_softap_dhcps_status() == DHCP_STARTED){ - os_bzero(please, sizeof(dhcps_lease)); - please->start_ip.addr = dhcps_lease.start_ip.addr; - please->end_ip.addr = dhcps_lease.end_ip.addr; - } - return true; -} - -static void ICACHE_FLASH_ATTR kill_oldest_dhcps_pool(void) -{ - list_node *pre = NULL, *p = NULL; - list_node *minpre = NULL, *minp = NULL; - struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL; - pre = plist; - p = pre->pnext; - minpre = pre; - minp = p; - while (p != NULL){ - pdhcps_pool = p->pnode; - pmin_pool = minp->pnode; - if (pdhcps_pool->lease_timer < pmin_pool->lease_timer){ - minp = p; - minpre = pre; - } - pre = p; - p = p->pnext; - } - minpre->pnext = minp->pnext; - os_free(minp->pnode); - minp->pnode = NULL; - os_free(minp); - minp = NULL; -} - -void ICACHE_FLASH_ATTR dhcps_coarse_tmr(void) -{ - uint8 num_dhcps_pool = 0; - list_node *pback_node = NULL; - list_node *pnode = NULL; - struct dhcps_pool *pdhcps_pool = NULL; - pnode = plist; - while (pnode != NULL) { - pdhcps_pool = pnode->pnode; - pdhcps_pool->lease_timer --; - if (pdhcps_pool->lease_timer == 0){ - pback_node = pnode; - pnode = pback_node->pnext; - node_remove_from_list(&plist,pback_node); - os_free(pback_node->pnode); - pback_node->pnode = NULL; - os_free(pback_node); - pback_node = NULL; - } else { - pnode = pnode ->pnext; - num_dhcps_pool ++; - } - } - - if (num_dhcps_pool >= MAX_STATION_NUM) - kill_oldest_dhcps_pool(); -} - -bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg) -{ - bool offer_flag = true; - uint8 option = 0; - if (optarg == NULL && wifi_softap_dhcps_status() == false) - return false; - - if (level <= OFFER_START || level >= OFFER_END) - return false; - - switch (level){ - case OFFER_ROUTER: - offer = (*(uint8 *)optarg) & 0x01; - offer_flag = true; - break; - default : - offer_flag = false; - break; - } - return offer_flag; -} - + if(os_memcmp((char *)m->options, + &magic_cookie, + sizeof(magic_cookie)) == 0){ +#if DHCPS_DEBUG + os_printf("dhcps: len = %d\n", len); +#endif + /* + * ��¼��ǰ��xid���ﴦ���? + * �˺�ΪDHCP�ͻ����������û�ͳһ��ȡIPʱ�� + */ +// if((old_xid[0] == 0) && +// (old_xid[1] == 0) && +// (old_xid[2] == 0) && +// (old_xid[3] == 0)){ +// /* +// * old_xidδ��¼�κ����? +// * �϶��ǵ�һ��ʹ�� +// */ +// os_memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); +// }else{ +// /* +// * ���δ����DHCP msg��Я���xid���ϴμ�¼�IJ�ͬ�� +// * �϶�Ϊ��ͬ��DHCP�ͻ��˷��ͣ���ʱ����Ҫ����Ŀͻ���IP +// * ���� 192.168.4.100(0x6404A8C0) <--> 192.168.4.200(0xC804A8C0) +// * +// */ +// if(os_memcmp((char *)old_xid, (char *)m->xid, sizeof(m->xid)) != 0){ + /* + * ��¼���ε�xid�ţ�ͬʱ�����IP���� + */ + struct ip_addr addr_tmp; +// os_memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); + +// { + struct dhcps_pool *pdhcps_pool = NULL; + list_node *pnode = NULL; + list_node *pback_node = NULL; + struct ip_addr first_address; + bool flag = false; + +// POOL_START: + first_address.addr = dhcps_lease.start_ip.addr; + client_address.addr = client_address_plus.addr; + renew = false; +// addr_tmp.addr = htonl(client_address_plus.addr); +// addr_tmp.addr++; +// client_address_plus.addr = htonl(addr_tmp.addr); + for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) { + pdhcps_pool = pback_node->pnode; + if (os_memcmp(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)) == 0){ +// os_printf("the same device request ip\n"); + if (os_memcmp(&pdhcps_pool->ip.addr, m->ciaddr, sizeof(pdhcps_pool->ip.addr)) == 0) { + renew = true; + } + client_address.addr = pdhcps_pool->ip.addr; + pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pnode = pback_node; + goto POOL_CHECK; + } else if (pdhcps_pool->ip.addr == client_address_plus.addr){ +// client_address.addr = client_address_plus.addr; +// os_printf("the ip addr has been request\n"); + addr_tmp.addr = htonl(client_address_plus.addr); + addr_tmp.addr++; + client_address_plus.addr = htonl(addr_tmp.addr); + client_address.addr = client_address_plus.addr; + } + + if(flag == false) { // search the fisrt unused ip + if(first_address.addr < pdhcps_pool->ip.addr) { + flag = true; + } else { + addr_tmp.addr = htonl(first_address.addr); + addr_tmp.addr++; + first_address.addr = htonl(addr_tmp.addr); + } + } + } + if (client_address_plus.addr > dhcps_lease.end_ip.addr) { + client_address.addr = first_address.addr; + } + if (client_address.addr > dhcps_lease.end_ip.addr) { + client_address_plus.addr = dhcps_lease.start_ip.addr; + pdhcps_pool = NULL; + pnode = NULL; + } else { + pdhcps_pool = (struct dhcps_pool *)os_zalloc(sizeof(struct dhcps_pool)); + pdhcps_pool->ip.addr = client_address.addr; + os_memcpy(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)); + pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pnode = (list_node *)os_zalloc(sizeof(list_node )); + pnode->pnode = pdhcps_pool; + pnode->pnext = NULL; + node_insert_to_list(&plist,pnode); + if (client_address.addr == dhcps_lease.end_ip.addr) { + client_address_plus.addr = dhcps_lease.start_ip.addr; + } else { + addr_tmp.addr = htonl(client_address.addr); + addr_tmp.addr++; + client_address_plus.addr = htonl(addr_tmp.addr); + } + } + + POOL_CHECK: + if ((client_address.addr > dhcps_lease.end_ip.addr) || (ip_addr_isany(&client_address))){ + os_printf("client_address_plus.addr %x %d\n", client_address_plus.addr, system_get_free_heap_size()); + if(pnode != NULL) { + node_remove_from_list(&plist,pnode); + os_free(pnode); + pnode = NULL; + } + + if (pdhcps_pool != NULL) { + os_free(pdhcps_pool); + pdhcps_pool = NULL; + } +// client_address_plus.addr = dhcps_lease.start_ip.addr; + return 4; + } + + sint16_t ret = parse_options(&m->options[4], len);; + + if(ret == DHCPS_STATE_RELEASE) { + if(pnode != NULL) { + node_remove_from_list(&plist,pnode); + os_free(pnode); + pnode = NULL; + } + + if (pdhcps_pool != NULL) { + os_free(pdhcps_pool); + pdhcps_pool = NULL; + } + os_memset(&client_address,0x0,sizeof(client_address)); + } + + if (wifi_softap_set_station_info(m->chaddr, &client_address) == false) { + return 0; + } +// } + +#if DHCPS_DEBUG + os_printf("dhcps: xid changed\n"); + os_printf("dhcps: client_address.addr = %x\n", client_address.addr); +#endif + +// } + +// } + return ret; + } + return 0; +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * DHCP ��������ݰ���մ���ص�����˺�����LWIP UDPģ������ʱ������ + * ��Ҫ����udp_recv()������LWIP����ע��. + * + * @param arg + * @param pcb ���յ�UDP��Ŀ��ƿ�? + * @param p ���յ���UDP�е��������? + * @param addr ���ʹ�UDP���Դ�����IP��ַ + * @param port ���ʹ�UDP���Դ�����UDPͨ���˿ں� + */ +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR handle_dhcp(void *arg, + struct udp_pcb *pcb, + struct pbuf *p, + struct ip_addr *addr, + uint16_t port) +{ + struct dhcps_msg *pmsg_dhcps = NULL; + sint16_t tlen = 0; + u16_t i = 0; + u16_t dhcps_msg_cnt = 0; + u8_t *p_dhcps_msg = NULL; + u8_t *data = NULL; + +#if DHCPS_DEBUG + os_printf("dhcps: handle_dhcp-> receive a packet\n"); +#endif + if (p==NULL) return; + + pmsg_dhcps = (struct dhcps_msg *)os_zalloc(sizeof(struct dhcps_msg)); + if (NULL == pmsg_dhcps){ + pbuf_free(p); + return; + } + p_dhcps_msg = (u8_t *)pmsg_dhcps; + tlen = p->tot_len; + data = p->payload; + +#if DHCPS_DEBUG + os_printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen); + os_printf("dhcps: handle_dhcp-> p->len = %d\n", p->len); +#endif + + for(i=0; ilen; i++){ + p_dhcps_msg[dhcps_msg_cnt++] = data[i]; +#if DHCPS_DEBUG + os_printf("%02x ",data[i]); + if((i+1)%16 == 0){ + os_printf("\n"); + } +#endif + } + + if(p->next != NULL) { +#if DHCPS_DEBUG + os_printf("dhcps: handle_dhcp-> p->next != NULL\n"); + os_printf("dhcps: handle_dhcp-> p->next->tot_len = %d\n",p->next->tot_len); + os_printf("dhcps: handle_dhcp-> p->next->len = %d\n",p->next->len); +#endif + + data = p->next->payload; + for(i=0; inext->len; i++){ + p_dhcps_msg[dhcps_msg_cnt++] = data[i]; +#if DHCPS_DEBUG + os_printf("%02x ",data[i]); + if((i+1)%16 == 0){ + os_printf("\n"); + } +#endif + } + } + + /* + * DHCP �ͻ���������Ϣ���� + */ +#if DHCPS_DEBUG + os_printf("dhcps: handle_dhcp-> parse_msg(p)\n"); +#endif + + switch(parse_msg(pmsg_dhcps, tlen - 240)) { + + case DHCPS_STATE_OFFER://1 +#if DHCPS_DEBUG + os_printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); +#endif + send_offer(pmsg_dhcps); + break; + case DHCPS_STATE_ACK://3 +#if DHCPS_DEBUG + os_printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); +#endif + send_ack(pmsg_dhcps); + break; + case DHCPS_STATE_NAK://4 +#if DHCPS_DEBUG + os_printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); +#endif + send_nak(pmsg_dhcps); + break; + default : + break; + } +#if DHCPS_DEBUG + os_printf("dhcps: handle_dhcp-> pbuf_free(p)\n"); +#endif + pbuf_free(p); + os_free(pmsg_dhcps); + pmsg_dhcps = NULL; +} +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR wifi_softap_init_dhcps_lease(uint32 ip) +{ + uint32 softap_ip = 0,local_ip = 0; + uint32 start_ip = 0; + uint32 end_ip = 0; +// if (dhcps_lease_flag) { + if (dhcps_lease.enable == TRUE) { + softap_ip = htonl(ip); + start_ip = htonl(dhcps_lease.start_ip.addr); + end_ip = htonl(dhcps_lease.end_ip.addr); + /*config ip information can't contain local ip*/ + if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) { + dhcps_lease.enable = FALSE; + } else { + /*config ip information must be in the same segment as the local ip*/ + softap_ip >>= 8; + if (((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip)) + || (end_ip - start_ip > DHCPS_MAX_LEASE)) { + dhcps_lease.enable = FALSE; + } + } + } + + if (dhcps_lease.enable == FALSE) { + local_ip = softap_ip = htonl(ip); + softap_ip &= 0xFFFFFF00; + local_ip &= 0xFF; + if (local_ip >= 0x80) + local_ip -= DHCPS_MAX_LEASE; + else + local_ip ++; + + os_bzero(&dhcps_lease, sizeof(dhcps_lease)); + dhcps_lease.start_ip.addr = softap_ip | local_ip; + dhcps_lease.end_ip.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1); + dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr); + dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr); + } +// dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr); +// dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr); +// os_printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip); +} +/////////////////////////////////////////////////////////////////////////////////// +void ICACHE_FLASH_ATTR dhcps_start(struct ip_info *info) +{ + struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); + + if(apnetif->dhcps_pcb != NULL) { + udp_remove(apnetif->dhcps_pcb); + } + + pcb_dhcps = udp_new(); + if (pcb_dhcps == NULL || info ==NULL) { + os_printf("dhcps_start(): could not obtain pcb\n"); + } + + apnetif->dhcps_pcb = pcb_dhcps; + + IP4_ADDR(&broadcast_dhcps, 255, 255, 255, 255); + + server_address = info->ip; + wifi_softap_init_dhcps_lease(server_address.addr); + client_address_plus.addr = dhcps_lease.start_ip.addr; + + udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT); + udp_recv(pcb_dhcps, handle_dhcp, NULL); +#if DHCPS_DEBUG + os_printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n"); +#endif + +} + +void ICACHE_FLASH_ATTR dhcps_stop(void) +{ + struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); + + udp_disconnect(pcb_dhcps); +// dhcps_lease_flag = true; + if(apnetif->dhcps_pcb != NULL) { + udp_remove(apnetif->dhcps_pcb); + apnetif->dhcps_pcb = NULL; + } + + //udp_remove(pcb_dhcps); + list_node *pnode = NULL; + list_node *pback_node = NULL; + pnode = plist; + while (pnode != NULL) { + pback_node = pnode; + pnode = pback_node->pnext; + node_remove_from_list(&plist, pback_node); + os_free(pback_node->pnode); + pback_node->pnode = NULL; + os_free(pback_node); + pback_node = NULL; + } +} + +/****************************************************************************** + * FunctionName : wifi_softap_set_dhcps_lease + * Description : set the lease information of DHCP server + * Parameters : please -- Additional argument to set the lease information, + * Little-Endian. + * Returns : true or false +*******************************************************************************/ +bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease(struct dhcps_lease *please) +{ + struct ip_info info; + uint32 softap_ip = 0; + uint32 start_ip = 0; + uint32 end_ip = 0; + + uint8 opmode = wifi_get_opmode(); + + if (opmode == STATION_MODE || opmode == NULL_MODE) { + return false; + } + + if (please == NULL || wifi_softap_dhcps_status() == DHCP_STARTED) + return false; + + if(please->enable) { + os_bzero(&info, sizeof(struct ip_info)); + wifi_get_ip_info(SOFTAP_IF, &info); + softap_ip = htonl(info.ip.addr); + start_ip = htonl(please->start_ip.addr); + end_ip = htonl(please->end_ip.addr); + + /*config ip information can't contain local ip*/ + if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) + return false; + + /*config ip information must be in the same segment as the local ip*/ + softap_ip >>= 8; + if ((start_ip >> 8 != softap_ip) + || (end_ip >> 8 != softap_ip)) { + return false; + } + + if (end_ip - start_ip > DHCPS_MAX_LEASE) + return false; + + os_bzero(&dhcps_lease, sizeof(dhcps_lease)); +// dhcps_lease.start_ip.addr = start_ip; +// dhcps_lease.end_ip.addr = end_ip; + dhcps_lease.start_ip.addr = please->start_ip.addr; + dhcps_lease.end_ip.addr = please->end_ip.addr; + } + dhcps_lease.enable = please->enable; +// dhcps_lease_flag = false; + return true; +} + +/****************************************************************************** + * FunctionName : wifi_softap_get_dhcps_lease + * Description : get the lease information of DHCP server + * Parameters : please -- Additional argument to get the lease information, + * Little-Endian. + * Returns : true or false +*******************************************************************************/ +bool ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease(struct dhcps_lease *please) +{ + uint8 opmode = wifi_get_opmode(); + + if (opmode == STATION_MODE || opmode == NULL_MODE) { + return false; + } + + if (NULL == please) + return false; + +// if (dhcps_lease_flag){ + if (dhcps_lease.enable == FALSE){ + if (wifi_softap_dhcps_status() == DHCP_STOPPED) + return false; + } else { +// os_bzero(please, sizeof(dhcps_lease)); +// if (wifi_softap_dhcps_status() == DHCP_STOPPED){ +// please->start_ip.addr = htonl(dhcps_lease.start_ip.addr); +// please->end_ip.addr = htonl(dhcps_lease.end_ip.addr); +// } + } + +// if (wifi_softap_dhcps_status() == DHCP_STARTED){ +// os_bzero(please, sizeof(dhcps_lease)); +// please->start_ip.addr = dhcps_lease.start_ip.addr; +// please->end_ip.addr = dhcps_lease.end_ip.addr; +// } + please->start_ip.addr = dhcps_lease.start_ip.addr; + please->end_ip.addr = dhcps_lease.end_ip.addr; + return true; +} + +static void ICACHE_FLASH_ATTR kill_oldest_dhcps_pool(void) +{ + list_node *pre = NULL, *p = NULL; + list_node *minpre = NULL, *minp = NULL; + struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL; + pre = plist; + p = pre->pnext; + minpre = pre; + minp = p; + while (p != NULL){ + pdhcps_pool = p->pnode; + pmin_pool = minp->pnode; + if (pdhcps_pool->lease_timer < pmin_pool->lease_timer){ + minp = p; + minpre = pre; + } + pre = p; + p = p->pnext; + } + minpre->pnext = minp->pnext; + os_free(minp->pnode); + minp->pnode = NULL; + os_free(minp); + minp = NULL; +} + +void ICACHE_FLASH_ATTR dhcps_coarse_tmr(void) +{ + uint8 num_dhcps_pool = 0; + list_node *pback_node = NULL; + list_node *pnode = NULL; + struct dhcps_pool *pdhcps_pool = NULL; + pnode = plist; + while (pnode != NULL) { + pdhcps_pool = pnode->pnode; + pdhcps_pool->lease_timer --; + if (pdhcps_pool->lease_timer == 0){ + pback_node = pnode; + pnode = pback_node->pnext; + node_remove_from_list(&plist,pback_node); + os_free(pback_node->pnode); + pback_node->pnode = NULL; + os_free(pback_node); + pback_node = NULL; + } else { + pnode = pnode ->pnext; + num_dhcps_pool ++; + } + } + + if (num_dhcps_pool >= MAX_STATION_NUM) + kill_oldest_dhcps_pool(); +} + +bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg) +{ + bool offer_flag = true; + uint8 option = 0; + if (optarg == NULL && wifi_softap_dhcps_status() == false) + return false; + + if (level <= OFFER_START || level >= OFFER_END) + return false; + + switch (level){ + case OFFER_ROUTER: + offer = (*(uint8 *)optarg) & 0x01; + offer_flag = true; + break; + default : + offer_flag = false; + break; + } + return offer_flag; +} + +bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease_time(uint32 minute) +{ + uint8 opmode = wifi_get_opmode(); + + if (opmode == STATION_MODE || opmode == NULL_MODE) { + return false; + } + + if (wifi_softap_dhcps_status() == DHCP_STARTED) { + return false; + } + + if(minute == 0) { + return false; + } + dhcps_lease_time = minute; + return true; +} + +bool ICACHE_FLASH_ATTR wifi_softap_reset_dhcps_lease_time(void) +{ + uint8 opmode = wifi_get_opmode(); + + if (opmode == STATION_MODE || opmode == NULL_MODE) { + return false; + } + + if (wifi_softap_dhcps_status() == DHCP_STARTED) { + return false; + } + dhcps_lease_time = DHCPS_LEASE_TIME_DEF; + return true; +} + +uint32 ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease_time(void) // minute +{ + return dhcps_lease_time; +} diff --git a/app/lwip/app/espconn.c b/app/lwip/app/espconn.c index 1d113f95..30a5601c 100644 --- a/app/lwip/app/espconn.c +++ b/app/lwip/app/espconn.c @@ -25,6 +25,10 @@ #include "lwip/app/espconn.h" #include "user_interface.h" +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + espconn_msg *plink_active = NULL; espconn_msg *pserver_list = NULL; remot_info premot[linkMax]; @@ -385,6 +389,10 @@ espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length) if (espconn_copy_enabled(pnode)){ if (espconn_tcp_get_buf_count(pnode->pcommon.pbuf) >= pnode ->pcommon.pbuf_num) return ESPCONN_MAXNUM; + } else { + struct tcp_pcb *pcb = pnode->pcommon.pcb; + if (pcb->snd_queuelen >= TCP_SND_QUEUELEN) + return ESPCONN_MAXNUM; } pbuf = (espconn_buf*) os_zalloc(sizeof(espconn_buf)); @@ -405,13 +413,13 @@ espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length) if (espconn_copy_disabled(pnode)) pnode->pcommon.write_flag = false; error = espconn_tcp_write(pnode); - if (error != ESPCONN_OK){ - /*send the application packet fail, - * ensure that each allocated is deleted*/ - espconn_pbuf_delete(&pnode->pcommon.pbuf, pbuf); - os_free(pbuf); - pbuf = NULL; - } +// if (error != ESPCONN_OK){ +// /*send the application packet fail, +// * ensure that each allocated is deleted*/ +// espconn_pbuf_delete(&pnode->pcommon.pbuf, pbuf); +// os_free(pbuf); +// pbuf = NULL; +// } return error; } else return ESPCONN_ARG; @@ -428,6 +436,33 @@ espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length) return ESPCONN_ARG; } +/****************************************************************************** + * FunctionName : espconn_sendto + * Description : send data for UDP + * Parameters : espconn -- espconn to set for UDP + * psent -- data to send + * length -- length of data to send + * Returns : error +*******************************************************************************/ +sint16 ICACHE_FLASH_ATTR +espconn_sendto(struct espconn *espconn, uint8 *psent, uint16 length) +{ + espconn_msg *pnode = NULL; + bool value = false; + err_t error = ESPCONN_OK; + + if (espconn == NULL || psent == NULL || length == 0) { + return ESPCONN_ARG; + } + + /*Find the node depend on the espconn message*/ + value = espconn_find_connection(espconn, &pnode); + if (value && espconn->type == ESPCONN_UDP) + return espconn_udp_sendto(pnode, psent, length); + else + return ESPCONN_ARG; +} + /****************************************************************************** * FunctionName : espconn_send * Description : sent data for client or server diff --git a/app/lwip/app/espconn_tcp.c b/app/lwip/app/espconn_tcp.c index 96975173..7c2e65d4 100644 --- a/app/lwip/app/espconn_tcp.c +++ b/app/lwip/app/espconn_tcp.c @@ -24,6 +24,10 @@ #include "lwip/mem.h" #include "lwip/app/espconn_tcp.h" +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + extern espconn_msg *plink_active; extern espconn_msg *pserver_list; extern struct espconn_packet pktinfo[2]; @@ -71,7 +75,7 @@ espconn_kill_oldest(void) inactivity = 0; inactive = NULL; for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->state == FIN_WAIT_2){ + if (pcb->state == FIN_WAIT_1 || pcb->state == FIN_WAIT_2){ if ((u32_t) (tcp_ticks - pcb->tmr) >= inactivity) { inactivity = tcp_ticks - pcb->tmr; inactive = pcb; @@ -121,7 +125,7 @@ void ICACHE_FLASH_ATTR espconn_kill_oldest_pcb(void) break; } - if (cpcb->state == FIN_WAIT_2 || cpcb->state == LAST_ACK){ + if (cpcb->state == FIN_WAIT_1 || cpcb->state == FIN_WAIT_2 || cpcb->state == LAST_ACK){ num_tcp_fin++; if (num_tcp_fin == MEMP_NUM_TCP_PCB) break; @@ -131,6 +135,8 @@ void ICACHE_FLASH_ATTR espconn_kill_oldest_pcb(void) if (num_tcp_fin == MEMP_NUM_TCP_PCB){ num_tcp_fin = 0; espconn_kill_oldest(); + } else if (cpcb == NULL){ + num_tcp_fin = 0; } } } @@ -901,7 +907,18 @@ espconn_tcp_client(struct espconn *espconn) pclient->pespconn = espconn; pclient->pespconn->state = ESPCONN_WAIT; pclient->pcommon.pcb = pcb; - tcp_bind(pcb, IP_ADDR_ANY, pclient->pespconn->proto.tcp->local_port); + tcp_bind(pcb, IP_ADDR_ANY, pclient->pespconn->proto.tcp->local_port); +#if 0 + pclient->pcommon.err = tcp_bind(pcb, IP_ADDR_ANY, pclient->pespconn->proto.tcp->local_port); + if (pclient->pcommon.err != ERR_OK){ + /*remove the node from the client's active connection list*/ + espconn_list_delete(&plink_active, pclient); + memp_free(MEMP_TCP_PCB, pcb); + os_free(pclient); + pclient = NULL; + return ERR_USE; + } +#endif /*Establish the connection*/ pclient->pcommon.err = tcp_connect(pcb, &ipaddr, pclient->pespconn->proto.tcp->remote_port, espconn_client_connect); diff --git a/app/lwip/app/espconn_udp.c b/app/lwip/app/espconn_udp.c index 8a8395cc..473e2a42 100644 --- a/app/lwip/app/espconn_udp.c +++ b/app/lwip/app/espconn_udp.c @@ -22,9 +22,17 @@ #include "lwip/app/espconn_udp.h" -//#include "net80211/ieee80211_var.h" +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + extern espconn_msg *plink_active; extern uint8 default_interface; + +enum send_opt{ + ESPCONN_SENDTO, + ESPCONN_SEND +}; static void ICACHE_FLASH_ATTR espconn_data_sentcb(struct espconn *pespconn) { if (pespconn == NULL) { @@ -36,7 +44,7 @@ static void ICACHE_FLASH_ATTR espconn_data_sentcb(struct espconn *pespconn) } } -static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg) +static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg, enum send_opt opt) { espconn_msg *psent = arg; @@ -49,7 +57,11 @@ static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg) // sys_timeout(10, espconn_data_sentcb, psent->pespconn); espconn_data_sentcb(psent->pespconn); } else { - espconn_udp_sent(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); + if (opt == ESPCONN_SEND){ + espconn_udp_sent(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); + } else { + espconn_udp_sendto(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); + } } } @@ -82,8 +94,8 @@ espconn_udp_sent(void *arg, uint8 *psent, uint16 length) return ESPCONN_ARG; } - if (TCP_MSS < length) { - datalen = TCP_MSS; + if (1470 < length) { + datalen = 1470; } else { datalen = length; } @@ -145,7 +157,9 @@ espconn_udp_sent(void *arg, uint8 *psent, uint16 length) pbuf_free(p); pudp_sent->pcommon.ptrbuf = psent + datalen; pudp_sent->pcommon.cntr = length - datalen; - espconn_data_sent(pudp_sent); + espconn_data_sent(pudp_sent, ESPCONN_SEND); + if (err > 0) + return ESPCONN_IF; return err; } else { pbuf_free(p); @@ -153,6 +167,108 @@ espconn_udp_sent(void *arg, uint8 *psent, uint16 length) } } +/****************************************************************************** + * FunctionName : espconn_udp_sendto + * Description : sent data for UDP + * Parameters : void *arg -- UDP to send + * uint8* psent -- Data to send + * uint16 length -- Length of data to send + * Returns : return espconn error code. + * - ESPCONN_OK. Successful. No error occured. + * - ESPCONN_MEM. Out of memory. + * - ESPCONN_RTE. Could not find route to destination address. + * - More errors could be returned by lower protocol layers. +*******************************************************************************/ +err_t ICACHE_FLASH_ATTR +espconn_udp_sendto(void *arg, uint8 *psent, uint16 length) +{ + espconn_msg *pudp_sent = arg; + struct udp_pcb *upcb = pudp_sent->pcommon.pcb; + struct espconn *pespconn = pudp_sent->pespconn; + struct pbuf *p, *q ,*p_temp; + struct ip_addr dst_ip; + u16_t dst_port; + u8_t *data = NULL; + u16_t cnt = 0; + u16_t datalen = 0; + u16_t i = 0; + err_t err; + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb)); + + if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) { + return ESPCONN_ARG; + } + + if (1470 < length) { + datalen = 1470; + } else { + datalen = length; + } + + p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); + + if (p != NULL) { + q = p; + + while (q != NULL) { + data = (u8_t *)q->payload; + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data)); + + for (i = 0; i < q->len; i++) { + data[i] = ((u8_t *) psent)[cnt++]; + } + + q = q->next; + } + } else { + return ESPCONN_MEM; + } + + dst_port = pespconn->proto.udp->remote_port; + IP4_ADDR(&dst_ip, pespconn->proto.udp->remote_ip[0], + pespconn->proto.udp->remote_ip[1], pespconn->proto.udp->remote_ip[2], + pespconn->proto.udp->remote_ip[3]); + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip, upcb->remote_port)); + + struct netif *sta_netif = (struct netif *)eagle_lwip_getif(0x00); + struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); + + if(wifi_get_opmode() == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) + { + if(netif_is_up(sta_netif) && netif_is_up(ap_netif) && \ + ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && \ + ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) { + + p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); + if (pbuf_copy (p_temp,p) != ERR_OK) { + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sendto: copying to new pbuf failed\n")); + return ESPCONN_ARG; + } + netif_set_default(sta_netif); + err = udp_sendto(upcb, p_temp, &dst_ip, dst_port); + pbuf_free(p_temp); + netif_set_default(ap_netif); + } + } + err = udp_sendto(upcb, p, &dst_ip, dst_port); + + if (p->ref != 0) { + pbuf_free(p); + pudp_sent->pcommon.ptrbuf = psent + datalen; + pudp_sent->pcommon.cntr = length - datalen; + if (err == ERR_OK) + espconn_data_sent(pudp_sent, ESPCONN_SENDTO); + + if (err > 0) + return ESPCONN_IF; + return err; + } else { + pbuf_free(p); + return ESPCONN_RTE; + } +} + /****************************************************************************** * FunctionName : espconn_udp_server_recv * Description : This callback will be called when receiving a datagram. @@ -175,15 +291,10 @@ espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_server_recv %d %p\n", __LINE__, upcb)); - upcb->remote_port = port; - upcb->remote_ip = *addr; - - precv->pcommon.remote_ip[0] = ip4_addr1_16(&upcb->remote_ip); - precv->pcommon.remote_ip[1] = ip4_addr2_16(&upcb->remote_ip); - precv->pcommon.remote_ip[2] = ip4_addr3_16(&upcb->remote_ip); - precv->pcommon.remote_ip[3] = ip4_addr4_16(&upcb->remote_ip); - os_memcpy(precv->pespconn->proto.udp->remote_ip, precv->pcommon.remote_ip, 4); - precv->pespconn->proto.udp->remote_port = port; + precv->pcommon.remote_ip[0] = ip4_addr1_16(addr); + precv->pcommon.remote_ip[1] = ip4_addr2_16(addr); + precv->pcommon.remote_ip[2] = ip4_addr3_16(addr); + precv->pcommon.remote_ip[3] = ip4_addr4_16(addr); precv->pcommon.remote_port = port; precv->pcommon.pcb = upcb; @@ -196,31 +307,13 @@ espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, } else { wifi_get_ip_info(0, &ipconfig); } -// upcb->local_ip = ipconfig.ip; + precv->pespconn->proto.udp->local_ip[0] = ip4_addr1_16(&ipconfig.ip); precv->pespconn->proto.udp->local_ip[1] = ip4_addr2_16(&ipconfig.ip); precv->pespconn->proto.udp->local_ip[2] = ip4_addr3_16(&ipconfig.ip); precv->pespconn->proto.udp->local_ip[3] = ip4_addr4_16(&ipconfig.ip); if (p != NULL) { -// q = p; - -// while (q != NULL) { -// pdata = (u8_t *)os_zalloc(q ->len + 1); -// length = pbuf_copy_partial(q, pdata, q ->len, 0); -// -// LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_server_recv %d %x\n", __LINE__, length)); -// precv->pcommon.pcb = upcb; -// -// if (length != 0) { -// if (precv->pespconn->recv_callback != NULL) { -// precv->pespconn->recv_callback(precv->pespconn, pdata, length); -// } -// } -// -// q = q->next; -// os_free(pdata); -// } pdata = (u8_t *)os_zalloc(p ->tot_len + 1); length = pbuf_copy_partial(p, pdata, p ->tot_len, 0); precv->pcommon.pcb = upcb; diff --git a/app/lwip/app/netio.c b/app/lwip/app/netio.c index 3aac7c59..47b35993 100644 --- a/app/lwip/app/netio.c +++ b/app/lwip/app/netio.c @@ -35,6 +35,10 @@ #if LWIP_TCP #include "lwip/tcp.h" +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + /* * This implements a netio server. * The client sends a command word (4 bytes) then a data length word (4 bytes). @@ -321,7 +325,7 @@ netio_accept(void *arg, struct tcp_pcb *pcb, err_t err) LWIP_UNUSED_ARG(err); - ns = mem_malloc(sizeof(struct netio_state)); + ns = (struct netio_state *)mem_malloc(sizeof(struct netio_state)); if(ns == NULL){ return ERR_MEM; @@ -335,7 +339,7 @@ netio_accept(void *arg, struct tcp_pcb *pcb, err_t err) #if NETIO_USE_STATIC_BUF == 1 ns->buf_ptr = netio_buf; #else - ns->buf_ptr = mem_malloc(NETIO_BUF_SIZE); + ns->buf_ptr = (u8_t *)mem_malloc(NETIO_BUF_SIZE); if(ns->buf_ptr == NULL){ mem_free(ns); diff --git a/app/lwip/app/ping.c b/app/lwip/app/ping.c index 38a85fa4..6bd6f0ea 100644 --- a/app/lwip/app/ping.c +++ b/app/lwip/app/ping.c @@ -63,6 +63,10 @@ #include "lwip/inet.h" #endif /* PING_USE_SOCKETS */ +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + /* ping variables */ static u16_t ping_seq_num = 0; static u32_t ping_time; diff --git a/app/lwip/core/dhcp.c b/app/lwip/core/dhcp.c index 73457eb2..342543ea 100644 --- a/app/lwip/core/dhcp.c +++ b/app/lwip/core/dhcp.c @@ -84,6 +84,10 @@ #include +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + /** Default for DHCP_GLOBAL_XID is 0xABCD0000 * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g. * #define DHCP_GLOBAL_XID_HEADER "stdlib.h" @@ -377,6 +381,15 @@ dhcp_fine_tmr() while (netif != NULL) { /* only act on DHCP configured interfaces */ if (netif->dhcp != NULL) { + /*add DHCP retries processing by LiuHan*/ + if (DHCP_MAXRTX != 0) { + if (netif->dhcp->tries >= DHCP_MAXRTX){ + os_printf("DHCP timeout\n"); + if (netif->dhcp_event != NULL) + netif->dhcp_event(); + break; + } + } /* timer is active (non zero), and is about to trigger now */ if (netif->dhcp->request_timeout > 1) { netif->dhcp->request_timeout--; @@ -392,6 +405,7 @@ dhcp_fine_tmr() /* proceed to next network interface */ netif = netif->next; } + } /** diff --git a/app/lwip/core/dns.c b/app/lwip/core/dns.c index e471646b..28ad5f5c 100644 --- a/app/lwip/core/dns.c +++ b/app/lwip/core/dns.c @@ -83,6 +83,10 @@ #include +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + /** DNS server IP address */ #ifndef DNS_SERVER_ADDRESS #define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, 0xDEDE43D0)) /* resolver1.opendns.com(208.67.222.222) */ diff --git a/app/lwip/core/init.c b/app/lwip/core/init.c index a0361b17..aa403f48 100644 --- a/app/lwip/core/init.c +++ b/app/lwip/core/init.c @@ -261,7 +261,7 @@ lwip_init(void) { MEMP_NUM_TCP_PCB = 5; TCP_WND = (4 * TCP_MSS); - TCP_MAXRTX = 3; + TCP_MAXRTX = 12; TCP_SYNMAXRTX = 6; /* Sanity check user-configurable values */ diff --git a/app/lwip/core/ipv4/igmp.c b/app/lwip/core/ipv4/igmp.c index b4cca192..2bb69e4d 100644 --- a/app/lwip/core/ipv4/igmp.c +++ b/app/lwip/core/ipv4/igmp.c @@ -95,6 +95,10 @@ Steve Reynolds #include "string.h" +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + /* * IGMP constants */ diff --git a/app/lwip/core/mdns.c b/app/lwip/core/mdns.c index 108a0885..a4d3c94b 100644 --- a/app/lwip/core/mdns.c +++ b/app/lwip/core/mdns.c @@ -49,6 +49,11 @@ #include "osapi.h" #include "os_type.h" #include "user_interface.h" + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + /** DNS server IP address */ #ifndef DNS_MULTICAST_ADDRESS #define DNS_MULTICAST_ADDRESS ipaddr_addr("224.0.0.251") /* resolver1.opendns.com */ @@ -971,11 +976,21 @@ mdns_get_servername(void) { void ICACHE_FLASH_ATTR mdns_server_unregister(void) { + struct ip_addr ap_host_addr; + struct ip_info ipconfig; if(register_flag == 1){ if (igmp_leavegroup(&host_addr, &multicast_addr) != ERR_OK) { - os_printf("udp_leave_multigrup failed!\n"); + os_printf("sta udp_leave_multigrup failed!\n"); return; }; + if(wifi_get_opmode() == 0x03 || wifi_get_opmode() == 0x02) { + wifi_get_ip_info(SOFTAP_IF, &ipconfig); + ap_host_addr.addr = ipconfig.ip.addr; + if (igmp_leavegroup(&ap_host_addr, &multicast_addr) != ERR_OK) { + os_printf("ap udp_join_multigrup failed!\n"); + return; + }; + } register_flag = 0; } } @@ -1013,6 +1028,8 @@ void ICACHE_FLASH_ATTR mdns_init(struct mdns_info *info) { /* initialize default DNS server address */ multicast_addr.addr = DNS_MULTICAST_ADDRESS; + struct ip_addr ap_host_addr; + struct ip_info ipconfig; if (info->ipAddr == 0) { os_printf("mdns ip error!\n "); return; @@ -1040,10 +1057,20 @@ mdns_init(struct mdns_info *info) { if (mdns_pcb != NULL) { /* join to the multicast address 224.0.0.251 */ - if (igmp_joingroup(&host_addr, &multicast_addr) != ERR_OK) { - os_printf("udp_join_multigrup failed!\n"); - return; - }; + if(wifi_get_opmode() == 0x03 || wifi_get_opmode() == 0x01) { + if (igmp_joingroup(&host_addr, &multicast_addr) != ERR_OK) { + os_printf("sta udp_join_multigrup failed!\n"); + return; + }; + } + if(wifi_get_opmode() == 0x03 || wifi_get_opmode() == 0x02) { + wifi_get_ip_info(SOFTAP_IF, &ipconfig); + ap_host_addr.addr = ipconfig.ip.addr; + if (igmp_joingroup(&ap_host_addr, &multicast_addr) != ERR_OK) { + os_printf("ap udp_join_multigrup failed!\n"); + return; + }; + } register_flag = 1; /* join to any IP address at the port 5353 */ if (udp_bind(mdns_pcb, IP_ADDR_ANY, DNS_MDNS_PORT) != ERR_OK) { diff --git a/app/lwip/core/pbuf.c b/app/lwip/core/pbuf.c index 97f1baa6..61967840 100644 --- a/app/lwip/core/pbuf.c +++ b/app/lwip/core/pbuf.c @@ -79,6 +79,10 @@ #include +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + #ifdef EBUF_LWIP #define EP_OFFSET 36 #else @@ -90,6 +94,45 @@ aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */ #define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) +/** + * Attempt to reclaim some memory from queued out-of-sequence TCP segments + * if we run out of pool pbufs. It's better to give priority to new packets + * if we're running out. + */ +#if TCP_QUEUE_OOSEQ +void ICACHE_FLASH_ATTR +pbuf_free_ooseq_new(void* arg) +{ + struct tcp_pcb* pcb; + struct tcp_seg *head = NULL; + struct tcp_seg *seg1 = NULL; + struct tcp_seg *seg2 = NULL; + for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) { + head = pcb->ooseq; + seg1 = head; + if (head != NULL) { + if (seg1->next == NULL){ + head = head->next; + tcp_seg_free(seg1); + pcb->ooseq = head; + } else { + while (seg1 != NULL){ + seg2 = seg1; + seg2 = seg2->next; + if (seg2 ->next == NULL){ + seg1->next = seg2->next; + tcp_seg_free(seg2); + break; + } + seg1 = seg1->next; + } + pcb->ooseq = head; + } + } + } +} +#endif + #if !LWIP_TCP || !TCP_QUEUE_OOSEQ || NO_SYS #define PBUF_POOL_IS_EMPTY() #else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || NO_SYS */ diff --git a/app/lwip/core/raw.c b/app/lwip/core/raw.c index 09540069..b89a4f82 100644 --- a/app/lwip/core/raw.c +++ b/app/lwip/core/raw.c @@ -52,6 +52,10 @@ #include +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + /** The list of RAW PCBs */ static struct raw_pcb *raw_pcbs; diff --git a/app/lwip/core/tcp.c b/app/lwip/core/tcp.c index 6713679e..362b3961 100644 --- a/app/lwip/core/tcp.c +++ b/app/lwip/core/tcp.c @@ -55,6 +55,10 @@ #include +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + #if TCP_DEBUG const char tcp_state_str_rodata[][12] ICACHE_RODATA_ATTR = { "CLOSED", diff --git a/app/lwip/core/tcp_in.c b/app/lwip/core/tcp_in.c index 80b02177..6ee0b58e 100644 --- a/app/lwip/core/tcp_in.c +++ b/app/lwip/core/tcp_in.c @@ -56,6 +56,10 @@ #include "lwip/snmp.h" #include "arch/perf.h" +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + /* These variables are global to all functions involved in the input processing of TCP segments. They are set by the tcp_input() function. */ @@ -436,6 +440,16 @@ aborted: pbuf_free(inseg.p);//�ͷ�buffer inseg.p = NULL; } + + /*add processing queue segments that arrive out of order by LiuHan*/ +#if TCP_QUEUE_OOSEQ + extern char RxNodeNum(void); + if (RxNodeNum() < 2){ + extern void pbuf_free_ooseq_new(void* arg); +// os_printf("reclaim some memory from queued\n"); + pbuf_free_ooseq_new(NULL); + } +#endif } else { /* If no matching PCB was found, send a TCP RST (reset) to the diff --git a/app/lwip/core/tcp_out.c b/app/lwip/core/tcp_out.c index 15867b77..e2f8e9aa 100644 --- a/app/lwip/core/tcp_out.c +++ b/app/lwip/core/tcp_out.c @@ -52,9 +52,14 @@ #include "lwip/inet_chksum.h" #include "lwip/stats.h" #include "lwip/snmp.h" +#include "netif/etharp.h" #include +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + /* Define some copy-macros for checksum-on-copy so that the code looks nicer by preventing too many ifdef's. */ #if TCP_CHECKSUM_ON_COPY @@ -226,16 +231,7 @@ tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, LWIP_UNUSED_ARG(apiflags); LWIP_UNUSED_ARG(first_seg); /* always create MSS-sized pbufs */ -#ifdef ESP_MESH_SUPPORT - if (espconn_mesh_is_on()) { - if (alloc > TCP_MSS) - alloc = TCP_MSS; - } else { - alloc = TCP_MSS; - } -#else alloc = TCP_MSS; -#endif #else /* LWIP_NETIF_TX_SINGLE_PBUF */ if (length < max_length) { /* Should we allocate an oversized pbuf, or just the minimum @@ -1451,6 +1447,7 @@ tcp_zero_window_probe(struct tcp_pcb *pcb) struct pbuf *p; struct tcp_hdr *tcphdr; struct tcp_seg *seg; + u16_t offset = 0; u16_t len; u8_t is_fin; @@ -1469,6 +1466,11 @@ tcp_zero_window_probe(struct tcp_pcb *pcb) if(seg == NULL) { seg = pcb->unsent; + } else { + struct ip_hdr *iphdr = NULL; + iphdr = (struct ip_hdr *)((char*)seg->p->payload + SIZEOF_ETH_HDR); + offset = IPH_HL(iphdr)*4; + offset += SIZEOF_ETH_HDR; } if(seg == NULL) { return; @@ -1492,7 +1494,12 @@ tcp_zero_window_probe(struct tcp_pcb *pcb) /* Data segment, copy in one byte from the head of the unacked queue */ struct tcp_hdr *thdr = (struct tcp_hdr *)seg->p->payload; char *d = ((char *)p->payload + TCP_HLEN); - pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4); + if (pcb->unacked == NULL) + pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4); + else { + thdr = (struct tcp_hdr *)((char*)seg->p->payload + offset); + pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4 + offset); + } } #if CHECKSUM_GEN_TCP diff --git a/app/lwip/core/timers.c b/app/lwip/core/timers.c index 84ba657d..e682bd2d 100644 --- a/app/lwip/core/timers.c +++ b/app/lwip/core/timers.c @@ -57,6 +57,9 @@ #include "lwip/igmp.h" #include "lwip/dns.h" +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif /** The one and only timeout list */ static struct sys_timeo *next_timeout = NULL; @@ -245,6 +248,7 @@ void sys_timeouts_init(void) sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); #endif /* LWIP_ARP */ #if LWIP_DHCP + DHCP_MAXRTX = 0; sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); #endif /* LWIP_DHCP */ @@ -259,8 +263,8 @@ void sys_timeouts_init(void) #endif /* LWIP_DNS */ #if LWIP_TCP - //sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); - sys_timeout(TCP_TMR_INTERVAL, tcp_timer_coarse, NULL); + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); +// sys_timeout(TCP_TMR_INTERVAL, tcp_timer_coarse, NULL); #endif #if NO_SYS diff --git a/app/lwip/core/udp.c b/app/lwip/core/udp.c index b43e0db8..e44d7f38 100644 --- a/app/lwip/core/udp.c +++ b/app/lwip/core/udp.c @@ -64,6 +64,10 @@ #include +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + /* The list of UDP PCBs */ /* exported in udp.h (was static) */ struct udp_pcb *udp_pcbs; diff --git a/app/lwip/netif/etharp.c b/app/lwip/netif/etharp.c index 264c1b39..7eb328ac 100644 --- a/app/lwip/netif/etharp.c +++ b/app/lwip/netif/etharp.c @@ -62,6 +62,10 @@ #include +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; const struct eth_addr ethzero = {{0,0,0,0,0,0}}; diff --git a/sdk/esp_iot_sdk_v1.4.0/include/user_interface.h b/sdk/esp_iot_sdk_v1.4.0/include/user_interface.h index 038772f8..7b134e91 100644 --- a/sdk/esp_iot_sdk_v1.4.0/include/user_interface.h +++ b/sdk/esp_iot_sdk_v1.4.0/include/user_interface.h @@ -275,6 +275,7 @@ struct station_info { }; struct dhcps_lease { + bool enable; struct ip_addr start_ip; struct ip_addr end_ip; };