version 1.1, 2011/11/21 12:16:11
|
version 1.1.2.1, 2011/11/21 12:16:11
|
Line 0
|
Line 1
|
|
#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; |
|
} |