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

Commit aa28997b authored by JohnLai's avatar JohnLai
Browse files

Floss: Fix handle_set_terminated

Some controllers will send the the HCI event
HCI_LE_Advertising_Set_Terminated with the status
HCI_ERROR_CANCELLED_BY_HOST when the host stops the advertisement.

This event is NOT generated when the host stops the advertisement.
Refer to the BT spec ver 5.3 vol 4 part E sec 7.7.65.18. Note that the
section was revised from BT spec ver 5.0 vol 2 part E sec 7.7.65.18
which was ambiguous about.

Bug: 261410147
Test: Manually
Tag: #floss

Change-Id: I6c3bd5fe084faac23edca75bc0be799272f27a1c
parent cdcb2c1f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -938,6 +938,7 @@ enum ErrorCode: 8 {
  CONNECTION_FAILED_ESTABLISHMENT = 0x3E,
  UNKNOWN_ADVERTISING_IDENTIFIER = 0x42,
  LIMIT_REACHED = 0x43,
  OPERATION_CANCELLED_BY_HOST = 0x44,
  PACKET_TOO_LONG = 0x45,
}

+15 −2
Original line number Diff line number Diff line
@@ -221,7 +221,20 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
      LOG_INFO("Dropping invalid advertising event");
      return;
    }
    LOG_VERBOSE("Received LE Advertising Set Terminated with status %s", ErrorCodeText(event_view.GetStatus()).c_str());

    auto status = event_view.GetStatus();
    LOG_VERBOSE(
        "Received LE Advertising Set Terminated with status %s", ErrorCodeText(status).c_str());

    /* The Bluetooth Core 5.3 specification clearly states that this event
     * shall not be sent when the Host disables the advertising set. So in
     * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event.
     */
    if (status == ErrorCode::OPERATION_CANCELLED_BY_HOST) {
      LOG_WARN(
          "Unexpected advertising set terminated event status: %s", ErrorCodeText(status).c_str());
      return;
    }

    uint8_t advertiser_id = event_view.GetAdvertisingHandle();

@@ -236,13 +249,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
    AddressWithType advertiser_address = advertising_sets_[event_view.GetAdvertisingHandle()].current_address;
    bool is_discoverable = advertising_sets_[event_view.GetAdvertisingHandle()].discoverable;

    auto status = event_view.GetStatus();
    acl_manager_->OnAdvertisingSetTerminated(
        status,
        event_view.GetConnectionHandle(),
        advertiser_id,
        advertiser_address,
        is_discoverable);

    if (status == ErrorCode::LIMIT_REACHED || status == ErrorCode::ADVERTISING_TIMEOUT) {
      if (id_map_[advertiser_id] == kIdLocal) {
        if (!advertising_sets_[advertiser_id].timeout_callback.is_null()) {