am a5df8e12: Merge "Accept takes a socklen_t, not an int."
* commit 'a5df8e122f4f322d9d1d4e9c14bf998ff2e3406a':
Accept takes a socklen_t, not an int.
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c
index 04bd186..f7422f7 100755
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -673,6 +673,11 @@
int i;
tBTA_DM_SEC sec_event;
+#if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
+ /* need to remove all pending background connection before unpair */
+ BTA_GATTC_CancelOpen(0, p_dev->bd_addr, FALSE);
+#endif
+
if (BTM_IsAclConnectionUp(p_dev->bd_addr))
{
/* Take the link down first, and mark the device for removal when disconnected */
@@ -692,6 +697,11 @@
else /* Ok to remove the device in application layer */
{
BTM_SecDeleteDevice(p_dev->bd_addr);
+#if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
+ /* remove all cached GATT information */
+ BTA_GATTC_Refresh(p_dev->bd_addr);
+#endif
+
if( bta_dm_cb.p_sec_cback )
{
bdcpy(sec_event.link_down.bd_addr, p_dev->bd_addr);
@@ -829,14 +839,14 @@
if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED))
{
- p_name = BTM_SecReadDevName(p_data->bond.bd_addr);
- if (!p_name)
- p_name = "";
-
memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
bdcpy(sec_event.auth_cmpl.bd_addr, p_data->bond.bd_addr);
- memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN-1));
- sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;
+ p_name = BTM_SecReadDevName(p_data->bond.bd_addr);
+ if (p_name != NULL)
+ {
+ memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN-1));
+ sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;
+ }
/* taken care of by memset [above]
sec_event.auth_cmpl.key_present = FALSE;
@@ -3459,6 +3469,10 @@
if( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING )
{
BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
+#if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
+ /* remove all cached GATT information */
+ BTA_GATTC_Refresh(p_bda);
+#endif
issue_unpair_cb = TRUE;
}
@@ -3768,6 +3782,12 @@
else
{
BTM_SecDeleteDevice (remote_bd_addr);
+#if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
+ /* need to remove all pending background connection */
+ BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
+ /* remove all cached GATT information */
+ BTA_GATTC_Refresh(remote_bd_addr);
+#endif
}
}
@@ -4997,6 +5017,7 @@
p_data->ble_set_adv_params.p_dir_bda,
BTA_DM_BLE_ADV_CHNL_MAP);
}
+
/*******************************************************************************
**
** Function bta_dm_ble_set_adv_config
@@ -5012,6 +5033,34 @@
(tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg);
}
+/*******************************************************************************
+**
+** Function bta_dm_ble_set_scan_rsp
+**
+** Description This function set the customized ADV scan resp. configuration
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
+{
+ BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
+ (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg);
+}
+
+/*******************************************************************************
+**
+** Function bta_dm_ble_broadcast
+**
+** Description Starts or stops LE broadcasts
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
+{
+ BTM_BleBroadcast(p_data->ble_observe.start);
+}
#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
#ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
diff --git a/bta/dm/bta_dm_api.c b/bta/dm/bta_dm_api.c
index 941213a..e37548e 100644
--- a/bta/dm/bta_dm_api.c
+++ b/bta/dm/bta_dm_api.c
@@ -1510,6 +1510,60 @@
bta_sys_sendmsg(p_msg);
}
}
+
+/*******************************************************************************
+**
+** Function BTA_DmBleSetScanRsp
+**
+** Description This function is called to override the BTA scan response.
+**
+** Parameters Pointer to User defined ADV data structure
+**
+** Returns None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg)
+{
+ tBTA_DM_API_SET_ADV_CONFIG *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
+ {
+ p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_EVT;
+ p_msg->data_mask = data_mask;
+ p_msg->p_adv_cfg = p_adv_cfg;
+
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_DmBleBroadcast
+**
+** Description This function starts or stops LE broadcasting.
+**
+** Parameters start: start or stop broadcast.
+**
+** Returns None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleBroadcast (BOOLEAN start)
+{
+ tBTA_DM_API_BLE_OBSERVE *p_msg;
+
+ APPL_TRACE_API1("BTA_DmBleBroadcast: start = %d ", start);
+
+ if ((p_msg = (tBTA_DM_API_BLE_OBSERVE *) GKI_getbuf(sizeof(tBTA_DM_API_BLE_OBSERVE))) != NULL)
+ {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_OBSERVE));
+
+ p_msg->hdr.event = BTA_DM_API_BLE_BROADCAST_EVT;
+ p_msg->start = start;
+
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
#endif
/*******************************************************************************
**
diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h
index d87dbf3..dd3e16c 100644
--- a/bta/dm/bta_dm_int.h
+++ b/bta/dm/bta_dm_int.h
@@ -101,6 +101,8 @@
BTA_DM_API_BLE_OBSERVE_EVT,
BTA_DM_API_BLE_ADV_PARAM_EVT,
BTA_DM_API_BLE_SET_ADV_CONFIG_EVT,
+ BTA_DM_API_BLE_SET_SCAN_RSP_EVT,
+ BTA_DM_API_BLE_BROADCAST_EVT,
#endif
#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
@@ -996,6 +998,8 @@
extern void bta_dm_ble_observe (tBTA_DM_MSG *p_data);
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);
#endif
extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
diff --git a/bta/dm/bta_dm_main.c b/bta/dm/bta_dm_main.c
index 50f871f..0f6b91a 100644
--- a/bta/dm/bta_dm_main.c
+++ b/bta/dm/bta_dm_main.c
@@ -98,6 +98,8 @@
bta_dm_ble_observe,
bta_dm_ble_set_adv_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
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 */
#endif
#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
diff --git a/bta/gatt/bta_gattc_act.c b/bta/gatt/bta_gattc_act.c
index f5b60fa..444c357 100644
--- a/bta/gatt/bta_gattc_act.c
+++ b/bta/gatt/bta_gattc_act.c
@@ -52,13 +52,16 @@
static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
+static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
+
static tGATT_CBACK bta_gattc_cl_cback =
{
bta_gattc_conn_cback,
bta_gattc_cmpl_cback,
bta_gattc_disc_res_cback,
bta_gattc_disc_cmpl_cback,
- NULL
+ NULL,
+ bta_gattc_enc_cmpl_cback
};
/* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
@@ -399,6 +402,34 @@
}
}
+
+/*******************************************************************************
+**
+** Function bta_gattc_process_enc_cmpl
+**
+** Description process encryption complete message.
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
+{
+ tBTA_GATTC_RCB *p_clreg;
+ tBTA_GATTC cb_data;
+
+ p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if);
+
+ if (p_clreg && p_clreg->p_cback)
+ {
+ memset(&cb_data, 0, sizeof(tBTA_GATTC));
+
+ cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if;
+ bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda);
+
+ (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
+ }
+}
+
/*******************************************************************************
**
** Function bta_gattc_cancel_open_error
@@ -1635,6 +1666,50 @@
/*******************************************************************************
**
+** Function bta_gattc_enc_cmpl_cback
+**
+** Description encryption complete callback function to GATT client stack.
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
+{
+ tBTA_GATTC_DATA *p_buf;
+ tBTA_GATTC_CLCB *p_clcb = NULL;
+
+ if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL)
+ {
+ return;
+ }
+
+#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
+ /* filter this event just for BTA HH LE GATT client,
+ In the future, if we want to enable encryption complete event
+ for all GATT clients, we can remove this code */
+ if (!bta_hh_le_is_hh_gatt_if(gattc_if))
+ {
+ return;
+ }
+#endif
+
+ APPL_TRACE_DEBUG1("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
+
+ if ((p_buf = (tBTA_GATTC_DATA *) GKI_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL)
+ {
+ memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
+
+ p_buf->enc_cmpl.hdr.event = BTA_GATTC_ENC_CMPL_EVT;
+ p_buf->enc_cmpl.hdr.layer_specific = p_clcb->bta_conn_id;
+ p_buf->enc_cmpl.client_if = gattc_if;
+ bdcpy(p_buf->enc_cmpl.remote_bda, bda);
+
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+/*******************************************************************************
+**
** Function bta_gattc_process_api_refresh
**
** Description process refresh API to delete cache and start a new discovery
diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h
index c2056d4..1ff8f79 100644
--- a/bta/gatt/bta_gattc_int.h
+++ b/bta/gatt/bta_gattc_int.h
@@ -69,7 +69,8 @@
BTA_GATTC_API_REG_EVT,
BTA_GATTC_API_DEREG_EVT,
BTA_GATTC_API_LISTEN_EVT,
- BTA_GATTC_API_DISABLE_EVT
+ BTA_GATTC_API_DISABLE_EVT,
+ BTA_GATTC_ENC_CMPL_EVT
};
typedef UINT16 tBTA_GATTC_INT_EVT;
@@ -195,6 +196,13 @@
tGATT_DISCONN_REASON reason;
}tBTA_GATTC_INT_CONN;
+typedef struct
+{
+ BT_HDR hdr;
+ BD_ADDR remote_bda;
+ tBTA_GATTC_IF client_if;
+}tBTA_GATTC_ENC_CMPL;
+
typedef union
{
BT_HDR hdr;
@@ -213,6 +221,7 @@
tBTA_GATTC_CI_EVT ci_save;
tBTA_GATTC_CI_LOAD ci_load;
tBTA_GATTC_INT_CONN int_conn;
+ tBTA_GATTC_ENC_CMPL enc_cmpl;
tBTA_GATTC_INT_START_IF int_start_if;
tBTA_GATTC_INT_DEREG int_dereg;
@@ -433,6 +442,7 @@
extern void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
extern void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
extern void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB *p_clreg);
+extern void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
/* function within state machine */
extern void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
diff --git a/bta/gatt/bta_gattc_main.c b/bta/gatt/bta_gattc_main.c
index 9427f89..650cf5e 100644
--- a/bta/gatt/bta_gattc_main.c
+++ b/bta/gatt/bta_gattc_main.c
@@ -386,6 +386,11 @@
bta_gattc_listen(p_cb, (tBTA_GATTC_DATA *) p_msg);
break;
#endif
+
+ case BTA_GATTC_ENC_CMPL_EVT:
+ bta_gattc_process_enc_cmpl(p_cb, (tBTA_GATTC_DATA *) p_msg);
+ break;
+
default:
if (p_msg->event == BTA_GATTC_INT_CONN_EVT)
p_clcb = bta_gattc_find_int_conn_clcb((tBTA_GATTC_DATA *) p_msg);
diff --git a/bta/gatt/bta_gatts_act.c b/bta/gatt/bta_gatts_act.c
index f59b593..f1bd88e 100644
--- a/bta/gatt/bta_gatts_act.c
+++ b/bta/gatt/bta_gatts_act.c
@@ -49,7 +49,8 @@
NULL,
NULL,
NULL,
- bta_gatts_send_request_cback
+ bta_gatts_send_request_cback,
+ NULL
};
tGATT_APPL_INFO bta_gatts_nv_cback =
diff --git a/bta/hh/bta_hh_act.c b/bta/hh/bta_hh_act.c
index 1c83d07..19f6b0c 100644
--- a/bta/hh/bta_hh_act.c
+++ b/bta/hh/bta_hh_act.c
@@ -222,6 +222,10 @@
p_cb->app_id = 0;
}
}
+ else
+ {
+ hdl = p_cb->hid_handle;
+ }
/* else : incoming connection after SDP should update the SDP information as well */
if (p_cb->app_id != 0)
diff --git a/bta/hh/bta_hh_int.h b/bta/hh/bta_hh_int.h
index 99a8b82..1ac40da 100644
--- a/bta/hh/bta_hh_int.h
+++ b/bta/hh/bta_hh_int.h
@@ -67,6 +67,7 @@
BTA_HH_GATT_READ_DESCR_CMPL_EVT,
BTA_HH_GATT_WRITE_DESCR_CMPL_EVT,
BTA_HH_API_SCPP_UPDATE_EVT,
+ BTA_HH_GATT_ENC_CMPL_EVT,
#endif
/* not handled by execute state machine */
@@ -182,6 +183,7 @@
tBTA_HH_LE_CLOSE le_close;
tBTA_GATTC_OPEN le_open;
tBTA_HH_SCPP_UPDATE le_scpp_update;
+ tBTA_GATTC_ENC_CMPL_CB le_enc_cmpl;
#endif
} tBTA_HH_DATA;
@@ -201,7 +203,7 @@
}tBTA_HH_LE_RPT;
#ifndef BTA_HH_LE_RPT_MAX
-#define BTA_HH_LE_RPT_MAX 10
+#define BTA_HH_LE_RPT_MAX 20
#endif
typedef struct
@@ -283,6 +285,7 @@
UINT8 scps_notify; /* scan refresh supported/notification enabled */
#endif
+ BOOLEAN security_pending;
} tBTA_HH_DEV_CB;
/* key board parsing control block */
@@ -404,7 +407,7 @@
extern void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
extern void bta_hh_security_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
extern void bta_hh_le_update_scpp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
-
+extern void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
#if BTA_HH_DEBUG
extern void bta_hh_trace_dev_db(void);
diff --git a/bta/hh/bta_hh_le.c b/bta/hh/bta_hh_le.c
index 52de4d6..dbbfb32 100644
--- a/bta/hh/bta_hh_le.c
+++ b/bta/hh/bta_hh_le.c
@@ -28,6 +28,7 @@
#include "bta_hh_co.h"
#include "bta_gatt_api.h"
#include "srvc_api.h"
+#include "btm_int.h"
#ifndef BTA_HH_LE_RECONN
#define BTA_HH_LE_RECONN TRUE
@@ -37,7 +38,7 @@
#define BTA_HH_LE_RPT_TYPE_VALID(x) ((x) <= BTA_LE_HID_RPT_FEATURE && (x)>=BTA_LE_HID_RPT_INPUT)
-#define BTA_HH_LE_RPT_INST_ID_MAP(s,c) (UINT8)(((s)<<4)||(c))
+#define BTA_HH_LE_RPT_INST_ID_MAP(s,c) (UINT8)(((s)<<4)|(c))
#define BTA_HH_LE_RPT_GET_SRVC_INST_ID(x) (UINT8)(x >> 4)
#define BTA_HH_LE_RPT_GET_RPT_INST_ID(x) (UINT8)(x & 0x0f)
@@ -638,6 +639,8 @@
while (p_rpt != NULL)
{
+ if (!p_rpt->in_use) break;
+
if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT)
{
/* is battery report */
@@ -718,9 +721,10 @@
#endif
}
- if (p_rpt->index < BTA_HH_LE_RPT_MAX)
+ if (p_rpt->index < BTA_HH_LE_RPT_MAX - 1)
p_rpt ++;
-
+ else
+ p_rpt = NULL;
/* read next report reference descriptor */
bta_hh_le_read_rpt_ref_descr(p_dev_cb, p_rpt);
@@ -1084,7 +1088,7 @@
p_char_id->char_id.inst_id,
prop) == NULL)
{
- APPL_TRACE_ERROR0("Add report entry failed !!!")
+ APPL_TRACE_ERROR0("Add report entry failed !!!");
break;
}
@@ -1125,7 +1129,7 @@
prop) == NULL)
{
- APPL_TRACE_ERROR0("Add report entry failed !!!")
+ APPL_TRACE_ERROR0("Add report entry failed !!!");
}
return;
@@ -1257,6 +1261,28 @@
bta_hh_le_api_disc_act(p_cb);
}
+
+/*******************************************************************************
+**
+** Function bta_hh_le_notify_enc_cmpl
+**
+** Description process GATT encryption complete event
+**
+** Returns
+**
+*******************************************************************************/
+void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf)
+{
+ if (p_cb == NULL || p_cb->security_pending == FALSE ||
+ p_buf == NULL || p_buf->le_enc_cmpl.client_if != bta_hh_cb.gatt_if)
+ {
+ return;
+ }
+
+ p_cb->security_pending = FALSE;
+ bta_hh_start_security(p_cb, NULL);
+}
+
/*******************************************************************************
**
** Function bta_hh_start_security
@@ -1269,6 +1295,19 @@
void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf)
{
UINT8 sec_flag=0;
+ tBTM_SEC_DEV_REC *p_dev_rec;
+
+ p_dev_rec = btm_find_dev(p_cb->addr);
+ if (p_dev_rec)
+ {
+ if (p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING ||
+ p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING)
+ {
+ /* if security collision happened, wait for encryption done */
+ p_cb->security_pending = TRUE;
+ return;
+ }
+ }
/* verify bond */
BTM_GetSecurityFlags(p_cb->addr, &sec_flag);
@@ -1372,7 +1411,7 @@
p_buf->reason = p_data->reason;
p_dev_cb->conn_id = BTA_GATT_INVALID_CONN_ID;
-
+ p_dev_cb->security_pending = FALSE;
bta_sys_sendmsg(p_buf);
}
}
@@ -2593,6 +2632,8 @@
*******************************************************************************/
UINT8 bta_hh_le_add_device(tBTA_HH_DEV_CB *p_cb, tBTA_HH_MAINT_DEV *p_dev_info)
{
+ p_cb->hid_handle = BTA_HH_GET_LE_DEV_HDL(p_cb->index);
+ bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
/* update DI information */
bta_hh_update_di_info(p_cb,
@@ -2709,7 +2750,9 @@
case BTA_GATTC_OPEN_EVT: /* 2 */
p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->open.remote_bda);
- bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_OPEN_EVT, (tBTA_HH_DATA *)&p_data->open);
+ if (p_dev_cb) {
+ bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_OPEN_EVT, (tBTA_HH_DATA *)&p_data->open);
+ }
break;
case BTA_GATTC_READ_CHAR_EVT: /* 3 */
@@ -2751,6 +2794,15 @@
case BTA_GATTC_NOTIF_EVT: /* 10 */
bta_hh_le_input_rpt_notify(&p_data->notify);
break;
+
+ case BTA_GATTC_ENC_CMPL_CB_EVT: /* 17 */
+ p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->enc_cmpl.remote_bda);
+ if (p_dev_cb) {
+ bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_ENC_CMPL_EVT,
+ (tBTA_HH_DATA *)&p_data->enc_cmpl);
+ }
+ break;
+
default:
break;
}
diff --git a/bta/hh/bta_hh_main.c b/bta/hh/bta_hh_main.c
index bf54e57..c2554c1 100644
--- a/bta/hh/bta_hh_main.c
+++ b/bta/hh/bta_hh_main.c
@@ -66,7 +66,7 @@
BTA_HH_START_SEC,
BTA_HH_SEC_CMPL,
BTA_HH_LE_UPDATE_SCPP,
-
+ BTA_HH_GATT_ENC_CMPL,
#endif
BTA_HH_NUM_ACTIONS
};
@@ -106,6 +106,7 @@
,bta_hh_start_security
,bta_hh_security_cmpl
,bta_hh_le_update_scpp
+ ,bta_hh_le_notify_enc_cmpl
#endif
};
@@ -140,6 +141,7 @@
/* READ_DESCR_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
/* WRITE_DESCR_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
/* SCPP_UPDATE_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
+/* BTA_HH_GATT_ENC_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
#endif
};
@@ -170,6 +172,7 @@
/* READ_DESCR_CMPL_EVT */ ,{BTA_HH_W4_LE_READ_DESCR, BTA_HH_W4_CONN_ST }
/* WRITE_DESCR_CMPL_EVT */ ,{BTA_HH_WRITE_DESCR, BTA_HH_W4_CONN_ST }
/* SCPP_UPDATE_EVT */ ,{BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
+/* BTA_HH_GATT_ENC_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
#endif
};
@@ -199,6 +202,7 @@
/* READ_DESCR_CMPL_EVT */ ,{BTA_HH_LE_READ_DESCR, BTA_HH_CONN_ST } /* do not currently read any descr when connection up */
/* WRITE_DESCR_CMPL_EVT */ ,{BTA_HH_WRITE_DESCR, BTA_HH_CONN_ST } /* do not currently write any descr when connection up */
/* SCPP_UPDATE_EVT */ ,{BTA_HH_LE_UPDATE_SCPP, BTA_HH_CONN_ST }
+/* BTA_HH_GATT_ENC_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_CONN_ST }
#endif
};
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
@@ -226,6 +230,7 @@
/* READ_DESCR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
/* WRITE_DESCR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC }
/* SCPP_UPDATE_EVT */ ,{BTA_HH_IGNORE, BTA_HH_W4_SEC }
+/* BTA_HH_GATT_ENC_CMPL_EVT */ ,{BTA_HH_GATT_ENC_CMPL, BTA_HH_W4_SEC }
};
#endif
diff --git a/bta/hh/bta_hh_utils.c b/bta/hh/bta_hh_utils.c
index 0c67513..c7c783c 100644
--- a/bta/hh/bta_hh_utils.c
+++ b/bta/hh/bta_hh_utils.c
@@ -335,7 +335,7 @@
APPL_TRACE_DEBUG1("found keycode %02x ", this_report[xx]);
#endif
p_data->caps_lock = p_kb->caps_lock;
- p_kb->num_lock = p_kb->num_lock;
+ p_data->num_lock = p_kb->num_lock;
}
memset (p_kb->last_report, 0, BTA_HH_MAX_RPT_CHARS);
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index e52e699..4345fbf 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -1884,7 +1884,7 @@
*******************************************************************************/
BTA_API extern void BTA_DmSetAfhChannelAssessment (BOOLEAN enable_or_disable);
-#if BLE_INCLUDE == TRUE
+#if BLE_INCLUDED == TRUE
// btla-specific --
/*******************************************************************************
**
@@ -1927,6 +1927,34 @@
*******************************************************************************/
BTA_API extern void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask,
tBTA_BLE_ADV_DATA *p_adv_cfg);
+
+/*******************************************************************************
+**
+** Function BTA_DmBleSetScanRsp
+**
+** Description This function is called to override the BTA scan response.
+**
+** Parameters Pointer to User defined ADV data structure
+**
+** Returns None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask,
+ tBTA_BLE_ADV_DATA *p_adv_cfg);
+
+/*******************************************************************************
+**
+** Function BTA_DmBleBroadcast
+**
+** Description This function starts or stops LE broadcasting.
+**
+** Parameters start: start or stop broadcast.
+**
+** Returns None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleBroadcast (BOOLEAN start);
+
#endif
#ifdef __cplusplus
diff --git a/bta/include/bta_gatt_api.h b/bta/include/bta_gatt_api.h
index 93eadd5..bf0d98c 100644
--- a/bta/include/bta_gatt_api.h
+++ b/bta/include/bta_gatt_api.h
@@ -115,6 +115,7 @@
#define BTA_GATTC_CANCEL_OPEN_EVT 14 /* cancel open event */
#define BTA_GATTC_SRVC_CHG_EVT 15 /* service change event */
#define BTA_GATTC_LISTEN_EVT 16 /* listen event */
+#define BTA_GATTC_ENC_CMPL_CB_EVT 17 /* encryption complete callback event */
typedef UINT8 tBTA_GATTC_EVT;
@@ -349,6 +350,12 @@
}tBTA_GATTC_OPEN_CLOSE;
// btla-specific --
+typedef struct
+{
+ tBTA_GATTC_IF client_if;
+ BD_ADDR remote_bda;
+}tBTA_GATTC_ENC_CMPL_CB;
+
typedef union
{
tBTA_GATT_STATUS status;
@@ -362,6 +369,7 @@
tBTA_GATTC_WRITE write; /* write complete data */
tBTA_GATTC_EXEC_CMPL exec_cmpl; /* execute complete */
tBTA_GATTC_NOTIFY notify; /* notification/indication event data */
+ tBTA_GATTC_ENC_CMPL_CB enc_cmpl;
BD_ADDR remote_bda; /* service change event */
} tBTA_GATTC;
diff --git a/btif/co/bta_hh_co.c b/btif/co/bta_hh_co.c
index 51edcd4..9db3370 100644
--- a/btif/co/bta_hh_co.c
+++ b/btif/co/bta_hh_co.c
@@ -419,6 +419,11 @@
memset(&ev, 0, sizeof(ev));
ev.type = UHID_CREATE;
strncpy((char*)ev.u.create.name, dev_name, sizeof(ev.u.create.name) - 1);
+ snprintf((char*)ev.u.create.uniq, sizeof(ev.u.create.uniq),
+ "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+ p_dev->bd_addr.address[5], p_dev->bd_addr.address[4],
+ p_dev->bd_addr.address[3], p_dev->bd_addr.address[2],
+ p_dev->bd_addr.address[1], p_dev->bd_addr.address[0]);
ev.u.create.rd_size = dscp_len;
ev.u.create.rd_data = p_dscp;
ev.u.create.bus = BUS_BLUETOOTH;
diff --git a/btif/src/bluetooth.c b/btif/src/bluetooth.c
index 476aaba..aa42dbc 100755
--- a/btif/src/bluetooth.c
+++ b/btif/src/bluetooth.c
@@ -155,7 +155,6 @@
return;
btif_shutdown_bluetooth();
- bt_utils_cleanup();
/* hal callbacks reset upon shutdown complete callback */
diff --git a/btif/src/btif_config_util.cpp b/btif/src/btif_config_util.cpp
index 885f5c2..0cc2b36 100644
--- a/btif/src/btif_config_util.cpp
+++ b/btif/src/btif_config_util.cpp
@@ -470,6 +470,8 @@
{
error("open_file_map fail, fd:%d, path:%s, size:%d", fd, path, size);
//debug("out");
+ if (fd >= 0)
+ close(fd);
return FALSE;
}
//get local bt device name from bluez config
@@ -539,6 +541,8 @@
{
error("open_file_map fail, fd:%d, path:%s, size:%d", fd, path, size);
//debug("out");
+ if (fd >= 0)
+ close(fd);
return FALSE;
}
int line_size = 0;
@@ -597,6 +601,8 @@
{
error("open_file_map fail, fd:%d, path:%s, size:%d", fd, path, size);
//debug("out");
+ if (fd >= 0)
+ close(fd);
return FALSE;
}
int pos = 0;
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 40f19d0..9504c3c 100644
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -37,6 +37,7 @@
#define LOG_TAG "BTIF_CORE"
#include "btif_api.h"
+#include "bt_utils.h"
#include "bta_api.h"
#include "gki.h"
#include "btu.h"
@@ -737,6 +738,14 @@
{
BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+ if (btif_core_state == BTIF_CORE_STATE_DISABLING)
+ {
+ BTIF_TRACE_WARNING0("shutdown during disabling");
+ /* shutdown called before disabling is done */
+ btif_shutdown_pending = 1;
+ return BT_STATUS_NOT_READY;
+ }
+
if (btif_is_enabled())
{
BTIF_TRACE_WARNING0("shutdown while still enabled, initiate disable");
@@ -765,6 +774,8 @@
btif_dut_mode = 0;
+ bt_utils_cleanup();
+
BTIF_TRACE_DEBUG1("%s done", __FUNCTION__);
return BT_STATUS_SUCCESS;
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index b2e80d3..3baee2b 100644
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -1936,6 +1936,25 @@
/*******************************************************************************
**
+** Function btif_dm_hh_open_failed
+**
+** Description informs the upper layers if the HH have failed during bonding
+**
+** Returns none
+**
+*******************************************************************************/
+
+void btif_dm_hh_open_failed(bt_bdaddr_t *bdaddr)
+{
+ if (pairing_cb.state == BT_BOND_STATE_BONDING &&
+ bdcmp(bdaddr->address, pairing_cb.bd_addr) == 0)
+ {
+ bond_state_changed(BT_STATUS_FAIL, bdaddr, BT_BOND_STATE_NONE);
+ }
+}
+
+/*******************************************************************************
+**
** Function btif_dm_remove_bond
**
** Description Removes bonding with the specified device
diff --git a/btif/src/btif_gatt_client.c b/btif/src/btif_gatt_client.c
index ce51ce2..64cd976 100644
--- a/btif/src/btif_gatt_client.c
+++ b/btif/src/btif_gatt_client.c
@@ -104,8 +104,8 @@
typedef struct
{
- tBTM_BLE_AD_MASK mask;
- tBTM_BLE_ADV_DATA data;
+ tBTA_BLE_AD_MASK mask;
+ tBTA_BLE_ADV_DATA data;
} btgatt_adv_data;
typedef struct
@@ -819,17 +819,46 @@
break;
case BTIF_GATTC_LISTEN:
+#ifdef BLE_PERIPHERAL_MODE_SUPPORT
BTA_GATTC_Listen(p_cb->client_if, p_cb->start, NULL);
+#else
+ BTA_DmBleBroadcast(p_cb->start);
+#endif
break;
case BTIF_GATTC_SET_ADV_DATA:
{
if (p_cb->start == 0)
- BTM_BleWriteAdvData(p_cb->adv_data.mask, &p_cb->adv_data.data);
+ BTA_DmBleSetAdvConfig(p_cb->adv_data.mask, &p_cb->adv_data.data);
else
- BTM_BleWriteScanRsp(p_cb->adv_data.mask, &p_cb->adv_data.data);
+ BTA_DmBleSetScanRsp(p_cb->adv_data.mask, &p_cb->adv_data.data);
+
+ // Cleanup ...
+
+ // ... manufacturer data
if (p_cb->adv_data.data.manu.p_val != NULL)
GKI_freebuf(p_cb->adv_data.data.manu.p_val);
+
+ // ... service data
+ if (p_cb->adv_data.data.p_proprietary != NULL)
+ {
+ int i = 0;
+ tBTA_BLE_PROP_ELEM *p_elem = p_cb->adv_data.data.p_proprietary->p_elem;
+ while (i++ != p_cb->adv_data.data.p_proprietary->num_elem && p_elem)
+ {
+ if (p_elem->p_val != NULL)
+ GKI_freebuf(p_elem->p_val);
+ ++p_elem;
+ }
+ if (p_cb->adv_data.data.p_proprietary->p_elem != NULL)
+ GKI_freebuf(p_cb->adv_data.data.p_proprietary->p_elem);
+ GKI_freebuf(p_cb->adv_data.data.p_proprietary);
+ }
+
+ // ... service list
+ if (p_cb->adv_data.data.services.p_uuid != NULL)
+ GKI_freebuf(p_cb->adv_data.data.services.p_uuid);
+
break;
}
@@ -904,7 +933,9 @@
static bt_status_t btif_gattc_set_adv_data(int client_if, bool set_scan_rsp, bool include_name,
bool include_txpower, int min_interval, int max_interval, int appearance,
- uint16_t manufacturer_len, char* manufacturer_data)
+ uint16_t manufacturer_len, char* manufacturer_data,
+ uint16_t service_data_len, char* service_data,
+ uint16_t service_uuid_len, char* service_uuid)
{
CHECK_BTGATT_INIT();
btif_gattc_cb_t btif_cb;
@@ -950,6 +981,112 @@
}
}
+ tBTA_BLE_PROP_ELEM *p_elem_service_data = NULL;
+ tBTA_BLE_PROP_ELEM *p_elem_service_128 = NULL;
+
+ if (service_data_len > 0 && service_data != NULL)
+ {
+ p_elem_service_data = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
+ if (p_elem_service_data != NULL)
+ {
+ p_elem_service_data->p_val = GKI_getbuf(service_data_len);
+ if (p_elem_service_data->p_val != NULL)
+ {
+ p_elem_service_data->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
+ p_elem_service_data->len = service_data_len;
+ memcpy(p_elem_service_data->p_val, service_data, service_data_len);
+
+ } else {
+ GKI_freebuf(p_elem_service_data);
+ p_elem_service_data = NULL;
+ }
+ }
+ }
+
+ if (service_uuid_len > 0 && service_uuid != NULL)
+ {
+ btif_cb.adv_data.data.services.list_cmpl = FALSE;
+ btif_cb.adv_data.data.services.num_service = 0;
+
+ btif_cb.adv_data.data.services.p_uuid =
+ GKI_getbuf(service_uuid_len / LEN_UUID_128 * LEN_UUID_16);
+ if (btif_cb.adv_data.data.services.p_uuid != NULL)
+ {
+ UINT16 *p_uuid_out = btif_cb.adv_data.data.services.p_uuid;
+ while (service_uuid_len >= LEN_UUID_128)
+ {
+ bt_uuid_t uuid;
+ memset(&uuid, 0, sizeof(bt_uuid_t));
+ memcpy(&uuid.uu, service_uuid, LEN_UUID_128);
+
+ tBT_UUID bt_uuid;
+ memset(&bt_uuid, 0, sizeof(tBT_UUID));
+ btif_to_bta_uuid(&bt_uuid, &uuid);
+
+ if (bt_uuid.len == LEN_UUID_16)
+ {
+ btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_SERVICE;
+ ++btif_cb.adv_data.data.services.num_service;
+ *p_uuid_out++ = bt_uuid.uu.uuid16;
+
+ } else if (bt_uuid.len == LEN_UUID_128 && p_elem_service_128 == NULL) {
+ /* Currently, only one 128-bit UUID is supported */
+ p_elem_service_128 = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
+ if (p_elem_service_128 != NULL)
+ {
+ p_elem_service_128->p_val = GKI_getbuf(LEN_UUID_128);
+ if (p_elem_service_128->p_val != NULL)
+ {
+ p_elem_service_128->adv_type = BTM_BLE_AD_TYPE_128SRV_PART;
+ p_elem_service_128->len = LEN_UUID_128;
+ memcpy(p_elem_service_128->p_val, bt_uuid.uu.uuid128, LEN_UUID_128);
+
+ } else {
+ GKI_freebuf(p_elem_service_128);
+ p_elem_service_128 = NULL;
+ }
+ }
+ }
+
+ service_uuid += LEN_UUID_128;
+ service_uuid_len -= LEN_UUID_128;
+ }
+ }
+ }
+
+ if (p_elem_service_data != NULL || p_elem_service_128 != NULL)
+ {
+ btif_cb.adv_data.data.p_proprietary = GKI_getbuf(sizeof(tBTA_BLE_PROPRIETARY));
+ if (btif_cb.adv_data.data.p_proprietary != NULL)
+ {
+ tBTA_BLE_PROPRIETARY *p_prop = btif_cb.adv_data.data.p_proprietary;
+ tBTA_BLE_PROP_ELEM *p_elem = NULL;
+ p_prop->num_elem = 0;
+ btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_PROPRIETARY;
+
+ if (p_elem_service_128 != NULL)
+ ++p_prop->num_elem;
+
+ if (p_elem_service_data != NULL)
+ ++p_prop->num_elem;
+
+ p_prop->p_elem = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM) * p_prop->num_elem);
+ p_elem = p_prop->p_elem;
+
+ if (p_elem_service_128 != NULL)
+ {
+ memcpy(p_elem++, p_elem_service_128, sizeof(tBTA_BLE_PROP_ELEM));
+ GKI_freebuf(p_elem_service_128);
+ }
+
+ if (p_elem_service_data != NULL)
+ {
+ memcpy(p_elem++, p_elem_service_data, sizeof(tBTA_BLE_PROP_ELEM));
+ GKI_freebuf(p_elem_service_data);
+ }
+ }
+ }
+
return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SET_ADV_DATA,
(char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
}
diff --git a/btif/src/btif_gatt_test.c b/btif/src/btif_gatt_test.c
index 8c23d56..2a316fe 100644
--- a/btif/src/btif_gatt_test.c
+++ b/btif/src/btif_gatt_test.c
@@ -197,6 +197,7 @@
btif_test_command_complete_cback,
btif_test_discovery_result_cback,
btif_test_discovery_complete_cback,
+ NULL,
NULL
};
diff --git a/btif/src/btif_hh.c b/btif/src/btif_hh.c
index 1c64e3e..1aca7df 100644
--- a/btif/src/btif_hh.c
+++ b/btif/src/btif_hh.c
@@ -159,6 +159,7 @@
extern void btif_dm_cb_remove_bond(bt_bdaddr_t *bd_addr);
extern BOOLEAN check_cod_hid(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
extern int scru_ascii_2_hex(char *p_ascii, int len, UINT8 *p_hex);
+extern void btif_dm_hh_open_failed(bt_bdaddr_t *bdaddr);
/*****************************************************************************
** Local Function prototypes
@@ -533,6 +534,9 @@
return;
}
+ /* need to notify up-layer device is disconnected to avoid state out of sync with up-layer */
+ HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr), BTHH_CONN_STATE_DISCONNECTED);
+
p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
if (btif_hh_cb.device_num > 0) {
@@ -842,6 +846,7 @@
}
else {
bt_bdaddr_t *bdaddr = (bt_bdaddr_t*)p_data->conn.bda;
+ btif_dm_hh_open_failed(bdaddr);
HAL_CBACK(bt_hh_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,BTHH_CONN_STATE_DISCONNECTED);
btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED;
}
@@ -873,14 +878,28 @@
BTIF_TRACE_WARNING1("Error: cannot find device with handle %d", p_data->dev_status.handle);
}
break;
- case BTA_HH_GET_RPT_EVT:
+ case BTA_HH_GET_RPT_EVT: {
+ BT_HDR *hdr = p_data->hs_data.rsp_data.p_rpt_data;
+ UINT8 *data = NULL;
+ UINT16 len = 0;
+
BTIF_TRACE_DEBUG2("BTA_HH_GET_RPT_EVT: status = %d, handle = %d",
p_data->hs_data.status, p_data->hs_data.handle);
- p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
- HAL_CBACK(bt_hh_callbacks, get_report_cb,(bt_bdaddr_t*) &(p_dev->bd_addr), (bthh_status_t) p_data->hs_data.status,
- (uint8_t*) p_data->hs_data.rsp_data.p_rpt_data, BT_HDR_SIZE);
+ /* p_rpt_data in HANDSHAKE response case */
+ if (hdr) {
+ data = (UINT8 *)(hdr + 1) + hdr->offset;
+ len = hdr->len;
+ }
+ p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
+ if (p_dev) {
+ HAL_CBACK(bt_hh_callbacks, get_report_cb,
+ (bt_bdaddr_t*) &(p_dev->bd_addr),
+ (bthh_status_t) p_data->hs_data.status, data, len);
+ } else {
+ BTIF_TRACE_WARNING1("Error: cannot find device with handle %d", p_data->hs_data.handle);
+ }
break;
-
+ }
case BTA_HH_SET_RPT_EVT:
BTIF_TRACE_DEBUG2("BTA_HH_SET_RPT_EVT: status = %d, handle = %d",
p_data->dev_status.status, p_data->dev_status.handle);
@@ -935,9 +954,18 @@
}
{
char *cached_name = NULL;
- char name[] = "Broadcom Bluetooth HID";
- if (cached_name == NULL) {
- cached_name = name;
+ bt_bdname_t bdname;
+ bt_property_t prop_name;
+ BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
+ sizeof(bt_bdname_t), &bdname);
+ if (btif_storage_get_remote_device_property(
+ &p_dev->bd_addr, &prop_name) == BT_STATUS_SUCCESS)
+ {
+ cached_name = (char *)bdname.name;
+ }
+ else
+ {
+ cached_name = "Bluetooth HID";
}
BTIF_TRACE_WARNING2("%s: name = %s", __FUNCTION__, cached_name);
@@ -1463,6 +1491,7 @@
p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
if (p_dev != NULL) {
+
BTA_HhGetProtoMode(p_dev->dev_handle);
}
else {
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index ff9f92c..d4d85f2 100755
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -88,6 +88,7 @@
#define BTIF_MEDIA_TASK_CMD_MBOX TASK_MBOX_0 /* cmd mailbox */
#define BTIF_MEDIA_TASK_DATA_MBOX TASK_MBOX_1 /* data mailbox */
+
/* BTIF media cmd event definition : BTIF_MEDIA_TASK_CMD */
enum
{
@@ -120,6 +121,7 @@
(1000/TICKS_PER_SEC) (10) */
#define BTIF_MEDIA_TIME_TICK (20 * BTIF_MEDIA_NUM_TICK)
+#define A2DP_DATA_READ_POLL_MS (BTIF_MEDIA_TIME_TICK / 2)
/* buffer pool */
#define BTIF_MEDIA_AA_POOL_ID GKI_POOL_ID_3
@@ -175,8 +177,11 @@
but due to link flow control or thread preemption in lower
layers we might need to temporarily buffer up data */
-/* 24 frames is equivalent to 6.89*24*2.9 ~= 480 ms @ 44.1 khz, 20 ms mediatick */
-#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 24
+/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
+#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 18
+#define A2DP_PACKET_COUNT_LOW_WATERMARK 5
+#define MAX_PCM_FRAME_NUM_PER_TICK 40
+#define RESET_RATE_COUNTER_THRESHOLD_MS 2000
//#define BTIF_MEDIA_VERBOSE_ENABLED
@@ -199,6 +204,10 @@
INT32 aa_feed_residue;
UINT32 counter;
UINT32 bytes_per_tick; /* pcm bytes read each media task tick */
+ UINT32 max_counter_exit;
+ UINT32 max_counter_enter;
+ UINT32 overflow_count;
+ BOOLEAN overflow;
} tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE;
@@ -553,7 +562,8 @@
/* read directly from media task from here on (keep callback for
connection events */
UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
-
+ UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
+ (void *)A2DP_DATA_READ_POLL_MS);
/* Start the media task to encode SBC */
btif_media_task_start_aa_req();
@@ -1772,6 +1782,11 @@
*******************************************************************************/
static void btif_media_task_feeding_state_reset(void)
{
+ APPL_TRACE_WARNING3("overflow %d, enter %d, exit %d",
+ btif_media_cb.media_feeding_state.pcm.overflow_count,
+ btif_media_cb.media_feeding_state.pcm.max_counter_enter,
+ btif_media_cb.media_feeding_state.pcm.max_counter_exit);
+
/* By default, just clear the entire state */
memset(&btif_media_cb.media_feeding_state, 0, sizeof(btif_media_cb.media_feeding_state));
@@ -1852,7 +1867,7 @@
*******************************************************************************/
static UINT8 btif_get_num_aa_frame(void)
{
- UINT8 result=0;
+ UINT32 result=0;
switch (btif_media_cb.TxTranscoding)
{
@@ -1865,11 +1880,24 @@
btif_media_cb.media_feeding_state.pcm.counter +=
btif_media_cb.media_feeding_state.pcm.bytes_per_tick;
+ if ((!btif_media_cb.media_feeding_state.pcm.overflow) ||
+ (btif_media_cb.TxAaQ.count < A2DP_PACKET_COUNT_LOW_WATERMARK)) {
+ if (btif_media_cb.media_feeding_state.pcm.overflow) {
+ btif_media_cb.media_feeding_state.pcm.overflow = FALSE;
- /* calculate nbr of frames pending for this media tick */
- result = btif_media_cb.media_feeding_state.pcm.counter/pcm_bytes_per_frame;
- btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;
-
+ if (btif_media_cb.media_feeding_state.pcm.counter >
+ btif_media_cb.media_feeding_state.pcm.max_counter_exit) {
+ btif_media_cb.media_feeding_state.pcm.max_counter_exit =
+ btif_media_cb.media_feeding_state.pcm.counter;
+ }
+ }
+ /* calculate nbr of frames pending for this media tick */
+ result = btif_media_cb.media_feeding_state.pcm.counter/pcm_bytes_per_frame;
+ if (result > MAX_PCM_FRAME_NUM_PER_TICK) result = MAX_PCM_FRAME_NUM_PER_TICK;
+ btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;
+ } else {
+ result = 0;
+ }
VERBOSE("WRITE %d FRAMES", result);
}
break;
@@ -1885,7 +1913,7 @@
APPL_TRACE_DEBUG1("btif_get_num_aa_frame returns %d", result);
#endif
- return result;
+ return (UINT8)result;
}
/*******************************************************************************
@@ -2182,6 +2210,32 @@
{
GKI_freebuf(p_buf);
}
+
+ if (btif_media_cb.TxAaQ.count >= MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ) {
+ UINT32 reset_rate_bytes = btif_media_cb.media_feeding_state.pcm.bytes_per_tick *
+ (RESET_RATE_COUNTER_THRESHOLD_MS / BTIF_MEDIA_TIME_TICK);
+ btif_media_cb.media_feeding_state.pcm.overflow = TRUE;
+ btif_media_cb.media_feeding_state.pcm.counter += nb_frame *
+ btif_media_cb.encoder.s16NumOfSubBands *
+ btif_media_cb.encoder.s16NumOfBlocks *
+ btif_media_cb.media_feeding.cfg.pcm.num_channel *
+ btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
+
+ btif_media_cb.media_feeding_state.pcm.overflow_count++;
+ if (btif_media_cb.media_feeding_state.pcm.counter >
+ btif_media_cb.media_feeding_state.pcm.max_counter_enter) {
+ btif_media_cb.media_feeding_state.pcm.max_counter_enter =
+ btif_media_cb.media_feeding_state.pcm.counter;
+ }
+
+ if (btif_media_cb.media_feeding_state.pcm.counter > reset_rate_bytes) {
+ btif_media_cb.media_feeding_state.pcm.counter = 0;
+ APPL_TRACE_WARNING0("btif_media_aa_prep_sbc_2_send:reset rate counter");
+ }
+
+ /* no more pcm to read */
+ nb_frame = 0;
+ }
}
}
@@ -2201,13 +2255,6 @@
VERBOSE("btif_media_aa_prep_2_send : %d frames (queue %d)", nb_frame,
btif_media_cb.TxAaQ.count);
- while (btif_media_cb.TxAaQ.count >= MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ)
- {
- APPL_TRACE_WARNING1("btif_media_aa_prep_2_send congestion buf count %d",
- btif_media_cb.TxAaQ.count);
- GKI_freebuf(GKI_dequeue(&(btif_media_cb.TxAaQ)));
- }
-
switch (btif_media_cb.TxTranscoding)
{
case BTIF_MEDIA_TRSCD_PCM_2_SBC:
@@ -2237,8 +2284,10 @@
/* get the number of frame to send */
nb_frame_2_send = btif_get_num_aa_frame();
- /* format and Q buffer to send */
- btif_media_aa_prep_2_send(nb_frame_2_send);
+ if (nb_frame_2_send != 0) {
+ /* format and Q buffer to send */
+ btif_media_aa_prep_2_send(nb_frame_2_send);
+ }
/* send it */
VERBOSE("btif_media_send_aa_frame : send %d frames", nb_frame_2_send);
diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c
index 86b1521..644fd1c 100644
--- a/btif/src/btif_storage.c
+++ b/btif/src/btif_storage.c
@@ -1499,7 +1499,7 @@
if (!btif_config_exist("Local", BTIF_STORAGE_HL_APP, BTIF_STORAGE_HL_APP_CB))
{
- memset(value, value_size, 0);
+ memset(value, 0, value_size);
if (!btif_config_set("Local", BTIF_STORAGE_HL_APP,BTIF_STORAGE_HL_APP_CB,
value, value_size, BTIF_CFG_TYPE_BIN))
{
@@ -1684,8 +1684,9 @@
char input_value [20];
bd2str(remote_bd_addr, &bdstr);
- strncpy(input_value, (char*)bdstr, 20);
- strncat(input_value,BTIF_AUTO_PAIR_CONF_VALUE_SEPARATOR, 20);
+ strlcpy(input_value, (char*)bdstr, sizeof(input_value));
+ strlcat(input_value,BTIF_AUTO_PAIR_CONF_VALUE_SEPARATOR, sizeof(input_value));
+
int line_size = sizeof(linebuf);
if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR, linebuf, &line_size))
diff --git a/hci/src/btsnoop.c b/hci/src/btsnoop.c
index 4807df8..5b0f26d 100755
--- a/hci/src/btsnoop.c
+++ b/hci/src/btsnoop.c
@@ -66,6 +66,11 @@
#define SNOOPDBG(param, ...) {}
#endif
+#define HCIT_TYPE_COMMAND 1
+#define HCIT_TYPE_ACL_DATA 2
+#define HCIT_TYPE_SCO_DATA 3
+#define HCIT_TYPE_EVENT 4
+
/* file descriptor of the BT snoop file (by default, -1 means disabled) */
int hci_btsnoop_fd = -1;
@@ -117,6 +122,7 @@
#define BTSNOOP_EPOCH_HI 0x00dcddb3U
#define BTSNOOP_EPOCH_LO 0x0f2f8000U
+
/*******************************************************************************
**
** Function tv_to_btsnoop_ts
@@ -252,6 +258,46 @@
}
/*******************************************************************************
+ ** Function btsnoop_write
+ **
+ ** Description Function used to write the actual data to the log
+ **
+ ** Returns none
+*******************************************************************************/
+
+void btsnoop_write(uint8_t *p, uint32_t flags, const uint8_t *ptype, uint32_t len)
+{
+ uint32_t value, value_hi;
+ struct timeval tv;
+ struct iovec io[3];
+ uint32_t header[6];
+
+ /* store the length in both original and included fields */
+ header[0] = l_to_be(len + 1);
+ header[1] = header[0];
+ /* flags: data can be sent or received */
+ header[2] = l_to_be(flags);
+ /* drops: none */
+ header[3] = 0;
+ /* time */
+ gettimeofday(&tv, NULL);
+ tv_to_btsnoop_ts(&header[5], &header[4], &tv);
+ header[4] = l_to_be(header[4]);
+ header[5] = l_to_be(header[5]);
+
+ io[0].iov_base = header;
+ io[0].iov_len = sizeof(header);
+
+ io[1].iov_base = (void*)ptype;
+ io[1].iov_len = 1;
+
+ io[2].iov_base = p;
+ io[2].iov_len = len;
+
+ (void) writev(hci_btsnoop_fd, io, 3);
+}
+
+/*******************************************************************************
**
** Function btsnoop_hci_cmd
**
@@ -261,42 +307,14 @@
*******************************************************************************/
void btsnoop_hci_cmd(uint8_t *p)
{
+ const uint8_t cmd = HCIT_TYPE_COMMAND;
+ int plen;
SNOOPDBG("btsnoop_hci_cmd: fd = %d", hci_btsnoop_fd);
-
- if (hci_btsnoop_fd != -1)
- {
- uint32_t value, value_hi;
- struct timeval tv;
-
- /* since these display functions are called from different contexts */
- utils_lock();
-
- /* store the length in both original and included fields */
- value = l_to_be(p[2] + 4);
- write(hci_btsnoop_fd, &value, 4);
- write(hci_btsnoop_fd, &value, 4);
- /* flags: command sent from the host */
- value = l_to_be(2);
- write(hci_btsnoop_fd, &value, 4);
- /* drops: none */
- value = 0;
- write(hci_btsnoop_fd, &value, 4);
- /* time */
- gettimeofday(&tv, NULL);
- tv_to_btsnoop_ts(&value, &value_hi, &tv);
- value_hi = l_to_be(value_hi);
- value = l_to_be(value);
- write(hci_btsnoop_fd, &value_hi, 4);
- write(hci_btsnoop_fd, &value, 4);
- /* data */
- write(hci_btsnoop_fd, "\x1", 1);
- write(hci_btsnoop_fd, p, p[2] + 3);
-
- /* since these display functions are called from different contexts */
- utils_unlock();
- }
+ plen = (int) p[2] + 3;
+ btsnoop_write(p, 2, &cmd, plen);
}
+
/*******************************************************************************
**
** Function btsnoop_hci_evt
@@ -307,40 +325,12 @@
*******************************************************************************/
void btsnoop_hci_evt(uint8_t *p)
{
+ const uint8_t evt = HCIT_TYPE_EVENT;
+ int plen;
SNOOPDBG("btsnoop_hci_evt: fd = %d", hci_btsnoop_fd);
+ plen = (int) p[1] + 2;
- if (hci_btsnoop_fd != -1)
- {
- uint32_t value, value_hi;
- struct timeval tv;
-
- /* since these display functions are called from different contexts */
- utils_lock();
-
- /* store the length in both original and included fields */
- value = l_to_be(p[1] + 3);
- write(hci_btsnoop_fd, &value, 4);
- write(hci_btsnoop_fd, &value, 4);
- /* flags: event received in the host */
- value = l_to_be(3);
- write(hci_btsnoop_fd, &value, 4);
- /* drops: none */
- value = 0;
- write(hci_btsnoop_fd, &value, 4);
- /* time */
- gettimeofday(&tv, NULL);
- tv_to_btsnoop_ts(&value, &value_hi, &tv);
- value_hi = l_to_be(value_hi);
- value = l_to_be(value);
- write(hci_btsnoop_fd, &value_hi, 4);
- write(hci_btsnoop_fd, &value, 4);
- /* data */
- write(hci_btsnoop_fd, "\x4", 1);
- write(hci_btsnoop_fd, p, p[1] + 2);
-
- /* since these display functions are called from different contexts */
- utils_unlock();
- }
+ btsnoop_write(p, 3, &evt, plen);
}
/*******************************************************************************
@@ -353,40 +343,12 @@
*******************************************************************************/
void btsnoop_sco_data(uint8_t *p, uint8_t is_rcvd)
{
+ const uint8_t sco = HCIT_TYPE_SCO_DATA;
+ int plen;
SNOOPDBG("btsnoop_sco_data: fd = %d", hci_btsnoop_fd);
+ plen = (int) p[2] + 3;
- if (hci_btsnoop_fd != -1)
- {
- uint32_t value, value_hi;
- struct timeval tv;
-
- /* since these display functions are called from different contexts */
- utils_lock();
-
- /* store the length in both original and included fields */
- value = l_to_be(p[2] + 4);
- write(hci_btsnoop_fd, &value, 4);
- write(hci_btsnoop_fd, &value, 4);
- /* flags: data can be sent or received */
- value = l_to_be(is_rcvd?1:0);
- write(hci_btsnoop_fd, &value, 4);
- /* drops: none */
- value = 0;
- write(hci_btsnoop_fd, &value, 4);
- /* time */
- gettimeofday(&tv, NULL);
- tv_to_btsnoop_ts(&value, &value_hi, &tv);
- value_hi = l_to_be(value_hi);
- value = l_to_be(value);
- write(hci_btsnoop_fd, &value_hi, 4);
- write(hci_btsnoop_fd, &value, 4);
- /* data */
- write(hci_btsnoop_fd, "\x3", 1);
- write(hci_btsnoop_fd, p, p[2] + 3);
-
- /* since these display functions are called from different contexts */
- utils_unlock();
- }
+ btsnoop_write(p, is_rcvd, &sco, plen);
}
/*******************************************************************************
@@ -399,42 +361,16 @@
*******************************************************************************/
void btsnoop_acl_data(uint8_t *p, uint8_t is_rcvd)
{
+ const uint8_t acl = HCIT_TYPE_ACL_DATA;
+ int plen;
+
SNOOPDBG("btsnoop_acl_data: fd = %d", hci_btsnoop_fd);
- if (hci_btsnoop_fd != -1)
- {
- uint32_t value, value_hi;
- struct timeval tv;
- /* since these display functions are called from different contexts */
- utils_lock();
+ plen = (((int) p[3]) << 8) + ((int) p[2]) +4;
- /* store the length in both original and included fields */
- value = l_to_be((p[3]<<8) + p[2] + 5);
- write(hci_btsnoop_fd, &value, 4);
- write(hci_btsnoop_fd, &value, 4);
- /* flags: data can be sent or received */
- value = l_to_be(is_rcvd?1:0);
- write(hci_btsnoop_fd, &value, 4);
- /* drops: none */
- value = 0;
- write(hci_btsnoop_fd, &value, 4);
- /* time */
- gettimeofday(&tv, NULL);
- tv_to_btsnoop_ts(&value, &value_hi, &tv);
- value_hi = l_to_be(value_hi);
- value = l_to_be(value);
- write(hci_btsnoop_fd, &value_hi, 4);
- write(hci_btsnoop_fd, &value, 4);
- /* data */
- write(hci_btsnoop_fd, "\x2", 1);
- write(hci_btsnoop_fd, p, (p[3]<<8) + p[2] + 4);
-
- /* since these display functions are called from different contexts */
- utils_unlock();
- }
+ btsnoop_write(p, is_rcvd, &acl, plen);
}
-
/********************************************************************************
** API allow external realtime parsing of output using e.g hcidump
*********************************************************************************/
@@ -619,11 +555,6 @@
}
-#define HCIT_TYPE_COMMAND 1
-#define HCIT_TYPE_ACL_DATA 2
-#define HCIT_TYPE_SCO_DATA 3
-#define HCIT_TYPE_EVENT 4
-
void btsnoop_capture(HC_BT_HDR *p_buf, uint8_t is_rcvd)
{
uint8_t *p = (uint8_t *)(p_buf + 1) + p_buf->offset;
diff --git a/stack/avdt/avdt_msg.c b/stack/avdt/avdt_msg.c
index 5d9c2fb..e3e4c98 100644
--- a/stack/avdt/avdt_msg.c
+++ b/stack/avdt/avdt_msg.c
@@ -688,8 +688,12 @@
/* verify length */
AVDT_TRACE_WARNING2("psc_mask=0x%x elem_len=%d", p_cfg->psc_mask, elem_len);
if( ((0 == (p_cfg->psc_mask & (AVDT_PSC_RECOV|AVDT_PSC_REPORT))) && (elem_len != 3))
- || ((p_cfg->psc_mask & AVDT_PSC_RECOV) && (elem_len != 7))
- || ((p_cfg->psc_mask & AVDT_PSC_REPORT) && (elem_len != 5)) )
+ || (((p_cfg->psc_mask & AVDT_PSC_REPORT) && !(p_cfg->psc_mask & AVDT_PSC_RECOV))
+ && (elem_len != 5))
+ || ((!(p_cfg->psc_mask & AVDT_PSC_REPORT) && (p_cfg->psc_mask & AVDT_PSC_RECOV))
+ && (elem_len != 5))
+ || (((p_cfg->psc_mask & AVDT_PSC_REPORT) && (p_cfg->psc_mask & AVDT_PSC_RECOV))
+ && (elem_len != 7)) )
{
err = AVDT_ERR_MUX_FMT;
break;
diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c
index 47ee8cf..bfe5fda 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -1518,6 +1518,7 @@
UINT8 data_len, rssi;
tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
UINT8 *p1;
+ UINT8 *p_uuid16;
STREAM_TO_UINT8 (data_len, p);
@@ -1562,6 +1563,26 @@
p_cur->flag = * p_flag;
}
+ if (p_le_inq_cb->adv_len != 0)
+ {
+ if ((p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache,
+ BTM_BLE_AD_TYPE_16SRV_CMPL, &len)) != NULL)
+ {
+ UINT8 i;
+ for (i = 0; i + 2 <= len; i = i + 2)
+ {
+ /* if this BLE device support HID over LE, set HID Major in class of device */
+ if ((p_uuid16[i] | (p_uuid16[i+1] << 8)) == UUID_SERVCLASS_LE_HID)
+ {
+ p_cur->dev_class[0] = 0;
+ p_cur->dev_class[1] = BTM_COD_MAJOR_PERIPHERAL;
+ p_cur->dev_class[2] = 0;
+ break;
+ }
+ }
+ }
+ }
+
/* if BR/EDR not supported is not set, assume is a DUMO device */
if ((p_cur->flag & BTM_BLE_BREDR_NOT_SPT) == 0 &&
evt_type != BTM_BLE_CONNECT_DIR_EVT)
diff --git a/stack/btm/btm_pm.c b/stack/btm/btm_pm.c
index 19b90d3..925e69f 100644
--- a/stack/btm/btm_pm.c
+++ b/stack/btm/btm_pm.c
@@ -369,8 +369,6 @@
cb = btm_cb.pm_reg_db[btm_cb.pm_pend_id].cback;
}
- /* no command pending */
- btm_cb.pm_pend_link = MAX_L2CAP_LINKS;
/* clear the register record */
for(xx=0; xx<BTM_MAX_PM_RECORDS; xx++)
@@ -378,8 +376,11 @@
btm_cb.pm_reg_db[xx].mask = BTM_PM_REC_NOT_USED;
}
- if(cb != NULL)
+ if(cb != NULL && btm_cb.pm_pend_link < MAX_L2CAP_LINKS)
(*cb)(btm_cb.acl_db[btm_cb.pm_pend_link].remote_addr, BTM_PM_STS_ERROR, BTM_DEV_RESET, 0);
+
+ /* no command pending */
+ btm_cb.pm_pend_link = MAX_L2CAP_LINKS;
}
/*******************************************************************************
diff --git a/stack/btu/btu_hcif.c b/stack/btu/btu_hcif.c
index 69b3882..bd7c9ff 100644
--- a/stack/btu/btu_hcif.c
+++ b/stack/btu/btu_hcif.c
@@ -2266,7 +2266,16 @@
static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len)
{
-/* This is empty until an upper layer cares about returning event */
+ /* LE connection update has completed successfully as a master. */
+ /* We can enable the update request if the result is a success. */
+ /* extract the HCI handle first */
+ UINT8 status;
+ UINT16 handle;
+ BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, "btu_ble_ll_conn_param_upd_evt");
+
+ STREAM_TO_UINT8 (status, p);
+ STREAM_TO_UINT16 (handle, p);
+ L2CA_HandleConnUpdateEvent(handle, status);
}
static void btu_ble_read_remote_feat_evt (UINT8 *p, UINT16 evt_len)
diff --git a/stack/gap/gap_ble.c b/stack/gap/gap_ble.c
index 6e3afeb..48f4723 100644
--- a/stack/gap/gap_ble.c
+++ b/stack/gap/gap_ble.c
@@ -65,7 +65,8 @@
gap_ble_c_cmpl_cback,
NULL,
NULL,
- gap_ble_s_attr_request_cback
+ gap_ble_s_attr_request_cback,
+ NULL
};
diff --git a/stack/gatt/att_protocol.c b/stack/gatt/att_protocol.c
index 9c715af..3348599 100644
--- a/stack/gatt/att_protocol.c
+++ b/stack/gatt/att_protocol.c
@@ -495,7 +495,7 @@
/* do not enq cmd if handle value confirmation or set request */
if (cmd_code != GATT_HANDLE_VALUE_CONF && cmd_code != GATT_CMD_WRITE)
{
- gatt_start_rsp_timer (p_tcb);
+ gatt_start_rsp_timer (clcb_idx);
gatt_cmd_enq(p_tcb, clcb_idx, FALSE, cmd_code, NULL);
}
}
diff --git a/stack/gatt/gatt_api.c b/stack/gatt/gatt_api.c
index a96c58a..232b191 100644
--- a/stack/gatt/gatt_api.c
+++ b/stack/gatt/gatt_api.c
@@ -1285,6 +1285,7 @@
(p_clcb->p_reg->gatt_if == gatt_if) &&
(p_clcb->p_tcb->tcb_idx == p_tcb->tcb_idx))
{
+ btu_stop_timer(&p_clcb->rsp_timer_ent);
gatt_clcb_dealloc (p_clcb);
break;
}
@@ -1294,7 +1295,9 @@
gatt_deregister_bgdev_list(gatt_if);
/* update the listen mode */
+#ifdef BLE_PERIPHERAL_MODE_SUPPORT
GATT_Listen(gatt_if, FALSE, NULL);
+#endif
memset (p_reg, 0, sizeof(tGATT_REG));
}
diff --git a/stack/gatt/gatt_attr.c b/stack/gatt/gatt_attr.c
index 459580e..9af6a60 100644
--- a/stack/gatt/gatt_attr.c
+++ b/stack/gatt/gatt_attr.c
@@ -48,7 +48,8 @@
NULL,
NULL,
NULL,
- gatt_profile_request_cback
+ gatt_profile_request_cback,
+ NULL
} ;
/*******************************************************************************
diff --git a/stack/gatt/gatt_auth.c b/stack/gatt/gatt_auth.c
index 504b7d8..e945c90 100644
--- a/stack/gatt/gatt_auth.c
+++ b/stack/gatt/gatt_auth.c
@@ -228,9 +228,18 @@
tGATT_TCB *p_tcb;
tGATT_PENDING_ENC_CLCB *p_buf;
UINT16 count;
+ UINT8 i = 0;
if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL)
{
+ for (i = 0; i < GATT_MAX_APPS; i++)
+ {
+ if (gatt_cb.cl_rcb[i].in_use && gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)
+ {
+ (*gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)(gatt_cb.cl_rcb[i].gatt_if, bd_addr);
+ }
+ }
+
if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING)
{
gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
diff --git a/stack/gatt/gatt_cl.c b/stack/gatt/gatt_cl.c
index b173be9..7457dcb 100644
--- a/stack/gatt/gatt_cl.c
+++ b/stack/gatt/gatt_cl.c
@@ -1096,7 +1096,7 @@
/* dequeue the request if is write command or sign write */
if (p_cmd->op_code != GATT_CMD_WRITE && p_cmd->op_code != GATT_SIGN_CMD_WRITE)
{
- gatt_start_rsp_timer (p_tcb);
+ gatt_start_rsp_timer (p_cmd->clcb_idx);
}
else
{
@@ -1153,7 +1153,10 @@
return;
}
else
- btu_stop_timer (&p_tcb->rsp_timer_ent);
+ {
+ btu_stop_timer (&p_clcb->rsp_timer_ent);
+ p_clcb->retry_count = 0;
+ }
}
/* the size of the message may not be bigger than the local max PDU size*/
/* The message has to be smaller than the agreed MTU, len does not count op_code */
diff --git a/stack/gatt/gatt_int.h b/stack/gatt/gatt_int.h
index 48278c2..1f81d63 100644
--- a/stack/gatt/gatt_int.h
+++ b/stack/gatt/gatt_int.h
@@ -78,6 +78,8 @@
/* wait for ATT cmd response timeout value */
#define GATT_WAIT_FOR_RSP_TOUT 30
+#define GATT_WAIT_FOR_DISC_RSP_TOUT 5
+#define GATT_REQ_RETRY_LIMIT 2
/* characteristic descriptor type */
#define GATT_DESCR_EXT_DSCPTOR 1 /* Characteristic Extended Properties */
@@ -360,7 +362,6 @@
UINT8 ind_count;
tGATT_CMD_Q cl_cmd_q[GATT_CL_MAX_LCB];
- TIMER_LIST_ENT rsp_timer_ent; /* peer response timer */
TIMER_LIST_ENT ind_ack_timer_ent; /* local app confirm to indication timer */
UINT8 pending_cl_req;
UINT8 next_slot_inq; /* index of next available slot in queue */
@@ -397,6 +398,8 @@
BOOLEAN first_read_blob_after_read;
tGATT_READ_INC_UUID128 read_uuid128;
BOOLEAN in_use;
+ TIMER_LIST_ENT rsp_timer_ent; /* peer response timer */
+ UINT8 retry_count;
} tGATT_CLCB;
typedef struct
@@ -556,7 +559,7 @@
extern UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid);
extern BOOLEAN gatt_uuid_compare(tBT_UUID src, tBT_UUID tar);
extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, BOOLEAN le_conn, UINT8 *p_sec_flag, UINT8 *p_key_size);
-extern void gatt_start_rsp_timer(tGATT_TCB *p_tcb);
+extern void gatt_start_rsp_timer(UINT16 clcb_idx);
extern void gatt_start_conf_timer(tGATT_TCB *p_tcb);
extern void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle);
extern void gatt_ind_ack_timeout(TIMER_LIST_ENT *p_tle);
diff --git a/stack/gatt/gatt_utils.c b/stack/gatt/gatt_utils.c
index e15918c..36f80a4 100644
--- a/stack/gatt/gatt_utils.c
+++ b/stack/gatt/gatt_utils.c
@@ -1116,11 +1116,18 @@
** Returns TRUE if command sent, otherwise FALSE.
**
*******************************************************************************/
-void gatt_start_rsp_timer(tGATT_TCB *p_tcb)
+void gatt_start_rsp_timer(UINT16 clcb_idx)
{
- p_tcb->rsp_timer_ent.param = (TIMER_PARAM_TYPE)p_tcb;
- btu_start_timer (&p_tcb->rsp_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP,
- GATT_WAIT_FOR_RSP_TOUT);
+ tGATT_CLCB *p_clcb = &gatt_cb.clcb[clcb_idx];
+ UINT32 timeout = GATT_WAIT_FOR_RSP_TOUT;
+ p_clcb->rsp_timer_ent.param = (TIMER_PARAM_TYPE)p_clcb;
+ if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
+ p_clcb->op_subtype == GATT_DISC_SRVC_ALL)
+ {
+ timeout = GATT_WAIT_FOR_DISC_RSP_TOUT;
+ }
+ btu_start_timer (&p_clcb->rsp_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP,
+ timeout);
}
/*******************************************************************************
**
@@ -1165,8 +1172,32 @@
*******************************************************************************/
void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle)
{
+ tGATT_CLCB *p_clcb = (tGATT_CLCB *)p_tle->param;
+ if (p_clcb == NULL || p_clcb->p_tcb == NULL)
+ {
+ GATT_TRACE_WARNING0("gatt_rsp_timeout clcb is already deleted");
+ return;
+ }
+ if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
+ p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
+ p_clcb->retry_count < GATT_REQ_RETRY_LIMIT)
+ {
+ UINT8 rsp_code;
+ GATT_TRACE_WARNING0("gatt_rsp_timeout retry discovery primary service");
+ if (p_clcb != gatt_cmd_dequeue(p_clcb->p_tcb, &rsp_code))
+ {
+ GATT_TRACE_ERROR0("gatt_rsp_timeout command queue out of sync, disconnect");
+ }
+ else
+ {
+ p_clcb->retry_count++;
+ gatt_act_discovery(p_clcb);
+ return;
+ }
+ }
+
GATT_TRACE_WARNING0("gatt_rsp_timeout disconnecting...");
- gatt_disconnect (((tGATT_TCB *)p_tle->param)->peer_bda);
+ gatt_disconnect (p_clcb->p_tcb->peer_bda);
}
/*******************************************************************************
@@ -2073,6 +2104,7 @@
operation = p_clcb->operation;
conn_id = p_clcb->conn_id;
+ btu_stop_timer(&p_clcb->rsp_timer_ent);
gatt_clcb_dealloc(p_clcb);
@@ -2114,6 +2146,7 @@
p_clcb = &gatt_cb.clcb[i];
if (p_clcb->in_use && p_clcb->p_tcb == p_tcb)
{
+ btu_stop_timer(&p_clcb->rsp_timer_ent);
GATT_TRACE_DEBUG2 ("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id, p_clcb->clcb_idx);
if (p_clcb->operation != GATTC_OPTYPE_NONE)
gatt_end_operation(p_clcb, GATT_ERROR, NULL);
@@ -2123,7 +2156,6 @@
}
}
- btu_stop_timer (&p_tcb->rsp_timer_ent);
btu_stop_timer (&p_tcb->ind_ack_timer_ent);
btu_stop_timer (&p_tcb->conf_timer_ent);
gatt_free_pending_ind(p_tcb);
diff --git a/stack/include/gatt_api.h b/stack/include/gatt_api.h
index 01afb71..d9704b7 100644
--- a/stack/include/gatt_api.h
+++ b/stack/include/gatt_api.h
@@ -573,7 +573,8 @@
/* attribute request callback for ATT server */
typedef void (tGATT_REQ_CBACK )(UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data);
-
+/* Define a callback function when encryption is established. */
+typedef void (tGATT_ENC_CMPL_CB)(tGATT_IF gatt_if, BD_ADDR bda);
/* Define the structure that applications use to register with
@@ -587,6 +588,7 @@
tGATT_DISC_RES_CB *p_disc_res_cb;
tGATT_DISC_CMPL_CB *p_disc_cmpl_cb;
tGATT_REQ_CBACK *p_req_cb;
+ tGATT_ENC_CMPL_CB *p_enc_cmpl_cb;
} tGATT_CBACK;
/*********************** Start Handle Management Definitions **********************
diff --git a/stack/include/l2c_api.h b/stack/include/l2c_api.h
index 95c44e0..7679d26 100644
--- a/stack/include/l2c_api.h
+++ b/stack/include/l2c_api.h
@@ -1146,6 +1146,18 @@
/*******************************************************************************
**
+** Function L2CA_HandleConnUpdateEvent
+**
+** Description This function enables the connection update request from remote
+** after a successful connection update response is received.
+**
+** Returns void
+**
+*******************************************************************************/
+L2C_API void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status);
+
+/*******************************************************************************
+**
** Function L2CA_GetBleConnRole
**
** Description This function returns the connection role.
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c
index b8cddd7..a440492 100644
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -81,6 +81,56 @@
return(FALSE);
}
+/*******************************************************************************
+**
+** Function L2CA_InternalBleConnUpdate
+**
+** Description update BLE connection based on status
+**
+** Parameters: lcb
+**
+** Return value: none
+**
+*******************************************************************************/
+static void L2CA_InternalBleConnUpdate (tL2C_LCB *p_lcb)
+{
+ if (p_lcb->upd_status & L2C_BLE_UPDATE_PENDING) return;
+
+ if (p_lcb->upd_status & L2C_BLE_CONN_UPDATE_DISABLE)
+ {
+ /* application requests to disable parameters update.
+ If parameters are already updated, lets set them
+ up to what has been requested during connection establishement */
+ if (p_lcb->upd_status & L2C_BLE_NOT_DEFAULT_PARAM)
+ {
+ tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
+
+ btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle,
+ (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
+ p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),
+ (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
+ p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),
+ (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
+ p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
+ (UINT16)((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
+ p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
+ 0, 0);
+ p_lcb->upd_status &= ~L2C_BLE_NOT_DEFAULT_PARAM;
+ p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NEW_CONN_PARAM);
+ }
+ }
+ else
+ {
+ /* application allows to do update, if we were delaying one do it now */
+ if (p_lcb->upd_status & L2C_BLE_NEW_CONN_PARAM)
+ {
+ btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->min_interval,
+ p_lcb->max_interval, p_lcb->latency, p_lcb->timeout, 0, 0);
+ p_lcb->upd_status &= ~L2C_BLE_NEW_CONN_PARAM;
+ p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NOT_DEFAULT_PARAM);
+ }
+ }
+}
/*******************************************************************************
**
@@ -116,7 +166,14 @@
}
if (p_lcb->link_role == HCI_ROLE_MASTER)
- btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int, latency, timeout, 0, 0);
+ {
+ p_lcb->min_interval = min_int;
+ p_lcb->max_interval = max_int;
+ p_lcb->latency = latency;
+ p_lcb->timeout = timeout;
+ p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM;
+ L2CA_InternalBleConnUpdate(p_lcb);
+ }
else
l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout);
@@ -150,8 +207,9 @@
return (FALSE);
}
- L2CAP_TRACE_API4 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x enable %d current upd state %d",
- (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->upd_disabled);
+ L2CAP_TRACE_API4 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x enable %d upd state %d",
+ (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5],
+ enable, p_lcb->upd_status);
if (!p_lcb->is_ble_link || (p_lcb->link_role != HCI_ROLE_MASTER))
{
@@ -162,42 +220,56 @@
if (enable)
{
- /* application allows to do update, if we were delaying one do it now, otherwise
- just mark lcb that updates are enabled */
- if (p_lcb->upd_disabled == UPD_PENDING)
- {
- btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval,
- p_lcb->latency, p_lcb->timeout, 0, 0);
- p_lcb->upd_disabled = UPD_UPDATED;
- }
- else
- {
- p_lcb->upd_disabled = UPD_ENABLED;
- }
+ p_lcb->upd_status &= ~L2C_BLE_CONN_UPDATE_DISABLE;
}
else
{
- /* application requests to disable parameters update. If parameters are already updated, lets set them
- up to what has been requested during connection establishement */
- if (p_lcb->upd_disabled == UPD_UPDATED)
- {
- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (rem_bda);
-
- btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
- (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),
- (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),
- (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
- (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
- 0, 0);
- }
- p_lcb->upd_disabled = UPD_DISABLED;
+ p_lcb->upd_status |= L2C_BLE_CONN_UPDATE_DISABLE;
}
+ L2CA_InternalBleConnUpdate(p_lcb);
+
return (TRUE);
}
/*******************************************************************************
**
+** Function L2CA_HandleConnUpdateEvent
+**
+** Description This function enables the connection update request from remote
+** after a successful connection update response is received.
+**
+** Returns void
+**
+*******************************************************************************/
+void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status)
+{
+ tL2C_LCB *p_lcb;
+
+ L2CAP_TRACE_DEBUG0("L2CA_HandleConnUpdateEvent");
+
+ /* See if we have a link control block for the remote device */
+ p_lcb = l2cu_find_lcb_by_handle(handle);
+ if (!p_lcb)
+ {
+ L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Invalid handle: %d", handle);
+ return;
+ }
+
+ p_lcb->upd_status &= ~L2C_BLE_UPDATE_PENDING;
+
+ if (status != HCI_SUCCESS)
+ {
+ L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Error status: %d", status);
+ }
+
+ L2CA_InternalBleConnUpdate(p_lcb);
+
+ L2CAP_TRACE_DEBUG1("L2CA_HandleConnUpdateEvent: upd_status=%d", p_lcb->upd_status);
+}
+
+/*******************************************************************************
+**
** Function L2CA_GetBleConnRole
**
** Description This function returns the connection role.
@@ -321,6 +393,7 @@
p_dev_rec->conn_params.slave_latency,
p_dev_rec->conn_params.supervision_tout,
0, 0);
+ p_lcb->upd_status |= L2C_BLE_UPDATE_PENDING;
}
/* Tell BTM Acl management about the link */
@@ -487,18 +560,8 @@
p_lcb->max_interval = max_interval;
p_lcb->latency = latency;
p_lcb->timeout = timeout;
-
- if (p_lcb->upd_disabled == UPD_ENABLED)
- {
- btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval,
- latency, timeout, 0, 0);
- p_lcb->upd_disabled = UPD_UPDATED;
- }
- else
- {
- L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled");
- p_lcb->upd_disabled = UPD_PENDING;
- }
+ p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM;
+ L2CA_InternalBleConnUpdate(p_lcb);
}
}
else
diff --git a/stack/l2cap/l2c_csm.c b/stack/l2cap/l2c_csm.c
index 0d04d8a..4e24c23 100644
--- a/stack/l2cap/l2c_csm.c
+++ b/stack/l2cap/l2c_csm.c
@@ -892,14 +892,17 @@
case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
L2CAP_TRACE_API1 ("L2CAP - Calling DataInd_Cb(), CID: 0x%04x", p_ccb->local_cid);
#if (L2CAP_NUM_FIXED_CHNLS > 0)
- if (p_ccb->local_cid < L2CAP_BASE_APPL_CID)
+ if (p_ccb->local_cid >= L2CAP_FIRST_FIXED_CHNL &&
+ p_ccb->local_cid <= L2CAP_LAST_FIXED_CHNL)
{
- if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)
- (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(p_ccb->p_lcb->remote_bd_addr,(BT_HDR *)p_data);
- else
- GKI_freebuf (p_data);
-
+ if (p_ccb->local_cid < L2CAP_BASE_APPL_CID)
+ {
+ if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)
+ (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(p_ccb->p_lcb->remote_bd_addr,(BT_HDR *)p_data);
+ else
+ GKI_freebuf (p_data);
break;
+ }
}
#endif
(*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, (BT_HDR *)p_data);
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index a17c583..72d5544 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -435,11 +435,11 @@
BOOLEAN is_ble_link;
tBLE_ADDR_TYPE ble_addr_type;
-#define UPD_ENABLED 0 /* If peer requests update, we will change params */
-#define UPD_DISABLED 1 /* application requested not to update */
-#define UPD_PENDING 2 /* while updates are disabled, peer requested new parameters */
-#define UPD_UPDATED 3 /* peer updated connection parameters */
- UINT8 upd_disabled;
+#define L2C_BLE_CONN_UPDATE_DISABLE 0x1 /* disable update connection parameters */
+#define L2C_BLE_NEW_CONN_PARAM 0x2 /* new connection parameter to be set */
+#define L2C_BLE_UPDATE_PENDING 0x4 /* waiting for connection update finished */
+#define L2C_BLE_NOT_DEFAULT_PARAM 0x8 /* not using default connection parameters */
+ UINT8 upd_status;
UINT16 min_interval; /* parameters as requested by peripheral */
UINT16 max_interval;
diff --git a/stack/rfcomm/rfc_mx_fsm.c b/stack/rfcomm/rfc_mx_fsm.c
index 842f8ee..d6bc506 100644
--- a/stack/rfcomm/rfc_mx_fsm.c
+++ b/stack/rfcomm/rfc_mx_fsm.c
@@ -614,7 +614,9 @@
else
{
p_mcb->state = RFC_MX_STATE_WAIT_SABME;
- rfc_timer_start (p_mcb, RFC_T2_TIMEOUT);
+ rfc_timer_start (p_mcb, RFCOMM_CONN_TIMEOUT); /* - increased from T2=20 to CONN=120
+ to allow the user more than 10 sec to type in the
+ pin which can be e.g. 16 digits */
}
}
}
@@ -657,7 +659,9 @@
else
{
p_mcb->state = RFC_MX_STATE_WAIT_SABME;
- rfc_timer_start (p_mcb, RFC_T2_TIMEOUT);
+ rfc_timer_start (p_mcb, RFCOMM_CONN_TIMEOUT); /* - increased from T2=20 to CONN=120
+ to allow the user more than 10 sec to type in the
+ pin which can be e.g. 16 digits */
}
}
}
diff --git a/stack/sdp/sdp_api.c b/stack/sdp/sdp_api.c
index cb632bd..7af690b 100644
--- a/stack/sdp/sdp_api.c
+++ b/stack/sdp/sdp_api.c
@@ -513,7 +513,7 @@
printf("SDP_FindServiceInDb - p_sattr value = 0x%x serviceuuid = 0x%x\r\n", p_sattr->attr_value.v.u16, service_uuid);
if(service_uuid == UUID_SERVCLASS_HDP_PROFILE)
{
- if( (p_sattr->attr_value.v.u16==UUID_SERVCLASS_HDP_SOURCE) || ( p_sattr->attr_value.v.u16==UUID_SERVCLASS_HDP_SOURCE))
+ if( (p_sattr->attr_value.v.u16==UUID_SERVCLASS_HDP_SOURCE) || ( p_sattr->attr_value.v.u16==UUID_SERVCLASS_HDP_SINK))
{
printf("SDP_FindServiceInDb found HDP source or sink\n" );
return (p_rec);
@@ -989,6 +989,34 @@
/*******************************************************************************
**
+** Function SDP_AttrStringCopy
+**
+** Description This function copy given attribute to specified buffer as a string
+**
+** Returns none
+**
+*******************************************************************************/
+static void SDP_AttrStringCopy(char *dst, tSDP_DISC_ATTR *p_attr, UINT16 dst_size)
+{
+ if ( dst == NULL ) return;
+ if ( p_attr )
+ {
+ UINT16 len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
+ if ( len > dst_size - 1 )
+ {
+ len = dst_size - 1;
+ }
+ memcpy(dst, (char *)p_attr->attr_value.v.array, len);
+ dst[len] = '\0';
+ }
+ else
+ {
+ dst[0] = '\0';
+ }
+}
+
+/*******************************************************************************
+**
** Function SDP_GetDiRecord
**
** Description This function retrieves a remote device's DI record from
@@ -1028,27 +1056,16 @@
/* ClientExecutableURL is optional */
p_curr_attr = SDP_FindAttributeInRec( p_curr_record, ATTR_ID_CLIENT_EXE_URL );
- if ( p_curr_attr )
- BCM_STRNCPY_S( p_device_info->rec.client_executable_url, sizeof(p_device_info->rec.client_executable_url),
- (char *)p_curr_attr->attr_value.v.array, SDP_MAX_ATTR_LEN );
- else
- p_device_info->rec.client_executable_url[0] = '\0';
+ SDP_AttrStringCopy( p_device_info->rec.client_executable_url, p_curr_attr,
+ SDP_MAX_ATTR_LEN );
/* Service Description is optional */
p_curr_attr = SDP_FindAttributeInRec( p_curr_record, ATTR_ID_SERVICE_DESCRIPTION );
- if ( p_curr_attr )
- BCM_STRNCPY_S( p_device_info->rec.service_description, sizeof(p_device_info->rec.service_description),
- (char *)p_curr_attr->attr_value.v.array, SDP_MAX_ATTR_LEN );
- else
- p_device_info->rec.service_description[0] = '\0';
+ SDP_AttrStringCopy( p_device_info->rec.service_description, p_curr_attr, SDP_MAX_ATTR_LEN );
/* DocumentationURL is optional */
p_curr_attr = SDP_FindAttributeInRec( p_curr_record, ATTR_ID_DOCUMENTATION_URL );
- if ( p_curr_attr )
- BCM_STRNCPY_S( p_device_info->rec.documentation_url, sizeof(p_device_info->rec.documentation_url),
- (char *)p_curr_attr->attr_value.v.array, SDP_MAX_ATTR_LEN );
- else
- p_device_info->rec.documentation_url[0] = '\0';
+ SDP_AttrStringCopy( p_device_info->rec.documentation_url, p_curr_attr, SDP_MAX_ATTR_LEN );
p_curr_attr = SDP_FindAttributeInRec( p_curr_record, ATTR_ID_SPECIFICATION_ID );
if ( p_curr_attr )
diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c
index 032f3ed..babd300 100644
--- a/stack/smp/smp_act.c
+++ b/stack/smp/smp_act.c
@@ -905,10 +905,9 @@
btu_stop_timer (&p_cb->rsp_timer_ent);
- /* if remote user terminate connection, finish SMP pairing as normal */
- if (p_data->reason == HCI_ERR_PEER_USER)
- p_cb->status = SMP_SUCCESS;
- else
+ /* if remote user terminate connection, keep the previous status */
+ /* this is to avoid reporting reverse status to uplayer */
+ if (p_data->reason != HCI_ERR_PEER_USER)
p_cb->status = SMP_CONN_TOUT;
smp_proc_pairing_cmpl(p_cb);
diff --git a/stack/smp/smp_api.c b/stack/smp/smp_api.c
index cfde2d4..b802376 100644
--- a/stack/smp/smp_api.c
+++ b/stack/smp/smp_api.c
@@ -204,6 +204,9 @@
memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
return;
+ /* clear the SMP_SEC_REQUEST_EVT event after get grant */
+ /* avoid generate duplicate pair request */
+ smp_cb.cb_evt = 0;
smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
}
diff --git a/stack/srvc/srvc_eng.c b/stack/srvc/srvc_eng.c
index a9b466e..d8db1b0 100644
--- a/stack/srvc/srvc_eng.c
+++ b/stack/srvc/srvc_eng.c
@@ -39,7 +39,8 @@
srvc_eng_c_cmpl_cback,
NULL,
NULL,
- srvc_eng_s_request_cback
+ srvc_eng_s_request_cback,
+ NULL
} ;
/* type for action functions */
typedef void (*tSRVC_ENG_C_CMPL_ACTION)(tSRVC_CLCB *p_clcb, tGATTC_OPTYPE op,
diff --git a/udrv/ulinux/uipc.c b/udrv/ulinux/uipc.c
index 28706de..67ccd4f 100644
--- a/udrv/ulinux/uipc.c
+++ b/udrv/ulinux/uipc.c
@@ -194,6 +194,7 @@
if(socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) < 0)
{
BTIF_TRACE_EVENT1("socket failed to create (%s)", strerror(errno));
+ close(s);
return -1;
}
@@ -429,7 +430,7 @@
ret = poll(&pfd, 1, 1);
BTIF_TRACE_EVENT3("uipc_flush_ch_locked polling : fd %d, rxev %x, ret %d", pfd.fd, pfd.revents, ret);
- if (pfd.revents | (POLLERR|POLLHUP))
+ if (pfd.revents & (POLLERR|POLLHUP))
return;
if (ret <= 0)
@@ -799,7 +800,7 @@
if (poll(&pfd, 1, uipc_main.ch[ch_id].read_poll_tmo_ms) == 0)
{
BTIF_TRACE_EVENT1("poll timeout (%d ms)", uipc_main.ch[ch_id].read_poll_tmo_ms);
- return 0;
+ break;
}
//BTIF_TRACE_EVENT1("poll revents %x", pfd.revents);