Skip to content

MQTTv5 Implementation #316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 370 commits into
base: main
Choose a base branch
from
Open

MQTTv5 Implementation #316

wants to merge 370 commits into from

Conversation

adituc
Copy link

@adituc adituc commented Mar 11, 2025

Upgrading MQTT Library to support v5 features

Description

Test Steps

  • Unit Tests are added for all new and modified features.
  • Unit Tests for MQTTv5 functions are added in a separate folder in test.

Checklist:

  • I have tested my changes. No regression in existing tests.
  • I have modified and/or added unit-tests to cover the code changes in this Pull Request.

Related Issue

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@DakshitBabbar DakshitBabbar changed the base branch from main to mqttv5-dev March 18, 2025 04:45
@DakshitBabbar DakshitBabbar marked this pull request as ready for review March 18, 2025 04:46
@DakshitBabbar DakshitBabbar marked this pull request as draft March 18, 2025 06:06
@@ -92,7 +92,7 @@ jobs:
uses: FreeRTOS/CI-CD-Github-Actions/complexity@main
with:
path: ./
horrid_threshold: 12
horrid_threshold: 17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did our complexity go up so much?

Copy link
Author

@adituc adituc Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The complexity increased mainly due to functions like deserializeConnackProperties, which now has a complexity of 17. This function handles parsing of all the possible properties in a CONNACK packet (about 17 different properties). I considered splitting the logic into smaller functions, but since all of it is part of a single, cohesive task (parsing the CONNACK properties), breaking it up would have made the flow harder to follow. So we decided to increase the complexity threshold.

( pSubscriptionList[ iterator ].topicFilterLength == 0U ) )
{
LogError( ( "Argument cannot be null : pTopicFilter or topicFilterLength cannot be zero. " ) );
status = MQTTBadParameter;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should validate the QoS level with the amxQoS sent by the server in the Connack as well.

Comment on lines +707 to +708
* @param[in] pContext MQTT Connection context.
* @param[in] pSubscriptionList List of MQTT subscription info.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code is written in a way that this function returns true if the wildcard subscriptions are used but not supported and false if it is valid. Please update the return values documentation.

const MQTTSubscribeInfo_t * pSubscriptionList,
const size_t iterator )
{
MQTTStatus_t status = MQTTSuccess;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create a macro for this constant.


if( bytesSentOrError != ( int32_t ) totalMessageLength )
{
status = MQTTSendFailed;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can create a local variable for pSubscriptionList[ iterator ].pTopicFilter

Comment on lines +4771 to +4778

static MQTTStatus_t validateSharedSubscriptions( const MQTTContext_t * pContext,
const MQTTSubscribeInfo_t * pSubscriptionList,
const size_t iterator )
{
MQTTStatus_t status = MQTTSuccess;
uint16_t topicFilterLength = pSubscriptionList[ iterator ].topicFilterLength;
bool isSharedSub = ( topicFilterLength > 7U );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to use the memchr function here instead of this loop.


return status;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a logerror statement here.

Comment on lines +7103 to +7107


if( ( pPropertyBuilder != NULL ) && ( pPropertyBuilder->pBuffer != NULL ) )
{
propertyLength = pPropertyBuilder->currentIndex;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the propbuilder is null or the buffer inside it is null then the return statement would be MQTTSuccess. But it should be MQTTBadParameter.

Comment on lines 2949 to +2950
{
/* MQTT DISCONNECT packets always have the same size. */
*pPacketSize = MQTT_DISCONNECT_PACKET_SIZE;
/*Reason code.*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a logerror statement here.

Comment on lines +4952 to +4965
status = MQTTBadParameter;
}
else if( pDisconnectInfo == NULL )
{
status = MQTTBadParameter;
}
else if( maxPacketSize == 0U )
{
status = MQTTBadParameter;
}
/*Packet size should not be more than the max allowed by the client.*/
else if( ( pPacket->remainingLength + variableLengthEncodedSize( pPacket->remainingLength ) + 1U ) > maxPacketSize )
{
status = MQTTBadResponse;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add the corresponding logerror statements at places where we assign status to MQTTBadParameter/MQTTBadResponse

Comment on lines +4994 to +5004
if( pPropBuffer != NULL )
{
pPropBuffer->bufferLength = propertyLength;
pPropBuffer->pBuffer = pIndex;
}

/*Validate the remaining length.*/
if( pPacket->remainingLength != ( propertyLength + variableLengthEncodedSize( propertyLength ) + 1U ) )
{
status = MQTTBadResponse;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this block be within the if( status == MQTTSuccess ) block?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants