Skip to content

Commit 8ce6d7b

Browse files
Add incoming disconnect handling
1 parent 464e228 commit 8ce6d7b

File tree

5 files changed

+303
-23
lines changed

5 files changed

+303
-23
lines changed

docs/doxygen/include/size_table.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
</tr>
1010
<tr>
1111
<td>core_mqtt.c</td>
12-
<td><center>7.3K</center></td>
13-
<td><center>6.5K</center></td>
12+
<td><center>7.5K</center></td>
13+
<td><center>6.6K</center></td>
1414
</tr>
1515
<tr>
1616
<td>core_mqtt_state.c</td>
@@ -19,8 +19,8 @@
1919
</tr>
2020
<tr>
2121
<td>core_mqtt_serializer.c</td>
22-
<td><center>8.2K</center></td>
23-
<td><center>6.6K</center></td>
22+
<td><center>8.5K</center></td>
23+
<td><center>7.0K</center></td>
2424
</tr>
2525
<tr>
2626
<td>core_mqtt_serializer_private.c</td>
@@ -39,7 +39,7 @@
3939
</tr>
4040
<tr>
4141
<td><b>Total estimates</b></td>
42-
<td><b><center>20.3K</center></b></td>
43-
<td><b><center>17.0K</center></b></td>
42+
<td><b><center>20.8K</center></b></td>
43+
<td><b><center>17.5K</center></b></td>
4444
</tr>
4545
</table>

source/core_mqtt.c

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,17 @@ static MQTTStatus_t sendDisconnectWithoutCopy( MQTTContext_t * pContext,
705705
size_t remainingLength,
706706
const MQTTPropBuilder_t * pPropertyBuilder );
707707

708+
/**
709+
* @brief Handle Incoming Disconnect
710+
*
711+
* @param[in] pContext MQTT Connection context.
712+
* @param[in] pIncomingPacket Information of incoming packet
713+
*
714+
* @return #MQTTSuccess, #MQTTBadResponse, #MQTTBadParameter, #MQTTEventCallbackFailed,
715+
*/
716+
static MQTTStatus_t handleIncomingDisconnect( MQTTContext_t * pContext,
717+
MQTTPacketInfo_t * pIncomingPacket );
718+
708719
/*-----------------------------------------------------------*/
709720

710721
static bool matchEndWildcardsSpecialCases( const char * pTopicFilter,
@@ -719,7 +730,7 @@ static bool matchEndWildcardsSpecialCases( const char * pTopicFilter,
719730
/* Check if the topic filter has 2 remaining characters and it ends in
720731
* "/#". This check handles the case to match filter "sport/#" with topic
721732
* "sport". The reason is that the '#' wildcard represents the parent and
722-
* any number of child levels in the topic name.*/
733+
* any number of child levels in the topic name. */
723734
if( ( topicFilterLength >= 3U ) &&
724735
( filterIndex == ( topicFilterLength - 3U ) ) &&
725736
( pTopicFilter[ filterIndex + 1U ] == '/' ) &&
@@ -771,7 +782,7 @@ static bool matchWildcards( const char * pTopicName,
771782
nameIndex = *pNameIndex;
772783

773784
/* Wild card in a topic filter is only valid either at the starting position
774-
* or when it is preceded by a '/'.*/
785+
* or when it is preceded by a '/'. */
775786
locationIsValidForWildcard = ( *pFilterIndex == 0u ) ||
776787
( pTopicFilter[ *pFilterIndex - 1U ] == '/' );
777788

@@ -826,7 +837,7 @@ static bool matchWildcards( const char * pTopicName,
826837
/* If we have reached here, the the loop terminated on the
827838
* ( nameIndex < topicNameLength) condition, which means that have
828839
* reached past the end of the topic name, and thus, we decrement the
829-
* index to the last character in the topic name.*/
840+
* index to the last character in the topic name. */
830841
/* coverity[integer_overflow] */
831842
nameIndex -= 1;
832843
}
@@ -2287,6 +2298,39 @@ static MQTTStatus_t handleIncomingAck( MQTTContext_t * pContext,
22872298

22882299
/*-----------------------------------------------------------*/
22892300

2301+
static MQTTStatus_t handleIncomingDisconnect( MQTTContext_t * pContext,
2302+
MQTTPacketInfo_t * pIncomingPacket )
2303+
{
2304+
MQTTStatus_t status = MQTTSuccess;
2305+
MQTTDeserializedInfo_t deserializedInfo = { 0 };
2306+
MQTTPropBuilder_t propBuffer = { 0 };
2307+
MQTTReasonCodeInfo_t reasonCode = { 0 };
2308+
2309+
assert( pContext != NULL );
2310+
assert( pContext->appCallback != NULL );
2311+
assert( pIncomingPacket != NULL );
2312+
2313+
status = MQTT_DeserializeDisconnect( pIncomingPacket,
2314+
pContext->connectionProperties.maxPacketSize,
2315+
&reasonCode,
2316+
&propBuffer );
2317+
2318+
if( status == MQTTSuccess )
2319+
{
2320+
deserializedInfo.pReasonCode = &reasonCode;
2321+
2322+
if( pContext->appCallback( pContext, pIncomingPacket, &deserializedInfo,
2323+
NULL, &pContext->ackPropsBuffer, &propBuffer ) == false )
2324+
{
2325+
status = MQTTEventCallbackFailed;
2326+
}
2327+
}
2328+
2329+
return status;
2330+
}
2331+
2332+
/*-----------------------------------------------------------*/
2333+
22902334
static MQTTStatus_t receiveSingleIteration( MQTTContext_t * pContext,
22912335
bool manageKeepAlive )
22922336
{
@@ -2422,6 +2466,36 @@ static MQTTStatus_t receiveSingleIteration( MQTTContext_t * pContext,
24222466
{
24232467
status = handleIncomingPublish( pContext, &incomingPacket );
24242468
}
2469+
else if( incomingPacket.type == MQTT_PACKET_TYPE_DISCONNECT )
2470+
{
2471+
status = handleIncomingDisconnect( pContext, &incomingPacket );
2472+
2473+
if( status == MQTTSuccess )
2474+
{
2475+
LogInfo( ( "Disconnected from the broker." ) );
2476+
}
2477+
else if( status != MQTTEventCallbackFailed )
2478+
{
2479+
/* Incoming packet is malformed at this stage. */
2480+
MQTTSuccessFailReasonCode_t reason = MQTT_REASON_DISCONNECT_MALFORMED_PACKET;
2481+
status = MQTT_Disconnect( pContext, NULL, &reason );
2482+
2483+
if( status != MQTTSuccess )
2484+
{
2485+
LogError( ( "Failed to send disconnect following a malformed disconnect "
2486+
"from the server. coreMQTT will forcefully disconnect now." ) );
2487+
}
2488+
}
2489+
else /* At this point the callback has failed. */
2490+
{
2491+
/* TODO: If handling fails, the packet should be
2492+
* resent to the application or not? */
2493+
}
2494+
2495+
MQTT_PRE_STATE_UPDATE_HOOK( pContext );
2496+
pContext->connectStatus = MQTTNotConnected;
2497+
MQTT_POST_STATE_UPDATE_HOOK( pContext );
2498+
}
24252499
else
24262500
{
24272501
status = handleIncomingAck( pContext, &incomingPacket, manageKeepAlive );
@@ -2907,7 +2981,7 @@ static MQTTStatus_t sendPublishWithoutCopy( MQTTContext_t * pContext,
29072981
iterator++;
29082982
ioVectorLength++;
29092983

2910-
/* Serialize the publish properties, if provided.*/
2984+
/* Serialize the publish properties, if provided. */
29112985

29122986
if( publishPropLength > 0U )
29132987
{
@@ -3130,7 +3204,7 @@ static MQTTStatus_t sendConnectWithoutCopy( MQTTContext_t * pContext,
31303204

31313205
if( willPropsLen > 0U )
31323206
{
3133-
/*Serialize the will properties, if present.*/
3207+
/* Serialize the will properties, if present. */
31343208

31353209
iterator->iov_base = pWillPropertyBuilder->pBuffer;
31363210
iterator->iov_len = pWillPropertyBuilder->currentIndex;
@@ -4274,7 +4348,7 @@ MQTTStatus_t MQTT_Subscribe( MQTTContext_t * pContext,
42744348

42754349
if( status == MQTTSuccess )
42764350
{
4277-
/* Get the remaining length and packet size.*/
4351+
/* Get the remaining length and packet size. */
42784352
status = MQTT_GetSubscribePacketSize( pSubscriptionList,
42794353
subscriptionCount,
42804354
pPropertyBuilder,
@@ -4364,7 +4438,7 @@ MQTTStatus_t MQTT_Publish( MQTTContext_t * pContext,
43644438

43654439
if( status == MQTTSuccess )
43664440
{
4367-
/* Get the remaining length and packet size.*/
4441+
/* Get the remaining length and packet size. */
43684442
status = MQTT_GetPublishPacketSize( pPublishInfo,
43694443
pPropertyBuilder,
43704444
&remainingLength,
@@ -4572,7 +4646,7 @@ MQTTStatus_t MQTT_Unsubscribe( MQTTContext_t * pContext,
45724646

45734647
if( status == MQTTSuccess )
45744648
{
4575-
/* Get the remaining length and packet size.*/
4649+
/* Get the remaining length and packet size. */
45764650
status = MQTT_GetUnsubscribePacketSize( pSubscriptionList,
45774651
subscriptionCount,
45784652
pPropertyBuilder,
@@ -4814,7 +4888,7 @@ MQTTStatus_t MQTT_MatchTopic( const char * pTopicName,
48144888
if( matchStatus == false )
48154889
{
48164890
/* If an exact match was not found, match against wildcard characters in
4817-
* topic filter.*/
4891+
* topic filter. */
48184892

48194893
/* Determine if topic filter starts with a wildcard. */
48204894
topicFilterStartsWithWildcard = ( pTopicFilter[ 0 ] == '+' ) ||
@@ -4888,7 +4962,7 @@ MQTTStatus_t MQTT_GetSubAckStatusCodes( const MQTTPacketInfo_t * pSubackPacket,
48884962
/* According to the MQTT 3.1.1 protocol specification, the "Remaining Length" field is a
48894963
* length of the variable header (2 bytes) plus the length of the payload.
48904964
* Therefore, we add 2 positions for the starting address of the payload, and
4891-
* subtract 2 bytes from the remaining length for the length of the payload.*/
4965+
* subtract 2 bytes from the remaining length for the length of the payload. */
48924966
*pPayloadStart = &pSubackPacket->pRemainingData[ sizeof( uint16_t ) ];
48934967
*pPayloadSize = pSubackPacket->remainingLength - sizeof( uint16_t );
48944968
}

0 commit comments

Comments
 (0)