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

Commit 4bf90010 authored by Chienyuan Huang's avatar Chienyuan Huang
Browse files

CS: Read vendor specific characteristics from RAS client

Bug: 338259287
Bug: 324185011
Test: m com.android.btservices
Change-Id: I704d113da321661ad0c378ebd0ceee07d9145e7b
parent 160dae71
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ RasServer* GetRasServer();
class RasClientCallbacks {
 public:
  virtual ~RasClientCallbacks() = default;
  virtual void OnConnected(const RawAddress& address, uint16_t att_handle,
                           const std::vector<VendorSpecificCharacteristic>&
                               vendor_specific_characteristics) = 0;
  virtual void OnRemoteData(const RawAddress& address,
                            const std::vector<uint8_t>& data) = 0;
};
@@ -56,6 +59,10 @@ class RasClient {
  virtual void Initialize() = 0;
  virtual void RegisterCallbacks(RasClientCallbacks* callbacks) = 0;
  virtual void Connect(const RawAddress& address) = 0;
  virtual void SendVendorSpecificReply(
      const RawAddress& address,
      const std::vector<VendorSpecificCharacteristic>&
          vendor_specific_data) = 0;
};

RasClient* GetRasClient();
+92 −5
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ using namespace bluetooth;
using namespace ::ras;
using namespace ::ras::feature;
using namespace ::ras::uuid;
using bluetooth::ras::VendorSpecificCharacteristic;

namespace {

@@ -45,6 +46,7 @@ class RasClientImpl : public bluetooth::ras::RasClient {
    uint32_t remote_supported_features_;
    uint16_t latest_ranging_counter_ = 0;
    bool handling_on_demand_data_ = false;
    std::vector<VendorSpecificCharacteristic> vendor_specific_characteristics_;

    const gatt::Characteristic* FindCharacteristicByUuid(Uuid uuid) {
      for (auto& characteristic : service_->characteristics) {
@@ -62,6 +64,16 @@ class RasClientImpl : public bluetooth::ras::RasClient {
      }
      return nullptr;
    }

    VendorSpecificCharacteristic* GetVendorSpecificCharacteristic(
        const bluetooth::Uuid& uuid) {
      for (auto& characteristic : vendor_specific_characteristics_) {
        if (characteristic.characteristicUuid_ == uuid) {
          return &characteristic;
        }
      }
      return nullptr;
    }
  };

  void Initialize() override {
@@ -98,6 +110,33 @@ class RasClientImpl : public bluetooth::ras::RasClient {
    BTA_GATTC_Open(gatt_if_, ble_bd_addr.bda, BTM_BLE_DIRECT_CONNECTION, false);
  }

  void SendVendorSpecificReply(
      const RawAddress& address,
      const std::vector<VendorSpecificCharacteristic>& vendor_specific_data) {
    tBLE_BD_ADDR ble_bd_addr;
    ResolveAddress(ble_bd_addr, address);
    log::info("address {}, resolve {}", address, ble_bd_addr.bda);
    auto tracker = FindTrackerByAddress(ble_bd_addr.bda);

    uint8_t index = 1;
    for (auto& vendor_specific_characteristic : vendor_specific_data) {
      auto characteristic = tracker->FindCharacteristicByUuid(
          vendor_specific_characteristic.characteristicUuid_);
      if (characteristic == nullptr) {
        log::warn("Can't find characteristic uuid {}",
                  vendor_specific_characteristic.characteristicUuid_);
        return;
      }
      log::debug("write to remote, uuid {}, len {}",
                 vendor_specific_characteristic.characteristicUuid_,
                 vendor_specific_characteristic.value_.size());
      BTA_GATTC_WriteCharValue(tracker->conn_id_, characteristic->value_handle,
                               GATT_WRITE,
                               vendor_specific_characteristic.value_,
                               GATT_AUTH_REQ_MITM, GattWriteCallback, nullptr);
    }
  }

  void GattcCallback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
    log::debug("event: {}", gatt_client_event_text(event));
    switch (event) {
@@ -167,7 +206,27 @@ class RasClientImpl : public bluetooth::ras::RasClient {
      return;
    } else {
      log::info("Found Ranging Service");
      ListCharacteristic(tracker->service_);
      ListCharacteristic(tracker);
    }

    // Read Vendor Specific Uuid
    if (!tracker->vendor_specific_characteristics_.empty()) {
      for (auto& vendor_specific_characteristic :
           tracker->vendor_specific_characteristics_) {
        log::debug("Read vendor specific characteristic uuid {}",
                   vendor_specific_characteristic.characteristicUuid_);
        auto characteristic = tracker->FindCharacteristicByUuid(
            vendor_specific_characteristic.characteristicUuid_);

        BTA_GATTC_ReadCharacteristic(
            tracker->conn_id_, characteristic->value_handle, GATT_AUTH_REQ_MITM,
            [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
               uint16_t len, uint8_t* value, void* data) {
              instance->OnReadCharacteristicCallback(conn_id, status, handle,
                                                     len, value, data);
            },
            nullptr);
      }
    }

    // Read Ras Features
@@ -390,15 +449,26 @@ class RasClientImpl : public bluetooth::ras::RasClient {
              gatt_status_text(status));
  }

  void ListCharacteristic(const gatt::Service* service) {
    for (auto& characteristic : service->characteristics) {
  void ListCharacteristic(std::shared_ptr<RasTracker> tracker) {
    for (auto& characteristic : tracker->service_->characteristics) {
      bool vendor_specific =
          !IsRangingServiceCharacteristic(characteristic.uuid);
      log::info(
          "Characteristic uuid:0x{:04x}, handle:0x{:04x}, properties:0x{:02x}, "
          "{}Characteristic uuid:0x{:04x}, handle:0x{:04x}, "
          "properties:0x{:02x}, "
          "{}",
          vendor_specific ? "Vendor Specific " : "",
          characteristic.uuid.As16Bit(), characteristic.value_handle,
          characteristic.properties, getUuidName(characteristic.uuid));
      if (vendor_specific) {
        VendorSpecificCharacteristic vendor_specific_characteristic;
        vendor_specific_characteristic.characteristicUuid_ =
            characteristic.uuid;
        tracker->vendor_specific_characteristics_.emplace_back(
            vendor_specific_characteristic);
      }
      for (auto& descriptor : characteristic.descriptors) {
        log::info("\tDescriptor uuid: 0x{:04x}, handle:{}, {}",
        log::info("\tDescriptor uuid:0x{:04x}, handle:0x{:04x}, {}",
                  descriptor.uuid.As16Bit(), descriptor.handle,
                  getUuidName(descriptor.uuid));
      }
@@ -430,6 +500,17 @@ class RasClientImpl : public bluetooth::ras::RasClient {
      return;
    }

    auto vendor_specific_characteristic =
        tracker->GetVendorSpecificCharacteristic(characteristic->uuid);
    if (vendor_specific_characteristic != nullptr) {
      log::info("Update vendor specific data, uuid: {}",
                vendor_specific_characteristic->characteristicUuid_);
      vendor_specific_characteristic->value_.clear();
      vendor_specific_characteristic->value_.reserve(len);
      vendor_specific_characteristic->value_.assign(value, value + len);
      return;
    }

    uint16_t uuid_16bit = characteristic->uuid.As16Bit();
    log::info("Handle uuid 0x{:04x}, {}", uuid_16bit,
              getUuidName(characteristic->uuid));
@@ -455,6 +536,12 @@ class RasClientImpl : public bluetooth::ras::RasClient {
          SubscribeCharacteristic(tracker,
                                  kRasRangingDataOverWrittenCharacteristic);
        }
        uint16_t att_handle = tracker
                                  ->FindCharacteristicByUuid(
                                      kRasRealTimeRangingDataCharacteristic)
                                  ->value_handle;
        callbacks_->OnConnected(tracker->address_for_cs_, att_handle,
                                tracker->vendor_specific_characteristics_);
      } break;
      default:
        log::warn("Unexpected UUID");
+2 −0
Original line number Diff line number Diff line
@@ -109,4 +109,6 @@ struct ControlPointResponse {
bool ParseControlPointCommand(ControlPointCommand* command,
                              const uint8_t* value, uint16_t len);

bool IsRangingServiceCharacteristic(const bluetooth::Uuid& uuid);

}  // namespace ras
+15 −0
Original line number Diff line number Diff line
@@ -133,4 +133,19 @@ std::string GetResponseOpcodeValueText(ResponseCodeValue response_code_value) {
  }
}

bool IsRangingServiceCharacteristic(const bluetooth::Uuid& uuid) {
  switch (uuid.As16Bit()) {
    case kRangingService16Bit:
    case kRasFeaturesCharacteristic16bit:
    case kRasRealTimeRangingDataCharacteristic16bit:
    case kRasOnDemandDataCharacteristic16bit:
    case kRasControlPointCharacteristic16bit:
    case kRasRangingDataReadyCharacteristic16bit:
    case kRasRangingDataOverWrittenCharacteristic16bit:
      return true;
    default:
      return false;
  }
}

}  // namespace ras
+16 −2
Original line number Diff line number Diff line
@@ -26,13 +26,27 @@ struct VendorSpecificCharacteristic {
  std::vector<uint8_t> value_;
};

class RangingHalCallback {
 public:
  virtual ~RangingHalCallback() = default;
  virtual void OnOpened(
      uint16_t connection_handle,
      const std::vector<VendorSpecificCharacteristic>& vendor_specific_reply) = 0;
  virtual void OnOpenFailed(uint16_t connection_handle) = 0;
};

class RangingHal : public ::bluetooth::Module {
 public:
  static const ModuleFactory Factory;

  virtual ~RangingHal() = default;
  virtual bool isBound() = 0;
  virtual std::vector<VendorSpecificCharacteristic> getVendorSpecificCharacteristics() = 0;
  virtual bool IsBound() = 0;
  virtual void RegisterCallback(RangingHalCallback* callback) = 0;
  virtual std::vector<VendorSpecificCharacteristic> GetVendorSpecificCharacteristics() = 0;
  virtual void OpenSession(
      uint16_t connection_handle,
      uint16_t att_handle,
      const std::vector<hal::VendorSpecificCharacteristic>& vendor_specific_data) = 0;
};

}  // namespace hal
Loading