--- libaitmqtt/src/conn.c 2012/06/20 15:02:24 1.2 +++ libaitmqtt/src/conn.c 2022/09/13 22:20:59 1.3.12.2 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: conn.c,v 1.2 2012/06/20 15:02:24 misho Exp $ +* $Id: conn.c,v 1.3.12.2 2022/09/13 22:20:59 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Copyright 2004 - 2022 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -49,9 +49,9 @@ SUCH DAMAGE. /* * mqtt_msgCONNECT() Create CONNECT message * - * @buf = Message buffer * @csConnID = ConnectID - * @kasec = Keep alive timeout, if =0 default timeout for MQTT + * @Version = MQTT version + * @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 @@ -59,44 +59,51 @@ SUCH DAMAGE. * @ClrSess = Clear Session subscriptions after disconnect * @WillQOS = Will QOS if csWillTopic is set * @WillRetain = Will Retain Will Message if csWillTopic is set - * return: -1 error or >-1 message size for send + * return: NULL error or allocated connect message */ -int -mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const char *csConnID, - u_short kasec, const char *csUser, const char *csPass, +mqtt_msg_t * +mqtt_msgCONNECT(const char *csConnID, u_char Version, u_short KASec, + const char *csUser, const char *csPass, const char *csWillTopic, const char *csWillMessage, u_char ClrSess, u_char WillQOS, u_char WillRetain) { int len, siz = 0; - u_int n; + u_int n, *l; + mqtt_msg_t *msg = NULL; struct mqtthdr *hdr; mqtthdr_var_t *var, *cid, *topic, *wmsg, *user, *pass; - mqtthdr_protover_t *proto; mqtthdr_connflgs_t *flags; mqtt_len_t *ka; void *data; - if (!buf || !csConnID) - return -1; - if (strlen(csConnID) > 23) { - mqtt_SetErr(EINVAL, "Invalid argument ConnID is too long (max 23 bytes)"); - return -1; + if (!csConnID) + return NULL; + if (strlen(csConnID) >= MQTT_CONNID_MAX) { + mqtt_SetErr(EINVAL, "Invalid argument ConnID is too long (max %d bytes)", + MQTT_CONNID_MAX - 1); + return NULL; } - if (csUser && strlen(csUser) > 12) { - mqtt_SetErr(EINVAL, "Invalid argument Username is too long (max 12 bytes)"); - return -1; + if (Version < MQTT_PROTO_VER_3 || Version > MQTT_PROTO_VER_5) { + mqtt_SetErr(EINVAL, "Unsupported version"); + return NULL; } - if (csPass && strlen(csPass) > 12) { - mqtt_SetErr(EINVAL, "Invalid argument Password is too long (max 12 bytes)"); - return -1; + if (csUser && strlen(csUser) >= MQTT_CRED_MAX) { + mqtt_SetErr(EINVAL, "Invalid argument Username is too long (max %d bytes)", + MQTT_CRED_MAX - 1); + return NULL; } + if (csPass && strlen(csPass) >= MQTT_CRED_MAX) { + mqtt_SetErr(EINVAL, "Invalid argument Password is too long (max %d bytes)", + MQTT_CRED_MAX - 1); + return NULL; + } if (WillQOS > MQTT_QOS_EXACTLY) { mqtt_SetErr(EINVAL, "Invalid argument WillQOS - unknown QOS value"); - return -1; + return NULL; } /* calculate message size */ - len = 10 + sizeof(mqtt_len_t); /* connect arguments */ + len = 10; /* connect arguments: MQTT(6)+Version(1)+ConnFlags(1)+KeepAlive(2) */ len += sizeof(mqtt_len_t) + strlen(csConnID); /* connect id */ if (csUser && *csUser) { /* user/pass */ len += sizeof(mqtt_len_t) + strlen(csUser); @@ -113,28 +120,27 @@ mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const cha n = mqtt_encodeLen(len); /* message size */ siz += mqtt_sizeLen(n) - 1; /* length size */ - if (mqtt_msgRealloc(buf, siz + len) == -1) - return -1; + if (!(msg = mqtt_msgAlloc(siz + len))) + return NULL; else { - data = buf->msg_base; + data = msg->msg_base; hdr = (struct mqtthdr *) data; } /* fixed header */ - MQTTHDR_MSGINIT(hdr); hdr->mqtt_msg.type = MQTT_TYPE_CONNECT; - *(u_int*) hdr->mqtt_len = n; + l = (u_int*) hdr->mqtt_len; + *l = n; data += siz; /* variable header */ var = (mqtthdr_var_t*) data; - var->var_sb.val = htons(strlen(MQTT_CONN_STR)); - memcpy(var->var_data, MQTT_CONN_STR, ntohs(var->var_sb.val)); + var->var_sb.val = htons(strlen(MQTT_PROTO_STR)); + memcpy(var->var_data, MQTT_PROTO_STR, ntohs(var->var_sb.val)); data += MQTTHDR_VAR_SIZEOF(var); /* protocol version */ - proto = (mqtthdr_protover_t*) data++; - *proto = MQTT_PROTO_VER; + *(u_char*) data++ = Version; /* CONNECT header */ flags = (mqtthdr_connflgs_t*) data++; @@ -158,7 +164,7 @@ mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const cha /* keep alive */ ka = (mqtt_len_t*) data; - ka->val = kasec ? htons(kasec) : htons(MQTT_KEEPALIVE); + ka->val = KASec ? htons(KASec) : htons(MQTT_KEEPALIVE); data += sizeof(mqtt_len_t); /* ConnID */ @@ -198,9 +204,9 @@ mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const cha } } - return siz + len; + return msg; } - +#if 0 /* * mqtt_msgCONNACK() Create CONNACK message * @@ -208,22 +214,21 @@ mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const cha * @retcode = Return code * return: -1 error or >-1 message size for send */ -int -mqtt_msgCONNACK(mqtt_msg_t * __restrict buf, u_char retcode) +mqtt_msg_t * +mqtt_msgCONNACK(u_char retcode) { int siz = 0; struct mqtthdr *hdr; mqtthdr_connack_t *ack; + mqtt_msg_t *msg = NULL; - if (!buf) - return -1; if (retcode > MQTT_RETCODE_DENIED) { mqtt_SetErr(EINVAL, "Invalid retcode"); - return -1; + return NULL; } - if (mqtt_msgRealloc(buf, sizeof(struct mqtthdr) + sizeof(mqtthdr_connack_t)) == -1) - return -1; + if (!(msg = mqtt_msgAlloc(sizeof(struct mqtthdr) + sizeof(mqtthdr_connack_t)))) + return NULL; else { hdr = (struct mqtthdr *) (buf->msg_base + siz); siz += sizeof(struct mqtthdr); @@ -330,7 +335,6 @@ mqtt_readCONNECT(mqtt_msg_t * __restrict buf, u_short struct mqtthdr *hdr; mqtthdr_var_t *var; mqtt_len_t *ka; - mqtthdr_protover_t *proto; int len, ret; caddr_t pos; @@ -559,3 +563,4 @@ mqtt_readPINGRESP(mqtt_msg_t * __restrict buf) return len; } +#endif