blob: 5cec196eec254c465977be040f5f6305220c64b9 [file] [log] [blame]
/*
* Copyright 2017 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 "acl_connection_handler.h"
#include "include/hci.h"
#include "include/inquiry.h"
#include "include/link.h"
#include "include/phy.h"
#include "model/devices/device_properties.h"
#include "model/setup/async_manager.h"
#include "packets/hci/acl_packet_view.h"
#include "packets/hci/sco_packet_view.h"
#include "packets/link_layer/link_layer_packet_builder.h"
#include "packets/link_layer/link_layer_packet_view.h"
#include "security_manager.h"
#include "types/address.h"
namespace test_vendor_lib {
class LinkLayerController {
public:
LinkLayerController(const DeviceProperties& properties) : properties_(properties) {}
hci::Status SendCommandToRemoteByAddress(hci::OpCode opcode, packets::PacketView<true> args, const Address& remote,
bool use_public_address);
hci::Status SendCommandToRemoteByHandle(hci::OpCode opcode, packets::PacketView<true> args, uint16_t handle);
hci::Status SendScoToRemote(packets::ScoPacketView sco_packet);
hci::Status SendAclToRemote(packets::AclPacketView acl_packet);
void WriteSimplePairingMode(bool enabled);
void StartSimplePairing(const Address& address);
void AuthenticateRemoteStage1(const Address& address, PairingType pairing_type);
void AuthenticateRemoteStage2(const Address& address);
hci::Status LinkKeyRequestReply(const Address& address, packets::PacketView<true> key);
hci::Status LinkKeyRequestNegativeReply(const Address& address);
hci::Status IoCapabilityRequestReply(const Address& peer, uint8_t io_capability, uint8_t oob_data_present_flag,
uint8_t authentication_requirements);
hci::Status IoCapabilityRequestNegativeReply(const Address& peer, hci::Status reason);
hci::Status UserConfirmationRequestReply(const Address& peer);
hci::Status UserConfirmationRequestNegativeReply(const Address& peer);
hci::Status UserPasskeyRequestReply(const Address& peer, uint32_t numeric_value);
hci::Status UserPasskeyRequestNegativeReply(const Address& peer);
hci::Status RemoteOobDataRequestReply(const Address& peer, const std::vector<uint8_t>& c,
const std::vector<uint8_t>& r);
hci::Status RemoteOobDataRequestNegativeReply(const Address& peer);
void HandleSetConnectionEncryption(const Address& address, uint16_t handle, uint8_t encryption_enable);
hci::Status SetConnectionEncryption(uint16_t handle, uint8_t encryption_enable);
void HandleAuthenticationRequest(const Address& address, uint16_t handle);
hci::Status AuthenticationRequested(uint16_t handle);
hci::Status AcceptConnectionRequest(const Address& addr, bool try_role_switch);
void MakeSlaveConnection(const Address& addr, bool try_role_switch);
hci::Status RejectConnectionRequest(const Address& addr, uint8_t reason);
void RejectSlaveConnection(const Address& addr, uint8_t reason);
hci::Status CreateConnection(const Address& addr, uint16_t packet_type, uint8_t page_scan_mode, uint16_t clock_offset,
uint8_t allow_role_switch);
hci::Status CreateConnectionCancel(const Address& addr);
hci::Status Disconnect(uint16_t handle, uint8_t reason);
private:
void DisconnectCleanup(uint16_t handle, uint8_t reason);
public:
void IncomingPacket(packets::LinkLayerPacketView incoming);
void TimerTick();
// Set the callbacks for sending packets to the HCI.
void RegisterEventChannel(const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& send_event);
void RegisterAclChannel(const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& send_acl);
void RegisterScoChannel(const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& send_sco);
void RegisterRemoteChannel(
const std::function<void(std::shared_ptr<packets::LinkLayerPacketBuilder>, Phy::Type)>& send_to_remote);
// Set the callbacks for scheduling tasks.
void RegisterTaskScheduler(
std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> event_scheduler);
void RegisterPeriodicTaskScheduler(
std::function<AsyncTaskId(std::chrono::milliseconds, std::chrono::milliseconds, const TaskCallback&)>
periodic_event_scheduler);
void RegisterTaskCancel(std::function<void(AsyncTaskId)> cancel);
void Reset();
void AddControllerEvent(std::chrono::milliseconds delay, const TaskCallback& task);
void PageScan();
void Connections();
void LeWhiteListClear();
void LeWhiteListAddDevice(Address addr, uint8_t addr_type);
void LeWhiteListRemoveDevice(Address addr, uint8_t addr_type);
bool LeWhiteListContainsDevice(Address addr, uint8_t addr_type);
bool LeWhiteListFull();
void SetLeScanEnable(uint8_t le_scan_enable) {
le_scan_enable_ = le_scan_enable;
}
void SetLeScanType(uint8_t le_scan_type) {
le_scan_type_ = le_scan_type;
}
void SetLeScanInterval(uint16_t le_scan_interval) {
le_scan_interval_ = le_scan_interval;
}
void SetLeScanWindow(uint16_t le_scan_window) {
le_scan_window_ = le_scan_window;
}
void SetLeScanFilterPolicy(uint8_t le_scan_filter_policy) {
le_scan_filter_policy_ = le_scan_filter_policy;
}
void SetLeFilterDuplicates(uint8_t le_scan_filter_duplicates) {
le_scan_filter_duplicates_ = le_scan_filter_duplicates;
}
void SetLeAddressType(uint8_t le_address_type) {
le_address_type_ = le_address_type;
}
hci::Status SetLeConnect(bool le_connect) {
le_connect_ = le_connect;
return hci::Status::SUCCESS;
}
void SetLeConnectionIntervalMin(uint16_t min) {
le_connection_interval_min_ = min;
}
void SetLeConnectionIntervalMax(uint16_t max) {
le_connection_interval_max_ = max;
}
void SetLeConnectionLatency(uint16_t latency) {
le_connection_latency_ = latency;
}
void SetLeSupervisionTimeout(uint16_t timeout) {
le_connection_supervision_timeout_ = timeout;
}
void SetLeMinimumCeLength(uint16_t min) {
le_connection_minimum_ce_length_ = min;
}
void SetLeMaximumCeLength(uint16_t max) {
le_connection_maximum_ce_length_ = max;
}
void SetLeInitiatorFilterPolicy(uint8_t le_initiator_filter_policy) {
le_initiator_filter_policy_ = le_initiator_filter_policy;
}
void SetLePeerAddressType(uint8_t peer_address_type) {
le_peer_address_type_ = peer_address_type;
}
void SetLePeerAddress(const Address& peer_address) {
le_peer_address_ = peer_address;
}
// Classic
void StartInquiry(std::chrono::milliseconds timeout);
void InquiryCancel();
void InquiryTimeout();
void SetInquiryMode(uint8_t mode);
void SetInquiryLAP(uint64_t lap);
void SetInquiryMaxResponses(uint8_t max);
void Inquiry();
void SetInquiryScanEnable(bool enable);
void SetPageScanEnable(bool enable);
hci::Status ChangeConnectionPacketType(uint16_t handle, uint16_t types);
hci::Status WriteLinkPolicySettings(uint16_t handle, uint16_t settings);
hci::Status WriteLinkSupervisionTimeout(uint16_t handle, uint16_t timeout);
protected:
void SendLELinkLayerPacket(std::shared_ptr<packets::LinkLayerPacketBuilder> packet);
void SendLinkLayerPacket(std::shared_ptr<packets::LinkLayerPacketBuilder> packet);
void IncomingAclPacket(packets::LinkLayerPacketView packet);
void IncomingAclAckPacket(packets::LinkLayerPacketView packet);
void IncomingCommandPacket(packets::LinkLayerPacketView packet);
void IncomingCreateConnectionPacket(packets::LinkLayerPacketView packet);
void IncomingDisconnectPacket(packets::LinkLayerPacketView packet);
void IncomingEncryptConnection(packets::LinkLayerPacketView packet);
void IncomingEncryptConnectionResponse(packets::LinkLayerPacketView packet);
void IncomingInquiryPacket(packets::LinkLayerPacketView packet);
void IncomingInquiryResponsePacket(packets::LinkLayerPacketView packet);
void IncomingIoCapabilityRequestPacket(packets::LinkLayerPacketView packet);
void IncomingIoCapabilityResponsePacket(packets::LinkLayerPacketView packet);
void IncomingIoCapabilityNegativeResponsePacket(packets::LinkLayerPacketView packet);
void IncomingLeAdvertisementPacket(packets::LinkLayerPacketView packet);
void IncomingLeScanPacket(packets::LinkLayerPacketView packet);
void IncomingLeScanResponsePacket(packets::LinkLayerPacketView packet);
void IncomingPagePacket(packets::LinkLayerPacketView packet);
void IncomingPageResponsePacket(packets::LinkLayerPacketView packet);
void IncomingResponsePacket(packets::LinkLayerPacketView packet);
private:
const DeviceProperties& properties_;
AclConnectionHandler classic_connections_;
// Add timestamps?
std::vector<std::shared_ptr<packets::LinkLayerPacketBuilder>> commands_awaiting_responses_;
// Timing related state
std::vector<AsyncTaskId> controller_events_;
AsyncTaskId timer_tick_task_;
std::chrono::milliseconds timer_period_ = std::chrono::milliseconds(100);
// Callbacks to schedule tasks.
std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> schedule_task_;
std::function<AsyncTaskId(std::chrono::milliseconds, std::chrono::milliseconds, const TaskCallback&)>
schedule_periodic_task_;
std::function<void(AsyncTaskId)> cancel_task_;
// Callbacks to send packets back to the HCI.
std::function<void(std::shared_ptr<std::vector<uint8_t>>)> send_acl_;
std::function<void(std::shared_ptr<std::vector<uint8_t>>)> send_event_;
std::function<void(std::shared_ptr<std::vector<uint8_t>>)> send_sco_;
// Callback to send packets to remote devices.
std::function<void(std::shared_ptr<packets::LinkLayerPacketBuilder>, Phy::Type phy_type)> send_to_remote_;
// LE state
std::vector<uint8_t> le_event_mask_;
std::vector<std::tuple<Address, uint8_t>> le_white_list_;
uint8_t le_scan_enable_;
uint8_t le_scan_type_;
uint16_t le_scan_interval_;
uint16_t le_scan_window_;
uint8_t le_scan_filter_policy_;
uint8_t le_scan_filter_duplicates_;
uint8_t le_address_type_;
bool le_connect_;
uint16_t le_connection_interval_min_;
uint16_t le_connection_interval_max_;
uint16_t le_connection_latency_;
uint16_t le_connection_supervision_timeout_;
uint16_t le_connection_minimum_ce_length_;
uint16_t le_connection_maximum_ce_length_;
uint8_t le_initiator_filter_policy_;
Address le_peer_address_;
uint8_t le_peer_address_type_;
// Classic state
SecurityManager security_manager_{10};
std::chrono::steady_clock::time_point last_inquiry_;
Inquiry::InquiryType inquiry_mode_;
Inquiry::InquiryState inquiry_state_;
uint64_t inquiry_lap_;
uint8_t inquiry_max_responses_;
bool page_scans_enabled_{false};
bool inquiry_scans_enabled_{false};
bool simple_pairing_mode_enabled_{false};
};
} // namespace test_vendor_lib