From 675335bf6a90dad4f67d23561768f959f41783bb Mon Sep 17 00:00:00 2001 From: Aniruddha Kanhere Date: Wed, 22 Apr 2026 13:20:23 -0700 Subject: [PATCH] Update demos to use MQTTv5 APIs and code (#1398) * Update coreMQTT to v5.0.0 and migrate demos to MQTT v5 API - Update coreMQTT submodule to v5.0.0 release * Update Agent module * Update coreMQTT-Agent to point to latest commit --- .github/workflows/freertos_plus_demos.yml | 62 +++++- .../DemoTasks/DefenderDemoExample.c | 19 +- .../Device_Defender_Demo.vcxproj | 3 + .../Device_Defender_Demo.vcxproj.filters | 9 + .../DemoTasks/ShadowDemoMainExample.c | 19 +- .../Device_Shadow_Demo.vcxproj | 3 + .../Device_Shadow_Demo.vcxproj.filters | 9 + .../CSR_Demo/FleetProvisioningDemoExample.c | 19 +- .../CSR_Demo/fleet_provisioning_demo.vcxproj | 3 + .../fleet_provisioning_demo.vcxproj.filters | 9 + .../Jobs_Demo/DemoTasks/JobsDemoExample.c | 19 +- .../Jobs_Demo/Jobs_Demo.vcxproj | 3 + .../Jobs_Demo/Jobs_Demo.vcxproj.filters | 9 + .../AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.c | 25 ++- .../mqtt_pkcs11_demo_helpers.c | 25 ++- .../DemoTasks/OtaOverHttpDemoExample.c | 31 ++- .../Ota_Over_Http_Demo.vcxproj | 3 + .../Ota_Over_Http_Demo.vcxproj.filters | 9 + .../DemoTasks/OtaOverMqttDemoExample.c | 31 ++- .../Ota_Over_Mqtt_Demo.vcxproj | 3 + .../Ota_Over_Mqtt_Demo.vcxproj.filters | 9 + .../Common/MutualAuthMQTTExample.c | 37 +++- .../mqtt_mutual_auth_demo_with_bg96.vcxproj | 3 + ...mutual_auth_demo_with_bg96.vcxproj.filters | 9 + .../mqtt_mutual_auth_demo_with_hl7802.vcxproj | 3 + ...tual_auth_demo_with_hl7802.vcxproj.filters | 9 + ...mqtt_mutual_auth_demo_with_sara_r4.vcxproj | 3 + ...ual_auth_demo_with_sara_r4.vcxproj.filters | 9 + .../DemoTasks/BasicTLSMQTTExample.c | 167 ++++++++++++++- .../MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj | 3 + .../MQTT_Basic_TLS.vcxproj.filters | 9 + .../DemoTasks/KeepAliveMQTTExample.c | 146 ++++++++++++- .../MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj | 3 + .../MQTT_Keep_Alive.vcxproj.filters | 9 + .../DemoTasks/mqtt-agent-task.c | 22 +- .../DemoTasks/simple_sub_pub_demo.c | 15 +- .../MQTT_Multitask/MQTT_Multitask.vcxproj | 3 + .../MQTT_Multitask.vcxproj.filters | 9 + .../DemoTasks/MutualAuthMQTTExample.c | 195 ++++++++++++++++-- .../MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj | 3 + .../MQTT_Mutual_Auth.vcxproj.filters | 9 + .../DemoTasks/MutualAuthMQTTExample.c | 124 +++++++++-- .../MQTT_Mutual_Auth_wolfSSL.vcxproj | 3 + .../MQTT_Mutual_Auth_wolfSSL.vcxproj.filters | 9 + .../DemoTasks/PlaintextMQTTExample.c | 151 +++++++++++++- .../MQTT_Plain_Text/MQTT_Plain_Text.vcxproj | 3 + .../MQTT_Plain_Text.vcxproj.filters | 9 + .../DemoTasks/SerializerMQTTExample.c | 147 +++++++++++-- .../MQTT_Serializer/MQTT_Serializer.vcxproj | 3 + .../MQTT_Serializer.vcxproj.filters | 9 + .../PKCS11_Mqtt_MutualAuthDemo.c | 39 +++- .../corePKCS11_MQTT_Mutual_Auth.vcxproj | 3 + ...orePKCS11_MQTT_Mutual_Auth.vcxproj.filters | 9 + .../Source/Application-Protocols/coreMQTT | 2 +- .../Application-Protocols/coreMQTT-Agent | 2 +- manifest.yml | 4 +- 56 files changed, 1314 insertions(+), 191 deletions(-) diff --git a/.github/workflows/freertos_plus_demos.yml b/.github/workflows/freertos_plus_demos.yml index 14c66584508..e3105bc904f 100644 --- a/.github/workflows/freertos_plus_demos.yml +++ b/.github/workflows/freertos_plus_demos.yml @@ -449,23 +449,63 @@ jobs: - name: Query CI host IP address id: get-ip run: | - # Query the device's IP address + # Query the device's IP address (same approach as the original working workflow) $SERVER_IP = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notmatch '127.0.0.1' } | Select-Object -First 1 -ExpandProperty IPAddress) Write-Host "Device IP address: $SERVER_IP" echo "server_ip=$SERVER_IP" >> $env:GITHUB_ENV shell: pwsh - - name: Start localhost MQTT broker + - name: Install Mosquitto MQTT v5 broker + id: install-mosquitto + shell: pwsh + run: | + $installerPath = "$env:RUNNER_TEMP\mosquitto-install.exe" + Invoke-WebRequest -Uri "https://mosquitto.org/files/binary/win64/mosquitto-2.1.2-install-windows-x64.exe" -OutFile $installerPath + $proc = Start-Process -FilePath $installerPath -ArgumentList '/S','/D=C:\mosquitto' -PassThru + $proc | Wait-Process -Timeout 120 -ErrorAction SilentlyContinue + if (!$proc.HasExited) { $proc | Stop-Process -Force } + Stop-Service -Name mosquitto -ErrorAction SilentlyContinue + Start-Sleep -Seconds 2 + if (!(Test-Path "C:\mosquitto\mosquitto.exe")) { + Write-Host "ERROR: mosquitto.exe not found" + exit 1 + } + Write-Host "Mosquitto installed successfully" + + - name: Start Mosquitto MQTT v5 broker id: mqtt-broker - uses: FreeRTOS/CI-CD-GitHub-Actions/localhost-mqtt-broker@main - with: - host_address: ${{ env.server_ip }} - root-ca-cert-path: - ${{ steps.generate-credentials.outputs.root-ca-cert-path }} - server-priv-key-path: - ${{ steps.generate-credentials.outputs.server-priv-key-path }} - server-cert-path: - ${{ steps.generate-credentials.outputs.server-cert-path }} + shell: bash + run: | + # Convert MSYS cert paths to Windows paths + CAFILE=$(cygpath -w "${{ steps.generate-credentials.outputs.root-ca-cert-path }}") + CERTFILE=$(cygpath -w "${{ steps.generate-credentials.outputs.server-cert-path }}") + KEYFILE=$(cygpath -w "${{ steps.generate-credentials.outputs.server-priv-key-path }}") + + # Write config + cat > "$(cygpath -w "${RUNNER_TEMP}")/mosquitto.conf" <packetIdentifier ); } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj index 872babac07a..2dbdfdcb340 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj @@ -50,6 +50,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj.filters index 490df121d95..1febcfff464 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj.filters @@ -99,6 +99,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\coreJSON diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/DemoTasks/ShadowDemoMainExample.c b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/DemoTasks/ShadowDemoMainExample.c index f8c1523377a..eadfac53162 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/DemoTasks/ShadowDemoMainExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/DemoTasks/ShadowDemoMainExample.c @@ -316,9 +316,12 @@ static BaseType_t xShadowDeleted = pdFALSE; * @param[in] pxPacketInfo Packet Info pointer for the incoming packet. * @param[in] pxDeserializedInfo Deserialized information from the incoming packet. */ -static void prvEventCallback( MQTTContext_t * pxMqttContext, +static bool prvEventCallback( MQTTContext_t * pxMqttContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ); + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ); /** * @brief Process payload from /update/delta topic. @@ -688,9 +691,12 @@ static void prvUpdateAcceptedHandler( MQTTPublishInfo_t * pxPublishInfo ) * function to determine whether the incoming message is a device shadow message * or not. If it is, it handles the message depending on the message type. */ -static void prvEventCallback( MQTTContext_t * pxMqttContext, +static bool prvEventCallback( MQTTContext_t * pxMqttContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ) + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ) { ShadowMessageType_t messageType = ShadowMessageTypeMaxNum; const char * pcThingName = NULL; @@ -700,6 +706,9 @@ static void prvEventCallback( MQTTContext_t * pxMqttContext, uint16_t usPacketIdentifier; ( void ) pxMqttContext; + ( void ) pxReasonCode; + ( void ) pxSendPropsBuffer; + ( void ) pxGetPropsBuffer; configASSERT( pxDeserializedInfo != NULL ); configASSERT( pxMqttContext != NULL ); @@ -769,6 +778,8 @@ static void prvEventCallback( MQTTContext_t * pxMqttContext, { vHandleOtherIncomingPacket( pxPacketInfo, usPacketIdentifier ); } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj index 41e2e81fe05..3d23c038d41 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj +++ b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj @@ -68,6 +68,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj.filters index ebe7fefa35f..014bf6af41f 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj.filters @@ -140,6 +140,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\coreJSON diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/FleetProvisioningDemoExample.c b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/FleetProvisioningDemoExample.c index c796ca6f4c2..594c29d46e2 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/FleetProvisioningDemoExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/FleetProvisioningDemoExample.c @@ -252,9 +252,12 @@ static MQTTFixedBuffer_t xBuffer = * @param[in] pPublishInfo Pointer to publish info of the incoming publish. * @param[in] usPacketIdentifier Packet identifier of the incoming publish. */ -static void prvProvisioningPublishCallback( MQTTContext_t * pxMqttContext, +static bool prvProvisioningPublishCallback( MQTTContext_t * pxMqttContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ); + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ); /** * @brief Subscribe to the CreateCertificateFromCsr accepted and rejected topics. @@ -297,9 +300,12 @@ BaseType_t xPlatformIsNetworkUp( void ); /*-----------------------------------------------------------*/ -static void prvProvisioningPublishCallback( MQTTContext_t * pxMqttContext, +static bool prvProvisioningPublishCallback( MQTTContext_t * pxMqttContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ) + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ) { FleetProvisioningStatus_t xStatus; FleetProvisioningTopic_t xApi; @@ -312,6 +318,9 @@ static void prvProvisioningPublishCallback( MQTTContext_t * pxMqttContext, /* Suppress the unused parameter warning when asserts are disabled in * build. */ ( void ) pxMqttContext; + ( void ) pxReasonCode; + ( void ) pxSendPropsBuffer; + ( void ) pxGetPropsBuffer; /* Handle an incoming publish. The lower 4 bits of the publish packet * type is used for the dup, QoS, and retain flags. Hence masking @@ -384,6 +393,8 @@ static void prvProvisioningPublishCallback( MQTTContext_t * pxMqttContext, vHandleOtherIncomingPacket( pxPacketInfo, pxDeserializedInfo->packetIdentifier ); xResponseStatus = ResponseAccepted; } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/fleet_provisioning_demo.vcxproj b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/fleet_provisioning_demo.vcxproj index 8a8e9d64291..da8952c0897 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/fleet_provisioning_demo.vcxproj +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/fleet_provisioning_demo.vcxproj @@ -56,6 +56,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/fleet_provisioning_demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/fleet_provisioning_demo.vcxproj.filters index 49d9e7469ee..ad48b751496 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/fleet_provisioning_demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/CSR_Demo/fleet_provisioning_demo.vcxproj.filters @@ -66,6 +66,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\coreMQTT diff --git a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/DemoTasks/JobsDemoExample.c b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/DemoTasks/JobsDemoExample.c index 950fe30d00e..d4c9456ebe0 100644 --- a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/DemoTasks/JobsDemoExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/DemoTasks/JobsDemoExample.c @@ -346,9 +346,12 @@ static JobActionType prvGetAction( const char * pcAction, * @param[in] pxPacketInfo Packet Info pointer for the incoming packet. * @param[in] pxDeserializedInfo Deserialized information from the incoming packet. */ -static void prvEventCallback( MQTTContext_t * pxMqttContext, +static bool prvEventCallback( MQTTContext_t * pxMqttContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ); + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ); /** * @brief Process payload from NextJobExecutionChanged and DescribeJobExecution @@ -688,13 +691,19 @@ static void prvNextJobHandler( MQTTPublishInfo_t * pxPublishInfo ) * function to determine whether the incoming message is a Jobs message * or not. If it is, it handles the message depending on the message type. */ -static void prvEventCallback( MQTTContext_t * pxMqttContext, +static bool prvEventCallback( MQTTContext_t * pxMqttContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ) + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ) { uint16_t usPacketIdentifier; ( void ) pxMqttContext; + ( void ) pxReasonCode; + ( void ) pxSendPropsBuffer; + ( void ) pxGetPropsBuffer; configASSERT( pxDeserializedInfo != NULL ); configASSERT( pxMqttContext != NULL ); @@ -822,6 +831,8 @@ static void prvEventCallback( MQTTContext_t * pxMqttContext, { vHandleOtherIncomingPacket( pxPacketInfo, usPacketIdentifier ); } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj index 95aecf4e96b..7c53d597f90 100644 --- a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj +++ b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj @@ -64,6 +64,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj.filters index 600bbd5ad83..add7a2010a6 100644 --- a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj.filters @@ -90,6 +90,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\Backoff Algorithm diff --git a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.c b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.c index 144d180a96e..5b2bb88f6eb 100644 --- a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.c +++ b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.c @@ -104,7 +104,7 @@ /** * @brief Timeout for receiving CONNACK packet in milliseconds. */ -#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 1000U ) +#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 10000U ) /** * @brief The number of topic filters to subscribe. @@ -267,6 +267,7 @@ static MQTTPubAckInfo_t pOutgoingPublishRecords[ mqttexampleOUTGOING_PUBLISH_REC */ static MQTTPubAckInfo_t pIncomingPublishRecords[ mqttexampleINCOMING_PUBLISH_RECORD_LEN ]; +static uint8_t ucAckPropsBuffer[ 500 ]; /*-----------------------------------------------------------*/ @@ -651,7 +652,8 @@ static BaseType_t xHandlePublishResend( MQTTContext_t * pxMqttContext ) outgoingPublishPackets[ ucIndex ].packetId ) ); xMQTTStatus = MQTT_Publish( pxMqttContext, &outgoingPublishPackets[ ucIndex ].pubInfo, - outgoingPublishPackets[ ucIndex ].packetId ); + outgoingPublishPackets[ ucIndex ].packetId, + NULL ); if( xMQTTStatus != MQTTSuccess ) { @@ -728,7 +730,9 @@ BaseType_t xEstablishMqttSession( MQTTContext_t * pxMqttContext, pOutgoingPublishRecords, mqttexampleOUTGOING_PUBLISH_RECORD_LEN, pIncomingPublishRecords, - mqttexampleINCOMING_PUBLISH_RECORD_LEN ); + mqttexampleINCOMING_PUBLISH_RECORD_LEN, + ucAckPropsBuffer, + sizeof( ucAckPropsBuffer ) ); if( xMQTTStatus != MQTTSuccess ) { @@ -786,7 +790,9 @@ BaseType_t xEstablishMqttSession( MQTTContext_t * pxMqttContext, &xConnectInfo, NULL, mqttexampleCONNACK_RECV_TIMEOUT_MS, - &sessionPresent ); + &sessionPresent, + NULL, + NULL ); if( xMQTTStatus != MQTTSuccess ) { @@ -851,7 +857,7 @@ BaseType_t xDisconnectMqttSession( MQTTContext_t * pxMqttContext, if( xMqttSessionEstablished == true ) { /* Send DISCONNECT. */ - xMQTTStatus = MQTT_Disconnect( pxMqttContext ); + xMQTTStatus = MQTT_Disconnect( pxMqttContext, NULL, NULL ); if( xMQTTStatus != MQTTSuccess ) { @@ -896,7 +902,8 @@ BaseType_t xSubscribeToTopic( MQTTContext_t * pxMqttContext, xMQTTStatus = MQTT_Subscribe( pxMqttContext, pSubscriptionList, sizeof( pSubscriptionList ) / sizeof( MQTTSubscribeInfo_t ), - globalSubscribePacketIdentifier ); + globalSubscribePacketIdentifier, + NULL ); if( xMQTTStatus != MQTTSuccess ) { @@ -959,7 +966,8 @@ BaseType_t xUnsubscribeFromTopic( MQTTContext_t * pxMqttContext, xMQTTStatus = MQTT_Unsubscribe( pxMqttContext, pSubscriptionList, sizeof( pSubscriptionList ) / sizeof( MQTTSubscribeInfo_t ), - globalUnsubscribePacketIdentifier ); + globalUnsubscribePacketIdentifier, + NULL ); if( xMQTTStatus != MQTTSuccess ) { @@ -1029,7 +1037,8 @@ BaseType_t xPublishToTopic( MQTTContext_t * pxMqttContext, /* Send PUBLISH packet. */ xMQTTStatus = MQTT_Publish( pxMqttContext, &outgoingPublishPackets[ ucPublishIndex ].pubInfo, - outgoingPublishPackets[ ucPublishIndex ].packetId ); + outgoingPublishPackets[ ucPublishIndex ].packetId, + NULL ); if( xMQTTStatus != MQTTSuccess ) { diff --git a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.c b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.c index 170e35758ef..617f0e916ce 100644 --- a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.c +++ b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.c @@ -98,7 +98,7 @@ /** * @brief Timeout for receiving CONNACK packet in milliseconds. */ -#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 1000U ) +#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 10000U ) /** * @brief The number of topic filters to subscribe. @@ -260,6 +260,7 @@ static MQTTPubAckInfo_t pOutgoingPublishRecords[ mqttexampleOUTGOING_PUBLISH_REC */ static MQTTPubAckInfo_t pIncomingPublishRecords[ mqttexampleINCOMING_PUBLISH_RECORD_LEN ]; +static uint8_t ucAckPropsBuffer[ 500 ]; /*-----------------------------------------------------------*/ @@ -646,7 +647,8 @@ static BaseType_t xHandlePublishResend( MQTTContext_t * pxMqttContext ) outgoingPublishPackets[ ucIndex ].packetId ) ); xMQTTStatus = MQTT_Publish( pxMqttContext, &outgoingPublishPackets[ ucIndex ].pubInfo, - outgoingPublishPackets[ ucIndex ].packetId ); + outgoingPublishPackets[ ucIndex ].packetId, + NULL ); if( xMQTTStatus != MQTTSuccess ) { @@ -727,7 +729,9 @@ BaseType_t xEstablishMqttSession( MQTTContext_t * pxMqttContext, pOutgoingPublishRecords, mqttexampleOUTGOING_PUBLISH_RECORD_LEN, pIncomingPublishRecords, - mqttexampleINCOMING_PUBLISH_RECORD_LEN ); + mqttexampleINCOMING_PUBLISH_RECORD_LEN, + ucAckPropsBuffer, + sizeof( ucAckPropsBuffer ) ); if( xMQTTStatus != MQTTSuccess ) { @@ -785,7 +789,9 @@ BaseType_t xEstablishMqttSession( MQTTContext_t * pxMqttContext, &xConnectInfo, NULL, mqttexampleCONNACK_RECV_TIMEOUT_MS, - &sessionPresent ); + &sessionPresent, + NULL, + NULL ); if( xMQTTStatus != MQTTSuccess ) { @@ -850,7 +856,7 @@ BaseType_t xDisconnectMqttSession( MQTTContext_t * pxMqttContext, if( xMqttSessionEstablished == true ) { /* Send DISCONNECT. */ - xMQTTStatus = MQTT_Disconnect( pxMqttContext ); + xMQTTStatus = MQTT_Disconnect( pxMqttContext, NULL, NULL ); if( xMQTTStatus != MQTTSuccess ) { @@ -895,7 +901,8 @@ BaseType_t xSubscribeToTopic( MQTTContext_t * pxMqttContext, xMQTTStatus = MQTT_Subscribe( pxMqttContext, pSubscriptionList, sizeof( pSubscriptionList ) / sizeof( MQTTSubscribeInfo_t ), - globalSubscribePacketIdentifier ); + globalSubscribePacketIdentifier, + NULL ); if( xMQTTStatus != MQTTSuccess ) { @@ -958,7 +965,8 @@ BaseType_t xUnsubscribeFromTopic( MQTTContext_t * pxMqttContext, xMQTTStatus = MQTT_Unsubscribe( pxMqttContext, pSubscriptionList, sizeof( pSubscriptionList ) / sizeof( MQTTSubscribeInfo_t ), - globalUnsubscribePacketIdentifier ); + globalUnsubscribePacketIdentifier, + NULL ); if( xMQTTStatus != MQTTSuccess ) { @@ -1028,7 +1036,8 @@ BaseType_t xPublishToTopic( MQTTContext_t * pxMqttContext, /* Send PUBLISH packet. */ xMQTTStatus = MQTT_Publish( pxMqttContext, &outgoingPublishPackets[ ucPublishIndex ].pubInfo, - outgoingPublishPackets[ ucPublishIndex ].packetId ); + outgoingPublishPackets[ ucPublishIndex ].packetId, + NULL ); if( xMQTTStatus != MQTTSuccess ) { diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/DemoTasks/OtaOverHttpDemoExample.c b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/DemoTasks/OtaOverHttpDemoExample.c index 762c3890ce3..14aa9a38901 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/DemoTasks/OtaOverHttpDemoExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/DemoTasks/OtaOverHttpDemoExample.c @@ -1301,7 +1301,7 @@ static void prvSubscriptionCommandCallback( void * pxCommandContext, /* Remove subscription callback for unsubscribe. */ removeSubscription( xGlobalSubscriptionList, pxSubscribeArgs->pSubscribeInfo[ xIndex ].pTopicFilter, - pxSubscribeArgs->pSubscribeInfo[ xIndex ].topicFilterLength ); + ( uint16_t ) pxSubscribeArgs->pSubscribeInfo[ xIndex ].topicFilterLength ); } } @@ -1590,7 +1590,9 @@ static MQTTStatus_t prvMQTTInit( void ) prvGetTimeMs, prvIncomingPublishCallback, /* Context to pass into the callback. Passing the pointer to subscription array. */ - xGlobalSubscriptionList ); + xGlobalSubscriptionList, + NULL, + 0U ); return xReturn; } @@ -1614,7 +1616,7 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) * the MQTT broker. In a production device the identifier can be something * unique, such as a device serial number. */ xConnectInfo.pClientIdentifier = democonfigCLIENT_IDENTIFIER; - xConnectInfo.clientIdentifierLength = ( uint16_t ) strlen( democonfigCLIENT_IDENTIFIER ); + xConnectInfo.clientIdentifierLength = strlen( democonfigCLIENT_IDENTIFIER ); /* Set MQTT keep-alive period. It is the responsibility of the application * to ensure that the interval between Control Packets being sent does not @@ -1627,12 +1629,12 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) #ifdef democonfigUSE_AWS_IOT_CORE_BROKER #ifdef democonfigCLIENT_USERNAME xConnectInfo.pUserName = democonfigCLIENT_USERNAME AWS_IOT_METRICS_STRING; - xConnectInfo.userNameLength = ( uint16_t ) strlen( democonfigCLIENT_USERNAME AWS_IOT_METRICS_STRING ); + xConnectInfo.userNameLength = strlen( democonfigCLIENT_USERNAME AWS_IOT_METRICS_STRING ); xConnectInfo.pPassword = democonfigCLIENT_PASSWORD; - xConnectInfo.passwordLength = ( uint16_t ) strlen( democonfigCLIENT_PASSWORD ); + xConnectInfo.passwordLength = strlen( democonfigCLIENT_PASSWORD ); #else xConnectInfo.pUserName = AWS_IOT_METRICS_STRING; - xConnectInfo.userNameLength = ( uint16_t ) strlen( AWS_IOT_METRICS_STRING ); + xConnectInfo.userNameLength = strlen( AWS_IOT_METRICS_STRING ); /* Password for authentication is not used. */ xConnectInfo.pPassword = NULL; xConnectInfo.passwordLength = 0U; @@ -1640,9 +1642,9 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) #else /* ifdef democonfigUSE_AWS_IOT_CORE_BROKER */ #ifdef democonfigCLIENT_USERNAME xConnectInfo.pUserName = democonfigCLIENT_USERNAME; - xConnectInfo.userNameLength = ( uint16_t ) strlen( democonfigCLIENT_USERNAME ); + xConnectInfo.userNameLength = strlen( democonfigCLIENT_USERNAME ); xConnectInfo.pPassword = democonfigCLIENT_PASSWORD; - xConnectInfo.passwordLength = ( uint16_t ) strlen( democonfigCLIENT_PASSWORD ); + xConnectInfo.passwordLength = strlen( democonfigCLIENT_PASSWORD ); #endif /* ifdef democonfigCLIENT_USERNAME */ #endif /* ifdef democonfigUSE_AWS_IOT_CORE_BROKER */ @@ -1652,7 +1654,9 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) &xConnectInfo, NULL, otaexampleCONNACK_RECV_TIMEOUT_MS, - &xSessionPresent ); + &xSessionPresent, + NULL, + NULL ); LogInfo( ( "Session present: %d\n", xSessionPresent ) ); @@ -1709,7 +1713,8 @@ static void prvDisconnectFromMQTTBroker( void ) xCommandContext.xReturnStatus = MQTTSendFailed; /* Disconnect MQTT session. */ - xCommandStatus = MQTTAgent_Disconnect( &xGlobalMqttAgentContext, &xCommandParams ); + MQTTAgentDisconnectArgs_t xDisconnectArgs = { 0 }; + xCommandStatus = MQTTAgent_Disconnect( &xGlobalMqttAgentContext, &xDisconnectArgs, &xCommandParams ); configASSERT( xCommandStatus == MQTTSuccess ); xTaskNotifyWait( 0, @@ -2120,6 +2125,7 @@ static OtaMqttStatus_t prvMQTTPublish( const char * const pacTopic, MQTTPublishInfo_t publishInfo = { 0 }; MQTTAgentCommandInfo_t xCommandParams = { 0 }; MQTTAgentCommandContext_t xCommandContext = { 0 }; + MQTTAgentPublishArgs_t xPublishArgs = { 0 }; publishInfo.pTopicName = pacTopic; publishInfo.topicNameLength = topicLen; @@ -2134,8 +2140,11 @@ static OtaMqttStatus_t prvMQTTPublish( const char * const pacTopic, xCommandParams.cmdCompleteCallback = prvCommandCallback; xCommandParams.pCmdCompleteCallbackContext = ( void * ) &xCommandContext; + xPublishArgs.pPublishInfo = &publishInfo; + xPublishArgs.pProperties = NULL; + mqttStatus = MQTTAgent_Publish( &xGlobalMqttAgentContext, - &publishInfo, + &xPublishArgs, &xCommandParams ); /* Wait for command to complete so MQTTSubscribeInfo_t remains in scope for the diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj index cfd0151e944..00d26131a62 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj @@ -69,6 +69,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj.filters index d5aafccd1a9..68da0e97214 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj.filters @@ -150,6 +150,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\coreMQTT-Agent diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/DemoTasks/OtaOverMqttDemoExample.c b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/DemoTasks/OtaOverMqttDemoExample.c index fea5663db83..66668cb85b4 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/DemoTasks/OtaOverMqttDemoExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/DemoTasks/OtaOverMqttDemoExample.c @@ -1158,7 +1158,7 @@ static void prvSubscriptionCommandCallback( void * pxCommandContext, /* Remove subscription callback for unsubscribe. */ removeSubscription( xGlobalSubscriptionList, pxSubscribeArgs->pSubscribeInfo[ xIndex ].pTopicFilter, - pxSubscribeArgs->pSubscribeInfo[ xIndex ].topicFilterLength ); + ( uint16_t ) pxSubscribeArgs->pSubscribeInfo[ xIndex ].topicFilterLength ); } } @@ -1448,7 +1448,9 @@ static MQTTStatus_t prvMQTTInit( void ) prvGetTimeMs, prvIncomingPublishCallback, /* Context to pass into the callback. Passing the pointer to subscription array. */ - xGlobalSubscriptionList ); + xGlobalSubscriptionList, + NULL, + 0U ); return xReturn; } @@ -1472,7 +1474,7 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) * the MQTT broker. In a production device the identifier can be something * unique, such as a device serial number. */ xConnectInfo.pClientIdentifier = democonfigCLIENT_IDENTIFIER; - xConnectInfo.clientIdentifierLength = ( uint16_t ) strlen( democonfigCLIENT_IDENTIFIER ); + xConnectInfo.clientIdentifierLength = strlen( democonfigCLIENT_IDENTIFIER ); /* Set MQTT keep-alive period. It is the responsibility of the application * to ensure that the interval between Control Packets being sent does not @@ -1485,12 +1487,12 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) #ifdef democonfigUSE_AWS_IOT_CORE_BROKER #ifdef democonfigCLIENT_USERNAME xConnectInfo.pUserName = democonfigCLIENT_USERNAME AWS_IOT_METRICS_STRING; - xConnectInfo.userNameLength = ( uint16_t ) strlen( democonfigCLIENT_USERNAME AWS_IOT_METRICS_STRING ); + xConnectInfo.userNameLength = strlen( democonfigCLIENT_USERNAME AWS_IOT_METRICS_STRING ); xConnectInfo.pPassword = democonfigCLIENT_PASSWORD; - xConnectInfo.passwordLength = ( uint16_t ) strlen( democonfigCLIENT_PASSWORD ); + xConnectInfo.passwordLength = strlen( democonfigCLIENT_PASSWORD ); #else xConnectInfo.pUserName = AWS_IOT_METRICS_STRING; - xConnectInfo.userNameLength = ( uint16_t ) strlen( AWS_IOT_METRICS_STRING ); + xConnectInfo.userNameLength = strlen( AWS_IOT_METRICS_STRING ); /* Password for authentication is not used. */ xConnectInfo.pPassword = NULL; xConnectInfo.passwordLength = 0U; @@ -1498,9 +1500,9 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) #else /* ifdef democonfigUSE_AWS_IOT_CORE_BROKER */ #ifdef democonfigCLIENT_USERNAME xConnectInfo.pUserName = democonfigCLIENT_USERNAME; - xConnectInfo.userNameLength = ( uint16_t ) strlen( democonfigCLIENT_USERNAME ); + xConnectInfo.userNameLength = strlen( democonfigCLIENT_USERNAME ); xConnectInfo.pPassword = democonfigCLIENT_PASSWORD; - xConnectInfo.passwordLength = ( uint16_t ) strlen( democonfigCLIENT_PASSWORD ); + xConnectInfo.passwordLength = strlen( democonfigCLIENT_PASSWORD ); #endif /* ifdef democonfigCLIENT_USERNAME */ #endif /* ifdef democonfigUSE_AWS_IOT_CORE_BROKER */ @@ -1510,7 +1512,9 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) &xConnectInfo, NULL, otaexampleCONNACK_RECV_TIMEOUT_MS, - &xSessionPresent ); + &xSessionPresent, + NULL, + NULL ); LogInfo( ( "Session present: %d\n", xSessionPresent ) ); @@ -1567,7 +1571,8 @@ static void prvDisconnectFromMQTTBroker( void ) xCommandContext.xReturnStatus = MQTTSendFailed; /* Disconnect MQTT session. */ - xCommandStatus = MQTTAgent_Disconnect( &xGlobalMqttAgentContext, &xCommandParams ); + MQTTAgentDisconnectArgs_t xDisconnectArgs = { 0 }; + xCommandStatus = MQTTAgent_Disconnect( &xGlobalMqttAgentContext, &xDisconnectArgs, &xCommandParams ); configASSERT( xCommandStatus == MQTTSuccess ); xTaskNotifyWait( 0, @@ -1662,6 +1667,7 @@ static OtaMqttStatus_t prvMQTTPublish( const char * const pacTopic, MQTTPublishInfo_t publishInfo = { 0 }; MQTTAgentCommandInfo_t xCommandParams = { 0 }; MQTTAgentCommandContext_t xCommandContext = { 0 }; + MQTTAgentPublishArgs_t xPublishArgs = { 0 }; publishInfo.pTopicName = pacTopic; publishInfo.topicNameLength = topicLen; @@ -1676,8 +1682,11 @@ static OtaMqttStatus_t prvMQTTPublish( const char * const pacTopic, xCommandParams.cmdCompleteCallback = prvCommandCallback; xCommandParams.pCmdCompleteCallbackContext = ( void * ) &xCommandContext; + xPublishArgs.pPublishInfo = &publishInfo; + xPublishArgs.pProperties = NULL; + mqttStatus = MQTTAgent_Publish( &xGlobalMqttAgentContext, - &publishInfo, + &xPublishArgs, &xCommandParams ); /* Wait for command to complete so MQTTSubscribeInfo_t remains in scope for the diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj index c40dbd588d5..d2a19426938 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj @@ -67,6 +67,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj.filters index 032f5b8aec8..0b36fcbbaba 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj.filters @@ -144,6 +144,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\coreMQTT-Agent diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/MutualAuthMQTTExample.c b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/MutualAuthMQTTExample.c index e79d5bfa707..7f35764aa0d 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/MutualAuthMQTTExample.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/MutualAuthMQTTExample.c @@ -381,9 +381,12 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ); * @param[in] pxPacketInfo Packet Info pointer for the incoming packet. * @param[in] pxDeserializedInfo Deserialized information from the incoming packet. */ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ); + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ); /** * @brief Call #MQTT_ProcessLoop in a loop for the duration of a timeout or @@ -599,7 +602,7 @@ static void prvMQTTDemoTask( void * pvParameters ) * connection. */ LogInfo( ( "Disconnecting the MQTT connection with %s.\r\n", democonfigMQTT_BROKER_ENDPOINT ) ); - xMQTTStatus = MQTT_Disconnect( &xMQTTContext ); + xMQTTStatus = MQTT_Disconnect( &xMQTTContext, NULL, NULL ); configASSERT( xMQTTStatus == MQTTSuccess ); /* Close the network connection. */ @@ -764,7 +767,9 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, pOutgoingPublishRecords, mqttexampleOUTGOING_PUBLISH_RECORD_LEN, pIncomingPublishRecords, - mqttexampleINCOMING_PUBLISH_RECORD_LEN ); + mqttexampleINCOMING_PUBLISH_RECORD_LEN, + NULL, + 0U ); configASSERT( xResult == MQTTSuccess ); /* Some fields are not used in this demo so start with everything at 0. */ @@ -820,7 +825,9 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, &xConnectInfo, NULL, mqttexampleCONNACK_RECV_TIMEOUT_MS, - &xSessionPresent ); + &xSessionPresent, + NULL, + NULL ); configASSERT( xResult == MQTTSuccess ); /* Successfully established and MQTT connection with the broker. */ @@ -889,7 +896,8 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) xResult = MQTT_Subscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usSubscribePacketIdentifier ); + usSubscribePacketIdentifier, + NULL ); configASSERT( xResult == MQTTSuccess ); LogInfo( ( "SUBSCRIBE sent for topic %s to broker.\n\n", mqttexampleTOPIC ) ); @@ -971,7 +979,7 @@ static void prvMQTTPublishToTopic( MQTTContext_t * pxMQTTContext ) usPublishPacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); /* Send PUBLISH packet. Packet ID is not used for a QoS1 publish. */ - xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier ); + xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier, NULL ); configASSERT( xResult == MQTTSuccess ); } @@ -1001,7 +1009,8 @@ static void prvMQTTUnsubscribeFromTopic( MQTTContext_t * pxMQTTContext ) xResult = MQTT_Unsubscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usUnsubscribePacketIdentifier ); + usUnsubscribePacketIdentifier, + NULL ); configASSERT( xResult == MQTTSuccess ); } @@ -1093,12 +1102,18 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ) /*-----------------------------------------------------------*/ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ) + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ) { /* The MQTT context is not used for this demo. */ ( void ) pxMQTTContext; + ( void ) pxReasonCode; + ( void ) pxSendPropsBuffer; + ( void ) pxGetPropsBuffer; if( ( pxPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) { @@ -1108,6 +1123,8 @@ static void prvEventCallback( MQTTContext_t * pxMQTTContext, { prvMQTTProcessResponse( pxPacketInfo, pxDeserializedInfo->packetIdentifier ); } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj index 8f2a1b80c15..b37d5559d9d 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj @@ -50,6 +50,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj.filters index 2ae20055a23..6c03f3724db 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj.filters @@ -120,6 +120,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\FreeRTOS Cellular Interface\module diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj index 5d5775ec3c2..b4395bbd18e 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj @@ -51,6 +51,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj.filters index 7b17bbbdc7b..d1900accaf6 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj.filters @@ -120,6 +120,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\Backoff Algorithm diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj index c1fc78bd0bb..653837a0cfd 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj @@ -50,6 +50,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj.filters index ce5a11d3135..c3dcb20e9de 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj.filters @@ -120,6 +120,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\Backoff Algorithm diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/DemoTasks/BasicTLSMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/DemoTasks/BasicTLSMQTTExample.c index 5f119afd810..7869bc5601d 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/DemoTasks/BasicTLSMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/DemoTasks/BasicTLSMQTTExample.c @@ -327,10 +327,16 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ); * @param[in] pxMQTTContext MQTT context pointer. * @param[in] pxPacketInfo Packet Info pointer for the incoming packet. * @param[in] pxDeserializedInfo Deserialized information from the incoming packet. + * @param[out] pxReasonCode Reason code for the outgoing acknowledgment. + * @param[out] pxSendPropsBuffer Properties to be sent in the outgoing acknowledgment. + * @param[in] pxGetPropsBuffer Properties received in the incoming packet. */ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ); + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ); /** * @brief Call #MQTT_ProcessLoop in a loop for the duration of a timeout or @@ -424,6 +430,11 @@ static MQTTPubAckInfo_t pOutgoingPublishRecords[ mqttexampleOUTGOING_PUBLISH_REC */ static MQTTPubAckInfo_t pIncomingPublishRecords[ mqttexampleINCOMING_PUBLISH_RECORD_LEN ]; +/** + * @brief Static buffer used to hold properties for outgoing ACK packets. + */ +static uint8_t ucAckPropsBuffer[ 500 ]; + /*-----------------------------------------------------------*/ /* @@ -566,7 +577,19 @@ static void prvMQTTDemoTask( void * pvParameters ) * There is no corresponding response expected from the broker. After sending the * disconnect request, the client must close the network connection. */ LogInfo( ( "Disconnecting the MQTT connection with %s.\r\n", democonfigMQTT_BROKER_ENDPOINT ) ); - xMQTTStatus = MQTT_Disconnect( &xMQTTContext ); + { + MQTTPropBuilder_t xDisconnectProps; + uint8_t ucDisconnectPropsBuf[ 200 ]; + MQTTSuccessFailReasonCode_t xReasonCode = MQTT_REASON_DISCONNECT_NORMAL_DISCONNECTION; + + xMQTTStatus = MQTTPropertyBuilder_Init( &xDisconnectProps, ucDisconnectPropsBuf, sizeof( ucDisconnectPropsBuf ) ); + configASSERT( xMQTTStatus == MQTTSuccess ); + + xMQTTStatus = MQTTPropAdd_ReasonString( &xDisconnectProps, "Normal disconnect", 17, &( uint8_t ) { MQTT_PACKET_TYPE_DISCONNECT } ); + configASSERT( xMQTTStatus == MQTTSuccess ); + + xMQTTStatus = MQTT_Disconnect( &xMQTTContext, &xDisconnectProps, &xReasonCode ); + } configASSERT( xMQTTStatus == MQTTSuccess ); /* Close the network connection. */ @@ -658,6 +681,8 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, MQTTConnectInfo_t xConnectInfo; bool xSessionPresent; TransportInterface_t xTransport; + MQTTPropBuilder_t xConnectProps; + uint8_t ucConnectPropsBuf[ 200 ]; /*** * For readability, error handling in this function is restricted to the use of @@ -677,7 +702,9 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, pOutgoingPublishRecords, mqttexampleOUTGOING_PUBLISH_RECORD_LEN, pIncomingPublishRecords, - mqttexampleINCOMING_PUBLISH_RECORD_LEN ); + mqttexampleINCOMING_PUBLISH_RECORD_LEN, + ucAckPropsBuffer, + sizeof( ucAckPropsBuffer ) ); configASSERT( xResult == MQTTSuccess ); /* Some fields are not used in this demo so start with everything at 0. */ @@ -699,13 +726,28 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, * the keep-alive period, the MQTT library will send PINGREQ packets. */ xConnectInfo.keepAliveSeconds = mqttexampleKEEP_ALIVE_TIMEOUT_SECONDS; + /* Initialize connect properties builder. */ + xResult = MQTTPropertyBuilder_Init( &xConnectProps, ucConnectPropsBuf, sizeof( ucConnectPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + /* Add session expiry interval of 3600 seconds. */ + xResult = MQTTPropAdd_SessionExpiry( &xConnectProps, 3600U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + configASSERT( xResult == MQTTSuccess ); + + /* Add receive maximum of 10. */ + xResult = MQTTPropAdd_ReceiveMax( &xConnectProps, 10U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + MQTTPropAdd_MaxPacketSize( &xConnectProps, ( uint32_t ) democonfigNETWORK_BUFFER_SIZE, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + configASSERT( xResult == MQTTSuccess ); + /* Send MQTT CONNECT packet to broker. LWT is not used in this demo, so it * is passed as NULL. */ xResult = MQTT_Connect( pxMQTTContext, &xConnectInfo, NULL, mqttexampleCONNACK_RECV_TIMEOUT_MS, - &xSessionPresent ); + &xSessionPresent, + &xConnectProps, + NULL ); configASSERT( xResult == MQTTSuccess ); /* Successfully established and MQTT connection with the broker. */ @@ -742,6 +784,8 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) MQTTSubscribeInfo_t xMQTTSubscription[ mqttexampleTOPIC_COUNT ]; bool xFailedSubscribeToTopic = false; uint32_t ulTopicCount = 0U; + MQTTPropBuilder_t xSubProps; + uint8_t ucSubPropsBuf[ 200 ]; /* Some fields not used by this demo so start with everything at 0. */ ( void ) memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); @@ -755,8 +799,19 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) xMQTTSubscription[ ulTopicCount ].qos = MQTTQoS2; xMQTTSubscription[ ulTopicCount ].pTopicFilter = xTopicFilterContext[ ulTopicCount ].pcTopicFilter; xMQTTSubscription[ ulTopicCount ].topicFilterLength = ( uint16_t ) strlen( xTopicFilterContext[ ulTopicCount ].pcTopicFilter ); + xMQTTSubscription[ ulTopicCount ].noLocalOption = false; + xMQTTSubscription[ ulTopicCount ].retainAsPublishedOption = true; + xMQTTSubscription[ ulTopicCount ].retainHandlingOption = retainSendOnSub; } + /* Initialize subscribe properties builder. */ + xResult = MQTTPropertyBuilder_Init( &xSubProps, ucSubPropsBuf, sizeof( ucSubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + /* Add subscription identifier. */ + xResult = MQTTPropAdd_SubscriptionId( &xSubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_SUBSCRIBE } ); + configASSERT( xResult == MQTTSuccess ); + /* Initialize context for backoff retry attempts if SUBSCRIBE request fails. */ BackoffAlgorithm_InitializeParams( &xRetryParams, mqttexampleRETRY_BACKOFF_BASE_MS, @@ -775,7 +830,8 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) xResult = MQTT_Subscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usSubscribePacketIdentifier ); + usSubscribePacketIdentifier, + &xSubProps ); configASSERT( xResult == MQTTSuccess ); for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) @@ -841,6 +897,9 @@ static void prvMQTTPublishToTopics( MQTTContext_t * pxMQTTContext ) MQTTStatus_t xResult; MQTTPublishInfo_t xMQTTPublishInfo; uint32_t ulTopicCount; + MQTTPropBuilder_t xPubProps; + uint8_t ucPubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; /*** * For readability, error handling in this function is restricted to the use of @@ -860,12 +919,32 @@ static void prvMQTTPublishToTopics( MQTTContext_t * pxMQTTContext ) xMQTTPublishInfo.pPayload = mqttexampleMESSAGE; xMQTTPublishInfo.payloadLength = strlen( mqttexampleMESSAGE ); + /* Re-initialize publish properties builder for each iteration. */ + xResult = MQTTPropertyBuilder_Init( &xPubProps, ucPubPropsBuf, sizeof( ucPubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + /* Add payload format indicator (1 = UTF-8). */ + xResult = MQTTPropAdd_PayloadFormat( &xPubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + + /* Add message expiry of 300 seconds. */ + xResult = MQTTPropAdd_MessageExpiry( &xPubProps, 300U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + + /* Add a user property. */ + xUserProp.pKey = "demo"; + xUserProp.keyLength = 4; + xUserProp.pValue = "basic-tls"; + xUserProp.valueLength = 9; + xResult = MQTTPropAdd_UserProp( &xPubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + /* Get a unique packet id. */ usPublishPacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); LogInfo( ( "Publishing to the MQTT topic %s.\r\n", xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) ); /* Send PUBLISH packet. */ - xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier ); + xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier, &xPubProps ); configASSERT( xResult == MQTTSuccess ); } } @@ -876,6 +955,9 @@ static void prvMQTTUnsubscribeFromTopics( MQTTContext_t * pxMQTTContext ) MQTTStatus_t xResult; MQTTSubscribeInfo_t xMQTTSubscription[ mqttexampleTOPIC_COUNT ]; uint32_t ulTopicCount; + MQTTPropBuilder_t xUnsubProps; + uint8_t ucUnsubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; /* Some fields are not used by this demo so start with everything at 0. */ memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); @@ -895,11 +977,24 @@ static void prvMQTTUnsubscribeFromTopics( MQTTContext_t * pxMQTTContext ) /* Make sure the packet id obtained is valid. */ configASSERT( usUnsubscribePacketIdentifier != 0 ); + /* Initialize unsubscribe properties builder. */ + xResult = MQTTPropertyBuilder_Init( &xUnsubProps, ucUnsubPropsBuf, sizeof( ucUnsubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + /* Add a user property. */ + xUserProp.pKey = "reason"; + xUserProp.keyLength = 6; + xUserProp.pValue = "demo-complete"; + xUserProp.valueLength = 13; + xResult = MQTTPropAdd_UserProp( &xUnsubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_UNSUBSCRIBE } ); + configASSERT( xResult == MQTTSuccess ); + /* Send UNSUBSCRIBE packet. */ xResult = MQTT_Unsubscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usUnsubscribePacketIdentifier ); + usUnsubscribePacketIdentifier, + &xUnsubProps ); configASSERT( xResult == MQTTSuccess ); } @@ -975,6 +1070,10 @@ static void prvMQTTProcessResponse( MQTTPacketInfo_t * pxIncomingPacket, usPacketId ) ); break; + case MQTT_PACKET_TYPE_DISCONNECT: + LogInfo( ( "Server initiated disconnect received.\r\n" ) ); + break; + /* Any other packet type is invalid. */ default: LogWarn( ( "prvMQTTProcessResponse() called with unknown packet type:(%02X).\r\n", @@ -1029,14 +1128,58 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ) /*-----------------------------------------------------------*/ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ) + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ) { /* The MQTT context is not used in this function. */ ( void ) pxMQTTContext; + ( void ) pxReasonCode; + ( void ) pxSendPropsBuffer; - if( ( pxPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) + /* Process incoming properties if available. */ + if( pxGetPropsBuffer != NULL ) + { + size_t xPropIndex = 0U; + uint8_t ucPropertyType = 0U; + MQTTUserProperty_t xUserProp; + + while( xPropIndex < pxGetPropsBuffer->currentIndex ) + { + if( MQTT_GetNextPropertyType( pxGetPropsBuffer, &xPropIndex, &ucPropertyType ) != MQTTSuccess ) + { + break; + } + + if( ucPropertyType == MQTT_USER_PROPERTY_ID ) + { + if( MQTTPropGet_UserProp( pxGetPropsBuffer, &xPropIndex, &xUserProp ) == MQTTSuccess ) + { + LogInfo( ( "User property received: key=%.*s, value=%.*s", + ( int ) xUserProp.keyLength, xUserProp.pKey, + ( int ) xUserProp.valueLength, xUserProp.pValue ) ); + } + } + else + { + if( MQTT_SkipNextProperty( pxGetPropsBuffer, &xPropIndex ) != MQTTSuccess ) + { + break; + } + } + } + } + + if( pxPacketInfo->type == MQTT_PACKET_TYPE_DISCONNECT ) + { + LogInfo( ( "Server-initiated disconnect. Reason code: 0x%02X.\r\n", + ( pxDeserializedInfo->pReasonCode != NULL ) ? + pxDeserializedInfo->pReasonCode->reasonCode[ 0 ] : 0U ) ); + } + else if( ( pxPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) { LogInfo( ( "PUBLISH received for packet id %u.\n\n", pxDeserializedInfo->packetIdentifier ) ); @@ -1046,6 +1189,8 @@ static void prvEventCallback( MQTTContext_t * pxMQTTContext, { prvMQTTProcessResponse( pxPacketInfo, pxDeserializedInfo->packetIdentifier ); } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj index 730f72e709f..4e15c9d09eb 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj @@ -96,6 +96,9 @@ xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dl + + + diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj.filters index 1770ea04fb4..08ba73f7589 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj.filters @@ -104,6 +104,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Network Transport Files\TCP Sockets Wrapper\ports diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/DemoTasks/KeepAliveMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/DemoTasks/KeepAliveMQTTExample.c index 95aa751c516..c76e35c0eaa 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/DemoTasks/KeepAliveMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/DemoTasks/KeepAliveMQTTExample.c @@ -129,7 +129,7 @@ /** * @brief Timeout for receiving CONNACK packet in milliseconds. */ -#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 1000U ) +#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 10000U ) /** * @brief The topic to subscribe and publish to in the example. @@ -366,9 +366,12 @@ static void prvPingRespTimerCallback( TimerHandle_t pxTimer ); * @param[in] pxPacketInfo Packet Info pointer for the incoming packet. * @param[in] pxDeserializedInfo Deserialized information from the incoming packet. */ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ); + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ); /*-----------------------------------------------------------*/ @@ -502,6 +505,11 @@ static MQTTPubAckInfo_t pOutgoingPublishRecords[ mqttexampleOUTGOING_PUBLISH_REC */ static MQTTPubAckInfo_t pIncomingPublishRecords[ mqttexampleINCOMING_PUBLISH_RECORD_LEN ]; +/** + * @brief Static buffer used to hold properties for outgoing ACK packets. + */ +static uint8_t ucAckPropsBuffer[ 500 ]; + /*-----------------------------------------------------------*/ /** @@ -663,7 +671,18 @@ static void prvMQTTDemoTask( void * pvParameters ) * sending the disconnect, the client must close the network connection. */ LogInfo( ( "Disconnecting the MQTT connection with %s.", democonfigMQTT_BROKER_ENDPOINT ) ); - xMQTTStatus = MQTT_Disconnect( &xMQTTContext ); + { + MQTTPropBuilder_t xDisconnectProps; + uint8_t ucDisconnectPropsBuf[ 200 ]; + MQTTSuccessFailReasonCode_t xReasonCode = MQTT_REASON_DISCONNECT_NORMAL_DISCONNECTION; + + xMQTTStatus = MQTTPropertyBuilder_Init( &xDisconnectProps, ucDisconnectPropsBuf, sizeof( ucDisconnectPropsBuf ) ); + configASSERT( xMQTTStatus == MQTTSuccess ); + xMQTTStatus = MQTTPropAdd_ReasonString( &xDisconnectProps, "Normal disconnect", strlen( "Normal disconnect" ), &( uint8_t ) { MQTT_PACKET_TYPE_DISCONNECT } ); + configASSERT( xMQTTStatus == MQTTSuccess ); + + xMQTTStatus = MQTT_Disconnect( &xMQTTContext, &xDisconnectProps, &xReasonCode ); + } configASSERT( xMQTTStatus == MQTTSuccess ); /* Stop the keep-alive timers for the next iteration. */ @@ -760,6 +779,8 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, MQTTConnectInfo_t xConnectInfo; bool xSessionPresent; TransportInterface_t xTransport; + MQTTPropBuilder_t xConnectProps; + uint8_t ucConnectPropsBuf[ 200 ]; /*** * For readability, error handling in this function is restricted to the use of @@ -779,7 +800,9 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, pOutgoingPublishRecords, mqttexampleOUTGOING_PUBLISH_RECORD_LEN, pIncomingPublishRecords, - mqttexampleINCOMING_PUBLISH_RECORD_LEN ); + mqttexampleINCOMING_PUBLISH_RECORD_LEN, + ucAckPropsBuffer, + sizeof( ucAckPropsBuffer ) ); configASSERT( xResult == MQTTSuccess ); /* Many fields not used in this demo so start with everything at 0. */ @@ -805,11 +828,21 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, /* Send MQTT CONNECT packet to broker. LWT is not used in this demo, so it * is passed as NULL. */ + xResult = MQTTPropertyBuilder_Init( &xConnectProps, ucConnectPropsBuf, sizeof( ucConnectPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTTPropAdd_SessionExpiry( &xConnectProps, 3600U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTTPropAdd_ReceiveMax( &xConnectProps, 10U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + MQTTPropAdd_MaxPacketSize( &xConnectProps, ( uint32_t ) mqttexampleSHARED_BUFFER_SIZE, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTT_Connect( pxMQTTContext, &xConnectInfo, NULL, mqttexampleCONNACK_RECV_TIMEOUT_MS, - &xSessionPresent ); + &xSessionPresent, + &xConnectProps, + NULL ); configASSERT( xResult == MQTTSuccess ); } /*-----------------------------------------------------------*/ @@ -844,6 +877,8 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) bool xFailedSubscribeToTopic = false; uint32_t ulTopicCount = 0U; uint16_t usNextRetryBackOff = 0U; + MQTTPropBuilder_t xSubProps; + uint8_t ucSubPropsBuf[ 200 ]; /* Some fields are not used by this demo so start with everything at 0. */ ( void ) memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); @@ -856,6 +891,9 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) xMQTTSubscription[ 0 ].qos = MQTTQoS1; xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC; xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC ); + xMQTTSubscription[ 0 ].noLocalOption = false; + xMQTTSubscription[ 0 ].retainAsPublishedOption = true; + xMQTTSubscription[ 0 ].retainHandlingOption = retainSendOnSub; /* Initialize context for backoff retry attempts if SUBSCRIBE request fails. */ BackoffAlgorithm_InitializeParams( &xRetryParams, @@ -873,10 +911,16 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) * from the broker. This demo uses QoS1 in Subscribe. Therefore, the publish * messages received from the broker will have QoS1. */ LogInfo( ( "Attempt to subscribe to the MQTT topic %s.", mqttexampleTOPIC ) ); + xResult = MQTTPropertyBuilder_Init( &xSubProps, ucSubPropsBuf, sizeof( ucSubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTTPropAdd_SubscriptionId( &xSubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_SUBSCRIBE } ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTT_Subscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usSubscribePacketIdentifier ); + usSubscribePacketIdentifier, + &xSubProps ); configASSERT( xResult == MQTTSuccess ); LogInfo( ( "SUBSCRIBE sent for topic %s to broker.\n\n", mqttexampleTOPIC ) ); @@ -955,6 +999,9 @@ static void prvMQTTPublishToTopic( MQTTContext_t * pxMQTTContext ) MQTTStatus_t xResult; MQTTPublishInfo_t xMQTTPublishInfo; BaseType_t xTimerStatus; + MQTTPropBuilder_t xPubProps; + uint8_t ucPubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; /*** * For readability, error handling in this function is restricted to the use of @@ -975,8 +1022,22 @@ static void prvMQTTPublishToTopic( MQTTContext_t * pxMQTTContext ) /* Get a unique packet id. */ usPublishPacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); + /* Build publish properties. */ + xResult = MQTTPropertyBuilder_Init( &xPubProps, ucPubPropsBuf, sizeof( ucPubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTTPropAdd_PayloadFormat( &xPubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTTPropAdd_MessageExpiry( &xPubProps, 300U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + xUserProp.pKey = "demo"; + xUserProp.keyLength = strlen( "demo" ); + xUserProp.pValue = "keep-alive"; + xUserProp.valueLength = strlen( "keep-alive" ); + xResult = MQTTPropAdd_UserProp( &xPubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + /* Send a PUBLISH packet. */ - xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier ); + xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier, &xPubProps ); configASSERT( xResult == MQTTSuccess ); /* When a PUBLISH packet has been sent, the keep-alive timer can be reset. */ @@ -990,6 +1051,9 @@ static void prvMQTTUnsubscribeFromTopic( MQTTContext_t * pxMQTTContext ) MQTTStatus_t xResult; MQTTSubscribeInfo_t xMQTTSubscription[ mqttexampleTOPIC_COUNT ]; BaseType_t xTimerStatus; + MQTTPropBuilder_t xUnsubProps; + uint8_t ucUnsubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; /* Some fields are not used by this demo, so start with everything at 0. */ ( void ) memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); @@ -1006,11 +1070,22 @@ static void prvMQTTUnsubscribeFromTopic( MQTTContext_t * pxMQTTContext ) /* Get the next unique packet identifier. */ usUnsubscribePacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); + /* Build unsubscribe properties. */ + xResult = MQTTPropertyBuilder_Init( &xUnsubProps, ucUnsubPropsBuf, sizeof( ucUnsubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + xUserProp.pKey = "reason"; + xUserProp.keyLength = strlen( "reason" ); + xUserProp.pValue = "demo-complete"; + xUserProp.valueLength = strlen( "demo-complete" ); + xResult = MQTTPropAdd_UserProp( &xUnsubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_UNSUBSCRIBE } ); + configASSERT( xResult == MQTTSuccess ); + /* Send the UNSUBSCRIBE packet. */ xResult = MQTT_Unsubscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usUnsubscribePacketIdentifier ); + usUnsubscribePacketIdentifier, + &xUnsubProps ); configASSERT( xResult == MQTTSuccess ); /* When an UNSUBSCRIBE packet has been sent, the keep-alive timer can be reset. */ @@ -1068,6 +1143,10 @@ static void prvMQTTProcessResponse( MQTTPacketInfo_t * pxIncomingPacket, LogInfo( ( "Ping Response successfully received." ) ); break; + case MQTT_PACKET_TYPE_DISCONNECT: + LogInfo( ( "Server initiated disconnect received." ) ); + break; + /* Any other packet type is invalid. */ default: LogWarn( ( "prvMQTTProcessResponse() called with unknown packet type:(%02X).", @@ -1142,21 +1221,66 @@ static void prvPingRespTimerCallback( TimerHandle_t pxTimer ) /*-----------------------------------------------------------*/ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ) + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ) { /* The MQTT context is not used for this demo. */ ( void ) pxMQTTContext; + ( void ) pxReasonCode; + ( void ) pxSendPropsBuffer; + + /* Process incoming properties if available. */ + if( pxGetPropsBuffer != NULL ) + { + size_t xPropIndex = 0U; + uint8_t ucPropertyType; + + while( xPropIndex < pxGetPropsBuffer->currentIndex ) + { + if( MQTT_GetNextPropertyType( pxGetPropsBuffer, &xPropIndex, &ucPropertyType ) != MQTTSuccess ) + { + break; + } + + if( ucPropertyType == MQTT_USER_PROPERTY_ID ) + { + MQTTUserProperty_t xUserProp; + + if( MQTTPropGet_UserProp( pxGetPropsBuffer, &xPropIndex, &xUserProp ) == MQTTSuccess ) + { + LogInfo( ( "Received user property: %.*s = %.*s", + ( int ) xUserProp.keyLength, xUserProp.pKey, + ( int ) xUserProp.valueLength, xUserProp.pValue ) ); + } + } + else + { + MQTT_SkipNextProperty( pxGetPropsBuffer, &xPropIndex ); + } + } + } if( ( pxPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) { prvMQTTProcessIncomingPublish( pxDeserializedInfo->pPublishInfo ); } + else if( pxPacketInfo->type == MQTT_PACKET_TYPE_DISCONNECT ) + { + LogInfo( ( "Server-initiated disconnect. Reason code: 0x%02X.", + ( pxDeserializedInfo->pReasonCode != NULL ) ? + pxDeserializedInfo->pReasonCode->reasonCode[ 0 ] : 0U ) ); + prvMQTTProcessResponse( pxPacketInfo, pxDeserializedInfo->packetIdentifier ); + } else { prvMQTTProcessResponse( pxPacketInfo, pxDeserializedInfo->packetIdentifier ); } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj index 7853aa7e3d9..a97bd6d038f 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj @@ -80,6 +80,9 @@ xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dl + + + diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj.filters index d784f4feba7..7f9d44b5ff4 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj.filters @@ -85,6 +85,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\backoff_algorithm diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/mqtt-agent-task.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/mqtt-agent-task.c index 2d88c9fa57d..856d4a551d4 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/mqtt-agent-task.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/mqtt-agent-task.c @@ -192,7 +192,7 @@ * @brief Timeout for receiving CONNACK after sending an MQTT CONNECT packet. * Defined in milliseconds. */ -#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 1000U ) +#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 10000U ) /** * @brief The maximum number of retries for network operation with server. @@ -529,7 +529,9 @@ static MQTTStatus_t prvMQTTInit( void ) prvGetTimeMs, prvIncomingPublishCallback, /* Context to pass into the callback. Passing the pointer to subscription array. */ - xGlobalSubscriptionList ); + xGlobalSubscriptionList, + NULL, + 0U ); return xReturn; } @@ -555,7 +557,7 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) * the MQTT broker. In a production device the identifier can be something * unique, such as a device serial number. */ xConnectInfo.pClientIdentifier = democonfigCLIENT_IDENTIFIER; - xConnectInfo.clientIdentifierLength = ( uint16_t ) strlen( democonfigCLIENT_IDENTIFIER ); + xConnectInfo.clientIdentifierLength = strlen( democonfigCLIENT_IDENTIFIER ); /* Set MQTT keep-alive period. It is the responsibility of the application * to ensure that the interval between Control Packets being sent does not @@ -567,11 +569,11 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) #if defined( democonfigUSE_AWS_IOT_CORE_BROKER ) && defined( democonfigCLIENT_USERNAME ) /* Append metrics string when connecting to AWS IoT Core with custom auth */ xConnectInfo.pUserName = democonfigCLIENT_USERNAME AWS_IOT_METRICS_STRING; - xConnectInfo.userNameLength = ( uint16_t ) strlen( democonfigCLIENT_USERNAME AWS_IOT_METRICS_STRING ); + xConnectInfo.userNameLength = strlen( democonfigCLIENT_USERNAME AWS_IOT_METRICS_STRING ); #elif defined( democonfigUSE_AWS_IOT_CORE_BROKER ) /* If no username is needed, only send the metrics string */ xConnectInfo.pUserName = AWS_IOT_METRICS_STRING; - xConnectInfo.userNameLength = ( uint16_t ) strlen( AWS_IOT_METRICS_STRING ); + xConnectInfo.userNameLength = strlen( AWS_IOT_METRICS_STRING ); /* Password for authentication is not used. */ xConnectInfo.pPassword = NULL; @@ -579,7 +581,7 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) #elif defined( democonfigCLIENT_USERNAME ) /* If not connecting to AWS IoT Core, send the username without modification. */ xConnectInfo.pUserName = democonfigCLIENT_USERNAME; - xConnectInfo.userNameLength = ( uint16_t ) strlen( democonfigCLIENT_USERNAME ); + xConnectInfo.userNameLength = strlen( democonfigCLIENT_USERNAME ); #endif /* defined( democonfigCLIENT_USERNAME ) */ /* Send MQTT CONNECT packet to broker. MQTT's Last Will and Testament feature @@ -588,7 +590,9 @@ static MQTTStatus_t prvMQTTConnect( bool xCleanSession ) &xConnectInfo, NULL, mqttexampleCONNACK_RECV_TIMEOUT_MS, - &xSessionPresent ); + &xSessionPresent, + NULL, + NULL ); LogInfo( ( "Session present: %d\n", xSessionPresent ) ); @@ -695,7 +699,7 @@ static void prvSubscriptionCommandCallback( void * pxCommandContext, /* Remove subscription callback for unsubscribe. */ removeSubscription( xGlobalSubscriptionList, pxSubscribeArgs->pSubscribeInfo[ lIndex ].pTopicFilter, - pxSubscribeArgs->pSubscribeInfo[ lIndex ].topicFilterLength ); + ( uint16_t ) pxSubscribeArgs->pSubscribeInfo[ lIndex ].topicFilterLength ); } } @@ -964,7 +968,7 @@ static void prvMQTTAgentTask( void * pvParameters ) else if( xMQTTStatus == MQTTSuccess ) { /* MQTTAgent_Terminate() was called, but MQTT was not disconnected. */ - xMQTTStatus = MQTT_Disconnect( &( xGlobalMqttAgentContext.mqttContext ) ); + xMQTTStatus = MQTT_Disconnect( &( xGlobalMqttAgentContext.mqttContext ), NULL, NULL ); configASSERT( xMQTTStatus == MQTTSuccess ); xNetworkResult = prvSocketDisconnect( &xNetworkContext ); configASSERT( xNetworkResult == pdPASS ); diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/simple_sub_pub_demo.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/simple_sub_pub_demo.c index 5eb6ff2d94b..85f9484b3c1 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/simple_sub_pub_demo.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/simple_sub_pub_demo.c @@ -277,7 +277,7 @@ static void prvSubscribeCommandCallback( void * pxCommandContext, * callback. */ xSubscriptionAdded = addSubscription( ( SubscriptionElement_t * ) xGlobalMqttAgentContext.pIncomingCallbackContext, pxSubscribeArgs->pSubscribeInfo->pTopicFilter, - pxSubscribeArgs->pSubscribeInfo->topicFilterLength, + ( uint16_t ) pxSubscribeArgs->pSubscribeInfo->topicFilterLength, prvIncomingPublishCallback, NULL ); @@ -363,10 +363,11 @@ static bool prvSubscribeToTopic( MQTTQoS_t xQoS, /* Complete the subscribe information. The topic string must persist for * duration of subscription! */ xSubscribeInfo.pTopicFilter = pcTopicFilter; - xSubscribeInfo.topicFilterLength = ( uint16_t ) strlen( pcTopicFilter ); + xSubscribeInfo.topicFilterLength = strlen( pcTopicFilter ); xSubscribeInfo.qos = xQoS; xSubscribeArgs.pSubscribeInfo = &xSubscribeInfo; xSubscribeArgs.numSubscriptions = 1; + xSubscribeArgs.pProperties = NULL; /* Complete an application defined context associated with this subscribe message. * This gets updated in the callback function so the variable must persist until @@ -433,6 +434,7 @@ static void prvSimpleSubscribePublishTask( void * pvParameters ) MQTTQoS_t xQoS; TickType_t xTicksToDelay; MQTTAgentCommandInfo_t xCommandParams = { 0 }; + MQTTAgentPublishArgs_t xPublishArgs = { 0 }; char * pcTopicBuffer = topicBuf[ ulTaskNumber ]; /* Have different tasks use different QoS. 0 and 1. 2 can also be used @@ -457,7 +459,7 @@ static void prvSimpleSubscribePublishTask( void * pvParameters ) memset( ( void * ) &xPublishInfo, 0x00, sizeof( xPublishInfo ) ); xPublishInfo.qos = xQoS; xPublishInfo.pTopicName = pcTopicBuffer; - xPublishInfo.topicNameLength = ( uint16_t ) strlen( pcTopicBuffer ); + xPublishInfo.topicNameLength = strlen( pcTopicBuffer ); xPublishInfo.pPayload = payloadBuf; /* Store the handler to this task in the command context so the callback @@ -481,7 +483,7 @@ static void prvSimpleSubscribePublishTask( void * pvParameters ) taskName, ( int ) ulValueToNotify ); - xPublishInfo.payloadLength = ( uint16_t ) strlen( payloadBuf ); + xPublishInfo.payloadLength = strlen( payloadBuf ); /* Also store the incrementing number in the command context so it can * be accessed by the callback that executes when the publish operation @@ -496,8 +498,11 @@ static void prvSimpleSubscribePublishTask( void * pvParameters ) * as it is to be checked against the value sent from the callback.. */ ulNotification = ~ulValueToNotify; + xPublishArgs.pPublishInfo = &xPublishInfo; + xPublishArgs.pProperties = NULL; + xCommandAdded = MQTTAgent_Publish( &xGlobalMqttAgentContext, - &xPublishInfo, + &xPublishArgs, &xCommandParams ); configASSERT( xCommandAdded == MQTTSuccess ); diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj index f549609f906..b000acccaf2 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj @@ -84,6 +84,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj.filters index 1dcc31d1b0a..f37a600ad09 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj.filters @@ -136,6 +136,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\backoff_algorithm diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/DemoTasks/MutualAuthMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/DemoTasks/MutualAuthMQTTExample.c index 625b793f45d..3fe8bec1fbe 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/DemoTasks/MutualAuthMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/DemoTasks/MutualAuthMQTTExample.c @@ -183,7 +183,7 @@ extern void vLoggingPrintf( const char * pcFormatString, /** * @brief Timeout for receiving CONNACK packet in milliseconds. */ -#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 1000U ) +#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 10000U ) /** * @brief The topic to subscribe and publish to in the example. @@ -408,9 +408,12 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ); * @param[in] pxPacketInfo Packet Info pointer for the incoming packet. * @param[in] pxDeserializedInfo Deserialized information from the incoming packet. */ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ); + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ); /** * @brief Call #MQTT_ProcessLoop in a loop for the duration of a timeout or @@ -502,6 +505,11 @@ static MQTTPubAckInfo_t pOutgoingPublishRecords[ mqttexampleOUTGOING_PUBLISH_REC */ static MQTTPubAckInfo_t pIncomingPublishRecords[ mqttexampleINCOMING_PUBLISH_RECORD_LEN ]; +/** + * @brief Static buffer used to hold properties for outgoing ACK packets. + */ +static uint8_t ucAckPropsBuffer[ 500 ]; + /*-----------------------------------------------------------*/ /* @@ -638,7 +646,19 @@ static void prvMQTTDemoTask( void * pvParameters ) * connection. */ LogInfo( ( "Disconnecting the MQTT connection with %s.\r\n", democonfigMQTT_BROKER_ENDPOINT ) ); - xMQTTStatus = MQTT_Disconnect( &xMQTTContext ); + { + MQTTPropBuilder_t xDisconnectProps; + uint8_t ucDisconnectPropsBuf[ 200 ]; + MQTTSuccessFailReasonCode_t xReasonCode = MQTT_REASON_DISCONNECT_NORMAL_DISCONNECTION; + + xMQTTStatus = MQTTPropertyBuilder_Init( &xDisconnectProps, ucDisconnectPropsBuf, sizeof( ucDisconnectPropsBuf ) ); + configASSERT( xMQTTStatus == MQTTSuccess ); + + xMQTTStatus = MQTTPropAdd_ReasonString( &xDisconnectProps, "Normal disconnect", 17, &( uint8_t ) { MQTT_PACKET_TYPE_DISCONNECT } ); + configASSERT( xMQTTStatus == MQTTSuccess ); + + xMQTTStatus = MQTT_Disconnect( &xMQTTContext, &xDisconnectProps, &xReasonCode ); + } configASSERT( xMQTTStatus == MQTTSuccess ); /* Close the network connection. */ @@ -799,7 +819,9 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, pOutgoingPublishRecords, mqttexampleOUTGOING_PUBLISH_RECORD_LEN, pIncomingPublishRecords, - mqttexampleINCOMING_PUBLISH_RECORD_LEN ); + mqttexampleINCOMING_PUBLISH_RECORD_LEN, + ucAckPropsBuffer, + sizeof( ucAckPropsBuffer ) ); configASSERT( xResult == MQTTSuccess ); /* Some fields are not used in this demo so start with everything at 0. */ @@ -851,11 +873,28 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, /* Send MQTT CONNECT packet to broker. LWT is not used in this demo, so it * is passed as NULL. */ - xResult = MQTT_Connect( pxMQTTContext, - &xConnectInfo, - NULL, - mqttexampleCONNACK_RECV_TIMEOUT_MS, - &xSessionPresent ); + { + MQTTPropBuilder_t xConnectProps; + uint8_t ucConnectPropsBuf[ 200 ]; + + xResult = MQTTPropertyBuilder_Init( &xConnectProps, ucConnectPropsBuf, sizeof( ucConnectPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + xResult = MQTTPropAdd_SessionExpiry( &xConnectProps, 3600U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + configASSERT( xResult == MQTTSuccess ); + + xResult = MQTTPropAdd_ReceiveMax( &xConnectProps, 10U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + MQTTPropAdd_MaxPacketSize( &xConnectProps, ( uint32_t ) democonfigNETWORK_BUFFER_SIZE, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + configASSERT( xResult == MQTTSuccess ); + + xResult = MQTT_Connect( pxMQTTContext, + &xConnectInfo, + NULL, + mqttexampleCONNACK_RECV_TIMEOUT_MS, + &xSessionPresent, + &xConnectProps, + NULL ); + } configASSERT( xResult == MQTTSuccess ); /* Successfully established and MQTT connection with the broker. */ @@ -904,6 +943,9 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) xMQTTSubscription[ 0 ].qos = MQTTQoS1; xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC; xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC ); + xMQTTSubscription[ 0 ].noLocalOption = false; + xMQTTSubscription[ 0 ].retainAsPublishedOption = true; + xMQTTSubscription[ 0 ].retainHandlingOption = retainSendOnSub; /* Initialize context for backoff retry attempts if SUBSCRIBE request fails. */ BackoffAlgorithm_InitializeParams( &xRetryParams, @@ -921,10 +963,22 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) * from the broker. This demo uses QOS0 in Subscribe, therefore, the Publish * messages received from the broker will have QOS0. */ LogInfo( ( "Attempt to subscribe to the MQTT topic %s.\r\n", mqttexampleTOPIC ) ); - xResult = MQTT_Subscribe( pxMQTTContext, - xMQTTSubscription, - sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usSubscribePacketIdentifier ); + { + MQTTPropBuilder_t xSubProps; + uint8_t ucSubPropsBuf[ 200 ]; + + xResult = MQTTPropertyBuilder_Init( &xSubProps, ucSubPropsBuf, sizeof( ucSubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + xResult = MQTTPropAdd_SubscriptionId( &xSubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_SUBSCRIBE } ); + configASSERT( xResult == MQTTSuccess ); + + xResult = MQTT_Subscribe( pxMQTTContext, + xMQTTSubscription, + sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), + usSubscribePacketIdentifier, + &xSubProps ); + } configASSERT( xResult == MQTTSuccess ); LogInfo( ( "SUBSCRIBE sent for topic %s to broker.\n\n", mqttexampleTOPIC ) ); @@ -1006,7 +1060,29 @@ static void prvMQTTPublishToTopic( MQTTContext_t * pxMQTTContext ) usPublishPacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); /* Send PUBLISH packet. Packet ID is not used for a QoS1 publish. */ - xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier ); + { + MQTTPropBuilder_t xPubProps; + uint8_t ucPubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; + + xResult = MQTTPropertyBuilder_Init( &xPubProps, ucPubPropsBuf, sizeof( ucPubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + xResult = MQTTPropAdd_PayloadFormat( &xPubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + + xResult = MQTTPropAdd_MessageExpiry( &xPubProps, 300U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + + xUserProp.pKey = "demo"; + xUserProp.keyLength = 4; + xUserProp.pValue = "mutual-auth"; + xUserProp.valueLength = 11; + xResult = MQTTPropAdd_UserProp( &xPubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + + xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier, &xPubProps ); + } configASSERT( xResult == MQTTSuccess ); } @@ -1033,10 +1109,27 @@ static void prvMQTTUnsubscribeFromTopic( MQTTContext_t * pxMQTTContext ) usUnsubscribePacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); /* Send UNSUBSCRIBE packet. */ - xResult = MQTT_Unsubscribe( pxMQTTContext, - xMQTTSubscription, - sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usUnsubscribePacketIdentifier ); + { + MQTTPropBuilder_t xUnsubProps; + uint8_t ucUnsubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; + + xResult = MQTTPropertyBuilder_Init( &xUnsubProps, ucUnsubPropsBuf, sizeof( ucUnsubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + xUserProp.pKey = "reason"; + xUserProp.keyLength = 6; + xUserProp.pValue = "demo-complete"; + xUserProp.valueLength = 13; + xResult = MQTTPropAdd_UserProp( &xUnsubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_UNSUBSCRIBE } ); + configASSERT( xResult == MQTTSuccess ); + + xResult = MQTT_Unsubscribe( pxMQTTContext, + xMQTTSubscription, + sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), + usUnsubscribePacketIdentifier, + &xUnsubProps ); + } configASSERT( xResult == MQTTSuccess ); } @@ -1091,6 +1184,10 @@ static void prvMQTTProcessResponse( MQTTPacketInfo_t * pxIncomingPacket, "callback when using MQTT_ProcessLoop.\n" ) ); break; + case MQTT_PACKET_TYPE_DISCONNECT: + LogInfo( ( "Server initiated disconnect received.\r\n" ) ); + break; + /* Any other packet type is invalid. */ default: LogWarn( ( "prvMQTTProcessResponse() called with unknown packet type:(%02X).\r\n", @@ -1128,14 +1225,66 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ) /*-----------------------------------------------------------*/ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ) + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ) { /* The MQTT context is not used for this demo. */ ( void ) pxMQTTContext; + ( void ) pxReasonCode; + ( void ) pxSendPropsBuffer; - if( ( pxPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) + /* Process incoming properties if available. */ + if( pxGetPropsBuffer != NULL ) + { + size_t xPropIndex = 0; + uint8_t ucPropertyType; + MQTTStatus_t xPropStatus; + + while( xPropIndex < pxGetPropsBuffer->currentIndex ) + { + xPropStatus = MQTT_GetNextPropertyType( pxGetPropsBuffer, &xPropIndex, &ucPropertyType ); + + if( xPropStatus != MQTTSuccess ) + { + break; + } + + if( ucPropertyType == MQTT_USER_PROPERTY_ID ) + { + MQTTUserProperty_t xUserProp; + + xPropStatus = MQTTPropGet_UserProp( pxGetPropsBuffer, &xPropIndex, &xUserProp ); + + if( xPropStatus == MQTTSuccess ) + { + LogInfo( ( "Received user property: key=%.*s, value=%.*s", + xUserProp.keyLength, xUserProp.pKey, + xUserProp.valueLength, xUserProp.pValue ) ); + } + } + else + { + xPropStatus = MQTT_SkipNextProperty( pxGetPropsBuffer, &xPropIndex ); + } + + if( xPropStatus != MQTTSuccess ) + { + break; + } + } + } + + if( pxPacketInfo->type == MQTT_PACKET_TYPE_DISCONNECT ) + { + LogInfo( ( "Server-initiated disconnect. Reason code: 0x%02X.\r\n", + ( pxDeserializedInfo->pReasonCode != NULL ) ? + pxDeserializedInfo->pReasonCode->reasonCode[ 0 ] : 0U ) ); + } + else if( ( pxPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) { prvMQTTProcessIncomingPublish( pxDeserializedInfo->pPublishInfo ); } @@ -1143,6 +1292,8 @@ static void prvEventCallback( MQTTContext_t * pxMQTTContext, { prvMQTTProcessResponse( pxPacketInfo, pxDeserializedInfo->packetIdentifier ); } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj index 9ad54e38868..e5b631eaf19 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj @@ -84,6 +84,9 @@ xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dl + + + diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj.filters index 11ec89b6c9d..7e375ed5b6e 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj.filters @@ -63,6 +63,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\Backoff Algorithm diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/DemoTasks/MutualAuthMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/DemoTasks/MutualAuthMQTTExample.c index f354064e5ad..909025105b4 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/DemoTasks/MutualAuthMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/DemoTasks/MutualAuthMQTTExample.c @@ -104,7 +104,7 @@ /** * @brief Timeout for receiving CONNACK packet in milliseconds. */ -#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 1000U ) +#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 10000U ) /** * @brief The topic to subscribe and publish to in the example. @@ -259,9 +259,12 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ); * @param[in] pxPacketInfo Packet Info pointer for the incoming packet. * @param[in] pxDeserializedInfo Deserialized information from the incoming packet. */ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ); + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ); /** * @brief TLS connect to endpoint democonfigMQTT_BROKER_ENDPOINT. @@ -343,6 +346,8 @@ static MQTTPubAckInfo_t pOutgoingPublishRecords[ mqttexampleOUTGOING_PUBLISH_REC */ static MQTTPubAckInfo_t pIncomingPublishRecords[ mqttexampleINCOMING_PUBLISH_RECORD_LEN ]; +static uint8_t ucAckPropsBuffer[ 500 ]; + /*-----------------------------------------------------------*/ /* @@ -480,7 +485,15 @@ static void prvMQTTDemoTask( void * pvParameters ) * There is no corresponding response for the disconnect packet. After sending * disconnect, client must close the network connection. */ LogInfo( ( "Disconnecting the MQTT connection with %s.\r\n", democonfigMQTT_BROKER_ENDPOINT ) ); - MQTT_Disconnect( &xMQTTContext ); + { + MQTTPropBuilder_t xDisconnectProps; + uint8_t ucDisconnectPropsBuf[ 200 ]; + MQTTSuccessFailReasonCode_t xReasonCode = MQTT_REASON_DISCONNECT_NORMAL_DISCONNECTION; + + MQTTPropertyBuilder_Init( &xDisconnectProps, ucDisconnectPropsBuf, sizeof( ucDisconnectPropsBuf ) ); + MQTTPropAdd_ReasonString( &xDisconnectProps, "Normal disconnect", ( uint16_t ) strlen( "Normal disconnect" ), &( uint8_t ) { MQTT_PACKET_TYPE_DISCONNECT } ); + MQTT_Disconnect( &xMQTTContext, &xDisconnectProps, &xReasonCode ); + } /* Close the network connection. */ TLS_FreeRTOS_Disconnect( &xNetworkContext ); @@ -536,6 +549,8 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, MQTTConnectInfo_t xConnectInfo; bool xSessionPresent; TransportInterface_t xTransport; + MQTTPropBuilder_t xConnectProps; + uint8_t ucConnectPropsBuf[ 200 ]; /*** * For readability, error handling in this function is restricted to the use of @@ -555,7 +570,9 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, pOutgoingPublishRecords, mqttexampleOUTGOING_PUBLISH_RECORD_LEN, pIncomingPublishRecords, - mqttexampleINCOMING_PUBLISH_RECORD_LEN ); + mqttexampleINCOMING_PUBLISH_RECORD_LEN, + ucAckPropsBuffer, + sizeof( ucAckPropsBuffer ) ); configASSERT( xResult == MQTTSuccess ); /* Some fields are not used in this demo so start with everything at 0. */ @@ -579,11 +596,18 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, /* Send MQTT CONNECT packet to broker. LWT is not used in this demo, so it * is passed as NULL. */ + MQTTPropertyBuilder_Init( &xConnectProps, ucConnectPropsBuf, sizeof( ucConnectPropsBuf ) ); + MQTTPropAdd_SessionExpiry( &xConnectProps, 3600U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + MQTTPropAdd_ReceiveMax( &xConnectProps, 10U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + MQTTPropAdd_MaxPacketSize( &xConnectProps, ( uint32_t ) democonfigNETWORK_BUFFER_SIZE, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + xResult = MQTT_Connect( pxMQTTContext, &xConnectInfo, NULL, mqttexampleCONNACK_RECV_TIMEOUT_MS, - &xSessionPresent ); + &xSessionPresent, + &xConnectProps, + NULL ); configASSERT( xResult == MQTTSuccess ); /* Successfully established and MQTT connection with the broker. */ @@ -595,6 +619,8 @@ static void prvMQTTSubscribeToTopic( MQTTContext_t * pxMQTTContext ) { MQTTStatus_t xResult; MQTTSubscribeInfo_t xMQTTSubscription[ 1 ]; + MQTTPropBuilder_t xSubProps; + uint8_t ucSubPropsBuf[ 200 ]; /*** * For readability, error handling in this function is restricted to the use of @@ -609,15 +635,23 @@ static void prvMQTTSubscribeToTopic( MQTTContext_t * pxMQTTContext ) xMQTTSubscription[ 0 ].qos = MQTTQoS1; xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC; xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC ); + xMQTTSubscription[ 0 ].noLocalOption = false; + xMQTTSubscription[ 0 ].retainAsPublishedOption = true; + xMQTTSubscription[ 0 ].retainHandlingOption = retainSendOnSub; /* Get a unique packet id. */ usSubscribePacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); + /* Build subscribe properties. */ + MQTTPropertyBuilder_Init( &xSubProps, ucSubPropsBuf, sizeof( ucSubPropsBuf ) ); + MQTTPropAdd_SubscriptionId( &xSubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_SUBSCRIBE } ); + /* Send SUBSCRIBE packet. */ xResult = MQTT_Subscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usSubscribePacketIdentifier ); + usSubscribePacketIdentifier, + &xSubProps ); configASSERT( xResult == MQTTSuccess ); } @@ -627,6 +661,9 @@ static void prvMQTTPublishToTopic( MQTTContext_t * pxMQTTContext ) { MQTTStatus_t xResult; MQTTPublishInfo_t xMQTTPublishInfo; + MQTTPropBuilder_t xPubProps; + uint8_t ucPubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; /*** @@ -648,8 +685,19 @@ static void prvMQTTPublishToTopic( MQTTContext_t * pxMQTTContext ) /* Get a unique packet id. */ usPublishPacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); + /* Build publish properties. */ + MQTTPropertyBuilder_Init( &xPubProps, ucPubPropsBuf, sizeof( ucPubPropsBuf ) ); + MQTTPropAdd_PayloadFormat( &xPubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + MQTTPropAdd_MessageExpiry( &xPubProps, 300U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + + xUserProp.pKey = "demo"; + xUserProp.keyLength = ( uint16_t ) strlen( "demo" ); + xUserProp.pValue = "mutual-auth-wolfssl"; + xUserProp.valueLength = ( uint16_t ) strlen( "mutual-auth-wolfssl" ); + MQTTPropAdd_UserProp( &xPubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + /* Send PUBLISH packet. Packet ID is not used for a QoS1 publish. */ - xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier ); + xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier, &xPubProps ); configASSERT( xResult == MQTTSuccess ); } @@ -659,6 +707,9 @@ static void prvMQTTUnsubscribeFromTopic( MQTTContext_t * pxMQTTContext ) { MQTTStatus_t xResult; MQTTSubscribeInfo_t xMQTTSubscription[ 1 ]; + MQTTPropBuilder_t xUnsubProps; + uint8_t ucUnsubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; /* Some fields are not used by this demo so start with everything at 0. */ memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); @@ -672,11 +723,21 @@ static void prvMQTTUnsubscribeFromTopic( MQTTContext_t * pxMQTTContext ) /* Make sure the packet id obtained is valid. */ configASSERT( usUnsubscribePacketIdentifier != 0 ); + /* Build unsubscribe properties. */ + MQTTPropertyBuilder_Init( &xUnsubProps, ucUnsubPropsBuf, sizeof( ucUnsubPropsBuf ) ); + + xUserProp.pKey = "reason"; + xUserProp.keyLength = ( uint16_t ) strlen( "reason" ); + xUserProp.pValue = "demo-complete"; + xUserProp.valueLength = ( uint16_t ) strlen( "demo-complete" ); + MQTTPropAdd_UserProp( &xUnsubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_UNSUBSCRIBE } ); + /* Send UNSUBSCRIBE packet. */ xResult = MQTT_Unsubscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usUnsubscribePacketIdentifier ); + usUnsubscribePacketIdentifier, + &xUnsubProps ); configASSERT( xResult == MQTTSuccess ); } @@ -709,6 +770,10 @@ static void prvMQTTProcessResponse( MQTTPacketInfo_t * pxIncomingPacket, LogInfo( ( "Ping Response successfully received.\r\n" ) ); break; + case MQTT_PACKET_TYPE_DISCONNECT: + LogInfo( ( "Server initiated disconnect received.\r\n" ) ); + break; + /* Any other packet type is invalid. */ default: LogWarn( ( "prvMQTTProcessResponse() called with unknown packet type:(%02X).\r\n", @@ -746,14 +811,47 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ) /*-----------------------------------------------------------*/ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ) + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ) { + uint8_t ucPropertyType; + size_t xCurrentIndex = 0; + MQTTUserProperty_t xUserProp; + /* The MQTT context is not used for this demo. */ ( void ) pxMQTTContext; + ( void ) pxReasonCode; + ( void ) pxSendPropsBuffer; - if( ( pxPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) + /* Iterate through incoming properties if available. */ + if( pxGetPropsBuffer != NULL ) + { + while( MQTT_GetNextPropertyType( pxGetPropsBuffer, &xCurrentIndex, &ucPropertyType ) == MQTTSuccess ) + { + if( ucPropertyType == MQTT_USER_PROPERTY_ID ) + { + MQTTPropGet_UserProp( pxGetPropsBuffer, &xCurrentIndex, &xUserProp ); + LogInfo( ( "Received user property: key=%.*s value=%.*s\r\n", + xUserProp.keyLength, xUserProp.pKey, + xUserProp.valueLength, xUserProp.pValue ) ); + } + else + { + MQTT_SkipNextProperty( pxGetPropsBuffer, &xCurrentIndex ); + } + } + } + + if( pxPacketInfo->type == MQTT_PACKET_TYPE_DISCONNECT ) + { + LogInfo( ( "Server initiated disconnect. Reason code: 0x%02X\r\n", + ( pxDeserializedInfo->pReasonCode != NULL ) ? pxDeserializedInfo->pReasonCode->reasonCode[ 0 ] : 0U ) ); + } + else if( ( pxPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) { prvMQTTProcessIncomingPublish( pxDeserializedInfo->pPublishInfo ); } @@ -761,6 +859,8 @@ static void prvEventCallback( MQTTContext_t * pxMQTTContext, { prvMQTTProcessResponse( pxPacketInfo, pxDeserializedInfo->packetIdentifier ); } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj index ab1b3d2517b..919a5e68442 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj @@ -158,6 +158,9 @@ xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dl + + + diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj.filters index 1781be7ab43..ecbee1e65c2 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj.filters @@ -321,6 +321,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Network Transport Files\TCP Sockets Wrapper\ports diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/DemoTasks/PlaintextMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/DemoTasks/PlaintextMQTTExample.c index 58685a298d5..d7f12d31d0a 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/DemoTasks/PlaintextMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/DemoTasks/PlaintextMQTTExample.c @@ -118,7 +118,7 @@ /** * @brief Timeout for receiving CONNACK packet in milliseconds. */ -#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 1000U ) +#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 10000U ) /** * @brief The prefix to the topic(s) subscribe(d) to and publish(ed) to in the example. @@ -320,9 +320,12 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ); * @param[in] pxPacketInfo Packet Info pointer for the incoming packet. * @param[in] pxDeserializedInfo Deserialized information from the incoming packet. */ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ); + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ); /** * @brief Call #MQTT_ProcessLoop in a loop for the duration of a timeout or @@ -416,6 +419,11 @@ static MQTTPubAckInfo_t pOutgoingPublishRecords[ mqttexampleOUTGOING_PUBLISH_REC */ static MQTTPubAckInfo_t pIncomingPublishRecords[ mqttexampleINCOMING_PUBLISH_RECORD_LEN ]; +/** + * @brief Static buffer used to store properties for outgoing publish ACK packets. + */ +static uint8_t ucAckPropsBuffer[ 500 ]; + /*-----------------------------------------------------------*/ /* @@ -555,7 +563,18 @@ static void prvMQTTDemoTask( void * pvParameters ) * There is no corresponding response expected from the broker. After sending the * disconnect request, the client must close the network connection. */ LogInfo( ( "Disconnecting the MQTT connection with %s.\r\n", democonfigMQTT_BROKER_ENDPOINT ) ); - xMQTTStatus = MQTT_Disconnect( &xMQTTContext ); + { + MQTTPropBuilder_t xDisconnectProps; + uint8_t ucDisconnectPropsBuf[ 200 ]; + MQTTSuccessFailReasonCode_t xReasonCode = MQTT_REASON_DISCONNECT_NORMAL_DISCONNECTION; + + xMQTTStatus = MQTTPropertyBuilder_Init( &xDisconnectProps, ucDisconnectPropsBuf, sizeof( ucDisconnectPropsBuf ) ); + configASSERT( xMQTTStatus == MQTTSuccess ); + xMQTTStatus = MQTTPropAdd_ReasonString( &xDisconnectProps, "Normal disconnect", strlen( "Normal disconnect" ), &( uint8_t ) { MQTT_PACKET_TYPE_DISCONNECT } ); + configASSERT( xMQTTStatus == MQTTSuccess ); + + xMQTTStatus = MQTT_Disconnect( &xMQTTContext, &xDisconnectProps, &xReasonCode ); + } configASSERT( xMQTTStatus == MQTTSuccess ); /* Close the network connection. */ @@ -642,6 +661,8 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, MQTTConnectInfo_t xConnectInfo; bool xSessionPresent; TransportInterface_t xTransport; + MQTTPropBuilder_t xConnectProps; + uint8_t ucConnectPropsBuf[ 200 ]; /*** * For readability, error handling in this function is restricted to the use of @@ -661,7 +682,9 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, pOutgoingPublishRecords, mqttexampleOUTGOING_PUBLISH_RECORD_LEN, pIncomingPublishRecords, - mqttexampleINCOMING_PUBLISH_RECORD_LEN ); + mqttexampleINCOMING_PUBLISH_RECORD_LEN, + ucAckPropsBuffer, + sizeof( ucAckPropsBuffer ) ); configASSERT( xResult == MQTTSuccess ); /* Some fields are not used in this demo so start with everything at 0. */ @@ -685,11 +708,21 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, /* Send MQTT CONNECT packet to broker. LWT is not used in this demo, so it * is passed as NULL. */ + xResult = MQTTPropertyBuilder_Init( &xConnectProps, ucConnectPropsBuf, sizeof( ucConnectPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTTPropAdd_SessionExpiry( &xConnectProps, 3600U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTTPropAdd_ReceiveMax( &xConnectProps, 10U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + MQTTPropAdd_MaxPacketSize( &xConnectProps, ( uint32_t ) democonfigNETWORK_BUFFER_SIZE, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTT_Connect( pxMQTTContext, &xConnectInfo, NULL, mqttexampleCONNACK_RECV_TIMEOUT_MS, - &xSessionPresent ); + &xSessionPresent, + &xConnectProps, + NULL ); configASSERT( xResult == MQTTSuccess ); /* Successfully established and MQTT connection with the broker. */ @@ -726,6 +759,8 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) MQTTSubscribeInfo_t xMQTTSubscription[ mqttexampleTOPIC_COUNT ]; bool xFailedSubscribeToTopic = false; uint32_t ulTopicCount = 0U; + MQTTPropBuilder_t xSubProps; + uint8_t ucSubPropsBuf[ 200 ]; /* Some fields not used by this demo so start with everything at 0. */ ( void ) memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); @@ -739,6 +774,9 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) xMQTTSubscription[ ulTopicCount ].qos = MQTTQoS2; xMQTTSubscription[ ulTopicCount ].pTopicFilter = xTopicFilterContext[ ulTopicCount ].pcTopicFilter; xMQTTSubscription[ ulTopicCount ].topicFilterLength = ( uint16_t ) strlen( xTopicFilterContext[ ulTopicCount ].pcTopicFilter ); + xMQTTSubscription[ ulTopicCount ].noLocalOption = false; + xMQTTSubscription[ ulTopicCount ].retainAsPublishedOption = true; + xMQTTSubscription[ ulTopicCount ].retainHandlingOption = retainSendOnSub; } /* Initialize context for backoff retry attempts if SUBSCRIBE request fails. */ @@ -756,10 +794,16 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) * will expect all the messages it sends to the broker to be sent back to it * from the broker. This demo uses QOS2 in Subscribe, therefore, the Publish * messages received from the broker will have QOS2. */ + xResult = MQTTPropertyBuilder_Init( &xSubProps, ucSubPropsBuf, sizeof( ucSubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTTPropAdd_SubscriptionId( &xSubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_SUBSCRIBE } ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTT_Subscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usSubscribePacketIdentifier ); + usSubscribePacketIdentifier, + &xSubProps ); configASSERT( xResult == MQTTSuccess ); for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) @@ -825,6 +869,9 @@ static void prvMQTTPublishToTopics( MQTTContext_t * pxMQTTContext ) MQTTStatus_t xResult; MQTTPublishInfo_t xMQTTPublishInfo; uint32_t ulTopicCount; + MQTTPropBuilder_t xPubProps; + uint8_t ucPubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; /*** * For readability, error handling in this function is restricted to the use of @@ -833,6 +880,21 @@ static void prvMQTTPublishToTopics( MQTTContext_t * pxMQTTContext ) for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { + /* Re-initialize the property builder for each publish. */ + xResult = MQTTPropertyBuilder_Init( &xPubProps, ucPubPropsBuf, sizeof( ucPubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTTPropAdd_PayloadFormat( &xPubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTTPropAdd_MessageExpiry( &xPubProps, 300U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + + xUserProp.pKey = "demo"; + xUserProp.keyLength = strlen( "demo" ); + xUserProp.pValue = "plaintext"; + xUserProp.valueLength = strlen( "plaintext" ); + xResult = MQTTPropAdd_UserProp( &xPubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + /* Some fields are not used by this demo so start with everything at 0. */ ( void ) memset( ( void * ) &xMQTTPublishInfo, 0x00, sizeof( xMQTTPublishInfo ) ); @@ -849,7 +911,7 @@ static void prvMQTTPublishToTopics( MQTTContext_t * pxMQTTContext ) LogInfo( ( "Publishing to the MQTT topic %s.\r\n", xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) ); /* Send PUBLISH packet. */ - xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier ); + xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier, &xPubProps ); configASSERT( xResult == MQTTSuccess ); } } @@ -860,6 +922,9 @@ static void prvMQTTUnsubscribeFromTopics( MQTTContext_t * pxMQTTContext ) MQTTStatus_t xResult; MQTTSubscribeInfo_t xMQTTSubscription[ mqttexampleTOPIC_COUNT ]; uint32_t ulTopicCount; + MQTTPropBuilder_t xUnsubProps; + uint8_t ucUnsubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; /* Some fields are not used by this demo so start with everything at 0. */ memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); @@ -880,10 +945,21 @@ static void prvMQTTUnsubscribeFromTopics( MQTTContext_t * pxMQTTContext ) configASSERT( usUnsubscribePacketIdentifier != 0 ); /* Send UNSUBSCRIBE packet. */ + xResult = MQTTPropertyBuilder_Init( &xUnsubProps, ucUnsubPropsBuf, sizeof( ucUnsubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + xUserProp.pKey = "reason"; + xUserProp.keyLength = strlen( "reason" ); + xUserProp.pValue = "demo-complete"; + xUserProp.valueLength = strlen( "demo-complete" ); + xResult = MQTTPropAdd_UserProp( &xUnsubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_UNSUBSCRIBE } ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTT_Unsubscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usUnsubscribePacketIdentifier ); + usUnsubscribePacketIdentifier, + &xUnsubProps ); configASSERT( xResult == MQTTSuccess ); } @@ -959,6 +1035,10 @@ static void prvMQTTProcessResponse( MQTTPacketInfo_t * pxIncomingPacket, usPacketId ) ); break; + case MQTT_PACKET_TYPE_DISCONNECT: + LogInfo( ( "Server initiated disconnect received.\r\n" ) ); + break; + /* Any other packet type is invalid. */ default: LogWarn( ( "prvMQTTProcessResponse() called with unknown packet type:(%02X).\r\n", @@ -1013,12 +1093,22 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ) /*-----------------------------------------------------------*/ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ) + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ) { + uint8_t ucPropertyType; + size_t ulPropIndex; + MQTTUserProperty_t xUserProp; + MQTTStatus_t xPropStatus; + /* The MQTT context is not used in this function. */ ( void ) pxMQTTContext; + ( void ) pxReasonCode; + ( void ) pxSendPropsBuffer; if( ( pxPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) { @@ -1026,10 +1116,49 @@ static void prvEventCallback( MQTTContext_t * pxMQTTContext, pxDeserializedInfo->packetIdentifier ) ); prvMQTTProcessIncomingPublish( pxDeserializedInfo->pPublishInfo ); } + else if( pxPacketInfo->type == MQTT_PACKET_TYPE_DISCONNECT ) + { + LogInfo( ( "Server-initiated DISCONNECT received. Reason code: 0x%02X.\r\n", + ( pxDeserializedInfo->pReasonCode != NULL ) ? pxDeserializedInfo->pReasonCode->reasonCode[ 0 ] : 0U ) ); + } else { prvMQTTProcessResponse( pxPacketInfo, pxDeserializedInfo->packetIdentifier ); } + + /* Iterate through incoming properties if available. */ + if( pxGetPropsBuffer != NULL ) + { + ulPropIndex = 0; + + while( ulPropIndex < pxGetPropsBuffer->currentIndex ) + { + xPropStatus = MQTT_GetNextPropertyType( pxGetPropsBuffer, &ulPropIndex, &ucPropertyType ); + + if( xPropStatus != MQTTSuccess ) + { + break; + } + + if( ucPropertyType == MQTT_USER_PROPERTY_ID ) + { + xPropStatus = MQTTPropGet_UserProp( pxGetPropsBuffer, &ulPropIndex, &xUserProp ); + + if( xPropStatus == MQTTSuccess ) + { + LogInfo( ( "User Property: key=%.*s, value=%.*s", + ( int ) xUserProp.keyLength, xUserProp.pKey, + ( int ) xUserProp.valueLength, xUserProp.pValue ) ); + } + } + else + { + MQTT_SkipNextProperty( pxGetPropsBuffer, &ulPropIndex ); + } + } + } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj index 78c30175778..6e8e8e64810 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj @@ -84,6 +84,9 @@ xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dl + + + diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj.filters index aad51bb98b2..28f8894d74d 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj.filters @@ -63,6 +63,15 @@ Libraries\coreMQTT + + Libraries\coreMQTT + + + Libraries\coreMQTT + + + Libraries\coreMQTT + Libraries\Backoff Algorithm diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/DemoTasks/SerializerMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/DemoTasks/SerializerMQTTExample.c index 9652742d107..0203cbf79dc 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/DemoTasks/SerializerMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/DemoTasks/SerializerMQTTExample.c @@ -376,6 +376,12 @@ const static MQTTFixedBuffer_t xBuffer = .size = mqttexampleSHARED_BUFFER_SIZE }; +/** + * @brief Connection properties received from the broker in CONNACK. + * Passed to MQTT_DeserializeAck for subsequent ACK packets. + */ +static MQTTConnectionProperties_t xConnectionProperties; + /*-----------------------------------------------------------*/ /** @@ -708,14 +714,15 @@ static Socket_t prvConnectToServerWithBackoffRetries() static void prvCreateMQTTConnectionWithBroker( Socket_t xMQTTSocket ) { BaseType_t xStatus; - size_t xRemainingLength; - size_t xPacketSize; + uint32_t xRemainingLength; + uint32_t xPacketSize; MQTTStatus_t xResult; MQTTPacketInfo_t xIncomingPacket; MQTTConnectInfo_t xConnectInfo; - uint16_t usPacketId; bool xSessionPresent; NetworkContext_t xNetworkContext; + MQTTPropBuilder_t xConnectProps; + uint8_t ucConnectPropsBuf[ 200 ]; /*** * For readability, error handling in this function is restricted to the use of @@ -742,9 +749,24 @@ static void prvCreateMQTTConnectionWithBroker( Socket_t xMQTTSocket ) * In the absence of sending any other control packets, the client MUST send a PINGREQ Packet. */ xConnectInfo.keepAliveSeconds = mqttexampleKEEP_ALIVE_TIMEOUT_SECONDS; + /* Initialize MQTT v5 connect properties. */ + xResult = MQTTPropertyBuilder_Init( &xConnectProps, ucConnectPropsBuf, sizeof( ucConnectPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + /* Set session expiry interval to 3600 seconds. */ + xResult = MQTTPropAdd_SessionExpiry( &xConnectProps, 3600U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + configASSERT( xResult == MQTTSuccess ); + + /* Set receive maximum to 10. */ + xResult = MQTTPropAdd_ReceiveMax( &xConnectProps, 10U, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + MQTTPropAdd_MaxPacketSize( &xConnectProps, ( uint32_t ) mqttexampleSHARED_BUFFER_SIZE, &( uint8_t ) { MQTT_PACKET_TYPE_CONNECT } ); + configASSERT( xResult == MQTTSuccess ); + /* Get size requirement for the connect packet. * Last Will and Testament is not used in this demo. It is passed as NULL. */ xResult = MQTT_GetConnectPacketSize( &xConnectInfo, + NULL, + &xConnectProps, NULL, &xRemainingLength, &xPacketSize ); @@ -755,6 +777,8 @@ static void prvCreateMQTTConnectionWithBroker( Socket_t xMQTTSocket ) /* Serialize MQTT connect packet into the provided buffer. */ xResult = MQTT_SerializeConnect( &xConnectInfo, + NULL, + &xConnectProps, NULL, xRemainingLength, &xBuffer ); @@ -793,9 +817,12 @@ static void prvCreateMQTTConnectionWithBroker( Socket_t xMQTTSocket ) configASSERT( xStatus == ( BaseType_t ) xIncomingPacket.remainingLength ); xIncomingPacket.pRemainingData = xBuffer.pBuffer; - xResult = MQTT_DeserializeAck( &xIncomingPacket, - &usPacketId, - &xSessionPresent ); + xResult = MQTT_InitConnect( &xConnectionProperties ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTT_DeserializeConnAck( &xIncomingPacket, + &xSessionPresent, + NULL, + &xConnectionProperties ); /* Log this convenient demo information before asserting if the result is * successful. */ @@ -811,10 +838,12 @@ static void prvCreateMQTTConnectionWithBroker( Socket_t xMQTTSocket ) static void prvMQTTSubscribeToTopic( Socket_t xMQTTSocket ) { MQTTStatus_t xResult; - size_t xRemainingLength; - size_t xPacketSize; + uint32_t xRemainingLength; + uint32_t xPacketSize; BaseType_t xStatus; MQTTSubscribeInfo_t xMQTTSubscription[ mqttexampleTOPIC_COUNT ]; + MQTTPropBuilder_t xSubProps; + uint8_t ucSubPropsBuf[ 200 ]; /* Some fields not used by this demo so start with everything at 0. */ ( void ) memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); @@ -824,16 +853,28 @@ static void prvMQTTSubscribeToTopic( Socket_t xMQTTSocket ) xMQTTSubscription[ 0 ].qos = MQTTQoS0; xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC; xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC ); + xMQTTSubscription[ 0 ].noLocalOption = false; + xMQTTSubscription[ 0 ].retainAsPublishedOption = true; + xMQTTSubscription[ 0 ].retainHandlingOption = retainSendOnSub; /*** * For readability, error handling in this function is restricted to the use of * asserts(). ***/ + /* Initialize MQTT v5 subscribe properties. */ + xResult = MQTTPropertyBuilder_Init( &xSubProps, ucSubPropsBuf, sizeof( ucSubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + /* Add subscription identifier. */ + xResult = MQTTPropAdd_SubscriptionId( &xSubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_SUBSCRIBE } ); + configASSERT( xResult == MQTTSuccess ); + xResult = MQTT_GetSubscribePacketSize( xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), + &xSubProps, &xRemainingLength, - &xPacketSize ); + &xPacketSize, ( uint32_t ) mqttexampleSHARED_BUFFER_SIZE ); /* Make sure the packet size is less than static buffer size. */ configASSERT( xResult == MQTTSuccess ); @@ -847,6 +888,7 @@ static void prvMQTTSubscribeToTopic( Socket_t xMQTTSocket ) /* Serialize subscribe into statically allocated ucSharedBuffer. */ xResult = MQTT_SerializeSubscribe( xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), + &xSubProps, usSubscribePacketIdentifier, xRemainingLength, &xBuffer ); @@ -983,10 +1025,13 @@ static void prvMQTTPublishToTopic( Socket_t xMQTTSocket ) { MQTTStatus_t xResult; MQTTPublishInfo_t xMQTTPublishInfo; - size_t xRemainingLength; - size_t xPacketSize; + uint32_t xRemainingLength; + uint32_t xPacketSize; size_t xHeaderSize; BaseType_t xStatus; + MQTTPropBuilder_t xPubProps; + uint8_t ucPubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; /*** * For readability, error handling in this function is restricted to the use of @@ -1004,10 +1049,31 @@ static void prvMQTTPublishToTopic( Socket_t xMQTTSocket ) xMQTTPublishInfo.pPayload = mqttexampleMESSAGE; xMQTTPublishInfo.payloadLength = strlen( mqttexampleMESSAGE ); + /* Initialize MQTT v5 publish properties. */ + xResult = MQTTPropertyBuilder_Init( &xPubProps, ucPubPropsBuf, sizeof( ucPubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + /* Set payload format indicator to UTF-8. */ + xResult = MQTTPropAdd_PayloadFormat( &xPubProps, 1U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + + /* Set message expiry interval to 300 seconds. */ + xResult = MQTTPropAdd_MessageExpiry( &xPubProps, 300U, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + + /* Add a user property. */ + xUserProp.pKey = "demo"; + xUserProp.keyLength = 4U; + xUserProp.pValue = "serializer"; + xUserProp.valueLength = 10U; + xResult = MQTTPropAdd_UserProp( &xPubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_PUBLISH } ); + configASSERT( xResult == MQTTSuccess ); + /* Find out length of Publish packet size. */ xResult = MQTT_GetPublishPacketSize( &xMQTTPublishInfo, + &xPubProps, &xRemainingLength, - &xPacketSize ); + &xPacketSize, ( uint32_t ) mqttexampleSHARED_BUFFER_SIZE ); configASSERT( xResult == MQTTSuccess ); /* Make sure the packet size is less than static buffer size. */ @@ -1017,6 +1083,7 @@ static void prvMQTTPublishToTopic( Socket_t xMQTTSocket ) * be sent directly in order to avoid copying it into the buffer. * QOS0 does not make use of packet identifier, therefore value of 0 is used */ xResult = MQTT_SerializePublishHeader( &xMQTTPublishInfo, + &xPubProps, 0, xRemainingLength, &xBuffer, @@ -1042,10 +1109,13 @@ static void prvMQTTPublishToTopic( Socket_t xMQTTSocket ) static void prvMQTTUnsubscribeFromTopic( Socket_t xMQTTSocket ) { MQTTStatus_t xResult; - size_t xRemainingLength; - size_t xPacketSize; + uint32_t xRemainingLength; + uint32_t xPacketSize; BaseType_t xStatus; MQTTSubscribeInfo_t xMQTTSubscription[ 1 ]; + MQTTPropBuilder_t xUnsubProps; + uint8_t ucUnsubPropsBuf[ 200 ]; + MQTTUserProperty_t xUserProp; /* Some fields not used by this demo so start with everything at 0. */ ( void ) memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); @@ -1056,11 +1126,23 @@ static void prvMQTTUnsubscribeFromTopic( Socket_t xMQTTSocket ) xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC; xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC ); + /* Initialize MQTT v5 unsubscribe properties. */ + xResult = MQTTPropertyBuilder_Init( &xUnsubProps, ucUnsubPropsBuf, sizeof( ucUnsubPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + /* Add a user property indicating reason for unsubscribe. */ + xUserProp.pKey = "reason"; + xUserProp.keyLength = 6U; + xUserProp.pValue = "demo-complete"; + xUserProp.valueLength = 13U; + xResult = MQTTPropAdd_UserProp( &xUnsubProps, &xUserProp, &( uint8_t ) { MQTT_PACKET_TYPE_DISCONNECT } ); + configASSERT( xResult == MQTTSuccess ); xResult = MQTT_GetUnsubscribePacketSize( xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), + &xUnsubProps, &xRemainingLength, - &xPacketSize ); + &xPacketSize, ( uint32_t ) mqttexampleSHARED_BUFFER_SIZE ); configASSERT( xResult == MQTTSuccess ); /* Make sure the packet size is less than static buffer size */ configASSERT( xPacketSize < mqttexampleSHARED_BUFFER_SIZE ); @@ -1072,6 +1154,7 @@ static void prvMQTTUnsubscribeFromTopic( Socket_t xMQTTSocket ) xResult = MQTT_SerializeUnsubscribe( xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), + &xUnsubProps, usUnsubscribePacketIdentifier, xRemainingLength, &xBuffer ); @@ -1111,14 +1194,33 @@ static void prvMQTTDisconnect( Socket_t xMQTTSocket ) { MQTTStatus_t xResult; BaseType_t xStatus; - size_t xPacketSize; + uint32_t xRemainingLength; + uint32_t xPacketSize; + MQTTPropBuilder_t xDisconnectProps; + uint8_t ucDisconnectPropsBuf[ 200 ]; + MQTTSuccessFailReasonCode_t xReasonCode = MQTT_REASON_DISCONNECT_NORMAL_DISCONNECTION; + + /* Initialize MQTT v5 disconnect properties. */ + xResult = MQTTPropertyBuilder_Init( &xDisconnectProps, ucDisconnectPropsBuf, sizeof( ucDisconnectPropsBuf ) ); + configASSERT( xResult == MQTTSuccess ); + + /* Add reason string for disconnect. */ + xResult = MQTTPropAdd_ReasonString( &xDisconnectProps, "Normal disconnect", 17U, &( uint8_t ) { MQTT_PACKET_TYPE_DISCONNECT } ); + configASSERT( xResult == MQTTSuccess ); /* Calculate DISCONNECT packet size. */ - xResult = MQTT_GetDisconnectPacketSize( &xPacketSize ); + xResult = MQTT_GetDisconnectPacketSize( &xDisconnectProps, + &xRemainingLength, + &xPacketSize, + ( uint32_t ) mqttexampleSHARED_BUFFER_SIZE, + &xReasonCode ); configASSERT( xResult == MQTTSuccess ); configASSERT( xPacketSize <= mqttexampleSHARED_BUFFER_SIZE ); - xResult = MQTT_SerializeDisconnect( &xBuffer ); + xResult = MQTT_SerializeDisconnect( &xDisconnectProps, + &xReasonCode, + xRemainingLength, + &xBuffer ); configASSERT( xResult == MQTTSuccess ); xStatus = FreeRTOS_send( xMQTTSocket, @@ -1165,6 +1267,10 @@ static void prvMQTTProcessResponse( MQTTPacketInfo_t * pxIncomingPacket, LogInfo( ( "Ping Response successfully received." ) ); break; + case MQTT_PACKET_TYPE_DISCONNECT: + LogInfo( ( "Server initiated disconnect received." ) ); + break; + /* Any other packet type is invalid. */ default: LogWarn( ( "prvMQTTProcessResponse() called with unknown packet type:(%02X).", @@ -1212,6 +1318,7 @@ static void prvMQTTProcessIncomingPacket( Socket_t xMQTTSocket ) MQTTPublishInfo_t xPublishInfo; uint16_t usPacketId; NetworkContext_t xNetworkContext; + MQTTReasonCodeInfo_t xReasonCodeInfo; /*** * For readability, error handling in this function is restricted to the use of @@ -1249,7 +1356,7 @@ static void prvMQTTProcessIncomingPacket( Socket_t xMQTTSocket ) /* Check if the incoming packet is a publish packet. */ if( ( xIncomingPacket.type & 0xf0 ) == MQTT_PACKET_TYPE_PUBLISH ) { - xResult = MQTT_DeserializePublish( &xIncomingPacket, &usPacketId, &xPublishInfo ); + xResult = MQTT_DeserializePublish( &xIncomingPacket, &usPacketId, &xPublishInfo, NULL, ( uint32_t ) mqttexampleSHARED_BUFFER_SIZE, 0U ); configASSERT( xResult == MQTTSuccess ); /* Process incoming Publish message. */ @@ -1262,7 +1369,7 @@ static void prvMQTTProcessIncomingPacket( Socket_t xMQTTSocket ) * packet. Session present is only valid for a CONNACK. CONNACK is not * expected to be received here. Hence pass NULL for pointer to session * present. */ - xResult = MQTT_DeserializeAck( &xIncomingPacket, &usPacketId, NULL ); + xResult = MQTT_DeserializeAck( &xIncomingPacket, &usPacketId, &xReasonCodeInfo, NULL, &xConnectionProperties ); configASSERT( xResult == MQTTSuccess ); if( xIncomingPacket.type == MQTT_PACKET_TYPE_SUBACK ) diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj index c056dba81a7..7a5ed7d339e 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj @@ -82,6 +82,9 @@ xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dl + + + diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj.filters index 3d8d8c04f43..5c27466bf81 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj.filters @@ -57,6 +57,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\Backoff Algorithm diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/PKCS11_Mqtt_MutualAuthDemo.c b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/PKCS11_Mqtt_MutualAuthDemo.c index c403a6396eb..0f22f765f5f 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/PKCS11_Mqtt_MutualAuthDemo.c +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/PKCS11_Mqtt_MutualAuthDemo.c @@ -107,7 +107,7 @@ /** * @brief Timeout for receiving CONNACK packet in milliseconds. */ -#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 1000U ) +#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 10000U ) /** * @brief The topic to subscribe and publish to in the example. @@ -276,9 +276,12 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ); * @param[in] pxPacketInfo Packet Info pointer for the incoming packet. * @param[in] pxDeserializedInfo Deserialized information from the incoming packet. */ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ); + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ); /** * @brief TLS connect to endpoint democonfigMQTT_BROKER_ENDPOINT. @@ -503,7 +506,7 @@ static void prvMQTTDemoTask( void * pvParameters ) * After sending disconnect, client must close the network connection. */ LogInfo( ( "Disconnecting the MQTT connection with %s.", democonfigMQTT_BROKER_ENDPOINT ) ); - xMQTTStatus = MQTT_Disconnect( &xMQTTContext ); + xMQTTStatus = MQTT_Disconnect( &xMQTTContext, NULL, NULL ); configASSERT( xMQTTStatus == MQTTSuccess ); /* Close the network connection. */ @@ -572,7 +575,9 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, pOutgoingPublishRecords, mqttexampleOUTGOING_PUBLISH_RECORD_LEN, pIncomingPublishRecords, - mqttexampleINCOMING_PUBLISH_RECORD_LEN ); + mqttexampleINCOMING_PUBLISH_RECORD_LEN, + NULL, + 0U ); configASSERT( xResult == MQTTSuccess ); /* Some fields are not used in this demo so start with everything at 0. */ @@ -600,7 +605,9 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext, &xConnectInfo, NULL, mqttexampleCONNACK_RECV_TIMEOUT_MS, - &xSessionPresent ); + &xSessionPresent, + NULL, + NULL ); configASSERT( xResult == MQTTSuccess ); /* Successfully established and MQTT connection with the broker. */ @@ -634,7 +641,8 @@ static void prvMQTTSubscribeToTopic( MQTTContext_t * pxMQTTContext ) xResult = MQTT_Subscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usSubscribePacketIdentifier ); + usSubscribePacketIdentifier, + NULL ); configASSERT( xResult == MQTTSuccess ); } @@ -666,7 +674,7 @@ static void prvMQTTPublishToTopic( MQTTContext_t * pxMQTTContext ) usPublishPacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); /* Send PUBLISH packet. Packet ID is not used for a QoS1 publish. */ - xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier ); + xResult = MQTT_Publish( pxMQTTContext, &xMQTTPublishInfo, usPublishPacketIdentifier, NULL ); configASSERT( xResult == MQTTSuccess ); } @@ -693,7 +701,8 @@ static void prvMQTTUnsubscribeFromTopic( MQTTContext_t * pxMQTTContext ) xResult = MQTT_Unsubscribe( pxMQTTContext, xMQTTSubscription, sizeof( xMQTTSubscription ) / sizeof( MQTTSubscribeInfo_t ), - usUnsubscribePacketIdentifier ); + usUnsubscribePacketIdentifier, + NULL ); configASSERT( xResult == MQTTSuccess ); } @@ -767,12 +776,18 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ) /*-----------------------------------------------------------*/ -static void prvEventCallback( MQTTContext_t * pxMQTTContext, +static bool prvEventCallback( MQTTContext_t * pxMQTTContext, MQTTPacketInfo_t * pxPacketInfo, - MQTTDeserializedInfo_t * pxDeserializedInfo ) + MQTTDeserializedInfo_t * pxDeserializedInfo, + MQTTSuccessFailReasonCode_t * pxReasonCode, + MQTTPropBuilder_t * pxSendPropsBuffer, + MQTTPropBuilder_t * pxGetPropsBuffer ) { /* The MQTT context is not used for this demo. */ ( void ) pxMQTTContext; + ( void ) pxReasonCode; + ( void ) pxSendPropsBuffer; + ( void ) pxGetPropsBuffer; if( ( pxPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) { @@ -782,6 +797,8 @@ static void prvEventCallback( MQTTContext_t * pxMQTTContext, { prvMQTTProcessResponse( pxPacketInfo, pxDeserializedInfo->packetIdentifier ); } + + return true; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj index 233b17f6b80..cca96148500 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj @@ -54,6 +54,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj.filters b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj.filters index 5671bff6c7d..e1e89769c4f 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj.filters @@ -51,6 +51,15 @@ Additional Libraries\coreMQTT + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + Additional Libraries\coreMQTT diff --git a/FreeRTOS-Plus/Source/Application-Protocols/coreMQTT b/FreeRTOS-Plus/Source/Application-Protocols/coreMQTT index 86a5750bb31..76e9d89cb8e 160000 --- a/FreeRTOS-Plus/Source/Application-Protocols/coreMQTT +++ b/FreeRTOS-Plus/Source/Application-Protocols/coreMQTT @@ -1 +1 @@ -Subproject commit 86a5750bb31e05fa69ef3f4e2f5e69d9317fae44 +Subproject commit 76e9d89cb8e2fb4cff965329d835594cebebf618 diff --git a/FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent b/FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent index a74d35a522a..71645386f3a 160000 --- a/FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent +++ b/FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent @@ -1 +1 @@ -Subproject commit a74d35a522ae55127ef345fde79368e249144626 +Subproject commit 71645386f3a648062de7851a923aa13a09048177 diff --git a/manifest.yml b/manifest.yml index 045673f867a..4062621520a 100644 --- a/manifest.yml +++ b/manifest.yml @@ -40,14 +40,14 @@ dependencies: path: "FreeRTOS-Plus/Source/Application-Protocols/coreHTTP" - name: "coreMQTT" - version: "86a5750" + version: "76e9d89" repository: type: "git" url: "https://github.com/FreeRTOS/coreMQTT.git" path: "FreeRTOS-Plus/Source/Application-Protocols/coreMQTT" - name: "coreMQTT Agent" - version: "a74d35a" + version: "7164538" repository: type: "git" url: "https://github.com/FreeRTOS/coreMQTT-Agent.git"