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