// Return packet type. If no packet avilable, return FAILURE, or READ_ERROR if timeout static int read_packet(mqtt_client_t* c, mqtt_timer_t* timer) { int rc = MQTT_FAILURE; mqtt_header_t header = {0}; int len = 0; int rem_len = 0; /* 1. read the header byte. This has the packet type in it */ if (c->ipstack->mqttread(c->ipstack, c->readbuf, 1, mqtt_timer_left_ms(timer)) != 1) goto exit; len = 1; /* 2. read the remaining length. This is variable in itself */ len += decode_packet(c, &rem_len, mqtt_timer_left_ms(timer)); if (len <= 1 || len + rem_len > c->readbuf_size) /* if packet is too big to fit in our readbuf, abort */ { rc = MQTT_READ_ERROR; goto exit; } mqtt_packet_encode(c->readbuf + 1, rem_len); /* put the original remaining length back into the buffer */ /* 3. read the rest of the buffer using a callback to supply the rest of the data */ if (rem_len > 0 && (c->ipstack->mqttread(c->ipstack, c->readbuf + len, rem_len, mqtt_timer_left_ms(timer)) != rem_len)) { rc = MQTT_READ_ERROR; goto exit; } header.byte = c->readbuf[0]; rc = header.bits.type; exit: return rc; }
//-------------------------------------------- void mqtt_pingresp_encode(unsigned char **buf, size_t *size) { mqtt_fixed_header_t fixhdr; fixhdr.msg_type = MQTT_PINGRESP; fixhdr.dup_flag = 0; fixhdr.qos_level = 0; fixhdr.retain = 0; fixhdr.rem_len = 0; mqtt_packet_encode(&fixhdr, buf, size); }
//-------------------------------------------- void mqtt_suback_encode(unsigned char **buf, size_t *size, mqtt_suback_header_t *suback) { mqtt_fixed_header_t fixhdr; fixhdr.msg_type = MQTT_SUBACK; fixhdr.dup_flag = 0; fixhdr.qos_level = 0; fixhdr.retain = 0; fixhdr.rem_len = (uint32_t)(2 + suback->qos_size); fixhdr.rem_buf = (unsigned char *)malloc(fixhdr.rem_len); *(uint16_t *)&fixhdr.rem_buf[0] = htons(suback->msg_id); memcpy(&fixhdr.rem_buf[2], suback->qos_buf, suback->qos_size); mqtt_packet_encode(&fixhdr, buf, size); }
//-------------------------------------------- void mqtt_connack_encode(unsigned char **buf, size_t *size, mqtt_connack_return_code_t code) { mqtt_fixed_header_t fixhdr; fixhdr.msg_type = MQTT_CONNACK; fixhdr.dup_flag = 0; fixhdr.qos_level = 0; fixhdr.retain = 0; fixhdr.rem_len = 2; fixhdr.rem_buf = (unsigned char *)malloc(fixhdr.rem_len); fixhdr.rem_buf[0] = 0; // unused fixhdr.rem_buf[1] = code; mqtt_packet_encode(&fixhdr, buf, size); }
//-------------------------------------------- void mqtt_pubxxx_encode(mqtt_msg_type_t msg_type, unsigned char **buf, size_t *size, uint16_t msg_id) { mqtt_fixed_header_t fixhdr; fixhdr.msg_type = msg_type; fixhdr.dup_flag = 0; if (msg_type == MQTT_PUBREL) fixhdr.qos_level = 1; else fixhdr.qos_level = 0; fixhdr.retain = 0; fixhdr.rem_len = 2; fixhdr.rem_buf = (unsigned char *)malloc(fixhdr.rem_len); *(uint16_t *)&fixhdr.rem_buf[0] = htons(msg_id); mqtt_packet_encode(&fixhdr, buf, size); }
//-------------------------------------------- void mqtt_publish_encode(unsigned char **buf, size_t *size, mqtt_publish_header_t *publish) { mqtt_fixed_header_t fixhdr; uint16_t name_len = publish->pub_item->name_len; uint16_t data_len = publish->pub_item->data_len; uint8_t *name = publish->pub_item->name; uint8_t *data = publish->pub_item->data; uint16_t msg_id_len = publish->qos > 0 ? 2 : 0; fixhdr.msg_type = MQTT_PUBLISH; fixhdr.dup_flag = 0; fixhdr.qos_level = publish->qos; fixhdr.retain = 0; fixhdr.rem_len = (uint32_t)(2 + name_len + msg_id_len + data_len); fixhdr.rem_buf = (uint8_t *)malloc(fixhdr.rem_len); *(uint16_t *)&fixhdr.rem_buf[0] = htons(name_len); memcpy(&fixhdr.rem_buf[2], name, name_len); if (fixhdr.qos_level > 0) *(uint16_t *)&fixhdr.rem_buf[2 + name_len] = htons(publish->msg_id); memcpy(&fixhdr.rem_buf[2 + name_len + msg_id_len], data, data_len); mqtt_packet_encode(&fixhdr, buf, size); }