From a3745c645f3ab5b80a7325092bd6bb14accc265f Mon Sep 17 00:00:00 2001 From: Jack He Date: Mon, 22 May 2017 19:23:04 -0700 Subject: [PATCH] HSP: Use peer_version during SCO setup * HSP profile should use peer_version obtained through SDP search to determine its behavior during SCO setup instead of a local version during initialization * Added a WARNING message if SDP search failed to get remote HSP version, the default behavior is to use HSP 1.0 * Changed SDP search initialization to look for one UUID at a time * See Bluetooth Erratum 3507 Test: make, HSP PTS test Bug: 38210042 Change-Id: I67ce615a785b25a2e9304613a29d9be66a656c54 --- bta/ag/bta_ag_act.cc | 2 +- bta/ag/bta_ag_cmd.cc | 2 +- bta/ag/bta_ag_int.h | 2 +- bta/ag/bta_ag_sdp.cc | 24 +++++++++++++++--------- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/bta/ag/bta_ag_act.cc b/bta/ag/bta_ag_act.cc index b15502426..b2d7c3e23 100644 --- a/bta/ag/bta_ag_act.cc +++ b/bta/ag/bta_ag_act.cc @@ -253,7 +253,7 @@ void bta_ag_disc_int_res(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { bta_ag_do_disc(p_scb, p_scb->open_services); } else if ((p_scb->open_services & BTA_HSP_SERVICE_MASK) && (p_scb->hsp_version == HSP_VERSION_1_2)) { - /* search for UUID_SERVCLASS_HEADSET for HSP 1.0 device */ + /* search for UUID_SERVCLASS_HEADSET instead */ p_scb->hsp_version = HSP_VERSION_1_0; bta_ag_do_disc(p_scb, p_scb->open_services); } else { diff --git a/bta/ag/bta_ag_cmd.cc b/bta/ag/bta_ag_cmd.cc index 7a47bda8b..779f005ff 100644 --- a/bta/ag/bta_ag_cmd.cc +++ b/bta/ag/bta_ag_cmd.cc @@ -1313,7 +1313,7 @@ void bta_ag_hsp_result(tBTA_AG_SCB* p_scb, tBTA_AG_API_RESULT* p_result) { } else { /* else open sco, send ring after sco opened */ /* HSPv1.2: AG shall not send RING if using in-band ring tone. */ - if (p_scb->hsp_version >= HSP_VERSION_1_2) { + if (p_scb->peer_version >= HSP_VERSION_1_2) { p_scb->post_sco = BTA_AG_POST_SCO_NONE; } else { p_scb->post_sco = BTA_AG_POST_SCO_RING; diff --git a/bta/ag/bta_ag_int.h b/bta/ag/bta_ag_int.h index eeee1b7d2..b1809127d 100644 --- a/bta/ag/bta_ag_int.h +++ b/bta/ag/bta_ag_int.h @@ -228,7 +228,7 @@ typedef struct { tBTA_AG_FEAT features; /* features registered by application */ tBTA_AG_PEER_FEAT peer_features; /* peer device features */ uint16_t peer_version; /* profile version of peer device */ - uint16_t hsp_version; /* HSP profile version */ + uint16_t hsp_version; /* HSP profile version before SDP */ uint16_t sco_idx; /* SCO handle */ bool in_use; /* scb in use */ bool dealloc; /* true if service shutting down */ diff --git a/bta/ag/bta_ag_sdp.cc b/bta/ag/bta_ag_sdp.cc index 5481fc6f5..ae3c97391 100644 --- a/bta/ag/bta_ag_sdp.cc +++ b/bta/ag/bta_ag_sdp.cc @@ -296,7 +296,7 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { p_scb->peer_version = HFP_VERSION_1_1; /* Default version */ } else if (service & BTA_HSP_SERVICE_MASK && p_scb->role == BTA_AG_INT) { uuid = UUID_SERVCLASS_HEADSET_HS; - p_scb->peer_version = 0x0100; /* Default version */ + p_scb->peer_version = HSP_VERSION_1_2; /* Default version */ } else { return result; } @@ -307,8 +307,9 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { p_rec = SDP_FindServiceInDb(p_scb->p_disc_db, uuid, p_rec); if (p_rec == NULL) { if (uuid == UUID_SERVCLASS_HEADSET_HS) { - /* Search again in case the peer device is HSP v1.0 */ + /* Search again in case the peer device uses the old HSP UUID */ uuid = UUID_SERVCLASS_HEADSET; + p_scb->peer_version = HSP_VERSION_1_0; p_rec = SDP_FindServiceInDb(p_scb->p_disc_db, uuid, p_rec); if (p_rec == NULL) { break; @@ -327,7 +328,10 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { } /* get profile version (if failure, version parameter is not updated) */ - SDP_FindProfileVersionInRec(p_rec, uuid, &p_scb->peer_version); + if (!SDP_FindProfileVersionInRec(p_rec, uuid, &p_scb->peer_version)) { + APPL_TRACE_WARNING("%s: Get peer_version failed, using default 0x%04x", + __func__, p_scb->peer_version); + } /* get features if HFP */ if (service & BTA_HFP_SERVICE_MASK) { @@ -370,7 +374,7 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { * ******************************************************************************/ void bta_ag_do_disc(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { - tSDP_UUID uuid_list[2]; + tSDP_UUID uuid_list[1]; uint16_t num_uuid = 1; uint16_t attr_list[4]; uint8_t num_attr; @@ -400,11 +404,14 @@ void bta_ag_do_disc(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST; attr_list[3] = ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL; num_attr = 4; - - uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HEADSET; /* Legacy from HSP v1.0 */ + // Although UUID_SERVCLASS_HEADSET_HS (0x1131) is to be used in HSP 1.2, + // some HSP 1.2 implementations, such as PTS, still use + // UUID_SERVCLASS_HEADSET (0x1108) to store its service record. However, + // most of such devices are HSP 1.0 devices. if (p_scb->hsp_version >= HSP_VERSION_1_2) { - uuid_list[1].uu.uuid16 = UUID_SERVCLASS_HEADSET_HS; - num_uuid = 2; + uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HEADSET_HS; + } else { + uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HEADSET; } } /* HSP acceptor; no discovery */ @@ -416,7 +423,6 @@ void bta_ag_do_disc(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { p_scb->p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(BTA_AG_DISC_BUF_SIZE); /* set up service discovery database; attr happens to be attr_list len */ uuid_list[0].len = LEN_UUID_16; - uuid_list[1].len = LEN_UUID_16; db_inited = SDP_InitDiscoveryDb(p_scb->p_disc_db, BTA_AG_DISC_BUF_SIZE, num_uuid, uuid_list, num_attr, attr_list); -- 2.11.0