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

Commit 3858422e authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "test_vendor: Extract DeviceProperties"

parents 7b097857 b6972698
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ cc_library_static {
        "src/connection.cc",
        "src/device.cc",
        "src/device_factory.cc",
        "src/device_properties.cc",
        "src/dual_mode_controller.cc",
        "src/event_packet.cc",
        "src/hci_packet.cc",
+154 −0
Original line number Diff line number Diff line
//
// Copyright 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#pragma once

#include <cstdint>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

#include "acl_packet.h"
#include "async_manager.h"
#include "base/json/json_value_converter.h"
#include "base/time/time.h"
#include "bt_address.h"

namespace test_vendor_lib {

// Emulates a dual mode BR/EDR + LE controller by maintaining the link layer
// state machine detailed in the Bluetooth Core Specification Version 4.2,
// Volume 6, Part B, Section 1.1 (page 30). Provides methods corresponding to
// commands sent by the HCI. These methods will be registered as callbacks from
// a controller instance with the HciHandler. To implement a new Bluetooth
// command, simply add the method declaration below, with return type void and a
// single const std::vector<uint8_t>& argument. After implementing the
// method, simply register it with the HciHandler using the SET_HANDLER macro in
// the controller's default constructor. Be sure to name your method after the
// corresponding Bluetooth command in the Core Specification with the prefix
// "Hci" to distinguish it as a controller command.
class DeviceProperties {
 public:
  explicit DeviceProperties(const std::string& file_name);

  // Access private configuration data

  // Specification Version 4.2, Volume 2, Part E, Section 7.4.1
  const std::vector<uint8_t>& GetLocalVersionInformation() const;

  // Specification Version 4.2, Volume 2, Part E, Section 7.4.2
  const std::vector<uint8_t>& GetLocalSupportedCommands() const {
    return local_supported_commands_;
  }

  // Specification Version 4.2, Volume 2, Part E, Section 7.4.3
  uint64_t GetLocalSupportedFeatures() const {
    return local_extended_features_[0];
  };

  // Specification Version 4.2, Volume 2, Part E, Section 7.4.4
  uint8_t GetLocalExtendedFeaturesMaximumPageNumber() const {
    return local_extended_features_.size() - 1;
  };

  uint64_t GetLocalExtendedFeatures(uint8_t page_number) const {
    CHECK(page_number < local_extended_features_.size());
    return local_extended_features_[page_number];
  };

  // Specification Version 4.2, Volume 2, Part E, Section 7.4.5
  uint16_t GetAclDataPacketSize() const { return acl_data_packet_size_; }

  uint8_t GetSynchronousDataPacketSize() const { return sco_data_packet_size_; }

  uint16_t GetTotalNumAclDataPackets() const { return num_acl_data_packets_; }

  uint16_t GetTotalNumSynchronousDataPackets() const {
    return num_sco_data_packets_;
  }

  const BtAddress& GetAddress() const { return address_; }

  // Specification Version 4.2, Volume 2, Part E, Section 7.4.8
  const std::vector<uint8_t>& GetSupportedCodecs() const {
    return supported_codecs_;
  }

  const std::vector<uint32_t>& GetVendorSpecificCodecs() const {
    return vendor_specific_codecs_;
  }

  const std::string& GetLocalName() const { return local_name_; }

  uint8_t GetVersion() const { return version_; }

  uint16_t GetRevision() const { return revision_; }

  uint8_t GetLmpPalVersion() const { return lmp_pal_version_; }

  uint16_t GetLmpPalSubversion() const { return lmp_pal_subversion_; }

  uint16_t GetManufacturerName() const { return manufacturer_name_; }

  // Specification Version 4.2, Volume 2, Part E, Section 7.8.2
  uint16_t GetLeDataPacketLength() const { return le_data_packet_length_; }

  uint8_t GetTotalNumLeDataPackets() const { return num_le_data_packets_; }

  // Specification Version 4.2, Volume 2, Part E, Section 7.8.3
  uint64_t GetLeLocalSupportedFeatures() const {
    return le_supported_features_;
  }

  // Specification Version 4.2, Volume 2, Part E, Section 7.8.14
  uint8_t GetLeWhiteListSize() const { return le_white_list_size_; }

  // Specification Version 4.2, Volume 2, Part E, Section 7.8.27
  uint64_t GetLeSupportedStates() const { return le_supported_states_; }

  // Vendor-specific commands (see hcidefs.h)
  const std::vector<uint8_t>& GetLeVendorCap() const { return le_vendor_cap_; }

  static void RegisterJSONConverter(
      base::JSONValueConverter<DeviceProperties>* converter);

 private:
  uint16_t acl_data_packet_size_;
  uint8_t sco_data_packet_size_;
  uint16_t num_acl_data_packets_;
  uint16_t num_sco_data_packets_;
  uint8_t version_;
  uint16_t revision_;
  uint8_t lmp_pal_version_;
  uint16_t manufacturer_name_;
  uint16_t lmp_pal_subversion_;
  std::vector<uint8_t> supported_codecs_;
  std::vector<uint32_t> vendor_specific_codecs_;
  std::vector<uint8_t> local_supported_commands_;
  std::string local_name_;
  std::vector<uint64_t> local_extended_features_;
  BtAddress address_;

  uint16_t le_data_packet_length_;
  uint8_t num_le_data_packets_;
  uint8_t le_white_list_size_;
  uint64_t le_supported_features_;
  uint64_t le_supported_states_;
  std::vector<uint8_t> le_vendor_cap_;
};

}  // namespace test_vendor_lib
+2 −116
Original line number Diff line number Diff line
@@ -24,12 +24,12 @@

#include "acl_packet.h"
#include "async_manager.h"
#include "base/json/json_value_converter.h"
#include "base/time/time.h"
#include "bt_address.h"
#include "command_packet.h"
#include "connection.h"
#include "device.h"
#include "device_properties.h"
#include "event_packet.h"
#include "sco_packet.h"
#include "test_channel_transport.h"
@@ -49,120 +49,6 @@ namespace test_vendor_lib {
// "Hci" to distinguish it as a controller command.
class DualModeController {
 public:
  class Properties {
   public:
    explicit Properties(const std::string& file_name);

    // Access private configuration data

    // Specification Version 4.2, Volume 2, Part E, Section 7.4.1
    const std::vector<uint8_t>& GetLocalVersionInformation() const;

    // Specification Version 4.2, Volume 2, Part E, Section 7.4.2
    const std::vector<uint8_t>& GetLocalSupportedCommands() const {
      return local_supported_commands_;
    }

    // Specification Version 4.2, Volume 2, Part E, Section 7.4.3
    uint64_t GetLocalSupportedFeatures() const {
      return local_extended_features_[0];
    };

    // Specification Version 4.2, Volume 2, Part E, Section 7.4.4
    uint8_t GetLocalExtendedFeaturesMaximumPageNumber() const {
      return local_extended_features_.size() - 1;
    };

    uint64_t GetLocalExtendedFeatures(uint8_t page_number) const {
      CHECK(page_number < local_extended_features_.size());
      return local_extended_features_[page_number];
    };

    // Specification Version 4.2, Volume 2, Part E, Section 7.4.5
    uint16_t GetAclDataPacketSize() const { return acl_data_packet_size_; }

    uint8_t GetSynchronousDataPacketSize() const {
      return sco_data_packet_size_;
    }

    uint16_t GetTotalNumAclDataPackets() const { return num_acl_data_packets_; }

    uint16_t GetTotalNumSynchronousDataPackets() const {
      return num_sco_data_packets_;
    }

    const BtAddress& GetAddress() const { return address_; }

    // Specification Version 4.2, Volume 2, Part E, Section 7.4.8
    const std::vector<uint8_t>& GetSupportedCodecs() const {
      return supported_codecs_;
    }

    const std::vector<uint32_t>& GetVendorSpecificCodecs() const {
      return vendor_specific_codecs_;
    }

    const std::string& GetLocalName() const { return local_name_; }

    uint8_t GetVersion() const { return version_; }

    uint16_t GetRevision() const { return revision_; }

    uint8_t GetLmpPalVersion() const { return lmp_pal_version_; }

    uint16_t GetLmpPalSubversion() const { return lmp_pal_subversion_; }

    uint16_t GetManufacturerName() const { return manufacturer_name_; }

    // Specification Version 4.2, Volume 2, Part E, Section 7.8.2
    uint16_t GetLeDataPacketLength() const { return le_data_packet_length_; }

    uint8_t GetTotalNumLeDataPackets() const { return num_le_data_packets_; }

    // Specification Version 4.2, Volume 2, Part E, Section 7.8.3
    uint64_t GetLeLocalSupportedFeatures() const {
      return le_supported_features_;
    }

    // Specification Version 4.2, Volume 2, Part E, Section 7.8.14
    uint8_t GetLeWhiteListSize() const { return le_white_list_size_; }

    // Specification Version 4.2, Volume 2, Part E, Section 7.8.27
    uint64_t GetLeSupportedStates() const { return le_supported_states_; }

    // Vendor-specific commands (see hcidefs.h)
    const std::vector<uint8_t>& GetLeVendorCap() const {
      return le_vendor_cap_;
    }

    static void RegisterJSONConverter(
        base::JSONValueConverter<Properties>* converter);

   private:
    uint16_t acl_data_packet_size_;
    uint8_t sco_data_packet_size_;
    uint16_t num_acl_data_packets_;
    uint16_t num_sco_data_packets_;
    uint8_t version_;
    uint16_t revision_;
    uint8_t lmp_pal_version_;
    uint16_t manufacturer_name_;
    uint16_t lmp_pal_subversion_;
    std::vector<uint8_t> supported_codecs_;
    std::vector<uint32_t> vendor_specific_codecs_;
    std::vector<uint8_t> local_supported_commands_;
    std::string local_name_;
    std::vector<uint64_t> local_extended_features_;
    BtAddress address_;

    uint16_t le_data_packet_length_;
    uint8_t num_le_data_packets_;
    uint8_t le_white_list_size_;
    uint64_t le_supported_features_;
    uint64_t le_supported_states_;
    std::vector<uint8_t> le_vendor_cap_;
  };

  // Sets all of the methods to be used as callbacks in the HciHandler.
  DualModeController();

@@ -579,7 +465,7 @@ class DualModeController {

  State state_;

  Properties properties_;
  DeviceProperties properties_;

  std::vector<std::shared_ptr<Device>> devices_;

+125 −0
Original line number Diff line number Diff line
//
// Copyright 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#define LOG_TAG "device_properties"

#include "device_properties.h"

#include <memory>

#include <base/logging.h>
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/values.h"

#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "stack/include/hcidefs.h"

using std::vector;

namespace {
// Functions used by JSONValueConverter to read stringified JSON.
bool ParseUint8t(const base::StringPiece& value, uint8_t* field) {
  *field = std::stoi(value.as_string());
  return true;
}

bool ParseUint16t(const base::StringPiece& value, uint16_t* field) {
  *field = std::stoi(value.as_string());
  return true;
}

}  // namespace

namespace test_vendor_lib {

DeviceProperties::DeviceProperties(const std::string& file_name)
    : acl_data_packet_size_(1024),
      sco_data_packet_size_(255),
      num_acl_data_packets_(10),
      num_sco_data_packets_(10),
      version_(HCI_PROTO_VERSION_4_1),
      revision_(0),
      lmp_pal_version_(7), /* 4.1 */
      manufacturer_name_(0),
      lmp_pal_subversion_(0),
      le_data_packet_length_(27),
      num_le_data_packets_(15),
      le_white_list_size_(15) {
  std::string properties_raw;

  local_extended_features_ = {0xffffffffffffffff, 0x7};

  CHECK(address_.FromString("01:02:03:04:05:06"));
  local_name_ = "DefaultName";

  supported_codecs_ = {1};
  vendor_specific_codecs_ = {};

  for (int i = 0; i < 64; i++) local_supported_commands_.push_back(0xff);

  le_supported_features_ = 0x1f;
  le_supported_states_ = 0x3ffffffffff;
  le_vendor_cap_ = {};

  LOG_INFO(LOG_TAG, "Reading controller properties from %s.",
           file_name.c_str());
  if (!base::ReadFileToString(base::FilePath(file_name), &properties_raw)) {
    LOG_ERROR(LOG_TAG, "Error reading controller properties from file.");
    return;
  }

  std::unique_ptr<base::Value> properties_value_ptr =
      base::JSONReader::Read(properties_raw);
  if (properties_value_ptr.get() == nullptr)
    LOG_INFO(LOG_TAG,
             "Error controller properties may consist of ill-formed JSON.");

  // Get the underlying base::Value object, which is of type
  // base::Value::TYPE_DICTIONARY, and read it into member variables.
  base::Value& properties_dictionary = *(properties_value_ptr.get());
  base::JSONValueConverter<DeviceProperties> converter;

  if (!converter.Convert(properties_dictionary, this))
    LOG_INFO(LOG_TAG,
             "Error converting JSON properties into Properties object.");
}

// static
void DeviceProperties::RegisterJSONConverter(
    base::JSONValueConverter<DeviceProperties>* converter) {
// TODO(dennischeng): Use RegisterIntField() here?
#define REGISTER_UINT8_T(field_name, field) \
  converter->RegisterCustomField<uint8_t>(  \
      field_name, &DeviceProperties::field, &ParseUint8t);
#define REGISTER_UINT16_T(field_name, field) \
  converter->RegisterCustomField<uint16_t>(  \
      field_name, &DeviceProperties::field, &ParseUint16t);
  REGISTER_UINT16_T("AclDataPacketSize", acl_data_packet_size_);
  REGISTER_UINT8_T("ScoDataPacketSize", sco_data_packet_size_);
  REGISTER_UINT16_T("NumAclDataPackets", num_acl_data_packets_);
  REGISTER_UINT16_T("NumScoDataPackets", num_sco_data_packets_);
  REGISTER_UINT8_T("Version", version_);
  REGISTER_UINT16_T("Revision", revision_);
  REGISTER_UINT8_T("LmpPalVersion", lmp_pal_version_);
  REGISTER_UINT16_T("ManufacturerName", manufacturer_name_);
  REGISTER_UINT16_T("LmpPalSubversion", lmp_pal_subversion_);
#undef REGISTER_UINT8_T
#undef REGISTER_UINT16_T
}

}  // namespace test_vendor_lib
+0 −87
Original line number Diff line number Diff line
@@ -48,18 +48,6 @@ void LogCommand(const char* command) {
  LOG_INFO(LOG_TAG, "Controller performing command: %s", command);
}

// Functions used by JSONValueConverter to read stringified JSON into Properties
// object.
bool ParseUint8t(const base::StringPiece& value, uint8_t* field) {
  *field = std::stoi(value.as_string());
  return true;
}

bool ParseUint16t(const base::StringPiece& value, uint16_t* field) {
  *field = std::stoi(value.as_string());
  return true;
}

}  // namespace

namespace test_vendor_lib {
@@ -930,79 +918,4 @@ void DualModeController::HciWriteLoopbackMode(const vector<uint8_t>& args) {
  SendCommandCompleteSuccess(HCI_WRITE_LOOPBACK_MODE);
}

DualModeController::Properties::Properties(const std::string& file_name)
    : acl_data_packet_size_(1024),
      sco_data_packet_size_(255),
      num_acl_data_packets_(10),
      num_sco_data_packets_(10),
      version_(HCI_PROTO_VERSION_4_1),
      revision_(0),
      lmp_pal_version_(7), /* 4.1 */
      manufacturer_name_(0),
      lmp_pal_subversion_(0),
      le_data_packet_length_(27),
      num_le_data_packets_(15),
      le_white_list_size_(15) {
  std::string properties_raw;

  local_extended_features_ = {0xffffffffffffffff, 0x7};

  CHECK(address_.FromString("01:02:03:04:05:06"));
  local_name_ = "DefaultName";

  supported_codecs_ = {1};
  vendor_specific_codecs_ = {};

  for (int i = 0; i < 64; i++) local_supported_commands_.push_back(0xff);

  le_supported_features_ = 0x1f;
  le_supported_states_ = 0x3ffffffffff;
  le_vendor_cap_ = {};

  LOG_INFO(LOG_TAG, "Reading controller properties from %s.",
           file_name.c_str());
  if (!base::ReadFileToString(base::FilePath(file_name), &properties_raw)) {
    LOG_ERROR(LOG_TAG, "Error reading controller properties from file.");
    return;
  }

  std::unique_ptr<base::Value> properties_value_ptr =
      base::JSONReader::Read(properties_raw);
  if (properties_value_ptr.get() == nullptr)
    LOG_INFO(LOG_TAG,
             "Error controller properties may consist of ill-formed JSON.");

  // Get the underlying base::Value object, which is of type
  // base::Value::TYPE_DICTIONARY, and read it into member variables.
  base::Value& properties_dictionary = *(properties_value_ptr.get());
  base::JSONValueConverter<DualModeController::Properties> converter;

  if (!converter.Convert(properties_dictionary, this))
    LOG_INFO(LOG_TAG,
             "Error converting JSON properties into Properties object.");
}

// static
void DualModeController::Properties::RegisterJSONConverter(
    base::JSONValueConverter<DualModeController::Properties>* converter) {
// TODO(dennischeng): Use RegisterIntField() here?
#define REGISTER_UINT8_T(field_name, field) \
  converter->RegisterCustomField<uint8_t>(  \
      field_name, &DualModeController::Properties::field, &ParseUint8t);
#define REGISTER_UINT16_T(field_name, field) \
  converter->RegisterCustomField<uint16_t>(  \
      field_name, &DualModeController::Properties::field, &ParseUint16t);
  REGISTER_UINT16_T("AclDataPacketSize", acl_data_packet_size_);
  REGISTER_UINT8_T("ScoDataPacketSize", sco_data_packet_size_);
  REGISTER_UINT16_T("NumAclDataPackets", num_acl_data_packets_);
  REGISTER_UINT16_T("NumScoDataPackets", num_sco_data_packets_);
  REGISTER_UINT8_T("Version", version_);
  REGISTER_UINT16_T("Revision", revision_);
  REGISTER_UINT8_T("LmpPalVersion", lmp_pal_version_);
  REGISTER_UINT16_T("ManufacturerName", manufacturer_name_);
  REGISTER_UINT16_T("LmpPalSubversion", lmp_pal_subversion_);
#undef REGISTER_UINT8_T
#undef REGISTER_UINT16_T
}

}  // namespace test_vendor_lib