diff --git a/include/bluetooth/hdf_bt_transport.h b/include/bluetooth/hdf_bt_transport.h
new file mode 100644
index 0000000000000000000000000000000000000000..514c8be188eab970a9792437af341938ff19bd10
--- /dev/null
+++ b/include/bluetooth/hdf_bt_transport.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ *
+ * HDF is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ * See the LICENSE file in the root of this repository for complete details.
+ */
+
+#ifndef HDF_BT_TRANSPORT_H
+#define HDF_BT_TRANSPORT_H
+#include "hdf_device_desc.h"
+
+struct HdfBtTransportOps;
+
+struct HdfBtTransport {
+ const struct HdfBtTransportOps *ops;
+};
+
+struct HdfBtTransportOps {
+ int32_t (*Init)(struct HdfBtTransport *transport);
+ int32_t (*GetVfsDevName)(struct HdfBtTransport *transport, char *buf, uint32_t size);
+ void (*Deinit)(struct HdfBtTransport *transport);
+ void (*Destory)(struct HdfBtTransport *transport);
+};
+
+struct HdfBtTransportService {
+ struct IDeviceIoService base;
+ struct HdfBtTransport *(*CreateTransport)(const struct DeviceResourceNode *node);
+};
+
+#endif
diff --git a/include/bluetooth/hdf_chip.h b/include/bluetooth/hdf_chip.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b633f136f2155a62b78dacefac504c26becff07
--- /dev/null
+++ b/include/bluetooth/hdf_chip.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ *
+ * HDF is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ * See the LICENSE file in the root of this repository for complete details.
+ */
+
+#ifndef HDF_CHIP_H
+#define HDF_CHIP_H
+
+#include "hdf_chip_config.h"
+#include "osal/osal_time.h"
+
+struct HdfReset;
+struct HdfPower;
+
+struct HdfPowerOps {
+ /**
+ * @brief Powers on the device using a specified power manage interface.
+ *
+ * @param powerMgr Indicates the pointer to the power manage interface.
+ * @return Returns 0 if the device is powered on; returns a negative value otherwise.
+ *
+ * @since 1.0
+ * @version 1.0
+ */
+ int32_t (*On)(struct HdfPower *powerMgr);
+
+ /**
+ * @brief Powers off the device using a specified power manage interface.
+ *
+ * @param powerMgr Indicates the pointer to the power manage interface.
+ * @return Returns 0 if the device is powered off; returns a negative value otherwise.
+ *
+ * @since 1.0
+ * @version 1.0
+ */
+ int32_t (*Off)(struct HdfPower *powerMgr);
+
+ /**
+ * @brief Releases power using a specified power manage interface.
+ *
+ * @param powerMgr Indicates the pointer to the power manage interface.
+ *
+ * @since 1.0
+ * @version 1.0
+ */
+ void (*Release)(struct HdfPower *powerMgr);
+};
+/**
+ * @brief Provides functions for powering on and off the device, releasing power, and creating a power manage interface.
+ *
+ * @since 1.0
+ * @version 1.0
+ */
+struct HdfPower {
+ const struct HdfPowerOps *ops;
+};
+
+struct HdfResetOps {
+ /**
+ * @brief Resets the WLAN module using a specified reset manage interface.
+ *
+ * @param resetManager Indicates the pointer to the reset manage interface.
+ * @return Returns 0 if the WLAN module is reset; returns a negative value otherwise.
+ *
+ * @since 1.0
+ * @version 1.0
+ */
+ int32_t (*Reset)(struct HdfReset *resetManager);
+
+ /**
+ * @brief Releases a specified reset manage interface.
+ *
+ * @param resetMgr Indicates the pointer to the reset manage interface.
+ *
+ * @since 1.0
+ * @version 1.0
+ */
+ void (*Release)(struct HdfReset *resetMgr);
+};
+
+/**
+ * @brief Describes the reset manage interface, including its configuration and functions.
+ *
+ * @since 1.0
+ * @version 1.0
+ */
+struct HdfReset {
+ const struct HdfResetOps *ops;
+};
+
+struct HdfUartBus {
+ const char *name;
+};
+
+struct HdfBus {
+ uint8_t type;
+ union {
+ struct HdfUartBus uart;
+ };
+};
+
+enum FunctionType { FUNC_TYPE_WLAN = 0, FUNC_TYPE_BT };
+
+struct HdfVirtualDevice {
+ const char *name;
+ struct HdfCompositeDevice *parent;
+ struct HdfPower *power;
+ struct HdfReset *reset;
+ struct HdfBus *bus;
+ uint8_t bootUpTimeOut;
+ uint8_t functionType;
+};
+
+struct HdfVirtualDevice *CreateVirtualDevice(struct HdfChipConfig *config);
+void ReleaseVirtualDevice(struct HdfVirtualDevice *device);
+
+inline static int32_t HdfPowerOnVirtualDevice(struct HdfVirtualDevice *device) {
+ if (device == NULL) {
+ return HDF_FAILURE;
+ }
+ if (device->power == NULL || device->power->ops == NULL || device->power->ops->On == NULL) {
+ return HDF_FAILURE;
+ }
+ return device->power->ops->On(device->power);
+}
+inline static int32_t HdfPowerOffVirtualDevice(struct HdfVirtualDevice *device) {
+ if (device == NULL) {
+ return HDF_FAILURE;
+ }
+ if (device->power == NULL || device->power->ops == NULL || device->power->ops->Off == NULL) {
+ return HDF_FAILURE;
+ }
+ return device->power->ops->Off(device->power);
+}
+inline static int32_t HdfResetVirtualDevice(struct HdfVirtualDevice *device) {
+ int32_t ret;
+ if (device == NULL) {
+ return HDF_FAILURE;
+ }
+ if (device->reset == NULL || device->reset->ops == NULL || device->reset->ops->Reset == NULL) {
+ return HDF_FAILURE;
+ }
+ ret = device->reset->ops->Reset(device->reset);
+ if (ret != HDF_SUCCESS) {
+ return ret;
+ }
+ OsalMSleep(device->bootUpTimeOut);
+}
+
+#endif
\ No newline at end of file
diff --git a/include/bluetooth/hdf_chip_config.h b/include/bluetooth/hdf_chip_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4f4ac97ddfbed7af9ad47c2356b90c72607cc14
--- /dev/null
+++ b/include/bluetooth/hdf_chip_config.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ *
+ * HDF is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ * See the LICENSE file in the root of this repository for complete details.
+ */
+
+#ifndef HDF_CHIP_CONFIG_H
+#define HDF_CHIP_CONFIG_H
+
+#include "device_resource_if.h"
+#include "hdf_base.h"
+#include "hdf_log.h"
+#include "osal/osal_mem.h"
+#include "securec.h"
+
+#define HDF_CHIP_MAX_POWER_SUPPORTED 2
+
+#define BUS_FUNC_MAX 1
+
+enum PowerType
+{
+ POWER_TYPE_ALWAYS_ON = 0,
+ POWER_TYPE_GPIO
+};
+
+struct HdfConfigGpioBasedSwitch {
+ uint8_t gpioId;
+ uint8_t activeLevel;
+};
+
+struct HdfPowerConfig {
+ uint8_t powerSeqDelay;
+ uint8_t type;
+ union {
+ struct HdfConfigGpioBasedSwitch gpio;
+ };
+};
+
+struct HdfPowersConfig {
+ uint8_t powerCount;
+ struct HdfPowerConfig power[0];
+};
+
+enum ResetType
+{
+ RESET_TYPE_NOT_MANAGEABLE = 0,
+ RESET_TYPE_GPIO
+};
+
+struct HdfResetConfig {
+ union {
+ struct HdfConfigGpioBasedSwitch gpio;
+ };
+ uint8_t resetType;
+ uint8_t resetHoldTime;
+};
+
+struct HdfChipConfig {
+ const char *name;
+ struct HdfPowersConfig *powers;
+ struct HdfResetConfig reset;
+ uint8_t bootUpTimeOut;
+};
+
+static inline int ParsePowerConfig(const struct DeviceResourceNode *node, struct HdfPowerConfig *config) {
+ struct DeviceResourceIface *drsOps = NULL;
+ if (node == NULL || config == NULL) {
+ HDF_LOGE("%s: one of the input para is NULL!", __func__);
+ return HDF_FAILURE;
+ }
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetUint8 == NULL) {
+ HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
+ return HDF_FAILURE;
+ }
+
+ if (drsOps->GetUint8(node, "powerSeqDelay", &config->powerSeqDelay, 0) != HDF_SUCCESS) {
+ HDF_LOGE("%s: powersSeqDelay fail!", __func__);
+ return HDF_FAILURE;
+ }
+
+ if (drsOps->GetUint8(node, "powerType", &config->type, 0) != HDF_SUCCESS) {
+ HDF_LOGE("%s: type fail!", __func__);
+ return HDF_FAILURE;
+ }
+
+ if (config->type == POWER_TYPE_GPIO) {
+ if (drsOps->GetUint8(node, "gpioId", &config->gpio.gpioId, 0) != HDF_SUCCESS) {
+ HDF_LOGE("%s: gpioId fail!", __func__);
+ return HDF_FAILURE;
+ }
+ if (drsOps->GetUint8(node, "activeLevel", &config->gpio.activeLevel, 0) != HDF_SUCCESS) {
+ HDF_LOGE("%s: activeLevel fail!", __func__);
+ return HDF_FAILURE;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+
+static inline struct HdfPowersConfig *ParsePowersConfig(const struct DeviceResourceNode *node) {
+ struct DeviceResourceIface *drsOps = NULL;
+ struct DeviceResourceNode *childNode = NULL;
+ struct HdfPowersConfig *config = NULL;
+ uint8_t nodeCount = 0;
+ int32_t ret;
+ if (node == NULL) {
+ HDF_LOGE("%s: input para is NULL!", __func__);
+ return NULL;
+ }
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetChildNode == NULL) {
+ HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
+ return NULL;
+ }
+ DEV_RES_NODE_FOR_EACH_CHILD_NODE(node, childNode) { ++nodeCount; }
+ if (nodeCount > HDF_CHIP_MAX_POWER_SUPPORTED) {
+ return NULL;
+ }
+ config = OsalMemCalloc(sizeof(struct HdfPowersConfig) + nodeCount * sizeof(struct HdfPowerConfig));
+ if (config == NULL) {
+ return NULL;
+ }
+ config->powerCount = nodeCount;
+ for (uint8_t i = 0; i < nodeCount; i++) {
+ char buff[32] = {0};
+ ret = snprintf_s(buff, 32, 32, "power%d", i);
+ if (ret < 0) {
+ HDF_LOGE("%s:snprintf_s failed!ret=%d, i=%d", __func__, ret, i);
+ break;
+ }
+ const struct DeviceResourceNode *powerNode = drsOps->GetChildNode(node, buff);
+ if (powerNode == NULL) {
+ HDF_LOGE("%s:Can not get node %s", __func__, buff);
+ ret = HDF_FAILURE;
+ break;
+ }
+ ret = ParsePowerConfig(powerNode, config->power + i);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:parse node %s failed!ret=%d", __func__, buff, ret);
+ break;
+ }
+ }
+
+ if (ret != HDF_SUCCESS) {
+ OsalMemFree(config);
+ config = NULL;
+ }
+ return config;
+}
+
+static inline int ParseResetConfig(const struct DeviceResourceNode *node, struct HdfResetConfig *reset) {
+ struct DeviceResourceIface *drsOps = NULL;
+ if (node == NULL || reset == NULL) {
+ HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
+ return HDF_FAILURE;
+ }
+
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetUint8 == NULL) {
+ HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
+ return HDF_FAILURE;
+ }
+
+ if (drsOps->GetUint8(node, "resetType", &reset->resetType, 0) != HDF_SUCCESS) {
+ HDF_LOGE("%s: powersSeqDelay fail!", __func__);
+ return HDF_FAILURE;
+ }
+ if (reset->resetType == RESET_TYPE_GPIO) {
+ if (drsOps->GetUint8(node, "gpioId", &reset->gpio.gpioId, 0) != HDF_SUCCESS) {
+ HDF_LOGE("%s: gpioId fail!", __func__);
+ return HDF_FAILURE;
+ }
+
+ if (drsOps->GetUint8(node, "activeLevel", &reset->gpio.activeLevel, 0) != HDF_SUCCESS) {
+ HDF_LOGE("%s: read activeLevel fail!", __func__);
+ return HDF_FAILURE;
+ }
+
+ if (drsOps->GetUint8(node, "resetHoldTime", &reset->resetHoldTime, 0) != HDF_SUCCESS) {
+ HDF_LOGE("%s: read resetHoldTime fail!", __func__);
+ return HDF_FAILURE;
+ }
+ }
+ return HDF_SUCCESS;
+}
+
+static inline void ClearChipConfig(struct HdfChipConfig *config) {
+
+ if (config->powers != NULL) {
+ OsalMemFree(config->powers);
+ config->powers = NULL;
+ }
+}
+
+static inline int32_t ParseChipConfig(const struct DeviceResourceNode *node, struct HdfChipConfig *config) {
+ struct DeviceResourceIface *drsOps = NULL;
+ const struct DeviceResourceNode *devPowerNode = NULL;
+ const struct DeviceResourceNode *resetNode = NULL;
+ int32_t ret = HDF_SUCCESS;
+ if (node == NULL || config == NULL) {
+ HDF_LOGE("%s: invalid node or devLstConfig!", __func__);
+ return HDF_FAILURE;
+ }
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetUint8 == NULL || drsOps->GetChildNode == NULL) {
+ HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
+ return HDF_FAILURE;
+ }
+ config->name = node->name;
+
+ if (drsOps->GetUint8(node, "bootUpTimeOut", &config->bootUpTimeOut, 0) != HDF_SUCCESS) {
+ HDF_LOGE("%s: bootUpTimeOut fail!", __func__);
+ return HDF_FAILURE;
+ }
+
+ resetNode = drsOps->GetChildNode(node, "reset");
+ if (resetNode == NULL) {
+ HDF_LOGE("%s: GetChildNode fail!", __func__);
+ return HDF_FAILURE;
+ }
+ if (ParseResetConfig(resetNode, &config->reset) != HDF_SUCCESS) {
+ return HDF_FAILURE;
+ }
+
+ do {
+ devPowerNode = drsOps->GetChildNode(node, "powers");
+ if (devPowerNode == NULL) {
+ HDF_LOGE("%s: GetChildNode fail!", __func__);
+ ret = HDF_FAILURE;
+ break;
+ }
+ config->powers = ParsePowersConfig(devPowerNode);
+ if (config->powers == NULL) {
+ ret = HDF_FAILURE;
+ break;
+ }
+ } while (false);
+
+ if (ret != HDF_SUCCESS) {
+ ClearChipConfig(config);
+ }
+ return ret;
+}
+
+#endif
\ No newline at end of file
diff --git a/model/network/bluetooth/hdf_bt_core.c b/model/network/bluetooth/hdf_bt_core.c
new file mode 100644
index 0000000000000000000000000000000000000000..df35fa7dcfd7a602e628a88ee876eaf916a772f3
--- /dev/null
+++ b/model/network/bluetooth/hdf_bt_core.c
@@ -0,0 +1,548 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ *
+ * HDF is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ * See the LICENSE file in the root of this repository for complete details.
+ */
+
+#include "devsvc_manager_clnt.h"
+#include "hdf_bt_transport.h"
+#include "hdf_chip.h"
+#include "hdf_chip_config.h"
+#include "hdf_device_desc.h"
+#include "hdf_io_service_if.h"
+#include "hdf_log.h"
+#include "osal/osal_io.h"
+#include "osal/osal_mem.h"
+#include "osal/osal_spinlock.h"
+#include "platform/gpio_if.h"
+
+#define HDF_LOG_TAG HDF_BT
+
+#define MAX_BT_DEVICE_COUNT 2
+
+#define MAX_NODE_NAME_SIZE 32
+
+struct HdfBtVirtualDevice {
+ struct HdfVirtualDevice *device;
+ struct HdfBtTransport *transport;
+};
+
+enum HdfBtTransportType
+{
+ BT_TRANSPORT_TYPE_RAW = 0,
+ BT_TRANSPORT_TYPE_CUSTOM
+};
+
+struct HdfBtTransportConfig {
+ uint8_t type;
+ union {
+ const char *devName;
+ const char *serviceName;
+ };
+};
+
+struct HdfBtRawTransport {
+ struct HdfBtTransport base;
+ const char *devName;
+};
+
+typedef int32_t (*DeviceOperator)(struct HdfVirtualDevice *);
+typedef int32_t (*BtDeviceOperator)(struct HdfBtVirtualDevice *);
+
+enum HDF_BT_CMD
+{
+ HDF_BT_CMD_GET_DEVICE_COUNT = 0,
+ HDF_BT_CMD_INIT_DEVICE,
+ HDF_BT_CMD_DEINIT_DEVICE
+};
+
+// registed device count
+uint8_t g_deviceCount = 0;
+// registed device tab
+struct HdfBtVirtualDevice g_btDevices[MAX_BT_DEVICE_COUNT];
+// lock of the device tab
+OSAL_DECLARE_SPINLOCK(g_devicesLock);
+
+static int32_t ParseTransportConfig(const struct DeviceResourceNode *node, struct HdfBtTransportConfig *config) {
+ struct DeviceResourceIface *drsOps = NULL;
+ int32_t ret = HDF_SUCCESS;
+ if (node == NULL || config == NULL) {
+ HDF_LOGE("%s: one of the input para is NULL!", __func__);
+ return HDF_FAILURE;
+ }
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetUint8 == NULL || drsOps->GetString == NULL) {
+ HDF_LOGE("%s: bad DeviceResourceIface!", __func__);
+ return HDF_FAILURE;
+ }
+ if (drsOps->GetUint8(node, "type", &config->type, 0) != HDF_SUCCESS) {
+ HDF_LOGE("%s: read type fail!", __func__);
+ return HDF_FAILURE;
+ }
+ switch (config->type) {
+ case BT_TRANSPORT_TYPE_RAW: {
+ if (drsOps->GetString(node, "devName", &config->devName, "") != HDF_SUCCESS) {
+ HDF_LOGE("%s: devName is required!", __func__);
+ ret = HDF_FAILURE;
+ }
+ break;
+ }
+ case BT_TRANSPORT_TYPE_CUSTOM: {
+ if (drsOps->GetString(node, "serviceName", &config->serviceName, "") != HDF_SUCCESS) {
+ HDF_LOGE("%s: serviceName is required!", __func__);
+ ret = HDF_FAILURE;
+ }
+ break;
+ }
+ default:
+ HDF_LOGE("%s: unexpected transport type %d!", __func__, config->type);
+ ret = HDF_FAILURE;
+ break;
+ }
+ return ret;
+}
+
+static int32_t InitDeivceList() {
+ (void)memset_s(g_btDevices, sizeof(g_btDevices), 0, sizeof(g_btDevices));
+ g_deviceCount = 0;
+ return OsalSpinInit(&g_devicesLock);
+}
+
+static int32_t RegistBtDevice(struct HdfVirtualDevice *device, struct HdfBtTransport *transport) {
+ int ret;
+ if (device == NULL || transport == NULL) {
+ HDF_LOGE("%s:nullptr!", __func__);
+ return HDF_FAILURE;
+ }
+ ret = OsalSpinLockIrq(&g_devicesLock);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:lock failed!ret=%d", __func__, ret);
+ return ret;
+ }
+ if (g_deviceCount < MAX_BT_DEVICE_COUNT) {
+ g_btDevices[g_deviceCount].device = device;
+ g_btDevices[g_deviceCount].transport = transport;
+ ++g_deviceCount;
+ } else {
+ HDF_LOGE("%s:deviceList is full!", __func__);
+ ret = HDF_FAILURE;
+ }
+ (void)OsalSpinUnlockIrq(&g_devicesLock);
+ return ret;
+}
+
+inline static int32_t OperateDevice(uint8_t id, DeviceOperator operator) {
+ int32_t ret = OsalSpinLockIrq(&g_devicesLock);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:lock failed!ret=%d", __func__, ret);
+ return ret;
+ }
+ HDF_LOGW("%s:operator %d", __func__, id);
+
+ do {
+ if (id >= g_deviceCount) {
+ HDF_LOGE("%s:no such device", __func__);
+ ret = HDF_FAILURE;
+ break;
+ }
+ ret = operator(g_btDevices[id].device);
+ } while (false);
+
+ (void)OsalSpinUnlockIrq(&g_devicesLock);
+ return ret;
+}
+
+#define OperateBtDevice(RET, ID, Operator, ARGS...) \
+ do { \
+ RET = OsalSpinLockIrq(&g_devicesLock); \
+ if (RET != HDF_SUCCESS) { \
+ HDF_LOGE("%s:lock failed!ret=%d", __func__, RET); \
+ break; \
+ } \
+ do { \
+ if (id >= g_deviceCount) { \
+ HDF_LOGE("%s:no such device", __func__); \
+ RET = HDF_FAILURE; \
+ break; \
+ } \
+ RET = Operator(&g_btDevices[ID], ##ARGS); \
+ } while (false); \
+ (void)OsalSpinUnlockIrq(&g_devicesLock); \
+ } while (false)
+
+inline int32_t PowerOnDevice(uint8_t id) {
+ return OperateDevice(id, HdfPowerOnVirtualDevice);
+}
+
+inline int32_t PowerOffDevice(uint8_t id) {
+ return OperateDevice(id, HdfPowerOffVirtualDevice);
+}
+
+static int32_t InitTransportOperation(struct HdfBtVirtualDevice *device) {
+ if (device == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return HDF_FAILURE;
+ }
+ if (device->transport != NULL && device->transport->ops != NULL && device->transport->ops->Init != NULL) {
+ return device->transport->ops->Init(device->transport);
+ }
+ return HDF_SUCCESS;
+}
+
+inline int32_t InitTransport(uint8_t id) {
+ int ret = HDF_SUCCESS;
+ OperateBtDevice(ret, id, InitTransportOperation);
+ return ret;
+}
+
+static int32_t DeinitTransportOperation(struct HdfBtVirtualDevice *device) {
+ if (device == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return HDF_FAILURE;
+ }
+ if (device->transport != NULL && device->transport->ops != NULL && device->transport->ops->Deinit != NULL) {
+ device->transport->ops->Deinit(device->transport);
+ }
+ return HDF_SUCCESS;
+}
+
+inline int32_t DeinitTransport(uint8_t id) {
+ int ret = HDF_SUCCESS;
+ OperateBtDevice(ret, id, DeinitTransportOperation);
+ return ret;
+}
+
+static int32_t GetDevNodeNameOperation(struct HdfBtVirtualDevice *device, char *buf, uint32_t size) {
+ if (device == NULL || device->transport == NULL || device->transport->ops == NULL ||
+ device->transport->ops->GetVfsDevName == NULL) {
+ HDF_LOGE("%s:bad transport.", __func__);
+ return HDF_FAILURE;
+ }
+ return device->transport->ops->GetVfsDevName(device->transport, buf, size);
+}
+
+inline int32_t GetDevNodeName(uint8_t id, char *buf, uint32_t size) {
+ int ret = HDF_SUCCESS;
+ OperateBtDevice(ret, id, GetDevNodeNameOperation, buf, size);
+ return ret;
+}
+
+static int32_t BtMessageDispatcher(struct HdfDeviceIoClient *client, int id, struct HdfSBuf *reqData,
+ struct HdfSBuf *rspData) {
+ int ret = HDF_FAILURE;
+ HDF_LOGV("%s: enter", __func__);
+ (void)client;
+ if (reqData == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return ret;
+ }
+ switch (id) {
+ case HDF_BT_CMD_GET_DEVICE_COUNT: {
+ if (HdfSbufWriteUint8(rspData, g_deviceCount)) {
+ ret = HDF_SUCCESS;
+ } else {
+ HDF_LOGE("%s:reponse device count failed!", __func__);
+ }
+ break;
+ }
+ case HDF_BT_CMD_INIT_DEVICE: {
+ uint8_t id = 0;
+ char buff[MAX_NODE_NAME_SIZE];
+ if (!HdfSbufReadUint8(reqData, &id)) {
+ HDF_LOGE("%s:read deviceID failed!", __func__);
+ break;
+ }
+ HDF_LOGI("%s:power on. devID=%d", __func__, id);
+ ret = PowerOnDevice(id);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:power on failed.devideID=%d", __func__, id);
+ break;
+ }
+ ret = InitTransport(id);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:init transport failed.devideID=%d,ret=%d", __func__, id, ret);
+ break;
+ }
+ ret = GetDevNodeName(id, buff, MAX_NODE_NAME_SIZE);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:get dev node failed!id=%d", __func__, id);
+ break;
+ }
+ if (rspData != NULL) {
+ if (!HdfSbufWriteString(rspData, buff)) {
+ HDF_LOGE("%s:respose dev node failed!id=%d", __func__, id);
+ break;
+ }
+ }
+ ret = HDF_SUCCESS;
+ break;
+ }
+ case HDF_BT_CMD_DEINIT_DEVICE: {
+ uint8_t id = 0;
+ if (!HdfSbufReadUint8(reqData, &id)) {
+ HDF_LOGE("%s:read deviceID failed!", __func__);
+ break;
+ }
+ ret = DeinitTransport(id);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:Deinit transport failed.devideID=%d", __func__, id);
+ }
+ HDF_LOGI("%s:power on %d", __func__, id);
+ ret = PowerOffDevice(id);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:power off failed.devideID=%d", __func__, id);
+ break;
+ }
+
+ break;
+ }
+ default:
+ HDF_LOGE("%s:unexpected cmd %d!", __func__, id);
+ break;
+ };
+ return ret;
+}
+
+static int HdfBtChipDriverBind(struct HdfDeviceObject *dev) {
+ static struct IDeviceIoService btService = {
+ .object.objectId = 1,
+ .Dispatch = BtMessageDispatcher,
+ };
+ HDF_LOGV("%s: enter", __func__);
+
+ dev->service = &btService;
+ return 0;
+}
+
+static int32_t HdfBtInitRawTransport(struct HdfBtTransport *transport) {
+ return HDF_SUCCESS;
+}
+
+static void HdfBtDeinitRawTransport(struct HdfBtTransport *transport) {
+ return;
+}
+
+static void HdfBtDestoryRawTransport(struct HdfBtTransport *transport) {
+ if (transport != NULL) {
+ OsalMemFree(transport);
+ }
+}
+
+static int32_t HdfBtGetRawTransportDeviceName(struct HdfBtTransport *transport, char *buf, uint32_t size) {
+ struct HdfBtRawTransport *rawTransport = (struct HdfBtRawTransport *)transport;
+ if (rawTransport == NULL) {
+ return HDF_FAILURE;
+ }
+ if (strncpy_s(buf, size, rawTransport->devName, strlen(rawTransport->devName)) != EOK) {
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+static const struct HdfBtTransportOps g_rawTransportOps = {.Init = HdfBtInitRawTransport,
+ .Deinit = HdfBtDeinitRawTransport,
+ .GetVfsDevName = HdfBtGetRawTransportDeviceName,
+ .Destory = HdfBtDestoryRawTransport};
+
+static struct HdfBtRawTransport *CreateRawTransport(const char *devName) {
+ struct HdfBtRawTransport *transport = NULL;
+ if (devName == NULL) {
+ return NULL;
+ }
+ transport = (struct HdfBtRawTransport *)OsalMemCalloc(sizeof(struct HdfBtRawTransport));
+ if (transport == NULL) {
+ return NULL;
+ }
+ transport->base.ops = &g_rawTransportOps;
+ transport->devName = devName;
+ return transport;
+}
+
+static struct HdfBtTransport *CreateCustomTransport(const char *serviceName, const struct DeviceResourceNode *node) {
+ struct SubscriberCallback callback = {NULL};
+ struct HdfDeviceObject *object = NULL;
+ struct HdfBtTransportService *service = NULL;
+
+ int ret = DevSvcManagerClntSubscribeService(serviceName, callback);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:load service failed!serviceName=%s", __func__, serviceName);
+ return NULL;
+ }
+ object = DevSvcManagerClntGetDeviceObject(serviceName);
+ if (object == NULL || object->service == NULL) {
+ HDF_LOGE("%s:bad service %s", __func__, serviceName);
+ return NULL;
+ }
+ service = (struct HdfBtTransportService *)object->service;
+ if (service->CreateTransport == NULL) {
+ HDF_LOGE("%s:service %s has no CreateTransport method", __func__, serviceName);
+ return NULL;
+ }
+ return service->CreateTransport(node);
+}
+
+static struct HdfBtTransport *CreateTransport(const struct DeviceResourceNode *node) {
+ struct HdfBtTransport *transport = NULL;
+ struct DeviceResourceIface *drsOps = NULL;
+ struct HdfBtTransportConfig config = {0};
+ const struct DeviceResourceNode *transportNode = NULL;
+ int32_t ret;
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetChildNode == NULL) {
+ HDF_LOGE("%s: bad DeviceResourceIface!", __func__);
+ return NULL;
+ }
+ transportNode = drsOps->GetChildNode(node, "transport");
+ if (transportNode == NULL) {
+ HDF_LOGE("%s:node transport in hcs is required", __func__);
+ return NULL;
+ }
+
+ ret = ParseTransportConfig(transportNode, &config);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: parse transport config failed!ret= %d", __func__, ret);
+ return NULL;
+ }
+ switch (config.type) {
+ case BT_TRANSPORT_TYPE_RAW: {
+ transport = (struct HdfBtTransport *)CreateRawTransport(config.devName);
+ break;
+ }
+ case BT_TRANSPORT_TYPE_CUSTOM: {
+ transport = CreateCustomTransport(config.serviceName, node);
+ break;
+ }
+ default:
+ HDF_LOGE("%s:unexpected transport type %d", __func__, config.type);
+ }
+ return transport;
+}
+
+static int32_t InitDevice(const struct DeviceResourceNode *node) {
+ struct HdfChipConfig config = {0};
+ struct HdfVirtualDevice *device = NULL;
+ struct HdfBtTransport *transport = NULL;
+
+ int32_t ret = ParseChipConfig(node, &config);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:parse config failed!", __func__);
+ return ret;
+ }
+ do {
+ device = CreateVirtualDevice(&config);
+ if (device == NULL) {
+ HDF_LOGE("%s:Create virtual device failed!", __func__);
+ ret = HDF_FAILURE;
+ break;
+ }
+ transport = CreateTransport(node);
+ if (transport == NULL) {
+ HDF_LOGE("%s:Create transport failed!", __func__);
+ ret = HDF_FAILURE;
+ break;
+ }
+ ret = RegistBtDevice(device, transport);
+ } while (false);
+ if (ret != HDF_SUCCESS) {
+ if (device != NULL) {
+ ReleaseVirtualDevice(device);
+ device = NULL;
+ }
+ if (transport != NULL && transport->ops != NULL && transport->ops->Destory != NULL) {
+ transport->ops->Destory(transport);
+ }
+ transport = NULL;
+ }
+ ClearChipConfig(&config);
+ return ret;
+}
+
+static int32_t InitDevices(struct HdfDeviceObject *device) {
+ struct DeviceResourceIface *drsOps = NULL;
+ const struct DeviceResourceNode *devListNode = NULL;
+ struct DeviceResourceNode *childNode = NULL;
+ int32_t ret = HDF_SUCCESS;
+ if (device == NULL || device->property == NULL) {
+ HDF_LOGE("%s:nullptr!", __func__);
+ return HDF_FAILURE;
+ }
+
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetChildNode == NULL) {
+ HDF_LOGE("%s: invalid drs ops fail!", __func__);
+ return HDF_FAILURE;
+ }
+
+ devListNode = drsOps->GetChildNode(device->property, "deviceList");
+ if (devListNode == NULL) {
+ HDF_LOGW("%s:no device list defined!", __func__);
+ return HDF_SUCCESS;
+ }
+
+ DEV_RES_NODE_FOR_EACH_CHILD_NODE(devListNode, childNode) {
+ ret = InitDevice(childNode);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:init device %s failed!", __func__, childNode->name);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int32_t HdfBtChipDriverInit(struct HdfDeviceObject *device) {
+
+ int ret;
+ HDF_LOGV("%s:driver init...", __func__);
+
+ ret = InitDeivceList();
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:InitDeivceList failed!ret=%d", __func__, ret);
+ return ret;
+ }
+
+ ret = InitDevices(device);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:init devices failed!ret=%d", __func__, ret);
+ return ret;
+ }
+ return HDF_SUCCESS;
+};
+
+static void HdfBtChipDriverRelease(struct HdfDeviceObject *object) {
+ uint8_t i;
+ int ret = OsalSpinLockIrq(&g_devicesLock);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:lock failed!ret=%d", __func__, ret);
+ return;
+ }
+
+ for (i = g_deviceCount - 1; i >= 0; --i) {
+ g_deviceCount--;
+ if (g_btDevices[i].device != NULL) {
+ ReleaseVirtualDevice(g_btDevices[i].device);
+ g_btDevices[i].device = NULL;
+ }
+
+ if (g_btDevices[i].transport != NULL && g_btDevices[i].transport->ops != NULL &&
+ g_btDevices[i].transport->ops->Destory != NULL) {
+ g_btDevices[i].transport->ops->Destory(g_btDevices[i].transport);
+ }
+ g_btDevices[i].transport = NULL;
+ }
+
+ (void)OsalSpinUnlockIrq(&g_devicesLock);
+ return;
+}
+
+struct HdfDriverEntry g_hdfBTDriver = {
+ .moduleVersion = 1,
+ .Bind = HdfBtChipDriverBind,
+ .Init = HdfBtChipDriverInit,
+ .Release = HdfBtChipDriverRelease,
+ .moduleName = "HDF_BT",
+};
+
+HDF_INIT(g_hdfBTDriver);
diff --git a/model/network/bluetooth/hdf_chip.c b/model/network/bluetooth/hdf_chip.c
new file mode 100644
index 0000000000000000000000000000000000000000..e40daeb58b722459086582667957b4ab65d8ab83
--- /dev/null
+++ b/model/network/bluetooth/hdf_chip.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ *
+ * HDF is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ * See the LICENSE file in the root of this repository for complete details.
+ */
+
+#include "hdf_chip.h"
+#include "hdf_chip_config.h"
+#include "hdf_device_desc.h"
+#include "hdf_power.h"
+#include "hdf_reset.h"
+#include "osal/osal_mem.h"
+
+struct HdfVirtualDevice *CreateVirtualDevice(struct HdfChipConfig *config) {
+ struct HdfVirtualDevice *device = NULL;
+ int32_t ret = HDF_SUCCESS;
+ if (config == NULL) {
+ return NULL;
+ }
+ device = (struct HdfVirtualDevice *)OsalMemCalloc(sizeof(struct HdfVirtualDevice));
+ if (device == NULL) {
+ return NULL;
+ }
+ do {
+ device->name = config->name;
+
+ device->power = CreateVirtualPower(config->powers);
+ if (device->power == NULL) {
+ ret = HDF_FAILURE;
+ break;
+ }
+
+ device->reset = CreateVirtualReset(&config->reset);
+ if (device->reset == NULL) {
+ ret = HDF_FAILURE;
+ break;
+ }
+ } while (false);
+
+ if (ret != HDF_SUCCESS) {
+ ReleaseVirtualDevice(device);
+ device = NULL;
+ }
+ return device;
+}
+void ReleaseVirtualDevice(struct HdfVirtualDevice *device) {
+ if (device == NULL) {
+ return;
+ }
+ if (device->power != NULL && device->power->ops != NULL && device->power->ops->Release != NULL) {
+ device->power->ops->Release(device->power);
+ device->power = NULL;
+ }
+
+ if (device->reset != NULL && device->reset->ops != NULL && device->reset->ops->Release != NULL) {
+ device->reset->ops->Release(device->reset);
+ device->reset = NULL;
+ }
+ OsalMemFree(device);
+}
diff --git a/model/network/bluetooth/hdf_power.c b/model/network/bluetooth/hdf_power.c
new file mode 100644
index 0000000000000000000000000000000000000000..a27bcfde19209938964065239b52fb848bdb8ed6
--- /dev/null
+++ b/model/network/bluetooth/hdf_power.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ *
+ * HDF is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ * See the LICENSE file in the root of this repository for complete details.
+ */
+
+#include "hdf_power.h"
+#include "gpio_if.h"
+#include "hdf_base.h"
+#include "hdf_chip.h"
+#include "hdf_chip_config.h"
+
+#define MAX_POWER_COUNT 4
+
+struct NoManagablePower {
+ struct HdfPower base;
+ uint8_t powerSeqDelay;
+};
+
+struct GpioBasedPower {
+ struct HdfPower base;
+ uint8_t powerSeqDelay;
+ uint8_t gpioId;
+ uint8_t activeLevel;
+};
+
+struct MutiPowers {
+ struct HdfPower base;
+ uint8_t innerPowerCount;
+ struct HdfPower *powers[0];
+};
+
+static int32_t NotManagablePowerOn(struct HdfPower *power) {
+ (void)power;
+ return HDF_SUCCESS;
+}
+
+static int32_t NotManagablePowerOff(struct HdfPower *power) {
+ (void)power;
+ return HDF_FAILURE;
+}
+
+static void ReleasePower(struct HdfPower *power) {
+ if (power == NULL) {
+ return;
+ }
+ OsalMemFree(power);
+}
+
+static struct NoManagablePower *CreateNoManagablePower(const struct HdfPowerConfig *power) {
+ struct NoManagablePower *result = NULL;
+ static const struct HdfPowerOps notManagablePowerOps = {.On = NotManagablePowerOn,
+ .Off = NotManagablePowerOff,
+ .Release = ReleasePower};
+ result = (struct NoManagablePower *)OsalMemCalloc(sizeof(struct NoManagablePower));
+ if (result == NULL) {
+ return NULL;
+ }
+ result->base.ops = ¬ManagablePowerOps;
+ result->powerSeqDelay = power->powerSeqDelay;
+ return result;
+}
+
+static int32_t GpioPowerOn(struct HdfPower *power) {
+ int32_t ret;
+ struct GpioBasedPower *gpioPower = (struct GpioBasedPower *)power;
+ if (power == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return HDF_FAILURE;
+ }
+ ret = GpioSetDir(gpioPower->gpioId, 1);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:set dir fail! ret=%d\n", __func__, ret);
+ return HDF_FAILURE;
+ }
+ ret = GpioWrite(gpioPower->gpioId, gpioPower->activeLevel);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:set power on fail! ret=%d\n", __func__, ret);
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+static int32_t GpioPowerOff(struct HdfPower *power) {
+ int32_t ret;
+ struct GpioBasedPower *gpioPower = (struct GpioBasedPower *)power;
+ if (power == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return HDF_FAILURE;
+ }
+ ret = GpioSetDir(gpioPower->gpioId, 1);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:set dir fail! ret=%d\n", __func__, ret);
+ return HDF_FAILURE;
+ }
+ ret = GpioWrite(gpioPower->gpioId, !gpioPower->activeLevel);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s:set power on fail! ret=%d\n", __func__, ret);
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+static struct GpioBasedPower *CreateGpioBasedPower(const struct HdfPowerConfig *power) {
+ struct GpioBasedPower *result = NULL;
+ result = (struct GpioBasedPower *)OsalMemCalloc(sizeof(struct GpioBasedPower));
+ if (result == NULL) {
+ return NULL;
+ }
+ static const struct HdfPowerOps notManagablePowerOps = {.On = GpioPowerOn,
+ .Off = GpioPowerOff,
+ .Release = ReleasePower};
+ result->base.ops = ¬ManagablePowerOps;
+ result->powerSeqDelay = power->powerSeqDelay;
+ result->gpioId = power->gpio.gpioId;
+ result->activeLevel = power->gpio.activeLevel;
+ return result;
+}
+
+static struct HdfPower *CreatePower(const struct HdfPowerConfig *power) {
+ if (power == NULL) {
+ return NULL;
+ }
+ if (power->type == POWER_TYPE_ALWAYS_ON) {
+ return (struct HdfPower *)CreateNoManagablePower(power);
+ } else if (power->type == POWER_TYPE_GPIO) {
+ return (struct HdfPower *)CreateGpioBasedPower(power);
+ } else {
+ HDF_LOGE("%s:not supported power type %d", __func__, power->type);
+ return NULL;
+ }
+}
+
+static int32_t ActiveMutiPower(struct HdfPower *power) {
+ struct MutiPowers *mutiPower = (struct MutiPowers *)power;
+ int ret;
+ if (power == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return HDF_FAILURE;
+ }
+ for (uint8_t i = 0; i < mutiPower->innerPowerCount; i++) {
+ if (mutiPower->powers[i] == NULL || mutiPower->powers[i]->ops == NULL ||
+ mutiPower->powers[i]->ops->On == NULL) {
+ HDF_LOGW("%s:bad power!index=%d", __func__, i);
+ ret = HDF_FAILURE;
+ break;
+ }
+ if (i > 0) {
+ struct NoManagablePower *innerPower = (struct NoManagablePower *)mutiPower->powers[i];
+ OsalMSleep(innerPower->powerSeqDelay);
+ }
+ ret = mutiPower->powers[i]->ops->On(mutiPower->powers[i]);
+ if (ret != HDF_SUCCESS) {
+ break;
+ }
+ }
+ return ret;
+}
+
+static int32_t DeactiveMutiPower(struct HdfPower *power) {
+ struct MutiPowers *mutiPower = (struct MutiPowers *)power;
+ int ret;
+ if (power == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return HDF_FAILURE;
+ }
+ for (uint8_t i = 0; i < mutiPower->innerPowerCount; i++) {
+ if (mutiPower->powers[i] == NULL || mutiPower->powers[i]->ops == NULL ||
+ mutiPower->powers[i]->ops->Off == NULL) {
+ HDF_LOGW("%s:bad power!index=%d", __func__, i);
+ ret = HDF_FAILURE;
+ break;
+ }
+ ret = mutiPower->powers[i]->ops->Off(mutiPower->powers[i]);
+ if (ret != HDF_SUCCESS) {
+ break;
+ }
+ }
+ return ret;
+}
+
+static void ReleaseMutiPower(struct HdfPower *power) {
+ struct MutiPowers *mutiPower = (struct MutiPowers *)power;
+ if (power == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return;
+ }
+ for (uint8_t i = 0; i < mutiPower->innerPowerCount; i++) {
+ if (mutiPower->powers[i] == NULL || mutiPower->powers[i]->ops == NULL ||
+ mutiPower->powers[i]->ops->Release == NULL) {
+ HDF_LOGW("%s:bad power!index=%d", __func__, i);
+ } else {
+ mutiPower->powers[i]->ops->Release(mutiPower->powers[i]);
+ }
+ mutiPower->powers[i] = NULL;
+ }
+ OsalMemFree(power);
+}
+
+static struct MutiPowers *CreateMutiPower(const struct HdfPowersConfig *powersConfig) {
+ int ret = HDF_SUCCESS;
+ struct MutiPowers *mutiPower =
+ OsalMemCalloc(sizeof(struct MutiPowers) + sizeof(struct HdfPower *) * powersConfig->powerCount);
+ static const struct HdfPowerOps mutiPowerOps = {.On = ActiveMutiPower,
+ .Off = DeactiveMutiPower,
+ .Release = ReleaseMutiPower};
+ for (uint8_t i = 0; i < powersConfig->powerCount; i++) {
+ mutiPower->powers[i] = CreatePower(powersConfig->power + i);
+ if (mutiPower->powers[i] == NULL) {
+ OsalMemFree(mutiPower);
+ ret = HDF_FAILURE;
+ break;
+ }
+ }
+ mutiPower->innerPowerCount = powersConfig->powerCount;
+ if (ret != HDF_SUCCESS) {
+ ReleaseMutiPower((struct HdfPower *)mutiPower);
+ return NULL;
+ }
+ mutiPower->base.ops = &mutiPowerOps;
+ return mutiPower;
+}
+
+struct HdfPower *CreateVirtualPower(const struct HdfPowersConfig *powers) {
+ if (powers == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return NULL;
+ }
+ if (powers->powerCount > MAX_POWER_COUNT) {
+ HDF_LOGE("%s:too many power in config!count=%d", __func__, powers->powerCount);
+ return NULL;
+ }
+ if (powers->powerCount == 1) {
+ return CreatePower(&powers->power[0]);
+ } else if (powers->powerCount > 1) {
+ return (struct HdfPower *)CreateMutiPower(powers);
+ } else {
+ return NULL;
+ }
+}
diff --git a/model/network/bluetooth/hdf_power.h b/model/network/bluetooth/hdf_power.h
new file mode 100644
index 0000000000000000000000000000000000000000..6fcca853785983669a3a5f0267d08ad2ae4ca779
--- /dev/null
+++ b/model/network/bluetooth/hdf_power.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ *
+ * HDF is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ * See the LICENSE file in the root of this repository for complete details.
+ */
+
+#ifndef HDF_POWER_H
+#define HDF_POWER_H
+#include "hdf_chip.h"
+
+struct HdfPower *CreateVirtualPower(const struct HdfPowersConfig *powers);
+
+#endif
\ No newline at end of file
diff --git a/model/network/bluetooth/hdf_reset.c b/model/network/bluetooth/hdf_reset.c
new file mode 100644
index 0000000000000000000000000000000000000000..7bf868d024df763b0976532101c8ed15b7886cb2
--- /dev/null
+++ b/model/network/bluetooth/hdf_reset.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ *
+ * HDF is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ * See the LICENSE file in the root of this repository for complete details.
+ */
+
+#include "hdf_reset.h"
+#include "gpio_if.h"
+#include "hdf_base.h"
+
+struct GpioBasedReset {
+ struct HdfReset base;
+ uint8_t resetHoldTime;
+ uint8_t gpioId;
+ uint8_t activeLevel;
+};
+
+int32_t ResetNoManagableReset(struct HdfReset *reset) {
+ (void)reset;
+ return HDF_FAILURE;
+}
+
+void ReleaseNoManagableReset(struct HdfReset *reset) {
+ if (reset != NULL) {
+ OsalMemFree(reset);
+ }
+}
+
+int32_t ResetGpioBasedReset(struct HdfReset *reset) {
+ int ret;
+ struct GpioBasedReset *gpioBasedReset = (struct GpioBasedReset *)reset;
+ if (reset == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return HDF_FAILURE;
+ }
+ ret = GpioSetDir(gpioBasedReset->gpioId, GPIO_DIR_OUT);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: set dir fail!", __func__);
+ return ret;
+ }
+ ret = GpioWrite(gpioBasedReset->gpioId, gpioBasedReset->activeLevel);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: write active fail! ret=%d", __func__, ret);
+ return ret;
+ }
+ OsalMSleep(gpioBasedReset->resetHoldTime);
+
+ ret = GpioWrite(gpioBasedReset->gpioId, !gpioBasedReset->activeLevel);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: write deactivate fail! ret=%d", __func__, ret);
+ return ret;
+ }
+ return ret;
+}
+
+void ReleaseGpioBasedReset(struct HdfReset *reset) {
+ if (reset != NULL) {
+ OsalMemFree(reset);
+ }
+}
+
+struct HdfReset *CreateVirtualReset(const struct HdfResetConfig *resetConfig) {
+ struct HdfReset *result = NULL;
+ if (resetConfig == NULL) {
+ HDF_LOGE("%s:nullptr", __func__);
+ return NULL;
+ }
+ if (resetConfig->resetType == RESET_TYPE_NOT_MANAGEABLE) {
+ const static struct HdfResetOps noManagableResetOps = {.Reset = ResetNoManagableReset,
+ .Release = ReleaseNoManagableReset};
+ result = (struct HdfReset *)OsalMemCalloc(sizeof(struct HdfReset));
+ result->ops = &noManagableResetOps;
+ } else if (resetConfig->resetType == RESET_TYPE_GPIO) {
+ const static struct HdfResetOps gpioBasedResetOps = {.Reset = ResetGpioBasedReset,
+ .Release = ReleaseGpioBasedReset};
+ struct GpioBasedReset *reset = (struct GpioBasedReset *)OsalMemCalloc(sizeof(struct GpioBasedReset));
+ reset->resetHoldTime = resetConfig->resetHoldTime;
+ reset->gpioId = resetConfig->gpio.gpioId;
+ reset->activeLevel = resetConfig->gpio.activeLevel;
+ reset->base.ops = &gpioBasedResetOps;
+ result = (struct HdfReset *)reset;
+ }
+ return result;
+}
\ No newline at end of file
diff --git a/model/network/bluetooth/hdf_reset.h b/model/network/bluetooth/hdf_reset.h
new file mode 100644
index 0000000000000000000000000000000000000000..9859140db08f8faf61d7ca1da70f0be4acdbd608
--- /dev/null
+++ b/model/network/bluetooth/hdf_reset.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ *
+ * HDF is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ * See the LICENSE file in the root of this repository for complete details.
+ */
+
+#ifndef HDF_RESET_H
+#define HDF_RESET_H
+#include "hdf_chip.h"
+#include "hdf_chip_config.h"
+
+struct HdfReset *CreateVirtualReset(const struct HdfResetConfig *powers);
+
+#endif
\ No newline at end of file