in source/core_mqtt_serializer.c [170:462]
static void serializePublishCommon( const MQTTPublishInfo_t * pPublishInfo,
size_t remainingLength,
uint16_t packetIdentifier,
const MQTTFixedBuffer_t * pFixedBuffer,
bool serializePayload );
/**
* @brief Calculates the packet size and remaining length of an MQTT
* PUBLISH packet.
*
* @param[in] pPublishInfo MQTT PUBLISH packet parameters.
* @param[out] pRemainingLength The Remaining Length of the MQTT PUBLISH packet.
* @param[out] pPacketSize The total size of the MQTT PUBLISH packet.
*
* @return false if the packet would exceed the size allowed by the
* MQTT spec; true otherwise.
*/
static bool calculatePublishPacketSize( const MQTTPublishInfo_t * pPublishInfo,
size_t * pRemainingLength,
size_t * pPacketSize );
/**
* @brief Calculates the packet size and remaining length of an MQTT
* SUBSCRIBE or UNSUBSCRIBE packet.
*
* @param[in] pSubscriptionList List of MQTT subscription info.
* @param[in] subscriptionCount The number of elements in pSubscriptionList.
* @param[out] pRemainingLength The Remaining Length of the MQTT SUBSCRIBE or
* UNSUBSCRIBE packet.
* @param[out] pPacketSize The total size of the MQTT MQTT SUBSCRIBE or
* UNSUBSCRIBE packet.
* @param[in] subscriptionType #MQTT_SUBSCRIBE or #MQTT_UNSUBSCRIBE.
*
* #MQTTBadParameter if the packet would exceed the size allowed by the
* MQTT spec or a subscription is empty; #MQTTSuccess otherwise.
*/
static MQTTStatus_t calculateSubscriptionPacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
size_t subscriptionCount,
size_t * pRemainingLength,
size_t * pPacketSize,
MQTTSubscriptionType_t subscriptionType );
/**
* @brief Validates parameters of #MQTT_SerializeSubscribe or
* #MQTT_SerializeUnsubscribe.
*
* @param[in] pSubscriptionList List of MQTT subscription info.
* @param[in] subscriptionCount The number of elements in pSubscriptionList.
* @param[in] packetId Packet identifier.
* @param[in] remainingLength Remaining length of the packet.
* @param[in] pFixedBuffer Buffer for packet serialization.
*
* @return #MQTTNoMemory if pBuffer is too small to hold the MQTT packet;
* #MQTTBadParameter if invalid parameters are passed;
* #MQTTSuccess otherwise.
*/
static MQTTStatus_t validateSubscriptionSerializeParams( const MQTTSubscribeInfo_t * pSubscriptionList,
size_t subscriptionCount,
uint16_t packetId,
size_t remainingLength,
const MQTTFixedBuffer_t * pFixedBuffer );
/**
* @brief Serialize an MQTT CONNECT packet in the given buffer.
*
* @param[in] pConnectInfo MQTT CONNECT packet parameters.
* @param[in] pWillInfo Last Will and Testament. Pass NULL if not used.
* @param[in] remainingLength Remaining Length of MQTT CONNECT packet.
* @param[out] pFixedBuffer Buffer for packet serialization.
*/
static void serializeConnectPacket( const MQTTConnectInfo_t * pConnectInfo,
const MQTTPublishInfo_t * pWillInfo,
size_t remainingLength,
const MQTTFixedBuffer_t * pFixedBuffer );
/**
* @brief Prints the appropriate message for the CONNACK response code if logs
* are enabled.
*
* @param[in] responseCode MQTT standard CONNACK response code.
*/
static void logConnackResponse( uint8_t responseCode );
/**
* @brief Encodes the remaining length of the packet using the variable length
* encoding scheme provided in the MQTT v3.1.1 specification.
*
* @param[out] pDestination The destination buffer to store the encoded remaining
* length.
* @param[in] length The remaining length to encode.
*
* @return The location of the byte following the encoded value.
*/
static uint8_t * encodeRemainingLength( uint8_t * pDestination,
size_t length );
/**
* @brief Retrieve the size of the remaining length if it were to be encoded.
*
* @param[in] length The remaining length to be encoded.
*
* @return The size of the remaining length if it were to be encoded.
*/
static size_t remainingLengthEncodedSize( size_t length );
/**
* @brief Encode a string whose size is at maximum 16 bits in length.
*
* @param[out] pDestination Destination buffer for the encoding.
* @param[in] pSource The source string to encode.
* @param[in] sourceLength The length of the source string to encode.
*
* @return A pointer to the end of the encoded string.
*/
static uint8_t * encodeString( uint8_t * pDestination,
const char * pSource,
uint16_t sourceLength );
/**
* @brief Retrieves and decodes the Remaining Length from the network interface
* by reading a single byte at a time.
*
* @param[in] recvFunc Network interface receive function.
* @param[in] pNetworkContext Network interface context to the receive function.
*
* @return The Remaining Length of the incoming packet.
*/
static size_t getRemainingLength( TransportRecv_t recvFunc,
NetworkContext_t * pNetworkContext );
/**
* @brief Check if an incoming packet type is valid.
*
* @param[in] packetType The packet type to check.
*
* @return `true` if the packet type is valid; `false` otherwise.
*/
static bool incomingPacketValid( uint8_t packetType );
/**
* @brief Check the remaining length of an incoming PUBLISH packet against some
* value for QoS 0, or for QoS 1 and 2.
*
* The remaining length for a QoS 1 and 2 packet will always be two greater than
* for a QoS 0.
*
* @param[in] remainingLength Remaining length of the PUBLISH packet.
* @param[in] qos The QoS of the PUBLISH.
* @param[in] qos0Minimum Minimum possible remaining length for a QoS 0 PUBLISH.
*
* @return #MQTTSuccess or #MQTTBadResponse.
*/
static MQTTStatus_t checkPublishRemainingLength( size_t remainingLength,
MQTTQoS_t qos,
size_t qos0Minimum );
/**
* @brief Process the flags of an incoming PUBLISH packet.
*
* @param[in] publishFlags Flags of an incoming PUBLISH.
* @param[in, out] pPublishInfo Pointer to #MQTTPublishInfo_t struct where
* output will be written.
*
* @return #MQTTSuccess or #MQTTBadResponse.
*/
static MQTTStatus_t processPublishFlags( uint8_t publishFlags,
MQTTPublishInfo_t * pPublishInfo );
/**
* @brief Deserialize a CONNACK packet.
*
* Converts the packet from a stream of bytes to an #MQTTStatus_t.
*
* @param[in] pConnack Pointer to an MQTT packet struct representing a
* CONNACK.
* @param[out] pSessionPresent Whether a previous session was present.
*
* @return #MQTTSuccess if CONNACK specifies that CONNECT was accepted;
* #MQTTServerRefused if CONNACK specifies that CONNECT was rejected;
* #MQTTBadResponse if the CONNACK packet doesn't follow MQTT spec.
*/
static MQTTStatus_t deserializeConnack( const MQTTPacketInfo_t * pConnack,
bool * pSessionPresent );
/**
* @brief Decode the status bytes of a SUBACK packet to a #MQTTStatus_t.
*
* @param[in] statusCount Number of status bytes in the SUBACK.
* @param[in] pStatusStart The first status byte in the SUBACK.
*
* @return #MQTTSuccess, #MQTTServerRefused, or #MQTTBadResponse.
*/
static MQTTStatus_t readSubackStatus( size_t statusCount,
const uint8_t * pStatusStart );
/**
* @brief Deserialize a SUBACK packet.
*
* Converts the packet from a stream of bytes to an #MQTTStatus_t and extracts
* the packet identifier.
*
* @param[in] pSuback Pointer to an MQTT packet struct representing a SUBACK.
* @param[out] pPacketIdentifier Packet ID of the SUBACK.
*
* @return #MQTTSuccess if SUBACK is valid; #MQTTBadResponse if SUBACK packet
* doesn't follow the MQTT spec.
*/
static MQTTStatus_t deserializeSuback( const MQTTPacketInfo_t * pSuback,
uint16_t * pPacketIdentifier );
/**
* @brief Deserialize a PUBLISH packet received from the server.
*
* Converts the packet from a stream of bytes to an #MQTTPublishInfo_t and
* extracts the packet identifier. Also prints out debug log messages about the
* packet.
*
* @param[in] pIncomingPacket Pointer to an MQTT packet struct representing a
* PUBLISH.
* @param[out] pPacketId Packet identifier of the PUBLISH.
* @param[out] pPublishInfo Pointer to #MQTTPublishInfo_t where output is
* written.
*
* @return #MQTTSuccess if PUBLISH is valid; #MQTTBadResponse
* if the PUBLISH packet doesn't follow MQTT spec.
*/
static MQTTStatus_t deserializePublish( const MQTTPacketInfo_t * pIncomingPacket,
uint16_t * pPacketId,
MQTTPublishInfo_t * pPublishInfo );
/**
* @brief Deserialize an UNSUBACK, PUBACK, PUBREC, PUBREL, or PUBCOMP packet.
*
* Converts the packet from a stream of bytes to an #MQTTStatus_t and extracts
* the packet identifier.
*
* @param[in] pAck Pointer to the MQTT packet structure representing the packet.
* @param[out] pPacketIdentifier Packet ID of the ack type packet.
*
* @return #MQTTSuccess if UNSUBACK, PUBACK, PUBREC, PUBREL, or PUBCOMP is valid;
* #MQTTBadResponse if the packet doesn't follow the MQTT spec.
*/
static MQTTStatus_t deserializeSimpleAck( const MQTTPacketInfo_t * pAck,
uint16_t * pPacketIdentifier );
/**
* @brief Deserialize a PINGRESP packet.
*
* Converts the packet from a stream of bytes to an #MQTTStatus_t.
*
* @param[in] pPingresp Pointer to an MQTT packet struct representing a PINGRESP.
*
* @return #MQTTSuccess if PINGRESP is valid; #MQTTBadResponse if the PINGRESP
* packet doesn't follow MQTT spec.
*/
static MQTTStatus_t deserializePingresp( const MQTTPacketInfo_t * pPingresp );
/*-----------------------------------------------------------*/
static size_t remainingLengthEncodedSize( size_t length )
{
size_t encodedSize;
/* Determine how many bytes are needed to encode length.
* The values below are taken from the MQTT 3.1.1 spec. */
/* 1 byte is needed to encode lengths between 0 and 127. */
if( length < 128U )
{
encodedSize = 1U;
}
/* 2 bytes are needed to encode lengths between 128 and 16,383. */
else if( length < 16384U )
{
encodedSize = 2U;
}
/* 3 bytes are needed to encode lengths between 16,384 and 2,097,151. */
else if( length < 2097152U )
{
encodedSize = 3U;
}
/* 4 bytes are needed to encode lengths between 2,097,152 and 268,435,455. */
else
{
encodedSize = 4U;
}
LogDebug( ( "Encoded size for length %lu is %lu bytes.",
( unsigned long ) length,
( unsigned long ) encodedSize ) );
return encodedSize;
}