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