From e80cd2fe874072eaa416c69cdeb26cef0b74b1e8 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 May 2024 11:16:23 +0200 Subject: [PATCH 1/9] Unit tests for BLE layer class --- src/ble/tests/BUILD.gn | 6 +- src/ble/tests/TestBleLayer.cpp | 336 +++++++++++++++++++++++++++++++++ 2 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 src/ble/tests/TestBleLayer.cpp diff --git a/src/ble/tests/BUILD.gn b/src/ble/tests/BUILD.gn index 687ad7be8f4167..ac897ab40a9c27 100644 --- a/src/ble/tests/BUILD.gn +++ b/src/ble/tests/BUILD.gn @@ -22,11 +22,15 @@ chip_test_suite("tests") { test_sources = [ "TestBleErrorStr.cpp", + "TestBleLayer.cpp", "TestBleUUID.cpp", "TestBtpEngine.cpp", ] cflags = [ "-Wconversion" ] - public_deps = [ "${chip_root}/src/ble" ] + public_deps = [ + "${chip_root}/src/ble", + "${chip_root}/src/platform", + ] } diff --git a/src/ble/tests/TestBleLayer.cpp b/src/ble/tests/TestBleLayer.cpp new file mode 100644 index 00000000000000..4a23f027787dbc --- /dev/null +++ b/src/ble/tests/TestBleLayer.cpp @@ -0,0 +1,336 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include +#include +#include + +#define _CHIP_BLE_BLE_H +#include +#include +#include +#include + +namespace chip { +namespace Ble { + +static constexpr ChipBleUUID uuidZero{}; +static constexpr ChipBleUUID uuidSvc = { { 0x00, 0x00, 0xFF, 0xF6, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, + 0xFB } }; +static constexpr ChipBleUUID uuidChar1 = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x11 } }; +static constexpr ChipBleUUID uuidChar2 = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x12 } }; +static constexpr ChipBleUUID uuidChar3 = { { 0x64, 0x63, 0x02, 0x38, 0x87, 0x72, 0x45, 0xF2, 0xB8, 0x7D, 0x74, 0x8A, 0x83, 0x21, + 0x8F, 0x04 } }; + +class TestBleLayer : public BleLayer, + private BleApplicationDelegate, + private BleLayerDelegate, + private BlePlatformDelegate, + public ::testing::Test +{ +public: + static void SetUpTestSuite() + { + ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); + ASSERT_EQ(DeviceLayer::SystemLayer().Init(), CHIP_NO_ERROR); + } + + static void TearDownTestSuite() + { + DeviceLayer::SystemLayer().Shutdown(); + chip::Platform::MemoryShutdown(); + } + + void SetUp() + { + ASSERT_EQ(Init(this, nullptr, this, &DeviceLayer::SystemLayer()), CHIP_NO_ERROR); + mBleTransport = this; + } + + void TearDown() + { + mBleTransport = nullptr; + Shutdown(); + } + + // Passing capabilities request message to HandleWriteReceived should create + // new BLE endpoint which later can be used to receive more data. + bool HandleWriteReceivedCapabilitiesRequest() + { + constexpr uint8_t capReq[] = { 0x65, 0x6c, 0x54, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x06 }; + auto connObj = reinterpret_cast(this); + auto buf = System::PacketBufferHandle::NewWithData(capReq, sizeof(capReq)); + return HandleWriteReceived(connObj, &uuidSvc, &uuidChar1, std::move(buf)); + } + + // Processing subscription request after capabilities request should finalize + // connection establishment. + bool HandleSubscribeReceivedOnChar2() + { + auto connObj = reinterpret_cast(this); + return HandleSubscribeReceived(connObj, &uuidSvc, &uuidChar2); + } + + /// + // Implementation of BleApplicationDelegate + + void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT connObj) override {} + + /// + // Implementation of BleLayerDelegate + + void OnBleConnectionComplete(BLEEndPoint * endpoint) override {} + void OnBleConnectionError(CHIP_ERROR err) override {} + void OnEndPointConnectComplete(BLEEndPoint * endPoint, CHIP_ERROR err) override {} + void OnEndPointMessageReceived(BLEEndPoint * endPoint, System::PacketBufferHandle && msg) override {} + void OnEndPointConnectionClosed(BLEEndPoint * endPoint, CHIP_ERROR err) override {} + CHIP_ERROR SetEndPoint(BLEEndPoint * endPoint) override { return CHIP_NO_ERROR; } + + /// + // Implementation of BlePlatformDelegate + + bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT, const ChipBleUUID *, const ChipBleUUID *) override { return true; } + bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT, const ChipBleUUID *, const ChipBleUUID *) override { return true; } + bool CloseConnection(BLE_CONNECTION_OBJECT connObj) override { return true; } + uint16_t GetMTU(BLE_CONNECTION_OBJECT connObj) const override { return 0; } + bool SendIndication(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) override + { + return true; + } + bool SendWriteRequest(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) override + { + return true; + } + bool SendReadRequest(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) override + { + return true; + } + bool SendReadResponse(BLE_CONNECTION_OBJECT connObj, BLE_READ_REQUEST_CONTEXT requestContext, const ChipBleUUID * svcId, + const ChipBleUUID * charId) override + { + return true; + } +}; + +TEST_F(TestBleLayer, CheckBleTransportCapabilitiesRequestMessage) +{ + auto buf = System::PacketBufferHandle::New(100); + ASSERT_FALSE(buf.IsNull()); + + BleTransportCapabilitiesRequestMessage msg{}; + msg.SetSupportedProtocolVersion(0, CHIP_BLE_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION); + msg.SetSupportedProtocolVersion(1, CHIP_BLE_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION + 1); + msg.mMtu = 200; + msg.mWindowSize = BLE_MAX_RECEIVE_WINDOW_SIZE; + + ASSERT_EQ(msg.Encode(buf), CHIP_NO_ERROR); + ChipLogByteSpan(Test, ByteSpan(buf->Start(), buf->DataLength())); + + BleTransportCapabilitiesRequestMessage msgVerify; + ASSERT_EQ(BleTransportCapabilitiesRequestMessage::Decode(buf, msgVerify), CHIP_NO_ERROR); + EXPECT_EQ(memcmp(msg.mSupportedProtocolVersions, msgVerify.mSupportedProtocolVersions, sizeof(msg.mSupportedProtocolVersions)), + 0); + EXPECT_EQ(msg.mMtu, msgVerify.mMtu); + EXPECT_EQ(msg.mWindowSize, msgVerify.mWindowSize); +} + +TEST_F(TestBleLayer, CheckBleTransportCapabilitiesResponseMessage) +{ + auto buf = System::PacketBufferHandle::New(100); + ASSERT_FALSE(buf.IsNull()); + + BleTransportCapabilitiesResponseMessage msg{}; + msg.mSelectedProtocolVersion = CHIP_BLE_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION; + msg.mFragmentSize = 200; + msg.mWindowSize = BLE_MAX_RECEIVE_WINDOW_SIZE; + + EXPECT_EQ(msg.Encode(buf), CHIP_NO_ERROR); + ChipLogByteSpan(Test, ByteSpan(buf->Start(), buf->DataLength())); + + BleTransportCapabilitiesResponseMessage msgVerify; + ASSERT_EQ(BleTransportCapabilitiesResponseMessage::Decode(buf, msgVerify), CHIP_NO_ERROR); + EXPECT_EQ(msg.mSelectedProtocolVersion, msgVerify.mSelectedProtocolVersion); + EXPECT_EQ(msg.mFragmentSize, msgVerify.mFragmentSize); + EXPECT_EQ(msg.mWindowSize, msgVerify.mWindowSize); +} + +TEST_F(TestBleLayer, HandleWriteReceivedCapabilitiesRequest) +{ + EXPECT_TRUE(HandleWriteReceivedCapabilitiesRequest()); +} + +TEST_F(TestBleLayer, HandleSubscribeReceivedInvalidUUID) +{ + auto connObj = reinterpret_cast(this); + EXPECT_FALSE(HandleSubscribeReceived(connObj, &uuidZero, &uuidZero)); + EXPECT_FALSE(HandleSubscribeReceived(connObj, &uuidSvc, &uuidChar1)); +} + +TEST_F(TestBleLayer, HandleSubscribeReceived) +{ + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + EXPECT_TRUE(HandleSubscribeReceivedOnChar2()); +} + +TEST_F(TestBleLayer, HandleSubscribeCompleteInvalidUUID) +{ + auto connObj = reinterpret_cast(this); + EXPECT_FALSE(HandleSubscribeComplete(connObj, &uuidZero, &uuidZero)); + EXPECT_FALSE(HandleSubscribeComplete(connObj, &uuidSvc, &uuidChar1)); +} + +TEST_F(TestBleLayer, HandleSubscribeComplete) +{ + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + ASSERT_TRUE(HandleSubscribeReceivedOnChar2()); + + auto connObj = reinterpret_cast(this); + EXPECT_TRUE(HandleSubscribeComplete(connObj, &uuidSvc, &uuidChar2)); +} + +TEST_F(TestBleLayer, HandleUnsubscribeReceivedInvalidUUID) +{ + auto connObj = reinterpret_cast(this); + EXPECT_FALSE(HandleUnsubscribeReceived(connObj, &uuidZero, &uuidZero)); + EXPECT_FALSE(HandleUnsubscribeReceived(connObj, &uuidSvc, &uuidChar1)); +} + +TEST_F(TestBleLayer, HandleUnsubscribeReceived) +{ + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + ASSERT_TRUE(HandleSubscribeReceivedOnChar2()); + + auto connObj = reinterpret_cast(this); + EXPECT_TRUE(HandleUnsubscribeReceived(connObj, &uuidSvc, &uuidChar2)); +} + +TEST_F(TestBleLayer, HandleUnsubscribeCompleteInvalidUUID) +{ + auto connObj = reinterpret_cast(this); + EXPECT_FALSE(HandleUnsubscribeComplete(connObj, &uuidZero, &uuidZero)); + EXPECT_FALSE(HandleUnsubscribeComplete(connObj, &uuidSvc, &uuidChar1)); +} + +TEST_F(TestBleLayer, HandleUnsubscribeComplete) +{ + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + ASSERT_TRUE(HandleSubscribeReceivedOnChar2()); + + auto connObj = reinterpret_cast(this); + EXPECT_TRUE(HandleUnsubscribeComplete(connObj, &uuidSvc, &uuidChar2)); +} + +TEST_F(TestBleLayer, HandleWriteReceivedInvalidUUID) +{ + auto connObj = reinterpret_cast(this); + auto buf = System::PacketBufferHandle::New(0); + ASSERT_FALSE(buf.IsNull()); + + EXPECT_FALSE(HandleWriteReceived(connObj, &uuidZero, &uuidZero, buf.Retain())); + EXPECT_FALSE(HandleWriteReceived(connObj, &uuidSvc, &uuidChar3, std::move(buf))); +} + +TEST_F(TestBleLayer, HandleWriteReceived) +{ + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + ASSERT_TRUE(HandleSubscribeReceivedOnChar2()); + + constexpr uint8_t data[] = { to_underlying(BtpEngine::HeaderFlags::kStartMessage) | + to_underlying(BtpEngine::HeaderFlags::kEndMessage), + 0x00, 0x01, 0x00, 0xff }; + auto buf = System::PacketBufferHandle::NewWithData(data, sizeof(data)); + ASSERT_FALSE(buf.IsNull()); + + auto connObj = reinterpret_cast(this); + EXPECT_TRUE(HandleWriteReceived(connObj, &uuidSvc, &uuidChar1, std::move(buf))); +} + +TEST_F(TestBleLayer, HandleWriteConfirmationInvalidUUID) +{ + auto connObj = reinterpret_cast(this); + EXPECT_FALSE(HandleWriteConfirmation(connObj, &uuidZero, &uuidZero)); + EXPECT_FALSE(HandleWriteConfirmation(connObj, &uuidSvc, &uuidChar2)); +} + +TEST_F(TestBleLayer, HandleWriteConfirmation) +{ + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + + auto connObj = reinterpret_cast(this); + EXPECT_TRUE(HandleWriteConfirmation(connObj, &uuidSvc, &uuidChar1)); +} + +TEST_F(TestBleLayer, HandleIndicationReceivedInvalidUUID) +{ + auto connObj = reinterpret_cast(this); + auto buf = System::PacketBufferHandle::New(0); + ASSERT_FALSE(buf.IsNull()); + + EXPECT_FALSE(HandleIndicationReceived(connObj, &uuidZero, &uuidZero, buf.Retain())); + EXPECT_FALSE(HandleIndicationReceived(connObj, &uuidSvc, &uuidChar1, std::move(buf))); +} + +TEST_F(TestBleLayer, HandleIndicationReceived) +{ + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + ASSERT_TRUE(HandleSubscribeReceivedOnChar2()); + + constexpr uint8_t data[] = { to_underlying(BtpEngine::HeaderFlags::kStartMessage) | + to_underlying(BtpEngine::HeaderFlags::kEndMessage), + 0x00, 0x01, 0x00, 0xff }; + auto buf = System::PacketBufferHandle::NewWithData(data, sizeof(data)); + ASSERT_FALSE(buf.IsNull()); + + auto connObj = reinterpret_cast(this); + EXPECT_TRUE(HandleIndicationReceived(connObj, &uuidSvc, &uuidChar2, std::move(buf))); +} + +TEST_F(TestBleLayer, HandleIndicationConfirmationInvalidUUID) +{ + auto connObj = reinterpret_cast(this); + EXPECT_FALSE(HandleIndicationConfirmation(connObj, &uuidZero, &uuidZero)); + EXPECT_FALSE(HandleIndicationConfirmation(connObj, &uuidSvc, &uuidChar1)); +} + +TEST_F(TestBleLayer, HandleIndicationConfirmation) +{ + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + + auto connObj = reinterpret_cast(this); + EXPECT_TRUE(HandleIndicationConfirmation(connObj, &uuidSvc, &uuidChar2)); +} + +TEST_F(TestBleLayer, HandleConnectionError) +{ + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + + auto connObj = reinterpret_cast(this); + HandleConnectionError(connObj, CHIP_ERROR_ACCESS_DENIED); +} + +}; // namespace Ble +}; // namespace chip From 7908b31968bf082b274d944f52d5fbecd6e6e7dd Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 May 2024 11:18:21 +0200 Subject: [PATCH 2/9] Check for mBleTransport NULL before dereference --- src/ble/BLEEndPoint.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ble/BLEEndPoint.cpp b/src/ble/BLEEndPoint.cpp index ba6400fc8a19b7..0e69e590df7f49 100644 --- a/src/ble/BLEEndPoint.cpp +++ b/src/ble/BLEEndPoint.cpp @@ -346,7 +346,7 @@ void BLEEndPoint::DoClose(uint8_t flags, CHIP_ERROR err) DoCloseCallback(oldState, flags, err); } - if ((flags & kBleCloseFlag_SuppressCallback) != 0) + if (mBleTransport != nullptr && (flags & kBleCloseFlag_SuppressCallback) != 0) { mBleTransport->OnEndPointConnectionClosed(this, err); } @@ -367,7 +367,7 @@ void BLEEndPoint::FinalizeClose(uint8_t oldState, uint8_t flags, CHIP_ERROR err) DoCloseCallback(oldState, flags, err); } - if ((flags & kBleCloseFlag_SuppressCallback) != 0) + if (mBleTransport != nullptr && (flags & kBleCloseFlag_SuppressCallback) != 0) { mBleTransport->OnEndPointConnectionClosed(this, err); } @@ -1290,7 +1290,7 @@ CHIP_ERROR BLEEndPoint::Receive(PacketBufferHandle && data) // Take ownership of message buffer System::PacketBufferHandle full_packet = mBtpEngine.TakeRxPacket(); - ChipLogDebugBleEndPoint(Ble, "reassembled whole msg, len = %d", full_packet->DataLength()); + ChipLogDebugBleEndPoint(Ble, "reassembled whole msg, len = %u", static_cast(full_packet->DataLength())); // If we have a message received callback, and end point is not closing... if (mBleTransport != nullptr && mState != kState_Closing) From 48b5ef9cf4789b91dac01f1c1719097a841b74cc Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 May 2024 11:31:16 +0200 Subject: [PATCH 3/9] Return false in case of handle error in BLE layer --- src/ble/BleLayer.cpp | 256 ++++++++++++------------------------------- src/ble/BleLayer.h | 1 - 2 files changed, 70 insertions(+), 187 deletions(-) diff --git a/src/ble/BleLayer.cpp b/src/ble/BleLayer.cpp index d4a1e3209610a6..de1f8458402efa 100644 --- a/src/ble/BleLayer.cpp +++ b/src/ble/BleLayer.cpp @@ -22,7 +22,7 @@ * a platform's Bluetooth Low Energy (BLE) implementation and the CHIP * stack. * - * The BleLayer obect accepts BLE data and control input from the + * The BleLayer object accepts BLE data and control input from the * application via a functional interface. It performs the fragmentation * and reassembly required to transmit CHIP message via a BLE GATT * characteristic interface, and drives incoming messages up the CHIP @@ -485,43 +485,24 @@ CHIP_ERROR BleLayer::HandleBleTransportConnectionInitiated(BLE_CONNECTION_OBJECT bool BleLayer::HandleWriteReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, PacketBufferHandle && pBuf) { - if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId)) - { - ChipLogError(Ble, "ble write rcvd on unknown svc id"); - return true; - } + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Write received on unknown svc")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId), false, ChipLogError(Ble, "Write received on unknown char")); + VerifyOrReturnError(!pBuf.IsNull(), false, ChipLogError(Ble, "Write received null buffer")); - if (UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId)) - { - if (pBuf.IsNull()) - { - ChipLogError(Ble, "rcvd null ble write"); - return true; - } - - // Find matching connection end point. - BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); + // Find matching connection end point. + BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); - if (endPoint != nullptr) - { - CHIP_ERROR status = endPoint->Receive(std::move(pBuf)); - if (status != CHIP_NO_ERROR) - { - ChipLogError(Ble, "BLEEndPoint rcv failed, err = %" CHIP_ERROR_FORMAT, status.Format()); - } - } - else - { - CHIP_ERROR status = HandleBleTransportConnectionInitiated(connObj, std::move(pBuf)); - if (status != CHIP_NO_ERROR) - { - ChipLogError(Ble, "failed handle new chip BLE connection, status = %" CHIP_ERROR_FORMAT, status.Format()); - } - } + if (endPoint != nullptr) + { + CHIP_ERROR err = endPoint->Receive(std::move(pBuf)); + VerifyOrReturnError(err == CHIP_NO_ERROR, false, + ChipLogError(Ble, "Receive failed, err = %" CHIP_ERROR_FORMAT, err.Format())); } else { - ChipLogError(Ble, "ble write rcvd on unknown char"); + CHIP_ERROR err = HandleBleTransportConnectionInitiated(connObj, std::move(pBuf)); + VerifyOrReturnError(err == CHIP_NO_ERROR, false, + ChipLogError(Ble, "Handle new BLE connection failed, err = %" CHIP_ERROR_FORMAT, err.Format())); } return true; @@ -530,197 +511,102 @@ bool BleLayer::HandleWriteReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleU bool BleLayer::HandleIndicationReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, PacketBufferHandle && pBuf) { - if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId)) - { - return false; - } + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Indication received on unknown svc")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId), false, ChipLogError(Ble, "Indication received on unknown char")); + VerifyOrReturnError(!pBuf.IsNull(), false, ChipLogError(Ble, "Indication received null buffer")); - if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId)) - { - if (pBuf.IsNull()) - { - ChipLogError(Ble, "rcvd null ble indication"); - return true; - } - - // find matching connection end point. - BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); + // Find matching connection end point. + BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); + VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for received indication")); - if (endPoint != nullptr) - { - CHIP_ERROR status = endPoint->Receive(std::move(pBuf)); - if (status != CHIP_NO_ERROR) - { - ChipLogError(Ble, "BLEEndPoint rcv failed, err = %" CHIP_ERROR_FORMAT, status.Format()); - } - } - else - { - ChipLogDetail(Ble, "no endpoint for rcvd indication"); - } - } - else - { - ChipLogError(Ble, "ble ind rcvd on unknown char"); - } + CHIP_ERROR err = endPoint->Receive(std::move(pBuf)); + VerifyOrReturnError(err == CHIP_NO_ERROR, false, ChipLogError(Ble, "Receive failed, err = %" CHIP_ERROR_FORMAT, err.Format())); return true; } bool BleLayer::HandleWriteConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { - if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId)) - { - return false; - } - - if (UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId)) - { - HandleAckReceived(connObj); - } - else - { - ChipLogError(Ble, "ble write con rcvd on unknown char"); - } + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Write confirmation on unknown svc")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId), false, ChipLogError(Ble, "Write confirmation on unknown char")); + HandleAckReceived(connObj); return true; } bool BleLayer::HandleIndicationConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { - if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId)) - { - return false; - } - - if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId)) - { - HandleAckReceived(connObj); - } - else - { - ChipLogError(Ble, "ble ind con rcvd on unknown char"); - } + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Indication confirmation on unknown svc")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId), false, + ChipLogError(Ble, "Indication confirmation on unknown char")); + HandleAckReceived(connObj); return true; } void BleLayer::HandleAckReceived(BLE_CONNECTION_OBJECT connObj) { - // find matching connection end point. + // Find matching connection end point. BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); + VerifyOrReturn(endPoint != nullptr, ChipLogDetail(Ble, "No endpoint for received ack")); - if (endPoint != nullptr) - { - CHIP_ERROR status = endPoint->HandleGattSendConfirmationReceived(); - - if (status != CHIP_NO_ERROR) - { - ChipLogError(Ble, "endpoint conf recvd failed, err = %" CHIP_ERROR_FORMAT, status.Format()); - } - } - else - { - ChipLogError(Ble, "no endpoint for BLE sent data ack"); - } + CHIP_ERROR err = endPoint->HandleGattSendConfirmationReceived(); + VerifyOrReturn(err == CHIP_NO_ERROR, + ChipLogError(Ble, "Send ack confirmation failed, err = %" CHIP_ERROR_FORMAT, err.Format())); } bool BleLayer::HandleSubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { - if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId)) - { - return false; - } + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Subscribe received on unknown svc")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false, + ChipLogError(Ble, "Subscribe received on unknown char")); - if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId)) - { - // Find end point already associated with BLE connection, if any. - BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); - - if (endPoint != nullptr) - { - endPoint->HandleSubscribeReceived(); - } - else - { - ChipLogError(Ble, "no endpoint for sub recvd"); - } - } + // Find end point already associated with BLE connection, if any. + BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); + VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for received subscribe")); + endPoint->HandleSubscribeReceived(); return true; } bool BleLayer::HandleSubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { - if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId)) - { - return false; - } + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Subscribe complete on unknown svc")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false, + ChipLogError(Ble, "Subscribe complete on unknown char")); - if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId)) - { - BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); - - if (endPoint != nullptr) - { - endPoint->HandleSubscribeComplete(); - } - else - { - ChipLogError(Ble, "no endpoint for sub complete"); - } - } + BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); + VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for subscribe complete")); + endPoint->HandleSubscribeComplete(); return true; } bool BleLayer::HandleUnsubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { - if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId)) - { - return false; - } + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Unsubscribe received on unknown svc")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false, + ChipLogError(Ble, "Unsubscribe received on unknown char")); - if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId)) - { - // Find end point already associated with BLE connection, if any. - BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); - - if (endPoint != nullptr) - { - endPoint->DoClose(kBleCloseFlag_AbortTransmission, BLE_ERROR_CENTRAL_UNSUBSCRIBED); - } - else - { - ChipLogError(Ble, "no endpoint for unsub recvd"); - } - } + // Find end point already associated with BLE connection, if any. + BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); + VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for unsubscribe received")); + endPoint->DoClose(kBleCloseFlag_AbortTransmission, BLE_ERROR_CENTRAL_UNSUBSCRIBED); return true; } bool BleLayer::HandleUnsubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { - if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId)) - { - return false; - } + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Unsubscribe complete on unknown svc")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false, + ChipLogError(Ble, "Unsubscribe complete on unknown char")); - if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId)) - { - // Find end point already associated with BLE connection, if any. - BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); - - if (endPoint != nullptr) - { - endPoint->HandleUnsubscribeComplete(); - } - else - { - ChipLogError(Ble, "no endpoint for unsub complete"); - } - } + // Find end point already associated with BLE connection, if any. + BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); + VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for unsubscribe complete")); + endPoint->HandleUnsubscribeComplete(); return true; } @@ -728,19 +614,17 @@ void BleLayer::HandleConnectionError(BLE_CONNECTION_OBJECT connObj, CHIP_ERROR e { // BLE connection has failed somehow, we must find and abort matching connection end point. BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); + VerifyOrReturn(endPoint != nullptr, ChipLogDetail(Ble, "No endpoint for connection error")); - if (endPoint != nullptr) + if (err == BLE_ERROR_GATT_UNSUBSCRIBE_FAILED && endPoint->IsUnsubscribePending()) { - if (err == BLE_ERROR_GATT_UNSUBSCRIBE_FAILED && endPoint->IsUnsubscribePending()) - { - // If end point was already closed and just waiting for unsubscribe to complete, free it. Call to Free() - // stops unsubscribe timer. - endPoint->Free(); - } - else - { - endPoint->DoClose(kBleCloseFlag_AbortTransmission, err); - } + // If end point was already closed and just waiting for unsubscribe to complete, free it. Call to Free() + // stops unsubscribe timer. + endPoint->Free(); + } + else + { + endPoint->DoClose(kBleCloseFlag_AbortTransmission, err); } } diff --git a/src/ble/BleLayer.h b/src/ble/BleLayer.h index bad3ab3fd62fe7..e7d619fe13420e 100644 --- a/src/ble/BleLayer.h +++ b/src/ble/BleLayer.h @@ -327,7 +327,6 @@ class DLL_EXPORT BleLayer // Private functions: void HandleAckReceived(BLE_CONNECTION_OBJECT connObj); - void DriveSending(); CHIP_ERROR HandleBleTransportConnectionInitiated(BLE_CONNECTION_OBJECT connObj, System::PacketBufferHandle && pBuf); static BleTransportProtocolVersion GetHighestSupportedProtocolVersion(const BleTransportCapabilitiesRequestMessage & reqMsg); From 3f9c300ff3fb2081778d61bfdaeb0280d4857845 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 May 2024 11:35:17 +0200 Subject: [PATCH 4/9] Check for NULL UUIDs match --- src/ble/tests/TestBleUUID.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ble/tests/TestBleUUID.cpp b/src/ble/tests/TestBleUUID.cpp index 40e425d623c9a4..4dbc6dd4c0fcdb 100644 --- a/src/ble/tests/TestBleUUID.cpp +++ b/src/ble/tests/TestBleUUID.cpp @@ -34,6 +34,12 @@ using namespace chip::Ble; namespace { +TEST(TestBleUUID, CheckUUIDsMatch_NULL) +{ + // Test that NULL pointer UUIDs are not equal + EXPECT_FALSE(UUIDsMatch(nullptr, nullptr)); +} + TEST(TestBleUUID, CheckStringToUUID_ChipUUID) { // Test positive scenario - CHIP Service UUID From eeeef54cb1971ab07b79209f5071d4b0b1cc08f3 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 May 2024 13:50:43 +0200 Subject: [PATCH 5/9] Test for exceeding max number of BLE connections --- src/ble/tests/TestBleLayer.cpp | 176 ++++++++++++++++++++------------- 1 file changed, 105 insertions(+), 71 deletions(-) diff --git a/src/ble/tests/TestBleLayer.cpp b/src/ble/tests/TestBleLayer.cpp index 4a23f027787dbc..7c136b9390916f 100644 --- a/src/ble/tests/TestBleLayer.cpp +++ b/src/ble/tests/TestBleLayer.cpp @@ -15,7 +15,9 @@ * limitations under the License. */ +#include #include +#include #include #include @@ -43,55 +45,9 @@ static constexpr ChipBleUUID uuidChar2 = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, static constexpr ChipBleUUID uuidChar3 = { { 0x64, 0x63, 0x02, 0x38, 0x87, 0x72, 0x45, 0xF2, 0xB8, 0x7D, 0x74, 0x8A, 0x83, 0x21, 0x8F, 0x04 } }; -class TestBleLayer : public BleLayer, - private BleApplicationDelegate, - private BleLayerDelegate, - private BlePlatformDelegate, - public ::testing::Test +class BleTestDelegate : public BleApplicationDelegate, public BleLayerDelegate, public BlePlatformDelegate { public: - static void SetUpTestSuite() - { - ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); - ASSERT_EQ(DeviceLayer::SystemLayer().Init(), CHIP_NO_ERROR); - } - - static void TearDownTestSuite() - { - DeviceLayer::SystemLayer().Shutdown(); - chip::Platform::MemoryShutdown(); - } - - void SetUp() - { - ASSERT_EQ(Init(this, nullptr, this, &DeviceLayer::SystemLayer()), CHIP_NO_ERROR); - mBleTransport = this; - } - - void TearDown() - { - mBleTransport = nullptr; - Shutdown(); - } - - // Passing capabilities request message to HandleWriteReceived should create - // new BLE endpoint which later can be used to receive more data. - bool HandleWriteReceivedCapabilitiesRequest() - { - constexpr uint8_t capReq[] = { 0x65, 0x6c, 0x54, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x06 }; - auto connObj = reinterpret_cast(this); - auto buf = System::PacketBufferHandle::NewWithData(capReq, sizeof(capReq)); - return HandleWriteReceived(connObj, &uuidSvc, &uuidChar1, std::move(buf)); - } - - // Processing subscription request after capabilities request should finalize - // connection establishment. - bool HandleSubscribeReceivedOnChar2() - { - auto connObj = reinterpret_cast(this); - return HandleSubscribeReceived(connObj, &uuidSvc, &uuidChar2); - } - /// // Implementation of BleApplicationDelegate @@ -136,6 +92,50 @@ class TestBleLayer : public BleLayer, } }; +class TestBleLayer : public BleLayer, private BleTestDelegate, public ::testing::Test +{ +public: + static void SetUpTestSuite() + { + ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); + ASSERT_EQ(DeviceLayer::SystemLayer().Init(), CHIP_NO_ERROR); + } + + static void TearDownTestSuite() + { + DeviceLayer::SystemLayer().Shutdown(); + chip::Platform::MemoryShutdown(); + } + + void SetUp() + { + ASSERT_EQ(Init(this, this, &DeviceLayer::SystemLayer()), CHIP_NO_ERROR); + mBleTransport = this; + } + + void TearDown() + { + mBleTransport = nullptr; + Shutdown(); + } + + // Passing capabilities request message to HandleWriteReceived should create + // new BLE endpoint which later can be used to receive more data. + bool HandleWriteReceivedCapabilitiesRequest(BLE_CONNECTION_OBJECT connObj) + { + constexpr uint8_t capReq[] = { 0x65, 0x6c, 0x54, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x06 }; + auto buf = System::PacketBufferHandle::NewWithData(capReq, sizeof(capReq)); + return HandleWriteReceived(connObj, &uuidSvc, &uuidChar1, std::move(buf)); + } + + // Processing subscription request after capabilities request should finalize + // connection establishment. + bool HandleSubscribeReceivedOnChar2(BLE_CONNECTION_OBJECT connObj) + { + return HandleSubscribeReceived(connObj, &uuidSvc, &uuidChar2); + } +}; + TEST_F(TestBleLayer, CheckBleTransportCapabilitiesRequestMessage) { auto buf = System::PacketBufferHandle::New(100); @@ -180,7 +180,8 @@ TEST_F(TestBleLayer, CheckBleTransportCapabilitiesResponseMessage) TEST_F(TestBleLayer, HandleWriteReceivedCapabilitiesRequest) { - EXPECT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + auto connObj = reinterpret_cast(this); + EXPECT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); } TEST_F(TestBleLayer, HandleSubscribeReceivedInvalidUUID) @@ -192,8 +193,9 @@ TEST_F(TestBleLayer, HandleSubscribeReceivedInvalidUUID) TEST_F(TestBleLayer, HandleSubscribeReceived) { - ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); - EXPECT_TRUE(HandleSubscribeReceivedOnChar2()); + auto connObj = reinterpret_cast(this); + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + EXPECT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); } TEST_F(TestBleLayer, HandleSubscribeCompleteInvalidUUID) @@ -205,10 +207,10 @@ TEST_F(TestBleLayer, HandleSubscribeCompleteInvalidUUID) TEST_F(TestBleLayer, HandleSubscribeComplete) { - ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); - ASSERT_TRUE(HandleSubscribeReceivedOnChar2()); - auto connObj = reinterpret_cast(this); + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); + EXPECT_TRUE(HandleSubscribeComplete(connObj, &uuidSvc, &uuidChar2)); } @@ -221,10 +223,10 @@ TEST_F(TestBleLayer, HandleUnsubscribeReceivedInvalidUUID) TEST_F(TestBleLayer, HandleUnsubscribeReceived) { - ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); - ASSERT_TRUE(HandleSubscribeReceivedOnChar2()); - auto connObj = reinterpret_cast(this); + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); + EXPECT_TRUE(HandleUnsubscribeReceived(connObj, &uuidSvc, &uuidChar2)); } @@ -237,10 +239,10 @@ TEST_F(TestBleLayer, HandleUnsubscribeCompleteInvalidUUID) TEST_F(TestBleLayer, HandleUnsubscribeComplete) { - ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); - ASSERT_TRUE(HandleSubscribeReceivedOnChar2()); - auto connObj = reinterpret_cast(this); + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); + EXPECT_TRUE(HandleUnsubscribeComplete(connObj, &uuidSvc, &uuidChar2)); } @@ -256,8 +258,9 @@ TEST_F(TestBleLayer, HandleWriteReceivedInvalidUUID) TEST_F(TestBleLayer, HandleWriteReceived) { - ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); - ASSERT_TRUE(HandleSubscribeReceivedOnChar2()); + auto connObj = reinterpret_cast(this); + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); constexpr uint8_t data[] = { to_underlying(BtpEngine::HeaderFlags::kStartMessage) | to_underlying(BtpEngine::HeaderFlags::kEndMessage), @@ -265,7 +268,6 @@ TEST_F(TestBleLayer, HandleWriteReceived) auto buf = System::PacketBufferHandle::NewWithData(data, sizeof(data)); ASSERT_FALSE(buf.IsNull()); - auto connObj = reinterpret_cast(this); EXPECT_TRUE(HandleWriteReceived(connObj, &uuidSvc, &uuidChar1, std::move(buf))); } @@ -276,11 +278,16 @@ TEST_F(TestBleLayer, HandleWriteConfirmationInvalidUUID) EXPECT_FALSE(HandleWriteConfirmation(connObj, &uuidSvc, &uuidChar2)); } -TEST_F(TestBleLayer, HandleWriteConfirmation) +TEST_F(TestBleLayer, HandleWriteConfirmationUninitialized) { - ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); + ASSERT_FALSE(HandleWriteReceivedCapabilitiesRequest(BLE_CONNECTION_UNINITIALIZED)); +} +TEST_F(TestBleLayer, HandleWriteConfirmation) +{ auto connObj = reinterpret_cast(this); + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + EXPECT_TRUE(HandleWriteConfirmation(connObj, &uuidSvc, &uuidChar1)); } @@ -296,8 +303,9 @@ TEST_F(TestBleLayer, HandleIndicationReceivedInvalidUUID) TEST_F(TestBleLayer, HandleIndicationReceived) { - ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); - ASSERT_TRUE(HandleSubscribeReceivedOnChar2()); + auto connObj = reinterpret_cast(this); + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); constexpr uint8_t data[] = { to_underlying(BtpEngine::HeaderFlags::kStartMessage) | to_underlying(BtpEngine::HeaderFlags::kEndMessage), @@ -305,7 +313,6 @@ TEST_F(TestBleLayer, HandleIndicationReceived) auto buf = System::PacketBufferHandle::NewWithData(data, sizeof(data)); ASSERT_FALSE(buf.IsNull()); - auto connObj = reinterpret_cast(this); EXPECT_TRUE(HandleIndicationReceived(connObj, &uuidSvc, &uuidChar2, std::move(buf))); } @@ -318,19 +325,46 @@ TEST_F(TestBleLayer, HandleIndicationConfirmationInvalidUUID) TEST_F(TestBleLayer, HandleIndicationConfirmation) { - ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); - auto connObj = reinterpret_cast(this); + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + EXPECT_TRUE(HandleIndicationConfirmation(connObj, &uuidSvc, &uuidChar2)); } TEST_F(TestBleLayer, HandleConnectionError) { - ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest()); - auto connObj = reinterpret_cast(this); + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + HandleConnectionError(connObj, CHIP_ERROR_ACCESS_DENIED); } +TEST_F(TestBleLayer, CloseBleConnectionUninitialized) +{ + CloseBleConnection(BLE_CONNECTION_UNINITIALIZED); +} + +TEST_F(TestBleLayer, CloseBleConnection) +{ + auto connObj = reinterpret_cast(this); + ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + + CloseBleConnection(connObj); +} + +TEST_F(TestBleLayer, ExceedBleConnectionEndPointLimit) +{ + std::array, BLE_LAYER_NUM_BLE_ENDPOINTS> delegates; + for (auto & delegate : delegates) + { + delegate = std::make_unique(); + auto connObj = reinterpret_cast(delegate.get()); + EXPECT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + } + + auto connObj = reinterpret_cast(this); + EXPECT_FALSE(HandleWriteReceivedCapabilitiesRequest(connObj)); +} + }; // namespace Ble }; // namespace chip From 5a0bc366bb02e6e14a0bfaa18bc61591a3fd9a4f Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 May 2024 15:00:36 +0200 Subject: [PATCH 6/9] Fix compilation on ESP32 --- src/ble/tests/TestBleLayer.cpp | 168 +++++++++++++++++---------------- 1 file changed, 88 insertions(+), 80 deletions(-) diff --git a/src/ble/tests/TestBleLayer.cpp b/src/ble/tests/TestBleLayer.cpp index 7c136b9390916f..ea7865c33a92b1 100644 --- a/src/ble/tests/TestBleLayer.cpp +++ b/src/ble/tests/TestBleLayer.cpp @@ -35,64 +35,31 @@ namespace chip { namespace Ble { -static constexpr ChipBleUUID uuidZero{}; -static constexpr ChipBleUUID uuidSvc = { { 0x00, 0x00, 0xFF, 0xF6, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, - 0xFB } }; -static constexpr ChipBleUUID uuidChar1 = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, - 0x9D, 0x11 } }; -static constexpr ChipBleUUID uuidChar2 = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, - 0x9D, 0x12 } }; -static constexpr ChipBleUUID uuidChar3 = { { 0x64, 0x63, 0x02, 0x38, 0x87, 0x72, 0x45, 0xF2, 0xB8, 0x7D, 0x74, 0x8A, 0x83, 0x21, - 0x8F, 0x04 } }; - -class BleTestDelegate : public BleApplicationDelegate, public BleLayerDelegate, public BlePlatformDelegate +namespace { + +constexpr ChipBleUUID uuidZero{}; +constexpr ChipBleUUID uuidSvc = { { 0x00, 0x00, 0xFF, 0xF6, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, + 0xFB } }; +constexpr ChipBleUUID uuidChar1 = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, + 0x11 } }; +constexpr ChipBleUUID uuidChar2 = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, + 0x12 } }; +constexpr ChipBleUUID uuidChar3 = { { 0x64, 0x63, 0x02, 0x38, 0x87, 0x72, 0x45, 0xF2, 0xB8, 0x7D, 0x74, 0x8A, 0x83, 0x21, 0x8F, + 0x04 } }; + +BLE_CONNECTION_OBJECT GetConnectionObject() { -public: - /// - // Implementation of BleApplicationDelegate - - void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT connObj) override {} - - /// - // Implementation of BleLayerDelegate - - void OnBleConnectionComplete(BLEEndPoint * endpoint) override {} - void OnBleConnectionError(CHIP_ERROR err) override {} - void OnEndPointConnectComplete(BLEEndPoint * endPoint, CHIP_ERROR err) override {} - void OnEndPointMessageReceived(BLEEndPoint * endPoint, System::PacketBufferHandle && msg) override {} - void OnEndPointConnectionClosed(BLEEndPoint * endPoint, CHIP_ERROR err) override {} - CHIP_ERROR SetEndPoint(BLEEndPoint * endPoint) override { return CHIP_NO_ERROR; } - - /// - // Implementation of BlePlatformDelegate + static auto connObj = reinterpret_cast(0x1234); + return ++connObj; +} - bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT, const ChipBleUUID *, const ChipBleUUID *) override { return true; } - bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT, const ChipBleUUID *, const ChipBleUUID *) override { return true; } - bool CloseConnection(BLE_CONNECTION_OBJECT connObj) override { return true; } - uint16_t GetMTU(BLE_CONNECTION_OBJECT connObj) const override { return 0; } - bool SendIndication(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, - PacketBufferHandle pBuf) override - { - return true; - } - bool SendWriteRequest(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, - PacketBufferHandle pBuf) override - { - return true; - } - bool SendReadRequest(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, - PacketBufferHandle pBuf) override - { - return true; - } - bool SendReadResponse(BLE_CONNECTION_OBJECT connObj, BLE_READ_REQUEST_CONTEXT requestContext, const ChipBleUUID * svcId, - const ChipBleUUID * charId) override - { - return true; - } -}; +}; // namespace -class TestBleLayer : public BleLayer, private BleTestDelegate, public ::testing::Test +class TestBleLayer : public BleLayer, + private BleApplicationDelegate, + private BleLayerDelegate, + private BlePlatformDelegate, + public ::testing::Test { public: static void SetUpTestSuite() @@ -134,6 +101,49 @@ class TestBleLayer : public BleLayer, private BleTestDelegate, public ::testing: { return HandleSubscribeReceived(connObj, &uuidSvc, &uuidChar2); } + + /// + // Implementation of BleApplicationDelegate + + void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT connObj) override {} + + /// + // Implementation of BleLayerDelegate + + void OnBleConnectionComplete(BLEEndPoint * endpoint) override {} + void OnBleConnectionError(CHIP_ERROR err) override {} + void OnEndPointConnectComplete(BLEEndPoint * endPoint, CHIP_ERROR err) override {} + void OnEndPointMessageReceived(BLEEndPoint * endPoint, System::PacketBufferHandle && msg) override {} + void OnEndPointConnectionClosed(BLEEndPoint * endPoint, CHIP_ERROR err) override {} + CHIP_ERROR SetEndPoint(BLEEndPoint * endPoint) override { return CHIP_NO_ERROR; } + + /// + // Implementation of BlePlatformDelegate + + bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT, const ChipBleUUID *, const ChipBleUUID *) override { return true; } + bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT, const ChipBleUUID *, const ChipBleUUID *) override { return true; } + bool CloseConnection(BLE_CONNECTION_OBJECT connObj) override { return true; } + uint16_t GetMTU(BLE_CONNECTION_OBJECT connObj) const override { return 0; } + bool SendIndication(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) override + { + return true; + } + bool SendWriteRequest(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) override + { + return true; + } + bool SendReadRequest(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) override + { + return true; + } + bool SendReadResponse(BLE_CONNECTION_OBJECT connObj, BLE_READ_REQUEST_CONTEXT requestContext, const ChipBleUUID * svcId, + const ChipBleUUID * charId) override + { + return true; + } }; TEST_F(TestBleLayer, CheckBleTransportCapabilitiesRequestMessage) @@ -180,34 +190,34 @@ TEST_F(TestBleLayer, CheckBleTransportCapabilitiesResponseMessage) TEST_F(TestBleLayer, HandleWriteReceivedCapabilitiesRequest) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); EXPECT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); } TEST_F(TestBleLayer, HandleSubscribeReceivedInvalidUUID) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleSubscribeReceived(connObj, &uuidZero, &uuidZero)); EXPECT_FALSE(HandleSubscribeReceived(connObj, &uuidSvc, &uuidChar1)); } TEST_F(TestBleLayer, HandleSubscribeReceived) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); EXPECT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); } TEST_F(TestBleLayer, HandleSubscribeCompleteInvalidUUID) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleSubscribeComplete(connObj, &uuidZero, &uuidZero)); EXPECT_FALSE(HandleSubscribeComplete(connObj, &uuidSvc, &uuidChar1)); } TEST_F(TestBleLayer, HandleSubscribeComplete) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); @@ -216,14 +226,14 @@ TEST_F(TestBleLayer, HandleSubscribeComplete) TEST_F(TestBleLayer, HandleUnsubscribeReceivedInvalidUUID) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleUnsubscribeReceived(connObj, &uuidZero, &uuidZero)); EXPECT_FALSE(HandleUnsubscribeReceived(connObj, &uuidSvc, &uuidChar1)); } TEST_F(TestBleLayer, HandleUnsubscribeReceived) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); @@ -232,14 +242,14 @@ TEST_F(TestBleLayer, HandleUnsubscribeReceived) TEST_F(TestBleLayer, HandleUnsubscribeCompleteInvalidUUID) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleUnsubscribeComplete(connObj, &uuidZero, &uuidZero)); EXPECT_FALSE(HandleUnsubscribeComplete(connObj, &uuidSvc, &uuidChar1)); } TEST_F(TestBleLayer, HandleUnsubscribeComplete) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); @@ -248,7 +258,7 @@ TEST_F(TestBleLayer, HandleUnsubscribeComplete) TEST_F(TestBleLayer, HandleWriteReceivedInvalidUUID) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); auto buf = System::PacketBufferHandle::New(0); ASSERT_FALSE(buf.IsNull()); @@ -258,7 +268,7 @@ TEST_F(TestBleLayer, HandleWriteReceivedInvalidUUID) TEST_F(TestBleLayer, HandleWriteReceived) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); @@ -273,7 +283,7 @@ TEST_F(TestBleLayer, HandleWriteReceived) TEST_F(TestBleLayer, HandleWriteConfirmationInvalidUUID) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleWriteConfirmation(connObj, &uuidZero, &uuidZero)); EXPECT_FALSE(HandleWriteConfirmation(connObj, &uuidSvc, &uuidChar2)); } @@ -285,7 +295,7 @@ TEST_F(TestBleLayer, HandleWriteConfirmationUninitialized) TEST_F(TestBleLayer, HandleWriteConfirmation) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); EXPECT_TRUE(HandleWriteConfirmation(connObj, &uuidSvc, &uuidChar1)); @@ -293,7 +303,7 @@ TEST_F(TestBleLayer, HandleWriteConfirmation) TEST_F(TestBleLayer, HandleIndicationReceivedInvalidUUID) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); auto buf = System::PacketBufferHandle::New(0); ASSERT_FALSE(buf.IsNull()); @@ -303,7 +313,7 @@ TEST_F(TestBleLayer, HandleIndicationReceivedInvalidUUID) TEST_F(TestBleLayer, HandleIndicationReceived) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); @@ -318,14 +328,14 @@ TEST_F(TestBleLayer, HandleIndicationReceived) TEST_F(TestBleLayer, HandleIndicationConfirmationInvalidUUID) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleIndicationConfirmation(connObj, &uuidZero, &uuidZero)); EXPECT_FALSE(HandleIndicationConfirmation(connObj, &uuidSvc, &uuidChar1)); } TEST_F(TestBleLayer, HandleIndicationConfirmation) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); EXPECT_TRUE(HandleIndicationConfirmation(connObj, &uuidSvc, &uuidChar2)); @@ -333,7 +343,7 @@ TEST_F(TestBleLayer, HandleIndicationConfirmation) TEST_F(TestBleLayer, HandleConnectionError) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); HandleConnectionError(connObj, CHIP_ERROR_ACCESS_DENIED); @@ -346,7 +356,7 @@ TEST_F(TestBleLayer, CloseBleConnectionUninitialized) TEST_F(TestBleLayer, CloseBleConnection) { - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); CloseBleConnection(connObj); @@ -354,15 +364,13 @@ TEST_F(TestBleLayer, CloseBleConnection) TEST_F(TestBleLayer, ExceedBleConnectionEndPointLimit) { - std::array, BLE_LAYER_NUM_BLE_ENDPOINTS> delegates; - for (auto & delegate : delegates) + for (size_t i = 0; i < BLE_LAYER_NUM_BLE_ENDPOINTS; i++) { - delegate = std::make_unique(); - auto connObj = reinterpret_cast(delegate.get()); - EXPECT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); + // Saturate BLE end-point pool + EXPECT_TRUE(HandleWriteReceivedCapabilitiesRequest(GetConnectionObject())); } - auto connObj = reinterpret_cast(this); + auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleWriteReceivedCapabilitiesRequest(connObj)); } From 55d7dcc137165d61f9f99dc9cbb0d1fcbf9b2bda Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 May 2024 15:53:37 +0200 Subject: [PATCH 7/9] More compilation fixes --- src/ble/tests/TestBleLayer.cpp | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/ble/tests/TestBleLayer.cpp b/src/ble/tests/TestBleLayer.cpp index ea7865c33a92b1..c5262bd0c90af4 100644 --- a/src/ble/tests/TestBleLayer.cpp +++ b/src/ble/tests/TestBleLayer.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -47,12 +48,6 @@ constexpr ChipBleUUID uuidChar2 = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, constexpr ChipBleUUID uuidChar3 = { { 0x64, 0x63, 0x02, 0x38, 0x87, 0x72, 0x45, 0xF2, 0xB8, 0x7D, 0x74, 0x8A, 0x83, 0x21, 0x8F, 0x04 } }; -BLE_CONNECTION_OBJECT GetConnectionObject() -{ - static auto connObj = reinterpret_cast(0x1234); - return ++connObj; -} - }; // namespace class TestBleLayer : public BleLayer, @@ -86,6 +81,25 @@ class TestBleLayer : public BleLayer, Shutdown(); } + // Return unique BLE connection object for each call. + template + BLE_CONNECTION_OBJECT GetConnectionObject() + { + T conn = BLE_CONNECTION_UNINITIALIZED; + + if constexpr (std::is_pointer_v) + { + conn = reinterpret_cast(&mNumConnection + mNumConnection); + } + else + { + conn = static_cast(mNumConnection); + } + + mNumConnection++; + return conn; + } + // Passing capabilities request message to HandleWriteReceived should create // new BLE endpoint which later can be used to receive more data. bool HandleWriteReceivedCapabilitiesRequest(BLE_CONNECTION_OBJECT connObj) @@ -144,6 +158,9 @@ class TestBleLayer : public BleLayer, { return true; } + +private: + unsigned int mNumConnection = 0; }; TEST_F(TestBleLayer, CheckBleTransportCapabilitiesRequestMessage) From 165e976fee29470f1d8ae023b5a09d8798527f9f Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 8 May 2024 19:40:55 +0200 Subject: [PATCH 8/9] Mark SetUp and TearDown as overrides --- src/ble/tests/TestBleLayer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ble/tests/TestBleLayer.cpp b/src/ble/tests/TestBleLayer.cpp index c5262bd0c90af4..b19e995b987750 100644 --- a/src/ble/tests/TestBleLayer.cpp +++ b/src/ble/tests/TestBleLayer.cpp @@ -69,13 +69,13 @@ class TestBleLayer : public BleLayer, chip::Platform::MemoryShutdown(); } - void SetUp() + void SetUp() override { ASSERT_EQ(Init(this, this, &DeviceLayer::SystemLayer()), CHIP_NO_ERROR); mBleTransport = this; } - void TearDown() + void TearDown() override { mBleTransport = nullptr; Shutdown(); From eb72c8dea653d369cfb9ee890d8ba09071e9361c Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Thu, 9 May 2024 09:27:55 +0200 Subject: [PATCH 9/9] Update includes --- src/ble/tests/TestBleLayer.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ble/tests/TestBleLayer.cpp b/src/ble/tests/TestBleLayer.cpp index b19e995b987750..9b79037acd0ea1 100644 --- a/src/ble/tests/TestBleLayer.cpp +++ b/src/ble/tests/TestBleLayer.cpp @@ -15,16 +15,21 @@ * limitations under the License. */ -#include #include -#include -#include +#include +#include #include +#include #include +#include #include +#include +#include +#include #include +#include #include #define _CHIP_BLE_BLE_H