blob: 22b16d8512d15e288d72ed202d75e1f591c09596 [file] [log] [blame]
/*
*
* Copyright 2019 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.
*
*/
#include "security/channel/security_manager_channel.h"
#include <gtest/gtest.h>
#include "hci/address.h"
#include "hci/hci_packets.h"
#include "packet/raw_builder.h"
#include "security/smp_packets.h"
#include "security/test/fake_hci_layer.h"
#include "security/test/fake_security_interface.h"
namespace bluetooth {
namespace security {
namespace channel {
namespace {
using bluetooth::security::channel::SecurityManagerChannel;
using hci::Address;
using hci::AuthenticationRequirements;
using hci::CommandCompleteBuilder;
using hci::IoCapabilityRequestReplyBuilder;
using hci::IoCapabilityRequestView;
using hci::OobDataPresent;
using hci::OpCode;
using os::Handler;
using os::Thread;
using packet::RawBuilder;
static bool on_link_connected_called = false;
static bool on_link_disconnected_called = false;
class FakeSecurityManagerChannel : public SecurityManagerChannel {
public:
FakeSecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer)
: SecurityManagerChannel(handler, hci_layer) {}
~FakeSecurityManagerChannel() {}
void OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link) {
on_link_connected_called = true;
}
void OnLinkDisconnected(hci::Address address) {
on_link_disconnected_called = true;
}
void OnAuthenticationComplete(hci::ErrorCode hci_status, hci::Address remote) override {}
void OnEncryptionChange(hci::Address address, bool encrypted) override {}
};
class SecurityManagerChannelCallback : public ISecurityManagerChannelListener {
public:
// HCI
bool receivedChangeConnectionLinkKeyComplete = false;
bool receivedCentralLinkKeyComplete = false;
bool receivedPinCodeRequest = false;
bool receivedLinkKeyRequest = false;
bool receivedLinkKeyNotification = false;
bool receivedIoCapabilityRequest = false;
bool receivedIoCapabilityResponse = false;
bool receivedSimplePairingComplete = false;
bool receivedReturnLinkKeys = false;
bool receivedEncryptionChange = false;
bool receivedEncryptionKeyRefreshComplete = false;
bool receivedRemoteOobDataRequest = false;
bool receivedUserPasskeyNotification = false;
bool receivedUserPasskeyRequest = false;
bool receivedKeypressNotification = false;
bool receivedUserConfirmationRequest = false;
void OnReceive(hci::AddressWithType device, hci::ChangeConnectionLinkKeyCompleteView packet) {
ASSERT_TRUE(packet.IsValid());
receivedChangeConnectionLinkKeyComplete = true;
}
void OnReceive(hci::AddressWithType device, hci::CentralLinkKeyCompleteView packet) {
ASSERT_TRUE(packet.IsValid());
receivedCentralLinkKeyComplete = true;
}
void OnReceive(hci::AddressWithType device, hci::PinCodeRequestView packet) {
ASSERT_TRUE(packet.IsValid());
receivedPinCodeRequest = true;
}
void OnReceive(hci::AddressWithType device, hci::LinkKeyRequestView packet) {
ASSERT_TRUE(packet.IsValid());
receivedLinkKeyRequest = true;
}
void OnReceive(hci::AddressWithType device, hci::LinkKeyNotificationView packet) {
ASSERT_TRUE(packet.IsValid());
receivedLinkKeyNotification = true;
}
void OnReceive(hci::AddressWithType device, hci::IoCapabilityRequestView packet) {
ASSERT_TRUE(packet.IsValid());
receivedIoCapabilityRequest = true;
}
void OnReceive(hci::AddressWithType device, hci::IoCapabilityResponseView packet) {
ASSERT_TRUE(packet.IsValid());
receivedIoCapabilityResponse = true;
}
void OnReceive(hci::AddressWithType device, hci::SimplePairingCompleteView packet) {
ASSERT_TRUE(packet.IsValid());
receivedSimplePairingComplete = true;
}
void OnReceive(hci::AddressWithType device, hci::ReturnLinkKeysView packet) {
ASSERT_TRUE(packet.IsValid());
receivedReturnLinkKeys = true;
}
void OnReceive(hci::AddressWithType device, hci::EncryptionChangeView packet) {
ASSERT_TRUE(packet.IsValid());
receivedEncryptionChange = true;
}
void OnReceive(hci::AddressWithType device, hci::EncryptionKeyRefreshCompleteView packet) {
ASSERT_TRUE(packet.IsValid());
receivedEncryptionKeyRefreshComplete = true;
}
void OnReceive(hci::AddressWithType device, hci::RemoteOobDataRequestView packet) {
ASSERT_TRUE(packet.IsValid());
receivedRemoteOobDataRequest = true;
}
void OnReceive(hci::AddressWithType device, hci::UserPasskeyNotificationView packet) {
ASSERT_TRUE(packet.IsValid());
receivedUserPasskeyNotification = true;
}
void OnReceive(hci::AddressWithType device, hci::KeypressNotificationView packet) {
ASSERT_TRUE(packet.IsValid());
receivedKeypressNotification = true;
}
void OnReceive(hci::AddressWithType device, hci::UserConfirmationRequestView packet) {
ASSERT_TRUE(packet.IsValid());
receivedUserConfirmationRequest = true;
}
void OnReceive(hci::AddressWithType device, hci::UserPasskeyRequestView packet) {
ASSERT_TRUE(packet.IsValid());
receivedUserPasskeyRequest = true;
}
void OnHciEventReceived(EventView packet) override {
auto event = EventView::Create(packet);
ASSERT_LOG(event.IsValid(), "Received invalid packet");
const hci::EventCode code = event.GetEventCode();
switch (code) {
case hci::EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE:
OnReceive(hci::AddressWithType(), hci::ChangeConnectionLinkKeyCompleteView::Create(event));
break;
case hci::EventCode::CENTRAL_LINK_KEY_COMPLETE:
OnReceive(hci::AddressWithType(), hci::CentralLinkKeyCompleteView::Create(event));
break;
case hci::EventCode::PIN_CODE_REQUEST:
OnReceive(hci::AddressWithType(), hci::PinCodeRequestView::Create(event));
break;
case hci::EventCode::LINK_KEY_REQUEST:
OnReceive(hci::AddressWithType(), hci::LinkKeyRequestView::Create(event));
break;
case hci::EventCode::LINK_KEY_NOTIFICATION:
OnReceive(hci::AddressWithType(), hci::LinkKeyNotificationView::Create(event));
break;
case hci::EventCode::IO_CAPABILITY_REQUEST:
OnReceive(hci::AddressWithType(), hci::IoCapabilityRequestView::Create(event));
break;
case hci::EventCode::IO_CAPABILITY_RESPONSE:
OnReceive(hci::AddressWithType(), hci::IoCapabilityResponseView::Create(event));
break;
case hci::EventCode::SIMPLE_PAIRING_COMPLETE:
OnReceive(hci::AddressWithType(), hci::SimplePairingCompleteView::Create(event));
break;
case hci::EventCode::RETURN_LINK_KEYS:
OnReceive(hci::AddressWithType(), hci::ReturnLinkKeysView::Create(event));
break;
case hci::EventCode::ENCRYPTION_CHANGE:
OnReceive(hci::AddressWithType(), hci::EncryptionChangeView::Create(event));
break;
case hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE:
OnReceive(hci::AddressWithType(), hci::EncryptionKeyRefreshCompleteView::Create(event));
break;
case hci::EventCode::REMOTE_OOB_DATA_REQUEST:
OnReceive(hci::AddressWithType(), hci::RemoteOobDataRequestView::Create(event));
break;
case hci::EventCode::USER_PASSKEY_NOTIFICATION:
OnReceive(hci::AddressWithType(), hci::UserPasskeyNotificationView::Create(event));
break;
case hci::EventCode::KEYPRESS_NOTIFICATION:
OnReceive(hci::AddressWithType(), hci::KeypressNotificationView::Create(event));
break;
case hci::EventCode::USER_CONFIRMATION_REQUEST:
OnReceive(hci::AddressWithType(), hci::UserConfirmationRequestView::Create(event));
break;
case hci::EventCode::USER_PASSKEY_REQUEST:
OnReceive(hci::AddressWithType(), hci::UserPasskeyRequestView::Create(event));
break;
default:
ASSERT_LOG(false, "Cannot handle received packet: %s", hci::EventCodeText(code).c_str());
break;
}
}
void OnConnectionClosed(hci::Address address) override {
LOG_INFO("Called");
}
};
class SecurityManagerChannelTest : public ::testing::Test {
protected:
void SetUp() override {
hci::Address address;
hci::Address::FromString("01:23:45:67:89:AB:CD", address);
device_ = hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS);
on_link_connected_called = false;
on_link_disconnected_called = false;
handler_ = new Handler(&thread_);
callback_ = new SecurityManagerChannelCallback();
hci_layer_ = new FakeHciLayer();
fake_registry_.InjectTestModule(&FakeHciLayer::Factory, hci_layer_);
fake_registry_.Start<FakeHciLayer>(&thread_);
channel_ = new FakeSecurityManagerChannel(handler_, hci_layer_);
channel_->SetChannelListener(callback_);
security_interface_ = new FakeSecurityInterface(handler_, channel_);
channel_->SetSecurityInterface(security_interface_);
}
void TearDown() override {
channel_->SetChannelListener(nullptr);
handler_->Clear();
synchronize();
fake_registry_.StopAll();
delete handler_;
delete channel_;
delete callback_;
delete security_interface_;
}
void synchronize() {
fake_registry_.SynchronizeModuleHandler(&FakeHciLayer::Factory, std::chrono::milliseconds(20));
}
TestModuleRegistry fake_registry_;
Thread& thread_ = fake_registry_.GetTestThread();
Handler* handler_ = nullptr;
FakeHciLayer* hci_layer_ = nullptr;
l2cap::classic::SecurityInterface* security_interface_ = nullptr;
SecurityManagerChannel* channel_ = nullptr;
SecurityManagerChannelCallback* callback_ = nullptr;
hci::AddressWithType device_;
};
TEST_F(SecurityManagerChannelTest, setup_teardown) {}
TEST_F(SecurityManagerChannelTest, recv_io_cap_request) {
hci_layer_->IncomingEvent(hci::IoCapabilityRequestBuilder::Create(device_.GetAddress()));
synchronize();
ASSERT_TRUE(callback_->receivedIoCapabilityRequest);
}
TEST_F(SecurityManagerChannelTest, send_io_cap_request_reply) {
// Arrange
hci::IoCapability io_capability = (hci::IoCapability)0x00;
OobDataPresent oob_present = (OobDataPresent)0x00;
AuthenticationRequirements authentication_requirements = (AuthenticationRequirements)0x00;
auto packet = hci::IoCapabilityRequestReplyBuilder::Create(device_.GetAddress(), io_capability, oob_present,
authentication_requirements);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_io_cap_request_neg_reply) {
// Arrange
auto packet =
hci::IoCapabilityRequestNegativeReplyBuilder::Create(device_.GetAddress(), hci::ErrorCode::COMMAND_DISALLOWED);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, recv_io_cap_response) {
hci::IoCapability io_capability = (hci::IoCapability)0x00;
OobDataPresent oob_present = (OobDataPresent)0x00;
AuthenticationRequirements authentication_requirements = (AuthenticationRequirements)0x00;
hci_layer_->IncomingEvent(hci::IoCapabilityResponseBuilder::Create(device_.GetAddress(), io_capability, oob_present,
authentication_requirements));
synchronize();
ASSERT_TRUE(callback_->receivedIoCapabilityResponse);
}
TEST_F(SecurityManagerChannelTest, recv_pin_code_request) {
hci_layer_->IncomingEvent(hci::PinCodeRequestBuilder::Create(device_.GetAddress()));
synchronize();
ASSERT_TRUE(callback_->receivedPinCodeRequest);
}
TEST_F(SecurityManagerChannelTest, send_pin_code_request_reply) {
// Arrange
uint8_t pin_code_length = 6;
std::array<uint8_t, 16> pin_code = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
auto packet = hci::PinCodeRequestReplyBuilder::Create(device_.GetAddress(), pin_code_length, pin_code);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::PIN_CODE_REQUEST_REPLY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_pin_code_request_neg_reply) {
// Arrange
auto packet = hci::PinCodeRequestNegativeReplyBuilder::Create(device_.GetAddress());
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::PIN_CODE_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, recv_user_passkey_notification) {
uint32_t passkey = 0x00;
hci_layer_->IncomingEvent(hci::UserPasskeyNotificationBuilder::Create(device_.GetAddress(), passkey));
synchronize();
ASSERT_TRUE(callback_->receivedUserPasskeyNotification);
}
TEST_F(SecurityManagerChannelTest, recv_user_confirmation_request) {
uint32_t numeric_value = 0x0;
hci_layer_->IncomingEvent(hci::UserConfirmationRequestBuilder::Create(device_.GetAddress(), numeric_value));
synchronize();
ASSERT_TRUE(callback_->receivedUserConfirmationRequest);
}
TEST_F(SecurityManagerChannelTest, send_user_confirmation_request_reply) {
// Arrange
auto packet = hci::UserConfirmationRequestReplyBuilder::Create(device_.GetAddress());
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_user_confirmation_request_negative_reply) {
// Arrange
auto packet = hci::UserConfirmationRequestNegativeReplyBuilder::Create(device_.GetAddress());
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, recv_remote_oob_data_request) {
hci_layer_->IncomingEvent(hci::RemoteOobDataRequestBuilder::Create(device_.GetAddress()));
synchronize();
ASSERT_TRUE(callback_->receivedRemoteOobDataRequest);
}
TEST_F(SecurityManagerChannelTest, send_remote_oob_data_request_reply) {
// Arrange
std::array<uint8_t, 16> c = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
std::array<uint8_t, 16> r = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
auto packet = hci::RemoteOobDataRequestReplyBuilder::Create(device_.GetAddress(), c, r);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::REMOTE_OOB_DATA_REQUEST_REPLY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_remote_oob_data_request_neg_reply) {
// Arrange
auto packet = hci::RemoteOobDataRequestNegativeReplyBuilder::Create(device_.GetAddress());
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_read_local_oob_data) {
// Arrange
auto packet = hci::ReadLocalOobDataBuilder::Create();
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::READ_LOCAL_OOB_DATA, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_read_local_oob_extended_data) {
// Arrange
auto packet = hci::ReadLocalOobExtendedDataBuilder::Create();
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::READ_LOCAL_OOB_EXTENDED_DATA, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, recv_link_key_request) {
hci_layer_->IncomingEvent(hci::LinkKeyRequestBuilder::Create(device_.GetAddress()));
synchronize();
ASSERT_TRUE(callback_->receivedLinkKeyRequest);
}
TEST_F(SecurityManagerChannelTest, recv_link_key_notification) {
std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
hci_layer_->IncomingEvent(
hci::LinkKeyNotificationBuilder::Create(device_.GetAddress(), link_key, hci::KeyType::DEBUG_COMBINATION));
synchronize();
ASSERT_TRUE(callback_->receivedLinkKeyNotification);
}
TEST_F(SecurityManagerChannelTest, recv_central_link_key_complete) {
uint16_t connection_handle = 0x0;
hci_layer_->IncomingEvent(
hci::CentralLinkKeyCompleteBuilder::Create(hci::ErrorCode::SUCCESS, connection_handle, hci::KeyFlag::TEMPORARY));
synchronize();
ASSERT_TRUE(callback_->receivedCentralLinkKeyComplete);
}
TEST_F(SecurityManagerChannelTest, recv_change_connection_link_key_complete) {
uint16_t connection_handle = 0x0;
hci_layer_->IncomingEvent(
hci::ChangeConnectionLinkKeyCompleteBuilder::Create(hci::ErrorCode::SUCCESS, connection_handle));
synchronize();
ASSERT_TRUE(callback_->receivedChangeConnectionLinkKeyComplete);
}
TEST_F(SecurityManagerChannelTest, recv_return_link_keys) {
std::vector<hci::ZeroKeyAndAddress> keys;
hci_layer_->IncomingEvent(hci::ReturnLinkKeysBuilder::Create(keys));
synchronize();
ASSERT_TRUE(callback_->receivedReturnLinkKeys);
}
TEST_F(SecurityManagerChannelTest, send_link_key_request_reply) {
// Arrange
std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
auto packet = hci::LinkKeyRequestReplyBuilder::Create(device_.GetAddress(), link_key);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::LINK_KEY_REQUEST_REPLY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_link_key_request_neg_reply) {
// Arrange
auto packet = hci::LinkKeyRequestNegativeReplyBuilder::Create(device_.GetAddress());
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_read_stored_link_key) {
// Arrange
auto packet = hci::ReadStoredLinkKeyBuilder::Create(device_.GetAddress(), hci::ReadStoredLinkKeyReadAllFlag::ALL);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::READ_STORED_LINK_KEY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_write_stored_link_key) {
// Arrange
std::vector<hci::KeyAndAddress> keys_to_write;
auto packet = hci::WriteStoredLinkKeyBuilder::Create(keys_to_write);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::WRITE_STORED_LINK_KEY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_delete_stored_link_key) {
// Arrange
auto packet =
hci::DeleteStoredLinkKeyBuilder::Create(device_.GetAddress(), hci::DeleteStoredLinkKeyDeleteAllFlag::ALL);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::DELETE_STORED_LINK_KEY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, recv_encryption_change) {
uint16_t connection_handle = 0x0;
hci_layer_->IncomingEvent(
hci::EncryptionChangeBuilder::Create(hci::ErrorCode::SUCCESS, connection_handle, hci::EncryptionEnabled::ON));
synchronize();
ASSERT_TRUE(callback_->receivedEncryptionChange);
}
TEST_F(SecurityManagerChannelTest, recv_encryption_key_refresh) {
uint16_t connection_handle = 0x0;
hci_layer_->IncomingEvent(
hci::EncryptionKeyRefreshCompleteBuilder::Create(hci::ErrorCode::SUCCESS, connection_handle));
synchronize();
ASSERT_TRUE(callback_->receivedEncryptionKeyRefreshComplete);
}
TEST_F(SecurityManagerChannelTest, send_refresh_encryption_key) {
// Arrange
uint16_t connection_handle = 0x0;
auto packet = hci::RefreshEncryptionKeyBuilder::Create(connection_handle);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::REFRESH_ENCRYPTION_KEY, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_read_encryption_key_size) {
// Arrange
uint16_t connection_handle = 0x0;
auto packet = hci::ReadEncryptionKeySizeBuilder::Create(connection_handle);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::READ_ENCRYPTION_KEY_SIZE, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, recv_simple_pairing_complete) {
hci_layer_->IncomingEvent(hci::SimplePairingCompleteBuilder::Create(hci::ErrorCode::SUCCESS, device_.GetAddress()));
synchronize();
ASSERT_TRUE(callback_->receivedSimplePairingComplete);
}
TEST_F(SecurityManagerChannelTest, send_read_simple_pairing_mode) {
// Arrange
auto packet = hci::ReadSimplePairingModeBuilder::Create();
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::READ_SIMPLE_PAIRING_MODE, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, send_write_simple_pairing_mode) {
// Arrange
auto packet = hci::WriteSimplePairingModeBuilder::Create(hci::Enable::ENABLED);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::WRITE_SIMPLE_PAIRING_MODE, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, recv_keypress_notification) {
hci_layer_->IncomingEvent(
hci::KeypressNotificationBuilder::Create(device_.GetAddress(), hci::KeypressNotificationType::ENTRY_COMPLETED));
synchronize();
ASSERT_TRUE(callback_->receivedKeypressNotification);
}
TEST_F(SecurityManagerChannelTest, send_keypress_notification) {
// Arrange
auto packet =
hci::SendKeypressNotificationBuilder::Create(device_.GetAddress(), hci::KeypressNotificationType::ENTRY_STARTED);
// Act
channel_->SendCommand(std::move(packet));
auto last_command = std::move(hci_layer_->GetLastCommand()->command);
auto command_packet = GetPacketView(std::move(last_command));
hci::CommandView packet_view = hci::CommandView::Create(command_packet);
// Assert
ASSERT_TRUE(packet_view.IsValid());
ASSERT_EQ(OpCode::SEND_KEYPRESS_NOTIFICATION, packet_view.GetOpCode());
}
TEST_F(SecurityManagerChannelTest, recv_user_passkey_request) {
hci_layer_->IncomingEvent(hci::UserPasskeyRequestBuilder::Create(device_.GetAddress()));
synchronize();
ASSERT_TRUE(callback_->receivedUserPasskeyRequest);
}
TEST_F(SecurityManagerChannelTest, test_l2cap_security_interface_api) {
ASSERT_FALSE(on_link_connected_called);
channel_->Connect(device_.GetAddress());
ASSERT_TRUE(on_link_connected_called);
ASSERT_FALSE(on_link_disconnected_called);
channel_->Release(device_.GetAddress());
// TODO(optedoblivion): Lock and wait
// ASSERT_TRUE(on_link_disconnected_called);
}
} // namespace
} // namespace channel
} // namespace security
} // namespace bluetooth