void aws_iot_mqtt_internal_write_utf8_string(unsigned char **pptr, const char *string, uint16_t stringLen) { /* Nothing that calls this function will have a stringLen with a size larger than 2 bytes (MQTT 3.1.1 - 1.5.3) */ aws_iot_mqtt_internal_write_uint_16(pptr, stringLen); if(stringLen > 0) { memcpy(*pptr, string, stringLen); *pptr += stringLen; } }
/** * Serializes the supplied subscribe data into the supplied buffer, ready for sending * @param pTxBuf the buffer into which the packet will be serialized * @param txBufLen the length in bytes of the supplied buffer * @param dup unsigned char - the MQTT dup flag * @param packetId uint16_t - the MQTT packet identifier * @param topicCount - number of members in the topicFilters and reqQos arrays * @param pTopicNameList - array of topic filter names * @param pTopicNameLenList - array of length of topic filter names * @param pRequestedQoSs - array of requested QoS * @param pSerializedLen - the length of the serialized data * * @return An IoT Error Type defining successful/failed operation */ static IoT_Error_t _aws_iot_mqtt_serialize_subscribe(unsigned char *pTxBuf, size_t txBufLen, unsigned char dup, uint16_t packetId, uint32_t topicCount, const char **pTopicNameList, uint16_t *pTopicNameLenList, QoS *pRequestedQoSs, uint32_t *pSerializedLen) { unsigned char *ptr; uint32_t itr, rem_len; IoT_Error_t rc; MQTTHeader header = {0}; FUNC_ENTRY; if(NULL == pTxBuf || NULL == pSerializedLen) { FUNC_EXIT_RC(NULL_VALUE_ERROR); } ptr = pTxBuf; rem_len = 2; /* packetId */ for(itr = 0; itr < topicCount; ++itr) { rem_len += (uint32_t) (pTopicNameLenList[itr] + 2 + 1); /* topic + length + req_qos */ } if(aws_iot_mqtt_internal_get_final_packet_length_from_remaining_length(rem_len) > txBufLen) { FUNC_EXIT_RC(MQTT_TX_BUFFER_TOO_SHORT_ERROR); } rc = aws_iot_mqtt_internal_init_header(&header, SUBSCRIBE, QOS1, dup, 0); if(AWS_SUCCESS != rc) { FUNC_EXIT_RC(rc); } /* write header */ aws_iot_mqtt_internal_write_char(&ptr, header.byte); /* write remaining length */ ptr += aws_iot_mqtt_internal_write_len_to_buffer(ptr, rem_len); aws_iot_mqtt_internal_write_uint_16(&ptr, packetId); for(itr = 0; itr < topicCount; ++itr) { aws_iot_mqtt_internal_write_utf8_string(&ptr, pTopicNameList[itr], pTopicNameLenList[itr]); aws_iot_mqtt_internal_write_char(&ptr, (unsigned char) pRequestedQoSs[itr]); } *pSerializedLen = (uint32_t) (ptr - pTxBuf); FUNC_EXIT_RC(AWS_SUCCESS); }
/** * Serializes the connect options into the buffer. * @param buf the buffer into which the packet will be serialized * @param len the length in bytes of the supplied buffer * @param options the options to be used to build the connect packet * @param serialized length * @return IoT_Error_t indicating function execution status */ static IoT_Error_t _aws_iot_mqtt_serialize_connect(unsigned char *pTxBuf, size_t txBufLen, IoT_Client_Connect_Params *pConnectParams, size_t *pSerializedLen) { unsigned char *ptr; uint32_t len; IoT_Error_t rc; MQTTHeader header = {0}; MQTT_Connect_Header_Flags flags = {0}; FUNC_ENTRY; if(NULL == pTxBuf || NULL == pConnectParams || NULL == pSerializedLen || (NULL == pConnectParams->pClientID && 0 != pConnectParams->clientIDLen) || (NULL != pConnectParams->pClientID && 0 == pConnectParams->clientIDLen)) { FUNC_EXIT_RC(NULL_VALUE_ERROR); } /* Check needed here before we start writing to the Tx buffer */ switch(pConnectParams->MQTTVersion) { case MQTT_3_1_1: break; default: return MQTT_CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR; } ptr = pTxBuf; len = _aws_iot_get_connect_packet_length(pConnectParams); if(aws_iot_mqtt_internal_get_final_packet_length_from_remaining_length(len) > txBufLen) { FUNC_EXIT_RC(MQTT_TX_BUFFER_TOO_SHORT_ERROR); } rc = aws_iot_mqtt_internal_init_header(&header, CONNECT, QOS0, 0, 0); if(SUCCESS != rc) { FUNC_EXIT_RC(rc); } aws_iot_mqtt_internal_write_char(&ptr, header.byte); /* write header */ ptr += aws_iot_mqtt_internal_write_len_to_buffer(ptr, len); /* write remaining length */ // Enable if adding support for more versions //if(MQTT_3_1_1 == pConnectParams->MQTTVersion) { aws_iot_mqtt_internal_write_utf8_string(&ptr, "MQTT", 4); aws_iot_mqtt_internal_write_char(&ptr, (unsigned char) pConnectParams->MQTTVersion); //} flags.all = 0; flags.bits.cleansession = (pConnectParams->isCleanSession) ? 1 : 0; flags.bits.will = (pConnectParams->isWillMsgPresent) ? 1 : 0; if(flags.bits.will) { flags.bits.willQoS = pConnectParams->will.qos; flags.bits.willRetain = (pConnectParams->will.isRetained) ? 1 : 0; } if(pConnectParams->pUsername) { flags.bits.username = 1; } if(pConnectParams->pPassword) { flags.bits.password = 1; } aws_iot_mqtt_internal_write_char(&ptr, flags.all); aws_iot_mqtt_internal_write_uint_16(&ptr, pConnectParams->keepAliveIntervalInSec); /* If the code have passed the check for incorrect values above, no client id was passed as argument */ if(NULL == pConnectParams->pClientID) { aws_iot_mqtt_internal_write_uint_16(&ptr, 0); } else { aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->pClientID, pConnectParams->clientIDLen); } if(pConnectParams->isWillMsgPresent) { aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->will.pTopicName, pConnectParams->will.topicNameLen); aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->will.pMessage, pConnectParams->will.msgLen); } if(flags.bits.username) { aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->pUsername, pConnectParams->usernameLen); } if(flags.bits.password) { aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->pPassword, pConnectParams->passwordLen); } *pSerializedLen = (size_t) (ptr - pTxBuf); FUNC_EXIT_RC(SUCCESS); }