client fixups after esp8266

This commit is contained in:
Andy Green 2016-08-07 08:33:08 +08:00
parent 7acf76cd3d
commit bbf93693d8
7 changed files with 125 additions and 36 deletions

34
README.esp8266.md Normal file
View file

@ -0,0 +1,34 @@
ESP8266 lws port
----------------
lws can now work well on the ESP8266.
You should get the ESP8266 Espressif SDK-based project here
https://github.com/lws-team/esplws
which includes lws as an "app" in the build. The project provides full AP-based setup over the web, and once the device has been configured to associate to a local AP, a separate station vhost with the lws test protocols.
Instructions for building that are here
https://github.com/lws-team/esplws/blob/master/README.md
There are also instructions there for how to remove the test apps from the build and customize your own station content.
Information about lws integration on ESP8266
--------------------------------------------
The following existing lws features are used to make a nice integration:
- vhosts: there are separate vhosts for the configuration AP mode and the normal station mode.
- file_ops: the lws file operations are overridden and handled by a ROMFS parser
- mounts: mounts are used to serve files automatically from the ROMFS
- plugins: standalone protocol plugins are included into the build, so there are clean individual implementations for each protocol, while everything is statically linked
- lws stability and security features like bytewise parsers, sophisticated timeouts, http/1.1 keepalive support

View file

@ -5,6 +5,11 @@
libwebsockets
-------------
| News |
------
| ESP8266 is now supported in lws! See https://github.com/warmcat/libwebsockets/blob/master/README.esp8266.md |
This is the libwebsockets C library for lightweight websocket clients and
servers. For support, visit
@ -15,10 +20,6 @@ and consider joining the project mailing list at
https://libwebsockets.org/mailman/listinfo/libwebsockets
| News |
------
| We have updated https://libwebsockets.org, if you would like your project using lws featured in the image carousel, send an image, project URL and brief summary to andy@warmcat.com |
You can get the latest version of the library from git:
- https://github.com/warmcat/libwebsockets

View file

@ -175,6 +175,8 @@ lws_client_connect_2(struct lws *wsi)
goto oom4;
}
lws_change_pollfd(wsi, 0, LWS_POLLIN);
/*
* past here, we can't simply free the structs as error
* handling as oom4 does. We have to run the whole close flow.
@ -485,6 +487,9 @@ lws_client_connect_via_info(struct lws_client_connect_info *i)
if (i->context->requested_kill)
return NULL;
if (!i->context->protocol_init_done)
lws_protocol_init(i->context);
wsi = lws_zalloc(sizeof(struct lws));
if (wsi == NULL)
goto bail;

View file

@ -119,7 +119,7 @@ lws_header_table_attach(struct lws *wsi, int autoservice)
struct lws **pwsi;
int n;
lwsl_notice("%s: wsi %p: ah %p (tsi %d, count = %d) in\n", __func__, (void *)wsi,
lwsl_info("%s: wsi %p: ah %p (tsi %d, count = %d) in\n", __func__, (void *)wsi,
(void *)wsi->u.hdr.ah, wsi->tsi, pt->ah_count_in_use);
/* if we are already bound to one, just clear it down */
@ -291,14 +291,15 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
lws_header_table_reset(wsi, autoservice);
time(&wsi->u.hdr.ah->assigned);
assert(wsi->position_in_fds_table != -1);
/* clients acquire the ah and then insert themselves in fds table... */
if (wsi->position_in_fds_table != -1) {
lwsl_info("%s: Enabling %p POLLIN\n", __func__, wsi);
lwsl_info("%s: Enabling %p POLLIN\n", __func__, wsi);
/* he has been stuck waiting for an ah, but now his wait is over,
* let him progress
*/
_lws_change_pollfd(wsi, 0, LWS_POLLIN, &pa);
/* he has been stuck waiting for an ah, but now his wait is over,
* let him progress
*/
_lws_change_pollfd(wsi, 0, LWS_POLLIN, &pa);
}
/* point prev guy to next guy in list instead */
*pwsi = wsi->u.hdr.ah_wait_list;

View file

@ -43,6 +43,8 @@ _lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa)
pa->prev_events = pfd->events;
pa->events = pfd->events = (pfd->events & ~_and) | _or;
//lwsl_notice("%s: wsi %p, posin %d. from %d -> %d\n", __func__, wsi, wsi->position_in_fds_table, pa->prev_events, pa->events);
if (wsi->http2_substream)
return 0;
@ -147,6 +149,9 @@ insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi)
if (wsi->position_in_fds_table == -1)
#endif
wsi->position_in_fds_table = pt->fds_count;
// lwsl_notice("%s: %p: setting posinfds %d\n", __func__, wsi, wsi->position_in_fds_table);
pt->fds[wsi->position_in_fds_table].fd = wsi->sock;
#if LWS_POSIX
pt->fds[wsi->position_in_fds_table].events = LWS_POLLIN;

View file

@ -701,6 +701,7 @@ struct lws_context_per_thread {
short ah_count_in_use;
unsigned char tid;
unsigned char lock_depth;
};
/*
@ -1752,13 +1753,15 @@ lws_pt_mutex_destroy(struct lws_context_per_thread *pt)
static LWS_INLINE void
lws_pt_lock(struct lws_context_per_thread *pt)
{
pthread_mutex_lock(&pt->lock);
if (!pt->lock_depth++)
pthread_mutex_lock(&pt->lock);
}
static LWS_INLINE void
lws_pt_unlock(struct lws_context_per_thread *pt)
{
pthread_mutex_unlock(&pt->lock);
if (!(--pt->lock_depth))
pthread_mutex_unlock(&pt->lock);
}
#else
#define lws_pt_mutex_init(_a) (void)(_a)

View file

@ -39,8 +39,9 @@
static int deny_deflate, longlived, mirror_lifetime;
static struct lws *wsi_dumb, *wsi_mirror;
static struct lws *wsi_multi[3];
static volatile int force_exit;
static unsigned int opts;
static unsigned int opts, rl_multi[3];
static int flag_no_mirror_traffic;
#if defined(LWS_USE_POLARSSL)
#else
@ -87,6 +88,8 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
void *user, void *in, size_t len)
{
const char *which = "http";
char which_wsi[10];
int n;
switch (reason) {
@ -116,6 +119,13 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
wsi_mirror = NULL;
}
for (n = 0; n < ARRAY_SIZE(wsi_multi); n++)
if (wsi == wsi_multi[n]) {
sprintf(which_wsi, "multi %d", n);
which = which_wsi;
wsi_multi[n] = NULL;
}
lwsl_err("CLIENT_CONNECTION_ERROR: %s: %s %p\n", which, in);
break;
@ -152,6 +162,10 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
}
break;
case LWS_CALLBACK_CLIENT_WRITEABLE:
lwsl_notice("Client wsi %p writable\n", wsi);
break;
case LWS_CALLBACK_COMPLETED_CLIENT_HTTP:
wsi_dumb = NULL;
force_exit = 1;
@ -322,6 +336,7 @@ static struct option options[] = {
{ "strict-ssl", no_argument, NULL, 'S' },
{ "version", required_argument, NULL, 'v' },
{ "undeflated", no_argument, NULL, 'u' },
{ "multi-test", no_argument, NULL, 'm' },
{ "nomirror", no_argument, NULL, 'n' },
{ "longlived", no_argument, NULL, 'l' },
{ "pingpong-secs", required_argument, NULL, 'P' },
@ -350,8 +365,8 @@ static int ratelimit_connects(unsigned int *last, unsigned int secs)
int main(int argc, char **argv)
{
int n = 0, ret = 0, port = 7681, use_ssl = 0, ietf_version = -1;
unsigned int rl_dumb = 0, rl_mirror = 0, do_ws = 1, pp_secs = 0;
int n = 0, m, ret = 0, port = 7681, use_ssl = 0, ietf_version = -1;
unsigned int rl_dumb = 0, rl_mirror = 0, do_ws = 1, pp_secs = 0, do_multi = 0;
struct lws_context_creation_info info;
struct lws_client_connect_info i;
struct lws_context *context;
@ -370,7 +385,7 @@ int main(int argc, char **argv)
goto usage;
while (n >= 0) {
n = getopt_long(argc, argv, "Snuv:hsp:d:lC:K:A:P:", options, NULL);
n = getopt_long(argc, argv, "Snuv:hsp:d:lC:K:A:P:m", options, NULL);
if (n < 0)
continue;
switch (n) {
@ -401,6 +416,9 @@ int main(int argc, char **argv)
case 'u':
deny_deflate = 1;
break;
case 'm':
do_multi = 1;
break;
case 'n':
flag_no_mirror_traffic = 1;
lwsl_notice("Disabled sending mirror data (for pingpong testing)\n");
@ -544,30 +562,52 @@ int main(int argc, char **argv)
* asynchronously.
*/
m = 0;
while (!force_exit) {
if (do_ws) {
if (!wsi_dumb && ratelimit_connects(&rl_dumb, 2u)) {
lwsl_notice("dumb: connecting\n");
i.protocol = protocols[PROTOCOL_DUMB_INCREMENT].name;
i.pwsi = &wsi_dumb;
lws_client_connect_via_info(&i);
if (do_multi) {
for (n = 0; n < ARRAY_SIZE(wsi_multi); n++) {
if (!wsi_multi[n] && ratelimit_connects(&rl_multi[n], 2u)) {
lwsl_notice("dumb %d: connecting\n", n);
i.protocol = protocols[PROTOCOL_DUMB_INCREMENT].name;
i.pwsi = &wsi_multi[n];
lws_client_connect_via_info(&i);
}
}
} else {
if (!wsi_mirror && ratelimit_connects(&rl_mirror, 2u)) {
lwsl_notice("mirror: connecting\n");
i.protocol = protocols[PROTOCOL_LWS_MIRROR].name;
i.pwsi = &wsi_mirror;
wsi_mirror = lws_client_connect_via_info(&i);
}
} else
if (!wsi_dumb && ratelimit_connects(&rl_dumb, 2u)) {
lwsl_notice("http: connecting\n");
i.pwsi = &wsi_dumb;
lws_client_connect_via_info(&i);
}
if (do_ws) {
if (!wsi_dumb && ratelimit_connects(&rl_dumb, 2u)) {
lwsl_notice("dumb: connecting\n");
i.protocol = protocols[PROTOCOL_DUMB_INCREMENT].name;
i.pwsi = &wsi_dumb;
lws_client_connect_via_info(&i);
}
if (!wsi_mirror && ratelimit_connects(&rl_mirror, 2u)) {
lwsl_notice("mirror: connecting\n");
i.protocol = protocols[PROTOCOL_LWS_MIRROR].name;
i.pwsi = &wsi_mirror;
wsi_mirror = lws_client_connect_via_info(&i);
}
} else
if (!wsi_dumb && ratelimit_connects(&rl_dumb, 2u)) {
lwsl_notice("http: connecting\n");
i.pwsi = &wsi_dumb;
lws_client_connect_via_info(&i);
}
}
lws_service(context, 500);
if (do_multi) {
m++;
if (m == 10) {
m = 0;
lwsl_notice("doing lws_callback_on_writable_all_protocol\n");
lws_callback_on_writable_all_protocol(context, &protocols[PROTOCOL_DUMB_INCREMENT]);
}
}
}
lwsl_err("Exiting\n");