mirror of
https://gitee.com/openharmony/drivers_framework
synced 2024-11-23 21:10:02 +00:00
add bluetooth model
Change-Id: Ib020a8396299ad8e6957663574e8fb705e75c6a2 Signed-off-by: duxbbo <duxiaobo@huawei.com>
This commit is contained in:
parent
908e1296e9
commit
7625212fd7
31
include/bluetooth/hdf_bt_transport.h
Normal file
31
include/bluetooth/hdf_bt_transport.h
Normal file
@ -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
|
153
include/bluetooth/hdf_chip.h
Normal file
153
include/bluetooth/hdf_chip.h
Normal file
@ -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 <b>0</b> 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 <b>0</b> 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 <b>0</b> 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
|
248
include/bluetooth/hdf_chip_config.h
Normal file
248
include/bluetooth/hdf_chip_config.h
Normal file
@ -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
|
548
model/network/bluetooth/hdf_bt_core.c
Normal file
548
model/network/bluetooth/hdf_bt_core.c
Normal file
@ -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);
|
62
model/network/bluetooth/hdf_chip.c
Normal file
62
model/network/bluetooth/hdf_chip.c
Normal file
@ -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);
|
||||
}
|
242
model/network/bluetooth/hdf_power.c
Normal file
242
model/network/bluetooth/hdf_power.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
15
model/network/bluetooth/hdf_power.h
Normal file
15
model/network/bluetooth/hdf_power.h
Normal file
@ -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
|
86
model/network/bluetooth/hdf_reset.c
Normal file
86
model/network/bluetooth/hdf_reset.c
Normal file
@ -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;
|
||||
}
|
16
model/network/bluetooth/hdf_reset.h
Normal file
16
model/network/bluetooth/hdf_reset.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user