Merge branch 'feature/btdm_bt_spp' into 'master'

component/bt: Add bt spp profile

See merge request !1593
This commit is contained in:
Jiang Jiang Jian 2018-01-09 10:44:46 +08:00
commit c147d7b03e
45 changed files with 7214 additions and 46 deletions

View File

@ -113,6 +113,20 @@ config CLASSIC_BT_ENABLED
help
For now this option needs "SMP_ENABLE" to be set to yes
config A2DP_SNK_ENABLED
bool "A2DP(SINK)"
depends on CLASSIC_BT_ENABLED
default n
help
This option is used to enable/disable Advanced Audio Distribution Profile(Sink)
config BT_SPP_ENABLED
bool "SPP Profile"
depends on CLASSIC_BT_ENABLED
default n
help
This enables the SPP Profile
config GATTS_ENABLE
bool "Include GATT server module(GATTS)"
depends on BLUEDROID_ENABLED

View File

@ -0,0 +1,169 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#include <string.h>
#include "esp_bt_main.h"
#include "btc_manage.h"
#include "btc_spp.h"
#include "esp_spp_api.h"
#include "bt_target.h"
#if (defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE)
static const uint8_t UUID_SPP[16] = {0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
};
static tSDP_UUID sdp_uuid;
esp_err_t esp_spp_register_callback(esp_spp_cb_t *callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (callback == NULL) {
return ESP_FAIL;
}
btc_profile_cb_set(BTC_PID_SPP, callback);
return ESP_OK;
}
esp_err_t esp_spp_init(esp_spp_mode_t mode)
{
btc_msg_t msg;
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (mode != ESP_SPP_MODE_CB) {
LOG_ERROR("%s Watch this space!", __func__);
return ESP_FAIL;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SPP;
msg.act = BTC_SPP_ACT_INIT;
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_spp_deinit()
{
btc_msg_t msg;
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SPP;
msg.act = BTC_SPP_ACT_UNINIT;
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr)
{
sdp_uuid.len = 16;
memcpy(sdp_uuid.uu.uuid128, UUID_SPP, sizeof(sdp_uuid.uu.uuid128));
btc_msg_t msg;
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SPP;
msg.act = BTC_SPP_ACT_START_DISCOVERY;
memcpy(arg.start_discovery.bd_addr, bd_addr, ESP_BD_ADDR_LEN);
arg.start_discovery.num_uuid = 1;
arg.start_discovery.p_uuid_list = &sdp_uuid;
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), btc_spp_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask,
esp_spp_role_t role, uint8_t remote_scn, esp_bd_addr_t peer_bd_addr)
{
btc_msg_t msg;
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SPP;
msg.act = BTC_SPP_ACT_CONNECT;
arg.connect.sec_mask = sec_mask;
arg.connect.role = role;
arg.connect.remote_scn = remote_scn;
memcpy(arg.connect.peer_bd_addr, peer_bd_addr, ESP_BD_ADDR_LEN);
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_spp_disconnect(uint32_t handle)
{
btc_msg_t msg;
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SPP;
msg.act = BTC_SPP_ACT_DISCONNECT;
arg.disconnect.handle = handle;
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask,
esp_spp_role_t role, uint8_t local_scn, const char *name)
{
btc_msg_t msg;
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (strlen(name) > ESP_SPP_SERVER_NAME_MAX) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SPP;
msg.act = BTC_SPP_ACT_START_SRV;
arg.start_srv.sec_mask = sec_mask;
arg.start_srv.role = role;
arg.start_srv.local_scn = local_scn;
arg.start_srv.max_session = ESP_SPP_MAX_SESSION;
strcpy(arg.start_srv.name, name);
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data)
{
btc_msg_t msg;
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SPP;
msg.act = BTC_SPP_ACT_WRITE;
arg.write.handle = handle;
arg.write.len = len;
arg.write.p_data = p_data;
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), btc_spp_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif ///defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE

View File

@ -0,0 +1,294 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 __ESP_SPP_API_H__
#define __ESP_SPP_API_H__
#include "esp_err.h"
#include "esp_bt_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ESP_SPP_SUCCESS = 0, /*!< Successful operation. */
ESP_SPP_FAILURE, /*!< Generic failure. */
ESP_SPP_BUSY, /*!< Temporarily can not handle this request. */
ESP_SPP_NO_DATA, /*!< no data. */
ESP_SPP_NO_RESOURCE /*!< No more set pm control block */
} esp_spp_status_t;
/* Security Setting Mask */
#define ESP_SPP_SEC_NONE 0x0000 /*!< No security. relate to BTA_SEC_NONE in bta_api.h */
#define ESP_SPP_SEC_AUTHORIZE 0x0001 /*!< Authorization required (only needed for out going connection ) relate to BTA_SEC_AUTHORIZE in bta_api.h*/
#define ESP_SPP_SEC_AUTHENTICATE 0x0012 /*!< Authentication required. relate to BTA_SEC_AUTHENTICATE in bta_api.h*/
#define ESP_SPP_SEC_ENCRYPT 0x0024 /*!< Encryption required. relate to BTA_SEC_ENCRYPT in bta_api.h*/
#define ESP_SPP_SEC_MODE4_LEVEL4 0x0040 /*!< Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption relate to BTA_SEC_MODE4_LEVEL4 in bta_api.h*/
#define ESP_SPP_SEC_MITM 0x3000 /*!< Man-In-The_Middle protection relate to BTA_SEC_MITM in bta_api.h*/
#define ESP_SPP_SEC_IN_16_DIGITS 0x4000 /*!< Min 16 digit for pin code relate to BTA_SEC_IN_16_DIGITS in bta_api.h*/
typedef uint16_t esp_spp_sec_t;
typedef enum {
ESP_SPP_ROLE_MASTER = 0, /*!< Role: master */
ESP_SPP_ROLE_SLAVE = 1, /*!< Role: slave */
} esp_spp_role_t;
typedef enum {
ESP_SPP_MODE_CB = 0, /*!< When data is coming, a callback will come with data */
ESP_SPP_MODE_VFS = 1, /*!< Use VFS to write/read data */
} esp_spp_mode_t;
#define ESP_SPP_MAX_MTU (3*330) /*!< SPP max MTU */
#define ESP_SPP_MAX_SCN 31 /*!< SPP max SCN */
/**
* @brief SPP callback function events
*/
typedef enum {
ESP_SPP_INIT_EVT = 0, /*!< When SPP is inited, the event comes */
ESP_SPP_DISCOVERY_COMP_EVT = 8, /*!< When SDP discovery complete, the event comes */
ESP_SPP_OPEN_EVT = 26, /*!< When SPP Client connection open, the event comes */
ESP_SPP_CLOSE_EVT = 27, /*!< When SPP connection closed, the event comes */
ESP_SPP_START_EVT = 28, /*!< When SPP server started, the event comes */
ESP_SPP_CL_INIT_EVT = 29, /*!< When SPP client initiated a connection, the event comes */
ESP_SPP_DATA_IND_EVT = 30, /*!< When SPP connection received data, the event comes */
ESP_SPP_CONG_EVT = 31, /*!< When SPP connection congestion status changed, the event comes */
ESP_SPP_WRITE_EVT = 33, /*!< When SPP write operation completes, the event comes */
ESP_SPP_SRV_OPEN_EVT = 34, /*!< When SPP Server connection open, the event comes */
} esp_spp_cb_event_t;
/**
* @brief SPP callback parameters union
*/
typedef union {
/**
* @brief SPP_INIT_EVT
*/
struct spp_init_evt_param {
esp_spp_status_t status; /*!< status */
} init; /*!< SPP callback param of SPP_INIT_EVT */
/**
* @brief SPP_DISCOVERY_COMP_EVT
*/
struct spp_discovery_comp_evt_param {
esp_spp_status_t status; /*!< status */
uint8_t scn_num; /*!< The num of scn_num */
uint8_t scn[ESP_SPP_MAX_SCN]; /*!< channel # */
} disc_comp; /*!< SPP callback param of SPP_DISCOVERY_COMP_EVT */
/**
* @brief ESP_SPP_OPEN_EVT
*/
struct spp_open_evt_param {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
esp_bd_addr_t rem_bda; /*!< The peer address */
} open; /*!< SPP callback param of ESP_SPP_OPEN_EVT */
/**
* @brief ESP_SPP_SRV_OPEN_EVT
*/
struct spp_srv_open_evt_param {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
uint32_t new_listen_handle; /*!< The new listen handle */
esp_bd_addr_t rem_bda; /*!< The peer address */
} srv_open; /*!< SPP callback param of ESP_SPP_SRV_OPEN_EVT */
/**
* @brief ESP_SPP_CLOSE_EVT
*/
struct spp_close_evt_param {
esp_spp_status_t status; /*!< status */
uint32_t port_status; /*!< PORT status */
uint32_t handle; /*!< The connection handle */
bool async; /*!< FALSE, if local initiates disconnect */
} close; /*!< SPP callback param of ESP_SPP_CLOSE_EVT */
/**
* @brief ESP_SPP_START_EVT
*/
struct spp_start_evt_param {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
uint8_t sec_id; /*!< security ID used by this server */
bool use_co; /*!< TRUE to use co_rfc_data */
} start; /*!< SPP callback param of ESP_SPP_START_EVT */
/**
* @brief ESP_SPP_CL_INIT_EVT
*/
struct spp_cl_init_evt_param {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
uint8_t sec_id; /*!< security ID used by this server */
bool use_co; /*!< TRUE to use co_rfc_data */
} cl_init; /*!< SPP callback param of ESP_SPP_CL_INIT_EVT */
/**
* @brief ESP_SPP_WRITE_EVT
*/
struct spp_write_evt_param {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
uint32_t req_id; /*!< The req_id in the associated BTA_JvRfcommWrite() */
int len; /*!< The length of the data written. */
bool cong; /*!< congestion status */
} write; /*!< SPP callback param of ESP_SPP_WRITE_EVT */
/**
* @brief ESP_SPP_DATA_IND_EVT
*/
struct spp_data_ind_evt_param {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
uint16_t len; /*!< The length of data */
uint8_t *data; /*!< The data recived */
} data_ind; /*!< SPP callback param of ESP_SPP_DATA_IND_EVT */
/**
* @brief ESP_SPP_CONG_EVT
*/
struct spp_cong_evt_param {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
bool cong; /*!< TRUE, congested. FALSE, uncongested */
} cong; /*!< SPP callback param of ESP_SPP_CONG_EVT */
} esp_spp_cb_param_t; /*!< SPP callback parameter union type */
/**
* @brief SPP callback function type
* @param event: Event type
* @param param: Point to callback parameter, currently is union type
*/
typedef void (esp_spp_cb_t)(esp_spp_cb_event_t event, esp_spp_cb_param_t *param);
/**
* @brief This function is called to init callbacks
* with SPP module.
*
* @param[in] callback: pointer to the init callback function.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_register_callback(esp_spp_cb_t callback);
/**
* @brief This function is called to init SPP.
*
* @param[in] mode: Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_CB.
* Now only supports ESP_SPP_MODE_CB mode, we will continue to update.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_init(esp_spp_mode_t mode);
/**
* @brief This function is called to uninit SPP.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_deinit();
/**
* @brief This function is called to performs service discovery for
* the services provided by the given peer device. When the
* operation is complete the callback function will be called
* with a ESP_SPP_DISCOVERY_COMP_EVT.
*
* @param[in] bd_addr: Remote device bluetooth device address.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr);
/**
* @brief This function makes an SPP conection to a remote BD Address.
* When the connection is initiated or failed to initiate,
* the callback is called with ESP_SPP_CL_INIT_EVT.
* When the connection is established or failed,
* the callback is called with ESP_SPP_OPEN_EVT.
*
* @param[in] sec_mask: Security Setting Mask .
* @param[in] role: Msater or slave.
* @param[in] remote_scn: Remote device bluetooth device SCN.
* @param[in] peer_bd_addr: Remote device bluetooth device address.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask,
esp_spp_role_t role, uint8_t remote_scn, esp_bd_addr_t peer_bd_addr);
/**
* @brief This function closes an SPP connection.
*
* @param[in] handle: The connection handle.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_disconnect(uint32_t handle);
/**
* @brief This function create a SPP server and starts listening for an
* SPP connection request from a remote Bluetooth device.
* When the server is started successfully, the callback is called
* with ESP_SPP_START_EVT.
* When the connection is established, the callback is called
* with ESP_SPP_SRV_OPEN_EVT.
*
* @param[in] sec_mask: Security Setting Mask .
* @param[in] role: Msater or slave.
* @param[in] local_scn: The specific channel you want to get.
* If channel is 0, means get any channel.
* @param[in] name: Server's name.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask,
esp_spp_role_t role, uint8_t local_scn, const char *name);
/**
* @brief This function closes an SPP connection.
*
* @param[in] handle: The connection handle.
* @param[in] len: The length of the data written.
* @param[in] p_data: The data written.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data);
#ifdef __cplusplus
}
#endif
#endif ///__ESP_SPP_API_H__

View File

@ -0,0 +1,884 @@
/******************************************************************************
*
* Copyright (C) 2006-2012 Broadcom Corporation
*
* Licensed 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.
*
******************************************************************************/
/******************************************************************************
*
* This is the public interface file the BTA Java I/F
*
******************************************************************************/
#ifndef BTA_JV_API_H
#define BTA_JV_API_H
#include "bt_target.h"
#include "bt_types.h"
#include "bta_api.h"
#include "btm_api.h"
#include "l2c_api.h"
#include "rfcdefs.h"
#include "sdp_api.h"
#if (defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE)
/*****************************************************************************
** Constants and data types
*****************************************************************************/
/* status values */
#define BTA_JV_SUCCESS 0 /* Successful operation. */
#define BTA_JV_FAILURE 1 /* Generic failure. */
#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 */
typedef UINT8 tBTA_JV_STATUS;
#define BTA_JV_INTERNAL_ERR (-1) /* internal error. */
#define BTA_JV_MAX_UUIDS SDP_MAX_UUID_FILTERS
#define BTA_JV_MAX_ATTRS SDP_MAX_ATTR_FILTERS
#define BTA_JV_MAX_SDP_REC SDP_MAX_RECORDS
#define BTA_JV_MAX_L2C_CONN GAP_MAX_CONNECTIONS /* GAP handle is used as index, hence do not change this value */
#define BTA_JV_MAX_SCN PORT_MAX_RFC_PORTS /* same as BTM_MAX_SCN (in btm_int.h) */
#define BTA_JV_MAX_RFC_CONN MAX_RFC_PORTS
#ifndef BTA_JV_DEF_RFC_MTU
#define BTA_JV_DEF_RFC_MTU (3*330)
#endif
#ifndef BTA_JV_MAX_RFC_SR_SESSION
#define BTA_JV_MAX_RFC_SR_SESSION MAX_BD_CONNECTIONS
#endif
/* BTA_JV_MAX_RFC_SR_SESSION can not be bigger than MAX_BD_CONNECTIONS */
#if (BTA_JV_MAX_RFC_SR_SESSION > MAX_BD_CONNECTIONS)
#undef BTA_JV_MAX_RFC_SR_SESSION
#define BTA_JV_MAX_RFC_SR_SESSION MAX_BD_CONNECTIONS
#endif
#define BTA_JV_FIRST_SERVICE_ID BTA_FIRST_JV_SERVICE_ID
#define BTA_JV_LAST_SERVICE_ID BTA_LAST_JV_SERVICE_ID
#define BTA_JV_NUM_SERVICE_ID (BTA_LAST_JV_SERVICE_ID - BTA_FIRST_JV_SERVICE_ID + 1)
/* Discoverable modes */
enum {
BTA_JV_DISC_NONE,
BTA_JV_DISC_LIMITED,
BTA_JV_DISC_GENERAL
};
typedef UINT16 tBTA_JV_DISC;
#define BTA_JV_ROLE_SLAVE BTM_ROLE_SLAVE
#define BTA_JV_ROLE_MASTER BTM_ROLE_MASTER
typedef UINT32 tBTA_JV_ROLE;
#define BTA_JV_SERVICE_LMTD_DISCOVER BTM_COD_SERVICE_LMTD_DISCOVER /* 0x0020 */
#define BTA_JV_SERVICE_POSITIONING BTM_COD_SERVICE_POSITIONING /* 0x0100 */
#define BTA_JV_SERVICE_NETWORKING BTM_COD_SERVICE_NETWORKING /* 0x0200 */
#define BTA_JV_SERVICE_RENDERING BTM_COD_SERVICE_RENDERING /* 0x0400 */
#define BTA_JV_SERVICE_CAPTURING BTM_COD_SERVICE_CAPTURING /* 0x0800 */
#define BTA_JV_SERVICE_OBJ_TRANSFER BTM_COD_SERVICE_OBJ_TRANSFER /* 0x1000 */
#define BTA_JV_SERVICE_AUDIO BTM_COD_SERVICE_AUDIO /* 0x2000 */
#define BTA_JV_SERVICE_TELEPHONY BTM_COD_SERVICE_TELEPHONY /* 0x4000 */
#define BTA_JV_SERVICE_INFORMATION BTM_COD_SERVICE_INFORMATION /* 0x8000 */
/* JV ID type */
#define BTA_JV_PM_ID_1 1 /* PM example profile 1 */
#define BTA_JV_PM_ID_2 2 /* PM example profile 2 */
#define BTA_JV_PM_ID_CLEAR 0 /* Special JV ID used to clear PM profile */
#define BTA_JV_PM_ALL 0xFF /* Generic match all id, see bta_dm_cfg.c */
typedef UINT8 tBTA_JV_PM_ID;
#define BTA_JV_PM_HANDLE_CLEAR 0xFF /* Special JV ID used to clear PM profile */
/* define maximum number of registered PM entities. should be in sync with bta pm! */
#ifndef BTA_JV_PM_MAX_NUM
#define BTA_JV_PM_MAX_NUM 5
#endif
/* JV pm connection states */
enum {
BTA_JV_CONN_OPEN = 0, /* Connection opened state */
BTA_JV_CONN_CLOSE, /* Connection closed state */
BTA_JV_APP_OPEN, /* JV Application opened state */
BTA_JV_APP_CLOSE, /* JV Application closed state */
BTA_JV_SCO_OPEN, /* SCO connection opened state */
BTA_JV_SCO_CLOSE, /* SCO connection opened state */
BTA_JV_CONN_IDLE, /* Connection idle state */
BTA_JV_CONN_BUSY, /* Connection busy state */
BTA_JV_MAX_CONN_STATE /* Max number of connection state */
};
typedef UINT8 tBTA_JV_CONN_STATE;
/* JV Connection types */
#define BTA_JV_CONN_TYPE_RFCOMM 0
#define BTA_JV_CONN_TYPE_L2CAP 1
#define BTA_JV_CONN_TYPE_L2CAP_LE 2
/* Java I/F callback events */
/* events received by tBTA_JV_DM_CBACK */
#define BTA_JV_ENABLE_EVT 0 /* JV enabled */
#define BTA_JV_GET_SCN_EVT 6 /* Reserved an SCN */
#define BTA_JV_GET_PSM_EVT 7 /* Reserved a PSM */
#define BTA_JV_DISCOVERY_COMP_EVT 8 /* SDP discovery complete */
#define BTA_JV_CREATE_RECORD_EVT 11 /* the result for BTA_JvCreateRecord */
/* events received by tBTA_JV_L2CAP_CBACK */
#define BTA_JV_L2CAP_OPEN_EVT 16 /* open status of L2CAP connection */
#define BTA_JV_L2CAP_CLOSE_EVT 17 /* L2CAP connection closed */
#define BTA_JV_L2CAP_START_EVT 18 /* L2CAP server started */
#define BTA_JV_L2CAP_CL_INIT_EVT 19 /* L2CAP client initiated a connection */
#define BTA_JV_L2CAP_DATA_IND_EVT 20 /* L2CAP connection received data */
#define BTA_JV_L2CAP_CONG_EVT 21 /* L2CAP connection congestion status changed */
#define BTA_JV_L2CAP_READ_EVT 22 /* the result for BTA_JvL2capRead */
#define BTA_JV_L2CAP_RECEIVE_EVT 23 /* the result for BTA_JvL2capReceive*/
#define BTA_JV_L2CAP_WRITE_EVT 24 /* the result for BTA_JvL2capWrite*/
#define BTA_JV_L2CAP_WRITE_FIXED_EVT 25 /* the result for BTA_JvL2capWriteFixed */
/* events received by tBTA_JV_RFCOMM_CBACK */
#define BTA_JV_RFCOMM_OPEN_EVT 26 /* open status of RFCOMM Client connection */
#define BTA_JV_RFCOMM_CLOSE_EVT 27 /* RFCOMM connection closed */
#define BTA_JV_RFCOMM_START_EVT 28 /* RFCOMM server started */
#define BTA_JV_RFCOMM_CL_INIT_EVT 29 /* RFCOMM client initiated a connection */
#define BTA_JV_RFCOMM_DATA_IND_EVT 30 /* RFCOMM connection received data */
#define BTA_JV_RFCOMM_CONG_EVT 31 /* RFCOMM connection congestion status changed */
#define BTA_JV_RFCOMM_READ_EVT 32 /* the result for BTA_JvRfcommRead */
#define BTA_JV_RFCOMM_WRITE_EVT 33 /* the result for BTA_JvRfcommWrite*/
#define BTA_JV_RFCOMM_SRV_OPEN_EVT 34 /* open status of Server RFCOMM connection */
#define BTA_JV_MAX_EVT 35 /* max number of JV events */
typedef UINT16 tBTA_JV_EVT;
/* data associated with BTA_JV_SET_DISCOVER_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
tBTA_JV_DISC disc_mode; /* The current discoverable mode */
} tBTA_JV_SET_DISCOVER;
/* data associated with BTA_JV_DISCOVERY_COMP_EVT_ */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT8 scn_num; /* num of channel */
UINT8 scn[BTA_JV_MAX_SCN]; /* channel # */
} tBTA_JV_DISCOVERY_COMP;
/* data associated with BTA_JV_CREATE_RECORD_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The SDP handle */
} tBTA_JV_CREATE_RECORD;
/* data associated with BTA_JV_L2CAP_OPEN_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
BD_ADDR rem_bda; /* The peer address */
INT32 tx_mtu; /* The transmit MTU */
} tBTA_JV_L2CAP_OPEN;
/* data associated with BTA_JV_L2CAP_OPEN_EVT for LE sockets */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
BD_ADDR rem_bda; /* The peer address */
INT32 tx_mtu; /* The transmit MTU */
void **p_p_cback; /* set them for new socket */
void **p_user_data;/* set them for new socket */
} tBTA_JV_L2CAP_LE_OPEN;
/* data associated with BTA_JV_L2CAP_CLOSE_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
BOOLEAN async; /* FALSE, if local initiates disconnect */
} tBTA_JV_L2CAP_CLOSE;
/* data associated with BTA_JV_L2CAP_START_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT8 sec_id; /* security ID used by this server */
} tBTA_JV_L2CAP_START;
/* data associated with BTA_JV_L2CAP_CL_INIT_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT8 sec_id; /* security ID used by this client */
} tBTA_JV_L2CAP_CL_INIT;
/* data associated with BTA_JV_L2CAP_CONG_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
BOOLEAN cong; /* TRUE, congested. FALSE, uncongested */
} tBTA_JV_L2CAP_CONG;
/* data associated with BTA_JV_L2CAP_READ_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT32 req_id; /* The req_id in the associated BTA_JvL2capRead() */
UINT8 *p_data; /* This points the same location as the p_data
* parameter in BTA_JvL2capRead () */
UINT16 len; /* The length of the data read. */
} tBTA_JV_L2CAP_READ;
/* data associated with BTA_JV_L2CAP_RECEIVE_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT32 req_id; /* The req_id in the associated BTA_JvL2capReceive() */
UINT8 *p_data; /* This points the same location as the p_data
* parameter in BTA_JvL2capReceive () */
UINT16 len; /* The length of the data read. */
} tBTA_JV_L2CAP_RECEIVE;
/* data associated with BTA_JV_L2CAP_WRITE_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT32 req_id; /* The req_id in the associated BTA_JvL2capWrite() */
UINT16 len; /* The length of the data written. */
BOOLEAN cong; /* congestion status */
} tBTA_JV_L2CAP_WRITE;
/* data associated with BTA_JV_L2CAP_WRITE_FIXED_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT16 channel; /* The connection channel */
BD_ADDR addr; /* The peer address */
UINT32 req_id; /* The req_id in the associated BTA_JvL2capWrite() */
UINT16 len; /* The length of the data written. */
BOOLEAN cong; /* congestion status */
} tBTA_JV_L2CAP_WRITE_FIXED;
/* data associated with BTA_JV_RFCOMM_OPEN_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
BD_ADDR rem_bda; /* The peer address */
} tBTA_JV_RFCOMM_OPEN;
/* data associated with BTA_JV_RFCOMM_SRV_OPEN_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT32 new_listen_handle; /* The new listen handle */
BD_ADDR rem_bda; /* The peer address */
} tBTA_JV_RFCOMM_SRV_OPEN;
/* data associated with BTA_JV_RFCOMM_CLOSE_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 port_status; /* PORT status */
UINT32 handle; /* The connection handle */
BOOLEAN async; /* FALSE, if local initiates disconnect */
} tBTA_JV_RFCOMM_CLOSE;
/* data associated with BTA_JV_RFCOMM_START_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT8 sec_id; /* security ID used by this server */
BOOLEAN use_co; /* TRUE to use co_rfc_data */
} tBTA_JV_RFCOMM_START;
/* data associated with BTA_JV_RFCOMM_CL_INIT_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT8 sec_id; /* security ID used by this client */
BOOLEAN use_co; /* TRUE to use co_rfc_data */
} tBTA_JV_RFCOMM_CL_INIT;
/*data associated with BTA_JV_L2CAP_DATA_IND_EVT & BTA_JV_RFCOMM_DATA_IND_EVT */
typedef struct {
UINT32 handle; /* The connection handle */
BT_HDR *p_buf; /* The incoming data */
} tBTA_JV_DATA_IND;
/*data associated with BTA_JV_L2CAP_DATA_IND_EVT if used for LE */
typedef struct {
UINT32 handle; /* The connection handle */
BT_HDR *p_buf; /* The incoming data */
} tBTA_JV_LE_DATA_IND;
/* data associated with BTA_JV_RFCOMM_CONG_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
BOOLEAN cong; /* TRUE, congested. FALSE, uncongested */
} tBTA_JV_RFCOMM_CONG;
/* data associated with BTA_JV_RFCOMM_READ_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT32 req_id; /* The req_id in the associated BTA_JvRfcommRead() */
UINT8 *p_data; /* This points the same location as the p_data
* parameter in BTA_JvRfcommRead () */
UINT16 len; /* The length of the data read. */
} tBTA_JV_RFCOMM_READ;
/* data associated with BTA_JV_RFCOMM_WRITE_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT32 handle; /* The connection handle */
UINT32 req_id; /* The req_id in the associated BTA_JvRfcommWrite() */
int len; /* The length of the data written. */
BOOLEAN cong; /* congestion status */
} tBTA_JV_RFCOMM_WRITE;
/* data associated with BTA_JV_API_SET_PM_PROFILE_EVT */
typedef struct {
tBTA_JV_STATUS status; /* Status of the operation */
UINT32 handle; /* Connection handle */
tBTA_JV_PM_ID app_id; /* JV app ID */
} tBTA_JV_SET_PM_PROFILE;
/* data associated with BTA_JV_API_NOTIFY_PM_STATE_CHANGE_EVT */
typedef struct {
UINT32 handle; /* Connection handle */
tBTA_JV_CONN_STATE state; /* JV connection stata */
} tBTA_JV_NOTIFY_PM_STATE_CHANGE;
/* union of data associated with JV callback */
typedef union {
tBTA_JV_STATUS status; /* BTA_JV_ENABLE_EVT */
tBTA_JV_DISCOVERY_COMP disc_comp; /* BTA_JV_DISCOVERY_COMP_EVT */
tBTA_JV_SET_DISCOVER set_discover; /* BTA_JV_SET_DISCOVER_EVT */
UINT8 scn; /* BTA_JV_GET_SCN_EVT */
UINT16 psm; /* BTA_JV_GET_PSM_EVT */
tBTA_JV_CREATE_RECORD create_rec; /* BTA_JV_CREATE_RECORD_EVT */
tBTA_JV_L2CAP_OPEN l2c_open; /* BTA_JV_L2CAP_OPEN_EVT */
tBTA_JV_L2CAP_CLOSE l2c_close; /* BTA_JV_L2CAP_CLOSE_EVT */
tBTA_JV_L2CAP_START l2c_start; /* BTA_JV_L2CAP_START_EVT */
tBTA_JV_L2CAP_CL_INIT l2c_cl_init; /* BTA_JV_L2CAP_CL_INIT_EVT */
tBTA_JV_L2CAP_CONG l2c_cong; /* BTA_JV_L2CAP_CONG_EVT */
tBTA_JV_L2CAP_READ l2c_read; /* BTA_JV_L2CAP_READ_EVT */
tBTA_JV_L2CAP_WRITE l2c_write; /* BTA_JV_L2CAP_WRITE_EVT */
tBTA_JV_RFCOMM_OPEN rfc_open; /* BTA_JV_RFCOMM_OPEN_EVT */
tBTA_JV_RFCOMM_SRV_OPEN rfc_srv_open; /* BTA_JV_RFCOMM_SRV_OPEN_EVT */
tBTA_JV_RFCOMM_CLOSE rfc_close; /* BTA_JV_RFCOMM_CLOSE_EVT */
tBTA_JV_RFCOMM_START rfc_start; /* BTA_JV_RFCOMM_START_EVT */
tBTA_JV_RFCOMM_CL_INIT rfc_cl_init; /* BTA_JV_RFCOMM_CL_INIT_EVT */
tBTA_JV_RFCOMM_CONG rfc_cong; /* BTA_JV_RFCOMM_CONG_EVT */
tBTA_JV_RFCOMM_READ rfc_read; /* BTA_JV_RFCOMM_READ_EVT */
tBTA_JV_RFCOMM_WRITE rfc_write; /* BTA_JV_RFCOMM_WRITE_EVT */
tBTA_JV_DATA_IND data_ind; /* BTA_JV_L2CAP_DATA_IND_EVT
BTA_JV_RFCOMM_DATA_IND_EVT */
tBTA_JV_LE_DATA_IND le_data_ind; /* BTA_JV_L2CAP_LE_DATA_IND_EVT */
tBTA_JV_L2CAP_LE_OPEN l2c_le_open; /* BTA_JV_L2CAP_OPEN_EVT */
tBTA_JV_L2CAP_WRITE_FIXED l2c_write_fixed; /* BTA_JV_L2CAP_WRITE_FIXED_EVT */
} tBTA_JV;
/* JAVA DM Interface callback */
typedef void (tBTA_JV_DM_CBACK)(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data);
/* JAVA RFCOMM interface callback */
typedef void *(tBTA_JV_RFCOMM_CBACK)(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data);
/* JAVA L2CAP interface callback */
typedef void (tBTA_JV_L2CAP_CBACK)(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_Data);
/* JV configuration structure */
typedef struct {
UINT16 sdp_raw_size; /* The size of p_sdp_raw_data */
UINT16 sdp_db_size; /* The size of p_sdp_db */
UINT8 *p_sdp_raw_data; /* The data buffer to keep raw data */
tSDP_DISCOVERY_DB *p_sdp_db; /* The data buffer to keep SDP database */
} tBTA_JV_CFG;
/*******************************************************************************
**
** Function BTA_JvEnable
**
** Description Enable the Java I/F service. When the enable
** operation is complete the callback function will be
** called with a BTA_JV_ENABLE_EVT. This function must
** be called before other functions in the JV API are
** called.
**
** Returns BTA_JV_SUCCESS if successful.
** BTA_JV_FAIL if internal failure.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvEnable(tBTA_JV_DM_CBACK *p_cback);
/*******************************************************************************
**
** Function BTA_JvDisable
**
** Description Disable the Java I/F
**
** Returns void
**
*******************************************************************************/
extern void BTA_JvDisable(void);
/*******************************************************************************
**
** Function BTA_JvIsEnable
**
** Description Get the JV registration status.
**
** Returns TRUE, if registered
**
*******************************************************************************/
extern BOOLEAN BTA_JvIsEnable(void);
/*******************************************************************************
**
** Function BTA_JvIsEncrypted
**
** Description This function checks if the link to peer device is encrypted
**
** Returns TRUE if encrypted.
** FALSE if not.
**
*******************************************************************************/
extern BOOLEAN BTA_JvIsEncrypted(BD_ADDR bd_addr);
/*******************************************************************************
**
** Function BTA_JvGetChannelId
**
** Description This function reserves a SCN/PSM for applications running
** over RFCOMM or L2CAP. It is primarily called by
** server profiles/applications to register their SCN/PSM into the
** SDP database. The SCN is reported by the tBTA_JV_DM_CBACK
** callback with a BTA_JV_GET_SCN_EVT.
** If the SCN/PSM reported is 0, that means all SCN resources are
** exhausted.
** The channel parameter can be used to request a specific
** channel. If the request on the specific channel fails, the
** SCN/PSM returned in the EVT will be 0 - no attempt to request
** a new channel will be made. set channel to <= 0 to automatically
** assign an channel ID.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvGetChannelId(int conn_type, void *user_data,
INT32 channel);
/*******************************************************************************
**
** Function BTA_JvFreeChannel
**
** Description This function frees a SCN/PSM that was used
** by an application running over RFCOMM or L2CAP.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvFreeChannel(UINT16 channel, int conn_type);
/*******************************************************************************
**
** Function BTA_JvStartDiscovery
**
** Description This function performs service discovery for the services
** provided by the given peer device. When the operation is
** complete the tBTA_JV_DM_CBACK callback function will be
** called with a BTA_JV_DISCOVERY_COMP_EVT.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvStartDiscovery(BD_ADDR bd_addr, UINT16 num_uuid,
tSDP_UUID *p_uuid_list, void *user_data);
/*******************************************************************************
**
** Function BTA_JvCreateRecordByUser
**
** Description Create a service record in the local SDP database by user in
** tBTA_JV_DM_CBACK callback with a BTA_JV_CREATE_RECORD_EVT.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvCreateRecordByUser(const char *name, UINT32 channel, void *user_data);
/*******************************************************************************
**
** Function BTA_JvDeleteRecord
**
** Description Delete a service record in the local SDP database.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvDeleteRecord(UINT32 handle);
/*******************************************************************************
**
** Function BTA_JvL2capConnectLE
**
** Description Initiate a connection as an LE L2CAP client to the given BD
** Address.
** When the connection is initiated or failed to initiate,
** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_CL_INIT_EVT
** When the connection is established or failed,
** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_OPEN_EVT
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capConnectLE(tBTA_SEC sec_mask, tBTA_JV_ROLE role,
const tL2CAP_ERTM_INFO *ertm_info, UINT16 remote_chan,
UINT16 rx_mtu, tL2CAP_CFG_INFO *cfg,
BD_ADDR peer_bd_addr, tBTA_JV_L2CAP_CBACK *p_cback, void *user_data);
/*******************************************************************************
**
** Function BTA_JvL2capConnect
**
** Description Initiate a connection as a L2CAP client to the given BD
** Address.
** When the connection is initiated or failed to initiate,
** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_CL_INIT_EVT
** When the connection is established or failed,
** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_OPEN_EVT
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capConnect(tBTA_SEC sec_mask, tBTA_JV_ROLE role,
const tL2CAP_ERTM_INFO *ertm_info, UINT16 remote_psm,
UINT16 rx_mtu, tL2CAP_CFG_INFO *cfg,
BD_ADDR peer_bd_addr, tBTA_JV_L2CAP_CBACK *p_cback, void *user_data);
/*******************************************************************************
**
** Function BTA_JvL2capClose
**
** Description This function closes an L2CAP client connection
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capClose(UINT32 handle);
/*******************************************************************************
**
** Function BTA_JvL2capCloseLE
**
** Description This function closes an L2CAP client connection for Fixed Channels
** Function is idempotent and no callbacks are called!
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capCloseLE(UINT32 handle);
/*******************************************************************************
**
** Function BTA_JvL2capStartServer
**
** Description This function starts an L2CAP server and listens for an L2CAP
** connection from a remote Bluetooth device. When the server
** is started successfully, tBTA_JV_L2CAP_CBACK is called with
** BTA_JV_L2CAP_START_EVT. When the connection is established,
** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_OPEN_EVT.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capStartServer(tBTA_SEC sec_mask, tBTA_JV_ROLE role,
const tL2CAP_ERTM_INFO *ertm_info,
UINT16 local_psm, UINT16 rx_mtu, tL2CAP_CFG_INFO *cfg,
tBTA_JV_L2CAP_CBACK *p_cback, void *user_data);
/*******************************************************************************
**
** Function BTA_JvL2capStartServerLE
**
** Description This function starts an LE L2CAP server and listens for an L2CAP
** connection from a remote Bluetooth device on a fixed channel
** over an LE link. When the server
** is started successfully, tBTA_JV_L2CAP_CBACK is called with
** BTA_JV_L2CAP_START_EVT. When the connection is established,
** tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_OPEN_EVT.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capStartServerLE(tBTA_SEC sec_mask, tBTA_JV_ROLE role,
const tL2CAP_ERTM_INFO *ertm_info,
UINT16 local_chan, UINT16 rx_mtu, tL2CAP_CFG_INFO *cfg,
tBTA_JV_L2CAP_CBACK *p_cback, void *user_data);
/*******************************************************************************
**
** Function BTA_JvL2capStopServerLE
**
** Description This function stops the LE L2CAP server. If the server has an
** active connection, it would be closed.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capStopServerLE(UINT16 local_chan, void *user_data);
/*******************************************************************************
**
** Function BTA_JvL2capStopServerLE
**
** Description This function stops the LE L2CAP server. If the server has an
** active connection, it would be closed.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capStopServer(UINT16 local_psm, void *user_data);
/*******************************************************************************
**
** Function BTA_JvL2capRead
**
** Description This function reads data from an L2CAP connection
** 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.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capRead(UINT32 handle, UINT32 req_id,
UINT8 *p_data, UINT16 len);
/*******************************************************************************
**
** Function BTA_JvL2capReceive
**
** Description This function reads data from an L2CAP connection
** When the operation is complete, tBTA_JV_L2CAP_CBACK is
** called with BTA_JV_L2CAP_RECEIVE_EVT.
** If there are more data queued in L2CAP than len, the extra data will be discarded.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capReceive(UINT32 handle, UINT32 req_id,
UINT8 *p_data, UINT16 len);
/*******************************************************************************
**
** Function BTA_JvL2capReady
**
** Description This function determined if there is data to read from
** an L2CAP connection
**
** Returns BTA_JV_SUCCESS, if data queue size is in *p_data_size.
** BTA_JV_FAILURE, if error.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capReady(UINT32 handle, UINT32 *p_data_size);
/*******************************************************************************
**
** Function BTA_JvL2capWrite
**
** Description This function writes data to an L2CAP connection
** When the operation is complete, tBTA_JV_L2CAP_CBACK is
** called with BTA_JV_L2CAP_WRITE_EVT. Works for
** PSM-based connections
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capWrite(UINT32 handle, UINT32 req_id,
UINT8 *p_data, UINT16 len, void *user_data);
/*******************************************************************************
**
** Function BTA_JvL2capWriteFixed
**
** Description This function writes data to an L2CAP connection
** When the operation is complete, tBTA_JV_L2CAP_CBACK is
** called with BTA_JV_L2CAP_WRITE_FIXED_EVT. Works for
** fixed-channel connections
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvL2capWriteFixed(UINT16 channel, BD_ADDR *addr, UINT32 req_id,
tBTA_JV_L2CAP_CBACK *p_cback,
UINT8 *p_data, UINT16 len, void *user_data);
/*******************************************************************************
**
** Function BTA_JvRfcommConnect
**
** Description This function makes an RFCOMM conection to a remote BD
** Address.
** When the connection is initiated or failed to initiate,
** tBTA_JV_RFCOMM_CBACK is called with BTA_JV_RFCOMM_CL_INIT_EVT
** When the connection is established or failed,
** tBTA_JV_RFCOMM_CBACK is called with BTA_JV_RFCOMM_OPEN_EVT
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvRfcommConnect(tBTA_SEC sec_mask,
tBTA_JV_ROLE role, UINT8 remote_scn, BD_ADDR peer_bd_addr,
tBTA_JV_RFCOMM_CBACK *p_cback, void *user_data);
/*******************************************************************************
**
** Function BTA_JvRfcommClose
**
** Description This function closes an RFCOMM connection
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, void *user_data);
/*******************************************************************************
**
** Function BTA_JvRfcommStartServer
**
** Description This function starts listening for an RFCOMM connection
** request from a remote Bluetooth device. When the server is
** started successfully, tBTA_JV_RFCOMM_CBACK is called
** with BTA_JV_RFCOMM_START_EVT.
** When the connection is established, tBTA_JV_RFCOMM_CBACK
** is called with BTA_JV_RFCOMM_OPEN_EVT.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvRfcommStartServer(tBTA_SEC sec_mask,
tBTA_JV_ROLE role, UINT8 local_scn, UINT8 max_session,
tBTA_JV_RFCOMM_CBACK *p_cback, void *user_data);
/*******************************************************************************
**
** Function BTA_JvRfcommStopServer
**
** Description This function stops the RFCOMM server. If the server has an
** active connection, it would be closed.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvRfcommStopServer(UINT32 handle, void *user_data);
/*******************************************************************************
**
** Function BTA_JvRfcommRead
**
** Description This function reads data from an RFCOMM connection
** When the operation is complete, tBTA_JV_RFCOMM_CBACK is
** called with BTA_JV_RFCOMM_READ_EVT.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvRfcommRead(UINT32 handle, UINT32 req_id,
UINT8 *p_data, UINT16 len);
/*******************************************************************************
**
** Function BTA_JvRfcommReady
**
** Description This function determined if there is data to read from
** an RFCOMM connection
**
** Returns BTA_JV_SUCCESS, if data queue size is in *p_data_size.
** BTA_JV_FAILURE, if error.
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvRfcommReady(UINT32 handle, UINT32 *p_data_size);
/*******************************************************************************
**
** Function BTA_JvRfcommWrite
**
** Description This function writes data to an RFCOMM connection
** When the operation is complete, tBTA_JV_RFCOMM_CBACK is
** called with BTA_JV_RFCOMM_WRITE_EVT.
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
// extern tBTA_JV_STATUS BTA_JvRfcommWrite(UINT32 handle, UINT32 req_id);
extern tBTA_JV_STATUS BTA_JvRfcommWrite(UINT32 handle, UINT32 req_id, int len, UINT8 *p_data);
/*******************************************************************************
**
** Function BTA_JVSetPmProfile
**
** Description This function set or free power mode profile for different JV application
**
** Parameters: handle, JV handle from RFCOMM or L2CAP
** app_id: app specific pm ID, can be BTA_JV_PM_ALL, see bta_dm_cfg.c for details
** BTA_JV_PM_ID_CLEAR: removes pm management on the handle. init_st is ignored and
** BTA_JV_CONN_CLOSE is called implicitely
** init_st: state after calling this API. typically it should be BTA_JV_CONN_OPEN
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
** NOTE: BTA_JV_PM_ID_CLEAR: In general no need to be called as jv pm calls automatically
** BTA_JV_CONN_CLOSE to remove in case of connection close!
**
*******************************************************************************/
extern tBTA_JV_STATUS BTA_JvSetPmProfile(UINT32 handle, tBTA_JV_PM_ID app_id,
tBTA_JV_CONN_STATE init_st);
/*******************************************************************************
**
** Function BTA_JvRfcommGetPortHdl
**
** Description This function fetches the rfcomm port handle
**
** Returns BTA_JV_SUCCESS, if the request is being processed.
** BTA_JV_FAILURE, otherwise.
**
*******************************************************************************/
UINT16 BTA_JvRfcommGetPortHdl(UINT32 handle);
#endif ///defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE
#endif /* BTA_JV_API_H */

View File

@ -0,0 +1,55 @@
/******************************************************************************
*
* Copyright (C) 2007-2012 Broadcom Corporation
*
* Licensed 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.
*
******************************************************************************/
/******************************************************************************
*
* This is the interface file for java interface call-out functions.
*
******************************************************************************/
#ifndef BTA_JV_CO_H
#define BTA_JV_CO_H
#include "bta_jv_api.h"
#if (defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE)
/*****************************************************************************
** Function Declarations
*****************************************************************************/
/*******************************************************************************
**
** Function bta_jv_co_rfc_data
**
** Description This function is called by JV to send data to the java glue
** code when the RX data path is configured to use a call-out
**
** Returns void
**
*******************************************************************************/
extern int bta_co_rfc_data_incoming(void *user_data, BT_HDR *p_buf);
extern int bta_co_rfc_data_outgoing_size(void *user_data, int *size);
extern int bta_co_rfc_data_outgoing(void *user_data, UINT8 *buf, UINT16 size);
extern int bta_co_l2cap_data_incoming(void *user_data, BT_HDR *p_buf);
extern int bta_co_l2cap_data_outgoing_size(void *user_data, int *size);
extern int bta_co_l2cap_data_outgoing(void *user_data, UINT8 *buf, UINT16 size);
#endif ///defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE
#endif /* BTA_DG_CO_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright (C) 2004-2012 Broadcom Corporation
*
* Licensed 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.
*
******************************************************************************/
/******************************************************************************
*
* This file contains compile-time configurable constants for advanced
* audio
*
******************************************************************************/
#include "allocator.h"
#include "bta_api.h"
#include "bta_jv_api.h"
#include "bt_target.h"
#if (defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE)
#ifndef BTA_JV_SDP_DB_SIZE
#define BTA_JV_SDP_DB_SIZE 4500
#endif
#ifndef BTA_JV_SDP_RAW_DATA_SIZE
#define BTA_JV_SDP_RAW_DATA_SIZE 1800
#endif
/* The platform may choose to use dynamic memory for these data buffers.
* p_bta_jv_cfg->p_sdp_db must be allocated/stay allocated
* between BTA_JvEnable and BTA_JvDisable
* p_bta_jv_cfg->p_sdp_raw_data can be allocated before calling BTA_JvStartDiscovery
* it can be de-allocated after the last call to access the database */
static UINT8 bta_jv_sdp_raw_data[BTA_JV_SDP_RAW_DATA_SIZE];
static UINT8 __attribute__ ((aligned(4))) bta_jv_sdp_db_data[BTA_JV_SDP_DB_SIZE];
/* JV configuration structure */
const tBTA_JV_CFG bta_jv_cfg = {
BTA_JV_SDP_RAW_DATA_SIZE, /* The size of p_sdp_raw_data */
BTA_JV_SDP_DB_SIZE, /* The size of p_sdp_db_data */
bta_jv_sdp_raw_data, /* The data buffer to keep raw data */
(tSDP_DISCOVERY_DB *)bta_jv_sdp_db_data /* The data buffer to keep SDP database */
};
tBTA_JV_CFG *p_bta_jv_cfg = (tBTA_JV_CFG *) &bta_jv_cfg;
#endif ///defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE

View File

@ -0,0 +1,429 @@
/******************************************************************************
*
* Copyright (C) 2006-2012 Broadcom Corporation
*
* Licensed 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.
*
******************************************************************************/
/******************************************************************************
*
* This is the private interface file for the BTA Java I/F
*
******************************************************************************/
#ifndef BTA_JV_INT_H
#define BTA_JV_INT_H
#include "bta_sys.h"
#include "bta_api.h"
#include "bta_jv_api.h"
#include "rfcdefs.h"
#include "port_api.h"
#include "sdp_api.h"
#include "bt_target.h"
#if (defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE)
/*****************************************************************************
** Constants
*****************************************************************************/
enum {
/* these events are handled by the state machine */
BTA_JV_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_JV),
BTA_JV_API_DISABLE_EVT,
BTA_JV_API_GET_CHANNEL_EVT,
BTA_JV_API_FREE_SCN_EVT,
BTA_JV_API_START_DISCOVERY_EVT,
BTA_JV_API_CREATE_RECORD_EVT,
BTA_JV_API_DELETE_RECORD_EVT,
BTA_JV_API_L2CAP_CONNECT_EVT,
BTA_JV_API_L2CAP_CLOSE_EVT,
BTA_JV_API_L2CAP_START_SERVER_EVT,
BTA_JV_API_L2CAP_STOP_SERVER_EVT,
BTA_JV_API_L2CAP_READ_EVT,
BTA_JV_API_L2CAP_WRITE_EVT,
BTA_JV_API_RFCOMM_CONNECT_EVT,
BTA_JV_API_RFCOMM_CLOSE_EVT,
BTA_JV_API_RFCOMM_START_SERVER_EVT,
BTA_JV_API_RFCOMM_STOP_SERVER_EVT,
BTA_JV_API_RFCOMM_READ_EVT,
BTA_JV_API_RFCOMM_WRITE_EVT,
BTA_JV_API_SET_PM_PROFILE_EVT,
BTA_JV_API_PM_STATE_CHANGE_EVT,
BTA_JV_API_L2CAP_CONNECT_LE_EVT,
BTA_JV_API_L2CAP_START_SERVER_LE_EVT,
BTA_JV_API_L2CAP_STOP_SERVER_LE_EVT,
BTA_JV_API_L2CAP_WRITE_FIXED_EVT,
BTA_JV_API_L2CAP_CLOSE_FIXED_EVT,
BTA_JV_MAX_INT_EVT
};
#ifndef BTA_JV_RFC_EV_MASK
#define BTA_JV_RFC_EV_MASK (PORT_EV_RXCHAR | PORT_EV_TXEMPTY | PORT_EV_FC | PORT_EV_FCS)
#endif
/* data type for BTA_JV_API_ENABLE_EVT */
typedef struct {
BT_HDR hdr;
tBTA_JV_DM_CBACK *p_cback;
} tBTA_JV_API_ENABLE;
/* data type for BTA_JV_API_START_DISCOVERY_EVT */
typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
UINT16 num_uuid;
tSDP_UUID uuid_list[BTA_JV_MAX_UUIDS];
UINT16 num_attr;
UINT16 attr_list[BTA_JV_MAX_ATTRS];
void *user_data; /* piggyback caller's private data*/
} tBTA_JV_API_START_DISCOVERY;
enum {
BTA_JV_PM_FREE_ST = 0, /* empty PM slot */
BTA_JV_PM_IDLE_ST,
BTA_JV_PM_BUSY_ST
};
/* BTA JV PM control block */
typedef struct {
UINT32 handle; /* The connection handle */
UINT8 state; /* state: see above enum */
tBTA_JV_PM_ID app_id; /* JV app specific id indicating power table to use */
BD_ADDR peer_bd_addr; /* Peer BD address */
} tBTA_JV_PM_CB;
enum {
BTA_JV_ST_NONE = 0,
BTA_JV_ST_CL_OPENING,
BTA_JV_ST_CL_OPEN,
BTA_JV_ST_CL_CLOSING,
BTA_JV_ST_SR_LISTEN,
BTA_JV_ST_SR_OPEN,
BTA_JV_ST_SR_CLOSING
} ;
typedef UINT8 tBTA_JV_STATE;
#define BTA_JV_ST_CL_MAX BTA_JV_ST_CL_CLOSING
/* JV L2CAP control block */
typedef struct {
tBTA_JV_L2CAP_CBACK *p_cback; /* the callback function */
UINT16 psm; /* the psm used for this server connection */
tBTA_JV_STATE state; /* the state of this control block */
tBTA_SERVICE_ID sec_id; /* service id */
UINT32 handle; /* the handle reported to java app (same as gap handle) */
BOOLEAN cong; /* TRUE, if congested */
tBTA_JV_PM_CB *p_pm_cb; /* ptr to pm control block, NULL: unused */
void *user_data; /* user data for callback from higher layers */
} tBTA_JV_L2C_CB;
#define BTA_JV_RFC_HDL_MASK 0xFF
#define BTA_JV_RFCOMM_MASK 0x80
#define BTA_JV_ALL_APP_ID 0xFF
#define BTA_JV_RFC_HDL_TO_SIDX(r) (((r)&0xFF00) >> 8)
#define BTA_JV_RFC_H_S_TO_HDL(h, s) ((h)|(s<<8))
/* port control block */
typedef struct {
UINT32 handle; /* the rfcomm session handle at jv */
UINT16 port_handle;/* port handle */
tBTA_JV_STATE state; /* the state of this control block */
UINT8 max_sess; /* max sessions */
void *user_data; /* piggyback caller's private data*/
BOOLEAN cong; /* TRUE, if congested */
tBTA_JV_PM_CB *p_pm_cb; /* ptr to pm control block, NULL: unused */
} tBTA_JV_PCB;
/* JV RFCOMM control block */
typedef struct {
tBTA_JV_RFCOMM_CBACK *p_cback; /* the callback function */
UINT16 rfc_hdl[BTA_JV_MAX_RFC_SR_SESSION];
tBTA_SERVICE_ID sec_id; /* service id */
UINT8 handle; /* index: the handle reported to java app */
UINT8 scn; /* the scn of the server */
UINT8 max_sess; /* max sessions */
int curr_sess; /* current sessions count*/
} tBTA_JV_RFC_CB;
/* data type for BTA_JV_API_L2CAP_CONNECT_EVT & BTA_JV_API_L2CAP_CONNECT_LE_EVT */
typedef struct {
BT_HDR hdr;
tBTA_SEC sec_mask;
tBTA_JV_ROLE role;
union {
UINT16 remote_psm;
UINT16 remote_chan;
};
UINT16 rx_mtu;
BD_ADDR peer_bd_addr;
INT32 has_cfg;
tL2CAP_CFG_INFO cfg;
INT32 has_ertm_info;
tL2CAP_ERTM_INFO ertm_info;
tBTA_JV_L2CAP_CBACK *p_cback;
void *user_data;
} tBTA_JV_API_L2CAP_CONNECT;
/* data type for BTA_JV_API_L2CAP_SERVER_EVT */
typedef struct {
BT_HDR hdr;
tBTA_SEC sec_mask;
tBTA_JV_ROLE role;
union {
UINT16 local_psm;
UINT16 local_chan;
};
UINT16 rx_mtu;
INT32 has_cfg;
tL2CAP_CFG_INFO cfg;
INT32 has_ertm_info;
tL2CAP_ERTM_INFO ertm_info;
tBTA_JV_L2CAP_CBACK *p_cback;
void *user_data;
} tBTA_JV_API_L2CAP_SERVER;
/* data type for BTA_JV_API_L2CAP_CLOSE_EVT */
typedef struct {
BT_HDR hdr;
UINT32 handle;
tBTA_JV_L2C_CB *p_cb;
} tBTA_JV_API_L2CAP_CLOSE;
/* data type for BTA_JV_API_L2CAP_READ_EVT */
typedef struct {
BT_HDR hdr;
UINT32 handle;
UINT32 req_id;
tBTA_JV_L2CAP_CBACK *p_cback;
UINT8 *p_data;
UINT16 len;
void *user_data;
} tBTA_JV_API_L2CAP_READ;
/* data type for BTA_JV_API_L2CAP_WRITE_EVT */
typedef struct {
BT_HDR hdr;
UINT32 handle;
UINT32 req_id;
tBTA_JV_L2C_CB *p_cb;
UINT8 *p_data;
UINT16 len;
void *user_data;
} tBTA_JV_API_L2CAP_WRITE;
/* data type for BTA_JV_API_L2CAP_WRITE_FIXED_EVT */
typedef struct {
BT_HDR hdr;
UINT16 channel;
BD_ADDR addr;
UINT32 req_id;
tBTA_JV_L2CAP_CBACK *p_cback;
UINT8 *p_data;
UINT16 len;
void *user_data;
} tBTA_JV_API_L2CAP_WRITE_FIXED;
/* data type for BTA_JV_API_RFCOMM_CONNECT_EVT */
typedef struct {
BT_HDR hdr;
tBTA_SEC sec_mask;
tBTA_JV_ROLE role;
UINT8 remote_scn;
BD_ADDR peer_bd_addr;
tBTA_JV_RFCOMM_CBACK *p_cback;
void *user_data;
} tBTA_JV_API_RFCOMM_CONNECT;
/* data type for BTA_JV_API_RFCOMM_SERVER_EVT */
typedef struct {
BT_HDR hdr;
tBTA_SEC sec_mask;
tBTA_JV_ROLE role;
UINT8 local_scn;
UINT8 max_session;
UINT32 handle;
tBTA_JV_RFCOMM_CBACK *p_cback;
void *user_data;
} tBTA_JV_API_RFCOMM_SERVER;
/* data type for BTA_JV_API_RFCOMM_READ_EVT */
typedef struct {
BT_HDR hdr;
UINT32 handle;
UINT32 req_id;
UINT8 *p_data;
UINT16 len;
tBTA_JV_RFC_CB *p_cb;
tBTA_JV_PCB *p_pcb;
} tBTA_JV_API_RFCOMM_READ;
/* data type for BTA_JV_API_SET_PM_PROFILE_EVT */
typedef struct {
BT_HDR hdr;
UINT32 handle;
tBTA_JV_PM_ID app_id;
tBTA_JV_CONN_STATE init_st;
} tBTA_JV_API_SET_PM_PROFILE;
/* data type for BTA_JV_API_PM_STATE_CHANGE_EVT */
typedef struct {
BT_HDR hdr;
tBTA_JV_PM_CB *p_cb;
tBTA_JV_CONN_STATE state;
} tBTA_JV_API_PM_STATE_CHANGE;
/* data type for BTA_JV_API_RFCOMM_WRITE_EVT */
typedef struct {
BT_HDR hdr;
UINT32 handle;
UINT32 req_id;
UINT8 *p_data;
int len;
tBTA_JV_RFC_CB *p_cb;
tBTA_JV_PCB *p_pcb;
} tBTA_JV_API_RFCOMM_WRITE;
/* data type for BTA_JV_API_RFCOMM_CLOSE_EVT */
typedef struct {
BT_HDR hdr;
UINT32 handle;
tBTA_JV_RFC_CB *p_cb;
tBTA_JV_PCB *p_pcb;
void *user_data;
} tBTA_JV_API_RFCOMM_CLOSE;
/* data type for BTA_JV_API_CREATE_RECORD_EVT */
typedef struct {
BT_HDR hdr;
#define ESP_SDP_SERVER_NAME_MAX (32)
char name[ESP_SDP_SERVER_NAME_MAX + 1];
INT32 channel;
void *user_data;
} tBTA_JV_API_CREATE_RECORD;
/* data type for BTA_JV_API_ADD_ATTRIBUTE_EVT */
typedef struct {
BT_HDR hdr;
UINT32 handle;
UINT16 attr_id;
UINT8 *p_value;
INT32 value_size;
} tBTA_JV_API_ADD_ATTRIBUTE;
/* data type for BTA_JV_API_FREE_SCN_EVT */
typedef struct {
BT_HDR hdr;
INT32 type; /* One of BTA_JV_CONN_TYPE_ */
UINT16 scn;
} tBTA_JV_API_FREE_CHANNEL;
/* data type for BTA_JV_API_ALLOC_CHANNEL_EVT */
typedef struct {
BT_HDR hdr;
INT32 type; /* One of BTA_JV_CONN_TYPE_ */
INT32 channel; /* optionally request a specific channel */
void *user_data;
} tBTA_JV_API_ALLOC_CHANNEL;
/* union of all data types */
typedef union {
/* GKI event buffer header */
BT_HDR hdr;
tBTA_JV_API_ENABLE enable;
tBTA_JV_API_START_DISCOVERY start_discovery;
tBTA_JV_API_ALLOC_CHANNEL alloc_channel;
tBTA_JV_API_FREE_CHANNEL free_channel;
tBTA_JV_API_CREATE_RECORD create_record;
tBTA_JV_API_ADD_ATTRIBUTE add_attr;
tBTA_JV_API_L2CAP_CONNECT l2cap_connect;
tBTA_JV_API_L2CAP_READ l2cap_read;
tBTA_JV_API_L2CAP_WRITE l2cap_write;
tBTA_JV_API_L2CAP_CLOSE l2cap_close;
tBTA_JV_API_L2CAP_SERVER l2cap_server;
tBTA_JV_API_RFCOMM_CONNECT rfcomm_connect;
tBTA_JV_API_RFCOMM_READ rfcomm_read;
tBTA_JV_API_RFCOMM_WRITE rfcomm_write;
tBTA_JV_API_SET_PM_PROFILE set_pm;
tBTA_JV_API_PM_STATE_CHANGE change_pm_state;
tBTA_JV_API_RFCOMM_CLOSE rfcomm_close;
tBTA_JV_API_RFCOMM_SERVER rfcomm_server;
tBTA_JV_API_L2CAP_WRITE_FIXED l2cap_write_fixed;
} tBTA_JV_MSG;
/* JV control block */
typedef struct {
/* the SDP handle reported to JV user is the (index + 1) to sdp_handle[].
* if sdp_handle[i]==0, it's not used.
* otherwise sdp_handle[i] is the stack SDP handle. */
UINT32 sdp_handle[BTA_JV_MAX_SDP_REC]; /* SDP records created */
UINT8 *p_sel_raw_data;/* the raw data of last service select */
tBTA_JV_DM_CBACK *p_dm_cback;
tBTA_JV_L2C_CB l2c_cb[BTA_JV_MAX_L2C_CONN]; /* index is GAP handle (index) */
tBTA_JV_RFC_CB rfc_cb[BTA_JV_MAX_RFC_CONN];
tBTA_JV_PCB port_cb[MAX_RFC_PORTS]; /* index of this array is
the port_handle, */
UINT8 sec_id[BTA_JV_NUM_SERVICE_ID]; /* service ID */
BOOLEAN scn[BTA_JV_MAX_SCN]; /* SCN allocated by java */
UINT16 free_psm_list[BTA_JV_MAX_L2C_CONN]; /* PSMs freed by java
(can be reused) */
UINT8 sdp_active; /* see BTA_JV_SDP_ACT_* */
tSDP_UUID uuid; /* current uuid of sdp discovery*/
tBTA_JV_PM_CB pm_cb[BTA_JV_PM_MAX_NUM]; /* PM on a per JV handle bases */
} tBTA_JV_CB;
enum {
BTA_JV_SDP_ACT_NONE = 0,
BTA_JV_SDP_ACT_YES, /* waiting for SDP result */
BTA_JV_SDP_ACT_CANCEL /* waiting for cancel complete */
};
/* JV control block */
#if BTA_DYNAMIC_MEMORY == FALSE
extern tBTA_JV_CB bta_jv_cb;
#else
extern tBTA_JV_CB *bta_jv_cb_ptr;
#define bta_jv_cb (*bta_jv_cb_ptr)
#endif
/* config struct */
extern tBTA_JV_CFG *p_bta_jv_cfg;
extern BOOLEAN bta_jv_sm_execute(BT_HDR *p_msg);
extern void bta_jv_enable (tBTA_JV_MSG *p_data);
extern void bta_jv_disable (tBTA_JV_MSG *p_data);
extern void bta_jv_get_channel_id (tBTA_JV_MSG *p_data);
extern void bta_jv_free_scn (tBTA_JV_MSG *p_data);
extern void bta_jv_start_discovery (tBTA_JV_MSG *p_data);
extern void bta_jv_create_record (tBTA_JV_MSG *p_data);
extern void bta_jv_delete_record (tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_connect (tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_close (tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_start_server (tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_stop_server (tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_read (tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_write (tBTA_JV_MSG *p_data);
extern void bta_jv_rfcomm_connect (tBTA_JV_MSG *p_data);
extern void bta_jv_rfcomm_close (tBTA_JV_MSG *p_data);
extern void bta_jv_rfcomm_start_server (tBTA_JV_MSG *p_data);
extern void bta_jv_rfcomm_stop_server (tBTA_JV_MSG *p_data);
extern void bta_jv_rfcomm_read (tBTA_JV_MSG *p_data);
extern void bta_jv_rfcomm_write (tBTA_JV_MSG *p_data);
extern void bta_jv_set_pm_profile (tBTA_JV_MSG *p_data);
extern void bta_jv_change_pm_state(tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_connect_le (tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_start_server_le (tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_stop_server_le (tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_write_fixed (tBTA_JV_MSG *p_data);
extern void bta_jv_l2cap_close_fixed (tBTA_JV_MSG *p_data);
#endif ///defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE
#endif /* BTA_JV_INT_H */

View File

@ -0,0 +1,100 @@
/******************************************************************************
*
* Copyright (C) 2012 Broadcom Corporation
*
* Licensed 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.
*
******************************************************************************/
/******************************************************************************
*
* This is the main implementation file for the BTA Java I/F
*
******************************************************************************/
#include "bta_api.h"
#include "bta_sys.h"
#include "bta_jv_api.h"
#include "bta_jv_int.h"
#include "bt_target.h"
#if (defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE)
/*****************************************************************************
** Constants and types
*****************************************************************************/
#if BTA_DYNAMIC_MEMORY == FALSE
tBTA_JV_CB bta_jv_cb;
#endif
/* state machine action enumeration list */
#define BTA_JV_NUM_ACTIONS (BTA_JV_MAX_INT_EVT & 0x00ff)
/* type for action functions */
typedef void (*tBTA_JV_ACTION)(tBTA_JV_MSG *p_data);
/* action function list */
const tBTA_JV_ACTION bta_jv_action[] = {
bta_jv_enable, /* BTA_JV_API_ENABLE_EVT */
bta_jv_disable, /* BTA_JV_API_DISABLE_EVT */
bta_jv_get_channel_id, /* BTA_JV_API_GET_CHANNEL_EVT */
bta_jv_free_scn, /* BTA_JV_API_FREE_SCN_EVT */
bta_jv_start_discovery, /* BTA_JV_API_START_DISCOVERY_EVT */
bta_jv_create_record, /* BTA_JV_API_CREATE_RECORD_EVT */
bta_jv_delete_record, /* BTA_JV_API_DELETE_RECORD_EVT */
bta_jv_l2cap_connect, /* BTA_JV_API_L2CAP_CONNECT_EVT */
bta_jv_l2cap_close, /* BTA_JV_API_L2CAP_CLOSE_EVT */
bta_jv_l2cap_start_server, /* BTA_JV_API_L2CAP_START_SERVER_EVT */
bta_jv_l2cap_stop_server, /* BTA_JV_API_L2CAP_STOP_SERVER_EVT */
bta_jv_l2cap_read, /* BTA_JV_API_L2CAP_READ_EVT */
bta_jv_l2cap_write, /* BTA_JV_API_L2CAP_WRITE_EVT */
bta_jv_rfcomm_connect, /* BTA_JV_API_RFCOMM_CONNECT_EVT */
bta_jv_rfcomm_close, /* BTA_JV_API_RFCOMM_CLOSE_EVT */
bta_jv_rfcomm_start_server, /* BTA_JV_API_RFCOMM_START_SERVER_EVT */
bta_jv_rfcomm_stop_server, /* BTA_JV_API_RFCOMM_STOP_SERVER_EVT */
bta_jv_rfcomm_read, /* BTA_JV_API_RFCOMM_READ_EVT */
bta_jv_rfcomm_write, /* BTA_JV_API_RFCOMM_WRITE_EVT */
bta_jv_set_pm_profile, /* BTA_JV_API_SET_PM_PROFILE_EVT */
bta_jv_change_pm_state, /* BTA_JV_API_PM_STATE_CHANGE_EVT */
bta_jv_l2cap_connect_le, /* BTA_JV_API_L2CAP_CONNECT_LE_EVT */
bta_jv_l2cap_start_server_le, /* BTA_JV_API_L2CAP_START_SERVER_LE_EVT */
bta_jv_l2cap_stop_server_le, /* BTA_JV_API_L2CAP_STOP_SERVER_LE_EVT */
bta_jv_l2cap_write_fixed, /* BTA_JV_API_L2CAP_WRITE_FIXED_EVT */
bta_jv_l2cap_close_fixed, /* BTA_JV_API_L2CAP_CLOSE_FIXED_EVT */
};
/*******************************************************************************
**
** Function bta_jv_sm_execute
**
** Description State machine event handling function for JV
**
**
** Returns void
**
*******************************************************************************/
BOOLEAN bta_jv_sm_execute(BT_HDR *p_msg)
{
BOOLEAN ret = FALSE;
UINT16 action = (p_msg->event & 0x00ff);
/* execute action functions */
if (action < BTA_JV_NUM_ACTIONS) {
(*bta_jv_action[action])((tBTA_JV_MSG *)p_msg);
ret = TRUE;
}
return (ret);
}
#endif ///defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE

View File

@ -34,8 +34,13 @@
#include "btc_gap_bt.h"
#endif /* BTC_GAP_BT_INCLUDED == TRUE */
#include "btc_profile_queue.h"
#if BTC_AV_INCLUDED
#include "btc_av.h"
#include "btc_avrc.h"
#endif /* #if BTC_AV_INCLUDED */
#if CONFIG_BT_SPP_ENABLED
#include "btc_spp.h"
#endif /* #if CONFIG_BT_SPP_ENABLED */
#endif /* #if CONFIG_CLASSIC_BT_ENABLED */
@ -64,8 +69,13 @@ static btc_func_t profile_tab[BTC_PID_NUM] = {
[BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, NULL },
#endif /* (BTC_GAP_BT_INCLUDED == TRUE) */
[BTC_PID_PRF_QUE] = {btc_profile_queue_handler, NULL },
#if BTC_AV_INCLUDED
[BTC_PID_A2DP] = {btc_a2dp_call_handler, btc_a2dp_cb_handler },
[BTC_PID_AVRC] = {btc_avrc_call_handler, NULL },
#endif /* #if BTC_AV_INCLUDED */
#if CONFIG_BT_SPP_ENABLED
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
#endif /* #if CONFIG_BT_SPP_ENABLED */
#endif /* #if CONFIG_CLASSIC_BT_ENABLED */
};

View File

@ -160,3 +160,22 @@ void uuid128_be_to_esp_uuid(esp_bt_uuid_t *u, uint8_t* uuid128)
return;
}
void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str)
{
uint32_t uuid0, uuid4;
uint16_t uuid1, uuid2, uuid3, uuid5;
memcpy(&uuid0, &(p_uuid->uu[0]), 4);
memcpy(&uuid1, &(p_uuid->uu[4]), 2);
memcpy(&uuid2, &(p_uuid->uu[6]), 2);
memcpy(&uuid3, &(p_uuid->uu[8]), 2);
memcpy(&uuid4, &(p_uuid->uu[10]), 4);
memcpy(&uuid5, &(p_uuid->uu[14]), 2);
sprintf((char *)str, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
ntohl(uuid0), ntohs(uuid1),
ntohs(uuid2), ntohs(uuid3),
ntohl(uuid4), ntohs(uuid5));
return;
}

View File

@ -52,6 +52,7 @@ typedef enum {
BTC_PID_PRF_QUE,
BTC_PID_A2DP,
BTC_PID_AVRC,
BTC_PID_SPP,
#endif /* CONFIG_CLASSIC_BT_ENABLED */
BTC_PID_NUM,
} btc_pid_t; //btc profile id

View File

@ -42,4 +42,6 @@ UINT32 devclass2uint(DEV_CLASS dev_class);
void uint2devclass(UINT32 dev, DEV_CLASS dev_class);
void uuid128_be_to_esp_uuid(esp_bt_uuid_t *u, uint8_t* uuid128);
void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str);
#endif /* __BTC_UTIL_H__ */

View File

@ -0,0 +1,89 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 __BTC_SPP_H__
#define __BTC_SPP_H__
#include "btc_task.h"
#include "esp_bt_defs.h"
#include "esp_spp_api.h"
#include "bt_target.h"
#include "bta_jv_api.h"
#if (defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE)
#define ESP_SPP_MAX_SESSION BTA_JV_MAX_RFC_SR_SESSION
#define ESP_SPP_SERVER_NAME_MAX 32
typedef enum {
BTC_SPP_ACT_INIT = 0,
BTC_SPP_ACT_UNINIT,
BTC_SPP_ACT_START_DISCOVERY,
BTC_SPP_ACT_CONNECT,
BTC_SPP_ACT_DISCONNECT,
BTC_SPP_ACT_START_SRV,
BTC_SPP_ACT_WRITE,
} btc_spp_act_t;
/* btc_spp_args_t */
typedef union {
//BTC_SPP_ACT_INIT
struct init_arg {
} init;
//BTC_SPP_ACT_UNINIT
struct uninit_arg {
} uninit;
//BTC_SPP_ACT_START_DISCOVERY
struct start_discovery_arg {
BD_ADDR bd_addr;
UINT16 num_uuid;
tSDP_UUID *p_uuid_list;
} start_discovery;
//BTC_SPP_ACT_CONNECT
struct connect_arg {
esp_spp_sec_t sec_mask;
esp_spp_role_t role;
UINT8 remote_scn;
esp_bd_addr_t peer_bd_addr;
} connect;
//BTC_SPP_ACT_DISCONNECT
struct disconnect_arg {
UINT32 handle;
} disconnect;
//BTC_SPP_ACT_START_SRV
struct start_srv_arg {
esp_spp_sec_t sec_mask;
esp_spp_role_t role;
UINT8 local_scn;
UINT8 max_session;
char name[ESP_SPP_SERVER_NAME_MAX + 1];
} start_srv;
//BTC_SPP_ACT_WRITE
struct write_arg {
UINT32 handle;
int len;
UINT8 *p_data;
} write;
} btc_spp_args_t;
void btc_spp_call_handler(btc_msg_t *msg);
void btc_spp_cb_handler(btc_msg_t *msg);
void btc_spp_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
#endif ///defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE
#endif ///__BTC_SPP_H__

View File

@ -0,0 +1,544 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#include <string.h>
#include "btc_spp.h"
#include "btc_manage.h"
#include "btc_task.h"
#include "bta_jv_api.h"
#include "bt_trace.h"
#include "allocator.h"
#include "esp_spp_api.h"
#include "list.h"
#if (defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE)
typedef struct {
uint8_t serial;
bool connected;
uint8_t scn;
uint8_t max_session;
uint32_t id;
uint32_t mtu;//unused
uint32_t sdp_handle;
uint32_t rfc_handle;
uint32_t rfc_port_handle;
esp_spp_role_t role;
esp_spp_sec_t security;
esp_bd_addr_t addr;
list_t *list;
uint8_t service_uuid[16];
char service_name[ESP_SPP_SERVER_NAME_MAX];
} spp_slot_t;
static spp_slot_t *spp_slots[BTA_JV_MAX_RFC_SR_SESSION + 1];
static uint32_t spp_slot_id = 0;
static void spp_osi_free(void *p)
{
osi_free(p);
}
static spp_slot_t *malloc_spp_slot(void)
{
if (++spp_slot_id == 0) {
spp_slot_id = 1;
}
for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
if (spp_slots[i] == NULL) {
spp_slots[i] = (spp_slot_t *)osi_malloc(sizeof(spp_slot_t));
if (!spp_slots[i]) {
return NULL;
}
spp_slots[i]->id = spp_slot_id;
spp_slots[i]->serial = i;
spp_slots[i]->connected = FALSE;
spp_slots[i]->list = list_new(spp_osi_free);
return spp_slots[i];
}
}
return NULL;
}
static spp_slot_t *find_slot_by_id(uint32_t id)
{
for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
if (spp_slots[i] != NULL && spp_slots[i]->id == id) {
return spp_slots[i];
}
}
return NULL;
}
static spp_slot_t *find_slot_by_handle(uint32_t handle)
{
for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
if (spp_slots[i] != NULL && spp_slots[i]->rfc_handle == handle) {
return spp_slots[i];
}
}
return NULL;
}
static void free_spp_slot(spp_slot_t *slot)
{
if (!slot) {
return;
}
spp_slots[slot->serial] = NULL;
list_free(slot->list);
osi_free(slot);
}
static inline void btc_spp_cb_to_app(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
esp_spp_cb_t *btc_spp_cb = (esp_spp_cb_t *)btc_profile_cb_get(BTC_PID_SPP);
if (btc_spp_cb) {
btc_spp_cb(event, param);
}
}
static void btc_create_server_fail_cb(void)
{
esp_spp_cb_param_t param;
param.start.status = ESP_SPP_FAILURE;
btc_spp_cb_to_app(ESP_SPP_START_EVT, &param);
}
static void btc_disconnect_cb(uint32_t handle)
{
esp_spp_cb_param_t param;
param.close.status = ESP_SPP_SUCCESS;
param.close.handle = handle;
param.close.async = FALSE;
btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, &param);
}
static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
{
bt_status_t status;
btc_msg_t msg;
void *new_user_data = NULL;
uint32_t id = (uintptr_t)user_data;
spp_slot_t *slot, *slot_new;
switch (event) {
case BTA_JV_RFCOMM_SRV_OPEN_EVT:
slot = find_slot_by_id(id);
if (!slot) {
LOG_ERROR("%s unable to find RFCOMM slot!", __func__);
break;
}
slot_new = malloc_spp_slot();
if (!slot_new) {
LOG_ERROR("%s unable to malloc RFCOMM slot!", __func__);
break;
}
new_user_data = (void *)(uintptr_t)slot_new->id;
slot_new->security = slot->security;
slot_new->role = slot->role;
slot_new->scn = slot->scn;;
slot_new->max_session = slot->max_session;
strcpy(slot_new->service_name, slot->service_name);
slot_new->sdp_handle = slot->sdp_handle;
slot_new->rfc_handle = p_data->rfc_srv_open.new_listen_handle;
slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_srv_open.new_listen_handle);
memcpy(slot->addr, p_data->rfc_srv_open.rem_bda, ESP_BD_ADDR_LEN);
slot->connected = TRUE;
slot->rfc_handle = p_data->rfc_srv_open.handle;
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_srv_open.handle);
break;
case BTA_JV_RFCOMM_OPEN_EVT:
slot = find_slot_by_id(id);
if (!slot) {
LOG_ERROR("%s unable to find RFCOMM slot!", __func__);
break;
}
slot->connected = TRUE;
slot->rfc_handle = p_data->rfc_open.handle;
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_open.handle);
break;
case BTA_JV_RFCOMM_CLOSE_EVT:
slot = find_slot_by_id(id);
if (!slot) {
LOG_ERROR("%s unable to find RFCOMM slot!", __func__);
break;
}
if (slot->connected) {
BTA_JvRfcommClose(slot->rfc_handle, (void *)slot->id);
}
free_spp_slot(slot);
break;
case BTA_JV_RFCOMM_DATA_IND_EVT:
break;
default:
break;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_SPP;
msg.act = event;
status = btc_transfer_context(&msg, p_data,
sizeof(tBTA_JV), NULL);
if (status != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed", __func__);
}
return new_user_data;
}
static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
{
bt_status_t status;
btc_msg_t msg;
uint32_t id = (uintptr_t)user_data;
spp_slot_t *slot;
switch (event) {
case BTA_JV_GET_SCN_EVT:
slot = find_slot_by_id(id);
if (!slot) {
LOG_ERROR("%s unable to find RFCOMM slot!", __func__);
break;
}
if (p_data->scn == 0) {
LOG_ERROR("%s unable to get scn, start server fail!", __func__);
btc_create_server_fail_cb();
free_spp_slot(slot);
break;
}
slot->scn = p_data->scn;
BTA_JvCreateRecordByUser(slot->service_name, slot->scn, (void *)slot->id);
break;
case BTA_JV_CREATE_RECORD_EVT:
slot = find_slot_by_id(id);
if (!slot) {
LOG_ERROR("%s unable to find RFCOMM slot!", __func__);
break;
}
if (p_data->create_rec.status == BTA_JV_SUCCESS) {
slot->sdp_handle = p_data->create_rec.handle;
BTA_JvRfcommStartServer(slot->security, slot->role, slot->scn,
slot->max_session, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)slot->id);
} else {
LOG_ERROR("%s unable to create record, start server fail!", __func__);
btc_create_server_fail_cb();
BTA_JvFreeChannel(slot->scn, BTA_JV_CONN_TYPE_RFCOMM);
free_spp_slot(slot);
}
break;
default:
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_SPP;
msg.act = event;
status = btc_transfer_context(&msg, p_data, sizeof(tBTA_JV), NULL);
if (status != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed\n", __func__);
}
break;
}
}
static void btc_spp_init(void)
{
BTA_JvEnable((tBTA_JV_DM_CBACK *)btc_spp_dm_inter_cb);
}
static void btc_spp_uninit(void)
{
for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
if (spp_slots[i] != NULL && spp_slots[i]->connected) {
BTA_JvRfcommClose(spp_slots[i]->rfc_handle, (void *)spp_slots[i]->id);
free_spp_slot(spp_slots[i]);
spp_slots[i] = NULL;
}
}
for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
if (spp_slots[i] != NULL && !(spp_slots[i]->connected)) {
BTA_JvDeleteRecord(spp_slots[i]->sdp_handle);
BTA_JvFreeChannel(spp_slots[i]->scn, BTA_JV_CONN_TYPE_RFCOMM);
free_spp_slot(spp_slots[i]);
spp_slots[i] = NULL;
}
}
BTA_JvDisable();
}
static void btc_spp_start_discovery(btc_spp_args_t *arg)
{
BTA_JvStartDiscovery(arg->start_discovery.bd_addr, arg->start_discovery.num_uuid, arg->start_discovery.p_uuid_list, NULL);
}
static void btc_spp_connect(btc_spp_args_t *arg)
{
spp_slot_t *slot = malloc_spp_slot();
if (!slot) {
LOG_ERROR("%s unable to malloc RFCOMM slot!", __func__);
return;
}
slot->security = arg->connect.sec_mask;
slot->role = arg->connect.role;
slot->scn = arg->connect.remote_scn;;
memcpy(slot->addr, arg->connect.peer_bd_addr, ESP_BD_ADDR_LEN);
BTA_JvRfcommConnect(arg->connect.sec_mask, arg->connect.role, arg->connect.remote_scn,
arg->connect.peer_bd_addr, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)slot->id);
}
static void btc_spp_disconnect(btc_spp_args_t *arg)
{
spp_slot_t *slot = find_slot_by_handle(arg->disconnect.handle);
if (!slot) {
LOG_ERROR("%s unable to find RFCOMM slot! disconnect fail!", __func__);
return;
}
BTA_JvRfcommClose(arg->disconnect.handle, (void *)slot->id);
btc_disconnect_cb(slot->rfc_handle);
free_spp_slot(slot);
}
static void btc_spp_start_srv(btc_spp_args_t *arg)
{
spp_slot_t *slot = malloc_spp_slot();
if (!slot) {
LOG_ERROR("%s unable to malloc RFCOMM slot!", __func__);
return;
}
slot->security = arg->start_srv.sec_mask;
slot->role = arg->start_srv.role;
slot->scn = arg->start_srv.local_scn;;
slot->max_session = arg->start_srv.max_session;
strcpy(slot->service_name, arg->start_srv.name);
BTA_JvGetChannelId(BTA_JV_CONN_TYPE_RFCOMM, (void *)slot->id, arg->start_srv.local_scn);
}
static void btc_spp_write(btc_spp_args_t *arg)
{
spp_slot_t *slot = find_slot_by_handle(arg->write.handle);
if (!slot) {
LOG_ERROR("%s unable to find RFCOMM slot! disconnect fail!", __func__);
return;
}
list_append(slot->list, arg->write.p_data);
BTA_JvRfcommWrite(arg->write.handle, slot->id, arg->write.len, arg->write.p_data);
}
void btc_spp_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_spp_args_t *dst = (btc_spp_args_t *) p_dest;
btc_spp_args_t *src = (btc_spp_args_t *) p_src;
switch (msg->act) {
case BTC_SPP_ACT_START_DISCOVERY:
dst->start_discovery.p_uuid_list = (tSDP_UUID *)osi_malloc(src->start_discovery.num_uuid * sizeof(tSDP_UUID));
if (dst->start_discovery.p_uuid_list) {
memcpy(dst->start_discovery.p_uuid_list, src->start_discovery.p_uuid_list, src->start_discovery.num_uuid * sizeof(tSDP_UUID));
} else if (src->start_discovery.num_uuid == 0) {
LOG_ERROR("%s %d no mem\n", __func__, msg->act);
} else {
LOG_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
}
break;
case BTC_SPP_ACT_WRITE:
dst->write.p_data = (uint8_t *)osi_malloc(src->write.len);
if (dst->write.p_data) {
memcpy(dst->write.p_data, src->write.p_data, src->write.len);
} else if (src->write.len == 0) {
LOG_DEBUG("%s %d no mem\n", __func__, msg->act);
} else {
LOG_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
}
break;
default:
break;
}
}
void btc_spp_arg_deep_free(btc_msg_t *msg)
{
btc_spp_args_t *arg = (btc_spp_args_t *)msg->arg;
switch (msg->act) {
case BTC_SPP_ACT_START_DISCOVERY:
if (arg->start_discovery.p_uuid_list) {
osi_free(arg->start_discovery.p_uuid_list);
}
break;
default:
break;
}
}
void btc_spp_call_handler(btc_msg_t *msg)
{
btc_spp_args_t *arg = (btc_spp_args_t *)(msg->arg);
switch (msg->act) {
case BTC_SPP_ACT_INIT:
btc_spp_init();
break;
case BTC_SPP_ACT_UNINIT:
btc_spp_uninit();
break;
case BTC_SPP_ACT_START_DISCOVERY:
btc_spp_start_discovery(arg);
break;
case BTC_SPP_ACT_CONNECT:
btc_spp_connect(arg);
break;
case BTC_SPP_ACT_DISCONNECT:
btc_spp_disconnect(arg);
break;
case BTC_SPP_ACT_START_SRV:
btc_spp_start_srv(arg);
break;
case BTC_SPP_ACT_WRITE:
btc_spp_write(arg);
break;
default:
LOG_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
break;
}
btc_spp_arg_deep_free(msg);
}
void btc_spp_cb_handler(btc_msg_t *msg)
{
esp_spp_cb_param_t param;
tBTA_JV *p_data = (tBTA_JV *)msg->arg;
switch (msg->act) {
case BTA_JV_ENABLE_EVT:
param.init.status = p_data->status;
btc_spp_cb_to_app(ESP_SPP_INIT_EVT, &param);
break;
case BTA_JV_DISCOVERY_COMP_EVT:
param.disc_comp.status = p_data->disc_comp.status;
param.disc_comp.scn_num = p_data->disc_comp.scn_num;
memcpy(param.disc_comp.scn, p_data->disc_comp.scn, p_data->disc_comp.scn_num);
btc_spp_cb_to_app(ESP_SPP_DISCOVERY_COMP_EVT, &param);
break;
case BTA_JV_RFCOMM_CL_INIT_EVT:
param.cl_init.status = p_data->rfc_cl_init.status;
param.cl_init.handle = p_data->rfc_cl_init.handle;
param.cl_init.sec_id = p_data->rfc_cl_init.sec_id;
param.cl_init.use_co = p_data->rfc_cl_init.use_co;
btc_spp_cb_to_app(ESP_SPP_CL_INIT_EVT, &param);
break;
case BTA_JV_RFCOMM_OPEN_EVT:
param.open.status = p_data->rfc_open.status;
param.open.handle = p_data->rfc_open.handle;
memcpy(param.open.rem_bda, p_data->rfc_open.rem_bda, ESP_BD_ADDR_LEN);
btc_spp_cb_to_app(ESP_SPP_OPEN_EVT, &param);
break;
case BTA_JV_RFCOMM_START_EVT:
param.start.status = p_data->rfc_start.status;
param.start.handle = p_data->rfc_start.handle;
param.start.sec_id = p_data->rfc_start.sec_id;
param.start.use_co = p_data->rfc_start.use_co;
btc_spp_cb_to_app(ESP_SPP_START_EVT, &param);
break;
case BTA_JV_RFCOMM_SRV_OPEN_EVT:
param.srv_open.status = p_data->rfc_srv_open.status;
param.srv_open.handle = p_data->rfc_srv_open.handle;
param.srv_open.new_listen_handle = p_data->rfc_srv_open.new_listen_handle;
memcpy(param.srv_open.rem_bda, p_data->rfc_srv_open.rem_bda, ESP_BD_ADDR_LEN);
btc_spp_cb_to_app(ESP_SPP_SRV_OPEN_EVT, &param);
break;
case BTA_JV_RFCOMM_WRITE_EVT:
param.write.status = p_data->rfc_write.status;
param.write.handle = p_data->rfc_write.handle;
param.write.req_id = p_data->rfc_write.req_id;
param.write.len = p_data->rfc_write.len;
param.write.cong = p_data->rfc_write.cong;
btc_spp_cb_to_app(ESP_SPP_WRITE_EVT, &param);
spp_slot_t *slot = find_slot_by_handle(p_data->rfc_write.handle);
if (!slot) {
LOG_ERROR("%s unable to find RFCOMM slot! disconnect fail!", __func__);
break;
}
list_remove(slot->list, list_front(slot->list));
break;
case BTA_JV_RFCOMM_CLOSE_EVT:
param.close.status = p_data->rfc_close.status;
param.close.port_status = p_data->rfc_close.port_status;
param.close.handle = p_data->rfc_close.handle;
param.close.async = p_data->rfc_close.async;
btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, &param);
break;
case BTA_JV_RFCOMM_CONG_EVT:
param.cong.status = p_data->rfc_cong.status;
param.cong.handle = p_data->rfc_cong.handle;
param.cong.cong = p_data->rfc_cong.cong;
btc_spp_cb_to_app(ESP_SPP_CONG_EVT, &param);
break;
case BTA_JV_RFCOMM_DATA_IND_EVT:
param.data_ind.status = ESP_SPP_SUCCESS;
param.data_ind.handle = p_data->data_ind.handle;
if (p_data->data_ind.p_buf) {
param.data_ind.len = p_data->data_ind.p_buf->len;
param.data_ind.data = p_data->data_ind.p_buf->data + p_data->data_ind.p_buf->offset;
} else {
param.data_ind.len = 0;
param.data_ind.data = NULL;
}
btc_spp_cb_to_app(ESP_SPP_DATA_IND_EVT, &param);
osi_free (p_data->data_ind.p_buf);
break;
default:
LOG_DEBUG("%s: Unhandled event (%d)!", __FUNCTION__, msg->act);
break;
}
}
int bta_co_rfc_data_incoming(void *user_data, BT_HDR *p_buf)
{
bt_status_t status;
tBTA_JV p_data;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_SPP;
msg.act = BTA_JV_RFCOMM_DATA_IND_EVT;
uint32_t id = (uintptr_t)user_data;
spp_slot_t *slot = find_slot_by_id(id);
if (!slot) {
LOG_ERROR("%s unable to find RFCOMM slot!", __func__);
return 0;
}
p_data.data_ind.handle = slot->rfc_handle;
p_data.data_ind.p_buf = p_buf;
status = btc_transfer_context(&msg, &p_data,
sizeof(tBTA_JV), NULL);
if (status != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed\n", __func__);
}
// osi_free (p_buf);
return 1;
}
int bta_co_rfc_data_outgoing_size(void *user_data, int *size)
{
return 1;
}
int bta_co_rfc_data_outgoing(void *user_data, uint8_t *buf, uint16_t size)
{
return 1;
}
#endif ///defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE

View File

@ -44,24 +44,47 @@
#define BTA_SDP_INCLUDED TRUE
#define BTA_PAN_INCLUDED FALSE
#define BTA_HH_INCLUDED FALSE
#define SDP_INCLUDED TRUE
#if CONFIG_A2DP_SNK_ENABLED
#define BTA_AR_INCLUDED TRUE
#define BTA_AV_INCLUDED TRUE
#define BTA_AV_SINK_INCLUDED TRUE
#define SDP_INCLUDED TRUE
#define RFCOMM_INCLUDED FALSE
#define PAN_INCLUDED FALSE
#define HID_HOST_INCLUDED FALSE
#define AVDT_INCLUDED TRUE
#define A2D_INCLUDED TRUE
#define AVCT_INCLUDED TRUE
#define AVRC_INCLUDED TRUE
#define BTC_AV_INCLUDED TRUE
#define SBC_DEC_INCLUDED TRUE
#else
#define BTA_AR_INCLUDED FALSE
#define BTA_AV_INCLUDED FALSE
#define BTA_AV_SINK_INCLUDED FALSE
#define AVDT_INCLUDED FALSE
#define A2D_INCLUDED FALSE
#define AVCT_INCLUDED FALSE
#define AVRC_INCLUDED FALSE
#define BTC_AV_INCLUDED FALSE
#define SBC_DEC_INCLUDED FALSE
#endif /* CONFIG_A2DP_SNK_ENABLED */
#if CONFIG_BT_SPP_ENABLED
#define RFCOMM_INCLUDED TRUE
#define BTA_JV_INCLUDED TRUE
#define BTC_SPP_INCLUDED TRUE
#else /* #if CONFIG_BT_SPP_ENABLED */
#define RFCOMM_INCLUDED FALSE
#define BTA_JV_INCLUDED FALSE
#define BTC_SPP_INCLUDED FALSE
#endif /* #if CONFIG_BT_SPP_ENABLED */
#define PAN_INCLUDED FALSE
#define HID_HOST_INCLUDED FALSE
#define SBC_ENC_INCLUDED FALSE
#define MCA_INCLUDED FALSE
#define BTC_SM_INCLUDED TRUE
#define BTC_PRF_QUEUE_INCLUDED TRUE
#define BTC_GAP_BT_INCLUDED TRUE
#define BTC_AV_INCLUDED TRUE
#else /* #if CONFIG_CLASSIC_BT_ENABLED */
#define CLASSIC_BT_INCLUDED FALSE
@ -73,6 +96,8 @@
#define BTA_AV_SINK_INCLUDED FALSE
#define SDP_INCLUDED FALSE
#define RFCOMM_INCLUDED FALSE
#define BTA_JV_INCLUDED FALSE
#define BTC_SPP_INCLUDED FALSE
#define PAN_INCLUDED FALSE
#define HID_HOST_INCLUDED FALSE
#define AVDT_INCLUDED FALSE

View File

@ -498,6 +498,34 @@ void btu_stop_timer(TIMER_LIST_ENT *p_tle)
osi_alarm_cancel(alarm);
}
/*******************************************************************************
**
** Function btu_free_timer
**
** Description Stop and free a timer.
**
** Returns void
**
*******************************************************************************/
void btu_free_timer(TIMER_LIST_ENT *p_tle)
{
assert(p_tle != NULL);
if (p_tle->in_use == FALSE) {
return;
}
p_tle->in_use = FALSE;
// Get the alarm for the timer list entry.
osi_alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
if (alarm == NULL) {
LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
return;
}
osi_alarm_cancel(alarm);
hash_map_erase(btu_general_alarm_hash_map, p_tle);
}
#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
/*******************************************************************************
**

View File

@ -234,6 +234,7 @@ extern const BD_ADDR BT_BD_ANY;
*/
void btu_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout);
void btu_stop_timer (TIMER_LIST_ENT *p_tle);
void btu_free_timer (TIMER_LIST_ENT *p_tle);
void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout);
void btu_stop_timer_oneshot(TIMER_LIST_ENT *p_tle);

View File

@ -598,7 +598,7 @@ extern int PORT_WriteData (UINT16 handle, char *p_data, UINT16 max_len,
** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
**
*******************************************************************************/
extern int PORT_WriteDataCO (UINT16 handle, int *p_len);
extern int PORT_WriteDataCO (UINT16 handle, int *p_len, int len, UINT8 *p_data);
/*******************************************************************************
**

View File

@ -28,6 +28,8 @@
#include "bt_target.h"
#include "rfcdefs.h"
#include "port_api.h"
#include "fixed_queue.h"
#include "bt_defs.h"
/* Local events passed when application event is sent from the api to PORT */
/* ???*/

View File

@ -32,7 +32,10 @@
#include "rfc_int.h"
#include "l2c_api.h"
#include "sdp_api.h"
#include "allocator.h"
#include "mutex.h"
#if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
/* duration of break in 200ms units */
#define PORT_BREAK_DURATION 1
@ -366,7 +369,7 @@ int PORT_SetDataCallback (UINT16 port_handle, tPORT_DATA_CALLBACK *p_port_cb)
{
tPORT *p_port;
RFCOMM_TRACE_API ("PORT_SetDataCallback() handle:%d cb 0x%x", port_handle, p_port_cb);
// RFCOMM_TRACE_API ("PORT_SetDataCallback() handle:%d cb 0x%x", port_handle, p_port_cb);
/* Check if handle is valid to avoid crashing */
if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
@ -400,7 +403,7 @@ int PORT_SetDataCOCallback (UINT16 port_handle, tPORT_DATA_CO_CALLBACK *p_port_c
{
tPORT *p_port;
RFCOMM_TRACE_API ("PORT_SetDataCOCallback() handle:%d cb 0x%x", port_handle, p_port_cb);
// RFCOMM_TRACE_API ("PORT_SetDataCOCallback() handle:%d cb 0x%x", port_handle, p_port_cb);
/* Check if handle is valid to avoid crashing */
if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
@ -1173,8 +1176,7 @@ int PORT_ReadData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
return (PORT_LINE_ERR);
}
if (fixed_queue_is_empty(p_port->rx.queue))
if (!p_buf) {
if (fixed_queue_is_empty(p_port->rx.queue)){
return (PORT_SUCCESS);
}
@ -1317,7 +1319,7 @@ static int port_write (tPORT *p_port, BT_HDR *p_buf)
|| ((p_port->port_ctrl & (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)) !=
(PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED))) {
if ((p_port->tx.queue_size > PORT_TX_CRITICAL_WM)
|| (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_CRITICAL_WM))
|| (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_CRITICAL_WM)){
RFCOMM_TRACE_WARNING ("PORT_Write: Queue size: %d",
p_port->tx.queue_size);
@ -1421,7 +1423,7 @@ int PORT_Write (UINT16 handle, BT_HDR *p_buf)
** p_len - Byte count returned
**
*******************************************************************************/
int PORT_WriteDataCO (UINT16 handle, int *p_len)
int PORT_WriteDataCO (UINT16 handle, int *p_len, int len, UINT8 *p_data)
{
tPORT *p_port;
@ -1449,12 +1451,7 @@ int PORT_WriteDataCO (UINT16 handle, int *p_len)
return (PORT_UNKNOWN_ERROR);
}
int available = 0;
//if(ioctl(fd, FIONREAD, &available) < 0)
if (p_port->p_data_co_callback(handle, (UINT8 *)&available, sizeof(available),
DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE) == FALSE) {
RFCOMM_TRACE_ERROR("p_data_co_callback DATA_CO_CALLBACK_TYPE_INCOMING_SIZE failed, available:%d", available);
return (PORT_UNKNOWN_ERROR);
}
available = len;
if (available == 0) {
return PORT_SUCCESS;
}
@ -1469,16 +1466,7 @@ int PORT_WriteDataCO (UINT16 handle, int *p_len)
if (((p_buf = (BT_HDR *)fixed_queue_try_peek_last(p_port->tx.queue)) != NULL)
&& (((int)p_buf->len + available) <= (int)p_port->peer_mtu)
&& (((int)p_buf->len + available) <= (int)length)) {
//if(recv(fd, (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, available, 0) != available)
if (p_port->p_data_co_callback(handle, (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len,
available, DATA_CO_CALLBACK_TYPE_OUTGOING) == FALSE)
{
RFCOMM_TRACE_ERROR("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, available:%d", available);
osi_mutex_global_unlock();
return (PORT_UNKNOWN_ERROR);
}
//memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, available);
p_port->tx.queue_size += (UINT16)available;
*p_len = available;
@ -1524,14 +1512,7 @@ int PORT_WriteDataCO (UINT16 handle, int *p_len)
p_buf->len = length;
p_buf->event = BT_EVT_TO_BTU_SP_DATA;
//memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, length);
//if(recv(fd, (UINT8 *)(p_buf + 1) + p_buf->offset, (int)length, 0) != (int)length)
if (p_port->p_data_co_callback(handle, (UINT8 *)(p_buf + 1) + p_buf->offset, length,
DATA_CO_CALLBACK_TYPE_OUTGOING) == FALSE) {
RFCOMM_TRACE_ERROR("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, length:%d", length);
return (PORT_UNKNOWN_ERROR);
}
memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, length);
RFCOMM_TRACE_EVENT ("PORT_WriteData %d bytes", length);
@ -1610,14 +1591,14 @@ int PORT_WriteData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
}
/* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len */
length = RFCOMM_DATA_POOL_BUF_SIZE -
length = RFCOMM_DATA_BUF_SIZE -
(UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
/* If there are buffers scheduled for transmission check if requested */
/* data fits into the end of the queue */
osi_mutex_global_lock();
if (((p_buf = (BT_HDR *)fixed_queue_try_peek_last(p_port->tx.queue)) != NULL) {
if (((p_buf = (BT_HDR *)fixed_queue_try_peek_last(p_port->tx.queue)) != NULL)
&& ((p_buf->len + max_len) <= p_port->peer_mtu)
&& ((p_buf->len + max_len) <= length)) {
memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
@ -1800,3 +1781,5 @@ const char *PORT_GetResultString (const uint8_t result_code)
return result_code_strings[result_code];
}
#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)

View File

@ -32,7 +32,9 @@
#include "port_int.h"
#include "rfc_int.h"
#include "bt_defs.h"
#include "mutex.h"
#include "allocator.h"
#if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
/*
** Local function definitions
*/
@ -1090,3 +1092,6 @@ void port_get_credits (tPORT *p_port, UINT8 k)
p_port->tx.peer_fc = TRUE;
}
}
#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)

View File

@ -31,6 +31,9 @@
#include "l2cdefs.h"
#include "btm_int.h"
#include "btu.h"
#include "mutex.h"
#include "allocator.h"
#if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
static const tPORT_STATE default_port_pars = {
PORT_BAUD_RATE_9600,
@ -564,3 +567,5 @@ void port_flow_control_peer(tPORT *p_port, BOOLEAN enable, UINT16 count)
}
}
#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)

View File

@ -32,8 +32,10 @@
#include "l2cdefs.h"
#include "rfc_int.h"
#include "bt_defs.h"
#include "allocator.h"
#include "mutex.h"
#include "alarm.h"
#if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
/*
** Define Callback functions to be called by L2CAP
*/
@ -413,3 +415,5 @@ void rfc_save_lcid_mcb (tRFC_MCB *p_mcb, UINT16 lcid)
{
rfc_cb.rfc.p_rfc_lcid_mcb[lcid - L2CAP_BASE_APPL_CID] = p_mcb;
}
#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)

View File

@ -31,6 +31,10 @@
#include "l2c_api.h"
#include "rfc_int.h"
#include "bt_defs.h"
#include "allocator.h"
#include "mutex.h"
#include "bt_target.h"
#if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
#define L2CAP_SUCCESS 0
#define L2CAP_ERROR 1
@ -572,7 +576,7 @@ static void rfc_mx_send_config_req (tRFC_MCB *p_mcb)
*******************************************************************************/
static void rfc_mx_conf_cnf (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg)
{
RFCOMM_TRACE_EVENT ("rfc_mx_conf_cnf p_cfg:%08x res:%d ", p_cfg, (p_cfg) ? p_cfg->result : 0);
// RFCOMM_TRACE_EVENT ("rfc_mx_conf_cnf p_cfg:%08x res:%d ", p_cfg, (p_cfg) ? p_cfg->result : 0);
if (p_cfg->result != L2CAP_CFG_OK) {
if (p_mcb->is_initiator) {
@ -639,3 +643,5 @@ static void rfc_mx_conf_ind (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg)
}
}
}
#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)

View File

@ -31,6 +31,9 @@
#include "port_int.h"
#include "rfc_int.h"
#include "bt_defs.h"
#include "allocator.h"
#include "mutex.h"
#if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
/********************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
@ -895,3 +898,4 @@ void rfc_set_port_state(tPORT_STATE *port_pars, MX_FRAME *p_frame)
}
}
#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)

View File

@ -32,6 +32,8 @@
#include "rfc_int.h"
#include "bt_defs.h"
#if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
#if RFC_DYNAMIC_MEMORY == FALSE
tRFC_CB rfc_cb;
#endif
@ -372,3 +374,4 @@ void RFCOMM_DataReq (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
}
#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)

View File

@ -29,6 +29,9 @@
#include "l2c_api.h"
#include "port_int.h"
#include "rfc_int.h"
#include "mutex.h"
#include "allocator.h"
#if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
/*******************************************************************************
**
@ -895,3 +898,4 @@ void rfc_process_mx_message (tRFC_MCB *p_mcb, BT_HDR *p_buf)
}
}
#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)

View File

@ -34,8 +34,12 @@
#include "btu.h"
#include "bt_defs.h"
#include "allocator.h"
#include "mutex.h"
#include <string.h>
#if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
/*******************************************************************************
**
** Function rfc_calc_fcs
@ -183,7 +187,9 @@ tRFC_MCB *rfc_alloc_multiplexer_channel (BD_ADDR bd_addr, BOOLEAN is_initiator)
return (NULL);
}
void osi_free_fun(void *p){
osi_free(p);
}
/*******************************************************************************
**
** Function rfc_release_multiplexer_channel
@ -197,8 +203,7 @@ void rfc_release_multiplexer_channel (tRFC_MCB *p_mcb)
rfc_timer_stop (p_mcb);
fixed_queue_free(p_mcb->cmd_q, osi_free);
fixed_queue_free(p_mcb->cmd_q, osi_free_fun);
memset (p_mcb, 0, sizeof (tRFC_MCB));
p_mcb->state = RFC_MX_STATE_IDLE;
@ -269,7 +274,7 @@ void rfc_port_timer_stop (tPORT *p_port)
{
RFCOMM_TRACE_EVENT ("rfc_port_timer_stop");
btu_stop_timer (&p_port->rfc.tle);
btu_free_timer (&p_port->rfc.tle);
}
@ -475,3 +480,4 @@ void rfc_check_send_cmd(tRFC_MCB *p_mcb, BT_HDR *p_buf)
}
#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)

View File

@ -52,6 +52,7 @@ COMPONENT_ADD_INCLUDEDIRS += bluedroid/bta/include \
bluedroid/stack/avrc/include \
bluedroid/stack/avdt/include \
bluedroid/stack/a2dp/include \
bluedroid/stack/rfcomm/include \
bluedroid/stack/include \
bluedroid/utils/include \
bluedroid/api/include \
@ -64,6 +65,7 @@ COMPONENT_SRCDIRS += bluedroid/bta/dm \
bluedroid/bta/av \
bluedroid/bta/ar \
bluedroid/bta/sys \
bluedroid/bta/jv \
bluedroid/bta \
bluedroid/btcore \
bluedroid/btif \
@ -79,6 +81,7 @@ COMPONENT_SRCDIRS += bluedroid/bta/dm \
bluedroid/btc/profile/std/gatt \
bluedroid/btc/profile/std/a2dp \
bluedroid/btc/profile/std/avrc \
bluedroid/btc/profile/std/spp \
bluedroid/btc/profile \
bluedroid/stack/btm \
bluedroid/stack/btu \
@ -93,6 +96,7 @@ COMPONENT_SRCDIRS += bluedroid/bta/dm \
bluedroid/stack/avrc \
bluedroid/stack/avdt \
bluedroid/stack/a2dp \
bluedroid/stack/rfcomm \
bluedroid/stack \
bluedroid/utils \
bluedroid/api \

View File

@ -48,6 +48,7 @@ INPUT = \
## Issue with __attribute__
../components/bt/bluedroid/api/include/esp_a2dp_api.h \
../components/bt/bluedroid/api/include/esp_avrc_api.h \
../components/bt/bluedroid/api/include/esp_spp_api.h \
##
## Ethernet - API Reference
##

View File

@ -7,3 +7,4 @@ CLASSIC BT
BT GAP <esp_gap_bt>
BT A2DP <esp_a2dp>
BT AVRC <esp_avrc>
BT SPP <esp_spp>

View File

@ -0,0 +1,22 @@
SPP API
===============
Overview
--------
`Instructions`_
.. _Instructions: ../template.html
Application Example
-------------------
Check :example:`bluetooth` folder in ESP-IDF examples, which contains the following application:
* This is a SPP demo. This demo can discover the service, connect, send and recive SPP data :example:`bluetooth/bt_spp_acceptor`, :example:`bluetooth/bt_spp_initiator`
API Reference
-------------
.. include:: /_build/inc/esp_spp_api.inc

View File

@ -2,3 +2,5 @@
# Classic BT is enabled and BT_DRAM_RELEASE is disabled
CONFIG_BT_ENABLED=y
CONFIG_CLASSIC_BT_ENABLED=y
CONFIG_A2DP_SNK_ENABLED=y

View File

@ -0,0 +1,10 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := bt_spp_acceptor_demo
#COMPONENT_ADD_INCLUDEDIRS := components/include
include $(IDF_PATH)/make/project.mk

View File

@ -0,0 +1,16 @@
ESP-IDF BT-SPP-ACCEPTOR demo
======================
Demo of SPP acceptor role
This is the demo for user to use ESP_APIs to create a SPP acceptor.
Options choose step:
1. make menuconfig.
2. enter menuconfig "Component config", choose "Bluetooth"
3. enter menu Bluetooth, choose "Classic Bluetooth" and "SPP Profile"
4. choose your options.
Then set SPP_SHOW_MODE as SPP_SHOW_DATA or SPP_SHOW_SPEED in code(should be same with bt_spp_initator).
After the program started, bt_spp_initator will connect it and send data.

View File

@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@ -0,0 +1,155 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "nvs.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_bt_device.h"
#include "esp_spp_api.h"
#include "time.h"
#include "sys/time.h"
#define SPP_TAG "SPP_ACCEPTOR_DEMO"
#define SPP_SERVER_NAME "SPP_SERVER"
#define EXCAMPLE_DEVICE_NAME "ESP_SPP_ACCEPTOR"
#define SPP_SHOW_DATA 0
#define SPP_SHOW_SPEED 1
#define SPP_SHOW_MODE SPP_SHOW_SPEED /*Choose show mode: show data or speed*/
static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
static struct timeval time_new, time_old;
static long data_num = 0;
static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE;
static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE;
static void print_speed(void)
{
float time_old_s = time_old.tv_sec + time_old.tv_usec / 1000000.0;
float time_new_s = time_new.tv_sec + time_new.tv_usec / 1000000.0;
float time_interval = time_new_s - time_old_s;
float speed = data_num * 8 / time_interval / 1000.0;
ESP_LOGI(SPP_TAG, "speed(%fs ~ %fs): %f kbit/s" , time_old_s, time_new_s, speed);
data_num = 0;
time_old.tv_sec = time_new.tv_sec;
time_old.tv_usec = time_new.tv_usec;
}
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
switch (event) {
case ESP_SPP_INIT_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT");
esp_bt_dev_set_device_name(EXCAMPLE_DEVICE_NAME);
esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
esp_spp_start_srv(sec_mask,role_slave, 0, SPP_SERVER_NAME);
break;
case ESP_SPP_DISCOVERY_COMP_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT");
break;
case ESP_SPP_OPEN_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT");
break;
case ESP_SPP_CLOSE_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT");
break;
case ESP_SPP_START_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT");
break;
case ESP_SPP_CL_INIT_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT");
break;
case ESP_SPP_DATA_IND_EVT:
#if (SPP_SHOW_MODE == SPP_SHOW_DATA)
ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d",
param->data_ind.len, param->data_ind.handle);
esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len);
#else
gettimeofday(&time_new, NULL);
data_num += param->data_ind.len;
if (time_new.tv_sec - time_old.tv_sec >= 3) {
print_speed();
}
#endif
break;
case ESP_SPP_CONG_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT");
break;
case ESP_SPP_WRITE_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT");
break;
case ESP_SPP_SRV_OPEN_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT");
gettimeofday(&time_old, NULL);
break;
default:
break;
}
}
void app_main()
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s initialize controller failed\n", __func__);
return;
}
if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s enable controller failed\n", __func__);
return;
}
if (esp_bluedroid_init() != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s initialize bluedroid failed\n", __func__);
return;
}
if (esp_bluedroid_enable() != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s enable bluedroid failed\n", __func__);
return;
}
if (esp_spp_register_callback(esp_spp_cb) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s spp register failed\n", __func__);
return;
}
if (esp_spp_init(esp_spp_mode) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s spp init failed\n", __func__);
return;
}
}

View File

@ -0,0 +1,6 @@
# Override some defaults so BT stack is enabled
# and WiFi disabled by default in this example
CONFIG_BT_ENABLED=y
CONFIG_CLASSIC_BT_ENABLED=y
CONFIG_WIFI_ENABLED=n
CONFIG_BT_SPP_ENABLED=y

View File

@ -0,0 +1,10 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := bt_spp_initiator_demo
#COMPONENT_ADD_INCLUDEDIRS := components/include
include $(IDF_PATH)/make/project.mk

View File

@ -0,0 +1,16 @@
ESP-IDF BT-SPP-INITATOR demo
======================
Demo of SPP initator role
This is the demo for user to use ESP_APIs to create a SPP initator.
Options choose step:
1. make menuconfig.
2. enter menuconfig "Component config", choose "Bluetooth"
3. enter menu Bluetooth, choose "Classic Bluetooth" and "SPP Profile"
4. choose your options.
Then set SPP_SHOW_MODE as SPP_SHOW_DATA or SPP_SHOW_SPEED in code(should be same with bt_spp_acceptor).
After the program started, It will connect to bt_spp_acceptor and send data.

View File

@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@ -0,0 +1,254 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "nvs.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_bt_device.h"
#include "esp_spp_api.h"
#include "time.h"
#include "sys/time.h"
#define SPP_TAG "SPP_INITIATOR_DEMO"
#define EXCAMPLE_DEVICE_NAME "ESP_SPP_INITIATOR"
#define SPP_SHOW_DATA 0
#define SPP_SHOW_SPEED 1
#define SPP_SHOW_MODE SPP_SHOW_SPEED /*Choose show mode: show data or speed*/
static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
static struct timeval time_new, time_old;
static long data_num = 0;
static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE;
static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER;
static esp_bd_addr_t peer_bd_addr;
static uint8_t peer_bdname_len;
static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
static const char remote_device_name[] = "ESP_SPP_ACCEPTOR";
static const esp_bt_inq_mode_t inq_mode = ESP_BT_INQ_MODE_GENERAL_INQUIRY;
static const uint8_t inq_len = 30;
static const uint8_t inq_num_rsps = 0;
#if (SPP_SHOW_MODE == SPP_SHOW_DATA)
#define SPP_DATA_LEN 20
#else
#define SPP_DATA_LEN ESP_SPP_MAX_MTU
#endif
static uint8_t spp_data[SPP_DATA_LEN];
static void print_speed(void)
{
float time_old_s = time_old.tv_sec + time_old.tv_usec / 1000000.0;
float time_new_s = time_new.tv_sec + time_new.tv_usec / 1000000.0;
float time_interval = time_new_s - time_old_s;
float speed = data_num * 8 / time_interval / 1000.0;
ESP_LOGI(SPP_TAG, "speed(%fs ~ %fs): %f kbit/s" , time_old_s, time_new_s, speed);
data_num = 0;
time_old.tv_sec = time_new.tv_sec;
time_old.tv_usec = time_new.tv_usec;
}
static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len)
{
uint8_t *rmt_bdname = NULL;
uint8_t rmt_bdname_len = 0;
if (!eir) {
return false;
}
rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len);
if (!rmt_bdname) {
rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len);
}
if (rmt_bdname) {
if (rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN) {
rmt_bdname_len = ESP_BT_GAP_MAX_BDNAME_LEN;
}
if (bdname) {
memcpy(bdname, rmt_bdname, rmt_bdname_len);
bdname[rmt_bdname_len] = '\0';
}
if (bdname_len) {
*bdname_len = rmt_bdname_len;
}
return true;
}
return false;
}
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
switch (event) {
case ESP_SPP_INIT_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT");
esp_bt_dev_set_device_name(EXCAMPLE_DEVICE_NAME);
esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps);
break;
case ESP_SPP_DISCOVERY_COMP_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT status=%d scn_num=%d",param->disc_comp.status, param->disc_comp.scn_num);
if (param->disc_comp.status == ESP_SPP_SUCCESS) {
esp_spp_connect(sec_mask, role_master, param->disc_comp.scn[0], peer_bd_addr);
}
break;
case ESP_SPP_OPEN_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT");
esp_spp_write(param->srv_open.handle, SPP_DATA_LEN, spp_data);
gettimeofday(&time_old, NULL);
break;
case ESP_SPP_CLOSE_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT");
break;
case ESP_SPP_START_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT");
break;
case ESP_SPP_CL_INIT_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT");
break;
case ESP_SPP_DATA_IND_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT");
break;
case ESP_SPP_CONG_EVT:
#if (SPP_SHOW_MODE == SPP_SHOW_DATA)
ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT cong=%d", param->cong.cong);
#endif
if (param->cong.cong == 0) {
esp_spp_write(param->cong.handle, SPP_DATA_LEN, spp_data);
}
break;
case ESP_SPP_WRITE_EVT:
#if (SPP_SHOW_MODE == SPP_SHOW_DATA)
ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT len=%d cong=%d", param->write.len , param->write.cong);
esp_log_buffer_hex("",spp_data,SPP_DATA_LEN);
#else
gettimeofday(&time_new, NULL);
data_num += param->write.len;
if (time_new.tv_sec - time_old.tv_sec >= 3) {
print_speed();
}
#endif
if (param->write.cong == 0) {
esp_spp_write(param->write.handle, SPP_DATA_LEN, spp_data);
}
break;
case ESP_SPP_SRV_OPEN_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT");
break;
default:
break;
}
}
static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
switch(event){
case ESP_BT_GAP_DISC_RES_EVT:
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_RES_EVT");
esp_log_buffer_hex(SPP_TAG, param->disc_res.bda, ESP_BD_ADDR_LEN);
for (int i = 0; i < param->disc_res.num_prop; i++){
if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_EIR
&& get_name_from_eir(param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)){
esp_log_buffer_char(SPP_TAG, peer_bdname, peer_bdname_len);
if (strlen(remote_device_name) == peer_bdname_len
&& strncmp(peer_bdname, remote_device_name, peer_bdname_len) == 0) {
memcpy(peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN);
esp_spp_start_discovery(peer_bd_addr);
esp_bt_gap_cancel_discovery();
}
}
}
break;
case ESP_BT_GAP_DISC_STATE_CHANGED_EVT:
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_STATE_CHANGED_EVT");
break;
case ESP_BT_GAP_RMT_SRVCS_EVT:
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_RMT_SRVCS_EVT");
break;
case ESP_BT_GAP_RMT_SRVC_REC_EVT:
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_RMT_SRVC_REC_EVT");
break;
default:
break;
}
}
void app_main()
{
for (int i = 0; i < SPP_DATA_LEN; ++i) {
spp_data[i] = i;
}
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s initialize controller failed\n", __func__);
return;
}
if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s enable controller failed\n", __func__);
return;
}
if (esp_bluedroid_init() != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s initialize bluedroid failed\n", __func__);
return;
}
if (esp_bluedroid_enable() != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s enable bluedroid failed\n", __func__);
return;
}
if (esp_bt_gap_register_callback(esp_bt_gap_cb) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s gap register failed\n", __func__);
return;
}
if (esp_spp_register_callback(esp_spp_cb) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s spp register failed\n", __func__);
return;
}
if (esp_spp_init(esp_spp_mode) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s spp init failed\n", __func__);
return;
}
}

View File

@ -0,0 +1,6 @@
# Override some defaults so BT stack is enabled
# and WiFi disabled by default in this example
CONFIG_BT_ENABLED=y
CONFIG_CLASSIC_BT_ENABLED=y
CONFIG_WIFI_ENABLED=n
CONFIG_BT_SPP_ENABLED=y