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

Commit e8ed8edd authored by En-Shuo Hsu's avatar En-Shuo Hsu
Browse files

floss: Add Enhanced Call Status support

Enhanced Call Status is mandatory for HFP. Add it to the build flag.
Also add codes to follow ChromeOS's existing behavior to send out
commands setting the call status and speaker volume for HFP.

Tag: #floss
Bug: 213408429
Test: Build, flush and verify the commands on btmon
BYPASS_LONG_LINES_REASON: Bluetooth likes 120 char lines

Change-Id: I05acf735d6a7fc170a74fa2bde545090893fb4f7
parent ec34017d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -119,10 +119,10 @@ config("target_defaults") {
    "FALLTHROUGH_INTENDED=[[clang::fallthrough]]",
    # TODO(b/214148074): Start with NB, should enable WB.
    "DISABLE_WBS=TRUE",
    # TODO(b/214149380): Start with no extra feature supported. Should enable
    # required features in the future.
    # TODO(b/214149380): Start with Enhanced Call Status feature supported.
    # Should enable required features in the future.
    # This will be consumed by BTA_AgRegister and passed to HF through AT+BRSF.
    "BTIF_HF_FEATURES=0x00000000"
    "BTIF_HF_FEATURES=0x00000040"
  ]

  if (!(defined(use.bt_nonstandard_codecs) && use.bt_nonstandard_codecs)) {
+67 −30
Original line number Diff line number Diff line
@@ -48,12 +48,53 @@ class DBusHeadsetCallbacks : public headset::Callbacks {
  DBusHeadsetCallbacks(headset::Interface* headset) : headset_(headset){};

  void ConnectionStateCallback(headset::bthf_connection_state_t state, RawAddress* bd_addr) override {
    LOG_WARN("ConnectionStateCallback from %s", bd_addr->ToString().c_str());
    LOG_INFO("ConnectionStateCallback from %s", bd_addr->ToString().c_str());
    topshim::rust::internal::connection_state_cb(state, bd_addr);
  }

  void AudioStateCallback(
      [[maybe_unused]] headset::bthf_audio_state_t state, [[maybe_unused]] RawAddress* bd_addr) override {}
  void AudioStateCallback(headset::bthf_audio_state_t state, RawAddress* bd_addr) override {
    LOG_INFO("AudioStateCallback %u from %s", state, bd_addr->ToString().c_str());
    switch (state) {
      case headset::bthf_audio_state_t::BTHF_AUDIO_STATE_CONNECTED:
        // This triggers a +CIEV command to set the call status for HFP
        // devices. It is required along with the SCO establishment for some
        // devices to provide sound.
        headset_->PhoneStateChange(
            /*num_active=*/1,
            /*num_held=*/0,
            /*call_setup_state=*/headset::bthf_call_state_t::BTHF_CALL_STATE_IDLE,
            /*number=*/"",
            /*type=*/(headset::bthf_call_addrtype_t)0,
            /*name=*/"",
            /*bd_addr=*/bd_addr);
        // This triggers a +VGS command to set the speaker volume for HFP
        // devices.
        // TODO(b/215089433): Add a set volume API and have client to handle the
        // set volume when start.
        headset_->VolumeControl(headset::bthf_volume_type_t::BTHF_VOLUME_TYPE_SPK, 5, bd_addr);
        return;
      case headset::bthf_audio_state_t::BTHF_AUDIO_STATE_DISCONNECTED:
        headset_->PhoneStateChange(
            /*num_active=*/0,
            /*num_held=*/0,
            /*call_setup_state=*/headset::bthf_call_state_t::BTHF_CALL_STATE_DISCONNECTED,
            /*number=*/"",
            /*type=*/(headset::bthf_call_addrtype_t)0,
            /*name=*/"",
            /*bd_addr=*/bd_addr);
        headset_->PhoneStateChange(
            /*num_active=*/0,
            /*num_held=*/0,
            /*call_setup_state=*/headset::bthf_call_state_t::BTHF_CALL_STATE_IDLE,
            /*number=*/"",
            /*type=*/(headset::bthf_call_addrtype_t)0,
            /*name=*/"",
            /*bd_addr=*/bd_addr);
        return;
      default:
        return;
    }
  }

  void VoiceRecognitionCallback(
      [[maybe_unused]] headset::bthf_vr_state_t state, [[maybe_unused]] RawAddress* bd_addr) override {}
@@ -81,19 +122,17 @@ class DBusHeadsetCallbacks : public headset::Callbacks {
  void AtCnumCallback([[maybe_unused]] RawAddress* bd_addr) override {}

  void AtCindCallback(RawAddress* bd_addr) override {
    /* This is required to setup the SLC, the format of the response should be
     * +CIND: <call>,<callsetup>,<service>,<signal>,<roam>,<battery>,<callheld>
     */
    LOG_WARN("Respond +CIND: 0,0,0,0,0,0,0 to AT+CIND? from %s", bd_addr->ToString().c_str());

    /* headset::Interface::CindResponse's parameters are similar but different
     * from the actual CIND response. It will construct the final response for
     * you based on the arguments you provide.
     * CindResponse(network_service_availability, active_call_num,
     *              held_call_num, callsetup_state, signal_strength,
     *              roam_state, battery_level, bd_addr);
     */
    headset_->CindResponse(0, 0, 0, headset::BTHF_CALL_STATE_IDLE, 0, 0, 0, bd_addr);
    // This is required to setup the SLC, the format of the response should be
    // +CIND: <call>,<callsetup>,<service>,<signal>,<roam>,<battery>,<callheld>
    LOG_WARN("Respond +CIND: 0,0,1,5,0,5,0 to AT+CIND? from %s", bd_addr->ToString().c_str());

    // headset::Interface::CindResponse's parameters are similar but different
    // from the actual CIND response. It will construct the final response for
    // you based on the arguments you provide.
    // CindResponse(network_service_availability, active_call_num,
    //              held_call_num, callsetup_state, signal_strength,
    //              roam_state, battery_level, bd_addr);
    headset_->CindResponse(1, 0, 0, headset::BTHF_CALL_STATE_IDLE, 5, 0, 5, bd_addr);
  }

  void AtCopsCallback(RawAddress* bd_addr) override {
@@ -102,20 +141,18 @@ class DBusHeadsetCallbacks : public headset::Callbacks {
  }

  void AtClccCallback(RawAddress* bd_addr) override {
    LOG_WARN("AT+CLCC from addr %s: Enhanced Call Status is not supported.", bd_addr->ToString().c_str());
    /*
    If we want to support the Enhanced Call Status feature, we need to use this
    callback to send response like "+CLCC: 0,0,0,0,0," with the following codes.
    headset_->ClccResponse(
        0,
        headset::BTHF_CALL_DIRECTION_OUTGOING,
        headset::BTHF_CALL_STATE_ACTIVE,
        headset::BTHF_CALL_TYPE_VOICE,
        headset::BTHF_CALL_MPTY_TYPE_SINGLE,
        NULL,
        headset::BTHF_CALL_ADDRTYPE_UNKNOWN,
        bd_addr);
    */
    // If we want to support the Enhanced Call Status feature, we need to use this
    // callback to send response like "+CLCC: 0,0,0,0,0," with the following codes.
    // headset_->ClccResponse(
    //    0,
    //    headset::BTHF_CALL_DIRECTION_OUTGOING,
    //    headset::BTHF_CALL_STATE_ACTIVE,
    //    headset::BTHF_CALL_TYPE_VOICE,
    //    headset::BTHF_CALL_MPTY_TYPE_SINGLE,
    //    NULL,
    //    headset::BTHF_CALL_ADDRTYPE_UNKNOWN,
    //    bd_addr);
    headset_->AtResponse(headset::BTHF_AT_RESPONSE_OK, 0, bd_addr);
  }

  void UnknownAtCallback(char* at_string, RawAddress* bd_addr) override {