in source/core_mqtt_serializer.c [1512:1608]
MQTTStatus_t MQTT_GetConnectPacketSize( const MQTTConnectInfo_t * pConnectInfo,
const MQTTPublishInfo_t * pWillInfo,
size_t * pRemainingLength,
size_t * pPacketSize )
{
MQTTStatus_t status = MQTTSuccess;
size_t remainingLength;
/* The CONNECT packet will always include a 10-byte variable header. */
size_t connectPacketSize = MQTT_PACKET_CONNECT_HEADER_SIZE;
/* Validate arguments. */
if( ( pConnectInfo == NULL ) || ( pRemainingLength == NULL ) ||
( pPacketSize == NULL ) )
{
LogError( ( "Argument cannot be NULL: pConnectInfo=%p, "
"pRemainingLength=%p, pPacketSize=%p.",
( void * ) pConnectInfo,
( void * ) pRemainingLength,
( void * ) pPacketSize ) );
status = MQTTBadParameter;
}
else if( ( pConnectInfo->clientIdentifierLength == 0U ) || ( pConnectInfo->pClientIdentifier == NULL ) )
{
LogError( ( "Mqtt_GetConnectPacketSize() client identifier must be set." ) );
status = MQTTBadParameter;
}
else if( ( pWillInfo != NULL ) && ( pWillInfo->payloadLength > ( size_t ) UINT16_MAX ) )
{
/* The MQTTPublishInfo_t is reused for the will message. The payload
* length for any other message could be larger than 65,535, but
* the will message length is required to be represented in 2 bytes.
* By bounding the payloadLength of the will message, the CONNECT
* packet will never be larger than 327699 bytes. */
LogError( ( "The Will Message length must not exceed %d. "
"pWillInfo->payloadLength=%lu.",
UINT16_MAX,
( unsigned long ) pWillInfo->payloadLength ) );
status = MQTTBadParameter;
}
else
{
/* Add the length of the client identifier. */
connectPacketSize += pConnectInfo->clientIdentifierLength + sizeof( uint16_t );
/* Add the lengths of the will message and topic name if provided. */
if( pWillInfo != NULL )
{
connectPacketSize += pWillInfo->topicNameLength + sizeof( uint16_t ) +
pWillInfo->payloadLength + sizeof( uint16_t );
}
/* Add the lengths of the user name and password if provided. */
if( pConnectInfo->pUserName != NULL )
{
connectPacketSize += pConnectInfo->userNameLength + sizeof( uint16_t );
}
if( pConnectInfo->pPassword != NULL )
{
connectPacketSize += pConnectInfo->passwordLength + sizeof( uint16_t );
}
/* At this point, the "Remaining Length" field of the MQTT CONNECT packet has
* been calculated. */
remainingLength = connectPacketSize;
/* Calculate the full size of the MQTT CONNECT packet by adding the size of
* the "Remaining Length" field plus 1 byte for the "Packet Type" field. */
connectPacketSize += 1U + remainingLengthEncodedSize( connectPacketSize );
/* The connectPacketSize calculated from this function's parameters is
* guaranteed to be less than the maximum MQTT CONNECT packet size, which
* is 327700. If the maximum client identifier length, the maximum will
* message topic length, the maximum will topic payload length, the
* maximum username length, and the maximum password length are all present
* in the MQTT CONNECT packet, the total size will be calculated to be
* 327699:
* (variable length header)10 +
* (maximum client identifier length) 65535 + (encoded length) 2 +
* (maximum will message topic name length) 65535 + (encoded length)2 +
* (maximum will message payload length) 65535 + 2 +
* (maximum username length) 65535 + (encoded length) 2 +
* (maximum password length) 65535 + (encoded length) 2 +
* (packet type field length) 1 +
* (CONNECT packet encoded length) 3 = 327699 */
*pRemainingLength = remainingLength;
*pPacketSize = connectPacketSize;
LogDebug( ( "CONNECT packet remaining length=%lu and packet size=%lu.",
( unsigned long ) *pRemainingLength,
( unsigned long ) *pPacketSize ) );
}
return status;
}