diff options
author | Ganesh Ganapathi Batta <ganeshg@broadcom.com> | 2014-04-16 16:50:09 -0700 |
---|---|---|
committer | Ganesh Ganapathi Batta <ganeshg@broadcom.com> | 2014-04-30 10:30:47 -0700 |
commit | 8fe58875ce67c6e1099e7ba2339dcd2b979491b0 (patch) | |
tree | 03dec9ddb8432a4beb3758db92fd4aa4b55464dc /stack/gatt/gatt_utils.c | |
parent | ffa5c93d455f33af1be3b04d39520413dc24afd5 (diff) | |
download | android_system_bt-8fe58875ce67c6e1099e7ba2339dcd2b979491b0.tar.gz android_system_bt-8fe58875ce67c6e1099e7ba2339dcd2b979491b0.tar.bz2 android_system_bt-8fe58875ce67c6e1099e7ba2339dcd2b979491b0.zip |
Merge BT 4.1 features
The features include:
- LE Peripheral Mode
- Link Layer topology (LE Central & Peripheral Concurrency)
- Dual Mode Topology (Ability to choose LE transport when connecting with
other Dual Mode devices)
- Fast advertising Interval
- Limited Discovery Time Changes
- GAP Authentication and Lost Bond
- Dual Mode Addressing
- Common Profile and Service Error Code
- 32 bit UUIDs
Change-Id: Ic6701da4cf6aaa390ff2c8816b43157f36b7fb42
Diffstat (limited to 'stack/gatt/gatt_utils.c')
-rw-r--r-- | stack/gatt/gatt_utils.c | 186 |
1 files changed, 105 insertions, 81 deletions
diff --git a/stack/gatt/gatt_utils.c b/stack/gatt/gatt_utils.c index 978c88ce5..d3d4c924d 100644 --- a/stack/gatt/gatt_utils.c +++ b/stack/gatt/gatt_utils.c @@ -705,7 +705,8 @@ BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIS ** Returns TRUE if found ** *******************************************************************************/ -BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx) +BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx, + tBT_TRANSPORT *p_transport) { UINT8 i; BOOLEAN found = FALSE; @@ -717,6 +718,7 @@ BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found { memcpy( bda, gatt_cb.tcb[i].peer_bda, BD_ADDR_LEN); *p_found_idx = i; + *p_transport = gatt_cb.tcb[i].transport; found = TRUE; GATT_TRACE_DEBUG6("gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x", bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); @@ -833,19 +835,19 @@ BOOLEAN gatt_is_bda_connected(BD_ADDR bda) ** Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. ** *******************************************************************************/ -UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda) +UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) { - UINT8 i = 0, j = GATT_INDEX_INVALID; + UINT8 i = 0; for ( ; i < GATT_MAX_PHY_CHANNEL; i ++) { - if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN)) + if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN) && + gatt_cb.tcb[i].transport == transport) { - j = i; - break; + return i; } } - return j; + return GATT_INDEX_INVALID; } @@ -877,12 +879,12 @@ tGATT_TCB * gatt_get_tcb_by_idx(UINT8 tcb_idx) ** Returns NULL if not found. Otherwise index to the tcb. ** *******************************************************************************/ -tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda) +tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) { tGATT_TCB *p_tcb = NULL; UINT8 i = 0; - if ((i = gatt_find_i_tcb_by_addr(bda)) != GATT_INDEX_INVALID) + if ((i = gatt_find_i_tcb_by_addr(bda, transport)) != GATT_INDEX_INVALID) p_tcb = &gatt_cb.tcb[i]; return p_tcb; @@ -919,14 +921,14 @@ UINT8 gatt_find_i_tcb_free(void) ** Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. ** *******************************************************************************/ -tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda) +tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) { UINT8 i = 0; BOOLEAN allocated = FALSE; tGATT_TCB *p_tcb = NULL; /* search for existing tcb with matching bda */ - i = gatt_find_i_tcb_by_addr(bda); + i = gatt_find_i_tcb_by_addr(bda, transport); /* find free tcb */ if (i == GATT_INDEX_INVALID) { @@ -944,6 +946,7 @@ tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda) GKI_init_q (&p_tcb->pending_ind_q); p_tcb->in_use = TRUE; p_tcb->tcb_idx = i; + p_tcb->transport = transport; } memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN); } @@ -970,6 +973,23 @@ void gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16 /******************************************************************************* ** +** Function gatt_convert_uuid32_to_uuid128 +** +** Description Convert a 32 bits UUID to be an standard 128 bits one. +** +** Returns TRUE if two uuid match; FALSE otherwise. +** +*******************************************************************************/ +void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32) +{ + UINT8 *p = &uuid_128[LEN_UUID_128 - 4]; + + memcpy (uuid_128, base_uuid, LEN_UUID_128); + + UINT32_TO_STREAM(p, uuid_32); +} +/******************************************************************************* +** ** Function gatt_uuid_compare ** ** Description Compare two UUID to see if they are the same. @@ -989,11 +1009,17 @@ BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar) } /* If both are 16-bit, we can do a simple compare */ - if (src.len == 2 && tar.len == 2) + if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16) { return src.uu.uuid16 == tar.uu.uuid16; } + /* If both are 32-bit, we can do a simple compare */ + if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32) + { + return src.uu.uuid32 == tar.uu.uuid32; + } + /* One or both of the UUIDs is 128-bit */ if (src.len == LEN_UUID_16) { @@ -1001,6 +1027,11 @@ BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar) gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16); ps = su; } + else if (src.len == LEN_UUID_32) + { + gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32); + ps = su; + } else ps = src.uu.uuid128; @@ -1010,6 +1041,12 @@ BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar) gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16); pt = tu; } + else if (tar.len == LEN_UUID_32) + { + /* convert a 32 bits UUID to 128 bits value */ + gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32); + pt = tu; + } else pt = tar.uu.uuid128; @@ -1035,6 +1072,12 @@ UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid) UINT16_TO_STREAM (p, uuid.uu.uuid16); len = LEN_UUID_16; } + else if (uuid.len == LEN_UUID_32) /* always convert 32 bits into 128 bits as alwats */ + { + gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32); + p += LEN_UUID_128; + len = LEN_UUID_128; + } else if (uuid.len == LEN_UUID_128) { ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128); @@ -1090,7 +1133,11 @@ BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 * STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid); } else - is_base_uuid = FALSE; + { + p_uuid += (LEN_UUID_128 - LEN_UUID_32); + p_uuid_rec->len = LEN_UUID_32; + STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid); + } } if (!is_base_uuid) { @@ -1100,6 +1147,9 @@ BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 * *p_data += LEN_UUID_128; break; + /* do not allow 32 bits UUID in ATT PDU now */ + case LEN_UUID_32: + GATT_TRACE_ERROR0("DO NOT ALLOW 32 BITS UUID IN ATT PDU"); case 0: default: if (uuid_size != 0) ret = FALSE; @@ -1200,7 +1250,7 @@ void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle) } GATT_TRACE_WARNING0("gatt_rsp_timeout disconnecting..."); - gatt_disconnect (p_clcb->p_tcb->peer_bda); + gatt_disconnect (p_clcb->p_tcb); } /******************************************************************************* @@ -1330,12 +1380,11 @@ UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list ) ** Returns void ** *******************************************************************************/ -void gatt_sr_get_sec_info(BD_ADDR rem_bda, BOOLEAN le_conn, UINT8 *p_sec_flag, UINT8 *p_key_size) +void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size) { UINT8 sec_flag = 0; - UNUSED(le_conn); - BTM_GetSecurityFlags(rem_bda, &sec_flag); + BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport); sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED); @@ -1438,6 +1487,14 @@ UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl) case LEN_UUID_16: SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16); break; + + case LEN_UUID_32: + UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES); + UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32); + SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE, + (UINT32) (p - buff), buff); + break; + case LEN_UUID_128: UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES); ARRAY_TO_BE_STREAM (p, p_uuid->uu.uuid128, LEN_UUID_128); @@ -1889,7 +1946,8 @@ BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda) tGATT_TCB *p_tcb=NULL; BOOLEAN status= TRUE; - p_tcb = gatt_find_tcb_by_addr(bda); + p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE); + if (p_tcb) { if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) @@ -1902,7 +1960,7 @@ BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda) gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE); if (!gatt_num_apps_hold_link(p_tcb)) { - gatt_disconnect(p_tcb->peer_bda); + gatt_disconnect(p_tcb); } } } @@ -2131,7 +2189,7 @@ void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data) ** Returns 16 bits uuid. ** *******************************************************************************/ -void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason) +void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) { tGATT_TCB *p_tcb = NULL; tGATT_CLCB *p_clcb; @@ -2142,9 +2200,10 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason) GATT_TRACE_DEBUG0 ("gatt_cleanup_upon_disc "); - if ((p_tcb = gatt_find_tcb_by_addr(bda)) != NULL) + if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL) { GATT_TRACE_DEBUG0 ("found p_tcb "); + gatt_set_ch_state(p_tcb, GATT_CH_CLOSE); for (i = 0; i < GATT_CL_MAX_LCB; i ++) { p_clcb = &gatt_cb.clcb[i]; @@ -2172,7 +2231,7 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason) { conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); GATT_TRACE_DEBUG3 ("found p_reg tcb_idx=%d gatt_if=%d conn_id=0x%x", p_tcb->tcb_idx, p_reg->gatt_if, conn_id); - (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, FALSE, reason); + (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, FALSE, reason, transport); } } memset(p_tcb, 0, sizeof(tGATT_TCB)); @@ -2228,6 +2287,10 @@ void gatt_dbg_display_uuid(tBT_UUID bt_uuid) { sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16); } + else if (bt_uuid.len == LEN_UUID_32) + { + sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32); + } else if (bt_uuid.len == LEN_UUID_128) { x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x", @@ -2406,7 +2469,7 @@ BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_init *******************************************************************************/ BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr) { - tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr); + tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); BOOLEAN status; if (p_tcb) @@ -2628,7 +2691,7 @@ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_ { BOOLEAN ret = FALSE; tGATT_REG *p_reg; - tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr); + tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); GATT_TRACE_API0 ("gatt_update_auto_connect_dev "); /* Make sure app is registered */ @@ -2659,54 +2722,6 @@ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_ /******************************************************************************* ** -** Function gatt_get_conn_id -** -** Description This function returns a connecttion handle to a ATT server -** if the server is already connected -** -** Parameters gatt_if: client interface. -** bd_addr: peer device address. -** -** Returns Connection handle or invalid handle value -** -*******************************************************************************/ -UINT16 gatt_get_conn_id (tGATT_IF gatt_if, BD_ADDR bd_addr) -{ - tGATT_REG *p_reg; - tGATT_CLCB *p_clcb; - tGATT_TCB *p_tcb; - UINT8 i; - - GATT_TRACE_API1 ("GATTC_GetConnIfConnected gatt_if=%d", gatt_if); - /* Do we have a transport to the peer ? If not, we are not connected */ - if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) == NULL) - { - GATT_TRACE_EVENT0 ("GATTC_GetConnIfConnected - no TCB found"); - return(GATT_INVALID_CONN_ID); - } - - /* Make sure app is registered */ - if ((p_reg = gatt_get_regcb(gatt_if)) == NULL) - { - GATT_TRACE_ERROR1("GATTC_GetConnIfConnected - gatt_if is not registered", gatt_if); - return(GATT_INVALID_CONN_ID); - } - - /* Now see if the app already has a client control block to that peer */ - for (i = 0, p_clcb = gatt_cb.clcb; i < GATT_CL_MAX_LCB; i++, p_clcb++) - { - if ( p_clcb->in_use && (p_clcb->p_reg == p_reg) && (p_clcb->p_tcb == p_tcb) ) - { - return(p_clcb->conn_id); - } - } - - /* If here, failed to allocate a client control block */ - GATT_TRACE_ERROR1 ("gatt_get_conn_id: not connected- gatt_if: %u", gatt_if); - return(GATT_INVALID_CONN_ID); -} -/******************************************************************************* -** ** Function gatt_add_pending_new_srv_start ** ** Description Add a pending new srv start to the new service start queue @@ -2736,12 +2751,13 @@ tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGAT ** Returns Pointer to the new service start buffer, NULL no buffer available ** *******************************************************************************/ -void gatt_update_listen_mode(void) +BOOLEAN gatt_update_listen_mode(void) { UINT8 ii = 0; tGATT_REG *p_reg = &gatt_cb.cl_rcb[0]; UINT8 listening = 0; UINT16 connectability, window, interval; + BOOLEAN rt = TRUE; for (; ii < GATT_MAX_APPS; ii ++, p_reg ++) { @@ -2757,16 +2773,24 @@ void gatt_update_listen_mode(void) else BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL); - connectability = BTM_ReadConnectability (&window, &interval); - - if (listening != GATT_LISTEN_TO_NONE) + if (rt) { - connectability |= BTM_BLE_CONNECTABLE; + connectability = BTM_ReadConnectability (&window, &interval); + + if (listening != GATT_LISTEN_TO_NONE) + { + connectability |= BTM_BLE_CONNECTABLE; + } + else + { + if ((connectability & BTM_BLE_CONNECTABLE) == 0) + connectability &= ~BTM_BLE_CONNECTABLE; + } + /* turning on the adv now */ + btm_ble_set_connectability(connectability); } - else - connectability &= ~BTM_BLE_CONNECTABLE; - /* turning on the adv now */ - BTM_SetConnectability(connectability, window, interval); + + return rt; } #endif |