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
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)
}
/* --- 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
*
...
...
@@ -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
);
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
);
}
...
...
@@ -675,7 +734,7 @@ static err_t streamout_sent (void *arg, struct tcp_pcb *pcb, u16_t len)
if
(
offs
>=
state
->
http_payload_len
)
{
tcp_sent
(
pcb
,
0
);
tcp
_close
(
pcb
);
deferred
_close
(
pcb
);
}
else
tcp_arg
(
pcb
,
(
void
*
)
offs
);
...
...
@@ -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
)
{
ENDUSER_SETUP_DEBUG
(
"enduser_setup_http_serve_html"
);
if
(
state
->
http_payload_data
==
NULL
)
{
enduser_setup_http_load_payload
();
...
...
@@ -719,8 +777,9 @@ static void serve_status(struct tcp_pcb *conn)
const
char
fmt
[]
=
"HTTP/1.1 200 OK
\r\n
"
"Cache-control: no-cache
\r\n
"
"Content-type: text/plain
\r\n
"
"Cache-control:no-cache
\r\n
"
"Connection:close
\r\n
"
"Content-type:text/plain
\r\n
"
"Content-length: %d
\r\n
"
"
\r\n
"
"%s%s"
;
...
...
@@ -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
)
{
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
;
}
...
...
@@ -883,7 +944,7 @@ static void on_scan_done (void *arg, STATUS status)
const
char
header_fmt
[]
=
"HTTP/1.1 200 OK
\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-length:%4d
\r\n
"
"
\r\n
"
;
...
...
@@ -939,10 +1000,10 @@ serve_500:
/* ---- 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
)
{
ENDUSER_SETUP_DEBUG
(
"enduser_setup_http_recvcb"
);
if
(
!
state
||
err
!=
ERR_OK
)
{
if
(
!
state
)
...
...
@@ -958,7 +1019,7 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s
if
(
l
)
remove_scan_listener
(
l
);
tcp
_close
(
http_client
);
deferred
_close
(
http_client
);
return
ERR_OK
;
}
...
...
@@ -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
);
pbuf_free
(
p
);
err_t
ret
=
ERR_OK
;
if
(
c_strncmp
(
data
,
"GET "
,
4
)
==
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
}
else
{
os_free
(
data
);
return
ERR_OK
;
/* streaming now in progress */
goto
free_out
;
/* streaming now in progress */
}
}
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
if
(
!
wifi_station_scan
(
NULL
,
on_scan_done
))
{
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
;
free_scan_listeners
();
}
}
os_free
(
data
);
return
ERR_OK
;
goto
free_out
;
/* request queued */
}
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
enduser_setup_http_serve_header
(
http_client
,
http_header_401
,
LITLEN
(
http_header_401
));
}
deferred_close
(
http_client
);
free_out:
os_free
(
data
);
#if 0
/* 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
return
ret
;
}
static
err_t
enduser_setup_http_connectcb
(
void
*
arg
,
struct
tcp_pcb
*
pcb
,
err_t
err
)
{
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
tcp_accepted
(
state
->
http_pcb
);
tcp_recv
(
pcb
,
enduser_setup_http_recvcb
);
tcp_nagle_disable
(
pcb
);
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