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