diff options
-rw-r--r-- | bta/dm/bta_dm_act.c | 18 | ||||
-rw-r--r-- | bta/dm/bta_dm_api.c | 26 | ||||
-rw-r--r-- | bta/dm/bta_dm_int.h | 11 | ||||
-rw-r--r-- | bta/dm/bta_dm_main.c | 1 | ||||
-rw-r--r-- | bta/include/bta_api.h | 11 | ||||
-rw-r--r-- | device/include/controller.h | 3 | ||||
-rw-r--r-- | device/src/controller.c | 25 | ||||
-rw-r--r-- | hci/include/hci_packet_factory.h | 1 | ||||
-rw-r--r-- | hci/include/hci_packet_parser.h | 4 | ||||
-rw-r--r-- | hci/src/hci_packet_factory.c | 5 | ||||
-rw-r--r-- | hci/src/hci_packet_parser.c | 13 | ||||
-rw-r--r-- | stack/btm/btm_ble.c | 49 | ||||
-rw-r--r-- | stack/btu/btu_hcif.c | 29 | ||||
-rw-r--r-- | stack/gatt/gatt_cl.c | 2 | ||||
-rw-r--r--[-rwxr-xr-x] | stack/gatt/gatt_sr.c | 4 | ||||
-rw-r--r-- | stack/hcic/hciblecmds.c | 23 | ||||
-rw-r--r-- | stack/include/btm_ble_api.h | 24 | ||||
-rw-r--r-- | stack/include/hcidefs.h | 11 | ||||
-rw-r--r-- | stack/include/hcimsgs.h | 7 | ||||
-rw-r--r-- | stack/l2cap/l2c_ble.c | 98 | ||||
-rw-r--r-- | stack/l2cap/l2c_int.h | 10 | ||||
-rw-r--r-- | stack/l2cap/l2c_utils.c | 1 |
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) { |