wireless/bluetooth:add bt bridge codes
Signed-off-by: chengkai <chengkai@xiaomi.com>
This commit is contained in:
parent
b933ea63c4
commit
7a7b5e5779
@ -53,6 +53,12 @@ config BLUETOOTH_UART_DUMP
|
||||
|
||||
endif # BLUETOOTH_UART
|
||||
|
||||
config BLUETOOTH_BRIDGE
|
||||
bool "Bluetooth BT/BLE Dual Mode Bridge Driver"
|
||||
default n
|
||||
---help---
|
||||
Enable Bluetooth BT/BLE Dual Mode Bridge Driver.
|
||||
|
||||
config BLUETOOTH_NULL
|
||||
bool "NULL Bluetooth device"
|
||||
default n
|
||||
|
@ -40,6 +40,10 @@ CSRCS += bt_uart_bcm4343x.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BLUETOOTH_BRIDGE),y)
|
||||
CSRCS += bt_bridge.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BLUETOOTH_NULL),y)
|
||||
CSRCS += bt_null.c
|
||||
endif
|
||||
|
548
drivers/wireless/bluetooth/bt_bridge.c
Normal file
548
drivers/wireless/bluetooth/bt_bridge.c
Normal file
@ -0,0 +1,548 @@
|
||||
/****************************************************************************
|
||||
* drivers/wireless/bluetooth/bt_bridge.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <debug.h>
|
||||
#include <stdatomic.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/net/snoop.h>
|
||||
|
||||
#include <nuttx/wireless/bluetooth/bt_bridge.h>
|
||||
#include <nuttx/wireless/bluetooth/bt_driver.h>
|
||||
#include <nuttx/wireless/bluetooth/bt_ioctl.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BT_FILTER_CONN_COUNT 16
|
||||
#define BT_FILTER_OPCODE_COUNT 16
|
||||
|
||||
#define BT_FILTER_TYPE_BT 0
|
||||
#define BT_FILTER_TYPE_BLE 1
|
||||
#define BT_FILTER_TYPE_COUNT 2
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct bt_filter_s
|
||||
{
|
||||
int type;
|
||||
uint16_t opcode[BT_FILTER_OPCODE_COUNT];
|
||||
uint16_t handle[BT_FILTER_CONN_COUNT];
|
||||
};
|
||||
|
||||
struct bt_bridge_device_s
|
||||
{
|
||||
struct bt_driver_s driver;
|
||||
struct bt_filter_s filter;
|
||||
FAR struct bt_bridge_s *bridge;
|
||||
};
|
||||
|
||||
struct bt_bridge_s
|
||||
{
|
||||
struct bt_bridge_device_s device[BT_FILTER_TYPE_COUNT];
|
||||
FAR struct bt_driver_s *driver;
|
||||
uint8_t refs;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const uint8_t g_bt_filter_bt_evt_table[] =
|
||||
{
|
||||
BT_HCI_EVT_INQUIRY_COMPLETE,
|
||||
BT_HCI_EVT_CONN_COMPLETE,
|
||||
BT_HCI_EVT_CONN_REQUEST,
|
||||
BT_HCI_EVT_AUTH_COMPLETE,
|
||||
BT_HCI_EVT_REMOTE_NAME_REQ_COMPLETE,
|
||||
BT_HCI_EVT_REMOTE_FEATURES,
|
||||
BT_HCI_EVT_ROLE_CHANGE,
|
||||
BT_HCI_EVT_PIN_CODE_REQ,
|
||||
BT_HCI_EVT_LINK_KEY_NOTIFY,
|
||||
BT_HCI_EVT_LINK_KEY_REQ,
|
||||
BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI,
|
||||
BT_HCI_EVT_REMOTE_EXT_FEATURES,
|
||||
BT_HCI_EVT_SYNC_CONN_COMPLETE,
|
||||
BT_HCI_EVT_EXTENDED_INQUIRY_RESULT,
|
||||
BT_HCI_EVT_IO_CAPA_RESP,
|
||||
BT_HCI_EVT_IO_CAPA_REQ,
|
||||
BT_HCI_EVT_SSP_COMPLETE,
|
||||
BT_HCI_EVT_USER_CONFIRM_REQ,
|
||||
BT_HCI_EVT_USER_PASSKEY_REQ,
|
||||
BT_HCI_EVT_USER_PASSKEY_NOTIFY,
|
||||
BT_HCI_EVT_PAGE_SCAN_REP_MODE_CHNG,
|
||||
BT_HCI_EVT_CONN_PKT_TYPE_CHANGE,
|
||||
BT_HCI_EVT_READ_CLOCK_OFF_COMP,
|
||||
BT_HCI_EVT_MAX_SLOTS_CHANGED,
|
||||
BT_HCI_EVT_MODE_CHANGE,
|
||||
BT_HCI_EVT_QOS_SETUP_COMP,
|
||||
BT_HCI_EVT_LINK_SUPER_TOUT_CHANGED,
|
||||
};
|
||||
|
||||
static const uint8_t g_bt_filter_ble_evt_table[] =
|
||||
{
|
||||
BT_HCI_EVT_LE_META_EVENT,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static bool bt_filter_set(FAR uint16_t *array, int size, uint16_t old,
|
||||
uint16_t new, uint16_t mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (array[i] == old)
|
||||
{
|
||||
array[i] = new & mask;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool bt_filter_set_handle(FAR uint16_t *handle, int size,
|
||||
uint16_t old, uint16_t new)
|
||||
{
|
||||
return bt_filter_set(handle, size, old, new, 0xfff);
|
||||
}
|
||||
|
||||
static bool bt_filter_alloc_handle(FAR struct bt_filter_s *filter,
|
||||
uint16_t handle)
|
||||
{
|
||||
return bt_filter_set_handle(filter->handle, BT_FILTER_CONN_COUNT,
|
||||
0, handle);
|
||||
}
|
||||
|
||||
static bool bt_filter_free_handle(FAR struct bt_filter_s *filter,
|
||||
uint16_t handle)
|
||||
{
|
||||
return bt_filter_set_handle(filter->handle, BT_FILTER_CONN_COUNT,
|
||||
handle, 0);
|
||||
}
|
||||
|
||||
static bool bt_filter_has_handle(FAR struct bt_filter_s *filter,
|
||||
uint16_t handle)
|
||||
{
|
||||
return bt_filter_set_handle(filter->handle, BT_FILTER_CONN_COUNT,
|
||||
handle, handle);
|
||||
}
|
||||
|
||||
static bool bt_filter_set_opcode(FAR uint16_t *opcode, int size,
|
||||
uint16_t old, uint16_t new)
|
||||
{
|
||||
return bt_filter_set(opcode, size, old, new, 0xffff);
|
||||
}
|
||||
|
||||
static bool bt_filter_alloc_opcode(FAR struct bt_filter_s *filter,
|
||||
uint16_t opcode)
|
||||
{
|
||||
return bt_filter_set_opcode(filter->opcode, BT_FILTER_OPCODE_COUNT,
|
||||
0, opcode);
|
||||
}
|
||||
|
||||
static bool bt_filter_free_opcode(FAR struct bt_filter_s *filter,
|
||||
uint16_t opcode)
|
||||
{
|
||||
return bt_filter_set_opcode(filter->opcode, BT_FILTER_OPCODE_COUNT,
|
||||
opcode, 0);
|
||||
}
|
||||
|
||||
static bool bt_filter_can_recv(FAR struct bt_filter_s *filter,
|
||||
enum bt_buf_type_e type,
|
||||
FAR const uint8_t *buffer, size_t buflen)
|
||||
{
|
||||
FAR const uint8_t *evt_table;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
if (type == BT_EVT)
|
||||
{
|
||||
if (filter->type == BT_FILTER_TYPE_BLE)
|
||||
{
|
||||
evt_table = g_bt_filter_bt_evt_table;
|
||||
size = sizeof(g_bt_filter_bt_evt_table);
|
||||
}
|
||||
else
|
||||
{
|
||||
evt_table = g_bt_filter_ble_evt_table;
|
||||
size = sizeof(g_bt_filter_ble_evt_table);
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (buffer[0] == evt_table[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (buffer[0])
|
||||
{
|
||||
case BT_HCI_EVT_LE_META_EVENT:
|
||||
if (buffer[2] == BT_HCI_EVT_LE_CONN_COMPLETE)
|
||||
{
|
||||
FAR struct bt_hci_evt_le_conn_complete_s *evt;
|
||||
|
||||
evt = (FAR void *)&buffer[3];
|
||||
if (evt->status == 0)
|
||||
{
|
||||
return bt_filter_alloc_handle(filter, evt->handle);
|
||||
}
|
||||
}
|
||||
else if (buffer[2] == BT_HCI_EVT_LE_ENH_CONN_COMPLETE)
|
||||
{
|
||||
FAR struct bt_hci_evt_le_enh_conn_complete_s *evt;
|
||||
|
||||
evt = (FAR void *)&buffer[3];
|
||||
if (evt->status == 0)
|
||||
{
|
||||
return bt_filter_alloc_handle(filter, evt->handle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BT_HCI_EVT_CONN_COMPLETE:
|
||||
{
|
||||
FAR struct bt_hci_evt_conn_complete_s *evt;
|
||||
|
||||
evt = (FAR void *)&buffer[2];
|
||||
if (evt->status == 0)
|
||||
{
|
||||
return bt_filter_alloc_handle(filter, evt->handle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
|
||||
{
|
||||
FAR struct bt_hci_evt_num_completed_packets_s *evt;
|
||||
|
||||
evt = (FAR void *)&buffer[2];
|
||||
return bt_filter_has_handle(filter, evt->h[0].handle);
|
||||
}
|
||||
break;
|
||||
case BT_HCI_EVT_REMOTE_VERSION_INFO:
|
||||
{
|
||||
FAR struct bt_hci_evt_remote_version_info_s *evt;
|
||||
|
||||
evt = (FAR void *)&buffer[2];
|
||||
return bt_filter_has_handle(filter, evt->handle);
|
||||
}
|
||||
break;
|
||||
case BT_HCI_EVT_ENCRYPT_CHANGE:
|
||||
{
|
||||
FAR struct bt_hci_evt_encrypt_change_s *evt;
|
||||
|
||||
evt = (FAR void *)&buffer[2];
|
||||
return bt_filter_has_handle(filter, evt->handle);
|
||||
}
|
||||
break;
|
||||
case BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE:
|
||||
{
|
||||
FAR struct bt_hci_evt_encrypt_key_refresh_complete_s *evt;
|
||||
|
||||
evt = (FAR void *)&buffer[2];
|
||||
return bt_filter_has_handle(filter, evt->handle);
|
||||
}
|
||||
break;
|
||||
case BT_HCI_EVT_DISCONN_COMPLETE:
|
||||
{
|
||||
FAR struct bt_hci_evt_disconn_complete_s *evt;
|
||||
|
||||
evt = (FAR void *)&buffer[2];
|
||||
return bt_filter_free_handle(filter, evt->handle);
|
||||
}
|
||||
break;
|
||||
case BT_HCI_EVT_CMD_COMPLETE:
|
||||
{
|
||||
FAR struct hci_evt_cmd_complete_s *evt;
|
||||
uint8_t ogf;
|
||||
|
||||
evt = (FAR void *)&buffer[2];
|
||||
ogf = evt->opcode >> 10;
|
||||
|
||||
if (BT_OGF_BASEBAND == ogf || BT_OGF_LINK_CTRL == ogf
|
||||
|| BT_OGF_INFO == ogf || BT_OGF_LE == ogf)
|
||||
{
|
||||
return bt_filter_free_opcode(filter, evt->opcode);
|
||||
}
|
||||
else if (BT_OGF_LINK_POLICY == ogf || BT_OGF_STATUS == ogf)
|
||||
{
|
||||
if (filter->type == BT_FILTER_TYPE_BLE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BT_HCI_EVT_CMD_STATUS:
|
||||
{
|
||||
FAR struct bt_hci_evt_cmd_status_s *stat;
|
||||
uint8_t ogf;
|
||||
|
||||
stat = (FAR void *)&buffer[2];
|
||||
ogf = stat->opcode >> 10;
|
||||
|
||||
if (BT_OGF_BASEBAND == ogf || BT_OGF_LINK_CTRL == ogf
|
||||
|| BT_OGF_INFO == ogf || BT_OGF_LE == ogf)
|
||||
{
|
||||
return bt_filter_free_opcode(filter, stat->opcode);
|
||||
}
|
||||
|
||||
if (BT_OGF_LINK_POLICY == ogf || BT_OGF_STATUS == ogf)
|
||||
{
|
||||
if (filter->type == BT_FILTER_TYPE_BLE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (type == BT_ACL_IN)
|
||||
{
|
||||
FAR struct bt_hci_acl_hdr_s *acl = (FAR void *)&buffer[0];
|
||||
|
||||
return bt_filter_has_handle(filter, acl->handle);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool bt_filter_can_send(FAR struct bt_filter_s *filter,
|
||||
enum bt_buf_type_e type,
|
||||
FAR uint8_t *buffer, size_t buflen)
|
||||
{
|
||||
uint16_t opcode;
|
||||
uint8_t ogf;
|
||||
int i;
|
||||
|
||||
if (type == BT_CMD)
|
||||
{
|
||||
opcode = (uint16_t)buffer[1] << 8 | (uint16_t)buffer[0];
|
||||
ogf = buffer[1] >> 2;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case BT_HCI_OP_SET_EVENT_MASK:
|
||||
{
|
||||
/* Override the all event bits roughly to avoid the
|
||||
* bt/ble host specific mask deliver to controller.
|
||||
*/
|
||||
|
||||
memset(&buffer[3], 0xff, 7);
|
||||
buffer[10] = 0x3f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (BT_OGF_BASEBAND == ogf || BT_OGF_LINK_CTRL == ogf
|
||||
|| BT_OGF_INFO == ogf || BT_OGF_LE == ogf)
|
||||
{
|
||||
if (!bt_filter_alloc_opcode(filter, opcode))
|
||||
{
|
||||
nerr("Unable to set opcode 0x%04x.\n", opcode);
|
||||
|
||||
for (i = 0; i < BT_FILTER_OPCODE_COUNT; i++)
|
||||
{
|
||||
nerr("PENDING opcode: %04x.\n", filter->opcode[i]);
|
||||
}
|
||||
|
||||
memset(filter->opcode, 0, sizeof(filter->opcode));
|
||||
|
||||
bt_filter_alloc_opcode(filter, opcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int bt_bridge_open(FAR struct bt_driver_s *drv)
|
||||
{
|
||||
FAR struct bt_bridge_device_s *device =
|
||||
(FAR struct bt_bridge_device_s *)drv;
|
||||
FAR struct bt_bridge_s *bridge = device->bridge;
|
||||
FAR struct bt_driver_s *driver = bridge->driver;
|
||||
|
||||
if (atomic_fetch_add(&bridge->refs, 1) == 0)
|
||||
{
|
||||
int ret = driver->open(driver);
|
||||
if (ret < 0)
|
||||
{
|
||||
atomic_fetch_sub(&bridge->refs, 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int bt_bridge_send(FAR struct bt_driver_s *drv,
|
||||
enum bt_buf_type_e type,
|
||||
FAR void *data, size_t len)
|
||||
{
|
||||
FAR struct bt_bridge_device_s *device =
|
||||
(FAR struct bt_bridge_device_s *)drv;
|
||||
FAR struct bt_bridge_s *bridge = device->bridge;
|
||||
FAR struct bt_driver_s *driver = bridge->driver;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
if (bt_filter_can_send(&device->filter, type, data, len))
|
||||
{
|
||||
leave_critical_section(flags);
|
||||
return driver->send(driver, type, data, len);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bt_bridge_close(FAR struct bt_driver_s *drv)
|
||||
{
|
||||
FAR struct bt_bridge_device_s *device =
|
||||
(FAR struct bt_bridge_device_s *)drv;
|
||||
FAR struct bt_bridge_s *bridge = device->bridge;
|
||||
FAR struct bt_driver_s *driver = bridge->driver;
|
||||
|
||||
if (atomic_fetch_sub(&bridge->refs, 1) == 1)
|
||||
{
|
||||
driver->close(driver);
|
||||
};
|
||||
}
|
||||
|
||||
static int bt_bridge_receive(FAR struct bt_driver_s *drv,
|
||||
enum bt_buf_type_e type,
|
||||
FAR void *data, size_t len)
|
||||
{
|
||||
FAR struct bt_bridge_s *bridge = (FAR struct bt_bridge_s *)drv->priv;
|
||||
FAR struct bt_bridge_device_s *device;
|
||||
FAR struct bt_driver_s *driver;
|
||||
irqstate_t flags;
|
||||
int i;
|
||||
|
||||
flags = enter_critical_section();
|
||||
for (i = 0; i < BT_FILTER_TYPE_COUNT; i++)
|
||||
{
|
||||
device = &bridge->device[i];
|
||||
driver = &device->driver;
|
||||
if (bt_filter_can_recv(&device->filter, type, data, len))
|
||||
{
|
||||
leave_critical_section(flags);
|
||||
return bt_netdev_receive(driver, type, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bt_bridge_ioctl(FAR struct bt_driver_s *drv, int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
FAR struct bt_bridge_device_s *device =
|
||||
(FAR struct bt_bridge_device_s *)drv;
|
||||
FAR struct bt_bridge_s *bridge = device->bridge;
|
||||
int ret;
|
||||
|
||||
|
||||
if (bridge->driver->ioctl)
|
||||
{
|
||||
ret = bridge->driver->ioctl(drv, cmd, arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENOTTY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bt_device_init(FAR struct bt_bridge_s *bridge,
|
||||
FAR struct bt_driver_s **drv, uint8_t type)
|
||||
{
|
||||
FAR struct bt_bridge_device_s *device = &bridge->device[type];
|
||||
FAR struct bt_driver_s *driver = &device->driver;
|
||||
|
||||
device->bridge = bridge;
|
||||
device->filter.type = type;
|
||||
|
||||
*drv = &device->driver;
|
||||
|
||||
driver->head_reserve = bridge->driver->head_reserve;
|
||||
driver->open = bt_bridge_open;
|
||||
driver->send = bt_bridge_send;
|
||||
driver->close = bt_bridge_close;
|
||||
driver->ioctl = bt_bridge_ioctl;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bt_bridge_register
|
||||
*
|
||||
* Description:
|
||||
* Register the Bluetooth BT/BLE dual mode bridge driver
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int bt_bridge_register(FAR struct bt_driver_s *hcidrv,
|
||||
FAR struct bt_driver_s **btdrv,
|
||||
FAR struct bt_driver_s **bledrv)
|
||||
{
|
||||
FAR struct bt_bridge_s *bridge;
|
||||
|
||||
if (!hcidrv || !btdrv || !bledrv)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bridge = (FAR struct bt_bridge_s *)kmm_zalloc(sizeof(struct bt_bridge_s));
|
||||
if (!bridge)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
bridge->driver = hcidrv;
|
||||
|
||||
hcidrv->receive = bt_bridge_receive;
|
||||
hcidrv->priv = bridge;
|
||||
|
||||
bt_device_init(bridge, btdrv, BT_FILTER_TYPE_BT);
|
||||
bt_device_init(bridge, bledrv, BT_FILTER_TYPE_BLE);
|
||||
|
||||
return OK;
|
||||
}
|
46
include/nuttx/wireless/bluetooth/bt_bridge.h
Normal file
46
include/nuttx/wireless/bluetooth/bt_bridge.h
Normal file
@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/wireless/bluetooth/bt_bridge.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_WIRELESS_BLUETOOTH_BT_BRIDGE_H
|
||||
#define __INCLUDE_NUTTX_WIRELESS_BLUETOOTH_BT_BRIDGE_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/wireless/bluetooth/bt_driver.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bt_bridge_register
|
||||
*
|
||||
* Description:
|
||||
* Register the Bluetooth BT/BLE dual mode bridge driver
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int bt_bridge_register(FAR struct bt_driver_s *hcidrv,
|
||||
FAR struct bt_driver_s **btdrv,
|
||||
FAR struct bt_driver_s **bledrv);
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_WIRELESS_BLUETOOTH_BT_BRIDGE_H */
|
Loading…
Reference in New Issue
Block a user