libwebsockets
Lightweight C library for HTML5 websockets
lws-mqtt.h
1 /*
2  * libwebsockets - protocol - mqtt
3  *
4  * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation:
9  * version 2.1 of the License.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301 USA
20  *
21  * included from libwebsockets.h
22  */
23 
24 #ifndef _LWS_MQTT_H
25 #define _LWS_MQTT_H 1
26 
27 struct _lws_mqtt_related;
28 typedef struct _lws_mqtt_related lws_mqtt_related_t;
29 struct lws_mqtt_str_st;
30 typedef struct lws_mqtt_str_st lws_mqtt_str_t;
31 
32 #define MQTT_VER_3_1_1 4
33 
34 #define LWS_MQTT_FINAL_PART 1
35 
36 #define LWS_MQTT_MAX_AWSIOT_TOPICLEN 256
37 #define LWS_MQTT_MAX_TOPICLEN 65535
38 #define LWS_MQTT_MAX_CIDLEN 128
39 #define LWS_MQTT_RANDOM_CIDLEN 23 /* 3.1.3.1-5: Server MUST... between
40  1 and 23 chars... */
41 
42 typedef enum {
43  QOS0,
44  QOS1,
45  QOS2, /* not supported */
46  RESERVED_QOS_LEVEL,
47  FAILURE_QOS_LEVEL = 0x80
48 } lws_mqtt_qos_levels_t;
49 
50 typedef union {
51  struct {
52  uint8_t retain:1;
53  uint8_t qos:2;
54  uint8_t dup:1;
55  uint8_t ctrl_pkt_type:4;
56  } flags;
57  uint8_t bits;
59 
60 /*
61  * MQTT connection parameters, passed into struct
62  * lws_client_connect_info to establish a connection using
63  * lws_client_connect_via_info().
64 */
65 typedef struct lws_mqtt_client_connect_param_s {
66  const char *client_id; /* Client ID */
67  uint16_t keep_alive; /* MQTT keep alive
68  interval in
69  seconds */
70  uint8_t clean_start; /* MQTT clean
71  session */
72  struct {
73  const char *topic;
74  const char *message;
75  lws_mqtt_qos_levels_t qos;
76  uint8_t retain;
77  } will_param; /* MQTT LWT
78  parameters */
79  const char *username;
80  const char *password;
81  uint8_t aws_iot;
83 
84 /*
85  * MQTT publish parameters
86 */
87 typedef struct lws_mqtt_publish_param_s {
88  char *topic; /* Topic Name */
89  uint16_t topic_len;
90  const void *payload; /* Publish Payload */
91  uint32_t payload_len; /* Size of the
92  complete payload */
93  uint32_t payload_pos; /* where we are in payload */
94  lws_mqtt_qos_levels_t qos;
95 
96  /*--v-Following will be used by LWS-v--*/
97  uint16_t packet_id; /* Packet ID for QoS >
98  0 */
99  uint8_t dup:1; /* Retried PUBLISH,
100  for QoS > 0 */
102 
103 typedef struct topic_elem {
104  const char *name; /* Topic Name */
105  lws_mqtt_qos_levels_t qos; /* Requested QoS */
106 
107  /*--v-Following will be used by LWS-v--*/
108  uint8_t acked;
110 
111 /*
112  * MQTT publish parameters
113 */
114 typedef struct lws_mqtt_subscribe_param_s {
115  uint32_t num_topics; /* Number of topics */
116  lws_mqtt_topic_elem_t *topic; /* Array of topic elements */
117 
118  /*--v-Following will be used by LWS-v--*/
119  uint16_t packet_id;
121 
122 typedef enum {
123  LMQCP_RESERVED,
124  LMQCP_CTOS_CONNECT, /* Connection request */
125  LMQCP_STOC_CONNACK, /* Connection acknowledgment */
126  LMQCP_PUBLISH, /* Publish Message */
127  LMQCP_PUBACK, /* QoS 1: Publish acknowledgment */
128  LMQCP_PUBREC, /* QoS 2.1: Publish received */
129  LMQCP_PUBREL, /* QoS 2.2: Publish release */
130  LMQCP_PUBCOMP, /* QoS 2.3: Publish complete */
131  LMQCP_CTOS_SUBSCRIBE, /* Subscribe request */
132  LMQCP_STOC_SUBACK, /* Subscribe acknowledgment */
133  LMQCP_CTOS_UNSUBSCRIBE, /* Unsubscribe request */
134  LMQCP_STOC_UNSUBACK, /* Unsubscribe acknowledgment */
135  LMQCP_CTOS_PINGREQ, /* PING request */
136  LMQCP_STOC_PINGRESP, /* PONG response */
137  LMQCP_DISCONNECT, /* Disconnect notification */
138  LMQCP_AUTH /* Authentication exchange */
139 } lws_mqtt_control_packet_t;
140 
141 /* flags from byte 8 of C_TO_S CONNECT */
142 typedef enum {
143  LMQCFT_USERNAME = (1 << 7),
144  LMQCFT_PASSWORD = (1 << 6),
145  LMQCFT_WILL_RETAIN = (1 << 5),
146  LMQCFT_WILL_QOS = (1 << 3),
147  LMQCFT_WILL_FLAG = (1 << 2),
148  LMQCFT_CLEAN_START = (1 << 1),
149  LMQCFT_RESERVED = (1 << 0),
150 
151  LMQCFT_WILL_QOS_MASK = (3 << 3),
152 } lws_mqtt_connect_flags_t;
153 
154 /* flags for S_TO_C CONNACK */
155 typedef enum {
156  LMQCFT_SESSION_PRESENT = (1 << 0),
157 } lws_mqtt_connack_flags_t;
158 
159 typedef enum {
160  LMQCP_REASON_SUCCESS = 0x00,
161  LMQCP_REASON_NORMAL_DISCONNECTION = 0x00,
162  LMQCP_REASON_GRANTED_QOS0 = 0x00,
163  LMQCP_REASON_GRANTED_QOS1 = 0x01,
164  LMQCP_REASON_GRANTED_QOS2 = 0x02,
165  LMQCP_REASON_DISCONNECT_WILL = 0x04,
166  LMQCP_REASON_NO_MATCHING_SUBSCRIBER = 0x10,
167  LMQCP_REASON_NO_SUBSCRIPTION_EXISTED = 0x11,
168  LMQCP_REASON_CONTINUE_AUTHENTICATION = 0x18,
169  LMQCP_REASON_RE_AUTHENTICATE = 0x19,
170 
171  LMQCP_REASON_UNSPECIFIED_ERROR = 0x80,
172  LMQCP_REASON_MALFORMED_PACKET = 0x81,
173  LMQCP_REASON_PROTOCOL_ERROR = 0x82,
174  LMQCP_REASON_IMPLEMENTATION_SPECIFIC_ERROR = 0x83,
175 
176  /* Begin - Error codes for CONNACK */
177  LMQCP_REASON_UNSUPPORTED_PROTOCOL = 0x84,
178  LMQCP_REASON_CLIENT_ID_INVALID = 0x85,
179  LMQCP_REASON_BAD_CREDENTIALS = 0x86,
180  LMQCP_REASON_NOT_AUTHORIZED = 0x87,
181  /* End - Error codes for CONNACK */
182 
183  LMQCP_REASON_SERVER_UNAVAILABLE = 0x88,
184  LMQCP_REASON_SERVER_BUSY = 0x89,
185  LMQCP_REASON_BANNED = 0x8a,
186  LMQCP_REASON_SERVER_SHUTTING_DOWN = 0x8b,
187  LMQCP_REASON_BAD_AUTHENTICATION_METHOD = 0x8c,
188  LMQCP_REASON_KEEPALIVE_TIMEOUT = 0x8d,
189  LMQCP_REASON_SESSION_TAKEN_OVER = 0x8e,
190  LMQCP_REASON_TOPIC_FILTER_INVALID = 0x8f,
191  LMQCP_REASON_TOPIC_NAME_INVALID = 0x90,
192  LMQCP_REASON_PACKET_ID_IN_USE = 0x91,
193  LMQCP_REASON_PACKET_ID_NOT_FOUND = 0x92,
194  LMQCP_REASON_MAX_RX_EXCEEDED = 0x93,
195  LMQCP_REASON_TOPIC_ALIAS_INVALID = 0x94,
196  LMQCP_REASON_PACKET_TOO_LARGE = 0x95,
197  LMQCP_REASON_RATELIMIT = 0x96,
198  LMQCP_REASON_QUOTA_EXCEEDED = 0x97,
199  LMQCP_REASON_ADMINISTRATIVE_ACTION = 0x98,
200  LMQCP_REASON_PAYLOAD_FORMAT_INVALID = 0x99,
201  LMQCP_REASON_RETAIN_NOT_SUPPORTED = 0x9a,
202  LMQCP_REASON_QOS_NOT_SUPPORTED = 0x9b,
203  LMQCP_REASON_USE_ANOTHER_SERVER = 0x9c,
204  LMQCP_REASON_SERVER_MOVED = 0x9d,
205  LMQCP_REASON_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 0x9e,
206  LMQCP_REASON_CONNECTION_RATE_EXCEEDED = 0x9f,
207  LMQCP_REASON_MAXIMUM_CONNECT_TIME = 0xa0,
208  LMQCP_REASON_SUBSCRIPTION_IDS_NOT_SUPPORTED = 0xa1,
209  LMQCP_REASON_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 0xa2,
210 } lws_mqtt_reason_t;
211 
212 typedef enum {
213  LMQPROP_INVALID,
214  LMQPROP_PAYLOAD_FORMAT_INDICATOR = 0x01,
215  LMQPROP_MESSAGE_EXPIRY_INTERVAL = 0x02,
216  LMQPROP_CONTENT_TYPE = 0x03,
217  LMQPROP_RESPONSE_TOPIC = 0x08,
218  LMQPROP_CORRELATION_DATA = 0x09,
219  LMQPROP_SUBSCRIPTION_IDENTIFIER = 0x0b,
220  LMQPROP_SESSION_EXPIRY_INTERVAL = 0x11,
221  LMQPROP_ASSIGNED_CLIENT_IDENTIFIER = 0x12,
222  LMQPROP_SERVER_KEEP_ALIVE = 0x13,
223  LMQPROP_AUTHENTICATION_METHOD = 0x15,
224  LMQPROP_AUTHENTICATION_DATA = 0x16,
225  LMQPROP_REQUEST_PROBLEM_INFORMATION = 0x17,
226  LMQPROP_WILL_DELAY_INTERVAL = 0x18,
227  LMQPROP_REQUEST_RESPONSE_INFORMATION = 0x19,
228  LMQPROP_RESPONSE_INFORMATION = 0x1a,
229  LMQPROP_SERVER_REFERENCE = 0x1c,
230  LMQPROP_REASON_STRING = 0x1f,
231  LMQPROP_RECEIVE_MAXIMUM = 0x21,
232  LMQPROP_TOPIC_ALIAS_MAXIMUM = 0x22,
233  LMQPROP_TOPIC_ALIAS = 0x23,
234  LMQPROP_MAXIMUM_QOS = 0x24,
235  LMQPROP_RETAIN_AVAILABLE = 0x25,
236  LMQPROP_USER_PROPERTY = 0x26,
237  LMQPROP_MAXIMUM_PACKET_SIZE = 0x27,
238  LMQPROP_WILDCARD_SUBSCRIPTION_AVAIL = 0x28,
239  LMQPROP_SUBSCRIPTION_IDENTIFIER_AVAIL = 0x29,
240  LMQPROP_SHARED_SUBSCRIPTION_AVAIL = 0x2a
241 } lws_mqtt_property;
242 
243 int
244 lws_read_mqtt(struct lws *wsi, unsigned char *buf, lws_filepos_t len);
245 
246 /* returns 0 if bd1 and bd2 are "the same", that includes empty, else nonzero */
247 LWS_VISIBLE LWS_EXTERN int
248 lws_mqtt_bindata_cmp(const lws_mqtt_str_t *bd1, const lws_mqtt_str_t *bd2);
249 
250 LWS_VISIBLE LWS_EXTERN void
251 lws_mqtt_str_init(lws_mqtt_str_t *s, uint8_t *buf, uint16_t lim, char nf);
252 
253 LWS_VISIBLE LWS_EXTERN lws_mqtt_str_t *
254 lws_mqtt_str_create(uint16_t lim);
255 
256 LWS_VISIBLE LWS_EXTERN lws_mqtt_str_t *
257 lws_mqtt_str_create_init(uint8_t *buf, uint16_t len, uint16_t lim);
258 
259 LWS_VISIBLE LWS_EXTERN lws_mqtt_str_t *
260 lws_mqtt_str_create_cstr_dup(const char *buf, uint16_t lim);
261 
262 LWS_VISIBLE LWS_EXTERN uint8_t *
263 lws_mqtt_str_next(lws_mqtt_str_t *s, uint16_t *budget);
264 
265 LWS_VISIBLE LWS_EXTERN int
266 lws_mqtt_str_advance(lws_mqtt_str_t *s, int n);
267 
268 LWS_VISIBLE LWS_EXTERN void
269 lws_mqtt_str_free(lws_mqtt_str_t **s);
270 
271 
299 LWS_VISIBLE LWS_EXTERN int
300 lws_mqtt_client_send_publish(struct lws *wsi, lws_mqtt_publish_param_t *pub,
301  const void *buf, uint32_t len, int final);
302 
316 LWS_VISIBLE LWS_EXTERN int
317 lws_mqtt_client_send_subcribe(struct lws *wsi, lws_mqtt_subscribe_param_t *sub);
318 
333 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
334 lws_mqtt_client_send_unsubcribe(struct lws *wsi,
335  const lws_mqtt_subscribe_param_t *unsub);
336 
337 #endif /* _LWS_MQTT_H */
Definition: lws-mqtt.h:64
Definition: lws-mqtt.h:86
Definition: lws-mqtt.h:113
Definition: lws-mqtt.h:102
Definition: lws-mqtt.h:49