system/bt
Revision | ca22ac493ab777199084d87b3c7627e7f27555af (tree) |
---|---|
Zeit | 2013-03-15 04:51:08 |
Autor | Andre Eisenbach <andre@broa...> |
Commiter | Matthew Xie |
LE fixes
- Null pointer exception check added.
An exception occurs at the memcpy in the bta_dm_gatt_disc_result.
User removed the battery on Ble device(Smart Nudge) during bonding
and connection. This exception occurs sometimes.
I used Broadcom LE Explorer to reproduce it.
- Fixed disconnect and encryption behaviour
Disconnect will now disconnect the physical link immediately when no
other application is interested in the device anymore. Also, the
connection to a remote device is now dropped if encryption fails.
- Deep copy buffers when transfering context
Certain BTA server event types require a deep copy of the request
data buffers when transfering context. Shallow copy of the pointers
involved may cause a crash when overlapping read and write requests
are received.
- 2nd encryption has not started
need to send encryption complete callback
when the encryption fail due to link drop without a complete event.
Otherwise BTA layer would not be able to clean up the status,
and no further encryption can be started.
Change-Id: If93e0a188e8779830c8991e4193b96dc95e23e5d
@@ -4978,10 +4978,17 @@ static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id) | ||
4978 | 4978 | { |
4979 | 4979 | APPL_TRACE_DEBUG3("ADDING BLE SERVICE uuid=0x%x, ble_ptr = 0x%x, ble_raw_used = 0x%x", service_id.uuid.uu.uuid16,bta_dm_search_cb.p_ble_rawdata,bta_dm_search_cb.ble_raw_used); |
4980 | 4980 | |
4981 | - memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id, | |
4982 | - sizeof(service_id) ); | |
4981 | + if(bta_dm_search_cb.p_ble_rawdata) | |
4982 | + { | |
4983 | + memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id, | |
4984 | + sizeof(service_id) ); | |
4983 | 4985 | |
4984 | - bta_dm_search_cb.ble_raw_used += sizeof(service_id); | |
4986 | + bta_dm_search_cb.ble_raw_used += sizeof(service_id); | |
4987 | + } | |
4988 | + else | |
4989 | + { | |
4990 | + APPL_TRACE_ERROR0("p_ble_rawdata is NULL"); | |
4991 | + } | |
4985 | 4992 | |
4986 | 4993 | } |
4987 | 4994 | else |
@@ -712,10 +712,7 @@ void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) | ||
712 | 712 | cb_data.close.reason = p_clcb->reason; |
713 | 713 | bdcpy(cb_data.close.remote_bda, p_clcb->bda); |
714 | 714 | |
715 | - if (p_clcb->status == BTA_GATT_OK) | |
716 | - { | |
717 | - bta_gattc_clcb_dealloc(p_clcb); | |
718 | - } | |
715 | + bta_gattc_clcb_dealloc(p_clcb); | |
719 | 716 | |
720 | 717 | ( * p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data); |
721 | 718 |
@@ -470,8 +470,6 @@ tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p | ||
470 | 470 | |
471 | 471 | if (param.s_handle > param.e_handle) |
472 | 472 | { |
473 | - APPL_TRACE_ERROR2("discover range invalid: [0x%04x ~ 0x%04x]", param.s_handle, param.e_handle); | |
474 | - | |
475 | 473 | return GATT_ERROR; |
476 | 474 | } |
477 | 475 | } |
@@ -489,8 +487,6 @@ tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p | ||
489 | 487 | *******************************************************************************/ |
490 | 488 | tBTA_GATT_STATUS bta_gattc_start_disc_include_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb) |
491 | 489 | { |
492 | - APPL_TRACE_DEBUG0("starting discovery included service"); | |
493 | - | |
494 | 490 | return bta_gattc_discover_procedure(conn_id, p_srvc_cb, GATT_DISC_INC_SRVC); |
495 | 491 | } |
496 | 492 | /******************************************************************************* |
@@ -506,8 +502,6 @@ tBTA_GATT_STATUS bta_gattc_start_disc_char(UINT16 conn_id, tBTA_GATTC_SERV *p_sr | ||
506 | 502 | { |
507 | 503 | p_srvc_cb->total_char = 0; |
508 | 504 | |
509 | - APPL_TRACE_DEBUG0("starting discover characteristics"); | |
510 | - | |
511 | 505 | return bta_gattc_discover_procedure(conn_id, p_srvc_cb, GATT_DISC_CHAR); |
512 | 506 | } |
513 | 507 | /******************************************************************************* |
@@ -606,8 +600,6 @@ static void bta_gattc_char_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb) | ||
606 | 600 | { |
607 | 601 | tBTA_GATTC_ATTR_REC *p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->cur_char_idx; |
608 | 602 | |
609 | - APPL_TRACE_DEBUG1("Total %d Char found ", p_srvc_cb->total_char); | |
610 | - | |
611 | 603 | /* if there are characteristic needs to be explored */ |
612 | 604 | if (p_srvc_cb->total_char > 0) |
613 | 605 | { |
@@ -709,7 +701,7 @@ static tBTA_GATT_STATUS bta_gattc_add_srvc_to_list(tBTA_GATTC_SERV *p_srvc_cb, | ||
709 | 701 | tBTA_GATTC_ATTR_REC *p_rec = NULL; |
710 | 702 | tBTA_GATT_STATUS status = BTA_GATT_OK; |
711 | 703 | |
712 | - if (p_srvc_cb->next_avail_idx < BTA_GATTC_MAX_CACHE_CHAR) | |
704 | + if (p_srvc_cb->p_srvc_list && p_srvc_cb->next_avail_idx < BTA_GATTC_MAX_CACHE_CHAR) | |
713 | 705 | { |
714 | 706 | p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->next_avail_idx; |
715 | 707 |
@@ -731,7 +723,7 @@ static tBTA_GATT_STATUS bta_gattc_add_srvc_to_list(tBTA_GATTC_SERV *p_srvc_cb, | ||
731 | 723 | { /* allocate bigger buffer ?? */ |
732 | 724 | status = GATT_DB_FULL; |
733 | 725 | |
734 | - APPL_TRACE_ERROR0("char not added, no resources"); | |
726 | + APPL_TRACE_ERROR0("service not added, no resources or wrong state"); | |
735 | 727 | } |
736 | 728 | return status; |
737 | 729 | } |
@@ -913,10 +905,11 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_ | ||
913 | 905 | { |
914 | 906 | tBTA_GATTC_SERV * p_srvc_cb = NULL; |
915 | 907 | BOOLEAN pri_srvc; |
908 | + tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); | |
916 | 909 | |
917 | 910 | p_srvc_cb = bta_gattc_find_scb_by_cid(conn_id); |
918 | 911 | |
919 | - if (p_srvc_cb != NULL) | |
912 | + if (p_srvc_cb != NULL && p_clcb != NULL && p_clcb->state == BTA_GATTC_DISCOVER_ST) | |
920 | 913 | { |
921 | 914 | switch (disc_type) |
922 | 915 | { |
@@ -981,7 +974,8 @@ void bta_gattc_disc_cmpl_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT | ||
981 | 974 | |
982 | 975 | if ( p_clcb && (status != GATT_SUCCESS || p_clcb->status != GATT_SUCCESS) ) |
983 | 976 | { |
984 | - p_clcb->status = status; | |
977 | + if (p_clcb->status == GATT_SUCCESS) | |
978 | + p_clcb->status = status; | |
985 | 979 | bta_gattc_sm_execute(p_clcb, BTA_GATTC_DISCOVER_CMPL_EVT, NULL); |
986 | 980 | return; |
987 | 981 | } |
@@ -1080,7 +1074,7 @@ UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service | ||
1080 | 1074 | if (bta_gattc_uuid_compare(descr_uuid, attr_uuid, TRUE)) |
1081 | 1075 | { |
1082 | 1076 | #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE) |
1083 | - APPL_TRACE_DEBUG0("found descripotor!!"); | |
1077 | + APPL_TRACE_DEBUG0("found descriptor!!"); | |
1084 | 1078 | #endif |
1085 | 1079 | handle = p_attr->attr_handle; |
1086 | 1080 | done = TRUE; |
@@ -1335,7 +1329,9 @@ static tBTA_GATT_STATUS bta_gattc_find_record(tBTA_GATTC_SERV *p_srcb, | ||
1335 | 1329 | attr_type == p_attr->attr_type) |
1336 | 1330 | { |
1337 | 1331 | |
1332 | +#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE) | |
1338 | 1333 | APPL_TRACE_DEBUG0("found char handle mapping characteristic"); |
1334 | +#endif | |
1339 | 1335 | p_result->inst_id = p_attr->inst_id; |
1340 | 1336 | |
1341 | 1337 | if (p_param != NULL) |
@@ -1354,10 +1350,12 @@ static tBTA_GATT_STATUS bta_gattc_find_record(tBTA_GATTC_SERV *p_srcb, | ||
1354 | 1350 | } |
1355 | 1351 | p_attr = p_attr->p_next; |
1356 | 1352 | } |
1353 | +#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE) | |
1357 | 1354 | if (status) |
1358 | 1355 | { |
1359 | 1356 | APPL_TRACE_ERROR0("In the given service, can not find matching record"); |
1360 | 1357 | } |
1358 | +#endif | |
1361 | 1359 | break; |
1362 | 1360 | } |
1363 | 1361 |
@@ -2256,9 +2256,8 @@ static void btif_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl) | ||
2256 | 2256 | /*Map the HCI fail reason to bt status */ |
2257 | 2257 | switch (p_auth_cmpl->fail_reason) |
2258 | 2258 | { |
2259 | - | |
2260 | - btif_dm_remove_ble_bonding_keys(); | |
2261 | 2259 | default: |
2260 | + btif_dm_remove_ble_bonding_keys(); | |
2262 | 2261 | status = BT_STATUS_FAIL; |
2263 | 2262 | break; |
2264 | 2263 | } |
@@ -39,6 +39,7 @@ | ||
39 | 39 | |
40 | 40 | #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) |
41 | 41 | |
42 | +#include "gki.h" | |
42 | 43 | #include "bta_api.h" |
43 | 44 | #include "bta_gatt_api.h" |
44 | 45 | #include "bd.h" |
@@ -116,6 +117,54 @@ extern const btgatt_callbacks_t *bt_gatt_callbacks; | ||
116 | 117 | ** Static functions |
117 | 118 | ************************************************************************************/ |
118 | 119 | |
120 | +static void btapp_gatts_copy_req_data(UINT16 event, char *p_dest, char *p_src) | |
121 | +{ | |
122 | + tBTA_GATTS *p_dest_data = (tBTA_GATTS*) p_dest; | |
123 | + tBTA_GATTS *p_src_data = (tBTA_GATTS*) p_src; | |
124 | + | |
125 | + if (!p_src_data || !p_dest_data) | |
126 | + return; | |
127 | + | |
128 | + // Copy basic structure first | |
129 | + memcpy(p_dest_data, p_src_data, sizeof(tBTA_GATTS)); | |
130 | + | |
131 | + // Allocate buffer for request data if necessary | |
132 | + switch (event) | |
133 | + { | |
134 | + case BTA_GATTS_READ_EVT: | |
135 | + case BTA_GATTS_WRITE_EVT: | |
136 | + case BTA_GATTS_EXEC_WRITE_EVT: | |
137 | + case BTA_GATTS_MTU_EVT: | |
138 | + p_dest_data->req_data.p_data = GKI_getbuf(sizeof(tBTA_GATTS_REQ_DATA)); | |
139 | + if (p_dest_data->req_data.p_data != NULL) | |
140 | + { | |
141 | + memcpy(p_dest_data->req_data.p_data, p_src_data->req_data.p_data, | |
142 | + sizeof(tBTA_GATTS_REQ_DATA)); | |
143 | + } | |
144 | + break; | |
145 | + | |
146 | + default: | |
147 | + break; | |
148 | + } | |
149 | +} | |
150 | + | |
151 | +static void btapp_gatts_free_req_data(UINT16 event, tBTA_GATTS *p_data) | |
152 | +{ | |
153 | + switch (event) | |
154 | + { | |
155 | + case BTA_GATTS_READ_EVT: | |
156 | + case BTA_GATTS_WRITE_EVT: | |
157 | + case BTA_GATTS_EXEC_WRITE_EVT: | |
158 | + case BTA_GATTS_MTU_EVT: | |
159 | + if (p_data && p_data->req_data.p_data) | |
160 | + GKI_freebuf(p_data->req_data.p_data); | |
161 | + break; | |
162 | + | |
163 | + default: | |
164 | + break; | |
165 | + } | |
166 | +} | |
167 | + | |
119 | 168 | static void btapp_gatts_handle_cback(uint16_t event, char* p_param) |
120 | 169 | { |
121 | 170 | ALOGD("%s: Event %d", __FUNCTION__, event); |
@@ -284,13 +333,15 @@ static void btapp_gatts_handle_cback(uint16_t event, char* p_param) | ||
284 | 333 | ALOGE("%s: Unhandled event (%d)!", __FUNCTION__, event); |
285 | 334 | break; |
286 | 335 | } |
336 | + | |
337 | + btapp_gatts_free_req_data(event, p_data); | |
287 | 338 | } |
288 | 339 | |
289 | 340 | static void btapp_gatts_cback(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) |
290 | 341 | { |
291 | 342 | bt_status_t status; |
292 | 343 | status = btif_transfer_context(btapp_gatts_handle_cback, (uint16_t) event, |
293 | - (void*)p_data, sizeof(tBTA_GATTS), NULL); | |
344 | + (void*)p_data, sizeof(tBTA_GATTS), btapp_gatts_copy_req_data); | |
294 | 345 | ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status); |
295 | 346 | } |
296 | 347 |
@@ -55,6 +55,8 @@ static char BASE_UUID[16] = { | ||
55 | 55 | |
56 | 56 | static btif_gatt_encrypted_link_t encrypted_links[BTIF_GATT_MAX_ENC_LINK_RECORDS]; |
57 | 57 | |
58 | +extern bt_status_t btif_dm_remove_bond(const bt_bdaddr_t *bd_addr); | |
59 | + | |
58 | 60 | int uuidType(unsigned char* p_uuid) |
59 | 61 | { |
60 | 62 | int i = 0; |
@@ -330,7 +332,11 @@ static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_STATUS result) | ||
330 | 332 | { |
331 | 333 | btif_gatt_add_encrypted_link(bd_addr); |
332 | 334 | } else { |
335 | + bt_bdaddr_t bda; | |
336 | + bdcpy(bda.address, bd_addr); | |
337 | + | |
333 | 338 | btif_gatt_remove_encrypted_link(bd_addr); |
339 | + btif_dm_remove_bond(&bda); | |
334 | 340 | } |
335 | 341 | } |
336 | 342 |
@@ -348,4 +354,4 @@ void btif_gatt_check_encrypted_link (BD_ADDR bd_addr) | ||
348 | 354 | BTA_DmSetEncryption(bd_addr, |
349 | 355 | &btif_gatt_set_encryption_cb, BTM_BLE_SEC_ENCRYPT); |
350 | 356 | } |
351 | -} | |
\ No newline at end of file | ||
357 | +} |
@@ -1198,12 +1198,17 @@ BOOLEAN btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk) | ||
1198 | 1198 | if (!btsnd_hcic_ble_start_enc(p_rec->hci_handle, dummy_rand, 0, stk)) |
1199 | 1199 | return FALSE; |
1200 | 1200 | } |
1201 | - else | |
1201 | + else if (p_rec->ble.key_type & BTM_LE_KEY_PENC) | |
1202 | 1202 | { |
1203 | 1203 | if (!btsnd_hcic_ble_start_enc(p_rec->hci_handle, p_rec->ble.keys.rand, |
1204 | 1204 | p_rec->ble.keys.ediv, p_rec->ble.keys.ltk)) |
1205 | 1205 | return FALSE; |
1206 | 1206 | } |
1207 | + else | |
1208 | + { | |
1209 | + return FALSE; | |
1210 | + } | |
1211 | + | |
1207 | 1212 | return TRUE; |
1208 | 1213 | } |
1209 | 1214 |
@@ -4471,6 +4471,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason) | ||
4471 | 4471 | tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle); |
4472 | 4472 | UINT8 old_pairing_flags = btm_cb.pairing_flags; |
4473 | 4473 | int result = HCI_ERR_AUTH_FAILURE; |
4474 | + tBTM_SEC_CALLBACK *p_callback = NULL; | |
4474 | 4475 | |
4475 | 4476 | /* If page was delayed for disc complete, can do it now */ |
4476 | 4477 | btm_cb.discing = FALSE; |
@@ -4532,7 +4533,17 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason) | ||
4532 | 4533 | p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED); |
4533 | 4534 | |
4534 | 4535 | p_dev_rec->security_required = BTM_SEC_NONE; |
4535 | - p_dev_rec->p_callback = NULL; /* when the peer device time out the authentication before we do, this call back must be reset here */ | |
4536 | + | |
4537 | + p_callback = p_dev_rec->p_callback; | |
4538 | + | |
4539 | + /* if security is pending, send callback to clean up the security state */ | |
4540 | + if(p_callback) | |
4541 | + { | |
4542 | + p_dev_rec->p_callback = NULL; /* when the peer device time out the authentication before | |
4543 | + we do, this call back must be reset here */ | |
4544 | + (*p_callback) (p_dev_rec->bd_addr, p_dev_rec->p_ref_data, BTM_ERR_PROCESSING); | |
4545 | + } | |
4546 | + | |
4536 | 4547 | BTM_TRACE_EVENT1("after Update sec_flags=0x%x", p_dev_rec->sec_flags); |
4537 | 4548 | } |
4538 | 4549 |
@@ -1489,6 +1489,12 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) | ||
1489 | 1489 | |
1490 | 1490 | p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = NULL; |
1491 | 1491 | p_lcb->disc_reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST; |
1492 | + | |
1493 | +#if BLE_INCLUDED == TRUE | |
1494 | + if (fixed_cid == L2CAP_ATT_CID && !p_lcb->ccb_queue.p_first_ccb) | |
1495 | + p_lcb->idle_timeout = 0; | |
1496 | +#endif | |
1497 | + | |
1492 | 1498 | l2cu_release_ccb (p_ccb); |
1493 | 1499 | |
1494 | 1500 | return (TRUE); |