Annotation of libaitmqtt/inc/aitmqtt.h, revision 1.1.1.1.2.6
1.1 misho 1: /*************************************************************************
2: * (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
3: * by Michael Pounov <misho@openbsd-bg.org>
4: *
5: * $Author: misho $
1.1.1.1.2.6! misho 6: * $Id: aitmqtt.h,v 1.1.1.1.2.5 2012/01/27 15:16:40 misho Exp $
1.1 misho 7: *
8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
46: #ifndef __AITMQTT_H
47: #define __AITMQTT_H
48:
49:
1.1.1.1.2.3 misho 50: #define MAX_CONNID 24
51: #define MAX_CRED 13
52: #define MQTTMSG_MAX 65529
1.1.1.1.2.5 misho 53: #define MQTT_DATA_MAX 268435455
1.1.1.1.2.3 misho 54:
1.1.1.1.2.4 misho 55: #define MQTT_PROTO_VER 3
56: #define MQTT_KEEPALIVE 10
1.1.1.1.2.5 misho 57: #define MQTT_DEFAULT_MSGID 0xDEBA
1.1.1.1.2.4 misho 58:
1.1 misho 59: /* FIXED HEADER */
60:
61: struct mqtthdr {
62: union {
63: struct {
64: unsigned char retain:1,
65: qos:2,
66: dup:1,
67: type:4;
68: };
69: unsigned char val;
70: } mqtt_msg;
71: unsigned char mqtt_len[1]; /* may be grow to 4 bytes */
72: } __packed;
73: #define MQTTHDR_MSGINIT(x) (assert((x)), (x)->mqtt_msg.val ^= (x)->mqtt_msg.val)
74:
75: #define MQTT_TYPE_UNKNOWN 0 /* reserved */
76: #define MQTT_TYPE_CONNECT 1 /* client request to connect to server */
77: #define MQTT_TYPE_CONNACK 2 /* connect acknowledgment */
78: #define MQTT_TYPE_PUBLISH 3 /* publish message */
79: #define MQTT_TYPE_PUBACK 4 /* publish acknowledgment */
80: #define MQTT_TYPE_PUBREC 5 /* publish received (assured delivery part 1) */
81: #define MQTT_TYPE_PUBREL 6 /* publish release (assured delivery part 2) */
82: #define MQTT_TYPE_PUBCOMP 7 /* publish complete (assured delivery part 3) */
83: #define MQTT_TYPE_SUBSCRIBE 8 /* client subscribe request */
84: #define MQTT_TYPE_SUBACK 9 /* subscribe acknowledgment */
85: #define MQTT_TYPE_UNSUBSCRIBE 10 /* client unsubscribe request */
86: #define MQTT_TYPE_UNSUBACK 11 /* unsubscribe acknowledgment */
87: #define MQTT_TYPE_PINGREQ 12 /* PING request */
88: #define MQTT_TYPE_PINGRESP 13 /* PING response */
89: #define MQTT_TYPE_DISCONNECT 14 /* client is disconnecting */
90: #define MQTT_TYPE_MAX 15 /* reserved */
91:
92: #define MQTT_FLAG_DUP 1 /* This flag is set when the client or server attempts to re-deliver
93: a PUBLISH, PUBREL, SUBSCRIBE or UNSUBSCRIBE message.
94: This applies to messages where the value of QoS is greater than
95: zero (0), and an acknowledgment is required.
96: When the DUP bit is set, the variable header includes a Message ID.
97:
98: The recipient should treat this flag as a hint as to whether
99: the message may have been previously received.
100: It should not be relied on to detect duplicates. */
101:
102: #define MQTT_QOS_ONCE 0 /* At most once, Fire and Forget, <=1 */
103: #define MQTT_QOS_ACK 1 /* At least once, Acknowledged delivery, >=1 */
104: #define MQTT_QOS_EXACTLY 2 /* Exactly once, Assured delivery, =1 */
105: #define MQTT_QOS_RESERVED 3 /* reserved */
106:
107: #define MQTT_FLAG_RETAIN 1 /* This flag is only used on PUBLISH messages.
108:
109: When a client sends a PUBLISH to a server,
110: if the Retain flag is set (1),
111: the server should hold on to the message after it has been
112: delivered to the current subscribers.
113: When a new subscription is established on a topic,
114: the last retained message on that topic should be sent to
115: the subscriber with the Retain flag set.
116: If there is no retained message, nothing is sent
117: This is useful where publishers send messages on a
118: "report by exception" basis, where it might be some time between messages.
119: This allows new subscribers to instantly receive data with the retained,
120: or Last Known Good, value.
121:
122: When a server sends a PUBLISH to a client as a result of
123: a subscription that already existed when the original PUBLISH arrived,
124: the Retain flag should not be set, regardless of the Retain flag
125: of the original PUBLISH. This allows a client to distinguish messages
126: that are being received because they were retained and those
127: that are being received "live".
128:
129: Retained messages should be kept over restarts of the server.
130: A server may delete a retained message if it receives a message
131: with a zero-length payload and the Retain flag set on the same topic. */
132:
133: /* VARIABLE HEADERS */
134:
135: #define MQTT_RETCODE_ACCEPTED 0
136: #define MQTT_RETCODE_REFUSE_VER 1
137: #define MQTT_RETCODE_REFUSE_ID 2
138: #define MQTT_RETCODE_REFUSE_UNAVAIL 3
139: #define MQTT_RETCODE_REFUSE_USERPASS 4
140: #define MQTT_RETCODE_DENIED 5
141:
142:
143: /* MQTT Message buffer */
144:
145: typedef struct {
146: void *msg_base;
147: unsigned short msg_len;
148: } mqtt_msg_t;
149:
150: /* MQTT structures */
151:
152: typedef union {
153: struct {
154: unsigned short m:8,
155: l:8;
156: } sb;
157: unsigned short val;
158: } mqtt_len_t;
159:
160: typedef struct {
161: unsigned char sub_ret;
162: mqtt_msg_t sub_topic;
163: mqtt_msg_t sub_value;
164: } mqtt_subscr_t;
165:
166: typedef struct {
167: mqtt_len_t var_sb;
168: unsigned char var_data[0];
169: } __packed mqtthdr_var_t;
170: #define MQTTHDR_VAR_SIZEOF(x) (assert((x)), sizeof(mqtt_len_t) + ntohs((x)->var_sb.val))
171:
172: typedef unsigned char mqtthdr_protover_t;
173:
174: typedef union {
175: struct {
176: unsigned char reserved:1,
177: clean_sess:1,
178: will_flg:1,
179: will_qos:2,
180: will_retain:1,
181: password:1,
182: username:1;
183: };
184: unsigned char flags;
185: } __packed mqtthdr_connflgs_t;
186:
187: typedef struct {
188: unsigned char reserved;
189: unsigned char retcode;
190: } __packed mqtthdr_connack_t;
191:
192:
193: // -------------------------------------------------------
194: // mqtt_GetErrno() Get error code of last operation
195: inline int mqtt_GetErrno();
196: // mqtt_GetError() Get error text of last operation
197: inline const char *mqtt_GetError();
198: // -------------------------------------------------------
199:
200:
201: /*
202: * mqtt_msgAlloc() Allocate memory for MQTT Message
203: *
204: * @len = >0 Allocate buffer with length
205: * return: NULL error or Message, after use must call mqtt_msgFree() with all!=0
206: */
207: inline mqtt_msg_t *mqtt_msgAlloc(unsigned short len);
208: /*
209: * mqtt_msgFree() Free MQTT message
210: *
211: * @msg = Message buffer
212: * @all = !=0 Destroy entire message, if MQTT Message allocated with mqtt_msgAlloc()
213: * return: none
214: */
215: inline void mqtt_msgFree(mqtt_msg_t ** __restrict msg, int all);
216: /*
217: * mqtt_msgRealloc() Reallocate MQTT message buffer
218: *
219: * @msg = MQTT message
220: * @len = new length
221: * return: -1 error or >-1 old buffer length
222: */
223: inline int mqtt_msgRealloc(mqtt_msg_t * __restrict msg, unsigned short len);
224:
225: /*
1.1.1.1.2.1 misho 226: * mqtt_expandTopic() - Expanding topic to regular expression
227: *
228: * @csInput = Input topic
229: * @psRegEx = Output to regular expression
230: * @regexLen = Length of psRegEx
231: * @BOL = Begin of Line, if =0 not added
232: * @EOL = End of Line, if =0 not appended
233: * return: -1 error, 0 nothing expanded or >0 expanded bytes
234: */
235: int mqtt_expandTopic(const char *csInput, char * __restrict psRegEx, int regexLen,
236: unsigned char BOL, unsigned char EOL);
1.1.1.1.2.6! misho 237: /*
! 238: * mqtt_sqlTopic() - Expanding topic to SQL search string
! 239: *
! 240: * @csInput = Input topic
! 241: * @psSQL = Output to SQL search string
! 242: * @sqlLen = Length of psSQL
! 243: * return: -1 error, 0 changed bytes
! 244: */
! 245: int mqtt_sqlTopic(const char *csInput, char * __restrict psSQL, int sqlLen);
1.1.1.1.2.1 misho 246:
247: /*
1.1 misho 248: * mqtt_encodeLen() Encode number to MQTT length field
249: *
250: * @num = number for encode
251: * return: -1 error or >-1 length
252: */
253: inline unsigned int mqtt_encodeLen(unsigned int num);
254: /*
255: * mqtt_decodeLen() Decode length from MQTT packet
256: *
257: * @len = length from MQTT header
258: * @n = sizeof bytes, if !=NULL
259: * return: -1 error, >-1 length of message
260: */
261: inline unsigned int mqtt_decodeLen(void * __restrict len, int * __restrict n);
262: /*
263: * mqtt_sizeLen Return sizeof len field
264: *
265: * @len = length
266: * return: -1 error, >-1 sizeof len in bytes
267: */
268: inline char mqtt_sizeLen(unsigned int len);
269: /*
270: * mqtt_str2sub Create MQTT subscribe variable from string(s)
271: *
272: * @csStr = strings
273: * @strnum = number of strings elements
274: * @qoses = QoS elements applied to subscribe variable,
275: * count of elements must be equal with csStr elements
276: * return: NULL error or != subscribe variables array, must be free after use with mqtt_freeSub()
277: */
278: inline mqtt_subscr_t *mqtt_str2sub(const char **csStr, unsigned short strnum, unsigned char *qoses);
279: /*
280: * mqtt_subFree() Free array from subscribe variables
281: *
282: * @subs = Subscribe variables
283: * return: none
284: */
285: inline void mqtt_subFree(mqtt_subscr_t ** __restrict subs);
286: /*
287: * mqtt_subAlloc() Create array from subscribe variables
288: *
289: * @num = Number of elements
290: * return: NULL error or subscribe array, after use must call mqtt_subFree()
291: */
292: inline mqtt_subscr_t *mqtt_subAlloc(unsigned short num);
293: /*
294: * mqtt_subRealloc() Reallocate array from subscribe variables
295: *
296: * @subs = Subscribe array
297: * @num = Number of elements
298: * return: NULL error or subscribe array, after use must call mqtt_subFree()
299: */
300: inline mqtt_subscr_t *mqtt_subRealloc(mqtt_subscr_t * __restrict subs, unsigned short num);
301:
302:
303: /*** SENDER FUNCTIONS ***/
304:
305: /*
306: * mqtt_msgCONNECT() Create CONNECT message
307: *
308: * @buf = Message buffer
309: * @csConnID = ConnectID
310: * @kasec = Keep alive timeout
311: * @csUser = Username if !=NULL
312: * @csPass = Password for Username, only if csUser is set
313: * @csWillTopic = Will Topic if !=NULL Will Flags set into message
314: * @csWillMessage = Will Message, may be NULL
315: * @ClrSess = Clear Session subscriptions after disconnect
316: * @WillQOS = Will QOS if csWillTopic is set
317: * @WillRetain = Will Retain Will Message if csWillTopic is set
318: * return: -1 error or >-1 message size for send
319: */
320: int mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const char *csConnID,
321: unsigned short kasec, const char *csUser, const char *csPass,
322: const char *csWillTopic, const char *csWillMessage,
323: unsigned char ClrSess, unsigned char WillQOS, unsigned char WillRetain);
324: /*
325: * mqtt_msgCONNACK() Create CONNACK message
326: *
327: * @buf = Message buffer
328: * @retcode = Return code
329: * return: -1 error or >-1 message size for send
330: */
331: int mqtt_msgCONNACK(mqtt_msg_t * __restrict buf, unsigned char retcode);
332: /*
333: * mqtt_msgDISCONNECT() Create DISCONNECT message
334: *
335: * @buf = Message buffer
336: * return: -1 error or >-1 message size for send
337: */
338: int mqtt_msgDISCONNECT(mqtt_msg_t * __restrict buf);
339: /*
340: * mqtt_msgPINGREQ() Create PINGREQ message
341: *
342: * @buf = Message buffer
343: * return: -1 error or >-1 message size for send
344: */
345: int mqtt_msgPINGREQ(mqtt_msg_t * __restrict buf);
346: /*
347: * mqtt_msgPINGRESP() Create PINGRESP message
348: *
349: * @buf = Message buffer
350: * return: -1 error or >-1 message size for send
351: */
352: int mqtt_msgPINGRESP(mqtt_msg_t * __restrict buf);
353:
354: /*
355: * mqtt_msgPUBLISH() Create PUBLISH message
356: *
357: * @buf = Message buffer
358: * @csTopic = Publish topic
359: * @msgID = MessageID >0, if QOS != MQTT_QOS_ONCE
360: * @Dup = Duplicate message
361: * @QOS = QoS
362: * @Retain = Retain message
363: * @pData = Publish data into topic
364: * @datlen = Publish data length
365: * return: -1 error or >-1 message size for send
366: */
367: int mqtt_msgPUBLISH(mqtt_msg_t * __restrict buf, const char *csTopic,
368: unsigned short msgID, unsigned char Dup, unsigned char QOS,
369: unsigned char Retain, const void *pData, int datlen);
370: /*
371: * mqtt_msgPUBACK() Create PUBACK message
372: *
373: * @buf = Message buffer
374: * @msgID = MessageID
375: * return: -1 error or >-1 message size for send
376: */
377: inline int mqtt_msgPUBACK(mqtt_msg_t * __restrict buf, unsigned short msgID);
378: /*
379: * mqtt_msgPUBREC() Create PUBREC message
380: *
381: * @buf = Message buffer
382: * @msgID = MessageID
383: * return: -1 error or >-1 message size for send
384: */
385: inline int mqtt_msgPUBREC(mqtt_msg_t * __restrict buf, unsigned short msgID);
386: /*
387: * mqtt_msgPUBREL() Create PUBREL message
388: *
389: * @buf = Message buffer
390: * @msgID = MessageID
391: * return: -1 error or >-1 message size for send
392: */
393: inline int mqtt_msgPUBREL(mqtt_msg_t * __restrict buf, unsigned short msgID);
394: /*
395: * mqtt_msgPUBCOMP() Create PUBCOMP message
396: *
397: * @buf = Message buffer
398: * @msgID = MessageID
399: * return: -1 error or >-1 message size for send
400: */
401: inline int mqtt_msgPUBCOMP(mqtt_msg_t * __restrict buf, unsigned short msgID);
402:
403: /*
404: * mqtt_msgSUBSCRIBE() Create SUBSCRIBE message
405: *
406: * @buf = Message buffer
407: * @Topics = MQTT subscription topics
408: * @msgID = MessageID
409: * @Dup = Duplicate message
410: * @QOS = QoS
411: * return: -1 error or >-1 message size for send
412: */
413: int
414: mqtt_msgSUBSCRIBE(mqtt_msg_t * __restrict buf, mqtt_subscr_t * __restrict Topics,
415: unsigned short msgID, unsigned char Dup, unsigned char QOS);
416: /*
417: * mqtt_msgSUBACK() Create SUBACK message
418: *
419: * @buf = Message buffer
420: * @Topics = MQTT subscription topics
421: * @msgID = MessageID
422: * return: -1 error or >-1 message size for send
423: */
424: int mqtt_msgSUBACK(mqtt_msg_t * __restrict buf, mqtt_subscr_t * __restrict Topics,
425: unsigned short msgID);
426: /*
427: * mqtt_msgUNSUBSCRIBE() Create UNSUBSCRIBE message
428: *
429: * @buf = Message buffer
430: * @Topics = MQTT subscription topics
431: * @msgID = MessageID
432: * @Dup = Duplicate message
433: * @QOS = QoS
434: * return: -1 error or >-1 message size for send
435: */
436: int
437: mqtt_msgUNSUBSCRIBE(mqtt_msg_t * __restrict buf, mqtt_subscr_t * __restrict Topics,
438: unsigned short msgID, unsigned char Dup, unsigned char QOS);
439: /*
440: * mqtt_msgUNSUBACK() Create UNSUBACK message
441: *
442: * @buf = Message buffer
443: * @msgID = MessageID
444: * return: -1 error or >-1 message size for send
445: */
446: int mqtt_msgUNSUBACK(mqtt_msg_t * __restrict buf, unsigned short msgID);
447:
448:
449: /*** RECEIVER FUNCTIONS ***/
450:
451: /*
452: * mqtt_readCONNECT() Read elements from CONNECT message
453: *
454: * @buf = Message buffer
455: * @kasec = Keep Alive in seconds for current connection
456: * @psConnID = ConnectID
457: * @connLen = ConnectID length
458: * @psUser = Username if !=NULL
459: * @userLen = Username length
460: * @psPass = Password for Username, only if csUser is set
461: * @passLen = Password length
462: * @psWillTopic = Will Topic if !=NULL Will Flags set into message and must be free()
463: * @psWillMessage = Will Message, may be NULL if !NULL must be free() after use!
464: * return: .reserved == 1 is error or == 0 connection flags & msg ok
465: */
466: mqtthdr_connack_t mqtt_readCONNECT(mqtt_msg_t * __restrict buf, unsigned short *kasec,
467: char * __restrict psConnID, int connLen,
468: char * __restrict psUser, int userLen, char * __restrict psPass, int passLen,
469: char ** __restrict psWillTopic, char ** __restrict psWillMessage);
470: /*
471: * mqtt_readCONNACK() Read CONNACK message
472: *
473: * @buf = Message buffer
474: * return: -1 error or >-1 CONNECT message return code
475: */
476: unsigned char mqtt_readCONNACK(mqtt_msg_t * __restrict buf);
477: /*
478: * mqtt_readDISCONNECT() Read DISCONNECT message
479: *
480: * @buf = Message buffer
481: * return: -1 error, 0 ok, >0 undefined result
482: */
483: int mqtt_readDISCONNECT(mqtt_msg_t * __restrict buf);
484: /*
485: * mqtt_readPINGREQ() Read PINGREQ message
486: *
487: * @buf = Message buffer
488: * return: -1 error, 0 ok, >0 undefined result
489: */
490: int mqtt_readPINGREQ(mqtt_msg_t * __restrict buf);
491: /*
492: * mqtt_readPINGRESP() Read PINGRESP message
493: *
494: * @buf = Message buffer
495: * return: -1 error, 0 ok, >0 undefined result
496: */
497: int mqtt_readPINGRESP(mqtt_msg_t * __restrict buf);
498:
499: /*
500: * mqtt_readPUBLISH() Read PUBLISH message
501: *
502: * @buf = Message buffer
503: * @psTopic = Topic
504: * @topicLen = Topic length
505: * @msgID = MessageID
506: * @pData = Data buffer
507: * @datLen = Data buffer length, if *datLen == 0 allocate memory for pData
508: * return: NULL error or !=NULL MQTT fixed header
509: */
510: struct mqtthdr *mqtt_readPUBLISH(mqtt_msg_t * __restrict buf, char * __restrict psTopic,
511: int topicLen, unsigned short *msgID, void * __restrict pData, int *datLen);
512: /*
513: * mqtt_readPUBACK() Read PUBACK message
514: *
515: * @buf = Message buffer
516: * return: -1 error or MessageID
517: */
1.1.1.1.2.2 misho 518: unsigned short mqtt_readPUBACK(mqtt_msg_t * __restrict buf);
1.1 misho 519: /*
520: * mqtt_readPUBREC() Read PUBREC message
521: *
522: * @buf = Message buffer
523: * return: -1 error or MessageID
524: */
1.1.1.1.2.2 misho 525: unsigned short mqtt_readPUBREC(mqtt_msg_t * __restrict buf);
1.1 misho 526: /*
527: * mqtt_readPUBREL() Read PUBREL message
528: *
529: * @buf = Message buffer
530: * return: -1 error or MessageID
531: */
1.1.1.1.2.2 misho 532: unsigned short mqtt_readPUBREL(mqtt_msg_t * __restrict buf);
1.1 misho 533: /*
534: * mqtt_readPUBCOMP() Read PUBCOMP message
535: *
536: * @buf = Message buffer
537: * return: -1 error or MessageID
538: */
1.1.1.1.2.2 misho 539: unsigned short mqtt_readPUBCOMP(mqtt_msg_t * __restrict buf);
1.1 misho 540:
541: /*
542: * mqtt_readSUBSCRIBE() Read SUBSCRIBE message
543: *
544: * @buf = Message buffer
545: * @msgID = MessageID
546: * @subscr = Subscriptions, must be free after use with mqtt_subFree()
547: * return: NULL error or !=NULL MQTT fixed header
548: */
549: struct mqtthdr *mqtt_readSUBSCRIBE(mqtt_msg_t * __restrict buf, unsigned short *msgID,
550: mqtt_subscr_t **subscr);
551: /*
552: * mqtt_readSUBACK() Read SUBACK message
553: *
554: * @buf = Message buffer
555: * @msgID = MessageID
556: * @subqos = Subscribes QoS, must be free after use with free()
557: * return: -1 error or >-1 readed subscribes QoS elements
558: */
1.1.1.1.2.2 misho 559: int mqtt_readSUBACK(mqtt_msg_t * __restrict buf, unsigned short *msgID, unsigned char **subqos);
1.1 misho 560: /*
561: * mqtt_readUNSUBSCRIBE() Read UNSUBSCRIBE message
562: *
563: * @buf = Message buffer
564: * @msgID = MessageID
565: * @subscr = Subscriptions, must be free after use with mqtt_subFree()
566: * return: NULL error or !=NULL MQTT fixed header
567: */
568: struct mqtthdr *mqtt_readUNSUBSCRIBE(mqtt_msg_t * __restrict buf, unsigned short *msgID,
569: mqtt_subscr_t **subscr);
570: /*
571: * mqtt_readUNSUBACK() Read UNSUBACK message
572: *
573: * @buf = Message buffer
574: * return: -1 error or MessageID
575: */
1.1.1.1.2.2 misho 576: unsigned short mqtt_readUNSUBACK(mqtt_msg_t * __restrict buf);
1.1 misho 577:
578:
579: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>