1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to 8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the 9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions: 12d4afb5ceSopenharmony_ci * 13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in 14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software. 15d4afb5ceSopenharmony_ci * 16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22d4afb5ceSopenharmony_ci * IN THE SOFTWARE. 23d4afb5ceSopenharmony_ci */ 24d4afb5ceSopenharmony_ci 25d4afb5ceSopenharmony_ci/* 26d4afb5ceSopenharmony_ci * You can leave buf NULL, if so it will be allocated on the heap once the 27d4afb5ceSopenharmony_ci * actual length is known. nf should be 0, it will be set at allocation time. 28d4afb5ceSopenharmony_ci * 29d4afb5ceSopenharmony_ci * Or you can ensure no allocation and use an external buffer by setting buf 30d4afb5ceSopenharmony_ci * and lim. But buf must be in the ep context somehow, since it may have to 31d4afb5ceSopenharmony_ci * survive returns to the event loop unchanged. Set nf to 0 in this case. 32d4afb5ceSopenharmony_ci * 33d4afb5ceSopenharmony_ci * Or you can set buf to an externally allocated buffer, in which case you may 34d4afb5ceSopenharmony_ci * set nf so it will be freed when the string is "freed". 35d4afb5ceSopenharmony_ci */ 36d4afb5ceSopenharmony_ci 37d4afb5ceSopenharmony_ci#include "private-lib-core.h" 38d4afb5ceSopenharmony_ci/* #include "lws-mqtt.h" */ 39d4afb5ceSopenharmony_ci/* 3.1.3.1-5: MUST allow... that contain only the characters... */ 40d4afb5ceSopenharmony_ci 41d4afb5ceSopenharmony_cistatic const uint8_t *code = (const uint8_t *) 42d4afb5ceSopenharmony_ci "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 43d4afb5ceSopenharmony_ci 44d4afb5ceSopenharmony_cistatic int 45d4afb5ceSopenharmony_cilws_mqtt_generate_id(struct lws* wsi, lws_mqtt_str_t **ms, const char *client_id) 46d4afb5ceSopenharmony_ci{ 47d4afb5ceSopenharmony_ci struct lws_context *context = wsi->a.context; 48d4afb5ceSopenharmony_ci uint16_t ran[24]; /* 16-bit so wrap bias from %62 diluted by ~1000 */ 49d4afb5ceSopenharmony_ci size_t n, len; 50d4afb5ceSopenharmony_ci uint8_t *buf; 51d4afb5ceSopenharmony_ci 52d4afb5ceSopenharmony_ci if (client_id) 53d4afb5ceSopenharmony_ci len = strlen(client_id); 54d4afb5ceSopenharmony_ci else 55d4afb5ceSopenharmony_ci len = LWS_MQTT_RANDOM_CIDLEN; 56d4afb5ceSopenharmony_ci 57d4afb5ceSopenharmony_ci *ms = lws_mqtt_str_create((uint16_t)(len + 1)); 58d4afb5ceSopenharmony_ci if (!*ms) 59d4afb5ceSopenharmony_ci return 1; 60d4afb5ceSopenharmony_ci 61d4afb5ceSopenharmony_ci buf = lws_mqtt_str_next(*ms, NULL); 62d4afb5ceSopenharmony_ci 63d4afb5ceSopenharmony_ci if (client_id) { 64d4afb5ceSopenharmony_ci lws_strnncpy((char *)buf, client_id, len, len + 1); 65d4afb5ceSopenharmony_ci lwsl_notice("%s: User space provided a client ID '%s'\n", 66d4afb5ceSopenharmony_ci __func__, (const char *)buf); 67d4afb5ceSopenharmony_ci } else { 68d4afb5ceSopenharmony_ci lwsl_notice("%s: generating random client id\n", __func__); 69d4afb5ceSopenharmony_ci n = len * sizeof(ran[0]); 70d4afb5ceSopenharmony_ci if (lws_get_random(context, ran, n) != n) { 71d4afb5ceSopenharmony_ci lws_mqtt_str_free(ms); 72d4afb5ceSopenharmony_ci 73d4afb5ceSopenharmony_ci return 1; 74d4afb5ceSopenharmony_ci } 75d4afb5ceSopenharmony_ci 76d4afb5ceSopenharmony_ci for (n = 0; n < len; n++) 77d4afb5ceSopenharmony_ci buf[n] = code[ran[n] % 62]; 78d4afb5ceSopenharmony_ci buf[len] = '\0'; 79d4afb5ceSopenharmony_ci } 80d4afb5ceSopenharmony_ci 81d4afb5ceSopenharmony_ci if (lws_mqtt_str_advance(*ms, (uint16_t)len)) { 82d4afb5ceSopenharmony_ci lws_mqtt_str_free(ms); 83d4afb5ceSopenharmony_ci 84d4afb5ceSopenharmony_ci return 1; 85d4afb5ceSopenharmony_ci } 86d4afb5ceSopenharmony_ci 87d4afb5ceSopenharmony_ci return 0; 88d4afb5ceSopenharmony_ci} 89d4afb5ceSopenharmony_ci 90d4afb5ceSopenharmony_ciint 91d4afb5ceSopenharmony_cilws_read_mqtt(struct lws *wsi, unsigned char *buf, lws_filepos_t len) 92d4afb5ceSopenharmony_ci{ 93d4afb5ceSopenharmony_ci lws_mqttc_t *c = &wsi->mqtt->client; 94d4afb5ceSopenharmony_ci 95d4afb5ceSopenharmony_ci return _lws_mqtt_rx_parser(wsi, &c->par, buf, (size_t)len); 96d4afb5ceSopenharmony_ci} 97d4afb5ceSopenharmony_ci 98d4afb5ceSopenharmony_ciint 99d4afb5ceSopenharmony_cilws_create_client_mqtt_object(const struct lws_client_connect_info *i, 100d4afb5ceSopenharmony_ci struct lws *wsi) 101d4afb5ceSopenharmony_ci{ 102d4afb5ceSopenharmony_ci lws_mqttc_t *c; 103d4afb5ceSopenharmony_ci const lws_mqtt_client_connect_param_t *cp = i->mqtt_cp; 104d4afb5ceSopenharmony_ci 105d4afb5ceSopenharmony_ci /* allocate the ws struct for the wsi */ 106d4afb5ceSopenharmony_ci wsi->mqtt = lws_zalloc(sizeof(*wsi->mqtt), "client mqtt struct"); 107d4afb5ceSopenharmony_ci if (!wsi->mqtt) 108d4afb5ceSopenharmony_ci goto oom; 109d4afb5ceSopenharmony_ci 110d4afb5ceSopenharmony_ci wsi->mqtt->wsi = wsi; 111d4afb5ceSopenharmony_ci c = &wsi->mqtt->client; 112d4afb5ceSopenharmony_ci 113d4afb5ceSopenharmony_ci if (lws_mqtt_generate_id(wsi, &c->id, cp->client_id)) { 114d4afb5ceSopenharmony_ci lwsl_err("%s: Error generating client ID\n", __func__); 115d4afb5ceSopenharmony_ci return 1; 116d4afb5ceSopenharmony_ci } 117d4afb5ceSopenharmony_ci lwsl_info("%s: using client id '%.*s'\n", __func__, c->id->len, 118d4afb5ceSopenharmony_ci (const char *)c->id->buf); 119d4afb5ceSopenharmony_ci 120d4afb5ceSopenharmony_ci if (cp->clean_start || !(cp->client_id && 121d4afb5ceSopenharmony_ci cp->client_id[0])) 122d4afb5ceSopenharmony_ci c->conn_flags = LMQCFT_CLEAN_START; 123d4afb5ceSopenharmony_ci if (cp->client_id_nofree) 124d4afb5ceSopenharmony_ci c->conn_flags |= LMQCFT_CLIENT_ID_NOFREE; 125d4afb5ceSopenharmony_ci if (cp->username_nofree) 126d4afb5ceSopenharmony_ci c->conn_flags |= LMQCFT_USERNAME_NOFREE; 127d4afb5ceSopenharmony_ci if (cp->password_nofree) 128d4afb5ceSopenharmony_ci c->conn_flags |= LMQCFT_PASSWORD_NOFREE; 129d4afb5ceSopenharmony_ci 130d4afb5ceSopenharmony_ci if (!(c->conn_flags & LMQCFT_CLIENT_ID_NOFREE)) 131d4afb5ceSopenharmony_ci lws_free((void *)cp->client_id); 132d4afb5ceSopenharmony_ci 133d4afb5ceSopenharmony_ci c->keep_alive_secs = cp->keep_alive; 134d4afb5ceSopenharmony_ci c->aws_iot = cp->aws_iot; 135d4afb5ceSopenharmony_ci 136d4afb5ceSopenharmony_ci if (cp->will_param.topic && 137d4afb5ceSopenharmony_ci *cp->will_param.topic) { 138d4afb5ceSopenharmony_ci c->will.topic = lws_mqtt_str_create_cstr_dup( 139d4afb5ceSopenharmony_ci cp->will_param.topic, 0); 140d4afb5ceSopenharmony_ci if (!c->will.topic) 141d4afb5ceSopenharmony_ci goto oom1; 142d4afb5ceSopenharmony_ci c->conn_flags |= LMQCFT_WILL_FLAG; 143d4afb5ceSopenharmony_ci if (cp->will_param.message) { 144d4afb5ceSopenharmony_ci c->will.message = lws_mqtt_str_create_cstr_dup( 145d4afb5ceSopenharmony_ci cp->will_param.message, 0); 146d4afb5ceSopenharmony_ci if (!c->will.message) 147d4afb5ceSopenharmony_ci goto oom2; 148d4afb5ceSopenharmony_ci } 149d4afb5ceSopenharmony_ci c->conn_flags = (uint16_t)(unsigned int)(c->conn_flags | ((cp->will_param.qos << 3) & LMQCFT_WILL_QOS_MASK)); 150d4afb5ceSopenharmony_ci c->conn_flags |= (uint16_t)((!!cp->will_param.retain) * LMQCFT_WILL_RETAIN); 151d4afb5ceSopenharmony_ci } 152d4afb5ceSopenharmony_ci 153d4afb5ceSopenharmony_ci if (cp->username && 154d4afb5ceSopenharmony_ci *cp->username) { 155d4afb5ceSopenharmony_ci c->username = lws_mqtt_str_create_cstr_dup(cp->username, 0); 156d4afb5ceSopenharmony_ci if (!c->username) 157d4afb5ceSopenharmony_ci goto oom3; 158d4afb5ceSopenharmony_ci c->conn_flags |= LMQCFT_USERNAME; 159d4afb5ceSopenharmony_ci if (!(c->conn_flags & LMQCFT_USERNAME_NOFREE)) 160d4afb5ceSopenharmony_ci lws_free((void *)cp->username); 161d4afb5ceSopenharmony_ci if (cp->password) { 162d4afb5ceSopenharmony_ci c->password = 163d4afb5ceSopenharmony_ci lws_mqtt_str_create_cstr_dup(cp->password, 0); 164d4afb5ceSopenharmony_ci if (!c->password) 165d4afb5ceSopenharmony_ci goto oom4; 166d4afb5ceSopenharmony_ci c->conn_flags |= LMQCFT_PASSWORD; 167d4afb5ceSopenharmony_ci if (!(c->conn_flags & LMQCFT_PASSWORD_NOFREE)) 168d4afb5ceSopenharmony_ci lws_free((void *)cp->password); 169d4afb5ceSopenharmony_ci } 170d4afb5ceSopenharmony_ci } 171d4afb5ceSopenharmony_ci 172d4afb5ceSopenharmony_ci return 0; 173d4afb5ceSopenharmony_cioom4: 174d4afb5ceSopenharmony_ci lws_mqtt_str_free(&c->username); 175d4afb5ceSopenharmony_cioom3: 176d4afb5ceSopenharmony_ci lws_mqtt_str_free(&c->will.message); 177d4afb5ceSopenharmony_cioom2: 178d4afb5ceSopenharmony_ci lws_mqtt_str_free(&c->will.topic); 179d4afb5ceSopenharmony_cioom1: 180d4afb5ceSopenharmony_ci lws_mqtt_str_free(&c->id); 181d4afb5ceSopenharmony_cioom: 182d4afb5ceSopenharmony_ci lwsl_err("%s: OOM!\n", __func__); 183d4afb5ceSopenharmony_ci return 1; 184d4afb5ceSopenharmony_ci} 185d4afb5ceSopenharmony_ci 186d4afb5ceSopenharmony_ciint 187d4afb5ceSopenharmony_cilws_mqtt_client_socket_service(struct lws *wsi, struct lws_pollfd *pollfd, 188d4afb5ceSopenharmony_ci struct lws *wsi_conn) 189d4afb5ceSopenharmony_ci{ 190d4afb5ceSopenharmony_ci struct lws_context *context = wsi->a.context; 191d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; 192d4afb5ceSopenharmony_ci int n = 0, m = 0; 193d4afb5ceSopenharmony_ci struct lws_tokens ebuf; 194d4afb5ceSopenharmony_ci int buffered = 0; 195d4afb5ceSopenharmony_ci int pending = 0; 196d4afb5ceSopenharmony_ci#if defined(LWS_WITH_TLS) 197d4afb5ceSopenharmony_ci char erbuf[128]; 198d4afb5ceSopenharmony_ci#endif 199d4afb5ceSopenharmony_ci const char *cce = NULL; 200d4afb5ceSopenharmony_ci 201d4afb5ceSopenharmony_ci switch (lwsi_state(wsi)) { 202d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SOCKS5) 203d4afb5ceSopenharmony_ci /* SOCKS Greeting Reply */ 204d4afb5ceSopenharmony_ci case LRS_WAITING_SOCKS_GREETING_REPLY: 205d4afb5ceSopenharmony_ci case LRS_WAITING_SOCKS_AUTH_REPLY: 206d4afb5ceSopenharmony_ci case LRS_WAITING_SOCKS_CONNECT_REPLY: 207d4afb5ceSopenharmony_ci 208d4afb5ceSopenharmony_ci switch (lws_socks5c_handle_state(wsi, pollfd, &cce)) { 209d4afb5ceSopenharmony_ci case LW5CHS_RET_RET0: 210d4afb5ceSopenharmony_ci return 0; 211d4afb5ceSopenharmony_ci case LW5CHS_RET_BAIL3: 212d4afb5ceSopenharmony_ci goto bail3; 213d4afb5ceSopenharmony_ci case LW5CHS_RET_STARTHS: 214d4afb5ceSopenharmony_ci 215d4afb5ceSopenharmony_ci /* 216d4afb5ceSopenharmony_ci * Now we got the socks5 connection, we need to go down 217d4afb5ceSopenharmony_ci * the tls path on it if that's what we want 218d4afb5ceSopenharmony_ci */ 219d4afb5ceSopenharmony_ci 220d4afb5ceSopenharmony_ci if (!(wsi->tls.use_ssl & LCCSCF_USE_SSL)) 221d4afb5ceSopenharmony_ci goto start_ws_handshake; 222d4afb5ceSopenharmony_ci 223d4afb5ceSopenharmony_ci switch (lws_client_create_tls(wsi, &cce, 0)) { 224d4afb5ceSopenharmony_ci case 0: 225d4afb5ceSopenharmony_ci break; 226d4afb5ceSopenharmony_ci case 1: 227d4afb5ceSopenharmony_ci return 0; 228d4afb5ceSopenharmony_ci default: 229d4afb5ceSopenharmony_ci goto bail3; 230d4afb5ceSopenharmony_ci } 231d4afb5ceSopenharmony_ci 232d4afb5ceSopenharmony_ci break; 233d4afb5ceSopenharmony_ci 234d4afb5ceSopenharmony_ci default: 235d4afb5ceSopenharmony_ci break; 236d4afb5ceSopenharmony_ci } 237d4afb5ceSopenharmony_ci break; 238d4afb5ceSopenharmony_ci#endif 239d4afb5ceSopenharmony_ci case LRS_WAITING_DNS: 240d4afb5ceSopenharmony_ci /* 241d4afb5ceSopenharmony_ci * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE 242d4afb5ceSopenharmony_ci * timeout protection set in client-handshake.c 243d4afb5ceSopenharmony_ci */ 244d4afb5ceSopenharmony_ci if (!lws_client_connect_2_dnsreq(wsi)) { 245d4afb5ceSopenharmony_ci /* closed */ 246d4afb5ceSopenharmony_ci lwsl_client("closed\n"); 247d4afb5ceSopenharmony_ci return -1; 248d4afb5ceSopenharmony_ci } 249d4afb5ceSopenharmony_ci 250d4afb5ceSopenharmony_ci /* either still pending connection, or changed mode */ 251d4afb5ceSopenharmony_ci return 0; 252d4afb5ceSopenharmony_ci 253d4afb5ceSopenharmony_ci case LRS_WAITING_CONNECT: 254d4afb5ceSopenharmony_ci 255d4afb5ceSopenharmony_ci /* 256d4afb5ceSopenharmony_ci * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE 257d4afb5ceSopenharmony_ci * timeout protection set in client-handshake.c 258d4afb5ceSopenharmony_ci */ 259d4afb5ceSopenharmony_ci if (pollfd->revents & LWS_POLLOUT) 260d4afb5ceSopenharmony_ci lws_client_connect_3_connect(wsi, NULL, NULL, 0, NULL); 261d4afb5ceSopenharmony_ci break; 262d4afb5ceSopenharmony_ci 263d4afb5ceSopenharmony_ci#if defined(LWS_WITH_TLS) 264d4afb5ceSopenharmony_ci case LRS_WAITING_SSL: 265d4afb5ceSopenharmony_ci 266d4afb5ceSopenharmony_ci if (wsi->tls.use_ssl & LCCSCF_USE_SSL) { 267d4afb5ceSopenharmony_ci n = lws_ssl_client_connect2(wsi, erbuf, sizeof(erbuf)); 268d4afb5ceSopenharmony_ci if (!n) 269d4afb5ceSopenharmony_ci return 0; 270d4afb5ceSopenharmony_ci if (n < 0) { 271d4afb5ceSopenharmony_ci cce = erbuf; 272d4afb5ceSopenharmony_ci goto bail3; 273d4afb5ceSopenharmony_ci } 274d4afb5ceSopenharmony_ci } else 275d4afb5ceSopenharmony_ci wsi->tls.ssl = NULL; 276d4afb5ceSopenharmony_ci#endif /* LWS_WITH_TLS */ 277d4afb5ceSopenharmony_ci 278d4afb5ceSopenharmony_ci /* fallthru */ 279d4afb5ceSopenharmony_ci 280d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SOCKS5) 281d4afb5ceSopenharmony_cistart_ws_handshake: 282d4afb5ceSopenharmony_ci#endif 283d4afb5ceSopenharmony_ci lwsi_set_state(wsi, LRS_MQTTC_IDLE); 284d4afb5ceSopenharmony_ci lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, 285d4afb5ceSopenharmony_ci (int)context->timeout_secs); 286d4afb5ceSopenharmony_ci 287d4afb5ceSopenharmony_ci /* fallthru */ 288d4afb5ceSopenharmony_ci 289d4afb5ceSopenharmony_ci case LRS_MQTTC_IDLE: 290d4afb5ceSopenharmony_ci /* 291d4afb5ceSopenharmony_ci * we should be ready to send out MQTT CONNECT 292d4afb5ceSopenharmony_ci */ 293d4afb5ceSopenharmony_ci lwsl_info("%s: %s: Transport established, send out CONNECT\n", 294d4afb5ceSopenharmony_ci __func__, lws_wsi_tag(wsi)); 295d4afb5ceSopenharmony_ci if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) 296d4afb5ceSopenharmony_ci return -1; 297d4afb5ceSopenharmony_ci if (!lws_mqtt_client_send_connect(wsi)) { 298d4afb5ceSopenharmony_ci lwsl_err("%s: Unable to send MQTT CONNECT\n", __func__); 299d4afb5ceSopenharmony_ci return -1; 300d4afb5ceSopenharmony_ci } 301d4afb5ceSopenharmony_ci if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) 302d4afb5ceSopenharmony_ci return -1; 303d4afb5ceSopenharmony_ci 304d4afb5ceSopenharmony_ci lwsi_set_state(wsi, LRS_MQTTC_AWAIT_CONNACK); 305d4afb5ceSopenharmony_ci return 0; 306d4afb5ceSopenharmony_ci 307d4afb5ceSopenharmony_ci case LRS_ESTABLISHED: 308d4afb5ceSopenharmony_ci case LRS_MQTTC_AWAIT_CONNACK: 309d4afb5ceSopenharmony_ci buffered = 0; 310d4afb5ceSopenharmony_ci ebuf.token = pt->serv_buf; 311d4afb5ceSopenharmony_ci ebuf.len = (int)wsi->a.context->pt_serv_buf_size; 312d4afb5ceSopenharmony_ci 313d4afb5ceSopenharmony_ci if ((unsigned int)ebuf.len > wsi->a.context->pt_serv_buf_size) 314d4afb5ceSopenharmony_ci ebuf.len = (int)wsi->a.context->pt_serv_buf_size; 315d4afb5ceSopenharmony_ci 316d4afb5ceSopenharmony_ci if ((int)pending > ebuf.len) 317d4afb5ceSopenharmony_ci pending = (char)ebuf.len; 318d4afb5ceSopenharmony_ci 319d4afb5ceSopenharmony_ci ebuf.len = lws_ssl_capable_read(wsi, ebuf.token, 320d4afb5ceSopenharmony_ci (unsigned int)(pending ? pending : 321d4afb5ceSopenharmony_ci ebuf.len)); 322d4afb5ceSopenharmony_ci switch (ebuf.len) { 323d4afb5ceSopenharmony_ci case 0: 324d4afb5ceSopenharmony_ci lwsl_info("%s: zero length read\n", 325d4afb5ceSopenharmony_ci __func__); 326d4afb5ceSopenharmony_ci goto fail; 327d4afb5ceSopenharmony_ci case LWS_SSL_CAPABLE_MORE_SERVICE: 328d4afb5ceSopenharmony_ci lwsl_info("SSL Capable more service\n"); 329d4afb5ceSopenharmony_ci return 0; 330d4afb5ceSopenharmony_ci case LWS_SSL_CAPABLE_ERROR: 331d4afb5ceSopenharmony_ci lwsl_info("%s: LWS_SSL_CAPABLE_ERROR\n", 332d4afb5ceSopenharmony_ci __func__); 333d4afb5ceSopenharmony_ci goto fail; 334d4afb5ceSopenharmony_ci } 335d4afb5ceSopenharmony_ci 336d4afb5ceSopenharmony_ci if (ebuf.len < 0) 337d4afb5ceSopenharmony_ci n = -1; 338d4afb5ceSopenharmony_ci else 339d4afb5ceSopenharmony_ci n = lws_read_mqtt(wsi, ebuf.token, (unsigned int)ebuf.len); 340d4afb5ceSopenharmony_ci if (n < 0) { 341d4afb5ceSopenharmony_ci lwsl_err("%s: Parsing packet failed\n", __func__); 342d4afb5ceSopenharmony_ci goto fail; 343d4afb5ceSopenharmony_ci } 344d4afb5ceSopenharmony_ci 345d4afb5ceSopenharmony_ci m = ebuf.len - n; 346d4afb5ceSopenharmony_ci // lws_buflist_describe(&wsi->buflist, wsi, __func__); 347d4afb5ceSopenharmony_ci lwsl_debug("%s: consuming %d / %d\n", __func__, n, ebuf.len); 348d4afb5ceSopenharmony_ci if (lws_buflist_aware_finished_consuming(wsi, &ebuf, m, 349d4afb5ceSopenharmony_ci buffered, 350d4afb5ceSopenharmony_ci __func__)) 351d4afb5ceSopenharmony_ci return -1; 352d4afb5ceSopenharmony_ci 353d4afb5ceSopenharmony_ci return 0; 354d4afb5ceSopenharmony_ci 355d4afb5ceSopenharmony_ci#if defined(LWS_WITH_TLS) || defined(LWS_WITH_SOCKS5) 356d4afb5ceSopenharmony_cibail3: 357d4afb5ceSopenharmony_ci#endif 358d4afb5ceSopenharmony_ci lwsl_info("closing conn at LWS_CONNMODE...SERVER_REPLY\n"); 359d4afb5ceSopenharmony_ci if (cce) 360d4afb5ceSopenharmony_ci lwsl_info("reason: %s\n", cce); 361d4afb5ceSopenharmony_ci lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce)); 362d4afb5ceSopenharmony_ci 363d4afb5ceSopenharmony_ci lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "cbail3"); 364d4afb5ceSopenharmony_ci return -1; 365d4afb5ceSopenharmony_ci 366d4afb5ceSopenharmony_ci default: 367d4afb5ceSopenharmony_ci break; 368d4afb5ceSopenharmony_ci } 369d4afb5ceSopenharmony_ci 370d4afb5ceSopenharmony_ci return 0; 371d4afb5ceSopenharmony_cifail: 372d4afb5ceSopenharmony_ci lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "mqtt svc fail"); 373d4afb5ceSopenharmony_ci 374d4afb5ceSopenharmony_ci return LWS_HPI_RET_WSI_ALREADY_DIED; 375d4afb5ceSopenharmony_ci} 376