--- libaitmqtt/src/conn.c 2012/04/07 21:00:52 1.1.1.1.2.1 +++ libaitmqtt/src/conn.c 2012/06/20 11:11:30 1.1.1.1.2.6 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: conn.c,v 1.1.1.1.2.1 2012/04/07 21:00:52 misho Exp $ +* $Id: conn.c,v 1.1.1.1.2.6 2012/06/20 11:11:30 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -51,7 +51,7 @@ SUCH DAMAGE. * * @buf = Message buffer * @csConnID = ConnectID - * @kasec = Keep alive timeout + * @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 @@ -67,12 +67,14 @@ mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const cha const char *csWillTopic, const char *csWillMessage, u_char ClrSess, u_char WillQOS, u_char WillRetain) { - int siz = 0; + int len, siz = 0; + u_int n; 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; @@ -93,33 +95,49 @@ mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const cha return -1; } - if (mqtt_msgRealloc(buf, BUFSIZ) == -1) + /* calculate message size */ + len = 10 + sizeof(mqtt_len_t); /* connect arguments */ + len += sizeof(mqtt_len_t) + strlen(csConnID); /* connect id */ + if (csUser && *csUser) { /* user/pass */ + len += sizeof(mqtt_len_t) + strlen(csUser); + if (csPass) + len += sizeof(mqtt_len_t) + strlen(csPass); + } + if (csWillTopic && *csWillTopic) { /* will messages */ + len += sizeof(mqtt_len_t) + strlen(csWillTopic); + len += sizeof(mqtt_len_t) + (csWillMessage ? strlen(csWillMessage) : 0); + } + + /* calculate header size */ + siz = sizeof(struct mqtthdr); /* mqtt fixed header */ + n = mqtt_encodeLen(len); /* message size */ + siz += mqtt_sizeLen(n) - 1; /* length size */ + + if (mqtt_msgRealloc(buf, siz + len) == -1) return -1; else { - hdr = (struct mqtthdr *) (buf->msg_base + siz); - siz += sizeof(struct mqtthdr); - var = (mqtthdr_var_t*) (buf->msg_base + siz); - siz += 8; - proto = buf->msg_base + siz; - siz++; - flags = (mqtthdr_connflgs_t*) (buf->msg_base + siz); - siz++; - ka = (mqtt_len_t*) (buf->msg_base + siz); - siz += sizeof(mqtt_len_t); + data = buf->msg_base; + hdr = (struct mqtthdr *) data; } /* fixed header */ MQTTHDR_MSGINIT(hdr); hdr->mqtt_msg.type = MQTT_TYPE_CONNECT; - *hdr->mqtt_len = 0; + *(u_int*) hdr->mqtt_len = n; + data += siz; /* variable header */ - var->var_sb.sb.l = 6; - memcpy(var->var_data, MQTT_CONN_STR, 6); + 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)); + data += MQTTHDR_VAR_SIZEOF(var); + /* protocol version */ + proto = (mqtthdr_protover_t*) data++; *proto = MQTT_PROTO_VER; /* CONNECT header */ + flags = (mqtthdr_connflgs_t*) data++; flags->clean_sess = ClrSess ? 1 : 0; if (csUser && *csUser) { flags->username = 1; @@ -138,48 +156,49 @@ mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const cha flags->will_retain = 0; } + /* keep alive */ + ka = (mqtt_len_t*) data; ka->val = kasec ? htons(kasec) : htons(MQTT_KEEPALIVE); + data += sizeof(mqtt_len_t); /* ConnID */ - cid = (mqtthdr_var_t*) (buf->msg_base + siz); + cid = (mqtthdr_var_t*) data; cid->var_sb.val = htons(strlen(csConnID)); - siz += MQTTHDR_VAR_SIZEOF(cid); memcpy(cid->var_data, csConnID, ntohs(cid->var_sb.val)); + data += MQTTHDR_VAR_SIZEOF(cid); /* If Will Flags setup */ if (csWillTopic && *csWillTopic) { - topic = (mqtthdr_var_t*) (buf->msg_base + siz); + topic = (mqtthdr_var_t*) data; topic->var_sb.val = htons(strlen(csWillTopic)); memcpy(topic->var_data, csWillTopic, ntohs(topic->var_sb.val)); - siz += MQTTHDR_VAR_SIZEOF(topic); + data += MQTTHDR_VAR_SIZEOF(topic); - wmsg = (mqtthdr_var_t*) (buf->msg_base + siz); + wmsg = (mqtthdr_var_t*) data; if (csWillMessage && *csWillMessage) { wmsg->var_sb.val = htons(strlen(csWillMessage)); memcpy(wmsg->var_data, csWillMessage, ntohs(wmsg->var_sb.val)); } else wmsg->var_sb.val = 0; - siz += MQTTHDR_VAR_SIZEOF(wmsg); + data += MQTTHDR_VAR_SIZEOF(wmsg); } /* If defined Username & Password */ if (csUser && *csUser) { - user = (mqtthdr_var_t*) (buf->msg_base + siz); + user = (mqtthdr_var_t*) data; user->var_sb.val = htons(strlen(csUser)); memcpy(user->var_data, csUser, ntohs(user->var_sb.val)); - siz += MQTTHDR_VAR_SIZEOF(user); + data += MQTTHDR_VAR_SIZEOF(user); if (csPass && *csPass) { - pass = (mqtthdr_var_t*) (buf->msg_base + siz); + pass = (mqtthdr_var_t*) data; pass->var_sb.val = htons(strlen(csPass)); memcpy(pass->var_data, csPass, ntohs(pass->var_sb.val)); - siz += MQTTHDR_VAR_SIZEOF(pass); + data += MQTTHDR_VAR_SIZEOF(pass); } } - *hdr->mqtt_len = mqtt_encodeLen(siz - sizeof(struct mqtthdr)); - mqtt_msgRealloc(buf, siz); - return siz; + return siz + len; } /*