Commit d77666c0 authored by sergio's avatar sergio Committed by Terry Ellison
Browse files

trailing spaces cleanup (#2659)

parent d7583040
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = liblwipapi.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = liblwipapi.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
......@@ -3,12 +3,12 @@
* Sequential API External module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
......@@ -17,21 +17,21 @@
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
......
......@@ -6,9 +6,9 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
......@@ -17,21 +17,21 @@
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
......@@ -332,7 +332,7 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
}
}
return ERR_OK;
}
......@@ -1465,7 +1465,7 @@ do_close(struct api_msg_msg *msg)
*/
void
do_join_leave_group(struct api_msg_msg *msg)
{
{
if (ERR_IS_FATAL(msg->conn->last_err)) {
msg->err = msg->conn->last_err;
} else {
......
......@@ -6,9 +6,9 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
......@@ -17,21 +17,21 @@
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
......
......@@ -3,12 +3,12 @@
* Network buffer management
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
......@@ -17,21 +17,21 @@
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
......
......@@ -5,7 +5,7 @@
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
......@@ -14,21 +14,21 @@
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*
* Author: Simon Goldschmidt
*
*/
......@@ -257,7 +257,7 @@ lwip_freeaddrinfo(struct addrinfo *ai)
*
* @param nodename descriptive name or address string of the host
* (may be NULL -> local address)
* @param servname port number as string of NULL
* @param servname port number as string of NULL
* @param hints structure containing input values that set socktype and protocol
* @param res pointer to a pointer where to store the result (set to NULL on failure)
* @return 0 on success, non-zero on failure
......
......@@ -5,7 +5,7 @@
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
......@@ -14,21 +14,21 @@
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*
*/
#include "lwip/opt.h"
......
......@@ -75,7 +75,7 @@ struct lwip_sock {
tested by select */
u16_t sendevent;
/** error happened for this socket, set by event_callback(), tested by select */
u16_t errevent;
u16_t errevent;
/** last error that occurred on this socket */
int err;
/** counter of how many threads are waiting for this socket using select */
......@@ -572,7 +572,7 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
buf = sock->lastdata;
} else {
/* If this is non-blocking call, then check first */
if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) &&
if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) &&
(sock->rcvevent <= 0)) {
if (off > 0) {
/* update receive window */
......@@ -644,9 +644,9 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
if (netconn_type(sock->conn) == NETCONN_TCP) {
LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen);
len -= copylen;
if ( (len <= 0) ||
(p->flags & PBUF_FLAG_PUSH) ||
(sock->rcvevent <= 0) ||
if ( (len <= 0) ||
(p->flags & PBUF_FLAG_PUSH) ||
(sock->rcvevent <= 0) ||
((flags & MSG_PEEK)!=0)) {
done = 1;
}
......@@ -868,7 +868,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
#endif /* LWIP_UDP */
}
UNLOCK_TCPIP_CORE();
pbuf_free(p);
} else {
err = ERR_MEM;
......@@ -1452,11 +1452,11 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
/* Do length and type checks for the various options first, to keep it readable. */
switch (level) {
/* Level: SOL_SOCKET */
case SOL_SOCKET:
switch (optname) {
case SO_ACCEPTCONN:
case SO_BROADCAST:
/* UNIMPL case SO_DEBUG: */
......@@ -1505,7 +1505,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = ENOPROTOOPT;
} /* switch (optname) */
break;
/* Level: IPPROTO_IP */
case IPPROTO_IP:
switch (optname) {
......@@ -1545,7 +1545,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = ENOPROTOOPT;
} /* switch (optname) */
break;
#if LWIP_TCP
/* Level: IPPROTO_TCP */
case IPPROTO_TCP:
......@@ -1553,7 +1553,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = EINVAL;
break;
}
/* If this is no TCP socket, ignore any options. */
if (sock->conn->type != NETCONN_TCP)
return 0;
......@@ -1567,7 +1567,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
case TCP_KEEPCNT:
#endif /* LWIP_TCP_KEEPALIVE */
break;
default:
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
s, optname));
......@@ -1582,7 +1582,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = EINVAL;
break;
}
/* If this is no UDP lite socket, ignore any options. */
if (sock->conn->type != NETCONN_UDPLITE) {
return 0;
......@@ -1592,7 +1592,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
case UDPLITE_SEND_CSCOV:
case UDPLITE_RECV_CSCOV:
break;
default:
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
s, optname));
......@@ -1607,7 +1607,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = ENOPROTOOPT;
} /* switch */
if (err != ERR_OK) {
sock_set_errno(sock, err);
return -1;
......@@ -1702,7 +1702,7 @@ lwip_getsockopt_internal(void *arg)
/* only overwrite ERR_OK or tempoary errors */
if ((sock->err == 0) || (sock->err == EINPROGRESS)) {
sock_set_errno(sock, err_to_errno(sock->conn->last_err));
}
}
*(int *)optval = sock->err;
sock->err = 0;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n",
......
......@@ -305,7 +305,7 @@ tcpip_apimsg(struct api_msg *apimsg)
/* catch functions that don't set err */
apimsg->msg.err = ERR_VAL;
#endif
if (sys_mbox_valid(&mbox)) {//内核邮箱有效
msg.type = TCPIP_MSG_API;
msg.msg.apimsg = apimsg;
......@@ -355,14 +355,14 @@ err_t
tcpip_netifapi(struct netifapi_msg* netifapimsg)
{
struct tcpip_msg msg;
if (sys_mbox_valid(&mbox)) {
err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
if (err != ERR_OK) {
netifapimsg->msg.err = err;
return err;
}
msg.type = TCPIP_MSG_NETIFAPI;
msg.msg.netifapimsg = netifapimsg;
sys_mbox_post(&mbox, &msg);
......@@ -384,7 +384,7 @@ tcpip_netifapi(struct netifapi_msg* netifapimsg)
err_t
tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
{
LOCK_TCPIP_CORE();
LOCK_TCPIP_CORE();
netifapimsg->function(&(netifapimsg->msg));
UNLOCK_TCPIP_CORE();
return netifapimsg->msg.err;
......
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = liblwipapp.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = liblwipapp.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
#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 "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 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
void wifi_softap_dhcps_client_leave(u8 *bssid, struct ip_addr *ip,bool force);
uint32 wifi_softap_dhcps_client_update(u8 *bssid, struct ip_addr *ip);
/******************************************************************************
* 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;
pdelete->pnext = NULL;
} else {
while (plist != NULL) {
if (plist->pnext == pdelete){
plist->pnext = pdelete->pnext;
pdelete->pnext = NULL;
}
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 = client_address.addr;
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));
//For xiaomi crash bug
uint32 magic_cookie1 = magic_cookie;
os_memcpy((char *) m->options, &magic_cookie1, sizeof(magic_cookie1));
}
struct pbuf * dhcps_pbuf_alloc(u16_t len)
{
u16_t mlen = sizeof(struct dhcps_msg);
if (len > mlen) {
#if DHCPS_DEBUG
DHCPS_LOG("dhcps: len=%d mlen=%d", len, mlen);
#endif
mlen = len;
}
return pbuf_alloc(PBUF_TRANSPORT, mlen, PBUF_RAM);
}
///////////////////////////////////////////////////////////////////////////////////
/*
* ����һ��OFFER
*
* @param -- m ָ����Ҫ���͵�DHCP msg����
*/
///////////////////////////////////////////////////////////////////////////////////
static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m, u16_t len)
{
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 = dhcps_pbuf_alloc(len);
#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; i<q->len; i++)
{
data[i] = ((u8_t *) m)[cnt++];
}
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, u16_t len)
{
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 = dhcps_pbuf_alloc(len);
#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; i<q->len; i++)
{
data[i] = ((u8_t *) m)[cnt++];
}
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, u16_t len)
{
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 = dhcps_pbuf_alloc(len);
#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; i<q->len; i++)
{
data[i] = ((u8_t *) m)[cnt++];
}
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
//os_printf("dhcps:0x%08x,0x%08x\n",client.addr,*(uint32*)(optptr+2));
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)
{
if(os_memcmp((char *)m->options,
&magic_cookie,
sizeof(magic_cookie)) == 0){
struct ip_addr ip;
os_memcpy(&ip.addr,m->ciaddr,sizeof(ip.addr));
client_address.addr = wifi_softap_dhcps_client_update(m->chaddr,&ip);
sint16_t ret = parse_options(&m->options[4], len);
if(ret == DHCPS_STATE_RELEASE) {
wifi_softap_dhcps_client_leave(m->chaddr,&ip,TRUE); // force to delete
client_address.addr = ip.addr;
}
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, malloc_len;
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;
malloc_len = sizeof(struct dhcps_msg);
#if DHCPS_DEBUG
DHCPS_LOG("dhcps: handle_dhcp malloc_len=%d rx_len=%d", malloc_len, p->tot_len);
#endif
if (malloc_len < p->tot_len) {
malloc_len = p->tot_len;
}
pmsg_dhcps = (struct dhcps_msg *)os_malloc(malloc_len);
if (NULL == pmsg_dhcps){
pbuf_free(p);
return;
}
memset(pmsg_dhcps , 0x00 , malloc_len);
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; i<p->len; i++){
p_dhcps_msg[dhcps_msg_cnt++] = data[i];
}
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; i<p->next->len; i++){
p_dhcps_msg[dhcps_msg_cnt++] = data[i];
}
}
/*
* 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, malloc_len);
break;
case DHCPS_STATE_ACK://3
#if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n");
#endif
send_ack(pmsg_dhcps, malloc_len);
wifi_softap_set_station_info(pmsg_dhcps->chaddr, &client_address.addr);
break;
case DHCPS_STATE_NAK://4
#if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n");
#endif
send_nak(pmsg_dhcps, malloc_len);
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);
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;
struct dhcps_pool* dhcp_node = NULL;
struct ip_addr ip_zero;
os_memset(&ip_zero,0x0,sizeof(ip_zero));
pnode = plist;
while (pnode != NULL) {
pback_node = pnode;
pnode = pback_node->pnext;
node_remove_from_list(&plist, pback_node);
dhcp_node = (struct dhcps_pool*)pback_node->pnode;
//wifi_softap_dhcps_client_leave(dhcp_node->mac,&dhcp_node->ip,TRUE); // force to delete
wifi_softap_set_station_info(dhcp_node->mac, &ip_zero);
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;
if ( pdhcps_pool->type == DHCPS_TYPE_DYNAMIC) {
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;
}
void ICACHE_FLASH_ATTR wifi_softap_dhcps_client_leave(u8 *bssid, struct ip_addr *ip,bool force)
{
struct dhcps_pool *pdhcps_pool = NULL;
list_node *pback_node = NULL;
if ((bssid == NULL) || (ip == NULL)) {
return;
}
for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
pdhcps_pool = pback_node->pnode;
if (os_memcmp(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)) == 0){
if (os_memcmp(&pdhcps_pool->ip.addr, &ip->addr, sizeof(pdhcps_pool->ip.addr)) == 0) {
if ((pdhcps_pool->type == DHCPS_TYPE_STATIC) || (force)) {
if(pback_node != NULL) {
node_remove_from_list(&plist,pback_node);
os_free(pback_node);
pback_node = NULL;
}
if (pdhcps_pool != NULL) {
os_free(pdhcps_pool);
pdhcps_pool = NULL;
}
} else {
pdhcps_pool->state = DHCPS_STATE_OFFLINE;
}
struct ip_addr ip_zero;
os_memset(&ip_zero,0x0,sizeof(ip_zero));
wifi_softap_set_station_info(bssid, &ip_zero);
break;
}
}
}
}
uint32 ICACHE_FLASH_ATTR wifi_softap_dhcps_client_update(u8 *bssid, struct ip_addr *ip)
{
struct dhcps_pool *pdhcps_pool = NULL;
list_node *pback_node = NULL;
list_node *pmac_node = NULL;
list_node *pip_node = NULL;
bool flag = FALSE;
uint32 start_ip = dhcps_lease.start_ip.addr;
uint32 end_ip = dhcps_lease.end_ip.addr;
dhcps_type_t type = DHCPS_TYPE_DYNAMIC;
if (bssid == NULL) {
return IPADDR_ANY;
}
if (ip) {
if (IPADDR_BROADCAST == ip->addr) {
return IPADDR_ANY;
} else if (IPADDR_ANY == ip->addr) {
ip = NULL;
} else {
type = DHCPS_TYPE_STATIC;
}
}
renew = FALSE;
for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
pdhcps_pool = pback_node->pnode;
//os_printf("mac:"MACSTR"bssid:"MACSTR"\r\n",MAC2STR(pdhcps_pool->mac),MAC2STR(bssid));
if (os_memcmp(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)) == 0){
pmac_node = pback_node;
if (ip == NULL) {
flag = TRUE;
break;
}
}
if (ip != NULL) {
if (os_memcmp(&pdhcps_pool->ip.addr, &ip->addr, sizeof(pdhcps_pool->ip.addr)) == 0) {
pip_node = pback_node;
}
} else if (flag == FALSE){
if (os_memcmp(&pdhcps_pool->ip.addr, &start_ip, sizeof(pdhcps_pool->ip.addr)) != 0) {
flag = TRUE;
} else {
start_ip = htonl((ntohl(start_ip) + 1));
}
}
}
if ((ip == NULL) && (flag == FALSE)) {
if (plist == NULL) {
if (start_ip <= end_ip) {
flag = TRUE;
} else {
return IPADDR_ANY;
}
} else {
if (start_ip > end_ip) {
return IPADDR_ANY;
}
//start_ip = htonl((ntohl(start_ip) + 1));
flag = TRUE;
}
}
if (pmac_node != NULL) { // update new ip
if (pip_node != NULL){
pdhcps_pool = pip_node->pnode;
if (pip_node != pmac_node) {
if(pdhcps_pool->state != DHCPS_STATE_OFFLINE) { // ip is used
return IPADDR_ANY;
}
// mac exists and ip exists in other node,delete mac
node_remove_from_list(&plist,pmac_node);
os_free(pmac_node->pnode);
pmac_node->pnode = NULL;
os_free(pmac_node);
pmac_node = pip_node;
os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
} else {
renew = true;
type = DHCPS_TYPE_DYNAMIC;
}
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE;
} else {
pdhcps_pool = pmac_node->pnode;
if (ip != NULL) {
pdhcps_pool->ip.addr = ip->addr;
} else if (flag == TRUE) {
pdhcps_pool->ip.addr = start_ip;
} else { // no ip to distribute
return IPADDR_ANY;
}
node_remove_from_list(&plist,pmac_node);
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE;
node_insert_to_list(&plist,pmac_node);
}
} else { // new station
if (pip_node != NULL) { // maybe ip has used
pdhcps_pool = pip_node->pnode;
if (pdhcps_pool->state != DHCPS_STATE_OFFLINE) {
return IPADDR_ANY;
}
os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE;
} else {
pdhcps_pool = (struct dhcps_pool *)os_zalloc(sizeof(struct dhcps_pool));
if (ip != NULL) {
pdhcps_pool->ip.addr = ip->addr;
} else if (flag == TRUE) {
pdhcps_pool->ip.addr = start_ip;
} else { // no ip to distribute
os_free(pdhcps_pool);
return IPADDR_ANY;
}
if (pdhcps_pool->ip.addr > end_ip) {
os_free(pdhcps_pool);
return IPADDR_ANY;
}
os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE;
pback_node = (list_node *)os_zalloc(sizeof(list_node ));
pback_node->pnode = pdhcps_pool;
pback_node->pnext = NULL;
node_insert_to_list(&plist,pback_node);
}
}
return pdhcps_pool->ip.addr;
}
#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 "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 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
void wifi_softap_dhcps_client_leave(u8 *bssid, struct ip_addr *ip,bool force);
uint32 wifi_softap_dhcps_client_update(u8 *bssid, struct ip_addr *ip);
/******************************************************************************
* 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;
pdelete->pnext = NULL;
} else {
while (plist != NULL) {
if (plist->pnext == pdelete){
plist->pnext = pdelete->pnext;
pdelete->pnext = NULL;
}
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 = client_address.addr;
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));
//For xiaomi crash bug
uint32 magic_cookie1 = magic_cookie;
os_memcpy((char *) m->options, &magic_cookie1, sizeof(magic_cookie1));
}
struct pbuf * dhcps_pbuf_alloc(u16_t len)
{
u16_t mlen = sizeof(struct dhcps_msg);
if (len > mlen) {
#if DHCPS_DEBUG
DHCPS_LOG("dhcps: len=%d mlen=%d", len, mlen);
#endif
mlen = len;
}
return pbuf_alloc(PBUF_TRANSPORT, mlen, PBUF_RAM);
}
///////////////////////////////////////////////////////////////////////////////////
/*
* ����һ��OFFER
*
* @param -- m ָ����Ҫ���͵�DHCP msg����
*/
///////////////////////////////////////////////////////////////////////////////////
static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m, u16_t len)
{
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 = dhcps_pbuf_alloc(len);
#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; i<q->len; i++)
{
data[i] = ((u8_t *) m)[cnt++];
}
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, u16_t len)
{
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 = dhcps_pbuf_alloc(len);
#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; i<q->len; i++)
{
data[i] = ((u8_t *) m)[cnt++];
}
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, u16_t len)
{
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 = dhcps_pbuf_alloc(len);
#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; i<q->len; i++)
{
data[i] = ((u8_t *) m)[cnt++];
}
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
//os_printf("dhcps:0x%08x,0x%08x\n",client.addr,*(uint32*)(optptr+2));
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)
{
if(os_memcmp((char *)m->options,
&magic_cookie,
sizeof(magic_cookie)) == 0){
struct ip_addr ip;
os_memcpy(&ip.addr,m->ciaddr,sizeof(ip.addr));
client_address.addr = wifi_softap_dhcps_client_update(m->chaddr,&ip);
sint16_t ret = parse_options(&m->options[4], len);
if(ret == DHCPS_STATE_RELEASE) {
wifi_softap_dhcps_client_leave(m->chaddr,&ip,TRUE); // force to delete
client_address.addr = ip.addr;
}
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, malloc_len;
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;
malloc_len = sizeof(struct dhcps_msg);
#if DHCPS_DEBUG
DHCPS_LOG("dhcps: handle_dhcp malloc_len=%d rx_len=%d", malloc_len, p->tot_len);
#endif
if (malloc_len < p->tot_len) {
malloc_len = p->tot_len;
}
pmsg_dhcps = (struct dhcps_msg *)os_malloc(malloc_len);
if (NULL == pmsg_dhcps){
pbuf_free(p);
return;
}
memset(pmsg_dhcps , 0x00 , malloc_len);
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; i<p->len; i++){
p_dhcps_msg[dhcps_msg_cnt++] = data[i];
}
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; i<p->next->len; i++){
p_dhcps_msg[dhcps_msg_cnt++] = data[i];
}
}
/*
* 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, malloc_len);
break;
case DHCPS_STATE_ACK://3
#if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n");
#endif
send_ack(pmsg_dhcps, malloc_len);
wifi_softap_set_station_info(pmsg_dhcps->chaddr, &client_address.addr);
break;
case DHCPS_STATE_NAK://4
#if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n");
#endif
send_nak(pmsg_dhcps, malloc_len);
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);
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;
struct dhcps_pool* dhcp_node = NULL;
struct ip_addr ip_zero;
os_memset(&ip_zero,0x0,sizeof(ip_zero));
pnode = plist;
while (pnode != NULL) {
pback_node = pnode;
pnode = pback_node->pnext;
node_remove_from_list(&plist, pback_node);
dhcp_node = (struct dhcps_pool*)pback_node->pnode;
//wifi_softap_dhcps_client_leave(dhcp_node->mac,&dhcp_node->ip,TRUE); // force to delete
wifi_softap_set_station_info(dhcp_node->mac, &ip_zero);
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;
if ( pdhcps_pool->type == DHCPS_TYPE_DYNAMIC) {
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;
}
void ICACHE_FLASH_ATTR wifi_softap_dhcps_client_leave(u8 *bssid, struct ip_addr *ip,bool force)
{
struct dhcps_pool *pdhcps_pool = NULL;
list_node *pback_node = NULL;
if ((bssid == NULL) || (ip == NULL)) {
return;
}
for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
pdhcps_pool = pback_node->pnode;
if (os_memcmp(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)) == 0){
if (os_memcmp(&pdhcps_pool->ip.addr, &ip->addr, sizeof(pdhcps_pool->ip.addr)) == 0) {
if ((pdhcps_pool->type == DHCPS_TYPE_STATIC) || (force)) {
if(pback_node != NULL) {
node_remove_from_list(&plist,pback_node);
os_free(pback_node);
pback_node = NULL;
}
if (pdhcps_pool != NULL) {
os_free(pdhcps_pool);
pdhcps_pool = NULL;
}
} else {
pdhcps_pool->state = DHCPS_STATE_OFFLINE;
}
struct ip_addr ip_zero;
os_memset(&ip_zero,0x0,sizeof(ip_zero));
wifi_softap_set_station_info(bssid, &ip_zero);
break;
}
}
}
}
uint32 ICACHE_FLASH_ATTR wifi_softap_dhcps_client_update(u8 *bssid, struct ip_addr *ip)
{
struct dhcps_pool *pdhcps_pool = NULL;
list_node *pback_node = NULL;
list_node *pmac_node = NULL;
list_node *pip_node = NULL;
bool flag = FALSE;
uint32 start_ip = dhcps_lease.start_ip.addr;
uint32 end_ip = dhcps_lease.end_ip.addr;
dhcps_type_t type = DHCPS_TYPE_DYNAMIC;
if (bssid == NULL) {
return IPADDR_ANY;
}
if (ip) {
if (IPADDR_BROADCAST == ip->addr) {
return IPADDR_ANY;
} else if (IPADDR_ANY == ip->addr) {
ip = NULL;
} else {
type = DHCPS_TYPE_STATIC;
}
}
renew = FALSE;
for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
pdhcps_pool = pback_node->pnode;
//os_printf("mac:"MACSTR"bssid:"MACSTR"\r\n",MAC2STR(pdhcps_pool->mac),MAC2STR(bssid));
if (os_memcmp(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)) == 0){
pmac_node = pback_node;
if (ip == NULL) {
flag = TRUE;
break;
}
}
if (ip != NULL) {
if (os_memcmp(&pdhcps_pool->ip.addr, &ip->addr, sizeof(pdhcps_pool->ip.addr)) == 0) {
pip_node = pback_node;
}
} else if (flag == FALSE){
if (os_memcmp(&pdhcps_pool->ip.addr, &start_ip, sizeof(pdhcps_pool->ip.addr)) != 0) {
flag = TRUE;
} else {
start_ip = htonl((ntohl(start_ip) + 1));
}
}
}
if ((ip == NULL) && (flag == FALSE)) {
if (plist == NULL) {
if (start_ip <= end_ip) {
flag = TRUE;
} else {
return IPADDR_ANY;
}
} else {
if (start_ip > end_ip) {
return IPADDR_ANY;
}
//start_ip = htonl((ntohl(start_ip) + 1));
flag = TRUE;
}
}
if (pmac_node != NULL) { // update new ip
if (pip_node != NULL){
pdhcps_pool = pip_node->pnode;
if (pip_node != pmac_node) {
if(pdhcps_pool->state != DHCPS_STATE_OFFLINE) { // ip is used
return IPADDR_ANY;
}
// mac exists and ip exists in other node,delete mac
node_remove_from_list(&plist,pmac_node);
os_free(pmac_node->pnode);
pmac_node->pnode = NULL;
os_free(pmac_node);
pmac_node = pip_node;
os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
} else {
renew = true;
type = DHCPS_TYPE_DYNAMIC;
}
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE;
} else {
pdhcps_pool = pmac_node->pnode;
if (ip != NULL) {
pdhcps_pool->ip.addr = ip->addr;
} else if (flag == TRUE) {
pdhcps_pool->ip.addr = start_ip;
} else { // no ip to distribute
return IPADDR_ANY;
}
node_remove_from_list(&plist,pmac_node);
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE;
node_insert_to_list(&plist,pmac_node);
}
} else { // new station
if (pip_node != NULL) { // maybe ip has used
pdhcps_pool = pip_node->pnode;
if (pdhcps_pool->state != DHCPS_STATE_OFFLINE) {
return IPADDR_ANY;
}
os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE;
} else {
pdhcps_pool = (struct dhcps_pool *)os_zalloc(sizeof(struct dhcps_pool));
if (ip != NULL) {
pdhcps_pool->ip.addr = ip->addr;
} else if (flag == TRUE) {
pdhcps_pool->ip.addr = start_ip;
} else { // no ip to distribute
os_free(pdhcps_pool);
return IPADDR_ANY;
}
if (pdhcps_pool->ip.addr > end_ip) {
os_free(pdhcps_pool);
return IPADDR_ANY;
}
os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE;
pback_node = (list_node *)os_zalloc(sizeof(list_node ));
pback_node->pnode = pdhcps_pool;
pback_node->pnext = NULL;
node_insert_to_list(&plist,pback_node);
}
}
return pdhcps_pool->ip.addr;
}
......@@ -370,7 +370,7 @@ espconn_sent(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;
}
......@@ -1315,7 +1315,7 @@ espconn_port(void)
* Description : Resolve a hostname (string) into an IP address.
* Parameters : pespconn -- espconn to resolve a hostname
* hostname -- the hostname that is to be queried
* addr -- pointer to a ip_addr_t where to store the address if
* addr -- pointer to a ip_addr_t where to store the address if
* it is already cached in the dns_table (only valid if
* ESPCONN_OK is returned!)
* found -- a callback function to be called on success, failure
......
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: espconn_udp.c
*
* Description: udp proto interface
*
* Modification history:
* 2014/3/31, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "os_type.h"
//#include "os.h"
#include "lwip/inet.h"
#include "lwip/err.h"
#include "lwip/pbuf.h"
#include "lwip/mem.h"
#include "lwip/tcp_impl.h"
#include "lwip/udp.h"
#include "lwip/app/espconn_udp.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) {
return;
}
if (pespconn->sent_callback != NULL) {
pespconn->sent_callback(pespconn);
}
}
static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg, enum send_opt opt)
{
espconn_msg *psent = arg;
if (psent == NULL) {
return;
}
if (psent->pcommon.cntr == 0) {
psent->pespconn->state = ESPCONN_CONNECT;
if (psent->pcommon.err == 0)
espconn_data_sentcb(psent->pespconn);
} else {
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);
}
}
}
/******************************************************************************
* FunctionName : espconn_udp_sent
* Description : sent data for client or server
* Parameters : void *arg -- client or server 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_sent(void *arg, uint8 *psent, uint16 length)
{
espconn_msg *pudp_sent = arg;
struct udp_pcb *upcb = pudp_sent->pcommon.pcb;
struct pbuf *p, *q ,*p_temp;
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 ((IP_FRAG_MAX_MTU - 20 - 8) < length) {
datalen = IP_FRAG_MAX_MTU - 20 - 8;
} 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;
}
upcb->remote_port = pudp_sent->pespconn->proto.udp->remote_port;
IP4_ADDR(&upcb->remote_ip, pudp_sent->pespconn->proto.udp->remote_ip[0],
pudp_sent->pespconn->proto.udp->remote_ip[1],
pudp_sent->pespconn->proto.udp->remote_ip[2],
pudp_sent->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_sent: copying to new pbuf failed\n"));
return ESPCONN_ARG;
}
netif_set_default(sta_netif);
err = udp_send(upcb, p_temp);
pbuf_free(p_temp);
netif_set_default(ap_netif);
}
}
err = udp_send(upcb, p);
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d\n", __LINE__, err));
if (p->ref != 0) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p));
pbuf_free(p);
pudp_sent->pcommon.ptrbuf = psent + datalen;
pudp_sent->pcommon.cntr = length - datalen;
pudp_sent->pcommon.err = err;
espconn_data_sent(pudp_sent, ESPCONN_SEND);
if (err > 0)
return ESPCONN_IF;
return err;
} else {
pbuf_free(p);
return ESPCONN_RTE;
}
}
/******************************************************************************
* 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 ((IP_FRAG_MAX_MTU - 20 - 8) < length) {
datalen = IP_FRAG_MAX_MTU - 20 - 8;
} 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(&dst_ip, sta_netif) && \
ip_addr_isbroadcast(&dst_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;
pudp_sent->pcommon.err = err;
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.
* Parameters : arg -- user supplied argument
* upcb -- the udp_pcb which received data
* p -- the packet buffer that was received
* addr -- the remote IP address from which the packet was received
* port -- the remote port from which the packet was received
* Returns : none
*******************************************************************************/
static void ICACHE_FLASH_ATTR
espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p,
struct ip_addr *addr, u16_t port)
{
espconn_msg *precv = arg;
struct pbuf *q = NULL;
u8_t *pdata = NULL;
u16_t length = 0;
struct ip_info ipconfig;
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_server_recv %d %p\n", __LINE__, upcb));
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;
if (wifi_get_opmode() != 1) {
wifi_get_ip_info(1, &ipconfig);
if (!ip_addr_netcmp(addr, &ipconfig.ip, &ipconfig.netmask)) {
wifi_get_ip_info(0, &ipconfig);
}
} else {
wifi_get_ip_info(0, &ipconfig);
}
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) {
pdata = (u8_t *)os_zalloc(p ->tot_len + 1);
length = pbuf_copy_partial(p, pdata, p ->tot_len, 0);
precv->pcommon.pcb = upcb;
pbuf_free(p);
if (length != 0) {
if (precv->pespconn->recv_callback != NULL) {
precv->pespconn->recv_callback(precv->pespconn, pdata, length);
}
}
os_free(pdata);
} else {
return;
}
}
/******************************************************************************
* FunctionName : espconn_udp_disconnect
* Description : A new incoming connection has been disconnected.
* Parameters : espconn -- the espconn used to disconnect with host
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR espconn_udp_disconnect(espconn_msg *pdiscon)
{
if (pdiscon == NULL) {
return;
}
struct udp_pcb *upcb = pdiscon->pcommon.pcb;
udp_disconnect(upcb);
udp_remove(upcb);
espconn_list_delete(&plink_active, pdiscon);
os_free(pdiscon);
pdiscon = NULL;
}
/******************************************************************************
* FunctionName : espconn_udp_server
* Description : Initialize the server: set up a PCB and bind it to the port
* Parameters : pespconn -- the espconn used to build server
* Returns : none
*******************************************************************************/
sint8 ICACHE_FLASH_ATTR
espconn_udp_server(struct espconn *pespconn)
{
struct udp_pcb *upcb = NULL;
espconn_msg *pserver = NULL;
upcb = udp_new();
if (upcb == NULL) {
return ESPCONN_MEM;
} else {
pserver = (espconn_msg *)os_zalloc(sizeof(espconn_msg));
if (pserver == NULL) {
udp_remove(upcb);
return ESPCONN_MEM;
}
pserver->pcommon.pcb = upcb;
pserver->pespconn = pespconn;
espconn_list_creat(&plink_active, pserver);
udp_bind(upcb, IP_ADDR_ANY, pserver->pespconn->proto.udp->local_port);
udp_recv(upcb, espconn_udp_recv, (void *)pserver);
return ESPCONN_OK;
}
}
/******************************************************************************
* FunctionName : espconn_igmp_leave
* Description : leave a multicast group
* Parameters : host_ip -- the ip address of udp server
* multicast_ip -- multicast ip given by user
* Returns : none
*******************************************************************************/
sint8 ICACHE_FLASH_ATTR
espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip)
{
if (igmp_leavegroup(host_ip, multicast_ip) != ERR_OK) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_leave_multigrup failed!\n"));
return -1;
};
return ESPCONN_OK;
}
/******************************************************************************
* FunctionName : espconn_igmp_join
* Description : join a multicast group
* Parameters : host_ip -- the ip address of udp server
* multicast_ip -- multicast ip given by user
* Returns : none
*******************************************************************************/
sint8 ICACHE_FLASH_ATTR
espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip)
{
if (igmp_joingroup(host_ip, multicast_ip) != ERR_OK) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_join_multigrup failed!\n"));
return -1;
};
/* join to any IP address at the port */
return ESPCONN_OK;
}
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: espconn_udp.c
*
* Description: udp proto interface
*
* Modification history:
* 2014/3/31, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "os_type.h"
//#include "os.h"
#include "lwip/inet.h"
#include "lwip/err.h"
#include "lwip/pbuf.h"
#include "lwip/mem.h"
#include "lwip/tcp_impl.h"
#include "lwip/udp.h"
#include "lwip/app/espconn_udp.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) {
return;
}
if (pespconn->sent_callback != NULL) {
pespconn->sent_callback(pespconn);
}
}
static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg, enum send_opt opt)
{
espconn_msg *psent = arg;
if (psent == NULL) {
return;
}
if (psent->pcommon.cntr == 0) {
psent->pespconn->state = ESPCONN_CONNECT;
if (psent->pcommon.err == 0)
espconn_data_sentcb(psent->pespconn);
} else {
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);
}
}
}
/******************************************************************************
* FunctionName : espconn_udp_sent
* Description : sent data for client or server
* Parameters : void *arg -- client or server 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_sent(void *arg, uint8 *psent, uint16 length)
{
espconn_msg *pudp_sent = arg;
struct udp_pcb *upcb = pudp_sent->pcommon.pcb;
struct pbuf *p, *q ,*p_temp;
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 ((IP_FRAG_MAX_MTU - 20 - 8) < length) {
datalen = IP_FRAG_MAX_MTU - 20 - 8;
} 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;
}
upcb->remote_port = pudp_sent->pespconn->proto.udp->remote_port;
IP4_ADDR(&upcb->remote_ip, pudp_sent->pespconn->proto.udp->remote_ip[0],
pudp_sent->pespconn->proto.udp->remote_ip[1],
pudp_sent->pespconn->proto.udp->remote_ip[2],
pudp_sent->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_sent: copying to new pbuf failed\n"));
return ESPCONN_ARG;
}
netif_set_default(sta_netif);
err = udp_send(upcb, p_temp);
pbuf_free(p_temp);
netif_set_default(ap_netif);
}
}
err = udp_send(upcb, p);
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d\n", __LINE__, err));
if (p->ref != 0) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p));
pbuf_free(p);
pudp_sent->pcommon.ptrbuf = psent + datalen;
pudp_sent->pcommon.cntr = length - datalen;
pudp_sent->pcommon.err = err;
espconn_data_sent(pudp_sent, ESPCONN_SEND);
if (err > 0)
return ESPCONN_IF;
return err;
} else {
pbuf_free(p);
return ESPCONN_RTE;
}
}
/******************************************************************************
* 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 ((IP_FRAG_MAX_MTU - 20 - 8) < length) {
datalen = IP_FRAG_MAX_MTU - 20 - 8;
} 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(&dst_ip, sta_netif) && \
ip_addr_isbroadcast(&dst_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;
pudp_sent->pcommon.err = err;
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.
* Parameters : arg -- user supplied argument
* upcb -- the udp_pcb which received data
* p -- the packet buffer that was received
* addr -- the remote IP address from which the packet was received
* port -- the remote port from which the packet was received
* Returns : none
*******************************************************************************/
static void ICACHE_FLASH_ATTR
espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p,
struct ip_addr *addr, u16_t port)
{
espconn_msg *precv = arg;
struct pbuf *q = NULL;
u8_t *pdata = NULL;
u16_t length = 0;
struct ip_info ipconfig;
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_server_recv %d %p\n", __LINE__, upcb));
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;
if (wifi_get_opmode() != 1) {
wifi_get_ip_info(1, &ipconfig);
if (!ip_addr_netcmp(addr, &ipconfig.ip, &ipconfig.netmask)) {
wifi_get_ip_info(0, &ipconfig);
}
} else {
wifi_get_ip_info(0, &ipconfig);
}
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) {
pdata = (u8_t *)os_zalloc(p ->tot_len + 1);
length = pbuf_copy_partial(p, pdata, p ->tot_len, 0);
precv->pcommon.pcb = upcb;
pbuf_free(p);
if (length != 0) {
if (precv->pespconn->recv_callback != NULL) {
precv->pespconn->recv_callback(precv->pespconn, pdata, length);
}
}
os_free(pdata);
} else {
return;
}
}
/******************************************************************************
* FunctionName : espconn_udp_disconnect
* Description : A new incoming connection has been disconnected.
* Parameters : espconn -- the espconn used to disconnect with host
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR espconn_udp_disconnect(espconn_msg *pdiscon)
{
if (pdiscon == NULL) {
return;
}
struct udp_pcb *upcb = pdiscon->pcommon.pcb;
udp_disconnect(upcb);
udp_remove(upcb);
espconn_list_delete(&plink_active, pdiscon);
os_free(pdiscon);
pdiscon = NULL;
}
/******************************************************************************
* FunctionName : espconn_udp_server
* Description : Initialize the server: set up a PCB and bind it to the port
* Parameters : pespconn -- the espconn used to build server
* Returns : none
*******************************************************************************/
sint8 ICACHE_FLASH_ATTR
espconn_udp_server(struct espconn *pespconn)
{
struct udp_pcb *upcb = NULL;
espconn_msg *pserver = NULL;
upcb = udp_new();
if (upcb == NULL) {
return ESPCONN_MEM;
} else {
pserver = (espconn_msg *)os_zalloc(sizeof(espconn_msg));
if (pserver == NULL) {
udp_remove(upcb);
return ESPCONN_MEM;
}
pserver->pcommon.pcb = upcb;
pserver->pespconn = pespconn;
espconn_list_creat(&plink_active, pserver);
udp_bind(upcb, IP_ADDR_ANY, pserver->pespconn->proto.udp->local_port);
udp_recv(upcb, espconn_udp_recv, (void *)pserver);
return ESPCONN_OK;
}
}
/******************************************************************************
* FunctionName : espconn_igmp_leave
* Description : leave a multicast group
* Parameters : host_ip -- the ip address of udp server
* multicast_ip -- multicast ip given by user
* Returns : none
*******************************************************************************/
sint8 ICACHE_FLASH_ATTR
espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip)
{
if (igmp_leavegroup(host_ip, multicast_ip) != ERR_OK) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_leave_multigrup failed!\n"));
return -1;
};
return ESPCONN_OK;
}
/******************************************************************************
* FunctionName : espconn_igmp_join
* Description : join a multicast group
* Parameters : host_ip -- the ip address of udp server
* multicast_ip -- multicast ip given by user
* Returns : none
*******************************************************************************/
sint8 ICACHE_FLASH_ATTR
espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip)
{
if (igmp_joingroup(host_ip, multicast_ip) != ERR_OK) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_join_multigrup failed!\n"));
return -1;
};
/* join to any IP address at the port */
return ESPCONN_OK;
}
/**
* @file
* MetIO Server
*
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#include "lwip/opt.h"
#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).
* If the command is "receive", the server is to consume "data length" bytes into
* a circular buffer until the first byte is non-zero, then it is to consume
* another command/data pair.
* If the command is "send", the server is to send "data length" bytes from a circular
* buffer with the first byte being zero, until "some time" (6 seconds in the
* current netio126.zip download) has passed and then send one final buffer with
* the first byte being non-zero. Then it is to consume another command/data pair.
*/
/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */
/* implementation options */
#define NETIO_BUF_SIZE (4 * 1024)
#define NETIO_USE_STATIC_BUF 0
/* NetIO server state definition */
#define NETIO_STATE_WAIT_FOR_CMD 0
#define NETIO_STATE_RECV_DATA 1
#define NETIO_STATE_SEND_DATA 2
#define NETIO_STATE_SEND_DATA_LAST 3
#define NETIO_STATE_DONE 4
struct netio_state {
u32_t state;
u32_t cmd;
u32_t data_len;
u32_t cntr;
u8_t * buf_ptr;
u32_t buf_pos;
u32_t first_byte;
u32_t time_stamp;
};
/* NetIO command protocol definition */
#define NETIO_CMD_QUIT 0
#define NETIO_CMD_C2S 1
#define NETIO_CMD_S2C 2
#define NETIO_CMD_RES 3
static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
static void ICACHE_FLASH_ATTR
netio_close(void *arg, struct tcp_pcb *pcb)
{
err_t err;
struct netio_state *ns = arg;
ns->state = NETIO_STATE_DONE;
tcp_recv(pcb, NULL);
err = tcp_close(pcb);
if (err != ERR_OK) {
/* closing failed, try again later */
tcp_recv(pcb, netio_recv);
} else {
/* closing succeeded */
#if NETIO_USE_STATIC_BUF != 1
if(ns->buf_ptr != NULL){
mem_free(ns->buf_ptr);
}
#endif
tcp_arg(pcb, NULL);
tcp_poll(pcb, NULL, 0);
tcp_sent(pcb, NULL);
if (arg != NULL) {
mem_free(arg);
}
}
}
static err_t ICACHE_FLASH_ATTR
netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
struct netio_state *ns = arg;
u8_t * data_ptr;
u32_t data_cntr;
struct pbuf *q = p;
u16_t len;
if (p != NULL) {
tcp_recved(pcb, p->tot_len);
}
if (err == ERR_OK && q != NULL) {
while (q != NULL) {
data_cntr = q->len;
data_ptr = q->payload;
while (data_cntr--) {
if (ns->state == NETIO_STATE_DONE){
netio_close(ns, pcb);
break;
} else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) {
if (ns->cntr < 4) {
/* build up the CMD field */
ns->cmd <<= 8;
ns->cmd |= *data_ptr++;
ns->cntr++;
} else if (ns->cntr < 8) {
/* build up the DATA field */
ns->data_len <<= 8;
ns->data_len |= *data_ptr++;
ns->cntr++;
if (ns->cntr == 8) {
/* now we have full command and data words */
ns->cntr = 0;
ns->buf_pos = 0;
ns->buf_ptr[0] = 0;
if (ns->cmd == NETIO_CMD_C2S) {
ns->state = NETIO_STATE_RECV_DATA;
} else if (ns->cmd == NETIO_CMD_S2C) {
ns->state = NETIO_STATE_SEND_DATA;
/* start timer */
ns->time_stamp = sys_now();
/* send first round of data */
len = tcp_sndbuf(pcb);
len = LWIP_MIN(len, ns->data_len - ns->cntr);
len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
do {
err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
if (err == ERR_MEM) {
len /= 2;
}
} while ((err == ERR_MEM) && (len > 1));
ns->buf_pos += len;
ns->cntr += len;
} else {
/* unrecognized command, punt */
ns->cntr = 0;
ns->buf_pos = 0;
ns->buf_ptr[0] = 0;
netio_close(ns, pcb);
break;
}
}
} else {
/* in trouble... shouldn't be in this state! */
}
} else if (ns->state == NETIO_STATE_RECV_DATA) {
if(ns->cntr == 0){
/* save the first byte of this new round of data
* this will not match ns->buf_ptr[0] in the case that
* NETIO_BUF_SIZE is less than ns->data_len.
*/
ns->first_byte = *data_ptr;
}
ns->buf_ptr[ns->buf_pos++] = *data_ptr++;
ns->cntr++;
if (ns->buf_pos == NETIO_BUF_SIZE) {
/* circularize the buffer */
ns->buf_pos = 0;
}
if(ns->cntr == ns->data_len){
ns->cntr = 0;
if (ns->first_byte != 0) {
/* if this last round did not start with 0,
* go look for another command */
ns->state = NETIO_STATE_WAIT_FOR_CMD;
ns->data_len = 0;
ns->cmd = 0;
/* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
} else {
/* stay here and wait on more data */
}
}
} else if (ns->state == NETIO_STATE_SEND_DATA
|| ns->state == NETIO_STATE_SEND_DATA_LAST) {
/* I don't think this should happen... */
} else {
/* done / quit */
netio_close(ns, pcb);
break;
} /* end of ns->state condition */
} /* end of while data still in this pbuf */
q = q->next;
}
pbuf_free(p);
} else {
/* error or closed by other side */
if (p != NULL) {
pbuf_free(p);
}
/* close the connection */
netio_close(ns, pcb);
}
return ERR_OK;
}
static err_t ICACHE_FLASH_ATTR
netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
struct netio_state *ns = arg;
err_t err = ERR_OK;
if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) {
/* done with this round of sending */
ns->buf_pos = 0;
ns->cntr = 0;
/* check if timer expired */
if (sys_now() - ns->time_stamp > 600) {
ns->buf_ptr[0] = 1;
ns->state = NETIO_STATE_SEND_DATA_LAST;
} else {
ns->buf_ptr[0] = 0;
}
}
if(ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA){
len = tcp_sndbuf(pcb);
len = LWIP_MIN(len, ns->data_len - ns->cntr);
len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
if(ns->cntr < ns->data_len){
do {
err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
if (err == ERR_MEM) {
len /= 2;
}
} while ((err == ERR_MEM) && (len > 1));
ns->buf_pos += len;
if(ns->buf_pos >= NETIO_BUF_SIZE){
ns->buf_pos = 0;
}
ns->cntr += len;
}
}
if(ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA_LAST){
/* we have buffered up all our data to send this last round, go look for a command */
ns->state = NETIO_STATE_WAIT_FOR_CMD;
ns->cntr = 0;
/* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
}
return ERR_OK;
}
static err_t ICACHE_FLASH_ATTR
netio_poll(void *arg, struct tcp_pcb *pcb)
{
struct netio_state * ns = arg;
if(ns->state == NETIO_STATE_SEND_DATA){
} else if(ns->state == NETIO_STATE_DONE){
netio_close(ns, pcb);
}
return ERR_OK;
}
#if NETIO_USE_STATIC_BUF == 1
static u8_t netio_buf[NETIO_BUF_SIZE];
#endif
static err_t ICACHE_FLASH_ATTR
netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct netio_state * ns;
LWIP_UNUSED_ARG(err);
ns = (struct netio_state *)mem_malloc(sizeof(struct netio_state));
if(ns == NULL){
return ERR_MEM;
}
ns->state = NETIO_STATE_WAIT_FOR_CMD;
ns->data_len = 0;
ns->cmd = 0;
ns->cntr = 0;
ns->buf_pos = 0;
#if NETIO_USE_STATIC_BUF == 1
ns->buf_ptr = netio_buf;
#else
ns->buf_ptr = (u8_t *)mem_malloc(NETIO_BUF_SIZE);
if(ns->buf_ptr == NULL){
mem_free(ns);
return ERR_MEM;
}
#endif
ns->buf_ptr[0] = 0;
tcp_arg(pcb, ns);
tcp_sent(pcb, netio_sent);
tcp_recv(pcb, netio_recv);
tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */
return ERR_OK;
}
void ICACHE_FLASH_ATTR netio_init(void)
{
struct tcp_pcb *pcb;
pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, 18767);
pcb = tcp_listen(pcb);
tcp_accept(pcb, netio_accept);
}
#endif /* LWIP_TCP */
/**
* @file
* MetIO Server
*
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#include "lwip/opt.h"
#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).
* If the command is "receive", the server is to consume "data length" bytes into
* a circular buffer until the first byte is non-zero, then it is to consume
* another command/data pair.
* If the command is "send", the server is to send "data length" bytes from a circular
* buffer with the first byte being zero, until "some time" (6 seconds in the
* current netio126.zip download) has passed and then send one final buffer with
* the first byte being non-zero. Then it is to consume another command/data pair.
*/
/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */
/* implementation options */
#define NETIO_BUF_SIZE (4 * 1024)
#define NETIO_USE_STATIC_BUF 0
/* NetIO server state definition */
#define NETIO_STATE_WAIT_FOR_CMD 0
#define NETIO_STATE_RECV_DATA 1
#define NETIO_STATE_SEND_DATA 2
#define NETIO_STATE_SEND_DATA_LAST 3
#define NETIO_STATE_DONE 4
struct netio_state {
u32_t state;
u32_t cmd;
u32_t data_len;
u32_t cntr;
u8_t * buf_ptr;
u32_t buf_pos;
u32_t first_byte;
u32_t time_stamp;
};
/* NetIO command protocol definition */
#define NETIO_CMD_QUIT 0
#define NETIO_CMD_C2S 1
#define NETIO_CMD_S2C 2
#define NETIO_CMD_RES 3
static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
static void ICACHE_FLASH_ATTR
netio_close(void *arg, struct tcp_pcb *pcb)
{
err_t err;
struct netio_state *ns = arg;
ns->state = NETIO_STATE_DONE;
tcp_recv(pcb, NULL);
err = tcp_close(pcb);
if (err != ERR_OK) {
/* closing failed, try again later */
tcp_recv(pcb, netio_recv);
} else {
/* closing succeeded */
#if NETIO_USE_STATIC_BUF != 1
if(ns->buf_ptr != NULL){
mem_free(ns->buf_ptr);
}
#endif
tcp_arg(pcb, NULL);
tcp_poll(pcb, NULL, 0);
tcp_sent(pcb, NULL);
if (arg != NULL) {
mem_free(arg);
}
}
}
static err_t ICACHE_FLASH_ATTR
netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
struct netio_state *ns = arg;
u8_t * data_ptr;
u32_t data_cntr;
struct pbuf *q = p;
u16_t len;
if (p != NULL) {
tcp_recved(pcb, p->tot_len);
}
if (err == ERR_OK && q != NULL) {
while (q != NULL) {
data_cntr = q->len;
data_ptr = q->payload;
while (data_cntr--) {
if (ns->state == NETIO_STATE_DONE){
netio_close(ns, pcb);
break;
} else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) {
if (ns->cntr < 4) {
/* build up the CMD field */
ns->cmd <<= 8;
ns->cmd |= *data_ptr++;
ns->cntr++;
} else if (ns->cntr < 8) {
/* build up the DATA field */
ns->data_len <<= 8;
ns->data_len |= *data_ptr++;
ns->cntr++;
if (ns->cntr == 8) {
/* now we have full command and data words */
ns->cntr = 0;
ns->buf_pos = 0;
ns->buf_ptr[0] = 0;
if (ns->cmd == NETIO_CMD_C2S) {
ns->state = NETIO_STATE_RECV_DATA;
} else if (ns->cmd == NETIO_CMD_S2C) {
ns->state = NETIO_STATE_SEND_DATA;
/* start timer */
ns->time_stamp = sys_now();
/* send first round of data */
len = tcp_sndbuf(pcb);
len = LWIP_MIN(len, ns->data_len - ns->cntr);
len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
do {
err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
if (err == ERR_MEM) {
len /= 2;
}
} while ((err == ERR_MEM) && (len > 1));
ns->buf_pos += len;
ns->cntr += len;
} else {
/* unrecognized command, punt */
ns->cntr = 0;
ns->buf_pos = 0;
ns->buf_ptr[0] = 0;
netio_close(ns, pcb);
break;
}
}
} else {
/* in trouble... shouldn't be in this state! */
}
} else if (ns->state == NETIO_STATE_RECV_DATA) {
if(ns->cntr == 0){
/* save the first byte of this new round of data
* this will not match ns->buf_ptr[0] in the case that
* NETIO_BUF_SIZE is less than ns->data_len.
*/
ns->first_byte = *data_ptr;
}
ns->buf_ptr[ns->buf_pos++] = *data_ptr++;
ns->cntr++;
if (ns->buf_pos == NETIO_BUF_SIZE) {
/* circularize the buffer */
ns->buf_pos = 0;
}
if(ns->cntr == ns->data_len){
ns->cntr = 0;
if (ns->first_byte != 0) {
/* if this last round did not start with 0,
* go look for another command */
ns->state = NETIO_STATE_WAIT_FOR_CMD;
ns->data_len = 0;
ns->cmd = 0;
/* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
} else {
/* stay here and wait on more data */
}
}
} else if (ns->state == NETIO_STATE_SEND_DATA
|| ns->state == NETIO_STATE_SEND_DATA_LAST) {
/* I don't think this should happen... */
} else {
/* done / quit */
netio_close(ns, pcb);
break;
} /* end of ns->state condition */
} /* end of while data still in this pbuf */
q = q->next;
}
pbuf_free(p);
} else {
/* error or closed by other side */
if (p != NULL) {
pbuf_free(p);
}
/* close the connection */
netio_close(ns, pcb);
}
return ERR_OK;
}
static err_t ICACHE_FLASH_ATTR
netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
struct netio_state *ns = arg;
err_t err = ERR_OK;
if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) {
/* done with this round of sending */
ns->buf_pos = 0;
ns->cntr = 0;
/* check if timer expired */
if (sys_now() - ns->time_stamp > 600) {
ns->buf_ptr[0] = 1;
ns->state = NETIO_STATE_SEND_DATA_LAST;
} else {
ns->buf_ptr[0] = 0;
}
}
if(ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA){
len = tcp_sndbuf(pcb);
len = LWIP_MIN(len, ns->data_len - ns->cntr);
len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
if(ns->cntr < ns->data_len){
do {
err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
if (err == ERR_MEM) {
len /= 2;
}
} while ((err == ERR_MEM) && (len > 1));
ns->buf_pos += len;
if(ns->buf_pos >= NETIO_BUF_SIZE){
ns->buf_pos = 0;
}
ns->cntr += len;
}
}
if(ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA_LAST){
/* we have buffered up all our data to send this last round, go look for a command */
ns->state = NETIO_STATE_WAIT_FOR_CMD;
ns->cntr = 0;
/* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
}
return ERR_OK;
}
static err_t ICACHE_FLASH_ATTR
netio_poll(void *arg, struct tcp_pcb *pcb)
{
struct netio_state * ns = arg;
if(ns->state == NETIO_STATE_SEND_DATA){
} else if(ns->state == NETIO_STATE_DONE){
netio_close(ns, pcb);
}
return ERR_OK;
}
#if NETIO_USE_STATIC_BUF == 1
static u8_t netio_buf[NETIO_BUF_SIZE];
#endif
static err_t ICACHE_FLASH_ATTR
netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct netio_state * ns;
LWIP_UNUSED_ARG(err);
ns = (struct netio_state *)mem_malloc(sizeof(struct netio_state));
if(ns == NULL){
return ERR_MEM;
}
ns->state = NETIO_STATE_WAIT_FOR_CMD;
ns->data_len = 0;
ns->cmd = 0;
ns->cntr = 0;
ns->buf_pos = 0;
#if NETIO_USE_STATIC_BUF == 1
ns->buf_ptr = netio_buf;
#else
ns->buf_ptr = (u8_t *)mem_malloc(NETIO_BUF_SIZE);
if(ns->buf_ptr == NULL){
mem_free(ns);
return ERR_MEM;
}
#endif
ns->buf_ptr[0] = 0;
tcp_arg(pcb, ns);
tcp_sent(pcb, netio_sent);
tcp_recv(pcb, netio_recv);
tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */
return ERR_OK;
}
void ICACHE_FLASH_ATTR netio_init(void)
{
struct tcp_pcb *pcb;
pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, 18767);
pcb = tcp_listen(pcb);
tcp_accept(pcb, netio_accept);
}
#endif /* LWIP_TCP */
......@@ -5,7 +5,7 @@
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
......@@ -14,24 +14,24 @@
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*
*/
/**
/**
* This is an example of a "ping" sender (with raw API and socket API).
* It can be used as a start point to maintain opened a network connection, or
* like a network "watchdog" for your device.
......
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = liblwipcore.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = liblwipcore.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
......@@ -44,7 +44,7 @@
* Again with the aim of being simple, correct and fully portable.
* Byte swapping is the second thing you would want to optimize. You will
* need to port it to your architecture and in your cc.h:
*
*
* #define LWIP_PLATFORM_BYTESWAP 1
* #define LWIP_PLATFORM_HTONS(x) <your_htons>
* #define LWIP_PLATFORM_HTONL(x) <your_htonl>
......
......@@ -187,14 +187,14 @@ static void ICACHE_FLASH_ATTR
dhcp_handle_nak(struct netif *netif)
{
struct dhcp *dhcp = netif->dhcp;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n",
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n",
(void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
/* Set the interface down since the address must no longer be used, as per RFC2131 */
netif_set_down(netif);
/* remove IP address from interface */
netif_set_ipaddr(netif, IP_ADDR_ANY);
netif_set_gw(netif, IP_ADDR_ANY);
netif_set_netmask(netif, IP_ADDR_ANY);
netif_set_netmask(netif, IP_ADDR_ANY);
/* Change to a defined state */
dhcp_set_state(dhcp, DHCP_BACKING_OFF);
/* We can immediately restart discovery */
......@@ -390,7 +390,7 @@ dhcp_fine_tmr()
break;
}
}
/* timer is active (non zero), and is about to trigger now */
/* timer is active (non zero), and is about to trigger now */
if (netif->dhcp->request_timeout > 1) {
netif->dhcp->request_timeout--;
}
......@@ -582,7 +582,7 @@ dhcp_handle_ack(struct netif *netif)
if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) {
ip4_addr_set_u32(&dhcp->offered_gw_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER)));
}
#if LWIP_DNS
/* DNS servers */
n = 0;
......@@ -687,7 +687,7 @@ dhcp_start(struct netif *netif)
LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL);
LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL );
}
/* clear data structure */
os_memset(dhcp, 0, sizeof(struct dhcp));
/* dhcp_set_state(&dhcp, DHCP_OFF); */
......@@ -1254,7 +1254,7 @@ dhcp_release(struct netif *netif)
ip_addr_set_zero(&dhcp->offered_si_addr);
#endif /* LWIP_DHCP_BOOTP_FILE */
dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
/* create and initialize the DHCP message header */
result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE);
if (result == ERR_OK) {
......@@ -1278,7 +1278,7 @@ dhcp_release(struct netif *netif)
netif_set_ipaddr(netif, IP_ADDR_ANY);
netif_set_gw(netif, IP_ADDR_ANY);
netif_set_netmask(netif, IP_ADDR_ANY);
return result;
}
......
......@@ -49,13 +49,13 @@
* The lwIP version of the resolver also adds a non-blocking version of
* gethostbyname() that will work with a raw API application. This function
* checks for an IP address string first and converts it if it is valid.
* gethostbyname() then does a dns_lookup() to see if the name is
* already in the table. If so, the IP is returned. If not, a query is
* gethostbyname() then does a dns_lookup() to see if the name is
* already in the table. If so, the IP is returned. If not, a query is
* issued and the function returns with a ERR_INPROGRESS status. The app
* using the dns client must then go into a waiting state.
*
* Once a hostname has been resolved (or found to be non-existent),
* the resolver code calls a specified callback function (which
* the resolver code calls a specified callback function (which
* must be implemented by the module that uses the resolver).
*/
......@@ -238,7 +238,7 @@ dns_init()
ip_addr_t dnsserver;
// dns_payload = (u8_t *)LWIP_MEM_ALIGN(dns_payload_buffer);
/* initialize default DNS server address */
DNS_SERVER_ADDRESS(&dnsserver);
......@@ -660,7 +660,7 @@ dns_check_entry(u8_t i)
pEntry->numdns = 0;
pEntry->tmr = 1;
pEntry->retries = 0;
/* send DNS packet for this entry */
err = dns_send(pEntry->numdns, pEntry->name, i);
if (err != ERR_OK) {
......@@ -773,7 +773,7 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t
goto memerr;
}
/* copy dns payload inside static buffer for processing */
/* copy dns payload inside static buffer for processing */
if (pbuf_copy_partial(p, dns_payload, p->tot_len, 0) == p->tot_len) {
/* The ID in the DNS header should be our entry into the name table. */
hdr = (struct dns_hdr*)dns_payload;
......
......@@ -6,9 +6,9 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
......@@ -17,21 +17,21 @@
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
......@@ -280,35 +280,35 @@ lwip_init(void)
pbuf_init();
netif_init();
#if LWIP_SOCKET
lwip_socket_init();
#endif /* LWIP_SOCKET */
ip_init();
#if LWIP_ARP
etharp_init();
#endif /* LWIP_ARP */
#if LWIP_RAW
raw_init();
#endif /* LWIP_RAW */
#if LWIP_UDP
udp_init();
#endif /* LWIP_UDP */
#if LWIP_TCP
tcp_init();
#endif /* LWIP_TCP */
#if LWIP_SNMP
snmp_init();
#endif /* LWIP_SNMP */
#if LWIP_AUTOIP
autoip_init();
#endif /* LWIP_AUTOIP */
#if LWIP_IGMP
igmp_init();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment