File:  [ELWIX - Embedded LightWeight unIX -] / libaitmqtt / inc / aitmqtt.h
Revision 1.3.4.13: download - view: text, annotated - select for diffs - revision graph
Thu Sep 15 15:04:44 2022 UTC (21 months, 2 weeks ago) by misho
Branches: mqtt1_8
Diff to: branchpoint 1.3: preferred, unified
split mqttapi to 2 separate headers for server and client
rework client

/*************************************************************************
* (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
*  by Michael Pounov <misho@openbsd-bg.org>
*
* $Author: misho $
* $Id: aitmqtt.h,v 1.3.4.13 2022/09/15 15:04:44 misho Exp $
*
**************************************************************************
The ELWIX and AITNET software is distributed under the following
terms:

All of the documentation and software included in the ELWIX and AITNET
Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>

Copyright 2004 - 2022
	by Michael Pounov <misho@elwix.org>.  All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
   must display the following acknowledgement:
This product includes software developed by Michael Pounov <misho@elwix.org>
ELWIX - Embedded LightWeight unIX and its contributors.
4. Neither the name of AITNET nor the names of its contributors
   may be used to endorse or promote products derived from this software
   without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#ifndef __AITMQTT_H
#define __AITMQTT_H


#define MQTT_CONNID_MAX		24
#define MQTT_CRED_MAX		13
#define MQTTMSG_MAX		65535
#define MQTTMSG_BIN_MAX		65535
#define MQTT_DATA_MAX		268435455

#define MQTT_PROTO_VER_3	3
#define MQTT_PROTO_VER_311	4
#define MQTT_PROTO_VER_5	5
#define MQTT_KEEPALIVE		60

/* FIXED HEADER */

struct mqtthdr {
	union {
		struct {
			unsigned char	retain:1, 
					qos:2,
					dup:1,
					type:4;
		};
		unsigned char		val;
	} mqtt_msg;
	unsigned char			mqtt_len[1];	/* may be grow to 4 bytes */
} __attribute__((packed));
#define MQTTHDR_MSGINIT(x)	(assert((x)), (x)->mqtt_msg.val ^= (x)->mqtt_msg.val, *(x)->mqtt_len = 0)
#define MQTTHDR_DATA_SIZEOF(x)	(assert((x)), mqtt_decodeLen((x)->mqtt_len, NULL))

typedef union {
	struct {
		unsigned short	m:8,
				l:8;
	} sb;
	unsigned short	val;
} __attribute__((packed)) mqtt_len_t;

typedef struct {
	mqtt_len_t	var_sb;
	unsigned char	var_data[0];
} __attribute__((packed)) mqtthdr_var_t;
#define MQTTHDR_VAR_SIZEOF(x)		(assert((x)), sizeof(mqtt_len_t) + ntohs((x)->var_sb.val))

typedef union {
	struct {
		unsigned char	reserved:1,
				clean_sess:1,
				will_flg:1,
				will_qos:2,
				will_retain:1,
				password:1,
				username:1;
	};
	unsigned char		flags;
} __attribute__((packed)) mqtthdr_connflgs_t;

typedef struct {
	unsigned char	reserved;
	unsigned char	retcode;
} __attribute__((packed)) mqtthdr_connack_t;

#define MQTT_TYPE_UNKNOWN	0	/* reserved */
#define MQTT_TYPE_CONNECT	1	/* client request to connect to server (CLI) */
#define MQTT_TYPE_CONNACK	2	/* connect acknowledgment (SRV) [ret_no_data] */
#define MQTT_TYPE_PUBLISH	3	/* publish message [ret_is_optional] */
#define MQTT_TYPE_PUBACK	4	/* publish acknowledgment [ret_no_data] */
#define MQTT_TYPE_PUBREC	5	/* publish received (assured delivery part 1) [ret_no_data] */
#define MQTT_TYPE_PUBREL	6	/* publish release (assured delivery part 2) [ret_no_data] */
#define MQTT_TYPE_PUBCOMP	7	/* publish complete (assured delivery part 3) [ret_no_data] */
#define MQTT_TYPE_SUBSCRIBE	8	/* client subscribe request (CLI) */
#define MQTT_TYPE_SUBACK	9	/* subscribe acknowledgment (SRV) */
#define MQTT_TYPE_UNSUBSCRIBE	10	/* client unsubscribe request (CLI) */
#define MQTT_TYPE_UNSUBACK	11	/* unsubscribe acknowledgment (SRV) */
#define MQTT_TYPE_PINGREQ	12	/* PING request (CLI) [ret_no_data] */
#define MQTT_TYPE_PINGRESP	13	/* PING response (SRV) [ret_no_data] */
#define MQTT_TYPE_DISCONNECT	14	/* client is disconnecting [ret_no_data] */
#define MQTT_TYPE_AUTH		15	/* authentication exchange [ret_no_data] */

#define MQTT_TYPE_MAX		15

#define MQTT_FLAG_DUP		1	/* This flag is set when the client or server attempts to re-deliver 
					   a PUBLISH, PUBREL, SUBSCRIBE or UNSUBSCRIBE message. 
					   This applies to messages where the value of QoS is greater than 
					   zero (0), and an acknowledgment is required. 
					   When the DUP bit is set, the variable header includes a Message ID.

					   The recipient should treat this flag as a hint as to whether 
					   the message may have been previously received. 
					   It should not be relied on to detect duplicates. */

#define MQTT_QOS_ONCE		0	/* At most once, Fire and Forget, <=1 */
#define MQTT_QOS_ACK		1	/* At least once, Acknowledged delivery, >=1 */
#define MQTT_QOS_EXACTLY	2	/* Exactly once, Assured delivery, =1 */
#define MQTT_QOS_RESERVED	3	/* reserved */

#define MQTT_QOS_DENY		0	/* Not granted QoS for SUBACK */
#define MQTT_QOS_PASS		2	/* Granted QoS for SUBACK */

#define MQTT_FLAG_RETAIN	1	/* This flag is only used on PUBLISH messages.

					   When a client sends a PUBLISH to a server, 
					   if the Retain flag is set (1), 
					   the server should hold on to the message after it has been 
					   delivered to the current subscribers.
					   When a new subscription is established on a topic, 
					   the last retained message on that topic should be sent to 
					   the subscriber with the Retain flag set.
					   If there is no retained message, nothing is sent
					   This is useful where publishers send messages on a 
					   "report by exception" basis, where it might be some time between messages. 
					   This allows new subscribers to instantly receive data with the retained, 
					   or Last Known Good, value.

					   When a server sends a PUBLISH to a client as a result of 
					   a subscription that already existed when the original PUBLISH arrived, 
					   the Retain flag should not be set, regardless of the Retain flag 
					   of the original PUBLISH. This allows a client to distinguish messages 
					   that are being received because they were retained and those 
					   that are being received "live".

					   Retained messages should be kept over restarts of the server.
					   A server may delete a retained message if it receives a message 
					   with a zero-length payload and the Retain flag set on the same topic. */

/* VARIABLE HEADERS */

#define MQTT_RETCODE_ACCEPTED		0
#define MQTT_RETCODE_REFUSE_VER		1
#define MQTT_RETCODE_REFUSE_ID		2
#define MQTT_RETCODE_REFUSE_UNAVAIL	3
#define MQTT_RETCODE_REFUSE_USERPASS	4
#define MQTT_RETCODE_DENIED		5

/* REASON CODES */

#define MQTT_REASON_OK			0x0	/* CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH, DISCONNECT, SUBACK */
#define MQTT_REASON_QOS1		0x1	/* SUBACK */
#define MQTT_REASON_QOS2		0x2	/* SUBACK */
#define MQTT_REASON_DWILL		0x4	/* DISCONNECT */
#define MQTT_REASON_NOMATCH		0x10	/* PUBACK, PUBREC */
#define MQTT_REASON_NOSUBEXIST		0x11	/* UNSUBACK */
#define MQTT_REASON_CONTAUTH		0x18	/* AUTH */
#define MQTT_REASON_REAUTH		0x19	/* AUTH */

/* REASON ERROR CODES */

#define MQTT_REASON_ERROR		0x80	/* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */
#define MQTT_REASON_MALFORMPKT		0x81	/* CONNACK, DISCONNECT */
#define MQTT_REASON_PROTOERR		0x82	/* CONNACK, DISCONNECT */
#define MQTT_REASON_IMPLSPECERR		0x83	/* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */
#define MQTT_REASON_UNSUPVERPROTO	0x84	/* CONNACK */
#define MQTT_REASON_CLINOVALID		0x85	/* CONNACK */
#define MQTT_REASON_BADUSERPASS		0x86	/* CONNACK */
#define MQTT_REASON_NOAUTH		0x87	/* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */
#define MQTT_REASON_SRVUNAVAIL		0x88	/* CONNACK */
#define MQTT_REASON_SRVBUSY		0x89	/* CONNACK, DISCONNECT */
#define MQTT_REASON_BANNED		0x8A	/* CONNACK */
#define MQTT_REASON_SRVSHUTDOWN		0x8B	/* DISCONNECT */
#define MQTT_REASON_BADAUTHMETHOD	0x8C	/* CONNACK, DISCONNECT */
#define MQTT_REASON_KEEPALIVETO		0x8D	/* DISCONNECT */
#define MQTT_REASON_SESTAKEOVER		0x8E	/* DISCONNECT */
#define MQTT_REASON_TOPICFLTINVAL	0x8F	/* SUBACK, UNSUBACK, DISCONNECT */
#define MQTT_REASON_TOPICNAMEINV	0x90	/* CONNACK, PUBACK, PUBREC, DISCONNECT */
#define MQTT_REASON_PKTIDINUSE		0x91	/* PUBACK, PUBREC, SUBACK, UNSUBACK */
#define MQTT_REASON_PKTIDNOTFOUND	0x92	/* PUBREL, PUBCOMP */
#define MQTT_REASON_RCVMAXEXCEED	0x93	/* DISCONNECT */
#define MQTT_REASON_TOPICALIASINV	0x94	/* DISCONNECT */
#define MQTT_REASON_PKTTOOLARGE		0x95	/* CONNACK, DISCONNECT */
#define MQTT_REASON_MSGRATETOHIGH	0x96	/* DISCONNECT */
#define MQTT_REASON_QUOTAEXCEED		0x97	/* CONNACK, PUBACK, PUBREC, SUBACK, DISCONNECT */
#define MQTT_REASON_ADMINACTION		0x98	/* DISCONNECT */
#define MQTT_REASON_PAYLOADFMTINV	0x99	/* CONNACK, PUBACK, PUBREC, DISCONNECT */
#define MQTT_REASON_RETAINNOTSUP	0x9A	/* CONNACK, DISCONNECT */
#define MQTT_REASON_QOSNOTSUP		0x9B	/* CONNACK, DISCONNECT */
#define MQTT_REASON_USENEXTSRV		0x9C	/* CONNACK, DISCONNECT */
#define MQTT_REASON_SRVMOVED		0x9D	/* CONNACK, DISCONNECT */
#define MQTT_REASON_SHARSUBNOTSUP	0x9E	/* SUBACK, DISCONNECT */
#define MQTT_REASON_CONRATEEXCEED	0x9F	/* CONNACK, DISCONNECT */
#define MQTT_REASON_MAXCONNTIME		0xA0	/* DISCONNECT */
#define MQTT_REASON_SUBIDNOTSUP		0xA1	/* SUBACK, DISCONNECT */
#define MQTT_RESON_WILDSUBNOTSUP	0xA2	/* SUBACK, DISCONNECT */

/* MQTT Message buffer */

typedef struct {
	void		*msg_base;
	unsigned int	msg_len;
} mqtt_msg_t;

/* MQTT structures */

typedef struct {
	unsigned char	sub_qos;
	mqtt_msg_t	sub_topic;
	mqtt_msg_t	sub_value;
} mqtt_subscr_t;


// -------------------------------------------------------
// mqtt_GetErrno() Get error code of last operation
int mqtt_GetErrno();
// mqtt_GetError() Get error text of last operation
const char *mqtt_GetError();
// -------------------------------------------------------


/*
 * mqtt_msgAlloc() Allocate memory for MQTT Message
 *
 * @len = >0 Allocate buffer with length
 * return: NULL error or Message, after use must call mqtt_msgFree() with all!=0
 */
mqtt_msg_t *mqtt_msgAlloc(unsigned int len);
/*
 * mqtt_msgFree() Free MQTT message
 *
 * @msg = Message buffer
 * @keepmsg = !=0 just free message content
 * return: none
 */
void mqtt_msgFree(mqtt_msg_t ** __restrict msg, int keepmsg);
/*
 * mqtt_msgRealloc() Reallocate MQTT message buffer
 *
 * @msg = MQTT message
 * @len = new length
 * return: -1 error or >-1 old buffer length
 */
int mqtt_msgRealloc(mqtt_msg_t * __restrict msg, unsigned int len);
/*
 * mqtt_msgDup() - Duplicate message buffer
 *
 * @msg = Message
 * return: NULL error or !=NULL duplicated message, after use must call mqtt_msgFree() with all!=0
 */
mqtt_msg_t *mqtt_msgDup(mqtt_msg_t * __restrict msg);

/*
 * mqtt_expandTopic() - Expanding topic to regular expression
 *
 * @csInput = Input topic
 * @psRegEx = Output to regular expression
 * @regexLen = Length of psRegEx
 * @BOL = Begin of Line, if =0 not added
 * @EOL = End of Line, if =0 not appended
 * return: -1 error, 0 nothing expanded or >0 expanded bytes
 */
int mqtt_expandTopic(const char *csInput, char * __restrict psRegEx, int regexLen, 
		unsigned char BOL, unsigned char EOL);
/*
 * mqtt_sqlTopic() - Expanding topic to SQL search string
 *
 * @csInput = Input topic
 * @psSQL = Output to SQL search string
 * @sqlLen = Length of psSQL
 * return: -1 error, 0 changed bytes
 */
int mqtt_sqlTopic(const char *csInput, char * __restrict psSQL, int sqlLen);

/*
 * mqtt_encodeLen() Encode number to MQTT length field
 *
 * @num = number for encode
 * return: -1 error or >-1 length
 */
unsigned int mqtt_encodeLen(unsigned int num);
/*
 * mqtt_decodeLen() Decode length from MQTT packet
 *
 * @len = length from MQTT header
 * @n = sizeof bytes, if !=NULL
 * return: -1 error, >-1 length of message
 */
unsigned int mqtt_decodeLen(void * __restrict len, int * __restrict n);
/*
 * mqtt_sizeLen Return sizeof len field
 *
 * @len = length
 * return: -1 error, >-1 sizeof len in bytes
 */
char mqtt_sizeLen(unsigned int len);
/*
 * mqtt_pktLen() - Get total packet length
 *
 * @hdr = MQTT packet header
 * return: packet length
 */
unsigned int mqtt_pktLen(struct mqtthdr * __restrict hdr);
/*
 * mqtt_strs2subs Create MQTT subscribe variable from string(s)
 *
 * @csStr = null terminated string array
 * @strnum = copy at most number of strings elements, ==0 till NULL element
 * @qoses = QoS elements applied to subscribe variable, 
 * 		count of elements must be equal with csStr elements
 * return: NULL error or != subscribe variables array, must be free after use with mqtt_freeSub()
 */
mqtt_subscr_t *mqtt_strs2subs(const char **csStr, unsigned short strnum, unsigned char *qoses);
/*
 * mqtt_subFree() Free array from subscribe variables
 *
 * @subs = Subscribe variables
 * return: none
 */
void mqtt_subFree(mqtt_subscr_t ** __restrict subs);
/*
 * mqtt_subAlloc() Create array from subscribe variables
 *
 * @num = Number of elements
 * return: NULL error or subscribe array, after use must call mqtt_subFree()
 */
mqtt_subscr_t *mqtt_subAlloc(unsigned short num);
/*
 * mqtt_subRealloc() Reallocate array from subscribe variables
 *
 * @subs = Subscribe array
 * @num = Number of elements
 * return: NULL error or subscribe array, after use must call mqtt_subFree()
 */
mqtt_subscr_t *mqtt_subRealloc(mqtt_subscr_t ** __restrict subs, unsigned short num);
/*
 * mqtt_subCopy() - Copy subscription structure to another one
 *
 * @dst = destination subscription
 * @src = source subscription
 * return: =NULL error or !=NULL successful copied a structure
 */
mqtt_subscr_t *mqtt_subCopy(mqtt_subscr_t * __restrict dst, mqtt_subscr_t * __restrict src);


/*** SENDER FUNCTIONS ***/

/*
 * mqtt_msgCONNECT() Create CONNECT message
 *
 * @csConnID = ConnectID
 * @Version = MQTT version, if =0 default version is 3.1.1
 * @KASec = Keep alive timeout, if =0 default timeout for MQTT
 * @csUser = Username if !=NULL
 * @csPass = Password for Username, only if csUser is set
 * @csWillTopic = Will Topic if !=NULL Will Flags set into message
 * @csWillMessage = Will Message, may be NULL
 * @ClrSess = Clear Session subscriptions after disconnect
 * @WillQOS = Will QOS if csWillTopic is set
 * @WillRetain = Will Retain Will Message if csWillTopic is set
 * return: NULL error or allocated CONNECT message
 */
mqtt_msg_t *mqtt_msgCONNECT(const char *csConnID, unsigned char Version, 
		unsigned short KASec, const char *csUser, const char *csPass, 
		const char *csWillTopic, const char *csWillMessage, 
		unsigned char ClrSess, unsigned char WillQOS, unsigned char WillRetain);
/*
 * mqtt_msgCONNACK() Create CONNACK message
 *
 * @retcode = Return code
 * return: NULL error or allocated CONNACK message
 */
mqtt_msg_t *mqtt_msgCONNACK(unsigned char retcode);
/*
 * mqtt_msgDISCONNECT() Create DISCONNECT message
 *
 * return: NULL error or allocated message
 */
mqtt_msg_t *mqtt_msgDISCONNECT();
/*
 * mqtt_msgPINGREQ() Create PINGREQ message
 *
 * return: NULL error or allocated message
 */
mqtt_msg_t *mqtt_msgPINGREQ();
/*
 * mqtt_msgPINGRESP() Create PINGRESP message
 *
 * return: NULL error or allocated message
 */
mqtt_msg_t *mqtt_msgPINGRESP();

/*
 * mqtt_msgPUBLISH() Create PUBLISH message
 *
 * @csTopic = Publish topic
 * @msgID = MessageID >0, if QOS != MQTT_QOS_ONCE
 * @Dup = Duplicate message
 * @QOS = QoS
 * @Retain = Retain message
 * @pData = Publish data into topic
 * @datlen = Publish data length
 * return: NULL error or allocated PUBLISH message
 */
mqtt_msg_t *mqtt_msgPUBLISH(const char *csTopic, unsigned short msgID, 
		unsigned char Dup, unsigned char QOS, 
		unsigned char Retain, const void *pData, int datlen);
/*
 * mqtt_msgPUBACK() Create PUBACK message
 *
 * @msgID = MessageID
 * return: NULL error or allocated PUBACK message
 */
mqtt_msg_t *mqtt_msgPUBACK(unsigned short msgID);
/*
 * mqtt_msgPUBREC() Create PUBREC message
 *
 * @msgID = MessageID
 * return: NULL error or allocated PUBREC message
 */
mqtt_msg_t *mqtt_msgPUBREC(unsigned short msgID);
/*
 * mqtt_msgPUBREL() Create PUBREL message
 *
 * @msgID = MessageID
 * return: NULL error or allocated PUBREL message
 */
mqtt_msg_t *mqtt_msgPUBREL(unsigned short msgID);
/*
 * mqtt_msgPUBCOMP() Create PUBCOMP message
 *
 * @msgID = MessageID
 * return: NULL error or allocated PUBCOMP message
 */
mqtt_msg_t *mqtt_msgPUBCOMP(unsigned short msgID);

/*
 * mqtt_msgSUBSCRIBE() Create SUBSCRIBE message
 *
 * @Topics = MQTT subscription topics
 * @msgID = MessageID
 * return: NULL error or allocated SUBSCRIBE message
 */
mqtt_msg_t *mqtt_msgSUBSCRIBE(mqtt_subscr_t ** __restrict Topics, unsigned short msgID);
/*
 * mqtt_msgSUBACK() Create SUBACK message
 *
 * @Topics = MQTT subscription topics
 * @msgID = MessageID
 * return: NULL error or allocated SUBACK message
 */
mqtt_msg_t *mqtt_msgSUBACK(mqtt_subscr_t ** __restrict Topics, unsigned short msgID);
/*
 * mqtt_msgUNSUBSCRIBE() Create UNSUBSCRIBE message
 *
 * @Topics = MQTT subscription topics
 * @msgID = MessageID
 * @Dup = Duplicate message
 * @QOS = QoS
 * return: NULL error or allocated UNSUBSCRIBE message
 */
mqtt_msg_t *mqtt_msgUNSUBSCRIBE(mqtt_subscr_t ** __restrict Topics, 
		unsigned short msgID, unsigned char Dup, unsigned char QOS);
/*
 * mqtt_msgUNSUBACK() Create UNSUBACK message
 *
 * @msgID = MessageID
 * return: NULL error or allocated UNSUBACK message
 */
mqtt_msg_t *mqtt_msgUNSUBACK(unsigned short msgID);


/*** RECEIVER FUNCTIONS ***/

/*
 * mqtt_readCONNECT() Read elements from CONNECT message
 *
 * @buf = Message buffer
 * @KASec = Keep Alive in seconds for current connection
 * @psConnID = ConnectID
 * @connLen = ConnectID length
 * @psUser = Username if !=NULL
 * @userLen = Username length
 * @psPass = Password for Username, only if csUser is set
 * @passLen = Password length
 * @psWillTopic = Will Topic if !=NULL Will Flags set into message and must be e_free()
 * @psWillMessage = Will Message, may be NULL if !NULL must be e_free() after use!
 * return: .reserved == 1 is error or == 0 connection flags & msg ok
 */
mqtthdr_connack_t mqtt_readCONNECT(mqtt_msg_t * __restrict buf, unsigned short *KASec, 
		char * __restrict psConnID, int connLen, 
		char * __restrict psUser, int userLen, char * __restrict psPass, int passLen,  
		char ** __restrict psWillTopic, char ** __restrict psWillMessage);
/*
 * mqtt_readCONNACK() Read CONNACK message
 *
 * @buf = Message buffer
 * return: -1 error or >-1 CONNECT message return code
 */
unsigned char mqtt_readCONNACK(mqtt_msg_t * __restrict buf);
/*
 * mqtt_readDISCONNECT() Read DISCONNECT message
 *
 * @buf = Message buffer
 * return: -1 error, 0 ok, >0 undefined result
 */
int mqtt_readDISCONNECT(mqtt_msg_t * __restrict buf);
/*
 * mqtt_readPINGREQ() Read PINGREQ message
 *
 * @buf = Message buffer
 * return: -1 error, 0 ok, >0 undefined result
 */
int mqtt_readPINGREQ(mqtt_msg_t * __restrict buf);
/*
 * mqtt_readPINGRESP() Read PINGRESP message
 *
 * @buf = Message buffer
 * return: -1 error, 0 ok, >0 undefined result
 */
int mqtt_readPINGRESP(mqtt_msg_t * __restrict buf);

/*
 * mqtt_readPUBLISH() Read PUBLISH message
 *
 * @buf = Message buffer
 * @psTopic = Topic
 * @topicLen = Topic length
 * @msgID = MessageID
 * @pData = Data buffer, may be NULL
 * return: -1 error or !=-1 allocated data buffer length
 */
int mqtt_readPUBLISH(mqtt_msg_t * __restrict buf, char * __restrict psTopic, 
		int topicLen, unsigned short *msgID, void ** __restrict pData);
/*
 * mqtt_readPUBACK() Read PUBACK message
 *
 * @buf = Message buffer
 * return: -1 error or MessageID
 */
unsigned short mqtt_readPUBACK(mqtt_msg_t * __restrict buf);
/*
 * mqtt_readPUBREC() Read PUBREC message
 *
 * @buf = Message buffer
 * return: -1 error or MessageID
 */
unsigned short mqtt_readPUBREC(mqtt_msg_t * __restrict buf);
/*
 * mqtt_readPUBREL() Read PUBREL message
 *
 * @buf = Message buffer
 * return: -1 error or MessageID
 */
unsigned short mqtt_readPUBREL(mqtt_msg_t * __restrict buf);
/*
 * mqtt_readPUBCOMP() Read PUBCOMP message
 *
 * @buf = Message buffer
 * return: -1 error or MessageID
 */
unsigned short mqtt_readPUBCOMP(mqtt_msg_t * __restrict buf);

/*
 * mqtt_readSUBSCRIBE() Read SUBSCRIBE message
 *
 * @buf = Message buffer
 * @msgID = MessageID
 * @subscr = Subscriptions, must be free after use with mqtt_subFree()
 * return: -1 error or >-1 elements into subscr
 */
int mqtt_readSUBSCRIBE(mqtt_msg_t * __restrict buf, unsigned short *msgID, 
		mqtt_subscr_t **subscr);
/*
 * mqtt_readSUBACK() Read SUBACK message
 *
 * @buf = Message buffer
 * @msgID = MessageID
 * @subqos = Subscribes QoS, must be free after use with e_free()
 * return: -1 error or >-1 readed subscribes QoS elements
 */
int mqtt_readSUBACK(mqtt_msg_t * __restrict buf, unsigned short *msgID, unsigned char **subqos);
/*
 * mqtt_readUNSUBSCRIBE() Read UNSUBSCRIBE message
 *
 * @buf = Message buffer
 * @msgID = MessageID
 * @subscr = Subscriptions, must be free after use with mqtt_subFree()
 * return: -1 error or >-1 elements into subscr
 */
int mqtt_readUNSUBSCRIBE(mqtt_msg_t * __restrict buf, unsigned short *msgID, 
		mqtt_subscr_t **subscr);
/*
 * mqtt_readUNSUBACK() Read UNSUBACK message
 *
 * @buf = Message buffer
 * return: -1 error or MessageID
 */
unsigned short mqtt_readUNSUBACK(mqtt_msg_t * __restrict buf);


#endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>