/** * Deserializes the supplied (wire) buffer into suback data * @param pPacketId returned integer - the MQTT packet identifier * @param maxExpectedQoSCount - the maximum number of members allowed in the grantedQoSs array * @param pGrantedQoSCount returned uint32_t - number of members in the grantedQoSs array * @param pGrantedQoSs returned array of QoS type - the granted qualities of service * @param pRxBuf the raw buffer data, of the correct length determined by the remaining length field * @param rxBufLen the length in bytes of the data in the supplied buffer * * @return An IoT Error Type defining successful/failed operation */ static IoT_Error_t _aws_iot_mqtt_deserialize_suback(uint16_t *pPacketId, uint32_t maxExpectedQoSCount, uint32_t *pGrantedQoSCount, QoS *pGrantedQoSs, unsigned char *pRxBuf, size_t rxBufLen) { unsigned char *curData, *endData; uint32_t decodedLen, readBytesLen; IoT_Error_t decodeRc; MQTTHeader header = {0}; FUNC_ENTRY; if(NULL == pPacketId || NULL == pGrantedQoSCount || NULL == pGrantedQoSs) { FUNC_EXIT_RC(NULL_VALUE_ERROR); } curData = pRxBuf; endData = NULL; decodeRc = AWS_FAILURE; decodedLen = 0; readBytesLen = 0; /* SUBACK header size is 4 bytes for header and at least one byte for QoS payload * Need at least a 5 bytes buffer. MQTT3.1.1 specification 3.9 */ if(5 > rxBufLen) { FUNC_EXIT_RC(MQTT_RX_BUFFER_TOO_SHORT_ERROR); } header.byte = aws_iot_mqtt_internal_read_char(&curData); if(SUBACK != header.bits.type) { FUNC_EXIT_RC(AWS_FAILURE); } /* read remaining length */ decodeRc = aws_iot_mqtt_internal_decode_remaining_length_from_buffer(curData, &decodedLen, &readBytesLen); if(AWS_SUCCESS != decodeRc) { FUNC_EXIT_RC(decodeRc); } curData += (readBytesLen); endData = curData + decodedLen; if(endData - curData < 2) { FUNC_EXIT_RC(AWS_FAILURE); } *pPacketId = aws_iot_mqtt_internal_read_uint16_t(&curData); *pGrantedQoSCount = 0; while(curData < endData) { if(*pGrantedQoSCount > maxExpectedQoSCount) { FUNC_EXIT_RC(AWS_FAILURE); } pGrantedQoSs[(*pGrantedQoSCount)++] = (QoS) aws_iot_mqtt_internal_read_char(&curData); } FUNC_EXIT_RC(AWS_SUCCESS); }
/** * Deserializes the supplied (wire) buffer into connack data - return code * @param sessionPresent the session present flag returned (only for MQTT 3.1.1) * @param connack_rc returned integer value of the connack return code * @param buf the raw buffer data, of the correct length determined by the remaining length field * @param buflen the length in bytes of the data in the supplied buffer * @return IoT_Error_t indicating function execution status */ static IoT_Error_t _aws_iot_mqtt_deserialize_connack(unsigned char *pSessionPresent, IoT_Error_t *pConnackRc, unsigned char *pRxBuf, size_t rxBufLen) { unsigned char *curdata, *enddata; unsigned char connack_rc_char; uint32_t decodedLen, readBytesLen; IoT_Error_t rc; MQTT_Connack_Header_Flags flags = {0}; MQTTHeader header = {0}; FUNC_ENTRY; if(NULL == pSessionPresent || NULL == pConnackRc || NULL == pRxBuf) { FUNC_EXIT_RC(NULL_VALUE_ERROR); } /* CONNACK header size is fixed at two bytes for fixed and 2 bytes for variable, * using that as minimum size * MQTT v3.1.1 Specification 3.2.1 */ if(4 > rxBufLen) { FUNC_EXIT_RC(MQTT_RX_BUFFER_TOO_SHORT_ERROR); } curdata = pRxBuf; enddata = NULL; decodedLen = 0; readBytesLen = 0; header.byte = aws_iot_mqtt_internal_read_char(&curdata); if(CONNACK != header.bits.type) { FUNC_EXIT_RC(FAILURE); } /* read remaining length */ rc = aws_iot_mqtt_internal_decode_remaining_length_from_buffer(curdata, &decodedLen, &readBytesLen); if(SUCCESS != rc) { FUNC_EXIT_RC(rc); } /* CONNACK remaining length should always be 2 as per MQTT 3.1.1 spec */ curdata += (readBytesLen); enddata = curdata + decodedLen; if(2 != (enddata - curdata)) { FUNC_EXIT_RC(MQTT_DECODE_REMAINING_LENGTH_ERROR); } flags.all = aws_iot_mqtt_internal_read_char(&curdata); *pSessionPresent = flags.bits.sessionpresent; connack_rc_char = aws_iot_mqtt_internal_read_char(&curdata); switch(connack_rc_char) { case CONNACK_CONNECTION_ACCEPTED: *pConnackRc = MQTT_CONNACK_CONNECTION_ACCEPTED; break; case CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR: *pConnackRc = MQTT_CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR; break; case CONNACK_IDENTIFIER_REJECTED_ERROR: *pConnackRc = MQTT_CONNACK_IDENTIFIER_REJECTED_ERROR; break; case CONNACK_SERVER_UNAVAILABLE_ERROR: *pConnackRc = MQTT_CONNACK_SERVER_UNAVAILABLE_ERROR; break; case CONNACK_BAD_USERDATA_ERROR: *pConnackRc = MQTT_CONNACK_BAD_USERDATA_ERROR; break; case CONNACK_NOT_AUTHORIZED_ERROR: *pConnackRc = MQTT_CONNACK_NOT_AUTHORIZED_ERROR; break; default: *pConnackRc = MQTT_CONNACK_UNKNOWN_ERROR; break; } FUNC_EXIT_RC(SUCCESS); }