[automerger] DO NOT MERGE HID Host: Check L2CAP packet data length am: 4344cfb76a
Change-Id: Iabccbce010c9c418b63a638c8936cc8616799070
diff --git a/EventLogTags.logtags b/EventLogTags.logtags
new file mode 100644
index 0000000..32493d8
--- /dev/null
+++ b/EventLogTags.logtags
@@ -0,0 +1,37 @@
+# The entries in this file map a sparse set of log tag numbers to tag names.
+# This is installed on the device, in /system/etc, and parsed by logcat.
+#
+# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the
+# negative values alone for now.)
+#
+# Tag names are one or more ASCII letters and numbers or underscores, i.e.
+# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former
+# impacts log readability, the latter makes regex searches more annoying).
+#
+# Tag numbers and names are separated by whitespace. Blank lines and lines
+# starting with '#' are ignored.
+#
+# Optionally, after the tag names can be put a description for the value(s)
+# of the tag. Description are in the format
+# (<name>|data type[|data unit])
+# Multiple values are separated by commas.
+#
+# The data type is a number from the following values:
+# 1: int
+# 2: long
+# 3: string
+# 4: list
+#
+# The data unit is a number taken from the following list:
+# 1: Number of objects
+# 2: Number of bytes
+# 3: Number of milliseconds
+# 4: Number of allocations
+# 5: Id
+# 6: Percent
+# Default value for data of type int/long is 2 (bytes).
+#
+# TODO: generate ".java" and ".h" files with integer constants from this file.
+
+1010000 bt_hci_timeout (opcode|1)
+1010001 bt_config_source (opcode|1)
diff --git a/bta/ag/bta_ag_act.c b/bta/ag/bta_ag_act.c
index 3d52cef..285a967 100644
--- a/bta/ag/bta_ag_act.c
+++ b/bta/ag/bta_ag_act.c
@@ -432,6 +432,9 @@
p_scb->hsp_version = HSP_VERSION_1_2;
bta_ag_at_reinit(&p_scb->at_cb);
+ memset(&(p_scb->peer_hf_indicators), 0, sizeof(p_scb->peer_hf_indicators));
+ memset(&(p_scb->local_hf_indicators), 0, sizeof(p_scb->local_hf_indicators));
+
/* stop timers */
alarm_cancel(p_scb->ring_timer);
#if (BTM_WBS_INCLUDED == TRUE)
diff --git a/bta/ag/bta_ag_cfg.c b/bta/ag/bta_ag_cfg.c
index cfe298a..e5893e1 100644
--- a/bta/ag/bta_ag_cfg.c
+++ b/bta/ag/bta_ag_cfg.c
@@ -52,9 +52,24 @@
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5)
#endif
+#ifndef BTA_AG_BIND_INFO
+#define BTA_AG_BIND_INFO "(1)"
+#endif
+
+const tBTA_AG_HF_IND bta_ag_local_hf_ind_cfg[] =
+{
+ /* The first row contains the number of indicators. Need to be updated accordingly */
+ {BTA_AG_NUM_LOCAL_HF_IND, 0, 0, 0, 0},
+
+ {1, 1, 1, 0, 1}, /* Enhanced Driver Status, supported, enabled, range 0 ~ 1 */
+ {2, 1, 1, 0, 100} /* Battery Level Status, supported, enabled, range 0 ~ 100 */
+};
+
const tBTA_AG_CFG bta_ag_cfg =
{
BTA_AG_CIND_INFO,
+ BTA_AG_BIND_INFO,
+ BTA_AG_NUM_LOCAL_HF_IND,
BTA_AG_CONN_TIMEOUT,
BTA_AG_SCO_PKT_TYPES,
BTA_AG_CHLD_VAL_ECC,
diff --git a/bta/ag/bta_ag_cmd.c b/bta/ag/bta_ag_cmd.c
index 2ab9f51..110b531 100644
--- a/bta/ag/bta_ag_cmd.c
+++ b/bta/ag/bta_ag_cmd.c
@@ -111,6 +111,8 @@
BTA_AG_HF_CMD_CBC,
BTA_AG_HF_CMD_BCC,
BTA_AG_HF_CMD_BCS,
+ BTA_AG_HF_CMD_BIND,
+ BTA_AG_HF_CMD_BIEV,
BTA_AG_HF_CMD_BAC
};
@@ -152,6 +154,8 @@
{"+CBC", BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 100},
{"+BCC", BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
{"+BCS", BTA_AG_AT_SET, BTA_AG_AT_INT, 0, BTA_AG_CMD_MAX_VAL},
+ {"+BIND", BTA_AG_AT_SET | BTA_AG_AT_READ | BTA_AG_AT_TEST , BTA_AG_AT_STR, 0, 0},
+ {"+BIEV", BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 0},
{"+BAC", BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 0},
{"", BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0}
};
@@ -194,6 +198,7 @@
BTA_AG_RES_COPS,
BTA_AG_RES_CMEE,
BTA_AG_RES_BCS,
+ BTA_AG_RES_BIND,
BTA_AG_RES_UNAT
};
@@ -223,6 +228,7 @@
{"+COPS: ", BTA_AG_RES_FMT_STR},
{"+CME ERROR: ", BTA_AG_RES_FMT_INT},
{"+BCS: ", BTA_AG_RES_FMT_INT},
+ {"+BIND: ", BTA_AG_RES_FMT_STR},
{"", BTA_AG_RES_FMT_STR}
};
@@ -268,6 +274,8 @@
BTA_AG_AT_CBC_EVT, /* BTA_AG_HF_CMD_CBC */
0, /* BTA_AG_HF_CMD_BCC */
BTA_AG_AT_BCS_EVT, /* BTA_AG_HF_CMD_BCS */
+ BTA_AG_AT_BIND_EVT, /* BTA_AG_HF_CMD_BIND */
+ BTA_AG_AT_BIEV_EVT, /* BTA_AG_HF_CMD_BIEV */
BTA_AG_AT_BAC_EVT /* BTA_AG_HF_CMD_BAC */
};
@@ -294,6 +302,7 @@
0, /* BTA_AG_CALL_CANCEL_RES */
0, /* BTA_AG_END_CALL_RES */
0, /* BTA_AG_IN_CALL_HELD_RES */
+ BTA_AG_RES_BIND, /* BTA_AG_BIND_RES */
BTA_AG_RES_UNAT /* BTA_AG_UNAT_RES */
};
@@ -319,7 +328,8 @@
BTA_AG_CALLSETUP_NONE, /* BTA_AG_OUT_CALL_CONN_RES */
BTA_AG_CALLSETUP_NONE, /* BTA_AG_CALL_CANCEL_RES */
BTA_AG_CALLSETUP_NONE, /* BTA_AG_END_CALL_RES */
- BTA_AG_CALLSETUP_NONE /* BTA_AG_IN_CALL_HELD_RES */
+ BTA_AG_CALLSETUP_NONE, /* BTA_AG_IN_CALL_HELD_RES */
+ 0 /* BTA_AG_BIND_RES */
};
/*******************************************************************************
@@ -858,6 +868,222 @@
/*******************************************************************************
**
+** Function bta_ag_find_empty_hf_ind)
+**
+** Description This function returns the index of an empty HF indicator
+** structure.
+**
+** Returns int : index of the empty HF indicator structure or
+** -1 if no empty indicator
+** is available.
+**
+*******************************************************************************/
+static int bta_ag_find_empty_hf_ind(tBTA_AG_SCB *p_scb)
+{
+ for (int index = 0; index < BTA_AG_MAX_NUM_PEER_HF_IND; index++)
+ {
+ if (p_scb->peer_hf_indicators[index].ind_id == 0)
+ return index;
+ }
+
+ return -1;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_ag_find_hf_ind_by_id
+**
+** Description This function returns the index of the HF indicator
+** structure by the indicator id
+**
+** Returns int : index of the HF indicator structure
+** -1 if the indicator
+** was not found.
+**
+*******************************************************************************/
+static int bta_ag_find_hf_ind_by_id(tBTA_AG_HF_IND *p_hf_ind, int size, uint32_t ind_id)
+{
+ for (int index = 0; index < size; index++)
+ {
+ if (p_hf_ind[index].ind_id == ind_id)
+ return index;
+ }
+
+ return -1;
+}
+
+/*******************************************************************************
+**
+** Function bta_ag_parse_bind_set
+**
+** Description Parse AT+BIND set command and save the indicators
+**
+** Returns true if successful
+**
+*******************************************************************************/
+static bool bta_ag_parse_bind_set(tBTA_AG_SCB *p_scb, tBTA_AG_VAL val)
+{
+ char *p_token = strtok(val.str, ",");
+ if (p_token == NULL)
+ return false;
+
+ while (p_token != NULL)
+ {
+ uint16_t rcv_ind_id = atoi(p_token);
+ int index = bta_ag_find_empty_hf_ind(p_scb);
+ if (index == -1)
+ {
+ APPL_TRACE_WARNING("%s Can't save more indicators", __func__);
+ return false;
+ }
+
+ p_scb->peer_hf_indicators[index].ind_id = rcv_ind_id;
+ APPL_TRACE_DEBUG("%s peer_hf_ind[%d] = %d", __func__, index, rcv_ind_id);
+
+ p_token = strtok(NULL, ",");
+ }
+
+ return true;
+}
+
+/*******************************************************************************
+**
+** Function bta_ag_bind_response
+**
+** Description Send response for the AT+BIND command (HFP 1.7) received
+** from the headset based on the argument types.
+**
+** Returns Void
+**
+*******************************************************************************/
+static void bta_ag_bind_response(tBTA_AG_SCB *p_scb, uint8_t arg_type)
+{
+ char buffer[BTA_AG_AT_MAX_LEN];
+ memset(buffer, 0, BTA_AG_AT_MAX_LEN);
+
+ if (arg_type == BTA_AG_AT_TEST)
+ {
+ int index = 0;
+ buffer[index++] = '(';
+
+ for (uint32_t i = 0; i < bta_ag_local_hf_ind_cfg[0].ind_id; i++)
+ {
+ if (bta_ag_local_hf_ind_cfg[i+1].is_supported == true)
+ {
+ /* Add ',' from second indicator */
+ if (index > 1)
+ buffer[index++] = ',';
+ sprintf(&buffer[index++], "%d", bta_ag_local_hf_ind_cfg[i+1].ind_id);
+ }
+ }
+
+ buffer[index++] = ')';
+
+ bta_ag_send_result(p_scb, BTA_AG_RES_BIND, buffer, 0);
+ bta_ag_send_ok(p_scb);
+ }
+ else if (arg_type == BTA_AG_AT_READ)
+ {
+ char *p = buffer;
+
+ /* bta_ag_local_hf_ind_cfg[0].ind_id is used as BTA_AG_NUM_LOCAL_HF_IND */
+ for (uint32_t i = 0; i < bta_ag_local_hf_ind_cfg[0].ind_id; i++)
+ {
+ if (i == BTA_AG_MAX_NUM_LOCAL_HF_IND)
+ {
+ APPL_TRACE_WARNING("%s No space for more HF indicators", __func__);
+ break;
+ }
+
+ p_scb->local_hf_indicators[i].ind_id = bta_ag_local_hf_ind_cfg[i+1].ind_id;
+ p_scb->local_hf_indicators[i].is_supported = bta_ag_local_hf_ind_cfg[i+1].is_supported;
+ p_scb->local_hf_indicators[i].is_enable = bta_ag_local_hf_ind_cfg[i+1].is_enable;
+
+ int peer_index = bta_ag_find_hf_ind_by_id(p_scb->peer_hf_indicators,
+ BTA_AG_MAX_NUM_PEER_HF_IND,
+ p_scb->local_hf_indicators[i].ind_id);
+
+ /* Check whether local and peer sides support this indicator */
+ if (p_scb->local_hf_indicators[i].is_supported == true && peer_index != -1)
+ {
+ /* In the format of ind, state */
+ p += utl_itoa((uint16_t) p_scb->local_hf_indicators[i].ind_id, p);
+ *p++ = ',';
+ p += utl_itoa((uint16_t) p_scb->local_hf_indicators[i].is_enable, p);
+
+ bta_ag_send_result(p_scb, BTA_AG_RES_BIND, buffer, 0);
+
+ memset(buffer, 0, sizeof(buffer));
+ p = buffer;
+ } else {
+ /* If indicator is not supported, also set it to disable */
+ p_scb->local_hf_indicators[i].is_enable = false;
+ }
+ }
+
+ bta_ag_send_ok(p_scb);
+
+ /* If the service level connection wan't already open, now it's open */
+ if (!p_scb->svc_conn)
+ bta_ag_svc_conn_open(p_scb, NULL);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_ag_parse_biev_response
+**
+** Description Send response for AT+BIEV command (HFP 1.7) received from
+** the headset based on the argument types.
+**
+** Returns true if the response was parsed successfully
+**
+*******************************************************************************/
+static bool bta_ag_parse_biev_response(tBTA_AG_SCB *p_scb, tBTA_AG_VAL *val)
+{
+ char *p_token = strtok(val->str, ",");
+ uint16_t rcv_ind_id = atoi(p_token);
+
+ p_token = strtok(NULL, ",");
+ uint16_t rcv_ind_val = atoi(p_token);
+
+ APPL_TRACE_DEBUG("%s BIEV indicator id %d, value %d", __func__, rcv_ind_id, rcv_ind_val);
+
+ /* Check whether indicator ID is valid or not */
+ if (rcv_ind_id > BTA_AG_NUM_LOCAL_HF_IND)
+ {
+ APPL_TRACE_WARNING("%s received invalid indicator id %d", __func__, rcv_ind_id);
+ return false;
+ }
+
+ /* Check this indicator is support or not and enabled or not */
+ int local_index = bta_ag_find_hf_ind_by_id(p_scb->local_hf_indicators,
+ BTA_AG_MAX_NUM_LOCAL_HF_IND, rcv_ind_id);
+ if (local_index == -1 ||
+ p_scb->local_hf_indicators[local_index].is_supported != true ||
+ p_scb->local_hf_indicators[local_index].is_enable != true)
+ {
+ APPL_TRACE_WARNING("%s indicator id %d not supported or disabled", __func__, rcv_ind_id);
+ return false;
+ }
+
+ /* For each indicator ID, check whether the indicator value is in range */
+ if (rcv_ind_val < bta_ag_local_hf_ind_cfg[rcv_ind_id].ind_min_val ||
+ rcv_ind_val > bta_ag_local_hf_ind_cfg[rcv_ind_id].ind_max_val)
+ {
+ APPL_TRACE_WARNING("%s invalid ind_val %d", __func__, rcv_ind_val);
+ return false;
+ }
+
+ val->lidx = rcv_ind_id;
+ val->num = rcv_ind_val;
+
+ return true;
+}
+
+/*******************************************************************************
+**
** Function bta_ag_at_hfp_cback
**
** Description AT command processing callback for HFP.
@@ -889,6 +1115,7 @@
val.hdr.handle = bta_ag_scb_to_idx(p_scb);
val.hdr.app_id = p_scb->app_id;
+ val.hdr.status = BTA_AG_SUCCESS;
val.num = int_arg;
bdcpy(val.bd_addr, p_scb->peer_addr);
strlcpy(val.str, p_arg, BTA_AG_AT_MAX_LEN);
@@ -1017,6 +1244,37 @@
}
break;
+ case BTA_AG_HF_CMD_BIND:
+ APPL_TRACE_DEBUG("%s BTA_AG_HF_CMD_BIND arg_type: %d", __func__, arg_type);
+ if (arg_type == BTA_AG_AT_SET)
+ {
+ if (bta_ag_parse_bind_set(p_scb, val))
+ {
+ bta_ag_send_ok(p_scb);
+ } else {
+ event = 0;/* don't call callback */
+ bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
+ }
+ } else {
+ bta_ag_bind_response(p_scb, arg_type);
+
+ /* Need not pass this command beyond BTIF.*/
+ /* Stack handles it internally */
+ event = 0;/* don't call callback */
+ }
+ break;
+
+ case BTA_AG_HF_CMD_BIEV:
+ if (bta_ag_parse_biev_response(p_scb, &val))
+ {
+ bta_ag_send_ok(p_scb);
+ } else {
+ bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
+ /* don't call callback receiving invalid indicator */
+ event = 0;
+ }
+ break;
+
case BTA_AG_HF_CMD_CIND:
if (arg_type == BTA_AG_AT_TEST)
{
@@ -1089,7 +1347,12 @@
case BTA_AG_HF_CMD_BRSF:
/* store peer features */
- p_scb->peer_features = (UINT16) int_arg;
+ p_scb->peer_features = (uint16_t) int_arg;
+#if (BTA_HFP_VERSION < HFP_VERSION_1_7 || BTA_HFP_HF_IND_SUPPORTED != true)
+ p_scb->features &= ~BTA_AG_FEAT_HF_IND;
+#endif
+ APPL_TRACE_DEBUG("%s BRSF HF: 0x%x, phone: 0x%x", __func__,
+ p_scb->peer_features, p_scb->features);
/* send BRSF, send OK */
bta_ag_send_result(p_scb, BTA_AG_RES_BRSF, NULL,
@@ -1317,6 +1580,7 @@
{
val.hdr.handle = bta_ag_scb_to_idx(p_scb);
val.hdr.app_id = p_scb->app_id;
+ val.hdr.status = BTA_AG_SUCCESS;
val.num = 0;
strlcpy(val.str, p_arg, BTA_AG_AT_MAX_LEN);
(*bta_ag_cb.p_cback)(BTA_AG_AT_UNAT_EVT, (tBTA_AG *) &val);
@@ -1452,7 +1716,6 @@
void bta_ag_hfp_result(tBTA_AG_SCB *p_scb, tBTA_AG_API_RESULT *p_result)
{
UINT8 code = bta_ag_trans_result[p_result->result];
-
APPL_TRACE_DEBUG("bta_ag_hfp_result : res = %d", p_result->result);
switch(p_result->result)
@@ -1709,12 +1972,53 @@
}
break;
- default:
+ case BTA_AG_BIND_RES:
+ {
+ /* Find whether ind_id is supported by local device or not */
+ int local_index = bta_ag_find_hf_ind_by_id(p_scb->local_hf_indicators,
+ BTA_AG_MAX_NUM_LOCAL_HF_IND, p_result->data.ind.id);
+ if (local_index == -1)
+ {
+ APPL_TRACE_WARNING("%s Invalid HF Indicator ID %d", __func__,
+ p_result->data.ind.id);
+ return;
+ }
+
+ /* Find whether ind_id is supported by peer device or not */
+ int peer_index = bta_ag_find_hf_ind_by_id(p_scb->peer_hf_indicators,
+ BTA_AG_MAX_NUM_PEER_HF_IND, p_result->data.ind.id);
+ if (peer_index == -1)
+ {
+ APPL_TRACE_WARNING("%s Invalid HF Indicator ID %d", __func__,
+ p_result->data.ind.id);
+ return;
+ } else {
+ /* If the current state is different from the one upper layer request
+ change current state and send out the result */
+ if (p_scb->local_hf_indicators[local_index].is_enable != p_result->data.ind.on_demand)
+ {
+ char buffer[BTA_AG_AT_MAX_LEN] = {0};
+ char *p = buffer;
+
+ p_scb->local_hf_indicators[local_index].is_enable = p_result->data.ind.on_demand;
+ p += utl_itoa(p_result->data.ind.id, p);
+ *p++ = ',';
+ p += utl_itoa(p_scb->local_hf_indicators[local_index].is_enable, p);
+
+ bta_ag_send_result(p_scb, code, buffer, 0);
+ } else {
+ APPL_TRACE_DEBUG("%s HF Indicator %d already %s", p_result->data.ind.id,
+ (p_result->data.ind.on_demand == true) ? "Enabled" : "Disabled");
+ }
+ }
+ break;
+ }
+
+ default:
break;
}
}
-
/*******************************************************************************
**
** Function bta_ag_result
diff --git a/bta/ag/bta_ag_int.h b/bta/ag/bta_ag_int.h
index a95f0a8..b721ac0 100644
--- a/bta/ag/bta_ag_int.h
+++ b/bta/ag/bta_ag_int.h
@@ -42,13 +42,6 @@
/*****************************************************************************
** Constants
*****************************************************************************/
-#define HFP_VERSION_1_1 0x0101
-#define HFP_VERSION_1_5 0x0105
-#define HFP_VERSION_1_6 0x0106
-
-#define HSP_VERSION_1_0 0x0100
-#define HSP_VERSION_1_2 0x0102
-
/* Number of SCBs (AG service instances that can be registered) */
#ifndef BTA_AG_NUM_SCB
#define BTA_AG_NUM_SCB 2
@@ -62,6 +55,10 @@
/* RFCOMM MTU SIZE */
#define BTA_AG_MTU 256
+/* Max number of peer and local HF indicators */
+#define BTA_AG_MAX_NUM_PEER_HF_IND 20
+#define BTA_AG_MAX_NUM_LOCAL_HF_IND 4
+
/* Internal profile indexes */
#define BTA_AG_HSP 0 /* index for HSP */
#define BTA_AG_HFP 1 /* index for HFP */
@@ -77,6 +74,7 @@
BTA_AG_FEAT_VTAG | BTA_AG_FEAT_REJECT | \
BTA_AG_FEAT_ECS | BTA_AG_FEAT_ECC | \
BTA_AG_FEAT_EXTERR | BTA_AG_FEAT_CODEC | \
+ BTA_AG_FEAT_HF_IND | BTA_AG_FEAT_ESCO | \
BTA_AG_FEAT_VOIP)
#define BTA_AG_SDP_FEAT_SPEC (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | \
@@ -298,6 +296,10 @@
tBTA_AG_SCO_MSBC_SETTINGS codec_msbc_settings; /* settings to be used for the impending eSCO */
#endif
+ tBTA_AG_HF_IND peer_hf_indicators[BTA_AG_MAX_NUM_PEER_HF_IND]; /* Peer supported
+ HF indicators */
+ tBTA_AG_HF_IND local_hf_indicators[BTA_AG_MAX_NUM_LOCAL_HF_IND]; /* Local supported
+ HF indicators */
} tBTA_AG_SCB;
/* type for sco data */
@@ -342,6 +344,7 @@
/* config struct */
extern tBTA_AG_CFG *p_bta_ag_cfg;
+extern tBTA_AG_HF_IND bta_ag_local_hf_ind_cfg[];
/*****************************************************************************
** Function prototypes
diff --git a/bta/ag/bta_ag_sco.c b/bta/ag/bta_ag_sco.c
index 2a5341b..89e6f6c 100644
--- a/bta/ag/bta_ag_sco.c
+++ b/bta/ag/bta_ag_sco.c
@@ -84,9 +84,9 @@
{
BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */
BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */
- 0x000a, /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */
+ 0x000c, /* 12 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */
BTM_VOICE_SETTING_CVSD, /* Inp Linear, Air CVSD, 2s Comp, 16bit */
- (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */
+ (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */
BTM_SCO_PKT_TYPES_MASK_HV2 +
BTM_SCO_PKT_TYPES_MASK_HV3 +
BTM_SCO_PKT_TYPES_MASK_EV3 +
@@ -94,7 +94,7 @@
BTM_SCO_PKT_TYPES_MASK_EV5 +
BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 +
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
- BTM_ESCO_RETRANS_POWER /* Retransmission effort */
+ BTM_ESCO_RETRANS_QUALITY /* Retransmission effort */
},
/* mSBC T1 */
{
@@ -1575,9 +1575,9 @@
{
resp.rx_bw = BTM_64KBITS_RATE;
resp.tx_bw = BTM_64KBITS_RATE;
- resp.max_latency = 10;
+ resp.max_latency = 12;
resp.voice_contfmt = 0x60;
- resp.retrans_effort = BTM_ESCO_RETRANS_POWER;
+ resp.retrans_effort = BTM_ESCO_RETRANS_QUALITY;
if (p_data->link_type == BTM_LINK_TYPE_SCO)
{
diff --git a/bta/ag/bta_ag_sdp.c b/bta/ag/bta_ag_sdp.c
index cb5bd80..aa43c02 100644
--- a/bta/ag/bta_ag_sdp.c
+++ b/bta/ag/bta_ag_sdp.c
@@ -159,7 +159,7 @@
if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE)
{
profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
- version = HFP_VERSION_1_6;
+ version = BTA_HFP_VERSION;
}
else
{
diff --git a/bta/av/bta_av_aact.c b/bta/av/bta_av_aact.c
index 6c5d874..1e73fa6 100644
--- a/bta/av/bta_av_aact.c
+++ b/bta/av/bta_av_aact.c
@@ -1567,7 +1567,10 @@
{
/* SNK initiated L2C connection while SRC was doing SDP. */
/* Wait until timeout to check if SNK starts signalling. */
- APPL_TRACE_EVENT("bta_av_connect_req: coll_mask = 0x%2X", p_scb->coll_mask);
+ APPL_TRACE_EVENT("%s: coll_mask = 0x%2X", __func__, p_scb->coll_mask);
+ p_scb->coll_mask |= BTA_AV_COLL_API_CALLED;
+ APPL_TRACE_EVENT("%s: updated coll_mask = 0x%2X", __func__,
+ p_scb->coll_mask);
return;
}
diff --git a/bta/av/bta_av_act.c b/bta/av/bta_av_act.c
index 5857dd6..9cc802f 100644
--- a/bta/av/bta_av_act.c
+++ b/bta/av/bta_av_act.c
@@ -1613,6 +1613,8 @@
if (bta_av_is_scb_opening(p_scb))
{
+ APPL_TRACE_DEBUG("%s: stream state opening: SDP started = %d",
+ __func__, p_scb->sdp_discovery_started);
if (p_scb->sdp_discovery_started)
{
/* We are still doing SDP. Run the timer again. */
@@ -1634,6 +1636,7 @@
{
/* Stay in incoming state if SNK does not start signalling */
+ APPL_TRACE_DEBUG("%s: stream state incoming", __func__);
/* API open was called right after SNK opened L2C connection. */
if (p_scb->coll_mask & BTA_AV_COLL_API_CALLED)
{
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c
index bb8e0b5..e156465 100644
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -4425,7 +4425,6 @@
else
{
sec_event.auth_cmpl.success = TRUE;
- /* We also register for Service Changed right after connect. */
if (!p_data->complt.smp_over_br)
GATT_ConfigServiceChangeCCC(bda, TRUE, BT_TRANSPORT_LE);
}
diff --git a/bta/gatt/bta_gattc_act.c b/bta/gatt/bta_gattc_act.c
index 388d9a4..01b06b8 100644
--- a/bta/gatt/bta_gattc_act.c
+++ b/bta/gatt/bta_gattc_act.c
@@ -518,7 +518,7 @@
/* open/hold a connection */
if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda,
- TRUE, p_data->api_conn.transport))
+ true, p_data->api_conn.transport, false))
{
APPL_TRACE_ERROR("Connection open failure");
@@ -558,7 +558,7 @@
if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE))
{
/* always call open to hold a connection */
- if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE, p_data->transport))
+ if (!GATT_Connect(p_data->client_if, p_data->remote_bda, false, p_data->transport, false))
{
uint8_t *bda = (uint8_t *)p_data->remote_bda;
status = BTA_GATT_ERROR;
diff --git a/bta/gatt/bta_gatts_act.c b/bta/gatt/bta_gatts_act.c
index 4c35b0c..3f357bf 100644
--- a/bta/gatt/bta_gatts_act.c
+++ b/bta/gatt/bta_gatts_act.c
@@ -689,7 +689,7 @@
{
/* should always get the connection ID */
if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
- p_msg->api_open.is_direct, p_msg->api_open.transport))
+ p_msg->api_open.is_direct, p_msg->api_open.transport, false))
{
status = BTA_GATT_OK;
diff --git a/bta/hh/bta_hh_le.c b/bta/hh/bta_hh_le.c
index e6f854f..92b3c40 100644
--- a/bta/hh/bta_hh_le.c
+++ b/bta/hh/bta_hh_le.c
@@ -802,7 +802,7 @@
if (p_rpt->uuid == GATT_UUID_HID_REPORT &&
p_rpt->client_cfg_value == BTA_GATT_CLT_CONFIG_NOTIFICATION)
{
- APPL_TRACE_DEBUG("---> Deregister Report ID: %d", p_rpt->rpt_id);
+ APPL_TRACE_DEBUG("%s ---> Deregister Report ID: %d", __func__, p_rpt->rpt_id);
BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
p_rpt->char_inst_id);
}
@@ -810,7 +810,7 @@
else if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT ||
p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT)
{
- APPL_TRACE_DEBUG("<--- Register Boot Report ID: %d", p_rpt->rpt_id);
+ APPL_TRACE_DEBUG("%s <--- Register Boot Report ID: %d", __func__, p_rpt->rpt_id);
BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
p_rpt->char_inst_id);
}
@@ -822,14 +822,14 @@
p_rpt->client_cfg_value == BTA_GATT_CLT_CONFIG_NOTIFICATION)
{
- APPL_TRACE_DEBUG("---> Deregister Boot Report ID: %d", p_rpt->rpt_id);
+ APPL_TRACE_DEBUG("%s ---> Deregister Boot Report ID: %d", __func__, p_rpt->rpt_id);
BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
p_rpt->char_inst_id);
}
else if (p_rpt->uuid == GATT_UUID_HID_REPORT &&
p_rpt->client_cfg_value == BTA_GATT_CLT_CONFIG_NOTIFICATION)
{
- APPL_TRACE_DEBUG("<--- Register Report ID: %d", p_rpt->rpt_id);
+ APPL_TRACE_DEBUG("%s <--- Register Report ID: %d", __func__, p_rpt->rpt_id);
BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
p_rpt->char_inst_id);
}
@@ -842,6 +842,41 @@
/*******************************************************************************
**
+** Function bta_hh_le_deregister_input_notif
+**
+** Description Deregister all notifications
+**
+*******************************************************************************/
+void bta_hh_le_deregister_input_notif(tBTA_HH_DEV_CB *p_dev_cb)
+{
+ tBTA_HH_LE_RPT *p_rpt = &p_dev_cb->hid_srvc.report[0];
+
+ for (UINT8 i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++)
+ {
+ if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT)
+ {
+ if (p_rpt->uuid == GATT_UUID_HID_REPORT &&
+ p_rpt->client_cfg_value == BTA_GATT_CLT_CONFIG_NOTIFICATION)
+ {
+ APPL_TRACE_DEBUG("%s ---> Deregister Report ID: %d", __func__, p_rpt->rpt_id);
+ BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
+ p_rpt->char_inst_id);
+ }
+ else if ((p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT ||
+ p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) &&
+ p_rpt->client_cfg_value == BTA_GATT_CLT_CONFIG_NOTIFICATION)
+ {
+ APPL_TRACE_DEBUG("%s ---> Deregister Boot Report ID: %d", __func__, p_rpt->rpt_id);
+ BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
+ p_rpt->char_inst_id);
+ }
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
** Function bta_hh_le_open_cmpl
**
** Description HID over GATT connection sucessfully opened
@@ -2208,6 +2243,8 @@
{
tBTA_HH_CBDATA disc_dat = {BTA_HH_OK, 0};
+ /* deregister all notification */
+ bta_hh_le_deregister_input_notif(p_cb);
/* finaliza device driver */
bta_hh_co_close(p_cb->hid_handle, p_cb->app_id);
/* update total conn number */
diff --git a/bta/hl/bta_hl_sdp.c b/bta/hl/bta_hl_sdp.c
index 0d7f7be..826adcd 100644
--- a/bta/hl/bta_hl_sdp.c
+++ b/bta/hl/bta_hl_sdp.c
@@ -179,7 +179,7 @@
UINT8 data_exchange_spec = BTA_HL_SDP_IEEE_11073_20601;
UINT8 mcap_sup_proc = BTA_HL_MCAP_SUP_PROC_MASK;
UINT16 profile_uuid = UUID_SERVCLASS_HDP_PROFILE;
- UINT16 version = BTA_HL_VERSION_01_00;
+ UINT16 version = BTA_HL_VERSION;
UINT8 num_services=1;
tBTA_HL_APP_CB *p_cb = BTA_HL_GET_APP_CB_PTR(0);
BOOLEAN result = TRUE;
@@ -382,7 +382,7 @@
UINT8 data_exchange_spec = BTA_HL_SDP_IEEE_11073_20601;
UINT8 mcap_sup_proc = BTA_HL_MCAP_SUP_PROC_MASK;
UINT16 profile_uuid = UUID_SERVCLASS_HDP_PROFILE;
- UINT16 version = BTA_HL_VERSION_01_00;
+ UINT16 version = BTA_HL_VERSION;
UINT8 num_services=1;
tBTA_HL_APP_CB *p_cb = BTA_HL_GET_APP_CB_PTR(app_idx);
BOOLEAN result = TRUE;
diff --git a/bta/include/bta_ag_api.h b/bta/include/bta_ag_api.h
index ff85c9b..fa76a57 100644
--- a/bta/include/bta_ag_api.h
+++ b/bta/include/bta_ag_api.h
@@ -30,6 +30,24 @@
/*****************************************************************************
** Constants and data types
*****************************************************************************/
+#define HFP_VERSION_1_1 0x0101
+#define HFP_VERSION_1_5 0x0105
+#define HFP_VERSION_1_6 0x0106
+#define HFP_VERSION_1_7 0x0107
+
+#define HSP_VERSION_1_0 0x0100
+#define HSP_VERSION_1_2 0x0102
+
+/* Note, if you change the default version here, please also change the one in
+ * bta_hs_api.h, they are meant to be the same.
+ */
+#ifndef BTA_HFP_VERSION
+#define BTA_HFP_VERSION HFP_VERSION_1_7
+#endif
+
+#ifndef BTA_HFP_HF_IND_SUPPORTED
+#define BTA_HFP_HF_IND_SUPPORTED TRUE
+#endif
/* AG feature masks */
#define BTA_AG_FEAT_3WAY 0x00000001 /* Three-way calling */
@@ -42,12 +60,15 @@
#define BTA_AG_FEAT_ECC 0x00000080 /* Enhanced Call Control */
#define BTA_AG_FEAT_EXTERR 0x00000100 /* Extended error codes */
#define BTA_AG_FEAT_CODEC 0x00000200 /* Codec Negotiation */
-#define BTA_AG_FEAT_VOIP 0x00000400 /* VoIP call */
+#define BTA_AG_FEAT_HF_IND 0x00000400 /* HF Indicators */
+#define BTA_AG_FEAT_ESCO 0x00000800 /* eSCO S4 (and T2) setting supported */
+
/* Proprietary features: using 31 ~ 16 bits */
#define BTA_AG_FEAT_BTRH 0x00010000 /* CCAP incoming call hold */
#define BTA_AG_FEAT_UNAT 0x00020000 /* Pass unknown AT commands to application */
#define BTA_AG_FEAT_NOSCO 0x00040000 /* No SCO control performed by BTA AG */
#define BTA_AG_FEAT_NO_ESCO 0x00080000 /* Do not allow or use eSCO */
+#define BTA_AG_FEAT_VOIP 0x00100000 /* VoIP call */
typedef UINT32 tBTA_AG_FEAT;
@@ -63,6 +84,9 @@
#define BTA_AG_FAIL_RFCOMM 2 /* Open failed due to RFCOMM */
#define BTA_AG_FAIL_RESOURCES 3 /* out of resources failure */
+/*Status to disallow passing AT Events after BTIF */
+
+#define BTA_AG_DISALLOW_AT 5
typedef UINT8 tBTA_AG_STATUS;
/* handle values used with BTA_AgResult */
@@ -73,6 +97,18 @@
* SCO_NO_CHANGE is used for changing sco behavior
* They donot interfere with each other
*/
+
+/* Number of supported HF indicators, there is one HF indicator so far i.e.
+ enhanced driver status. */
+/* Number of supported HF indicators,
+ 1 for Enhanced Safety Status
+ 2 for Battery Level Status */
+#ifndef BTA_AG_NUM_LOCAL_HF_IND
+#define BTA_AG_NUM_LOCAL_HF_IND 2
+#endif
+
+
+
#define BTA_AG_HANDLE_SCO_NO_CHANGE 0xFFFF
/* AG result codes used with BTA_AgResult */
@@ -98,6 +134,7 @@
#define BTA_AG_IN_CALL_HELD_RES 19 /* Incoming call held */
#define BTA_AG_UNAT_RES 20 /* Response to unknown AT command event */
#define BTA_AG_MULTI_CALL_RES 21 /* SLC at three way call */
+#define BTA_AG_BIND_RES 22 /* Activate/Deactivate HF indicator */
typedef UINT8 tBTA_AG_RES;
@@ -110,9 +147,14 @@
#define BTA_AG_PEER_FEAT_ECS 0x0020 /* Enhanced Call Status */
#define BTA_AG_PEER_FEAT_ECC 0x0040 /* Enhanced Call Control */
#define BTA_AG_PEER_FEAT_CODEC 0x0080 /* Codec Negotiation */
-#define BTA_AG_PEER_FEAT_VOIP 0x0100 /* VoIP call */
+#define BTA_AG_PEER_FEAT_HF_IND 0x0100 /* HF Indicators */
+#define BTA_AG_PEER_FEAT_ESCO 0x0200 /* eSCO S4 (and T2) setting supported */
-typedef UINT16 tBTA_AG_PEER_FEAT;
+/* Proprietary features: using bits after 12 */
+#define BTA_AG_PEER_FEAT_UNAT 0x1000 /* Pass unknown AT command responses to application */
+#define BTA_AG_PEER_FEAT_VOIP 0x2000 /* VoIP call */
+
+typedef uint16_t tBTA_AG_PEER_FEAT;
/* HFP peer supported codec masks */
// TODO(google) This should use common definitions
@@ -204,8 +246,9 @@
/* data associated with BTA_AG_IND_RES */
typedef struct
{
- UINT16 id;
- UINT16 value;
+ uint16_t id;
+ uint16_t value;
+ bool on_demand;
} tBTA_AG_IND;
/* data type for BTA_AgResult() */
@@ -254,6 +297,8 @@
#define BTA_AG_AT_CBC_EVT 25 /* Battery Level report from HF */
#define BTA_AG_AT_BAC_EVT 26 /* avablable codec */
#define BTA_AG_AT_BCS_EVT 27 /* Codec select */
+#define BTA_AG_AT_BIND_EVT 28 /* HF indicator */
+#define BTA_AG_AT_BIEV_EVT 29 /* HF indicator updates from peer */
typedef UINT8 tBTA_AG_EVT;
@@ -305,6 +350,7 @@
char str[BTA_AG_AT_MAX_LEN+1];
UINT16 num;
UINT8 idx; /* call number used by CLCC and CHLD */
+ UINT16 lidx; /* long index, ex, HF indicator */
} tBTA_AG_VAL;
/* union of data associated with AG callback */
@@ -368,12 +414,24 @@
#define BTA_AG_BEARER_RES2 6 /* Reserved */
#define BTA_AG_BEARER_RES3 7 /* Reserved */
+/* type for HF indicator */
+typedef struct
+{
+ UINT16 ind_id;
+ BOOLEAN is_supported;
+ BOOLEAN is_enable;
+ UINT32 ind_min_val;
+ UINT32 ind_max_val;
+} tBTA_AG_HF_IND;
+
/* AG configuration structure */
typedef struct
{
char *cind_info;
- INT32 conn_tout;
- UINT16 sco_pkt_types;
+ char *bind_info;
+ uint8_t num_local_hf_ind;
+ int32_t conn_tout;
+ uint16_t sco_pkt_types;
char *chld_val_ecc;
char *chld_val;
} tBTA_AG_CFG;
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index b305499..b20c271 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -614,8 +614,11 @@
/* BLE related definition */
#define BTA_DM_AUTH_FAIL_BASE (HCI_ERR_MAX_ERR + 10)
-#define BTA_DM_AUTH_CONVERT_SMP_CODE(x) (BTA_DM_AUTH_FAIL_BASE + (x))
-#define BTA_DM_AUTH_SMP_PASSKEY_FAIL BTA_DM_AUTH_CONVERT_SMP_CODE (SMP_PASSKEY_ENTRY_FAIL)
+
+/* Converts SMP error codes defined in smp_api.h to SMP auth fail reasons below. */
+#define BTA_DM_AUTH_CONVERT_SMP_CODE(x) (BTA_DM_AUTH_FAIL_BASE + (x))
+
+#define BTA_DM_AUTH_SMP_PASSKEY_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_PASSKEY_ENTRY_FAIL)
#define BTA_DM_AUTH_SMP_OOB_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_OOB_FAIL)
#define BTA_DM_AUTH_SMP_PAIR_AUTH_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_PAIR_AUTH_FAIL)
#define BTA_DM_AUTH_SMP_CONFIRM_VALUE_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_CONFIRM_VALUE_ERR)
@@ -632,6 +635,7 @@
#define BTA_DM_AUTH_SMP_BUSY (BTA_DM_AUTH_FAIL_BASE + SMP_BUSY)
#define BTA_DM_AUTH_SMP_ENC_FAIL (BTA_DM_AUTH_FAIL_BASE + SMP_ENC_FAIL)
#define BTA_DM_AUTH_SMP_RSP_TIMEOUT (BTA_DM_AUTH_FAIL_BASE + SMP_RSP_TIMEOUT)
+#define BTA_DM_AUTH_SMP_CONN_TOUT (BTA_DM_AUTH_FAIL_BASE + SMP_CONN_TOUT)
/* connection parameter boundary value and dummy value */
#define BTA_DM_BLE_SCAN_INT_MIN BTM_BLE_SCAN_INT_MIN
diff --git a/bta/include/bta_hl_api.h b/bta/include/bta_hl_api.h
index b8e2c9a..62388be 100644
--- a/bta/include/bta_hl_api.h
+++ b/bta/include/bta_hl_api.h
@@ -89,7 +89,7 @@
#define BTA_HL_NUM_PROTO_ELEMS 2
#endif
-#define BTA_HL_VERSION_01_00 0x0100
+#define BTA_HL_VERSION 0x0101
#define BTA_HL_NUM_ADD_PROTO_LISTS 1
#define BTA_HL_NUM_ADD_PROTO_ELEMS 2
#define BTA_HL_MDEP_SEQ_SIZE 20
diff --git a/btif/Android.mk b/btif/Android.mk
index 78a475b..eee76b9 100644
--- a/btif/Android.mk
+++ b/btif/Android.mk
@@ -23,7 +23,8 @@
# HAL layer
btifCommonSrc := \
- src/bluetooth.c
+ src/bluetooth.c \
+ ../EventLogTags.logtags
# BTIF implementation
btifCommonSrc += \
diff --git a/btif/src/btif_av.c b/btif/src/btif_av.c
index 03ba842..f852d48 100644
--- a/btif/src/btif_av.c
+++ b/btif/src/btif_av.c
@@ -1044,13 +1044,21 @@
static void btif_av_handle_event(UINT16 event, char* p_param)
{
+ BTIF_TRACE_EVENT("%s event:%s", __func__,
+ dump_av_sm_event_name((btif_av_sm_event_t)event));
switch(event)
{
case BTIF_AV_CLEANUP_REQ_EVT:
- BTIF_TRACE_EVENT("%s: BTIF_AV_CLEANUP_REQ_EVT", __FUNCTION__);
btif_a2dp_stop_media_task();
break;
+ case BTA_AV_REGISTER_EVT:
+ if (btif_av_cb.sm_handle == NULL)
+ {
+ btif_av_cb.bta_handle = ((tBTA_AV*)p_param)->registr.hndl;
+ BTIF_TRACE_DEBUG("%s: BTA AV Handle updated", __func__);
+ }
+ /* FALLTHROUGH */
default:
btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
btif_av_event_free_data(event, p_param);
diff --git a/btif/src/btif_config.c b/btif/src/btif_config.c
index 24a8c17..d5fb323 100644
--- a/btif/src/btif_config.c
+++ b/btif/src/btif_config.c
@@ -52,6 +52,8 @@
#include <cutils/properties.h>
#endif /* !defined(OS_GENERIC) */
+#define BT_CONFIG_SOURCE_TAG_NUM 1010001
+
#define INFO_SECTION "Info"
#define FILE_TIMESTAMP "TimeCreated"
#define FILE_SOURCE "FileSource"
@@ -199,6 +201,8 @@
goto error;
}
+ LOG_EVENT_INT(BT_CONFIG_SOURCE_TAG_NUM, btif_config_source);
+
pthread_mutex_unlock(&lock);
return future_new_immediate(FUTURE_SUCCESS);
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index b1ad00b..49fa274 100644
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -3086,6 +3086,8 @@
{
case BTA_DM_AUTH_SMP_PAIR_AUTH_FAIL:
case BTA_DM_AUTH_SMP_CONFIRM_VALUE_FAIL:
+ case BTA_DM_AUTH_SMP_UNKNOWN_ERR:
+ case BTA_DM_AUTH_SMP_CONN_TOUT:
btif_dm_remove_ble_bonding_keys();
status = BT_STATUS_AUTH_FAILURE;
break;
diff --git a/btif/src/btif_gatt_client.c b/btif/src/btif_gatt_client.c
index 57b5958..c70fa49 100644
--- a/btif/src/btif_gatt_client.c
+++ b/btif/src/btif_gatt_client.c
@@ -1023,6 +1023,9 @@
static void btm_read_rssi_cb (tBTM_RSSI_RESULTS *p_result)
{
+ if (!p_result)
+ return;
+
btif_gattc_cb_t btif_cb;
bdcpy(btif_cb.bd_addr.address, p_result->rem_bda);
diff --git a/btif/src/btif_gatt_test.c b/btif/src/btif_gatt_test.c
index 349674e..ab1c1d2 100644
--- a/btif/src/btif_gatt_test.c
+++ b/btif/src/btif_gatt_test.c
@@ -240,7 +240,7 @@
if (params->u1 == BT_DEVICE_TYPE_BLE)
BTM_SecAddBleDevice(params->bda1->address, NULL, BT_DEVICE_TYPE_BLE, params->u2);
- if ( !GATT_Connect(test_cb.gatt_if, params->bda1->address, TRUE, BT_TRANSPORT_LE) )
+ if ( !GATT_Connect(test_cb.gatt_if, params->bda1->address, true, BT_TRANSPORT_LE, false) )
{
LOG_ERROR(LOG_TAG, "%s: GATT_Connect failed!", __FUNCTION__);
}
diff --git a/btif/src/btif_hf.c b/btif/src/btif_hf.c
index 4987bbe..6abf099 100644
--- a/btif/src/btif_hf.c
+++ b/btif/src/btif_hf.c
@@ -73,6 +73,8 @@
BTA_AG_FEAT_BTRH | \
BTA_AG_FEAT_VREC | \
BTA_AG_FEAT_CODEC |\
+ BTA_AG_FEAT_HF_IND | \
+ BTA_AG_FEAT_ESCO | \
BTA_AG_FEAT_UNAT)
#endif
#else
@@ -84,6 +86,8 @@
BTA_AG_FEAT_EXTERR | \
BTA_AG_FEAT_BTRH | \
BTA_AG_FEAT_VREC | \
+ BTA_AG_FEAT_HF_IND | \
+ BTA_AG_FEAT_ESCO | \
BTA_AG_FEAT_UNAT)
#endif
#endif
@@ -621,6 +625,21 @@
BTHF_WBS_YES : BTHF_WBS_NO, &btif_hf_cb[idx].connected_bda);
break;
+ case BTA_AG_AT_BIND_EVT:
+ if (p_data->val.hdr.status == BTA_AG_SUCCESS)
+ {
+ HAL_CBACK(bt_hf_callbacks, bind_cb,p_data->val.str,
+ &btif_hf_cb[idx].connected_bda);
+ }
+ break;
+
+ case BTA_AG_AT_BIEV_EVT:
+ if (p_data->val.hdr.status == BTA_AG_SUCCESS)
+ {
+ HAL_CBACK(bt_hf_callbacks, biev_cb, (bthf_hf_ind_type_t)p_data->val.lidx, (int)p_data->val.num,
+ &btif_hf_cb[idx].connected_bda);
+ }
+ break;
default:
BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event);
break;
@@ -1107,6 +1126,33 @@
/*******************************************************************************
**
+** Function bind_response
+**
+** Description Send +BIND response
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t bind_response(bthf_hf_ind_type_t ind_id, bthf_hf_ind_status_t ind_status,
+ bt_bdaddr_t * bd_addr)
+{
+ CHECK_BTHF_INIT();
+
+ int index = btif_hf_idx_by_bdaddr(bd_addr);
+ if (!is_connected(bd_addr) || index == BTIF_HF_INVALID_IDX)
+ return BT_STATUS_FAIL;
+
+ tBTA_AG_RES_DATA ag_res;
+ memset(&ag_res, 0, sizeof(ag_res));
+ ag_res.ind.id = ind_id;
+ ag_res.ind.on_demand = (ind_status == BTHF_HF_IND_ENABLED);
+
+ BTA_AgResult(btif_hf_cb[index].handle, BTA_AG_BIND_RES, &ag_res);
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
** Function formatted_at_response
**
** Description Pre-formatted AT response, typically in response to unknown AT cmd
@@ -1581,6 +1627,7 @@
phone_state_change,
cleanup,
configure_wbs,
+ bind_response,
};
/*******************************************************************************
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index 08af577..262bc53 100644
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -492,6 +492,25 @@
}
}
+static void btm_read_rssi_cb(void *data)
+{
+ assert(data);
+
+ tBTM_RSSI_RESULTS *result = (tBTM_RSSI_RESULTS*)data;
+ if (result->status != BTM_SUCCESS)
+ {
+ LOG_ERROR(LOG_TAG, "%s unable to read remote RSSI (status %d)",
+ __func__, result->status);
+ return;
+ }
+
+ char temp_buffer[20] = {0};
+ LOG_WARN(LOG_TAG, "%s device: %s, rssi: %d", __func__,
+ bdaddr_to_string((bt_bdaddr_t *)result->rem_bda, temp_buffer,
+ sizeof(temp_buffer)),
+ result->rssi);
+}
+
/*****************************************************************************
** A2DP CTRL PATH
*****************************************************************************/
@@ -3096,13 +3115,19 @@
APPL_TRACE_WARNING("%s() - TX queue buffer count %d/%d", __func__,
fixed_queue_length(btif_media_cb.TxAaQ),
MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ - nb_frame);
+ // Keep track of drop-outs
btif_media_cb.stats.tx_queue_dropouts++;
btif_media_cb.stats.tx_queue_last_dropouts_us = timestamp_us;
+ // Flush all queued buffers...
while (fixed_queue_length(btif_media_cb.TxAaQ)) {
btif_media_cb.stats.tx_queue_total_dropped_messages++;
osi_free(fixed_queue_try_dequeue(btif_media_cb.TxAaQ));
}
+
+ // Request RSSI for log purposes if we had to flush buffers
+ bt_bdaddr_t peer_bda = btif_av_get_addr();
+ BTM_ReadRSSI(peer_bda.address, btm_read_rssi_cb);
}
// Transcode frame
diff --git a/btif/src/btif_rc.c b/btif/src/btif_rc.c
index b79832b..28a2499 100644
--- a/btif/src/btif_rc.c
+++ b/btif/src/btif_rc.c
@@ -280,6 +280,7 @@
#endif
static void rc_start_play_status_timer(void);
static bool absolute_volume_disabled(void);
+static char const* key_id_to_str(uint16_t id);
/*****************************************************************************
** Static variables
@@ -332,7 +333,7 @@
return;
}
- BTIF_TRACE_DEBUG("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd);
+ LOG_INFO(LOG_TAG, "AVRCP: Send key %s (%d) fd=%d", key_id_to_str(key), pressed, fd);
send_event(fd, EV_KEY, key, pressed);
send_event(fd, EV_SYN, SYN_REPORT, 0);
}
@@ -4257,3 +4258,11 @@
}
return false;
}
+
+static char const* key_id_to_str(uint16_t id) {
+ for (int i = 0; key_map[i].name != NULL; i++) {
+ if (id == key_map[i].mapped_id)
+ return key_map[i].name;
+ }
+ return "UNKNOWN KEY";
+}
diff --git a/btif/src/btif_util.c b/btif/src/btif_util.c
index f4cffcb..a8c58c9 100644
--- a/btif/src/btif_util.c
+++ b/btif/src/btif_util.c
@@ -306,6 +306,8 @@
CASE_RETURN_STR(BTA_AG_AT_CBC_EVT)
CASE_RETURN_STR(BTA_AG_AT_BAC_EVT)
CASE_RETURN_STR(BTA_AG_AT_BCS_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_BIND_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_BIEV_EVT)
default:
return "UNKNOWN MSG ID";
diff --git a/hci/Android.mk b/hci/Android.mk
index 24e3d4d..0727100 100644
--- a/hci/Android.mk
+++ b/hci/Android.mk
@@ -19,7 +19,8 @@
src/hci_packet_parser.c \
src/low_power_manager.c \
src/packet_fragmenter.c \
- src/vendor.c
+ src/vendor.c \
+ ../EventLogTags.logtags
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/include \
diff --git a/hci/src/hci_layer.c b/hci/src/hci_layer.c
index d566141..3a45135 100644
--- a/hci/src/hci_layer.c
+++ b/hci/src/hci_layer.c
@@ -55,6 +55,8 @@
#define PREAMBLE_BUFFER_SIZE 4 // max preamble size, ACL
#define RETRIEVE_ACL_LENGTH(preamble) ((((preamble)[3]) << 8) | (preamble)[2])
+#define BT_HCI_TIMEOUT_TAG_NUM 1010000
+
static const uint8_t preamble_sizes[] = {
HCI_COMMAND_PREAMBLE_SIZE,
HCI_ACL_PREAMBLE_SIZE,
@@ -534,6 +536,7 @@
// We shouldn't try to recover the stack from this command timeout.
// If it's caused by a software bug, fix it. If it's a hardware bug, fix it.
LOG_ERROR(LOG_TAG, "%s hci layer timeout waiting for response to a command. opcode: 0x%x", __func__, wait_entry->opcode);
+ LOG_EVENT_INT(BT_HCI_TIMEOUT_TAG_NUM, wait_entry->opcode);
}
LOG_ERROR(LOG_TAG, "%s restarting the bluetooth process.", __func__);
diff --git a/stack/avdt/avdt_msg.c b/stack/avdt/avdt_msg.c
index adc1ae7..9697a59 100644
--- a/stack/avdt/avdt_msg.c
+++ b/stack/avdt/avdt_msg.c
@@ -26,6 +26,7 @@
*
******************************************************************************/
+#include <log/log.h>
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
@@ -673,6 +674,11 @@
case AVDT_CAT_PROTECT:
p_cfg->psc_mask &= ~AVDT_PSC_PROTECT;
+ if (p + elem_len > p_end) {
+ err = AVDT_ERR_LENGTH;
+ android_errorWriteLog(0x534e4554, "78288378");
+ break;
+ }
if ((elem_len + protect_offset) < AVDT_PROTECT_SIZE)
{
p_cfg->num_protect++;
@@ -747,6 +753,11 @@
{
tmp = AVDT_CODEC_SIZE - 1;
}
+ if (p + tmp > p_end) {
+ err = AVDT_ERR_LENGTH;
+ android_errorWriteLog(0x534e4554, "78288378");
+ break;
+ }
p_cfg->num_codec++;
p_cfg->codec_info[0] = elem_len;
memcpy(&p_cfg->codec_info[1], p, tmp);
diff --git a/stack/avrc/avrc_api.c b/stack/avrc/avrc_api.c
index 77ca7d4..e612031 100644
--- a/stack/avrc/avrc_api.c
+++ b/stack/avrc/avrc_api.c
@@ -316,15 +316,15 @@
if (status != AVRC_STS_NO_ERROR)
{
- /* use the current GKI buffer to build/send the reject message */
- p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
+ p_rsp = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
+ p_rsp->offset = p_pkt->offset;
+ p_data = (uint8_t*)(p_rsp + 1) + p_pkt->offset;
*p_data++ = AVRC_RSP_REJ;
p_data += AVRC_VENDOR_HDR_SIZE; /* pdu */
*p_data++ = 0; /* pkt_type */
UINT16_TO_BE_STREAM(p_data, 1); /* len */
*p_data++ = status; /* error code */
- p_pkt->len = AVRC_VENDOR_HDR_SIZE + 5;
- p_rsp = p_pkt;
+ p_rsp->len = AVRC_VENDOR_HDR_SIZE + 5;
}
return p_rsp;
@@ -472,6 +472,7 @@
if (p_rsp)
{
AVCT_MsgReq( handle, label, AVCT_RSP, p_rsp);
+ osi_free_and_reset((void **)pp_pkt);
drop_code = 3;
}
else if (p_msg->hdr.opcode == AVRC_OP_DROP)
diff --git a/stack/bnep/bnep_main.c b/stack/bnep/bnep_main.c
index ad1f59f..39a5a5f 100644
--- a/stack/bnep/bnep_main.c
+++ b/stack/bnep/bnep_main.c
@@ -483,6 +483,13 @@
UINT16 protocol = 0;
UINT8 *p_src_addr, *p_dst_addr;
+ if (rem_len == 0)
+ {
+ android_errorWriteLog(0x534e4554, "78286118");
+ osi_free(p_buf);
+ return;
+ }
+
/* Find CCB based on CID */
if ((p_bcb = bnepu_find_bcb_by_cid (l2cap_cid)) == NULL)
@@ -529,23 +536,35 @@
UINT16 org_len, new_len;
/* parse the extension headers and process unknown control headers */
org_len = rem_len;
- new_len = 0;
do {
- if (org_len < 2) break;
+ if (org_len < 2) {
+ android_errorWriteLog(0x534e4554, "67863755");
+ break;
+ }
ext = *p++;
length = *p++;
- p += length;
new_len = (length + 2);
- if (new_len > org_len) break;
+ if (new_len > org_len) {
+ android_errorWriteLog(0x534e4554, "67863755");
+ break;
+ }
- if ((!(ext & 0x7F)) && (*p > BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG))
- bnep_send_command_not_understood (p_bcb, *p);
+ if ((ext & 0x7F) == BNEP_EXTENSION_FILTER_CONTROL) {
+ if (length == 0) {
+ android_errorWriteLog(0x534e4554, "79164722");
+ break;
+ }
+ if (*p > BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG) {
+ bnep_send_command_not_understood(p_bcb, *p);
+ }
+ }
+
+ p += length;
org_len -= new_len;
} while (ext & 0x80);
- android_errorWriteLog(0x534e4554, "67863755");
}
osi_free(p_buf);
@@ -595,14 +614,13 @@
{
ext_type = *p++;
rem_len--;
- android_errorWriteLog(0x534e4554, "69271284");
extension_present = ext_type >> 7;
ext_type &= 0x7F;
/* if unknown extension present stop processing */
- if (ext_type)
- break;
+ if (ext_type != BNEP_EXTENSION_FILTER_CONTROL) break;
+ android_errorWriteLog(0x534e4554, "69271284");
p = bnep_process_control_packet (p_bcb, p, &rem_len, TRUE);
}
}
diff --git a/stack/btm/btm_sco.c b/stack/btm/btm_sco.c
index 8c374f9..4ceb640 100644
--- a/stack/btm/btm_sco.c
+++ b/stack/btm/btm_sco.c
@@ -34,6 +34,8 @@
#include "btm_int.h"
#include "hcidefs.h"
#include "bt_utils.h"
+#include "device/include/controller.h"
+
#if BTM_SCO_INCLUDED == TRUE
@@ -59,7 +61,7 @@
{
BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */
BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */
- 0x000a, /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */
+ 0x000c, /* 12 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */
0x0060, /* Inp Linear, Air CVSD, 2s Comp, 16bit */
(BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */
BTM_SCO_PKT_TYPES_MASK_HV2 +
@@ -67,7 +69,7 @@
BTM_SCO_PKT_TYPES_MASK_EV3 +
BTM_SCO_PKT_TYPES_MASK_EV4 +
BTM_SCO_PKT_TYPES_MASK_EV5),
- BTM_ESCO_RETRANS_POWER /* Retransmission Effort (Power) */
+ BTM_ESCO_RETRANS_QUALITY /* Retransmission Effort */
};
/*******************************************************************************
@@ -668,7 +670,7 @@
btm_cb.btm_sco_pkt_types_supported);
/* OR in any exception packet types */
- if (btm_cb.sco_cb.desired_sco_mode == HCI_LINK_TYPE_ESCO)
+ if (controller_get_interface()->get_bt_version()->hci_version >= HCI_PROTO_VERSION_2_0)
{
temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
(btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
diff --git a/stack/btu/btu_hcif.c b/stack/btu/btu_hcif.c
index 9fa29e7..ade7a9b 100644
--- a/stack/btu/btu_hcif.c
+++ b/stack/btu/btu_hcif.c
@@ -1633,10 +1633,17 @@
/* extract the HCI handle first */
UINT8 status;
UINT16 handle;
+ UINT16 interval;
+ UINT16 latency;
+ UINT16 timeout;
- STREAM_TO_UINT8 (status, p);
- STREAM_TO_UINT16 (handle, p);
- l2cble_process_conn_update_evt(handle, status);
+ STREAM_TO_UINT8(status, p);
+ STREAM_TO_UINT16(handle, p);
+ STREAM_TO_UINT16(interval, p);
+ STREAM_TO_UINT16(latency, p);
+ STREAM_TO_UINT16(timeout, p);
+
+ l2cble_process_conn_update_evt(handle, status, interval, latency, timeout);
}
static void btu_ble_read_remote_feat_evt (UINT8 *p)
diff --git a/stack/gap/gap_ble.c b/stack/gap/gap_ble.c
index d92665a..e14b13e 100644
--- a/stack/gap/gap_ble.c
+++ b/stack/gap/gap_ble.c
@@ -708,7 +708,7 @@
p_clcb->connected = TRUE;
/* hold the link here */
- if (!GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE, BT_TRANSPORT_LE))
+ if (!GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE, BT_TRANSPORT_LE, false))
return started;
/* enqueue the request */
diff --git a/stack/gatt/gatt_api.c b/stack/gatt/gatt_api.c
index b8c45d3..597dc63 100644
--- a/stack/gatt/gatt_api.c
+++ b/stack/gatt/gatt_api.c
@@ -1357,7 +1357,8 @@
** Returns TRUE if connection started; FALSE if connection start failure.
**
*******************************************************************************/
-BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct, tBT_TRANSPORT transport)
+BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct,
+ tBT_TRANSPORT transport, BOOLEAN opportunistic)
{
tGATT_REG *p_reg;
BOOLEAN status = FALSE;
@@ -1372,7 +1373,7 @@
}
if (is_direct)
- status = gatt_act_connect (p_reg, bd_addr, transport);
+ status = gatt_act_connect (p_reg, bd_addr, transport, opportunistic);
else
{
if (transport == BT_TRANSPORT_LE)
diff --git a/stack/gatt/gatt_attr.c b/stack/gatt/gatt_attr.c
index 9a2c6fa..74f0f35 100644
--- a/stack/gatt/gatt_attr.c
+++ b/stack/gatt/gatt_attr.c
@@ -235,24 +235,26 @@
{
UNUSED(gatt_if);
- GATT_TRACE_EVENT("%s: from %08x%04x connected:%d conn_id=%d reason = 0x%04x", __func__,
- (bda[0]<<24)+(bda[1]<<16)+(bda[2]<<8)+bda[3],
- (bda[4]<<8)+bda[5], connected, conn_id, reason);
+ GATT_TRACE_EVENT ("%s: from %08x%04x connected:%d conn_id=%d reason = 0x%04x", __FUNCTION__,
+ (bda[0]<<24)+(bda[1]<<16)+(bda[2]<<8)+bda[3],
+ (bda[4]<<8)+bda[5], connected, conn_id, reason);
tGATT_PROFILE_CLCB *p_clcb = gatt_profile_find_clcb_by_bd_addr(bda, transport);
- if (connected) {
- if (p_clcb == NULL)
- p_clcb = gatt_profile_clcb_alloc(conn_id, bda, transport);
+ if (p_clcb == NULL)
+ return;
- if (p_clcb == NULL)
- return;
-
+ if (connected)
+ {
+ p_clcb->conn_id = conn_id;
p_clcb->connected = TRUE;
- p_clcb->ccc_stage = GATT_SVC_CHANGED_SERVICE;
- gatt_cl_start_config_ccc(p_clcb);
+
+ if (p_clcb->ccc_stage == GATT_SVC_CHANGED_CONNECTING)
+ {
+ p_clcb->ccc_stage ++;
+ gatt_cl_start_config_ccc(p_clcb);
+ }
} else {
- if (p_clcb != NULL)
- gatt_profile_clcb_dealloc(p_clcb);
+ gatt_profile_clcb_dealloc(p_clcb);
}
}
@@ -455,7 +457,7 @@
p_clcb->connected = TRUE;
}
/* hold the link here */
- GATT_Connect(gatt_cb.gatt_if, remote_bda, TRUE, transport);
+ GATT_Connect(gatt_cb.gatt_if, remote_bda, TRUE, transport, true);
p_clcb->ccc_stage = GATT_SVC_CHANGED_CONNECTING;
if (!p_clcb->connected)
diff --git a/stack/gatt/gatt_cl.c b/stack/gatt/gatt_cl.c
index 433a2f1..e4cb58f 100644
--- a/stack/gatt/gatt_cl.c
+++ b/stack/gatt/gatt_cl.c
@@ -31,6 +31,7 @@
#include "bt_common.h"
#include "gatt_int.h"
#include "l2c_int.h"
+#include "log/log.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)
@@ -566,9 +567,24 @@
UNUSED(len);
GATT_TRACE_DEBUG("gatt_process_error_rsp ");
- STREAM_TO_UINT8(opcode, p);
- STREAM_TO_UINT16(handle, p);
- STREAM_TO_UINT8(reason, p);
+
+ if (len < 4) {
+ android_errorWriteLog(0x534e4554, "79591688");
+ GATT_TRACE_ERROR("Error response too short");
+ // Specification does not clearly define what should happen if error
+ // response is too short. General rule in BT Spec 5.0 Vol 3, Part F 3.4.1.1
+ // is: "If an error code is received in the Error Response that is not
+ // understood by the client, for example an error code that was reserved for
+ // future use that is now being used in a future version of this
+ // specification, then the Error Response shall still be considered to state
+ // that the given request cannot be performed for an unknown reason."
+ opcode = handle = 0;
+ reason = 0x7F;
+ } else {
+ STREAM_TO_UINT8(opcode, p);
+ STREAM_TO_UINT16(handle, p);
+ STREAM_TO_UINT8(reason, p);
+ }
if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY)
{
diff --git a/stack/gatt/gatt_int.h b/stack/gatt/gatt_int.h
index 56760e9..1f97cb7 100644
--- a/stack/gatt/gatt_int.h
+++ b/stack/gatt/gatt_int.h
@@ -532,7 +532,7 @@
/* from gatt_main.c */
extern BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb);
-extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport);
+extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport, bool opportunistic);
extern BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb, tBT_TRANSPORT transport);
extern void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf);
extern void gatt_update_app_use_link_flag ( tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add, BOOLEAN check_acl_link);
diff --git a/stack/gatt/gatt_main.c b/stack/gatt/gatt_main.c
index bda5b41..4f1568a 100644
--- a/stack/gatt/gatt_main.c
+++ b/stack/gatt/gatt_main.c
@@ -274,49 +274,25 @@
**
** Description Update the application use link status
**
-** Returns void.
+** Returns true if any modifications are made, false otherwise.
**
*******************************************************************************/
-void gatt_update_app_hold_link_status (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add)
+BOOLEAN gatt_update_app_hold_link_status(tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add)
{
- UINT8 i;
- BOOLEAN found=FALSE;
-
- if (p_tcb == NULL)
- {
- GATT_TRACE_ERROR("gatt_update_app_hold_link_status p_tcb=NULL");
- return;
- }
-
-
- for (i=0; i<GATT_MAX_APPS; i++)
- {
- if (p_tcb->app_hold_link[i] == gatt_if)
- {
- found = TRUE;
- if (!is_add)
- {
- p_tcb->app_hold_link[i] = 0;
- break;
- }
+ for (int i=0; i<GATT_MAX_APPS; i++) {
+ if (p_tcb->app_hold_link[i] == 0 && is_add) {
+ p_tcb->app_hold_link[i] = gatt_if;
+ GATT_TRACE_DEBUG("%s: added gatt_if=%d idx=%d ", __func__, gatt_if, i);
+ return TRUE;
+ } else if (p_tcb->app_hold_link[i] == gatt_if && !is_add) {
+ p_tcb->app_hold_link[i] = 0;
+ GATT_TRACE_DEBUG("%s: removed gatt_if=%d idx=%d", __func__, gatt_if, i);
+ return TRUE;
}
}
- if (!found && is_add)
- {
- for (i=0; i<GATT_MAX_APPS; i++)
- {
- if (p_tcb->app_hold_link[i] == 0)
- {
- p_tcb->app_hold_link[i] = gatt_if;
- found = TRUE;
- break;
- }
- }
- }
-
- GATT_TRACE_DEBUG("gatt_update_app_hold_link_status found=%d[1-found] idx=%d gatt_if=%d is_add=%d", found, i, gatt_if, is_add);
-
+ GATT_TRACE_DEBUG("%s: gatt_if=%d not found; is_add=%d", __func__, gatt_if, is_add);
+ return FALSE;
}
/*******************************************************************************
@@ -329,34 +305,37 @@
** Returns void.
**
*******************************************************************************/
-void gatt_update_app_use_link_flag (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add, BOOLEAN check_acl_link)
+void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add,
+ BOOLEAN check_acl_link)
{
- GATT_TRACE_DEBUG("gatt_update_app_use_link_flag is_add=%d chk_link=%d",
- is_add, check_acl_link);
+ GATT_TRACE_DEBUG("%s: is_add=%d chk_link=%d", __func__, is_add, check_acl_link);
- gatt_update_app_hold_link_status(gatt_if, p_tcb, is_add);
+ if (!p_tcb)
+ return;
- if (check_acl_link &&
- p_tcb &&
- p_tcb->att_lcid == L2CAP_ATT_CID && /* only update link idle timer for fixed channel */
- (BTM_GetHCIConnHandle(p_tcb->peer_bda, p_tcb->transport) != GATT_INVALID_ACL_HANDLE))
- {
- if (is_add)
- {
- GATT_TRACE_DEBUG("GATT disables link idle timer");
- /* acl link is connected disable the idle timeout */
- GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport);
- }
- else
- {
- if (!gatt_num_apps_hold_link(p_tcb))
- {
- /* acl link is connected but no application needs to use the link
- so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */
- GATT_TRACE_DEBUG("GATT starts link idle timer =%d sec", GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP);
- GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, p_tcb->transport);
- }
+ // If we make no modification, i.e. kill app that was never connected to a device,
+ // skip updating the device state.
+ if (!gatt_update_app_hold_link_status(gatt_if, p_tcb, is_add))
+ return;
+ if (!check_acl_link ||
+ p_tcb->att_lcid != L2CAP_ATT_CID || /* only update link idle timer for fixed channel */
+ (BTM_GetHCIConnHandle(p_tcb->peer_bda, p_tcb->transport) == GATT_INVALID_ACL_HANDLE)) {
+ return;
+ }
+
+ if (is_add) {
+ GATT_TRACE_DEBUG("%s: disable link idle timer", __func__);
+ /* acl link is connected disable the idle timeout */
+ GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport);
+ } else {
+ if (!gatt_num_apps_hold_link(p_tcb)) {
+ /* acl link is connected but no application needs to use the link
+ so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */
+ GATT_TRACE_DEBUG("%s: start link idle timer =%d sec", __func__,
+ GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP);
+ GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP,
+ p_tcb->transport);
}
}
}
@@ -370,7 +349,8 @@
** Returns void.
**
*******************************************************************************/
-BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport)
+BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr,
+ tBT_TRANSPORT transport, BOOLEAN opportunistic)
{
BOOLEAN ret = FALSE;
tGATT_TCB *p_tcb;
@@ -403,7 +383,6 @@
GATT_TRACE_ERROR("gatt_connect failed");
fixed_queue_free(p_tcb->pending_enc_clcb, NULL);
fixed_queue_free(p_tcb->pending_ind_q, NULL);
- fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL);
memset(p_tcb, 0, sizeof(tGATT_TCB));
}
else
@@ -418,7 +397,11 @@
if (ret)
{
- gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, FALSE);
+ if (!opportunistic)
+ gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, FALSE);
+ else
+ GATT_TRACE_DEBUG("%s: connection is opportunistic, not updating app usage",
+ __func__);
}
return ret;
diff --git a/stack/gatt/gatt_sr.c b/stack/gatt/gatt_sr.c
index f1fcea7..e159bae 100644
--- a/stack/gatt/gatt_sr.c
+++ b/stack/gatt/gatt_sr.c
@@ -123,13 +123,16 @@
tGATTS_RSP *p_msg, UINT16 mtu)
{
UINT16 ii, total_len, len;
- BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(tGATTS_RSP));
UINT8 *p;
BOOLEAN is_overflow = FALSE;
- GATT_TRACE_DEBUG ("process_read_multi_rsp status=%d mtu=%d", status, mtu);
+ GATT_TRACE_DEBUG ("%s status=%d mtu=%d", __func__, status, mtu);
+
+ if (p_cmd->multi_rsp_q == NULL)
+ p_cmd->multi_rsp_q = fixed_queue_new(SIZE_MAX);
/* Enqueue the response */
+ BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(tGATTS_RSP));
memcpy((void *)p_buf, (const void *)p_msg, sizeof(tGATTS_RSP));
fixed_queue_enqueue(p_cmd->multi_rsp_q, p_buf);
diff --git a/stack/gatt/gatt_utils.c b/stack/gatt/gatt_utils.c
index f56925d..c2db770 100644
--- a/stack/gatt/gatt_utils.c
+++ b/stack/gatt/gatt_utils.c
@@ -972,7 +972,6 @@
p_tcb->pending_ind_q = fixed_queue_new(SIZE_MAX);
p_tcb->conf_timer = alarm_new("gatt.conf_timer");
p_tcb->ind_ack_timer = alarm_new("gatt.ind_ack_timer");
- p_tcb->sr_cmd.multi_rsp_q = fixed_queue_new(SIZE_MAX);
p_tcb->in_use = TRUE;
p_tcb->tcb_idx = i;
p_tcb->transport = transport;
diff --git a/stack/include/gatt_api.h b/stack/include/gatt_api.h
index a042bb9..182b5ba 100644
--- a/stack/include/gatt_api.h
+++ b/stack/include/gatt_api.h
@@ -1070,14 +1070,18 @@
**
** Parameters gatt_if: applicaiton interface
** bd_addr: peer device address.
-** is_direct: is a direct conenection or a background auto connection
+** is_direct: is a direct connection or a background auto connection
** transport : Physical transport for GATT connection (BR/EDR or LE)
+** opportunistic: will not keep device connected if other apps
+** disconnect, will not update connected apps counter, when
+** disconnected won't cause physical disconnection.
**
** Returns TRUE if connection started; FALSE if connection start failure.
**
*******************************************************************************/
extern BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr,
- BOOLEAN is_direct, tBT_TRANSPORT transport);
+ BOOLEAN is_direct, tBT_TRANSPORT transport,
+ BOOLEAN opportunistic);
/*******************************************************************************
diff --git a/stack/include/sdpdefs.h b/stack/include/sdpdefs.h
index 44d87e7..a4d6cc2 100644
--- a/stack/include/sdpdefs.h
+++ b/stack/include/sdpdefs.h
@@ -281,6 +281,9 @@
#define UUID_CODEC_MSBC 0x0002 /* mSBC */
#endif
+#define UUID_HF_IND_ENHANCED_DRIVER_SAFETY 0x0001 /* Assigned number for Enhanced Safety */
+#define UUID_HF_IND_BATTERY_LEVEL_STATUS 0x0002 /* Assigned number for Battery Status */
+
/* Define all the 'Descriptor Type' values.
*/
#define NULL_DESC_TYPE 0
diff --git a/stack/include/smp_api.h b/stack/include/smp_api.h
index 62ef1db..87f526d 100644
--- a/stack/include/smp_api.h
+++ b/stack/include/smp_api.h
@@ -85,23 +85,23 @@
#define SMP_MAX_FAIL_RSN_PER_SPEC SMP_XTRANS_DERIVE_NOT_ALLOW
/* self defined error code */
-#define SMP_PAIR_INTERNAL_ERR (SMP_MAX_FAIL_RSN_PER_SPEC + 0x01) /* 0x0E */
+#define SMP_PAIR_INTERNAL_ERR (SMP_MAX_FAIL_RSN_PER_SPEC + 0x01) /* 0x0F */
-/* 0x0F unknown IO capability, unable to decide association model */
-#define SMP_UNKNOWN_IO_CAP (SMP_MAX_FAIL_RSN_PER_SPEC + 0x02) /* 0x0F */
+/* Unknown IO capability, unable to decide association model */
+#define SMP_UNKNOWN_IO_CAP (SMP_MAX_FAIL_RSN_PER_SPEC + 0x02) /* 0x10 */
-#define SMP_INIT_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x03) /* 0x10 */
-#define SMP_CONFIRM_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x04) /* 0x11 */
-#define SMP_BUSY (SMP_MAX_FAIL_RSN_PER_SPEC + 0x05) /* 0x12 */
-#define SMP_ENC_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x06) /* 0x13 */
-#define SMP_STARTED (SMP_MAX_FAIL_RSN_PER_SPEC + 0x07) /* 0x14 */
-#define SMP_RSP_TIMEOUT (SMP_MAX_FAIL_RSN_PER_SPEC + 0x08) /* 0x15 */
-#define SMP_DIV_NOT_AVAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x09) /* 0x16 */
+#define SMP_INIT_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x03) /* 0x11 */
+#define SMP_CONFIRM_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x04) /* 0x12 */
+#define SMP_BUSY (SMP_MAX_FAIL_RSN_PER_SPEC + 0x05) /* 0x13 */
+#define SMP_ENC_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x06) /* 0x14 */
+#define SMP_STARTED (SMP_MAX_FAIL_RSN_PER_SPEC + 0x07) /* 0x15 */
+#define SMP_RSP_TIMEOUT (SMP_MAX_FAIL_RSN_PER_SPEC + 0x08) /* 0x16 */
+#define SMP_DIV_NOT_AVAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x09) /* 0x17 */
-/* 0x17 unspecified failed reason */
-#define SMP_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0A) /* 0x17 */
+/* Unspecified failure reason */
+#define SMP_FAIL (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0A) /* 0x18 */
-#define SMP_CONN_TOUT (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0B)
+#define SMP_CONN_TOUT (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0B) /* 0x19 */
#define SMP_SUCCESS 0
typedef UINT8 tSMP_STATUS;
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c
index 7ebbef3..9104078 100644
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -582,17 +582,16 @@
** Returns void
**
*******************************************************************************/
-void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status)
+void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status,
+ UINT16 interval, UINT16 latency, UINT16 timeout)
{
- tL2C_LCB *p_lcb;
-
- L2CAP_TRACE_DEBUG("l2cble_process_conn_update_evt");
+ L2CAP_TRACE_DEBUG("%s", __func__);
/* See if we have a link control block for the remote device */
- p_lcb = l2cu_find_lcb_by_handle(handle);
+ tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
if (!p_lcb)
{
- L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Invalid handle: %d", handle);
+ L2CAP_TRACE_WARNING("%s: Invalid handle: %d", __func__, handle);
return;
}
@@ -600,13 +599,14 @@
if (status != HCI_SUCCESS)
{
- L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Error status: %d", status);
+ L2CAP_TRACE_WARNING("%s: Error status: %d", __func__, status);
}
l2cble_start_conn_update(p_lcb);
- L2CAP_TRACE_DEBUG("l2cble_process_conn_update_evt: conn_update_mask=%d", p_lcb->conn_update_mask);
+ L2CAP_TRACE_DEBUG("%s: conn_update_mask=%d", __func__, p_lcb->conn_update_mask);
}
+
/*******************************************************************************
**
** Function l2cble_process_sig_cmd
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index 54e1f03..8af47d7 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -767,7 +767,8 @@
extern BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb);
extern void l2cble_notify_le_connection (BD_ADDR bda);
extern void l2c_ble_link_adjust_allocation (void);
-extern void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status);
+extern void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status,
+ UINT16 interval, UINT16 latency, UINT16 timeout);
extern void l2cble_credit_based_conn_req (tL2C_CCB *p_ccb);
extern void l2cble_credit_based_conn_res (tL2C_CCB *p_ccb, UINT16 result);
diff --git a/stack/sdp/sdp_discovery.c b/stack/sdp/sdp_discovery.c
index ac43160..0beb04c 100644
--- a/stack/sdp/sdp_discovery.c
+++ b/stack/sdp/sdp_discovery.c
@@ -353,7 +353,7 @@
#if (SDP_RAW_DATA_INCLUDED == TRUE)
static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset)
{
- unsigned int cpy_len;
+ unsigned int cpy_len, rem_len;
UINT32 list_len;
UINT8 *p;
UINT8 type;
@@ -380,10 +380,15 @@
type = *p++;
p = sdpu_get_len_from_type (p, type, &list_len);
}
- if(list_len && list_len < cpy_len )
+ if(list_len < cpy_len )
{
cpy_len = list_len;
}
+ rem_len = SDP_MAX_LIST_BYTE_COUNT - (unsigned int)(p - &p_ccb->rsp_list[0]);
+ if (cpy_len > rem_len) {
+ SDP_TRACE_WARNING("rem_len :%d less than cpy_len:%d", rem_len, cpy_len);
+ cpy_len = rem_len;
+ }
#if (SDP_DEBUG_RAW == TRUE)
SDP_TRACE_WARNING("list_len :%d cpy_len:%d raw_size:%d raw_used:%d",
list_len, cpy_len, p_ccb->p_db->raw_size, p_ccb->p_db->raw_used);
@@ -568,6 +573,13 @@
/* If p_reply is NULL, we were called for the initial read */
if (p_reply)
{
+ if (p_reply + 4 /* transaction ID and length */ + sizeof(lists_byte_count) >
+ p_reply_end) {
+ android_errorWriteLog(0x534e4554, "79884292");
+ sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE);
+ return;
+ }
+
#if (SDP_DEBUG_RAW == TRUE)
SDP_TRACE_WARNING("ID & len: 0x%02x-%02x-%02x-%02x",
p_reply[0], p_reply[1], p_reply[2], p_reply[3]);
@@ -591,6 +603,13 @@
SDP_TRACE_WARNING("list_len: %d, list_byte_count: %d",
p_ccb->list_len, lists_byte_count);
#endif
+
+ if (p_reply + lists_byte_count + 1 /* continuation */ > p_reply_end) {
+ android_errorWriteLog(0x534e4554, "79884292");
+ sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE);
+ return;
+ }
+
if (p_ccb->rsp_list == NULL)
p_ccb->rsp_list = (UINT8 *)osi_malloc(SDP_MAX_LIST_BYTE_COUNT);
memcpy (&p_ccb->rsp_list[p_ccb->list_len], p_reply, lists_byte_count);
diff --git a/stack/sdp/sdp_server.c b/stack/sdp/sdp_server.c
index ca98d86..100d35b 100644
--- a/stack/sdp/sdp_server.c
+++ b/stack/sdp/sdp_server.c
@@ -351,13 +351,16 @@
/* Extract the record handle */
BE_STREAM_TO_UINT32 (rec_handle, p_req);
+ param_len -= sizeof(rec_handle);
/* Get the max list length we can send. Cap it at MTU size minus overhead */
BE_STREAM_TO_UINT16 (max_list_len, p_req);
+ param_len -= sizeof(max_list_len);
if (max_list_len > (p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN))
max_list_len = p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN;
+ param_len = (UINT16)(p_req_end - p_req);
p_req = sdpu_extract_attr_seq (p_req, param_len, &attr_seq);
if ((!p_req) || (!attr_seq.num_attr) ||
diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c
index 78db66a..4c6cd59 100644
--- a/stack/smp/smp_act.c
+++ b/stack/smp/smp_act.c
@@ -26,6 +26,8 @@
#include "stack/smp/smp_int.h"
#include "utils/include/bt_utils.h"
+extern fixed_queue_t *btu_general_alarm_queue;
+
#if SMP_INCLUDED == TRUE
const UINT8 smp_association_table[2][SMP_IO_CAP_MAX][SMP_IO_CAP_MAX] =
{
@@ -555,6 +557,9 @@
{
SMP_TRACE_DEBUG("%s", __func__);
p_cb->status = *(UINT8 *)p_data;
+
+ /* Cancel pending auth complete timer if set */
+ alarm_cancel(p_cb->delayed_auth_timer_ent);
}
/*******************************************************************************
@@ -1300,7 +1305,6 @@
*******************************************************************************/
void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
- UINT8 reason = SMP_SUCCESS;
SMP_TRACE_DEBUG("%s role=%d (0-master) r_keys=0x%x i_keys=0x%x",
__func__, p_cb->role, p_cb->local_r_key, p_cb->local_i_key);
@@ -1322,9 +1326,22 @@
}
if (p_cb->total_tx_unacked == 0)
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- else
+ {
+ /*
+ * Instead of declaring authorization complete immediately,
+ * delay the event from being sent by SMP_DELAYED_AUTH_TIMEOUT_MS.
+ * This allows the slave to send over Pairing Failed if the
+ * last key is rejected. During this waiting window, the
+ * state should remain in SMP_STATE_BOND_PENDING.
+ */
+ if (!alarm_is_scheduled(p_cb->delayed_auth_timer_ent)) {
+ SMP_TRACE_DEBUG("%s delaying auth complete.", __func__);
+ alarm_set_on_queue(p_cb->delayed_auth_timer_ent, SMP_DELAYED_AUTH_TIMEOUT_MS,
+ smp_delayed_auth_complete_timeout, NULL, btu_general_alarm_queue);
+ }
+ } else {
p_cb->wait_for_authorization_complete = TRUE;
+ }
}
}
}
diff --git a/stack/smp/smp_api.c b/stack/smp/smp_api.c
index b3373b5..ddf9ba4 100644
--- a/stack/smp/smp_api.c
+++ b/stack/smp/smp_api.c
@@ -52,6 +52,7 @@
{
memset(&smp_cb, 0, sizeof(tSMP_CB));
smp_cb.smp_rsp_timer_ent = alarm_new("smp.smp_rsp_timer_ent");
+ smp_cb.delayed_auth_timer_ent = alarm_new("smp.delayed_auth_timer_ent");
#if defined(SMP_INITIAL_TRACE_LEVEL)
smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL;
diff --git a/stack/smp/smp_int.h b/stack/smp/smp_int.h
index fbb4289..aea8538 100644
--- a/stack/smp/smp_int.h
+++ b/stack/smp/smp_int.h
@@ -51,6 +51,7 @@
#endif
#define SMP_WAIT_FOR_RSP_TIMEOUT_MS (30 * 1000)
+#define SMP_DELAYED_AUTH_TIMEOUT_MS 500
#define SMP_OPCODE_INIT 0x04
@@ -340,7 +341,8 @@
UINT16 total_tx_unacked;
BOOLEAN wait_for_authorization_complete;
UINT8 cert_failure; /*failure case for certification */
-} tSMP_CB;
+ alarm_t *delayed_auth_timer_ent;
+}tSMP_CB;
/* Server Action functions are of this type */
typedef void (*tSMP_ACT)(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
@@ -481,6 +483,7 @@
extern void smp_convert_string_to_tk(BT_OCTET16 tk, UINT32 passkey);
extern void smp_mask_enc_key(UINT8 loc_enc_size, UINT8 * p_data);
extern void smp_rsp_timeout(void *data);
+extern void smp_delayed_auth_complete_timeout(void *data);
extern void smp_xor_128(BT_OCTET16 a, BT_OCTET16 b);
extern BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len,
UINT8 *plain_text, UINT8 pt_len,
diff --git a/stack/smp/smp_l2c.c b/stack/smp/smp_l2c.c
index d401136..bd38525 100644
--- a/stack/smp/smp_l2c.c
+++ b/stack/smp/smp_l2c.c
@@ -29,7 +29,7 @@
#include <string.h>
#include "btm_ble_api.h"
#include "l2c_api.h"
-
+#include "log/log.h"
#include "smp_int.h"
@@ -264,6 +264,12 @@
(bd_addr[4]<<8)+bd_addr[5],
(connected) ? "connected" : "disconnected");
+ if (p_cb->role > HCI_ROLE_SLAVE) {
+ SMP_TRACE_ERROR ("%s: invalid role %d", __func__, p_cb->role);
+ android_errorWriteLog(0x534e4554, "80145946");
+ return;
+ }
+
if (connected)
{
if(!p_cb->connect_initialized)
diff --git a/stack/smp/smp_main.c b/stack/smp/smp_main.c
index 38f9688..2727af8 100644
--- a/stack/smp/smp_main.c
+++ b/stack/smp/smp_main.c
@@ -241,7 +241,7 @@
/* PAIR_RSP */{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* CONFIRM */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* RAND */{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
-/* PAIR_FAIL */{ 0, 0x81, 0, 0x81, 0x81,0x81, 0x81,0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0, 0, 0 },
+/* PAIR_FAIL */{ 0, 0x81, 0, 0x81, 0x81,0x81, 0x81,0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0, 0x81, 0 },
/* ENC_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
/* MASTER_ID */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0 },
/* ID_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0 },
diff --git a/stack/smp/smp_utils.c b/stack/smp/smp_utils.c
index f34fcbb..675cb42 100644
--- a/stack/smp/smp_utils.c
+++ b/stack/smp/smp_utils.c
@@ -374,6 +374,30 @@
/*******************************************************************************
**
+** Function smp_delayed_auth_complete_timeout
+**
+** Description Called when no pairing failed command received within timeout
+** period.
+**
+** Returns void
+**
+*******************************************************************************/
+void smp_delayed_auth_complete_timeout(UNUSED_ATTR void *data)
+{
+ /*
+ * Waited for potential pair failure. Send SMP_AUTH_CMPL_EVT if
+ * the state is still in bond pending.
+ */
+ if (smp_get_state() == SMP_STATE_BOND_PENDING)
+ {
+ UINT8 reason = SMP_SUCCESS;
+ SMP_TRACE_EVENT("%s sending delayed auth complete.", __func__);
+ smp_sm_event(&smp_cb, SMP_AUTH_CMPL_EVT, &reason);
+ }
+}
+
+/*******************************************************************************
+**
** Function smp_build_pairing_req_cmd
**
** Description Build pairing request command.
@@ -841,10 +865,12 @@
SMP_TRACE_EVENT("smp_cb_cleanup");
alarm_free(p_cb->smp_rsp_timer_ent);
+ alarm_free(p_cb->delayed_auth_timer_ent);
memset(p_cb, 0, sizeof(tSMP_CB));
p_cb->p_callback = p_callback;
p_cb->trace_level = trace_level;
p_cb->smp_rsp_timer_ent = alarm_new("smp.smp_rsp_timer_ent");
+ p_cb->delayed_auth_timer_ent = alarm_new("smp.delayed_auth_timer_ent");
}
/*******************************************************************************
diff --git a/stack/srvc/srvc_dis.c b/stack/srvc/srvc_dis.c
index c17c660..12ae5a5 100644
--- a/stack/srvc/srvc_dis.c
+++ b/stack/srvc/srvc_dis.c
@@ -472,7 +472,7 @@
if (conn_id == GATT_INVALID_CONN_ID)
{
- return GATT_Connect(srvc_eng_cb.gatt_if, peer_bda, TRUE, BT_TRANSPORT_LE);
+ return GATT_Connect(srvc_eng_cb.gatt_if, peer_bda, TRUE, BT_TRANSPORT_LE, false);
}
return dis_gatt_c_read_dis_req(conn_id);
diff --git a/vendor_libs/linux/bt_vendor_linux.c b/vendor_libs/linux/bt_vendor_linux.c
index eec3e01..41abc8a 100644
--- a/vendor_libs/linux/bt_vendor_linux.c
+++ b/vendor_libs/linux/bt_vendor_linux.c
@@ -202,10 +202,10 @@
}
if (fds[0].revents & POLLIN) {
- n = read(fd, &ev, sizeof(struct mgmt_pkt));
+ OSI_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt)));
if (n < 0) {
- LOG_ERROR(LOG_TAG,
- "Error reading control channel");
+ LOG_ERROR(LOG_TAG, "Error reading control channel: %s",
+ strerror(errno));
ret = -1;
break;
}