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