Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
e7c6790b
Commit
e7c6790b
authored
Mar 31, 2016
by
Johny Mattsson
Browse files
Merge pull request #1200 from DiUS/enduser-setup-status-fix
enduser_setup: Fixed missing status update.
parents
7b957116
0e404770
Changes
1
Hide whitespace changes
Inline
Side-by-side
app/modules/enduser_setup.c
View file @
e7c6790b
...
@@ -392,6 +392,65 @@ static void enduser_setup_check_station(void *p)
...
@@ -392,6 +392,65 @@ static void enduser_setup_check_station(void *p)
}
}
/* --- Connection closing handling ----------------------------------------- */
/* It is far more memory efficient to let the other end close the connection
* first and respond to that, than us initiating the closing. The latter
* seems to leave the pcb in a fin_wait state for a long time, which can
* starve us of memory over time.
*
* By instead using the poll function to schedule a hard abort a few seconds
* from now we achieve a deadline close. The downside is a (very) slight
* risk of dropping the connection early, but in this application that's
* hidden by the retries on the JavaScript side anyway.
*/
/* Callback on timeout to hard-close a connection */
static
err_t
force_abort
(
void
*
arg
,
struct
tcp_pcb
*
pcb
)
{
(
void
)
arg
;
tcp_poll
(
pcb
,
0
,
0
);
tcp_abort
(
pcb
);
return
ERR_ABRT
;
}
/* Callback to detect a remote-close of a connection */
static
err_t
handle_remote_close
(
void
*
arg
,
struct
tcp_pcb
*
pcb
,
struct
pbuf
*
p
,
err_t
err
)
{
(
void
)
arg
;
(
void
)
err
;
if
(
p
)
/* server sent us data, just ACK and move on */
{
tcp_recved
(
pcb
,
p
->
tot_len
);
pbuf_free
(
p
);
}
else
/* hey, remote end closed, we can do a soft close safely, yay! */
{
tcp_recv
(
pcb
,
0
);
tcp_poll
(
pcb
,
0
,
0
);
tcp_close
(
pcb
);
}
return
ERR_OK
;
}
/* Set up a deferred close of a connection, as discussed above. */
static
inline
void
deferred_close
(
struct
tcp_pcb
*
pcb
)
{
tcp_poll
(
pcb
,
force_abort
,
15
);
/* ~3sec from now */
tcp_recv
(
pcb
,
handle_remote_close
);
tcp_sent
(
pcb
,
0
);
}
/* Convenience function to queue up a close-after-send. */
static
err_t
close_once_sent
(
void
*
arg
,
struct
tcp_pcb
*
pcb
,
u16_t
len
)
{
(
void
)
arg
;
(
void
)
len
;
deferred_close
(
pcb
);
return
ERR_OK
;
}
/* ------------------------------------------------------------------------- */
/**
/**
* Search String
* Search String
*
*
...
@@ -636,7 +695,7 @@ static int enduser_setup_http_serve_header(struct tcp_pcb *http_client, const ch
...
@@ -636,7 +695,7 @@ static int enduser_setup_http_serve_header(struct tcp_pcb *http_client, const ch
err_t
err
=
tcp_write
(
http_client
,
header
,
header_len
,
TCP_WRITE_FLAG_COPY
);
err_t
err
=
tcp_write
(
http_client
,
header
,
header_len
,
TCP_WRITE_FLAG_COPY
);
if
(
err
!=
ERR_OK
)
if
(
err
!=
ERR_OK
)
{
{
tcp
_close
(
http_client
);
deferred
_close
(
http_client
);
ENDUSER_SETUP_ERROR
(
"http_serve_header failed on tcp_write"
,
ENDUSER_SETUP_ERR_UNKOWN_ERROR
,
ENDUSER_SETUP_ERR_NONFATAL
);
ENDUSER_SETUP_ERROR
(
"http_serve_header failed on tcp_write"
,
ENDUSER_SETUP_ERR_UNKOWN_ERROR
,
ENDUSER_SETUP_ERR_NONFATAL
);
}
}
...
@@ -675,7 +734,7 @@ static err_t streamout_sent (void *arg, struct tcp_pcb *pcb, u16_t len)
...
@@ -675,7 +734,7 @@ static err_t streamout_sent (void *arg, struct tcp_pcb *pcb, u16_t len)
if
(
offs
>=
state
->
http_payload_len
)
if
(
offs
>=
state
->
http_payload_len
)
{
{
tcp_sent
(
pcb
,
0
);
tcp_sent
(
pcb
,
0
);
tcp
_close
(
pcb
);
deferred
_close
(
pcb
);
}
}
else
else
tcp_arg
(
pcb
,
(
void
*
)
offs
);
tcp_arg
(
pcb
,
(
void
*
)
offs
);
...
@@ -692,7 +751,6 @@ static err_t streamout_sent (void *arg, struct tcp_pcb *pcb, u16_t len)
...
@@ -692,7 +751,6 @@ static err_t streamout_sent (void *arg, struct tcp_pcb *pcb, u16_t len)
static
int
enduser_setup_http_serve_html
(
struct
tcp_pcb
*
http_client
)
static
int
enduser_setup_http_serve_html
(
struct
tcp_pcb
*
http_client
)
{
{
ENDUSER_SETUP_DEBUG
(
"enduser_setup_http_serve_html"
);
ENDUSER_SETUP_DEBUG
(
"enduser_setup_http_serve_html"
);
if
(
state
->
http_payload_data
==
NULL
)
if
(
state
->
http_payload_data
==
NULL
)
{
{
enduser_setup_http_load_payload
();
enduser_setup_http_load_payload
();
...
@@ -719,8 +777,9 @@ static void serve_status(struct tcp_pcb *conn)
...
@@ -719,8 +777,9 @@ static void serve_status(struct tcp_pcb *conn)
const
char
fmt
[]
=
const
char
fmt
[]
=
"HTTP/1.1 200 OK
\r\n
"
"HTTP/1.1 200 OK
\r\n
"
"Cache-control: no-cache
\r\n
"
"Cache-control:no-cache
\r\n
"
"Content-type: text/plain
\r\n
"
"Connection:close
\r\n
"
"Content-type:text/plain
\r\n
"
"Content-length: %d
\r\n
"
"Content-length: %d
\r\n
"
"
\r\n
"
"
\r\n
"
"%s%s"
;
"%s%s"
;
...
@@ -856,8 +915,10 @@ static void notify_scan_listeners (const char *payload, size_t sz)
...
@@ -856,8 +915,10 @@ static void notify_scan_listeners (const char *payload, size_t sz)
if
(
tcp_write
(
l
->
conn
,
payload
,
sz
,
TCP_WRITE_FLAG_COPY
)
!=
ERR_OK
)
if
(
tcp_write
(
l
->
conn
,
payload
,
sz
,
TCP_WRITE_FLAG_COPY
)
!=
ERR_OK
)
{
{
ENDUSER_SETUP_DEBUG
(
"failed to send wifi list"
);
ENDUSER_SETUP_DEBUG
(
"failed to send wifi list"
);
tcp_abort
(
l
->
conn
);
}
}
tcp_close
(
l
->
conn
);
else
tcp_sent
(
l
->
conn
,
close_once_sent
);
/* TODO: time-out sends? */
l
->
conn
=
0
;
l
->
conn
=
0
;
}
}
...
@@ -883,7 +944,7 @@ static void on_scan_done (void *arg, STATUS status)
...
@@ -883,7 +944,7 @@ static void on_scan_done (void *arg, STATUS status)
const
char
header_fmt
[]
=
const
char
header_fmt
[]
=
"HTTP/1.1 200 OK
\r\n
"
"HTTP/1.1 200 OK
\r\n
"
"Connection:close
\r\n
"
"Connection:close
\r\n
"
"Cache-control:
no-cache
\r\n
"
"Cache-control:no-cache
\r\n
"
"Content-type:application/json
\r\n
"
"Content-type:application/json
\r\n
"
"Content-length:%4d
\r\n
"
"Content-length:%4d
\r\n
"
"
\r\n
"
;
"
\r\n
"
;
...
@@ -939,10 +1000,10 @@ serve_500:
...
@@ -939,10 +1000,10 @@ serve_500:
/* ---- end WiFi AP scan support ------------------------------------------- */
/* ---- end WiFi AP scan support ------------------------------------------- */
static
err_t
enduser_setup_http_recvcb
(
void
*
arg
,
struct
tcp_pcb
*
http_client
,
struct
pbuf
*
p
,
err_t
err
)
static
err_t
enduser_setup_http_recvcb
(
void
*
arg
,
struct
tcp_pcb
*
http_client
,
struct
pbuf
*
p
,
err_t
err
)
{
{
ENDUSER_SETUP_DEBUG
(
"enduser_setup_http_recvcb"
);
ENDUSER_SETUP_DEBUG
(
"enduser_setup_http_recvcb"
);
if
(
!
state
||
err
!=
ERR_OK
)
if
(
!
state
||
err
!=
ERR_OK
)
{
{
if
(
!
state
)
if
(
!
state
)
...
@@ -958,7 +1019,7 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
...
@@ -958,7 +1019,7 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
if
(
l
)
if
(
l
)
remove_scan_listener
(
l
);
remove_scan_listener
(
l
);
tcp
_close
(
http_client
);
deferred
_close
(
http_client
);
return
ERR_OK
;
return
ERR_OK
;
}
}
...
@@ -970,6 +1031,7 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
...
@@ -970,6 +1031,7 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
tcp_recved
(
http_client
,
p
->
tot_len
);
tcp_recved
(
http_client
,
p
->
tot_len
);
pbuf_free
(
p
);
pbuf_free
(
p
);
err_t
ret
=
ERR_OK
;
if
(
c_strncmp
(
data
,
"GET "
,
4
)
==
0
)
if
(
c_strncmp
(
data
,
"GET "
,
4
)
==
0
)
{
{
if
(
c_strncmp
(
data
+
4
,
"/ "
,
2
)
==
0
)
if
(
c_strncmp
(
data
+
4
,
"/ "
,
2
)
==
0
)
...
@@ -980,8 +1042,7 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
...
@@ -980,8 +1042,7 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
}
}
else
else
{
{
os_free
(
data
);
goto
free_out
;
/* streaming now in progress */
return
ERR_OK
;
/* streaming now in progress */
}
}
}
}
else
if
(
c_strncmp
(
data
+
4
,
"/aplist "
,
8
)
==
0
)
else
if
(
c_strncmp
(
data
+
4
,
"/aplist "
,
8
)
==
0
)
...
@@ -1005,13 +1066,12 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
...
@@ -1005,13 +1066,12 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
if
(
!
wifi_station_scan
(
NULL
,
on_scan_done
))
if
(
!
wifi_station_scan
(
NULL
,
on_scan_done
))
{
{
enduser_setup_http_serve_header
(
http_client
,
http_header_500
,
LITLEN
(
http_header_500
));
enduser_setup_http_serve_header
(
http_client
,
http_header_500
,
LITLEN
(
http_header_500
));
tcp
_close
(
l
->
conn
);
deferred
_close
(
l
->
conn
);
l
->
conn
=
0
;
l
->
conn
=
0
;
free_scan_listeners
();
free_scan_listeners
();
}
}
}
}
os_free
(
data
);
goto
free_out
;
/* request queued */
return
ERR_OK
;
}
}
else
if
(
c_strncmp
(
data
+
4
,
"/status "
,
8
)
==
0
)
else
if
(
c_strncmp
(
data
+
4
,
"/status "
,
8
)
==
0
)
{
{
...
@@ -1049,18 +1109,13 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
...
@@ -1049,18 +1109,13 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
enduser_setup_http_serve_header
(
http_client
,
http_header_401
,
LITLEN
(
http_header_401
));
enduser_setup_http_serve_header
(
http_client
,
http_header_401
,
LITLEN
(
http_header_401
));
}
}
deferred_close
(
http_client
);
free_out:
os_free
(
data
);
os_free
(
data
);
#if 0
return
ret
;
/* being nice apparently costs us a lot of pcbs in time_wait state :( */
tcp_close (http_client);
return ERR_OK;
#else
tcp_abort
(
http_client
);
return
ERR_ABRT
;
#endif
}
}
static
err_t
enduser_setup_http_connectcb
(
void
*
arg
,
struct
tcp_pcb
*
pcb
,
err_t
err
)
static
err_t
enduser_setup_http_connectcb
(
void
*
arg
,
struct
tcp_pcb
*
pcb
,
err_t
err
)
{
{
ENDUSER_SETUP_DEBUG
(
"enduser_setup_http_connectcb"
);
ENDUSER_SETUP_DEBUG
(
"enduser_setup_http_connectcb"
);
...
@@ -1073,6 +1128,7 @@ static err_t enduser_setup_http_connectcb(void *arg, struct tcp_pcb *pcb, err_t
...
@@ -1073,6 +1128,7 @@ static err_t enduser_setup_http_connectcb(void *arg, struct tcp_pcb *pcb, err_t
tcp_accepted
(
state
->
http_pcb
);
tcp_accepted
(
state
->
http_pcb
);
tcp_recv
(
pcb
,
enduser_setup_http_recvcb
);
tcp_recv
(
pcb
,
enduser_setup_http_recvcb
);
tcp_nagle_disable
(
pcb
);
return
ERR_OK
;
return
ERR_OK
;
}
}
...
...
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