![]() ![]() | ![]() |
start implement read* message commands & ut
1: #ifndef __AITMQTT_H 2: #define __AITMQTT_H 3: 4: 5: /* FIXED HEADER */ 6: 7: struct mqtthdr { 8: union { 9: struct { 10: unsigned char retain:1, 11: qos:2, 12: dup:1, 13: type:4; 14: }; 15: unsigned char val; 16: } mqtt_msg; 17: unsigned char mqtt_len[1]; /* may be grow to 4 bytes */ 18: } __packed; 19: #define MQTTHDR_MSGINIT(x) (assert((x)), (x)->mqtt_msg.val ^= (x)->mqtt_msg.val) 20: 21: #define MQTT_TYPE_UNKNOWN 0 /* reserved */ 22: #define MQTT_TYPE_CONNECT 1 /* client request to connect to server */ 23: #define MQTT_TYPE_CONNACK 2 /* connect acknowledgment */ 24: #define MQTT_TYPE_PUBLISH 3 /* publish message */ 25: #define MQTT_TYPE_PUBACK 4 /* publish acknowledgment */ 26: #define MQTT_TYPE_PUBREC 5 /* publish received (assured delivery part 1) */ 27: #define MQTT_TYPE_PUBREL 6 /* publish release (assured delivery part 2) */ 28: #define MQTT_TYPE_PUBCOMP 7 /* publish complete (assured delivery part 3) */ 29: #define MQTT_TYPE_SUBSCRIBE 8 /* client subscribe request */ 30: #define MQTT_TYPE_SUBACK 9 /* subscribe acknowledgment */ 31: #define MQTT_TYPE_UNSUBSCRIBE 10 /* client unsubscribe request */ 32: #define MQTT_TYPE_UNSUBACK 11 /* unsubscribe acknowledgment */ 33: #define MQTT_TYPE_PINGREQ 12 /* PING request */ 34: #define MQTT_TYPE_PINGRESP 13 /* PING response */ 35: #define MQTT_TYPE_DISCONNECT 14 /* client is disconnecting */ 36: #define MQTT_TYPE_MAX 15 /* reserved */ 37: 38: #define MQTT_FLAG_DUP 1 /* This flag is set when the client or server attempts to re-deliver 39: a PUBLISH, PUBREL, SUBSCRIBE or UNSUBSCRIBE message. 40: This applies to messages where the value of QoS is greater than 41: zero (0), and an acknowledgment is required. 42: When the DUP bit is set, the variable header includes a Message ID. 43: 44: The recipient should treat this flag as a hint as to whether 45: the message may have been previously received. 46: It should not be relied on to detect duplicates. */ 47: 48: #define MQTT_QOS_ONCE 0 /* At most once, Fire and Forget, <=1 */ 49: #define MQTT_QOS_ACK 1 /* At least once, Acknowledged delivery, >=1 */ 50: #define MQTT_QOS_EXACTLY 2 /* Exactly once, Assured delivery, =1 */ 51: #define MQTT_QOS_RESERVED 3 /* reserved */ 52: 53: #define MQTT_FLAG_RETAIN 1 /* This flag is only used on PUBLISH messages. 54: 55: When a client sends a PUBLISH to a server, 56: if the Retain flag is set (1), 57: the server should hold on to the message after it has been 58: delivered to the current subscribers. 59: When a new subscription is established on a topic, 60: the last retained message on that topic should be sent to 61: the subscriber with the Retain flag set. 62: If there is no retained message, nothing is sent 63: This is useful where publishers send messages on a 64: "report by exception" basis, where it might be some time between messages. 65: This allows new subscribers to instantly receive data with the retained, 66: or Last Known Good, value. 67: 68: When a server sends a PUBLISH to a client as a result of 69: a subscription that already existed when the original PUBLISH arrived, 70: the Retain flag should not be set, regardless of the Retain flag 71: of the original PUBLISH. This allows a client to distinguish messages 72: that are being received because they were retained and those 73: that are being received "live". 74: 75: Retained messages should be kept over restarts of the server. 76: A server may delete a retained message if it receives a message 77: with a zero-length payload and the Retain flag set on the same topic. */ 78: 79: /* VARIABLE HEADERS */ 80: 81: #define MQTT_RETCODE_ACCEPTED 0 82: #define MQTT_RETCODE_REFUSE_VER 1 83: #define MQTT_RETCODE_REFUSE_ID 2 84: #define MQTT_RETCODE_REFUSE_UNAVAIL 3 85: #define MQTT_RETCODE_REFUSE_USERPASS 4 86: #define MQTT_RETCODE_DENIED 5 87: 88: 89: typedef union { 90: struct { 91: unsigned short m:8, 92: l:8; 93: } sb; 94: unsigned short val; 95: } mqtt_v_t; 96: 97: typedef struct { 98: unsigned char sub_ret; 99: struct __sbuf sub_topic; 100: struct __sbuf sub_value; 101: } mqtt_subscr_t; 102: 103: typedef struct { 104: mqtt_v_t var_sb; 105: unsigned char var_data[0]; 106: } __packed mqtthdr_var_t; 107: #define MQTTHDR_VAR_SIZEOF(x) (assert((x)), sizeof(mqtt_v_t) + ntohs((x)->var_sb.val)) 108: 109: typedef unsigned char mqtthdr_protover_t; 110: 111: typedef struct { 112: unsigned char reserved:1, 113: clean_sess:1, 114: will_flg:1, 115: will_qos:2, 116: will_retain:1, 117: password:1, 118: username:1; 119: } __packed mqtthdr_connflgs_t; 120: 121: typedef struct { 122: unsigned char reserved; 123: unsigned char retcode; 124: } __packed mqtthdr_connack_t; 125: 126: 127: /* MQTT Message buffer */ 128: 129: typedef struct { 130: void *msg_base; 131: unsigned short msg_len; 132: } mqtt_msg_t; 133: 134: /* MQTT dispatcher callbacks */ 135: 136: typedef int (*mqtt_cb_t)(void *); 137: 138: 139: // ------------------------------------------------------- 140: // mqtt_GetErrno() Get error code of last operation 141: inline int mqtt_GetErrno(); 142: // mqtt_GetError() Get error text of last operation 143: inline const char *mqtt_GetError(); 144: // ------------------------------------------------------- 145: 146: 147: /* 148: * mqtt_msgAlloc() Allocate memory for MQTT Message 149: * 150: * @len = >0 Allocate buffer with length 151: * return: NULL error or Message, after use must call mqtt_msgFree() with all!=0 152: */ 153: inline mqtt_msg_t *mqtt_msgAlloc(unsigned short len); 154: /* 155: * mqtt_msgFree() Free MQTT message 156: * 157: * @msg = Message buffer 158: * @all = !=0 Destroy entire message, if MQTT Message allocated with mqtt_msgAlloc() 159: * return: none 160: */ 161: inline void mqtt_msgFree(mqtt_msg_t ** __restrict msg, int all); 162: /* 163: * mqtt_msgRealloc() Reallocate MQTT message buffer 164: * 165: * @msg = MQTT message 166: * @len = new length 167: * return: -1 error or >-1 old buffer length 168: */ 169: inline int mqtt_msgRealloc(mqtt_msg_t * __restrict msg, unsigned short len); 170: 171: /* 172: * mqtt_encodeLen() Encode number to MQTT length field 173: * 174: * @num = number for encode 175: * return: -1 error or >-1 length 176: */ 177: inline unsigned int mqtt_encodeLen(unsigned int num); 178: /* 179: * mqtt_decodeLen() Decode length from MQTT packet 180: * 181: * @len = length from MQTT header 182: * @n = sizeof bytes, if !=NULL 183: * return: -1 error, >-1 length of message 184: */ 185: inline unsigned int mqtt_decodeLen(void * __restrict len, int * __restrict n); 186: /* 187: * mqtt_sizeLen Return sizeof len field 188: * 189: * @len = length 190: * return: -1 error, >-1 sizeof len in bytes 191: */ 192: inline char mqtt_sizeLen(unsigned int len); 193: /* 194: * mqtt_str2sub Create MQTT subscribe variable from string(s) 195: * 196: * @csStr = strings 197: * @strnum = number of strings elements 198: * @qoses = QoS elements applied to subscribe variable, 199: * count of elements must be equal with csStr elements 200: * return: NULL error or != subscribe variables array, must be free after use with mqtt_freeSub() 201: */ 202: inline mqtt_subscr_t *mqtt_str2sub(const char **csStr, unsigned short strnum, unsigned char *qoses); 203: /* 204: * mqtt_subFree() Free array from subscribe variables 205: * 206: * @subs = Subscribe variables 207: * return: none 208: */ 209: inline void mqtt_subFree(mqtt_subscr_t ** __restrict subs); 210: /* 211: * mqtt_subAlloc() Create array from subscribe variables 212: * 213: * @num = Number of elements 214: * return: NULL error or subscribe array, after use must call mqtt_subFree() 215: */ 216: inline mqtt_subscr_t *mqtt_subAlloc(unsigned short num); 217: 218: 219: /*** SENDER FUNCTIONS ***/ 220: 221: /* 222: * mqtt_msgCONNECT() Create CONNECT message 223: * 224: * @buf = Message buffer 225: * @csConnID = ConnectID 226: * @csUser = Username if !=NULL 227: * @csPass = Password for Username, only if csUser is set 228: * @csWillTopic = Will Topic if !=NULL Will Flags set into message 229: * @csWillMessage = Will Message, may be NULL 230: * @ClrSess = Clear Session subscriptions after disconnect 231: * @WillQOS = Will QOS if csWillTopic is set 232: * @WillRetain = Will Retain Will Message if csWillTopic is set 233: * return: -1 error or >-1 message size for send 234: */ 235: int mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const char *csConnID, 236: const char *csUser, const char *csPass, 237: const char *csWillTopic, const char *csWillMessage, 238: unsigned char ClrSess, unsigned char WillQOS, unsigned char WillRetain); 239: /* 240: * mqtt_msgCONNACK() Create CONNACK message 241: * 242: * @buf = Message buffer 243: * @retcode = Return code 244: * return: -1 error or >-1 message size for send 245: */ 246: int mqtt_msgCONNACK(mqtt_msg_t * __restrict buf, unsigned char retcode); 247: /* 248: * mqtt_msgDISCONNECT() Create DISCONNECT message 249: * 250: * @buf = Message buffer 251: * return: -1 error or >-1 message size for send 252: */ 253: int mqtt_msgDISCONNECT(mqtt_msg_t * __restrict buf); 254: /* 255: * mqtt_msgPINGREQ() Create PINGREQ message 256: * 257: * @buf = Message buffer 258: * return: -1 error or >-1 message size for send 259: */ 260: int mqtt_msgPINGREQ(mqtt_msg_t * __restrict buf); 261: /* 262: * mqtt_msgPINGRESP() Create PINGRESP message 263: * 264: * @buf = Message buffer 265: * return: -1 error or >-1 message size for send 266: */ 267: int mqtt_msgPINGRESP(mqtt_msg_t * __restrict buf); 268: 269: /* 270: * mqtt_msgPUBLISH() Create PUBLISH message 271: * 272: * @buf = Message buffer 273: * @csTopic = Publish topic 274: * @msgID = MessageID >0, if QOS != MQTT_QOS_ONCE 275: * @Dup = Duplicate message 276: * @QOS = QoS 277: * @Retain = Retain message 278: * @pData = Publish data into topic 279: * @datlen = Publish data length 280: * return: -1 error or >-1 message size for send 281: */ 282: int mqtt_msgPUBLISH(mqtt_msg_t * __restrict buf, const char *csTopic, unsigned short msgID, 283: unsigned char Dup, unsigned char QOS, unsigned char Retain, 284: const void *pData, unsigned short datlen); 285: /* 286: * mqtt_msgPUBACK() Create PUBACK message 287: * 288: * @buf = Message buffer 289: * @msgID = MessageID 290: * return: -1 error or >-1 message size for send 291: */ 292: inline int mqtt_msgPUBACK(mqtt_msg_t * __restrict buf, unsigned short msgID); 293: /* 294: * mqtt_msgPUBREC() Create PUBREC message 295: * 296: * @buf = Message buffer 297: * @msgID = MessageID 298: * return: -1 error or >-1 message size for send 299: */ 300: inline int mqtt_msgPUBREC(mqtt_msg_t * __restrict buf, unsigned short msgID); 301: /* 302: * mqtt_msgPUBREL() Create PUBREL message 303: * 304: * @buf = Message buffer 305: * @msgID = MessageID 306: * return: -1 error or >-1 message size for send 307: */ 308: inline int mqtt_msgPUBREL(mqtt_msg_t * __restrict buf, unsigned short msgID); 309: /* 310: * mqtt_msgPUBCOMP() Create PUBCOMP message 311: * 312: * @buf = Message buffer 313: * @msgID = MessageID 314: * return: -1 error or >-1 message size for send 315: */ 316: inline int mqtt_msgPUBCOMP(mqtt_msg_t * __restrict buf, unsigned short msgID); 317: 318: /* 319: * mqtt_msgSUBSCRIBE() Create SUBSCRIBE message 320: * 321: * @buf = Message buffer 322: * @Topics = MQTT subscription topics 323: * @msgID = MessageID 324: * @Dup = Duplicate message 325: * @QOS = QoS 326: * return: -1 error or >-1 message size for send 327: */ 328: int 329: mqtt_msgSUBSCRIBE(mqtt_msg_t * __restrict buf, mqtt_subscr_t * __restrict Topics, 330: unsigned short msgID, unsigned char Dup, unsigned char QOS); 331: /* 332: * mqtt_msgSUBACK() Create SUBACK message 333: * 334: * @buf = Message buffer 335: * @Topics = MQTT subscription topics 336: * @msgID = MessageID 337: * return: -1 error or >-1 message size for send 338: */ 339: int mqtt_msgSUBACK(mqtt_msg_t * __restrict buf, mqtt_subscr_t * __restrict Topics, 340: unsigned short msgID); 341: /* 342: * mqtt_msgUNSUBSCRIBE() Create UNSUBSCRIBE message 343: * 344: * @buf = Message buffer 345: * @Topics = MQTT subscription topics 346: * @msgID = MessageID 347: * @Dup = Duplicate message 348: * @QOS = QoS 349: * return: -1 error or >-1 message size for send 350: */ 351: int 352: mqtt_msgUNSUBSCRIBE(mqtt_msg_t * __restrict buf, mqtt_subscr_t * __restrict Topics, 353: unsigned short msgID, unsigned char Dup, unsigned char QOS); 354: /* 355: * mqtt_msgUNSUBACK() Create UNSUBACK message 356: * 357: * @buf = Message buffer 358: * @msgID = MessageID 359: * return: -1 error or >-1 message size for send 360: */ 361: int mqtt_msgUNSUBACK(mqtt_msg_t * __restrict buf, unsigned short msgID); 362: 363: 364: /*** RECEIVER FUNCTIONS ***/ 365: 366: /* 367: * mqtt_readCONNECT() Read elements from CONNECT message 368: * 369: * @buf = Message buffer 370: * @kasec = Keep Alive in seconds for current connection 371: * @psConnID = ConnectID 372: * @connLen = ConnectID length 373: * @psUser = Username if !=NULL 374: * @userLen = Username length 375: * @psPass = Password for Username, only if csUser is set 376: * @passLen = Password length 377: * @psWillTopic = Will Topic if !=NULL Will Flags set into message 378: * @topicLen = Will Topic length 379: * @psWillMessage = Will Message, may be NULL 380: * @msgLen = Will Message length 381: * return: .reserved == 1 is error or == 0 connection flags & msg ok 382: */ 383: mqtthdr_connflgs_t mqtt_readCONNECT(mqtt_msg_t * __restrict buf, unsigned short *kasec, 384: char * __restrict psConnID, int connLen, 385: char * __restrict psUser, int userLen, char * __restrict psPass, int passLen, 386: char * __restrict psWillTopic, int topicLen, char * __restrict psWillMessage, int msgLen); 387: 388: 389: /*** ENGINE FUNCTIONS ***/ 390: 391: /* 392: * mqttInitCallbacks() Init callback array for dispatcher 393: * 394: * return: NULL error or !=NULL allocated callback array, after use free with mqttFiniCallbacks() 395: */ 396: mqtt_cb_t *mqttInitCallbacks(void); 397: /* 398: * mqttFiniCallbacks() Free callback array 399: * 400: * @cb = Callback array 401: * return: none 402: */ 403: void mqttFiniCallbacks(mqtt_cb_t ** __restrict cb); 404: /* 405: * MQTT_CALLBACK() Assign function to callback array for MQTT dispatcher 406: * 407: * @_cbs = Callback array 408: * @_x = MQTT Message type, like MQTT_TYPE_* ... 409: * @_func = Function 410: * return: none 411: */ 412: #define MQTT_CALLBACK(_cbs, _x, _func) (assert((_cbs)), (_cbs)[(_x)] = (_func)) 413: /* 414: * mqttDispatcher() MQTT Message type dispatcher 415: * 416: * @cb = Callback array 417: * @buf = Received MQTT message 418: * return: -1 error or >-1 return value from executed callback 419: */ 420: inline int mqttDispatcher(mqtt_cb_t * __restrict cb, mqtt_msg_t * __restrict buf); 421: 422: 423: #endif