From 6bba345acfe8c9bc04ce2e53d26142c953c01702 Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Sun, 12 Jun 2022 11:32:56 +0800 Subject: [PATCH] Add minimal protocol Protocol retrieved from lws git repo for samples. --- CMakeLists.txt | 2 +- src/packages/server/main.c | 4 + src/packages/server/protocol_lws_minimal.c | 143 +++++++++++++++++++++ 3 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 src/packages/server/protocol_lws_minimal.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a37f989..fbca47b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,7 +168,7 @@ add_executable( dependencies/minIni/dev/minIni.c src/packages/server/IZ_common.h src/packages/server/main.c -) + src/packages/server/protocol_lws_minimal.c) target_link_libraries( server diff --git a/src/packages/server/main.c b/src/packages/server/main.c index cb1490d..d2aa919 100644 --- a/src/packages/server/main.c +++ b/src/packages/server/main.c @@ -2,8 +2,12 @@ #include #include "IZ_common.h" +#define LWS_PLUGIN_STATIC +#include "protocol_lws_minimal.c" + static struct lws_protocols protocols[] = { { "http", lws_callback_http_dummy, 0, 0, 0, NULL, 0}, + LWS_PLUGIN_PROTOCOL_MINIMAL, LWS_PROTOCOL_LIST_TERM }; diff --git a/src/packages/server/protocol_lws_minimal.c b/src/packages/server/protocol_lws_minimal.c new file mode 100644 index 0000000..a7b1980 --- /dev/null +++ b/src/packages/server/protocol_lws_minimal.c @@ -0,0 +1,143 @@ + +#if !defined (LWS_PLUGIN_STATIC) +#define LWS_DLL +#define LWS_INTERNAL +#include +#endif + +#include + +/* one of these created for each message */ + +struct msg { + void *payload; /* is malloc'd */ + size_t len; +}; + +/* one of these is created for each client connecting to us */ + +struct per_session_data__minimal { + struct per_session_data__minimal *pss_list; + struct lws *wsi; + int last; /* the last message number we sent */ +}; + +/* one of these is created for each vhost our protocol is used with */ + +struct per_vhost_data__minimal { + struct lws_context *context; + struct lws_vhost *vhost; + const struct lws_protocols *protocol; + + struct per_session_data__minimal *pss_list; /* linked-list of live pss*/ + + struct msg amsg; /* the one pending message... */ + int current; /* the current message number we are caching */ +}; + +/* destroys the message when everyone has had a copy of it */ + +static void +__minimal_destroy_message(void *_msg) +{ + struct msg *msg = _msg; + + free(msg->payload); + msg->payload = NULL; + msg->len = 0; +} + +static int +callback_minimal(struct lws *wsi, enum lws_callback_reasons reason, + void *user, void *in, size_t len) +{ + struct per_session_data__minimal *pss = + (struct per_session_data__minimal *)user; + struct per_vhost_data__minimal *vhd = + (struct per_vhost_data__minimal *) + lws_protocol_vh_priv_get(lws_get_vhost(wsi), + lws_get_protocol(wsi)); + int m; + + switch (reason) { + case LWS_CALLBACK_PROTOCOL_INIT: + vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi), + lws_get_protocol(wsi), + sizeof(struct per_vhost_data__minimal)); + vhd->context = lws_get_context(wsi); + vhd->protocol = lws_get_protocol(wsi); + vhd->vhost = lws_get_vhost(wsi); + break; + + case LWS_CALLBACK_ESTABLISHED: + /* add ourselves to the list of live pss held in the vhd */ + lws_ll_fwd_insert(pss, pss_list, vhd->pss_list); + pss->wsi = wsi; + pss->last = vhd->current; + break; + + case LWS_CALLBACK_CLOSED: + /* remove our closing pss from the list of live pss */ + lws_ll_fwd_remove(struct per_session_data__minimal, pss_list, + pss, vhd->pss_list); + break; + + case LWS_CALLBACK_SERVER_WRITEABLE: + if (!vhd->amsg.payload) + break; + + if (pss->last == vhd->current) + break; + + /* notice we allowed for LWS_PRE in the payload already */ + m = lws_write(wsi, ((unsigned char *)vhd->amsg.payload) + + LWS_PRE, vhd->amsg.len, LWS_WRITE_TEXT); + if (m < (int)vhd->amsg.len) { + lwsl_err("ERROR %d writing to ws\n", m); + return -1; + } + + pss->last = vhd->current; + break; + + case LWS_CALLBACK_RECEIVE: + if (vhd->amsg.payload) + __minimal_destroy_message(&vhd->amsg); + + vhd->amsg.len = len; + /* notice we over-allocate by LWS_PRE */ + vhd->amsg.payload = malloc(LWS_PRE + len); + if (!vhd->amsg.payload) { + lwsl_user("OOM: dropping\n"); + break; + } + + memcpy((char *)vhd->amsg.payload + LWS_PRE, in, len); + vhd->current++; + + /* + * let everybody know we want to write something on them + * as soon as they are ready + */ + lws_start_foreach_llp(struct per_session_data__minimal **, + ppss, vhd->pss_list) { + lws_callback_on_writable((*ppss)->wsi); + } lws_end_foreach_llp(ppss, pss_list); + break; + + default: + break; + } + + return 0; +} + +#define LWS_PLUGIN_PROTOCOL_MINIMAL \ + { \ + "lws-minimal", \ + callback_minimal, \ + sizeof(struct per_session_data__minimal), \ + 128, \ + 0, NULL, 0 \ + } +