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
070973e6
Commit
070973e6
authored
Jul 06, 2017
by
devsaurus
Browse files
Port net module to netconn API.
parent
5ee043cf
Changes
2
Hide whitespace changes
Inline
Side-by-side
components/modules/net.c
View file @
070973e6
...
...
@@ -11,12 +11,12 @@
#include <stdlib.h>
#include <string.h>
#include "lwip/api.h"
#include "lwip/err.h"
#include "lwip/ip_addr.h"
#include "lwip/dns.h"
#include "lwip/igmp.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
// Some LWIP macros cause complaints with ptr NULL checks, so shut them off :(
#pragma GCC diagnostic ignored "-Waddress"
...
...
@@ -44,11 +44,8 @@ static const net_table_name NET_TABLES[] = {
typedef
struct
lnet_userdata
{
enum
net_type
type
;
int
self_ref
;
union
{
struct
tcp_pcb
*
tcp_pcb
;
struct
udp_pcb
*
udp_pcb
;
void
*
pcb
;
};
uint16_t
port
;
struct
netconn
*
netconn
;
union
{
struct
{
int
cb_accept_ref
;
...
...
@@ -59,8 +56,11 @@ typedef struct lnet_userdata {
int
cb_dns_ref
;
int
cb_receive_ref
;
int
cb_sent_ref
;
bool
closing
;
// Only for TCP:
bool
connecting
;
int
hold
;
size_t
num_held
;
int
cb_connect_ref
;
int
cb_disconnect_ref
;
int
cb_reconnect_ref
;
...
...
@@ -69,17 +69,8 @@ typedef struct lnet_userdata {
}
lnet_userdata
;
// --- Event handling
typedef
struct
{
ip_addr_t
src_ip
;
uint16_t
src_port
;
uint16_t
payload_len
;
char
payload
[
0
];
}
lnet_recvdata
;
typedef
struct
{
enum
{
DNSFOUND
,
...
...
@@ -95,10 +86,8 @@ typedef struct {
int
cb_ref
;
};
union
{
struct
tcp_pcb
*
accept_newpcb
;
lnet_recvdata
recvdata
;
ip_addr_t
resolved_ip
;
int
err
;
ip_addr_t
resolved_ip
;
int
err
;
};
}
lnet_event
;
...
...
@@ -140,7 +129,7 @@ lnet_userdata *net_create( lua_State *L, enum net_type type ) {
ud
->
type
=
type
;
ud
->
self_ref
=
LUA_NOREF
;
ud
->
pcb
=
NULL
;
ud
->
netconn
=
NULL
;
switch
(
type
)
{
case
TYPE_TCP_CLIENT
:
...
...
@@ -148,7 +137,10 @@ lnet_userdata *net_create( lua_State *L, enum net_type type ) {
ud
->
client
.
cb_reconnect_ref
=
LUA_NOREF
;
ud
->
client
.
cb_disconnect_ref
=
LUA_NOREF
;
ud
->
client
.
hold
=
0
;
ud
->
client
.
num_held
=
0
;
ud
->
client
.
connecting
=
false
;
case
TYPE_UDP_SOCKET
:
ud
->
client
.
closing
=
false
;
ud
->
client
.
wait_dns
=
0
;
ud
->
client
.
cb_dns_ref
=
LUA_NOREF
;
ud
->
client
.
cb_receive_ref
=
LUA_NOREF
;
...
...
@@ -177,14 +169,6 @@ static bool post_net_err (lnet_userdata *ud, err_t err) {
return
true
;
}
static
void
net_err_cb
(
void
*
arg
,
err_t
err
)
{
lnet_userdata
*
ud
=
(
lnet_userdata
*
)
arg
;
if
(
!
ud
||
ud
->
type
!=
TYPE_TCP_CLIENT
||
ud
->
self_ref
==
LUA_NOREF
)
return
;
ud
->
pcb
=
NULL
;
// Will be freed at LWIP level
post_net_err
(
ud
,
err
);
}
static
bool
post_net_connected
(
lnet_userdata
*
ud
)
{
lnet_event
*
ev
=
(
lnet_event
*
)
malloc
(
sizeof
(
lnet_event
));
...
...
@@ -199,17 +183,6 @@ static bool post_net_connected (lnet_userdata *ud) {
return
true
;
}
static
err_t
net_connected_cb
(
void
*
arg
,
struct
tcp_pcb
*
tpcb
,
err_t
err
)
{
lnet_userdata
*
ud
=
(
lnet_userdata
*
)
arg
;
if
(
!
ud
||
ud
->
pcb
!=
tpcb
)
return
ERR_ABRT
;
if
(
err
!=
ERR_OK
)
{
net_err_cb
(
arg
,
err
);
return
ERR_ABRT
;
}
post_net_connected
(
ud
);
return
ERR_OK
;
}
static
bool
post_net_dns
(
lnet_userdata
*
ud
,
const
char
*
name
,
const
ip_addr_t
*
ipaddr
)
{
...
...
@@ -237,21 +210,15 @@ static void net_dns_cb(const char *name, const ip_addr_t *ipaddr, void *arg) {
}
static
bool
post_net_recv
(
lnet_userdata
*
ud
,
struct
pbuf
*
p
,
const
ip_addr_t
*
ip
,
u16_t
port
)
static
bool
post_net_recv
(
lnet_userdata
*
ud
)
{
lnet_event
*
ev
=
(
lnet_event
*
)
malloc
(
sizeof
(
lnet_event
)
+
p
->
len
);
lnet_event
*
ev
=
(
lnet_event
*
)
malloc
(
sizeof
(
lnet_event
)
/*
+ p->len
*/
);
if
(
!
ev
)
return
false
;
ev
->
event
=
RECVDATA
;
ev
->
ud
=
ud
;
if
(
ip
)
ev
->
recvdata
.
src_ip
=
*
ip
;
ev
->
recvdata
.
src_port
=
port
;
ev
->
recvdata
.
payload_len
=
p
->
len
;
pbuf_copy_partial
(
p
,
&
ev
->
recvdata
.
payload
,
p
->
len
,
0
);
if
(
!
task_post_high
(
net_event
,
(
task_param_t
)
ev
))
{
free
(
ev
);
...
...
@@ -260,30 +227,6 @@ static bool post_net_recv (lnet_userdata *ud, struct pbuf *p, const ip_addr_t *i
return
true
;
}
static
void
net_udp_recv_cb
(
void
*
arg
,
struct
udp_pcb
*
pcb
,
struct
pbuf
*
p
,
const
ip_addr_t
*
addr
,
u16_t
port
)
{
lnet_userdata
*
ud
=
(
lnet_userdata
*
)
arg
;
if
(
!
ud
||
!
ud
->
pcb
||
ud
->
type
!=
TYPE_UDP_SOCKET
||
ud
->
self_ref
==
LUA_NOREF
)
{
if
(
p
)
pbuf_free
(
p
);
return
;
}
post_net_recv
(
ud
,
p
,
addr
,
port
);
}
static
err_t
net_tcp_recv_cb
(
void
*
arg
,
struct
tcp_pcb
*
tpcb
,
struct
pbuf
*
p
,
err_t
err
)
{
lnet_userdata
*
ud
=
(
lnet_userdata
*
)
arg
;
if
(
!
ud
||
!
ud
->
pcb
||
ud
->
type
!=
TYPE_TCP_CLIENT
||
ud
->
self_ref
==
LUA_NOREF
)
return
ERR_ABRT
;
if
(
!
p
)
{
net_err_cb
(
arg
,
err
);
return
tcp_close
(
tpcb
);
}
if
(
post_net_recv
(
ud
,
p
,
0
,
0
))
tcp_recved
(
tpcb
,
ud
->
client
.
hold
?
0
:
TCP_WND
(
tpcb
));
return
ERR_OK
;
}
static
bool
post_net_sent
(
lnet_userdata
*
ud
)
{
lnet_event
*
ev
=
(
lnet_event
*
)
malloc
(
sizeof
(
lnet_event
));
...
...
@@ -298,24 +241,13 @@ static bool post_net_sent (lnet_userdata *ud) {
return
true
;
}
static
err_t
net_sent_cb
(
void
*
arg
,
struct
tcp_pcb
*
tpcb
,
u16_t
len
)
{
lnet_userdata
*
ud
=
(
lnet_userdata
*
)
arg
;
if
(
!
ud
||
!
ud
->
pcb
||
ud
->
type
!=
TYPE_TCP_CLIENT
||
ud
->
self_ref
==
LUA_NOREF
)
return
ERR_ABRT
;
if
(
ud
->
client
.
cb_sent_ref
==
LUA_NOREF
)
return
ERR_OK
;
post_net_sent
(
ud
);
// TODO: if we can't post this, we effectively stall this socket, how to fix?
return
ERR_OK
;
}
static
bool
post_net_accept
(
lnet_userdata
*
ud
,
struct
tcp_pcb
*
newpcb
)
{
static
bool
post_net_accept
(
lnet_userdata
*
ud
)
{
lnet_event
*
ev
=
(
lnet_event
*
)
malloc
(
sizeof
(
lnet_event
));
if
(
!
ev
)
return
false
;
ev
->
event
=
ACCEPT
;
ev
->
ud
=
ud
;
ev
->
accept_newpcb
=
newpcb
;
if
(
!
task_post_medium
(
net_event
,
(
task_param_t
)
ev
))
{
free
(
ev
);
return
false
;
...
...
@@ -324,14 +256,103 @@ static bool post_net_accept (lnet_userdata *ud, struct tcp_pcb *newpcb) {
}
static
err_t
net_accept_cb
(
void
*
arg
,
struct
tcp_pcb
*
newpcb
,
err_t
err
)
{
lnet_userdata
*
ud
=
(
lnet_userdata
*
)
arg
;
if
(
!
ud
||
ud
->
type
!=
TYPE_TCP_SERVER
||
!
ud
->
pcb
)
return
ERR_ABRT
;
if
(
ud
->
self_ref
==
LUA_NOREF
||
ud
->
server
.
cb_accept_ref
==
LUA_NOREF
)
return
ERR_ABRT
;
static
void
lnet_netconn_callback
(
struct
netconn
*
netconn
,
enum
netconn_evt
evt
,
u16_t
len
)
{
SYS_ARCH_DECL_PROTECT
(
lev
);
if
(
!
netconn
)
return
;
SYS_ARCH_PROTECT
(
lev
);
if
(
netconn
->
socket
<
0
)
{
if
(
evt
==
NETCONN_EVT_RCVPLUS
&&
len
>
0
)
{
// data received before userdata was set up, note receive event
netconn
->
socket
--
;
}
SYS_ARCH_UNPROTECT
(
lev
);
return
;
}
SYS_ARCH_UNPROTECT
(
lev
);
lnet_userdata
*
ud
=
(
lnet_userdata
*
)
netconn
->
socket
;
if
(
!
ud
||
!
ud
->
netconn
)
return
;
if
(
ud
->
type
==
TYPE_TCP_CLIENT
||
ud
->
type
==
TYPE_UDP_SOCKET
)
{
// if a previous event triggered to close the connection then skip further event processing
if
(
ud
->
client
.
closing
)
return
;
switch
(
evt
)
{
case
NETCONN_EVT_SENDPLUS
:
if
(
ud
->
type
==
TYPE_TCP_CLIENT
&&
ud
->
client
.
connecting
)
{
// connection established, trigger Lua callback
ud
->
client
.
connecting
=
false
;
post_net_connected
(
ud
);
}
else
if
(
len
>
0
)
{
// data sent, trigger Lua callback
post_net_sent
(
ud
);
}
break
;
case
NETCONN_EVT_ERROR
:
post_net_err
(
ud
,
netconn_err
(
ud
->
netconn
));
ud
->
client
.
closing
=
true
;
break
;
case
NETCONN_EVT_RCVPLUS
:
if
(
len
>
0
)
{
// data received, collect it in Lua callback
post_net_recv
(
ud
);
}
else
{
// signals closed connection from peer
post_net_err
(
ud
,
0
);
ud
->
client
.
closing
=
true
;
}
break
;
default:
break
;
}
return
post_net_accept
(
ud
,
newpcb
)
?
ERR_OK
:
ERR_ABRT
;
}
else
if
(
ud
->
type
==
TYPE_TCP_SERVER
)
{
switch
(
evt
)
{
case
NETCONN_EVT_RCVPLUS
:
// new connection available from netconn_listen()
if
(
ud
->
netconn
&&
ud
->
self_ref
!=
LUA_NOREF
&&
ud
->
server
.
cb_accept_ref
!=
LUA_NOREF
)
{
post_net_accept
(
ud
);
}
break
;
// no error callback for server type
case
NETCONN_EVT_ERROR
:
post_net_err
(
ud
,
netconn_err
(
ud
->
netconn
));
break
;
default:
break
;
}
}
}
// workaround for https://github.com/espressif/esp-idf/issues/784
#include "lwip/priv/api_msg.h"
#define NETCONN_DELETE(conn) \
if (netconn_delete(conn) == ERR_OK) netconn_free(conn);
#define NETCONN_CLOSE(conn) netconn_close_wa(conn);
static
void
netconn_close_wa
(
struct
netconn
*
conn
)
{
if
(
netconn_close
(
conn
)
!=
ERR_OK
)
{
NETCONN_DELETE
(
conn
);
}
else
{
netconn_free
(
conn
);
}
}
// --- Lua API - create
extern
int
tls_socket_create
(
lua_State
*
L
);
...
...
@@ -402,7 +423,7 @@ int net_listen( lua_State *L ) {
lnet_userdata
*
ud
=
net_get_udata
(
L
);
if
(
!
ud
||
ud
->
type
==
TYPE_TCP_CLIENT
)
return
luaL_error
(
L
,
"invalid user data"
);
if
(
ud
->
pcb
)
if
(
ud
->
netconn
)
return
luaL_error
(
L
,
"already listening"
);
int
stack
=
2
;
uint16_t
port
=
0
;
...
...
@@ -428,39 +449,39 @@ int net_listen( lua_State *L ) {
err_t
err
=
ERR_OK
;
switch
(
ud
->
type
)
{
case
TYPE_TCP_SERVER
:
ud
->
tcp_pcb
=
tcp_new
();
if
(
!
ud
->
tcp_pcb
)
return
luaL_error
(
L
,
"cannot allocate PCB"
);
err
=
tcp_bind
(
ud
->
tcp_pcb
,
&
addr
,
port
);
ud
->
netconn
=
netconn_new_with_callback
(
NETCONN_TCP
,
lnet_netconn_callback
);
if
(
!
ud
->
netconn
)
return
luaL_error
(
L
,
"cannot allocate netconn"
);
ud
->
netconn
->
socket
=
(
int
)
ud
;
netconn_set_nonblocking
(
ud
->
netconn
,
1
);
netconn_set_noautorecved
(
ud
->
netconn
,
1
);
err
=
netconn_bind
(
ud
->
netconn
,
&
addr
,
port
);
if
(
err
==
ERR_OK
)
{
tcp_arg
(
ud
->
tcp_pcb
,
ud
);
struct
tcp_pcb
*
pcb
=
tcp_listen
(
ud
->
tcp_pcb
);
if
(
!
pcb
)
{
err
=
ERR_MEM
;
}
else
{
ud
->
tcp_pcb
=
pcb
;
tcp_accept
(
ud
->
tcp_pcb
,
net_accept_cb
);
}
err
=
netconn_listen
(
ud
->
netconn
);
}
break
;
case
TYPE_UDP_SOCKET
:
ud
->
udp_pcb
=
udp_new
();
if
(
!
ud
->
udp_pcb
)
return
luaL_error
(
L
,
"cannot allocate PCB"
);
udp_recv
(
ud
->
udp_pcb
,
net_udp_recv_cb
,
ud
);
err
=
udp_bind
(
ud
->
udp_pcb
,
&
addr
,
port
);
ud
->
netconn
=
netconn_new_with_callback
(
NETCONN_UDP
,
lnet_netconn_callback
);
if
(
!
ud
->
netconn
)
return
luaL_error
(
L
,
"cannot allocate netconn"
);
ud
->
netconn
->
socket
=
(
int
)
ud
;
netconn_set_nonblocking
(
ud
->
netconn
,
1
);
netconn_set_noautorecved
(
ud
->
netconn
,
1
);
err
=
netconn_bind
(
ud
->
netconn
,
&
addr
,
port
);
break
;
default:
break
;
}
if
(
err
!=
ERR_OK
)
{
switch
(
ud
->
type
)
{
case
TYPE_TCP_SERVER
:
tcp_close
(
ud
->
tcp_pcb
);
ud
->
tcp_pcb
=
NULL
;
NETCONN_CLOSE
(
ud
->
netconn
);
ud
->
netconn
=
NULL
;
break
;
case
TYPE_UDP_SOCKET
:
udp_remove
(
ud
->
udp_pcb
);
ud
->
udp_pcb
=
NULL
;
NETCONN_CLOSE
(
ud
->
netconn
);
ud
->
netconn
=
NULL
;
break
;
default:
break
;
}
...
...
@@ -478,7 +499,7 @@ int net_connect( lua_State *L ) {
lnet_userdata
*
ud
=
net_get_udata
(
L
);
if
(
!
ud
||
ud
->
type
!=
TYPE_TCP_CLIENT
)
return
luaL_error
(
L
,
"invalid user data"
);
if
(
ud
->
pcb
)
if
(
ud
->
netconn
)
return
luaL_error
(
L
,
"already connected"
);
uint16_t
port
=
luaL_checkinteger
(
L
,
2
);
if
(
port
==
0
)
...
...
@@ -488,14 +509,15 @@ int net_connect( lua_State *L ) {
size_t
dl
=
0
;
domain
=
luaL_checklstring
(
L
,
3
,
&
dl
);
}
ud
->
tcp_pcb
=
tcp_new
();
if
(
!
ud
->
tcp_pcb
)
return
luaL_error
(
L
,
"cannot allocate PCB"
);
tcp_arg
(
ud
->
tcp_pcb
,
ud
);
tcp_err
(
ud
->
tcp_pcb
,
net_err_cb
);
tcp_recv
(
ud
->
tcp_pcb
,
net_tcp_recv_cb
);
tcp_sent
(
ud
->
tcp_pcb
,
net_sent_cb
);
ud
->
tcp_pcb
->
remote_port
=
port
;
ud
->
netconn
=
netconn_new_with_callback
(
NETCONN_TCP
,
lnet_netconn_callback
);
if
(
!
ud
->
netconn
)
return
luaL_error
(
L
,
"cannot allocate netconn"
);
ud
->
netconn
->
socket
=
(
int
)
ud
;
netconn_set_nonblocking
(
ud
->
netconn
,
1
);
netconn_set_noautorecved
(
ud
->
netconn
,
1
);
ud
->
port
=
port
;
ip_addr_t
addr
;
ud
->
client
.
wait_dns
++
;
int
unref
=
0
;
...
...
@@ -504,6 +526,7 @@ int net_connect( lua_State *L ) {
lua_pushvalue
(
L
,
1
);
ud
->
self_ref
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
}
err_t
err
=
dns_gethostbyname
(
domain
,
&
addr
,
net_dns_cb
,
ud
);
if
(
err
==
ERR_OK
)
{
net_dns_cb
(
domain
,
&
addr
,
ud
);
...
...
@@ -513,8 +536,8 @@ int net_connect( lua_State *L ) {
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
ud
->
self_ref
);
ud
->
self_ref
=
LUA_NOREF
;
}
tcp_abort
(
ud
->
tcp_pcb
);
ud
->
tcp_pcb
=
NULL
;
NETCONN_CLOSE
(
ud
->
netconn
);
ud
->
netconn
=
NULL
;
return
lwip_lua_checkerr
(
L
,
err
);
}
return
0
;
...
...
@@ -586,16 +609,16 @@ int net_send( lua_State *L ) {
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
ud
->
client
.
cb_sent_ref
);
ud
->
client
.
cb_sent_ref
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
}
if
(
ud
->
type
==
TYPE_UDP_SOCKET
&&
!
ud
->
pcb
)
{
ud
->
udp_pcb
=
udp_new
();
if
(
!
ud
->
udp_pcb
)
return
luaL_error
(
L
,
"cannot allocate PCB"
);
udp_recv
(
ud
->
udp_pcb
,
net_udp_recv_cb
,
ud
);
ip_addr_t
laddr
=
IPADDR_ANY_TYPE_INIT
;
err_t
err
=
udp
_bind
(
ud
->
udp_pcb
,
&
laddr
,
0
);
if
(
ud
->
type
==
TYPE_UDP_SOCKET
&&
!
ud
->
netconn
)
{
ud
->
netconn
=
netconn_new_with_callback
(
NETCONN_UDP
,
lnet_netconn_callback
);
if
(
!
ud
->
netconn
)
return
luaL_error
(
L
,
"cannot allocate netconn"
);
ud
->
netconn
->
socket
=
(
int
)
ud
;
err_t
err
=
netconn
_bind
(
ud
->
netconn
,
IP_ADDR_ANY
,
0
);
if
(
err
!=
ERR_OK
)
{
udp_remove
(
ud
->
udp_pcb
);
ud
->
udp_pcb
=
NULL
;
NETCONN_CLOSE
(
ud
->
netconn
);
ud
->
netconn
=
NULL
;
return
lwip_lua_checkerr
(
L
,
err
);
}
if
(
ud
->
self_ref
==
LUA_NOREF
)
{
...
...
@@ -603,23 +626,27 @@ int net_send( lua_State *L ) {
ud
->
self_ref
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
}
}
if
(
!
ud
->
pcb
||
ud
->
self_ref
==
LUA_NOREF
)
if
(
!
ud
->
netconn
||
ud
->
self_ref
==
LUA_NOREF
)
return
luaL_error
(
L
,
"not connected"
);
err_t
err
;
if
(
ud
->
type
==
TYPE_UDP_SOCKET
)
{
struct
p
buf
*
pb
=
pbuf_alloc
(
PBUF_TRANSPORT
,
datalen
,
PBUF_RAM
);
if
(
!
p
b
)
struct
net
buf
*
buf
=
netbuf_new
(
);
if
(
!
b
uf
||
!
netbuf_alloc
(
buf
,
datalen
)
)
return
luaL_error
(
L
,
"cannot allocate message buffer"
);
pbuf_take
(
pb
,
data
,
datalen
);
err
=
udp_sendto
(
ud
->
udp_pcb
,
pb
,
&
addr
,
port
);
pbuf_free
(
pb
);
netbuf_take
(
buf
,
data
,
datalen
);
err
=
netconn_sendto
(
ud
->
netconn
,
buf
,
&
addr
,
port
);
netbuf_delete
(
buf
);
if
(
ud
->
client
.
cb_sent_ref
!=
LUA_NOREF
)
{
lua_rawgeti
(
L
,
LUA_REGISTRYINDEX
,
ud
->
client
.
cb_sent_ref
);
lua_rawgeti
(
L
,
LUA_REGISTRYINDEX
,
ud
->
self_ref
);
lua_call
(
L
,
1
,
0
);
}
}
else
if
(
ud
->
type
==
TYPE_TCP_CLIENT
)
{
err
=
tcp_write
(
ud
->
tcp_pcb
,
data
,
datalen
,
TCP_WRITE_FLAG_COPY
);
size_t
bytes_written
;
err
=
netconn_write_partly
(
ud
->
netconn
,
data
,
datalen
,
NETCONN_COPY
,
&
bytes_written
);
}
else
{
err
=
ERR_VAL
;
...
...
@@ -632,9 +659,10 @@ int net_hold( lua_State *L ) {
lnet_userdata
*
ud
=
net_get_udata
(
L
);
if
(
!
ud
||
ud
->
type
!=
TYPE_TCP_CLIENT
)
return
luaL_error
(
L
,
"invalid user data"
);
if
(
!
ud
->
client
.
hold
&&
ud
->
tcp_pcb
)
if
(
!
ud
->
client
.
hold
&&
ud
->
netconn
)
{
ud
->
client
.
hold
=
1
;
ud
->
client
.
num_held
=
0
;
}
return
0
;
}
...
...
@@ -644,11 +672,10 @@ int net_unhold( lua_State *L ) {
lnet_userdata
*
ud
=
net_get_udata
(
L
);
if
(
!
ud
||
ud
->
type
!=
TYPE_TCP_CLIENT
)
return
luaL_error
(
L
,
"invalid user data"
);
if
(
ud
->
client
.
hold
&&
ud
->
tcp_pcb
)
if
(
ud
->
client
.
hold
&&
ud
->
netconn
)
{
ud
->
client
.
hold
=
0
;
ud
->
tcp_pcb
->
flags
|=
TF_ACK_NOW
;
tcp_recved
(
ud
->
tcp_pcb
,
TCP_WND
(
ud
->
tcp_pcb
));
netconn_recved
(
ud
->
netconn
,
ud
->
client
.
num_held
);
}
return
0
;
}
...
...
@@ -696,13 +723,16 @@ int net_getpeer( lua_State *L ) {
lnet_userdata
*
ud
=
net_get_udata
(
L
);
if
(
!
ud
||
ud
->
type
!=
TYPE_TCP_CLIENT
)
return
luaL_error
(
L
,
"invalid user data"
);
if
(
!
ud
->
pcb
)
{
if
(
!
ud
->
netconn
)
{
lua_pushnil
(
L
);
lua_pushnil
(
L
);
return
2
;
}
uint16_t
port
=
ud
->
tcp_pcb
->
remote_port
;
ip_addr_t
addr
=
ud
->
tcp_pcb
->
remote_ip
;
uint16_t
port
;
ip_addr_t
addr
;
netconn_peer
(
ud
->
netconn
,
&
addr
,
&
port
);
if
(
port
==
0
)
{
lua_pushnil
(
L
);
lua_pushnil
(
L
);
...
...
@@ -719,7 +749,7 @@ int net_getpeer( lua_State *L ) {
int
net_getaddr
(
lua_State
*
L
)
{
lnet_userdata
*
ud
=
net_get_udata
(
L
);
if
(
!
ud
)
return
luaL_error
(
L
,
"invalid user data"
);
if
(
!
ud
->
pcb
)
{
if
(
!
ud
->
netconn
)
{
lua_pushnil
(
L
);
lua_pushnil
(
L
);
return
2
;
...
...
@@ -729,13 +759,10 @@ int net_getaddr( lua_State *L ) {
switch
(
ud
->
type
)
{
case
TYPE_TCP_CLIENT
:
case
TYPE_TCP_SERVER
:
addr
=
ud
->
tcp_pcb
->
local_ip
;
port
=
ud
->
tcp_pcb
->
local_port
;
break
;
case
TYPE_UDP_SOCKET
:
addr
=
ud
->
udp_pcb
->
local_ip
;
port
=
ud
->
udp_pcb
->
local_port
;
netconn_addr
(
ud
->
netconn
,
&
addr
,
&
port
);
break
;
default:
break
;
}
if
(
port
==
0
)
{
lua_pushnil
(
L
);
...
...
@@ -753,29 +780,21 @@ int net_getaddr( lua_State *L ) {
int
net_close
(
lua_State
*
L
)
{
lnet_userdata
*
ud
=
net_get_udata
(
L
);
if
(
!
ud
)
return
luaL_error
(
L
,
"invalid user data"
);
if
(
ud
->
pcb
)
{
if
(
ud
->
netconn
)
{
switch
(
ud
->
type
)
{
case
TYPE_TCP_CLIENT
:
if
(
ERR_OK
!=
tcp_close
(
ud
->
tcp_pcb
))
{
tcp_arg
(
ud
->
tcp_pcb
,
NULL
);
tcp_abort
(
ud
->
tcp_pcb
);
}
ud
->
tcp_pcb
=
NULL
;
break
;
case
TYPE_TCP_SERVER
:
tcp_close
(
ud
->
tcp_pcb
);
ud
->
tcp_pcb
=
NULL
;
break
;
case
TYPE_UDP_SOCKET
:
udp_remove
(
ud
->
udp_pcb
);
ud
->
udp_pcb
=
NULL
;
NETCONN_CLOSE
(
ud
->
netconn
);
ud
->
netconn
=
NULL
;
break
;
default:
break
;
}
}
else
{
return
luaL_error
(
L
,
"not connected"
);
}
if
(
ud
->
type
==
TYPE_TCP_SERVER
||
(
ud
->
pcb
==
NULL
&&
ud
->
client
.
wait_dns
==
0
))
{
(
ud
->
netconn
==
NULL
&&
ud
->
client
.
wait_dns
==
0
))
{
lua_gc
(
L
,
LUA_GCSTOP
,
0
);
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
ud
->
self_ref
);
ud
->
self_ref
=
LUA_NOREF
;
...
...
@@ -787,21 +806,15 @@ int net_close( lua_State *L ) {
int
net_delete
(
lua_State
*
L
)
{
lnet_userdata
*
ud
=
net_get_udata
(
L
);
if
(
!
ud
)
return
luaL_error
(
L
,
"no user data"
);
if
(
ud
->
pcb
)
{
if
(
ud
->
netconn
)
{
switch
(
ud
->
type
)
{
case
TYPE_TCP_CLIENT
:
tcp_arg
(
ud
->
tcp_pcb
,
NULL
);
tcp_abort
(
ud
->
tcp_pcb
);
ud
->
tcp_pcb
=
NULL
;
break
;
case
TYPE_TCP_SERVER
:
tcp_close
(
ud
->
tcp_pcb
);
ud
->
tcp_pcb
=
NULL
;
break
;
case
TYPE_UDP_SOCKET
:
udp_remove
(
ud
->
udp_pcb
);
ud
->
udp_pcb
=
NULL
;
NETCONN_CLOSE
(
ud
->
netconn
);
ud
->
netconn
=
NULL
;
break
;
default:
break
;
}
}
switch
(
ud
->
type
)
{
...
...
@@ -982,9 +995,10 @@ static void ldnsfound_cb (lua_State *L, lnet_userdata *ud, ip_addr_t *addr) {
lua_call
(
L
,
2
,
0
);
}
ud
->
client
.
wait_dns
--
;
if
(
ud
->
pcb
&&
ud
->
type
==
TYPE_TCP_CLIENT
&&
ud
->
tcp_pcb
->
state
==
CLOSED
)
{
tcp_connect
(
ud
->
tcp_pcb
,
addr
,
ud
->
tcp_pcb
->
remote_port
,
net_connected_cb
);
}
else
if
(
!
ud
->
pcb
&&
ud
->
client
.
wait_dns
==
0
)
{
if
(
ud
->
netconn
&&
ud
->
type
==
TYPE_TCP_CLIENT
&&
!
ud
->
client
.
connecting
)
{
ud
->
client
.
connecting
=
true
;
netconn_connect
(
ud
->
netconn
,
addr
,
ud
->
port
);
}
else
if
(
!
ud
->
netconn
&&
ud
->
client
.
wait_dns
==
0
)
{
lua_gc
(
L
,
LUA_GCSTOP
,
0
);
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
ud
->
self_ref
);
ud
->
self_ref
=
LUA_NOREF
;
...
...
@@ -1017,40 +1031,89 @@ static void lconnected_cb (lua_State *L, lnet_userdata *ud) {
}
}
static
void
laccept_cb
(
lua_State
*
L
,
lnet_userdata
*
ud
,
struct
tcp_pcb
*
newpcb
)
{
static
void
laccept_cb
(
lua_State
*
L
,
lnet_userdata
*
ud
)
{
SYS_ARCH_DECL_PROTECT
(
lev
);
lua_rawgeti
(
L
,
LUA_REGISTRYINDEX
,
ud
->
server
.
cb_accept_ref
);
lnet_userdata
*
nud
=
net_create
(
L
,
TYPE_TCP_CLIENT
);
lua_pushvalue
(
L
,
-
1
);
nud
->
self_ref
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
nud
->
tcp_pcb
=
newpcb
;
tcp_arg
(
nud
->
tcp_pcb
,
nud
);
tcp_err
(
nud
->
tcp_pcb
,
net_err_cb
);
tcp_recv
(
nud
->
tcp_pcb
,
net_tcp_recv_cb
);
tcp_sent
(
nud
->
tcp_pcb
,
net_sent_cb
);
nud
->
tcp_pcb
->
so_options
|=
SOF_KEEPALIVE
;
nud
->
tcp_pcb
->
keep_idle
=
ud
->
server
.
timeout
*
1000
;
nud
->
tcp_pcb
->
keep_cnt
=
1
;
tcp_accepted
(
ud
->
tcp_pcb
);
int
recvevent
=
0
;
struct
netconn
*
newconn
;
err_t
err
=
netconn_accept
(
ud
->
netconn
,
&
newconn
);
if
(
err
==
ERR_OK
)
{
nud
->
netconn
=
newconn
;
SYS_ARCH_PROTECT
(
lev
);
// take buffered receive events
recvevent
=
(
int
)(
-
1
-
newconn
->
socket
);
nud
->
netconn
->
socket
=
(
int
)
nud
;
SYS_ARCH_UNPROTECT
(
lev
);
netconn_set_nonblocking
(
nud
->
netconn
,
1
);
netconn_set_noautorecved
(
nud
->
netconn
,
1
);
nud
->
netconn
->
pcb
.
tcp
->
so_options
|=
SOF_KEEPALIVE
;
nud
->
netconn
->
pcb
.
tcp
->
keep_idle
=
ud
->
server
.
timeout
*
1000
;
nud
->
netconn
->
pcb
.
tcp
->
keep_cnt
=
1
;
}
else
luaL_error
(
L
,
"cannot accept new server socket connection"
);
lua_call
(
L
,
1
,
0
);
while
(
recvevent
--
>
0
)
{
// kick receive callback in case of pending events
post_net_recv
(
nud
);
}
}
static
void
lrecv_cb
(
lua_State
*
L
,
lnet_userdata
*
ud
,
const
lnet_recvdata
*
rd
)
{
if
(
ud
->
client
.
cb_receive_ref
!=
LUA_NOREF
)
{
static
void
lrecv_cb
(
lua_State
*
L
,
lnet_userdata
*
ud
)
{
if
(
!
ud
->
netconn
)
return
;
struct
netbuf
*
p
;
char
*
payload
;
uint16_t
len
;
err_t
err
=
netconn_recv
(
ud
->
netconn
,
&
p
);
if
(
err
!=
ERR_OK
)
{
lwip_lua_checkerr
(
L
,
err
);
return
;
}
if
(
p
)
{
netbuf_data
(
p
,
(
void
**
)
&
payload
,
&
len
);
}
else
{
len
=
0
;
}
if
(
len
>
0
&&
ud
->
client
.
cb_receive_ref
!=
LUA_NOREF
){
lua_rawgeti
(
L
,
LUA_REGISTRYINDEX
,
ud
->
client
.
cb_receive_ref
);
int
num_args
=
2
;
lua_rawgeti
(
L
,
LUA_REGISTRYINDEX
,
ud
->
self_ref
);
lua_pushlstring
(
L
,
rd
->
payload
,
rd
->
payload_
len
);
lua_pushlstring
(
L
,
payload
,
len
);
if
(
ud
->
type
==
TYPE_UDP_SOCKET
)
{
num_args
+=
2
;
char
iptmp
[
IP_STR_SZ
];
ipstr
(
iptmp
,
&
rd
->
src_ip
);
lua_pushinteger
(
L
,
rd
->
src_port
);
ip_addr_t
*
addr
=
netbuf_fromaddr
(
p
);
uint16_t
port
=
netbuf_fromport
(
p
);
ipstr
(
iptmp
,
addr
);
lua_pushinteger
(
L
,
port
);
lua_pushstring
(
L
,
iptmp
);
}
lua_call
(
L
,
num_args
,
0
);
}
if
(
p
)
{
netbuf_delete
(
p
);
if
(
ud
->
type
==
TYPE_TCP_CLIENT
)
{
if
(
ud
->
client
.
hold
)
{
netconn_recved
(
ud
->
netconn
,
0
);
ud
->
client
.
num_held
+=
len
;
}
else
{
netconn_recved
(
ud
->
netconn
,
len
);
}
}
}
}
static
void
lsent_cb
(
lua_State
*
L
,
lnet_userdata
*
ud
)
{
...
...
@@ -1063,6 +1126,8 @@ static void lsent_cb (lua_State *L, lnet_userdata *ud) {
static
void
lerr_cb
(
lua_State
*
L
,
lnet_userdata
*
ud
,
err_t
err
)
{
if
(
!
ud
->
netconn
)
return
;
int
ref
;
if
(
err
!=
ERR_OK
&&
ud
->
client
.
cb_reconnect_ref
!=
LUA_NOREF
)
ref
=
ud
->
client
.
cb_reconnect_ref
;
...
...
@@ -1092,8 +1157,8 @@ static void handle_net_event (task_param_t param, task_prio_t prio)
case
DNSFOUND
:
ldnsfound_cb
(
L
,
ev
->
ud
,
&
ev
->
resolved_ip
);
break
;
case
DNSSTATIC
:
ldnsstatic_cb
(
L
,
ev
->
cb_ref
,
&
ev
->
resolved_ip
);
break
;
case
CONNECTED
:
lconnected_cb
(
L
,
ev
->
ud
);
break
;
case
ACCEPT
:
laccept_cb
(
L
,
ev
->
ud
,
ev
->
accept_newpcb
);
break
;
case
RECVDATA
:
lrecv_cb
(
L
,
ev
->
ud
,
&
ev
->
recvdata
);
break
;
case
ACCEPT
:
laccept_cb
(
L
,
ev
->
ud
);
break
;
case
RECVDATA
:
lrecv_cb
(
L
,
ev
->
ud
);
break
;
case
SENTDATA
:
lsent_cb
(
L
,
ev
->
ud
);
break
;
case
ERR
:
lerr_cb
(
L
,
ev
->
ud
,
ev
->
err
);
break
;
}
...
...
sdkconfig.defaults
View file @
070973e6
# Empirical value to prevent a firmware crash due to stack overflow.
CONFIG_MAIN_TASK_STACK_SIZE=8192
# Enable address reuse for sockets in TIME_WAIT
# see https://github.com/nodemcu/nodemcu-firmware/pull/1838
CONFIG_LWIP_SO_REUSE=y
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