diff --git a/examples/contact-sensor-app/nxp/k32w1/BUILD.gn b/examples/contact-sensor-app/nxp/k32w1/BUILD.gn
index e887b2c5cc4f7f..8e215d4c7d6517 100644
--- a/examples/contact-sensor-app/nxp/k32w1/BUILD.gn
+++ b/examples/contact-sensor-app/nxp/k32w1/BUILD.gn
@@ -139,9 +139,11 @@ mcxw71_k32w1_executable("contact_sensor_app") {
     "${common_example_dir}/low_power/include",
     "${common_example_dir}/operational_keystore/include",
     "${common_example_dir}/ui_feedback/include",
+    "${common_example_dir}/app_ble/include",
   ]
 
   sources += [
+    "${common_example_dir}/app_ble/source/BLEApplicationManagerEmpty.cpp",
     "${common_example_dir}/app_task/source/AppTaskBase.cpp",
     "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp",
     "${common_example_dir}/clusters/source/ZclCallbacks.cpp",
diff --git a/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn b/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn
index 87b25125d1c47c..cf22ec5c658509 100644
--- a/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn
+++ b/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn
@@ -138,9 +138,11 @@ mcxw71_k32w1_executable("contact_sensor_app") {
     "${common_example_dir}/low_power/include",
     "${common_example_dir}/operational_keystore/include",
     "${common_example_dir}/ui_feedback/include",
+    "${common_example_dir}/app_ble/include",
   ]
 
   sources += [
+    "${common_example_dir}/app_ble/source/BLEApplicationManagerEmpty.cpp",
     "${common_example_dir}/app_task/source/AppTaskBase.cpp",
     "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp",
     "${common_example_dir}/clusters/source/ZclCallbacks.cpp",
diff --git a/examples/lighting-app/nxp/k32w1/BUILD.gn b/examples/lighting-app/nxp/k32w1/BUILD.gn
index 8b5bd6b2cd77f2..54030a789763ea 100644
--- a/examples/lighting-app/nxp/k32w1/BUILD.gn
+++ b/examples/lighting-app/nxp/k32w1/BUILD.gn
@@ -146,9 +146,11 @@ mcxw71_k32w1_executable("light_app") {
     "${common_example_dir}/operational_keystore/include",
     "${common_example_dir}/rpc/include",
     "${common_example_dir}/ui_feedback/include",
+    "${common_example_dir}/app_ble/include",
   ]
 
   sources += [
+    "${common_example_dir}/app_ble/source/BLEApplicationManagerEmpty.cpp",
     "${common_example_dir}/app_task/source/AppTaskBase.cpp",
     "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp",
     "${common_example_dir}/clusters/source/ZclCallbacks.cpp",
diff --git a/examples/lighting-app/nxp/mcxw71/BUILD.gn b/examples/lighting-app/nxp/mcxw71/BUILD.gn
index b5d393dc6b9afc..efd3af6fd5e19a 100644
--- a/examples/lighting-app/nxp/mcxw71/BUILD.gn
+++ b/examples/lighting-app/nxp/mcxw71/BUILD.gn
@@ -146,9 +146,11 @@ mcxw71_k32w1_executable("light_app") {
     "${common_example_dir}/operational_keystore/include",
     "${common_example_dir}/rpc/include",
     "${common_example_dir}/ui_feedback/include",
+    "${common_example_dir}/app_ble/include",
   ]
 
   sources += [
+    "${common_example_dir}/app_ble/source/BLEApplicationManagerEmpty.cpp",
     "${common_example_dir}/app_task/source/AppTaskBase.cpp",
     "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp",
     "${common_example_dir}/clusters/source/ZclCallbacks.cpp",
diff --git a/examples/lock-app/nxp/common/main/AppTask.cpp b/examples/lock-app/nxp/common/main/AppTask.cpp
index 26a385ec0b2c97..d2a983e68d32ad 100644
--- a/examples/lock-app/nxp/common/main/AppTask.cpp
+++ b/examples/lock-app/nxp/common/main/AppTask.cpp
@@ -19,6 +19,7 @@
  */
 
 #include "AppTask.h"
+#include "BLEApplicationManager.h"
 #include "CHIPDeviceManager.h"
 #include "LockManager.h"
 #include <app-common/zap-generated/attributes/Accessors.h>
@@ -115,6 +116,9 @@ static CHIP_ERROR cliDoorLock(int argc, char * argv[])
 void LockApp::AppTask::PreInitMatterStack()
 {
     ChipLogProgress(DeviceLayer, "Welcome to NXP Lock Demo App");
+
+    /* BLEApplicationManager implemented per platform or left blank */
+    chip::NXP::App::BleAppMgr().Init();
 }
 
 void LockApp::AppTask::PostInitMatterStack()
diff --git a/examples/lock-app/nxp/k32w1/BUILD.gn b/examples/lock-app/nxp/k32w1/BUILD.gn
index 42cff8a8b42c45..602398e0d604b4 100644
--- a/examples/lock-app/nxp/k32w1/BUILD.gn
+++ b/examples/lock-app/nxp/k32w1/BUILD.gn
@@ -92,6 +92,14 @@ mcxw71_k32w1_sdk("sdk") {
       "${example_platform_dir}/board/peripherals.h",
     ]
   }
+
+  if (nxp_multiple_ble_connections) {
+    include_dirs += [ "${example_platform_dir}/app_ble/include" ]
+    defines += [
+      "EXTRA_GATT_DB_HEADER=\"extra_gatt_db.h\"",
+      "EXTRA_GATT_UUID_HEADER=\"extra_gatt_uuid128.h\"",
+    ]
+  }
 }
 
 mcxw71_k32w1_executable("lock_app") {
@@ -140,6 +148,7 @@ mcxw71_k32w1_executable("lock_app") {
     "${common_example_dir}/low_power/include",
     "${common_example_dir}/operational_keystore/include",
     "${common_example_dir}/ui_feedback/include",
+    "${common_example_dir}/app_ble/include",
   ]
 
   sources += [
@@ -189,6 +198,15 @@ mcxw71_k32w1_executable("lock_app") {
     deps += [ "${chip_root}/src/platform/nxp:nxp_ota" ]
   }
 
+  if (nxp_multiple_ble_connections) {
+    sources +=
+        [ "${example_platform_dir}/app_ble/source/BLEApplicationManager.cpp" ]
+  } else {
+    sources += [
+      "${common_example_dir}/app_ble/source/BLEApplicationManagerEmpty.cpp",
+    ]
+  }
+
   if (chip_with_diag_logs_demo) {
     sources += [
       "${common_example_dir}/diagnostic_logs/source/DiagnosticLogsDemo.cpp",
diff --git a/examples/lock-app/nxp/k32w1/README.md b/examples/lock-app/nxp/k32w1/README.md
index 9b3cd33c1d4ed2..a085d94afd29d6 100644
--- a/examples/lock-app/nxp/k32w1/README.md
+++ b/examples/lock-app/nxp/k32w1/README.md
@@ -12,6 +12,7 @@ For generic information related to door lock application, please see the
         -   [Flashing the host image](#flashing-the-host-image)
     -   [Debugging](#debugging)
     -   [OTA](#ota)
+    -   [Multiple BLE connections](#multiple-ble-connections)
 
 ## Introduction
 
@@ -163,3 +164,15 @@ Run -> Debug Configurations... -> C/C++ Application
 
 Please see
 [k32w1 OTA guide](../../../../docs/guides/nxp/nxp_mcxw71_ota_guide.md).
+
+## Multiple BLE connections
+
+To compile with the Multiple BLE connections support demo example add the gn
+argument `nxp_multiple_ble_connections=true`.
+
+The application will accept multiple BLE connections after commissioning, by
+pressing the BLE advertise button again. Once discovered by a BLE central, a
+custom GATT service will be visible on the device.
+
+The user can change the default behavior by implementing the class defined in
+[BLEApplicationManager.h](../../../platform/nxp/common/app_ble/include/BLEApplicationManager.h)
diff --git a/examples/lock-app/nxp/mcxw71/BUILD.gn b/examples/lock-app/nxp/mcxw71/BUILD.gn
index febab870a524ca..6d105f16ffd163 100644
--- a/examples/lock-app/nxp/mcxw71/BUILD.gn
+++ b/examples/lock-app/nxp/mcxw71/BUILD.gn
@@ -92,6 +92,14 @@ mcxw71_k32w1_sdk("sdk") {
       "${example_platform_dir}/board/peripherals.h",
     ]
   }
+
+  if (nxp_multiple_ble_connections) {
+    include_dirs += [ "${example_platform_dir}/app_ble/include" ]
+    defines += [
+      "EXTRA_GATT_DB_HEADER=\"extra_gatt_db.h\"",
+      "EXTRA_GATT_UUID_HEADER=\"extra_gatt_uuid128.h\"",
+    ]
+  }
 }
 
 mcxw71_k32w1_executable("lock_app") {
@@ -140,6 +148,7 @@ mcxw71_k32w1_executable("lock_app") {
     "${common_example_dir}/low_power/include",
     "${common_example_dir}/operational_keystore/include",
     "${common_example_dir}/ui_feedback/include",
+    "${common_example_dir}/app_ble/include",
   ]
 
   sources += [
@@ -189,6 +198,15 @@ mcxw71_k32w1_executable("lock_app") {
     deps += [ "${chip_root}/src/platform/nxp:nxp_ota" ]
   }
 
+  if (nxp_multiple_ble_connections) {
+    sources +=
+        [ "${example_platform_dir}/app_ble/source/BLEApplicationManager.cpp" ]
+  } else {
+    sources += [
+      "${common_example_dir}/app_ble/source/BLEApplicationManagerEmpty.cpp",
+    ]
+  }
+
   if (chip_with_diag_logs_demo) {
     sources += [
       "${common_example_dir}/diagnostic_logs/source/DiagnosticLogsDemo.cpp",
diff --git a/examples/lock-app/nxp/mcxw71/README.md b/examples/lock-app/nxp/mcxw71/README.md
index 593aed82f58641..db877d0c0075f7 100644
--- a/examples/lock-app/nxp/mcxw71/README.md
+++ b/examples/lock-app/nxp/mcxw71/README.md
@@ -12,6 +12,7 @@ For generic information related to door lock application, please see the
         -   [Flashing the host image](#flashing-the-host-image)
     -   [Debugging](#debugging)
     -   [OTA](#ota)
+    -   [Multiple BLE connections](#multiple-ble-connections)
 
 ## Introduction
 
@@ -195,3 +196,15 @@ Run -> Debug Configurations... -> C/C++ Application
 
 Please see
 [mcxw71 OTA guide](../../../../docs/guides/nxp/nxp_mcxw71_ota_guide.md).
+
+## Multiple BLE connections
+
+To compile with the Multiple BLE connections support demo example add the gn
+argument `nxp_multiple_ble_connections=true`.
+
+The application will accept multiple BLE connections after commissioning, by
+pressing the BLE advertise button again. Once discovered by a BLE central, a
+custom GATT service will be visible on the device.
+
+The user can change the default behavior by implementing the class defined in
+[BLEApplicationManager.h](../../../platform/nxp/common/app_ble/include/BLEApplicationManager.h)
diff --git a/examples/platform/nxp/common/app_ble/include/BLEApplicationManager.h b/examples/platform/nxp/common/app_ble/include/BLEApplicationManager.h
new file mode 100644
index 00000000000000..21a417d9ced7ce
--- /dev/null
+++ b/examples/platform/nxp/common/app_ble/include/BLEApplicationManager.h
@@ -0,0 +1,49 @@
+/*
+ *
+ *    Copyright (c) 2024 Project CHIP Authors
+ *    Copyright 2024 NXP
+ *    All rights reserved.
+ *
+ *    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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+namespace chip::NXP::App {
+
+/**
+ * @brief This class describes a manager for extra application BLE-related
+ * functionality (e.g multiple BLE connections).
+ *
+ */
+class BLEApplicationManager
+{
+public:
+    void Init();
+    void EnableMultipleConnectionsHandler();
+
+private:
+    static void EnableMultipleConnections(intptr_t arg);
+
+    friend BLEApplicationManager & BleAppMgr();
+    static BLEApplicationManager sInstance;
+};
+
+inline BLEApplicationManager & BleAppMgr()
+{
+    return BLEApplicationManager::sInstance;
+}
+
+} // namespace chip::NXP::App
diff --git a/examples/platform/nxp/common/app_ble/source/BLEApplicationManagerEmpty.cpp b/examples/platform/nxp/common/app_ble/source/BLEApplicationManagerEmpty.cpp
new file mode 100644
index 00000000000000..17682f85738f1a
--- /dev/null
+++ b/examples/platform/nxp/common/app_ble/source/BLEApplicationManagerEmpty.cpp
@@ -0,0 +1,39 @@
+/*
+ *
+ *    Copyright (c) 2024 Project CHIP Authors
+ *    Copyright 2024 NXP
+ *    All rights reserved.
+ *
+ *    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 "BLEApplicationManager.h"
+
+using namespace ::chip::NXP::App;
+
+BLEApplicationManager BLEApplicationManager::sInstance;
+
+void BLEApplicationManager::Init(void)
+{
+    /*Empty implementation. Intentionally left blank */
+}
+
+void BLEApplicationManager::EnableMultipleConnectionsHandler(void)
+{
+    /*Empty implementation. Intentionally left blank */
+}
+
+void BLEApplicationManager::EnableMultipleConnections(intptr_t arg)
+{
+    /*Empty implementation. Intentionally left blank */
+}
diff --git a/examples/platform/nxp/mcxw71_k32w1/app_ble/include/extra_gatt_db.h b/examples/platform/nxp/mcxw71_k32w1/app_ble/include/extra_gatt_db.h
new file mode 100644
index 00000000000000..d30a4064a9ac5e
--- /dev/null
+++ b/examples/platform/nxp/mcxw71_k32w1/app_ble/include/extra_gatt_db.h
@@ -0,0 +1,4 @@
+PRIMARY_SERVICE_UUID128(service_wireless_uart, uuid_service_wireless_uart)
+CHARACTERISTIC_UUID128(char_uart_stream, uuid_uart_stream, (gGattCharPropWriteWithoutRsp_c))
+VALUE_UUID128_VARLEN(value_uart_stream, uuid_uart_stream, (gPermissionFlagWritable_c), gAttMaxWriteDataSize_d(gAttMaxMtu_c), 1,
+                     0x00)
diff --git a/examples/platform/nxp/mcxw71_k32w1/app_ble/include/extra_gatt_uuid128.h b/examples/platform/nxp/mcxw71_k32w1/app_ble/include/extra_gatt_uuid128.h
new file mode 100644
index 00000000000000..b741d0bc348cdd
--- /dev/null
+++ b/examples/platform/nxp/mcxw71_k32w1/app_ble/include/extra_gatt_uuid128.h
@@ -0,0 +1,23 @@
+/*
+* Declare all custom 128-bit UUIDs here using the format:
+*
+*  UUID128(name, bytes)
+*
+* where:
+*	-name : an unique tag for the newly defined UUID;
+                will be used to reference this UUID when defining
+                services and characteristics in <<gattDb.h>>
+*	-bytes: 16 bytes representing the 128-bit value
+*
+* One definition per line. No semicolon required after each definition.
+*
+* example:
+*  UUID128(uuid_service_robot_characteristics, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB,
+0xCD, 0xEF)
+*  UUID128(uuid_char_robot_direction, 0x12, 0x34, 0x50, 0x00, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD,
+0xEF)
+*/
+/* Services */
+
+UUID128(uuid_service_wireless_uart, 0xE0, 0x1C, 0x4B, 0x5E, 0x1E, 0xEB, 0xA1, 0x5C, 0xEE, 0xF4, 0x5E, 0xBA, 0x00, 0x01, 0xFF, 0x01)
+UUID128(uuid_uart_stream, 0xE0, 0x1C, 0x4B, 0x5E, 0x1E, 0xEB, 0xA1, 0x5C, 0xEE, 0xF4, 0x5E, 0xBA, 0x01, 0x01, 0xFF, 0x01)
diff --git a/examples/platform/nxp/mcxw71_k32w1/app_ble/source/BLEApplicationManager.cpp b/examples/platform/nxp/mcxw71_k32w1/app_ble/source/BLEApplicationManager.cpp
new file mode 100644
index 00000000000000..1a3b9113a24736
--- /dev/null
+++ b/examples/platform/nxp/mcxw71_k32w1/app_ble/source/BLEApplicationManager.cpp
@@ -0,0 +1,94 @@
+/*
+ *
+ *    Copyright (c) 2024 Project CHIP Authors
+ *    Copyright 2024 NXP
+ *    All rights reserved.
+ *
+ *    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 "BLEApplicationManager.h"
+
+#include <platform/ConfigurationManager.h>
+#include <platform/ConnectivityManager.h>
+#include <platform/PlatformManager.h>
+#include <src/platform/nxp/common/ble/BLEManagerCommon.h>
+
+#include "gatt_db_app_interface.h"
+#include "gatt_db_handles.h"
+
+using namespace ::chip::DeviceLayer;
+using namespace ::chip::DeviceLayer::Internal;
+using namespace ::chip::NXP::App;
+
+BLEApplicationManager BLEApplicationManager::sInstance;
+
+void app_gap_callback(gapGenericEvent_t * event)
+{
+    /*Demo Gap application callback*/
+}
+
+void app_gatt_callback(deviceId_t id, gattServerEvent_t * event)
+{
+    /*Demo Gatt application callback*/
+
+    if (event->eventType == gEvtAttributeWrittenWithoutResponse_c)
+    {
+        if (event->eventData.attributeWrittenEvent.handle == value_uart_stream)
+        {
+            ChipLogProgress(DeviceLayer, "Write to custom service");
+        }
+    }
+}
+
+void BLEApplicationManager::Init(void)
+{
+    CHIP_ERROR err    = CHIP_NO_ERROR;
+    auto * bleManager = &chip::DeviceLayer::Internal::BLEMgrImpl();
+
+    bleManager->RegisterAppCallbacks(app_gap_callback, app_gatt_callback);
+    err = bleManager->AddWriteNotificationHandle((uint16_t) value_uart_stream);
+
+    if (err != CHIP_NO_ERROR)
+    {
+        ChipLogError(DeviceLayer, "Error while adding BLE write notification handle");
+    }
+}
+
+void BLEApplicationManager::EnableMultipleConnectionsHandler(void)
+{
+    /* Publish an event to the Matter task to always set the commissioning state in the Matter task context */
+    PlatformMgr().ScheduleWork(EnableMultipleConnections, 0);
+}
+
+void BLEApplicationManager::EnableMultipleConnections(intptr_t arg)
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+
+    /* Check the status of the commissioning */
+    if (ConfigurationMgr().IsFullyProvisioned())
+    {
+        ChipLogProgress(DeviceLayer, "Multiple connections, start advertising");
+        auto * bleManager = &chip::DeviceLayer::Internal::BLEMgrImpl();
+        bleManager->SetBLEServiceMode(kMultipleBLE_Enabled);
+        err = ConnectivityMgr().SetBLEAdvertisingEnabled(true);
+        if (err != CHIP_NO_ERROR)
+        {
+            ChipLogError(DeviceLayer, "Error during ConnectivityMgr().SetBLEAdvertisingEnabled()");
+        }
+    }
+    else
+    {
+        ChipLogProgress(DeviceLayer, "Device must be commissioned before adding multiple BLE connections");
+    }
+}
diff --git a/examples/platform/nxp/mcxw71_k32w1/button/ButtonManager.cpp b/examples/platform/nxp/mcxw71_k32w1/button/ButtonManager.cpp
index 6e5390d997a9b8..8bc61eeba64e72 100644
--- a/examples/platform/nxp/mcxw71_k32w1/button/ButtonManager.cpp
+++ b/examples/platform/nxp/mcxw71_k32w1/button/ButtonManager.cpp
@@ -20,6 +20,7 @@
 #include "AppConfig.h"
 #include "AppMatterButton.h"
 #include "AppTask.h"
+#include "BLEApplicationManager.h"
 #include "UserInterfaceFeedback.h"
 
 #include <app-common/zap-generated/attributes/Accessors.h>
@@ -200,6 +201,8 @@ void ButtonManager::BleHandler(const AppEvent & event)
 #endif
 
     chip::NXP::App::GetAppTask().SwitchCommissioningStateHandler();
+
+    chip::NXP::App::BleAppMgr().EnableMultipleConnectionsHandler();
 }
 
 #if (CHIP_CONFIG_ENABLE_ICD_LIT && CHIP_CONFIG_ENABLE_ICD_DSLS)
diff --git a/src/platform/nxp/common/ble/BLEManagerCommon.cpp b/src/platform/nxp/common/ble/BLEManagerCommon.cpp
index 02871e31f71058..6078fa80acb715 100644
--- a/src/platform/nxp/common/ble/BLEManagerCommon.cpp
+++ b/src/platform/nxp/common/ble/BLEManagerCommon.cpp
@@ -139,13 +139,13 @@ CHIP_ERROR BLEManagerCommon::_Init()
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
     EventBits_t eventBits;
-    uint16_t attChipRxHandle[1] = { (uint16_t) value_chipoble_rx };
+    mWriteNotificationHandle[mWriteHandleSize++] = (uint16_t) value_chipoble_rx;
 
 #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
-    uint16_t attChipC3Handle[1] = { (uint16_t) value_chipoble_c3 };
+    mReadNotificationHandle[mReadHandleSize++] = (uint16_t) value_chipoble_c3;
 #endif
 
-    mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
+    mServiceMode = kCHIPoBLE_Enabled;
 
     // Check if BLE stack is initialized
     VerifyOrExit(!mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE);
@@ -196,9 +196,9 @@ CHIP_ERROR BLEManagerCommon::_Init()
     PWR_ChangeDeepSleepMode(cPWR_PowerDown_RamRet);
 #endif
 
-    GattServer_RegisterHandlesForWriteNotifications(1, attChipRxHandle);
+    GattServer_RegisterHandlesForWriteNotifications(mWriteHandleSize, mWriteNotificationHandle);
 #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
-    VerifyOrExit(GattServer_RegisterHandlesForReadNotifications(1, attChipC3Handle) == gBleSuccess_c,
+    VerifyOrExit(GattServer_RegisterHandlesForReadNotifications(mReadHandleSize, mReadNotificationHandle) == gBleSuccess_c,
                  err = CHIP_ERROR_INCORRECT_STATE);
 #endif
 
@@ -221,7 +221,7 @@ CHIP_ERROR BLEManagerCommon::_Init()
 
 uint16_t BLEManagerCommon::_NumConnections(void)
 {
-    return static_cast<uint16_t>(mDeviceConnected == true);
+    return mDeviceIds.size();
 }
 
 bool BLEManagerCommon::_IsAdvertisingEnabled(void)
@@ -238,7 +238,8 @@ CHIP_ERROR BLEManagerCommon::_SetAdvertisingEnabled(bool val)
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
+    VerifyOrExit((mServiceMode == kCHIPoBLE_Enabled) || (mServiceMode == kMultipleBLE_Enabled),
+                 err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
 
     if (mFlags.Has(Flags::kAdvertisingEnabled) != val)
     {
@@ -284,10 +285,6 @@ CHIP_ERROR BLEManagerCommon::_GetDeviceName(char * buf, size_t bufSize)
 
 CHIP_ERROR BLEManagerCommon::_SetDeviceName(const char * deviceName)
 {
-    if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported)
-    {
-        return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
-    }
     if (deviceName != NULL && deviceName[0] != 0)
     {
         if (strlen(deviceName) >= kMaxDeviceNameLength)
@@ -767,7 +764,7 @@ CHIP_ERROR BLEManagerCommon::StopAdvertising(void)
         mFlags.Clear(Flags::kAdvertising);
         mFlags.Clear(Flags::kRestartAdvertising);
 
-        if (!mDeviceConnected)
+        if (mDeviceIds.size())
         {
             ble_err_t err = blekw_stop_advertising();
             VerifyOrReturnError(err == BLE_OK, CHIP_ERROR_INCORRECT_STATE);
@@ -794,7 +791,7 @@ void BLEManagerCommon::DriveBLEState(void)
     VerifyOrExit(mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE);
 
     // Start advertising if needed...
-    if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags.Has(Flags::kAdvertisingEnabled))
+    if (((mServiceMode == kCHIPoBLE_Enabled) || (mServiceMode == kMultipleBLE_Enabled)) && mFlags.Has(Flags::kAdvertisingEnabled))
     {
         // Start/re-start advertising if not already started, or if there is a pending change
         // to the advertising configuration.
@@ -817,7 +814,7 @@ void BLEManagerCommon::DriveBLEState(void)
     if (err != CHIP_NO_ERROR)
     {
         ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err));
-        mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
+        mServiceMode = kCHIPoBLE_Disabled;
     }
 }
 
@@ -863,7 +860,9 @@ void BLEManagerCommon::DoBleProcessing(void)
         }
         else if (msg->type == BLE_KW_MSG_MTU_CHANGED)
         {
-            blekw_start_connection_timeout();
+            if (mServiceMode == kCHIPoBLE_Enabled)
+                blekw_start_connection_timeout();
+
             ChipLogProgress(DeviceLayer, "BLE MTU size has been changed to %d.", msg->data.u16);
         }
         else if (msg->type == BLE_KW_MSG_ATT_WRITTEN || msg->type == BLE_KW_MSG_ATT_LONG_WRITTEN ||
@@ -897,6 +896,32 @@ void BLEManagerCommon::RegisterAppCallbacks(BLECallbackDelegate::GapGenericCallb
     callbackDelegate.gattCallback = gattCallback;
 }
 
+CHIP_ERROR BLEManagerCommon::AddWriteNotificationHandle(uint16_t name)
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+
+    // This function should be called before calling  BLEManagerCommon::_Init
+    VerifyOrExit(!mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE);
+
+    mWriteNotificationHandle[mWriteHandleSize++] = name;
+
+exit:
+    return err;
+}
+
+CHIP_ERROR BLEManagerCommon::AddReadNotificationHandle(uint16_t name)
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+
+    // This function should be called before calling  BLEManagerCommon::_Init
+    VerifyOrExit(!mFlags.Has(Flags::kK32WBLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE);
+
+    mReadNotificationHandle[mReadHandleSize++] = name;
+
+exit:
+    return err;
+}
+
 void BLEManagerCommon::HandleConnectEvent(blekw_msg_t * msg)
 {
     uint8_t deviceId = msg->data.u8;
@@ -906,10 +931,17 @@ void BLEManagerCommon::HandleConnectEvent(blekw_msg_t * msg)
     PWR_DisallowDeviceToSleep();
 #endif
 
-    mDeviceId        = deviceId;
-    mDeviceConnected = true;
+    mDeviceIds.insert(deviceId);
+
+    if (mServiceMode == kCHIPoBLE_Enabled)
+        blekw_start_connection_timeout();
+
+    if (mServiceMode == kMultipleBLE_Enabled)
+    {
+        _SetAdvertisingEnabled(false);
+        mServiceMode = kMultipleBLE_Disabled;
+    }
 
-    blekw_start_connection_timeout();
     PlatformMgr().ScheduleWork(DriveBLEState, 0);
 }
 
@@ -922,7 +954,7 @@ void BLEManagerCommon::HandleConnectionCloseEvent(blekw_msg_t * msg)
     PWR_AllowDeviceToSleep();
 #endif
 
-    mDeviceConnected = false;
+    mDeviceIds.erase(deviceId);
 
     ChipDeviceEvent event;
     event.Type                           = DeviceEventType::kCHIPoBLEConnectionClosed;
@@ -946,7 +978,8 @@ void BLEManagerCommon::HandleWriteEvent(blekw_msg_t * msg)
     ChipLogProgress(DeviceLayer, "Attribute write request(device: %d,handle: %d).", att_wr_data->device_id, att_wr_data->handle);
 #endif
 
-    blekw_start_connection_timeout();
+    if (mServiceMode == kCHIPoBLE_Enabled)
+        blekw_start_connection_timeout();
 
     if (value_chipoble_rx == att_wr_data->handle)
     {
@@ -1047,9 +1080,12 @@ void BLEManagerCommon::HandleForceDisconnect()
     ChipLogProgress(DeviceLayer, "BLE connection timeout: Forcing disconnection.");
 
     /* Set the advertising parameters */
-    if (Gap_Disconnect(mDeviceId) != gBleSuccess_c)
+    for (auto & id : mDeviceIds)
     {
-        ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed.");
+        if (Gap_Disconnect(id) != gBleSuccess_c)
+        {
+            ChipLogProgress(DeviceLayer, "Gap_Disconnect() failed.");
+        }
     }
 
 #if defined(chip_with_low_power) && (chip_with_low_power == 1)
diff --git a/src/platform/nxp/common/ble/BLEManagerCommon.h b/src/platform/nxp/common/ble/BLEManagerCommon.h
index 780ee194b8b28f..36c4304174351f 100644
--- a/src/platform/nxp/common/ble/BLEManagerCommon.h
+++ b/src/platform/nxp/common/ble/BLEManagerCommon.h
@@ -27,6 +27,8 @@
 
 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
 
+#include <set>
+
 #include "fsl_os_abstraction.h"
 
 #include "ble_conn_manager.h"
@@ -59,6 +61,15 @@ struct BLECallbackDelegate
     GattServerCallback gattCallback = nullptr;
 };
 
+typedef enum service_mode_t
+{
+    kCHIPoBLE_NotSupported = 0,
+    kCHIPoBLE_Enabled,
+    kCHIPoBLE_Disabled,
+    kMultipleBLE_Enabled,
+    kMultipleBLE_Disabled,
+} service_mode_t;
+
 /**
  * Base class for different platform implementations (K32W0 and K32W1 for now).
  */
@@ -69,7 +80,6 @@ class BLEManagerCommon : public BLEManager, protected BleLayer, private BlePlatf
 
     CHIP_ERROR _Init(void);
     CHIP_ERROR _Shutdown() { return CHIP_NO_ERROR; }
-    CHIPoBLEServiceMode _GetCHIPoBLEServiceMode(void);
     CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val);
     bool _IsAdvertisingEnabled(void);
     CHIP_ERROR _SetAdvertisingEnabled(bool val);
@@ -116,6 +126,11 @@ class BLEManagerCommon : public BLEManager, protected BleLayer, private BlePlatf
         kUnusedIndex         = 0xFF,
     };
 
+    enum
+    {
+        kMaxHandles = 5,
+    };
+
     typedef enum
     {
         BLE_KW_MSG_ERROR = 0x01,
@@ -175,14 +190,18 @@ class BLEManagerCommon : public BLEManager, protected BleLayer, private BlePlatf
         uint16_t handle;
     } blekw_att_read_data_t;
 
-    CHIPoBLEServiceMode mServiceMode;
+    service_mode_t mServiceMode;
     char mDeviceName[kMaxDeviceNameLength + 1];
 #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
     chip::System::PacketBufferHandle c3AdditionalDataBufferHandle;
 #endif
-    uint8_t mDeviceId;
+    std::set<uint8_t> mDeviceIds;
     bool mDeviceSubscribed = false;
-    bool mDeviceConnected  = false;
+
+    uint8_t mReadHandleSize  = 0;
+    uint8_t mWriteHandleSize = 0;
+    uint16_t mReadNotificationHandle[kMaxHandles];
+    uint16_t mWriteNotificationHandle[kMaxHandles];
 
     void DriveBLEState(void);
     CHIP_ERROR ConfigureAdvertising(void);
@@ -235,12 +254,13 @@ class BLEManagerCommon : public BLEManager, protected BleLayer, private BlePlatf
     BLECallbackDelegate callbackDelegate;
     void RegisterAppCallbacks(BLECallbackDelegate::GapGenericCallback gapCallback,
                               BLECallbackDelegate::GattServerCallback gattCallback);
-};
 
-inline BLEManager::CHIPoBLEServiceMode BLEManagerCommon::_GetCHIPoBLEServiceMode(void)
-{
-    return mServiceMode;
-}
+    CHIP_ERROR AddWriteNotificationHandle(uint16_t name);
+    CHIP_ERROR AddReadNotificationHandle(uint16_t name);
+
+    service_mode_t GetBLEServiceMode(void) { return mServiceMode; }
+    void SetBLEServiceMode(service_mode_t mode) { mServiceMode = mode; };
+};
 
 } // namespace Internal
 } // namespace DeviceLayer