[BEKEN] add beken platform file (#21824)
* [BEKEN] add beken platform file
* add beken platform src file
* support examples/lighting-app
* add beken config file
* [BEKEN] change the return type of InitClock_RealTime() and update some
comments.
* [BEKEN] del obsolete interface
* del obsolete interface
* fix copyright headers (2020 -> 2022) in all files
Co-authored-by: Tao Yang <tao.yang@bekencorp.com>
Co-authored-by: cenfang <fly92727@outlook.com>
diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn
index b8b20ee..31e25b4 100644
--- a/src/platform/BUILD.gn
+++ b/src/platform/BUILD.gn
@@ -262,6 +262,12 @@
"CHIP_DEVICE_LAYER_TARGET_ZEPHYR=1",
"CHIP_DEVICE_LAYER_TARGET=Zephyr",
]
+ } else if (chip_device_platform == "beken") {
+ defines += [
+ "CHIP_DEVICE_LAYER_TARGET_BEKEN=1",
+ "CHIP_DEVICE_LAYER_TARGET=Beken",
+ "CHIP_DEVICE_CONFIG_ENABLE_WIFI=${chip_enable_wifi}",
+ ]
}
if (chip_device_config_device_software_version_string != "") {
@@ -431,6 +437,8 @@
_platform_target = "nxp/mw320"
} else if (chip_device_platform == "zephyr") {
_platform_target = "Zephyr"
+ } else if (chip_device_platform == "beken") {
+ _platform_target = "Beken"
} else {
assert(false, "Unknown chip_device_platform: ${chip_device_platform}")
}
diff --git a/src/platform/Beken/BLEManagerImpl.cpp b/src/platform/Beken/BLEManagerImpl.cpp
new file mode 100644
index 0000000..613ff12
--- /dev/null
+++ b/src/platform/Beken/BLEManagerImpl.cpp
@@ -0,0 +1,1275 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Provides an implementation of the BLEManager singleton object
+ * for the Beken platforms.
+ */
+
+/* this file behaves like a config.h, comes first */
+#include <crypto/CHIPCryptoPAL.h>
+#include <platform/CommissionableDataProvider.h>
+#include <platform/DeviceInstanceInfoProvider.h>
+#include <platform/internal/CHIPDeviceLayerInternal.h>
+#include <setup_payload/AdditionalDataPayloadGenerator.h>
+
+#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
+#include <ble/CHIPBleServiceData.h>
+#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
+#include <setup_payload/AdditionalDataPayloadGenerator.h>
+#endif
+#include "stdio.h"
+#include "timers.h"
+#include <string.h>
+
+// BK7231n BLE related header files
+#include "matter_pal.h"
+
+/*******************************************************************************
+ * Local data types
+ *******************************************************************************/
+using namespace ::chip;
+using namespace ::chip::Ble;
+
+namespace chip {
+namespace DeviceLayer {
+namespace Internal {
+
+namespace {
+
+/*******************************************************************************
+ * Macros & Constants definitions
+ *******************************************************************************/
+#ifndef MAX_ADV_DATA_LEN
+#define MAX_ADV_DATA_LEN 31
+#endif
+#define CHIP_ADV_DATA_TYPE_FLAGS 0x01
+#define CHIP_ADV_DATA_FLAGS 0x06
+
+/* advertising configuration */
+#define CHIP_ADV_SHORT_UUID_LEN (2)
+
+/* FreeRTOS sw timer */
+TimerHandle_t bleFastAdvTimer;
+
+enum
+{
+ DriveBLEExtPerfEvt_DISCONNECT = 0,
+};
+
+const ChipBleUUID ChipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
+ 0x9D, 0x11 } };
+const ChipBleUUID ChipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F,
+ 0x9D, 0x12 } };
+static const uint8_t _svc_uuid[16] = { 0xF6, 0xFF, 0, 0, 0x0, 0x0, 0, 0, 0, 0, 0x0, 0x0, 0, 0, 0, 0 };
+
+#define UUID_CHIPoBLECharact_RX \
+ { \
+ 0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 \
+ }
+//#define UUID_CHIPoBLECharact_RX { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, 0x11
+//}
+#define ChipUUID_CHIPoBLECharact_TX \
+ { \
+ 0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 \
+ }
+//#define ChipUUID_CHIPoBLECharact_TX { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D,
+// 0x12 }
+#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
+#define UUID_CHIPoBLEChar_C3 \
+ { \
+ 0x04, 0x8F, 0x21, 0x83, 0x8A, 0x74, 0x7D, 0xB8, 0xF2, 0x45, 0x72, 0x87, 0x38, 0x02, 0x63, 0x64 \
+ }
+#endif
+#define BEKEN_ATT_DECL_PRIMARY_SERVICE_128 \
+ { \
+ 0x00, 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
+ }
+#define BEKEN_ATT_DECL_CHARACTERISTIC_128 \
+ { \
+ 0x03, 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
+ }
+#define BEKEN_ATT_DESC_CLIENT_CHAR_CFG_128 \
+ { \
+ 0x02, 0x29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
+ }
+
+enum
+{
+ SVR_FFF6_IDX_SVC,
+ SVR_FFF6_RX_DECL,
+ SVR_FFF6_RX_VALUE,
+ SVR_FFF6_TX_DECL,
+ SVR_FFF6_TX_VALUE,
+#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
+ SVR_FFF6_C3_VALUE,
+#endif
+ SVR_FFF6_TX_CFG,
+ SVR_FFF6_MAX,
+};
+
+ble_attm_desc_t svr_fff6_att_db[SVR_FFF6_MAX] = {
+ // Service Declaration
+ [SVR_FFF6_IDX_SVC] = { BEKEN_ATT_DECL_PRIMARY_SERVICE_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 2 },
+
+ // Level Characteristic Declaration
+ [SVR_FFF6_RX_DECL] = { BEKEN_ATT_DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0 },
+ // Level Characteristic Value BK_PERM_RIGHT_ENABLE WRITE_REQ_POS RI_POS UUID_LEN_POS BK_PERM_RIGHT_UUID_128
+ [SVR_FFF6_RX_VALUE] = { UUID_CHIPoBLECharact_RX, BK_BLE_PERM_SET(WRITE_REQ, ENABLE),
+ BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_128), 512 },
+
+ /// RD_POS NTF_POS
+ [SVR_FFF6_TX_DECL] = { BEKEN_ATT_DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE) | BK_BLE_PERM_SET(NTF, ENABLE), 0, 0 },
+ //// UUID_LEN_POS BK_PERM_RIGHT_UUID_128 RD_POS
+ [SVR_FFF6_TX_VALUE] = { ChipUUID_CHIPoBLECharact_TX, BK_BLE_PERM_SET(RD, ENABLE) | BK_BLE_PERM_SET(NTF, ENABLE),
+ BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_128), 512 },
+#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
+ [SVR_FFF6_C3_VALUE] = { UUID_CHIPoBLEChar_C3, BK_BLE_PERM_SET(RD, ENABLE),
+ BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_128), 512 },
+#endif
+ [SVR_FFF6_TX_CFG] = { BEKEN_ATT_DESC_CLIENT_CHAR_CFG_128, BK_BLE_PERM_SET(RD, ENABLE) | BK_BLE_PERM_SET(WRITE_REQ, ENABLE), 0,
+ 2 },
+};
+
+/// const static uint8_t svr_fff6_att_db_item = SVR_FFF6_MAX;
+} // namespace
+
+BLEManagerImpl BLEManagerImpl::sInstance;
+
+int BLEManagerImpl::beken_ble_init(void)
+{
+ int status;
+
+ struct bk_ble_db_cfg ble_db_cfg;
+
+ ble_db_cfg.att_db = svr_fff6_att_db;
+ ble_db_cfg.att_db_nb = SVR_FFF6_MAX;
+ ble_db_cfg.prf_task_id = 0;
+ ble_db_cfg.start_hdl = 0;
+ ble_db_cfg.svc_perm = BK_BLE_PERM_SET(SVC_UUID_LEN, UUID_16);
+ memcpy(&(ble_db_cfg.uuid[0]), &_svc_uuid[0], 16);
+ status = bk_ble_create_db(&ble_db_cfg);
+
+ if (status != BK_ERR_BLE_SUCCESS)
+ {
+ return -1;
+ }
+ return 0;
+}
+
+CHIP_ERROR BLEManagerImpl::_Init()
+{
+ CHIP_ERROR err;
+
+ // Initialize the CHIP BleLayer.
+ err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer());
+ SuccessOrExit(err);
+
+ mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
+ memset(mBleConnections, 0, sizeof(mBleConnections));
+ // Check if BLE stack is initialized
+ VerifyOrExit(!mFlags.Has(Flags::kAMEBABLEStackInitialized), err = CHIP_ERROR_INCORRECT_STATE);
+ bk_ble_set_notice_cb(ble_event_notice);
+
+ // Set related flags
+ mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART);
+ mFlags.Set(Flags::kAMEBABLEStackInitialized);
+ mFlags.Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART ? true : false);
+ mFlags.Set(Flags::kFastAdvertisingEnabled);
+ mFlags.Set(Flags::kSlowAdvertisingEnabled);
+ if (!mFlags.Has(Flags::kBEKENBLEAdvTimer))
+ {
+ uint32_t bleAdvTimeoutMs = CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME;
+ bleFastAdvTimer = xTimerCreate("", (bleAdvTimeoutMs / 2), pdFALSE, NULL, ble_adv_timer_timeout_handle);
+ mFlags.Set(Flags::kBEKENBLEAdvTimer);
+ }
+
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+
+exit:
+ return err;
+}
+
+void BLEManagerImpl::HandleTXCharRead(void * param)
+{
+ CHIPoBLEConState * conState;
+ ble_read_req_t * r_req = (ble_read_req_t *) param;
+ if (param == NULL)
+ {
+ ChipLogError(DeviceLayer, "HandleTXCharRead failed: %p", param);
+ }
+ r_req->length = 0;
+}
+
+void BLEManagerImpl::HandleTXCharCCCDRead(void * param)
+{
+ CHIPoBLEConState * conState;
+ ble_read_req_t * r_req = (ble_read_req_t *) param;
+ conState = GetConnectionState(r_req->conn_idx);
+
+ if (param == NULL)
+ {
+ ChipLogError(DeviceLayer, "HandleTXCharCCCDRead failed");
+ return;
+ }
+
+ if (conState != NULL)
+ {
+ r_req->value[0] = conState->subscribed ? 1 : 0;
+ r_req->value[1] = 0;
+ r_req->length = 2;
+ }
+ else
+ {
+ ChipLogError(DeviceLayer, "conState failed: %p", conState);
+ r_req->length = 0;
+ }
+}
+
+void BLEManagerImpl::HandleTXCharCCCDWrite(int conn_id, int notificationsEnabled, int indicationsEnabled)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ // If the client has requested to enabled indications/notifications
+ if (indicationsEnabled || notificationsEnabled)
+ {
+ // If indications are not already enabled for the connection...
+ if (!IsSubscribed(conn_id))
+ {
+ // Record that indications have been enabled for this connection.
+ err = SetSubscribed(conn_id);
+ VerifyOrExit(err != CHIP_ERROR_NO_MEMORY, err = CHIP_NO_ERROR);
+ SuccessOrExit(err);
+ }
+ }
+ else
+ {
+ // If indications had previously been enabled for this connection, record that they are no longer enabled.
+ UnsetSubscribed(conn_id);
+ }
+
+ // Post an event to the Chip queue to process either a CHIPoBLE Subscribe or Unsubscribe based on
+ // whether the client is enabling or disabling indications.
+ {
+ ChipDeviceEvent event;
+ event.Type = (indicationsEnabled || notificationsEnabled) ? DeviceEventType::kCHIPoBLESubscribe
+ : DeviceEventType::kCHIPoBLEUnsubscribe;
+ event.CHIPoBLESubscribe.ConId = conn_id;
+ PlatformMgr().PostEventOrDie(&event);
+ }
+
+ ChipLogProgress(DeviceLayer, "CHIPoBLE %s received",
+ (indicationsEnabled || notificationsEnabled) ? "subscribe" : "unsubscribe");
+
+exit:
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err));
+ }
+
+ return;
+}
+
+CHIP_ERROR BLEManagerImpl::HandleTXComplete(int conn_id)
+{
+ // Post an event to the Chip queue to process the indicate confirmation.
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm;
+ event.CHIPoBLEIndicateConfirm.ConId = conn_id;
+ PlatformMgr().PostEventOrDie(&event);
+ return CHIP_NO_ERROR;
+}
+
+uint16_t BLEManagerImpl::_NumConnections(void)
+{
+ uint16_t numCons = 0;
+
+ for (uint8_t i = 0; i < kMaxConnections; i++)
+ {
+ if (mBleConnections[i].allocated == 1)
+ {
+ numCons += 1;
+ }
+ }
+
+ return numCons;
+}
+
+CHIP_ERROR BLEManagerImpl::HandleGAPConnect(uint16_t conn_id)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ // Track the number of active GAP connections.
+ mNumGAPCons++;
+ err = SetSubscribed(conn_id);
+ VerifyOrExit(err != CHIP_ERROR_NO_MEMORY, err = CHIP_NO_ERROR);
+ SuccessOrExit(err);
+
+exit:
+ return err;
+}
+
+CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(uint16_t conn_id, uint16_t disc_cause)
+{
+ // Update the number of GAP connections.
+ if (mNumGAPCons > 0)
+ {
+ mNumGAPCons--;
+ }
+
+ if (RemoveConnection(conn_id))
+ {
+ CHIP_ERROR disconReason;
+ switch (disc_cause)
+ {
+ case 0x13:
+ case 0x08:
+ disconReason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED;
+ break;
+ case 0x16:
+ disconReason = BLE_ERROR_APP_CLOSED_CONNECTION;
+ break;
+ default:
+ disconReason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT;
+ break;
+ }
+ HandleConnectionError(conn_id, disconReason);
+ }
+
+ // Force a reconfiguration of advertising in case we switched to non-connectable mode when
+ // the BLE connection was established.
+ mFlags.Set(Flags::kAdvertisingRefreshNeeded);
+ return CHIP_NO_ERROR;
+}
+
+bool BLEManagerImpl::RemoveConnection(uint8_t connectionHandle)
+{
+ CHIPoBLEConState * bleConnState = GetConnectionState(connectionHandle);
+ bool status = false;
+
+ if (bleConnState != NULL)
+ {
+ bleConnState->Reset();
+ memset(bleConnState, 0, sizeof(CHIPoBLEConState));
+ status = true;
+ }
+ return status;
+}
+
+BLEManagerImpl::CHIPoBLEConState * BLEManagerImpl::GetConnectionState(uint8_t connectionHandle, bool allocate)
+{
+ uint8_t freeIndex = kMaxConnections;
+
+ for (uint8_t i = 0; i < kMaxConnections; i++)
+ {
+ if (mBleConnections[i].allocated == 1)
+ {
+ if (mBleConnections[i].conn_idx == connectionHandle)
+ {
+ return &mBleConnections[i];
+ }
+ }
+
+ else if (i < freeIndex)
+ {
+ freeIndex = i;
+ }
+ }
+
+ if (allocate)
+ {
+ if (freeIndex < kMaxConnections)
+ {
+ mBleConnections[freeIndex].Set(connectionHandle);
+ return &mBleConnections[freeIndex];
+ }
+
+ ChipLogError(DeviceLayer, "Failed to allocate CHIPoBLEConState");
+ }
+
+ return NULL;
+}
+
+CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ VerifyOrExit(val != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
+
+ if (val != mServiceMode)
+ {
+ mServiceMode = val;
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ }
+
+exit:
+ return err;
+}
+
+CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
+
+ if (mFlags.Has(Flags::kAdvertisingEnabled) != val)
+ {
+ mFlags.Set(Flags::kAdvertisingEnabled, val);
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ }
+
+exit:
+ return err;
+}
+
+CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode)
+{
+ switch (mode)
+ {
+ case BLEAdvertisingMode::kFastAdvertising:
+ mFlags.Set(Flags::kFastAdvertisingEnabled, true);
+ break;
+ case BLEAdvertisingMode::kSlowAdvertising:
+ mFlags.Set(Flags::kFastAdvertisingEnabled, false);
+ break;
+ default:
+ return CHIP_ERROR_INVALID_ARGUMENT;
+ }
+ mFlags.Set(Flags::kAdvertisingRefreshNeeded);
+
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize)
+{
+ if (strlen(mDeviceName) >= bufSize)
+ {
+ return CHIP_ERROR_BUFFER_TOO_SMALL;
+ }
+ strcpy(buf, mDeviceName);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
+
+ if (deviceName != NULL && deviceName[0] != 0)
+ {
+ VerifyOrExit(strlen(deviceName) >= kMaxDeviceNameLength, err = CHIP_ERROR_INVALID_ARGUMENT);
+ strcpy(mDeviceName, deviceName);
+ mFlags.Set(Flags::kDeviceNameSet);
+ ChipLogProgress(DeviceLayer, "Setting device name to : \"%s\"", deviceName);
+ }
+ else
+ {
+ mDeviceName[0] = 0;
+ mFlags.Clear(Flags::kDeviceNameSet);
+ }
+
+exit:
+ return err;
+}
+
+void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
+{
+ switch (event->Type)
+ {
+ // Platform specific events
+ case DeviceEventType::kCHIPoBLESubscribe:
+ HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
+ {
+ ChipDeviceEvent connEstEvent;
+ connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
+ PlatformMgr().PostEventOrDie(&connEstEvent);
+ }
+ break;
+
+ case DeviceEventType::kCHIPoBLEUnsubscribe: {
+ ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEUnsubscribe");
+ HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
+ }
+ break;
+
+ case DeviceEventType::kCHIPoBLEWriteReceived: {
+ ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEWriteReceived");
+ HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_RX,
+ PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data));
+ }
+ break;
+
+ case DeviceEventType::kCHIPoBLEConnectionError: {
+ ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEConnectionError");
+ HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason);
+ }
+ break;
+
+ case DeviceEventType::kCHIPoBLEIndicateConfirm: {
+ ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEIndicateConfirm");
+ HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX);
+ }
+ break;
+
+ case DeviceEventType::kServiceProvisioningChange:
+ case DeviceEventType::kWiFiConnectivityChange:
+ ChipLogProgress(DeviceLayer, "Updating advertising data");
+ StartAdvertising();
+ break;
+
+ default:
+ ChipLogProgress(DeviceLayer, "_OnPlatformEvent default: event->Type = %d", event->Type);
+ break;
+ }
+}
+
+bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
+{
+ ChipLogProgress(DeviceLayer, "BLEManagerImpl::SubscribeCharacteristic() not supported");
+ return false;
+}
+
+bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId)
+{
+ ChipLogProgress(DeviceLayer, "BLEManagerImpl::UnsubscribeCharacteristic() not supported");
+ return false;
+}
+
+bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId)
+{
+ CHIP_ERROR err;
+ ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %u)", conId);
+ uint32_t delay_time = 20;
+ int ret;
+
+ do
+ {
+ ret = bk_ble_disconnect(conId, beken_ble_cmd_cb);
+ if (BK_ERR_BLE_SUCCESS == ret)
+ {
+ break;
+ }
+
+ rtos_delay_milliseconds(10);
+ delay_time--;
+ } while (delay_time);
+ // Beken Ble close function
+ err = MapBLEError(ret);
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "bk_ble_disconnect() failed: %s", ErrorStr(err));
+ }
+
+ return false;
+}
+
+uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const
+{
+ CHIPoBLEConState * conState = const_cast<BLEManagerImpl *>(this)->GetConnectionState(conId);
+ return (conState != NULL) ? conState->mtu : 0;
+}
+
+bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
+ PacketBufferHandle pBuf)
+{
+ ChipLogError(DeviceLayer, "BLEManagerImpl::SendWriteRequest() not supported");
+ return false;
+}
+
+bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
+ PacketBufferHandle pBuf)
+{
+ ChipLogError(DeviceLayer, "BLEManagerImpl::SendReadRequest() not supported");
+ return false;
+}
+
+bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext,
+ const ChipBleUUID * svcId, const ChipBleUUID * charId)
+{
+ ChipLogError(DeviceLayer, "BLEManagerImpl::SendReadResponse() not supported");
+ return false;
+}
+
+void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId)
+{
+ // Nothing to do
+}
+
+bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
+ PacketBufferHandle data)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ int ret;
+
+ VerifyOrExit(IsSubscribed(conId), err = CHIP_ERROR_INVALID_ARGUMENT);
+ ret = bk_ble_send_noti_value(data->DataLength(), data->Start(), 0, SVR_FFF6_TX_VALUE);
+ err = MapBLEError(ret);
+exit:
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "BLEManagerImpl::SendIndication() failed: %s", ErrorStr(err));
+ return false;
+ }
+
+ return true;
+}
+
+/*******************************************************************************
+ * Private functions
+ *******************************************************************************/
+
+CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ // If the device name is not specified, generate a CHIP-standard name based on the bottom digits of the Chip device id.
+ uint16_t discriminator;
+ SuccessOrExit(err = GetCommissionableDataProvider()->GetSetupDiscriminator(discriminator));
+
+ if (!mFlags.Has(Flags::kDeviceNameSet))
+ {
+ snprintf(mDeviceName, sizeof(mDeviceName), "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, discriminator);
+ mDeviceName[kMaxDeviceNameLength] = 0;
+ }
+
+ // Configure the BLE device name.
+ sInstance.mFlags.Set(Flags::kDeviceNameDefSet);
+ bk_ble_appm_set_dev_name(kMaxDeviceNameLength, (uint8_t *) mDeviceName);
+exit:
+ return err;
+}
+
+CHIP_ERROR BLEManagerImpl::StartAdvertising(void)
+{
+ ble_err_t bk_err;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ ChipLogProgress(DeviceLayer, "StartAdvertising...");
+ ChipLogProgress(DeviceLayer, "BLE flag = %x", mFlags.Raw());
+ if ((!mFlags.Has(Flags::kDeviceNameSet)) && (!mFlags.Has(Flags::kDeviceNameDefSet)))
+ {
+ err = sInstance.ConfigureAdvertisingData();
+ SuccessOrExit(err);
+ }
+ // Post a CHIPoBLEAdvertisingChange(Stopped) event.
+ if (mFlags.Has(Flags::kBEKENBLEADVStop))
+ {
+ bk_ble_delete_advertising(adv_actv_idx, beken_ble_cmd_cb);
+ mFlags.Clear(Flags::kBEKENBLEADVStop);
+ ChipDeviceEvent advChange;
+ advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange;
+ advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped;
+ PlatformMgr().PostEventOrDie(&advChange);
+ goto exit;
+ }
+ else if (!mFlags.Has(Flags::kBEKENBLEADVCreate))
+ {
+ ChipLogProgress(DeviceLayer, "BLE ADVCreate...");
+ uint16_t adv_int_min;
+ uint16_t adv_int_max;
+ ble_adv_param_t adv_param;
+
+ memset(&adv_param, 0, sizeof(adv_param));
+
+ if (mFlags.Has(Flags::kFastAdvertisingEnabled))
+ {
+ adv_int_min = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN;
+ adv_int_max = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX;
+ mFlags.Set(Flags::kAdvertisingIsFastADV);
+ }
+ else
+ {
+ adv_int_min = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN;
+ adv_int_max = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX;
+ mFlags.Clear(Flags::kAdvertisingIsFastADV);
+ }
+
+ adv_actv_idx = bk_ble_get_idle_actv_idx_handle();
+ if (UNKNOW_ACT_IDX == adv_actv_idx)
+ {
+ ChipLogError(DeviceLayer, "adv act-idx:%d error", adv_actv_idx);
+ return MapBLEError(-1);
+ }
+ adv_param.chnl_map = 7;
+ adv_param.adv_intv_max = 160;
+ adv_param.adv_intv_min = 160;
+ adv_param.own_addr_type = 0;
+ adv_param.adv_type = 0;
+ adv_param.adv_prop = 3;
+ adv_param.prim_phy = 1;
+ // bk_ble_create_advertising(adv_actv_idx, 7, adv_int_min, adv_int_max, beken_ble_cmd_cb);
+ bk_err = bk_ble_create_advertising(adv_actv_idx, &adv_param, beken_ble_cmd_cb);
+ if (bk_err != BK_OK)
+ {
+ ChipLogProgress(DeviceLayer, "BLE ADVCreate ret= %x.", bk_err);
+ }
+ ChipLogProgress(DeviceLayer, "BLE ADVCreate ret= %x. adv_actv_idx = %x", bk_err, adv_actv_idx);
+ sInstance.mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
+ goto exit;
+ }
+ else if (!mFlags.Has(Flags::kBEKENBLEADVSetData))
+ {
+ ChipLogProgress(DeviceLayer, "BLE SetData...");
+ ChipBLEDeviceIdentificationInfo deviceIdInfo;
+ uint8_t advData[MAX_ADV_DATA_LEN] = { 0 };
+ uint8_t index = 0;
+ /**************** Prepare advertising data *******************************************/
+ memset(advData, 0, sizeof(advData));
+ advData[index++] = 0x02; // length
+ advData[index++] = CHIP_ADV_DATA_TYPE_FLAGS; // AD type : flags
+ advData[index++] = CHIP_ADV_DATA_FLAGS; // AD value
+ advData[index++] = static_cast<uint8_t>(sizeof(deviceIdInfo) + CHIP_ADV_SHORT_UUID_LEN + 1);
+ ; // length
+ advData[index++] = 0x16; // AD type: (Service Data - 16-bit UUID)
+ advData[index++] = static_cast<uint8_t>(_svc_uuid[0] & 0xFF); // AD value
+ advData[index++] = static_cast<uint8_t>(_svc_uuid[1] & 0xFF); // AD value
+ err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(deviceIdInfo);
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "GetBLEDeviceIdentificationInfo(): %s", ErrorStr(err));
+ ExitNow();
+ }
+
+#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
+ deviceIdInfo.SetAdditionalDataFlag(true);
+#endif
+ VerifyOrExit(index + sizeof(deviceIdInfo) <= sizeof(advData), err = CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG);
+
+ memcpy(&advData[index], &deviceIdInfo, sizeof(deviceIdInfo));
+ index = static_cast<uint8_t>(index + sizeof(deviceIdInfo));
+ bk_ble_set_adv_data(adv_actv_idx, advData, index, beken_ble_cmd_cb);
+ goto exit;
+ }
+ else if (!mFlags.Has(Flags::kBEKENBLEADVSetRsp))
+ {
+ /// uint8_t advData[MAX_ADV_DATA_LEN] = { 0 };
+ /// bk_ble_set_scan_rsp_data(adv_actv_idx, advData, 0xF, beken_ble_cmd_cb);
+ sInstance.mFlags.Set(Flags::kBEKENBLEADVSetRsp);
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ goto exit;
+ }
+ else if (!mFlags.Has(Flags::kBEKENBLEADVStarted))
+ {
+ ChipLogProgress(DeviceLayer, "BLE Started...");
+ bk_ble_start_advertising(adv_actv_idx, 0, beken_ble_cmd_cb);
+ goto exit;
+ }
+
+ if (mFlags.Has(Flags::kBEKENBLEADVStarted))
+ {
+ ChipDeviceEvent advChange;
+ advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange;
+ advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started;
+ PlatformMgr().PostEventOrDie(&advChange);
+ }
+
+exit:
+ return err;
+}
+
+CHIP_ERROR BLEManagerImpl::StopAdvertising(void)
+{
+ // Change flag status to the 'not Advertising state'
+ if ((mFlags.Has(Flags::kBEKENBLEADVStarted)) && (!mFlags.Has(Flags::kBEKENBLEADVStop)))
+ {
+ mFlags.Set(Flags::kBEKENBLEADVStop);
+ bk_ble_stop_advertising(adv_actv_idx, beken_ble_cmd_cb);
+ ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopping");
+ goto exit;
+ }
+
+ // Post a CHIPoBLEAdvertisingChange(Stopped) event.
+ if (mFlags.Has(Flags::kBEKENBLEADVStop))
+ {
+ bk_ble_delete_advertising(adv_actv_idx, beken_ble_cmd_cb);
+ mFlags.Clear(Flags::kBEKENBLEADVStop);
+ ChipDeviceEvent advChange;
+ advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange;
+ advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped;
+ PlatformMgr().PostEventOrDie(&advChange);
+ }
+exit:
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr)
+{
+ switch (bleErr)
+ {
+ case BK_ERR_BLE_SUCCESS:
+ return CHIP_NO_ERROR;
+ default:
+ return CHIP_ERROR_INCORRECT_STATE;
+ }
+}
+
+void BLEManagerImpl::DriveBLEState(void)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ // Check if BLE stack is initialized
+ VerifyOrExit(mFlags.Has(Flags::kAMEBABLEStackInitialized), /* */);
+ if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled)
+ {
+ if (!mFlags.Has(Flags::kBekenBLESGATTSReady))
+ {
+ beken_ble_init();
+ goto exit;
+ }
+ }
+
+ if ((!mFlags.Has(Flags::kFastAdvertisingEnabled)) && (!mFlags.Has(Flags::kSlowAdvertisingEnabled)))
+ {
+ mFlags.Clear(Flags::kAdvertisingEnabled);
+ mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
+ }
+
+ if (mFlags.Has(Flags::kAdvertisingRefreshNeeded))
+ {
+ if (mFlags.Has(Flags::kBEKENBLEADVStarted))
+ {
+ err = StopAdvertising();
+ SuccessOrExit(err);
+ goto exit;
+ }
+ else if (mFlags.Has(Flags::kBEKENBLEADVStarted))
+ {
+ bk_ble_delete_advertising(adv_actv_idx, beken_ble_cmd_cb);
+ goto exit;
+ }
+ }
+
+ // Start advertising if needed...
+ if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled &&
+ ((mFlags.Has(Flags::kAdvertisingEnabled)) || (mFlags.Has(Flags::kAdvertisingRefreshNeeded))))
+ {
+ // Start/re-start advertising if not already started, or if there is a pending change
+ // to the advertising configuration.
+ if (!mFlags.Has(Flags::kBEKENBLEADVStarted))
+ {
+ err = StartAdvertising();
+ SuccessOrExit(err);
+ }
+ else
+ {
+ mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
+ }
+ }
+ // Otherwise, stop advertising if it is enabled.
+ else if ((mFlags.Has(Flags::kBEKENBLEADVStarted)) || (mFlags.Has(Flags::kBEKENBLEADVStop)))
+ {
+ err = StopAdvertising();
+ SuccessOrExit(err);
+ ChipLogProgress(DeviceLayer, "Stopped Advertising");
+ }
+
+exit:
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err));
+ mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
+ }
+}
+
+void BLEManagerImpl::DriveBLEState(intptr_t arg)
+{
+ sInstance.DriveBLEState();
+}
+
+void BLEManagerImpl::DriveBLEExtPerf(intptr_t arg)
+{
+ int arg_int = static_cast<int>(arg);
+ int event = arg_int & 0xFFU;
+ switch (event)
+ {
+ case DriveBLEExtPerfEvt_DISCONNECT: {
+ uint8_t conn_indx = (arg_int >> 8) & 0xFFU;
+ sInstance.CloseConnection(conn_indx);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/*******************************************************************************
+ * FreeRTOS Task Management Functions
+ *******************************************************************************/
+void BLEManagerImpl::ble_adv_timer_timeout_handle(TimerHandle_t xTimer)
+{
+ if (sInstance.mFlags.Has(Flags::kFastAdvertisingEnabled))
+ {
+ ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop Fast advertisement");
+
+ sInstance.mFlags.Clear(Flags::kFastAdvertisingEnabled);
+ // Stop advertising, change interval and restart it;
+ sInstance.StopAdvertising();
+ }
+ else if (sInstance._IsAdvertisingEnabled())
+ {
+ // Advertisement time expired. Stop advertising
+ ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop slow advertisement");
+ sInstance.mFlags.Clear(Flags::kSlowAdvertisingEnabled);
+ sInstance.StopAdvertising();
+ }
+}
+
+void BLEManagerImpl::CancelBleAdvTimeoutTimer(void)
+{
+ if (xTimerIsTimerActive(bleFastAdvTimer))
+ {
+ if (xTimerStop(bleFastAdvTimer, 0) == pdFAIL)
+ {
+ ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer");
+ sInstance.mFlags.Clear(Flags::kBEKENBLEAdvTimerRun);
+ }
+ }
+}
+
+void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs)
+{
+ CancelBleAdvTimeoutTimer();
+ // timer is not active, change its period to required value (== restart).
+ // FreeRTOS- Block for a maximum of 100 ticks if the change period command
+ // cannot immediately be sent to the timer command queue.
+ if (xTimerChangePeriod(bleFastAdvTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS)
+ {
+ ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer");
+ }
+ else
+ {
+ xTimerStart(bleFastAdvTimer, BEKEN_WAIT_FOREVER);
+ sInstance.mFlags.Set(Flags::kBEKENBLEAdvTimerRun);
+ }
+}
+
+CHIP_ERROR BLEManagerImpl::SetSubscribed(uint16_t conId)
+{
+ CHIPoBLEConState * bleConnState = GetConnectionState(conId, false);
+
+ if (bleConnState != NULL)
+ {
+ bleConnState->subscribed = 1;
+ return CHIP_NO_ERROR;
+ }
+
+ return CHIP_ERROR_NO_MEMORY;
+}
+
+bool BLEManagerImpl::UnsetSubscribed(uint16_t conId)
+{
+ CHIPoBLEConState * bleConnState = GetConnectionState(conId, false);
+
+ if (bleConnState != NULL)
+ {
+ bleConnState->subscribed = 0;
+ return true;
+ }
+
+ return false;
+}
+
+bool BLEManagerImpl::IsSubscribed(uint16_t conId)
+{
+ CHIPoBLEConState * bleConnState = GetConnectionState(conId, false);
+
+ if (bleConnState != NULL)
+ {
+ if (bleConnState->subscribed)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void BLEManagerImpl::HandleRXCharWrite(uint8_t * p_value, uint16_t len, uint8_t conn_id)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ PacketBufferHandle buf = System::PacketBufferHandle::New(len, 0);
+ memcpy(buf->Start(), p_value, len);
+ buf->SetDataLength(len);
+
+ // Post an event to the Chip queue to deliver the data into the Chip stack.
+ {
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kCHIPoBLEWriteReceived;
+ event.CHIPoBLEWriteReceived.ConId = (uint16_t) conn_id;
+ event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease();
+ PlatformMgr().PostEventOrDie(&event);
+ }
+
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err));
+ }
+}
+
+void BLEManagerImpl::HandleTXCharConfirm(CHIPoBLEConState * conState, int status)
+{
+ // If the confirmation was successful...
+ if (status == 0)
+ {
+ // Post an event to the Chip queue to process the indicate confirmation.
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm;
+ event.CHIPoBLEIndicateConfirm.ConId = conState->conn_idx;
+ PlatformMgr().PostEventOrDie(&event);
+ }
+ else
+ {
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kCHIPoBLEConnectionError;
+ event.CHIPoBLEConnectionError.ConId = conState->conn_idx;
+ event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT;
+ PlatformMgr().PostEventOrDie(&event);
+ }
+}
+
+void BLEManagerImpl::beken_ble_cmd_cb(ble_cmd_t cmd, ble_cmd_param_t * param)
+{
+ ChipLogProgress(DeviceLayer, "cmd:%d idx:%d status:%d\r\n", cmd, param->cmd_idx, param->status);
+ switch (cmd)
+ {
+ case BLE_CREATE_ADV:
+ sInstance.mFlags.Set(Flags::kBEKENBLEADVCreate);
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ break;
+ case BLE_SET_ADV_DATA:
+ sInstance.mFlags.Set(Flags::kBEKENBLEADVSetData);
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ break;
+ case BLE_SET_RSP_DATA:
+ sInstance.mFlags.Set(Flags::kBEKENBLEADVSetRsp);
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ break;
+ case BLE_START_ADV: {
+ uint32_t bleAdvTimeoutMs;
+ sInstance.mFlags.Set(Flags::kBEKENBLEADVStarted);
+ // if (sInstance.mFlags.Has(Flags::kAdvertisingIsFastADV)){
+ bleAdvTimeoutMs = CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME;
+ //}else{
+ // bleAdvTimeoutMs = CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT;
+ //}
+ StartBleAdvTimeoutTimer(bleAdvTimeoutMs);
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ }
+ break;
+ case BLE_STOP_ADV:
+ sInstance.mFlags.Clear(Flags::kBEKENBLEADVStarted);
+ ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped");
+ CancelBleAdvTimeoutTimer();
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ break;
+ case BLE_DELETE_ADV:
+ sInstance.mFlags.Clear(Flags::kBEKENBLEADVCreate);
+ sInstance.mFlags.Clear(Flags::kBEKENBLEADVSetData);
+ sInstance.mFlags.Clear(Flags::kBEKENBLEADVSetRsp);
+ sInstance.mFlags.Clear(Flags::kBEKENBLEADVStarted);
+ sInstance.adv_actv_idx = kUnusedIndex;
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ break;
+ case BLE_CONN_DIS_CONN:
+ break;
+ default:
+ break;
+ }
+}
+
+#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
+void BLEManagerImpl::HandleC3CharRead(void * param)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ chip::System::PacketBufferHandle bufferHandle;
+ ble_read_req_t * r_req = (ble_read_req_t *) param;
+
+ AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
+ BitFlags<AdditionalDataFields> additionalDataFields;
+
+#if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
+ uint8_t rotatingDeviceIdUniqueId[ConfigurationManager::kRotatingDeviceIDUniqueIDLength] = {};
+ MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId);
+
+ err = DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan);
+ SuccessOrExit(err);
+ err = ConfigurationMgr().GetLifetimeCounter(additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter);
+ SuccessOrExit(err);
+ additionalDataPayloadParams.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan;
+ additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId);
+#endif /* CHIP_ENABLE_ROTATING_DEVICE_ID */
+
+ err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(additionalDataPayloadParams, bufferHandle,
+ additionalDataFields);
+ SuccessOrExit(err);
+ if (r_req->value == NULL)
+ {
+ ChipLogError(DeviceLayer, "param->value == NULL");
+ return;
+ }
+ memcpy(r_req->value, bufferHandle->Start(), bufferHandle->DataLength());
+ r_req->length = bufferHandle->DataLength();
+exit:
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data");
+ }
+ return;
+}
+#endif
+
+void BLEManagerImpl::ble_event_notice(ble_notice_t notice, void * param)
+{
+ /// BLEManagerImpl * blemgr = static_cast<BLEManagerImpl *>(param);
+ static int conn_idx = 0; // TODO. will improve this when driver notify the status and channel to app.
+ switch (notice)
+ {
+ case BLE_5_STACK_OK: {
+ ChipLogProgress(DeviceLayer, "ble stack ok");
+ sInstance.mFlags.Set(Flags::kAMEBABLEStackInitialized);
+ }
+ break;
+ case BLE_5_WRITE_EVENT: {
+ ble_write_req_t * w_req = (ble_write_req_t *) param;
+ ChipLogProgress(DeviceLayer, "write_cb:conn_idx:%d, prf_id:%d, add_id:%d, len:%d, data[0]:%02x\r\n", w_req->conn_idx,
+ w_req->prf_id, w_req->att_idx, w_req->len, w_req->value[0]);
+ if (w_req->att_idx == SVR_FFF6_TX_VALUE)
+ {
+ sInstance.HandleRXCharWrite((uint8_t *) &w_req->value[0], w_req->len, w_req->conn_idx);
+ }
+ else if (w_req->att_idx == SVR_FFF6_TX_CFG)
+ {
+ int notificationsEnabled = w_req->value[0] | (w_req->value[0] << 8);
+ sInstance.HandleTXCharCCCDWrite(w_req->conn_idx, notificationsEnabled);
+ }
+ else if (w_req->att_idx == SVR_FFF6_RX_VALUE)
+ {
+ sInstance.HandleRXCharWrite((uint8_t *) &w_req->value[0], w_req->len, w_req->conn_idx);
+ }
+ break;
+ }
+ case BLE_5_READ_EVENT: {
+ ble_read_req_t * r_req = (ble_read_req_t *) param;
+ ChipLogProgress(DeviceLayer, "read_cb:conn_idx:%d, prf_id:%d, add_id:%d\r\n", r_req->conn_idx, r_req->prf_id,
+ r_req->att_idx);
+ if (r_req->att_idx == SVR_FFF6_RX_VALUE)
+ {
+ sInstance.HandleTXCharRead(param);
+ }
+ if (r_req->att_idx == SVR_FFF6_TX_CFG)
+ {
+ sInstance.HandleTXCharCCCDRead(param);
+ }
+#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
+ if (r_req->att_idx == SVR_FFF6_C3_VALUE)
+ {
+ ChipLogProgress(DeviceLayer, "SVR_FFF6_OPT_VALUE!!!!\r\n");
+ sInstance.HandleTXCharRead((void *) param);
+ }
+#endif
+ break;
+ }
+ case BLE_5_TX_DONE: {
+ ChipLogProgress(DeviceLayer, "BLE_5_TX_DONE");
+#if 0
+ tx_done_rsp_t* txd_rsp = (tx_done_rsp_t*)param;
+ if(txd_rsp) {
+ CHIPoBLEConState * conState = sInstance.GetConnectionState(txd_rsp->conn_idx,false);
+ if (conState != NULL)
+ {
+ sInstance.HandleTXCharConfirm(conState, txd_rsp->status);
+ }
+ }
+#endif
+ CHIPoBLEConState * conState = sInstance.GetConnectionState(conn_idx, false);
+ if (conState != NULL)
+ {
+ sInstance.HandleTXCharConfirm(conState, 0);
+ }
+ }
+ break;
+ case BLE_5_MTU_CHANGE: {
+ ble_mtu_change_t * m_ind = (ble_mtu_change_t *) param;
+ ChipLogProgress(DeviceLayer, "m_ind:conn_idx:%d, mtu_size:%d\r\n", m_ind->conn_idx, m_ind->mtu_size);
+ CHIPoBLEConState * conState = sInstance.GetConnectionState(m_ind->conn_idx);
+ if (conState != NULL)
+ {
+ conState->mtu = (m_ind->mtu_size >= (1 << 10)) ? ((1 << 10) - 1) : m_ind->mtu_size;
+ }
+ break;
+ }
+ case BLE_5_CONNECT_EVENT: {
+ ble_conn_ind_t * c_ind = (ble_conn_ind_t *) param;
+ ChipLogProgress(DeviceLayer, "BLE GATT connection established (con %u)", c_ind->conn_idx);
+ ChipLogProgress(DeviceLayer, "c_ind:conn_idx:%d, addr_type:%d, peer_addr:%02x:%02x:%02x:%02x:%02x:%02x\r\n",
+ c_ind->conn_idx, c_ind->peer_addr_type, c_ind->peer_addr[0], c_ind->peer_addr[1], c_ind->peer_addr[2],
+ c_ind->peer_addr[3], c_ind->peer_addr[4], c_ind->peer_addr[5]);
+ sInstance.mFlags.Clear(Flags::kBEKENBLEADVStarted);
+ CHIPoBLEConState * bleConnState = sInstance.GetConnectionState(c_ind->conn_idx, true);
+ if (bleConnState == NULL)
+ {
+ ChipLogError(DeviceLayer, "BLE_5_CONNECT_EVENT failed");
+ int ext_evt = DriveBLEExtPerfEvt_DISCONNECT | (c_ind->conn_idx << 8);
+ PlatformMgr().ScheduleWork(DriveBLEExtPerf, ext_evt);
+ }
+ conn_idx = c_ind->conn_idx;
+ break;
+ }
+ case BLE_5_DISCONNECT_EVENT: {
+ ble_discon_ind_t * d_ind = (ble_discon_ind_t *) param;
+ ChipLogProgress(DeviceLayer, "d_ind:conn_idx:%d,reason:%d\r\n", d_ind->conn_idx, d_ind->reason);
+ sInstance.HandleGAPDisconnect(d_ind->conn_idx, d_ind->reason);
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ break;
+ }
+ case BLE_5_ATT_INFO_REQ: {
+ ble_att_info_req_t * a_ind = (ble_att_info_req_t *) param;
+ ChipLogProgress(DeviceLayer, "a_ind:conn_idx:%d\r\n", a_ind->conn_idx);
+ if (SVR_FFF6_RX_VALUE == a_ind->att_idx)
+ {
+ a_ind->length = 512;
+ a_ind->status = BK_ERR_BLE_SUCCESS;
+ }
+ else if (SVR_FFF6_TX_CFG == a_ind->att_idx)
+ {
+ a_ind->length = 2;
+ a_ind->status = BK_ERR_BLE_SUCCESS;
+ }
+ break;
+ }
+ case BLE_5_CREATE_DB: {
+ ble_create_db_t * cd_ind = (ble_create_db_t *) param;
+ ChipLogProgress(DeviceLayer, "cd_ind:prf_id:%d, status:%d\r\n", cd_ind->prf_id, cd_ind->status);
+ sInstance.mFlags.Set(Flags::kBekenBLESGATTSReady);
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+ break;
+ }
+ default: {
+ ChipLogProgress(DeviceLayer, "Unhandled event:%x", notice);
+ }
+ break;
+ }
+}
+
+} // namespace Internal
+} // namespace DeviceLayer
+} // namespace chip
+#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
diff --git a/src/platform/Beken/BLEManagerImpl.h b/src/platform/Beken/BLEManagerImpl.h
new file mode 100644
index 0000000..5c8ef37
--- /dev/null
+++ b/src/platform/Beken/BLEManagerImpl.h
@@ -0,0 +1,232 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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
+
+#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
+#include "FreeRTOS.h"
+#include "event_groups.h"
+
+#include "matter_pal.h"
+
+namespace chip {
+namespace DeviceLayer {
+namespace Internal {
+
+using namespace chip::Ble;
+
+/**
+ * Concrete implementation of the BLEManager singleton object for the Ameba platforms.
+ */
+class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePlatformDelegate, private BleApplicationDelegate
+{
+ // Allow the BLEManager interface class to delegate method calls to
+ // the implementation methods provided by this class.
+ friend BLEManager;
+
+private:
+ // ===== Members that implement the BLEManager internal interface.
+
+ 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);
+ bool _IsAdvertising(void);
+ CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode);
+ CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize);
+ CHIP_ERROR _SetDeviceName(const char * deviceName);
+ uint16_t _NumConnections(void);
+ void _OnPlatformEvent(const ChipDeviceEvent * event);
+ BleLayer * _GetBleLayer(void);
+
+ // ===== Members that implement virtual methods on BlePlatformDelegate.
+
+ bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
+ const Ble::ChipBleUUID * charId) override;
+ bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
+ const Ble::ChipBleUUID * charId) override;
+ bool CloseConnection(BLE_CONNECTION_OBJECT conId) override;
+ uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override;
+ bool SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
+ System::PacketBufferHandle pBuf) override;
+ bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
+ System::PacketBufferHandle pBuf) override;
+ bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
+ System::PacketBufferHandle pBuf) override;
+ bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const Ble::ChipBleUUID * svcId,
+ const Ble::ChipBleUUID * charId) override;
+
+ // ===== Members that implement virtual methods on BleApplicationDelegate.
+
+ void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override;
+
+ // ===== Members for internal use by the following friends.
+
+ friend BLEManager & BLEMgr(void);
+ friend BLEManagerImpl & BLEMgrImpl(void);
+
+ static BLEManagerImpl sInstance;
+
+ // ===== Private members reserved for use by this class only.
+ enum class Flags : uint32_t
+ {
+ kAdvertisingEnabled = 0x0001,
+ kAdvertisingRefreshNeeded = 0x0002,
+ kFastAdvertisingEnabled = 0x0004,
+ kSlowAdvertisingEnabled = 0x0008,
+ kAdvertisingIsFastADV = 0x0010,
+ kAMEBABLEStackInitialized = 0x0020,
+ kDeviceNameSet = 0x0040,
+ kDeviceNameDefSet = 0x0080,
+
+ kBekenBLESGATTSReady = 0x00100,
+ kBEKENBLEADVCreate = 0x00200,
+ kBEKENBLEADVSetData = 0x00400,
+ kBEKENBLEADVSetRsp = 0x00800,
+ kBEKENBLEADVStarted = 0x01000,
+ kBEKENBLEADVStop = 0x02000,
+ kBEKENBLEADVDelet = 0x04000,
+ kBEKENBLEAdvTimer = 0x08000,
+ kBEKENBLEAdvTimerRun = 0x10000,
+ };
+
+ BitFlags<BLEManagerImpl::Flags> mFlags;
+
+ enum
+ {
+ kMaxConnections = BLE_LAYER_NUM_BLE_ENDPOINTS,
+ kMaxDeviceNameLength = 16,
+ kUnusedIndex = 0xFF,
+ };
+
+ struct CHIPoBLEConState
+ {
+ uint8_t conn_idx;
+ uint16_t mtu : 16;
+ uint16_t allocated : 1;
+ uint16_t subscribed : 1;
+ uint16_t unused : 6;
+ void Set(uint16_t conId)
+ {
+ conn_idx = conId;
+ mtu = 0;
+ allocated = 1;
+ subscribed = 0;
+ unused = 0;
+ }
+ void Reset()
+ {
+ conn_idx = kUnusedIndex;
+ mtu = 0;
+ allocated = 0;
+ subscribed = 0;
+ unused = 0;
+ }
+ };
+ CHIPoBLEConState mBleConnections[kMaxConnections];
+
+ CHIPoBLEServiceMode mServiceMode;
+
+ uint16_t mNumGAPCons;
+ uint16_t mTXCharCCCDAttrHandle;
+ char mDeviceName[kMaxDeviceNameLength + 1];
+ CHIP_ERROR MapBLEError(int bleErr);
+
+ void DriveBLEState(void);
+ CHIP_ERROR StartAdvertising(void);
+ CHIP_ERROR StopAdvertising(void);
+ CHIP_ERROR ConfigureAdvertisingData(void);
+
+ void HandleRXCharWrite(uint8_t *, uint16_t, uint8_t);
+ void HandleTXCharRead(void * param);
+ void HandleTXCharCCCDRead(void * param);
+ void HandleTXCharCCCDWrite(int, int, int ind = 0);
+ void HandleTXCharConfirm(CHIPoBLEConState * conState, int status);
+ CHIP_ERROR HandleTXComplete(int);
+ CHIP_ERROR HandleGAPConnect(uint16_t);
+ CHIP_ERROR HandleGAPDisconnect(uint16_t, uint16_t);
+ CHIP_ERROR SetSubscribed(uint16_t conId);
+ bool UnsetSubscribed(uint16_t conId);
+ bool IsSubscribed(uint16_t conId);
+
+ bool RemoveConnection(uint8_t connectionHandle);
+
+ uint8_t adv_actv_idx;
+ BLEManagerImpl::CHIPoBLEConState * GetConnectionState(uint8_t connectionHandle, bool allocate = false);
+ static void ble_event_notice(ble_notice_t notice, void * param);
+ static void beken_ble_cmd_cb(ble_cmd_t cmd, ble_cmd_param_t * param);
+ static void DriveBLEState(intptr_t arg);
+ static void DriveBLEExtPerf(intptr_t arg);
+ static int beken_ble_init(void);
+ static void ble_adv_timer_timeout_handle(TimerHandle_t xTimer);
+ static void CancelBleAdvTimeoutTimer(void);
+ static void StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs);
+#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
+ void HandleC3CharRead(void * param);
+#endif
+};
+
+/**
+ * Returns a reference to the public interface of the BLEManager singleton object.
+ *
+ * Internal components should use this to access features of the BLEManager object
+ * that are common to all platforms.
+ */
+inline BLEManager & BLEMgr(void)
+{
+ return BLEManagerImpl::sInstance;
+}
+
+/**
+ * Returns the platform-specific implementation of the BLEManager singleton object.
+ *
+ * Internal components can use this to gain access to features of the BLEManager
+ * that are specific to the platforms.
+ */
+inline BLEManagerImpl & BLEMgrImpl(void)
+{
+ return BLEManagerImpl::sInstance;
+}
+
+inline BleLayer * BLEManagerImpl::_GetBleLayer()
+{
+ return this;
+}
+
+inline BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode(void)
+{
+ return mServiceMode;
+}
+
+inline bool BLEManagerImpl::_IsAdvertisingEnabled(void)
+{
+ return mFlags.Has(Flags::kAdvertisingEnabled);
+}
+
+inline bool BLEManagerImpl::_IsAdvertising(void)
+{
+ return mFlags.Has(Flags::kBEKENBLEADVStarted);
+}
+
+} // namespace Internal
+} // namespace DeviceLayer
+} // namespace chip
+
+#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
diff --git a/src/platform/Beken/BUILD.gn b/src/platform/Beken/BUILD.gn
new file mode 100755
index 0000000..5e21bf5
--- /dev/null
+++ b/src/platform/Beken/BUILD.gn
@@ -0,0 +1,62 @@
+# Copyright (c) 2022 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.
+
+import("//build_overrides/chip.gni")
+
+import("${chip_root}/src/platform/device.gni")
+
+assert(chip_device_platform == "beken")
+
+static_library("Beken") {
+ sources = [
+ "../SingletonConfigurationManager.cpp",
+ "BLEManagerImpl.cpp",
+ "BLEManagerImpl.h",
+ "BekenConfig.cpp",
+ "BekenConfig.h",
+ "CHIPDevicePlatformConfig.h",
+ "CHIPDevicePlatformEvent.h",
+ "CHIPMem-Platform.cpp",
+ "ConfigurationManagerImpl.cpp",
+ "ConfigurationManagerImpl.h",
+ "ConnectivityManagerImpl.cpp",
+ "ConnectivityManagerImpl.h",
+
+ #"DeviceInfoProviderImpl.cpp",
+ #"DeviceInfoProviderImpl.h",
+ "DiagnosticDataProviderImpl.cpp",
+ "DiagnosticDataProviderImpl.h",
+ "KeyValueStoreManagerImpl.cpp",
+ "KeyValueStoreManagerImpl.h",
+ "Logging.cpp",
+ "LwIPCoreLock.cpp",
+ "NetworkCommissioningWiFiDriver.cpp",
+ "OTAImageProcessorImpl.cpp",
+ "OTAImageProcessorImpl.h",
+ "PlatformManagerImpl.cpp",
+ "PlatformManagerImpl.h",
+ "SystemPlatformConfig.h",
+ "SystemTimeSupport.cpp",
+ ]
+
+ deps = [
+ "${chip_root}/src/lib/dnssd:platform_header",
+ "${chip_root}/src/setup_payload",
+ ]
+
+ public_deps = [
+ "${chip_root}/src/crypto",
+ "${chip_root}/src/platform:platform_base",
+ ]
+}
diff --git a/src/platform/Beken/BekenConfig.cpp b/src/platform/Beken/BekenConfig.cpp
new file mode 100644
index 0000000..ab2fdca
--- /dev/null
+++ b/src/platform/Beken/BekenConfig.cpp
@@ -0,0 +1,316 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/* this file behaves like a config.h, comes first */
+#include <platform/internal/CHIPDeviceLayerInternal.h>
+
+#include <core/CHIPEncoding.h>
+#include <platform/Beken/BekenConfig.h>
+#include <support/CHIPMem.h>
+#include <support/CHIPMemString.h>
+#include <support/CodeUtils.h>
+#include <support/logging/CHIPLogging.h>
+
+#include "matter_pal.h"
+
+enum
+{
+ kPrefsTypeBoolean = 1,
+ kPrefsTypeInteger = 2,
+ kPrefsTypeString = 3,
+ kPrefsTypeBuffer = 4,
+ kPrefsTypeBinary = 5
+};
+
+namespace chip {
+namespace DeviceLayer {
+namespace Internal {
+
+// *** CAUTION ***: Changing the names or namespaces of these values will *break* existing devices.
+
+// NVS namespaces used to store device configuration information.
+const char BekenConfig::kConfigNamespace_ChipFactory[] = "chip-factory";
+const char BekenConfig::kConfigNamespace_ChipConfig[] = "chip-config";
+const char BekenConfig::kConfigNamespace_ChipCounters[] = "chip-counters";
+
+// Keys stored in the chip-factory namespace
+const BekenConfig::Key BekenConfig::kConfigKey_SerialNum = { kConfigNamespace_ChipFactory, "serial-num" };
+const BekenConfig::Key BekenConfig::kConfigKey_MfrDeviceId = { kConfigNamespace_ChipFactory, "device-id" };
+const BekenConfig::Key BekenConfig::kConfigKey_MfrDeviceCert = { kConfigNamespace_ChipFactory, "device-cert" };
+const BekenConfig::Key BekenConfig::kConfigKey_MfrDeviceICACerts = { kConfigNamespace_ChipFactory, "device-ca-certs" };
+const BekenConfig::Key BekenConfig::kConfigKey_MfrDevicePrivateKey = { kConfigNamespace_ChipFactory, "device-key" };
+const BekenConfig::Key BekenConfig::kConfigKey_HardwareVersion = { kConfigNamespace_ChipFactory, "hardware-ver" };
+const BekenConfig::Key BekenConfig::kConfigKey_ManufacturingDate = { kConfigNamespace_ChipFactory, "mfg-date" };
+const BekenConfig::Key BekenConfig::kConfigKey_SetupPinCode = { kConfigNamespace_ChipFactory, "pin-code" };
+const BekenConfig::Key BekenConfig::kConfigKey_SetupDiscriminator = { kConfigNamespace_ChipFactory, "discriminator" };
+const BekenConfig::Key BekenConfig::kConfigKey_Spake2pIterationCount = { kConfigNamespace_ChipFactory, "iteration-count" };
+const BekenConfig::Key BekenConfig::kConfigKey_Spake2pSalt = { kConfigNamespace_ChipFactory, "salt" };
+const BekenConfig::Key BekenConfig::kConfigKey_Spake2pVerifier = { kConfigNamespace_ChipFactory, "verifier" };
+const BekenConfig::Key BekenConfig::kConfigKey_UniqueId = { kConfigNamespace_ChipFactory, "uniqueId" };
+
+// Keys stored in the chip-config namespace
+const BekenConfig::Key BekenConfig::kConfigKey_FabricId = { kConfigNamespace_ChipConfig, "fabric-id" };
+const BekenConfig::Key BekenConfig::kConfigKey_ServiceConfig = { kConfigNamespace_ChipConfig, "service-config" };
+const BekenConfig::Key BekenConfig::kConfigKey_PairedAccountId = { kConfigNamespace_ChipConfig, "account-id" };
+const BekenConfig::Key BekenConfig::kConfigKey_ServiceId = { kConfigNamespace_ChipConfig, "service-id" };
+const BekenConfig::Key BekenConfig::kConfigKey_GroupKeyIndex = { kConfigNamespace_ChipConfig, "group-key-index" };
+const BekenConfig::Key BekenConfig::kConfigKey_LastUsedEpochKeyId = { kConfigNamespace_ChipConfig, "last-ek-id" };
+const BekenConfig::Key BekenConfig::kConfigKey_FailSafeArmed = { kConfigNamespace_ChipConfig, "fail-safe-armed" };
+const BekenConfig::Key BekenConfig::kConfigKey_WiFiStationSecType = { kConfigNamespace_ChipConfig, "sta-sec-type" };
+const BekenConfig::Key BekenConfig::kConfigKey_OperationalDeviceId = { kConfigNamespace_ChipConfig, "op-device-id" };
+const BekenConfig::Key BekenConfig::kConfigKey_OperationalDeviceCert = { kConfigNamespace_ChipConfig, "op-device-cert" };
+const BekenConfig::Key BekenConfig::kConfigKey_OperationalDeviceICACerts = { kConfigNamespace_ChipConfig, "op-device-ca-certs" };
+const BekenConfig::Key BekenConfig::kConfigKey_OperationalDevicePrivateKey = { kConfigNamespace_ChipConfig, "op-device-key" };
+const BekenConfig::Key BekenConfig::kConfigKey_RegulatoryLocation = { kConfigNamespace_ChipConfig, "regulatory-location" };
+const BekenConfig::Key BekenConfig::kConfigKey_CountryCode = { kConfigNamespace_ChipConfig, "country-code" };
+const BekenConfig::Key BekenConfig::kConfigKey_Breadcrumb = { kConfigNamespace_ChipConfig, "breadcrumb" };
+
+// Keys stored in the Chip-counters namespace
+const BekenConfig::Key BekenConfig::kCounterKey_RebootCount = { kConfigNamespace_ChipCounters, "reboot-count" };
+const BekenConfig::Key BekenConfig::kCounterKey_UpTime = { kConfigNamespace_ChipCounters, "up-time" };
+const BekenConfig::Key BekenConfig::kCounterKey_TotalOperationalHours = { kConfigNamespace_ChipCounters, "total-hours" };
+const BekenConfig::Key BekenConfig::kCounterKey_BootReason = { kConfigNamespace_ChipCounters, "boot-reason" };
+
+CHIP_ERROR BekenConfig::ReadConfigValue(Key key, bool & val)
+{
+ uint32_t success = 0;
+ uint32_t out_length = 0;
+ uint8_t intval = 0;
+ success = bk_read_data(key.Namespace, key.Name, (char *) &intval, 1, &out_length);
+
+ if (kNoErr != success)
+ ChipLogProgress(DeviceLayer, "bk_read_data: %s %s failed\n", (char *) key.Namespace, (char *) key.Name);
+
+ val = (intval != 0);
+ if (kNoErr == success)
+ return CHIP_NO_ERROR;
+ else
+ return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
+}
+
+CHIP_ERROR BekenConfig::ReadConfigValue(Key key, uint32_t & val)
+{
+ uint32_t success = 0;
+ uint32_t out_length = 0;
+ uint32_t temp_data = 0;
+
+ success = bk_read_data(key.Namespace, key.Name, (char *) &temp_data, sizeof(uint32_t), &out_length);
+
+ if (kNoErr != success)
+ ChipLogProgress(DeviceLayer, "bk_read_data: %s %s failed\n", (char *) key.Namespace, (char *) key.Name);
+ val = temp_data;
+
+ if (kNoErr == success)
+ return CHIP_NO_ERROR;
+ else
+ return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
+}
+
+CHIP_ERROR BekenConfig::ReadConfigValue(Key key, uint64_t & val)
+{
+ uint32_t success = 0;
+ uint32_t out_length = 0;
+ uint64_t temp_data = 0;
+
+ success = bk_read_data(key.Namespace, key.Name, (char *) &temp_data, sizeof(uint64_t), &out_length);
+
+ if (kNoErr != success)
+ ChipLogProgress(DeviceLayer, "bk_read_data: %s %s failed\n", (char *) key.Namespace, (char *) key.Name);
+ val = temp_data;
+
+ if (kNoErr == success)
+ return CHIP_NO_ERROR;
+ else
+ return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
+}
+
+CHIP_ERROR BekenConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen)
+{
+ uint32_t success = 0;
+ uint32_t out_length = 0;
+
+ success = bk_read_data(key.Namespace, key.Name, buf, bufSize, &out_length);
+ outLen = out_length;
+
+ if (kNoErr != success)
+ ChipLogProgress(DeviceLayer, "bk_read_data: %s %s failed\n", (char *) key.Namespace, (char *) key.Name);
+
+ if (kNoErr == success)
+ {
+ return CHIP_NO_ERROR;
+ }
+ else
+ {
+ outLen = 0;
+ return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
+ }
+}
+
+CHIP_ERROR BekenConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen)
+{
+ uint32_t success = 0;
+ uint32_t out_length = 0;
+
+ success = bk_read_data(key.Namespace, key.Name, (char *) buf, bufSize, &out_length);
+ outLen = out_length;
+
+ if (kNoErr != success)
+ ChipLogProgress(DeviceLayer, "bk_read_data: %s %s failed\n", (char *) key.Namespace, (char *) key.Name);
+
+ if (kNoErr == success)
+ {
+ return CHIP_NO_ERROR;
+ }
+ else
+ {
+ outLen = 0;
+ return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
+ }
+}
+
+CHIP_ERROR BekenConfig::WriteConfigValue(Key key, bool val)
+{
+ uint32_t success = 0;
+ uint8_t value = 0;
+
+ if (val == 1)
+ {
+ value = 1;
+ }
+ else
+ {
+ value = 0;
+ }
+
+ success = bk_write_data(key.Namespace, key.Name, (char *) &value, 1);
+ if (kNoErr != success)
+ ChipLogError(DeviceLayer, "bk_write_data: %s %s %s failed\n", (char *) key.Namespace, (char *) key.Name,
+ value ? "true" : "false");
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BekenConfig::WriteConfigValue(Key key, uint32_t val)
+{
+ uint32_t success = 0;
+
+ success = bk_write_data(key.Namespace, key.Name, (char *) &val, sizeof(val));
+ if (kNoErr != success)
+ ChipLogError(DeviceLayer, "bk_write_data: %s %s = %lu(0x%lx) failed\n", (char *) key.Namespace, (char *) key.Name, val,
+ val);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BekenConfig::WriteConfigValue(Key key, uint64_t val)
+{
+ uint32_t success = 0;
+
+ success = bk_write_data(key.Namespace, key.Name, (char *) &val, sizeof(val));
+ if (kNoErr != success)
+ ChipLogError(DeviceLayer, "bk_write_data: %s %s = %llu(0x%llx) failed\n", (char *) key.Namespace, (char *) key.Name, val,
+ val);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BekenConfig::WriteConfigValueStr(Key key, const char * str)
+{
+ uint32_t success = 0;
+
+ success = bk_write_data(key.Namespace, key.Name, (char *) str, strlen(str));
+ if (kNoErr != success)
+ ChipLogError(DeviceLayer, "bk_write_data: %s %s %s failed\n", (char *) key.Namespace, (char *) key.Name, (char *) str);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BekenConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen)
+{
+ uint32_t success = 0;
+ strLen = (strLen > strlen(str)) ? strlen(str) : strLen;
+
+ success = bk_write_data(key.Namespace, key.Name, (char *) str, strLen);
+ if (kNoErr != success)
+ ChipLogError(DeviceLayer, "bk_write_data: %s %s %s failed\n", (char *) key.Namespace, (char *) key.Name, (char *) str);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BekenConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen)
+{
+ uint32_t success = 0;
+
+ success = bk_write_data(key.Namespace, key.Name, (char *) data, dataLen);
+ if (kNoErr != success)
+ ChipLogError(DeviceLayer, "bk_write_data: %s %s failed \r\n", key.Namespace, key.Name);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BekenConfig::ClearConfigValue(Key key)
+{
+ uint32_t success = 0;
+
+ success = bk_clean_data(key.Namespace, key.Name);
+ if (kNoErr != success)
+ ChipLogProgress(DeviceLayer, "%s : %s %s failed\n", __FUNCTION__, key.Namespace, key.Name);
+ return CHIP_NO_ERROR;
+}
+
+bool BekenConfig::ConfigValueExists(Key key)
+{
+ if (kNoErr == bk_ensure_name_data(key.Namespace, key.Name))
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+CHIP_ERROR BekenConfig::EnsureNamespace(const char * ns)
+{
+ uint32_t success = 0;
+
+ success = bk_ensure_namespace(ns);
+ if (kNoErr != success)
+ {
+ ChipLogError(DeviceLayer, "dct_register_module failed\n");
+ }
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BekenConfig::ClearNamespace(const char * ns)
+{
+ uint32_t success = 0;
+
+ success = bK_clear_namespace(ns);
+ if (success != 0)
+ {
+ ChipLogError(DeviceLayer, "ClearNamespace failed\n");
+ }
+ return CHIP_NO_ERROR;
+}
+
+void BekenConfig::RunConfigUnitTest() {}
+
+} // namespace Internal
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/BekenConfig.h b/src/platform/Beken/BekenConfig.h
new file mode 100755
index 0000000..7913e39
--- /dev/null
+++ b/src/platform/Beken/BekenConfig.h
@@ -0,0 +1,116 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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 <platform/internal/CHIPDeviceLayerInternal.h>
+
+#include <string.h>
+namespace chip {
+namespace DeviceLayer {
+namespace Internal {
+
+class BekenConfig
+{
+public:
+ struct Key;
+
+ // Maximum length of an NVS key name.
+ static constexpr size_t kMaxConfigKeyNameLength = 15;
+
+ // NVS namespaces used to store device configuration information.
+ static const char kConfigNamespace_ChipFactory[];
+ static const char kConfigNamespace_ChipConfig[];
+ static const char kConfigNamespace_ChipCounters[];
+
+ // Key definitions for well-known keys.
+ static const Key kConfigKey_SerialNum;
+ static const Key kConfigKey_MfrDeviceId;
+ static const Key kConfigKey_MfrDeviceCert;
+ static const Key kConfigKey_MfrDeviceICACerts;
+ static const Key kConfigKey_MfrDevicePrivateKey;
+ static const Key kConfigKey_HardwareVersion;
+ static const Key kConfigKey_ManufacturingDate;
+ static const Key kConfigKey_SetupPinCode;
+ static const Key kConfigKey_FabricId;
+ static const Key kConfigKey_ServiceConfig;
+ static const Key kConfigKey_PairedAccountId;
+ static const Key kConfigKey_ServiceId;
+ static const Key kConfigKey_FabricSecret;
+ static const Key kConfigKey_GroupKeyIndex;
+ static const Key kConfigKey_LastUsedEpochKeyId;
+ static const Key kConfigKey_FailSafeArmed;
+ static const Key kConfigKey_WiFiStationSecType;
+ static const Key kConfigKey_OperationalDeviceId;
+ static const Key kConfigKey_OperationalDeviceCert;
+ static const Key kConfigKey_OperationalDeviceICACerts;
+ static const Key kConfigKey_OperationalDevicePrivateKey;
+ static const Key kConfigKey_SetupDiscriminator;
+ static const Key kConfigKey_RegulatoryLocation;
+ static const Key kConfigKey_CountryCode;
+ static const Key kConfigKey_Breadcrumb;
+ static const Key kConfigKey_Spake2pIterationCount;
+ static const Key kConfigKey_Spake2pSalt;
+ static const Key kConfigKey_Spake2pVerifier;
+
+ // Counter keys
+ static const Key kConfigKey_UniqueId;
+ static const Key kCounterKey_RebootCount;
+ static const Key kCounterKey_UpTime;
+ static const Key kCounterKey_TotalOperationalHours;
+ static const Key kCounterKey_BootReason;
+
+ static const char kGroupKeyNamePrefix[];
+
+ // Config value accessors.
+ static CHIP_ERROR ReadConfigValue(Key key, bool & val);
+ static CHIP_ERROR ReadConfigValue(Key key, uint32_t & val);
+ static CHIP_ERROR ReadConfigValue(Key key, uint64_t & val);
+ static CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen);
+ static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen);
+ static CHIP_ERROR WriteConfigValue(Key key, bool val);
+ static CHIP_ERROR WriteConfigValue(Key key, uint32_t val);
+ static CHIP_ERROR WriteConfigValue(Key key, uint64_t val);
+ static CHIP_ERROR WriteConfigValueStr(Key key, const char * str);
+ static CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen);
+ static CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen);
+ static CHIP_ERROR ClearConfigValue(Key key);
+ static bool ConfigValueExists(Key key);
+
+ static CHIP_ERROR EnsureNamespace(const char * ns);
+ static CHIP_ERROR ClearNamespace(const char * ns);
+
+ static void RunConfigUnitTest(void);
+};
+
+struct BekenConfig::Key
+{
+ const char * Namespace;
+ const char * Name;
+
+ bool operator==(const Key & other) const;
+};
+
+inline bool BekenConfig::Key::operator==(const Key & other) const
+{
+ return strcmp(Namespace, other.Namespace) == 0 && strcmp(Name, other.Name) == 0;
+}
+
+} // namespace Internal
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/BlePlatformConfig.h b/src/platform/Beken/BlePlatformConfig.h
new file mode 100644
index 0000000..774fb3e
--- /dev/null
+++ b/src/platform/Beken/BlePlatformConfig.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Platform-specific configuration overrides for the CHIP BLE
+ * Layer on Beken platform.
+ *
+ */
+
+#pragma once
+
+// ==================== Platform Adaptations ====================
+
+#define BLE_CONNECTION_OBJECT uint16_t
+#define BLE_CONNECTION_UNINITIALIZED (0xFFFF)
+#define BLE_MAX_RECEIVE_WINDOW_SIZE 5
+
+#define BLE_CONFIG_ERROR_MIN 6000000
+#define BLE_CONFIG_ERROR_MAX 6000999
+
+// ========== Platform-specific Configuration Overrides =========
+
+/* none so far */
diff --git a/src/platform/Beken/CHIPDevicePlatformConfig.h b/src/platform/Beken/CHIPDevicePlatformConfig.h
new file mode 100755
index 0000000..622faa0
--- /dev/null
+++ b/src/platform/Beken/CHIPDevicePlatformConfig.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Platform-specific configuration overrides for the chip Device Layer
+ * on Beken platform.
+ */
+
+#pragma once
+
+// ==================== Platform Adaptations ====================
+#define CHIP_CONFIG_ERROR_CLASS 1
+
+#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0
+#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0
+
+#if CHIP_ENABLE_OPENTHREAD
+#define CHIP_DEVICE_CONFIG_ENABLE_THREAD 1
+#endif
+
+#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1
+
+#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0
+
+// ========== Platform-specific Configuration =========
+
+// These are configuration options that are unique to the platform.
+// These can be overridden by the application as needed.
+
+// ...
+
+// ========== Platform-specific Configuration Overrides =========
+
+#ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE
+#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE 8192
+#endif // CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE
+
+#ifndef CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE
+#define CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE 4096
+#endif // CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE
+
+#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_TELEMETRY 0
+#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY 0
+#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY_FULL 0
+#define CHIP_DEVICE_CONFIG_LOG_PROVISIONING_HASH 0
+
+#define CHIP_DEVICE_LAYER_NONE 0
+
+// Use a default pairing code if one hasn't been provisioned in flash.
+#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021
+#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00
+
+#define CONFIG_RENDEZVOUS_MODE 6
+#define CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY 2
+
+#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1
+#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DISCOVERY 1
diff --git a/src/platform/Beken/CHIPDevicePlatformEvent.h b/src/platform/Beken/CHIPDevicePlatformEvent.h
new file mode 100644
index 0000000..02d621a
--- /dev/null
+++ b/src/platform/Beken/CHIPDevicePlatformEvent.h
@@ -0,0 +1,91 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Defines platform-specific event types and data for the chip
+ * Device Layer on Beken platforms.
+ */
+
+#pragma once
+
+#include <platform/CHIPDeviceEvent.h>
+
+namespace chip {
+namespace DeviceLayer {
+namespace DeviceEventType {
+
+/**
+ * Enumerates platform-specific event types that are visible to the application.
+ */
+enum PublicPlatformSpecificEventTypes
+{
+ kBKSystemEvent = kRange_PublicPlatformSpecific,
+};
+
+/**
+ * Enumerates platform-specific event types that are internal to the chip Device Layer.
+ */
+enum InternalPlatformSpecificEventTypes
+{
+ kQorvoBLEConnected = kRange_InternalPlatformSpecific,
+ kQorvoBLEDisconnected,
+ kCHIPoBLECCCWriteEvent,
+ kCHIPoBLERXCharWriteEvent,
+ kCHIPoBLETXCharWriteEvent,
+ kRtkWiFiStationConnectedEvent,
+};
+
+} // namespace DeviceEventType
+
+/**
+ * Represents platform-specific event information.
+ */
+struct ChipDevicePlatformEvent final
+{
+ // TODO - add platform specific definition extension
+ union
+ {
+ struct
+ {
+ uint8_t dummy;
+ } QorvoBLEConnected;
+ struct
+ {
+ uint8_t dummy;
+ } CHIPoBLECCCWriteEvent;
+ struct
+ {
+ uint8_t dummy;
+ } CHIPoBLERXCharWriteEvent;
+ struct
+ {
+ uint8_t dummy;
+ } CHIPoBLETXCharWriteEvent;
+ struct
+ {
+ union
+ {
+ uint16_t WiFiStaDisconnected;
+ } Data;
+ } BKSystemEvent;
+ };
+};
+
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/CHIPMem-Platform.cpp b/src/platform/Beken/CHIPMem-Platform.cpp
new file mode 100644
index 0000000..09830b5
--- /dev/null
+++ b/src/platform/Beken/CHIPMem-Platform.cpp
@@ -0,0 +1,123 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * This file implements heap memory allocation APIs for CHIP. These functions are platform
+ * specific and might be C Standard Library heap functions re-direction in most of cases.
+ *
+ */
+
+//#include <lib/core/CHIPConfig.h>
+#include "matter_pal.h"
+#include <lib/support/CHIPMem.h>
+#include <platform/PlatformManager.h>
+
+#include <atomic>
+#include <cstdio>
+#include <cstring>
+#include <stdlib.h>
+
+#if CHIP_CONFIG_MEMORY_MGMT_PLATFORM
+
+namespace chip {
+namespace Platform {
+
+#define VERIFY_INITIALIZED() VerifyInitialized(__func__)
+
+static std::atomic_int memoryInitialized{ 0 };
+
+static void VerifyInitialized(const char * func)
+{
+#if 0
+ if (!memoryInitialized)
+ {
+ fprintf(stderr, "ABORT: chip::Platform::%s() called before chip::Platform::MemoryInit()\n", func);
+ abort();
+ }
+#endif
+}
+
+CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize)
+{
+#ifndef NDEBUG
+ if (memoryInitialized++ > 0)
+ {
+ fprintf(stderr, "ABORT: chip::Platform::MemoryInit() called twice.\n");
+ abort();
+ }
+#endif
+ return CHIP_NO_ERROR;
+}
+
+void MemoryAllocatorShutdown()
+{
+#ifndef NDEBUG
+ if (--memoryInitialized < 0)
+ {
+ fprintf(stderr, "ABORT: chip::Platform::MemoryShutdown() called twice.\n");
+ abort();
+ }
+#endif
+}
+
+void * MemoryAlloc(size_t size)
+{
+ void * ptr;
+ VERIFY_INITIALIZED();
+ ptr = os_zalloc(size); // NULL;
+ return ptr;
+}
+
+void * MemoryAlloc(size_t size, bool isLongTermAlloc)
+{
+ void * ptr;
+ VERIFY_INITIALIZED();
+ ptr = os_zalloc(size);
+ return ptr;
+}
+
+void * MemoryCalloc(size_t num, size_t size)
+{
+ VERIFY_INITIALIZED();
+ void * ptr = os_zalloc(num * size);
+ return ptr;
+}
+
+void * MemoryRealloc(void * p, size_t size)
+{
+ VERIFY_INITIALIZED();
+ p = os_realloc(p, size);
+ return p;
+}
+
+void MemoryFree(void * p)
+{
+ VERIFY_INITIALIZED();
+ os_free(p);
+}
+
+bool MemoryInternalCheckPointer(const void * p, size_t min_size)
+{
+ return (p != nullptr);
+}
+
+} // namespace Platform
+} // namespace chip
+
+#endif // CHIP_CONFIG_MEMORY_MGMT_PLATFORM
diff --git a/src/platform/Beken/CHIPPlatformConfig.h b/src/platform/Beken/CHIPPlatformConfig.h
new file mode 100644
index 0000000..33f416e
--- /dev/null
+++ b/src/platform/Beken/CHIPPlatformConfig.h
@@ -0,0 +1,116 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Platform-specific configuration overrides for CHIP on
+ * Beken platforms.
+ */
+
+#pragma once
+
+// ==================== General Platform Adaptations ====================
+
+#define CHIP_CONFIG_ERROR_TYPE uint32_t
+#define CHIP_CONFIG_ERROR_FORMAT PRId32
+#define CHIP_CONFIG_NO_ERROR 0
+#define CHIP_CONFIG_ERROR_MIN 4000000
+#define CHIP_CONFIG_ERROR_MAX 4000999
+
+#define ASN1_CONFIG_ERROR_TYPE uint32_t
+#define ASN1_CONFIG_NO_ERROR 0
+#define ASN1_CONFIG_ERROR_MIN 5000000
+#define ASN1_CONFIG_ERROR_MAX 5000999
+
+#define CHIP_CONFIG_TIME_ENABLE_CLIENT 1
+#define CHIP_CONFIG_TIME_ENABLE_SERVER 0
+
+#define ChipDie() abort()
+
+// ==================== Security Adaptations ====================
+
+#define CHIP_CONFIG_USE_OPENSSL_ECC 0
+#define CHIP_CONFIG_USE_MICRO_ECC 0
+
+#define CHIP_CONFIG_HASH_IMPLEMENTATION_OPENSSL 0
+#define CHIP_CONFIG_HASH_IMPLEMENTATION_MINCRYPT 1
+
+#define CHIP_CONFIG_AES_IMPLEMENTATION_OPENSSL 0
+#define CHIP_CONFIG_AES_IMPLEMENTATION_AESNI 0
+#define CHIP_CONFIG_AES_IMPLEMENTATION_MBEDTLS 0
+#define CHIP_CONFIG_AES_IMPLEMENTATION_PLATFORM 1
+
+#define CHIP_CONFIG_RNG_IMPLEMENTATION_OPENSSL 0
+#define CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG 1
+#define CHIP_CONFIG_RNG_IMPLEMENTATION_PLATFORM 0
+
+#define CHIP_CONFIG_ENABLE_PASE_INITIATOR 0
+#define CHIP_CONFIG_ENABLE_PASE_RESPONDER 1
+#define CHIP_CONFIG_ENABLE_CASE_INITIATOR 1
+
+#define CHIP_CONFIG_SUPPORT_PASE_CONFIG0 0
+#define CHIP_CONFIG_SUPPORT_PASE_CONFIG1 0
+#define CHIP_CONFIG_SUPPORT_PASE_CONFIG2 0
+#define CHIP_CONFIG_SUPPORT_PASE_CONFIG3 0
+#define CHIP_CONFIG_SUPPORT_PASE_CONFIG4 1
+
+#define CHIP_CONFIG_ENABLE_KEY_EXPORT_INITIATOR 0
+
+#define CHIP_CONFIG_ENABLE_PROVISIONING_BUNDLE_SUPPORT 0
+
+// ==================== General Configuration Overrides ====================
+
+#ifndef CHIP_CONFIG_MAX_PEER_NODES
+#define CHIP_CONFIG_MAX_PEER_NODES 16
+#endif // CHIP_CONFIG_MAX_PEER_NODES
+
+#ifndef CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS
+#define CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS 16
+#endif // CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS
+
+#ifndef CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS
+#define CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS 8
+#endif // CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS
+
+#ifndef CHIP_CONFIG_WRMP_TIMER_DEFAULT_PERIOD
+#define CHIP_CONFIG_WRMP_TIMER_DEFAULT_PERIOD 50
+#endif // CHIP_CONFIG_WRMP_TIMER_DEFAULT_PERIOD
+
+#ifndef CHIP_LOG_FILTERING
+#define CHIP_LOG_FILTERING 0
+#endif // CHIP_LOG_FILTERING
+
+#ifndef CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS
+#define CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS 1
+#endif // CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS
+
+// ==================== Security Configuration Overrides ====================
+
+#ifndef CHIP_CONFIG_MAX_APPLICATION_GROUPS
+#define CHIP_CONFIG_MAX_APPLICATION_GROUPS 4
+#endif // CHIP_CONFIG_MAX_APPLICATION_GROUPS
+
+#ifndef CHIP_CONFIG_DEBUG_CERT_VALIDATION
+#define CHIP_CONFIG_DEBUG_CERT_VALIDATION 0
+#endif // CHIP_CONFIG_DEBUG_CERT_VALIDATION
+
+#ifndef CHIP_CONFIG_ENABLE_CASE_RESPONDER
+#define CHIP_CONFIG_ENABLE_CASE_RESPONDER 1
+#endif // CHIP_CONFIG_ENABLE_CASE_RESPONDER
+
+#define CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE 1
diff --git a/src/platform/Beken/ConfigurationManagerImpl.cpp b/src/platform/Beken/ConfigurationManagerImpl.cpp
new file mode 100644
index 0000000..895f76f
--- /dev/null
+++ b/src/platform/Beken/ConfigurationManagerImpl.cpp
@@ -0,0 +1,242 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Provides the implementation of the Device Layer ConfigurationManager object
+ * for the Beken.
+ */
+/* this file behaves like a config.h, comes first */
+#include <platform/internal/CHIPDeviceLayerInternal.h>
+
+#include <platform/Beken/BekenConfig.h>
+#include <platform/ConfigurationManager.h>
+#include <platform/DiagnosticDataProvider.h>
+#include <platform/internal/GenericConfigurationManagerImpl.ipp>
+#include <support/CodeUtils.h>
+#include <support/logging/CHIPLogging.h>
+
+#include "matter_pal.h"
+
+namespace chip {
+namespace DeviceLayer {
+
+using namespace chip::DeviceLayer::Internal;
+
+ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance()
+{
+ static ConfigurationManagerImpl sInstance;
+ return sInstance;
+}
+
+CHIP_ERROR ConfigurationManagerImpl::Init()
+{
+ CHIP_ERROR err;
+ uint32_t rebootCount;
+
+ ChipLogProgress(DeviceLayer, "ConfigurationManagerImpl::Init");
+ // Force initialization of NVS namespaces if they doesn't already exist.
+ err = BekenConfig::EnsureNamespace(BekenConfig::kConfigNamespace_ChipFactory);
+ SuccessOrExit(err);
+ err = BekenConfig::EnsureNamespace(BekenConfig::kConfigNamespace_ChipConfig);
+ SuccessOrExit(err);
+ err = BekenConfig::EnsureNamespace(BekenConfig::kConfigNamespace_ChipCounters);
+ SuccessOrExit(err);
+
+ if (BekenConfig::ConfigValueExists(BekenConfig::kCounterKey_RebootCount))
+ {
+ err = GetRebootCount(rebootCount);
+ SuccessOrExit(err);
+
+ err = StoreRebootCount(rebootCount + 1);
+ SuccessOrExit(err);
+ }
+ else
+ {
+ // The first boot after factory reset of the Node.
+ err = StoreRebootCount(1);
+ SuccessOrExit(err);
+ }
+
+ if (!BekenConfig::ConfigValueExists(BekenConfig::kCounterKey_TotalOperationalHours))
+ {
+ err = StoreTotalOperationalHours(0);
+ SuccessOrExit(err);
+ }
+
+ if (!BekenConfig::ConfigValueExists(BekenConfig::kCounterKey_BootReason))
+ {
+ err = StoreBootReason(to_underlying(BootReasonType::kUnspecified));
+ SuccessOrExit(err);
+ }
+
+ // Initialize the generic implementation base class.
+ err = Internal::GenericConfigurationManagerImpl<BekenConfig>::Init();
+ SuccessOrExit(err);
+
+ err = CHIP_NO_ERROR;
+exit:
+ return err;
+}
+
+CHIP_ERROR ConfigurationManagerImpl::GetRebootCount(uint32_t & rebootCount)
+{
+ return ReadConfigValue(BekenConfig::kCounterKey_RebootCount, rebootCount);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::StoreRebootCount(uint32_t rebootCount)
+{
+ return WriteConfigValue(BekenConfig::kCounterKey_RebootCount, rebootCount);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours)
+{
+ return ReadConfigValue(BekenConfig::kCounterKey_TotalOperationalHours, totalOperationalHours);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::StoreTotalOperationalHours(uint32_t totalOperationalHours)
+{
+ return WriteConfigValue(BekenConfig::kCounterKey_TotalOperationalHours, totalOperationalHours);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::GetBootReason(uint32_t & bootReason)
+{
+ return ReadConfigValue(BekenConfig::kCounterKey_BootReason, bootReason);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::StoreBootReason(uint32_t bootReason)
+{
+ return WriteConfigValue(BekenConfig::kCounterKey_BootReason, bootReason);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::GetPrimaryWiFiMACAddress(uint8_t * buf)
+{
+ bk_wifi_sta_get_mac(buf);
+ return CHIP_NO_ERROR;
+}
+
+bool ConfigurationManagerImpl::CanFactoryReset()
+{
+ // TODO: query the application to determine if factory reset is allowed.
+ return true;
+}
+
+void ConfigurationManagerImpl::InitiateFactoryReset()
+{
+ PlatformMgr().ScheduleWork(DoFactoryReset);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value)
+{
+ BekenConfig::Key configKey{ BekenConfig::kConfigNamespace_ChipCounters, key };
+
+ CHIP_ERROR err = ReadConfigValue(configKey, value);
+ if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND)
+ {
+ err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
+ }
+ return err;
+}
+
+CHIP_ERROR ConfigurationManagerImpl::WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value)
+{
+ BekenConfig::Key configKey{ BekenConfig::kConfigNamespace_ChipCounters, key };
+ return WriteConfigValue(configKey, value);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, bool & val)
+{
+ return BekenConfig::ReadConfigValue(key, val);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint32_t & val)
+{
+ return BekenConfig::ReadConfigValue(key, val);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint64_t & val)
+{
+ return BekenConfig::ReadConfigValue(key, val);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen)
+{
+ return BekenConfig::ReadConfigValueStr(key, buf, bufSize, outLen);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen)
+{
+ return BekenConfig::ReadConfigValueBin(key, buf, bufSize, outLen);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, bool val)
+{
+ return BekenConfig::WriteConfigValue(key, val);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint32_t val)
+{
+ return BekenConfig::WriteConfigValue(key, val);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint64_t val)
+{
+ return BekenConfig::WriteConfigValue(key, val);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str)
+{
+ return BekenConfig::WriteConfigValueStr(key, str);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str, size_t strLen)
+{
+ return BekenConfig::WriteConfigValueStr(key, str, strLen);
+}
+
+CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen)
+{
+ return BekenConfig::WriteConfigValueBin(key, data, dataLen);
+}
+
+void ConfigurationManagerImpl::RunConfigUnitTest(void)
+{
+ BekenConfig::RunConfigUnitTest();
+}
+
+void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg)
+{
+ CHIP_ERROR err;
+
+ ChipLogProgress(DeviceLayer, "Performing factory reset");
+
+ // Erase all values in the chip-config NVS namespace.
+ bk_erase_all(BK_PARTITION_MATTER_FLASH);
+
+ // Restart the system.
+ ChipLogProgress(DeviceLayer, "System restarting");
+ bk_reboot();
+}
+
+ConfigurationManager & ConfigurationMgrImpl()
+{
+ return ConfigurationManagerImpl::GetDefaultInstance();
+}
+
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/ConfigurationManagerImpl.h b/src/platform/Beken/ConfigurationManagerImpl.h
new file mode 100644
index 0000000..6d67840
--- /dev/null
+++ b/src/platform/Beken/ConfigurationManagerImpl.h
@@ -0,0 +1,87 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Provides an implementation of the ConfigurationManager object
+ * for the Beken platform.
+ */
+#pragma once
+
+#include <platform/Beken/BekenConfig.h>
+#include <platform/ConnectivityManager.h>
+#include <platform/internal/GenericConfigurationManagerImpl.h>
+
+namespace chip {
+namespace DeviceLayer {
+/**
+ * Concrete implementation of the ConfigurationManager singleton object for the Beken platform.
+ */
+class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl<Internal::BekenConfig>
+{
+public:
+ // This returns an instance of this class.
+ static ConfigurationManagerImpl & GetDefaultInstance();
+
+private:
+ // ===== Members that implement the ConfigurationManager public interface.
+
+ CHIP_ERROR Init(void);
+ CHIP_ERROR GetPrimaryWiFiMACAddress(uint8_t * buf);
+ bool CanFactoryReset(void);
+ void InitiateFactoryReset(void);
+ CHIP_ERROR ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value);
+ CHIP_ERROR WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value);
+ CHIP_ERROR GetRebootCount(uint32_t & rebootCount);
+ CHIP_ERROR StoreRebootCount(uint32_t rebootCount);
+ CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours);
+ CHIP_ERROR StoreTotalOperationalHours(uint32_t totalOperationalHours);
+ CHIP_ERROR GetBootReason(uint32_t & bootReason);
+ CHIP_ERROR StoreBootReason(uint32_t bootReason);
+
+ // NOTE: Other public interface methods are implemented by GenericConfigurationManagerImpl<>.
+
+ // ===== Members that implement the GenericConfigurationManagerImpl protected interface.
+ CHIP_ERROR ReadConfigValue(Key key, bool & val);
+ CHIP_ERROR ReadConfigValue(Key key, uint32_t & val);
+ CHIP_ERROR ReadConfigValue(Key key, uint64_t & val);
+ CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen);
+ CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen);
+ CHIP_ERROR WriteConfigValue(Key key, bool val);
+ CHIP_ERROR WriteConfigValue(Key key, uint32_t val);
+ CHIP_ERROR WriteConfigValue(Key key, uint64_t val);
+ CHIP_ERROR WriteConfigValueStr(Key key, const char * str);
+ CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen);
+ CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen);
+ void RunConfigUnitTest(void);
+
+ // ===== Private members reserved for use by this class only.
+
+ static void DoFactoryReset(intptr_t arg);
+};
+
+/**
+ * Returns the platform-specific implementation of the ConfigurationManager object.
+ *
+ * Applications can use this to gain access to features of the ConfigurationManager
+ * that are specific to the selected platform.
+ */
+ConfigurationManager & ConfigurationMgrImpl();
+
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/ConnectivityManagerImpl.cpp b/src/platform/Beken/ConnectivityManagerImpl.cpp
new file mode 100644
index 0000000..eb66359
--- /dev/null
+++ b/src/platform/Beken/ConnectivityManagerImpl.cpp
@@ -0,0 +1,649 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+/* this file behaves like a config.h, comes first */
+#include <platform/internal/CHIPDeviceLayerInternal.h>
+
+#include <platform/ConnectivityManager.h>
+
+#include <platform/internal/GenericConnectivityManagerImpl_UDP.ipp>
+
+#if INET_CONFIG_ENABLE_TCP_ENDPOINT
+#include <platform/internal/GenericConnectivityManagerImpl_TCP.ipp>
+#endif
+
+#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
+#include <platform/internal/GenericConnectivityManagerImpl_BLE.ipp>
+#endif
+
+#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
+#include <platform/internal/GenericConnectivityManagerImpl_Thread.ipp>
+#endif
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+#include <platform/internal/GenericConnectivityManagerImpl_WiFi.ipp>
+#endif
+
+#include <platform/internal/BLEManager.h>
+#include <support/CodeUtils.h>
+#include <support/logging/CHIPLogging.h>
+
+#include <lwip/dns.h>
+#include <lwip/ip_addr.h>
+#include <lwip/nd6.h>
+#include <lwip/netif.h>
+
+#include "NetworkCommissioningDriver.h"
+
+#include "matter_pal.h"
+#include <components/netif.h>
+
+using namespace ::chip;
+using namespace ::chip::Inet;
+using namespace ::chip::TLV;
+using namespace ::chip::DeviceLayer::Internal;
+
+namespace chip {
+namespace DeviceLayer {
+
+ConnectivityManagerImpl ConnectivityManagerImpl::sInstance;
+NetworkCommissioning::BekenWiFiDriver::WiFiNetwork mWifiNetconf;
+
+// ==================== ConnectivityManager Platform Internal Methods ====================
+
+CHIP_ERROR ConnectivityManagerImpl::_Init()
+{
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+ mLastStationConnectFailTime = System::Clock::kZero;
+ mLastAPDemandTime = System::Clock::kZero;
+ mWiFiStationMode = kWiFiStationMode_Disabled;
+ mWiFiStationState = kWiFiStationState_NotConnected;
+ mWiFiAPMode = kWiFiAPMode_Disabled;
+ mWiFiAPState = kWiFiAPState_NotActive;
+ mWiFiStationReconnectInterval = System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_WIFI_STATION_RECONNECT_INTERVAL);
+ mWiFiAPIdleTimeout = System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_WIFI_AP_IDLE_TIMEOUT);
+ mFlags.SetRaw(0);
+
+ memset(&mWifiNetconf, 0x0, sizeof(mWifiNetconf));
+ // If there is no persistent station provision...
+ if (!IsWiFiStationProvisioned())
+ {
+ // If the code has been compiled with a default WiFi station provision, configure that now.
+#if !defined(CONFIG_DEFAULT_WIFI_SSID)
+ printf("%s %d pls define CONFIG_DEFAULT_WIFI_SSID\r\n", __func__, __LINE__);
+#else
+ if (CONFIG_DEFAULT_WIFI_SSID[0] != 0)
+ {
+ ChipLogProgress(DeviceLayer, "Setting default WiFi station configuration (SSID: %s)", CONFIG_DEFAULT_WIFI_SSID);
+
+ // Set a default station configuration.
+ rtw_wifi_setting_t wifiConfig;
+
+ // Set the wifi configuration
+ memset(&wifiConfig, 0, sizeof(wifiConfig));
+ memcpy(wifiConfig.ssid, CONFIG_DEFAULT_WIFI_SSID, strlen(CONFIG_DEFAULT_WIFI_SSID) + 1);
+ memcpy(wifiConfig.password, CONFIG_DEFAULT_WIFI_PASSWORD, strlen(CONFIG_DEFAULT_WIFI_PASSWORD) + 1);
+ wifiConfig.mode = RTW_MODE_STA;
+
+ // Configure the WiFi interface.
+ int err = CHIP_SetWiFiConfig(&wifiConfig);
+ if (err != 0)
+ {
+ ChipLogError(DeviceLayer, "_Init _SetWiFiConfig() failed: %d", err);
+ }
+
+ // Enable WiFi station mode.
+ ReturnErrorOnFailure(SetWiFiStationMode(kWiFiStationMode_Enabled));
+ }
+
+ // Otherwise, ensure WiFi station mode is disabled.
+ else
+ {
+ ReturnErrorOnFailure(SetWiFiStationMode(kWiFiStationMode_Disabled));
+ }
+#endif
+ }
+
+ // Force AP mode off for now.
+
+ // Queue work items to bootstrap the AP and station state machines once the Chip event loop is running.
+ ReturnErrorOnFailure(DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL));
+ ReturnErrorOnFailure(DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL));
+
+#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
+
+ return CHIP_NO_ERROR;
+}
+
+void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
+{
+ // Forward the event to the generic base classes as needed.
+#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
+ GenericConnectivityManagerImpl_Thread<ConnectivityManagerImpl>::_OnPlatformEvent(event);
+#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+ if (event->Type == DeviceEventType::kRtkWiFiStationConnectedEvent)
+ {
+ ChipLogProgress(DeviceLayer, "_OnPlatformEvent WIFI_EVENT_STA_CONNECTED");
+ if (mWiFiStationState == kWiFiStationState_Connecting)
+ {
+ NetworkCommissioning::BekenWiFiDriver::GetInstance().OnConnectWiFiNetwork();
+ ChangeWiFiStationState(kWiFiStationState_Connecting_Succeeded);
+ }
+ DriveStationState();
+ }
+#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
+}
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+ConnectivityManager::WiFiStationMode ConnectivityManagerImpl::_GetWiFiStationMode(void)
+{
+ // Enabled when platform instance initilazed
+ return kWiFiStationMode_Enabled;
+}
+
+bool ConnectivityManagerImpl::_IsWiFiStationEnabled(void)
+{
+ return GetWiFiStationMode() == kWiFiStationMode_Enabled;
+}
+
+CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationMode(WiFiStationMode val)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ VerifyOrExit(val != kWiFiStationMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT);
+
+ if (mWiFiStationMode == kWiFiStationMode_Disabled && val == kWiFiStationMode_Enabled)
+ {
+ BK_LOG_ON_ERR(bk_event_register_cb(EVENT_MOD_WIFI, EVENT_ID_ALL, ConnectivityManagerImpl().wlan_event_cb, NULL));
+ BK_LOG_ON_ERR(bk_event_register_cb(EVENT_MOD_NETIF, EVENT_ID_ALL, ConnectivityManagerImpl().netif_event_cb, NULL));
+ ChangeWiFiStationState(kWiFiStationState_Connecting);
+ }
+
+ if (val != kWiFiStationMode_ApplicationControlled)
+ {
+ DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL);
+ }
+
+ if (mWiFiStationMode != val)
+ {
+ ChipLogProgress(DeviceLayer, "WiFi station mode change: %s -> %s", WiFiStationModeToStr(mWiFiStationMode),
+ WiFiStationModeToStr(val));
+ }
+
+ mWiFiStationMode = val;
+
+exit:
+ return err;
+}
+
+bool ConnectivityManagerImpl::_IsWiFiStationProvisioned(void)
+{
+ if (mWifiNetconf.ssidLen == 0)
+ NetworkCommissioning::BekenWiFiDriver::GetInstance().GetSavedNetWorkConfig(&mWifiNetconf);
+ ChipLogError(DeviceLayer, "wifi ssid:%s\r\n", mWifiNetconf.ssid);
+ return (mWifiNetconf.ssidLen != 0) ? true : false;
+}
+
+void ConnectivityManagerImpl::_ClearWiFiStationProvision(void)
+{
+ // TBD
+}
+
+CHIP_ERROR ConnectivityManagerImpl::_SetWiFiAPMode(WiFiAPMode val)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ VerifyOrExit(val != kWiFiAPMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT);
+
+ if (mWiFiAPMode != val)
+ {
+ ChipLogProgress(DeviceLayer, "WiFi AP mode change: %s -> %s", WiFiAPModeToStr(mWiFiAPMode), WiFiAPModeToStr(val));
+ }
+
+ mWiFiAPMode = val;
+
+ DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL);
+
+exit:
+ return err;
+}
+
+void ConnectivityManagerImpl::_DemandStartWiFiAP(void)
+{
+ if (mWiFiAPMode == kWiFiAPMode_OnDemand || mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision)
+ {
+ mLastAPDemandTime = System::SystemClock().GetMonotonicTimestamp();
+ DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL);
+ }
+}
+
+void ConnectivityManagerImpl::_StopOnDemandWiFiAP(void)
+{
+ if (mWiFiAPMode == kWiFiAPMode_OnDemand || mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision)
+ {
+ mLastAPDemandTime = System::Clock::kZero;
+ DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL);
+ }
+}
+
+void ConnectivityManagerImpl::_MaintainOnDemandWiFiAP(void)
+{
+ if (mWiFiAPMode == kWiFiAPMode_OnDemand || mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision)
+ {
+ if (mWiFiAPState == kWiFiAPState_Activating || mWiFiAPState == kWiFiAPState_Active)
+ {
+ mLastAPDemandTime = System::SystemClock().GetMonotonicTimestamp();
+ }
+ }
+}
+
+void ConnectivityManagerImpl::_SetWiFiAPIdleTimeout(System::Clock::Timeout val)
+{
+ mWiFiAPIdleTimeout = val;
+ DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL);
+}
+
+CHIP_ERROR ConnectivityManagerImpl::_GetAndLogWifiStatsCounters(void)
+{
+ return CHIP_NO_ERROR;
+}
+
+void ConnectivityManagerImpl::_OnWiFiScanDone()
+{
+ // Schedule a call to DriveStationState method in case a station connect attempt was
+ // deferred because the scan was in progress.
+ DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL);
+}
+
+void ConnectivityManagerImpl::_OnWiFiStationProvisionChange()
+{
+ // Schedule a call to the DriveStationState method to adjust the station state as needed.
+ DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL);
+}
+
+// ==================== ConnectivityManager Private Methods ====================
+void ConnectivityManagerImpl::WiFiStationConnectedHandler()
+{
+ ChipDeviceEvent event;
+ memset(&event, 0, sizeof(event));
+ event.Type = DeviceEventType::kRtkWiFiStationConnectedEvent;
+ PlatformMgr().PostEventOrDie(&event);
+}
+
+static bool stationConnected = false;
+
+int ConnectivityManagerImpl::netif_event_cb(void * arg, event_module_t event_module, int event_id, void * event_data)
+{
+ ssid_key_save_t wpa_save = { { 0 } };
+ switch (event_id)
+ {
+ case EVENT_NETIF_GOT_IP4:
+ stationConnected = true;
+ WiFiStationConnectedHandler();
+ ChipLogProgress(DeviceLayer, "netif_event_cb EVENT_NETIF_GOT_IP4");
+ break;
+ default:
+ ChipLogProgress(DeviceLayer, "unSupported netif status:%d", event_id);
+ break;
+ }
+
+ return BK_OK;
+}
+
+int ConnectivityManagerImpl::wlan_event_cb(void * arg, event_module_t event_module, int event_id, void * event_data)
+{
+ switch (event_id)
+ {
+ case EVENT_WIFI_STA_CONNECTED:
+ ChipLogProgress(DeviceLayer, "wlan_event_cb EVENT_WIFI_STA_CONNECTED");
+ break;
+ case EVENT_WIFI_STA_DISCONNECTED:
+ stationConnected = false;
+ ChipLogProgress(DeviceLayer, "wlan_event_cb EVENT_WIFI_STA_DISCONNECTED");
+ wifi_event_sta_disconnected_t * sta_disconnected;
+ sta_disconnected = (wifi_event_sta_disconnected_t *) event_data;
+ ChipDeviceEvent myevent;
+ myevent.Platform.BKSystemEvent.Data.WiFiStaDisconnected = sta_disconnected->disconnect_reason;
+ NetworkCommissioning::BekenWiFiDriver::GetInstance().SetLastDisconnectReason(&myevent);
+ break;
+ default:
+ ChipLogProgress(DeviceLayer, "unSupported wifi status:%d", event_id);
+ break;
+ }
+ return BK_OK;
+}
+
+void ConnectivityManagerImpl::DriveStationState()
+{
+ mWiFiStationMode = GetWiFiStationMode();
+ ChipLogProgress(DeviceLayer, "wifi station state:%d, mWiFiStationState:%d", stationConnected, mWiFiStationState);
+ // If the station interface is currently connected ...
+ if (stationConnected)
+ {
+ // Advance the station state to Connected if it was previously NotConnected or
+ // a previously initiated connect attempt succeeded.
+ if (mWiFiStationState == kWiFiStationState_NotConnected || mWiFiStationState == kWiFiStationState_Connecting_Succeeded)
+ {
+ ChangeWiFiStationState(kWiFiStationState_Connected);
+ ChipLogProgress(DeviceLayer, "WiFi station interface connected");
+ mLastStationConnectFailTime = System::Clock::kZero;
+ OnStationConnected();
+ IpConnectedEventNotify();
+ }
+ }
+
+ // Otherwise the station interface is NOT connected to an AP, so...
+ else
+ {
+ System::Clock::Timestamp now = System::SystemClock().GetMonotonicTimestamp();
+
+ // Advance the station state to NotConnected if it was previously Connected or Disconnecting,
+ // or if a previous initiated connect attempt failed.
+ if (mWiFiStationState == kWiFiStationState_Connected || mWiFiStationState == kWiFiStationState_Disconnecting ||
+ mWiFiStationState == kWiFiStationState_Connecting_Failed)
+ {
+ WiFiStationState prevState = mWiFiStationState;
+ ChangeWiFiStationState(kWiFiStationState_NotConnected);
+ if (prevState != kWiFiStationState_Connecting_Failed)
+ {
+ ChipLogProgress(DeviceLayer, "WiFi station interface disconnected");
+ mLastStationConnectFailTime = System::Clock::kZero;
+ OnStationDisconnected();
+ }
+ else
+ {
+ mLastStationConnectFailTime = now;
+ }
+ }
+ // If the WiFi station interface is now enabled and provisioned (and by implication,
+ // not presently under application control), AND the system is not in the process of
+ // scanning, then...
+ ChipLogProgress(DeviceLayer, "mWiFiStationMode:%d, IsWiFiStationProvisioned:%d", mWiFiStationMode,
+ IsWiFiStationProvisioned());
+ if (mWiFiStationMode == kWiFiStationMode_Enabled && IsWiFiStationProvisioned() &&
+ mWiFiStationState != kWiFiStationState_Connecting)
+ {
+ // Initiate a connection to the AP if we haven't done so before, or if enough
+ // time has passed since the last attempt.
+ if (mLastStationConnectFailTime == System::Clock::kZero ||
+ now >= mLastStationConnectFailTime + mWiFiStationReconnectInterval)
+ {
+ ChipLogProgress(DeviceLayer, "try to connect wifi");
+ wifi_sta_config_t sta_config;
+
+ memset(&sta_config, 0x0, sizeof(sta_config));
+ sta_config.security = WIFI_SECURITY_AUTO; // can't use WIFI_DEFAULT_STA_CONFIG because of C99 designator error
+ strncpy(sta_config.ssid, mWifiNetconf.ssid, mWifiNetconf.ssidLen);
+ strncpy(sta_config.password, mWifiNetconf.credentials, mWifiNetconf.credentialsLen);
+ BK_LOG_ON_ERR(bk_wifi_sta_set_config(&sta_config));
+ BK_LOG_ON_ERR(bk_wifi_sta_start());
+ BK_LOG_ON_ERR(bk_event_register_cb(EVENT_MOD_WIFI, EVENT_ID_ALL, ConnectivityManagerImpl().wlan_event_cb, NULL));
+ BK_LOG_ON_ERR(bk_event_register_cb(EVENT_MOD_NETIF, EVENT_ID_ALL, ConnectivityManagerImpl().netif_event_cb, NULL));
+ BK_LOG_ON_ERR(bk_wifi_sta_connect());
+ ChangeWiFiStationState(kWiFiStationState_Connecting);
+ }
+
+ // Otherwise arrange another connection attempt at a suitable point in the future.
+ else
+ {
+ System::Clock::Timeout timeToNextConnect = (mLastStationConnectFailTime + mWiFiStationReconnectInterval) - now;
+
+ ChipLogProgress(DeviceLayer, "Next WiFi station reconnect in %" PRIu32 " ms",
+ System::Clock::Milliseconds32(timeToNextConnect).count());
+
+ ReturnOnFailure(DeviceLayer::SystemLayer().StartTimer(timeToNextConnect, DriveStationState, nullptr));
+ }
+ }
+ }
+ ChipLogProgress(DeviceLayer, "Done driving station state, nothing else to do...");
+ // Kick-off any pending network scan that might have been deferred due to the activity
+ // of the WiFi station.
+}
+
+void ConnectivityManagerImpl::OnStationConnected()
+{
+ // Alert other components of the new state.
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kWiFiConnectivityChange;
+ event.WiFiConnectivityChange.Result = kConnectivity_Established;
+ PlatformMgr().PostEventOrDie(&event);
+
+ UpdateInternetConnectivityState();
+}
+
+void ConnectivityManagerImpl::OnStationDisconnected()
+{
+ // Alert other components of the new state.
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kWiFiConnectivityChange;
+ event.WiFiConnectivityChange.Result = kConnectivity_Lost;
+ PlatformMgr().PostEventOrDie(&event);
+
+ UpdateInternetConnectivityState();
+}
+
+void ConnectivityManagerImpl::ChangeWiFiStationState(WiFiStationState newState)
+{
+ if (mWiFiStationState != newState)
+ {
+ ChipLogProgress(DeviceLayer, "WiFi station state change: %s -> %s", WiFiStationStateToStr(mWiFiStationState),
+ WiFiStationStateToStr(newState));
+ mWiFiStationState = newState;
+ SystemLayer().ScheduleLambda([]() { NetworkCommissioning::BekenWiFiDriver::GetInstance().OnNetworkStatusChange(); });
+ }
+}
+
+void ConnectivityManagerImpl::DriveStationState(::chip::System::Layer * aLayer, void * aAppState)
+{
+ sInstance.DriveStationState();
+}
+
+void ConnectivityManagerImpl::DriveAPState()
+{
+ ChipLogProgress(DeviceLayer, "WiFi ConnectivityManagerImpl::DriveAPState, do nothing!");
+ CHIP_ERROR err = CHIP_NO_ERROR;
+}
+
+CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP()
+{
+ return CHIP_NO_ERROR;
+}
+
+void ConnectivityManagerImpl::ChangeWiFiAPState(WiFiAPState newState)
+{
+ if (mWiFiAPState != newState)
+ {
+ ChipLogProgress(DeviceLayer, "WiFi AP state change: %s -> %s", WiFiAPStateToStr(mWiFiAPState), WiFiAPStateToStr(newState));
+ mWiFiAPState = newState;
+ }
+}
+
+void ConnectivityManagerImpl::DriveAPState(::chip::System::Layer * aLayer, void * aAppState)
+{
+ sInstance.DriveAPState();
+}
+
+void ConnectivityManagerImpl::UpdateInternetConnectivityState(void)
+{
+ bool haveIPv4Conn = false;
+ bool haveIPv6Conn = false;
+ const bool hadIPv4Conn = mFlags.Has(ConnectivityFlags::kHaveIPv4InternetConnectivity);
+ const bool hadIPv6Conn = mFlags.Has(ConnectivityFlags::kHaveIPv6InternetConnectivity);
+ IPAddress addr;
+
+ // If the WiFi station is currently in the connected state...
+ if (mWiFiStationState == kWiFiStationState_Connected)
+ {
+ // Get the LwIP netif for the WiFi station interface.
+ struct netif * netif = netif_list;
+
+ // If the WiFi station interface is up...
+ if (netif != NULL && netif_is_up(netif) && netif_is_link_up(netif))
+ {
+ // Check if a DNS server is currently configured. If so...
+ ip_addr_t dnsServerAddr = *dns_getserver(0);
+ if (!ip_addr_isany_val(dnsServerAddr))
+ {
+ // If the station interface has been assigned an IPv4 address, and has
+ // an IPv4 gateway, then presume that the device has IPv4 Internet
+ // connectivity.
+ if (!ip4_addr_isany_val(*netif_ip4_addr(netif)) && !ip4_addr_isany_val(*netif_ip4_gw(netif)))
+ {
+ haveIPv4Conn = true;
+ // char addrStr[INET_ADDRSTRLEN];
+ // ip4addr_ntoa_r((const ip4_addr_t *) LwIP_GetIP(&xnetif[0]), addrStr, sizeof(addrStr));
+ // IPAddress::FromString(addrStr, addr);
+ }
+
+ // Search among the IPv6 addresses assigned to the interface for a Global Unicast
+ // address (2000::/3) that is in the valid state. If such an address is found...
+ for (uint8_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++)
+ {
+ if (ip6_addr_isglobal(netif_ip6_addr(netif, i)) && ip6_addr_isvalid(netif_ip6_addr_state(netif, i)))
+ {
+ // Determine if there is a default IPv6 router that is currently reachable
+ // via the station interface. If so, presume for now that the device has
+ // IPv6 connectivity.
+ struct netif * found_if = nd6_find_route(IP6_ADDR_ANY6);
+ if (found_if && netif->num == found_if->num)
+ {
+ haveIPv6Conn = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // If the internet connectivity state has changed...
+ if (haveIPv4Conn != hadIPv4Conn || haveIPv6Conn != hadIPv6Conn)
+ {
+ // Update the current state.
+ mFlags.Set(ConnectivityFlags::kHaveIPv4InternetConnectivity, haveIPv4Conn)
+ .Set(ConnectivityFlags::kHaveIPv6InternetConnectivity, haveIPv6Conn);
+
+ // Alert other components of the state change.
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kInternetConnectivityChange;
+ event.InternetConnectivityChange.IPv4 = GetConnectivityChange(hadIPv4Conn, haveIPv4Conn);
+ event.InternetConnectivityChange.IPv6 = GetConnectivityChange(hadIPv6Conn, haveIPv6Conn);
+ // addr.ToString(event.InternetConnectivityChange.address);
+ PlatformMgr().PostEventOrDie(&event);
+
+ if (haveIPv4Conn != hadIPv4Conn)
+ {
+ ChipLogProgress(DeviceLayer, "%s Internet connectivity %s", "IPv4", (haveIPv4Conn) ? "ESTABLISHED" : "LOST");
+ }
+
+ if (haveIPv6Conn != hadIPv6Conn)
+ {
+ ChipLogProgress(DeviceLayer, "%s Internet connectivity %s", "IPv6", (haveIPv6Conn) ? "ESTABLISHED" : "LOST");
+ }
+ }
+}
+
+void ConnectivityManagerImpl::OnStationIPv4AddressAvailable(void)
+{
+#if 0
+ uint8_t * ip = LwIP_GetIP(&xnetif[0]);
+ uint8_t * gw = LwIP_GetGW(&xnetif[0]);
+ uint8_t * msk = LwIP_GetMASK(&xnetif[0]);
+#if CHIP_PROGRESS_LOGGING
+ {
+ ChipLogProgress(DeviceLayer, "\n\r\tIP => %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+ ChipLogProgress(DeviceLayer, "\n\r\tGW => %d.%d.%d.%d\n\r", gw[0], gw[1], gw[2], gw[3]);
+ ChipLogProgress(DeviceLayer, "\n\r\tmsk => %d.%d.%d.%d\n\r", msk[0], msk[1], msk[2], msk[3]);
+ }
+#endif // CHIP_PROGRESS_LOGGING
+#endif
+
+ UpdateInternetConnectivityState();
+ ChipLogProgress(DeviceLayer, "IPv4 address available on WiFi station interface");
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kInterfaceIpAddressChanged;
+ event.InterfaceIpAddressChanged.Type = InterfaceIpChangeType::kIpV4_Assigned;
+ PlatformMgr().PostEventOrDie(&event);
+}
+
+void ConnectivityManagerImpl::OnStationIPv4AddressLost(void)
+{
+ ChipLogProgress(DeviceLayer, "IPv4 address lost on WiFi station interface");
+
+ UpdateInternetConnectivityState();
+
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kInterfaceIpAddressChanged;
+ event.InterfaceIpAddressChanged.Type = InterfaceIpChangeType::kIpV4_Lost;
+ PlatformMgr().PostEventOrDie(&event);
+}
+
+void ConnectivityManagerImpl::OnIPv6AddressAvailable(void)
+{
+#if 0
+#if LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 1
+#if LWIP_IPV6
+ uint8_t * ipv6_0 = LwIP_GetIPv6_linklocal(&xnetif[0]);
+ uint8_t * ipv6_1 = LwIP_GetIPv6_global(&xnetif[0]);
+#endif
+#endif
+#if CHIP_PROGRESS_LOGGING
+ {
+#if LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 1
+#if LWIP_IPV6
+ ChipLogProgress(DeviceLayer,
+ "\n\r\tLink-local IPV6 => %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+ ipv6_0[0], ipv6_0[1], ipv6_0[2], ipv6_0[3], ipv6_0[4], ipv6_0[5], ipv6_0[6], ipv6_0[7], ipv6_0[8],
+ ipv6_0[9], ipv6_0[10], ipv6_0[11], ipv6_0[12], ipv6_0[13], ipv6_0[14], ipv6_0[15]);
+ ChipLogProgress(DeviceLayer,
+ "\n\r\tIPV6 => %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+ ipv6_1[0], ipv6_1[1], ipv6_1[2], ipv6_1[3], ipv6_1[4], ipv6_1[5], ipv6_1[6], ipv6_1[7], ipv6_1[8],
+ ipv6_1[9], ipv6_1[10], ipv6_1[11], ipv6_1[12], ipv6_1[13], ipv6_1[14], ipv6_1[15]);
+#endif
+#endif
+ }
+#endif // CHIP_PROGRESS_LOGGING
+#endif
+
+ UpdateInternetConnectivityState();
+ ChipLogProgress(DeviceLayer, "IPv6 address available on WiFi station interface");
+ ChipDeviceEvent event;
+ event.Type = DeviceEventType::kInterfaceIpAddressChanged;
+ event.InterfaceIpAddressChanged.Type = InterfaceIpChangeType::kIpV6_Assigned;
+ PlatformMgr().PostEventOrDie(&event);
+}
+
+void ConnectivityManagerImpl::IpConnectedEventNotify()
+{
+ const bool hadIPv4Conn = mFlags.Has(ConnectivityFlags::kHaveIPv4InternetConnectivity);
+ const bool hadIPv6Conn = mFlags.Has(ConnectivityFlags::kHaveIPv6InternetConnectivity);
+
+ if (hadIPv4Conn)
+ {
+ sInstance.OnStationIPv4AddressAvailable();
+ }
+ if (hadIPv6Conn)
+ {
+ sInstance.OnIPv6AddressAvailable();
+ }
+}
+
+#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
+
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/ConnectivityManagerImpl.h b/src/platform/Beken/ConnectivityManagerImpl.h
new file mode 100644
index 0000000..e4d200c
--- /dev/null
+++ b/src/platform/Beken/ConnectivityManagerImpl.h
@@ -0,0 +1,224 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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 <platform/ConnectivityManager.h>
+#include <platform/internal/GenericConnectivityManagerImpl.h>
+#include <platform/internal/GenericConnectivityManagerImpl_UDP.h>
+
+#if INET_CONFIG_ENABLE_TCP_ENDPOINT
+#include <platform/internal/GenericConnectivityManagerImpl_TCP.h>
+#endif
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+#include <platform/internal/GenericConnectivityManagerImpl_WiFi.h>
+#else
+#include <platform/internal/GenericConnectivityManagerImpl_NoWiFi.h>
+#endif
+
+#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
+#include <platform/internal/GenericConnectivityManagerImpl_Thread.h>
+#else
+#include <platform/internal/GenericConnectivityManagerImpl_NoThread.h>
+#endif
+
+#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
+#include <platform/internal/GenericConnectivityManagerImpl_BLE.h>
+#else
+#include <platform/internal/GenericConnectivityManagerImpl_NoBLE.h>
+#endif
+
+#include <lib/support/BitFlags.h>
+
+#include <components/event.h>
+
+namespace chip {
+
+namespace Inet {
+class IPAddress;
+} // namespace Inet
+
+namespace DeviceLayer {
+
+class PlatformManagerImpl;
+
+class ConnectivityManagerImpl final : public ConnectivityManager,
+ public Internal::GenericConnectivityManagerImpl<ConnectivityManagerImpl>,
+ public Internal::GenericConnectivityManagerImpl_UDP<ConnectivityManagerImpl>,
+#if INET_CONFIG_ENABLE_TCP_ENDPOINT
+ public Internal::GenericConnectivityManagerImpl_TCP<ConnectivityManagerImpl>,
+#endif
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+ public Internal::GenericConnectivityManagerImpl_WiFi<ConnectivityManagerImpl>,
+#else
+ public Internal::GenericConnectivityManagerImpl_NoWiFi<ConnectivityManagerImpl>,
+#endif
+#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
+ public Internal::GenericConnectivityManagerImpl_BLE<ConnectivityManagerImpl>,
+#else
+ public Internal::GenericConnectivityManagerImpl_NoBLE<ConnectivityManagerImpl>,
+#endif
+#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
+ public Internal::GenericConnectivityManagerImpl_Thread<ConnectivityManagerImpl>
+#else
+ public Internal::GenericConnectivityManagerImpl_NoThread<ConnectivityManagerImpl>
+#endif
+{
+ // Allow the ConnectivityManager interface class to delegate method calls to
+ // the implementation methods provided by this class.
+ friend class ConnectivityManager;
+
+private:
+ CHIP_ERROR _Init(void);
+ void _OnPlatformEvent(const ChipDeviceEvent * event);
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+ using Flags = GenericConnectivityManagerImpl_WiFi::ConnectivityFlags;
+ // ===== Members that implement the ConnectivityManager abstract interface.
+
+ WiFiStationMode _GetWiFiStationMode(void);
+ CHIP_ERROR _SetWiFiStationMode(WiFiStationMode val);
+ bool _IsWiFiStationEnabled(void);
+ bool _IsWiFiStationApplicationControlled(void);
+ bool _IsWiFiStationConnected(void);
+ System::Clock::Timeout _GetWiFiStationReconnectInterval(void);
+ CHIP_ERROR _SetWiFiStationReconnectInterval(System::Clock::Timeout val);
+ bool _IsWiFiStationProvisioned(void);
+ void _ClearWiFiStationProvision(void);
+ WiFiAPMode _GetWiFiAPMode(void);
+ CHIP_ERROR _SetWiFiAPMode(WiFiAPMode val);
+ bool _IsWiFiAPActive(void);
+ bool _IsWiFiAPApplicationControlled(void);
+ void _DemandStartWiFiAP(void);
+ void _StopOnDemandWiFiAP(void);
+ void _MaintainOnDemandWiFiAP(void);
+ System::Clock::Timeout _GetWiFiAPIdleTimeout(void);
+ void _SetWiFiAPIdleTimeout(System::Clock::Timeout val);
+ CHIP_ERROR _GetAndLogWifiStatsCounters(void);
+ bool _CanStartWiFiScan();
+ void _OnWiFiScanDone();
+ void _OnWiFiStationProvisionChange();
+
+ // ===== Private members reserved for use by this class only.
+
+ System::Clock::Timestamp mLastStationConnectFailTime;
+ System::Clock::Timestamp mLastAPDemandTime;
+ WiFiStationMode mWiFiStationMode;
+ WiFiStationState mWiFiStationState;
+ WiFiAPMode mWiFiAPMode;
+ WiFiAPState mWiFiAPState;
+ System::Clock::Timeout mWiFiStationReconnectInterval;
+ System::Clock::Timeout mWiFiAPIdleTimeout;
+ BitFlags<Flags> mFlags;
+
+ void DriveStationState(void);
+ void OnStationConnected(void);
+ void OnStationDisconnected(void);
+ void ChangeWiFiStationState(WiFiStationState newState);
+ static void DriveStationState(::chip::System::Layer * aLayer, void * aAppState);
+
+ void DriveAPState(void);
+ CHIP_ERROR ConfigureWiFiAP(void);
+ void ChangeWiFiAPState(WiFiAPState newState);
+ static void DriveAPState(::chip::System::Layer * aLayer, void * aAppState);
+
+ void UpdateInternetConnectivityState(void);
+ void OnStationIPv4AddressAvailable(void);
+ void OnStationIPv4AddressLost(void);
+ void OnIPv6AddressAvailable(void);
+
+#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
+
+ // ===== Members for internal use by the following friends.
+
+ friend ConnectivityManager & ConnectivityMgr(void);
+ friend ConnectivityManagerImpl & ConnectivityMgrImpl(void);
+
+ static ConnectivityManagerImpl sInstance;
+ static void WiFiStationConnectedHandler();
+ static int wlan_event_cb(void * arg, event_module_t event_module, int event_id, void * event_data);
+ static int netif_event_cb(void * arg, event_module_t event_module, int event_id, void * event_data);
+ void IpConnectedEventNotify(void);
+};
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+inline bool ConnectivityManagerImpl::_IsWiFiStationApplicationControlled(void)
+{
+ return mWiFiStationMode == kWiFiStationMode_ApplicationControlled;
+}
+
+inline bool ConnectivityManagerImpl::_IsWiFiStationConnected(void)
+{
+ return mWiFiStationState == kWiFiStationState_Connected;
+}
+
+inline bool ConnectivityManagerImpl::_IsWiFiAPApplicationControlled(void)
+{
+ return mWiFiAPMode == kWiFiAPMode_ApplicationControlled;
+}
+
+inline System::Clock::Timeout ConnectivityManagerImpl::_GetWiFiStationReconnectInterval(void)
+{
+ return mWiFiStationReconnectInterval;
+}
+
+inline ConnectivityManager::WiFiAPMode ConnectivityManagerImpl::_GetWiFiAPMode(void)
+{
+ return mWiFiAPMode;
+}
+
+inline bool ConnectivityManagerImpl::_IsWiFiAPActive(void)
+{
+ return mWiFiAPState == kWiFiAPState_Active;
+}
+
+inline System::Clock::Timeout ConnectivityManagerImpl::_GetWiFiAPIdleTimeout(void)
+{
+ return mWiFiAPIdleTimeout;
+}
+
+inline bool ConnectivityManagerImpl::_CanStartWiFiScan()
+{
+ return mWiFiStationState != kWiFiStationState_Connecting;
+}
+#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
+
+/**
+ * Returns the public interface of the ConnectivityManager singleton object.
+ *
+ * Chip applications should use this to access features of the ConnectivityManager object
+ * that are common to all platforms.
+ */
+inline ConnectivityManager & ConnectivityMgr(void)
+{
+ return ConnectivityManagerImpl::sInstance;
+}
+
+/**
+ * Returns the platform-specific implementation of the ConnectivityManager singleton object.
+ *
+ * Chip applications can use this to gain access to features of the ConnectivityManager
+ * that are specific to the Beken platform.
+ */
+inline ConnectivityManagerImpl & ConnectivityMgrImpl(void)
+{
+ return ConnectivityManagerImpl::sInstance;
+}
+
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/DiagnosticDataProviderImpl.cpp b/src/platform/Beken/DiagnosticDataProviderImpl.cpp
new file mode 100644
index 0000000..b3f7a98
--- /dev/null
+++ b/src/platform/Beken/DiagnosticDataProviderImpl.cpp
@@ -0,0 +1,301 @@
+/*
+ *
+ * Copyright (c) 2022 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.
+ */
+
+/**
+ * @file
+ * Provides an implementation of the DiagnosticDataProvider object
+ * for Beken platform.
+ */
+
+#include <platform/internal/CHIPDeviceLayerInternal.h>
+
+#include <crypto/CHIPCryptoPAL.h>
+#include <platform/Beken/DiagnosticDataProviderImpl.h>
+#include <platform/DiagnosticDataProvider.h>
+
+#include "matter_pal.h"
+
+namespace chip {
+namespace DeviceLayer {
+
+DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance()
+{
+ static DiagnosticDataProviderImpl sInstance;
+ return sInstance;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeapFree)
+{
+ currentHeapFree = xPortGetFreeHeapSize();
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeapUsed)
+{
+ currentHeapUsed = prvHeapGetTotalSize() - xPortGetFreeHeapSize();
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark)
+{
+ currentHeapHighWatermark = prvHeapGetTotalSize() - xPortGetMinimumEverFreeHeapSize();
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetRebootCount(uint16_t & rebootCount)
+{
+ uint32_t count = 0;
+
+ CHIP_ERROR err = ConfigurationMgr().GetRebootCount(count);
+
+ if (err == CHIP_NO_ERROR)
+ {
+ VerifyOrReturnError(count <= UINT16_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+ rebootCount = static_cast<uint16_t>(count);
+ }
+
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetUpTime(uint64_t & upTime)
+{
+ System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp();
+ System::Clock::Timestamp startTime = PlatformMgrImpl().GetStartTime();
+
+ if (currentTime >= startTime)
+ {
+ upTime = std::chrono::duration_cast<System::Clock::Seconds64>(currentTime - startTime).count();
+ return CHIP_NO_ERROR;
+ }
+
+ return CHIP_ERROR_INVALID_TIME;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours)
+{
+ uint64_t upTime = 0;
+
+ if (GetUpTime(upTime) == CHIP_NO_ERROR)
+ {
+ uint32_t totalHours = 0;
+ if (ConfigurationMgr().GetTotalOperationalHours(totalHours) == CHIP_NO_ERROR)
+ {
+ VerifyOrReturnError(upTime / 3600 <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+ totalOperationalHours = totalHours + static_cast<uint32_t>(upTime / 3600);
+ return CHIP_NO_ERROR;
+ }
+ }
+
+ return CHIP_ERROR_INVALID_TIME;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetBootReason(BootReasonType & bootReason)
+{
+ uint32_t reason = 0;
+
+ CHIP_ERROR err = ConfigurationMgr().GetBootReason(reason);
+
+ if (err == CHIP_NO_ERROR)
+ {
+ VerifyOrReturnError(reason <= UINT8_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
+ bootReason = static_cast<BootReasonType>(reason);
+ }
+
+ return err;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetNetworkInterfaces(NetworkInterface ** netifpp)
+{
+ NetworkInterface * ifp = new NetworkInterface();
+ struct netif * netif;
+
+ netif = (struct netif *) net_get_sta_handle(); // assume only on station mode
+ if (netif == NULL || ifp == NULL)
+ {
+ ChipLogError(DeviceLayer, "Can't get the netif instance");
+ *netifpp = NULL;
+ return CHIP_ERROR_INTERNAL;
+ }
+
+ strncpy(ifp->Name, netif->hostname, Inet::InterfaceId::kMaxIfNameLength);
+ ifp->Name[Inet::InterfaceId::kMaxIfNameLength - 1] = '\0';
+ ifp->name = CharSpan::fromCharString(ifp->Name);
+ ifp->type = EMBER_ZCL_INTERFACE_TYPE_WI_FI;
+ ifp->offPremiseServicesReachableIPv4.SetNonNull(false);
+ ifp->offPremiseServicesReachableIPv6.SetNonNull(false);
+ memcpy(ifp->MacAddress, netif->hwaddr, sizeof(netif->hwaddr));
+ *netifpp = ifp;
+ return CHIP_NO_ERROR;
+}
+
+void DiagnosticDataProviderImpl::ReleaseNetworkInterfaces(NetworkInterface * netifp)
+{
+ while (netifp)
+ {
+ NetworkInterface * del = netifp;
+ netifp = netifp->Next;
+ delete del;
+ }
+}
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiBssId(ByteSpan & BssId)
+{
+ LinkStatusTypeDef linkStatus;
+
+ memset(&linkStatus, 0x0, sizeof(LinkStatusTypeDef));
+ if (0 == bk_wlan_get_link_status(&linkStatus))
+ {
+ BssId = ByteSpan(linkStatus.bssid, 6);
+ }
+ else
+ {
+ ChipLogError(DeviceLayer, "GetWiFiBssId Not Supported");
+ return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
+ }
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiVersion(uint8_t & wifiVersion)
+{
+ // Support 802.11a/n Wi-Fi in Beken chipset
+ wifiVersion = EMBER_ZCL_WI_FI_VERSION_TYPE_802__11N;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiSecurityType(uint8_t & securityType)
+{
+ int cipher_type;
+ cipher_type = bk_sta_cipher_type();
+ switch (cipher_type)
+ {
+ case BK_SECURITY_TYPE_NONE:
+ securityType = EMBER_ZCL_SECURITY_TYPE_NONE;
+ break;
+ case BK_SECURITY_TYPE_WEP:
+ securityType = EMBER_ZCL_SECURITY_TYPE_WEP;
+ break;
+ case BK_SECURITY_TYPE_WPA_TKIP:
+ case BK_SECURITY_TYPE_WPA_AES:
+ securityType = EMBER_ZCL_SECURITY_TYPE_WPA;
+ break;
+ case BK_SECURITY_TYPE_WPA2_AES:
+ case BK_SECURITY_TYPE_WPA2_TKIP:
+ case BK_SECURITY_TYPE_WPA2_MIXED:
+ securityType = EMBER_ZCL_SECURITY_TYPE_WPA2;
+ break;
+ case BK_SECURITY_TYPE_WPA3_SAE:
+ case BK_SECURITY_TYPE_WPA3_WPA2_MIXED:
+ securityType = EMBER_ZCL_SECURITY_TYPE_WPA3;
+ break;
+ case BK_SECURITY_TYPE_AUTO:
+ default:
+ securityType = EMBER_ZCL_SECURITY_TYPE_UNSPECIFIED;
+ }
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiChannelNumber(uint16_t & channelNumber)
+{
+ LinkStatusTypeDef linkStatus;
+
+ memset(&linkStatus, 0x0, sizeof(LinkStatusTypeDef));
+ if (0 == bk_wlan_get_link_status(&linkStatus))
+ {
+ channelNumber = linkStatus.channel;
+ }
+ else
+ {
+ ChipLogError(DeviceLayer, "GetWiFiChannelNumber Not Supported");
+ return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
+ }
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiRssi(int8_t & rssi)
+{
+ LinkStatusTypeDef linkStatus;
+
+ memset(&linkStatus, 0x0, sizeof(LinkStatusTypeDef));
+ if (0 == bk_wlan_get_link_status(&linkStatus))
+ {
+ rssi = linkStatus.wifi_strength;
+ }
+ else
+ {
+ ChipLogError(DeviceLayer, "GetWiFiRssi Not Supported");
+ return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
+ }
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiBeaconLostCount(uint32_t & beaconLostCount)
+{
+ beaconLostCount = 0;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiCurrentMaxRate(uint64_t & currentMaxRate)
+{
+ currentMaxRate = 0;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiPacketMulticastRxCount(uint32_t & packetMulticastRxCount)
+{
+ packetMulticastRxCount = 0;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiPacketMulticastTxCount(uint32_t & packetMulticastTxCount)
+{
+ packetMulticastTxCount = 0;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiPacketUnicastRxCount(uint32_t & packetUnicastRxCount)
+{
+ packetUnicastRxCount = 0;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiPacketUnicastTxCount(uint32_t & packetUnicastTxCount)
+{
+ packetUnicastTxCount = 0;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::GetWiFiOverrunCount(uint64_t & overrunCount)
+{
+ overrunCount = 0;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DiagnosticDataProviderImpl::ResetWiFiNetworkDiagnosticsCounts()
+{
+ return CHIP_NO_ERROR;
+}
+
+#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
+
+DiagnosticDataProvider & GetDiagnosticDataProviderImpl()
+{
+ return DiagnosticDataProviderImpl::GetDefaultInstance();
+}
+
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/DiagnosticDataProviderImpl.h b/src/platform/Beken/DiagnosticDataProviderImpl.h
new file mode 100644
index 0000000..a898486
--- /dev/null
+++ b/src/platform/Beken/DiagnosticDataProviderImpl.h
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright (c) 2022 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.
+ */
+
+/**
+ * @file
+ * Provides an implementation of the DiagnosticDataProvider object.
+ */
+
+#pragma once
+
+#include <platform/DiagnosticDataProvider.h>
+
+namespace chip {
+namespace DeviceLayer {
+
+/**
+ * Concrete implementation of the PlatformManager singleton object for Linux platforms.
+ */
+class DiagnosticDataProviderImpl : public DiagnosticDataProvider
+{
+public:
+ static DiagnosticDataProviderImpl & GetDefaultInstance();
+
+ // ===== Methods that implement the PlatformManager abstract interface.
+
+ CHIP_ERROR GetCurrentHeapFree(uint64_t & currentHeapFree) override;
+ CHIP_ERROR GetCurrentHeapUsed(uint64_t & currentHeapUsed) override;
+ CHIP_ERROR GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) override;
+
+ CHIP_ERROR GetRebootCount(uint16_t & rebootCount) override;
+ CHIP_ERROR GetUpTime(uint64_t & upTime) override;
+ CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours) override;
+ CHIP_ERROR GetBootReason(BootReasonType & bootReason) override;
+
+ CHIP_ERROR GetNetworkInterfaces(NetworkInterface ** netifpp) override;
+ void ReleaseNetworkInterfaces(NetworkInterface * netifp) override;
+
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+ CHIP_ERROR GetWiFiBssId(ByteSpan & BssId) override;
+ CHIP_ERROR GetWiFiSecurityType(uint8_t & securityType) override;
+ CHIP_ERROR GetWiFiVersion(uint8_t & wifiVersion) override;
+ CHIP_ERROR GetWiFiChannelNumber(uint16_t & channelNumber) override;
+ CHIP_ERROR GetWiFiRssi(int8_t & rssi) override;
+ CHIP_ERROR GetWiFiBeaconLostCount(uint32_t & beaconLostCount) override;
+ CHIP_ERROR GetWiFiPacketMulticastRxCount(uint32_t & packetMulticastRxCount) override;
+ CHIP_ERROR GetWiFiPacketMulticastTxCount(uint32_t & packetMulticastTxCount) override;
+ CHIP_ERROR GetWiFiPacketUnicastRxCount(uint32_t & packetUnicastRxCount) override;
+ CHIP_ERROR GetWiFiPacketUnicastTxCount(uint32_t & packetUnicastTxCount) override;
+ CHIP_ERROR GetWiFiCurrentMaxRate(uint64_t & currentMaxRate) override;
+ CHIP_ERROR GetWiFiOverrunCount(uint64_t & overrunCount) override;
+ CHIP_ERROR ResetWiFiNetworkDiagnosticsCounts() override;
+#endif
+};
+
+/**
+ * Returns the platform-specific implementation of the DiagnosticDataProvider singleton object.
+ *
+ * Applications can use this to gain access to features of the DiagnosticDataProvider
+ * that are specific to the selected platform.
+ */
+DiagnosticDataProvider & GetDiagnosticDataProviderImpl();
+
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/InetPlatformConfig.h b/src/platform/Beken/InetPlatformConfig.h
new file mode 100755
index 0000000..5f5664a
--- /dev/null
+++ b/src/platform/Beken/InetPlatformConfig.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Platform-specific configuration overrides for the CHIP Inet
+ * Layer on the Beken platform.
+ *
+ */
+
+#pragma once
+
+// ==================== Platform Adaptations ====================
+
+#define INET_CONFIG_ERROR_TYPE int32_t
+#define INET_CONFIG_NO_ERROR 0
+#define INET_CONFIG_ERROR_MIN 1000000
+#define INET_CONFIG_ERROR_MAX 1000999
+
+// ==================== General Configuration Overrides ====================
+
+// NOTE: Values that are mapped to CONFIG_ #defines are settable via the Kconfig mechanism.
+
+#ifndef INET_CONFIG_NUM_TCP_ENDPOINTS
+#define INET_CONFIG_NUM_TCP_ENDPOINTS 10
+#endif // INET_CONFIG_NUM_TCP_ENDPOINTS
+
+#ifndef INET_CONFIG_NUM_UDP_ENDPOINTS
+#define INET_CONFIG_NUM_UDP_ENDPOINTS 10
+#endif // INET_CONFIG_NUM_UDP_ENDPOINTS
+
+#define INET_CONFIG_ENABLE_IPV4 1
diff --git a/src/platform/Beken/KeyValueStoreManagerImpl.cpp b/src/platform/Beken/KeyValueStoreManagerImpl.cpp
new file mode 100644
index 0000000..5cd4b9a
--- /dev/null
+++ b/src/platform/Beken/KeyValueStoreManagerImpl.cpp
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Platform-specific key value storage implementation for Beken
+ */
+/* this file behaves like a config.h, comes first */
+#include "matter_pal.h"
+#include <platform/KeyValueStoreManager.h>
+#include <support/CodeUtils.h>
+
+namespace chip {
+namespace DeviceLayer {
+namespace PersistedStorage {
+
+KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance;
+
+CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size,
+ size_t offset_bytes)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ int32_t ret = -1;
+ uint32_t dwTeReadBytes = 0;
+
+ if ((!value) || offset_bytes > 0)
+ {
+ // Offset and partial reads are not supported in nvs, for now just return NOT_IMPLEMENTED. Support can be added in the
+ // future if this is needed.
+ return (err = CHIP_ERROR_INVALID_ARGUMENT);
+ }
+
+ if (read_bytes_size == NULL)
+ {
+ ret = bk_read_data(GetKVNameSpaceName(key), key, (char *) value, value_size, &dwTeReadBytes);
+ }
+ else
+ {
+ ret = bk_read_data(GetKVNameSpaceName(key), key, (char *) value, value_size, (uint32_t *) read_bytes_size);
+ }
+ if (ret == kNoErr)
+ {
+ err = CHIP_NO_ERROR;
+ }
+ else
+ {
+ err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
+ }
+
+ return err;
+}
+
+CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ uint32_t ret = 0;
+ bk_printf("put key:%s \r\n", key);
+ if (!value)
+ {
+ return (err = CHIP_ERROR_INVALID_ARGUMENT);
+ }
+
+ ret = bk_write_data(GetKVNameSpaceName(key), key, (char *) value, value_size);
+
+ if (ret == kNoErr)
+ {
+ err = CHIP_NO_ERROR;
+ }
+ else
+ {
+ err = CHIP_ERROR_INTERNAL;
+ }
+
+ return err;
+}
+
+CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key)
+{
+ uint32_t ret = 0;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ bk_clean_data(GetKVNameSpaceName(key), key);
+
+ return CHIP_NO_ERROR;
+}
+
+const char * KeyValueStoreManagerImpl::GetKVNameSpaceName(const char * key)
+{
+ int idx = 0;
+ const char * BekenkeyValueNameSpace[] = { "BEKEN0", "BEKEN1", "BEKEN2", "BEKEN3",
+ "BEKEN4" }; // Put all key-value date into this namespace
+ if (key != NULL)
+ {
+ int i, len = strlen(key);
+ int sum = 0;
+ for (i = 0; i < len; i += 2)
+ sum += key[i];
+ idx = sum % (sizeof(BekenkeyValueNameSpace) / sizeof(BekenkeyValueNameSpace[0]));
+ }
+ return BekenkeyValueNameSpace[idx];
+}
+
+} // namespace PersistedStorage
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/KeyValueStoreManagerImpl.h b/src/platform/Beken/KeyValueStoreManagerImpl.h
new file mode 100644
index 0000000..59a873f
--- /dev/null
+++ b/src/platform/Beken/KeyValueStoreManagerImpl.h
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Platform-specific key value storage implementation for Beken
+ */
+/* this file behaves like a config.h, comes first */
+
+#pragma once
+
+#include <cstring>
+
+namespace chip {
+namespace DeviceLayer {
+namespace PersistedStorage {
+
+class KeyValueStoreManagerImpl final : public KeyValueStoreManager
+{
+ // Allow the KeyValueStoreManager interface class to delegate method calls to
+ // the implementation methods provided by this class.
+ friend class KeyValueStoreManager;
+
+public:
+ // NOTE: Currently this platform does not support partial and offset reads
+ // these will return CHIP_ERROR_NOT_IMPLEMENTED.
+ CHIP_ERROR _Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size = nullptr, size_t offset = 0);
+
+ CHIP_ERROR _Delete(const char * key);
+
+ CHIP_ERROR _Put(const char * key, const void * value, size_t value_size);
+
+private:
+ // ===== Members for internal use by the following friends.
+ friend KeyValueStoreManager & KeyValueStoreMgr();
+ friend KeyValueStoreManagerImpl & KeyValueStoreMgrImpl();
+
+ static KeyValueStoreManagerImpl sInstance;
+ const char * GetKVNameSpaceName(const char * key);
+};
+
+/**
+ * Returns the public interface of the KeyValueStoreManager singleton object.
+ *
+ * Chip applications should use this to access features of the KeyValueStoreManager object
+ * that are common to all platforms.
+ */
+inline KeyValueStoreManager & KeyValueStoreMgr(void)
+{
+ return KeyValueStoreManagerImpl::sInstance;
+}
+
+/**
+ * Returns the platform-specific implementation of the KeyValueStoreManager singleton object.
+ *
+ * Chip applications can use this to gain access to features of the KeyValueStoreManager.
+ */
+inline KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(void)
+{
+ return KeyValueStoreManagerImpl::sInstance;
+}
+
+} // namespace PersistedStorage
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/Logging.cpp b/src/platform/Beken/Logging.cpp
new file mode 100644
index 0000000..98e5afe
--- /dev/null
+++ b/src/platform/Beken/Logging.cpp
@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Provides implementations for the CHIP logging functions
+ * on the Beken platform.
+ */
+/* this file behaves like a config.h, comes first */
+#include <platform/logging/LogV.h>
+
+#include <core/CHIPConfig.h>
+#include <support/logging/Constants.h>
+
+#include <stdio.h>
+extern "C" void bk_printf(const char * fmt, ...);
+
+#ifdef LOG_LOCAL_LEVEL
+#undef LOG_LOCAL_LEVEL
+#endif
+
+namespace chip {
+namespace Logging {
+namespace Platform {
+
+void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+{
+ char tag[11];
+
+ snprintf(tag, sizeof(tag), "chip[%s]", module);
+ tag[sizeof(tag) - 1] = 0;
+
+ char formattedMsg[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
+ vsnprintf(formattedMsg, sizeof(formattedMsg), msg, v);
+
+ switch (category)
+ {
+ case kLogCategory_Error:
+ bk_printf("%s %s\r\n", tag, formattedMsg);
+ break;
+ case kLogCategory_Progress:
+ default:
+ bk_printf("%s %s\r\n", tag, formattedMsg);
+ break;
+ case kLogCategory_Detail:
+ case kLogCategory_Automation:
+ bk_printf("%s %s\r\n", tag, formattedMsg);
+ break;
+ }
+}
+
+} // namespace Platform
+} // namespace Logging
+} // namespace chip
diff --git a/src/platform/Beken/LwIPCoreLock.cpp b/src/platform/Beken/LwIPCoreLock.cpp
new file mode 100644
index 0000000..da259c6
--- /dev/null
+++ b/src/platform/Beken/LwIPCoreLock.cpp
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+/* this file behaves like a config.h, comes first */
+#include <platform/internal/CHIPDeviceLayerInternal.h>
+
+#include <support/logging/CHIPLogging.h>
+
+namespace {
+
+SemaphoreHandle_t LwIPCoreLock;
+
+}
+
+namespace chip {
+namespace DeviceLayer {
+namespace Internal {
+
+CHIP_ERROR InitLwIPCoreLock(void)
+{
+ if (LwIPCoreLock == NULL)
+ {
+ LwIPCoreLock = xSemaphoreCreateMutex();
+ if (LwIPCoreLock == NULL)
+ {
+ ChipLogError(DeviceLayer, "Failed to create LwIP core lock");
+ return CHIP_ERROR_NO_MEMORY;
+ }
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+} // namespace Internal
+} // namespace DeviceLayer
+} // namespace chip
+
+extern "C" void lock_lwip_core()
+{
+ xSemaphoreTake(LwIPCoreLock, portMAX_DELAY);
+}
+
+extern "C" void unlock_lwip_core()
+{
+ xSemaphoreGive(LwIPCoreLock);
+}
diff --git a/src/platform/Beken/NetworkCommissioningDriver.h b/src/platform/Beken/NetworkCommissioningDriver.h
new file mode 100644
index 0000000..5f83d0d
--- /dev/null
+++ b/src/platform/Beken/NetworkCommissioningDriver.h
@@ -0,0 +1,142 @@
+/*
+ *
+ * Copyright (c) 2022 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.
+ */
+
+#pragma once
+#include "matter_pal.h"
+#include <platform/NetworkCommissioning.h>
+
+#define NC_SECURITYCONVERT(security) ((security < 3) ? security : (security == 3) ? 2 : (security < 7) ? 3 : 4)
+
+namespace chip {
+namespace DeviceLayer {
+namespace NetworkCommissioning {
+
+namespace {
+constexpr uint8_t kMaxWiFiNetworks = 1;
+constexpr uint8_t kWiFiScanNetworksTimeOutSeconds = 10;
+constexpr uint8_t kWiFiConnectNetworkTimeoutSeconds = 20;
+} // namespace
+
+class BKScanResponseIterator : public Iterator<WiFiScanResponse>
+{
+public:
+ BKScanResponseIterator(const size_t size, const wifi_scan_result_t * scanResults) : mSize(size), mpScanResults(scanResults) {}
+ size_t Count() override { return mSize; }
+ bool Next(WiFiScanResponse & item) override
+ {
+ if (mIternum >= mSize)
+ {
+ return false;
+ }
+ uint8_t ssidlenth = strlen(mpScanResults->aps[mIternum].ssid);
+ item.security.SetRaw(NC_SECURITYCONVERT(mpScanResults->aps[mIternum].security));
+ item.ssidLen = ssidlenth;
+ item.channel = mpScanResults->aps[mIternum].channel;
+ item.wiFiBand = chip::DeviceLayer::NetworkCommissioning::WiFiBand::k2g4;
+ item.rssi = mpScanResults->aps[mIternum].rssi;
+ memcpy(item.ssid, mpScanResults->aps[mIternum].ssid, ssidlenth);
+ memcpy(item.bssid, mpScanResults->aps[mIternum].bssid, 6);
+
+ mIternum++;
+ return true;
+ }
+ void Release() override {}
+
+private:
+ const size_t mSize;
+ const wifi_scan_result_t * mpScanResults;
+ size_t mIternum = 1;
+};
+
+class BekenWiFiDriver final : public WiFiDriver
+{
+public:
+ class WiFiNetworkIterator final : public NetworkIterator
+ {
+ public:
+ WiFiNetworkIterator(BekenWiFiDriver * aDriver) : mDriver(aDriver) {}
+ size_t Count() override;
+ bool Next(Network & item) override;
+ void Release() override { delete this; }
+ ~WiFiNetworkIterator() = default;
+
+ private:
+ BekenWiFiDriver * mDriver;
+ bool mExhausted = false;
+ };
+
+ struct WiFiNetwork
+ {
+ char ssid[DeviceLayer::Internal::kMaxWiFiSSIDLength];
+ uint8_t ssidLen = 0;
+ char credentials[DeviceLayer::Internal::kMaxWiFiKeyLength];
+ uint8_t credentialsLen = 0;
+ };
+
+ // BaseDriver
+ NetworkIterator * GetNetworks() override { return new WiFiNetworkIterator(this); }
+ CHIP_ERROR Init(NetworkStatusChangeCallback * networkStatusChangeCallback) override;
+ void Shutdown() override;
+
+ // WirelessDriver
+ uint8_t GetMaxNetworks() override { return kMaxWiFiNetworks; }
+ uint8_t GetScanNetworkTimeoutSeconds() override { return kWiFiScanNetworksTimeOutSeconds; }
+ uint8_t GetConnectNetworkTimeoutSeconds() override { return kWiFiConnectNetworkTimeoutSeconds; }
+
+ CHIP_ERROR CommitConfiguration() override;
+ CHIP_ERROR RevertConfiguration() override;
+
+ Status RemoveNetwork(ByteSpan networkId, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) override;
+ Status ReorderNetwork(ByteSpan networkId, uint8_t index, MutableCharSpan & outDebugText) override;
+ void ConnectNetwork(ByteSpan networkId, ConnectCallback * callback) override;
+
+ // WiFiDriver
+ Status AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText,
+ uint8_t & outNetworkIndex) override;
+ void ScanNetworks(ByteSpan ssid, ScanCallback * callback) override;
+
+ CHIP_ERROR ConnectWiFiNetwork(const char * ssid, uint8_t ssidLen, const char * key, uint8_t keyLen);
+ void OnConnectWiFiNetwork();
+ void OnScanWiFiNetworkDone();
+ void OnNetworkStatusChange();
+
+ CHIP_ERROR SetLastDisconnectReason(const ChipDeviceEvent * event);
+ int32_t GetLastDisconnectReason();
+
+ static BekenWiFiDriver & GetInstance()
+ {
+ static BekenWiFiDriver instance;
+ return instance;
+ }
+ CHIP_ERROR GetSavedNetWorkConfig(WiFiNetwork * WifiNetconf);
+
+private:
+ bool NetworkMatch(const WiFiNetwork & network, ByteSpan networkId);
+ CHIP_ERROR StartScanWiFiNetworks(ByteSpan ssid);
+
+ WiFiNetworkIterator mWiFiIterator = WiFiNetworkIterator(this);
+ WiFiNetwork mSavedNetwork;
+ WiFiNetwork mStagingNetwork;
+ ScanCallback * mpScanCallback;
+ ConnectCallback * mpConnectCallback;
+ NetworkStatusChangeCallback * mpStatusChangeCallback = nullptr;
+ int32_t mLastDisconnectedReason;
+};
+
+} // namespace NetworkCommissioning
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/NetworkCommissioningWiFiDriver.cpp b/src/platform/Beken/NetworkCommissioningWiFiDriver.cpp
new file mode 100644
index 0000000..d556fae
--- /dev/null
+++ b/src/platform/Beken/NetworkCommissioningWiFiDriver.cpp
@@ -0,0 +1,366 @@
+/*
+ *
+ * Copyright (c) 2022 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 <lib/support/CodeUtils.h>
+#include <lib/support/SafeInt.h>
+#include <platform/Beken/NetworkCommissioningDriver.h>
+#include <platform/CHIPDeviceLayer.h>
+
+#include <limits>
+#include <string>
+
+#include "wlan_ui_pub.h"
+
+using namespace ::chip;
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+namespace chip {
+namespace DeviceLayer {
+namespace NetworkCommissioning {
+
+namespace {
+constexpr char kWiFiSSIDKeyName[] = "wifi-ssid";
+constexpr char kWiFiCredentialsKeyName[] = "wifi-pass";
+} // namespace
+
+CHIP_ERROR BekenWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChangeCallback)
+{
+ CHIP_ERROR err;
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::Init\r\n");
+
+ err = GetSavedNetWorkConfig(&mSavedNetwork);
+
+ mStagingNetwork = mSavedNetwork;
+ mpScanCallback = nullptr;
+ mpConnectCallback = nullptr;
+ mpStatusChangeCallback = networkStatusChangeCallback;
+ return err;
+}
+
+CHIP_ERROR BekenWiFiDriver::GetSavedNetWorkConfig(WiFiNetwork * WifiNetconf)
+{
+ CHIP_ERROR err;
+ size_t ssidLen = 0;
+ size_t credentialsLen = 0;
+
+ memset(WifiNetconf, 0x0, sizeof(WiFiNetwork));
+ err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiCredentialsKeyName, WifiNetconf->credentials,
+ sizeof(WifiNetconf->credentials), &credentialsLen);
+ if (err == CHIP_ERROR_NOT_FOUND)
+ {
+ return CHIP_NO_ERROR;
+ }
+
+ err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, WifiNetconf->ssid, sizeof(WifiNetconf->ssid), &ssidLen);
+ if (err == CHIP_ERROR_NOT_FOUND)
+ {
+ return CHIP_NO_ERROR;
+ }
+ WifiNetconf->credentialsLen = credentialsLen;
+ WifiNetconf->ssidLen = ssidLen;
+ return err;
+}
+
+void BekenWiFiDriver::Shutdown()
+{
+ mpStatusChangeCallback = nullptr;
+}
+
+CHIP_ERROR BekenWiFiDriver::CommitConfiguration()
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::CommitConfiguration\r\n");
+ ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiSSIDKeyName, mStagingNetwork.ssid, mStagingNetwork.ssidLen));
+ ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiCredentialsKeyName, mStagingNetwork.credentials,
+ mStagingNetwork.credentialsLen));
+ mSavedNetwork = mStagingNetwork;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BekenWiFiDriver::RevertConfiguration()
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::RevertConfiguration\r\n");
+ mStagingNetwork = mSavedNetwork;
+ return CHIP_NO_ERROR;
+}
+
+bool BekenWiFiDriver::NetworkMatch(const WiFiNetwork & network, ByteSpan networkId)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::NetworkMatch\r\n");
+ return networkId.size() == network.ssidLen && memcmp(networkId.data(), network.ssid, network.ssidLen) == 0;
+}
+
+Status BekenWiFiDriver::AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText,
+ uint8_t & outNetworkIndex)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::AddOrUpdateNetwork\r\n");
+
+ outDebugText.reduce_size(0);
+ outNetworkIndex = 0;
+ VerifyOrReturnError(mStagingNetwork.ssidLen == 0 || NetworkMatch(mStagingNetwork, ssid), Status::kBoundsExceeded);
+ VerifyOrReturnError(credentials.size() <= sizeof(mStagingNetwork.credentials), Status::kOutOfRange);
+ VerifyOrReturnError(ssid.size() <= sizeof(mStagingNetwork.ssid), Status::kOutOfRange);
+
+ memcpy(mStagingNetwork.credentials, credentials.data(), credentials.size());
+ mStagingNetwork.credentialsLen = static_cast<decltype(mStagingNetwork.credentialsLen)>(credentials.size());
+
+ memcpy(mStagingNetwork.ssid, ssid.data(), ssid.size());
+ mStagingNetwork.ssidLen = static_cast<decltype(mStagingNetwork.ssidLen)>(ssid.size());
+
+ return Status::kSuccess;
+}
+
+Status BekenWiFiDriver::RemoveNetwork(ByteSpan networkId, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::RemoveNetwork\r\n");
+
+ outDebugText.reduce_size(0);
+ outNetworkIndex = 0;
+ VerifyOrReturnError(NetworkMatch(mStagingNetwork, networkId), Status::kNetworkIDNotFound);
+
+ // Use empty ssid for representing invalid network
+ mStagingNetwork.ssidLen = 0;
+ return Status::kSuccess;
+}
+
+Status BekenWiFiDriver::ReorderNetwork(ByteSpan networkId, uint8_t index, MutableCharSpan & outDebugText)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::ReorderNetwork\r\n");
+ // Only one network is supported now
+ outDebugText.reduce_size(0);
+ VerifyOrReturnError(index == 0, Status::kOutOfRange);
+ VerifyOrReturnError(NetworkMatch(mStagingNetwork, networkId), Status::kNetworkIDNotFound);
+ return Status::kSuccess;
+}
+
+CHIP_ERROR BekenWiFiDriver::ConnectWiFiNetwork(const char * ssid, uint8_t ssidLen, const char * key, uint8_t keyLen)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::ConnectWiFiNetwork....ssid:%s", ssid);
+ ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled));
+
+ wifi_sta_config_t sta_config;
+ memset(&sta_config, 0x0, sizeof(sta_config));
+ sta_config.security = WIFI_SECURITY_AUTO; // can't use WIFI_DEFAULT_STA_CONFIG because of C99 designator error
+ strncpy(sta_config.ssid, ssid, ssidLen);
+ strncpy(sta_config.password, key, keyLen);
+
+ BK_LOG_ON_ERR(bk_wifi_sta_set_config(&sta_config));
+ BK_LOG_ON_ERR(bk_wifi_sta_start());
+ BK_LOG_ON_ERR(bk_wifi_sta_connect());
+
+ return ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Enabled);
+}
+
+void BekenWiFiDriver::OnConnectWiFiNetwork()
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::OnConnectWiFiNetwork\r\n");
+ if (mpConnectCallback)
+ {
+ // chip::DeviceLayer::PlatformMgr().LockChipStack();
+ mpConnectCallback->OnResult(Status::kSuccess, CharSpan(), 0);
+ // chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+ mpConnectCallback = nullptr;
+ }
+}
+
+void BekenWiFiDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * callback)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::ConnectNetwork\r\n");
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ Status networkingStatus = Status::kSuccess;
+
+ VerifyOrExit(NetworkMatch(mStagingNetwork, networkId), networkingStatus = Status::kNetworkIDNotFound);
+ VerifyOrExit(mpConnectCallback == nullptr, networkingStatus = Status::kUnknownError);
+
+ err = ConnectWiFiNetwork(reinterpret_cast<const char *>(mStagingNetwork.ssid), mStagingNetwork.ssidLen,
+ reinterpret_cast<const char *>(mStagingNetwork.credentials), mStagingNetwork.credentialsLen);
+ mpConnectCallback = callback;
+exit:
+ if (err != CHIP_NO_ERROR)
+ {
+ networkingStatus = Status::kUnknownError;
+ }
+ if (networkingStatus != Status::kSuccess)
+ {
+ ChipLogError(NetworkProvisioning, "Failed to connect to WiFi network:%s", chip::ErrorStr(err));
+ mpConnectCallback = nullptr;
+ // chip::DeviceLayer::PlatformMgr().LockChipStack();
+ callback->OnResult(networkingStatus, CharSpan(), 0);
+ // chip::DeviceLayer::PlatformMgr().UnlockChipStack();
+ }
+}
+
+CHIP_ERROR GetConnectedNetwork(Network & network)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::GetConnectedNetwork\r\n");
+ wifi_link_status_t wifi_setting;
+ memset(&wifi_setting, 0x0, sizeof(wifi_setting));
+ bk_wifi_sta_get_link_status(&wifi_setting);
+ uint8_t length = strnlen(reinterpret_cast<const char *>(wifi_setting.ssid), DeviceLayer::Internal::kMaxWiFiSSIDLength);
+
+ os_memcpy(network.networkID, wifi_setting.ssid, length);
+ ChipLogProgress(NetworkProvisioning, "networkID:[%s][%d]\r\n", network.networkID, length);
+ network.networkIDLen = length;
+ return CHIP_NO_ERROR;
+}
+
+void BekenWiFiDriver::OnNetworkStatusChange()
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::OnNetworkStatusChange\r\n");
+ Network configuredNetwork = { 0 };
+
+ VerifyOrReturn(mpStatusChangeCallback != nullptr);
+ GetConnectedNetwork(configuredNetwork);
+
+ if (configuredNetwork.networkIDLen)
+ {
+ mpStatusChangeCallback->OnNetworkingStatusChange(
+ Status::kSuccess, MakeOptional(ByteSpan(configuredNetwork.networkID, configuredNetwork.networkIDLen)), NullOptional);
+ return;
+ }
+ mpStatusChangeCallback->OnNetworkingStatusChange(
+ Status::kUnknownError, MakeOptional(ByteSpan(configuredNetwork.networkID, configuredNetwork.networkIDLen)),
+ MakeOptional(GetLastDisconnectReason()));
+}
+
+CHIP_ERROR BekenWiFiDriver::SetLastDisconnectReason(const ChipDeviceEvent * event)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::SetLastDisconnectReason\r\n");
+ mLastDisconnectedReason = event->Platform.BKSystemEvent.Data.WiFiStaDisconnected;
+ return CHIP_NO_ERROR;
+}
+
+int32_t BekenWiFiDriver::GetLastDisconnectReason()
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::GetLastDisconnectReason\r\n");
+ return mLastDisconnectedReason;
+}
+
+static beken_semaphore_t matter_scan_sema = NULL;
+
+int scan_done_handler(void * arg, event_module_t event_module, int event_id, void * event_data)
+{
+ if (matter_scan_sema)
+ {
+ rtos_set_semaphore(&matter_scan_sema);
+ }
+ return BK_OK;
+}
+
+CHIP_ERROR BekenWiFiDriver::StartScanWiFiNetworks(ByteSpan ssid)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::StartScanWiFiNetworks\r\n");
+ wifi_scan_config_t config = { 0 };
+ if (ssid.data() == NULL) // non-directed scanning
+ {
+ ChipLogProgress(NetworkProvisioning, "non-directed scanning...\r\n");
+ BK_LOG_ON_ERR(bk_wifi_scan_start(NULL));
+ }
+ else // directed scanning
+ {
+ os_memcpy(config.ssid, ssid.data(), ssid.size());
+ ChipLogProgress(NetworkProvisioning, "directed scanning... ssid:%s ; %d \r\n", config.ssid, ssid.size());
+ BK_LOG_ON_ERR(bk_wifi_scan_start(&config));
+ }
+ return CHIP_NO_ERROR;
+}
+
+void BekenWiFiDriver::OnScanWiFiNetworkDone()
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::OnScanWiFiNetworkDone\r\n");
+ if (!GetInstance().mpScanCallback)
+ {
+ ChipLogProgress(NetworkProvisioning, "can't find the ScanCallback function\r\n");
+ return;
+ }
+ wifi_scan_result_t scan_result = { 0 };
+ int scan_rst_ap_num = 0;
+ BK_LOG_ON_ERR(bk_wifi_scan_get_result(&scan_result));
+ scan_rst_ap_num = scan_result.ap_num;
+ if (scan_rst_ap_num < 2) // beken scan result > = 1
+ {
+ ChipLogProgress(NetworkProvisioning, "NULL AP\r\n");
+ GetInstance().mpScanCallback->OnFinished(Status::kNetworkNotFound, CharSpan(), nullptr);
+ }
+ else
+ {
+ ChipLogProgress(NetworkProvisioning, "AP num = %d\r\n", scan_rst_ap_num);
+ BKScanResponseIterator iter(scan_rst_ap_num, &scan_result);
+ GetInstance().mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), &iter);
+ }
+ GetInstance().mpScanCallback = nullptr;
+ bk_wifi_scan_free_result(&scan_result);
+}
+
+void BekenWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callback)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::ScanNetworks\r\n");
+ if (callback != nullptr)
+ {
+ mpScanCallback = callback;
+ if (matter_scan_sema == NULL)
+ {
+ BK_LOG_ON_ERR(rtos_init_semaphore(&matter_scan_sema, 1));
+ }
+ BK_LOG_ON_ERR(bk_event_register_cb(EVENT_MOD_WIFI, EVENT_WIFI_SCAN_DONE, scan_done_handler, NULL));
+ if (StartScanWiFiNetworks(ssid) != CHIP_NO_ERROR)
+ {
+ mpScanCallback = nullptr;
+ callback->OnFinished(Status::kUnknownError, CharSpan(), nullptr);
+ }
+ BK_LOG_ON_ERR(rtos_get_semaphore(&matter_scan_sema, 4000)); // timeout 4000ms
+ BK_LOG_ON_ERR(bk_event_unregister_cb(EVENT_MOD_WIFI, EVENT_WIFI_SCAN_DONE, scan_done_handler));
+ BK_LOG_ON_ERR(rtos_deinit_semaphore(&matter_scan_sema));
+ matter_scan_sema = NULL;
+ OnScanWiFiNetworkDone();
+ }
+}
+
+size_t BekenWiFiDriver::WiFiNetworkIterator::Count()
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::WiFiNetworkIterator::Count\r\n");
+ return mDriver->mStagingNetwork.ssidLen == 0 ? 0 : 1;
+}
+
+bool BekenWiFiDriver::WiFiNetworkIterator::Next(Network & item)
+{
+ ChipLogProgress(NetworkProvisioning, "BekenWiFiDriver::WiFiNetworkIterator::Next\r\n");
+ if (mExhausted || mDriver->mStagingNetwork.ssidLen == 0)
+ {
+ return false;
+ }
+ uint8_t length =
+ strnlen(reinterpret_cast<const char *>(mDriver->mStagingNetwork.ssid), DeviceLayer::Internal::kMaxWiFiSSIDLength);
+ memcpy(item.networkID, mDriver->mStagingNetwork.ssid, length);
+ item.networkIDLen = length;
+ item.connected = false;
+ mExhausted = true;
+ Network connectedNetwork = { 0 };
+ CHIP_ERROR err = GetConnectedNetwork(connectedNetwork);
+ if (err == CHIP_NO_ERROR)
+ {
+ if (connectedNetwork.networkIDLen == item.networkIDLen &&
+ memcmp(connectedNetwork.networkID, item.networkID, item.networkIDLen) == 0)
+ {
+ item.connected = true;
+ }
+ }
+ return true;
+}
+
+} // namespace NetworkCommissioning
+} // namespace DeviceLayer
+} // namespace chip
+#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
diff --git a/src/platform/Beken/OTAImageProcessorImpl.cpp b/src/platform/Beken/OTAImageProcessorImpl.cpp
new file mode 100644
index 0000000..c500f32
--- /dev/null
+++ b/src/platform/Beken/OTAImageProcessorImpl.cpp
@@ -0,0 +1,351 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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 <app/clusters/ota-requestor/OTADownloader.h>
+#include <app/clusters/ota-requestor/OTARequestorInterface.h>
+#include <lib/support/logging/CHIPLogging.h>
+
+#include "matter_pal.h"
+#include <platform/Beken/OTAImageProcessorImpl.h>
+#include <string.h>
+
+using namespace chip::System;
+using namespace ::chip::DeviceLayer::Internal;
+
+namespace chip {
+
+namespace {
+void HandleRestart(Layer * systemLayer, void * appState)
+{
+ bk_reboot();
+}
+} // namespace
+
+const char ucFinishFlag[] = { 0xF0, 0x5D, 0x4A, 0x8C }; // Flag that OTA update has finished
+CHIP_ERROR OTAImageProcessorImpl::PrepareDownload()
+{
+ ChipLogProgress(SoftwareUpdate, "Prepare download");
+
+ DeviceLayer::PlatformMgr().ScheduleWork(HandlePrepareDownload, reinterpret_cast<intptr_t>(this));
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OTAImageProcessorImpl::Finalize()
+{
+ ChipLogProgress(SoftwareUpdate, "Finalize");
+
+ DeviceLayer::PlatformMgr().ScheduleWork(HandleFinalize, reinterpret_cast<intptr_t>(this));
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OTAImageProcessorImpl::Apply()
+{
+ ChipLogProgress(SoftwareUpdate, "Apply");
+
+ DeviceLayer::PlatformMgr().ScheduleWork(HandleApply, reinterpret_cast<intptr_t>(this));
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OTAImageProcessorImpl::Abort()
+{
+ ChipLogProgress(SoftwareUpdate, "Abort");
+
+ DeviceLayer::PlatformMgr().ScheduleWork(HandleAbort, reinterpret_cast<intptr_t>(this));
+ return CHIP_NO_ERROR;
+}
+
+bool OTAImageProcessorImpl::IsFirstImageRun()
+{
+ OTARequestorInterface * requestor = chip::GetRequestorInstance();
+ if (requestor == nullptr)
+ {
+ return false;
+ }
+
+ return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying;
+}
+
+CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage()
+{
+ OTARequestorInterface * requestor = chip::GetRequestorInstance();
+ if (requestor == nullptr)
+ {
+ return CHIP_ERROR_INTERNAL;
+ }
+
+ uint32_t currentVersion;
+ uint32_t targetVersion = requestor->GetTargetVersion();
+ ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion));
+ if (currentVersion != targetVersion)
+ {
+ ChipLogError(SoftwareUpdate, "Current software version = %" PRIu32 ", expected software version = %" PRIu32, currentVersion,
+ targetVersion);
+ return CHIP_ERROR_INCORRECT_STATE;
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block)
+{
+ ChipLogProgress(SoftwareUpdate, "Process Block");
+
+ if ((block.data() == nullptr) || block.empty())
+ {
+ return CHIP_ERROR_INVALID_ARGUMENT;
+ }
+ CHIP_ERROR err = SetBlock(block);
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(SoftwareUpdate, "Cannot set block data: %" CHIP_ERROR_FORMAT, err.Format());
+ return err;
+ }
+
+ DeviceLayer::PlatformMgr().ScheduleWork(HandleProcessBlock, reinterpret_cast<intptr_t>(this));
+ return CHIP_NO_ERROR;
+}
+
+void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)
+{
+ auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context);
+ if (imageProcessor == nullptr)
+ {
+ ChipLogError(SoftwareUpdate, "ImageProcessor context is null");
+ return;
+ }
+ else if (imageProcessor->mDownloader == nullptr)
+ {
+ ChipLogError(SoftwareUpdate, "mDownloader is null");
+ return;
+ }
+
+ ChipLogProgress(SoftwareUpdate, "%s [%d] OTA address space will be upgraded", __FUNCTION__, __LINE__);
+ imageProcessor->mHeaderParser.Init(); // Initialize the status of OTA parse
+ imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR);
+}
+
+void OTAImageProcessorImpl::HandleFinalize(intptr_t context)
+{
+ auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context);
+ bk_logic_partition_t * partition_info = NULL;
+ UINT32 dwFlagAddrOffset = 0;
+ if (imageProcessor == nullptr)
+ {
+ ChipLogError(SoftwareUpdate, "ImageProcessor context is null");
+ return;
+ }
+
+ partition_info = bk_flash_get_info(BK_PARTITION_OTA);
+ BK_CHECK_POINTER_NULL_TO_VOID(partition_info);
+ dwFlagAddrOffset = partition_info->partition_length - (sizeof(ucFinishFlag) - 1);
+
+ bk_write_ota_data_to_flash((char *) ucFinishFlag, dwFlagAddrOffset, (sizeof(ucFinishFlag) - 1));
+
+ imageProcessor->ReleaseBlock();
+
+ ChipLogProgress(SoftwareUpdate, "OTA image downloaded and written to flash");
+}
+
+void OTAImageProcessorImpl::HandleAbort(intptr_t context)
+{
+ auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context);
+ if (imageProcessor == nullptr)
+ {
+ ChipLogError(SoftwareUpdate, "ImageProcessor context is null");
+ return;
+ }
+
+ // Abort OTA procedure
+
+ imageProcessor->ReleaseBlock();
+}
+
+void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)
+{
+ auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context);
+
+ if (imageProcessor == nullptr)
+ {
+ ChipLogError(SoftwareUpdate, "ImageProcessor context is null");
+ return;
+ }
+ else if (imageProcessor->mDownloader == nullptr)
+ {
+ ChipLogError(SoftwareUpdate, "mDownloader is null");
+ return;
+ }
+
+ ByteSpan block = ByteSpan(imageProcessor->mBlock.data(), imageProcessor->mBlock.size());
+
+ CHIP_ERROR error = imageProcessor->ProcessHeader(block);
+ if (error != CHIP_NO_ERROR)
+ {
+ ChipLogError(SoftwareUpdate, "Failed to process OTA image header");
+ imageProcessor->mDownloader->EndDownload(error);
+ return;
+ }
+
+ if (!imageProcessor->readHeader) // First block received, process header
+ {
+ ota_data_struct_t * tempBuf = (ota_data_struct_t *) chip::Platform::MemoryAlloc(sizeof(ota_data_struct_t));
+
+ if (NULL == tempBuf)
+ {
+ ChipLogError(SoftwareUpdate, "%s [%d] malloc failed ", __FUNCTION__, __LINE__);
+ }
+ memset((char *) tempBuf, 0, sizeof(ota_data_struct_t));
+ memcpy((char *) &(imageProcessor->pOtaTgtHdr), block.data(), sizeof(ota_data_struct_t));
+
+ imageProcessor->flash_data_offset = 0;
+
+ bk_read_ota_data_in_flash((char *) tempBuf, imageProcessor->flash_data_offset, sizeof(ota_data_struct_t));
+ ChipLogProgress(SoftwareUpdate, "Download version %s,date is %ld ", tempBuf->version, tempBuf->timestamp);
+ ChipLogProgress(SoftwareUpdate, "Download size_raw %ld,size_package is %ld ", tempBuf->size_raw, tempBuf->size_package);
+ ChipLogProgress(SoftwareUpdate, "imageProcessor version %s,date is 0x%lx ", imageProcessor->pOtaTgtHdr.version,
+ imageProcessor->pOtaTgtHdr.timestamp);
+
+ bk_logic_partition_t * partition_info = NULL;
+ UINT32 dwFlagAddrOffset = 0;
+ char ucflag[(sizeof(ucFinishFlag) - 1)] = { 0 };
+
+ partition_info = bk_flash_get_info(BK_PARTITION_OTA);
+ BK_CHECK_POINTER_NULL_TO_VOID(partition_info);
+
+ dwFlagAddrOffset = partition_info->partition_length - (sizeof(ucFinishFlag) - 1);
+ bk_read_ota_data_in_flash((char *) ucflag, dwFlagAddrOffset, (sizeof(ucFinishFlag) - 1));
+ ChipLogProgress(SoftwareUpdate, "Block size is %d ,ucFinishFlag size len is %d", block.size(), sizeof(ucFinishFlag));
+
+ if ((0 == memcmp(ucflag, ucFinishFlag, (sizeof(ucFinishFlag) - 1))) &&
+ (0 == memcmp(tempBuf->version, imageProcessor->pOtaTgtHdr.version, sizeof(imageProcessor->pOtaTgtHdr.version))))
+ {
+ chip::Platform::MemoryFree(tempBuf);
+ tempBuf = NULL;
+ ChipLogError(SoftwareUpdate, "The version is is the same as the previous version");
+ return;
+ }
+
+ imageProcessor->readHeader = true;
+ ChipLogProgress(SoftwareUpdate, "flash_data_offset is 0x%lx", imageProcessor->flash_data_offset);
+
+ // Erase update partition
+ ChipLogProgress(SoftwareUpdate, "Erasing target partition...");
+ bk_erase_ota_data_in_flash();
+ ChipLogProgress(SoftwareUpdate, "Erasing target partition...");
+
+ if (0 != bk_write_ota_data_to_flash((char *) block.data(), imageProcessor->flash_data_offset, block.size()))
+ {
+ chip::Platform::MemoryFree(tempBuf);
+ tempBuf = NULL;
+ ChipLogError(SoftwareUpdate, "bk_write_ota_data_to_flash failed %s [%d] ", __FUNCTION__, __LINE__);
+ imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
+ return;
+ }
+
+ imageProcessor->flash_data_offset += block.size(); // count next write flash address
+
+ chip::Platform::MemoryFree(tempBuf);
+ tempBuf = NULL;
+ }
+ else // received subsequent blocks
+ {
+ if (0 != bk_write_ota_data_to_flash((char *) block.data(), imageProcessor->flash_data_offset, block.size()))
+ {
+ ChipLogError(SoftwareUpdate, "bk_write_ota_data_to_flash failed %s [%d] ", __FUNCTION__, __LINE__);
+ imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
+ return;
+ }
+
+ imageProcessor->flash_data_offset += block.size(); // count next write flash address
+
+ imageProcessor->size += block.size();
+ }
+
+ imageProcessor->mParams.downloadedBytes += block.size();
+ imageProcessor->mDownloader->FetchNextData();
+}
+
+void OTAImageProcessorImpl::HandleApply(intptr_t context)
+{
+ auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context);
+ ChipLogError(SoftwareUpdate, "Update completly,will reboot %s [%d] ", __FUNCTION__, __LINE__);
+
+ // HandleApply is called after delayed action time seconds are elapsed, so it would be safe to schedule the restart
+ chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(2 * 1000), HandleRestart, nullptr);
+}
+
+CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block)
+{
+ if (!IsSpanUsable(block))
+ {
+ ReleaseBlock();
+ return CHIP_NO_ERROR;
+ }
+
+ if (mBlock.size() < block.size())
+ {
+ if (!mBlock.empty())
+ {
+ ReleaseBlock();
+ }
+ uint8_t * mBlock_ptr = static_cast<uint8_t *>(chip::Platform::MemoryAlloc(block.size()));
+ if (mBlock_ptr == nullptr)
+ {
+ return CHIP_ERROR_NO_MEMORY;
+ }
+ mBlock = MutableByteSpan(mBlock_ptr, block.size());
+ }
+ CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock);
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format());
+ return err;
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock()
+{
+ if (mBlock.data() != nullptr)
+ {
+ chip::Platform::MemoryFree(mBlock.data());
+ }
+
+ mBlock = MutableByteSpan();
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block)
+{
+ if (mHeaderParser.IsInitialized())
+ {
+ OTAImageHeader header;
+ CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header);
+
+ // Needs more data to decode the header
+ ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR);
+ ReturnErrorOnFailure(error);
+
+ mParams.totalFileBytes = header.mPayloadSize;
+ mHeaderParser.Clear();
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+} // namespace chip
diff --git a/src/platform/Beken/OTAImageProcessorImpl.h b/src/platform/Beken/OTAImageProcessorImpl.h
new file mode 100644
index 0000000..92652f3
--- /dev/null
+++ b/src/platform/Beken/OTAImageProcessorImpl.h
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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 "flash_namespace_value.h"
+#include <app/clusters/ota-requestor/BDXDownloader.h>
+#include <cstring>
+#include <lib/core/OTAImageHeader.h>
+#include <platform/CHIPDeviceLayer.h>
+#include <platform/OTAImageProcessor.h>
+
+namespace chip {
+
+class OTAImageProcessorImpl : public OTAImageProcessorInterface
+{
+public:
+ //////////// OTAImageProcessorInterface Implementation ///////////////
+ CHIP_ERROR PrepareDownload() override;
+ CHIP_ERROR Finalize() override;
+ CHIP_ERROR Apply() override;
+ CHIP_ERROR Abort() override;
+ CHIP_ERROR ProcessBlock(ByteSpan & block) override;
+ bool IsFirstImageRun() override;
+ CHIP_ERROR ConfirmCurrentImage() override;
+ void SetOTADownloader(OTADownloader * downloader) { mDownloader = downloader; }
+
+private:
+ //////////// Actual handlers for the OTAImageProcessorInterface ///////////////
+ static void HandlePrepareDownload(intptr_t context);
+ static void HandleFinalize(intptr_t context);
+ static void HandleAbort(intptr_t context);
+ static void HandleProcessBlock(intptr_t context);
+ static void HandleApply(intptr_t context);
+
+ /**
+ * Called to allocate memory for mBlock if necessary and set it to block
+ */
+ CHIP_ERROR SetBlock(ByteSpan & block);
+
+ /**
+ * Called to release allocated memory for mBlock
+ */
+ CHIP_ERROR ReleaseBlock();
+ CHIP_ERROR ProcessHeader(ByteSpan & block);
+
+ MutableByteSpan mBlock;
+ OTADownloader * mDownloader;
+ OTAImageHeaderParser mHeaderParser;
+ bool readHeader = false;
+ ota_data_struct_t pOtaTgtHdr = { 0 };
+ uint32_t flash_data_offset = 0;
+ uint32_t size = 0;
+};
+
+} // namespace chip
diff --git a/src/platform/Beken/PlatformManagerImpl.cpp b/src/platform/Beken/PlatformManagerImpl.cpp
new file mode 100644
index 0000000..763bff0
--- /dev/null
+++ b/src/platform/Beken/PlatformManagerImpl.cpp
@@ -0,0 +1,96 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Provides an implementation of the PlatformManager object
+ * for the Beken platform.
+ */
+/* this file behaves like a config.h, comes first */
+#include <platform/internal/CHIPDeviceLayerInternal.h>
+
+#include <crypto/CHIPCryptoPAL.h>
+#include <platform/Beken/DiagnosticDataProviderImpl.h>
+#include <platform/Beken/SystemTimeSupport.h>
+#include <platform/PlatformManager.h>
+#include <platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp>
+
+namespace chip {
+namespace DeviceLayer {
+namespace Internal {
+CHIP_ERROR InitLwIPCoreLock(void);
+}
+
+PlatformManagerImpl PlatformManagerImpl::sInstance;
+
+extern "C" int mbedtls_hardware_poll(void * data, unsigned char * output, size_t len, size_t * olen);
+
+CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)
+{
+
+ CHIP_ERROR err;
+
+ // Make sure the LwIP core lock has been initialized
+ err = Internal::InitLwIPCoreLock();
+
+ SuccessOrExit(err);
+
+ mStartTime = System::SystemClock().GetMonotonicTimestamp();
+
+ // TODO Wi-Fi Initialzation currently done through the example app needs to be moved into here.
+ // for now we will let this happen that way and assume all is OK
+ chip::Crypto::add_entropy_source(mbedtls_hardware_poll, NULL, 32);
+
+ // Call _InitChipStack() on the generic implementation base class
+ // to finish the initialization process.
+ err = Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_InitChipStack();
+ SuccessOrExit(err);
+ err = System::Clock::InitClock_RealTime();
+ SuccessOrExit(err);
+
+exit:
+ return err;
+}
+
+void PlatformManagerImpl::_Shutdown()
+{
+ uint64_t upTime = 0;
+
+ if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR)
+ {
+ uint32_t totalOperationalHours = 0;
+
+ if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR)
+ {
+ ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast<uint32_t>(upTime / 3600));
+ }
+ else
+ {
+ ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
+ }
+ }
+ else
+ {
+ ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot");
+ }
+
+ Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_Shutdown();
+}
+
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/PlatformManagerImpl.h b/src/platform/Beken/PlatformManagerImpl.h
new file mode 100644
index 0000000..fae7589
--- /dev/null
+++ b/src/platform/Beken/PlatformManagerImpl.h
@@ -0,0 +1,93 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Provides an implementation of the PlatformManager object
+ * for the Beken platform.
+ */
+
+#pragma once
+
+#include <platform/internal/GenericPlatformManagerImpl_FreeRTOS.h>
+
+namespace chip {
+namespace DeviceLayer {
+
+/**
+ * Concrete implementation of the PlatformManager singleton object for the Beken platform.
+ */
+class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>
+{
+ // Allow the PlatformManager interface class to delegate method calls to
+ // the implementation methods provided by this class.
+ friend PlatformManager;
+
+ // Allow the generic implementation base class to call helper methods on
+ // this class.
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ friend Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>;
+#endif
+
+public:
+ // ===== Platform-specific members that may be accessed directly by the application.
+
+ System::Clock::Timestamp GetStartTime() { return mStartTime; }
+
+private:
+ // ===== Methods that implement the PlatformManager abstract interface.
+
+ CHIP_ERROR _InitChipStack(void);
+ void _Shutdown();
+
+ // ===== Members for internal use by the following friends.
+
+ friend PlatformManager & PlatformMgr(void);
+ friend PlatformManagerImpl & PlatformMgrImpl(void);
+
+ System::Clock::Timestamp mStartTime = System::Clock::kZero;
+
+ static PlatformManagerImpl sInstance;
+
+ using Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::PostEventFromISR;
+};
+
+/**
+ * Returns the public interface of the PlatformManager singleton object.
+ *
+ * Chip applications should use this to access features of the PlatformManager object
+ * that are common to all platforms.
+ */
+inline PlatformManager & PlatformMgr(void)
+{
+ return PlatformManagerImpl::sInstance;
+}
+
+/**
+ * Returns the platform-specific implementation of the PlatformManager singleton object.
+ *
+ * Chip applications can use this to gain access to features of the PlatformManager
+ * that are specific to the Beken platform.
+ */
+inline PlatformManagerImpl & PlatformMgrImpl(void)
+{
+ return PlatformManagerImpl::sInstance;
+}
+
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/Beken/SystemPlatformConfig.h b/src/platform/Beken/SystemPlatformConfig.h
new file mode 100755
index 0000000..b1f16a1
--- /dev/null
+++ b/src/platform/Beken/SystemPlatformConfig.h
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Platform-specific configuration overrides for the CHIP System
+ * Layer on the Beken platform.
+ *
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+namespace chip {
+namespace DeviceLayer {
+struct ChipDeviceEvent;
+} // namespace DeviceLayer
+} // namespace chip
+
+// ==================== Platform Adaptations ====================
+#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS 1
+#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 1
+#define CHIP_SYSTEM_CONFIG_EVENT_OBJECT_TYPE const struct ::chip::DeviceLayer::ChipDeviceEvent *
+
+#define CHIP_SYSTEM_CONFIG_ERROR_TYPE uint32_t
+#define CHIP_SYSTEM_CONFIG_NO_ERROR 0
+#define CHIP_SYSTEM_CONFIG_ERROR_MIN 7000000
+#define CHIP_SYSTEM_CONFIG_ERROR_MAX 7000999
+#define _CHIP_SYSTEM_CONFIG_ERROR(e) (CHIP_SYSTEM_CONFIG_ERROR_MIN + (e))
+#define CHIP_SYSTEM_LWIP_ERROR_MIN 3000000
+#define CHIP_SYSTEM_LWIP_ERROR_MAX 3000128
+
+// ==================== General Configuration Overrides ====================
+
+// NOTE: Values that are mapped to CONFIG_ #defines are settable via the Kconfig mechanism.
+
+#ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS
+#define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16
+#endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS
+
+#define CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF 0
+#define CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS 0
+#define CHIP_SYSTEM_CONFIG_USE_ZEPHYR_SOCKET_EXTENSIONS0 0
+#define CHIP_SYSTEM_CONFIG_USE_LWIP 1
+#define CHIP_SYSTEM_CONFIG_USE_SOCKETS 0
+#define CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK 0
+#define CHIP_SYSTEM_CONFIG_POSIX_LOCKING 0
+#define CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING 1
+#define CHIP_CONFIG_MDNS_CACHE_SIZE 4
diff --git a/src/platform/Beken/SystemTimeSupport.cpp b/src/platform/Beken/SystemTimeSupport.cpp
new file mode 100644
index 0000000..ff83239
--- /dev/null
+++ b/src/platform/Beken/SystemTimeSupport.cpp
@@ -0,0 +1,85 @@
+/*
+ *
+ * Copyright (c) 2022 Project CHIP Authors
+ * 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.
+ */
+
+/**
+ * @file
+ * Provides implementations of the CHIP System Layer platform
+ * time/clock functions that are suitable for use on the Beken platform.
+ */
+/* this file behaves like a config.h, comes first */
+#include <platform/internal/CHIPDeviceLayerInternal.h>
+
+#include "FreeRTOS.h"
+
+namespace chip {
+namespace System {
+namespace Clock {
+
+namespace Internal {
+ClockImpl gClockImpl;
+} // namespace Internal
+
+Clock::Milliseconds64 baseTime;
+
+Microseconds64 ClockImpl::GetMonotonicMicroseconds64(void)
+{
+ return (Clock::Microseconds64(xTaskGetTickCount() << 1) * kMicrosecondsPerMillisecond);
+}
+
+Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void)
+{
+ return (Clock::Milliseconds64(xTaskGetTickCount() << 1));
+}
+
+CHIP_ERROR ClockImpl::GetClock_RealTime(Clock::Microseconds64 & curTime)
+{
+ curTime = GetMonotonicMicroseconds64();
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Clock::Milliseconds64 & curTime)
+{
+ curTime = baseTime + GetMonotonicMilliseconds64();
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR ClockImpl::SetClock_RealTime(Clock::Microseconds64 aNewCurTime)
+{
+ baseTime = Clock::Milliseconds64(aNewCurTime.count() / kMicrosecondsPerMillisecond);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR InitClock_RealTime()
+{
+ baseTime =
+ Clock::Milliseconds64((static_cast<uint64_t>(CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD) * kMicrosecondsPerMillisecond));
+
+ // Use CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD as the initial value of RealTime.
+ // Then the RealTime obtained from GetClock_RealTime will be always valid.
+ //
+ // TODO(19081): This is broken because it causes the platform to report
+ // that it does have wall clock time when it actually doesn't.
+ return System::SystemClock().SetClock_RealTime(baseTime);
+}
+
+} // namespace Clock
+} // namespace System
+} // namespace chip
diff --git a/src/platform/Beken/SystemTimeSupport.h b/src/platform/Beken/SystemTimeSupport.h
new file mode 100755
index 0000000..da38a26
--- /dev/null
+++ b/src/platform/Beken/SystemTimeSupport.h
@@ -0,0 +1,28 @@
+/*
+ *
+ * Copyright (c) 2022 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 <lib/support/TimeUtils.h>
+
+namespace chip {
+namespace System {
+namespace Clock {
+
+CHIP_ERROR InitClock_RealTime();
+
+} // namespace Clock
+} // namespace System
+} // namespace chip
diff --git a/src/platform/Beken/args.gni b/src/platform/Beken/args.gni
new file mode 100755
index 0000000..fbc11f6
--- /dev/null
+++ b/src/platform/Beken/args.gni
@@ -0,0 +1,25 @@
+# Copyright (c) 2022 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.
+
+import("//build_overrides/chip.gni")
+
+chip_device_platform = "beken"
+
+lwip_platform = "external"
+mbedtls_target = "//mbedtls:mbedtls"
+
+chip_build_tests = false
+chip_inet_config_enable_tun_endpoint = false
+chip_inet_config_enable_tcp_endpoint = true
+chip_inet_config_enable_udp_endpoint = true
diff --git a/src/platform/Beken/matter_pal.h b/src/platform/Beken/matter_pal.h
new file mode 100644
index 0000000..aa216f4
--- /dev/null
+++ b/src/platform/Beken/matter_pal.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright (c) 2022 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.
+ */
+
+/**
+ * @file
+ * This file contains matter_pal.
+ */
+
+#ifndef _MATTER_PAL_H_
+#define _MATTER_PAL_H_
+
+#include <os/mem.h>
+#include <os/os.h>
+
+#include <components/system.h>
+
+#include <modules/wifi.h>
+#include <modules/wifi_types.h>
+
+#include "common/bk_err.h"
+#include "common/bk_include.h"
+
+#include "BkDriverFlash.h"
+#include "flash_namespace_value.h"
+
+#include "wlan_ui_pub.h"
+
+#include "bk_wifi.h"
+#include "bk_wifi_types.h"
+#include "bk_wifi_v1.h"
+#include "net.h"
+
+#include "at_ble_common.h"
+#include "ble.h"
+
+#endif // _MATTER_PAL_H_
+// eof
diff --git a/src/platform/device.gni b/src/platform/device.gni
index 3e4486b..0592a67 100755
--- a/src/platform/device.gni
+++ b/src/platform/device.gni
@@ -16,7 +16,7 @@
import("${chip_root}/src/ble/ble.gni")
declare_args() {
- # Device platform layer: cc13x2_26x2, cc32xx, darwin, efr32, esp32, external, freertos, linux, nrfconnect, k32w0, qpg, tizen, cyw30739, bl602, mw320, zephyr, none.
+ # Device platform layer: cc13x2_26x2, cc32xx, darwin, efr32, esp32, external, freertos, linux, nrfconnect, k32w0, qpg, tizen, cyw30739, bl602, mw320, zephyr, beken, none.
chip_device_platform = "auto"
chip_platform_target = ""
@@ -64,7 +64,7 @@
chip_device_platform == "android" || chip_device_platform == "ameba" ||
chip_device_platform == "webos" || chip_device_platform == "cc32xx" ||
chip_device_platform == "bl602" || chip_device_platform == "bl602" ||
- chip_device_platform == "mw320" ||
+ chip_device_platform == "mw320" || chip_device_platform == "beken" ||
(chip_device_platform == "darwin" && current_os == "mac")
# Enable ble support.
@@ -85,7 +85,7 @@
chip_device_platform == "mbed" || chip_device_platform == "p6" ||
chip_device_platform == "ameba" || chip_device_platform == "webos" ||
chip_device_platform == "cc32xx" || chip_device_platform == "bl602" ||
- chip_device_platform == "mw320") {
+ chip_device_platform == "mw320" || chip_device_platform == "beken") {
chip_mdns = "minimal"
} else if (chip_device_platform == "darwin" ||
chip_device_platform == "cc13x2_26x2" || current_os == "android" ||
@@ -138,6 +138,8 @@
_chip_device_layter = "nxp/mw320"
} else if (chip_device_platform == "zephyr") {
_chip_device_layer = "Zephyr"
+} else if (chip_device_platform == "beken") {
+ _chip_device_layer = "Beken"
}
if (chip_device_platform != "external") {
@@ -197,5 +199,6 @@
chip_device_platform == "p6" || chip_device_platform == "android" ||
chip_device_platform == "ameba" || chip_device_platform == "cyw30739" ||
chip_device_platform == "webos" || chip_device_platform == "bl602" ||
- chip_device_platform == "mw320" || chip_device_platform == "zephyr",
+ chip_device_platform == "mw320" || chip_device_platform == "zephyr" ||
+ chip_device_platform == "beken",
"Please select a valid value for chip_device_platform")