add bluetooth model

Change-Id: Ib020a8396299ad8e6957663574e8fb705e75c6a2
Signed-off-by: duxbbo  <duxiaobo@huawei.com>
This commit is contained in:
YOUR_NAME 2021-06-15 09:08:22 +00:00
parent 908e1296e9
commit 7625212fd7
9 changed files with 1401 additions and 0 deletions

View 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

View 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

View 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

View 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);

View 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);
}

View 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 = &notManagablePowerOps;
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 = &notManagablePowerOps;
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;
}
}

View 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

View 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;
}

View 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