--- mqtt/src/Attic/conn.c 2011/11/21 12:16:11 1.1 +++ mqtt/src/Attic/conn.c 2011/11/21 12:16:11 1.1.2.1 @@ -0,0 +1,138 @@ +#include "global.h" + + +/* ------------------------------------------------------------------- */ + +/* + * mqtt_msgCONNECT() Create CONNECT message + * + * @buf = Message buffer + * @csConnID = ConnectID + * @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: -1 error or >-1 message size for send + */ +int +mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const char *csConnID, + const char *csUser, const char *csPass, + const char *csWillTopic, const char *csWillMessage, + char ClrSess, char WillQOS, char WillRetain) +{ + int siz = 0; + struct mqtthdr *hdr; + mqtthdr_var_t *var, *cid, *topic, *wmsg, *user, *pass; + mqtthdr_protover_t *proto; + mqtthdr_connflgs_t *flags; + mqtt_v_t *ka; + + if (!buf || !csConnID) + return -1; + if (strlen(csConnID) > 23) { + mqtt_SetErr(EINVAL, "Error:: invalid argument ConnID is too long (max 23 bytes)"); + return -1; + } + if (csUser && strlen(csUser) > 12) { + mqtt_SetErr(EINVAL, "Error:: invalid argument Username is too long (max 12 bytes)"); + return -1; + } + if (csPass && strlen(csPass) > 12) { + mqtt_SetErr(EINVAL, "Error:: invalid argument Password is too long (max 12 bytes)"); + return -1; + } + if (WillQOS < MQTT_QOS_ONCE && WillQOS > MQTT_QOS_EXACTLY) { + mqtt_SetErr(EINVAL, "Error:: invalid argument WillQOS - unknown QOS value"); + return -1; + } + + if (mqtt_msgRealloc(buf, BUFSIZ) == -1) + return -1; + else { + hdr = (struct mqtthdr *) (buf->msg_base + siz); + siz += 2; + 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_v_t*) (buf->msg_base + siz); + siz += sizeof(mqtt_v_t); + } + + /* fixed header */ + hdr->mqtt_msg.type = MQTT_TYPE_CONNECT; + *hdr->mqtt_len = 0; + + /* variable header */ + var->var_sb.sb.l = 6; + memcpy(var->var_data, MQTT_CONN_STR, 6); + + *proto = MQTT_PROTO_VER; + + /* CONNECT header */ + flags->clean_sess = ClrSess ? 1 : 0; + if (csUser) { + flags->username = 1; + flags->password = csPass ? 1 : 0; + } else { + flags->username = 0; + flags->password = 0; + } + if (csWillTopic) { + flags->will_flg = 1; + flags->will_qos = WillQOS; + flags->will_retain = WillRetain ? 1 : 0; + } else { + flags->will_flg = 0; + flags->will_qos = 0; + flags->will_retain = 0; + } + + ka->sb.l = MQTT_KEEPALIVE; + + /* ConnID */ + cid = (mqtthdr_var_t*) (buf->msg_base + siz); + cid->var_sb.val = htons(strlen(csConnID)); + siz += MQTTHDR_VAR_SIZEOF(cid); + memcpy(cid->var_data, csConnID, ntohs(cid->var_sb.val)); + + /* If Will Flags setup */ + if (csWillTopic) { + topic = (mqtthdr_var_t*) (buf->msg_base + siz); + topic->var_sb.val = htons(strlen(csWillTopic)); + memcpy(topic->var_data, csWillTopic, ntohs(topic->var_sb.val)); + siz += MQTTHDR_VAR_SIZEOF(topic); + + wmsg = (mqtthdr_var_t*) (buf->msg_base + siz); + if (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); + } + + /* If defined Username & Password */ + if (csUser) { + user = (mqtthdr_var_t*) (buf->msg_base + siz); + user->var_sb.val = htons(strlen(csUser)); + memcpy(user->var_data, csUser, ntohs(user->var_sb.val)); + siz += MQTTHDR_VAR_SIZEOF(user); + + if (csPass) { + pass = (mqtthdr_var_t*) (buf->msg_base + siz); + pass->var_sb.val = htons(strlen(csPass)); + memcpy(pass->var_data, csPass, ntohs(pass->var_sb.val)); + siz += MQTTHDR_VAR_SIZEOF(pass); + } + } + + *hdr->mqtt_len = mqtt_encodeLen(siz - 2); + mqtt_msgRealloc(buf, siz); + return siz; +}