diff --git a/src/ble/BLEEndPoint.cpp b/src/ble/BLEEndPoint.cpp
index ba6400f..0e69e59 100644
--- a/src/ble/BLEEndPoint.cpp
+++ b/src/ble/BLEEndPoint.cpp
@@ -346,7 +346,7 @@
                 DoCloseCallback(oldState, flags, err);
             }
 
-            if ((flags & kBleCloseFlag_SuppressCallback) != 0)
+            if (mBleTransport != nullptr && (flags & kBleCloseFlag_SuppressCallback) != 0)
             {
                 mBleTransport->OnEndPointConnectionClosed(this, err);
             }
@@ -367,7 +367,7 @@
         DoCloseCallback(oldState, flags, err);
     }
 
-    if ((flags & kBleCloseFlag_SuppressCallback) != 0)
+    if (mBleTransport != nullptr && (flags & kBleCloseFlag_SuppressCallback) != 0)
     {
         mBleTransport->OnEndPointConnectionClosed(this, err);
     }
@@ -1290,7 +1290,7 @@
         // 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<unsigned>(full_packet->DataLength()));
 
         // If we have a message received callback, and end point is not closing...
         if (mBleTransport != nullptr && mState != kState_Closing)
diff --git a/src/ble/BleLayer.cpp b/src/ble/BleLayer.cpp
index d4a1e32..de1f845 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 @@
 bool BleLayer::HandleWriteReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
                                    PacketBufferHandle && pBuf)
 {
-    if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId))
+    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"));
+
+    // Find matching connection end point.
+    BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
+
+    if (endPoint != nullptr)
     {
-        ChipLogError(Ble, "ble write rcvd on unknown svc id");
-        return true;
-    }
-
-    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);
-
-        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());
-            }
-        }
+        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::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);
+    VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for received indication"));
 
-        // 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
-        {
-            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;
-    }
+    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"));
 
-    if (UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId))
-    {
-        HandleAckReceived(connObj);
-    }
-    else
-    {
-        ChipLogError(Ble, "ble write con rcvd 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;
-    }
+    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"));
 
-    if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId))
-    {
-        HandleAckReceived(connObj);
-    }
-    else
-    {
-        ChipLogError(Ble, "ble ind con rcvd 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);
+    // 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"));
 
-        if (endPoint != nullptr)
-        {
-            endPoint->HandleSubscribeReceived();
-        }
-        else
-        {
-            ChipLogError(Ble, "no endpoint for sub recvd");
-        }
-    }
-
+    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);
+    BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
+    VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for subscribe complete"));
 
-        if (endPoint != nullptr)
-        {
-            endPoint->HandleSubscribeComplete();
-        }
-        else
-        {
-            ChipLogError(Ble, "no endpoint for sub 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);
+    // 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"));
 
-        if (endPoint != nullptr)
-        {
-            endPoint->DoClose(kBleCloseFlag_AbortTransmission, BLE_ERROR_CENTRAL_UNSUBSCRIBED);
-        }
-        else
-        {
-            ChipLogError(Ble, "no endpoint for unsub recvd");
-        }
-    }
-
+    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);
+    // 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"));
 
-        if (endPoint != nullptr)
-        {
-            endPoint->HandleUnsubscribeComplete();
-        }
-        else
-        {
-            ChipLogError(Ble, "no endpoint for unsub complete");
-        }
-    }
-
+    endPoint->HandleUnsubscribeComplete();
     return true;
 }
 
@@ -728,19 +614,17 @@
 {
     // 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 bad3ab3..e7d619f 100644
--- a/src/ble/BleLayer.h
+++ b/src/ble/BleLayer.h
@@ -327,7 +327,6 @@
 
     // 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);
diff --git a/src/ble/tests/BUILD.gn b/src/ble/tests/BUILD.gn
index 687ad7b..ac897ab 100644
--- a/src/ble/tests/BUILD.gn
+++ b/src/ble/tests/BUILD.gn
@@ -22,11 +22,15 @@
 
   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 0000000..9b79037
--- /dev/null
+++ b/src/ble/tests/TestBleLayer.cpp
@@ -0,0 +1,400 @@
+/*
+ *
+ *    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 <cstdint>
+#include <cstring>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#include <gtest/gtest.h>
+
+#include <lib/core/CHIPError.h>
+#include <lib/support/CHIPMem.h>
+#include <lib/support/Span.h>
+#include <lib/support/TypeTraits.h>
+#include <lib/support/logging/CHIPLogging.h>
+#include <platform/CHIPDeviceLayer.h>
+#include <system/SystemLayer.h>
+#include <system/SystemPacketBuffer.h>
+
+#define _CHIP_BLE_BLE_H
+#include <ble/BleApplicationDelegate.h>
+#include <ble/BleLayer.h>
+#include <ble/BleLayerDelegate.h>
+#include <ble/BlePlatformDelegate.h>
+
+namespace chip {
+namespace Ble {
+
+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 } };
+
+}; // namespace
+
+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() override
+    {
+        ASSERT_EQ(Init(this, this, &DeviceLayer::SystemLayer()), CHIP_NO_ERROR);
+        mBleTransport = this;
+    }
+
+    void TearDown() override
+    {
+        mBleTransport = nullptr;
+        Shutdown();
+    }
+
+    // Return unique BLE connection object for each call.
+    template <typename T = BLE_CONNECTION_OBJECT>
+    BLE_CONNECTION_OBJECT GetConnectionObject()
+    {
+        T conn = BLE_CONNECTION_UNINITIALIZED;
+
+        if constexpr (std::is_pointer_v<T>)
+        {
+            conn = reinterpret_cast<T>(&mNumConnection + mNumConnection);
+        }
+        else
+        {
+            conn = static_cast<T>(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)
+    {
+        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);
+    }
+
+    ///
+    // 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;
+    }
+
+private:
+    unsigned int mNumConnection = 0;
+};
+
+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)
+{
+    auto connObj = GetConnectionObject();
+    EXPECT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+}
+
+TEST_F(TestBleLayer, HandleSubscribeReceivedInvalidUUID)
+{
+    auto connObj = GetConnectionObject();
+    EXPECT_FALSE(HandleSubscribeReceived(connObj, &uuidZero, &uuidZero));
+    EXPECT_FALSE(HandleSubscribeReceived(connObj, &uuidSvc, &uuidChar1));
+}
+
+TEST_F(TestBleLayer, HandleSubscribeReceived)
+{
+    auto connObj = GetConnectionObject();
+    ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+    EXPECT_TRUE(HandleSubscribeReceivedOnChar2(connObj));
+}
+
+TEST_F(TestBleLayer, HandleSubscribeCompleteInvalidUUID)
+{
+    auto connObj = GetConnectionObject();
+    EXPECT_FALSE(HandleSubscribeComplete(connObj, &uuidZero, &uuidZero));
+    EXPECT_FALSE(HandleSubscribeComplete(connObj, &uuidSvc, &uuidChar1));
+}
+
+TEST_F(TestBleLayer, HandleSubscribeComplete)
+{
+    auto connObj = GetConnectionObject();
+    ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+    ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj));
+
+    EXPECT_TRUE(HandleSubscribeComplete(connObj, &uuidSvc, &uuidChar2));
+}
+
+TEST_F(TestBleLayer, HandleUnsubscribeReceivedInvalidUUID)
+{
+    auto connObj = GetConnectionObject();
+    EXPECT_FALSE(HandleUnsubscribeReceived(connObj, &uuidZero, &uuidZero));
+    EXPECT_FALSE(HandleUnsubscribeReceived(connObj, &uuidSvc, &uuidChar1));
+}
+
+TEST_F(TestBleLayer, HandleUnsubscribeReceived)
+{
+    auto connObj = GetConnectionObject();
+    ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+    ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj));
+
+    EXPECT_TRUE(HandleUnsubscribeReceived(connObj, &uuidSvc, &uuidChar2));
+}
+
+TEST_F(TestBleLayer, HandleUnsubscribeCompleteInvalidUUID)
+{
+    auto connObj = GetConnectionObject();
+    EXPECT_FALSE(HandleUnsubscribeComplete(connObj, &uuidZero, &uuidZero));
+    EXPECT_FALSE(HandleUnsubscribeComplete(connObj, &uuidSvc, &uuidChar1));
+}
+
+TEST_F(TestBleLayer, HandleUnsubscribeComplete)
+{
+    auto connObj = GetConnectionObject();
+    ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+    ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj));
+
+    EXPECT_TRUE(HandleUnsubscribeComplete(connObj, &uuidSvc, &uuidChar2));
+}
+
+TEST_F(TestBleLayer, HandleWriteReceivedInvalidUUID)
+{
+    auto connObj = GetConnectionObject();
+    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)
+{
+    auto connObj = GetConnectionObject();
+    ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+    ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj));
+
+    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());
+
+    EXPECT_TRUE(HandleWriteReceived(connObj, &uuidSvc, &uuidChar1, std::move(buf)));
+}
+
+TEST_F(TestBleLayer, HandleWriteConfirmationInvalidUUID)
+{
+    auto connObj = GetConnectionObject();
+    EXPECT_FALSE(HandleWriteConfirmation(connObj, &uuidZero, &uuidZero));
+    EXPECT_FALSE(HandleWriteConfirmation(connObj, &uuidSvc, &uuidChar2));
+}
+
+TEST_F(TestBleLayer, HandleWriteConfirmationUninitialized)
+{
+    ASSERT_FALSE(HandleWriteReceivedCapabilitiesRequest(BLE_CONNECTION_UNINITIALIZED));
+}
+
+TEST_F(TestBleLayer, HandleWriteConfirmation)
+{
+    auto connObj = GetConnectionObject();
+    ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+
+    EXPECT_TRUE(HandleWriteConfirmation(connObj, &uuidSvc, &uuidChar1));
+}
+
+TEST_F(TestBleLayer, HandleIndicationReceivedInvalidUUID)
+{
+    auto connObj = GetConnectionObject();
+    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)
+{
+    auto connObj = GetConnectionObject();
+    ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+    ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj));
+
+    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());
+
+    EXPECT_TRUE(HandleIndicationReceived(connObj, &uuidSvc, &uuidChar2, std::move(buf)));
+}
+
+TEST_F(TestBleLayer, HandleIndicationConfirmationInvalidUUID)
+{
+    auto connObj = GetConnectionObject();
+    EXPECT_FALSE(HandleIndicationConfirmation(connObj, &uuidZero, &uuidZero));
+    EXPECT_FALSE(HandleIndicationConfirmation(connObj, &uuidSvc, &uuidChar1));
+}
+
+TEST_F(TestBleLayer, HandleIndicationConfirmation)
+{
+    auto connObj = GetConnectionObject();
+    ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+
+    EXPECT_TRUE(HandleIndicationConfirmation(connObj, &uuidSvc, &uuidChar2));
+}
+
+TEST_F(TestBleLayer, HandleConnectionError)
+{
+    auto connObj = GetConnectionObject();
+    ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+
+    HandleConnectionError(connObj, CHIP_ERROR_ACCESS_DENIED);
+}
+
+TEST_F(TestBleLayer, CloseBleConnectionUninitialized)
+{
+    CloseBleConnection(BLE_CONNECTION_UNINITIALIZED);
+}
+
+TEST_F(TestBleLayer, CloseBleConnection)
+{
+    auto connObj = GetConnectionObject();
+    ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj));
+
+    CloseBleConnection(connObj);
+}
+
+TEST_F(TestBleLayer, ExceedBleConnectionEndPointLimit)
+{
+    for (size_t i = 0; i < BLE_LAYER_NUM_BLE_ENDPOINTS; i++)
+    {
+        // Saturate BLE end-point pool
+        EXPECT_TRUE(HandleWriteReceivedCapabilitiesRequest(GetConnectionObject()));
+    }
+
+    auto connObj = GetConnectionObject();
+    EXPECT_FALSE(HandleWriteReceivedCapabilitiesRequest(connObj));
+}
+
+}; // namespace Ble
+}; // namespace chip
diff --git a/src/ble/tests/TestBleUUID.cpp b/src/ble/tests/TestBleUUID.cpp
index 40e425d..4dbc6dd 100644
--- a/src/ble/tests/TestBleUUID.cpp
+++ b/src/ble/tests/TestBleUUID.cpp
@@ -34,6 +34,12 @@
 
 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
