blob: 8f8cfb50f242d2900c2dce89f477ea1c130d308b [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.
#pragma once
#include "garnet/drivers/bluetooth/lib/common/device_address.h"
#include "garnet/drivers/bluetooth/lib/hci/hci.h"
#include "lib/fxl/functional/closure.h"
#include "lib/fxl/logging.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/ref_ptr.h"
#include "lib/fxl/memory/weak_ptr.h"
#include "lib/fxl/synchronization/thread_checker.h"
namespace bluetooth {
namespace hci {
class Transport;
// Represents a logical link connection to a remote device. This class is not
// thread-safe. Instances should only be accessed on their creation thread.
class Connection final {
public:
// This defines the various connection types. These do not exactly correspond
// to the baseband logical/physical link types but instead provide a
// high-level abstraction.
enum class LinkType {
// Represents a BR/EDR baseband link (ACL-U).
kACL,
// BR/EDR isochronous links (SCO-S, eSCO-S).
kSCO,
kESCO,
// A LE logical link (LE-U).
kLE,
};
// Role of the local device in the established connection.
enum class Role {
kMaster,
kSlave,
};
// Connection parameters for a LE connection.
class LowEnergyParameters {
public:
LowEnergyParameters(uint16_t interval_min,
uint16_t interval_max,
uint16_t interval,
uint16_t latency,
uint16_t supervision_timeout);
// Default constructor initializes values to HCI defaults. This is intended
// for unit tests.
LowEnergyParameters();
// The minimum and maximum allowed connection intervals. The connection
// interval indicates the frequency of link layer connection events over
// which data channel PDUs can be transmitted. See Core Spec v5.0, Vol 6,
// Part B, Section 4.5.1 for more information on the link layer connection
// events.
uint16_t interval_min() const { return interval_min_; }
uint16_t interval_max() const { return interval_max_; }
// The actual connection interval used for a connection. This parameter is
// only valid for an active connection and will be set to 0 when an instance
// of this class is used during a connection request.
uint16_t interval() const { return interval_; }
// The maximum allowed connection latency. See Core Spec v5.0, Vol 6, Part
// B, Section 4.5.2.
uint16_t latency() const { return latency_; }
// This defines the maximum time between two received data packet PDUs
// before the connection is considered lost. See Core Spec v5.0, Vol 6, Part
// B, Section 4.5.2. This value is given in centiseconds and must be within
// the range 100 ms - 32 s (10 cs - 3200 cs).
uint16_t supervision_timeout() const { return supervision_timeout_; }
bool operator==(const LowEnergyParameters& other) const;
private:
uint16_t interval_min_;
uint16_t interval_max_;
uint16_t interval_;
uint16_t latency_;
uint16_t supervision_timeout_;
};
// Initializes this as a LE ACL connection.
Connection(ConnectionHandle handle,
Role role,
const common::DeviceAddress& peer_address,
const LowEnergyParameters& params,
fxl::RefPtr<Transport> hci);
// The destructor closes this connection.
~Connection();
// The type of the connection.
LinkType ll_type() const { return ll_type_; }
// Returns the 12-bit connection handle of this connection. This handle is
// used to identify an individual logical link maintained by the controller.
ConnectionHandle handle() const { return handle_; }
// Returns the role of the local device in the established connection.
Role role() const { return role_; }
// The LE connection parameters of this connection. Must only be called on a
// Connection with a link type LinkType::kLE.
const LowEnergyParameters& low_energy_parameters() const {
FXL_DCHECK(ll_type_ == LinkType::kLE);
return le_params_;
}
// The identity address of the peer device.
// TODO(armansito): Implement mechanism to store identity address here after
// address resolution.
const common::DeviceAddress& peer_address() const { return peer_address_; }
// Returns true if this connection is currently open.
bool is_open() const { return is_open_; }
void set_closed() { is_open_ = false; }
// Closes this connection by sending the HCI_Disconnect command to the
// controller. This method is a NOP if the connecton is already closed.
void Close(Status reason = Status::kRemoteUserTerminatedConnection);
std::string ToString() const;
private:
LinkType ll_type_;
ConnectionHandle handle_;
Role role_;
bool is_open_;
fxl::ThreadChecker thread_checker_;
// The address of the peer device.
common::DeviceAddress peer_address_;
// Connection parameters for a LE link. Not nullptr if the link type is LE.
LowEnergyParameters le_params_;
// The underlying HCI transport. We use this to terminate the connection by
// sending the HCI_Disconnect command.
fxl::RefPtr<Transport> hci_;
// TODO(armansito): Add a BREDRParameters struct.
// Keep this as the last member to make sure that all weak pointers are
// invalidated before other members get destroyed.
fxl::WeakPtrFactory<Connection> weak_ptr_factory_;
FXL_DISALLOW_COPY_AND_ASSIGN(Connection);
};
} // namespace hci
} // namespace bluetooth