add l2cap api

This commit is contained in:
xiongweichao 2022-04-21 11:45:55 +08:00 committed by BOT
parent 2042840974
commit 4719db7047
15 changed files with 1815 additions and 60 deletions

View File

@ -113,6 +113,7 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/api/esp_hf_ag_api.c"
"host/bluedroid/api/esp_hf_client_api.c"
"host/bluedroid/api/esp_spp_api.c"
"host/bluedroid/api/esp_l2cap_bt_api.c"
"host/bluedroid/bta/ar/bta_ar.c"
"host/bluedroid/bta/av/bta_av_aact.c"
"host/bluedroid/bta/av/bta_av_act.c"
@ -214,6 +215,7 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/btc/profile/std/gatt/btc_gattc.c"
"host/bluedroid/btc/profile/std/gatt/btc_gatts.c"
"host/bluedroid/btc/profile/std/spp/btc_spp.c"
"host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c"
"host/bluedroid/device/bdaddr.c"
"host/bluedroid/device/controller.c"
"host/bluedroid/device/interop.c"

View File

@ -39,6 +39,9 @@
#if (BTC_SPP_INCLUDED == TRUE)
#include "btc_spp.h"
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
#if (BTC_L2CAP_INCLUDED == TRUE)
#include "btc_l2cap.h"
#endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */
#if BTC_HF_INCLUDED
#include "btc_hf_ag.h"
#endif/* #if BTC_HF_INCLUDED */
@ -112,6 +115,9 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
#if (BTC_SPP_INCLUDED == TRUE)
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
#if (BTC_L2CAP_INCLUDED == TRUE)
[BTC_PID_L2CAP] = {btc_l2cap_call_handler, btc_l2cap_cb_handler },
#endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */
#if BTC_HF_INCLUDED
[BTC_PID_HF] = {btc_hf_call_handler, btc_hf_cb_handler},
#endif /* #if BTC_HF_INCLUDED */

View File

@ -59,6 +59,7 @@ typedef enum {
BTC_PID_SPP,
BTC_PID_HD,
BTC_PID_HH,
BTC_PID_L2CAP,
#if (BTC_HF_INCLUDED == TRUE)
BTC_PID_HF,
#endif /* BTC_HF_INCLUDED */

View File

@ -61,6 +61,14 @@ config BT_SPP_ENABLED
help
This enables the Serial Port Profile
config BT_L2CAP_ENABLED
bool "BT L2CAP"
depends on BT_CLASSIC_ENABLED
default n
help
This enables the Logical Link Control and Adaptation Layer Protocol.
Only supported classic bluetooth.
config BT_HFP_ENABLE
bool "Hands Free/Handset Profile"
depends on BT_CLASSIC_ENABLED

View File

@ -0,0 +1,131 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "esp_bt_main.h"
#include "btc/btc_manage.h"
#include "btc_l2cap.h"
#include "esp_l2cap_bt_api.h"
#include "common/bt_target.h"
#if (defined BTC_L2CAP_INCLUDED && BTC_L2CAP_INCLUDED == TRUE)
esp_err_t esp_bt_l2cap_register_callback(esp_bt_l2cap_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (callback == NULL) {
return ESP_FAIL;
}
btc_profile_cb_set(BTC_PID_L2CAP, callback);
return ESP_OK;
}
esp_err_t esp_bt_l2cap_init(void)
{
btc_msg_t msg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_L2CAP;
msg.act = BTC_L2CAP_ACT_INIT;
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_bt_l2cap_deinit(void)
{
btc_msg_t msg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_L2CAP;
msg.act = BTC_L2CAP_ACT_UNINIT;
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_bt_l2cap_connect(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t remote_psm, esp_bd_addr_t peer_bd_addr)
{
btc_msg_t msg;
btc_l2cap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_L2CAP;
msg.act = BTC_L2CAP_ACT_CONNECT;
arg.connect.sec_mask = (cntl_flag & 0xffff);
arg.connect.remote_psm = remote_psm;
memcpy(arg.connect.peer_bd_addr, peer_bd_addr, ESP_BD_ADDR_LEN);
return (btc_transfer_context(&msg, &arg, sizeof(btc_l2cap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_bt_l2cap_start_srv(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t local_psm)
{
btc_msg_t msg;
btc_l2cap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_L2CAP;
msg.act = BTC_L2CAP_ACT_START_SRV;
arg.start_srv.sec_mask = (cntl_flag & 0xffff);
arg.start_srv.local_psm = local_psm;
return (btc_transfer_context(&msg, &arg, sizeof(btc_l2cap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_bt_l2cap_stop_all_srv(void)
{
btc_msg_t msg;
btc_l2cap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_L2CAP;
msg.act = BTC_L2CAP_ACT_STOP_SRV;
arg.stop_srv.psm = BTC_L2CAP_INVALID_PSM;
return (btc_transfer_context(&msg, &arg, sizeof(btc_l2cap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm)
{
btc_msg_t msg;
btc_l2cap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_L2CAP;
msg.act = BTC_L2CAP_ACT_STOP_SRV;
arg.stop_srv.psm = local_psm;
return (btc_transfer_context(&msg, &arg, sizeof(btc_l2cap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_bt_l2cap_vfs_register(void)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return btc_l2cap_vfs_register();
}
esp_err_t esp_bt_l2cap_vfs_unregister(void)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return btc_l2cap_vfs_unregister();
}
#endif ///defined BTC_L2CAP_INCLUDED && BTC_L2CAP_INCLUDED == TRUE

View File

@ -0,0 +1,251 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_L2CAP_BT_API_H__
#define __ESP_L2CAP_BT_API_H__
#include "esp_err.h"
#include "esp_bt_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief L2CAP operation success and failure codes
*/
typedef enum {
ESP_BT_L2CAP_SUCCESS = 0, /*!< Successful operation. */
ESP_BT_L2CAP_FAILURE, /*!< Generic failure. */
ESP_BT_L2CAP_BUSY, /*!< Temporarily can not handle this request. */
ESP_BT_L2CAP_NO_RESOURCE, /*!< No more resource */
ESP_BT_L2CAP_NEED_INIT, /*!< L2CAP module shall init first */
ESP_BT_L2CAP_NEED_DEINIT, /*!< L2CAP module shall deinit first */
ESP_BT_L2CAP_NO_CONNECTION, /*!< Connection may have been closed */
ESP_BT_L2CAP_NO_SERVER, /*!< No server */
} esp_bt_l2cap_status_t;
/**
* @brief Security Setting Mask. Use these three mask mode:
* 1. ESP_BT_L2CAP_SEC_NONE
* 2. ESP_BT_L2CAP_SEC_AUTHENTICATE
* 3. (ESP_BT_L2CAP_SEC_ENCRYPT|ESP_BT_L2CAP_SEC_AUTHENTICATE)
*/
#define ESP_BT_L2CAP_SEC_NONE 0x0000 /*!< No security */
#define ESP_BT_L2CAP_SEC_AUTHORIZE 0x0001 /*!< Authorization required */
#define ESP_BT_L2CAP_SEC_AUTHENTICATE 0x0012 /*!< Authentication required */
#define ESP_BT_L2CAP_SEC_ENCRYPT 0x0024 /*!< Encryption required */
typedef uint32_t esp_bt_l2cap_cntl_flags_t;
/**
* @brief L2CAP callback function events
*/
typedef enum {
ESP_BT_L2CAP_INIT_EVT = 0, /*!< When L2CAP is inited, the event comes */
ESP_BT_L2CAP_UNINIT_EVT = 1, /*!< When L2CAP is uninited, the event comes */
ESP_BT_L2CAP_OPEN_EVT = 16, /*!< When L2CAP Client connection open, the event comes */
ESP_BT_L2CAP_CLOSE_EVT = 17, /*!< When L2CAP connection closed, the event comes */
ESP_BT_L2CAP_START_EVT = 18, /*!< When L2CAP server started, the event comes */
ESP_BT_L2CAP_CL_INIT_EVT = 19, /*!< When L2CAP client initiated a connection, the event comes */
ESP_BT_L2CAP_SRV_STOP_EVT = 36, /*!< When L2CAP server stopped, the event comes */
} esp_bt_l2cap_cb_event_t;
/**
* @brief L2CAP callback parameters union
*/
typedef union {
/**
* @brief ESP_BT_L2CAP_INIT_EVT
*/
struct l2cap_init_evt_param {
esp_bt_l2cap_status_t status; /*!< status */
} init; /*!< L2CAP callback param of ESP_BT_L2CAP_INIT_EVT */
/**
* @brief ESP_BT_L2CAP_UNINIT_EVT
*/
struct l2cap_uninit_evt_param {
esp_bt_l2cap_status_t status; /*!< status */
} uninit; /*!< L2CAP callback param of ESP_BT_L2CAP_UNINIT_EVT */
/**
* @brief ESP_BT_L2CAP_OPEN_EVT
*/
struct l2cap_open_evt_param {
esp_bt_l2cap_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
int fd; /*!< File descriptor */
esp_bd_addr_t rem_bda; /*!< The peer address */
int32_t tx_mtu; /*!< The transmit MTU */
} open; /*!< L2CAP callback param of ESP_BT_L2CAP_OPEN_EVT */
/**
* @brief ESP_BT_L2CAP_CLOSE_EVT
*/
struct l2cap_close_evt_param {
esp_bt_l2cap_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
bool async; /*!< FALSE, if local initiates disconnect */
} close; /*!< L2CAP callback param of ESP_BT_L2CAP_CLOSE_EVT */
/**
* @brief ESP_BT_L2CAP_START_EVT
*/
struct l2cap_start_evt_param {
esp_bt_l2cap_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
uint8_t sec_id; /*!< security ID used by this server */
} start; /*!< L2CAP callback param of ESP_BT_L2CAP_START_EVT */
/**
* @brief ESP_BT_L2CAP_CL_INIT_EVT
*/
struct l2cap_cl_init_evt_param {
esp_bt_l2cap_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
uint8_t sec_id; /*!< security ID used by this server */
} cl_init; /*!< L2CAP callback param of ESP_BT_L2CAP_CL_INIT_EVT */
/**
* @brief ESP_BT_L2CAP_SRV_STOP_EVT
*/
struct l2cap_srv_stop_evt_param {
esp_bt_l2cap_status_t status; /*!< status */
uint8_t psm; /*!< local psm */
} srv_stop; /*!< L2CAP callback param of ESP_BT_L2CAP_SRV_STOP_EVT */
} esp_bt_l2cap_cb_param_t;
/**
* @brief L2CAP callback function type.
*
* @param event: Event type
* @param param: Point to callback parameter, currently is union type
*/
typedef void (* esp_bt_l2cap_cb_t)(esp_bt_l2cap_cb_event_t event, esp_bt_l2cap_cb_param_t *param);
/**
* @brief This function is called to init callbacks with L2CAP module.
*
* @param[in] callback: pointer to the init callback function.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_bt_l2cap_register_callback(esp_bt_l2cap_cb_t callback);
/**
* @brief This function is called to init L2CAP module.
* When the operation is completed, the callback function will be called with ESP_BT_L2CAP_INIT_EVT.
* This function should be called after esp_bluedroid_enable() completes successfully.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_bt_l2cap_init(void);
/**
* @brief This function is called to uninit l2cap module.
* The operation will close all active L2CAP connection first, then the callback function will be called
* with ESP_BT_L2CAP_CLOSE_EVT, and the number of ESP_BT_L2CAP_CLOSE_EVT is equal to the number of connection.
* When the operation is completed, the callback function will be called with ESP_BT_L2CAP_UNINIT_EVT.
* This function should be called after esp_bt_l2cap_init() completes successfully.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_bt_l2cap_deinit(void);
/**
* @brief This function makes an L2CAP connection to a remote BD Address.
* When the connection is initiated or failed to initiate, the callback is called with ESP_BT_L2CAP_CL_INIT_EVT.
* When the connection is established or failed, the callback is called with ESP_BT_L2CAP_OPEN_EVT.
* This funciton must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit().
*
* @param[in] cntl_flag: Lower 16-bit security settings mask.
* @param[in] remote_psm: Remote device bluetooth Profile PSM.
* @param[in] peer_bd_addr: Remote device bluetooth device address.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_bt_l2cap_connect(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t remote_psm, esp_bd_addr_t peer_bd_addr);
/**
* @brief This function create a L2CAP server and starts listening for an
* L2CAP connection request from a remote Bluetooth device.
* When the server is started successfully, the callback is called with ESP_BT_L2CAP_START_EVT.
* When the connection is established, the callback is called with ESP_BT_L2CAP_OPEN_EVT.
* This funciton must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit().
*
* @param[in] cntl_flag: Lower 16-bit security settings mask.
* @param[in] local_psm: Dynamic PSM.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_bt_l2cap_start_srv(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t local_psm);
/**
* @brief This function stops all L2CAP servers.
* The operation will close all active L2CAP connection first, then the callback function will be called
* with ESP_BT_L2CAP_CLOSE_EVT, and the number of ESP_BT_L2CAP_CLOSE_EVT is equal to the number of connection.
* When the operation is completed, the callback is called with ESP_BT_L2CAP_SRV_STOP_EVT.
* This funciton must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit().
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_bt_l2cap_stop_all_srv(void);
/**
* @brief This function stops a specific L2CAP server.
* The operation will close all active L2CAP connection first on the specific L2CAP server, then the callback function will
* be called with ESP_BT_L2CAP_CLOSE_EVT, and the number of ESP_BT_L2CAP_CLOSE_EVT is equal to the number of connection.
* When the operation is completed, the callback is called with ESP_BT_L2CAP_SRV_STOP_EVT.
* This funciton must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit().
*
* @param[in] local_psm: Dynamic PSM.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm);
/**
* @brief This function is used to register VFS.
* Only supports write, read and close.
* This funciton must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit().
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_bt_l2cap_vfs_register(void);
/**
* @brief This function is used to unregister VFS.
* This funciton must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit().
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_bt_l2cap_vfs_unregister(void);
#ifdef __cplusplus
}
#endif
#endif ///__ESP_L2CAP_BT_API_H__

View File

@ -42,6 +42,7 @@
#define BTA_JV_BUSY 2 /* Temporarily can not handle this request. */
#define BTA_JV_NO_DATA 3 /* no data. */
#define BTA_JV_NO_RESOURCE 4 /* No more set pm control block */
#define BTA_JV_ALREADY_DONE 5 /* already done, repeat the operation */
typedef UINT8 tBTA_JV_STATUS;
#define BTA_JV_INTERNAL_ERR (-1) /* internal error. */
@ -198,6 +199,7 @@ typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
BOOLEAN async; /* FALSE, if local initiates disconnect */
void * user_data; /* piggyback caller's private data */
} tBTA_JV_L2CAP_CLOSE;
/* data associated with BTA_JV_L2CAP_START_EVT */
@ -428,7 +430,7 @@ typedef void *(tBTA_JV_RFCOMM_CBACK)(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
#if BTA_JV_L2CAP_INCLUDED
/* JAVA L2CAP interface callback */
typedef void (tBTA_JV_L2CAP_CBACK)(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_Data);
typedef void *(tBTA_JV_L2CAP_CBACK)(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_Data);
#endif /* BTA_JV_L2CAP_INCLUDED */
/* JV configuration structure */
@ -636,7 +638,7 @@ extern tBTA_JV_STATUS BTA_JvL2capConnect(tBTA_SEC sec_mask, tBTA_JV_ROLE role,
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capClose(UINT32 handle);
extern tBTA_JV_STATUS BTA_JvL2capClose(UINT32 handle, tBTA_JV_L2CAP_CBACK *p_cback, void *user_data);
/*******************************************************************************
**
@ -724,12 +726,10 @@ extern tBTA_JV_STATUS BTA_JvL2capStopServer(UINT16 local_psm, void *user_data);
** When the operation is complete, tBTA_JV_L2CAP_CBACK is
** called with BTA_JV_L2CAP_READ_EVT.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
** Returns Length of read data.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capRead(UINT32 handle, UINT32 req_id,
UINT8 *p_data, UINT16 len);
extern int BTA_JvL2capRead(UINT32 handle, UINT32 req_id, UINT8 *p_data, UINT16 len);
/*******************************************************************************
**

View File

@ -865,10 +865,25 @@ void bta_jv_free_scn(tBTA_JV_MSG *p_data)
bta_jv_cb.scn[scn - 1] = FALSE;
BTM_FreeSCN(scn);
}
if (fc->user_data) {
user_data = (tBTA_JV_FREE_SCN_USER_DATA *)fc->user_data;
evt_data.server_status = user_data->server_status;
if (user_data->server_status == BTA_JV_SERVER_RUNNING && find_rfc_pcb((void *)user_data->slot_id, &p_cb, &p_pcb)) {
/* if call bta_jv_rfcomm_stop_server successfully, find_rfc_pcb shall return false */
evt_data.status = BTA_JV_FAILURE;
}
if (fc->p_cback) {
fc->p_cback(BTA_JV_FREE_SCN_EVT, (tBTA_JV *)&evt_data, (void *)user_data);
}
}
break;
}
case BTA_JV_CONN_TYPE_L2CAP:
bta_jv_set_free_psm(scn);
if (fc->p_cback) {
fc->p_cback(BTA_JV_FREE_SCN_EVT, (tBTA_JV *)&evt_data, (void *)user_data);
}
break;
case BTA_JV_CONN_TYPE_L2CAP_LE:
// TODO: Not yet implemented...
@ -876,20 +891,6 @@ void bta_jv_free_scn(tBTA_JV_MSG *p_data)
default:
break;
}
if (fc->user_data)
{
user_data = (tBTA_JV_FREE_SCN_USER_DATA *)fc->user_data;
evt_data.server_status = user_data->server_status;
if (user_data->server_status == BTA_JV_SERVER_RUNNING && find_rfc_pcb((void *)user_data->slot_id, &p_cb, &p_pcb)) {
/* if call bta_jv_rfcomm_stop_server successfully, find_rfc_pcb shall return false */
evt_data.status = BTA_JV_FAILURE;
}
if (fc->p_cback) {
fc->p_cback(BTA_JV_FREE_SCN_EVT, (tBTA_JV *)&evt_data, (void *)user_data);
}
}
}
static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID *u)
{
@ -1271,7 +1272,7 @@ void bta_jv_l2cap_connect(tBTA_JV_MSG *p_data)
if (cc->has_cfg == TRUE) {
cfg = cc->cfg;
if (cfg.fcr_present && cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
chan_mode_mask = GAP_FCR_CHAN_OPT_ERTM;
chan_mode_mask |= GAP_FCR_CHAN_OPT_ERTM;
}
}
@ -1331,15 +1332,14 @@ void bta_jv_l2cap_close(tBTA_JV_MSG *p_data)
{
tBTA_JV_L2CAP_CLOSE evt_data;
tBTA_JV_API_L2CAP_CLOSE *cc = &(p_data->l2cap_close);
tBTA_JV_L2CAP_CBACK *p_cback = cc->p_cb->p_cback;
void *user_data = cc->p_cb->user_data;
void *user_data = cc->user_data;
evt_data.handle = cc->handle;
evt_data.status = bta_jv_free_l2c_cb(cc->p_cb);
evt_data.async = FALSE;
if (p_cback) {
p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data);
if (cc->p_cback) {
cc->p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data);
}
}
@ -1430,7 +1430,7 @@ void bta_jv_l2cap_start_server(tBTA_JV_MSG *p_data)
if (ls->has_cfg == TRUE) {
cfg = ls->cfg;
if (cfg.fcr_present && cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
chan_mode_mask = GAP_FCR_CHAN_OPT_ERTM;
chan_mode_mask |= GAP_FCR_CHAN_OPT_ERTM;
}
}
@ -2854,7 +2854,7 @@ void bta_jv_l2cap_connect_le(tBTA_JV_MSG *p_data)
id = t->id;
t->init_called = FALSE;
if (L2CA_ConnectFixedChnl(t->chan, t->remote_addr, BLE_ADDR_UNKNOWN_TYPE)) {
if (L2CA_ConnectFixedChnl(t->chan, t->remote_addr, BLE_ADDR_UNKNOWN_TYPE, FALSE)) {
evt.l2c_cl_init.status = BTA_JV_SUCCESS;
evt.l2c_cl_init.handle = id;

View File

@ -98,7 +98,7 @@ tBTA_JV_STATUS BTA_JvEnable(tBTA_JV_DM_CBACK *p_cback)
APPL_TRACE_ERROR("No p_cback.");
} else {
APPL_TRACE_WARNING("No need to Init again.");
// status = BTA_JV_SUCCESS;
status = BTA_JV_ALREADY_DONE;
}
return (status);
}
@ -467,7 +467,7 @@ tBTA_JV_STATUS BTA_JvL2capConnect(tBTA_SEC sec_mask, tBTA_JV_ROLE role,
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
tBTA_JV_STATUS BTA_JvL2capClose(UINT32 handle)
tBTA_JV_STATUS BTA_JvL2capClose(UINT32 handle, tBTA_JV_L2CAP_CBACK *p_cback, void *user_data)
{
tBTA_JV_STATUS status = BTA_JV_FAILURE;
tBTA_JV_API_L2CAP_CLOSE *p_msg;
@ -479,6 +479,8 @@ tBTA_JV_STATUS BTA_JvL2capClose(UINT32 handle)
p_msg->hdr.event = BTA_JV_API_L2CAP_CLOSE_EVT;
p_msg->handle = handle;
p_msg->p_cb = &bta_jv_cb.l2c_cb[handle];
p_msg->p_cback = p_cback;
p_msg->user_data = user_data;
bta_sys_sendmsg(p_msg);
status = BTA_JV_SUCCESS;
}
@ -684,20 +686,16 @@ on
** When the operation is complete, tBTA_JV_L2CAP_CBACK is
** called with BTA_JV_L2CAP_READ_EVT.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
** Returns Length of read data.
**
*******************************************************************************/
tBTA_JV_STATUS BTA_JvL2capRead(UINT32 handle, UINT32 req_id, UINT8 *p_data, UINT16 len)
int BTA_JvL2capRead(UINT32 handle, UINT32 req_id, UINT8 *p_data, UINT16 len)
{
tBTA_JV_STATUS status = BTA_JV_FAILURE;
tBTA_JV_L2CAP_READ evt_data;
APPL_TRACE_API( "%s", __func__);
if (handle < BTA_JV_MAX_L2C_CONN && bta_jv_cb.l2c_cb[handle].p_cback) {
status = BTA_JV_SUCCESS;
evt_data.status = BTA_JV_FAILURE;
evt_data.handle = handle;
evt_data.req_id = req_id;
@ -711,7 +709,7 @@ tBTA_JV_STATUS BTA_JvL2capRead(UINT32 handle, UINT32 req_id, UINT8 *p_data, UINT
BTA_JV_L2CAP_READ_EVT, (tBTA_JV *)&evt_data, bta_jv_cb.l2c_cb[handle].user_data);
}
return (status);
return (evt_data.len);
}
/*******************************************************************************

View File

@ -213,6 +213,8 @@ typedef struct {
BT_HDR hdr;
UINT32 handle;
tBTA_JV_L2C_CB *p_cb;
tBTA_JV_L2CAP_CBACK *p_cback;
void *user_data;
} tBTA_JV_API_L2CAP_CLOSE;
/* data type for BTA_JV_API_L2CAP_READ_EVT */

View File

@ -0,0 +1,72 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BTC_L2CAP_H__
#define __BTC_L2CAP_H__
#include "btc/btc_task.h"
#include "esp_bt_defs.h"
#include "esp_l2cap_bt_api.h"
#include "common/bt_target.h"
#include "bta/bta_jv_api.h"
#if (defined BTC_L2CAP_INCLUDED && BTC_L2CAP_INCLUDED == TRUE)
#define BTC_L2CAP_INVALID_PSM 0x00
typedef enum {
BTC_L2CAP_ACT_INIT = 0,
BTC_L2CAP_ACT_UNINIT,
BTC_L2CAP_ACT_START_DISCOVERY,
BTC_L2CAP_ACT_CONNECT,
BTC_L2CAP_ACT_START_SRV,
BTC_L2CAP_ACT_STOP_SRV,
} btc_l2cap_act_t;
/* btc_l2cap_args_t */
typedef union {
//BTC_L2CAP_ACT_INIT
struct l2cap_init_arg {
} init;
//BTC_L2CAP_ACT_UNINIT
struct l2cap_uninit_arg {
} uninit;
//BTC_L2CAP_ACT_START_DISCOVERY
struct l2cap_start_discovery_arg {
BD_ADDR bd_addr;
UINT16 num_uuid;
tSDP_UUID *p_uuid_list;
} start_discovery;
//BTC_L2CAP_ACT_CONNECT
struct l2cap_connect_arg {
UINT16 sec_mask;
UINT16 remote_psm;
esp_bd_addr_t peer_bd_addr;
} connect;
//BTC_L2CAP_ACT_START_SRV
struct l2cap_start_srv_arg {
UINT16 sec_mask;
UINT16 local_psm;
} start_srv;
//BTC_L2CAP_ACT_STOP_SRV
struct l2cap_stop_srv_arg {
UINT16 psm;
} stop_srv;
} btc_l2cap_args_t;
void btc_l2cap_call_handler(btc_msg_t *msg);
void btc_l2cap_cb_handler(btc_msg_t *msg);
esp_err_t btc_l2cap_vfs_register(void);
esp_err_t btc_l2cap_vfs_unregister(void);
#endif ///defined BTC_L2CAP_INCLUDED && BTC_L2CAP_INCLUDED == TRUE
#endif ///__BTC_L2CAP_H__

File diff suppressed because it is too large Load Diff

View File

@ -106,7 +106,7 @@ static int init_slot_data(slot_data_t *slot_data, size_t queue_size)
return 0;
}
void free_slot_data(slot_data_t *slot_data)
static void free_slot_data(slot_data_t *slot_data)
{
fixed_queue_free(slot_data->queue, spp_osi_free);
slot_data->queue = NULL;

View File

@ -45,6 +45,13 @@
#define UC_BT_SPP_ENABLED FALSE
#endif
//L2CAP
#ifdef CONFIG_BT_L2CAP_ENABLED
#define UC_BT_L2CAP_ENABLED CONFIG_BT_L2CAP_ENABLED
#else
#define UC_BT_L2CAP_ENABLED FALSE
#endif
//HFP(AG)
#ifdef CONFIG_BT_HFP_AG_ENABLE
#define UC_BT_HFP_AG_ENABLED CONFIG_BT_HFP_AG_ENABLE

View File

@ -83,6 +83,13 @@
#define BTC_SPP_INCLUDED TRUE
#endif /* UC_BT_SPP_ENABLED */
#if (UC_BT_L2CAP_ENABLED == TRUE)
#define BTA_JV_INCLUDED TRUE
#define RFCOMM_INCLUDED TRUE
#define BTC_L2CAP_INCLUDED TRUE
#define VND_BT_JV_BTA_L2CAP TRUE
#endif /* UC_BT_L2CAP_ENABLED */
#if (UC_BT_HFP_AG_ENABLED == TRUE)
#define BTC_HF_INCLUDED TRUE
#define BTA_AG_INCLUDED TRUE
@ -1594,51 +1601,88 @@
#define OBX_FCR_TX_BUF_SIZE BT_DEFAULT_BUFFER_SIZE
#endif
/* This option is application when OBX_14_INCLUDED=TRUE
Size of the transmission window when using enhanced retransmission mode. Not used
in basic and streaming modes. Range: 1 - 63
*/
/*
* Size of the transmission window when using enhanced retransmission mode. Not used
* in basic and streaming modes. Range: 1 - 63
*/
#ifndef OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR
#define OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR 20
#endif
/* This option is application when OBX_14_INCLUDED=TRUE
Number of transmission attempts for a single I-Frame before taking
Down the connection. Used In ERTM mode only. Value is Ignored in basic and
Streaming modes.
Range: 0, 1-0xFF
0 - infinite retransmissions
1 - single transmission
*/
/*
* Number of transmission attempts for a single I-Frame before taking
* Down the connection. Used In ERTM mode only. Value is Ignored in basic and
* Streaming modes.
* Range: 0, 1-0xFF
* 0 - infinite retransmissions
* 1 - single transmission
*/
#ifndef OBX_FCR_OPT_MAX_TX_B4_DISCNT
#define OBX_FCR_OPT_MAX_TX_B4_DISCNT 20
#endif
/* This option is application when OBX_14_INCLUDED=TRUE
Retransmission Timeout
Range: Minimum 2000 (2 secs) on BR/EDR when supporting PBF.
/*
* Retransmission Timeout
* Range: Minimum 2000 (2 secs) on BR/EDR when supporting PBF.
*/
#ifndef OBX_FCR_OPT_RETX_TOUT
#define OBX_FCR_OPT_RETX_TOUT 2000
#endif
/* This option is application when OBX_14_INCLUDED=TRUE
Monitor Timeout
Range: Minimum 12000 (12 secs) on BR/EDR when supporting PBF.
*/
/*
* Monitor Timeout
* Range: Minimum 12000 (12 secs) on BR/EDR when supporting PBF.
*/
#ifndef OBX_FCR_OPT_MONITOR_TOUT
#define OBX_FCR_OPT_MONITOR_TOUT 12000
#endif
/* This option is application when OBX_14_INCLUDED=TRUE
Maximum PDU payload size.
Suggestion: The maximum amount of data that will fit into a 3-DH5 packet.
Range: 2 octets
/*
* Maximum PDU payload size.
* Suggestion: The maximum amount of data that will fit into a 3-DH5 packet.
* Range: 2 octets
*/
#ifndef OBX_FCR_OPT_MAX_PDU_SIZE
#define OBX_FCR_OPT_MAX_PDU_SIZE L2CAP_MPS_OVER_BR_EDR
#endif
/*
* Pool ID where to reassemble the SDU.
* This Pool will allow buffers to be used that are larger than
* the L2CAP_MAX_MTU.
*/
#ifndef OBX_USER_RX_POOL_ID
#define OBX_USER_RX_POOL_ID 4
#endif
/*
* Pool ID where to hold the SDU.
* This Pool will allow buffers to be used that are larger than
* the L2CAP_MAX_MTU.
*/
#ifndef OBX_USER_TX_POOL_ID
#define OBX_USER_TX_POOL_ID 4
#endif
/*
* GKI Buffer Pool ID used to hold MPS segments during SDU reassembly
*/
#ifndef OBX_FCR_RX_POOL_ID
#define OBX_FCR_RX_POOL_ID 3
#endif
/*
* Pool ID used to hold MPS segments used in (re)transmissions.
* L2CAP_DEFAULT_ERM_POOL_ID is specified to use the HCI ACL data pool.
* Note: This pool needs to have enough buffers to hold two times the window size negotiated
* in the L2CA_SetFCROptions (2 * tx_win_size) to allow for retransmissions.
* The size of each buffer must be able to hold the maximum MPS segment size passed in
* L2CA_SetFCROptions plus BT_HDR (8) + HCI preamble (4) + L2CAP_MIN_OFFSET (11 - as of BT 2.1 + EDR Spec).
*/
#ifndef OBX_FCR_TX_POOL_ID
#define OBX_FCR_TX_POOL_ID 3
#endif
/******************************************************************************
**