1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2021 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#ifndef _PRIVATE_LIB_ROLES_MQTT 26d4afb5ceSopenharmony_ci#define _PRIVATE_LIB_ROLES_MQTT 1 27d4afb5ceSopenharmony_ci 28d4afb5ceSopenharmony_ciextern struct lws_role_ops role_ops_mqtt; 29d4afb5ceSopenharmony_ci 30d4afb5ceSopenharmony_ci#define lwsi_role_mqtt(wsi) (wsi->role_ops == &role_ops_mqtt) 31d4afb5ceSopenharmony_ci 32d4afb5ceSopenharmony_ci#define LWS_MQTT_MAX_CHILDREN 8 /* max child streams on same parent */ 33d4afb5ceSopenharmony_ci 34d4afb5ceSopenharmony_ci#define LMQCP_LUT_FLAG_RESERVED_FLAGS 0x10 35d4afb5ceSopenharmony_ci#define LMQCP_LUT_FLAG_PACKET_ID_NONE 0x00 36d4afb5ceSopenharmony_ci#define LMQCP_LUT_FLAG_PACKET_ID_HAS 0x20 37d4afb5ceSopenharmony_ci#define LMQCP_LUT_FLAG_PACKET_ID_QOS12 0x40 38d4afb5ceSopenharmony_ci#define LMQCP_LUT_FLAG_PACKET_ID_MASK 0x60 39d4afb5ceSopenharmony_ci#define LMQCP_LUT_FLAG_PAYLOAD 0x80 /* payload req (publish = opt)*/ 40d4afb5ceSopenharmony_ci 41d4afb5ceSopenharmony_ci#define lws_mqtt_str_is_not_empty(s) ( ((s)) && \ 42d4afb5ceSopenharmony_ci ((s))->len && \ 43d4afb5ceSopenharmony_ci ((s))->buf && \ 44d4afb5ceSopenharmony_ci *((s))->buf ) 45d4afb5ceSopenharmony_ci 46d4afb5ceSopenharmony_ci#define LWS_MQTT_RESPONSE_TIMEOUT (3 * LWS_US_PER_SEC) 47d4afb5ceSopenharmony_ci#define LWS_MQTT_RETRY_CEILING (60 * LWS_US_PER_SEC) 48d4afb5ceSopenharmony_ci#define LWS_MQTT_MAX_PUBLISH_RETRY (3) 49d4afb5ceSopenharmony_ci 50d4afb5ceSopenharmony_citypedef enum { 51d4afb5ceSopenharmony_ci LMSPR_COMPLETED = 0, 52d4afb5ceSopenharmony_ci LMSPR_NEED_MORE = 1, 53d4afb5ceSopenharmony_ci 54d4afb5ceSopenharmony_ci LMSPR_FAILED_OOM = -1, 55d4afb5ceSopenharmony_ci LMSPR_FAILED_OVERSIZE = -2, 56d4afb5ceSopenharmony_ci LMSPR_FAILED_FORMAT = -3, 57d4afb5ceSopenharmony_ci LMSPR_FAILED_ALREADY_COMPLETED = -4, 58d4afb5ceSopenharmony_ci} lws_mqtt_stateful_primitive_return_t; 59d4afb5ceSopenharmony_ci 60d4afb5ceSopenharmony_citypedef struct { 61d4afb5ceSopenharmony_ci uint32_t value; 62d4afb5ceSopenharmony_ci char budget; 63d4afb5ceSopenharmony_ci char consumed; 64d4afb5ceSopenharmony_ci} lws_mqtt_vbi; 65d4afb5ceSopenharmony_ci 66d4afb5ceSopenharmony_ci/* works for vbi, 2-byte and 4-byte fixed length */ 67d4afb5ceSopenharmony_cistatic inline int 68d4afb5ceSopenharmony_cilws_mqtt_mb_first(lws_mqtt_vbi *vbi) { return !vbi->consumed; } 69d4afb5ceSopenharmony_ci 70d4afb5ceSopenharmony_ciint 71d4afb5ceSopenharmony_cilws_mqtt_vbi_encode(uint32_t value, void *buf); 72d4afb5ceSopenharmony_ci 73d4afb5ceSopenharmony_ci/* 74d4afb5ceSopenharmony_ci * Decode is done statefully on an arbitrary amount of input data (which may 75d4afb5ceSopenharmony_ci * be one byte). It's like this so it can continue seamlessly if a buffer ends 76d4afb5ceSopenharmony_ci * partway through the primitive, and the api matches the bulk binary data case. 77d4afb5ceSopenharmony_ci * 78d4afb5ceSopenharmony_ci * VBI decode: 79d4afb5ceSopenharmony_ci * 80d4afb5ceSopenharmony_ci * Initialize the lws_mqtt_vbi state by calling lws_mqtt_vbi_init() on it, then 81d4afb5ceSopenharmony_ci * feed lws_mqtt_vbi_r() bytes to decode. 82d4afb5ceSopenharmony_ci * 83d4afb5ceSopenharmony_ci * Returns <0 for error, LMSPR_COMPLETED if done (vbi->value is valid), or 84d4afb5ceSopenharmony_ci * LMSPR_NEED_MORE if more calls to lws_mqtt_vbi_r() with subsequent bytes 85d4afb5ceSopenharmony_ci * needed. 86d4afb5ceSopenharmony_ci * 87d4afb5ceSopenharmony_ci * *in and *len are updated accordingly. 88d4afb5ceSopenharmony_ci * 89d4afb5ceSopenharmony_ci * 2-byte and 4-byte decode: 90d4afb5ceSopenharmony_ci * 91d4afb5ceSopenharmony_ci * Initialize the lws_mqtt_vbi state by calling lws_mqtt_2byte_init() or 92d4afb5ceSopenharmony_ci * lws_mqtt_4byte_init() on it, then feed lws_mqtt_mb_parse() bytes 93d4afb5ceSopenharmony_ci * to decode. 94d4afb5ceSopenharmony_ci * 95d4afb5ceSopenharmony_ci * Returns <0 for error, LMSPR_COMPLETED if done (vbi->value is valid), or 96d4afb5ceSopenharmony_ci * LMSPR_NEED_MORE if more calls to lws_mqtt_mb_parse() with subsequent 97d4afb5ceSopenharmony_ci * bytes needed. 98d4afb5ceSopenharmony_ci * 99d4afb5ceSopenharmony_ci * *in and *len are updated accordingly. 100d4afb5ceSopenharmony_ci */ 101d4afb5ceSopenharmony_ci 102d4afb5ceSopenharmony_civoid 103d4afb5ceSopenharmony_cilws_mqtt_vbi_init(lws_mqtt_vbi *vbi); 104d4afb5ceSopenharmony_ci 105d4afb5ceSopenharmony_civoid 106d4afb5ceSopenharmony_cilws_mqtt_2byte_init(lws_mqtt_vbi *vbi); 107d4afb5ceSopenharmony_ci 108d4afb5ceSopenharmony_civoid 109d4afb5ceSopenharmony_cilws_mqtt_4byte_init(lws_mqtt_vbi *vbi); 110d4afb5ceSopenharmony_ci 111d4afb5ceSopenharmony_cilws_mqtt_stateful_primitive_return_t 112d4afb5ceSopenharmony_cilws_mqtt_vbi_r(lws_mqtt_vbi *vbi, const uint8_t **in, size_t *len); 113d4afb5ceSopenharmony_ci 114d4afb5ceSopenharmony_cilws_mqtt_stateful_primitive_return_t 115d4afb5ceSopenharmony_cilws_mqtt_mb_parse(lws_mqtt_vbi *vbi, const uint8_t **in, size_t *len); 116d4afb5ceSopenharmony_ci 117d4afb5ceSopenharmony_cistruct lws_mqtt_str_st { 118d4afb5ceSopenharmony_ci uint8_t *buf; 119d4afb5ceSopenharmony_ci uint16_t len; 120d4afb5ceSopenharmony_ci 121d4afb5ceSopenharmony_ci uint16_t limit; /* it's cheaper to add the state here than 122d4afb5ceSopenharmony_ci * the pointer to point to it elsewhere */ 123d4afb5ceSopenharmony_ci uint16_t pos; 124d4afb5ceSopenharmony_ci char len_valid; 125d4afb5ceSopenharmony_ci char needs_freeing; 126d4afb5ceSopenharmony_ci}; 127d4afb5ceSopenharmony_ci 128d4afb5ceSopenharmony_cistatic inline int 129d4afb5ceSopenharmony_cilws_mqtt_str_first(struct lws_mqtt_str_st *s) { return !s->buf && !s->pos; } 130d4afb5ceSopenharmony_ci 131d4afb5ceSopenharmony_ci 132d4afb5ceSopenharmony_cilws_mqtt_stateful_primitive_return_t 133d4afb5ceSopenharmony_cilws_mqtt_str_parse(struct lws_mqtt_str_st *bd, const uint8_t **in, size_t *len); 134d4afb5ceSopenharmony_ci 135d4afb5ceSopenharmony_citypedef enum { 136d4afb5ceSopenharmony_ci LMQCPP_IDLE, 137d4afb5ceSopenharmony_ci 138d4afb5ceSopenharmony_ci /* receive packet type part of fixed header took us out of idle... */ 139d4afb5ceSopenharmony_ci LMQCPP_CONNECT_PACKET = LMQCP_CTOS_CONNECT << 4, 140d4afb5ceSopenharmony_ci LMQCPP_CONNECT_REMAINING_LEN_VBI, 141d4afb5ceSopenharmony_ci LMQCPP_CONNECT_VH_PNAME, 142d4afb5ceSopenharmony_ci LMQCPP_CONNECT_VH_PVERSION, 143d4afb5ceSopenharmony_ci LMQCPP_CONNECT_VH_FLAGS, 144d4afb5ceSopenharmony_ci LMQCPP_CONNECT_VH_KEEPALIVE, 145d4afb5ceSopenharmony_ci LMQCPP_CONNECT_VH_PROPERTIES_VBI_LEN, 146d4afb5ceSopenharmony_ci 147d4afb5ceSopenharmony_ci LMQCPP_CONNACK_PACKET = LMQCP_STOC_CONNACK << 4, 148d4afb5ceSopenharmony_ci LMQCPP_CONNACK_VH_FLAGS, 149d4afb5ceSopenharmony_ci LMQCPP_CONNACK_VH_RETURN_CODE, 150d4afb5ceSopenharmony_ci 151d4afb5ceSopenharmony_ci LMQCPP_PUBLISH_PACKET = LMQCP_PUBLISH << 4, 152d4afb5ceSopenharmony_ci LMQCPP_PUBLISH_REMAINING_LEN_VBI, 153d4afb5ceSopenharmony_ci LMQCPP_PUBLISH_VH_TOPIC, 154d4afb5ceSopenharmony_ci LMQCPP_PUBLISH_VH_PKT_ID, 155d4afb5ceSopenharmony_ci 156d4afb5ceSopenharmony_ci LMQCPP_PUBACK_PACKET = LMQCP_PUBACK << 4, 157d4afb5ceSopenharmony_ci LMQCPP_PUBACK_VH_PKT_ID, 158d4afb5ceSopenharmony_ci LMQCPP_PUBACK_PROPERTIES_LEN_VBI, 159d4afb5ceSopenharmony_ci 160d4afb5ceSopenharmony_ci LMQCPP_PUBREC_PACKET = LMQCP_PUBREC << 4, 161d4afb5ceSopenharmony_ci LMQCPP_PUBREC_VH_PKT_ID, 162d4afb5ceSopenharmony_ci 163d4afb5ceSopenharmony_ci LMQCPP_PUBREL_PACKET = LMQCP_PUBREL << 4, 164d4afb5ceSopenharmony_ci LMQCPP_PUBREL_VH_PKT_ID, 165d4afb5ceSopenharmony_ci 166d4afb5ceSopenharmony_ci LMQCPP_PUBCOMP_PACKET = LMQCP_PUBCOMP << 4, 167d4afb5ceSopenharmony_ci LMQCPP_PUBCOMP_VH_PKT_ID, 168d4afb5ceSopenharmony_ci 169d4afb5ceSopenharmony_ci LMQCPP_SUBACK_PACKET = LMQCP_STOC_SUBACK << 4, 170d4afb5ceSopenharmony_ci LMQCPP_SUBACK_VH_PKT_ID, 171d4afb5ceSopenharmony_ci LMQCPP_SUBACK_PAYLOAD, 172d4afb5ceSopenharmony_ci 173d4afb5ceSopenharmony_ci LMQCPP_UNSUBACK_PACKET = LMQCP_STOC_UNSUBACK << 4, 174d4afb5ceSopenharmony_ci LMQCPP_UNSUBACK_VH_PKT_ID, 175d4afb5ceSopenharmony_ci 176d4afb5ceSopenharmony_ci LMQCPP_PINGRESP_ZERO = LMQCP_STOC_PINGRESP << 4, 177d4afb5ceSopenharmony_ci 178d4afb5ceSopenharmony_ci LMQCPP_PAYLOAD, 179d4afb5ceSopenharmony_ci 180d4afb5ceSopenharmony_ci LMQCPP_EAT_PROPERTIES_AND_COMPLETE, 181d4afb5ceSopenharmony_ci 182d4afb5ceSopenharmony_ci LMQCPP_PROP_ID_VBI, 183d4afb5ceSopenharmony_ci 184d4afb5ceSopenharmony_ci /* all possible property payloads */ 185d4afb5ceSopenharmony_ci 186d4afb5ceSopenharmony_ci /* 3.3.2.3.2 */ 187d4afb5ceSopenharmony_ci LMQCPP_PROP_PAYLOAD_FORMAT_INDICATOR_1BYTE = 0x101, 188d4afb5ceSopenharmony_ci 189d4afb5ceSopenharmony_ci LMQCPP_PROP_MSG_EXPIRY_INTERVAL_4BYTE = 0x102, 190d4afb5ceSopenharmony_ci 191d4afb5ceSopenharmony_ci LMQCPP_PROP_CONTENT_TYPE_UTF8S = 0x103, 192d4afb5ceSopenharmony_ci 193d4afb5ceSopenharmony_ci LMQCPP_PROP_RESPONSE_TOPIC_UTF8S = 0x108, 194d4afb5ceSopenharmony_ci 195d4afb5ceSopenharmony_ci LMQCPP_PROP_CORRELATION_BINDATA = 0x109, 196d4afb5ceSopenharmony_ci 197d4afb5ceSopenharmony_ci LMQCPP_PROP_SUBSCRIPTION_ID_VBI = 0x10b, 198d4afb5ceSopenharmony_ci 199d4afb5ceSopenharmony_ci LMQCPP_PROP_SESSION_EXPIRY_INTERVAL_4BYTE = 0x111, 200d4afb5ceSopenharmony_ci 201d4afb5ceSopenharmony_ci LMQCPP_PROP_ASSIGNED_CLIENTID_UTF8S = 0x112, 202d4afb5ceSopenharmony_ci 203d4afb5ceSopenharmony_ci LMQCPP_PROP_SERVER_KEEPALIVE_2BYTE = 0x113, 204d4afb5ceSopenharmony_ci 205d4afb5ceSopenharmony_ci LMQCPP_PROP_AUTH_METHOD_UTF8S = 0x115, 206d4afb5ceSopenharmony_ci 207d4afb5ceSopenharmony_ci LMQCPP_PROP_AUTH_DATA_BINDATA = 0x116, 208d4afb5ceSopenharmony_ci 209d4afb5ceSopenharmony_ci LMQCPP_PROP_REQUEST_PROBLEM_INFO_1BYTE = 0x117, 210d4afb5ceSopenharmony_ci 211d4afb5ceSopenharmony_ci LMQCPP_PROP_WILL_DELAY_INTERVAL_4BYTE = 0x118, 212d4afb5ceSopenharmony_ci 213d4afb5ceSopenharmony_ci LMQCPP_PROP_REQUEST_REPSONSE_INFO_1BYTE = 0x119, 214d4afb5ceSopenharmony_ci 215d4afb5ceSopenharmony_ci LMQCPP_PROP_RESPONSE_INFO_UTF8S = 0x11a, 216d4afb5ceSopenharmony_ci 217d4afb5ceSopenharmony_ci LMQCPP_PROP_SERVER_REFERENCE_UTF8S = 0x11c, 218d4afb5ceSopenharmony_ci 219d4afb5ceSopenharmony_ci LMQCPP_PROP_REASON_STRING_UTF8S = 0x11f, 220d4afb5ceSopenharmony_ci 221d4afb5ceSopenharmony_ci LMQCPP_PROP_RECEIVE_MAXIMUM_2BYTE = 0x121, 222d4afb5ceSopenharmony_ci 223d4afb5ceSopenharmony_ci LMQCPP_PROP_TOPIC_MAXIMUM_2BYTE = 0x122, 224d4afb5ceSopenharmony_ci 225d4afb5ceSopenharmony_ci LMQCPP_PROP_TOPIC_ALIAS_2BYTE = 0x123, 226d4afb5ceSopenharmony_ci 227d4afb5ceSopenharmony_ci LMQCPP_PROP_MAXIMUM_QOS_1BYTE = 0x124, 228d4afb5ceSopenharmony_ci 229d4afb5ceSopenharmony_ci LMQCPP_PROP_RETAIN_AVAILABLE_1BYTE = 0x125, 230d4afb5ceSopenharmony_ci 231d4afb5ceSopenharmony_ci LMQCPP_PROP_USER_PROPERTY_NAME_UTF8S = 0x126, 232d4afb5ceSopenharmony_ci LMQCPP_PROP_USER_PROPERTY_VALUE_UTF8S = 0x226, 233d4afb5ceSopenharmony_ci 234d4afb5ceSopenharmony_ci LMQCPP_PROP_MAXIMUM_PACKET_SIZE_4BYTE = 0x127, 235d4afb5ceSopenharmony_ci 236d4afb5ceSopenharmony_ci LMQCPP_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE_1BYTE = 0x128, 237d4afb5ceSopenharmony_ci 238d4afb5ceSopenharmony_ci LMQCPP_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE_1BYTE = 0x129, 239d4afb5ceSopenharmony_ci 240d4afb5ceSopenharmony_ci LMQCPP_PROP_SHARED_SUBSCRIPTION_AVAILABLE_1BYTE = 0x12a, 241d4afb5ceSopenharmony_ci 242d4afb5ceSopenharmony_ci} lws_mqtt_packet_parse_state_t; 243d4afb5ceSopenharmony_ci 244d4afb5ceSopenharmony_ci/* 245d4afb5ceSopenharmony_ci * the states an MQTT connection can be in 246d4afb5ceSopenharmony_ci */ 247d4afb5ceSopenharmony_ci 248d4afb5ceSopenharmony_citypedef enum { 249d4afb5ceSopenharmony_ci LGSMQTT_UNKNOWN, 250d4afb5ceSopenharmony_ci LGSMQTT_IDLE, 251d4afb5ceSopenharmony_ci LGSMQTT_TRANSPORT_CONNECTED, 252d4afb5ceSopenharmony_ci 253d4afb5ceSopenharmony_ci LGSMQTT_SENT_CONNECT, 254d4afb5ceSopenharmony_ci LGSMQTT_ESTABLISHED, 255d4afb5ceSopenharmony_ci 256d4afb5ceSopenharmony_ci LGSMQTT_SENT_SUBSCRIBE, 257d4afb5ceSopenharmony_ci LGSMQTT_SUBSCRIBED, 258d4afb5ceSopenharmony_ci 259d4afb5ceSopenharmony_ci} lwsgs_mqtt_states_t; 260d4afb5ceSopenharmony_ci 261d4afb5ceSopenharmony_citypedef struct lws_mqtt_parser_st { 262d4afb5ceSopenharmony_ci /* struct lws_mqtt_str_st s_content_type; */ 263d4afb5ceSopenharmony_ci lws_mqtt_packet_parse_state_t state; 264d4afb5ceSopenharmony_ci lws_mqtt_vbi vbit; 265d4afb5ceSopenharmony_ci 266d4afb5ceSopenharmony_ci lws_mqtt_reason_t reason; 267d4afb5ceSopenharmony_ci 268d4afb5ceSopenharmony_ci lws_mqtt_str_t s_temp; 269d4afb5ceSopenharmony_ci 270d4afb5ceSopenharmony_ci uint8_t fixed_seen[4]; 271d4afb5ceSopenharmony_ci uint8_t props_seen[8]; 272d4afb5ceSopenharmony_ci 273d4afb5ceSopenharmony_ci uint8_t cpkt_flags; 274d4afb5ceSopenharmony_ci uint32_t cpkt_remlen; 275d4afb5ceSopenharmony_ci 276d4afb5ceSopenharmony_ci uint32_t props_len; 277d4afb5ceSopenharmony_ci uint32_t consumed; 278d4afb5ceSopenharmony_ci uint32_t prop_id; 279d4afb5ceSopenharmony_ci uint32_t props_consumed; 280d4afb5ceSopenharmony_ci uint32_t payload_consumed; 281d4afb5ceSopenharmony_ci 282d4afb5ceSopenharmony_ci uint16_t keepalive; 283d4afb5ceSopenharmony_ci uint16_t cpkt_id; 284d4afb5ceSopenharmony_ci uint32_t n; 285d4afb5ceSopenharmony_ci 286d4afb5ceSopenharmony_ci uint8_t temp[32]; 287d4afb5ceSopenharmony_ci uint8_t conn_rc; 288d4afb5ceSopenharmony_ci uint8_t payload_format; 289d4afb5ceSopenharmony_ci uint8_t packet_type_flags; 290d4afb5ceSopenharmony_ci uint8_t conn_protocol_version; 291d4afb5ceSopenharmony_ci uint8_t fixed; 292d4afb5ceSopenharmony_ci 293d4afb5ceSopenharmony_ci uint8_t flag_pending_send_connack_close:1; 294d4afb5ceSopenharmony_ci uint8_t flag_pending_send_reason_close:1; 295d4afb5ceSopenharmony_ci uint8_t flag_prop_multi:1; 296d4afb5ceSopenharmony_ci uint8_t flag_server:1; 297d4afb5ceSopenharmony_ci 298d4afb5ceSopenharmony_ci} lws_mqtt_parser_t; 299d4afb5ceSopenharmony_ci 300d4afb5ceSopenharmony_citypedef enum { 301d4afb5ceSopenharmony_ci LMVTR_VALID = 0, 302d4afb5ceSopenharmony_ci LMVTR_VALID_WILDCARD = 1, 303d4afb5ceSopenharmony_ci LMVTR_VALID_SHADOW = 2, 304d4afb5ceSopenharmony_ci 305d4afb5ceSopenharmony_ci LMVTR_FAILED_OVERSIZE = -1, 306d4afb5ceSopenharmony_ci LMVTR_FAILED_WILDCARD_FORMAT = -2, 307d4afb5ceSopenharmony_ci LMVTR_FAILED_SHADOW_FORMAT = -3, 308d4afb5ceSopenharmony_ci} lws_mqtt_validate_topic_return_t; 309d4afb5ceSopenharmony_ci 310d4afb5ceSopenharmony_citypedef enum { 311d4afb5ceSopenharmony_ci LMMTR_TOPIC_NOMATCH = 0, 312d4afb5ceSopenharmony_ci LMMTR_TOPIC_MATCH = 1, 313d4afb5ceSopenharmony_ci 314d4afb5ceSopenharmony_ci LMMTR_TOPIC_MATCH_ERROR = -1 315d4afb5ceSopenharmony_ci} lws_mqtt_match_topic_return_t; 316d4afb5ceSopenharmony_ci 317d4afb5ceSopenharmony_citypedef struct lws_mqtt_subs { 318d4afb5ceSopenharmony_ci struct lws_mqtt_subs *next; 319d4afb5ceSopenharmony_ci 320d4afb5ceSopenharmony_ci uint8_t ref_count; /* number of children referencing */ 321d4afb5ceSopenharmony_ci 322d4afb5ceSopenharmony_ci /* Flags */ 323d4afb5ceSopenharmony_ci uint8_t wildcard:1; 324d4afb5ceSopenharmony_ci uint8_t shadow:1; 325d4afb5ceSopenharmony_ci 326d4afb5ceSopenharmony_ci /* subscription name + NUL overallocated here */ 327d4afb5ceSopenharmony_ci char topic[]; 328d4afb5ceSopenharmony_ci} lws_mqtt_subs_t; 329d4afb5ceSopenharmony_ci 330d4afb5ceSopenharmony_citypedef struct lws_mqtts { 331d4afb5ceSopenharmony_ci lws_mqtt_parser_t par; 332d4afb5ceSopenharmony_ci lwsgs_mqtt_states_t estate; 333d4afb5ceSopenharmony_ci struct lws_dll2 active_session_list_head; 334d4afb5ceSopenharmony_ci struct lws_dll2 limbo_session_list_head; 335d4afb5ceSopenharmony_ci} lws_mqtts_t; 336d4afb5ceSopenharmony_ci 337d4afb5ceSopenharmony_citypedef struct lws_mqttc { 338d4afb5ceSopenharmony_ci lws_mqtt_parser_t par; 339d4afb5ceSopenharmony_ci lwsgs_mqtt_states_t estate; 340d4afb5ceSopenharmony_ci struct lws_mqtt_str_st *id; 341d4afb5ceSopenharmony_ci struct lws_mqtt_str_st *username; 342d4afb5ceSopenharmony_ci struct lws_mqtt_str_st *password; 343d4afb5ceSopenharmony_ci struct { 344d4afb5ceSopenharmony_ci struct lws_mqtt_str_st *topic; 345d4afb5ceSopenharmony_ci struct lws_mqtt_str_st *message; 346d4afb5ceSopenharmony_ci lws_mqtt_qos_levels_t qos; 347d4afb5ceSopenharmony_ci uint8_t retain; 348d4afb5ceSopenharmony_ci } will; 349d4afb5ceSopenharmony_ci uint16_t keep_alive_secs; 350d4afb5ceSopenharmony_ci uint16_t conn_flags; 351d4afb5ceSopenharmony_ci uint8_t aws_iot; 352d4afb5ceSopenharmony_ci} lws_mqttc_t; 353d4afb5ceSopenharmony_ci 354d4afb5ceSopenharmony_cistruct _lws_mqtt_related { 355d4afb5ceSopenharmony_ci lws_mqttc_t client; 356d4afb5ceSopenharmony_ci lws_sorted_usec_list_t sul_qos_puback_pubrec_wait; /* QoS1 puback or QoS2 pubrec wait TO */ 357d4afb5ceSopenharmony_ci lws_sorted_usec_list_t sul_qos1_puback_wait; /* QoS1 puback wait TO */ 358d4afb5ceSopenharmony_ci lws_sorted_usec_list_t sul_unsuback_wait; /* unsuback wait TO */ 359d4afb5ceSopenharmony_ci lws_sorted_usec_list_t sul_qos2_pubrec_wait; /* QoS2 pubrec wait TO */ 360d4afb5ceSopenharmony_ci lws_sorted_usec_list_t sul_shadow_wait; /* Device Shadow wait TO */ 361d4afb5ceSopenharmony_ci struct lws *wsi; /**< so sul can use lws_container_of */ 362d4afb5ceSopenharmony_ci lws_mqtt_subs_t *subs_head; /**< Linked-list of heap-allocated subscription objects */ 363d4afb5ceSopenharmony_ci void *rx_cpkt_param; 364d4afb5ceSopenharmony_ci uint16_t pkt_id; 365d4afb5ceSopenharmony_ci uint16_t ack_pkt_id; 366d4afb5ceSopenharmony_ci uint16_t peer_ack_pkt_id; 367d4afb5ceSopenharmony_ci uint16_t sub_size; 368d4afb5ceSopenharmony_ci 369d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT) 370d4afb5ceSopenharmony_ci uint8_t send_pingreq:1; 371d4afb5ceSopenharmony_ci uint8_t session_resumed:1; 372d4afb5ceSopenharmony_ci#endif 373d4afb5ceSopenharmony_ci uint8_t inside_payload:1; 374d4afb5ceSopenharmony_ci uint8_t inside_subscribe:1; 375d4afb5ceSopenharmony_ci uint8_t inside_unsubscribe:1; 376d4afb5ceSopenharmony_ci uint8_t inside_birth:1; 377d4afb5ceSopenharmony_ci uint8_t inside_resume_session:1; 378d4afb5ceSopenharmony_ci uint8_t send_puback:1; 379d4afb5ceSopenharmony_ci uint8_t send_pubrel:1; 380d4afb5ceSopenharmony_ci uint8_t send_pubrec:1; 381d4afb5ceSopenharmony_ci uint8_t send_pubcomp:1; 382d4afb5ceSopenharmony_ci uint8_t unacked_publish:1; 383d4afb5ceSopenharmony_ci uint8_t unacked_pubrel:1; 384d4afb5ceSopenharmony_ci 385d4afb5ceSopenharmony_ci uint8_t done_subscribe:1; 386d4afb5ceSopenharmony_ci uint8_t done_birth:1; 387d4afb5ceSopenharmony_ci uint8_t inside_shadow:1; 388d4afb5ceSopenharmony_ci uint8_t done_shadow_subscribe:1; 389d4afb5ceSopenharmony_ci uint8_t send_shadow_unsubscribe:1; 390d4afb5ceSopenharmony_ci}; 391d4afb5ceSopenharmony_ci 392d4afb5ceSopenharmony_ci/* 393d4afb5ceSopenharmony_ci * New sessions are created by starting CONNECT. If the ClientID sent 394d4afb5ceSopenharmony_ci * by the client matches a different, extant session, then the 395d4afb5ceSopenharmony_ci * existing one is taken over and the new one created for duration of 396d4afb5ceSopenharmony_ci * CONNECT processing is destroyed. 397d4afb5ceSopenharmony_ci * 398d4afb5ceSopenharmony_ci * On the server side, bearing in mind multiple simultaneous, 399d4afb5ceSopenharmony_ci * fragmented CONNECTs may be interleaved ongoing, all state and 400d4afb5ceSopenharmony_ci * parsing temps for a session must live in the session object. 401d4afb5ceSopenharmony_ci */ 402d4afb5ceSopenharmony_ci 403d4afb5ceSopenharmony_cistruct lws_mqtt_endpoint_st; 404d4afb5ceSopenharmony_ci 405d4afb5ceSopenharmony_citypedef struct lws_mqtts_session_st { 406d4afb5ceSopenharmony_ci struct lws_dll2 session_list; 407d4afb5ceSopenharmony_ci 408d4afb5ceSopenharmony_ci} lws_mqtts_session_t; 409d4afb5ceSopenharmony_ci 410d4afb5ceSopenharmony_ci#define ctl_pkt_type(x) (x->packet_type_flags >> 4) 411d4afb5ceSopenharmony_ci 412d4afb5ceSopenharmony_ci 413d4afb5ceSopenharmony_civoid 414d4afb5ceSopenharmony_cilws_mqttc_state_transition(lws_mqttc_t *ep, lwsgs_mqtt_states_t s); 415d4afb5ceSopenharmony_ci 416d4afb5ceSopenharmony_ciint 417d4afb5ceSopenharmony_ci_lws_mqtt_rx_parser(struct lws *wsi, lws_mqtt_parser_t *par, 418d4afb5ceSopenharmony_ci const uint8_t *buf, size_t len); 419d4afb5ceSopenharmony_ci 420d4afb5ceSopenharmony_ciint 421d4afb5ceSopenharmony_cilws_mqtt_client_socket_service(struct lws *wsi, struct lws_pollfd *pollfd, 422d4afb5ceSopenharmony_ci struct lws *wsi_conn); 423d4afb5ceSopenharmony_ci 424d4afb5ceSopenharmony_ciint 425d4afb5ceSopenharmony_cilws_create_client_mqtt_object(const struct lws_client_connect_info *i, 426d4afb5ceSopenharmony_ci struct lws *wsi); 427d4afb5ceSopenharmony_ci 428d4afb5ceSopenharmony_cistruct lws * 429d4afb5ceSopenharmony_cilws_mqtt_client_send_connect(struct lws *wsi); 430d4afb5ceSopenharmony_ci 431d4afb5ceSopenharmony_cistruct lws * 432d4afb5ceSopenharmony_cilws_mqtt_client_send_disconnect(struct lws *wsi); 433d4afb5ceSopenharmony_ci 434d4afb5ceSopenharmony_ciint 435d4afb5ceSopenharmony_cilws_mqtt_fill_fixed_header(uint8_t *p, lws_mqtt_control_packet_t ctrl_pkt_type, 436d4afb5ceSopenharmony_ci uint8_t dup, lws_mqtt_qos_levels_t qos, 437d4afb5ceSopenharmony_ci uint8_t retain); 438d4afb5ceSopenharmony_ci 439d4afb5ceSopenharmony_cistruct lws * 440d4afb5ceSopenharmony_cilws_wsi_mqtt_adopt(struct lws *parent_wsi, struct lws *wsi); 441d4afb5ceSopenharmony_ci 442d4afb5ceSopenharmony_cilws_mqtt_subs_t * 443d4afb5ceSopenharmony_cilws_mqtt_find_sub(struct _lws_mqtt_related *mqtt, const char *topic); 444d4afb5ceSopenharmony_ci 445d4afb5ceSopenharmony_cilws_mqtt_match_topic_return_t 446d4afb5ceSopenharmony_cilws_mqtt_is_topic_matched(const char* sub, const char* pub); 447d4afb5ceSopenharmony_ci 448d4afb5ceSopenharmony_ci#endif /* _PRIVATE_LIB_ROLES_MQTT */ 449d4afb5ceSopenharmony_ci 450