summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bta/dm/bta_dm_act.c18
-rw-r--r--bta/dm/bta_dm_api.c26
-rw-r--r--bta/dm/bta_dm_int.h11
-rw-r--r--bta/dm/bta_dm_main.c1
-rw-r--r--bta/include/bta_api.h11
-rw-r--r--device/include/controller.h3
-rw-r--r--device/src/controller.c25
-rw-r--r--hci/include/hci_packet_factory.h1
-rw-r--r--hci/include/hci_packet_parser.h4
-rw-r--r--hci/src/hci_packet_factory.c5
-rw-r--r--hci/src/hci_packet_parser.c13
-rw-r--r--stack/btm/btm_ble.c49
-rw-r--r--stack/btu/btu_hcif.c29
-rw-r--r--stack/gatt/gatt_cl.c2
-rw-r--r--[-rwxr-xr-x]stack/gatt/gatt_sr.c4
-rw-r--r--stack/hcic/hciblecmds.c23
-rw-r--r--stack/include/btm_ble_api.h24
-rw-r--r--stack/include/hcidefs.h11
-rw-r--r--stack/include/hcimsgs.h7
-rw-r--r--stack/l2cap/l2c_ble.c98
-rw-r--r--stack/l2cap/l2c_int.h10
-rw-r--r--stack/l2cap/l2c_utils.c1
22 files changed, 365 insertions, 11 deletions
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c
index 68d99d41f..1251f5d5b 100644
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -4757,6 +4757,24 @@ void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
/*******************************************************************************
**
+** Function bta_dm_ble_set_data_length
+**
+** Description This function set the maximum transmission packet size
+**
+** Parameters
+**
+*******************************************************************************/
+void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data)
+{
+ if (BTM_SetBleDataLength(p_data->ble_set_data_length.remote_bda,
+ p_data->ble_set_data_length.tx_data_length) != BTM_SUCCESS)
+ {
+ APPL_TRACE_ERROR("%s failed", __FUNCTION__);
+ }
+}
+
+/*******************************************************************************
+**
** Function bta_dm_ble_broadcast
**
** Description Starts or stops LE broadcasts
diff --git a/bta/dm/bta_dm_api.c b/bta/dm/bta_dm_api.c
index 47b948821..9ff3e98e2 100644
--- a/bta/dm/bta_dm_api.c
+++ b/bta/dm/bta_dm_api.c
@@ -1882,6 +1882,32 @@ void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max
bta_sys_sendmsg(p_msg);
}
}
+
+/*******************************************************************************
+**
+** Function BTA_DmBleSetDataLength
+**
+** Description This function is to set maximum LE data packet size
+**
+** Returns void
+**
+**
+*******************************************************************************/
+void BTA_DmBleSetDataLength(BD_ADDR remote_device, UINT16 tx_data_length)
+{
+ tBTA_DM_API_BLE_SET_DATA_LENGTH *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_BLE_SET_DATA_LENGTH *)GKI_getbuf(sizeof(tBTA_DM_API_BLE_SET_DATA_LENGTH)))
+ != NULL)
+ {
+ bdcpy(p_msg->remote_bda, remote_device);
+ p_msg->hdr.event = BTA_DM_API_SET_DATA_LENGTH_EVT;
+ p_msg->tx_data_length = tx_data_length;
+
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
#endif
/*******************************************************************************
diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h
index 798a90975..cabe88eff 100644
--- a/bta/dm/bta_dm_int.h
+++ b/bta/dm/bta_dm_int.h
@@ -99,6 +99,7 @@ enum
BTA_DM_API_BLE_SET_ADV_CONFIG_EVT,
BTA_DM_API_BLE_SET_SCAN_RSP_EVT,
BTA_DM_API_BLE_BROADCAST_EVT,
+ BTA_DM_API_SET_DATA_LENGTH_EVT,
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
BTA_DM_API_CFG_FILTER_COND_EVT,
@@ -466,6 +467,13 @@ typedef struct
tBTA_DM_SEARCH_CBACK * p_cback;
}tBTA_DM_API_BLE_OBSERVE;
+typedef struct
+{
+ BT_HDR hdr;
+ BD_ADDR remote_bda;
+ UINT16 tx_data_length;
+}tBTA_DM_API_BLE_SET_DATA_LENGTH;
+
/* set adv parameter for BLE advertising */
typedef struct
{
@@ -692,6 +700,8 @@ typedef union
tBTA_DM_API_ENABLE_SCAN_FILTER ble_enable_scan_filt;
#endif
tBTA_DM_API_UPDATE_CONN_PARAM ble_update_conn_params;
+ tBTA_DM_API_BLE_SET_DATA_LENGTH ble_set_data_length;
+
tBTA_DM_API_BLE_MULTI_ADV_ENB ble_multi_adv_enb;
tBTA_DM_API_BLE_MULTI_ADV_PARAM ble_multi_adv_param;
tBTA_DM_API_BLE_MULTI_ADV_DATA ble_multi_adv_data;
@@ -1057,6 +1067,7 @@ extern void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data);
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
extern void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data);
diff --git a/bta/dm/bta_dm_main.c b/bta/dm/bta_dm_main.c
index 75de1f3b2..450151a21 100644
--- a/bta/dm/bta_dm_main.c
+++ b/bta/dm/bta_dm_main.c
@@ -96,6 +96,7 @@ const tBTA_DM_ACTION bta_dm_action[] =
bta_dm_ble_set_adv_config, /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */
bta_dm_ble_set_scan_rsp, /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */
bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */
+ bta_dm_ble_set_data_length, /* BTA_DM_API_SET_DATA_LENGTH_EVT */
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
bta_dm_cfg_filter_cond, /* BTA_DM_API_CFG_FILTER_COND_EVT */
bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index e6de6bb49..9c13be45e 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -2146,6 +2146,17 @@ extern void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int,
/*******************************************************************************
**
+** Function BTA_DmBleSetDataLength
+**
+** Description This function is to set maximum LE data packet size
+**
+** Returns void
+**
+*******************************************************************************/
+extern void BTA_DmBleSetDataLength(BD_ADDR remote_device, UINT16 tx_data_length);
+
+/*******************************************************************************
+**
** Function BTA_DmBleSetStorageParams
**
** Description This function is called to set the storage parameters
diff --git a/device/include/controller.h b/device/include/controller.h
index af93e4742..2acca1bc0 100644
--- a/device/include/controller.h
+++ b/device/include/controller.h
@@ -51,6 +51,7 @@ typedef struct controller_t {
bool (*supports_master_slave_role_switch)(void);
bool (*supports_ble)(void);
+ bool (*supports_ble_packet_extension)(void);
bool (*supports_ble_connection_parameters_request)(void);
bool (*supports_ble_privacy)(void);
@@ -64,6 +65,8 @@ typedef struct controller_t {
uint16_t (*get_acl_packet_size_classic)(void);
uint16_t (*get_acl_packet_size_ble)(void);
+ uint16_t (*get_ble_default_data_packet_length)(void);
+
// Get the number of acl packets the controller can buffer.
uint16_t (*get_acl_buffer_count_classic)(void);
uint8_t (*get_acl_buffer_count_ble)(void);
diff --git a/device/src/controller.c b/device/src/controller.c
index f0d3e584d..02edc4faf 100644
--- a/device/src/controller.c
+++ b/device/src/controller.c
@@ -34,7 +34,8 @@
#include "stack/include/btm_ble_api.h"
#include "btcore/include/version.h"
-const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x00\x3f" };
+const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x04\x7f" };
+
#if (BLE_INCLUDED)
const bt_event_mask_t CLASSIC_EVENT_MASK = { HCI_DUMO_EVENT_MASK_EXT };
#else
@@ -69,6 +70,7 @@ static uint8_t ble_white_list_size;
static uint8_t ble_resolving_list_max_size;
static uint8_t ble_supported_states[BLE_SUPPORTED_STATES_SIZE];
static bt_device_features_t features_ble;
+static uint16_t ble_suggested_default_data_length;
static bool readable;
static bool ble_supported;
@@ -225,6 +227,13 @@ static future_t *start_up(void) {
&ble_resolving_list_max_size);
}
+ if (HCI_LE_DATA_LEN_EXT_SUPPORTED(features_ble.as_array)) {
+ response = AWAIT_COMMAND(packet_factory->make_ble_read_suggested_default_data_length());
+ packet_parser->parse_ble_read_suggested_default_data_length_response(
+ response,
+ &ble_suggested_default_data_length);
+ }
+
// Set the ble event mask next
response = AWAIT_COMMAND(packet_factory->make_ble_set_event_mask(&BLE_EVENT_MASK));
packet_parser->parse_generic_command_complete(response);
@@ -348,6 +357,12 @@ static bool supports_ble_privacy(void) {
return HCI_LE_ENHANCED_PRIVACY_SUPPORTED(features_ble.as_array);
}
+static bool supports_ble_packet_extension(void) {
+ assert(readable);
+ assert(ble_supported);
+ return HCI_LE_DATA_LEN_EXT_SUPPORTED(features_ble.as_array);
+}
+
static bool supports_ble_connection_parameters_request(void) {
assert(readable);
assert(ble_supported);
@@ -375,6 +390,12 @@ static uint16_t get_acl_packet_size_ble(void) {
return acl_data_size_ble + HCI_DATA_PREAMBLE_SIZE;
}
+static uint16_t get_ble_suggested_default_data_length(void) {
+ assert(readable);
+ assert(ble_supported);
+ return ble_suggested_default_data_length;
+}
+
static uint16_t get_acl_buffer_count_classic(void) {
assert(readable);
return acl_buffer_count_classic;
@@ -420,6 +441,7 @@ static const controller_t interface = {
supports_master_slave_role_switch,
supports_ble,
+ supports_ble_packet_extension,
supports_ble_connection_parameters_request,
supports_ble_privacy,
@@ -428,6 +450,7 @@ static const controller_t interface = {
get_acl_packet_size_classic,
get_acl_packet_size_ble,
+ get_ble_suggested_default_data_length,
get_acl_buffer_count_classic,
get_acl_buffer_count_ble,
diff --git a/hci/include/hci_packet_factory.h b/hci/include/hci_packet_factory.h
index 5a50b5199..79110e178 100644
--- a/hci/include/hci_packet_factory.h
+++ b/hci/include/hci_packet_factory.h
@@ -38,6 +38,7 @@ typedef struct {
BT_HDR *(*make_ble_read_supported_states)(void);
BT_HDR *(*make_ble_read_local_supported_features)(void);
BT_HDR *(*make_ble_read_resolving_list_size)(void);
+ BT_HDR *(*make_ble_read_suggested_default_data_length)(void);
BT_HDR *(*make_ble_set_event_mask)(const bt_event_mask_t *event_mask);
} hci_packet_factory_t;
diff --git a/hci/include/hci_packet_parser.h b/hci/include/hci_packet_parser.h
index 45b934a5d..57e5d1c25 100644
--- a/hci/include/hci_packet_parser.h
+++ b/hci/include/hci_packet_parser.h
@@ -87,6 +87,10 @@ typedef struct {
uint8_t *resolving_list_size_ptr
);
+ void (*parse_ble_read_suggested_default_data_length_response)(
+ BT_HDR *response,
+ uint16_t *ble_default_packet_length_ptr
+ );
} hci_packet_parser_t;
const hci_packet_parser_t *hci_packet_parser_get_interface();
diff --git a/hci/src/hci_packet_factory.c b/hci/src/hci_packet_factory.c
index 89b82d189..bc8fca51d 100644
--- a/hci/src/hci_packet_factory.c
+++ b/hci/src/hci_packet_factory.c
@@ -133,6 +133,10 @@ static BT_HDR *make_ble_read_resolving_list_size(void) {
return make_command_no_params(HCI_BLE_READ_RESOLVING_LIST_SIZE);
}
+static BT_HDR *make_ble_read_suggested_default_data_length(void) {
+ return make_command_no_params(HCI_BLE_READ_DEFAULT_DATA_LENGTH);
+}
+
static BT_HDR *make_ble_set_event_mask(const bt_event_mask_t *event_mask) {
uint8_t *stream;
uint8_t parameter_size = sizeof(bt_event_mask_t);
@@ -188,6 +192,7 @@ static const hci_packet_factory_t interface = {
make_ble_read_supported_states,
make_ble_read_local_supported_features,
make_ble_read_resolving_list_size,
+ make_ble_read_suggested_default_data_length,
make_ble_set_event_mask
};
diff --git a/hci/src/hci_packet_parser.c b/hci/src/hci_packet_parser.c
index e25b7c479..b9f4080cd 100644
--- a/hci/src/hci_packet_parser.c
+++ b/hci/src/hci_packet_parser.c
@@ -173,6 +173,16 @@ static void parse_ble_read_resolving_list_size_response(
buffer_allocator->free(response);
}
+static void parse_ble_read_suggested_default_data_length_response(
+ BT_HDR *response,
+ uint16_t *ble_default_packet_length_ptr) {
+
+ uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 2 /* bytes after */);
+ STREAM_TO_UINT8(*ble_default_packet_length_ptr, stream);
+
+ buffer_allocator->free(response);
+}
+
// Internal functions
static uint8_t *read_command_complete_header(
@@ -225,7 +235,8 @@ static const hci_packet_parser_t interface = {
parse_ble_read_buffer_size_response,
parse_ble_read_supported_states_response,
parse_ble_read_local_supported_features_response,
- parse_ble_read_resolving_list_size_response
+ parse_ble_read_resolving_list_size_response,
+ parse_ble_read_suggested_default_data_length_response
};
const hci_packet_parser_t *hci_packet_parser_get_interface() {
diff --git a/stack/btm/btm_ble.c b/stack/btm/btm_ble.c
index e492b1f3b..789cfb1e6 100644
--- a/stack/btm/btm_ble.c
+++ b/stack/btm/btm_ble.c
@@ -38,6 +38,7 @@
#include "gap_api.h"
#include "bt_utils.h"
#include "device/include/controller.h"
+
#define LOG_TAG "bt_btm_ble"
#include "osi/include/log.h"
@@ -759,6 +760,54 @@ BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr)
}
return use_le;
}
+
+
+/*******************************************************************************
+**
+** Function BTM_SetBleDataLength
+**
+** Description This function is to set maximum BLE transmission packet size
+**
+** Returns BTM_SUCCESS if success; otherwise failed.
+**
+*******************************************************************************/
+tBTM_STATUS BTM_SetBleDataLength(BD_ADDR bd_addr, UINT16 tx_pdu_length)
+{
+ tACL_CONN *p_acl = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE);
+ BTM_TRACE_DEBUG("%s: tx_pdu_length =%d", __FUNCTION__, tx_pdu_length);
+
+ if (!controller_get_interface()->supports_ble_packet_extension())
+ {
+ BTM_TRACE_ERROR("%s failed, request not supported", __FUNCTION__);
+ return BTM_ILLEGAL_VALUE;
+ }
+
+ if (!HCI_LE_DATA_LEN_EXT_SUPPORTED(p_acl->peer_le_features))
+ {
+ BTM_TRACE_ERROR("%s failed, peer does not support request", __FUNCTION__);
+ return BTM_ILLEGAL_VALUE;
+ }
+
+ if (p_acl != NULL)
+ {
+ if (tx_pdu_length > BTM_BLE_DATA_SIZE_MAX)
+ tx_pdu_length = BTM_BLE_DATA_SIZE_MAX;
+ else if (tx_pdu_length < BTM_BLE_DATA_SIZE_MIN)
+ tx_pdu_length = BTM_BLE_DATA_SIZE_MIN;
+
+ /* always set the TxTime to be max, as controller does not care for now */
+ btsnd_hcic_ble_set_data_length(p_acl->hci_handle, tx_pdu_length,
+ BTM_BLE_DATA_TX_TIME_MAX);
+
+ return BTM_SUCCESS;
+ }
+ else
+ {
+ BTM_TRACE_ERROR("%s: Wrong mode: no LE link exist or LE not supported",__FUNCTION__);
+ return BTM_WRONG_MODE;
+ }
+}
+
/*******************************************************************************
**
** Function btm_ble_rand_enc_complete
diff --git a/stack/btu/btu_hcif.c b/stack/btu/btu_hcif.c
index e3f61398c..700577271 100644
--- a/stack/btu/btu_hcif.c
+++ b/stack/btu/btu_hcif.c
@@ -40,7 +40,8 @@
#include "btm_api.h"
#include "btm_int.h"
#include "bt_utils.h"
-#include "osi/include/osi.h"
+#include "device/include/controller.h"
+#include "osi.h"
#include "osi/include/log.h"
#include "hci_layer.h"
@@ -119,6 +120,7 @@ static void btu_ble_read_remote_feat_evt (UINT8 *p);
static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len);
static void btu_ble_proc_ltk_req (UINT8 *p);
static void btu_hcif_encryption_key_refresh_cmpl_evt (UINT8 *p);
+static void btu_ble_data_length_change_evt (UINT8 *p, UINT16 evt_len);
#if (BLE_LLT_INCLUDED == TRUE)
static void btu_ble_rc_param_req_evt(UINT8 *p);
#endif
@@ -332,7 +334,9 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
btu_ble_rc_param_req_evt(p);
break;
#endif
-
+ case HCI_BLE_DATA_LENGTH_CHANGE_EVT:
+ btu_ble_data_length_change_evt(p, hci_evt_len);
+ break;
}
break;
#endif /* BLE_INCLUDED */
@@ -1721,6 +1725,27 @@ static void btu_ble_proc_ltk_req (UINT8 *p)
#endif
/* This is empty until an upper layer cares about returning event */
}
+
+static void btu_ble_data_length_change_evt(UINT8 *p, UINT16 evt_len)
+{
+ UINT16 handle;
+ UINT16 tx_data_len;
+ UINT16 rx_data_len;
+
+ if (!controller_get_interface()->supports_ble_packet_extension())
+ {
+ HCI_TRACE_WARNING("%s, request not supported", __FUNCTION__);
+ return;
+ }
+
+ STREAM_TO_UINT16(handle, p);
+ STREAM_TO_UINT16(tx_data_len, p);
+ p += 2; /* Skip the TxTimer */
+ STREAM_TO_UINT16(rx_data_len, p);
+
+ l2cble_process_data_length_change_event(handle, tx_data_len, rx_data_len);
+}
+
/**********************************************
** End of BLE Events Handler
***********************************************/
diff --git a/stack/gatt/gatt_cl.c b/stack/gatt/gatt_cl.c
index 0578086bb..3e623bf7b 100644
--- a/stack/gatt/gatt_cl.c
+++ b/stack/gatt/gatt_cl.c
@@ -30,6 +30,7 @@
#include "bt_utils.h"
#include "gki.h"
#include "gatt_int.h"
+#include "l2c_int.h"
#define GATT_WRITE_LONG_HDR_SIZE 5 /* 1 opcode + 2 handle + 2 offset */
#define GATT_READ_CHAR_VALUE_HDL (GATT_READ_CHAR_VALUE | 0x80)
@@ -1065,6 +1066,7 @@ void gatt_process_mtu_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT16 len, UINT
p_tcb->payload_size = mtu;
}
+ l2cble_set_fixed_channel_tx_data_length(p_tcb->peer_bda, L2CAP_ATT_CID, p_tcb->payload_size);
gatt_end_operation(p_clcb, status, NULL);
}
/*******************************************************************************
diff --git a/stack/gatt/gatt_sr.c b/stack/gatt/gatt_sr.c
index d4323c74b..05facd606 100755..100644
--- a/stack/gatt/gatt_sr.c
+++ b/stack/gatt/gatt_sr.c
@@ -29,7 +29,7 @@
#include <string.h>
#include "gatt_int.h"
#include "l2c_api.h"
-
+#include "l2c_int.h"
#define GATT_MTU_REQ_MIN_LEN 2
@@ -935,6 +935,8 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data)
GATT_TRACE_ERROR("MTU request PDU with MTU size %d", p_tcb->payload_size);
+ l2cble_set_fixed_channel_tx_data_length(p_tcb->peer_bda, L2CAP_ATT_CID, p_tcb->payload_size);
+
if ((p_buf = attp_build_sr_msg(p_tcb, GATT_RSP_MTU, (tGATT_SR_MSG *) &p_tcb->payload_size)) != NULL)
{
attp_send_sr_msg (p_tcb, p_buf);
diff --git a/stack/hcic/hciblecmds.c b/stack/hcic/hciblecmds.c
index 9a5e1069d..5d7d2106b 100644
--- a/stack/hcic/hciblecmds.c
+++ b/stack/hcic/hciblecmds.c
@@ -929,6 +929,29 @@ BOOLEAN btsnd_hcic_ble_set_rand_priv_addr_timeout (UINT16 rpa_timout)
return (TRUE);
}
+BOOLEAN btsnd_hcic_ble_set_data_length(UINT16 conn_handle, UINT16 tx_octets, UINT16 tx_time)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH)) == NULL)
+ return FALSE;
+
+ pp = p->data;
+
+ p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH;
+ p->offset = 0;
+
+ UINT16_TO_STREAM(pp, HCI_BLE_SET_DATA_LENGTH);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH);
+
+ UINT16_TO_STREAM(pp, conn_handle);
+ UINT16_TO_STREAM(pp, tx_octets);
+ UINT16_TO_STREAM(pp, tx_time);
+
+ btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return TRUE;
+}
#endif
diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h
index 607e6871e..df61449d9 100644
--- a/stack/include/btm_ble_api.h
+++ b/stack/include/btm_ble_api.h
@@ -327,10 +327,21 @@ typedef UINT32 tBTM_BLE_AD_MASK;
#define BTM_BLE_AD_TYPE_MANU HCI_EIR_MANUFACTURER_SPECIFIC_TYPE /* 0xff */
typedef UINT8 tBTM_BLE_AD_TYPE;
-/* security settings used with L2CAP LE COC */
+/* Security settings used with L2CAP LE COC */
#define BTM_SEC_LE_LINK_ENCRYPTED 0x01
#define BTM_SEC_LE_LINK_PAIRED_WITHOUT_MITM 0x02
#define BTM_SEC_LE_LINK_PAIRED_WITH_MITM 0x04
+
+/* Min/max Preferred number of payload octets that the local Controller
+ should include in a single Link Layer Data Channel PDU. */
+#define BTM_BLE_DATA_SIZE_MAX 0x00fb
+#define BTM_BLE_DATA_SIZE_MIN 0x001b
+
+/* Preferred maximum number of microseconds that the local Controller
+ should use to transmit a single Link Layer Data Channel PDU. */
+#define BTM_BLE_DATA_TX_TIME_MIN 0x0148
+#define BTM_BLE_DATA_TX_TIME_MAX 0x0848
+
/* adv tx power level */
#define BTM_BLE_ADV_TX_POWER_MIN 0 /* minimum tx power */
#define BTM_BLE_ADV_TX_POWER_LOW 1 /* low tx power */
@@ -1765,6 +1776,17 @@ extern tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable,
*******************************************************************************/
extern tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback);
+/*******************************************************************************
+**
+** Function BTM_SetBleDataLength
+**
+** Description This function is called to set maximum BLE transmission packet size
+**
+** Returns BTM_SUCCESS if success; otherwise failed.
+**
+*******************************************************************************/
+extern tBTM_STATUS BTM_SetBleDataLength(BD_ADDR bd_addr, UINT16 tx_pdu_length);
+
#ifdef __cplusplus
}
#endif
diff --git a/stack/include/hcidefs.h b/stack/include/hcidefs.h
index 92d9d844e..04c5ed665 100644
--- a/stack/include/hcidefs.h
+++ b/stack/include/hcidefs.h
@@ -333,6 +333,10 @@
#define HCI_BLE_RC_PARAM_REQ_REPLY (0x0020 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_RC_PARAM_REQ_NEG_REPLY (0x0021 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_DATA_LENGTH (0x0022 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_DEFAULT_DATA_LENGTH (0x0023 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_DEFAULT_DATA_LENGTH (0x0024 | HCI_GRP_BLE_CMDS)
+
#define HCI_BLE_ADD_DEV_RESOLVING_LIST (0x0027 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_RM_DEV_RESOLVING_LIST (0x0028 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_CLEAR_RESOLVING_LIST (0x0029 | HCI_GRP_BLE_CMDS)
@@ -342,7 +346,6 @@
#define HCI_BLE_SET_ADDR_RESOLUTION_ENABLE (0x002D | HCI_GRP_BLE_CMDS)
#define HCI_BLE_SET_RAND_PRIV_ADDR_TIMOUT (0x002E | HCI_GRP_BLE_CMDS)
-
/* LE Get Vendor Capabilities Command OCF */
#define HCI_BLE_VENDOR_CAP_OCF (0x0153 | HCI_GRP_VENDOR_SPECIFIC)
@@ -1757,12 +1760,16 @@ typedef struct
#define HCI_LE_FEATURE_ENHANCED_PRIVACY_OFF 0
#define HCI_LE_ENHANCED_PRIVACY_SUPPORTED(x) ((x)[HCI_LE_FEATURE_ENHANCED_PRIVACY_OFF] & HCI_LE_FEATURE_ENHANCED_PRIVACY_MASK)
-
/* Extended scanner filter policy : 7 */
#define HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_MASK 0x80
#define HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_OFF 0
#define HCI_LE_EXT_SCAN_FILTER_POLICY_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_OFF] & HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_MASK)
+/* Slave-initiated Features Exchange */
+#define HCI_LE_FEATURE_DATA_LEN_EXT_MASK 0x20
+#define HCI_LE_FEATURE_DATA_LEN_EXT_OFF 0
+#define HCI_LE_DATA_LEN_EXT_SUPPORTED(x) ((x)[HCI_LE_FEATURE_DATA_LEN_EXT_OFF] & HCI_LE_FEATURE_DATA_LEN_EXT_MASK)
+
/*
** Local Supported Commands encoding
*/
diff --git a/stack/include/hcimsgs.h b/stack/include/hcimsgs.h
index dfc0d50cb..672f5fb4c 100644
--- a/stack/include/hcimsgs.h
+++ b/stack/include/hcimsgs.h
@@ -661,13 +661,13 @@ extern void btsnd_hcic_vendor_spec_cmd (void *buffer, UINT16 opcode,
#define HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT 2
#define HCIC_PARAM_SIZE_BLE_ENCRYPT 32
#define HCIC_PARAM_SIZE_BLE_RAND 0
-#define HCIC_PARAM_SIZE_WRITE_LE_HOST_SUPPORTED 2
+#define HCIC_PARAM_SIZE_WRITE_LE_HOST_SUPPORTED 2
#define HCIC_BLE_RAND_DI_SIZE 8
#define HCIC_BLE_ENCRYT_KEY_SIZE 16
#define HCIC_PARAM_SIZE_BLE_START_ENC (4 + HCIC_BLE_RAND_DI_SIZE + HCIC_BLE_ENCRYT_KEY_SIZE)
#define HCIC_PARAM_SIZE_LTK_REQ_REPLY (2 + HCIC_BLE_ENCRYT_KEY_SIZE)
-#define HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY 2
+#define HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY 2
#define HCIC_BLE_CHNL_MAP_SIZE 5
#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA 31
@@ -679,6 +679,7 @@ extern void btsnd_hcic_vendor_spec_cmd (void *buffer, UINT16 opcode,
#define HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_LOCAL 7
#define HCIC_PARAM_SIZE_BLE_SET_ADDR_RESOLUTION_ENABLE 1
#define HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT 2
+#define HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH 6
/* ULP HCI command */
extern BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask);
@@ -771,6 +772,8 @@ extern BOOLEAN btsnd_hcic_ble_rc_param_req_neg_reply(UINT16 handle, UINT8 reason
#endif /* BLE_LLT_INCLUDED */
+extern BOOLEAN btsnd_hcic_ble_set_data_length(UINT16 conn_handle, UINT16 tx_octets,
+ UINT16 tx_time);
extern BOOLEAN btsnd_hcic_ble_add_device_resolving_list (UINT8 addr_type_peer,
BD_ADDR bda_peer,
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c
index 94ddf4268..05ff5bf40 100644
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -985,5 +985,103 @@ void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 i
}
#endif
+/*******************************************************************************
+**
+** Function l2cble_update_data_length
+**
+** Description This function update link tx data length if applicable
+**
+** Returns void
+**
+*******************************************************************************/
+void l2cble_update_data_length(tL2C_LCB *p_lcb)
+{
+ UINT16 tx_mtu = 0;
+ UINT16 i = 0;
+
+ L2CAP_TRACE_DEBUG("%s", __FUNCTION__);
+
+ /* See if we have a link control block for the connection */
+ if (p_lcb == NULL)
+ return;
+
+ for (i = 0; i < L2CAP_NUM_FIXED_CHNLS; i++)
+ {
+ if (i + L2CAP_FIRST_FIXED_CHNL != L2CAP_BLE_SIGNALLING_CID)
+ {
+ if ((p_lcb->p_fixed_ccbs[i] != NULL) &&
+ (tx_mtu < (p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD)))
+ tx_mtu = p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD;
+ }
+ }
+
+ if (tx_mtu > BTM_BLE_DATA_SIZE_MAX)
+ tx_mtu = BTM_BLE_DATA_SIZE_MAX;
+
+ /* update TX data length if changed */
+ if (p_lcb->tx_data_len != tx_mtu)
+ BTM_SetBleDataLength(p_lcb->remote_bd_addr, tx_mtu);
+
+}
+
+/*******************************************************************************
+**
+** Function l2cble_process_data_length_change_evt
+**
+** Description This function process the data length change event
+**
+** Returns void
+**
+*******************************************************************************/
+void l2cble_process_data_length_change_event(UINT16 handle, UINT16 tx_data_len, UINT16 rx_data_len)
+{
+ tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
+
+ L2CAP_TRACE_DEBUG("%s TX data len = %d", __FUNCTION__, tx_data_len);
+ if (p_lcb == NULL)
+ return;
+
+ if (tx_data_len > 0)
+ p_lcb->tx_data_len = tx_data_len;
+
+ /* ignore rx_data len for now */
+}
+
+/*******************************************************************************
+**
+** Function l2cble_set_fixed_channel_tx_data_length
+**
+** Description This function update max fixed channel tx data length if applicable
+**
+** Returns void
+**
+*******************************************************************************/
+void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 fix_cid, UINT16 tx_mtu)
+{
+ tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(remote_bda, BT_TRANSPORT_LE);
+ UINT16 cid = fix_cid - L2CAP_FIRST_FIXED_CHNL;
+
+ L2CAP_TRACE_DEBUG("%s TX MTU = %d", __FUNCTION__, tx_mtu);
+
+ if (!controller_get_interface()->supports_ble_packet_extension())
+ {
+ L2CAP_TRACE_WARNING("%s, request not supported", __FUNCTION__);
+ return;
+ }
+
+ /* See if we have a link control block for the connection */
+ if (p_lcb == NULL)
+ return;
+
+ if (p_lcb->p_fixed_ccbs[cid] != NULL)
+ {
+ if (tx_mtu > BTM_BLE_DATA_SIZE_MAX)
+ tx_mtu = BTM_BLE_DATA_SIZE_MAX;
+
+ p_lcb->p_fixed_ccbs[cid]->tx_data_len = tx_mtu;
+ }
+
+ l2cble_update_data_length(p_lcb);
+}
#endif /* (BLE_INCLUDED == TRUE) */
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index 08c4ea10e..cbaca8251 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -313,7 +313,7 @@ typedef struct t_l2c_ccb
#if (L2CAP_NUM_FIXED_CHNLS > 0) || (L2CAP_UCD_INCLUDED == TRUE)
UINT16 fixed_chnl_idle_tout; /* Idle timeout to use for the fixed channel */
#endif
-
+ UINT16 tx_data_len;
} tL2C_CCB;
/***********************************************************************
@@ -403,6 +403,7 @@ typedef struct t_l2c_linkcb
tBT_TRANSPORT transport;
#if (BLE_INCLUDED == TRUE)
tBLE_ADDR_TYPE ble_addr_type;
+ UINT16 tx_data_len; /* tx data length used in data length extension */
#define L2C_BLE_CONN_UPDATE_DISABLE 0x1 /* disable update connection parameters */
#define L2C_BLE_NEW_CONN_PARAM 0x2 /* new connection parameter to be set */
@@ -744,6 +745,13 @@ extern void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status);
extern void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max,
UINT16 latency, UINT16 timeout);
#endif
+
+extern void l2cble_update_data_length(tL2C_LCB *p_lcb);
+extern void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 fix_cid,
+ UINT16 tx_mtu);
+extern void l2cble_process_data_length_change_event(UINT16 handle, UINT16 tx_data_len,
+ UINT16 rx_data_len);
+
#endif
extern void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb);
diff --git a/stack/l2cap/l2c_utils.c b/stack/l2cap/l2c_utils.c
index d3ee908f2..e80d16b0f 100644
--- a/stack/l2cap/l2c_utils.c
+++ b/stack/l2cap/l2c_utils.c
@@ -74,6 +74,7 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR
p_lcb->is_bonding = is_bonding;
#if (BLE_INCLUDED == TRUE)
p_lcb->transport = transport;
+ p_lcb->tx_data_len = controller_get_interface()->get_ble_default_data_packet_length();
if (transport == BT_TRANSPORT_LE)
{