Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f1dcced authored by Jack He's avatar Jack He Committed by Andre Eisenbach
Browse files

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
parent 84e7cdda
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 {
+1 −1
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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 */
+15 −9
Original line number Diff line number Diff line
@@ -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);