blob: 1dc827e2a302ec31c11c0985ea10da2fd0b5c360 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_CONNECTIVITY_BLUETOOTH_HCI_VENDOR_INTEL_VENDOR_HCI_H_
#define SRC_CONNECTIVITY_BLUETOOTH_HCI_VENDOR_INTEL_VENDOR_HCI_H_
#include <lib/zx/channel.h>
#include "hci_event_handler.h"
#include "packets.emb.h"
namespace bt_hci_intel {
constexpr uint16_t kReadVersionOcf = 0x0005;
constexpr uint8_t kVersionSupportTlv = 0xff;
constexpr uint8_t kLegacyVersionParams = 0x37; // For AX201 and older.
constexpr uint8_t kCurrentModeOfOperationBootloader = 0x01;
constexpr uint8_t kCurrentModeOfOperationOperationalFirmware = 0x03;
struct ReadVersionReturnParamsTlv {
pw::bluetooth::emboss::StatusCode status;
uint16_t CNVi;
uint16_t CNVR;
uint8_t hw_platform; // 0x37: only supported value at the moment
uint8_t hw_variant; // * 0x17: Typhoon Peak
// * 0x1c: Gale Peak
uint16_t device_revision;
uint8_t current_mode_of_operation; // see kCurrentModeOfOperation*.
uint8_t timestamp_calendar_week;
uint8_t timestamp_year;
uint8_t build_type;
uint32_t build_number;
uint8_t secure_boot;
uint8_t otp_lock;
uint8_t api_lock;
uint8_t debug_lock;
uint8_t firmware_build_number;
uint8_t firmware_build_calendar_week;
uint8_t firmware_build_year;
uint8_t unknown;
uint8_t secure_boot_engine_type; // - 0x00: RSA
// - 0x01: ECDSA
uint8_t bluetooth_address[6]; // BD_ADDR
} __PACKED;
constexpr uint8_t kBootloaderFirmwareVariant = 0x06;
constexpr uint8_t kFirmwareFirmwareVariant = 0x23;
constexpr uint8_t kVendorOgf = 0x3F;
constexpr uint16_t kLoadPatchOcf = 0x008e;
constexpr uint16_t kSecureSendOcf = 0x0009;
constexpr uint16_t kReadBootParamsOcf = 0x000D;
constexpr uint16_t kVendorResetOcf = 0x0001;
constexpr uint16_t kMfgModeChangeOcf = 0x0011;
struct BootloaderVendorEventParams {
uint8_t vendor_event_code;
uint8_t vendor_params[];
} __PACKED;
// Helper functions.
uint32_t fetch_tlv_value(const uint8_t* p, size_t fetch_len);
ReadVersionReturnParamsTlv parse_tlv_version_return_params(const uint8_t* p, size_t len);
class VendorHci {
public:
explicit VendorHci(fidl::SharedClient<fuchsia_hardware_bluetooth::HciTransport>& client,
HciEventHandler& event_handler);
// Read the version info from the hardware.
//
// The legacy method.
// Returns an empty vector on error.
std::vector<uint8_t> SendReadVersion() const;
// The new method that supports TLV.
std::optional<ReadVersionReturnParamsTlv> SendReadVersionTlv() const;
std::vector<uint8_t> SendReadBootParams() const;
pw::bluetooth::emboss::StatusCode SendHciReset() const;
void SendVendorReset(uint32_t boot_address) const;
bool SendSecureSend(uint8_t type, cpp20::span<const uint8_t> bytes) const;
bool SendAndExpect(cpp20::span<const uint8_t> command,
std::deque<cpp20::span<const uint8_t>> events) const;
void EnterManufacturerMode();
bool ExitManufacturerMode(MfgDisableMode mode);
private:
// Intel controllers that support the "secure send" can send
// vendor events over the bulk endpoint while in bootloader mode. We listen on
// both types of incoming events, if provided.
fidl::SharedClient<fuchsia_hardware_bluetooth::HciTransport>& hci_transport_client_;
HciEventHandler& hci_event_handler_;
// True when we are in Manufacturer Mode
bool manufacturer_;
void SendCommand(std::vector<uint8_t> command) const;
// Send commands as ACL packets. When |FirmwareLoader::LoadSfi| invokes |SendSecureSend|, it
// assumes that the commands will be sent as ACL packets. This logic is to match behavior before
// HciTransport migration, where all the packets were sent through channels, and |SendSecureSend|
// sends commands through acl channel at that time.
void SendAcl(std::vector<uint8_t> command) const;
std::vector<uint8_t> WaitForEventBuffer(
zx::duration timeout = zx::sec(5),
std::optional<pw::bluetooth::emboss::EventCode> expected_event = std::nullopt) const;
};
} // namespace bt_hci_intel
#endif // SRC_CONNECTIVITY_BLUETOOTH_HCI_VENDOR_INTEL_VENDOR_HCI_H_