diff --git a/src/core/radio/ble_secure.cpp b/src/core/radio/ble_secure.cpp index ba66ed64b..3186f9509 100644 --- a/src/core/radio/ble_secure.cpp +++ b/src/core/radio/ble_secure.cpp @@ -196,10 +196,19 @@ Error BleSecure::NotifyAdvertisementChanged(void) uint16_t advertisementLen = 0; uint8_t *advertisementData = nullptr; - VerifyOrExit(mBleState == kAdvertising); + VerifyOrExit(mBleState != kStopped); SuccessOrExit(error = otPlatBleGetAdvertisementBuffer(&GetInstance(), &advertisementData)); SuccessOrExit(error = Get().GetAdvertisementData(advertisementLen, advertisementData)); - SuccessOrExit(error = otPlatBleGapAdvUpdateData(&GetInstance(), advertisementData, advertisementLen)); + + if (mBleState == kAdvertising) + { + SuccessOrExit(error = otPlatBleGapAdvUpdateData(&GetInstance(), advertisementData, advertisementLen)); + } + else + { + // Any other state: update buffered data for when advertising resumes. + SuccessOrExit(error = otPlatBleGapAdvSetData(&GetInstance(), advertisementData, advertisementLen)); + } exit: return error; diff --git a/tests/scripts/expect/cli-tcat-decommission.exp b/tests/scripts/expect/cli-tcat-decommission.exp index cfd5e589c..3825dac3c 100755 --- a/tests/scripts/expect/cli-tcat-decommission.exp +++ b/tests/scripts/expect/cli-tcat-decommission.exp @@ -53,6 +53,9 @@ send "thread start\n" expect_line "\tTYPE:\tRESPONSE_W_STATUS" expect_line "\tVALUE:\t0x00" +send "disconnect\n" +expect_line "Done" + dispose_tcat_client 1 switch_node 1 diff --git a/tests/unit/test_platform.cpp b/tests/unit/test_platform.cpp index 621dd0f81..d29e3748d 100644 --- a/tests/unit/test_platform.cpp +++ b/tests/unit/test_platform.cpp @@ -801,6 +801,10 @@ OT_TOOL_WEAK otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance) { OT_TOOL_WEAK otError otPlatSetMcuPowerState(otInstance *aInstance, otPlatMcuPowerState aState) { return OT_ERROR_NONE; } #endif // OPENTHREAD_CONFIG_NCP_ENABLE_MCU_POWER_STATE_CONTROL #ifdef OPENTHREAD_CONFIG_BLE_TCAT_ENABLE + +uint8_t sPlatBleLastAdvSetData[OT_TCAT_ADVERTISEMENT_MAX_LEN]; +uint16_t sPlatBleLastAdvSetDataLen = 0; + otError otPlatBleEnable(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); @@ -875,17 +879,19 @@ bool otPlatBleSupportsMultiRadio(otInstance *aInstance) otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen) { OT_UNUSED_VARIABLE(aInstance); - OT_UNUSED_VARIABLE(aAdvertisementData); - OT_UNUSED_VARIABLE(aAdvertisementLen); + if (aAdvertisementData == nullptr || aAdvertisementLen > OT_TCAT_ADVERTISEMENT_MAX_LEN) + { + return OT_ERROR_INVALID_ARGS; + } + memcpy(sPlatBleLastAdvSetData, aAdvertisementData, aAdvertisementLen); + sPlatBleLastAdvSetDataLen = aAdvertisementLen; + return OT_ERROR_NONE; } otError otPlatBleGapAdvUpdateData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen) { - OT_UNUSED_VARIABLE(aInstance); - OT_UNUSED_VARIABLE(aAdvertisementData); - OT_UNUSED_VARIABLE(aAdvertisementLen); - return OT_ERROR_NONE; + return otPlatBleGapAdvSetData(aInstance, aAdvertisementData, aAdvertisementLen); } #endif // OPENTHREAD_CONFIG_BLE_TCAT_ENABLE diff --git a/tests/unit/test_platform.h b/tests/unit/test_platform.h index 4eedd4edc..87904c214 100644 --- a/tests/unit/test_platform.h +++ b/tests/unit/test_platform.h @@ -57,4 +57,16 @@ ot::Instance *testInitAdditionalInstance(uint8_t id); #endif void testFreeInstance(otInstance *aInstance); +#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE +#include +#ifdef __cplusplus +extern "C" { +#endif +extern uint8_t sPlatBleLastAdvSetData[OT_TCAT_ADVERTISEMENT_MAX_LEN]; +extern uint16_t sPlatBleLastAdvSetDataLen; +#ifdef __cplusplus +} +#endif +#endif + #endif // OT_UNIT_TEST_PLATFORM_H_ diff --git a/tests/unit/test_tcat.cpp b/tests/unit/test_tcat.cpp index 2c4acfd56..a6f8a7e16 100644 --- a/tests/unit/test_tcat.cpp +++ b/tests/unit/test_tcat.cpp @@ -36,6 +36,7 @@ #include #include "cli/cli_dataset.hpp" +#include "radio/ble_secure.hpp" #define OT_TCAT_X509_CERT \ "-----BEGIN CERTIFICATE-----\n" \ @@ -267,6 +268,8 @@ static Instance *TestInitInstanceTcat(void) memcpy(&sCommExtPanId, &kExtPanId, sizeof(sCommExtPanId)); memcpy(&sCommAuth, &kCommCert1AuthField, sizeof(sCommAuth)); memcpy(&sDeviceAuth, &kDeviceCert1AuthField, sizeof(sDeviceAuth)); + sPlatBleLastAdvSetDataLen = 0; + memset(sPlatBleLastAdvSetData, 0, OT_TCAT_ADVERTISEMENT_MAX_LEN); return instance; } @@ -336,6 +339,46 @@ void TestTcatConnectionAndCertAttributes(void) testFreeInstance(instance); } +void TestTcatAdvertisementUpdates(void) +{ + TestBleSecure ble; + Instance *instance = TestInitInstanceTcat(); + uint8_t advDataSnapshot[OT_TCAT_ADVERTISEMENT_MAX_LEN]; + uint16_t advDataSnapshotLen; + + VerifyOrQuit(sPlatBleLastAdvSetDataLen == 0, "Adv data should be unset before BleSecure start"); + + SuccessOrQuit(otBleSecureStart(instance, HandleBleSecureConnect, nullptr, true, &ble)); + SuccessOrQuit(otBleSecureTcatStart(instance, nullptr)); + + VerifyOrQuit(sPlatBleLastAdvSetDataLen > 0, "Adv data should be set after BleSecure start"); + advDataSnapshotLen = sPlatBleLastAdvSetDataLen; + memcpy(advDataSnapshot, sPlatBleLastAdvSetData, advDataSnapshotLen); + + otPlatBleGapOnConnected(instance, kConnectionId); + SuccessOrQuit(otBleSecureConnect(instance)); + + // BLE connect and initiating TLS does not change the adv data. + VerifyOrQuit(sPlatBleLastAdvSetDataLen == advDataSnapshotLen && + memcmp(sPlatBleLastAdvSetData, advDataSnapshot, advDataSnapshotLen) == 0, + "Adv data changed unexpectedly after BLE connect"); + advDataSnapshotLen = sPlatBleLastAdvSetDataLen; + memcpy(advDataSnapshot, sPlatBleLastAdvSetData, advDataSnapshotLen); + + // Commissioner sets dataset, then disconnects + instance->Get().SaveLocal(sPartialDataset); + otBleSecureDisconnect(instance); + + // Adv is changed due to the partial dataset now being advertised in the S flag. + VerifyOrQuit(sPlatBleLastAdvSetDataLen == advDataSnapshotLen, "Adv data length changed unexpectedly"); + VerifyOrQuit(memcmp(sPlatBleLastAdvSetData, advDataSnapshot, advDataSnapshotLen) != 0, + "Adv data did not change after disconnect, which it should due to S flag"); + + otBleSecureStop(instance); + + testFreeInstance(instance); +} + class UnitTester { private: @@ -834,6 +877,7 @@ int main(void) ot::MeshCoP::UnitTester::TestTcatCommissioner1AuthWithDeviceRequirements(); ot::MeshCoP::UnitTester::TestTcatCommissioner2AuthWithDeviceRequirements(); ot::MeshCoP::UnitTester::TestTcatCommissioner4AuthWithExistingPartialDataset(); + ot::MeshCoP::TestTcatAdvertisementUpdates(); printf("All tests passed\n"); #else printf("TCAT feature is not enabled\n");