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 # Required variables for each makefile
# Discard this section from all parent makefiles # Discard this section from all parent makefiles
# Expected variables (with automatic defaults): # Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir) # CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile) # SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated () # GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated () # GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form # COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into # subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a () # a generated lib/image xxx.a ()
# #
ifndef PDIR ifndef PDIR
GEN_LIBS = liblwipapi.a GEN_LIBS = liblwipapi.a
endif endif
############################################################# #############################################################
# Configuration i.e. compile options etc. # Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here! # Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the # Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden # makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein # for a subtree within the makefile rooted therein
# #
#DEFINES += #DEFINES +=
############################################################# #############################################################
# Recursion Magic - Don't touch this!! # Recursion Magic - Don't touch this!!
# #
# Each subtree potentially has an include directory # Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules # corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH # rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up # of a module can only contain the include directories up
# its parent path, and not its siblings # its parent path, and not its siblings
# #
# Required for each makefile to inherit from the parent # Required for each makefile to inherit from the parent
# #
INCLUDES := $(INCLUDES) -I $(PDIR)include INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./ INCLUDES += -I ./
PDIR := ../$(PDIR) PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile sinclude $(PDIR)Makefile
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
* Sequential API External module * Sequential API External module
* *
*/ */
/* /*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved. * All rights reserved.
* *
* 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: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
...@@ -17,21 +17,21 @@ ...@@ -17,21 +17,21 @@
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of the lwIP TCP/IP stack. * This file is part of the lwIP TCP/IP stack.
* *
* Author: Adam Dunkels <adam@sics.se> * Author: Adam Dunkels <adam@sics.se>
* *
*/ */
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
/* /*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved. * All rights reserved.
* *
* 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: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
...@@ -17,21 +17,21 @@ ...@@ -17,21 +17,21 @@
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of the lwIP TCP/IP stack. * This file is part of the lwIP TCP/IP stack.
* *
* Author: Adam Dunkels <adam@sics.se> * Author: Adam Dunkels <adam@sics.se>
* *
*/ */
...@@ -332,7 +332,7 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) ...@@ -332,7 +332,7 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
} }
} }
return ERR_OK; return ERR_OK;
} }
...@@ -1465,7 +1465,7 @@ do_close(struct api_msg_msg *msg) ...@@ -1465,7 +1465,7 @@ do_close(struct api_msg_msg *msg)
*/ */
void void
do_join_leave_group(struct api_msg_msg *msg) do_join_leave_group(struct api_msg_msg *msg)
{ {
if (ERR_IS_FATAL(msg->conn->last_err)) { if (ERR_IS_FATAL(msg->conn->last_err)) {
msg->err = msg->conn->last_err; msg->err = msg->conn->last_err;
} else { } else {
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
/* /*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved. * All rights reserved.
* *
* 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: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
...@@ -17,21 +17,21 @@ ...@@ -17,21 +17,21 @@
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of the lwIP TCP/IP stack. * This file is part of the lwIP TCP/IP stack.
* *
* Author: Adam Dunkels <adam@sics.se> * Author: Adam Dunkels <adam@sics.se>
* *
*/ */
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
* Network buffer management * Network buffer management
* *
*/ */
/* /*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved. * All rights reserved.
* *
* 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: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
...@@ -17,21 +17,21 @@ ...@@ -17,21 +17,21 @@
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of the lwIP TCP/IP stack. * This file is part of the lwIP TCP/IP stack.
* *
* Author: Adam Dunkels <adam@sics.se> * Author: Adam Dunkels <adam@sics.se>
* *
*/ */
......
...@@ -5,7 +5,7 @@ ...@@ -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: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
...@@ -14,21 +14,21 @@ ...@@ -14,21 +14,21 @@
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of the lwIP TCP/IP stack. * This file is part of the lwIP TCP/IP stack.
* *
* Author: Simon Goldschmidt * Author: Simon Goldschmidt
* *
*/ */
...@@ -257,7 +257,7 @@ lwip_freeaddrinfo(struct addrinfo *ai) ...@@ -257,7 +257,7 @@ lwip_freeaddrinfo(struct addrinfo *ai)
* *
* @param nodename descriptive name or address string of the host * @param nodename descriptive name or address string of the host
* (may be NULL -> local address) * (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 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) * @param res pointer to a pointer where to store the result (set to NULL on failure)
* @return 0 on success, non-zero on failure * @return 0 on success, non-zero on failure
......
...@@ -5,7 +5,7 @@ ...@@ -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: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
...@@ -14,21 +14,21 @@ ...@@ -14,21 +14,21 @@
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of the lwIP TCP/IP stack. * This file is part of the lwIP TCP/IP stack.
* *
*/ */
#include "lwip/opt.h" #include "lwip/opt.h"
......
...@@ -75,7 +75,7 @@ struct lwip_sock { ...@@ -75,7 +75,7 @@ struct lwip_sock {
tested by select */ tested by select */
u16_t sendevent; u16_t sendevent;
/** error happened for this socket, set by event_callback(), tested by select */ /** 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 */ /** last error that occurred on this socket */
int err; int err;
/** counter of how many threads are waiting for this socket using select */ /** 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, ...@@ -572,7 +572,7 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
buf = sock->lastdata; buf = sock->lastdata;
} else { } else {
/* If this is non-blocking call, then check first */ /* 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)) { (sock->rcvevent <= 0)) {
if (off > 0) { if (off > 0) {
/* update receive window */ /* update receive window */
...@@ -644,9 +644,9 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, ...@@ -644,9 +644,9 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
if (netconn_type(sock->conn) == NETCONN_TCP) { if (netconn_type(sock->conn) == NETCONN_TCP) {
LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen); LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen);
len -= copylen; len -= copylen;
if ( (len <= 0) || if ( (len <= 0) ||
(p->flags & PBUF_FLAG_PUSH) || (p->flags & PBUF_FLAG_PUSH) ||
(sock->rcvevent <= 0) || (sock->rcvevent <= 0) ||
((flags & MSG_PEEK)!=0)) { ((flags & MSG_PEEK)!=0)) {
done = 1; done = 1;
} }
...@@ -868,7 +868,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, ...@@ -868,7 +868,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
#endif /* LWIP_UDP */ #endif /* LWIP_UDP */
} }
UNLOCK_TCPIP_CORE(); UNLOCK_TCPIP_CORE();
pbuf_free(p); pbuf_free(p);
} else { } else {
err = ERR_MEM; err = ERR_MEM;
...@@ -1452,11 +1452,11 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ...@@ -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. */ /* Do length and type checks for the various options first, to keep it readable. */
switch (level) { switch (level) {
/* Level: SOL_SOCKET */ /* Level: SOL_SOCKET */
case SOL_SOCKET: case SOL_SOCKET:
switch (optname) { switch (optname) {
case SO_ACCEPTCONN: case SO_ACCEPTCONN:
case SO_BROADCAST: case SO_BROADCAST:
/* UNIMPL case SO_DEBUG: */ /* UNIMPL case SO_DEBUG: */
...@@ -1505,7 +1505,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ...@@ -1505,7 +1505,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = ENOPROTOOPT; err = ENOPROTOOPT;
} /* switch (optname) */ } /* switch (optname) */
break; break;
/* Level: IPPROTO_IP */ /* Level: IPPROTO_IP */
case IPPROTO_IP: case IPPROTO_IP:
switch (optname) { switch (optname) {
...@@ -1545,7 +1545,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ...@@ -1545,7 +1545,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = ENOPROTOOPT; err = ENOPROTOOPT;
} /* switch (optname) */ } /* switch (optname) */
break; break;
#if LWIP_TCP #if LWIP_TCP
/* Level: IPPROTO_TCP */ /* Level: IPPROTO_TCP */
case IPPROTO_TCP: case IPPROTO_TCP:
...@@ -1553,7 +1553,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ...@@ -1553,7 +1553,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = EINVAL; err = EINVAL;
break; break;
} }
/* If this is no TCP socket, ignore any options. */ /* If this is no TCP socket, ignore any options. */
if (sock->conn->type != NETCONN_TCP) if (sock->conn->type != NETCONN_TCP)
return 0; return 0;
...@@ -1567,7 +1567,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ...@@ -1567,7 +1567,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
case TCP_KEEPCNT: case TCP_KEEPCNT:
#endif /* LWIP_TCP_KEEPALIVE */ #endif /* LWIP_TCP_KEEPALIVE */
break; break;
default: default:
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
s, optname)); s, optname));
...@@ -1582,7 +1582,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ...@@ -1582,7 +1582,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = EINVAL; err = EINVAL;
break; break;
} }
/* If this is no UDP lite socket, ignore any options. */ /* If this is no UDP lite socket, ignore any options. */
if (sock->conn->type != NETCONN_UDPLITE) { if (sock->conn->type != NETCONN_UDPLITE) {
return 0; return 0;
...@@ -1592,7 +1592,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ...@@ -1592,7 +1592,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
case UDPLITE_SEND_CSCOV: case UDPLITE_SEND_CSCOV:
case UDPLITE_RECV_CSCOV: case UDPLITE_RECV_CSCOV:
break; break;
default: default:
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
s, optname)); s, optname));
...@@ -1607,7 +1607,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ...@@ -1607,7 +1607,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = ENOPROTOOPT; err = ENOPROTOOPT;
} /* switch */ } /* switch */
if (err != ERR_OK) { if (err != ERR_OK) {
sock_set_errno(sock, err); sock_set_errno(sock, err);
return -1; return -1;
...@@ -1702,7 +1702,7 @@ lwip_getsockopt_internal(void *arg) ...@@ -1702,7 +1702,7 @@ lwip_getsockopt_internal(void *arg)
/* only overwrite ERR_OK or tempoary errors */ /* only overwrite ERR_OK or tempoary errors */
if ((sock->err == 0) || (sock->err == EINPROGRESS)) { if ((sock->err == 0) || (sock->err == EINPROGRESS)) {
sock_set_errno(sock, err_to_errno(sock->conn->last_err)); sock_set_errno(sock, err_to_errno(sock->conn->last_err));
} }
*(int *)optval = sock->err; *(int *)optval = sock->err;
sock->err = 0; sock->err = 0;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n",
......
...@@ -305,7 +305,7 @@ tcpip_apimsg(struct api_msg *apimsg) ...@@ -305,7 +305,7 @@ tcpip_apimsg(struct api_msg *apimsg)
/* catch functions that don't set err */ /* catch functions that don't set err */
apimsg->msg.err = ERR_VAL; apimsg->msg.err = ERR_VAL;
#endif #endif
if (sys_mbox_valid(&mbox)) {//内核邮箱有效 if (sys_mbox_valid(&mbox)) {//内核邮箱有效
msg.type = TCPIP_MSG_API; msg.type = TCPIP_MSG_API;
msg.msg.apimsg = apimsg; msg.msg.apimsg = apimsg;
...@@ -355,14 +355,14 @@ err_t ...@@ -355,14 +355,14 @@ err_t
tcpip_netifapi(struct netifapi_msg* netifapimsg) tcpip_netifapi(struct netifapi_msg* netifapimsg)
{ {
struct tcpip_msg msg; struct tcpip_msg msg;
if (sys_mbox_valid(&mbox)) { if (sys_mbox_valid(&mbox)) {
err_t err = sys_sem_new(&netifapimsg->msg.sem, 0); err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
if (err != ERR_OK) { if (err != ERR_OK) {
netifapimsg->msg.err = err; netifapimsg->msg.err = err;
return err; return err;
} }
msg.type = TCPIP_MSG_NETIFAPI; msg.type = TCPIP_MSG_NETIFAPI;
msg.msg.netifapimsg = netifapimsg; msg.msg.netifapimsg = netifapimsg;
sys_mbox_post(&mbox, &msg); sys_mbox_post(&mbox, &msg);
...@@ -384,7 +384,7 @@ tcpip_netifapi(struct netifapi_msg* netifapimsg) ...@@ -384,7 +384,7 @@ tcpip_netifapi(struct netifapi_msg* netifapimsg)
err_t err_t
tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
{ {
LOCK_TCPIP_CORE(); LOCK_TCPIP_CORE();
netifapimsg->function(&(netifapimsg->msg)); netifapimsg->function(&(netifapimsg->msg));
UNLOCK_TCPIP_CORE(); UNLOCK_TCPIP_CORE();
return netifapimsg->msg.err; return netifapimsg->msg.err;
......
############################################################# #############################################################
# Required variables for each makefile # Required variables for each makefile
# Discard this section from all parent makefiles # Discard this section from all parent makefiles
# Expected variables (with automatic defaults): # Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir) # CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile) # SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated () # GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated () # GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form # COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into # subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a () # a generated lib/image xxx.a ()
# #
ifndef PDIR ifndef PDIR
GEN_LIBS = liblwipapp.a GEN_LIBS = liblwipapp.a
endif endif
############################################################# #############################################################
# Configuration i.e. compile options etc. # Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here! # Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the # Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden # makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein # for a subtree within the makefile rooted therein
# #
#DEFINES += #DEFINES +=
############################################################# #############################################################
# Recursion Magic - Don't touch this!! # Recursion Magic - Don't touch this!!
# #
# Each subtree potentially has an include directory # Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules # corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH # rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up # of a module can only contain the include directories up
# its parent path, and not its siblings # its parent path, and not its siblings
# #
# Required for each makefile to inherit from the parent # Required for each makefile to inherit from the parent
# #
INCLUDES := $(INCLUDES) -I $(PDIR)include INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./ INCLUDES += -I ./
PDIR := ../$(PDIR) PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile sinclude $(PDIR)Makefile
#include "lwip/inet.h" #include "lwip/inet.h"
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/pbuf.h" #include "lwip/pbuf.h"
#include "lwip/udp.h" #include "lwip/udp.h"
#include "lwip/mem.h" #include "lwip/mem.h"
//#include "crypto/common.h" //#include "crypto/common.h"
#include "osapi.h" #include "osapi.h"
#include "lwip/app/dhcpserver.h" #include "lwip/app/dhcpserver.h"
#ifndef LWIP_OPEN_SRC #ifndef LWIP_OPEN_SRC
#include "net80211/ieee80211_var.h" #include "net80211/ieee80211_var.h"
#endif #endif
#include "user_interface.h" #include "user_interface.h"
#ifdef MEMLEAK_DEBUG #ifdef MEMLEAK_DEBUG
static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
#endif #endif
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
//static const uint8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; //static const uint8_t xid[4] = {0xad, 0xde, 0x12, 0x23};
//static u8_t old_xid[4] = {0}; //static u8_t old_xid[4] = {0};
static const uint32 magic_cookie ICACHE_RODATA_ATTR = 0x63538263; static const uint32 magic_cookie ICACHE_RODATA_ATTR = 0x63538263;
static struct udp_pcb *pcb_dhcps = NULL; static struct udp_pcb *pcb_dhcps = NULL;
static struct ip_addr broadcast_dhcps; static struct ip_addr broadcast_dhcps;
static struct ip_addr server_address; static struct ip_addr server_address;
static struct ip_addr client_address;//added static struct ip_addr client_address;//added
static struct dhcps_lease dhcps_lease; static struct dhcps_lease dhcps_lease;
//static bool dhcps_lease_flag = true; //static bool dhcps_lease_flag = true;
static list_node *plist = NULL; static list_node *plist = NULL;
static uint8 offer = 0xFF; static uint8 offer = 0xFF;
static bool renew = false; static bool renew = false;
#define DHCPS_LEASE_TIME_DEF (120) #define DHCPS_LEASE_TIME_DEF (120)
uint32 dhcps_lease_time = DHCPS_LEASE_TIME_DEF; //minute uint32 dhcps_lease_time = DHCPS_LEASE_TIME_DEF; //minute
void wifi_softap_dhcps_client_leave(u8 *bssid, struct ip_addr *ip,bool force); 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); uint32 wifi_softap_dhcps_client_update(u8 *bssid, struct ip_addr *ip);
/****************************************************************************** /******************************************************************************
* FunctionName : node_insert_to_list * FunctionName : node_insert_to_list
* Description : insert the node to the list * Description : insert the node to the list
* Parameters : arg -- Additional argument to pass to the callback function * Parameters : arg -- Additional argument to pass to the callback function
* Returns : none * Returns : none
*******************************************************************************/ *******************************************************************************/
void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node* pinsert) void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node* pinsert)
{ {
list_node *plist = NULL; list_node *plist = NULL;
struct dhcps_pool *pdhcps_pool = NULL; struct dhcps_pool *pdhcps_pool = NULL;
struct dhcps_pool *pdhcps_node = NULL; struct dhcps_pool *pdhcps_node = NULL;
if (*phead == NULL) if (*phead == NULL)
*phead = pinsert; *phead = pinsert;
else { else {
plist = *phead; plist = *phead;
pdhcps_node = pinsert->pnode; pdhcps_node = pinsert->pnode;
pdhcps_pool = plist->pnode; pdhcps_pool = plist->pnode;
if(pdhcps_node->ip.addr < pdhcps_pool->ip.addr) { if(pdhcps_node->ip.addr < pdhcps_pool->ip.addr) {
pinsert->pnext = plist; pinsert->pnext = plist;
*phead = pinsert; *phead = pinsert;
} else { } else {
while (plist->pnext != NULL) { while (plist->pnext != NULL) {
pdhcps_pool = plist->pnext->pnode; pdhcps_pool = plist->pnext->pnode;
if (pdhcps_node->ip.addr < pdhcps_pool->ip.addr) { if (pdhcps_node->ip.addr < pdhcps_pool->ip.addr) {
pinsert->pnext = plist->pnext; pinsert->pnext = plist->pnext;
plist->pnext = pinsert; plist->pnext = pinsert;
break; break;
} }
plist = plist->pnext; plist = plist->pnext;
} }
if(plist->pnext == NULL) { if(plist->pnext == NULL) {
plist->pnext = pinsert; plist->pnext = pinsert;
} }
} }
} }
// pinsert->pnext = NULL; // pinsert->pnext = NULL;
} }
/****************************************************************************** /******************************************************************************
* FunctionName : node_delete_from_list * FunctionName : node_delete_from_list
* Description : remove the node from list * Description : remove the node from list
* Parameters : arg -- Additional argument to pass to the callback function * Parameters : arg -- Additional argument to pass to the callback function
* Returns : none * Returns : none
*******************************************************************************/ *******************************************************************************/
void ICACHE_FLASH_ATTR node_remove_from_list(list_node **phead, list_node* pdelete) void ICACHE_FLASH_ATTR node_remove_from_list(list_node **phead, list_node* pdelete)
{ {
list_node *plist = NULL; list_node *plist = NULL;
plist = *phead; plist = *phead;
if (plist == NULL){ if (plist == NULL){
*phead = NULL; *phead = NULL;
} else { } else {
if (plist == pdelete){ if (plist == pdelete){
*phead = plist->pnext; *phead = plist->pnext;
pdelete->pnext = NULL; pdelete->pnext = NULL;
} else { } else {
while (plist != NULL) { while (plist != NULL) {
if (plist->pnext == pdelete){ if (plist->pnext == pdelete){
plist->pnext = pdelete->pnext; plist->pnext = pdelete->pnext;
pdelete->pnext = NULL; pdelete->pnext = NULL;
} }
plist = plist->pnext; plist = plist->pnext;
} }
} }
} }
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/* /*
* ��DHCP msg��Ϣ�ṹ���������� * ��DHCP msg��Ϣ�ṹ����������
* *
* @param optptr -- DHCP msg��Ϣλ�� * @param optptr -- DHCP msg��Ϣλ��
* @param type -- Ҫ��ӵ�����option * @param type -- Ҫ��ӵ�����option
* *
* @return uint8_t* ����DHCP msgƫ�Ƶ�ַ * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static uint8_t* ICACHE_FLASH_ATTR add_msg_type(uint8_t *optptr, uint8_t type) static uint8_t* ICACHE_FLASH_ATTR add_msg_type(uint8_t *optptr, uint8_t type)
{ {
*optptr++ = DHCP_OPTION_MSG_TYPE; *optptr++ = DHCP_OPTION_MSG_TYPE;
*optptr++ = 1; *optptr++ = 1;
*optptr++ = type; *optptr++ = type;
return optptr; return optptr;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/* /*
* ��DHCP msg�ṹ������offerӦ������ * ��DHCP msg�ṹ������offerӦ������
* *
* @param optptr -- DHCP msg��Ϣλ�� * @param optptr -- DHCP msg��Ϣλ��
* *
* @return uint8_t* ����DHCP msgƫ�Ƶ�ַ * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr)
{ {
struct ip_addr ipadd; struct ip_addr ipadd;
ipadd.addr = *( (uint32_t *) &server_address); ipadd.addr = *( (uint32_t *) &server_address);
#ifdef USE_CLASS_B_NET #ifdef USE_CLASS_B_NET
*optptr++ = DHCP_OPTION_SUBNET_MASK; *optptr++ = DHCP_OPTION_SUBNET_MASK;
*optptr++ = 4; //length *optptr++ = 4; //length
*optptr++ = 255; *optptr++ = 255;
*optptr++ = 240; *optptr++ = 240;
*optptr++ = 0; *optptr++ = 0;
*optptr++ = 0; *optptr++ = 0;
#else #else
*optptr++ = DHCP_OPTION_SUBNET_MASK; *optptr++ = DHCP_OPTION_SUBNET_MASK;
*optptr++ = 4; *optptr++ = 4;
*optptr++ = 255; *optptr++ = 255;
*optptr++ = 255; *optptr++ = 255;
*optptr++ = 255; *optptr++ = 255;
*optptr++ = 0; *optptr++ = 0;
#endif #endif
*optptr++ = DHCP_OPTION_LEASE_TIME; *optptr++ = DHCP_OPTION_LEASE_TIME;
*optptr++ = 4; *optptr++ = 4;
*optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 24) & 0xFF; *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 24) & 0xFF;
*optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 16) & 0xFF; *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 16) & 0xFF;
*optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 8) & 0xFF; *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 8) & 0xFF;
*optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 0) & 0xFF; *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 0) & 0xFF;
*optptr++ = DHCP_OPTION_SERVER_ID; *optptr++ = DHCP_OPTION_SERVER_ID;
*optptr++ = 4; *optptr++ = 4;
*optptr++ = ip4_addr1( &ipadd); *optptr++ = ip4_addr1( &ipadd);
*optptr++ = ip4_addr2( &ipadd); *optptr++ = ip4_addr2( &ipadd);
*optptr++ = ip4_addr3( &ipadd); *optptr++ = ip4_addr3( &ipadd);
*optptr++ = ip4_addr4( &ipadd); *optptr++ = ip4_addr4( &ipadd);
if (dhcps_router_enabled(offer)){ if (dhcps_router_enabled(offer)){
struct ip_info if_ip; struct ip_info if_ip;
os_bzero(&if_ip, sizeof(struct ip_info)); os_bzero(&if_ip, sizeof(struct ip_info));
wifi_get_ip_info(SOFTAP_IF, &if_ip); wifi_get_ip_info(SOFTAP_IF, &if_ip);
*optptr++ = DHCP_OPTION_ROUTER; *optptr++ = DHCP_OPTION_ROUTER;
*optptr++ = 4; *optptr++ = 4;
*optptr++ = ip4_addr1( &if_ip.gw); *optptr++ = ip4_addr1( &if_ip.gw);
*optptr++ = ip4_addr2( &if_ip.gw); *optptr++ = ip4_addr2( &if_ip.gw);
*optptr++ = ip4_addr3( &if_ip.gw); *optptr++ = ip4_addr3( &if_ip.gw);
*optptr++ = ip4_addr4( &if_ip.gw); *optptr++ = ip4_addr4( &if_ip.gw);
} }
#ifdef USE_DNS #ifdef USE_DNS
*optptr++ = DHCP_OPTION_DNS_SERVER; *optptr++ = DHCP_OPTION_DNS_SERVER;
*optptr++ = 4; *optptr++ = 4;
*optptr++ = ip4_addr1( &ipadd); *optptr++ = ip4_addr1( &ipadd);
*optptr++ = ip4_addr2( &ipadd); *optptr++ = ip4_addr2( &ipadd);
*optptr++ = ip4_addr3( &ipadd); *optptr++ = ip4_addr3( &ipadd);
*optptr++ = ip4_addr4( &ipadd); *optptr++ = ip4_addr4( &ipadd);
#endif #endif
#ifdef CLASS_B_NET #ifdef CLASS_B_NET
*optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS;
*optptr++ = 4; *optptr++ = 4;
*optptr++ = ip4_addr1( &ipadd); *optptr++ = ip4_addr1( &ipadd);
*optptr++ = 255; *optptr++ = 255;
*optptr++ = 255; *optptr++ = 255;
*optptr++ = 255; *optptr++ = 255;
#else #else
*optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS;
*optptr++ = 4; *optptr++ = 4;
*optptr++ = ip4_addr1( &ipadd); *optptr++ = ip4_addr1( &ipadd);
*optptr++ = ip4_addr2( &ipadd); *optptr++ = ip4_addr2( &ipadd);
*optptr++ = ip4_addr3( &ipadd); *optptr++ = ip4_addr3( &ipadd);
*optptr++ = 255; *optptr++ = 255;
#endif #endif
*optptr++ = DHCP_OPTION_INTERFACE_MTU; *optptr++ = DHCP_OPTION_INTERFACE_MTU;
*optptr++ = 2; *optptr++ = 2;
#ifdef CLASS_B_NET #ifdef CLASS_B_NET
*optptr++ = 0x05; *optptr++ = 0x05;
*optptr++ = 0xdc; *optptr++ = 0xdc;
#else #else
*optptr++ = 0x02; *optptr++ = 0x02;
*optptr++ = 0x40; *optptr++ = 0x40;
#endif #endif
*optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY; *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY;
*optptr++ = 1; *optptr++ = 1;
*optptr++ = 0x00; *optptr++ = 0x00;
*optptr++ = 43; *optptr++ = 43;
*optptr++ = 6; *optptr++ = 6;
*optptr++ = 0x01; *optptr++ = 0x01;
*optptr++ = 4; *optptr++ = 4;
*optptr++ = 0x00; *optptr++ = 0x00;
*optptr++ = 0x00; *optptr++ = 0x00;
*optptr++ = 0x00; *optptr++ = 0x00;
*optptr++ = 0x02; *optptr++ = 0x02;
return optptr; return optptr;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/* /*
* ��DHCP msg�ṹ����ӽ����־���� * ��DHCP msg�ṹ����ӽ����־����
* *
* @param optptr -- DHCP msg��Ϣλ�� * @param optptr -- DHCP msg��Ϣλ��
* *
* @return uint8_t* ����DHCP msgƫ�Ƶ�ַ * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static uint8_t* ICACHE_FLASH_ATTR add_end(uint8_t *optptr) static uint8_t* ICACHE_FLASH_ATTR add_end(uint8_t *optptr)
{ {
*optptr++ = DHCP_OPTION_END; *optptr++ = DHCP_OPTION_END;
return optptr; return optptr;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static void ICACHE_FLASH_ATTR create_msg(struct dhcps_msg *m) static void ICACHE_FLASH_ATTR create_msg(struct dhcps_msg *m)
{ {
struct ip_addr client; struct ip_addr client;
client.addr = client_address.addr; client.addr = client_address.addr;
m->op = DHCP_REPLY; m->op = DHCP_REPLY;
m->htype = DHCP_HTYPE_ETHERNET; m->htype = DHCP_HTYPE_ETHERNET;
m->hlen = 6; m->hlen = 6;
m->hops = 0; m->hops = 0;
// os_memcpy((char *) xid, (char *) m->xid, sizeof(m->xid)); // os_memcpy((char *) xid, (char *) m->xid, sizeof(m->xid));
m->secs = 0; m->secs = 0;
m->flags = htons(BOOTP_BROADCAST); m->flags = htons(BOOTP_BROADCAST);
os_memcpy((char *) m->yiaddr, (char *) &client.addr, sizeof(m->yiaddr)); os_memcpy((char *) m->yiaddr, (char *) &client.addr, sizeof(m->yiaddr));
os_memset((char *) m->ciaddr, 0, sizeof(m->ciaddr)); os_memset((char *) m->ciaddr, 0, sizeof(m->ciaddr));
os_memset((char *) m->siaddr, 0, sizeof(m->siaddr)); os_memset((char *) m->siaddr, 0, sizeof(m->siaddr));
os_memset((char *) m->giaddr, 0, sizeof(m->giaddr)); os_memset((char *) m->giaddr, 0, sizeof(m->giaddr));
os_memset((char *) m->sname, 0, sizeof(m->sname)); os_memset((char *) m->sname, 0, sizeof(m->sname));
os_memset((char *) m->file, 0, sizeof(m->file)); os_memset((char *) m->file, 0, sizeof(m->file));
os_memset((char *) m->options, 0, sizeof(m->options)); os_memset((char *) m->options, 0, sizeof(m->options));
//For xiaomi crash bug //For xiaomi crash bug
uint32 magic_cookie1 = magic_cookie; uint32 magic_cookie1 = magic_cookie;
os_memcpy((char *) m->options, &magic_cookie1, sizeof(magic_cookie1)); os_memcpy((char *) m->options, &magic_cookie1, sizeof(magic_cookie1));
} }
struct pbuf * dhcps_pbuf_alloc(u16_t len) struct pbuf * dhcps_pbuf_alloc(u16_t len)
{ {
u16_t mlen = sizeof(struct dhcps_msg); u16_t mlen = sizeof(struct dhcps_msg);
if (len > mlen) { if (len > mlen) {
#if DHCPS_DEBUG #if DHCPS_DEBUG
DHCPS_LOG("dhcps: len=%d mlen=%d", len, mlen); DHCPS_LOG("dhcps: len=%d mlen=%d", len, mlen);
#endif #endif
mlen = len; mlen = len;
} }
return pbuf_alloc(PBUF_TRANSPORT, mlen, PBUF_RAM); return pbuf_alloc(PBUF_TRANSPORT, mlen, PBUF_RAM);
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/* /*
* ����һ��OFFER * ����һ��OFFER
* *
* @param -- m ָ����Ҫ���͵�DHCP msg���� * @param -- m ָ����Ҫ���͵�DHCP msg����
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m, u16_t len) static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m, u16_t len)
{ {
uint8_t *end; uint8_t *end;
struct pbuf *p, *q; struct pbuf *p, *q;
u8_t *data; u8_t *data;
u16_t cnt=0; u16_t cnt=0;
u16_t i; u16_t i;
err_t SendOffer_err_t; err_t SendOffer_err_t;
create_msg(m); create_msg(m);
end = add_msg_type(&m->options[4], DHCPOFFER); end = add_msg_type(&m->options[4], DHCPOFFER);
end = add_offer_options(end); end = add_offer_options(end);
end = add_end(end); end = add_end(end);
p = dhcps_pbuf_alloc(len); p = dhcps_pbuf_alloc(len);
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("udhcp: send_offer>>p->ref = %d\n", p->ref); os_printf("udhcp: send_offer>>p->ref = %d\n", p->ref);
#endif #endif
if(p != NULL){ if(p != NULL){
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_offer>>pbuf_alloc succeed\n"); 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->tot_len = %d\n", p->tot_len);
os_printf("dhcps: send_offer>>p->len = %d\n", p->len); os_printf("dhcps: send_offer>>p->len = %d\n", p->len);
#endif #endif
q = p; q = p;
while(q != NULL){ while(q != NULL){
data = (u8_t *)q->payload; data = (u8_t *)q->payload;
for(i=0; i<q->len; i++) for(i=0; i<q->len; i++)
{ {
data[i] = ((u8_t *) m)[cnt++]; data[i] = ((u8_t *) m)[cnt++];
} }
q = q->next; q = q->next;
} }
}else{ }else{
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_offer>>pbuf_alloc failed\n"); os_printf("dhcps: send_offer>>pbuf_alloc failed\n");
#endif #endif
return; return;
} }
SendOffer_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); SendOffer_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT );
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_offer>>udp_sendto result %x\n",SendOffer_err_t); os_printf("dhcps: send_offer>>udp_sendto result %x\n",SendOffer_err_t);
#endif #endif
if(p->ref != 0){ if(p->ref != 0){
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("udhcp: send_offer>>free pbuf\n"); os_printf("udhcp: send_offer>>free pbuf\n");
#endif #endif
pbuf_free(p); pbuf_free(p);
} }
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/* /*
* ����һ��NAK��Ϣ * ����һ��NAK��Ϣ
* *
* @param m ָ����Ҫ���͵�DHCP msg���� * @param m ָ����Ҫ���͵�DHCP msg����
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static void ICACHE_FLASH_ATTR send_nak(struct dhcps_msg *m, u16_t len) static void ICACHE_FLASH_ATTR send_nak(struct dhcps_msg *m, u16_t len)
{ {
u8_t *end; u8_t *end;
struct pbuf *p, *q; struct pbuf *p, *q;
u8_t *data; u8_t *data;
u16_t cnt=0; u16_t cnt=0;
u16_t i; u16_t i;
err_t SendNak_err_t; err_t SendNak_err_t;
create_msg(m); create_msg(m);
end = add_msg_type(&m->options[4], DHCPNAK); end = add_msg_type(&m->options[4], DHCPNAK);
end = add_end(end); end = add_end(end);
p = dhcps_pbuf_alloc(len); p = dhcps_pbuf_alloc(len);
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("udhcp: send_nak>>p->ref = %d\n", p->ref); os_printf("udhcp: send_nak>>p->ref = %d\n", p->ref);
#endif #endif
if(p != NULL){ if(p != NULL){
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_nak>>pbuf_alloc succeed\n"); 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->tot_len = %d\n", p->tot_len);
os_printf("dhcps: send_nak>>p->len = %d\n", p->len); os_printf("dhcps: send_nak>>p->len = %d\n", p->len);
#endif #endif
q = p; q = p;
while(q != NULL){ while(q != NULL){
data = (u8_t *)q->payload; data = (u8_t *)q->payload;
for(i=0; i<q->len; i++) for(i=0; i<q->len; i++)
{ {
data[i] = ((u8_t *) m)[cnt++]; data[i] = ((u8_t *) m)[cnt++];
} }
q = q->next; q = q->next;
} }
}else{ }else{
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_nak>>pbuf_alloc failed\n"); os_printf("dhcps: send_nak>>pbuf_alloc failed\n");
#endif #endif
return; return;
} }
SendNak_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); SendNak_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT );
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_nak>>udp_sendto result %x\n",SendNak_err_t); os_printf("dhcps: send_nak>>udp_sendto result %x\n",SendNak_err_t);
#endif #endif
if(p->ref != 0){ if(p->ref != 0){
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("udhcp: send_nak>>free pbuf\n"); os_printf("udhcp: send_nak>>free pbuf\n");
#endif #endif
pbuf_free(p); pbuf_free(p);
} }
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/* /*
* ����һ��ACK��DHCP�ͻ��� * ����һ��ACK��DHCP�ͻ���
* *
* @param m ָ����Ҫ���͵�DHCP msg���� * @param m ָ����Ҫ���͵�DHCP msg����
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static void ICACHE_FLASH_ATTR send_ack(struct dhcps_msg *m, u16_t len) static void ICACHE_FLASH_ATTR send_ack(struct dhcps_msg *m, u16_t len)
{ {
u8_t *end; u8_t *end;
struct pbuf *p, *q; struct pbuf *p, *q;
u8_t *data; u8_t *data;
u16_t cnt=0; u16_t cnt=0;
u16_t i; u16_t i;
err_t SendAck_err_t; err_t SendAck_err_t;
create_msg(m); create_msg(m);
end = add_msg_type(&m->options[4], DHCPACK); end = add_msg_type(&m->options[4], DHCPACK);
end = add_offer_options(end); end = add_offer_options(end);
end = add_end(end); end = add_end(end);
p = dhcps_pbuf_alloc(len); p = dhcps_pbuf_alloc(len);
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("udhcp: send_ack>>p->ref = %d\n", p->ref); os_printf("udhcp: send_ack>>p->ref = %d\n", p->ref);
#endif #endif
if(p != NULL){ if(p != NULL){
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_ack>>pbuf_alloc succeed\n"); 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->tot_len = %d\n", p->tot_len);
os_printf("dhcps: send_ack>>p->len = %d\n", p->len); os_printf("dhcps: send_ack>>p->len = %d\n", p->len);
#endif #endif
q = p; q = p;
while(q != NULL){ while(q != NULL){
data = (u8_t *)q->payload; data = (u8_t *)q->payload;
for(i=0; i<q->len; i++) for(i=0; i<q->len; i++)
{ {
data[i] = ((u8_t *) m)[cnt++]; data[i] = ((u8_t *) m)[cnt++];
} }
q = q->next; q = q->next;
} }
}else{ }else{
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_ack>>pbuf_alloc failed\n"); os_printf("dhcps: send_ack>>pbuf_alloc failed\n");
#endif #endif
return; return;
} }
SendAck_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); SendAck_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT );
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: send_ack>>udp_sendto result %x\n",SendAck_err_t); os_printf("dhcps: send_ack>>udp_sendto result %x\n",SendAck_err_t);
#endif #endif
if(p->ref != 0){ if(p->ref != 0){
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("udhcp: send_ack>>free pbuf\n"); os_printf("udhcp: send_ack>>free pbuf\n");
#endif #endif
pbuf_free(p); pbuf_free(p);
} }
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/* /*
* ����DHCP�ͻ��˷�����DHCP����������Ϣ�����Բ�ͬ��DHCP��������������Ӧ��Ӧ�� * ����DHCP�ͻ��˷�����DHCP����������Ϣ�����Բ�ͬ��DHCP��������������Ӧ��Ӧ��
* *
* @param optptr DHCP msg��������� * @param optptr DHCP msg���������
* @param len ��������Ĵ��?(byte) * @param len ��������Ĵ��?(byte)
* *
* @return uint8_t ���ش�����DHCP Server״ֵ̬ * @return uint8_t ���ش�����DHCP Server״ֵ̬
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len) static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len)
{ {
struct ip_addr client; struct ip_addr client;
bool is_dhcp_parse_end = false; bool is_dhcp_parse_end = false;
struct dhcps_state s; struct dhcps_state s;
client.addr = *( (uint32_t *) &client_address);// Ҫ�����DHCP�ͻ��˵�IP client.addr = *( (uint32_t *) &client_address);// Ҫ�����DHCP�ͻ��˵�IP
u8_t *end = optptr + len; u8_t *end = optptr + len;
u16_t type = 0; u16_t type = 0;
s.state = DHCPS_STATE_IDLE; s.state = DHCPS_STATE_IDLE;
while (optptr < end) { while (optptr < end) {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr); os_printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr);
#endif #endif
switch ((sint16_t) *optptr) { switch ((sint16_t) *optptr) {
case DHCP_OPTION_MSG_TYPE: //53 case DHCP_OPTION_MSG_TYPE: //53
type = *(optptr + 2); type = *(optptr + 2);
break; break;
case DHCP_OPTION_REQ_IPADDR://50 case DHCP_OPTION_REQ_IPADDR://50
//os_printf("dhcps:0x%08x,0x%08x\n",client.addr,*(uint32*)(optptr+2)); //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( os_memcmp( (char *) &client.addr, (char *) optptr+2,4)==0 ) {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); os_printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n");
#endif #endif
s.state = DHCPS_STATE_ACK; s.state = DHCPS_STATE_ACK;
}else { }else {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n"); os_printf("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n");
#endif #endif
s.state = DHCPS_STATE_NAK; s.state = DHCPS_STATE_NAK;
} }
break; break;
case DHCP_OPTION_END: case DHCP_OPTION_END:
{ {
is_dhcp_parse_end = true; is_dhcp_parse_end = true;
} }
break; break;
} }
if(is_dhcp_parse_end){ if(is_dhcp_parse_end){
break; break;
} }
optptr += optptr[1] + 2; optptr += optptr[1] + 2;
} }
switch (type){ switch (type){
case DHCPDISCOVER://1 case DHCPDISCOVER://1
s.state = DHCPS_STATE_OFFER; s.state = DHCPS_STATE_OFFER;
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: DHCPD_STATE_OFFER\n"); os_printf("dhcps: DHCPD_STATE_OFFER\n");
#endif #endif
break; break;
case DHCPREQUEST://3 case DHCPREQUEST://3
if ( !(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK) ) { if ( !(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK) ) {
if(renew == true) { if(renew == true) {
s.state = DHCPS_STATE_ACK; s.state = DHCPS_STATE_ACK;
} else { } else {
s.state = DHCPS_STATE_NAK; s.state = DHCPS_STATE_NAK;
} }
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: DHCPD_STATE_NAK\n"); os_printf("dhcps: DHCPD_STATE_NAK\n");
#endif #endif
} }
break; break;
case DHCPDECLINE://4 case DHCPDECLINE://4
s.state = DHCPS_STATE_IDLE; s.state = DHCPS_STATE_IDLE;
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: DHCPD_STATE_IDLE\n"); os_printf("dhcps: DHCPD_STATE_IDLE\n");
#endif #endif
break; break;
case DHCPRELEASE://7 case DHCPRELEASE://7
s.state = DHCPS_STATE_RELEASE; s.state = DHCPS_STATE_RELEASE;
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: DHCPD_STATE_IDLE\n"); os_printf("dhcps: DHCPD_STATE_IDLE\n");
#endif #endif
break; break;
} }
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: return s.state = %d\n", s.state); os_printf("dhcps: return s.state = %d\n", s.state);
#endif #endif
return s.state; return s.state;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len) static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len)
{ {
if(os_memcmp((char *)m->options, if(os_memcmp((char *)m->options,
&magic_cookie, &magic_cookie,
sizeof(magic_cookie)) == 0){ sizeof(magic_cookie)) == 0){
struct ip_addr ip; struct ip_addr ip;
os_memcpy(&ip.addr,m->ciaddr,sizeof(ip.addr)); os_memcpy(&ip.addr,m->ciaddr,sizeof(ip.addr));
client_address.addr = wifi_softap_dhcps_client_update(m->chaddr,&ip); client_address.addr = wifi_softap_dhcps_client_update(m->chaddr,&ip);
sint16_t ret = parse_options(&m->options[4], len); sint16_t ret = parse_options(&m->options[4], len);
if(ret == DHCPS_STATE_RELEASE) { if(ret == DHCPS_STATE_RELEASE) {
wifi_softap_dhcps_client_leave(m->chaddr,&ip,TRUE); // force to delete wifi_softap_dhcps_client_leave(m->chaddr,&ip,TRUE); // force to delete
client_address.addr = ip.addr; client_address.addr = ip.addr;
} }
return ret; return ret;
} }
return 0; return 0;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
/* /*
* DHCP ��������ݰ���մ���ص�����˺�����LWIP UDPģ������ʱ������ * DHCP ��������ݰ���մ���ص�����˺�����LWIP UDPģ������ʱ������
* ��Ҫ����udp_recv()������LWIP����ע��. * ��Ҫ����udp_recv()������LWIP����ע��.
* *
* @param arg * @param arg
* @param pcb ���յ�UDP��Ŀ��ƿ�? * @param pcb ���յ�UDP��Ŀ��ƿ�?
* @param p ���յ���UDP�е��������? * @param p ���յ���UDP�е��������?
* @param addr ���ʹ�UDP���Դ�����IP��ַ * @param addr ���ʹ�UDP���Դ�����IP��ַ
* @param port ���ʹ�UDP���Դ�����UDPͨ���˿ں� * @param port ���ʹ�UDP���Դ�����UDPͨ���˿ں�
*/ */
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static void ICACHE_FLASH_ATTR handle_dhcp(void *arg, static void ICACHE_FLASH_ATTR handle_dhcp(void *arg,
struct udp_pcb *pcb, struct udp_pcb *pcb,
struct pbuf *p, struct pbuf *p,
struct ip_addr *addr, struct ip_addr *addr,
uint16_t port) uint16_t port)
{ {
struct dhcps_msg *pmsg_dhcps = NULL; struct dhcps_msg *pmsg_dhcps = NULL;
sint16_t tlen = 0, malloc_len; sint16_t tlen = 0, malloc_len;
u16_t i = 0; u16_t i = 0;
u16_t dhcps_msg_cnt = 0; u16_t dhcps_msg_cnt = 0;
u8_t *p_dhcps_msg = NULL; u8_t *p_dhcps_msg = NULL;
u8_t *data = NULL; u8_t *data = NULL;
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> receive a packet\n"); os_printf("dhcps: handle_dhcp-> receive a packet\n");
#endif #endif
if (p==NULL) return; if (p==NULL) return;
malloc_len = sizeof(struct dhcps_msg); malloc_len = sizeof(struct dhcps_msg);
#if DHCPS_DEBUG #if DHCPS_DEBUG
DHCPS_LOG("dhcps: handle_dhcp malloc_len=%d rx_len=%d", malloc_len, p->tot_len); DHCPS_LOG("dhcps: handle_dhcp malloc_len=%d rx_len=%d", malloc_len, p->tot_len);
#endif #endif
if (malloc_len < p->tot_len) { if (malloc_len < p->tot_len) {
malloc_len = p->tot_len; malloc_len = p->tot_len;
} }
pmsg_dhcps = (struct dhcps_msg *)os_malloc(malloc_len); pmsg_dhcps = (struct dhcps_msg *)os_malloc(malloc_len);
if (NULL == pmsg_dhcps){ if (NULL == pmsg_dhcps){
pbuf_free(p); pbuf_free(p);
return; return;
} }
memset(pmsg_dhcps , 0x00 , malloc_len); memset(pmsg_dhcps , 0x00 , malloc_len);
p_dhcps_msg = (u8_t *)pmsg_dhcps; p_dhcps_msg = (u8_t *)pmsg_dhcps;
tlen = p->tot_len; tlen = p->tot_len;
data = p->payload; data = p->payload;
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen); os_printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen);
os_printf("dhcps: handle_dhcp-> p->len = %d\n", p->len); os_printf("dhcps: handle_dhcp-> p->len = %d\n", p->len);
#endif #endif
for(i=0; i<p->len; i++){ for(i=0; i<p->len; i++){
p_dhcps_msg[dhcps_msg_cnt++] = data[i]; p_dhcps_msg[dhcps_msg_cnt++] = data[i];
} }
if(p->next != NULL) { if(p->next != NULL) {
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> p->next != NULL\n"); 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->tot_len = %d\n",p->next->tot_len);
os_printf("dhcps: handle_dhcp-> p->next->len = %d\n",p->next->len); os_printf("dhcps: handle_dhcp-> p->next->len = %d\n",p->next->len);
#endif #endif
data = p->next->payload; data = p->next->payload;
for(i=0; i<p->next->len; i++){ for(i=0; i<p->next->len; i++){
p_dhcps_msg[dhcps_msg_cnt++] = data[i]; p_dhcps_msg[dhcps_msg_cnt++] = data[i];
} }
} }
/* /*
* DHCP �ͻ���������Ϣ���� * DHCP �ͻ���������Ϣ����
*/ */
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> parse_msg(p)\n"); os_printf("dhcps: handle_dhcp-> parse_msg(p)\n");
#endif #endif
switch(parse_msg(pmsg_dhcps, tlen - 240)) { switch(parse_msg(pmsg_dhcps, tlen - 240)) {
case DHCPS_STATE_OFFER://1 case DHCPS_STATE_OFFER://1
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); os_printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n");
#endif #endif
send_offer(pmsg_dhcps, malloc_len); send_offer(pmsg_dhcps, malloc_len);
break; break;
case DHCPS_STATE_ACK://3 case DHCPS_STATE_ACK://3
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); os_printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n");
#endif #endif
send_ack(pmsg_dhcps, malloc_len); send_ack(pmsg_dhcps, malloc_len);
wifi_softap_set_station_info(pmsg_dhcps->chaddr, &client_address.addr); wifi_softap_set_station_info(pmsg_dhcps->chaddr, &client_address.addr);
break; break;
case DHCPS_STATE_NAK://4 case DHCPS_STATE_NAK://4
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); os_printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n");
#endif #endif
send_nak(pmsg_dhcps, malloc_len); send_nak(pmsg_dhcps, malloc_len);
break; break;
default : default :
break; break;
} }
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps: handle_dhcp-> pbuf_free(p)\n"); os_printf("dhcps: handle_dhcp-> pbuf_free(p)\n");
#endif #endif
pbuf_free(p); pbuf_free(p);
os_free(pmsg_dhcps); os_free(pmsg_dhcps);
pmsg_dhcps = NULL; pmsg_dhcps = NULL;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static void ICACHE_FLASH_ATTR wifi_softap_init_dhcps_lease(uint32 ip) static void ICACHE_FLASH_ATTR wifi_softap_init_dhcps_lease(uint32 ip)
{ {
uint32 softap_ip = 0,local_ip = 0; uint32 softap_ip = 0,local_ip = 0;
uint32 start_ip = 0; uint32 start_ip = 0;
uint32 end_ip = 0; uint32 end_ip = 0;
// if (dhcps_lease_flag) { // if (dhcps_lease_flag) {
if (dhcps_lease.enable == TRUE) { if (dhcps_lease.enable == TRUE) {
softap_ip = htonl(ip); softap_ip = htonl(ip);
start_ip = htonl(dhcps_lease.start_ip.addr); start_ip = htonl(dhcps_lease.start_ip.addr);
end_ip = htonl(dhcps_lease.end_ip.addr); end_ip = htonl(dhcps_lease.end_ip.addr);
/*config ip information can't contain local ip*/ /*config ip information can't contain local ip*/
if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) { if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) {
dhcps_lease.enable = FALSE; dhcps_lease.enable = FALSE;
} else { } else {
/*config ip information must be in the same segment as the local ip*/ /*config ip information must be in the same segment as the local ip*/
softap_ip >>= 8; softap_ip >>= 8;
if (((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip)) if (((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip))
|| (end_ip - start_ip > DHCPS_MAX_LEASE)) { || (end_ip - start_ip > DHCPS_MAX_LEASE)) {
dhcps_lease.enable = FALSE; dhcps_lease.enable = FALSE;
} }
} }
} }
if (dhcps_lease.enable == FALSE) { if (dhcps_lease.enable == FALSE) {
local_ip = softap_ip = htonl(ip); local_ip = softap_ip = htonl(ip);
softap_ip &= 0xFFFFFF00; softap_ip &= 0xFFFFFF00;
local_ip &= 0xFF; local_ip &= 0xFF;
if (local_ip >= 0x80) if (local_ip >= 0x80)
local_ip -= DHCPS_MAX_LEASE; local_ip -= DHCPS_MAX_LEASE;
else else
local_ip ++; local_ip ++;
os_bzero(&dhcps_lease, sizeof(dhcps_lease)); os_bzero(&dhcps_lease, sizeof(dhcps_lease));
dhcps_lease.start_ip.addr = softap_ip | local_ip; dhcps_lease.start_ip.addr = softap_ip | local_ip;
dhcps_lease.end_ip.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1); 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.start_ip.addr = htonl(dhcps_lease.start_ip.addr);
dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_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.start_ip.addr = htonl(dhcps_lease.start_ip.addr);
// dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_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); // 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) void ICACHE_FLASH_ATTR dhcps_start(struct ip_info *info)
{ {
struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01);
if(apnetif->dhcps_pcb != NULL) { if(apnetif->dhcps_pcb != NULL) {
udp_remove(apnetif->dhcps_pcb); udp_remove(apnetif->dhcps_pcb);
} }
pcb_dhcps = udp_new(); pcb_dhcps = udp_new();
if (pcb_dhcps == NULL || info ==NULL) { if (pcb_dhcps == NULL || info ==NULL) {
os_printf("dhcps_start(): could not obtain pcb\n"); os_printf("dhcps_start(): could not obtain pcb\n");
} }
apnetif->dhcps_pcb = pcb_dhcps; apnetif->dhcps_pcb = pcb_dhcps;
IP4_ADDR(&broadcast_dhcps, 255, 255, 255, 255); IP4_ADDR(&broadcast_dhcps, 255, 255, 255, 255);
server_address = info->ip; server_address = info->ip;
wifi_softap_init_dhcps_lease(server_address.addr); wifi_softap_init_dhcps_lease(server_address.addr);
udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT); udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT);
udp_recv(pcb_dhcps, handle_dhcp, NULL); udp_recv(pcb_dhcps, handle_dhcp, NULL);
#if DHCPS_DEBUG #if DHCPS_DEBUG
os_printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n"); os_printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n");
#endif #endif
} }
void ICACHE_FLASH_ATTR dhcps_stop(void) void ICACHE_FLASH_ATTR dhcps_stop(void)
{ {
struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01);
udp_disconnect(pcb_dhcps); udp_disconnect(pcb_dhcps);
// dhcps_lease_flag = true; // dhcps_lease_flag = true;
if(apnetif->dhcps_pcb != NULL) { if(apnetif->dhcps_pcb != NULL) {
udp_remove(apnetif->dhcps_pcb); udp_remove(apnetif->dhcps_pcb);
apnetif->dhcps_pcb = NULL; apnetif->dhcps_pcb = NULL;
} }
//udp_remove(pcb_dhcps); //udp_remove(pcb_dhcps);
list_node *pnode = NULL; list_node *pnode = NULL;
list_node *pback_node = NULL; list_node *pback_node = NULL;
struct dhcps_pool* dhcp_node = NULL; struct dhcps_pool* dhcp_node = NULL;
struct ip_addr ip_zero; struct ip_addr ip_zero;
os_memset(&ip_zero,0x0,sizeof(ip_zero)); os_memset(&ip_zero,0x0,sizeof(ip_zero));
pnode = plist; pnode = plist;
while (pnode != NULL) { while (pnode != NULL) {
pback_node = pnode; pback_node = pnode;
pnode = pback_node->pnext; pnode = pback_node->pnext;
node_remove_from_list(&plist, pback_node); node_remove_from_list(&plist, pback_node);
dhcp_node = (struct dhcps_pool*)pback_node->pnode; 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_dhcps_client_leave(dhcp_node->mac,&dhcp_node->ip,TRUE); // force to delete
wifi_softap_set_station_info(dhcp_node->mac, &ip_zero); wifi_softap_set_station_info(dhcp_node->mac, &ip_zero);
os_free(pback_node->pnode); os_free(pback_node->pnode);
pback_node->pnode = NULL; pback_node->pnode = NULL;
os_free(pback_node); os_free(pback_node);
pback_node = NULL; pback_node = NULL;
} }
} }
/****************************************************************************** /******************************************************************************
* FunctionName : wifi_softap_set_dhcps_lease * FunctionName : wifi_softap_set_dhcps_lease
* Description : set the lease information of DHCP server * Description : set the lease information of DHCP server
* Parameters : please -- Additional argument to set the lease information, * Parameters : please -- Additional argument to set the lease information,
* Little-Endian. * Little-Endian.
* Returns : true or false * Returns : true or false
*******************************************************************************/ *******************************************************************************/
bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease(struct dhcps_lease *please) bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease(struct dhcps_lease *please)
{ {
struct ip_info info; struct ip_info info;
uint32 softap_ip = 0; uint32 softap_ip = 0;
uint32 start_ip = 0; uint32 start_ip = 0;
uint32 end_ip = 0; uint32 end_ip = 0;
uint8 opmode = wifi_get_opmode(); uint8 opmode = wifi_get_opmode();
if (opmode == STATION_MODE || opmode == NULL_MODE) { if (opmode == STATION_MODE || opmode == NULL_MODE) {
return false; return false;
} }
if (please == NULL || wifi_softap_dhcps_status() == DHCP_STARTED) if (please == NULL || wifi_softap_dhcps_status() == DHCP_STARTED)
return false; return false;
if(please->enable) { if(please->enable) {
os_bzero(&info, sizeof(struct ip_info)); os_bzero(&info, sizeof(struct ip_info));
wifi_get_ip_info(SOFTAP_IF, &info); wifi_get_ip_info(SOFTAP_IF, &info);
softap_ip = htonl(info.ip.addr); softap_ip = htonl(info.ip.addr);
start_ip = htonl(please->start_ip.addr); start_ip = htonl(please->start_ip.addr);
end_ip = htonl(please->end_ip.addr); end_ip = htonl(please->end_ip.addr);
/*config ip information can't contain local ip*/ /*config ip information can't contain local ip*/
if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) if ((start_ip <= softap_ip) && (softap_ip <= end_ip))
return false; return false;
/*config ip information must be in the same segment as the local ip*/ /*config ip information must be in the same segment as the local ip*/
softap_ip >>= 8; softap_ip >>= 8;
if ((start_ip >> 8 != softap_ip) if ((start_ip >> 8 != softap_ip)
|| (end_ip >> 8 != softap_ip)) { || (end_ip >> 8 != softap_ip)) {
return false; return false;
} }
if (end_ip - start_ip > DHCPS_MAX_LEASE) if (end_ip - start_ip > DHCPS_MAX_LEASE)
return false; return false;
os_bzero(&dhcps_lease, sizeof(dhcps_lease)); os_bzero(&dhcps_lease, sizeof(dhcps_lease));
// dhcps_lease.start_ip.addr = start_ip; // dhcps_lease.start_ip.addr = start_ip;
// dhcps_lease.end_ip.addr = end_ip; // dhcps_lease.end_ip.addr = end_ip;
dhcps_lease.start_ip.addr = please->start_ip.addr; dhcps_lease.start_ip.addr = please->start_ip.addr;
dhcps_lease.end_ip.addr = please->end_ip.addr; dhcps_lease.end_ip.addr = please->end_ip.addr;
} }
dhcps_lease.enable = please->enable; dhcps_lease.enable = please->enable;
// dhcps_lease_flag = false; // dhcps_lease_flag = false;
return true; return true;
} }
/****************************************************************************** /******************************************************************************
* FunctionName : wifi_softap_get_dhcps_lease * FunctionName : wifi_softap_get_dhcps_lease
* Description : get the lease information of DHCP server * Description : get the lease information of DHCP server
* Parameters : please -- Additional argument to get the lease information, * Parameters : please -- Additional argument to get the lease information,
* Little-Endian. * Little-Endian.
* Returns : true or false * Returns : true or false
*******************************************************************************/ *******************************************************************************/
bool ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease(struct dhcps_lease *please) bool ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease(struct dhcps_lease *please)
{ {
uint8 opmode = wifi_get_opmode(); uint8 opmode = wifi_get_opmode();
if (opmode == STATION_MODE || opmode == NULL_MODE) { if (opmode == STATION_MODE || opmode == NULL_MODE) {
return false; return false;
} }
if (NULL == please) if (NULL == please)
return false; return false;
// if (dhcps_lease_flag){ // if (dhcps_lease_flag){
if (dhcps_lease.enable == FALSE){ if (dhcps_lease.enable == FALSE){
if (wifi_softap_dhcps_status() == DHCP_STOPPED) if (wifi_softap_dhcps_status() == DHCP_STOPPED)
return false; return false;
} else { } else {
// os_bzero(please, sizeof(dhcps_lease)); // os_bzero(please, sizeof(dhcps_lease));
// if (wifi_softap_dhcps_status() == DHCP_STOPPED){ // if (wifi_softap_dhcps_status() == DHCP_STOPPED){
// please->start_ip.addr = htonl(dhcps_lease.start_ip.addr); // please->start_ip.addr = htonl(dhcps_lease.start_ip.addr);
// please->end_ip.addr = htonl(dhcps_lease.end_ip.addr); // please->end_ip.addr = htonl(dhcps_lease.end_ip.addr);
// } // }
} }
// if (wifi_softap_dhcps_status() == DHCP_STARTED){ // if (wifi_softap_dhcps_status() == DHCP_STARTED){
// os_bzero(please, sizeof(dhcps_lease)); // os_bzero(please, sizeof(dhcps_lease));
// please->start_ip.addr = dhcps_lease.start_ip.addr; // please->start_ip.addr = dhcps_lease.start_ip.addr;
// please->end_ip.addr = dhcps_lease.end_ip.addr; // please->end_ip.addr = dhcps_lease.end_ip.addr;
// } // }
please->start_ip.addr = dhcps_lease.start_ip.addr; please->start_ip.addr = dhcps_lease.start_ip.addr;
please->end_ip.addr = dhcps_lease.end_ip.addr; please->end_ip.addr = dhcps_lease.end_ip.addr;
return true; return true;
} }
static void ICACHE_FLASH_ATTR kill_oldest_dhcps_pool(void) static void ICACHE_FLASH_ATTR kill_oldest_dhcps_pool(void)
{ {
list_node *pre = NULL, *p = NULL; list_node *pre = NULL, *p = NULL;
list_node *minpre = NULL, *minp = NULL; list_node *minpre = NULL, *minp = NULL;
struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL; struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL;
pre = plist; pre = plist;
p = pre->pnext; p = pre->pnext;
minpre = pre; minpre = pre;
minp = p; minp = p;
while (p != NULL){ while (p != NULL){
pdhcps_pool = p->pnode; pdhcps_pool = p->pnode;
pmin_pool = minp->pnode; pmin_pool = minp->pnode;
if (pdhcps_pool->lease_timer < pmin_pool->lease_timer){ if (pdhcps_pool->lease_timer < pmin_pool->lease_timer){
minp = p; minp = p;
minpre = pre; minpre = pre;
} }
pre = p; pre = p;
p = p->pnext; p = p->pnext;
} }
minpre->pnext = minp->pnext; minpre->pnext = minp->pnext;
os_free(minp->pnode); os_free(minp->pnode);
minp->pnode = NULL; minp->pnode = NULL;
os_free(minp); os_free(minp);
minp = NULL; minp = NULL;
} }
void ICACHE_FLASH_ATTR dhcps_coarse_tmr(void) void ICACHE_FLASH_ATTR dhcps_coarse_tmr(void)
{ {
uint8 num_dhcps_pool = 0; uint8 num_dhcps_pool = 0;
list_node *pback_node = NULL; list_node *pback_node = NULL;
list_node *pnode = NULL; list_node *pnode = NULL;
struct dhcps_pool *pdhcps_pool = NULL; struct dhcps_pool *pdhcps_pool = NULL;
pnode = plist; pnode = plist;
while (pnode != NULL) { while (pnode != NULL) {
pdhcps_pool = pnode->pnode; pdhcps_pool = pnode->pnode;
if ( pdhcps_pool->type == DHCPS_TYPE_DYNAMIC) { if ( pdhcps_pool->type == DHCPS_TYPE_DYNAMIC) {
pdhcps_pool->lease_timer --; pdhcps_pool->lease_timer --;
} }
if (pdhcps_pool->lease_timer == 0){ if (pdhcps_pool->lease_timer == 0){
pback_node = pnode; pback_node = pnode;
pnode = pback_node->pnext; pnode = pback_node->pnext;
node_remove_from_list(&plist,pback_node); node_remove_from_list(&plist,pback_node);
os_free(pback_node->pnode); os_free(pback_node->pnode);
pback_node->pnode = NULL; pback_node->pnode = NULL;
os_free(pback_node); os_free(pback_node);
pback_node = NULL; pback_node = NULL;
} else { } else {
pnode = pnode ->pnext; pnode = pnode ->pnext;
num_dhcps_pool ++; num_dhcps_pool ++;
} }
} }
if (num_dhcps_pool >= MAX_STATION_NUM) if (num_dhcps_pool >= MAX_STATION_NUM)
kill_oldest_dhcps_pool(); kill_oldest_dhcps_pool();
} }
bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg) bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg)
{ {
bool offer_flag = true; bool offer_flag = true;
uint8 option = 0; uint8 option = 0;
if (optarg == NULL && wifi_softap_dhcps_status() == false) if (optarg == NULL && wifi_softap_dhcps_status() == false)
return false; return false;
if (level <= OFFER_START || level >= OFFER_END) if (level <= OFFER_START || level >= OFFER_END)
return false; return false;
switch (level){ switch (level){
case OFFER_ROUTER: case OFFER_ROUTER:
offer = (*(uint8 *)optarg) & 0x01; offer = (*(uint8 *)optarg) & 0x01;
offer_flag = true; offer_flag = true;
break; break;
default : default :
offer_flag = false; offer_flag = false;
break; break;
} }
return offer_flag; return offer_flag;
} }
bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease_time(uint32 minute) bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease_time(uint32 minute)
{ {
uint8 opmode = wifi_get_opmode(); uint8 opmode = wifi_get_opmode();
if (opmode == STATION_MODE || opmode == NULL_MODE) { if (opmode == STATION_MODE || opmode == NULL_MODE) {
return false; return false;
} }
if (wifi_softap_dhcps_status() == DHCP_STARTED) { if (wifi_softap_dhcps_status() == DHCP_STARTED) {
return false; return false;
} }
if(minute == 0) { if(minute == 0) {
return false; return false;
} }
dhcps_lease_time = minute; dhcps_lease_time = minute;
return true; return true;
} }
bool ICACHE_FLASH_ATTR wifi_softap_reset_dhcps_lease_time(void) bool ICACHE_FLASH_ATTR wifi_softap_reset_dhcps_lease_time(void)
{ {
uint8 opmode = wifi_get_opmode(); uint8 opmode = wifi_get_opmode();
if (opmode == STATION_MODE || opmode == NULL_MODE) { if (opmode == STATION_MODE || opmode == NULL_MODE) {
return false; return false;
} }
if (wifi_softap_dhcps_status() == DHCP_STARTED) { if (wifi_softap_dhcps_status() == DHCP_STARTED) {
return false; return false;
} }
dhcps_lease_time = DHCPS_LEASE_TIME_DEF; dhcps_lease_time = DHCPS_LEASE_TIME_DEF;
return true; return true;
} }
uint32 ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease_time(void) // minute uint32 ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease_time(void) // minute
{ {
return dhcps_lease_time; return dhcps_lease_time;
} }
void ICACHE_FLASH_ATTR wifi_softap_dhcps_client_leave(u8 *bssid, struct ip_addr *ip,bool force) void ICACHE_FLASH_ATTR wifi_softap_dhcps_client_leave(u8 *bssid, struct ip_addr *ip,bool force)
{ {
struct dhcps_pool *pdhcps_pool = NULL; struct dhcps_pool *pdhcps_pool = NULL;
list_node *pback_node = NULL; list_node *pback_node = NULL;
if ((bssid == NULL) || (ip == NULL)) { if ((bssid == NULL) || (ip == NULL)) {
return; return;
} }
for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) { for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
pdhcps_pool = pback_node->pnode; pdhcps_pool = pback_node->pnode;
if (os_memcmp(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)) == 0){ 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 (os_memcmp(&pdhcps_pool->ip.addr, &ip->addr, sizeof(pdhcps_pool->ip.addr)) == 0) {
if ((pdhcps_pool->type == DHCPS_TYPE_STATIC) || (force)) { if ((pdhcps_pool->type == DHCPS_TYPE_STATIC) || (force)) {
if(pback_node != NULL) { if(pback_node != NULL) {
node_remove_from_list(&plist,pback_node); node_remove_from_list(&plist,pback_node);
os_free(pback_node); os_free(pback_node);
pback_node = NULL; pback_node = NULL;
} }
if (pdhcps_pool != NULL) { if (pdhcps_pool != NULL) {
os_free(pdhcps_pool); os_free(pdhcps_pool);
pdhcps_pool = NULL; pdhcps_pool = NULL;
} }
} else { } else {
pdhcps_pool->state = DHCPS_STATE_OFFLINE; pdhcps_pool->state = DHCPS_STATE_OFFLINE;
} }
struct ip_addr ip_zero; struct ip_addr ip_zero;
os_memset(&ip_zero,0x0,sizeof(ip_zero)); os_memset(&ip_zero,0x0,sizeof(ip_zero));
wifi_softap_set_station_info(bssid, &ip_zero); wifi_softap_set_station_info(bssid, &ip_zero);
break; break;
} }
} }
} }
} }
uint32 ICACHE_FLASH_ATTR wifi_softap_dhcps_client_update(u8 *bssid, struct ip_addr *ip) uint32 ICACHE_FLASH_ATTR wifi_softap_dhcps_client_update(u8 *bssid, struct ip_addr *ip)
{ {
struct dhcps_pool *pdhcps_pool = NULL; struct dhcps_pool *pdhcps_pool = NULL;
list_node *pback_node = NULL; list_node *pback_node = NULL;
list_node *pmac_node = NULL; list_node *pmac_node = NULL;
list_node *pip_node = NULL; list_node *pip_node = NULL;
bool flag = FALSE; bool flag = FALSE;
uint32 start_ip = dhcps_lease.start_ip.addr; uint32 start_ip = dhcps_lease.start_ip.addr;
uint32 end_ip = dhcps_lease.end_ip.addr; uint32 end_ip = dhcps_lease.end_ip.addr;
dhcps_type_t type = DHCPS_TYPE_DYNAMIC; dhcps_type_t type = DHCPS_TYPE_DYNAMIC;
if (bssid == NULL) { if (bssid == NULL) {
return IPADDR_ANY; return IPADDR_ANY;
} }
if (ip) { if (ip) {
if (IPADDR_BROADCAST == ip->addr) { if (IPADDR_BROADCAST == ip->addr) {
return IPADDR_ANY; return IPADDR_ANY;
} else if (IPADDR_ANY == ip->addr) { } else if (IPADDR_ANY == ip->addr) {
ip = NULL; ip = NULL;
} else { } else {
type = DHCPS_TYPE_STATIC; type = DHCPS_TYPE_STATIC;
} }
} }
renew = FALSE; renew = FALSE;
for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) { for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
pdhcps_pool = pback_node->pnode; pdhcps_pool = pback_node->pnode;
//os_printf("mac:"MACSTR"bssid:"MACSTR"\r\n",MAC2STR(pdhcps_pool->mac),MAC2STR(bssid)); //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){ if (os_memcmp(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)) == 0){
pmac_node = pback_node; pmac_node = pback_node;
if (ip == NULL) { if (ip == NULL) {
flag = TRUE; flag = TRUE;
break; break;
} }
} }
if (ip != NULL) { if (ip != NULL) {
if (os_memcmp(&pdhcps_pool->ip.addr, &ip->addr, sizeof(pdhcps_pool->ip.addr)) == 0) { if (os_memcmp(&pdhcps_pool->ip.addr, &ip->addr, sizeof(pdhcps_pool->ip.addr)) == 0) {
pip_node = pback_node; pip_node = pback_node;
} }
} else if (flag == FALSE){ } else if (flag == FALSE){
if (os_memcmp(&pdhcps_pool->ip.addr, &start_ip, sizeof(pdhcps_pool->ip.addr)) != 0) { if (os_memcmp(&pdhcps_pool->ip.addr, &start_ip, sizeof(pdhcps_pool->ip.addr)) != 0) {
flag = TRUE; flag = TRUE;
} else { } else {
start_ip = htonl((ntohl(start_ip) + 1)); start_ip = htonl((ntohl(start_ip) + 1));
} }
} }
} }
if ((ip == NULL) && (flag == FALSE)) { if ((ip == NULL) && (flag == FALSE)) {
if (plist == NULL) { if (plist == NULL) {
if (start_ip <= end_ip) { if (start_ip <= end_ip) {
flag = TRUE; flag = TRUE;
} else { } else {
return IPADDR_ANY; return IPADDR_ANY;
} }
} else { } else {
if (start_ip > end_ip) { if (start_ip > end_ip) {
return IPADDR_ANY; return IPADDR_ANY;
} }
//start_ip = htonl((ntohl(start_ip) + 1)); //start_ip = htonl((ntohl(start_ip) + 1));
flag = TRUE; flag = TRUE;
} }
} }
if (pmac_node != NULL) { // update new ip if (pmac_node != NULL) { // update new ip
if (pip_node != NULL){ if (pip_node != NULL){
pdhcps_pool = pip_node->pnode; pdhcps_pool = pip_node->pnode;
if (pip_node != pmac_node) { if (pip_node != pmac_node) {
if(pdhcps_pool->state != DHCPS_STATE_OFFLINE) { // ip is used if(pdhcps_pool->state != DHCPS_STATE_OFFLINE) { // ip is used
return IPADDR_ANY; return IPADDR_ANY;
} }
// mac exists and ip exists in other node,delete mac // mac exists and ip exists in other node,delete mac
node_remove_from_list(&plist,pmac_node); node_remove_from_list(&plist,pmac_node);
os_free(pmac_node->pnode); os_free(pmac_node->pnode);
pmac_node->pnode = NULL; pmac_node->pnode = NULL;
os_free(pmac_node); os_free(pmac_node);
pmac_node = pip_node; pmac_node = pip_node;
os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)); os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
} else { } else {
renew = true; renew = true;
type = DHCPS_TYPE_DYNAMIC; type = DHCPS_TYPE_DYNAMIC;
} }
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type; pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE; pdhcps_pool->state = DHCPS_STATE_ONLINE;
} else { } else {
pdhcps_pool = pmac_node->pnode; pdhcps_pool = pmac_node->pnode;
if (ip != NULL) { if (ip != NULL) {
pdhcps_pool->ip.addr = ip->addr; pdhcps_pool->ip.addr = ip->addr;
} else if (flag == TRUE) { } else if (flag == TRUE) {
pdhcps_pool->ip.addr = start_ip; pdhcps_pool->ip.addr = start_ip;
} else { // no ip to distribute } else { // no ip to distribute
return IPADDR_ANY; return IPADDR_ANY;
} }
node_remove_from_list(&plist,pmac_node); node_remove_from_list(&plist,pmac_node);
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type; pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE; pdhcps_pool->state = DHCPS_STATE_ONLINE;
node_insert_to_list(&plist,pmac_node); node_insert_to_list(&plist,pmac_node);
} }
} else { // new station } else { // new station
if (pip_node != NULL) { // maybe ip has used if (pip_node != NULL) { // maybe ip has used
pdhcps_pool = pip_node->pnode; pdhcps_pool = pip_node->pnode;
if (pdhcps_pool->state != DHCPS_STATE_OFFLINE) { if (pdhcps_pool->state != DHCPS_STATE_OFFLINE) {
return IPADDR_ANY; return IPADDR_ANY;
} }
os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)); os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type; pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE; pdhcps_pool->state = DHCPS_STATE_ONLINE;
} else { } else {
pdhcps_pool = (struct dhcps_pool *)os_zalloc(sizeof(struct dhcps_pool)); pdhcps_pool = (struct dhcps_pool *)os_zalloc(sizeof(struct dhcps_pool));
if (ip != NULL) { if (ip != NULL) {
pdhcps_pool->ip.addr = ip->addr; pdhcps_pool->ip.addr = ip->addr;
} else if (flag == TRUE) { } else if (flag == TRUE) {
pdhcps_pool->ip.addr = start_ip; pdhcps_pool->ip.addr = start_ip;
} else { // no ip to distribute } else { // no ip to distribute
os_free(pdhcps_pool); os_free(pdhcps_pool);
return IPADDR_ANY; return IPADDR_ANY;
} }
if (pdhcps_pool->ip.addr > end_ip) { if (pdhcps_pool->ip.addr > end_ip) {
os_free(pdhcps_pool); os_free(pdhcps_pool);
return IPADDR_ANY; return IPADDR_ANY;
} }
os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)); os_memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac));
pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
pdhcps_pool->type = type; pdhcps_pool->type = type;
pdhcps_pool->state = DHCPS_STATE_ONLINE; pdhcps_pool->state = DHCPS_STATE_ONLINE;
pback_node = (list_node *)os_zalloc(sizeof(list_node )); pback_node = (list_node *)os_zalloc(sizeof(list_node ));
pback_node->pnode = pdhcps_pool; pback_node->pnode = pdhcps_pool;
pback_node->pnext = NULL; pback_node->pnext = NULL;
node_insert_to_list(&plist,pback_node); node_insert_to_list(&plist,pback_node);
} }
} }
return pdhcps_pool->ip.addr; return pdhcps_pool->ip.addr;
} }
...@@ -370,7 +370,7 @@ espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length) ...@@ -370,7 +370,7 @@ espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length)
espconn_msg *pnode = NULL; espconn_msg *pnode = NULL;
bool value = false; bool value = false;
err_t error = ESPCONN_OK; err_t error = ESPCONN_OK;
if (espconn == NULL || psent == NULL || length == 0) { if (espconn == NULL || psent == NULL || length == 0) {
return ESPCONN_ARG; return ESPCONN_ARG;
} }
...@@ -1315,7 +1315,7 @@ espconn_port(void) ...@@ -1315,7 +1315,7 @@ espconn_port(void)
* Description : Resolve a hostname (string) into an IP address. * Description : Resolve a hostname (string) into an IP address.
* Parameters : pespconn -- espconn to resolve a hostname * Parameters : pespconn -- espconn to resolve a hostname
* hostname -- the hostname that is to be queried * 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 * it is already cached in the dns_table (only valid if
* ESPCONN_OK is returned!) * ESPCONN_OK is returned!)
* found -- a callback function to be called on success, failure * found -- a callback function to be called on success, failure
......
/****************************************************************************** /******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi) * Copyright 2013-2014 Espressif Systems (Wuxi)
* *
* FileName: espconn_udp.c * FileName: espconn_udp.c
* *
* Description: udp proto interface * Description: udp proto interface
* *
* Modification history: * Modification history:
* 2014/3/31, v1.0 create this file. * 2014/3/31, v1.0 create this file.
*******************************************************************************/ *******************************************************************************/
#include "ets_sys.h" #include "ets_sys.h"
#include "os_type.h" #include "os_type.h"
//#include "os.h" //#include "os.h"
#include "lwip/inet.h" #include "lwip/inet.h"
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/pbuf.h" #include "lwip/pbuf.h"
#include "lwip/mem.h" #include "lwip/mem.h"
#include "lwip/tcp_impl.h" #include "lwip/tcp_impl.h"
#include "lwip/udp.h" #include "lwip/udp.h"
#include "lwip/app/espconn_udp.h" #include "lwip/app/espconn_udp.h"
#ifdef MEMLEAK_DEBUG #ifdef MEMLEAK_DEBUG
static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
#endif #endif
extern espconn_msg *plink_active; extern espconn_msg *plink_active;
extern uint8 default_interface; extern uint8 default_interface;
enum send_opt{ enum send_opt{
ESPCONN_SENDTO, ESPCONN_SENDTO,
ESPCONN_SEND ESPCONN_SEND
}; };
static void ICACHE_FLASH_ATTR espconn_data_sentcb(struct espconn *pespconn) static void ICACHE_FLASH_ATTR espconn_data_sentcb(struct espconn *pespconn)
{ {
if (pespconn == NULL) { if (pespconn == NULL) {
return; return;
} }
if (pespconn->sent_callback != NULL) { if (pespconn->sent_callback != NULL) {
pespconn->sent_callback(pespconn); pespconn->sent_callback(pespconn);
} }
} }
static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg, enum send_opt opt) static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg, enum send_opt opt)
{ {
espconn_msg *psent = arg; espconn_msg *psent = arg;
if (psent == NULL) { if (psent == NULL) {
return; return;
} }
if (psent->pcommon.cntr == 0) { if (psent->pcommon.cntr == 0) {
psent->pespconn->state = ESPCONN_CONNECT; psent->pespconn->state = ESPCONN_CONNECT;
if (psent->pcommon.err == 0) if (psent->pcommon.err == 0)
espconn_data_sentcb(psent->pespconn); espconn_data_sentcb(psent->pespconn);
} else { } else {
if (opt == ESPCONN_SEND){ if (opt == ESPCONN_SEND){
espconn_udp_sent(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); espconn_udp_sent(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr);
} else { } else {
espconn_udp_sendto(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); espconn_udp_sendto(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr);
} }
} }
} }
/****************************************************************************** /******************************************************************************
* FunctionName : espconn_udp_sent * FunctionName : espconn_udp_sent
* Description : sent data for client or server * Description : sent data for client or server
* Parameters : void *arg -- client or server to send * Parameters : void *arg -- client or server to send
* uint8* psent -- Data to send * uint8* psent -- Data to send
* uint16 length -- Length of data to send * uint16 length -- Length of data to send
* Returns : return espconn error code. * Returns : return espconn error code.
* - ESPCONN_OK. Successful. No error occured. * - ESPCONN_OK. Successful. No error occured.
* - ESPCONN_MEM. Out of memory. * - ESPCONN_MEM. Out of memory.
* - ESPCONN_RTE. Could not find route to destination address. * - ESPCONN_RTE. Could not find route to destination address.
* - More errors could be returned by lower protocol layers. * - More errors could be returned by lower protocol layers.
*******************************************************************************/ *******************************************************************************/
err_t ICACHE_FLASH_ATTR err_t ICACHE_FLASH_ATTR
espconn_udp_sent(void *arg, uint8 *psent, uint16 length) espconn_udp_sent(void *arg, uint8 *psent, uint16 length)
{ {
espconn_msg *pudp_sent = arg; espconn_msg *pudp_sent = arg;
struct udp_pcb *upcb = pudp_sent->pcommon.pcb; struct udp_pcb *upcb = pudp_sent->pcommon.pcb;
struct pbuf *p, *q ,*p_temp; struct pbuf *p, *q ,*p_temp;
u8_t *data = NULL; u8_t *data = NULL;
u16_t cnt = 0; u16_t cnt = 0;
u16_t datalen = 0; u16_t datalen = 0;
u16_t i = 0; u16_t i = 0;
err_t err; err_t err;
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb)); 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) { if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) {
return ESPCONN_ARG; return ESPCONN_ARG;
} }
if ((IP_FRAG_MAX_MTU - 20 - 8) < length) { if ((IP_FRAG_MAX_MTU - 20 - 8) < length) {
datalen = IP_FRAG_MAX_MTU - 20 - 8; datalen = IP_FRAG_MAX_MTU - 20 - 8;
} else { } else {
datalen = length; datalen = length;
} }
p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM);
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p));
if (p != NULL) { if (p != NULL) {
q = p; q = p;
while (q != NULL) { while (q != NULL) {
data = (u8_t *)q->payload; data = (u8_t *)q->payload;
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data)); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data));
for (i = 0; i < q->len; i++) { for (i = 0; i < q->len; i++) {
data[i] = ((u8_t *) psent)[cnt++]; data[i] = ((u8_t *) psent)[cnt++];
} }
q = q->next; q = q->next;
} }
} else { } else {
return ESPCONN_MEM; return ESPCONN_MEM;
} }
upcb->remote_port = pudp_sent->pespconn->proto.udp->remote_port; upcb->remote_port = pudp_sent->pespconn->proto.udp->remote_port;
IP4_ADDR(&upcb->remote_ip, pudp_sent->pespconn->proto.udp->remote_ip[0], 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[1],
pudp_sent->pespconn->proto.udp->remote_ip[2], pudp_sent->pespconn->proto.udp->remote_ip[2],
pudp_sent->pespconn->proto.udp->remote_ip[3]); 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)); 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 *sta_netif = (struct netif *)eagle_lwip_getif(0x00);
struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); 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(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) && \ 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, sta_netif) && \
ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) { ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) {
p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM);
if (pbuf_copy (p_temp,p) != ERR_OK) { if (pbuf_copy (p_temp,p) != ERR_OK) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent: copying to new pbuf failed\n")); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent: copying to new pbuf failed\n"));
return ESPCONN_ARG; return ESPCONN_ARG;
} }
netif_set_default(sta_netif); netif_set_default(sta_netif);
err = udp_send(upcb, p_temp); err = udp_send(upcb, p_temp);
pbuf_free(p_temp); pbuf_free(p_temp);
netif_set_default(ap_netif); netif_set_default(ap_netif);
} }
} }
err = udp_send(upcb, p); err = udp_send(upcb, p);
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d\n", __LINE__, err)); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d\n", __LINE__, err));
if (p->ref != 0) { if (p->ref != 0) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p));
pbuf_free(p); pbuf_free(p);
pudp_sent->pcommon.ptrbuf = psent + datalen; pudp_sent->pcommon.ptrbuf = psent + datalen;
pudp_sent->pcommon.cntr = length - datalen; pudp_sent->pcommon.cntr = length - datalen;
pudp_sent->pcommon.err = err; pudp_sent->pcommon.err = err;
espconn_data_sent(pudp_sent, ESPCONN_SEND); espconn_data_sent(pudp_sent, ESPCONN_SEND);
if (err > 0) if (err > 0)
return ESPCONN_IF; return ESPCONN_IF;
return err; return err;
} else { } else {
pbuf_free(p); pbuf_free(p);
return ESPCONN_RTE; return ESPCONN_RTE;
} }
} }
/****************************************************************************** /******************************************************************************
* FunctionName : espconn_udp_sendto * FunctionName : espconn_udp_sendto
* Description : sent data for UDP * Description : sent data for UDP
* Parameters : void *arg -- UDP to send * Parameters : void *arg -- UDP to send
* uint8* psent -- Data to send * uint8* psent -- Data to send
* uint16 length -- Length of data to send * uint16 length -- Length of data to send
* Returns : return espconn error code. * Returns : return espconn error code.
* - ESPCONN_OK. Successful. No error occured. * - ESPCONN_OK. Successful. No error occured.
* - ESPCONN_MEM. Out of memory. * - ESPCONN_MEM. Out of memory.
* - ESPCONN_RTE. Could not find route to destination address. * - ESPCONN_RTE. Could not find route to destination address.
* - More errors could be returned by lower protocol layers. * - More errors could be returned by lower protocol layers.
*******************************************************************************/ *******************************************************************************/
err_t ICACHE_FLASH_ATTR err_t ICACHE_FLASH_ATTR
espconn_udp_sendto(void *arg, uint8 *psent, uint16 length) espconn_udp_sendto(void *arg, uint8 *psent, uint16 length)
{ {
espconn_msg *pudp_sent = arg; espconn_msg *pudp_sent = arg;
struct udp_pcb *upcb = pudp_sent->pcommon.pcb; struct udp_pcb *upcb = pudp_sent->pcommon.pcb;
struct espconn *pespconn = pudp_sent->pespconn; struct espconn *pespconn = pudp_sent->pespconn;
struct pbuf *p, *q ,*p_temp; struct pbuf *p, *q ,*p_temp;
struct ip_addr dst_ip; struct ip_addr dst_ip;
u16_t dst_port; u16_t dst_port;
u8_t *data = NULL; u8_t *data = NULL;
u16_t cnt = 0; u16_t cnt = 0;
u16_t datalen = 0; u16_t datalen = 0;
u16_t i = 0; u16_t i = 0;
err_t err; err_t err;
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb)); 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) { if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) {
return ESPCONN_ARG; return ESPCONN_ARG;
} }
if ((IP_FRAG_MAX_MTU - 20 - 8) < length) { if ((IP_FRAG_MAX_MTU - 20 - 8) < length) {
datalen = IP_FRAG_MAX_MTU - 20 - 8; datalen = IP_FRAG_MAX_MTU - 20 - 8;
} else { } else {
datalen = length; datalen = length;
} }
p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM);
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p));
if (p != NULL) { if (p != NULL) {
q = p; q = p;
while (q != NULL) { while (q != NULL) {
data = (u8_t *)q->payload; data = (u8_t *)q->payload;
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data)); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data));
for (i = 0; i < q->len; i++) { for (i = 0; i < q->len; i++) {
data[i] = ((u8_t *) psent)[cnt++]; data[i] = ((u8_t *) psent)[cnt++];
} }
q = q->next; q = q->next;
} }
} else { } else {
return ESPCONN_MEM; return ESPCONN_MEM;
} }
dst_port = pespconn->proto.udp->remote_port; dst_port = pespconn->proto.udp->remote_port;
IP4_ADDR(&dst_ip, pespconn->proto.udp->remote_ip[0], 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[1], pespconn->proto.udp->remote_ip[2],
pespconn->proto.udp->remote_ip[3]); 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)); 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 *sta_netif = (struct netif *)eagle_lwip_getif(0x00);
struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); 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(wifi_get_opmode() == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL)
{ {
if( netif_is_up(sta_netif) && \ if( netif_is_up(sta_netif) && \
netif_is_up(ap_netif) && \ netif_is_up(ap_netif) && \
ip_addr_isbroadcast(&dst_ip, sta_netif) && \ ip_addr_isbroadcast(&dst_ip, sta_netif) && \
ip_addr_isbroadcast(&dst_ip, ap_netif)) { ip_addr_isbroadcast(&dst_ip, ap_netif)) {
p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM);
if (pbuf_copy (p_temp,p) != ERR_OK) { if (pbuf_copy (p_temp,p) != ERR_OK) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sendto: copying to new pbuf failed\n")); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sendto: copying to new pbuf failed\n"));
return ESPCONN_ARG; return ESPCONN_ARG;
} }
netif_set_default(sta_netif); netif_set_default(sta_netif);
err = udp_sendto(upcb, p_temp, &dst_ip, dst_port); err = udp_sendto(upcb, p_temp, &dst_ip, dst_port);
pbuf_free(p_temp); pbuf_free(p_temp);
netif_set_default(ap_netif); netif_set_default(ap_netif);
} }
} }
err = udp_sendto(upcb, p, &dst_ip, dst_port); err = udp_sendto(upcb, p, &dst_ip, dst_port);
if (p->ref != 0) { if (p->ref != 0) {
pbuf_free(p); pbuf_free(p);
pudp_sent->pcommon.ptrbuf = psent + datalen; pudp_sent->pcommon.ptrbuf = psent + datalen;
pudp_sent->pcommon.cntr = length - datalen; pudp_sent->pcommon.cntr = length - datalen;
pudp_sent->pcommon.err = err; pudp_sent->pcommon.err = err;
espconn_data_sent(pudp_sent, ESPCONN_SENDTO); espconn_data_sent(pudp_sent, ESPCONN_SENDTO);
if (err > 0) if (err > 0)
return ESPCONN_IF; return ESPCONN_IF;
return err; return err;
} else { } else {
pbuf_free(p); pbuf_free(p);
return ESPCONN_RTE; return ESPCONN_RTE;
} }
} }
/****************************************************************************** /******************************************************************************
* FunctionName : espconn_udp_server_recv * FunctionName : espconn_udp_server_recv
* Description : This callback will be called when receiving a datagram. * Description : This callback will be called when receiving a datagram.
* Parameters : arg -- user supplied argument * Parameters : arg -- user supplied argument
* upcb -- the udp_pcb which received data * upcb -- the udp_pcb which received data
* p -- the packet buffer that was received * p -- the packet buffer that was received
* addr -- the remote IP address from which the packet was received * addr -- the remote IP address from which the packet was received
* port -- the remote port from which the packet was received * port -- the remote port from which the packet was received
* Returns : none * Returns : none
*******************************************************************************/ *******************************************************************************/
static void ICACHE_FLASH_ATTR static void ICACHE_FLASH_ATTR
espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p,
struct ip_addr *addr, u16_t port) struct ip_addr *addr, u16_t port)
{ {
espconn_msg *precv = arg; espconn_msg *precv = arg;
struct pbuf *q = NULL; struct pbuf *q = NULL;
u8_t *pdata = NULL; u8_t *pdata = NULL;
u16_t length = 0; u16_t length = 0;
struct ip_info ipconfig; struct ip_info ipconfig;
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_server_recv %d %p\n", __LINE__, upcb)); 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[0] = ip4_addr1_16(addr);
precv->pcommon.remote_ip[1] = ip4_addr2_16(addr); precv->pcommon.remote_ip[1] = ip4_addr2_16(addr);
precv->pcommon.remote_ip[2] = ip4_addr3_16(addr); precv->pcommon.remote_ip[2] = ip4_addr3_16(addr);
precv->pcommon.remote_ip[3] = ip4_addr4_16(addr); precv->pcommon.remote_ip[3] = ip4_addr4_16(addr);
precv->pcommon.remote_port = port; precv->pcommon.remote_port = port;
precv->pcommon.pcb = upcb; precv->pcommon.pcb = upcb;
if (wifi_get_opmode() != 1) { if (wifi_get_opmode() != 1) {
wifi_get_ip_info(1, &ipconfig); wifi_get_ip_info(1, &ipconfig);
if (!ip_addr_netcmp(addr, &ipconfig.ip, &ipconfig.netmask)) { if (!ip_addr_netcmp(addr, &ipconfig.ip, &ipconfig.netmask)) {
wifi_get_ip_info(0, &ipconfig); wifi_get_ip_info(0, &ipconfig);
} }
} else { } else {
wifi_get_ip_info(0, &ipconfig); wifi_get_ip_info(0, &ipconfig);
} }
precv->pespconn->proto.udp->local_ip[0] = ip4_addr1_16(&ipconfig.ip); precv->pespconn->proto.udp->local_ip[0] = ip4_addr1_16(&ipconfig.ip);
precv->pespconn->proto.udp->local_ip[1] = ip4_addr2_16(&ipconfig.ip); precv->pespconn->proto.udp->local_ip[1] = ip4_addr2_16(&ipconfig.ip);
precv->pespconn->proto.udp->local_ip[2] = ip4_addr3_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); precv->pespconn->proto.udp->local_ip[3] = ip4_addr4_16(&ipconfig.ip);
if (p != NULL) { if (p != NULL) {
pdata = (u8_t *)os_zalloc(p ->tot_len + 1); pdata = (u8_t *)os_zalloc(p ->tot_len + 1);
length = pbuf_copy_partial(p, pdata, p ->tot_len, 0); length = pbuf_copy_partial(p, pdata, p ->tot_len, 0);
precv->pcommon.pcb = upcb; precv->pcommon.pcb = upcb;
pbuf_free(p); pbuf_free(p);
if (length != 0) { if (length != 0) {
if (precv->pespconn->recv_callback != NULL) { if (precv->pespconn->recv_callback != NULL) {
precv->pespconn->recv_callback(precv->pespconn, pdata, length); precv->pespconn->recv_callback(precv->pespconn, pdata, length);
} }
} }
os_free(pdata); os_free(pdata);
} else { } else {
return; return;
} }
} }
/****************************************************************************** /******************************************************************************
* FunctionName : espconn_udp_disconnect * FunctionName : espconn_udp_disconnect
* Description : A new incoming connection has been disconnected. * Description : A new incoming connection has been disconnected.
* Parameters : espconn -- the espconn used to disconnect with host * Parameters : espconn -- the espconn used to disconnect with host
* Returns : none * Returns : none
*******************************************************************************/ *******************************************************************************/
void ICACHE_FLASH_ATTR espconn_udp_disconnect(espconn_msg *pdiscon) void ICACHE_FLASH_ATTR espconn_udp_disconnect(espconn_msg *pdiscon)
{ {
if (pdiscon == NULL) { if (pdiscon == NULL) {
return; return;
} }
struct udp_pcb *upcb = pdiscon->pcommon.pcb; struct udp_pcb *upcb = pdiscon->pcommon.pcb;
udp_disconnect(upcb); udp_disconnect(upcb);
udp_remove(upcb); udp_remove(upcb);
espconn_list_delete(&plink_active, pdiscon); espconn_list_delete(&plink_active, pdiscon);
os_free(pdiscon); os_free(pdiscon);
pdiscon = NULL; pdiscon = NULL;
} }
/****************************************************************************** /******************************************************************************
* FunctionName : espconn_udp_server * FunctionName : espconn_udp_server
* Description : Initialize the server: set up a PCB and bind it to the port * Description : Initialize the server: set up a PCB and bind it to the port
* Parameters : pespconn -- the espconn used to build server * Parameters : pespconn -- the espconn used to build server
* Returns : none * Returns : none
*******************************************************************************/ *******************************************************************************/
sint8 ICACHE_FLASH_ATTR sint8 ICACHE_FLASH_ATTR
espconn_udp_server(struct espconn *pespconn) espconn_udp_server(struct espconn *pespconn)
{ {
struct udp_pcb *upcb = NULL; struct udp_pcb *upcb = NULL;
espconn_msg *pserver = NULL; espconn_msg *pserver = NULL;
upcb = udp_new(); upcb = udp_new();
if (upcb == NULL) { if (upcb == NULL) {
return ESPCONN_MEM; return ESPCONN_MEM;
} else { } else {
pserver = (espconn_msg *)os_zalloc(sizeof(espconn_msg)); pserver = (espconn_msg *)os_zalloc(sizeof(espconn_msg));
if (pserver == NULL) { if (pserver == NULL) {
udp_remove(upcb); udp_remove(upcb);
return ESPCONN_MEM; return ESPCONN_MEM;
} }
pserver->pcommon.pcb = upcb; pserver->pcommon.pcb = upcb;
pserver->pespconn = pespconn; pserver->pespconn = pespconn;
espconn_list_creat(&plink_active, pserver); espconn_list_creat(&plink_active, pserver);
udp_bind(upcb, IP_ADDR_ANY, pserver->pespconn->proto.udp->local_port); udp_bind(upcb, IP_ADDR_ANY, pserver->pespconn->proto.udp->local_port);
udp_recv(upcb, espconn_udp_recv, (void *)pserver); udp_recv(upcb, espconn_udp_recv, (void *)pserver);
return ESPCONN_OK; return ESPCONN_OK;
} }
} }
/****************************************************************************** /******************************************************************************
* FunctionName : espconn_igmp_leave * FunctionName : espconn_igmp_leave
* Description : leave a multicast group * Description : leave a multicast group
* Parameters : host_ip -- the ip address of udp server * Parameters : host_ip -- the ip address of udp server
* multicast_ip -- multicast ip given by user * multicast_ip -- multicast ip given by user
* Returns : none * Returns : none
*******************************************************************************/ *******************************************************************************/
sint8 ICACHE_FLASH_ATTR sint8 ICACHE_FLASH_ATTR
espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip) espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip)
{ {
if (igmp_leavegroup(host_ip, multicast_ip) != ERR_OK) { if (igmp_leavegroup(host_ip, multicast_ip) != ERR_OK) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_leave_multigrup failed!\n")); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_leave_multigrup failed!\n"));
return -1; return -1;
}; };
return ESPCONN_OK; return ESPCONN_OK;
} }
/****************************************************************************** /******************************************************************************
* FunctionName : espconn_igmp_join * FunctionName : espconn_igmp_join
* Description : join a multicast group * Description : join a multicast group
* Parameters : host_ip -- the ip address of udp server * Parameters : host_ip -- the ip address of udp server
* multicast_ip -- multicast ip given by user * multicast_ip -- multicast ip given by user
* Returns : none * Returns : none
*******************************************************************************/ *******************************************************************************/
sint8 ICACHE_FLASH_ATTR sint8 ICACHE_FLASH_ATTR
espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip) espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip)
{ {
if (igmp_joingroup(host_ip, multicast_ip) != ERR_OK) { if (igmp_joingroup(host_ip, multicast_ip) != ERR_OK) {
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_join_multigrup failed!\n")); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_join_multigrup failed!\n"));
return -1; return -1;
}; };
/* join to any IP address at the port */ /* join to any IP address at the port */
return ESPCONN_OK; return ESPCONN_OK;
} }
/** /**
* @file * @file
* MetIO Server * MetIO Server
* *
*/ */
/* /*
* 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: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of the lwIP TCP/IP stack. * This file is part of the lwIP TCP/IP stack.
* *
*/ */
#include "lwip/opt.h" #include "lwip/opt.h"
#if LWIP_TCP #if LWIP_TCP
#include "lwip/tcp.h" #include "lwip/tcp.h"
#ifdef MEMLEAK_DEBUG #ifdef MEMLEAK_DEBUG
static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
#endif #endif
/* /*
* This implements a netio server. * This implements a netio server.
* The client sends a command word (4 bytes) then a data length word (4 bytes). * 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 * 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 * a circular buffer until the first byte is non-zero, then it is to consume
* another command/data pair. * another command/data pair.
* If the command is "send", the server is to send "data length" bytes from a circular * 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 * 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 * 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. * 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 */ /* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */
/* implementation options */ /* implementation options */
#define NETIO_BUF_SIZE (4 * 1024) #define NETIO_BUF_SIZE (4 * 1024)
#define NETIO_USE_STATIC_BUF 0 #define NETIO_USE_STATIC_BUF 0
/* NetIO server state definition */ /* NetIO server state definition */
#define NETIO_STATE_WAIT_FOR_CMD 0 #define NETIO_STATE_WAIT_FOR_CMD 0
#define NETIO_STATE_RECV_DATA 1 #define NETIO_STATE_RECV_DATA 1
#define NETIO_STATE_SEND_DATA 2 #define NETIO_STATE_SEND_DATA 2
#define NETIO_STATE_SEND_DATA_LAST 3 #define NETIO_STATE_SEND_DATA_LAST 3
#define NETIO_STATE_DONE 4 #define NETIO_STATE_DONE 4
struct netio_state { struct netio_state {
u32_t state; u32_t state;
u32_t cmd; u32_t cmd;
u32_t data_len; u32_t data_len;
u32_t cntr; u32_t cntr;
u8_t * buf_ptr; u8_t * buf_ptr;
u32_t buf_pos; u32_t buf_pos;
u32_t first_byte; u32_t first_byte;
u32_t time_stamp; u32_t time_stamp;
}; };
/* NetIO command protocol definition */ /* NetIO command protocol definition */
#define NETIO_CMD_QUIT 0 #define NETIO_CMD_QUIT 0
#define NETIO_CMD_C2S 1 #define NETIO_CMD_C2S 1
#define NETIO_CMD_S2C 2 #define NETIO_CMD_S2C 2
#define NETIO_CMD_RES 3 #define NETIO_CMD_RES 3
static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
static void ICACHE_FLASH_ATTR static void ICACHE_FLASH_ATTR
netio_close(void *arg, struct tcp_pcb *pcb) netio_close(void *arg, struct tcp_pcb *pcb)
{ {
err_t err; err_t err;
struct netio_state *ns = arg; struct netio_state *ns = arg;
ns->state = NETIO_STATE_DONE; ns->state = NETIO_STATE_DONE;
tcp_recv(pcb, NULL); tcp_recv(pcb, NULL);
err = tcp_close(pcb); err = tcp_close(pcb);
if (err != ERR_OK) { if (err != ERR_OK) {
/* closing failed, try again later */ /* closing failed, try again later */
tcp_recv(pcb, netio_recv); tcp_recv(pcb, netio_recv);
} else { } else {
/* closing succeeded */ /* closing succeeded */
#if NETIO_USE_STATIC_BUF != 1 #if NETIO_USE_STATIC_BUF != 1
if(ns->buf_ptr != NULL){ if(ns->buf_ptr != NULL){
mem_free(ns->buf_ptr); mem_free(ns->buf_ptr);
} }
#endif #endif
tcp_arg(pcb, NULL); tcp_arg(pcb, NULL);
tcp_poll(pcb, NULL, 0); tcp_poll(pcb, NULL, 0);
tcp_sent(pcb, NULL); tcp_sent(pcb, NULL);
if (arg != NULL) { if (arg != NULL) {
mem_free(arg); mem_free(arg);
} }
} }
} }
static err_t ICACHE_FLASH_ATTR static err_t ICACHE_FLASH_ATTR
netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{ {
struct netio_state *ns = arg; struct netio_state *ns = arg;
u8_t * data_ptr; u8_t * data_ptr;
u32_t data_cntr; u32_t data_cntr;
struct pbuf *q = p; struct pbuf *q = p;
u16_t len; u16_t len;
if (p != NULL) { if (p != NULL) {
tcp_recved(pcb, p->tot_len); tcp_recved(pcb, p->tot_len);
} }
if (err == ERR_OK && q != NULL) { if (err == ERR_OK && q != NULL) {
while (q != NULL) { while (q != NULL) {
data_cntr = q->len; data_cntr = q->len;
data_ptr = q->payload; data_ptr = q->payload;
while (data_cntr--) { while (data_cntr--) {
if (ns->state == NETIO_STATE_DONE){ if (ns->state == NETIO_STATE_DONE){
netio_close(ns, pcb); netio_close(ns, pcb);
break; break;
} else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) { } else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) {
if (ns->cntr < 4) { if (ns->cntr < 4) {
/* build up the CMD field */ /* build up the CMD field */
ns->cmd <<= 8; ns->cmd <<= 8;
ns->cmd |= *data_ptr++; ns->cmd |= *data_ptr++;
ns->cntr++; ns->cntr++;
} else if (ns->cntr < 8) { } else if (ns->cntr < 8) {
/* build up the DATA field */ /* build up the DATA field */
ns->data_len <<= 8; ns->data_len <<= 8;
ns->data_len |= *data_ptr++; ns->data_len |= *data_ptr++;
ns->cntr++; ns->cntr++;
if (ns->cntr == 8) { if (ns->cntr == 8) {
/* now we have full command and data words */ /* now we have full command and data words */
ns->cntr = 0; ns->cntr = 0;
ns->buf_pos = 0; ns->buf_pos = 0;
ns->buf_ptr[0] = 0; ns->buf_ptr[0] = 0;
if (ns->cmd == NETIO_CMD_C2S) { if (ns->cmd == NETIO_CMD_C2S) {
ns->state = NETIO_STATE_RECV_DATA; ns->state = NETIO_STATE_RECV_DATA;
} else if (ns->cmd == NETIO_CMD_S2C) { } else if (ns->cmd == NETIO_CMD_S2C) {
ns->state = NETIO_STATE_SEND_DATA; ns->state = NETIO_STATE_SEND_DATA;
/* start timer */ /* start timer */
ns->time_stamp = sys_now(); ns->time_stamp = sys_now();
/* send first round of data */ /* send first round of data */
len = tcp_sndbuf(pcb); len = tcp_sndbuf(pcb);
len = LWIP_MIN(len, ns->data_len - ns->cntr); len = LWIP_MIN(len, ns->data_len - ns->cntr);
len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos); len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
do { do {
err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY); err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
if (err == ERR_MEM) { if (err == ERR_MEM) {
len /= 2; len /= 2;
} }
} while ((err == ERR_MEM) && (len > 1)); } while ((err == ERR_MEM) && (len > 1));
ns->buf_pos += len; ns->buf_pos += len;
ns->cntr += len; ns->cntr += len;
} else { } else {
/* unrecognized command, punt */ /* unrecognized command, punt */
ns->cntr = 0; ns->cntr = 0;
ns->buf_pos = 0; ns->buf_pos = 0;
ns->buf_ptr[0] = 0; ns->buf_ptr[0] = 0;
netio_close(ns, pcb); netio_close(ns, pcb);
break; break;
} }
} }
} else { } else {
/* in trouble... shouldn't be in this state! */ /* in trouble... shouldn't be in this state! */
} }
} else if (ns->state == NETIO_STATE_RECV_DATA) { } else if (ns->state == NETIO_STATE_RECV_DATA) {
if(ns->cntr == 0){ if(ns->cntr == 0){
/* save the first byte of this new round of data /* save the first byte of this new round of data
* this will not match ns->buf_ptr[0] in the case that * this will not match ns->buf_ptr[0] in the case that
* NETIO_BUF_SIZE is less than ns->data_len. * NETIO_BUF_SIZE is less than ns->data_len.
*/ */
ns->first_byte = *data_ptr; ns->first_byte = *data_ptr;
} }
ns->buf_ptr[ns->buf_pos++] = *data_ptr++; ns->buf_ptr[ns->buf_pos++] = *data_ptr++;
ns->cntr++; ns->cntr++;
if (ns->buf_pos == NETIO_BUF_SIZE) { if (ns->buf_pos == NETIO_BUF_SIZE) {
/* circularize the buffer */ /* circularize the buffer */
ns->buf_pos = 0; ns->buf_pos = 0;
} }
if(ns->cntr == ns->data_len){ if(ns->cntr == ns->data_len){
ns->cntr = 0; ns->cntr = 0;
if (ns->first_byte != 0) { if (ns->first_byte != 0) {
/* if this last round did not start with 0, /* if this last round did not start with 0,
* go look for another command */ * go look for another command */
ns->state = NETIO_STATE_WAIT_FOR_CMD; ns->state = NETIO_STATE_WAIT_FOR_CMD;
ns->data_len = 0; ns->data_len = 0;
ns->cmd = 0; ns->cmd = 0;
/* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */ /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
} else { } else {
/* stay here and wait on more data */ /* stay here and wait on more data */
} }
} }
} else if (ns->state == NETIO_STATE_SEND_DATA } else if (ns->state == NETIO_STATE_SEND_DATA
|| ns->state == NETIO_STATE_SEND_DATA_LAST) { || ns->state == NETIO_STATE_SEND_DATA_LAST) {
/* I don't think this should happen... */ /* I don't think this should happen... */
} else { } else {
/* done / quit */ /* done / quit */
netio_close(ns, pcb); netio_close(ns, pcb);
break; break;
} /* end of ns->state condition */ } /* end of ns->state condition */
} /* end of while data still in this pbuf */ } /* end of while data still in this pbuf */
q = q->next; q = q->next;
} }
pbuf_free(p); pbuf_free(p);
} else { } else {
/* error or closed by other side */ /* error or closed by other side */
if (p != NULL) { if (p != NULL) {
pbuf_free(p); pbuf_free(p);
} }
/* close the connection */ /* close the connection */
netio_close(ns, pcb); netio_close(ns, pcb);
} }
return ERR_OK; return ERR_OK;
} }
static err_t ICACHE_FLASH_ATTR static err_t ICACHE_FLASH_ATTR
netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len) netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{ {
struct netio_state *ns = arg; struct netio_state *ns = arg;
err_t err = ERR_OK; err_t err = ERR_OK;
if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) { if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) {
/* done with this round of sending */ /* done with this round of sending */
ns->buf_pos = 0; ns->buf_pos = 0;
ns->cntr = 0; ns->cntr = 0;
/* check if timer expired */ /* check if timer expired */
if (sys_now() - ns->time_stamp > 600) { if (sys_now() - ns->time_stamp > 600) {
ns->buf_ptr[0] = 1; ns->buf_ptr[0] = 1;
ns->state = NETIO_STATE_SEND_DATA_LAST; ns->state = NETIO_STATE_SEND_DATA_LAST;
} else { } else {
ns->buf_ptr[0] = 0; ns->buf_ptr[0] = 0;
} }
} }
if(ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA){ if(ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA){
len = tcp_sndbuf(pcb); len = tcp_sndbuf(pcb);
len = LWIP_MIN(len, ns->data_len - ns->cntr); len = LWIP_MIN(len, ns->data_len - ns->cntr);
len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos); len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
if(ns->cntr < ns->data_len){ if(ns->cntr < ns->data_len){
do { do {
err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY); err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
if (err == ERR_MEM) { if (err == ERR_MEM) {
len /= 2; len /= 2;
} }
} while ((err == ERR_MEM) && (len > 1)); } while ((err == ERR_MEM) && (len > 1));
ns->buf_pos += len; ns->buf_pos += len;
if(ns->buf_pos >= NETIO_BUF_SIZE){ if(ns->buf_pos >= NETIO_BUF_SIZE){
ns->buf_pos = 0; ns->buf_pos = 0;
} }
ns->cntr += len; ns->cntr += len;
} }
} }
if(ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA_LAST){ 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 */ /* 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->state = NETIO_STATE_WAIT_FOR_CMD;
ns->cntr = 0; ns->cntr = 0;
/* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */ /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
} }
return ERR_OK; return ERR_OK;
} }
static err_t ICACHE_FLASH_ATTR static err_t ICACHE_FLASH_ATTR
netio_poll(void *arg, struct tcp_pcb *pcb) netio_poll(void *arg, struct tcp_pcb *pcb)
{ {
struct netio_state * ns = arg; struct netio_state * ns = arg;
if(ns->state == NETIO_STATE_SEND_DATA){ if(ns->state == NETIO_STATE_SEND_DATA){
} else if(ns->state == NETIO_STATE_DONE){ } else if(ns->state == NETIO_STATE_DONE){
netio_close(ns, pcb); netio_close(ns, pcb);
} }
return ERR_OK; return ERR_OK;
} }
#if NETIO_USE_STATIC_BUF == 1 #if NETIO_USE_STATIC_BUF == 1
static u8_t netio_buf[NETIO_BUF_SIZE]; static u8_t netio_buf[NETIO_BUF_SIZE];
#endif #endif
static err_t ICACHE_FLASH_ATTR static err_t ICACHE_FLASH_ATTR
netio_accept(void *arg, struct tcp_pcb *pcb, err_t err) netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{ {
struct netio_state * ns; struct netio_state * ns;
LWIP_UNUSED_ARG(err); LWIP_UNUSED_ARG(err);
ns = (struct netio_state *)mem_malloc(sizeof(struct netio_state)); ns = (struct netio_state *)mem_malloc(sizeof(struct netio_state));
if(ns == NULL){ if(ns == NULL){
return ERR_MEM; return ERR_MEM;
} }
ns->state = NETIO_STATE_WAIT_FOR_CMD; ns->state = NETIO_STATE_WAIT_FOR_CMD;
ns->data_len = 0; ns->data_len = 0;
ns->cmd = 0; ns->cmd = 0;
ns->cntr = 0; ns->cntr = 0;
ns->buf_pos = 0; ns->buf_pos = 0;
#if NETIO_USE_STATIC_BUF == 1 #if NETIO_USE_STATIC_BUF == 1
ns->buf_ptr = netio_buf; ns->buf_ptr = netio_buf;
#else #else
ns->buf_ptr = (u8_t *)mem_malloc(NETIO_BUF_SIZE); ns->buf_ptr = (u8_t *)mem_malloc(NETIO_BUF_SIZE);
if(ns->buf_ptr == NULL){ if(ns->buf_ptr == NULL){
mem_free(ns); mem_free(ns);
return ERR_MEM; return ERR_MEM;
} }
#endif #endif
ns->buf_ptr[0] = 0; ns->buf_ptr[0] = 0;
tcp_arg(pcb, ns); tcp_arg(pcb, ns);
tcp_sent(pcb, netio_sent); tcp_sent(pcb, netio_sent);
tcp_recv(pcb, netio_recv); tcp_recv(pcb, netio_recv);
tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */ tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */
return ERR_OK; return ERR_OK;
} }
void ICACHE_FLASH_ATTR netio_init(void) void ICACHE_FLASH_ATTR netio_init(void)
{ {
struct tcp_pcb *pcb; struct tcp_pcb *pcb;
pcb = tcp_new(); pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, 18767); tcp_bind(pcb, IP_ADDR_ANY, 18767);
pcb = tcp_listen(pcb); pcb = tcp_listen(pcb);
tcp_accept(pcb, netio_accept); tcp_accept(pcb, netio_accept);
} }
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
...@@ -5,7 +5,7 @@ ...@@ -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: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
...@@ -14,24 +14,24 @@ ...@@ -14,24 +14,24 @@
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of the lwIP TCP/IP stack. * This file is part of the lwIP TCP/IP stack.
* *
*/ */
/** /**
* This is an example of a "ping" sender (with raw API and socket API). * 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 * It can be used as a start point to maintain opened a network connection, or
* like a network "watchdog" for your device. * like a network "watchdog" for your device.
......
############################################################# #############################################################
# Required variables for each makefile # Required variables for each makefile
# Discard this section from all parent makefiles # Discard this section from all parent makefiles
# Expected variables (with automatic defaults): # Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir) # CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile) # SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated () # GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated () # GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form # COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into # subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a () # a generated lib/image xxx.a ()
# #
ifndef PDIR ifndef PDIR
GEN_LIBS = liblwipcore.a GEN_LIBS = liblwipcore.a
endif endif
############################################################# #############################################################
# Configuration i.e. compile options etc. # Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here! # Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the # Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden # makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein # for a subtree within the makefile rooted therein
# #
#DEFINES += #DEFINES +=
############################################################# #############################################################
# Recursion Magic - Don't touch this!! # Recursion Magic - Don't touch this!!
# #
# Each subtree potentially has an include directory # Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules # corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH # rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up # of a module can only contain the include directories up
# its parent path, and not its siblings # its parent path, and not its siblings
# #
# Required for each makefile to inherit from the parent # Required for each makefile to inherit from the parent
# #
INCLUDES := $(INCLUDES) -I $(PDIR)include INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./ INCLUDES += -I ./
PDIR := ../$(PDIR) PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile sinclude $(PDIR)Makefile
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
* Again with the aim of being simple, correct and fully portable. * Again with the aim of being simple, correct and fully portable.
* Byte swapping is the second thing you would want to optimize. You will * 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: * need to port it to your architecture and in your cc.h:
* *
* #define LWIP_PLATFORM_BYTESWAP 1 * #define LWIP_PLATFORM_BYTESWAP 1
* #define LWIP_PLATFORM_HTONS(x) <your_htons> * #define LWIP_PLATFORM_HTONS(x) <your_htons>
* #define LWIP_PLATFORM_HTONL(x) <your_htonl> * #define LWIP_PLATFORM_HTONL(x) <your_htonl>
......
...@@ -187,14 +187,14 @@ static void ICACHE_FLASH_ATTR ...@@ -187,14 +187,14 @@ static void ICACHE_FLASH_ATTR
dhcp_handle_nak(struct netif *netif) dhcp_handle_nak(struct netif *netif)
{ {
struct dhcp *dhcp = netif->dhcp; 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)); (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 */ /* Set the interface down since the address must no longer be used, as per RFC2131 */
netif_set_down(netif); netif_set_down(netif);
/* remove IP address from interface */ /* remove IP address from interface */
netif_set_ipaddr(netif, IP_ADDR_ANY); netif_set_ipaddr(netif, IP_ADDR_ANY);
netif_set_gw(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 */ /* Change to a defined state */
dhcp_set_state(dhcp, DHCP_BACKING_OFF); dhcp_set_state(dhcp, DHCP_BACKING_OFF);
/* We can immediately restart discovery */ /* We can immediately restart discovery */
...@@ -390,7 +390,7 @@ dhcp_fine_tmr() ...@@ -390,7 +390,7 @@ dhcp_fine_tmr()
break; 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) { if (netif->dhcp->request_timeout > 1) {
netif->dhcp->request_timeout--; netif->dhcp->request_timeout--;
} }
...@@ -582,7 +582,7 @@ dhcp_handle_ack(struct netif *netif) ...@@ -582,7 +582,7 @@ dhcp_handle_ack(struct netif *netif)
if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) { 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))); ip4_addr_set_u32(&dhcp->offered_gw_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER)));
} }
#if LWIP_DNS #if LWIP_DNS
/* DNS servers */ /* DNS servers */
n = 0; n = 0;
...@@ -687,7 +687,7 @@ dhcp_start(struct netif *netif) ...@@ -687,7 +687,7 @@ dhcp_start(struct netif *netif)
LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL); LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL);
LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL ); LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL );
} }
/* clear data structure */ /* clear data structure */
os_memset(dhcp, 0, sizeof(struct dhcp)); os_memset(dhcp, 0, sizeof(struct dhcp));
/* dhcp_set_state(&dhcp, DHCP_OFF); */ /* dhcp_set_state(&dhcp, DHCP_OFF); */
...@@ -1254,7 +1254,7 @@ dhcp_release(struct netif *netif) ...@@ -1254,7 +1254,7 @@ dhcp_release(struct netif *netif)
ip_addr_set_zero(&dhcp->offered_si_addr); ip_addr_set_zero(&dhcp->offered_si_addr);
#endif /* LWIP_DHCP_BOOTP_FILE */ #endif /* LWIP_DHCP_BOOTP_FILE */
dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
/* create and initialize the DHCP message header */ /* create and initialize the DHCP message header */
result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE); result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE);
if (result == ERR_OK) { if (result == ERR_OK) {
...@@ -1278,7 +1278,7 @@ dhcp_release(struct netif *netif) ...@@ -1278,7 +1278,7 @@ dhcp_release(struct netif *netif)
netif_set_ipaddr(netif, IP_ADDR_ANY); netif_set_ipaddr(netif, IP_ADDR_ANY);
netif_set_gw(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);
return result; return result;
} }
......
...@@ -49,13 +49,13 @@ ...@@ -49,13 +49,13 @@
* The lwIP version of the resolver also adds a non-blocking version of * The lwIP version of the resolver also adds a non-blocking version of
* gethostbyname() that will work with a raw API application. This function * 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. * 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 * 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 * 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 * issued and the function returns with a ERR_INPROGRESS status. The app
* using the dns client must then go into a waiting state. * using the dns client must then go into a waiting state.
* *
* Once a hostname has been resolved (or found to be non-existent), * 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). * must be implemented by the module that uses the resolver).
*/ */
...@@ -238,7 +238,7 @@ dns_init() ...@@ -238,7 +238,7 @@ dns_init()
ip_addr_t dnsserver; ip_addr_t dnsserver;
// dns_payload = (u8_t *)LWIP_MEM_ALIGN(dns_payload_buffer); // dns_payload = (u8_t *)LWIP_MEM_ALIGN(dns_payload_buffer);
/* initialize default DNS server address */ /* initialize default DNS server address */
DNS_SERVER_ADDRESS(&dnsserver); DNS_SERVER_ADDRESS(&dnsserver);
...@@ -660,7 +660,7 @@ dns_check_entry(u8_t i) ...@@ -660,7 +660,7 @@ dns_check_entry(u8_t i)
pEntry->numdns = 0; pEntry->numdns = 0;
pEntry->tmr = 1; pEntry->tmr = 1;
pEntry->retries = 0; pEntry->retries = 0;
/* send DNS packet for this entry */ /* send DNS packet for this entry */
err = dns_send(pEntry->numdns, pEntry->name, i); err = dns_send(pEntry->numdns, pEntry->name, i);
if (err != ERR_OK) { 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 ...@@ -773,7 +773,7 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t
goto memerr; 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) { 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. */ /* The ID in the DNS header should be our entry into the name table. */
hdr = (struct dns_hdr*)dns_payload; hdr = (struct dns_hdr*)dns_payload;
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
/* /*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved. * All rights reserved.
* *
* 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: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
...@@ -17,21 +17,21 @@ ...@@ -17,21 +17,21 @@
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of the lwIP TCP/IP stack. * This file is part of the lwIP TCP/IP stack.
* *
* Author: Adam Dunkels <adam@sics.se> * Author: Adam Dunkels <adam@sics.se>
* *
*/ */
...@@ -280,35 +280,35 @@ lwip_init(void) ...@@ -280,35 +280,35 @@ lwip_init(void)
pbuf_init(); pbuf_init();
netif_init(); netif_init();
#if LWIP_SOCKET #if LWIP_SOCKET
lwip_socket_init(); lwip_socket_init();
#endif /* LWIP_SOCKET */ #endif /* LWIP_SOCKET */
ip_init(); ip_init();
#if LWIP_ARP #if LWIP_ARP
etharp_init(); etharp_init();
#endif /* LWIP_ARP */ #endif /* LWIP_ARP */
#if LWIP_RAW #if LWIP_RAW
raw_init(); raw_init();
#endif /* LWIP_RAW */ #endif /* LWIP_RAW */
#if LWIP_UDP #if LWIP_UDP
udp_init(); udp_init();
#endif /* LWIP_UDP */ #endif /* LWIP_UDP */
#if LWIP_TCP #if LWIP_TCP
tcp_init(); tcp_init();
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
#if LWIP_SNMP #if LWIP_SNMP
snmp_init(); snmp_init();
#endif /* LWIP_SNMP */ #endif /* LWIP_SNMP */
#if LWIP_AUTOIP #if LWIP_AUTOIP
autoip_init(); autoip_init();
#endif /* LWIP_AUTOIP */ #endif /* LWIP_AUTOIP */
#if LWIP_IGMP #if LWIP_IGMP
igmp_init(); 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