"android.hardware.bluetooth-async",
"android.hardware.bluetooth-hci",
"libbt-rootcanal",
- "libbluetooth-types",
+ "libbt-rootcanal-types",
],
include_dirs: [
"system/bt",
"-DHAS_NO_BDROID_BUILDCFG",
],
static_libs: [
- "libbluetooth-types",
"android.hardware.bluetooth-async",
"android.hardware.bluetooth-hci",
"libbt-rootcanal",
+ "libbt-rootcanal-types",
],
include_dirs: [
"system/bt",
#include <base/logging.h>
#include <cutils/properties.h>
+#include <netdb.h>
+#include <netinet/in.h>
#include <string.h>
#include <utils/Log.h>
-#include "acl_packet.h"
-#include "event_packet.h"
#include "hci_internals.h"
-#include "sco_packet.h"
namespace android {
namespace hardware {
namespace sim {
using android::hardware::hidl_vec;
-using test_vendor_lib::AclPacket;
-using test_vendor_lib::AsyncManager;
using test_vendor_lib::AsyncTaskId;
-using test_vendor_lib::CommandPacket;
using test_vendor_lib::DualModeController;
-using test_vendor_lib::EventPacket;
-using test_vendor_lib::ScoPacket;
using test_vendor_lib::TaskCallback;
-using test_vendor_lib::TestChannelTransport;
namespace {
public:
BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
- virtual void serviceDied(
- uint64_t /* cookie */,
- const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
+ virtual void serviceDied(uint64_t /* cookie */, const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
has_died_ = true;
mHci->close();
}
sp<IBluetoothHci> mHci;
- bool getHasDied() const { return has_died_; }
- void setHasDied(bool has_died) { has_died_ = has_died; }
+ bool getHasDied() const {
+ return has_died_;
+ }
+ void setHasDied(bool has_died) {
+ has_died_ = has_died;
+ }
private:
bool has_died_;
};
-BluetoothHci::BluetoothHci()
- : death_recipient_(new BluetoothDeathRecipient(this)) {}
+BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {}
Return<void> BluetoothHci::initialize(const sp<IBluetoothHciCallbacks>& cb) {
ALOGI("%s", __func__);
death_recipient_->setHasDied(false);
cb->linkToDeath(death_recipient_, 0);
- test_channel_transport_.RegisterCommandHandler(
- [this](const std::string& name, const std::vector<std::string>& args) {
- async_manager_.ExecAsync(
- std::chrono::milliseconds(0), [this, name, args]() {
- controller_.HandleTestChannelCommand(name, args);
- });
- });
+ test_channel_transport_.RegisterCommandHandler([this](const std::string& name, const std::vector<std::string>& args) {
+ async_manager_.ExecAsync(std::chrono::milliseconds(0),
+ [this, name, args]() { test_channel_.HandleCommand(name, args); });
+ });
- controller_.RegisterEventChannel([cb](std::unique_ptr<EventPacket> event) {
- size_t header_bytes = event->GetHeaderSize();
- size_t payload_bytes = event->GetPayloadSize();
- hidl_vec<uint8_t> hci_event;
- hci_event.resize(header_bytes + payload_bytes);
- memcpy(hci_event.data(), event->GetHeader().data(), header_bytes);
- memcpy(hci_event.data() + header_bytes, event->GetPayload().data(),
- payload_bytes);
+ controller_ = std::make_shared<DualModeController>();
+ controller_->Initialize({"dmc", "3C:5A:B4:01:02:03"});
+
+ controller_->RegisterEventChannel([cb](std::shared_ptr<std::vector<uint8_t>> packet) {
+ hidl_vec<uint8_t> hci_event(packet->begin(), packet->end());
cb->hciEventReceived(hci_event);
});
- controller_.RegisterAclChannel([cb](std::unique_ptr<AclPacket> packet) {
- std::vector<uint8_t> acl_vector = packet->GetPacket();
- hidl_vec<uint8_t> acl_packet = acl_vector;
-
+ controller_->RegisterAclChannel([cb](std::shared_ptr<std::vector<uint8_t>> packet) {
+ hidl_vec<uint8_t> acl_packet(packet->begin(), packet->end());
cb->aclDataReceived(acl_packet);
});
- controller_.RegisterScoChannel([cb](std::unique_ptr<ScoPacket> packet) {
- size_t header_bytes = packet->GetHeaderSize();
- size_t payload_bytes = packet->GetPayloadSize();
- hidl_vec<uint8_t> sco_packet;
- sco_packet.resize(header_bytes + payload_bytes);
- memcpy(sco_packet.data(), packet->GetHeader().data(), header_bytes);
- memcpy(sco_packet.data() + header_bytes, packet->GetPayload().data(),
- payload_bytes);
-
- cb->scoDataReceived(sco_packet);
+ controller_->RegisterScoChannel([cb](std::shared_ptr<std::vector<uint8_t>> packet) {
+ hidl_vec<uint8_t> sco_packet(packet->begin(), packet->end());
+ cb->aclDataReceived(sco_packet);
});
- controller_.RegisterTaskScheduler(
- [this](std::chrono::milliseconds delay, const TaskCallback& task) {
- return async_manager_.ExecAsync(delay, task);
- });
+ controller_->RegisterTaskScheduler([this](std::chrono::milliseconds delay, const TaskCallback& task) {
+ return async_manager_.ExecAsync(delay, task);
+ });
- controller_.RegisterPeriodicTaskScheduler(
- [this](std::chrono::milliseconds delay, std::chrono::milliseconds period,
- const TaskCallback& task) {
+ controller_->RegisterPeriodicTaskScheduler(
+ [this](std::chrono::milliseconds delay, std::chrono::milliseconds period, const TaskCallback& task) {
return async_manager_.ExecAsyncPeriodically(delay, period, task);
});
- controller_.RegisterTaskCancel(
- [this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); });
+ controller_->RegisterTaskCancel([this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); });
+
+ test_model_.Reset();
+ // Add the controller as a device in the model.
+ test_model_.Add(controller_);
if (BtTestConsoleEnabled()) {
SetUpTestChannel(6111);
}
+ SetUpHciServer(6211, [this](int fd) { test_model_.IncomingHciConnection(fd); });
+ SetUpLinkLayerServer(6311, [this](int fd) { test_model_.IncomingLinkLayerConnection(fd); });
unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
if (death_recipient->getHasDied())
Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
- uint16_t opcode = packet[0] | (packet[1] << 8);
- std::unique_ptr<CommandPacket> command =
- std::unique_ptr<CommandPacket>(new CommandPacket(opcode));
- for (size_t i = 3; i < packet.size(); i++)
- command->AddPayloadOctets1(packet[i]);
-
- controller_.HandleCommand(std::move(command));
+ std::shared_ptr<std::vector<uint8_t>> packet_copy =
+ std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
+ controller_->HandleCommand(packet_copy);
});
return Void();
}
Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
- uint16_t channel = (packet[0] | (packet[1] << 8)) & 0xfff;
- AclPacket::PacketBoundaryFlags boundary_flags =
- static_cast<AclPacket::PacketBoundaryFlags>((packet[1] & 0x30) >> 4);
- AclPacket::BroadcastFlags broadcast_flags =
- static_cast<AclPacket::BroadcastFlags>((packet[1] & 0xC0) >> 6);
-
- std::unique_ptr<AclPacket> acl = std::unique_ptr<AclPacket>(
- new AclPacket(channel, boundary_flags, broadcast_flags));
- for (size_t i = 4; i < packet.size(); i++)
- acl->AddPayloadOctets1(packet[i]);
-
- controller_.HandleAcl(std::move(acl));
+ std::shared_ptr<std::vector<uint8_t>> packet_copy =
+ std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
+ controller_->HandleAcl(packet_copy);
});
return Void();
}
Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
- uint16_t channel = (packet[0] | (packet[1] << 8)) & 0xfff;
- ScoPacket::PacketStatusFlags packet_status =
- static_cast<ScoPacket::PacketStatusFlags>((packet[1] & 0x30) >> 4);
- std::unique_ptr<ScoPacket> sco =
- std::unique_ptr<ScoPacket>(new ScoPacket(channel, packet_status));
- for (size_t i = 3; i < packet.size(); i++)
- sco->AddPayloadOctets1(packet[i]);
-
- controller_.HandleSco(std::move(sco));
+ std::shared_ptr<std::vector<uint8_t>> packet_copy =
+ std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
+ controller_->HandleSco(packet_copy);
});
return Void();
}
+void BluetoothHci::SetUpHciServer(int port, const std::function<void(int)>& connection_callback) {
+ int socket_fd = remote_hci_transport_.SetUp(port);
+
+ test_channel_.RegisterSendResponse(
+ [](const std::string& response) { ALOGI("No HCI Response channel: %s", response.c_str()); });
+
+ if (socket_fd == -1) {
+ ALOGE("Remote HCI channel SetUp(%d) failed.", port);
+ return;
+ }
+
+ async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) {
+ int conn_fd = remote_hci_transport_.Accept(socket_fd);
+ if (conn_fd < 0) {
+ ALOGE("Error watching remote HCI channel fd.");
+ return;
+ }
+ int flags = fcntl(conn_fd, F_GETFL, NULL);
+ int ret;
+ ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK);
+ CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno);
+
+ connection_callback(conn_fd);
+ });
+}
+
+void BluetoothHci::SetUpLinkLayerServer(int port, const std::function<void(int)>& connection_callback) {
+ int socket_fd = remote_link_layer_transport_.SetUp(port);
+
+ test_channel_.RegisterSendResponse(
+ [](const std::string& response) { ALOGI("No LinkLayer Response channel: %s", response.c_str()); });
+
+ if (socket_fd == -1) {
+ ALOGE("Remote LinkLayer channel SetUp(%d) failed.", port);
+ return;
+ }
+
+ async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) {
+ int conn_fd = remote_link_layer_transport_.Accept(socket_fd);
+ if (conn_fd < 0) {
+ ALOGE("Error watching remote LinkLayer channel fd.");
+ return;
+ }
+ int flags = fcntl(conn_fd, F_GETFL, NULL);
+ int ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK);
+ CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno);
+
+ connection_callback(conn_fd);
+ });
+}
+
+int BluetoothHci::ConnectToRemoteServer(const std::string& server, int port) {
+ int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (socket_fd < 1) {
+ ALOGI("socket() call failed: %s", strerror(errno));
+ return -1;
+ }
+
+ struct hostent* host;
+ host = gethostbyname(server.c_str());
+ if (host == NULL) {
+ ALOGI("gethostbyname() failed for %s: %s", server.c_str(), strerror(errno));
+ return -1;
+ }
+
+ struct sockaddr_in serv_addr;
+ memset((void*)&serv_addr, 0, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = INADDR_ANY;
+ serv_addr.sin_port = htons(port);
+
+ int result = connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
+ if (result < 0) {
+ ALOGI("connect() failed for %s@%d: %s", server.c_str(), port, strerror(errno));
+ return -1;
+ }
+
+ int flags = fcntl(socket_fd, F_GETFL, NULL);
+ int ret = fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK);
+ CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno);
+
+ return socket_fd;
+}
+
void BluetoothHci::SetUpTestChannel(int port) {
int socket_fd = test_channel_transport_.SetUp(port);
+ test_channel_.RegisterSendResponse(
+ [](const std::string& response) { ALOGI("No test channel: %s", response.c_str()); });
+
+ // Add some default devices for easier debugging
+ test_channel_.AddDefaults();
+
if (socket_fd == -1) {
ALOGE("Test channel SetUp(%d) failed.", port);
return;
return;
}
ALOGI("Test channel connection accepted.");
+ test_channel_.RegisterSendResponse(
+ [this, conn_fd](const std::string& response) { test_channel_transport_.SendResponse(conn_fd, response); });
+
async_manager_.WatchFdForNonBlockingReads(conn_fd, [this](int conn_fd) {
- test_channel_transport_.OnCommandReady(conn_fd, [this, conn_fd]() {
- async_manager_.StopWatchingFileDescriptor(conn_fd);
- });
+ test_channel_transport_.OnCommandReady(conn_fd,
+ [this, conn_fd]() { async_manager_.StopWatchingFileDescriptor(conn_fd); });
});
});
}
return new BluetoothHci();
}
-} // namespace gce
+} // namespace sim
} // namespace V1_0
} // namespace bluetooth
} // namespace hardware
#include "hci_packetizer.h"
-#include "async_manager.h"
-#include "dual_mode_controller.h"
-#include "test_channel_transport.h"
+#include "model/controller/dual_mode_controller.h"
+#include "model/setup/async_manager.h"
+#include "model/setup/test_channel_transport.h"
+#include "model/setup/test_command_handler.h"
+#include "model/setup/test_model.h"
namespace android {
namespace hardware {
public:
BluetoothHci();
- ::android::hardware::Return<void> initialize(
- const sp<IBluetoothHciCallbacks>& cb) override;
+ ::android::hardware::Return<void> initialize(const sp<IBluetoothHciCallbacks>& cb) override;
- ::android::hardware::Return<void> sendHciCommand(
- const ::android::hardware::hidl_vec<uint8_t>& packet) override;
+ ::android::hardware::Return<void> sendHciCommand(const ::android::hardware::hidl_vec<uint8_t>& packet) override;
- ::android::hardware::Return<void> sendAclData(
- const ::android::hardware::hidl_vec<uint8_t>& packet) override;
+ ::android::hardware::Return<void> sendAclData(const ::android::hardware::hidl_vec<uint8_t>& packet) override;
- ::android::hardware::Return<void> sendScoData(
- const ::android::hardware::hidl_vec<uint8_t>& packet) override;
+ ::android::hardware::Return<void> sendScoData(const ::android::hardware::hidl_vec<uint8_t>& packet) override;
::android::hardware::Return<void> close() override;
test_vendor_lib::AsyncManager async_manager_;
void SetUpTestChannel(int port);
+ void SetUpHciServer(int port, const std::function<void(int)>& on_connect);
+ void SetUpLinkLayerServer(int port, const std::function<void(int)>& on_connect);
+ int ConnectToRemoteServer(const std::string& server, int port);
- test_vendor_lib::DualModeController controller_;
+ std::shared_ptr<test_vendor_lib::DualModeController> controller_;
test_vendor_lib::TestChannelTransport test_channel_transport_;
+ test_vendor_lib::TestChannelTransport remote_hci_transport_;
+ test_vendor_lib::TestChannelTransport remote_link_layer_transport_;
+
+ test_vendor_lib::TestModel test_model_{
+ [this](std::chrono::milliseconds delay, const test_vendor_lib::TaskCallback& task) {
+ return async_manager_.ExecAsync(delay, task);
+ },
+
+ [this](std::chrono::milliseconds delay, std::chrono::milliseconds period,
+ const test_vendor_lib::TaskCallback& task) {
+ return async_manager_.ExecAsyncPeriodically(delay, period, task);
+ },
+
+ [this](test_vendor_lib::AsyncTaskId task) { async_manager_.CancelAsyncTask(task); },
+
+ [this](const std::string& server, int port) { return ConnectToRemoteServer(server, port); }};
+
+ test_vendor_lib::TestCommandHandler test_channel_{test_model_};
};
extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
#include "bluetooth_hci.h"
+using ::android::sp;
using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
using ::android::hardware::bluetooth::V1_0::sim::BluetoothHci;
-using ::android::hardware::joinRpcThreadpool;
-using ::android::sp;
int main(int /* argc */, char** /* argv */) {
sp<IBluetoothHci> bluetooth = new BluetoothHci;
cc_library_static {
name: "libbt-rootcanal",
defaults: ["libchrome_support_defaults"],
+ host_supported: true,
proprietary: true,
srcs: [
- "src/acl_packet.cc",
- "src/async_manager.cc",
- "src/beacon.cc",
- "src/beacon_swarm.cc",
- "src/broken_adv.cc",
- "src/bt_address.cc",
- "src/classic.cc",
- "src/command_packet.cc",
- "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",
- "src/keyboard.cc",
- "src/l2cap_packet.cc",
- "src/l2cap_sdu.cc",
- "src/packet.cc",
- "src/packet_stream.cc",
- "src/sco_packet.cc",
- "src/test_channel_transport.cc",
+ "model/controller/acl_connection.cc",
+ "model/controller/acl_connection_handler.cc",
+ "model/controller/dual_mode_controller.cc",
+ "model/controller/link_layer_controller.cc",
+ "model/controller/security_manager.cc",
+ "model/devices/beacon.cc",
+ "model/devices/beacon_swarm.cc",
+ "model/devices/broken_adv.cc",
+ "model/devices/car_kit.cc",
+ "model/devices/classic.cc",
+ "model/devices/device.cc",
+ "model/devices/device_properties.cc",
+ "model/devices/h4_packetizer.cc",
+ "model/devices/h4_protocol.cc",
+ "model/devices/hci_packetizer.cc",
+ "model/devices/hci_protocol.cc",
+ "model/devices/hci_socket_device.cc",
+ "model/devices/keyboard.cc",
+ "model/devices/link_layer_socket_device.cc",
+ "model/devices/loopback.cc",
+ "model/devices/polled_socket.cc",
+ "model/devices/remote_loopback_device.cc",
+ "model/devices/sniffer.cc",
+ "model/setup/async_manager.cc",
+ "model/setup/device_boutique.cc",
+ "model/setup/phy_layer_factory.cc",
+ "model/setup/test_channel_transport.cc",
+ "model/setup/test_command_handler.cc",
+ "model/setup/test_model.cc",
],
cflags: [
"-fvisibility=hidden",
"libbase",
"liblog",
],
- static_libs: [
- "libbluetooth-types",
+ whole_static_libs: [
"libbt-rootcanal-packets",
],
+ static_libs: [
+ "libbt-rootcanal-types",
+ ],
}
// test-vendor unit tests for host
"clang_coverage_bin",
],
srcs: [
- "src/async_manager.cc",
- "src/bt_address.cc",
- "src/hci_packet.cc",
- "src/command_packet.cc",
- "src/event_packet.cc",
- "src/packet.cc",
- "src/packet_stream.cc",
- "src/l2cap_packet.cc",
- "src/l2cap_sdu.cc",
"test/async_manager_unittest.cc",
- "test/bt_address_unittest.cc",
- "test/packet_stream_unittest.cc",
- "test/iterator_test.cc",
- "test/l2cap_test.cc",
- "test/l2cap_sdu_test.cc",
+ "test/security_manager_unittest.cc",
+ "test/link_layer_socket_device_test.cc",
],
header_libs: [
"libbluetooth_headers",
"liblog",
],
static_libs: [
- "libbluetooth-types",
- "libbt-rootcanal-packets",
+ "libbt-rootcanal-types",
+ "libbt-rootcanal",
],
cflags: [
"-fvisibility=hidden",
--- /dev/null
+/*
+ * 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 <cstdint>
+
+namespace test_vendor_lib {
+namespace acl {
+
+// ACL data packets are specified in the Bluetooth Core Specification Version
+// 4.2, Volume 2, Part E, Section 5.4.2
+static constexpr uint16_t kReservedHandle = 0xF00;
+
+enum class PacketBoundaryFlagsType : uint8_t {
+ FIRST_NON_AUTOMATICALLY_FLUSHABLE = 0,
+ CONTINUING = 1,
+ FIRST_AUTOMATICALLY_FLUSHABLE = 2,
+ COMPLETE = 3
+};
+
+enum class BroadcastFlagsType : uint8_t {
+ POINT_TO_POINT = 0,
+ ACTIVE_SLAVE_BROADCAST = 1,
+ PARKED_SLAVE_BROADCAST = 2,
+ RESERVED = 3
+};
+} // namespace acl
+} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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 <cstdint>
-#include <string>
-#include <vector>
-
-namespace test_vendor_lib {
-
-// ACL data packets are specified in the Bluetooth Core Specification Version
-// 4.2, Volume 2, Part E, Section 5.4.2
-class AclPacket {
- public:
- typedef enum {
- FirstNonAutomaticallyFlushable,
- Continuing,
- FirstAutomaticallyFlushable,
- Complete
- } PacketBoundaryFlags;
- typedef enum {
- PointToPoint,
- ActiveSlaveBroadcast,
- ParkedSlaveBroadcast,
- Reserved
- } BroadcastFlags;
-
- virtual ~AclPacket() = default;
-
- uint16_t GetChannel() const {
- return (raw_packet_[0] | (raw_packet_[1] << 8)) & 0xfff;
- }
-
- PacketBoundaryFlags GetPacketBoundaryFlags() const {
- return static_cast<PacketBoundaryFlags>((raw_packet_[1] & 0x30) >> 4);
- }
-
- BroadcastFlags GetBroadcastFlags() const {
- return static_cast<BroadcastFlags>((raw_packet_[1] & 0xC0) >> 6);
- }
-
- explicit AclPacket(uint16_t channel,
- AclPacket::PacketBoundaryFlags boundary_flags,
- AclPacket::BroadcastFlags broadcast);
-
- size_t GetPacketSize() const;
-
- const std::vector<uint8_t>& GetPacket() const;
-
- void AddPayloadOctets(size_t octets, const std::vector<uint8_t>& bytes);
-
- private:
- // Add |octets| bytes to the payload.
- void AddPayloadOctets(size_t octets, uint64_t value);
-
- static const size_t kHeaderSize = 4;
-
- public:
- // Add type-checking versions
- void AddPayloadOctets1(uint8_t value) { AddPayloadOctets(1, value); }
- void AddPayloadOctets2(uint16_t value) { AddPayloadOctets(2, value); }
- void AddPayloadOctets3(uint32_t value) { AddPayloadOctets(3, value); }
- void AddPayloadOctets4(uint32_t value) { AddPayloadOctets(4, value); }
- void AddPayloadOctets6(uint64_t value) { AddPayloadOctets(6, value); }
- void AddPayloadOctets8(uint64_t value) { AddPayloadOctets(8, value); }
-
- private:
- std::vector<uint8_t> raw_packet_;
-};
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * Copyright 2016 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 <string>
-#include <vector>
-
-namespace test_vendor_lib {
-
-// Encapsulate handling for Bluetooth Addresses:
-// - store the address
-// - convert to/from strings and vectors of bytes
-// - check strings to see if they represent a valid address
-class BtAddress {
- public:
- // Conversion constants
- static const size_t kStringLength = 17; // "XX:XX:XX:XX:XX:XX"
- static const size_t kOctets = 6; // "X0:X1:X2:X3:X4:X5"
-
- BtAddress() : address_(0){};
- virtual ~BtAddress() = default;
-
- // Returns true if |addr| has the form "XX:XX:XX:XX:XX:XX":
- // - the length of |addr| is >= kStringLength
- // - every third character is ':'
- // - each remaining character is a hexadecimal digit
- static bool IsValid(const std::string& addr);
-
- inline bool operator==(const BtAddress& right) const {
- return address_ == right.address_;
- }
- inline bool operator!=(const BtAddress& right) const {
- return address_ != right.address_;
- }
- inline bool operator<(const BtAddress& right) const {
- return address_ < right.address_;
- }
- inline bool operator>(const BtAddress& right) const {
- return address_ > right.address_;
- }
- inline bool operator<=(const BtAddress& right) const {
- return address_ <= right.address_;
- }
- inline bool operator>=(const BtAddress& right) const {
- return address_ >= right.address_;
- }
-
- inline void operator=(const BtAddress& right) { address_ = right.address_; }
- inline void operator|=(const BtAddress& right) { address_ |= right.address_; }
- inline void operator&=(const BtAddress& right) { address_ &= right.address_; }
-
- // Set the address to the address represented by |str|.
- // returns true if |str| represents a valid address, otherwise false.
- bool FromString(const std::string& str);
-
- // Set the address to the address represented by |str|.
- // returns true if octets.size() >= kOctets, otherwise false.
- bool FromVector(const std::vector<uint8_t>& octets);
-
- // Appends the Bluetooth address to the vector |octets|.
- void ToVector(std::vector<uint8_t>& octets) const;
-
- // Return a string representation of the Bluetooth address, in this format:
- // "xx:xx:xx:xx:xx:xx", where x represents a lowercase hexadecimal digit.
- std::string ToString() const;
-
- private:
- // The Bluetooth Address is stored in the lower 48 bits of a 64-bit value
- uint64_t address_;
-};
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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 <vector>
-
-#include "base/macros.h"
-#include "packet.h"
-
-namespace test_vendor_lib {
-
-// The following is specified in the Bluetooth Core Specification Version 4.2,
-// Volume 2, Part E, Section 5.4.1 (page 470). Command Packets begin with a 3
-// octet header formatted as follows:
-// - Opcode: 2 octets
-// - Opcode Group Field (OGF): Upper bits 10-15
-// - Opcode Command Field (OCF): Lower bits 0-9
-// - Payload size (in octets): 1 octet
-// The header is followed by the payload, which contains command specific
-// parameters and has a maximum size of 255 octets. Valid command opcodes are
-// defined in stack/include/hcidefs.h. The OGF ranges from 0x00 to 0x3F, with
-// 0x3F reserved for vendor-specific debug functions. The OCF ranges from
-// 0x0000 to 0x03FF. Note that the payload size is the size in octets of the
-// command parameters and not the number of parameters. Finally, although the
-// parameters contained in the payload are command specific (including the size
-// and number of parameters), each parameter will be an integer number of octets
-// in size.
-class CommandPacket : public Packet {
- public:
- explicit CommandPacket(std::vector<uint8_t> header);
- explicit CommandPacket(uint16_t opcode);
- CommandPacket(std::vector<uint8_t> header, std::vector<uint8_t> payload);
-
- CommandPacket(const CommandPacket&) = default;
- CommandPacket& operator=(const CommandPacket&) = default;
- CommandPacket(CommandPacket&&) = default;
- CommandPacket& operator=(CommandPacket&&) = default;
- virtual ~CommandPacket() override = default;
-
- // Returns the command opcode as defined in stack/include/hcidefs.h.
- // See the Bluetooth Core Specification Version 4.2, Volume 2, Part E,
- // Section 7 for more information about each HCI commands and for a listing
- // of their specific opcodes/OGF and OCF values.
- uint16_t GetOpcode() const;
-
- // Returns the 6 bit opcode group field that specifies the general category of
- // the command. The OGF can be one of seven values:
- // - 0x01: Link control commands
- // - 0x02: Link policy commands
- // - 0x03: Controller and baseband commands
- // - 0x04: Informational parameters commands
- // - 0x05: Status parameters commands
- // - 0x06: Testing commands
- // - 0x08: Low energy controller commands
- // The upper 2 bits will be zero filled.
- uint8_t GetOGF() const;
-
- // Returns the 10 bit opcode command field that specifies an exact command
- // within an opcode group field. The upper 6 bits will be zero filled.
- uint16_t GetOCF() const;
-
- // Size of a command packet header, which consists of a 2 octet opcode
- static const size_t kCommandHeaderSize = 2;
-};
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * Copyright 2016 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 <queue>
-#include <string>
-#include <vector>
-
-#include "async_manager.h"
-#include "device.h"
-
-#include "hci/include/hci_hal.h"
-
-namespace test_vendor_lib {
-
-// Model the connection of a device to the controller.
-class Connection {
- public:
- Connection(std::shared_ptr<Device> dev, uint16_t handle)
- : dev_(dev), handle_(handle), connected_(true), encrypted_(false) {}
-
- virtual ~Connection() = default;
-
- // Return a string representing the connection for logging.
- const std::string ToString();
-
- // Return a pointer to the device in the connection.
- std::shared_ptr<Device> GetDevice() { return dev_; }
-
- // Return true if the handle matches and the device is connected.
- inline bool operator==(uint16_t handle) {
- return (handle_ == handle) && connected_;
- }
-
- // Return true if the handle doesn't match or the device is not connected.
- inline bool operator!=(uint16_t handle) {
- return (handle_ != handle) || !connected_;
- }
-
- void Disconnect() { connected_ = false; };
- bool Connected() { return connected_; };
-
- void Encrypt() { encrypted_ = true; };
- bool Encrypted() { return encrypted_; };
-
- // Add an action to the connection queue.
- void AddAction(const TaskCallback& task);
-
- // Execute the next action in the connection queue to simulate packet
- // exchange.
- void SendToDevice();
-
- // Add a message from the device.
- void AddMessage(const std::vector<uint8_t>& message);
-
- // Receive data from the device to simulate packet exchange.
- bool ReceiveFromDevice(std::vector<uint8_t>& data);
-
- private:
- // A shared pointer to the connected device
- std::shared_ptr<Device> dev_;
-
- // The connection handle
- uint16_t handle_;
-
- // State variables
- bool connected_;
- bool encrypted_;
-
- // Actions for the next packet exchange.
- std::queue<TaskCallback> actions_;
-
- // Messages from the device for the next packet exchange.
- std::queue<std::vector<uint8_t>> messages_;
-};
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * Copyright 2016 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 <chrono>
-#include <cstdint>
-#include <string>
-#include <vector>
-
-#include "bt_address.h"
-
-#include "hci/include/hci_hal.h"
-#include "stack/include/btm_ble_api.h"
-
-namespace test_vendor_lib {
-
-// Represent a Bluetooth Device
-// - Provide Get*() and Set*() functions for device attributes.
-class Device {
- public:
- Device() : time_stamp_(std::chrono::steady_clock::now()) {}
- virtual ~Device() = default;
-
- // Initialize the device based on the values of |args|.
- virtual void Initialize(const std::vector<std::string>& args) = 0;
-
- // Return a string representation of the type of device.
- virtual std::string GetTypeString() const = 0;
-
- // Return the string representation of the device.
- virtual std::string ToString() const;
-
- // Return a reference to the address.
- const BtAddress& GetBtAddress() const { return address_; }
-
- // Set the address to the |addr|.
- void SetBtAddress(const BtAddress& addr) { address_ = addr; }
-
- // Return the address type.
- uint8_t GetAddressType() const { return address_type_; }
-
- // Decide whether to accept a connection request
- // May need to be extended to check peer address & type, and other
- // connection parameters.
- // Return true if the device accepts the connection request.
- virtual bool LeConnect() { return false; }
-
- // Return the advertisement data.
- const std::vector<uint8_t>& GetAdvertisement() const { return adv_data_; }
-
- // Return the advertisement type.
- uint8_t GetAdvertisementType() const { return advertising_type_; }
-
- // Set the advertisement interval in milliseconds.
- void SetAdvertisementInterval(std::chrono::milliseconds ms) {
- advertising_interval_ms_ = ms;
- }
-
- // Return true if there is a scan response (allows for empty responses).
- bool HasScanResponse() const { return scan_response_present_; }
-
- // Return the scan response data.
- const std::vector<uint8_t>& GetScanResponse() const { return scan_data_; }
-
- // Returns true if the host could see an advertisement in the next
- // |scan_time| milliseconds.
- virtual bool IsAdvertisementAvailable(
- std::chrono::milliseconds scan_time) const;
-
- // Returns true if the host could see a page scan now.
- virtual bool IsPageScanAvailable() const;
-
- // Return the device class.
- // The device class is a 3-byte value. Look for DEV_CLASS in
- // stack/include/bt_types.h
- uint32_t GetDeviceClass() const { return device_class_; }
-
- // Return the clock offset, which is a defined in the Spec as:
- // (CLKN_16-2 slave - CLKN_16-2 master ) mod 2**15.
- // Bluetooth Core Specification Version 4.2, Volume 2, Part C, Section 4.3.2
- uint16_t GetClockOffset() const { return clock_offset_; }
-
- // Set the clock offset.
- void SetClockOffset(uint16_t offset) { clock_offset_ = offset; }
-
- // Return the page scan repetition mode.
- // Bluetooth Core Specification Version 4.2, Volume 2, Part B, Section 8.3.1
- // The values are:
- // 0 - R0 T_page_scan <= 1.28s and T_page_scan == T_window and
- // 1 - R1 T_page_scan <= 1.28s
- // 2 - R2 T_page_scan <= 2.56s
- uint8_t GetPageScanRepetitionMode() const {
- return page_scan_repetition_mode_;
- }
-
- // Return the extended inquiry data.
- const std::vector<uint8_t>& GetExtendedInquiryData() const {
- return extended_inquiry_data_;
- }
-
- // Let the device know that time has passed.
- virtual void TimerTick() {}
-
- protected:
- BtAddress address_;
-
- // Address type is defined in the spec:
- // 0x00 Public Device Address
- // 0x01 Random Device Address
- // 0x02 Public Identity Address
- // 0x03 Random (static) Identity Address
- // 0x04 – 0xFF Reserved for future use
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.12
- uint8_t address_type_;
-
- std::chrono::steady_clock::time_point time_stamp_;
-
- // Return the device class.
- // The device class is a 3-byte value. Look for DEV_CLASS in
- // stack/include/bt_types.h
- uint32_t device_class_;
-
- // Return the page scan repetition mode.
- // Bluetooth Core Specification Version 4.2, Volume 2, Part B, Section 8.3.1
- // The values are:
- // 0 - R0 T_page_scan <= 1.28s and T_page_scan == T_window and
- // 1 - R1 T_page_scan <= 1.28s
- // 2 - R2 T_page_scan <= 2.56s
- uint8_t page_scan_repetition_mode_;
-
- // The time between page scans.
- std::chrono::milliseconds page_scan_delay_ms_;
-
- std::vector<uint8_t> extended_inquiry_data_;
-
- // Classic Bluetooth CLKN_slave[16..2] - CLKN_master[16..2]
- // Bluetooth Core Specification Version 4.2, Volume 2, Part C, Section 4.3.2
- uint16_t clock_offset_;
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.5
- uint8_t advertising_type_;
-
- // The spec defines the advertising interval as a 16-bit value, but since it
- // is never sent in packets, we use std::chrono::milliseconds.
- std::chrono::milliseconds advertising_interval_ms_;
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.7
-
- // Bluetooth Core Specification Version 4.2, Volume 3, Part C, Section
- // 11.1
- // https://www.bluetooth.com/specifications/assigned-numbers
- // Supplement to Bluetooth Core Specification | CSSv6, Part A
- std::vector<uint8_t> adv_data_ = {0x07, // Length
- BTM_BLE_AD_TYPE_NAME_CMPL,
- 'd',
- 'e',
- 'v',
- 'i',
- 'c',
- 'e'};
-
- bool scan_response_present_ = true;
- std::vector<uint8_t> scan_data_ = {0x04, // Length
- BTM_BLE_AD_TYPE_NAME_SHORT, 'd', 'e', 'v'};
-
- public:
- static const uint8_t kBtAddressTypePublic = 0x00;
- static const uint8_t kBtAddressTypeRandom = 0x01;
- static const uint8_t kBtAddressTypePublicIdentity = 0x02;
- static const uint8_t kBtAddressTypeRandomIdentity = 0x03;
-};
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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/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"
-
-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 DualModeController {
- public:
- // Sets all of the methods to be used as callbacks in the HciHandler.
- DualModeController();
-
- ~DualModeController() = default;
-
- // Route commands and data from the stack.
- void HandleAcl(std::unique_ptr<AclPacket> acl_packet);
- void HandleCommand(std::unique_ptr<CommandPacket> command_packet);
- void HandleSco(std::unique_ptr<ScoPacket> sco_packet);
-
- // Dispatches the test channel action corresponding to the command specified
- // by |name|.
- void HandleTestChannelCommand(const std::string& name,
- const std::vector<std::string>& args);
-
- // Set the callbacks for scheduling tasks.
- void RegisterTaskScheduler(
- std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)>
- evtScheduler);
-
- void RegisterPeriodicTaskScheduler(
- std::function<AsyncTaskId(std::chrono::milliseconds,
- std::chrono::milliseconds, const TaskCallback&)>
- periodicEvtScheduler);
-
- void RegisterTaskCancel(std::function<void(AsyncTaskId)> cancel);
-
- // Set the callbacks for sending packets to the HCI.
- void RegisterEventChannel(
- const std::function<void(std::unique_ptr<EventPacket>)>& send_event);
-
- void RegisterAclChannel(
- const std::function<void(std::unique_ptr<AclPacket>)>& send_acl);
-
- void RegisterScoChannel(
- const std::function<void(std::unique_ptr<ScoPacket>)>& send_sco);
-
- // Controller commands. For error codes, see the Bluetooth Core Specification,
- // Version 4.2, Volume 2, Part D (page 370).
-
- // OGF: 0x0003
- // OCF: 0x0003
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.2
- void HciReset(const std::vector<uint8_t>& args);
-
- // OGF: 0x0004
- // OGF: 0x0005
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.5
- void HciReadBufferSize(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0033
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.39
- void HciHostBufferSize(const std::vector<uint8_t>& args);
-
- // OGF: 0x0004
- // OCF: 0x0001
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.1
- void HciReadLocalVersionInformation(const std::vector<uint8_t>& args);
-
- // OGF: 0x0004
- // OCF: 0x0009
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.6
- void HciReadBdAddr(const std::vector<uint8_t>& args);
-
- // OGF: 0x0004
- // OCF: 0x0002
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.2
- void HciReadLocalSupportedCommands(const std::vector<uint8_t>& args);
-
- // OGF: 0x0004
- // OCF: 0x0004
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.4
- void HciReadLocalExtendedFeatures(const std::vector<uint8_t>& args);
-
- // OGF: 0x0004
- // OCF: 0x000B
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4.8
- void HciReadLocalSupportedCodecs(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0056
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.59
- void HciWriteSimplePairingMode(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x006D
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.79
- void HciWriteLeHostSupport(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0001
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.1
- void HciSetEventMask(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0045
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.50
- void HciWriteInquiryMode(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0047
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.52
- void HciWritePageScanType(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0043
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.48
- void HciWriteInquiryScanType(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0024
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.26
- void HciWriteClassOfDevice(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0018
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.16
- void HciWritePageTimeout(const std::vector<uint8_t>& args);
-
- // OGF: 0x0002
- // OCF: 0x000F
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.2.12
- void HciWriteDefaultLinkPolicySettings(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0014
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.12
- void HciReadLocalName(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0013
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.11
- void HciWriteLocalName(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0052
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.56
- void HciWriteExtendedInquiryResponse(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0026
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.28
- void HciWriteVoiceSetting(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x003A
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.45
- void HciWriteCurrentIacLap(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x001E
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.22
- void HciWriteInquiryScanActivity(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x001A
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.18
- void HciWriteScanEnable(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0005
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.3
- void HciSetEventFilter(const std::vector<uint8_t>& args);
-
- // OGF: 0x0001
- // OCF: 0x0001
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1.1
- void HciInquiry(const std::vector<uint8_t>& args);
-
- void InquiryTimeout();
-
- // OGF: 0x0001
- // OCF: 0x0002
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1.2
- void HciInquiryCancel(const std::vector<uint8_t>& args);
-
- // OGF: 0x0003
- // OCF: 0x0012
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3.10
- void HciDeleteStoredLinkKey(const std::vector<uint8_t>& args);
-
- // OGF: 0x0001
- // OCF: 0x0019
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1.19
- void HciRemoteNameRequest(const std::vector<uint8_t>& args);
-
- // Test Commands
-
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.7.1
- void HciReadLoopbackMode(const std::vector<uint8_t>& args);
-
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.7.2
- void HciWriteLoopbackMode(const std::vector<uint8_t>& args);
-
- // LE Controller Commands
-
- // OGF: 0x0008
- // OCF: 0x0001
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.1
- void HciLeSetEventMask(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x0002
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.2
- void HciLeReadBufferSize(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x0003
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.3
- void HciLeReadLocalSupportedFeatures(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x0005
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.4
- void HciLeSetRandomAddress(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x0006
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.5
- void HciLeSetAdvertisingParameters(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x0008
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.7
- void HciLeSetAdvertisingData(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x000B
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.10
- void HciLeSetScanParameters(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x000C
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.11
- void HciLeSetScanEnable(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x000D
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.12
- void HciLeCreateConnection(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x000E
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.13
- void HciLeConnectionCancel(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x000F
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.14
- void HciLeReadWhiteListSize(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x0016
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.21
- void HciLeReadRemoteUsedFeatures(const std::vector<uint8_t>& args);
- void HciLeReadRemoteUsedFeaturesB(uint16_t handle);
-
- // OGF: 0x0008
- // OCF: 0x0018
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.23
- void HciLeRand(const std::vector<uint8_t>& args);
-
- // OGF: 0x0008
- // OCF: 0x001C
- // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8.27
- void HciLeReadSupportedStates(const std::vector<uint8_t>& args);
-
- // Vendor-specific commands (see hcidefs.h)
-
- // OGF: 0x00FC
- // OCF: 0x0027
- void HciBleVendorSleepMode(const std::vector<uint8_t>& args);
-
- // OGF: 0x00FC
- // OCF: 0x0153
- void HciBleVendorCap(const std::vector<uint8_t>& args);
-
- // OGF: 0x00FC
- // OCF: 0x0154
- void HciBleVendorMultiAdv(const std::vector<uint8_t>& args);
-
- // OGF: 0x00FC
- // OCF: 0x0155
- void HciBleVendor155(const std::vector<uint8_t>& args);
-
- // OGF: 0x00FC
- // OCF: 0x0157
- void HciBleVendor157(const std::vector<uint8_t>& args);
-
- // OGF: 0x00FC
- // OCF: 0x0159
- void HciBleEnergyInfo(const std::vector<uint8_t>& args);
-
- // Test
- void HciBleAdvertisingFilter(const std::vector<uint8_t>& args);
-
- // OGF: 0x00FC
- // OCF: 0x015A
- void HciBleExtendedScanParams(const std::vector<uint8_t>& args);
-
- // Test Channel commands:
-
- // Add devices
- void TestChannelAdd(const std::vector<std::string>& args);
-
- // Remove devices by index
- void TestChannelDel(const std::vector<std::string>& args);
-
- // List the devices that the controller knows about
- void TestChannelList(const std::vector<std::string>& args) const;
-
- void Connections();
-
- void LeScan();
-
- void PageScan();
-
- void HandleTimerTick();
- void SetTimerPeriod(std::chrono::milliseconds new_period);
- void StartTimer();
- void StopTimer();
-
- private:
- // Current link layer state of the controller.
- enum State {
- kStandby, // Not receiving/transmitting any packets from/to other devices.
- kInquiry, // The controller is discovering other nearby devices.
- };
-
- // Set a timer for a future action
- void AddControllerEvent(std::chrono::milliseconds,
- const TaskCallback& callback);
-
- void AddConnectionAction(const TaskCallback& callback, uint16_t handle);
-
- // Creates a command complete event and sends it back to the HCI.
- void SendCommandComplete(uint16_t command_opcode,
- const std::vector<uint8_t>& return_parameters) const;
-
- // Sends a command complete event with no return parameters. This event is
- // typically sent for commands that can be completed immediately.
- void SendCommandCompleteSuccess(uint16_t command_opcode) const;
-
- // Sends a command complete event with no return parameters. This event is
- // typically sent for commands that can be completed immediately.
- void SendCommandCompleteOnlyStatus(uint16_t command_opcode,
- uint8_t status) const;
-
- // Creates a command status event and sends it back to the HCI.
- void SendCommandStatus(uint8_t status, uint16_t command_opcode) const;
-
- // Sends a command status event with default event parameters.
- void SendCommandStatusSuccess(uint16_t command_opcode) const;
-
- void SetEventDelay(int64_t delay);
-
- // 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::unique_ptr<AclPacket>)> send_acl_;
- std::function<void(std::unique_ptr<EventPacket>)> send_event_;
- std::function<void(std::unique_ptr<ScoPacket>)> send_sco_;
-
- // Maintains the commands to be registered and used in the HciHandler object.
- // Keys are command opcodes and values are the callbacks to handle each
- // command.
- std::unordered_map<uint16_t, std::function<void(const std::vector<uint8_t>&)>>
- active_hci_commands_;
-
- std::unordered_map<std::string,
- std::function<void(const std::vector<std::string>&)>>
- active_test_channel_commands_;
-
- // Specifies the format of Inquiry Result events to be returned during the
- // Inquiry command.
- // 0x00: Standard Inquiry Result event format (default).
- // 0x01: Inquiry Result format with RSSI.
- // 0x02 Inquiry Result with RSSI format or Extended Inquiry Result format.
- // 0x03-0xFF: Reserved.
- uint8_t inquiry_mode_;
-
- bool inquiry_responses_limited_;
- uint8_t inquiry_num_responses_;
- uint8_t inquiry_lap_[3];
-
- std::vector<uint8_t> le_event_mask_;
-
- BtAddress le_random_address_;
-
- uint8_t le_scan_type_;
- uint16_t le_scan_interval_;
- uint16_t le_scan_window_;
- uint8_t own_address_type_;
- uint8_t scanning_filter_policy_;
-
- uint8_t le_scan_enable_;
- uint8_t filter_duplicates_;
-
- bool le_connect_;
- uint8_t initiator_filter_policy_;
-
- BtAddress peer_address_;
- uint8_t peer_address_type_;
-
- uint8_t loopback_mode_;
-
- State state_;
-
- DeviceProperties properties_;
-
- std::vector<std::shared_ptr<Device>> devices_;
-
- std::vector<AsyncTaskId> controller_events_;
-
- std::vector<std::shared_ptr<Connection>> connections_;
-
- AsyncTaskId timer_tick_task_;
- std::chrono::milliseconds timer_period_ = std::chrono::milliseconds(100);
-
- DualModeController(const DualModeController& cmdPckt) = delete;
- DualModeController& operator=(const DualModeController& cmdPckt) = delete;
-};
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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 <vector>
-
-#include "base/logging.h"
-#include "bt_address.h"
-#include "packet.h"
-
-namespace test_vendor_lib {
-
-// Event Packets are specified in the Bluetooth Core Specification Version 4.2,
-// Volume 2, Part E, Section 5.4.4
-class EventPacket : public Packet {
- public:
- virtual ~EventPacket() override = default;
-
- uint8_t GetEventCode() const;
-
- // Static functions for creating event packets:
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.1
- static std::unique_ptr<EventPacket> CreateInquiryCompleteEvent(
- uint8_t status);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.14
- // This should only be used for testing to send non-standard packets
- // Most code should use the more specific functions that follow
- static std::unique_ptr<EventPacket> CreateCommandCompleteEvent(
- uint16_t command_opcode,
- const std::vector<uint8_t>& event_return_parameters);
-
- static std::unique_ptr<EventPacket> CreateCommandCompleteOnlyStatusEvent(
- uint16_t command_opcode, uint8_t status);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.15
- static std::unique_ptr<EventPacket> CreateCommandStatusEvent(
- uint8_t status, uint16_t command_opcode);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.19
- static std::unique_ptr<EventPacket> CreateNumberOfCompletedPacketsEvent(
- uint16_t handle, uint16_t num_completed_packets);
-
- void AddCompletedPackets(uint16_t handle, uint16_t num_completed_packets);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.10
- static std::unique_ptr<EventPacket> CreateCommandCompleteDeleteStoredLinkKey(
- uint8_t status, uint16_t num_keys_deleted);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.12
- static std::unique_ptr<EventPacket> CreateCommandCompleteReadLocalName(
- uint8_t status, const std::string& local_name);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.1
- static std::unique_ptr<EventPacket>
- CreateCommandCompleteReadLocalVersionInformation(uint8_t status,
- uint8_t hci_version,
- uint16_t hci_revision,
- uint8_t lmp_pal_version,
- uint16_t manufacturer_name,
- uint16_t lmp_pal_subversion);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.2
- static std::unique_ptr<EventPacket>
- CreateCommandCompleteReadLocalSupportedCommands(
- uint8_t status, const std::vector<uint8_t>& supported_commands);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.4
- static std::unique_ptr<EventPacket>
- CreateCommandCompleteReadLocalExtendedFeatures(
- uint8_t status, uint8_t page_number, uint8_t maximum_page_number,
- uint64_t extended_lmp_features);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.5
- static std::unique_ptr<EventPacket> CreateCommandCompleteReadBufferSize(
- uint8_t status, uint16_t hc_acl_data_packet_length,
- uint8_t hc_synchronous_data_packet_length,
- uint16_t hc_total_num_acl_data_packets,
- uint16_t hc_total_synchronous_data_packets);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.6
- static std::unique_ptr<EventPacket> CreateCommandCompleteReadBdAddr(
- uint8_t status, const BtAddress& bt_address);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.8
- static std::unique_ptr<EventPacket>
- CreateCommandCompleteReadLocalSupportedCodecs(
- uint8_t status, const std::vector<uint8_t>& supported_codecs,
- const std::vector<uint32_t>& vendor_specific_codecs);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.6.1
- static std::unique_ptr<EventPacket> CreateCommandCompleteReadLoopbackMode(
- uint8_t status, uint8_t mode);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.2
- static std::unique_ptr<EventPacket> CreateInquiryResultEvent();
-
- // Returns true if the result can be added to the event packet.
- bool AddInquiryResult(const BtAddress& bt_address,
- uint8_t page_scan_repetition_mode,
- uint32_t class_of_device, uint16_t clock_offset);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.3
- static std::unique_ptr<EventPacket> CreateConnectionCompleteEvent(
- uint8_t status, uint16_t handle, const BtAddress& address,
- uint8_t link_type, bool encryption_enabled);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.25
- static std::unique_ptr<EventPacket> CreateLoopbackCommandEvent(
- uint16_t opcode, const std::vector<uint8_t>& payload);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.38
- static std::unique_ptr<EventPacket> CreateExtendedInquiryResultEvent(
- const BtAddress& bt_address, uint8_t page_scan_repetition_mode,
- uint32_t class_of_device, uint16_t clock_offset, uint8_t rssi,
- const std::vector<uint8_t>& extended_inquiry_response);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
- // 7.7.65.1
- static std::unique_ptr<EventPacket> CreateLeConnectionCompleteEvent(
- uint8_t status, uint16_t handle, uint8_t role, uint8_t peer_address_type,
- const BtAddress& peer, uint16_t interval, uint16_t latency,
- uint16_t supervision_timeout);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
- // 7.7.65.2
- static std::unique_ptr<EventPacket> CreateLeAdvertisingReportEvent();
-
- // Returns true if the report can be added to the event packet.
- bool AddLeAdvertisingReport(uint8_t event_type, uint8_t addr_type,
- const BtAddress& addr,
- const std::vector<uint8_t>& data, uint8_t rssi);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
- // 7.7.65.4
- static std::unique_ptr<EventPacket> CreateLeRemoteUsedFeaturesEvent(
- uint8_t status, uint16_t handle, uint64_t features);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.2
- static std::unique_ptr<EventPacket> CreateCommandCompleteLeReadBufferSize(
- uint8_t status, uint16_t hc_le_data_packet_length,
- uint8_t hc_total_num_le_data_packets);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.3
- static std::unique_ptr<EventPacket>
- CreateCommandCompleteLeReadLocalSupportedFeatures(uint8_t status,
- uint64_t le_features);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.14
- static std::unique_ptr<EventPacket> CreateCommandCompleteLeReadWhiteListSize(
- uint8_t status, uint8_t white_list_size);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.23
- static std::unique_ptr<EventPacket> CreateCommandCompleteLeRand(
- uint8_t status, uint64_t random_val);
-
- // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.27
- static std::unique_ptr<EventPacket>
- CreateCommandCompleteLeReadSupportedStates(uint8_t status,
- uint64_t le_states);
-
- // Vendor-specific commands (see hcidefs.h)
-
- static std::unique_ptr<EventPacket> CreateCommandCompleteLeVendorCap(
- uint8_t status, const std::vector<uint8_t>& vendor_cap);
-
- // Size of a data packet header, which consists of a 1 octet event code
- static const size_t kEventHeaderSize = 1;
-
- private:
- explicit EventPacket(uint8_t event_code);
- EventPacket(uint8_t event_code, const std::vector<uint8_t>& payload);
-};
-
-} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "include/hci/event_code.h"
+#include "include/hci/le_sub_event_code.h"
+#include "include/hci/op_code.h"
+#include "include/hci/status.h"
+
+namespace test_vendor_lib {
+namespace hci {
+
+enum class PacketType : uint8_t {
+ UNKNOWN = 0,
+ COMMAND = 1,
+ ACL = 2,
+ SCO = 3,
+ EVENT = 4,
+};
+
+enum class LinkType : uint8_t {
+ SCO = 0x00,
+ ACL = 0x01,
+ ESCO = 0x02,
+};
+
+enum class LoopbackMode : uint8_t {
+ NO = 0x00,
+ LOCAL = 0x01,
+ REMOTE = 0x02,
+};
+
+/* HCI, PAL, and LMP Version numbers are the same */
+enum class Version : uint8_t {
+ V1_0 = 0,
+ V1_1 = 1,
+ V1_2 = 2,
+ V2_0 = 3,
+ V2_1 = 4,
+ V3_0 = 5,
+ V4_0 = 6,
+ V4_1 = 7,
+ V4_2 = 8,
+ V5_0 = 9,
+};
+
+} // namespace hci
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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>
+
+namespace test_vendor_lib {
+namespace hci {
+
+enum class EventCode : uint8_t {
+ INQUIRY_COMPLETE = 0x01,
+ INQUIRY_RESULT = 0x02,
+ CONNECTION_COMPLETE = 0x03,
+ CONNECTION_REQUEST = 0x04,
+ DISCONNECTION_COMPLETE = 0x05,
+ AUTHENTICATION_COMPLETE = 0x06,
+ REMOTE_NAME_REQUEST_COMPLETE = 0x07,
+ ENCRYPTION_CHANGE = 0x08,
+ CHANGE_CONNECTION_LINK_KEY_COMPLETE = 0x09,
+ MASTER_LINK_KEY_COMPLETE = 0x0A,
+ READ_REMOTE_SUPPORTED_FEATURES_COMPLETE = 0x0B,
+ READ_REMOTE_VERSION_INFORMATION_COMPLETE = 0x0C,
+ QOS_SETUP_COMPLETE = 0x0D,
+ COMMAND_COMPLETE = 0x0E,
+ COMMAND_STATUS = 0x0F,
+ HARDWARE_ERROR = 0x10,
+ FLUSH_OCCURED = 0x11,
+ ROLE_CHANGE = 0x12,
+ NUMBER_OF_COMPLETED_PACKETS = 0x13,
+ MODE_CHANGE = 0x14,
+ RETURN_LINK_KEYS = 0x15,
+ PIN_CODE_REQUEST = 0x16,
+ LINK_KEY_REQUEST = 0x17,
+ LINK_KEY_NOTIFICATION = 0x18,
+ LOOPBACK_COMMAND = 0x19,
+ DATA_BUFFER_OVERFLOW = 0x1A,
+ MAX_SLOTS_CHANGE = 0x1B,
+ READ_CLOCK_OFFSET_COMPLETE = 0x1C,
+ CONNECTION_PACKET_TYPE_CHANGE = 0x1D,
+ QOS_VIOLATION = 0x1E,
+ PAGE_SCAN_REPETITION_MODE_CHANGE = 0x20,
+ FLOW_SPECIFICATION_COMPLETE = 0x21,
+ INQUIRY_RESULT_WITH_RSSI = 0x22,
+ READ_REMOTE_EXTENDED_FEATURES_COMPLETE = 0x23,
+ SYNCHRONOUS_CONNECTION_COMPLETE = 0x2C,
+ SYNCHRONOUS_CONNECTION_CHANGED = 0x2D,
+ SNIFF_SUBRATING = 0x2E,
+ EXTENDED_INQUIRY_RESULT = 0x2F,
+ ENCRYPTION_KEY_REFRESH_COMPLETE = 0x30,
+ IO_CAPABILITY_REQUEST = 0x31,
+ IO_CAPABILITY_RESPONSE = 0x32,
+ USER_CONFIRMATION_REQUEST = 0x33,
+ USER_PASSKEY_REQUEST = 0x34,
+ REMOTE_OOB_DATA_REQUEST = 0x35,
+ SIMPLE_PAIRING_COMPLETE = 0x36,
+ LINK_SUPERVISION_TIMEOUT_CHANGED = 0x38,
+ ENHANCED_FLUSH_COMPLETE = 0x39,
+ USER_PASSKEY_NOTIFICATION = 0x3B,
+ KEYPRESS_NOTIFICATION = 0x3C,
+ REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION = 0x3D,
+ LE_META_EVENT = 0x3e,
+ PHYSICAL_LINK_COMPLETE = 0x40,
+ CHANNEL_SELECTED = 0x41,
+ DISCONNECTION_PHYSICAL_LINK_COMPLETE = 0x42,
+ PHYSICAL_LINK_LOSS_EARLY_WARNING = 0x43,
+ PHYSICAL_LINK_RECOVERY = 0x44,
+ LOGICAL_LINK_COMPLETE = 0x45,
+ DISCONNECTION_LOGICAL_LINK_COMPLETE = 0x46,
+ FLOW_SPEC_MODIFY_COMPLETE = 0x47,
+ NUMBER_OF_COMPLETED_DATA_BLOCKS = 0x48,
+ SHORT_RANGE_MODE_CHANGE_COMPLETE = 0x4C,
+};
+}
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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>
+
+namespace test_vendor_lib {
+namespace hci {
+
+enum class LeSubEventCode : uint8_t {
+ CONNECTION_COMPLETE = 0x01,
+ ADVERTISING_REPORT = 0x02,
+ CONNECTION_UPDATE_COMPLETE = 0x03,
+ READ_REMOTE_FEATURES_COMPLETE = 0x04,
+ LONG_TERM_KEY_REQUEST = 0x05,
+ REMOTE_CONNECTION_PARAMETER_REQUEST = 0x06,
+ DATA_LENGTH_CHANGE = 0x07,
+ ENHANCED_CONNECTION_COMPLETE = 0x0a,
+ DIRECTED_ADVERTISING_REPORT = 0x0b,
+ PHY_UPDATE_COMPLETE = 0x0c,
+ EXTENDED_ADVERTISING_REPORT = 0x0D,
+ PERIODIC_ADVERTISING_SYNC_ESTABLISHED = 0x0E,
+ PERIODIC_ADVERTISING_REPORT = 0x0F,
+ PERIODIC_ADVERTISING_SYNC_LOST = 0x10,
+ SCAN_TIMEOUT = 0x11,
+ ADVERTISING_SET_TERMINATED = 0x12,
+ SCAN_REQUEST_RECEIVED = 0x13,
+};
+}
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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>
+
+namespace test_vendor_lib {
+namespace hci {
+
+using CommandGroups = enum {
+ LINK_CONTROL = 0x01 << 10, /* 0x0400 */
+ LINK_POLICY = 0x02 << 10, /* 0x0800 */
+ CONTROLLER_AND_BASEBAND = 0x03 << 10, /* 0x0C00 */
+ INFORMATIONAL_PARAMETERS = 0x04 << 10, /* 0x1000 */
+ STATUS_PARAMETERS = 0x05 << 10, /* 0x1400 */
+ TESTING = 0x06 << 10, /* 0x1800 */
+ LE_CONTROLLER = 0x08 << 10, /* 0x2000 */
+ VENDOR_SPECIFIC = 0x3F << 10, /* 0xFC00 */
+};
+
+enum class OpCode : uint16_t {
+ NONE = 0x0000,
+
+ /* LINK_CONTROL */
+ INQUIRY = LINK_CONTROL | 0x0001,
+ INQUIRY_CANCEL = LINK_CONTROL | 0x0002,
+ PERIODIC_INQUIRY_MODE = LINK_CONTROL | 0x0003,
+ EXIT_PERIODIC_INQUIRY_MODE = LINK_CONTROL | 0x0004,
+ CREATE_CONNECTION = LINK_CONTROL | 0x0005,
+ DISCONNECT = LINK_CONTROL | 0x0006,
+ CREATE_CONNECTION_CANCEL = LINK_CONTROL | 0x0008,
+ ACCEPT_CONNECTION_REQUEST = LINK_CONTROL | 0x0009,
+ REJECT_CONNECTION_REQUEST = LINK_CONTROL | 0x000A,
+ LINK_KEY_REQUEST_REPLY = LINK_CONTROL | 0x000B,
+ LINK_KEY_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x000C,
+ PIN_CODE_REQUEST_REPLY = LINK_CONTROL | 0x000D,
+ PIN_CODE_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x000E,
+ CHANGE_CONNECTION_PACKET_TYPE = LINK_CONTROL | 0x000F,
+ AUTHENTICATION_REQUESTED = LINK_CONTROL | 0x0011,
+ SET_CONNECTION_ENCRYPTION = LINK_CONTROL | 0x0013,
+ CHANGE_CONNECTION_LINK_KEY = LINK_CONTROL | 0x0015,
+ MASTER_LINK_KEY = LINK_CONTROL | 0x0017,
+ REMOTE_NAME_REQUEST = LINK_CONTROL | 0x0019,
+ REMOTE_NAME_REQUEST_CANCEL = LINK_CONTROL | 0x001A,
+ READ_REMOTE_SUPPORTED_FEATURES = LINK_CONTROL | 0x001B,
+ READ_REMOTE_EXTENDED_FEATURES = LINK_CONTROL | 0x001C,
+ READ_REMOTE_VERSION_INFORMATION = LINK_CONTROL | 0x001D,
+ READ_CLOCK_OFFSET = LINK_CONTROL | 0x001F,
+ READ_LMP_HANDLE = LINK_CONTROL | 0x0020,
+ SETUP_SYNCHRONOUS_CONNECTION = LINK_CONTROL | 0x0028,
+ ACCEPT_SYNCHRONOUS_CONNECTION = LINK_CONTROL | 0x0029,
+ REJECT_SYNCHRONOUS_CONNECTION = LINK_CONTROL | 0x002A,
+ IO_CAPABILITY_REQUEST_REPLY = LINK_CONTROL | 0x002B,
+ USER_CONFIRMATION_REQUEST_REPLY = LINK_CONTROL | 0x002C,
+ USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x002D,
+ USER_PASSKEY_REQUEST_REPLY = LINK_CONTROL | 0x002E,
+ USER_PASSKEY_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x002F,
+ REMOTE_OOB_DATA_REQUEST_REPLY = LINK_CONTROL | 0x0030,
+ REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x0033,
+ IO_CAPABILITY_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x0034,
+ ENHANCED_SETUP_SYNCHRONOUS_CONNECTION = LINK_CONTROL | 0x003D,
+ ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION = LINK_CONTROL | 0x003E,
+
+ /* LINK_POLICY */
+ HOLD_MODE = LINK_POLICY | 0x0001,
+ SNIFF_MODE = LINK_POLICY | 0x0003,
+ EXIT_SNIFF_MODE = LINK_POLICY | 0x0004,
+ QOS_SETUP = LINK_POLICY | 0x0007,
+ ROLE_DISCOVERY = LINK_POLICY | 0x0009,
+ SWITCH_ROLE = LINK_POLICY | 0x000B,
+ READ_LINK_POLICY_SETTINGS = LINK_POLICY | 0x000C,
+ WRITE_LINK_POLICY_SETTINGS = LINK_POLICY | 0x000D,
+ READ_DEFAULT_LINK_POLICY_SETTINGS = LINK_POLICY | 0x000E,
+ WRITE_DEFAULT_LINK_POLICY_SETTINGS = LINK_POLICY | 0x000F,
+ FLOW_SPECIFICATION = LINK_POLICY | 0x0010,
+ SNIFF_SUBRATING = LINK_POLICY | 0x0011,
+
+ /* CONTROLLER_AND_BASEBAND */
+ SET_EVENT_MASK = CONTROLLER_AND_BASEBAND | 0x0001,
+ RESET = CONTROLLER_AND_BASEBAND | 0x0003,
+ SET_EVENT_FILTER = CONTROLLER_AND_BASEBAND | 0x0005,
+ FLUSH = CONTROLLER_AND_BASEBAND | 0x0008,
+ READ_PIN_TYPE = CONTROLLER_AND_BASEBAND | 0x0009,
+ WRITE_PIN_TYPE = CONTROLLER_AND_BASEBAND | 0x000A,
+ CREATE_NEW_UNIT_KEY = CONTROLLER_AND_BASEBAND | 0x000B,
+ READ_STORED_LINK_KEY = CONTROLLER_AND_BASEBAND | 0x000D,
+ WRITE_STORED_LINK_KEY = CONTROLLER_AND_BASEBAND | 0x0011,
+ DELETE_STORED_LINK_KEY = CONTROLLER_AND_BASEBAND | 0x0012,
+ WRITE_LOCAL_NAME = CONTROLLER_AND_BASEBAND | 0x0013,
+ READ_LOCAL_NAME = CONTROLLER_AND_BASEBAND | 0x0014,
+ READ_CONNECTION_ACCEPT_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0015,
+ WRITE_CONNECTION_ACCEPT_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0016,
+ READ_PAGE_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0017,
+ WRITE_PAGE_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0018,
+ READ_SCAN_ENABLE = CONTROLLER_AND_BASEBAND | 0x0019,
+ WRITE_SCAN_ENABLE = CONTROLLER_AND_BASEBAND | 0x001A,
+ READ_PAGE_SCAN_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x001B,
+ WRITE_PAGE_SCAN_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x001C,
+ READ_INQUIRY_SCAN_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x001D,
+ WRITE_INQUIRY_SCAN_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x001E,
+ READ_AUTHENTICATION_ENABLE = CONTROLLER_AND_BASEBAND | 0x001F,
+ WRITE_AUTHENTICATION_ENABLE = CONTROLLER_AND_BASEBAND | 0x0020,
+ READ_CLASS_OF_DEVICE = CONTROLLER_AND_BASEBAND | 0x0023,
+ WRITE_CLASS_OF_DEVICE = CONTROLLER_AND_BASEBAND | 0x0024,
+ READ_VOICE_SETTING = CONTROLLER_AND_BASEBAND | 0x0025,
+ WRITE_VOICE_SETTING = CONTROLLER_AND_BASEBAND | 0x0026,
+ READ_AUTOMATIC_FLUSH_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0027,
+ WRITE_AUTOMATIC_FLUSH_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0028,
+ READ_NUM_BROADCAST_RETRANSMITS = CONTROLLER_AND_BASEBAND | 0x0029,
+ WRITE_NUM_BROADCAST_RETRANSMITS = CONTROLLER_AND_BASEBAND | 0x002A,
+ READ_HOLD_MODE_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x002B,
+ WRITE_HOLD_MODE_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x002C,
+ READ_TRANSMIT_POWER_LEVEL = CONTROLLER_AND_BASEBAND | 0x002D,
+ READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE = CONTROLLER_AND_BASEBAND | 0x002E,
+ WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE = CONTROLLER_AND_BASEBAND | 0x002F,
+ SET_CONTROLLER_TO_HOST_FLOW_CONTROL = CONTROLLER_AND_BASEBAND | 0x0031,
+ HOST_BUFFER_SIZE = CONTROLLER_AND_BASEBAND | 0x0033,
+ HOST_NUM_COMPLETED_PACKETS = CONTROLLER_AND_BASEBAND | 0x0035,
+ READ_LINK_SUPERVISION_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0036,
+ WRITE_LINK_SUPERVISION_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0037,
+ READ_NUMBER_OF_SUPPORTED_IAC = CONTROLLER_AND_BASEBAND | 0x0038,
+ READ_CURRENT_IAC_LAP = CONTROLLER_AND_BASEBAND | 0x0039,
+ WRITE_CURRENT_IAC_LAP = CONTROLLER_AND_BASEBAND | 0x003A,
+ SET_AFH_HOST_CHANNEL_CLASSIFICATION = CONTROLLER_AND_BASEBAND | 0x003F,
+ READ_LE_HOST_SUPPORT = CONTROLLER_AND_BASEBAND | 0x6C,
+ WRITE_LE_HOST_SUPPORT = CONTROLLER_AND_BASEBAND | 0x6D,
+ READ_INQUIRY_SCAN_TYPE = CONTROLLER_AND_BASEBAND | 0x0042,
+ WRITE_INQUIRY_SCAN_TYPE = CONTROLLER_AND_BASEBAND | 0x0043,
+ READ_INQUIRY_MODE = CONTROLLER_AND_BASEBAND | 0x0044,
+ WRITE_INQUIRY_MODE = CONTROLLER_AND_BASEBAND | 0x0045,
+ READ_PAGE_SCAN_TYPE = CONTROLLER_AND_BASEBAND | 0x0046,
+ WRITE_PAGE_SCAN_TYPE = CONTROLLER_AND_BASEBAND | 0x0047,
+ READ_AFH_CHANNEL_ASSESSMENT_MODE = CONTROLLER_AND_BASEBAND | 0x0048,
+ WRITE_AFH_CHANNEL_ASSESSMENT_MODE = CONTROLLER_AND_BASEBAND | 0x0049,
+ READ_EXTENDED_INQUIRY_RESPONSE = CONTROLLER_AND_BASEBAND | 0x0051,
+ WRITE_EXTENDED_INQUIRY_RESPONSE = CONTROLLER_AND_BASEBAND | 0x0052,
+ REFRESH_ENCRYPTION_KEY = CONTROLLER_AND_BASEBAND | 0x0053,
+ READ_SIMPLE_PAIRING_MODE = CONTROLLER_AND_BASEBAND | 0x0055,
+ WRITE_SIMPLE_PAIRING_MODE = CONTROLLER_AND_BASEBAND | 0x0056,
+ READ_LOCAL_OOB_DATA = CONTROLLER_AND_BASEBAND | 0x0057,
+ READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL = CONTROLLER_AND_BASEBAND | 0x0058,
+ WRITE_INQUIRY_TRANSMIT_POWER_LEVEL = CONTROLLER_AND_BASEBAND | 0x0059,
+ SEND_KEYPRESS_NOTIFICATION = CONTROLLER_AND_BASEBAND | 0x0060,
+
+ READ_SECURE_CONNECTIONS_HOST_SUPPORT = CONTROLLER_AND_BASEBAND | 0x0079,
+ WRITE_SECURE_CONNECTIONS_HOST_SUPPORT = CONTROLLER_AND_BASEBAND | 0x007A,
+
+ /* INFORMATIONAL_PARAMETERS */
+ READ_LOCAL_VERSION_INFORMATION = INFORMATIONAL_PARAMETERS | 0x0001,
+ READ_LOCAL_SUPPORTED_COMMANDS = INFORMATIONAL_PARAMETERS | 0x0002,
+ READ_LOCAL_SUPPORTED_FEATURES = INFORMATIONAL_PARAMETERS | 0x0003,
+ READ_LOCAL_EXTENDED_FEATURES = INFORMATIONAL_PARAMETERS | 0x0004,
+ READ_BUFFER_SIZE = INFORMATIONAL_PARAMETERS | 0x0005,
+ READ_BD_ADDR = INFORMATIONAL_PARAMETERS | 0x0009,
+ READ_DATA_BLOCK_SIZE = INFORMATIONAL_PARAMETERS | 0x000A,
+ READ_LOCAL_SUPPORTED_CODECS = INFORMATIONAL_PARAMETERS | 0x000B,
+
+ /* STATUS_PARAMETERS */
+ READ_FAILED_CONTACT_COUNTER = STATUS_PARAMETERS | 0x0001,
+ RESET_FAILED_CONTACT_COUNTER = STATUS_PARAMETERS | 0x0002,
+ READ_LINK_QUALITY = STATUS_PARAMETERS | 0x0003,
+ READ_RSSI = STATUS_PARAMETERS | 0x0005,
+ READ_AFH_CHANNEL_MAP = STATUS_PARAMETERS | 0x0006,
+ READ_CLOCK = STATUS_PARAMETERS | 0x0007,
+ READ_ENCRYPTION_KEY_SIZE = STATUS_PARAMETERS | 0x0008,
+
+ /* TESTING */
+ READ_LOOPBACK_MODE = TESTING | 0x0001,
+ WRITE_LOOPBACK_MODE = TESTING | 0x0002,
+ ENABLE_DEVICE_UNDER_TEST_MODE = TESTING | 0x0003,
+ WRITE_SIMPLE_PAIRING_DEBUG_MODE = TESTING | 0x0004,
+ WRITE_SECURE_CONNECTIONS_TEST_MODE = TESTING | 0x000A,
+
+ /* LE_CONTROLLER */
+ LE_SET_EVENT_MASK = LE_CONTROLLER | 0x0001,
+ LE_READ_BUFFER_SIZE = LE_CONTROLLER | 0x0002,
+ LE_READ_LOCAL_SUPPORTED_FEATURES = LE_CONTROLLER | 0x0003,
+ LE_WRITE_LOCAL_SUPPORTED_FEATURES = LE_CONTROLLER | 0x0004,
+ LE_SET_RANDOM_ADDRESS = LE_CONTROLLER | 0x0005,
+ LE_SET_ADVERTISING_PARAMETERS = LE_CONTROLLER | 0x0006,
+ LE_READ_ADVERTISING_CHANNEL_TX_POWER = LE_CONTROLLER | 0x0007,
+ LE_SET_ADVERTISING_DATA = LE_CONTROLLER | 0x0008,
+ LE_SET_SCAN_RSPONSE_DATA = LE_CONTROLLER | 0x0009,
+ LE_SET_ADVERTISING_ENABLE = LE_CONTROLLER | 0x000A,
+ LE_SET_SCAN_PARAMETERS = LE_CONTROLLER | 0x000B,
+ LE_SET_SCAN_ENABLE = LE_CONTROLLER | 0x000C,
+ LE_CREATE_CONNECTION = LE_CONTROLLER | 0x000D,
+ LE_CREATE_CONNECTION_CANCEL = LE_CONTROLLER | 0x000E,
+ LE_READ_WHITE_LIST_SIZE = LE_CONTROLLER | 0x000F,
+ LE_CLEAR_WHITE_LIST = LE_CONTROLLER | 0x0010,
+ LE_ADD_DEVICE_TO_WHITE_LIST = LE_CONTROLLER | 0x0011,
+ LE_REMOVE_DEVICE_FROM_WHITE_LIST = LE_CONTROLLER | 0x0012,
+ LE_CONNECTION_UPDATE = LE_CONTROLLER | 0x0013,
+ LE_SET_HOST_CHANNEL_CLASSIFICATION = LE_CONTROLLER | 0x0014,
+ LE_READ_CHANNEL_MAP = LE_CONTROLLER | 0x0015,
+ LE_READ_REMOTE_FEATURES = LE_CONTROLLER | 0x0016,
+ LE_ENCRYPT = LE_CONTROLLER | 0x0017,
+ LE_RAND = LE_CONTROLLER | 0x0018,
+ LE_START_ENCRYPTION = LE_CONTROLLER | 0x0019,
+ LE_LONG_TERM_KEY_REQUEST_REPLY = LE_CONTROLLER | 0x001A,
+ LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY = LE_CONTROLLER | 0x001B,
+ LE_READ_SUPPORTED_STATES = LE_CONTROLLER | 0x001C,
+ LE_RECEIVER_TEST = LE_CONTROLLER | 0x001D,
+ LE_TRANSMITTER_TEST = LE_CONTROLLER | 0x001E,
+ LE_TEST_END = LE_CONTROLLER | 0x001F,
+ LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY = LE_CONTROLLER | 0x0020,
+ LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY = LE_CONTROLLER | 0x0021,
+
+ LE_SET_DATA_LENGTH = LE_CONTROLLER | 0x0022,
+ LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH = LE_CONTROLLER | 0x0023,
+ LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH = LE_CONTROLLER | 0x0024,
+ LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND = LE_CONTROLLER | 0x0025,
+ LE_GENERATE_DHKEY_COMMAND = LE_CONTROLLER | 0x0026,
+ LE_ADD_DEVICE_TO_RESOLVING_LIST = LE_CONTROLLER | 0x0027,
+ LE_REMOVE_DEVICE_FROM_RESOLVING_LIST = LE_CONTROLLER | 0x0028,
+ LE_CLEAR_RESOLVING_LIST = LE_CONTROLLER | 0x0029,
+ LE_READ_RESOLVING_LIST_SIZE = LE_CONTROLLER | 0x002A,
+ LE_READ_PEER_RESOLVABLE_ADDRESS = LE_CONTROLLER | 0x002B,
+ LE_READ_LOCAL_RESOLVABLE_ADDRESS = LE_CONTROLLER | 0x002C,
+ LE_SET_ADDRESS_RESOLUTION_ENABLE = LE_CONTROLLER | 0x002D,
+ LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT = LE_CONTROLLER | 0x002E,
+ LE_READ_MAXIMUM_DATA_LENGTH = LE_CONTROLLER | 0x002F,
+ LE_READ_PHY = LE_CONTROLLER | 0x0030,
+ LE_SET_DEFAULT_PHY = LE_CONTROLLER | 0x0031,
+ LE_SET_PHY = LE_CONTROLLER | 0x0032,
+ LE_ENHANCED_RECEIVER_TEST = LE_CONTROLLER | 0x0033,
+ LE_ENHANCED_TRANSMITTER_TEST = LE_CONTROLLER | 0x0034,
+ LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS = LE_CONTROLLER | 0x35,
+ LE_SET_EXTENDED_ADVERTISING_PARAMETERS = LE_CONTROLLER | 0x36,
+ LE_SET_EXTENDED_ADVERTISING_DATA = LE_CONTROLLER | 0x37,
+ LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE = LE_CONTROLLER | 0x38,
+ LE_SET_EXTENDED_ADVERTISING_ENABLE = LE_CONTROLLER | 0x39,
+ LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = LE_CONTROLLER | 0x003A,
+ LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = LE_CONTROLLER | 0x003B,
+ LE_REMOVE_ADVERTISING_SET = LE_CONTROLLER | 0x003C,
+ LE_CLEAR_ADVERTISING_SETS = LE_CONTROLLER | 0x003D,
+ LE_SET_PERIODIC_ADVERTISING_PARAM = LE_CONTROLLER | 0x003E,
+ LE_SET_PERIODIC_ADVERTISING_DATA = LE_CONTROLLER | 0x003F,
+ LE_SET_PERIODIC_ADVERTISING_ENABLE = LE_CONTROLLER | 0x0040,
+ LE_SET_EXTENDED_SCAN_PARAMETERS = LE_CONTROLLER | 0x0041,
+ LE_SET_EXTENDED_SCAN_ENABLE = LE_CONTROLLER | 0x0042,
+ LE_EXTENDED_CREATE_CONNECTION = LE_CONTROLLER | 0x0043,
+ LE_PERIODIC_ADVERTISING_CREATE_SYNC = LE_CONTROLLER | 0x0044,
+ LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = LE_CONTROLLER | 0x0045,
+ LE_PERIODIC_ADVERTISING_TERMINATE_SYNC = LE_CONTROLLER | 0x0046,
+ LE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST = LE_CONTROLLER | 0x0047,
+ LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISING_LIST = LE_CONTROLLER | 0x0048,
+ LE_CLEAR_PERIODIC_ADVERTISING_LIST = LE_CONTROLLER | 0x0049,
+ LE_READ_PERIODIC_ADVERTISING_LIST_SIZE = LE_CONTROLLER | 0x004A,
+ LE_READ_TRANSMIT_POWER = LE_CONTROLLER | 0x004B,
+ LE_READ_RF_PATH_COMPENSATION_POWER = LE_CONTROLLER | 0x004C,
+ LE_WRITE_RF_PATH_COMPENSATION_POWER = LE_CONTROLLER | 0x004D,
+ LE_SET_PRIVACY_MODE = LE_CONTROLLER | 0x004E,
+
+ /* VENDOR_SPECIFIC */
+ LE_GET_VENDOR_CAPABILITIES = VENDOR_SPECIFIC | 0x0153,
+ LE_MULTI_ADVT = VENDOR_SPECIFIC | 0x0154,
+ LE_BATCH_SCAN = VENDOR_SPECIFIC | 0x0156,
+ LE_ADV_FILTER = VENDOR_SPECIFIC | 0x0157,
+ LE_TRACK_ADV = VENDOR_SPECIFIC | 0x0158,
+ LE_ENERGY_INFO = VENDOR_SPECIFIC | 0x0159,
+ LE_EXTENDED_SCAN_PARAMS = VENDOR_SPECIFIC | 0x015A,
+ CONTROLLER_DEBUG_INFO = VENDOR_SPECIFIC | 0x015B,
+ CONTROLLER_A2DP_OPCODE = VENDOR_SPECIFIC | 0x015D,
+};
+
+} // namespace hci
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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>
+
+namespace test_vendor_lib {
+namespace hci {
+
+enum class Status : uint8_t {
+ SUCCESS = 0,
+ UNKNOWN_COMMAND = 1,
+ UNKNOWN_CONNECTION = 2,
+ HARDWARE_FAILURE = 3,
+ PAGE_TIMEOUT = 4,
+ AUTHENTICATION_FAILURE = 5,
+ PIN_OR_KEY_MISSING = 6,
+ MEMORY_CAPACITY_EXCEEDED = 7,
+ CONNECTION_TIMEOUT = 8,
+ COMMAND_DISALLOWED = 0x0c,
+ CONNECTION_REJECTED_LIMITED_RESOURCES = 0x0d,
+ CONNECTION_REJECTED_SECURITY = 0x0e,
+ CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR = 0x0f,
+ INVALID_HCI_COMMAND_PARAMETERS = 0x12,
+ REMOTE_USER_TERMINATED_CONNECTION = 0x13,
+ CONNECTION_TERMINATED_BY_LOCAL_HOST = 0x16,
+ UNSPECIFIED_ERROR = 0x1f,
+ ENCRYPTION_MODE_NOT_ACCEPTABLE = 0x25,
+ HOST_BUSY_PAIRING = 0x38,
+ CONTROLLER_BUSY = 0x3a,
+};
+}
+} // namespace test_vendor_lib
+++ /dev/null
-#pragma once
-#include <iterator>
-#include <memory>
-#include <type_traits>
-
-#include "base/logging.h"
-
-namespace test_vendor_lib {
-
-// Iterator is a custom iterator class for HciPackets.
-class Iterator
- : public std::iterator<std::random_access_iterator_tag, uint8_t> {
- public:
- Iterator(std::shared_ptr<class HciPacket> packet, size_t i);
- Iterator(const Iterator& itr);
-
- ~Iterator() {}
-
- operator bool() const;
-
- // All addition and subtraction operators are bounded from 0 to the length of
- // the packet.
- Iterator operator+(size_t offset);
- Iterator& operator+=(size_t offset);
- Iterator operator++(int);
- Iterator& operator++();
-
- Iterator operator-(size_t offset);
- int operator-(Iterator& itr);
- Iterator& operator-=(size_t offset);
- Iterator operator--(int);
- Iterator& operator--();
-
- Iterator& operator=(const Iterator& itr);
-
- bool operator!=(Iterator& itr);
- bool operator==(Iterator& itr);
-
- bool operator<(Iterator& itr);
- bool operator>(Iterator& itr);
-
- bool operator<=(Iterator& itr);
- bool operator>=(Iterator& itr);
-
- uint8_t& operator*() const;
- uint8_t* operator->() const;
-
- // Get the next sizeof(FixedWidthIntegerType) bytes and return the filled type
- template <typename FixedWidthIntegerType>
- FixedWidthIntegerType extract() {
- static_assert(std::is_integral<FixedWidthIntegerType>::value,
- "Iterator::extract requires an integral type.");
- FixedWidthIntegerType extracted_value = 0;
-
- for (size_t i = 0; i < sizeof(FixedWidthIntegerType); i++) {
- extracted_value |= static_cast<FixedWidthIntegerType>(**this) << i * 8;
- (*this)++;
- }
-
- return extracted_value;
- }
-
- private:
- std::shared_ptr<class HciPacket> hci_packet_;
- size_t index_;
-
-}; // Iterator
-
-// HciPacket is an abstract class that will serve as the base class for all
-// packet types.
-class HciPacket : public std::enable_shared_from_this<HciPacket> {
- public:
- virtual ~HciPacket() = default;
-
- Iterator get_begin();
- Iterator get_end();
-
- uint8_t operator[](size_t i);
-
- virtual size_t get_length() = 0;
-
- virtual uint8_t& get_at_index(size_t index) = 0;
-
-}; // HciPacket
-
-}; // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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
+
+namespace test_vendor_lib {
+
+class Inquiry {
+ public:
+ enum class InquiryState : uint8_t {
+ STANDBY = 0x00,
+ INQUIRY = 0x01,
+ };
+ enum class InquiryType : uint8_t {
+ STANDARD = 0x00,
+ RSSI = 0x01,
+ EXTENDED = 0x02,
+ };
+};
+} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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 <cmath>
-#include <cstdint>
-#include <iterator>
-#include <memory>
-#include <vector>
-
-#include "base/macros.h"
-#include "hci_packet.h"
-#include "l2cap_sdu.h"
-
-namespace test_vendor_lib {
-
-const int kSduHeaderLength = 4;
-
-class L2capPacket : public HciPacket {
- public:
- // Returns an assembled L2cap object if successful, nullptr if failure.
- static std::shared_ptr<L2capPacket> assemble(
- const std::vector<std::shared_ptr<L2capSdu> >& sdu_packet);
-
- // Returns a fragmented vector of L2capSdu objects if successful
- // Returns an empty vector of L2capSdu objects if unsuccessful
- std::vector<std::shared_ptr<L2capSdu> > fragment(uint16_t maximum_sdu_size,
- uint8_t txseq,
- uint8_t reqseq);
-
- uint16_t get_l2cap_cid() const;
-
- // HciPacket Functions
- size_t get_length();
- uint8_t& get_at_index(size_t index);
-
- private:
- L2capPacket() = default;
-
- // Entire L2CAP packet: length, CID, and payload in that order.
- std::vector<uint8_t> l2cap_packet_;
-
- DISALLOW_COPY_AND_ASSIGN(L2capPacket);
-
- // Helper functions for fragmenting.
- static void set_sdu_header_length(std::vector<uint8_t>& sdu, uint16_t length);
-
- static void set_total_sdu_length(std::vector<uint8_t>& sdu,
- uint16_t total_sdu_length);
-
- static void set_sdu_cid(std::vector<uint8_t>& sdu, uint16_t cid);
-
- static void set_sdu_control_bytes(std::vector<uint8_t>& sdu, uint8_t txseq,
- uint8_t reqseq);
-
- bool check_l2cap_packet() const;
-
-}; // L2capPacket
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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 <cstdint>
-#include <iterator>
-#include <vector>
-
-#include "hci_packet.h"
-
-namespace test_vendor_lib {
-
-// Abstract representation of an SDU packet that contains an L2CAP
-// payload. This class is meant to be used in collaboration with
-// the L2cap class defined in l2cap.h. For example, an SDU packet
-// may look as follows:
-//
-// vector<uint8_t> sdu = {0x04, 0x00, 0x48, 0x00, 0x04, 0x00, 0xab,
-// 0xcd, 0x78, 0x56}
-//
-// The first two bytes (in little endian) should be read as 0x0004
-// and is the length of the payload of the SDU packet.
-//
-// The next two bytes (also in little endian) are the channel ID
-// and should be read as 0x0048. These should remain the same for
-// any number of SDUs that are a part of the same packet stream.
-//
-// Following the CID bytes, are the total length bytes. Since this
-// SDU only requires a single packet, the length here is the same
-// as the length in the first two bytes of the packet. Again stored
-// in little endian.
-//
-// Next comes the two control bytes. These begin the L2CAP payload
-// of the SDU packet; however, they will not be added to the L2CAP
-// packet that is being constructed in the assemble function that
-// will be creating an L2CAP packet from a stream of L2capSdu
-// objects.
-//
-// The final two bytes are the frame check sequence that should be
-// calculated from the start of the vector to the end of the
-// payload.
-//
-// Thus, calling assemble on this example would create a
-// zero-length L2CAP packet because the information payload of the
-// L2CAP packet will not include either of the control or FCS
-// bytes.
-//
-class L2capSdu : public HciPacket {
- public:
- // Returns a unique_ptr to an L2capSdu object that is constructed with the
- // assumption that the SDU packet is complete and correct.
- static std::shared_ptr<L2capSdu> L2capSduConstructor(
- std::vector<uint8_t> create_from);
-
- // Adds an FCS to create_from and returns a unique_ptr to an L2capSdu object.
- static std::shared_ptr<L2capSdu> L2capSduBuilder(
- std::vector<uint8_t> create_from);
-
- // Get the FCS bytes from the end of the L2CAP payload of an SDU
- // packet.
- uint16_t get_fcs() const;
-
- uint16_t get_payload_length() const;
-
- uint16_t calculate_fcs() const;
-
- // Get the two control bytes that begin the L2CAP payload. These
- // bytes will contain information such as the Segmentation and
- // Reassembly bits, and the TxSeq/ReqSeq numbers.
- uint16_t get_controls() const;
-
- uint16_t get_total_l2cap_length() const;
-
- size_t get_vector_size() const;
-
- uint16_t get_channel_id() const;
-
- // Returns true if the SDU control sequence for Segmentation and
- // Reassembly is 00b, false otherwise.
- static bool is_complete_l2cap(const L2capSdu& sdu);
-
- // Returns true if the SDU control sequence for Segmentation and
- // Reassembly is 01b, false otherwise.
- static bool is_starting_sdu(const L2capSdu& sdu);
-
- // Returns true if the SDU control sequence for Segmentation and
- // Reasembly is 10b, false otherwise.
- static bool is_ending_sdu(const L2capSdu& sdu);
-
- // HciPacket functions
- size_t get_length();
- uint8_t& get_at_index(size_t index);
-
- private:
- // This is the SDU packet in bytes.
- std::vector<uint8_t> sdu_data_;
-
- // Returns a completed L2capSdu object.
- L2capSdu(std::vector<uint8_t>&& create_from);
-
- // Table for precalculated lfsr values.
- static const uint16_t lfsr_table_[256];
-
- uint16_t convert_from_little_endian(const unsigned int starting_index) const;
-
-}; // L2capSdu
-
-} // namespace test_vendor_lib
+++ /dev/null
-/******************************************************************************
- *
- * Copyright 2017 Google, Inc.
- *
- * 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 <vector>
-namespace {
-
-// Complete SDUs that should always assemble.
-std::vector<std::vector<uint8_t> > good_sdu = {
- {0x0c, 0x00, 0x47, 0x00, 0x02, 0x41, 0x12, 0x00, 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0xeb, 0x0f},
-
- {0x0a, 0x00, 0x47, 0x00, 0x04, 0xc1, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
- 0x5a, 0x8a},
-
- {0x0a, 0x00, 0x47, 0x00, 0x06, 0x81, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
- 0x68, 0x1e}};
-
-// The complete L2CAP packet that should be created by calling assemble on the
-// good_sdu vector.
-std::vector<uint8_t> good_l2cap_packet = {
- 0x12, 0x00, 0x47, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11};
-
-// SDUs that are missing a payload.
-std::vector<std::vector<uint8_t> > empty_sdu_payload = {
- {0x06, 0x00, 0x47, 0x00, 0x02, 0x41, 0x00, 0x00, 0xde, 0xf1},
-
- {0x04, 0x00, 0x47, 0x00, 0x04, 0x81, 0xd7, 0x90}};
-
-// The l2cap packet that should be created by calling assemble on the
-// empty_sdu_payload vector.
-std::vector<uint8_t> empty_l2cap_payload = {0x00, 0x00, 0x47, 0x00};
-
-// SDUs that have all of the control bytes set to be the start of the SDU.
-std::vector<std::vector<uint8_t> > all_first_packet = {
- {0x0c, 0x00, 0x47, 0x00, 0x02, 0x41, 0x18, 0x00, 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x6b, 0x70},
-
- {0x0c, 0x00, 0x47, 0x00, 0x02, 0x41, 0x18, 0x00, 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x6b, 0x70},
-
- {0x0c, 0x00, 0x47, 0x00, 0x02, 0x41, 0x18, 0x00, 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x6b, 0x70}};
-
-// A complete L2CAP packet that has not been segmented.
-std::vector<std::vector<uint8_t> > one_sdu = {{0x0b, 0x00, 0x47, 0x00, 0x02,
- 0x00, 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x4a, 0x2f}};
-
-// l2cap_test_packet_[1-9] are SDUs that were extracted from snoop logs.
-std::vector<uint8_t> l2cap_test_packet_1 = {
- 0xf8, 0x03, 0x47, 0x00, 0x02, 0x41, 0x95, 0x1f, 0x02, 0x1f, 0x95, 0xcb,
- 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x33, 0x00, 0x49, 0x00, 0x4d, 0x00,
- 0x47, 0x00, 0x5f, 0x00, 0x32, 0x00, 0x30, 0x00, 0x31, 0x00, 0x37, 0x00,
- 0x30, 0x00, 0x36, 0x00, 0x30, 0x00, 0x36, 0x00, 0x5f, 0x00, 0x31, 0x00,
- 0x35, 0x00, 0x34, 0x00, 0x33, 0x00, 0x33, 0x00, 0x38, 0x00, 0x2e, 0x00,
- 0x6a, 0x00, 0x70, 0x00, 0x67, 0x00, 0x00, 0x42, 0x00, 0x0e, 0x69, 0x6d,
- 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0x00, 0xc3, 0x00, 0x12,
- 0x30, 0x03, 0x97, 0x01, 0x48, 0x1f, 0x45, 0xff, 0xd8, 0xff, 0xe0, 0x00,
- 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0xff, 0xe1, 0x2b, 0x18, 0x45, 0x78, 0x69, 0x66, 0x00,
- 0x00, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x01,
- 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0c, 0xc0, 0x01,
- 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0x90, 0x01,
- 0x0f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x4c, 0x47, 0x45, 0x00, 0x01,
- 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x9e, 0x01,
- 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
- 0x1a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x01,
- 0x1b, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae, 0x01,
- 0x28, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01,
- 0x31, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xb6, 0x01,
- 0x32, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xbd, 0x02,
- 0x13, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x87,
- 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x00,
- 0x00, 0x02, 0x78, 0x4e, 0x65, 0x78, 0x75, 0x73, 0x20, 0x35, 0x00, 0x00,
- 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00,
- 0x00, 0x00, 0x01, 0x50, 0x69, 0x63, 0x61, 0x73, 0x61, 0x00, 0x32, 0x30,
- 0x31, 0x37, 0x3a, 0x30, 0x36, 0x3a, 0x30, 0x36, 0x20, 0x31, 0x35, 0x3a,
- 0x34, 0x33, 0x3a, 0x33, 0x38, 0x00, 0x00, 0x00, 0x15, 0x82, 0x9a, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xd4, 0x82, 0x9d, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xdc, 0x88, 0x27, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x02, 0x1f, 0x00, 0x00, 0x90, 0x00, 0x00,
- 0x07, 0x00, 0x00, 0x00, 0x04, 0x30, 0x32, 0x32, 0x30, 0x90, 0x03, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x01, 0xe4, 0x90, 0x04, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x01, 0xf8, 0x91, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x00, 0x92, 0x01, 0x00,
- 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x0c, 0x92, 0x02, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x14, 0x92, 0x09, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x92, 0x0a, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x1c, 0x92, 0x90, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x24, 0x92, 0x91, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x2b, 0x92, 0x92, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x32, 0xa0, 0x00, 0x00,
- 0x07, 0x00, 0x00, 0x00, 0x04, 0x30, 0x31, 0x30, 0x30, 0xa0, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0a, 0xa0, 0x03, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x77, 0xa0, 0x05, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x5a, 0xa4, 0x03, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x20, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0xfc, 0x8c, 0xb2, 0x3b, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0x00, 0x00, 0x00, 0x64, 0x32, 0x30, 0x31, 0x37, 0x3a, 0x30, 0x36,
- 0x3a, 0x30, 0x36, 0x20, 0x31, 0x35, 0x3a, 0x34, 0x33, 0x3a, 0x33, 0x38,
- 0x00, 0x32, 0x30, 0x31, 0x37, 0x3a, 0x30, 0x36, 0x3a, 0x30, 0x36, 0x20,
- 0x31, 0x35, 0x3a, 0x34, 0x33, 0x3a, 0x33, 0x38, 0x00, 0xff, 0xff, 0xfe,
- 0x16, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
- 0x64, 0x00, 0x00, 0x0f, 0x82, 0x00, 0x00, 0x03, 0xe8, 0x39, 0x39, 0x39,
- 0x37, 0x32, 0x39, 0x00, 0x39, 0x39, 0x39, 0x37, 0x32, 0x39, 0x00, 0x39,
- 0x39, 0x39, 0x37, 0x32, 0x39, 0x00, 0x31, 0x30, 0x61, 0x66, 0x39, 0x37,
- 0x31, 0x37, 0x63, 0x31, 0x30, 0x36, 0x36, 0x33, 0x65, 0x62, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x04, 0x52, 0x39, 0x38, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00,
- 0x04, 0x30, 0x31, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01,
- 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x01,
- 0x1a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xc6, 0x01,
- 0x1b, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xce, 0x01,
- 0x28, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x02,
- 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xd6, 0x02,
- 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x28, 0x39, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0xff, 0xd8, 0xff, 0xe0, 0x00,
- 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x05, 0x03, 0x04, 0x04,
- 0x04, 0x03, 0x05, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c,
- 0x08, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09, 0x0c, 0x11, 0x0f,
- 0x12, 0x12, 0x11, 0x0f, 0x11, 0x11, 0x13, 0x16, 0x1c, 0x17, 0x13, 0x14,
- 0x1a, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1a, 0x1d, 0x1d, 0x1f, 0x1f,
- 0x1f, 0x13, 0x17, 0x22, 0x24, 0x22, 0x1e, 0x24, 0x1c, 0x1e, 0x1f, 0x1e,
- 0xff, 0xdb, 0x00, 0x43, 0x01, 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0e,
- 0x08, 0x08, 0x0e, 0x1e, 0x14, 0x11, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0xff, 0xc0, 0x00,
- 0x11, 0x08, 0x00, 0x78, 0x00, 0xa0, 0x03, 0x01, 0x22, 0x00, 0xaa, 0x72};
-
-std::vector<uint8_t> l2cap_test_packet_2 = {
- 0xf6, 0x03, 0x47, 0x00, 0x04, 0xc1, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
- 0xff, 0xc4, 0x00, 0x1c, 0x00, 0x00, 0x03, 0x00, 0x03, 0x01, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07,
- 0x00, 0x04, 0x08, 0x03, 0x02, 0x01, 0xff, 0xc4, 0x00, 0x40, 0x10, 0x00,
- 0x01, 0x03, 0x02, 0x05, 0x02, 0x04, 0x04, 0x04, 0x03, 0x06, 0x04, 0x07,
- 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x00, 0x06, 0x12,
- 0x21, 0x31, 0x07, 0x41, 0x13, 0x22, 0x51, 0x61, 0x14, 0x32, 0x71, 0x81,
- 0x08, 0x42, 0x91, 0xa1, 0x15, 0x16, 0xc1, 0x23, 0x52, 0x62, 0x82, 0xb1,
- 0xe1, 0x24, 0x43, 0x72, 0xf0, 0x17, 0x25, 0x33, 0x92, 0xb2, 0xd1, 0xd2,
- 0xff, 0xc4, 0x00, 0x1c, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07,
- 0x04, 0x03, 0x00, 0x02, 0x08, 0x01, 0xff, 0xc4, 0x00, 0x37, 0x11, 0x00,
- 0x01, 0x02, 0x04, 0x04, 0x03, 0x06, 0x04, 0x05, 0x04, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0x11, 0x06, 0x21,
- 0x31, 0x41, 0x12, 0x51, 0x71, 0x13, 0x22, 0x61, 0x81, 0x91, 0xa1, 0x07,
- 0xb1, 0xc1, 0xf0, 0x14, 0x42, 0xd1, 0xe1, 0xf1, 0x15, 0x24, 0x32, 0x82,
- 0x33, 0x52, 0x72, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11,
- 0x03, 0x11, 0x00, 0x3f, 0x00, 0xb1, 0x31, 0x2c, 0x2d, 0xd8, 0xd2, 0xda,
- 0x43, 0x26, 0x4a, 0x99, 0x1e, 0x15, 0x98, 0x2e, 0x2f, 0x51, 0x49, 0x0b,
- 0x03, 0x70, 0x90, 0x6c, 0x9f, 0x4d, 0xb7, 0xf5, 0xc3, 0x0b, 0x4f, 0x09,
- 0x1f, 0x08, 0xa5, 0x95, 0xb6, 0xb7, 0x50, 0x4e, 0x95, 0xab, 0xe4, 0xbf,
- 0x2a, 0xb1, 0x17, 0xb8, 0xb1, 0xde, 0xdd, 0xf1, 0x34, 0xa1, 0x3b, 0x25,
- 0xb6, 0x5d, 0x67, 0xe2, 0xda, 0x5b, 0xeb, 0x49, 0xf0, 0xd2, 0x83, 0xe1,
- 0xa9, 0x37, 0xbe, 0x91, 0x72, 0xab, 0x5f, 0x73, 0x7f, 0xb6, 0x1d, 0x28,
- 0xf0, 0xdf, 0xf1, 0x9b, 0x05, 0x2e, 0x20, 0x32, 0xd8, 0x64, 0x23, 0x52,
- 0x4a, 0x9c, 0xb7, 0x2b, 0x52, 0x8d, 0xd5, 0xe9, 0xe5, 0xdb, 0x83, 0xea,
- 0x30, 0x09, 0x75, 0x86, 0x25, 0xec, 0x1e, 0x58, 0x4d, 0xf9, 0x90, 0x20,
- 0x87, 0x60, 0x4e, 0x91, 0xb2, 0xc3, 0x72, 0x63, 0xcd, 0x40, 0x76, 0x63,
- 0xd2, 0x5b, 0x4a, 0x75, 0x04, 0x20, 0x06, 0xf9, 0xdb, 0xcd, 0xdc, 0x83,
- 0xe9, 0x6b, 0xec, 0x0d, 0xf1, 0xba, 0x5f, 0x76, 0xe9, 0x50, 0x43, 0x65,
- 0xd9, 0x05, 0x21, 0x08, 0xf2, 0x92, 0x94, 0x05, 0x73, 0x72, 0x48, 0x20,
- 0x5c, 0xaa, 0xf8, 0xf8, 0xa9, 0x34, 0x97, 0xe4, 0x3e, 0xc7, 0xc4, 0x80,
- 0x95, 0x90, 0x90, 0x9d, 0x1a, 0x94, 0x8b, 0xd8, 0x6d, 0xb5, 0x80, 0xef,
- 0xf7, 0xc7, 0xeb, 0x14, 0xb7, 0xdb, 0x79, 0x45, 0x2f, 0xb6, 0x50, 0x55,
- 0x7b, 0x96, 0x86, 0xb4, 0xf1, 0xc2, 0xaf, 0x7e, 0xc3, 0x7c, 0x65, 0x77,
- 0x15, 0x52, 0x98, 0x36, 0x53, 0xc3, 0xca, 0xe7, 0xe5, 0x78, 0xf0, 0xb0,
- 0xb3, 0x99, 0x11, 0xae, 0xa6, 0xd8, 0x91, 0x2c, 0x38, 0x3c, 0x37, 0xb4,
- 0x36, 0xa6, 0x99, 0xd2, 0xb2, 0xb0, 0xda, 0x01, 0x04, 0xea, 0x24, 0x8d,
- 0xcd, 0xb6, 0xfa, 0x63, 0x62, 0x92, 0xdb, 0x2c, 0xb8, 0xcb, 0x29, 0x7d,
- 0x97, 0x94, 0x5b, 0x53, 0xa0, 0x22, 0xfa, 0x02, 0x52, 0x52, 0x35, 0x12,
- 0x2f, 0x71, 0x7b, 0x72, 0x77, 0xe0, 0x63, 0xc2, 0xb9, 0x43, 0xa9, 0x39,
- 0x09, 0xc8, 0xd0, 0x1f, 0x6d, 0x95, 0xbb, 0xa5, 0x7f, 0x10, 0xfa, 0x3c,
- 0x5d, 0xf5, 0x58, 0x24, 0x20, 0x5b, 0x51, 0x3c, 0x58, 0x9b, 0x5a, 0xf7,
- 0xbd, 0xf1, 0x2f, 0xcd, 0x94, 0x9c, 0xff, 0x00, 0x4a, 0x94, 0xe4, 0xba,
- 0x8e, 0x60, 0xa8, 0xba, 0xc0, 0x05, 0x1a, 0xe2, 0x47, 0x09, 0x09, 0x4f,
- 0xa6, 0x94, 0x8b, 0xa7, 0xd8, 0x0f, 0xb6, 0x0a, 0xd3, 0xaa, 0x54, 0xe9,
- 0xe5, 0xa1, 0x29, 0x98, 0x4a, 0x4a, 0xb4, 0x0a, 0xba, 0x6f, 0x9d, 0xb7,
- 0x16, 0xbf, 0x21, 0x7b, 0x9d, 0x84, 0x0d, 0xa8, 0x4c, 0xb9, 0x26, 0xd9,
- 0x73, 0xb2, 0x52, 0xc0, 0xff, 0x00, 0xa8, 0x07, 0xda, 0xf7, 0xeb, 0x95,
- 0x84, 0x55, 0xdb, 0x4c, 0x26, 0xa4, 0x3e, 0xdb, 0x0b, 0x2e, 0xcb, 0x91,
- 0x24, 0xbe, 0xa2, 0x2c, 0x08, 0x52, 0x86, 0xca, 0xb7, 0x17, 0x00, 0x58,
- 0xed, 0x72, 0x0e, 0xf8, 0xf8, 0x7e, 0x6c, 0x28, 0xce, 0x3a, 0xc3, 0x25,
- 0x90, 0x88, 0xc9, 0xd4, 0xe9, 0x71, 0xc0, 0x09, 0x52, 0x85, 0xed, 0xa8,
- 0xf7, 0xbd, 0xff, 0x00, 0x4d, 0x86, 0x39, 0x96, 0xa7, 0xd4, 0x6a, 0x63,
- 0x28, 0x5b, 0x1f, 0xce, 0x33, 0xf5, 0x36, 0x0a, 0x5c, 0x49, 0x75, 0x6b,
- 0x70, 0xab, 0x8b, 0x8b, 0x91, 0x63, 0x6b, 0x6d, 0x6e, 0xd8, 0x00, 0xee,
- 0x76, 0xca, 0xce, 0x27, 0xc6, 0x6a, 0x8b, 0x32, 0x78, 0x69, 0x3f, 0xda,
- 0x3a, 0xa6, 0xca, 0x89, 0xb7, 0x2a, 0x3b, 0x9f, 0x7c, 0x37, 0xff, 0x00,
- 0x41, 0x69, 0x1f, 0xf2, 0xbe, 0x07, 0xa7, 0xd4, 0x88, 0x54, 0x18, 0xaa,
- 0x61, 0xcf, 0xf8, 0xa4, 0xd6, 0x7a, 0xe5, 0xf3, 0x1f, 0xac, 0x75, 0x8c,
- 0x0c, 0xc3, 0x02, 0xa3, 0x50, 0x6a, 0x9c, 0xc5, 0x62, 0x92, 0xe4, 0xa7,
- 0x10, 0xb6, 0xbe, 0x1d, 0xb9, 0x2d, 0xad, 0x00, 0x80, 0x3f, 0x2f, 0xcc,
- 0xb5, 0x0b, 0x1e, 0x2c, 0x07, 0xb9, 0xc7, 0xae, 0x68, 0x96, 0xa4, 0xd2,
- 0xcb, 0x31, 0x25, 0x29, 0x72, 0x00, 0x0d, 0x96, 0xda, 0xec, 0x9b, 0xf7,
- 0xb0, 0xd8, 0xf7, 0xda, 0xc7, 0xb6, 0x21, 0x79, 0x22, 0x3d, 0x1e, 0xbf,
- 0x45, 0x8b, 0x3c, 0xd3, 0x95, 0x11, 0xb9, 0x26, 0xf1, 0x5c, 0x69, 0x65,
- 0xa7, 0x10, 0xa0, 0xe6, 0x84, 0x9d, 0xb7, 0x1e, 0x71, 0x89, 0xac, 0x0a,
- 0x9d, 0x56, 0x8f, 0x38, 0x48, 0x8d, 0x52, 0x9d, 0x0d, 0x65, 0xc2, 0x54,
- 0xeb, 0x2e, 0xa9, 0x0a, 0x55, 0x8d, 0x89, 0xe7, 0x7e, 0xfc, 0xe0, 0x0d,
- 0x79, 0xb6, 0xe9, 0x8a, 0x42, 0x50, 0x4a, 0x82, 0xc6, 0xbf, 0xa4, 0x51,
- 0xbe, 0x1b, 0xc8, 0x2b, 0x18, 0x35, 0x32, 0xe3, 0x87, 0xb2, 0x53, 0x2a,
- 0x09, 0xe1, 0xd6, 0xe4, 0x8b, 0xe6, 0x76, 0xf4, 0x31, 0xd6, 0x31, 0x67,
- 0x66, 0x00, 0xda, 0x90, 0x22, 0xc6, 0x79, 0xb4, 0x20, 0xa1, 0x6f, 0xbc,
- 0x0a, 0x41, 0x09, 0xf3, 0x6b, 0x09, 0x37, 0xb0, 0x36, 0xdc, 0x12, 0x4e,
- 0xd8, 0x11, 0x51, 0x7f, 0xf8, 0xed, 0x5a, 0x1c, 0x88, 0x35, 0x04, 0xa5,
- 0xc8, 0x4d, 0x2d, 0x4d, 0xa9, 0xc8, 0xd6, 0x6b, 0x52, 0x87, 0x99, 0x4a,
- 0xb8, 0xdc, 0x93, 0xc0, 0x06, 0xdc, 0xe2, 0x21, 0x13, 0xa9, 0xd9, 0xb0,
- 0xb1, 0xe1, 0x4a, 0xaf, 0x3a, 0xe9, 0x4a, 0xb5, 0x21, 0x6e, 0xb0, 0x85,
- 0x9f, 0x6b, 0xa8, 0x6f, 0x7f, 0xb6, 0x35, 0xe2, 0xf5, 0x37, 0x37, 0xca,
- 0x7c, 0x35, 0x51, 0xaf, 0xae, 0x13, 0x00, 0xfc, 0xed, 0x46, 0xd7, 0x71,
- 0xfe, 0x22, 0x0d, 0xc7, 0xe8, 0x70, 0x10, 0xcf, 0xb0, 0x53, 0x61, 0x73,
- 0xe9, 0xfa, 0xc3, 0xcc, 0xc6, 0x09, 0x7a, 0x50, 0x15, 0x29, 0x1c, 0x5f,
- 0xf9, 0xb9, 0xfa, 0x67, 0xe5, 0x68, 0xe8, 0x7a, 0x34, 0x17, 0x60, 0x34,
- 0xa0, 0x66, 0x53, 0xdb, 0x53, 0x84, 0xea, 0x5b, 0x67, 0x4d, 0xfd, 0xfc,
- 0xbe, 0xfb, 0xf3, 0xbf, 0xd3, 0x6c, 0x7d, 0x66, 0x57, 0x5b};
-
-std::vector<uint8_t> l2cap_test_packet_3 = {
- 0xf6, 0x03, 0x47, 0x00, 0x06, 0xc1, 0x87, 0xeb, 0x74, 0xf8, 0xb1, 0xe1,
- 0xd2, 0xc4, 0x35, 0x49, 0x90, 0xcb, 0xae, 0xc3, 0x73, 0x7d, 0x3a, 0x90,
- 0x9b, 0x90, 0x45, 0xed, 0xbd, 0xf6, 0x3c, 0x0e, 0x6d, 0x89, 0xa6, 0x46,
- 0x89, 0x56, 0xac, 0x4b, 0x81, 0x35, 0xac, 0xdc, 0xfd, 0x56, 0x31, 0x7d,
- 0x2a, 0x29, 0x60, 0x0b, 0x25, 0x49, 0x58, 0xd9, 0xc0, 0x07, 0x96, 0xe3,
- 0xb1, 0xb6, 0xd8, 0xac, 0xe7, 0xb4, 0x45, 0x6a, 0xaf, 0x4b, 0x43, 0x4a,
- 0x6d, 0x25, 0xa9, 0x32, 0x11, 0xa1, 0x24, 0x5d, 0x29, 0x53, 0x5b, 0x6d,
- 0xd8, 0x5c, 0x60, 0xad, 0x29, 0x4d, 0xcc, 0x38, 0x3b, 0xb6, 0x00, 0x8d,
- 0x77, 0x85, 0xb9, 0x96, 0x19, 0x49, 0x52, 0x10, 0x9c, 0xc2, 0x54, 0x73,
- 0x1a, 0x10, 0x92, 0x47, 0xbd, 0xa2, 0x1c, 0x9f, 0xfc, 0x40, 0x7a, 0x32,
- 0x5f, 0x97, 0x99, 0x1d, 0x52, 0xdb, 0x36, 0x11, 0x92, 0xe2, 0x90, 0xd3,
- 0x62, 0xdc, 0x0d, 0x24, 0x11, 0xb1, 0xc2, 0xfd, 0x5a, 0x5e, 0x60, 0x42,
- 0x2c, 0xfc, 0x07, 0x18, 0x75, 0x2a, 0xba, 0x26, 0x21, 0xe5, 0x3f, 0x63,
- 0xfd, 0xe4, 0xa9, 0x47, 0xca, 0x46, 0xe3, 0x71, 0xdf, 0x19, 0xd6, 0x3a,
- 0xd5, 0x5e, 0x91, 0x0d, 0x2f, 0xc1, 0x21, 0x94, 0x29, 0xd7, 0x2e, 0x15,
- 0x65, 0x05, 0x5b, 0x4e, 0xe4, 0x7d, 0xf8, 0x38, 0x0b, 0x42, 0xea, 0x69,
- 0x30, 0x9b, 0x6a, 0xb9, 0x4b, 0x43, 0xe1, 0xb0, 0x12, 0x1d, 0x8e, 0x7c,
- 0x32, 0x8f, 0xb7, 0x6f, 0xb6, 0x28, 0xcb, 0x99, 0x92, 0x95, 0x74, 0x36,
- 0xa0, 0x94, 0xa8, 0x8b, 0x8c, 0xac, 0x39, 0x74, 0x88, 0xa6, 0x1f, 0xc4,
- 0x18, 0xbd, 0x12, 0x9f, 0x8e, 0x67, 0x85, 0xe6, 0xd4, 0x4d, 0xd2, 0x6d,
- 0x71, 0x6d, 0x6d, 0x98, 0x3e, 0x40, 0xf9, 0x40, 0xf9, 0x19, 0x9a, 0xad,
- 0xe3, 0x3b, 0x11, 0x6e, 0xca, 0xa9, 0x6b, 0x56, 0x8d, 0x72, 0x5c, 0x4a,
- 0xad, 0x7b, 0x0b, 0x24, 0xe9, 0x3a, 0x71, 0xf7, 0x97, 0xaa, 0x19, 0x86,
- 0x65, 0x52, 0x24, 0x66, 0xe9, 0x0d, 0xb7, 0xe3, 0x38, 0x1b, 0x49, 0x44,
- 0x50, 0xab, 0x82, 0xab, 0x5e, 0xc4, 0x6f, 0x6c, 0x35, 0xb3, 0x4b, 0xcb,
- 0x79, 0x89, 0xe4, 0xce, 0xa6, 0x26, 0x6c, 0x69, 0x5a, 0x82, 0x95, 0x29,
- 0x2b, 0x52, 0x1d, 0x41, 0x3b, 0x8b, 0x91, 0xda, 0xc3, 0x6d, 0x88, 0xd8,
- 0xe1, 0x93, 0x2f, 0xcf, 0xab, 0xe5, 0x7c, 0xc7, 0x4d, 0x46, 0x60, 0x97,
- 0x0e, 0x75, 0x31, 0xe9, 0x08, 0x69, 0x12, 0x8c, 0x60, 0x87, 0xda, 0xf4,
- 0xbe, 0x8b, 0x05, 0x0f, 0xb0, 0x3d, 0xf1, 0x8a, 0x64, 0xd5, 0x5a, 0x1c,
- 0x52, 0xae, 0x24, 0xa0, 0x67, 0x6b, 0x01, 0xfc, 0xfa, 0xc3, 0x75, 0x33,
- 0xe2, 0x63, 0x4f, 0xbc, 0x99, 0x57, 0xd2, 0x59, 0x73, 0x4e, 0x12, 0x32,
- 0xbf, 0xcf, 0xd6, 0x06, 0xf5, 0x01, 0xd9, 0x74, 0xac, 0xba, 0xdb, 0x2f,
- 0x33, 0x1d, 0xba, 0x85, 0x36, 0xae, 0xe4, 0x77, 0x5d, 0x61, 0xad, 0x96,
- 0x0b, 0x63, 0x70, 0x07, 0xfd, 0x37, 0xb6, 0x1f, 0xba, 0x4b, 0x5b, 0x95,
- 0x3f, 0x2b, 0xc1, 0x44, 0xc7, 0x1e, 0x96, 0x02, 0x8d, 0xca, 0x9b, 0xb2,
- 0x94, 0x41, 0x24, 0x12, 0x2f, 0xcd, 0xec, 0x37, 0xe7, 0xdf, 0x13, 0xbe,
- 0xb2, 0x54, 0x4c, 0xba, 0xce, 0x60, 0x5c, 0x25, 0x87, 0xe9, 0xee, 0x4a,
- 0x6e, 0x49, 0xf0, 0xd3, 0x72, 0x95, 0x29, 0x24, 0x03, 0xa8, 0x1d, 0xb9,
- 0x3b, 0x7b, 0x7b, 0x60, 0xef, 0x43, 0x5d, 0x29, 0x88, 0xdb, 0x8b, 0x72,
- 0x33, 0x65, 0x5e, 0x25, 0xee, 0x17, 0x7b, 0x10, 0x05, 0xac, 0x0d, 0x89,
- 0xdb, 0x83, 0x85, 0x8c, 0x5a, 0x78, 0x66, 0x9a, 0x58, 0xdd, 0x20, 0x9f,
- 0x3b, 0x9f, 0xac, 0x3b, 0xd5, 0xdb, 0xb9, 0x4a, 0xd5, 0xa9, 0x00, 0xfb,
- 0x40, 0xac, 0xbf, 0x98, 0xbe, 0x31, 0x9a, 0xab, 0x73, 0x42, 0xde, 0x80,
- 0xc7, 0x87, 0xa9, 0x2b, 0x6c, 0x10, 0xe0, 0x28, 0xbe, 0xe0, 0xec, 0x47,
- 0xa7, 0xfb, 0x62, 0x9b, 0x94, 0x9a, 0xa9, 0xd6, 0x72, 0xa8, 0x95, 0x90,
- 0x33, 0x73, 0x72, 0xd6, 0x86, 0x2e, 0x69, 0x92, 0xbc, 0xcb, 0x61, 0x76,
- 0xf9, 0x52, 0x54, 0x6f, 0xa7, 0xd8, 0x92, 0x3d, 0x14, 0x31, 0x03, 0x76,
- 0x3b, 0x4d, 0xe4, 0xcc, 0xcd, 0x23, 0x58, 0xbb, 0x8d, 0xa2, 0xe9, 0x04,
- 0xd9, 0x20, 0x04, 0x8d, 0xbd, 0x76, 0xc4, 0xf3, 0x2a, 0x55, 0x33, 0x44,
- 0x4c, 0xf6, 0x22, 0xe5, 0x27, 0xa6, 0xae, 0xa2, 0xe4, 0xa0, 0x96, 0x44,
- 0x72, 0x6e, 0x0d, 0x85, 0xcd, 0x87, 0x6b, 0x5e, 0xff, 0x00, 0xbe, 0x3d,
- 0xa6, 0x9a, 0x94, 0x98, 0xa7, 0xcb, 0x4a, 0x4c, 0xb4, 0x16, 0x14, 0x9b,
- 0xe6, 0x01, 0xcf, 0x2d, 0xb5, 0xdf, 0x50, 0x41, 0x89, 0x54, 0x8c, 0xa3,
- 0xc2, 0xa1, 0x3d, 0x50, 0x65, 0xee, 0x12, 0x85, 0x81, 0x62, 0x6c, 0x2d,
- 0x62, 0x49, 0xdc, 0x65, 0x6d, 0xd2, 0x44, 0x5c, 0x1e, 0xcf, 0x3d, 0x5a,
- 0x62, 0xa4, 0xe5, 0x3e, 0xa5, 0x50, 0xa7, 0xd2, 0xdd, 0x49, 0xd2, 0x84,
- 0xbc, 0xd6, 0x95, 0x39, 0xcd, 0x82, 0x6f, 0x7b, 0xf1, 0xce, 0xe0, 0x7a,
- 0xe1, 0x83, 0x20, 0xbf, 0xd4, 0x0a, 0xad, 0x42, 0x4b, 0xd5, 0x6c, 0xe0,
- 0xf1, 0x66, 0x24, 0xe6, 0xee, 0xcb, 0x6d, 0x20, 0x02, 0x9b, 0x82, 0x52,
- 0xab, 0x0f, 0x4d, 0x88, 0xf7, 0xc1, 0x8c, 0xd5, 0x2e, 0x8a, 0x7a, 0x5d,
- 0x4e, 0x8b, 0x5b, 0x8e, 0xd2, 0xab, 0x06, 0xea, 0x50, 0x6d, 0x3b, 0xa1,
- 0xb2, 0xa3, 0xa0, 0x58, 0x7f, 0xcc, 0x50, 0xb5, 0x80, 0xdc, 0x83, 0xbe,
- 0x24, 0xbd, 0x36, 0xcc, 0x33, 0xb2, 0xcd, 0x54, 0x25, 0x42, 0x4a, 0x5a,
- 0x2e, 0x02, 0x96, 0xdc, 0x90, 0x4a, 0x55, 0x7d, 0x89, 0xb7, 0x04, 0x81,
- 0xff, 0x00, 0xd6, 0xf8, 0x54, 0xad, 0xe1, 0x4a, 0x6d, 0x38, 0x07, 0x19,
- 0x69, 0x20, 0x1b, 0xe4, 0x52, 0x2f, 0x96, 0xe0, 0xf2, 0x3b, 0x7d, 0x61,
- 0xaf, 0x0d, 0x62, 0x79, 0x8a, 0xb0, 0x52, 0x1c, 0x02, 0xe9, 0x09, 0xcc,
- 0x68, 0x4a, 0x85, 0xed, 0xa7, 0xf9, 0x0d, 0xc7, 0x8e, 0xd1, 0xd8, 0x64,
- 0xff, 0x00, 0xc5, 0xb4, 0xd3, 0x68, 0x05, 0x28, 0x0a, 0x5a, 0x92, 0x4f,
- 0xe5, 0x4b, 0x97, 0xb7, 0xe8, 0x71, 0x1a, 0xab, 0xfe, 0x21, 0x29, 0xd4,
- 0x7e, 0xa5, 0xce, 0xca, 0x35, 0xea, 0x64, 0x91, 0x09, 0x01, 0x05, 0x12,
- 0xda, 0x40, 0x50, 0x4e, 0xa1, 0xdd, 0x3c, 0xd8, 0x7a, 0xef, 0x8a, 0xc5,
- 0x36, 0xa9, 0x0e, 0x44, 0x84, 0xe8, 0x73, 0xfb, 0x59, 0x2c, 0x29, 0x4d,
- 0xa7, 0xbf, 0x65, 0x7f, 0xa1, 0xc7, 0x13, 0xf5, 0x06, 0x9b, 0x52, 0xac,
- 0xfe, 0x20, 0x6a, 0x90, 0x20, 0x45, 0x91, 0x2a, 0x5b, 0x8b, 0x6d, 0xb6,
- 0x19, 0x6c, 0x5d, 0x4b, 0xb2, 0x78, 0x1f, 0xbe, 0xfc, 0x0c, 0x21, 0x61,
- 0xb9, 0x66, 0xa7, 0xdb, 0xb3, 0xa7, 0x44, 0x2b, 0x43, 0x6b, 0x10, 0xb4,
- 0x81, 0xec, 0x77, 0xb8, 0xcc, 0xc1, 0xa7, 0xf8, 0x99, 0x48, 0x36, 0xce,
- 0xe0, 0x67, 0xc8, 0x85, 0x1f, 0xa6, 0xa2, 0x3a, 0x3b, 0x33, 0xe4, 0x8c,
- 0x85, 0xd4, 0x46, 0xda, 0xae, 0x52, 0xc4, 0x07, 0x64, 0x2e, 0xc0, 0x49,
- 0x61, 0x00, 0x2b, 0xe8, 0xbb, 0x6f, 0xbe, 0x14, 0xab, 0xb9, 0x30, 0x50,
- 0x22, 0xff, 0x00, 0x0f, 0xfe, 0x13, 0x18, 0x7c, 0x72, 0x96, 0xc0, 0x90,
- 0x41, 0x29, 0x41, 0x50, 0xb0, 0xbf, 0x1e, 0x5e, 0x76, 0xdb, 0xdc, 0xfa,
- 0xb5, 0xf4, 0xeb, 0x24, 0x53, 0x7a, 0x71, 0x45, 0x44, 0xe6};
-
-std::vector<uint8_t> l2cap_test_packet_4 = {
- 0xf6, 0x03, 0x47, 0x00, 0x08, 0xc1, 0x7a, 0xa1, 0x5b, 0xa8, 0x32, 0x89,
- 0xd3, 0x96, 0xda, 0xa5, 0x25, 0xb5, 0xf9, 0x1b, 0x08, 0x3a, 0x92, 0x80,
- 0x7f, 0x32, 0xb5, 0x5a, 0xea, 0xf6, 0xb0, 0xbe, 0x06, 0x75, 0x3e, 0xa9,
- 0x5a, 0xce, 0x51, 0xa1, 0xc3, 0xa7, 0xb0, 0x61, 0xc5, 0x5c, 0x80, 0x59,
- 0x52, 0x8d, 0x9c, 0x58, 0x48, 0x24, 0x1b, 0x7e, 0x54, 0xef, 0xdf, 0x72,
- 0x71, 0xda, 0x98, 0xf4, 0xe8, 0x9f, 0xec, 0xa5, 0x9d, 0x2e, 0x32, 0x35,
- 0xb8, 0xc8, 0x78, 0x03, 0xe9, 0xa6, 0xa7, 0x6b, 0x46, 0x87, 0xc3, 0x45,
- 0xae, 0x35, 0xa4, 0x5f, 0x9e, 0xff, 0x00, 0xbf, 0xa6, 0x9b, 0xc2, 0xfc,
- 0xa9, 0xf1, 0x13, 0x97, 0xbc, 0x4a, 0x32, 0x2e, 0xd4, 0x0b, 0xb4, 0xa0,
- 0x11, 0xa7, 0xcc, 0xd3, 0x89, 0x52, 0x94, 0x94, 0x8b, 0x00, 0x2f, 0x72,
- 0x3d, 0xb1, 0x36, 0xeb, 0x1c, 0x07, 0x28, 0xd3, 0x6b, 0xb4, 0xc9, 0x4e,
- 0x15, 0x25, 0x82, 0xb5, 0x31, 0xa4, 0xdd, 0x29, 0x4a, 0x9c, 0x43, 0xa9,
- 0x23, 0xfc, 0xaa, 0xfd, 0xf1, 0xbb, 0x2e, 0x55, 0x6a, 0x87, 0x1a, 0xbc,
- 0x89, 0x20, 0x29, 0x69, 0x63, 0x5a, 0x52, 0xb0, 0x6c, 0x51, 0xa1, 0x40,
- 0xf1, 0xea, 0x06, 0x06, 0x67, 0xc9, 0x92, 0x33, 0x14, 0x36, 0xe4, 0xcb,
- 0x5f, 0x8a, 0xec, 0x9a, 0x6c, 0x7b, 0xab, 0x48, 0x04, 0xff, 0x00, 0x62,
- 0x11, 0xfb, 0x14, 0xe2, 0xb3, 0x88, 0x78, 0x7f, 0x01, 0x26, 0xb3, 0xa8,
- 0x03, 0xe9, 0xfa, 0x46, 0x4f, 0x85, 0x0c, 0x3c, 0xa9, 0xba, 0xd4, 0xba,
- 0x45, 0xc2, 0xc5, 0xc5, 0xb5, 0xe2, 0xb1, 0xb7, 0xce, 0xde, 0x71, 0x36,
- 0xa6, 0x4b, 0xaa, 0xbf, 0x20, 0x98, 0xaf, 0x68, 0x69, 0xb4, 0xdf, 0x4d,
- 0xb6, 0xb0, 0xf6, 0xe4, 0x93, 0x87, 0x95, 0xaa, 0x38, 0xa5, 0x44, 0x4a,
- 0x81, 0xf8, 0xd4, 0xeb, 0x32, 0x1d, 0x1b, 0x21, 0x49, 0x36, 0x29, 0xb0,
- 0xf5, 0x1b, 0xdc, 0xfd, 0x30, 0x0f, 0x2d, 0xd1, 0xd3, 0x0d, 0xa6, 0xde,
- 0xa8, 0xb8, 0x12, 0xb0, 0x2f, 0x60, 0x0a, 0x83, 0x7b, 0x6f, 0x6b, 0x72,
- 0xac, 0x36, 0xd2, 0xa8, 0x46, 0xbb, 0x1e, 0x4c, 0xa8, 0x92, 0x22, 0xa0,
- 0x34, 0xc9, 0x71, 0xa6, 0x0b, 0xa1, 0x4a, 0x3d, 0xbc, 0xd6, 0x3b, 0x2b,
- 0x93, 0x7e, 0x01, 0xdb, 0x9c, 0x28, 0x4c, 0xad, 0x2e, 0x2a, 0xc8, 0x02,
- 0xdc, 0xe2, 0xc1, 0x46, 0x2f, 0x50, 0x25, 0x7f, 0x11, 0x50, 0x75, 0x5c,
- 0x4a, 0xff, 0x00, 0x16, 0xef, 0xa7, 0x5b, 0xe9, 0xd3, 0x6d, 0xf3, 0xc8,
- 0x6e, 0xf4, 0xff, 0x00, 0x3d, 0x4c, 0xca, 0xf9, 0x88, 0x7c, 0x2c, 0x1d,
- 0x46, 0x63, 0x29, 0x6c, 0xa4, 0x27, 0x40, 0xb2, 0x38, 0x59, 0xf5, 0x27,
- 0x7f, 0xd7, 0x1d, 0x08, 0xce, 0x65, 0x6e, 0xa7, 0x54, 0xa7, 0x4f, 0xac,
- 0xa6, 0x3c, 0x79, 0x29, 0x7e, 0x13, 0xc8, 0x49, 0x50, 0x05, 0x45, 0xd0,
- 0xa4, 0xad, 0x36, 0xfc, 0xdc, 0x03, 0x8e, 0x7d, 0x32, 0xa0, 0x57, 0xa9,
- 0x52, 0x6a, 0xeb, 0x52, 0x19, 0xaa, 0x46, 0x8a, 0x52, 0x96, 0xb4, 0x24,
- 0x2d, 0xc2, 0x15, 0xdf, 0xe8, 0x07, 0x1c, 0x91, 0xfa, 0x63, 0xa0, 0xf3,
- 0x25, 0x39, 0x0e, 0x51, 0x29, 0x12, 0xc2, 0x59, 0xb3, 0x52, 0x60, 0x91,
- 0x74, 0x0b, 0xdb, 0xc3, 0x3d, 0xff, 0x00, 0x4c, 0x14, 0xa5, 0x29, 0x69,
- 0x70, 0x24, 0x69, 0xcb, 0xce, 0x13, 0xa6, 0xa7, 0x45, 0x49, 0xf7, 0x5d,
- 0x75, 0x20, 0x29, 0x79, 0x65, 0xb0, 0xd2, 0xde, 0x62, 0x21, 0xff, 0x00,
- 0x88, 0xf6, 0x9b, 0xa9, 0x52, 0x2a, 0xb2, 0xa1, 0x21, 0x6d, 0x21, 0x55,
- 0x37, 0x96, 0xce, 0xa1, 0xa4, 0xe8, 0x52, 0xc1, 0xbe, 0x9e, 0xc2, 0xd7,
- 0xdb, 0x12, 0x9e, 0x9c, 0xd2, 0xe6, 0xd5, 0x5f, 0x31, 0xe1, 0x34, 0xeb,
- 0xce, 0xa9, 0x77, 0x5a, 0x95, 0xe6, 0x48, 0x48, 0x16, 0x25, 0x46, 0xf6,
- 0x03, 0x91, 0x8b, 0xa6, 0x64, 0xa0, 0x53, 0xb3, 0x35, 0x3e, 0x43, 0x55,
- 0x17, 0x8b, 0x4d, 0x25, 0xe2, 0xe2, 0x8a, 0x57, 0xa7, 0x6b, 0x9b, 0x8b,
- 0x8c, 0x20, 0x55, 0xf3, 0xad, 0x03, 0x2c, 0x43, 0x5e, 0x5a, 0xca, 0x8c,
- 0xc6, 0x6e, 0xc7, 0x77, 0xd1, 0x65, 0x24, 0x2b, 0xde, 0xff, 0x00, 0x3e,
- 0x29, 0x53, 0xb4, 0xa6, 0x9e, 0x71, 0x2f, 0xbc, 0xab, 0x21, 0x09, 0x00,
- 0xff, 0x00, 0x3f, 0x66, 0x3e, 0x6d, 0xa0, 0xe2, 0x09, 0xa6, 0xd8, 0x5c,
- 0x8c, 0x8b, 0x65, 0x4f, 0x95, 0xa8, 0xdf, 0xf2, 0xa4, 0x13, 0xaf, 0xcf,
- 0x28, 0x6c, 0x8e, 0xec, 0x2c, 0xa7, 0x0d, 0x98, 0xad, 0x3d, 0xfc, 0x46,
- 0xa5, 0x21, 0x21, 0xa4, 0x45, 0x8e, 0x92, 0x55, 0xb7, 0x01, 0x29, 0xf4,
- 0xdc, 0xf9, 0x8f, 0xfa, 0x63, 0xe2, 0xa1, 0x42, 0xcc, 0xf5, 0x67, 0x04,
- 0xfa, 0xac, 0x96, 0xd8, 0x75, 0x2b, 0x40, 0x6a, 0x1b, 0x67, 0x59, 0x66,
- 0xff, 0x00, 0x4f, 0x99, 0x7f, 0xb0, 0xf7, 0xc0, 0x8c, 0x9b, 0x51, 0xa7,
- 0x46, 0xa6, 0xaa, 0x5c, 0xe9, 0xaf, 0x3d, 0x52, 0x99, 0xaf, 0xc5, 0x74,
- 0x2e, 0xca, 0x52, 0x38, 0xb1, 0x3f, 0x30, 0x16, 0xbe, 0xc2, 0xc3, 0x7c,
- 0x51, 0x1e, 0xcd, 0xd4, 0xc5, 0x25, 0xa8, 0xca, 0x9d, 0x09, 0x98, 0xcd,
- 0xa5, 0xb6, 0x8a, 0x84, 0x93, 0xad, 0x56, 0x1c, 0x9b, 0x26, 0xfe, 0xbb,
- 0x8e, 0x6f, 0x85, 0xaa, 0x96, 0x21, 0x2a, 0x4f, 0xe1, 0xa4, 0xc7, 0x0a,
- 0x34, 0xbe, 0xe7, 0xa7, 0x21, 0xef, 0x0e, 0x94, 0x6c, 0x22, 0xdc, 0xab,
- 0x9f, 0x8d, 0x9d, 0x3d, 0xac, 0xc1, 0xcc, 0x93, 0x98, 0x1d, 0x07, 0x84,
- 0x44, 0x73, 0x33, 0xd3, 0xe9, 0x30, 0x26, 0x95, 0xbb, 0xe3, 0x04, 0xb6,
- 0x94, 0x3e, 0x82, 0x2d, 0x72, 0x97, 0x08, 0xbe, 0xde, 0x84, 0x1c, 0x51,
- 0xba, 0x0d, 0x3d, 0x72, 0x29, 0x25, 0x6c, 0x48, 0x5b, 0x5a, 0x96, 0x97,
- 0x2e, 0xa2, 0x12, 0x1b, 0x00, 0x8b, 0xf3, 0x7b, 0xdf, 0xb6, 0x17, 0xb3,
- 0x4c, 0x5a, 0x6d, 0x43, 0x2d, 0x66, 0x37, 0x20, 0xba, 0x99, 0x29, 0x44,
- 0x67, 0x9c, 0x2e, 0x24, 0x6c, 0x56, 0x97, 0x8a, 0xbf, 0xf8, 0xd8, 0xfd,
- 0xf1, 0xf5, 0xf8, 0x7d, 0x6c, 0x38, 0x66, 0x43, 0x4a, 0x1d, 0xf0, 0x8b,
- 0xc1, 0xd0, 0x7c, 0x3b, 0xa5, 0x28, 0xd3, 0x7b, 0x0b, 0x5f, 0xbe, 0xd6,
- 0x27, 0x1e, 0x63, 0x04, 0x36, 0x4b, 0x2e, 0xb7, 0xba, 0x47, 0xb4, 0x3e,
- 0xcf, 0xa5, 0x60, 0xa0, 0xab, 0x74, 0x88, 0x1f, 0x4d, 0x6a, 0x75, 0x5a,
- 0x85, 0x98, 0xe0, 0xb0, 0x94, 0x95, 0x49, 0x75, 0xb6, 0xc0, 0xe6, 0xc0,
- 0x5a, 0xdb, 0xfa, 0x5b, 0x9c, 0x13, 0xc9, 0xf5, 0xea, 0x5f, 0x4b, 0xa2,
- 0x4c, 0xa8, 0xc4, 0x9e, 0xc2, 0x6b, 0x13, 0x9b, 0x51, 0x54, 0x94, 0xb4,
- 0x16, 0xea, 0x49, 0x04, 0x14, 0xb6, 0x54, 0x3c, 0xa9, 0x17, 0xed, 0xb9,
- 0x3e, 0x98, 0x0f, 0x42, 0x62, 0xa9, 0x22, 0x74, 0xb8, 0x14, 0xe9, 0x11,
- 0x23, 0xc7, 0x92, 0xe0, 0x52, 0xca, 0x95, 0xa0, 0x71, 0x62, 0x9d, 0x86,
- 0xff, 0x00, 0x41, 0x6b, 0xf0, 0x4e, 0x08, 0x37, 0xd1, 0x25, 0x57, 0x67,
- 0x99, 0x55, 0x4c, 0xd8, 0xb5, 0xb8, 0xad, 0x92, 0x94, 0x37, 0xa7, 0x48,
- 0xec, 0x07, 0x60, 0x31, 0x96, 0x6b, 0x15, 0x52, 0x29, 0xf2, 0xad, 0x05,
- 0xaa, 0xee, 0x84, 0x81, 0xa1, 0x36, 0xc8, 0x5e, 0xff, 0x00, 0x7e, 0xd1,
- 0x3c, 0x6b, 0x0b, 0x55, 0xa7, 0x66, 0x5e, 0xba, 0xb8, 0x18, 0x52, 0xf8,
- 0xb2, 0x20, 0x15, 0x1d, 0xb3, 0xfb, 0xf3, 0x3a, 0xb0, 0x21};
-
-std::vector<uint8_t> l2cap_test_packet_5 = {
- 0xf6, 0x03, 0x47, 0x00, 0x0a, 0xc1, 0x0a, 0x8d, 0x2e, 0xa1, 0x99, 0xd9,
- 0x12, 0x98, 0xab, 0x13, 0x50, 0x64, 0x87, 0x9b, 0xf1, 0x1c, 0xb0, 0x48,
- 0xd4, 0x76, 0x1f, 0xdd, 0x1e, 0xa7, 0xe8, 0x37, 0xbe, 0x1b, 0xe9, 0x35,
- 0x68, 0x53, 0x99, 0x55, 0x32, 0x7c, 0x66, 0x51, 0x53, 0x41, 0x0e, 0x3c,
- 0xeb, 0x29, 0x1e, 0x1b, 0x8d, 0x95, 0x69, 0x0b, 0xd8, 0xec, 0x49, 0x3f,
- 0x4d, 0xb0, 0x73, 0x2e, 0xf4, 0x5f, 0x24, 0xd0, 0x90, 0xbf, 0x8e, 0xcd,
- 0x32, 0x8b, 0x65, 0x43, 0xc4, 0x02, 0x62, 0x12, 0x92, 0x47, 0xaf, 0x9a,
- 0xe7, 0xe9, 0x86, 0x58, 0x39, 0x6b, 0xa3, 0x14, 0x79, 0xc9, 0x9a, 0xe5,
- 0x4a, 0x13, 0xb2, 0xda, 0x01, 0x21, 0xc7, 0x65, 0xeb, 0xb0, 0x1c, 0x6c,
- 0x4e, 0x9b, 0x62, 0x73, 0x52, 0xc5, 0xcd, 0x4d, 0x3a, 0x57, 0xc2, 0xb5,
- 0x93, 0xc9, 0x3f, 0xc6, 0x50, 0xf7, 0x23, 0x4e, 0x44, 0xab, 0x61, 0xb6,
- 0x80, 0x00, 0x6c, 0x9f, 0xd8, 0x6b, 0xce, 0x1b, 0x24, 0x43, 0x99, 0x1a,
- 0x65, 0x00, 0x38, 0xb5, 0x29, 0x25, 0xa5, 0xb4, 0xbb, 0x7a, 0xea, 0x40,
- 0xfe, 0x98, 0xf0, 0xae, 0xcd, 0xc9, 0x3d, 0x32, 0x7a, 0xa7, 0x99, 0x24,
- 0x31, 0x09, 0x35, 0x49, 0x48, 0x4a, 0x65, 0xc9, 0x2b, 0x25, 0xd2, 0x81,
- 0xc2, 0x4a, 0xbf, 0x28, 0x3f, 0xdc, 0x4e, 0xe4, 0xf3, 0x7c, 0x22, 0x75,
- 0xaf, 0xad, 0x59, 0x7e, 0x9b, 0x0e, 0x9f, 0x13, 0x2c, 0x4c, 0x6e, 0x6c,
- 0xf2, 0xfa, 0x34, 0xe8, 0x21, 0xd0, 0x11, 0xbe, 0xa2, 0x42, 0x4d, 0xf7,
- 0xd8, 0x0e, 0x09, 0x3c, 0x71, 0x88, 0xd6, 0x70, 0xcd, 0x31, 0xf3, 0x25,
- 0x41, 0x2e, 0xd5, 0x68, 0x95, 0x29, 0xe9, 0x4a, 0x8a, 0xc3, 0x0b, 0x49,
- 0x4a, 0x50, 0xa3, 0xed, 0xdc, 0xf6, 0xb9, 0xdf, 0x18, 0xf0, 0xa6, 0x0d,
- 0xa8, 0x55, 0x07, 0x6a, 0xb5, 0x76, 0x4d, 0xd8, 0x85, 0x0c, 0xee, 0x41,
- 0x37, 0xb5, 0xad, 0xa1, 0xf1, 0xcb, 0x2d, 0xe3, 0xde, 0xa9, 0x5b, 0x6a,
- 0x59, 0x09, 0x41, 0x69, 0x4e, 0x2f, 0x50, 0x00, 0x16, 0xbe, 0xd7, 0x37,
- 0xca, 0xc3, 0x61, 0x99, 0xbe, 0xd0, 0xe3, 0x37, 0xac, 0xc9, 0xcd, 0xb9,
- 0x8d, 0x72, 0x65, 0xca, 0x8d, 0x1a, 0x9f, 0x1d, 0xc0, 0x98, 0xa8, 0x20,
- 0x0d, 0x42, 0xe4, 0x03, 0x63, 0xb8, 0x16, 0x37, 0xb7, 0x3f, 0xd0, 0x3d,
- 0x2b, 0xa9, 0x52, 0xa8, 0xb5, 0x1b, 0xc2, 0x9e, 0xa9, 0x3e, 0x0a, 0xac,
- 0xea, 0x96, 0x92, 0xef, 0x8e, 0x02, 0x48, 0xb6, 0xc3, 0x6d, 0xcf, 0x3e,
- 0xc3, 0x1e, 0x39, 0x2a, 0x3c, 0x19, 0xad, 0x95, 0x46, 0xc8, 0xae, 0xb0,
- 0x11, 0x75, 0x17, 0x9d, 0x6d, 0x94, 0x22, 0xd7, 0xb5, 0xb5, 0x38, 0x40,
- 0xf6, 0xe4, 0x9f, 0x6c, 0x13, 0x55, 0x4e, 0xbe, 0x89, 0x0e, 0xb1, 0x0b,
- 0x25, 0x25, 0xf0, 0xcb, 0xab, 0x6c, 0x3a, 0xd8, 0x6d, 0x68, 0x5d, 0xb7,
- 0xd8, 0xa4, 0xd8, 0xd8, 0x11, 0x72, 0x0d, 0xb1, 0x5d, 0x63, 0x05, 0xca,
- 0xa1, 0x29, 0x42, 0x5c, 0xb0, 0x1a, 0x00, 0x3f, 0x7b, 0xf9, 0x98, 0x4a,
- 0xfe, 0xb9, 0x5b, 0x71, 0xc2, 0x96, 0xa4, 0x14, 0xa2, 0x79, 0xe5, 0x97,
- 0x90, 0xb5, 0xba, 0x46, 0xf3, 0x75, 0x37, 0x73, 0x65, 0x1e, 0xb1, 0x53,
- 0x96, 0xd2, 0x51, 0x25, 0xe8, 0x2a, 0x43, 0x89, 0x4b, 0x6a, 0x4e, 0xe1,
- 0xb2, 0x01, 0x37, 0xee, 0x7f, 0x7b, 0x13, 0x8d, 0x2a, 0xad, 0x06, 0xac,
- 0xed, 0x0f, 0x2f, 0xcd, 0x85, 0x49, 0x95, 0x22, 0x3b, 0xb4, 0xb6, 0x42,
- 0x5c, 0x61, 0xa5, 0x2c, 0x13, 0xa4, 0x13, 0x7b, 0x0d, 0x8d, 0xcf, 0x7c,
- 0x7d, 0x48, 0x77, 0xa8, 0xd2, 0xe9, 0xef, 0xf8, 0x39, 0x6d, 0x2c, 0xc7,
- 0x28, 0x50, 0x71, 0x20, 0x04, 0xdd, 0x36, 0xdc, 0x12, 0x2e, 0x78, 0xf4,
- 0xdf, 0x1e, 0x1d, 0x31, 0xce, 0x99, 0xaa, 0x9b, 0x96, 0xc5, 0x39, 0xfa,
- 0xb5, 0x3a, 0x0e, 0x95, 0xa9, 0xa6, 0x93, 0xf1, 0x0a, 0x42, 0x96, 0x80,
- 0x4d, 0xb5, 0x24, 0x0b, 0x0b, 0x5e, 0xc0, 0x92, 0x36, 0x03, 0x1a, 0xeb,
- 0xf4, 0xd0, 0xe4, 0xa3, 0x52, 0xa8, 0x24, 0xf0, 0xee, 0x6c, 0x32, 0x1c,
- 0xc9, 0xb0, 0x83, 0x38, 0x0e, 0x7a, 0xa5, 0x86, 0x2a, 0x53, 0x35, 0x2a,
- 0x8b, 0x25, 0x01, 0xdd, 0x12, 0x02, 0x95, 0x9f, 0x44, 0x82, 0x72, 0x19,
- 0xe9, 0x68, 0x13, 0x23, 0x20, 0x67, 0x9a, 0xa2, 0xd2, 0x5a, 0xa5, 0xaa,
- 0x24, 0x72, 0x6c, 0x16, 0xf1, 0xd3, 0x72, 0x76, 0x16, 0xc3, 0x36, 0x42,
- 0xe9, 0x8e, 0x68, 0xa5, 0x3a, 0xec, 0x31, 0x5e, 0xa2, 0x35, 0x2a, 0x45,
- 0x99, 0x0d, 0xf8, 0xda, 0x9c, 0x4a, 0xb7, 0x16, 0x00, 0x7e, 0x6d, 0xef,
- 0xf5, 0x03, 0x04, 0x17, 0x54, 0xcc, 0x09, 0x74, 0x3e, 0xac, 0xcd, 0x1d,
- 0x85, 0x83, 0xa8, 0x29, 0x0b, 0x2a, 0x50, 0xf7, 0x1e, 0x71, 0x8d, 0x79,
- 0xf9, 0x8e, 0xb7, 0xf0, 0x4e, 0xd3, 0x0e, 0x64, 0x68, 0xb6, 0xe5, 0xd0,
- 0xa9, 0xa1, 0xd8, 0xed, 0xad, 0x77, 0x37, 0x2a, 0xb6, 0x92, 0xb2, 0x77,
- 0x3c, 0xaa, 0xfe, 0xf8, 0x0a, 0xde, 0x16, 0x9c, 0x29, 0xe0, 0x20, 0x01,
- 0xd4, 0x7d, 0x2f, 0x05, 0x2a, 0xbf, 0x13, 0xe8, 0x73, 0x93, 0x05, 0xd2,
- 0x54, 0xe2, 0x8f, 0x81, 0x00, 0x0f, 0x00, 0x48, 0x19, 0x72, 0xd4, 0xc1,
- 0x8c, 0xbf, 0xd0, 0xc9, 0x10, 0xa5, 0x2e, 0x54, 0x9c, 0xe1, 0x19, 0x84,
- 0xa9, 0x65, 0x4a, 0x07, 0x65, 0x13, 0xde, 0xfa, 0xad, 0x7d, 0xfd, 0x71,
- 0x4a, 0xcf, 0x79, 0x96, 0x83, 0x46, 0xca, 0xb1, 0x62, 0xbb, 0x5c, 0x8b,
- 0x29, 0xf8, 0xcf, 0x32, 0xe2, 0xfc, 0x35, 0x02, 0x43, 0x6d, 0x24, 0xdd,
- 0x4a, 0xb6, 0xc3, 0xf2, 0x8d, 0xf9, 0x27, 0x10, 0x77, 0x17, 0x45, 0xf1,
- 0x94, 0x26, 0x66, 0xb9, 0x4f, 0xac, 0x9e, 0x4a, 0x91, 0x73, 0xf7, 0xb1,
- 0xc7, 0xb5, 0x7b, 0x2a, 0x51, 0x6a, 0x79, 0x3e, 0x5c, 0xc8, 0x95, 0x19,
- 0xcf, 0xa9, 0xa4, 0xeb, 0xb2, 0x9f, 0x51, 0x06, 0xde, 0xa3, 0x83, 0x82,
- 0xac, 0xe1, 0xa9, 0x86, 0x7b, 0xe9, 0x29, 0xe2, 0xea, 0x4f, 0xd2, 0x03,
- 0x2f, 0xe2, 0x75, 0x19, 0xa7, 0x12, 0x7b, 0x27, 0x2d, 0x71, 0x6e, 0xe8,
- 0x02, 0xfb, 0x5c, 0xdc, 0x9b, 0x40, 0x2c, 0xcf, 0x57, 0xa5, 0xc9, 0x6e,
- 0x75, 0x35, 0x55, 0xa5, 0xb1, 0x19, 0xc7, 0x54, 0x7c, 0x26, 0x93, 0x7b,
- 0x79, 0x89, 0xb0, 0x3b, 0x6d, 0x85, 0x08, 0xd4, 0x6c, 0xa4, 0xf4, 0x84,
- 0x80, 0x9a, 0x9c, 0x85, 0x13, 0x62, 0xb2, 0xda, 0x95, 0xfa, 0x01, 0x8e,
- 0x87, 0x43, 0xf1, 0x29, 0x61, 0x8a, 0x76, 0x5c, 0xc9, 0xf4, 0x09, 0x50,
- 0x62, 0x46, 0x6c, 0x27, 0xc6, 0x6c, 0xba, 0xe3, 0xde, 0x51, 0xa9, 0x45,
- 0x77, 0xe4, 0x9b, 0xf0, 0x0f, 0xdf, 0x18, 0xff, 0x00, 0x54, 0x59, 0xa4,
- 0x7f, 0x66, 0x3a, 0x74, 0xc4, 0x37, 0x00, 0xf9, 0xda, 0x4a, 0x54, 0x01,
- 0xf6, 0xf2, 0x7f, 0xa8, 0x18, 0x2d, 0x3f, 0x3d, 0x34, 0x5b, 0x4a, 0x9e,
- 0x65, 0x27, 0xc8, 0x9b, 0x75, 0x17, 0xfa, 0x43, 0xf4, 0xae, 0x1a, 0x69,
- 0x94, 0x87, 0x99, 0x96, 0x48, 0x0b, 0xef, 0x1b, 0x01, 0xbe, 0xe7, 0x33,
- 0x6f, 0x41, 0x12, 0x68, 0xb9, 0x4d, 0x86, 0x23, 0x7c, 0x44, 0x6a, 0x0d,
- 0x5a, 0x53, 0x62, 0xca, 0xf2, 0xc5, 0x74, 0x5c, 0x7d, 0x54, 0x9b, 0x71,
- 0xef, 0x82, 0xf0, 0x32, 0x95, 0x69, 0x6f, 0x29, 0x11, 0xb2, 0x24, 0x97,
- 0xd2, 0x4d, 0xd2, 0x5f, 0x6c, 0xa4, 0xe9, 0x3c, 0x96, 0xae};
-
-std::vector<uint8_t> l2cap_test_packet_6 = {
- 0xf6, 0x03, 0x47, 0x00, 0x0c, 0xc1, 0x5c, 0x0b, 0x8c, 0x33, 0x2b, 0xac,
- 0x14, 0x79, 0x95, 0x37, 0x6a, 0x2b, 0xca, 0x2e, 0xbb, 0x31, 0x0b, 0x4b,
- 0x8a, 0x2a, 0x71, 0xd2, 0x02, 0xbb, 0x10, 0x92, 0x42, 0x47, 0x1c, 0x01,
- 0x82, 0x8b, 0xeb, 0x4e, 0x66, 0x76, 0x58, 0x71, 0x14, 0xe9, 0x11, 0x12,
- 0xf0, 0xd4, 0x35, 0x35, 0x74, 0xda, 0xc3, 0x72, 0x49, 0x36, 0xda, 0xdc,
- 0xe1, 0x69, 0x58, 0x8d, 0x6d, 0x9e, 0xe8, 0x48, 0xe8, 0x91, 0x1d, 0x84,
- 0xc2, 0x19, 0x3c, 0x29, 0x09, 0x1e, 0x9f, 0x40, 0x60, 0x2b, 0x99, 0x1f,
- 0xa9, 0x12, 0x68, 0x52, 0xa0, 0xc4, 0xa0, 0xc3, 0xa7, 0x46, 0x76, 0x3a,
- 0xdb, 0x5a, 0x02, 0x14, 0x14, 0xa4, 0x11, 0xba, 0x45, 0xc5, 0x85, 0xfd,
- 0x70, 0x13, 0xa5, 0xd9, 0x39, 0xd8, 0xcb, 0xf0, 0x5a, 0x9d, 0x32, 0x9a,
- 0xea, 0xd6, 0x59, 0x90, 0x1a, 0x59, 0x2a, 0x4a, 0xfd, 0x2c, 0x38, 0xb5,
- 0xb1, 0xd1, 0x7d, 0x1c, 0xcd, 0x33, 0xb3, 0x35, 0x0d, 0xea, 0x9c, 0x97,
- 0x94, 0xb2, 0xd4, 0xa2, 0xc3, 0x8d, 0xad, 0x20, 0x8b, 0x69, 0x06, 0xe0,
- 0x81, 0xf5, 0x18, 0x8b, 0xe7, 0x5f, 0x8a, 0xa4, 0x75, 0x36, 0xac, 0x23,
- 0xad, 0x49, 0x40, 0x9e, 0x56, 0x50, 0xa2, 0x40, 0x20, 0x80, 0x47, 0x18,
- 0x15, 0x58, 0x9f, 0x76, 0x71, 0xa4, 0xba, 0xb5, 0x5c, 0x79, 0x0f, 0xbd,
- 0x20, 0x7c, 0xea, 0xbf, 0x11, 0x72, 0x75, 0x1f, 0x28, 0x97, 0x3a, 0xc5,
- 0x52, 0xb5, 0x29, 0x70, 0x68, 0xb2, 0xdc, 0x8f, 0x31, 0x0d, 0x97, 0x95,
- 0xe1, 0x91, 0x7d, 0xd4, 0x76, 0xbd, 0xf6, 0xb5, 0xb9, 0xde, 0xfb, 0x61,
- 0x36, 0xb9, 0xfc, 0xcf, 0x47, 0x7c, 0xb5, 0x57, 0x7e, 0xb3, 0xc6, 0xea,
- 0x4c, 0x85, 0x14, 0x1f, 0xdf, 0x0d, 0x9d, 0x3b, 0x8f, 0x36, 0x99, 0x9b,
- 0xeb, 0x4b, 0x1a, 0x89, 0x6a, 0x31, 0xb1, 0x4f, 0x3a, 0x49, 0x2b, 0xb8,
- 0x27, 0xd8, 0x7e, 0xa7, 0x1e, 0x39, 0x6b, 0xa9, 0x5f, 0x1c, 0xfb, 0xb1,
- 0x6b, 0xd1, 0x14, 0xe2, 0x5c, 0x73, 0x50, 0x79, 0xb4, 0xa5, 0x6a, 0x48,
- 0x1c, 0x02, 0x95, 0x6c, 0xa0, 0x2f, 0xc6, 0x1b, 0xa9, 0x32, 0xf2, 0x32,
- 0xf2, 0x4d, 0xad, 0x49, 0x4f, 0x12, 0xaf, 0x9a, 0x80, 0x39, 0xf9, 0xe9,
- 0x12, 0x49, 0xfa, 0xa5, 0x4c, 0x4f, 0xbc, 0x86, 0x87, 0x1b, 0x68, 0xb6,
- 0x40, 0xd8, 0x8b, 0xf2, 0x84, 0x96, 0xaa, 0xce, 0xc8, 0x64, 0xc4, 0x65,
- 0x87, 0x54, 0xca, 0xc5, 0x94, 0x84, 0xb2, 0x92, 0x55, 0xbd, 0xcf, 0x98,
- 0xdc, 0xfe, 0xf8, 0xd9, 0x4b, 0xae, 0x34, 0x14, 0xf2, 0xe8, 0x0c, 0x21,
- 0x29, 0xdc, 0xf8, 0x82, 0xc7, 0xf4, 0xbe, 0x2a, 0xa7, 0x28, 0xb1, 0x2d,
- 0x46, 0xab, 0x95, 0xaa, 0x10, 0x52, 0xf2, 0x95, 0xe2, 0xa5, 0xa4, 0x37,
- 0x76, 0xaf, 0x6e, 0x34, 0x9d, 0xc7, 0xaf, 0xd7, 0x08, 0x35, 0x18, 0xf2,
- 0x20, 0xd4, 0x16, 0xc5, 0x5d, 0x2a, 0x65, 0xf0, 0x8b, 0x8f, 0x35, 0xc1,
- 0xed, 0xa8, 0x11, 0xee, 0x38, 0xc7, 0x5a, 0x85, 0x4e, 0xa9, 0x4f, 0x1c,
- 0x69, 0x42, 0x78, 0x79, 0x81, 0xf7, 0x6f, 0x94, 0x68, 0xa3, 0xcc, 0x53,
- 0x6a, 0xaa, 0x2d, 0xa5, 0x44, 0x2f, 0x74, 0x9b, 0x83, 0xe3, 0xd6, 0x19,
- 0xfa, 0x3f, 0x06, 0x8b, 0x5b, 0xcf, 0xf4, 0x09, 0x4f, 0xc0, 0x43, 0x5e,
- 0x12, 0x1d, 0x79, 0x2d, 0xa1, 0x45, 0x20, 0xba, 0x84, 0x9d, 0x17, 0x23,
- 0x7b, 0x03, 0x63, 0xf6, 0xb6, 0x3a, 0x0e, 0xbb, 0xd3, 0xa6, 0x44, 0x24,
- 0x0c, 0xbd, 0x3d, 0xba, 0x6c, 0xb2, 0xd8, 0x21, 0xb5, 0x30, 0x85, 0xa1,
- 0x47, 0xd4, 0x02, 0x2e, 0x2f, 0xed, 0x8e, 0x7e, 0xfc, 0x3c, 0x32, 0xb7,
- 0xb3, 0xe5, 0x27, 0x72, 0xa4, 0x21, 0x52, 0x75, 0x90, 0x3e, 0x54, 0xe8,
- 0x51, 0xfe, 0x98, 0x6c, 0xfc, 0x47, 0xe7, 0xdc, 0xd7, 0x94, 0xb3, 0xed,
- 0x1d, 0xda, 0x05, 0x5d, 0x71, 0xdb, 0x11, 0x0a, 0x8b, 0x7a, 0x02, 0x9b,
- 0x76, 0xe4, 0x6c, 0xb4, 0x91, 0xb8, 0xed, 0x89, 0xee, 0x39, 0x99, 0xaa,
- 0xb9, 0x88, 0xd8, 0x44, 0x8b, 0xe5, 0xb2, 0x5a, 0x0a, 0xf0, 0xdf, 0x23,
- 0xcf, 0x6d, 0x61, 0xef, 0x0d, 0x38, 0xdc, 0x9d, 0x35, 0xc5, 0x9f, 0xca,
- 0xb2, 0x0e, 0xe6, 0xd7, 0x00, 0x7c, 0xe0, 0x1f, 0x50, 0x8f, 0x55, 0xf2,
- 0xa3, 0xaa, 0x45, 0x4a, 0x04, 0x79, 0xb0, 0x55, 0xb8, 0x91, 0x19, 0x8d,
- 0x4d, 0xaa, 0xde, 0xa3, 0x80, 0x47, 0xd3, 0x09, 0xea, 0xae, 0xf5, 0x11,
- 0x6d, 0xa5, 0xc7, 0x1c, 0x99, 0x15, 0xbd, 0x65, 0x01, 0x49, 0x8b, 0xa0,
- 0x6a, 0xb5, 0xf4, 0x8b, 0x27, 0x9d, 0x8f, 0xe9, 0x8b, 0x87, 0x4c, 0xba,
- 0xd9, 0x4b, 0xce, 0x4d, 0xff, 0x00, 0x07, 0xcc, 0x94, 0x71, 0x16, 0x72,
- 0x80, 0x05, 0x6d, 0x5d, 0x71, 0xdd, 0x27, 0x61, 0x71, 0xc8, 0x37, 0x3d,
- 0xef, 0xcf, 0x38, 0x79, 0x9f, 0x93, 0x8c, 0x58, 0x4e, 0xd4, 0x68, 0xf2,
- 0x4b, 0x4c, 0xdb, 0x53, 0x8c, 0x2c, 0x6a, 0x09, 0x23, 0x6f, 0x29, 0x3b,
- 0x8f, 0x4f, 0xbe, 0x04, 0x9c, 0x77, 0x52, 0x92, 0x58, 0x97, 0xa9, 0xdd,
- 0x2a, 0xe6, 0x0e, 0x47, 0xd2, 0x0e, 0x25, 0x2e, 0x4c, 0x27, 0x8d, 0xa7,
- 0x8d, 0x8e, 0xd7, 0xb7, 0x95, 0xf5, 0xf5, 0xf5, 0x89, 0x1f, 0x47, 0xa4,
- 0x67, 0x06, 0x27, 0x4a, 0x35, 0xc7, 0x25, 0x86, 0xd4, 0xd1, 0x08, 0xf1,
- 0x52, 0x52, 0x1c, 0xba, 0x55, 0x71, 0xbf, 0xd0, 0x1f, 0xbe, 0x00, 0xaf,
- 0x5c, 0xa8, 0x5a, 0x94, 0x10, 0x5a, 0x84, 0xcb, 0x81, 0x5c, 0x27, 0x48,
- 0xf1, 0xd4, 0x3e, 0xe4, 0x95, 0x7b, 0x9f, 0xd3, 0x14, 0x2f, 0xe6, 0xaa,
- 0x6d, 0x4d, 0x6c, 0xd3, 0xdb, 0x42, 0x5a, 0x79, 0x32, 0x1d, 0x2a, 0x4a,
- 0x2e, 0x92, 0x2c, 0x40, 0xb6, 0xae, 0x49, 0xb0, 0xb9, 0x3e, 0xf8, 0x47,
- 0xcc, 0xb4, 0xc3, 0x4a, 0x6d, 0x6b, 0x2e, 0x25, 0xc2, 0xe4, 0xa7, 0xc1,
- 0x08, 0xb8, 0x03, 0x4b, 0xa4, 0xff, 0x00, 0xa1, 0x18, 0x6f, 0xa9, 0xce,
- 0x2e, 0x6a, 0x8a, 0xda, 0x9c, 0x37, 0x25, 0x47, 0xdb, 0xf9, 0x87, 0x1c,
- 0x20, 0xa3, 0xda, 0x25, 0xc3, 0x9a, 0x80, 0x56, 0xb9, 0x9d, 0xb7, 0x85,
- 0x77, 0xe9, 0xb4, 0xfa, 0xab, 0x28, 0x11, 0xe7, 0x2e, 0x39, 0x24, 0x85,
- 0xad, 0x06, 0xc1, 0x06, 0xfe, 0xd7, 0xfb, 0xed, 0x82, 0x39, 0x17, 0x2c,
- 0xd0, 0xd9, 0x9e, 0xf4, 0x3c, 0xcf, 0x54, 0x5f, 0x88, 0xbb, 0x18, 0x8b,
- 0x5b, 0xc4, 0xb6, 0xbd, 0xf9, 0x0a, 0x1d, 0xfd, 0xb6, 0xf4, 0xb6, 0x25,
- 0x94, 0xb9, 0x92, 0x62, 0x49, 0x75, 0xd8, 0xce, 0xa9, 0xb5, 0x29, 0xc5,
- 0x6d, 0x7d, 0xb9, 0x3b, 0x1c, 0x51, 0x28, 0x4e, 0x48, 0xaa, 0xd2, 0x5e,
- 0x79, 0xf8, 0xbe, 0x46, 0x52, 0x95, 0x2c, 0x84, 0xdd, 0x04, 0x15, 0x69,
- 0xe7, 0xd6, 0xfd, 0xb0, 0x15, 0xd3, 0x31, 0x2c, 0x9b, 0x71, 0x92, 0x9e,
- 0xb0, 0x2a, 0x5d, 0x9a, 0x26, 0x2b, 0x50, 0x2a, 0x68, 0x31, 0x30, 0xad,
- 0xc0, 0x04, 0x28, 0xfb, 0x67, 0xd7, 0x3f, 0x13, 0x15, 0xe8, 0x99, 0x07,
- 0x2d, 0x48, 0x6d, 0x0d, 0xc5, 0x61, 0x12, 0xdc, 0x5b, 0x6e, 0x5d, 0xa5,
- 0x2f, 0xec, 0x13, 0xb8, 0x3c, 0x1b, 0x0d, 0xf7, 0xbd, 0xce, 0x05, 0xc1,
- 0xa4, 0x39, 0x43, 0xca, 0x15, 0x0a, 0x3b, 0xad, 0x84, 0x2e, 0x3b, 0x6f,
- 0xb4, 0x42, 0x56, 0x5c, 0x06, 0xc5, 0x44, 0x79, 0xac, 0x2e, 0x34, 0xdb,
- 0x7b, 0x0c, 0x2b, 0x65, 0x9a, 0xcd, 0x47, 0x2d, 0x54, 0x92};
-
-std::vector<uint8_t> l2cap_test_packet_7 = {
- 0xf6, 0x03, 0x47, 0x00, 0x0e, 0xc1, 0xa0, 0xaa, 0x33, 0xea, 0x72, 0x1b,
- 0xab, 0xb2, 0xa3, 0xea, 0x1a, 0xae, 0x3c, 0xd7, 0x07, 0xe6, 0xb5, 0xff,
- 0x00, 0xec, 0x61, 0xd2, 0x7e, 0x67, 0x6b, 0x30, 0x49, 0x9a, 0xb0, 0x9f,
- 0x04, 0x2c, 0x36, 0x1f, 0xb6, 0xc0, 0x21, 0x68, 0x20, 0x8d, 0xb8, 0xb5,
- 0xb0, 0xc7, 0x84, 0x66, 0x82, 0xa7, 0x14, 0x39, 0xa4, 0xfd, 0x22, 0x3f,
- 0xf1, 0x5f, 0x0e, 0xcc, 0x52, 0x24, 0xd0, 0xdb, 0x80, 0x1b, 0x2d, 0x26,
- 0xe3, 0x96, 0x63, 0xe7, 0x1a, 0xf4, 0xf9, 0xb2, 0xe3, 0xe5, 0xb9, 0x2f,
- 0xb6, 0x99, 0x09, 0x53, 0x71, 0xf4, 0x25, 0xc4, 0x70, 0x8b, 0x2b, 0x7b,
- 0xff, 0x00, 0x97, 0xd3, 0x08, 0x59, 0x5f, 0xab, 0x71, 0xd2, 0xa5, 0xc5,
- 0xae, 0x53, 0x64, 0x25, 0xbd, 0x56, 0xf8, 0x86, 0x5e, 0x2a, 0x5a, 0x2c,
- 0x6f, 0x7b, 0x1e, 0x37, 0xdf, 0x6c, 0x58, 0xd2, 0xdd, 0x2e, 0xa5, 0xd2,
- 0x9a, 0x1f, 0xf0, 0xc2, 0xcf, 0xc5, 0xae, 0x0b, 0xc2, 0x62, 0x19, 0xf9,
- 0x8d, 0xd3, 0xb2, 0x96, 0x3e, 0xa9, 0xef, 0x8e, 0x46, 0x7d, 0x6b, 0x8b,
- 0x52, 0x93, 0x09, 0xc4, 0x95, 0xa1, 0x0f, 0xad, 0x36, 0x1c, 0xde, 0xe4,
- 0x6d, 0x83, 0x75, 0x4a, 0x93, 0xe8, 0x29, 0x71, 0xbc, 0xb6, 0x3e, 0x36,
- 0x8a, 0x83, 0xd5, 0xe9, 0x96, 0x29, 0xb2, 0x4e, 0xb2, 0x78, 0x41, 0x4d,
- 0x88, 0x23, 0x5b, 0x00, 0x05, 0xf7, 0xd8, 0xe9, 0x1d, 0x04, 0xec, 0xac,
- 0xbb, 0x9a, 0xa0, 0xae, 0x45, 0x3a, 0xb4, 0x15, 0x2d, 0xb2, 0x16, 0xd1,
- 0x69, 0x94, 0xb6, 0xf2, 0x8d, 0xff, 0x00, 0x38, 0xb5, 0x96, 0x07, 0x3c,
- 0x5f, 0x1f, 0x12, 0x8e, 0x69, 0x0d, 0x33, 0x26, 0xa0, 0x83, 0x52, 0x84,
- 0x96, 0xf4, 0x78, 0x91, 0xd0, 0x94, 0x92, 0x9b, 0x8f, 0x99, 0x36, 0xb1,
- 0xe3, 0x8d, 0xb0, 0x1f, 0xa4, 0x19, 0x3e, 0x7c, 0x69, 0x10, 0xf3, 0x0b,
- 0x8c, 0x7c, 0x38, 0x68, 0x97, 0x63, 0xb0, 0xf1, 0xf3, 0xba, 0x46, 0xe0,
- 0x1e, 0x39, 0xf4, 0xed, 0x83, 0x15, 0xac, 0xf6, 0xed, 0x26, 0x24, 0x88,
- 0x34, 0x94, 0xaf, 0xc6, 0xd4, 0x4b, 0xcb, 0x6d, 0x37, 0xd1, 0x7d, 0xac,
- 0x3d, 0xf9, 0xdb, 0x9c, 0x63, 0x5c, 0x8c, 0xac, 0xcc, 0xa9, 0x76, 0x75,
- 0x01, 0xbe, 0x56, 0xca, 0xfe, 0x50, 0xc0, 0xd2, 0x18, 0x9a, 0x94, 0x33,
- 0x33, 0xcd, 0x04, 0x11, 0xbd, 0xed, 0x97, 0x80, 0xd7, 0xa0, 0xb1, 0x31,
- 0x7b, 0xe9, 0x12, 0xe8, 0xec, 0xe5, 0x1b, 0xd3, 0x65, 0x25, 0x2b, 0x7e,
- 0x38, 0x94, 0xb2, 0xa5, 0x15, 0x0b, 0x8d, 0x8d, 0xc6, 0xd6, 0x20, 0x1d,
- 0xc0, 0xe0, 0x8c, 0x47, 0xfa, 0xd7, 0x35, 0x11, 0x33, 0xed, 0x55, 0xe7,
- 0x8b, 0x6a, 0xd4, 0x84, 0xb8, 0x46, 0xab, 0x0b, 0x80, 0x47, 0xef, 0x6c,
- 0x6c, 0xf4, 0x0a, 0x53, 0xf3, 0xe4, 0xd4, 0x59, 0xbc, 0x86, 0x5b, 0x4c,
- 0x72, 0xd8, 0x4b, 0xbb, 0x06, 0xf5, 0x21, 0x57, 0x1f, 0x5b, 0x81, 0x7c,
- 0x2a, 0x7e, 0x26, 0x9b, 0x7e, 0x36, 0x64, 0x8b, 0xe6, 0x4b, 0xa8, 0x98,
- 0xd2, 0x3c, 0xac, 0x82, 0xa2, 0xa0, 0x9b, 0x77, 0x23, 0x6d, 0xf7, 0xc2,
- 0x83, 0xbc, 0x0b, 0x68, 0x34, 0x9d, 0x02, 0xb2, 0xe9, 0x09, 0xce, 0x80,
- 0x86, 0x94, 0xb4, 0x1b, 0x8b, 0x9d, 0x75, 0xb5, 0xf2, 0x8d, 0x18, 0x68,
- 0x47, 0xf3, 0x58, 0x60, 0x04, 0x24, 0x96, 0x46, 0xab, 0xaa, 0xdb, 0x59,
- 0x69, 0x23, 0x7e, 0xe4, 0xf6, 0x18, 0x8c, 0x65, 0x88, 0x92, 0xe5, 0xd7,
- 0xfe, 0x12, 0x23, 0x0b, 0x79, 0xd5, 0x28, 0xa7, 0x4a, 0x47, 0xbf, 0xed,
- 0x8b, 0x58, 0x8b, 0x1d, 0x59, 0xe9, 0xb6, 0xd6, 0xa0, 0xd2, 0x1c, 0x80,
- 0x95, 0x6c, 0x6c, 0x51, 0xe6, 0x26, 0xff, 0x00, 0x6e, 0x70, 0x0e, 0xa7,
- 0x99, 0x72, 0xbe, 0x49, 0x79, 0xf6, 0x29, 0x30, 0x99, 0x9c, 0xe3, 0xaa,
- 0xd6, 0xe0, 0x4a, 0x8a, 0x75, 0x2b, 0x7b, 0x82, 0x46, 0xf6, 0x3d, 0xc6,
- 0x1e, 0xa4, 0xe4, 0x91, 0x35, 0x4c, 0x61, 0x4e, 0x2a, 0xc9, 0x48, 0x37,
- 0xf5, 0x88, 0xd4, 0xe4, 0xeb, 0xb2, 0xb5, 0x59, 0x86, 0xd8, 0x41, 0x5a,
- 0xd4, 0x13, 0x6e, 0x43, 0x5c, 0xc9, 0xf3, 0x86, 0x4c, 0xb5, 0x16, 0x9f,
- 0x93, 0x61, 0x8a, 0x85, 0x46, 0xa4, 0xc7, 0x8e, 0xa4, 0xa8, 0x2d, 0x09,
- 0x57, 0x97, 0x56, 0xdb, 0x7b, 0x9d, 0xb0, 0xbd, 0x9d, 0x69, 0xd5, 0x4c,
- 0xc7, 0x25, 0xea, 0xab, 0x2c, 0x06, 0xda, 0x6e, 0x3a, 0xec, 0x93, 0xf3,
- 0x2a, 0xf6, 0x55, 0xcd, 0xb8, 0xe0, 0x58, 0x5c, 0xfb, 0xde, 0xf8, 0x9b,
- 0xe6, 0x0c, 0xd3, 0x2b, 0x30, 0xd5, 0x05, 0x4a, 0xa4, 0xab, 0xbf, 0xa9,
- 0x21, 0x0d, 0x36, 0x90, 0x96, 0x9a, 0x48, 0xb5, 0x92, 0x00, 0x1e, 0x82,
- 0xd8, 0x7d, 0x9d, 0xd4, 0x5a, 0x62, 0xe8, 0x72, 0x22, 0xc7, 0x6d, 0xe5,
- 0x3a, 0xe4, 0x52, 0xd0, 0x48, 0x05, 0x37, 0x51, 0xb0, 0xd4, 0x3d, 0x3b,
- 0xfe, 0xd8, 0xc7, 0x51, 0x9f, 0x79, 0xf6, 0x44, 0xac, 0x93, 0x47, 0x83,
- 0xa1, 0x37, 0xb7, 0xdf, 0x58, 0xdf, 0x45, 0xa1, 0xa1, 0x89, 0x83, 0x3f,
- 0x38, 0xbe, 0x27, 0x8f, 0x90, 0x17, 0xe5, 0x19, 0xf8, 0x7e, 0xa9, 0x7f,
- 0x0c, 0xcf, 0x74, 0xe6, 0x41, 0x4a, 0xd2, 0xeb, 0xce, 0xb3, 0xa8, 0xde,
- 0xe0, 0x68, 0x5e, 0xff, 0x00, 0xed, 0x86, 0xef, 0xc4, 0xae, 0x57, 0xad,
- 0x66, 0x9c, 0xf5, 0x96, 0xa9, 0x99, 0x7a, 0x9d, 0x22, 0xa3, 0x2d, 0xe8,
- 0xaa, 0x40, 0x08, 0x48, 0x09, 0x16, 0x37, 0x25, 0x44, 0xec, 0x91, 0x6d,
- 0xee, 0x48, 0x18, 0x40, 0xe9, 0x72, 0x97, 0x1f, 0x38, 0xd0, 0xe4, 0x4c,
- 0x01, 0x82, 0xed, 0x49, 0xc4, 0x5d, 0xc5, 0x00, 0x2e, 0xa4, 0xe9, 0x1b,
- 0xf1, 0xc9, 0xb6, 0x3a, 0x7f, 0x38, 0x67, 0x5a, 0x2e, 0x59, 0xa6, 0xa5,
- 0xe0, 0x17, 0x2e, 0xa6, 0xb8, 0xfa, 0x52, 0xdb, 0x00, 0xd8, 0x26, 0xfb,
- 0x6b, 0x20, 0x5c, 0xef, 0xc2, 0x45, 0xf0, 0x93, 0x8e, 0x17, 0x35, 0x2b,
- 0x5d, 0x93, 0x71, 0x96, 0x8a, 0xd6, 0x59, 0x02, 0xde, 0x3d, 0xe1, 0xed,
- 0xbc, 0x50, 0xb0, 0xeb, 0x0d, 0xcd, 0x53, 0xdf, 0x6c, 0x1d, 0x56, 0x6f,
- 0xe5, 0x63, 0xf4, 0x85, 0xbe, 0x94, 0xf4, 0x72, 0x85, 0xd3, 0xd8, 0x08,
- 0xcc, 0xb9, 0x96, 0x4b, 0x33, 0xab, 0x2c, 0xd8, 0x87, 0x41, 0xbc, 0x68,
- 0x8b, 0xec, 0x1b, 0x07, 0xff, 0x00, 0x51, 0x63, 0xfb, 0xdd, 0xbb, 0x0e,
- 0xf8, 0xdb, 0xcc, 0xd9, 0xc6, 0x7d, 0x6e, 0x97, 0x22, 0x99, 0x97, 0xdc,
- 0x30, 0xd2, 0xa6, 0xd4, 0x18, 0x23, 0xe7, 0x70, 0xff, 0x00, 0x7d, 0x44,
- 0xf0, 0x2f, 0xe9, 0xbd, 0xed, 0xef, 0x88, 0x96, 0x6e, 0xcd, 0xdd, 0x45,
- 0xce, 0x15, 0x44, 0x29, 0xea, 0x7c, 0xe4, 0x42, 0x6a, 0xe1, 0xa6, 0x49,
- 0x08, 0xda, 0xe7, 0x7b, 0x5f, 0xcb, 0x7f, 0x41, 0xe9, 0xdf, 0x07, 0xa9,
- 0xaf, 0xe7, 0x01, 0x14, 0xb6, 0xb8, 0x4d, 0x0f, 0x11, 0x21, 0x09, 0x40,
- 0x76, 0xe5, 0x24, 0xef, 0x60, 0x07, 0xdf, 0x6c, 0x0f, 0x6b, 0x07, 0xd4,
- 0xa6, 0xdd, 0x13, 0x53, 0xa8, 0x2b, 0x5e, 0xc2, 0xdd, 0xd4, 0xf4, 0x82,
- 0xcd, 0x87, 0x52, 0x9e, 0xce, 0x55, 0xb2, 0x40, 0xde, 0xc7, 0xda, 0xff,
- 0x00, 0x3f, 0xe6, 0x14, 0xb2, 0x2c, 0x09, 0x51, 0x33, 0x8c, 0x66, 0x96,
- 0xe1, 0x7d, 0xc5, 0x2d, 0xc4, 0x94, 0x29, 0xcb, 0xf9, 0x86, 0xc6, 0xe4,
- 0x5e, 0xdd, 0xf0, 0x56, 0x6c, 0xc9, 0x93, 0x95, 0xfa, 0xf6};
-
-std::vector<uint8_t> l2cap_test_packet_8 = {
- 0xf6, 0x03, 0x47, 0x00, 0x10, 0xc1, 0x53, 0x69, 0x65, 0xc7, 0x52, 0xcc,
- 0xa7, 0x94, 0x02, 0xd5, 0xa8, 0xa0, 0x6b, 0xde, 0xde, 0xbd, 0xbf, 0x4c,
- 0x39, 0xe4, 0xec, 0x9f, 0x57, 0x77, 0x33, 0x35, 0x50, 0x9f, 0x4e, 0x44,
- 0x25, 0x34, 0xab, 0xa5, 0xd0, 0x8d, 0x3a, 0x81, 0xd8, 0x85, 0x71, 0xc7,
- 0x37, 0xe4, 0x93, 0x84, 0x99, 0x2f, 0xb0, 0xd5, 0x72, 0xae, 0x88, 0xe8,
- 0x7a, 0x4a, 0xdb, 0x98, 0xf0, 0x75, 0x09, 0x68, 0x9d, 0x0a, 0xd5, 0xb0,
- 0xbf, 0x1b, 0xdb, 0x0e, 0x75, 0x19, 0x29, 0x84, 0x51, 0xd0, 0x85, 0xa0,
- 0xf1, 0xf1, 0xde, 0xdb, 0xd8, 0x8f, 0xda, 0x1b, 0xb0, 0xc3, 0x8c, 0xc8,
- 0x9f, 0xee, 0x94, 0x1b, 0x04, 0x2b, 0xfc, 0x8d, 0xb6, 0x1b, 0x9e, 0x86,
- 0x13, 0x32, 0xee, 0x51, 0x95, 0x26, 0x62, 0x97, 0x2b, 0xca, 0x85, 0x38,
- 0x74, 0x36, 0x8d, 0xd4, 0xab, 0x9d, 0xbe, 0x98, 0x69, 0xa8, 0xfc, 0x0d,
- 0x1c, 0x22, 0x1c, 0x55, 0x32, 0x08, 0x1b, 0xa5, 0x0e, 0x6a, 0x08, 0xf5,
- 0x04, 0x8e, 0x4f, 0x7d, 0xb1, 0xf9, 0x3a, 0x8f, 0x99, 0xea, 0x68, 0x4a,
- 0x63, 0xc8, 0x85, 0x01, 0xbe, 0x74, 0x97, 0x81, 0xd3, 0x7f, 0x5b, 0x72,
- 0x71, 0xa3, 0x1b, 0xa7, 0x33, 0x18, 0x92, 0xdb, 0x95, 0x3a, 0xd3, 0x84,
- 0xba, 0x82, 0xa1, 0xe0, 0x46, 0x71, 0x6a, 0x29, 0xe3, 0xb0, 0x36, 0xc6,
- 0x54, 0xe1, 0xea, 0x8c, 0xd0, 0x0b, 0x75, 0x36, 0x1c, 0xb2, 0x10, 0xa0,
- 0xf7, 0xc4, 0x6c, 0x37, 0x86, 0xc1, 0x96, 0xa4, 0x1e, 0x35, 0x0c, 0x8a,
- 0xc8, 0xb9, 0x3d, 0x32, 0xf6, 0xc8, 0x43, 0x2e, 0x4d, 0x99, 0x97, 0xd4,
- 0x5c, 0x4d, 0x69, 0x97, 0x3c, 0x55, 0x0b, 0xa6, 0x42, 0xaf, 0x66, 0xc6,
- 0x92, 0x6c, 0x12, 0x0d, 0xbe, 0xfe, 0xbd, 0xf0, 0xcf, 0x05, 0xa8, 0x4e,
- 0xd6, 0x27, 0x1a, 0x5b, 0xc8, 0x2c, 0x08, 0x8d, 0x82, 0xb6, 0x55, 0x70,
- 0xa5, 0x00, 0xaf, 0x5e, 0xdb, 0xe1, 0x61, 0x8e, 0x9b, 0x44, 0x0a, 0x68,
- 0xbd, 0x5a, 0x7d, 0x69, 0x28, 0x05, 0x2a, 0x5a, 0xc8, 0xf2, 0xfa, 0x7b,
- 0x7d, 0x30, 0xdd, 0x95, 0xa9, 0x54, 0xbc, 0xb6, 0xc4, 0x8b, 0xcf, 0x69,
- 0x48, 0x5f, 0x9c, 0xf9, 0x49, 0x3b, 0x0b, 0x6e, 0x7b, 0xe1, 0x86, 0x83,
- 0x40, 0x98, 0x91, 0x9b, 0x0f, 0x39, 0x60, 0x90, 0x0e, 0xf1, 0x1b, 0xc6,
- 0xf8, 0xe6, 0x56, 0xbb, 0x28, 0xa4, 0xa5, 0x4a, 0x53, 0x84, 0x8d, 0x41,
- 0xd8, 0xc6, 0x8e, 0x49, 0x2b, 0xfe, 0x58, 0xa4, 0x2c, 0x3a, 0xb4, 0x07,
- 0x1a, 0x2d, 0x2e, 0xcb, 0x29, 0xbe, 0x95, 0x91, 0xcf, 0xf9, 0x86, 0x34,
- 0x1b, 0xc8, 0xf4, 0x8c, 0xaf, 0x5e, 0x7b, 0x30, 0xd7, 0x5a, 0x69, 0xe4,
- 0x15, 0xf8, 0x89, 0x2e, 0x3a, 0x34, 0x81, 0xea, 0x07, 0xae, 0x0e, 0xf4,
- 0xc1, 0xba, 0x5d, 0x63, 0xa7, 0xae, 0xc4, 0x55, 0x72, 0x1c, 0x19, 0xf0,
- 0x66, 0x38, 0x02, 0x5f, 0x41, 0xf9, 0x54, 0x41, 0x1c, 0x6f, 0x6f, 0x70,
- 0x0e, 0xe2, 0xc7, 0x1e, 0x95, 0x1c, 0xa7, 0x95, 0x6a, 0x8f, 0x78, 0x99,
- 0xa7, 0x38, 0xbb, 0x31, 0x60, 0xec, 0xdc, 0x55, 0x04, 0xb2, 0x91, 0xed,
- 0xab, 0x73, 0xf5, 0x23, 0x1e, 0xf3, 0x75, 0x49, 0x44, 0x23, 0x3e, 0xf2,
- 0x92, 0x4d, 0x87, 0x99, 0xce, 0x3e, 0x82, 0xa0, 0x54, 0x25, 0x95, 0x47,
- 0x96, 0xed, 0x52, 0x14, 0xb4, 0x0c, 0xae, 0x0e, 0x47, 0x63, 0x7d, 0xad,
- 0x7f, 0x13, 0xf3, 0x08, 0x59, 0xa7, 0xa9, 0x90, 0xe7, 0xd4, 0x3f, 0x87,
- 0xd3, 0xd6, 0x44, 0x73, 0xb1, 0x7d, 0x46, 0xca, 0xb7, 0x64, 0x8b, 0x7c,
- 0xa3, 0x8d, 0x86, 0xe7, 0xb9, 0xed, 0x80, 0xd4, 0x1a, 0xac, 0x04, 0xb8,
- 0xe1, 0x71, 0x0b, 0xd2, 0xb7, 0x09, 0xdc, 0xdf, 0x49, 0xdf, 0x6b, 0x1f,
- 0xad, 0xcf, 0xed, 0x8a, 0xe2, 0x32, 0x5e, 0x40, 0x85, 0x1d, 0x89, 0x14,
- 0xa8, 0x54, 0xea, 0xb8, 0x52, 0x94, 0x1c, 0x0f, 0x4f, 0x53, 0x3e, 0x1f,
- 0xf7, 0x46, 0xc8, 0x37, 0x36, 0xbd, 0xed, 0xc6, 0x18, 0xa9, 0xf4, 0xfe,
- 0x9a, 0xa6, 0x12, 0x14, 0xfd, 0x0c, 0x31, 0x25, 0x0a, 0x21, 0xe6, 0x58,
- 0x43, 0xce, 0x83, 0xb6, 0xc5, 0x2e, 0x5b, 0x71, 0xfa, 0x61, 0x36, 0xa1,
- 0x3e, 0x26, 0x94, 0x4b, 0xae, 0x0f, 0x33, 0x18, 0x26, 0x3b, 0x79, 0xb7,
- 0x4a, 0x9e, 0x70, 0x78, 0x00, 0x32, 0x1e, 0xa7, 0xde, 0x37, 0x7a, 0x17,
- 0xe0, 0x3b, 0x48, 0x42, 0x53, 0xe0, 0x3a, 0xfb, 0xa9, 0x5b, 0xee, 0x29,
- 0xa1, 0xc9, 0x06, 0xc7, 0x9e, 0xc0, 0x5b, 0x02, 0x7f, 0x12, 0x50, 0xd2,
- 0xdd, 0x7e, 0x93, 0x25, 0x20, 0x05, 0x29, 0x82, 0x90, 0x37, 0xb1, 0xb1,
- 0x1e, 0x9f, 0x43, 0x86, 0xaa, 0x5d, 0x7f, 0x25, 0x51, 0x5d, 0x0b, 0xa7,
- 0x50, 0xaa, 0x37, 0x00, 0x68, 0x09, 0x69, 0x66, 0xc3, 0xef, 0x84, 0xbe,
- 0xa7, 0xe6, 0x98, 0xb9, 0xb2, 0xbf, 0x16, 0x33, 0x50, 0x64, 0xc2, 0xf8,
- 0x26, 0xff, 0x00, 0xe7, 0x24, 0xa5, 0x4a, 0x4f, 0xae, 0xe3, 0x8d, 0xf9,
- 0xe3, 0x6c, 0x60, 0x4b, 0x8c, 0xf6, 0x25, 0x01, 0x60, 0xaa, 0xf7, 0xc8,
- 0xc6, 0x57, 0x18, 0xec, 0x90, 0x45, 0xf2, 0xf1, 0xb7, 0xca, 0xe6, 0x24,
- 0x3d, 0x41, 0x97, 0x21, 0x1f, 0x0d, 0xf0, 0x4e, 0xa2, 0x3c, 0xc7, 0x96,
- 0x4e, 0xa5, 0x10, 0x0f, 0x86, 0x05, 0x92, 0x8b, 0x9f, 0xca, 0x76, 0xfd,
- 0x31, 0x3c, 0x10, 0xaa, 0xae, 0xbe, 0xaf, 0xfc, 0xad, 0x97, 0x97, 0x7d,
- 0xce, 0x92, 0xa3, 0xfa, 0xe2, 0xae, 0x8a, 0x4c, 0x1a, 0xef, 0x50, 0x69,
- 0x54, 0x9a, 0x83, 0xc9, 0x62, 0x3f, 0xc0, 0xba, 0xf1, 0x71, 0x36, 0x3a,
- 0x52, 0x3e, 0x5d, 0xcf, 0xa0, 0x37, 0xbe, 0x07, 0xe6, 0x8c, 0x85, 0x9a,
- 0xe3, 0xcf, 0x28, 0xc9, 0xd5, 0x29, 0xb5, 0x66, 0x42, 0x43, 0x88, 0x44,
- 0x72, 0xa2, 0xbd, 0x2a, 0xbd, 0xb9, 0xdd, 0x5c, 0x1b, 0x73, 0xf5, 0xc5,
- 0x33, 0x0d, 0xb6, 0xf3, 0x34, 0xd0, 0xe7, 0x19, 0xb1, 0xb9, 0x00, 0x01,
- 0x90, 0xb9, 0x1a, 0xab, 0x2f, 0x28, 0x57, 0x55, 0x29, 0xb7, 0xc2, 0xa6,
- 0x0a, 0x49, 0xd8, 0xdb, 0x5c, 0xa0, 0x05, 0x1f, 0x29, 0x54, 0xdd, 0xa7,
- 0xa9, 0xe7, 0xe3, 0x53, 0xa2, 0x10, 0x9b, 0xb7, 0xe2, 0x4f, 0x09, 0x2e,
- 0x0b, 0x5e, 0xe0, 0x04, 0x2a, 0xff, 0x00, 0xb6, 0x3c, 0x19, 0xcb, 0xd9,
- 0xd9, 0x45, 0x3f, 0x0d, 0x47, 0x8e, 0x9d, 0x48, 0x4a, 0xbc, 0xa5, 0x2a,
- 0xb5, 0xc6, 0xd7, 0xb9, 0x36, 0x3e, 0xd8, 0x0e, 0x89, 0x59, 0xb5, 0x89,
- 0x4b, 0x82, 0xa9, 0x72, 0xe3, 0xb8, 0x83, 0x65, 0x24, 0xf9, 0x74, 0x9f,
- 0x43, 0xb6, 0xc7, 0xeb, 0x82, 0xb4, 0xea, 0x6e, 0x75, 0x9e, 0xca, 0xa5,
- 0x36, 0xed, 0x49, 0xc4, 0xa1, 0x5a, 0x54, 0x52, 0x6f, 0xc7, 0x3c, 0x63,
- 0x43, 0xb8, 0xa9, 0xa6, 0xcf, 0x0a, 0x8a, 0xc5, 0xbf, 0xf3, 0xf7, 0xe8,
- 0x04, 0x71, 0x6e, 0x9f, 0x4a, 0x51, 0xcd, 0x0b, 0x3d, 0x48, 0xfa, 0xde,
- 0x33, 0x30, 0xe5, 0xec, 0xe9, 0x12, 0x9a, 0x89, 0xd5, 0x86, 0x99, 0x6a,
- 0x34, 0x75, 0x78, 0x88, 0xd4, 0x05, 0x8a, 0x86, 0xe1, 0x36, 0xb7, 0x7b,
- 0x7d, 0x31, 0xeb, 0x53, 0xa8, 0x67, 0xc8, 0x49, 0x65, 0x6e, 0x39, 0x22,
- 0x13, 0x2a, 0x17, 0x65, 0x41, 0xb5, 0xb4, 0x9b, 0x13, 0xdb, 0x55, 0x88,
- 0x1b, 0xf7, 0xc3, 0xfd, 0x0e, 0x44, 0xc7, 0xa8, 0x2c, 0xc1, 0xac, 0x34,
- 0x92, 0xb6, 0x27, 0xc7, 0x6d, 0x68, 0x51, 0xb8, 0xa4, 0x1d};
-
-std::vector<uint8_t> l2cap_test_packet_9 = {0x09, 0x00, 0x47, 0x00, 0x12,
- 0x81, 0x3c, 0x1d, 0xc7, 0x62,
- 0x45, 0x1a, 0x78};
-
-// complete_l2cap_packet is the l2cap packet that should be created when
-// assemble is called on a vector<L2capSdu*> that contains the previous 9 test
-// packets.
-std::vector<uint8_t> complete_l2cap_packet = {
- 0x95, 0x1f, 0x47, 0x00, 0x02, 0x1f, 0x95, 0xcb, 0x00, 0x00, 0x00, 0x01,
- 0x01, 0x00, 0x33, 0x00, 0x49, 0x00, 0x4d, 0x00, 0x47, 0x00, 0x5f, 0x00,
- 0x32, 0x00, 0x30, 0x00, 0x31, 0x00, 0x37, 0x00, 0x30, 0x00, 0x36, 0x00,
- 0x30, 0x00, 0x36, 0x00, 0x5f, 0x00, 0x31, 0x00, 0x35, 0x00, 0x34, 0x00,
- 0x33, 0x00, 0x33, 0x00, 0x38, 0x00, 0x2e, 0x00, 0x6a, 0x00, 0x70, 0x00,
- 0x67, 0x00, 0x00, 0x42, 0x00, 0x0e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f,
- 0x6a, 0x70, 0x65, 0x67, 0x00, 0xc3, 0x00, 0x12, 0x30, 0x03, 0x97, 0x01,
- 0x48, 0x1f, 0x45, 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49,
- 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff,
- 0xe1, 0x2b, 0x18, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x4d, 0x4d, 0x00,
- 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x04, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x0c, 0xc0, 0x01, 0x01, 0x00, 0x04, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0x90, 0x01, 0x0f, 0x00, 0x02, 0x00,
- 0x00, 0x00, 0x04, 0x4c, 0x47, 0x45, 0x00, 0x01, 0x10, 0x00, 0x02, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x9e, 0x01, 0x12, 0x00, 0x03, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x05, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x01, 0x1b, 0x00, 0x05, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae, 0x01, 0x28, 0x00, 0x03, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x31, 0x00, 0x02, 0x00,
- 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xb6, 0x01, 0x32, 0x00, 0x02, 0x00,
- 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xbd, 0x02, 0x13, 0x00, 0x03, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x87, 0x69, 0x00, 0x04, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x02, 0x78, 0x4e,
- 0x65, 0x78, 0x75, 0x73, 0x20, 0x35, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x50,
- 0x69, 0x63, 0x61, 0x73, 0x61, 0x00, 0x32, 0x30, 0x31, 0x37, 0x3a, 0x30,
- 0x36, 0x3a, 0x30, 0x36, 0x20, 0x31, 0x35, 0x3a, 0x34, 0x33, 0x3a, 0x33,
- 0x38, 0x00, 0x00, 0x00, 0x15, 0x82, 0x9a, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x01, 0xd4, 0x82, 0x9d, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x01, 0xdc, 0x88, 0x27, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x01, 0x02, 0x1f, 0x00, 0x00, 0x90, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
- 0x04, 0x30, 0x32, 0x32, 0x30, 0x90, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x01, 0xe4, 0x90, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x01, 0xf8, 0x91, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00,
- 0x04, 0x01, 0x02, 0x03, 0x00, 0x92, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x02, 0x0c, 0x92, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x02, 0x14, 0x92, 0x09, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x92, 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x02, 0x1c, 0x92, 0x90, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x07, 0x00, 0x00, 0x02, 0x24, 0x92, 0x91, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x07, 0x00, 0x00, 0x02, 0x2b, 0x92, 0x92, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x07, 0x00, 0x00, 0x02, 0x32, 0xa0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
- 0x04, 0x30, 0x31, 0x30, 0x30, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x0a, 0x0a, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x07, 0x77, 0xa0, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x02, 0x5a, 0xa4, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x8c,
- 0xb2, 0x3b, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
- 0x64, 0x32, 0x30, 0x31, 0x37, 0x3a, 0x30, 0x36, 0x3a, 0x30, 0x36, 0x20,
- 0x31, 0x35, 0x3a, 0x34, 0x33, 0x3a, 0x33, 0x38, 0x00, 0x32, 0x30, 0x31,
- 0x37, 0x3a, 0x30, 0x36, 0x3a, 0x30, 0x36, 0x20, 0x31, 0x35, 0x3a, 0x34,
- 0x33, 0x3a, 0x33, 0x38, 0x00, 0xff, 0xff, 0xfe, 0x16, 0x00, 0x00, 0x00,
- 0x64, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x0f,
- 0x82, 0x00, 0x00, 0x03, 0xe8, 0x39, 0x39, 0x39, 0x37, 0x32, 0x39, 0x00,
- 0x39, 0x39, 0x39, 0x37, 0x32, 0x39, 0x00, 0x39, 0x39, 0x39, 0x37, 0x32,
- 0x39, 0x00, 0x31, 0x30, 0x61, 0x66, 0x39, 0x37, 0x31, 0x37, 0x63, 0x31,
- 0x30, 0x36, 0x36, 0x33, 0x65, 0x62, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00,
- 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x52, 0x39, 0x38,
- 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x30, 0x31, 0x30,
- 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x03, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x05, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xc6, 0x01, 0x1b, 0x00, 0x05, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xce, 0x01, 0x28, 0x00, 0x03, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xd6, 0x02, 0x02, 0x00, 0x04, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x28, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00,
- 0x00, 0x00, 0x01, 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49,
- 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff,
- 0xdb, 0x00, 0x43, 0x00, 0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04,
- 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08, 0x07, 0x07, 0x07,
- 0x07, 0x0f, 0x0b, 0x0b, 0x09, 0x0c, 0x11, 0x0f, 0x12, 0x12, 0x11, 0x0f,
- 0x11, 0x11, 0x13, 0x16, 0x1c, 0x17, 0x13, 0x14, 0x1a, 0x15, 0x11, 0x11,
- 0x18, 0x21, 0x18, 0x1a, 0x1d, 0x1d, 0x1f, 0x1f, 0x1f, 0x13, 0x17, 0x22,
- 0x24, 0x22, 0x1e, 0x24, 0x1c, 0x1e, 0x1f, 0x1e, 0xff, 0xdb, 0x00, 0x43,
- 0x01, 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0e, 0x08, 0x08, 0x0e, 0x1e,
- 0x14, 0x11, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x78,
- 0x00, 0xa0, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
- 0xff, 0xc4, 0x00, 0x1c, 0x00, 0x00, 0x03, 0x00, 0x03, 0x01, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07,
- 0x00, 0x04, 0x08, 0x03, 0x02, 0x01, 0xff, 0xc4, 0x00, 0x40, 0x10, 0x00,
- 0x01, 0x03, 0x02, 0x05, 0x02, 0x04, 0x04, 0x04, 0x03, 0x06, 0x04, 0x07,
- 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x00, 0x06, 0x12,
- 0x21, 0x31, 0x07, 0x41, 0x13, 0x22, 0x51, 0x61, 0x14, 0x32, 0x71, 0x81,
- 0x08, 0x42, 0x91, 0xa1, 0x15, 0x16, 0xc1, 0x23, 0x52, 0x62, 0x82, 0xb1,
- 0xe1, 0x24, 0x43, 0x72, 0xf0, 0x17, 0x25, 0x33, 0x92, 0xb2, 0xd1, 0xd2,
- 0xff, 0xc4, 0x00, 0x1c, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07,
- 0x04, 0x03, 0x00, 0x02, 0x08, 0x01, 0xff, 0xc4, 0x00, 0x37, 0x11, 0x00,
- 0x01, 0x02, 0x04, 0x04, 0x03, 0x06, 0x04, 0x05, 0x04, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0x11, 0x06, 0x21,
- 0x31, 0x41, 0x12, 0x51, 0x71, 0x13, 0x22, 0x61, 0x81, 0x91, 0xa1, 0x07,
- 0xb1, 0xc1, 0xf0, 0x14, 0x42, 0xd1, 0xe1, 0xf1, 0x15, 0x24, 0x32, 0x82,
- 0x33, 0x52, 0x72, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11,
- 0x03, 0x11, 0x00, 0x3f, 0x00, 0xb1, 0x31, 0x2c, 0x2d, 0xd8, 0xd2, 0xda,
- 0x43, 0x26, 0x4a, 0x99, 0x1e, 0x15, 0x98, 0x2e, 0x2f, 0x51, 0x49, 0x0b,
- 0x03, 0x70, 0x90, 0x6c, 0x9f, 0x4d, 0xb7, 0xf5, 0xc3, 0x0b, 0x4f, 0x09,
- 0x1f, 0x08, 0xa5, 0x95, 0xb6, 0xb7, 0x50, 0x4e, 0x95, 0xab, 0xe4, 0xbf,
- 0x2a, 0xb1, 0x17, 0xb8, 0xb1, 0xde, 0xdd, 0xf1, 0x34, 0xa1, 0x3b, 0x25,
- 0xb6, 0x5d, 0x67, 0xe2, 0xda, 0x5b, 0xeb, 0x49, 0xf0, 0xd2, 0x83, 0xe1,
- 0xa9, 0x37, 0xbe, 0x91, 0x72, 0xab, 0x5f, 0x73, 0x7f, 0xb6, 0x1d, 0x28,
- 0xf0, 0xdf, 0xf1, 0x9b, 0x05, 0x2e, 0x20, 0x32, 0xd8, 0x64, 0x23, 0x52,
- 0x4a, 0x9c, 0xb7, 0x2b, 0x52, 0x8d, 0xd5, 0xe9, 0xe5, 0xdb, 0x83, 0xea,
- 0x30, 0x09, 0x75, 0x86, 0x25, 0xec, 0x1e, 0x58, 0x4d, 0xf9, 0x90, 0x20,
- 0x87, 0x60, 0x4e, 0x91, 0xb2, 0xc3, 0x72, 0x63, 0xcd, 0x40, 0x76, 0x63,
- 0xd2, 0x5b, 0x4a, 0x75, 0x04, 0x20, 0x06, 0xf9, 0xdb, 0xcd, 0xdc, 0x83,
- 0xe9, 0x6b, 0xec, 0x0d, 0xf1, 0xba, 0x5f, 0x76, 0xe9, 0x50, 0x43, 0x65,
- 0xd9, 0x05, 0x21, 0x08, 0xf2, 0x92, 0x94, 0x05, 0x73, 0x72, 0x48, 0x20,
- 0x5c, 0xaa, 0xf8, 0xf8, 0xa9, 0x34, 0x97, 0xe4, 0x3e, 0xc7, 0xc4, 0x80,
- 0x95, 0x90, 0x90, 0x9d, 0x1a, 0x94, 0x8b, 0xd8, 0x6d, 0xb5, 0x80, 0xef,
- 0xf7, 0xc7, 0xeb, 0x14, 0xb7, 0xdb, 0x79, 0x45, 0x2f, 0xb6, 0x50, 0x55,
- 0x7b, 0x96, 0x86, 0xb4, 0xf1, 0xc2, 0xaf, 0x7e, 0xc3, 0x7c, 0x65, 0x77,
- 0x15, 0x52, 0x98, 0x36, 0x53, 0xc3, 0xca, 0xe7, 0xe5, 0x78, 0xf0, 0xb0,
- 0xb3, 0x99, 0x11, 0xae, 0xa6, 0xd8, 0x91, 0x2c, 0x38, 0x3c, 0x37, 0xb4,
- 0x36, 0xa6, 0x99, 0xd2, 0xb2, 0xb0, 0xda, 0x01, 0x04, 0xea, 0x24, 0x8d,
- 0xcd, 0xb6, 0xfa, 0x63, 0x62, 0x92, 0xdb, 0x2c, 0xb8, 0xcb, 0x29, 0x7d,
- 0x97, 0x94, 0x5b, 0x53, 0xa0, 0x22, 0xfa, 0x02, 0x52, 0x52, 0x35, 0x12,
- 0x2f, 0x71, 0x7b, 0x72, 0x77, 0xe0, 0x63, 0xc2, 0xb9, 0x43, 0xa9, 0x39,
- 0x09, 0xc8, 0xd0, 0x1f, 0x6d, 0x95, 0xbb, 0xa5, 0x7f, 0x10, 0xfa, 0x3c,
- 0x5d, 0xf5, 0x58, 0x24, 0x20, 0x5b, 0x51, 0x3c, 0x58, 0x9b, 0x5a, 0xf7,
- 0xbd, 0xf1, 0x2f, 0xcd, 0x94, 0x9c, 0xff, 0x00, 0x4a, 0x94, 0xe4, 0xba,
- 0x8e, 0x60, 0xa8, 0xba, 0xc0, 0x05, 0x1a, 0xe2, 0x47, 0x09, 0x09, 0x4f,
- 0xa6, 0x94, 0x8b, 0xa7, 0xd8, 0x0f, 0xb6, 0x0a, 0xd3, 0xaa, 0x54, 0xe9,
- 0xe5, 0xa1, 0x29, 0x98, 0x4a, 0x4a, 0xb4, 0x0a, 0xba, 0x6f, 0x9d, 0xb7,
- 0x16, 0xbf, 0x21, 0x7b, 0x9d, 0x84, 0x0d, 0xa8, 0x4c, 0xb9, 0x26, 0xd9,
- 0x73, 0xb2, 0x52, 0xc0, 0xff, 0x00, 0xa8, 0x07, 0xda, 0xf7, 0xeb, 0x95,
- 0x84, 0x55, 0xdb, 0x4c, 0x26, 0xa4, 0x3e, 0xdb, 0x0b, 0x2e, 0xcb, 0x91,
- 0x24, 0xbe, 0xa2, 0x2c, 0x08, 0x52, 0x86, 0xca, 0xb7, 0x17, 0x00, 0x58,
- 0xed, 0x72, 0x0e, 0xf8, 0xf8, 0x7e, 0x6c, 0x28, 0xce, 0x3a, 0xc3, 0x25,
- 0x90, 0x88, 0xc9, 0xd4, 0xe9, 0x71, 0xc0, 0x09, 0x52, 0x85, 0xed, 0xa8,
- 0xf7, 0xbd, 0xff, 0x00, 0x4d, 0x86, 0x39, 0x96, 0xa7, 0xd4, 0x6a, 0x63,
- 0x28, 0x5b, 0x1f, 0xce, 0x33, 0xf5, 0x36, 0x0a, 0x5c, 0x49, 0x75, 0x6b,
- 0x70, 0xab, 0x8b, 0x8b, 0x91, 0x63, 0x6b, 0x6d, 0x6e, 0xd8, 0x00, 0xee,
- 0x76, 0xca, 0xce, 0x27, 0xc6, 0x6a, 0x8b, 0x32, 0x78, 0x69, 0x3f, 0xda,
- 0x3a, 0xa6, 0xca, 0x89, 0xb7, 0x2a, 0x3b, 0x9f, 0x7c, 0x37, 0xff, 0x00,
- 0x41, 0x69, 0x1f, 0xf2, 0xbe, 0x07, 0xa7, 0xd4, 0x88, 0x54, 0x18, 0xaa,
- 0x61, 0xcf, 0xf8, 0xa4, 0xd6, 0x7a, 0xe5, 0xf3, 0x1f, 0xac, 0x75, 0x8c,
- 0x0c, 0xc3, 0x02, 0xa3, 0x50, 0x6a, 0x9c, 0xc5, 0x62, 0x92, 0xe4, 0xa7,
- 0x10, 0xb6, 0xbe, 0x1d, 0xb9, 0x2d, 0xad, 0x00, 0x80, 0x3f, 0x2f, 0xcc,
- 0xb5, 0x0b, 0x1e, 0x2c, 0x07, 0xb9, 0xc7, 0xae, 0x68, 0x96, 0xa4, 0xd2,
- 0xcb, 0x31, 0x25, 0x29, 0x72, 0x00, 0x0d, 0x96, 0xda, 0xec, 0x9b, 0xf7,
- 0xb0, 0xd8, 0xf7, 0xda, 0xc7, 0xb6, 0x21, 0x79, 0x22, 0x3d, 0x1e, 0xbf,
- 0x45, 0x8b, 0x3c, 0xd3, 0x95, 0x11, 0xb9, 0x26, 0xf1, 0x5c, 0x69, 0x65,
- 0xa7, 0x10, 0xa0, 0xe6, 0x84, 0x9d, 0xb7, 0x1e, 0x71, 0x89, 0xac, 0x0a,
- 0x9d, 0x56, 0x8f, 0x38, 0x48, 0x8d, 0x52, 0x9d, 0x0d, 0x65, 0xc2, 0x54,
- 0xeb, 0x2e, 0xa9, 0x0a, 0x55, 0x8d, 0x89, 0xe7, 0x7e, 0xfc, 0xe0, 0x0d,
- 0x79, 0xb6, 0xe9, 0x8a, 0x42, 0x50, 0x4a, 0x82, 0xc6, 0xbf, 0xa4, 0x51,
- 0xbe, 0x1b, 0xc8, 0x2b, 0x18, 0x35, 0x32, 0xe3, 0x87, 0xb2, 0x53, 0x2a,
- 0x09, 0xe1, 0xd6, 0xe4, 0x8b, 0xe6, 0x76, 0xf4, 0x31, 0xd6, 0x31, 0x67,
- 0x66, 0x00, 0xda, 0x90, 0x22, 0xc6, 0x79, 0xb4, 0x20, 0xa1, 0x6f, 0xbc,
- 0x0a, 0x41, 0x09, 0xf3, 0x6b, 0x09, 0x37, 0xb0, 0x36, 0xdc, 0x12, 0x4e,
- 0xd8, 0x11, 0x51, 0x7f, 0xf8, 0xed, 0x5a, 0x1c, 0x88, 0x35, 0x04, 0xa5,
- 0xc8, 0x4d, 0x2d, 0x4d, 0xa9, 0xc8, 0xd6, 0x6b, 0x52, 0x87, 0x99, 0x4a,
- 0xb8, 0xdc, 0x93, 0xc0, 0x06, 0xdc, 0xe2, 0x21, 0x13, 0xa9, 0xd9, 0xb0,
- 0xb1, 0xe1, 0x4a, 0xaf, 0x3a, 0xe9, 0x4a, 0xb5, 0x21, 0x6e, 0xb0, 0x85,
- 0x9f, 0x6b, 0xa8, 0x6f, 0x7f, 0xb6, 0x35, 0xe2, 0xf5, 0x37, 0x37, 0xca,
- 0x7c, 0x35, 0x51, 0xaf, 0xae, 0x13, 0x00, 0xfc, 0xed, 0x46, 0xd7, 0x71,
- 0xfe, 0x22, 0x0d, 0xc7, 0xe8, 0x70, 0x10, 0xcf, 0xb0, 0x53, 0x61, 0x73,
- 0xe9, 0xfa, 0xc3, 0xcc, 0xc6, 0x09, 0x7a, 0x50, 0x15, 0x29, 0x1c, 0x5f,
- 0xf9, 0xb9, 0xfa, 0x67, 0xe5, 0x68, 0xe8, 0x7a, 0x34, 0x17, 0x60, 0x34,
- 0xa0, 0x66, 0x53, 0xdb, 0x53, 0x84, 0xea, 0x5b, 0x67, 0x4d, 0xfd, 0xfc,
- 0xbe, 0xfb, 0xf3, 0xbf, 0xd3, 0x6c, 0x7d, 0x66, 0x87, 0xeb, 0x74, 0xf8,
- 0xb1, 0xe1, 0xd2, 0xc4, 0x35, 0x49, 0x90, 0xcb, 0xae, 0xc3, 0x73, 0x7d,
- 0x3a, 0x90, 0x9b, 0x90, 0x45, 0xed, 0xbd, 0xf6, 0x3c, 0x0e, 0x6d, 0x89,
- 0xa6, 0x46, 0x89, 0x56, 0xac, 0x4b, 0x81, 0x35, 0xac, 0xdc, 0xfd, 0x56,
- 0x31, 0x7d, 0x2a, 0x29, 0x60, 0x0b, 0x25, 0x49, 0x58, 0xd9, 0xc0, 0x07,
- 0x96, 0xe3, 0xb1, 0xb6, 0xd8, 0xac, 0xe7, 0xb4, 0x45, 0x6a, 0xaf, 0x4b,
- 0x43, 0x4a, 0x6d, 0x25, 0xa9, 0x32, 0x11, 0xa1, 0x24, 0x5d, 0x29, 0x53,
- 0x5b, 0x6d, 0xd8, 0x5c, 0x60, 0xad, 0x29, 0x4d, 0xcc, 0x38, 0x3b, 0xb6,
- 0x00, 0x8d, 0x77, 0x85, 0xb9, 0x96, 0x19, 0x49, 0x52, 0x10, 0x9c, 0xc2,
- 0x54, 0x73, 0x1a, 0x10, 0x92, 0x47, 0xbd, 0xa2, 0x1c, 0x9f, 0xfc, 0x40,
- 0x7a, 0x32, 0x5f, 0x97, 0x99, 0x1d, 0x52, 0xdb, 0x36, 0x11, 0x92, 0xe2,
- 0x90, 0xd3, 0x62, 0xdc, 0x0d, 0x24, 0x11, 0xb1, 0xc2, 0xfd, 0x5a, 0x5e,
- 0x60, 0x42, 0x2c, 0xfc, 0x07, 0x18, 0x75, 0x2a, 0xba, 0x26, 0x21, 0xe5,
- 0x3f, 0x63, 0xfd, 0xe4, 0xa9, 0x47, 0xca, 0x46, 0xe3, 0x71, 0xdf, 0x19,
- 0xd6, 0x3a, 0xd5, 0x5e, 0x91, 0x0d, 0x2f, 0xc1, 0x21, 0x94, 0x29, 0xd7,
- 0x2e, 0x15, 0x65, 0x05, 0x5b, 0x4e, 0xe4, 0x7d, 0xf8, 0x38, 0x0b, 0x42,
- 0xea, 0x69, 0x30, 0x9b, 0x6a, 0xb9, 0x4b, 0x43, 0xe1, 0xb0, 0x12, 0x1d,
- 0x8e, 0x7c, 0x32, 0x8f, 0xb7, 0x6f, 0xb6, 0x28, 0xcb, 0x99, 0x92, 0x95,
- 0x74, 0x36, 0xa0, 0x94, 0xa8, 0x8b, 0x8c, 0xac, 0x39, 0x74, 0x88, 0xa6,
- 0x1f, 0xc4, 0x18, 0xbd, 0x12, 0x9f, 0x8e, 0x67, 0x85, 0xe6, 0xd4, 0x4d,
- 0xd2, 0x6d, 0x71, 0x6d, 0x6d, 0x98, 0x3e, 0x40, 0xf9, 0x40, 0xf9, 0x19,
- 0x9a, 0xad, 0xe3, 0x3b, 0x11, 0x6e, 0xca, 0xa9, 0x6b, 0x56, 0x8d, 0x72,
- 0x5c, 0x4a, 0xad, 0x7b, 0x0b, 0x24, 0xe9, 0x3a, 0x71, 0xf7, 0x97, 0xaa,
- 0x19, 0x86, 0x65, 0x52, 0x24, 0x66, 0xe9, 0x0d, 0xb7, 0xe3, 0x38, 0x1b,
- 0x49, 0x44, 0x50, 0xab, 0x82, 0xab, 0x5e, 0xc4, 0x6f, 0x6c, 0x35, 0xb3,
- 0x4b, 0xcb, 0x79, 0x89, 0xe4, 0xce, 0xa6, 0x26, 0x6c, 0x69, 0x5a, 0x82,
- 0x95, 0x29, 0x2b, 0x52, 0x1d, 0x41, 0x3b, 0x8b, 0x91, 0xda, 0xc3, 0x6d,
- 0x88, 0xd8, 0xe1, 0x93, 0x2f, 0xcf, 0xab, 0xe5, 0x7c, 0xc7, 0x4d, 0x46,
- 0x60, 0x97, 0x0e, 0x75, 0x31, 0xe9, 0x08, 0x69, 0x12, 0x8c, 0x60, 0x87,
- 0xda, 0xf4, 0xbe, 0x8b, 0x05, 0x0f, 0xb0, 0x3d, 0xf1, 0x8a, 0x64, 0xd5,
- 0x5a, 0x1c, 0x52, 0xae, 0x24, 0xa0, 0x67, 0x6b, 0x01, 0xfc, 0xfa, 0xc3,
- 0x75, 0x33, 0xe2, 0x63, 0x4f, 0xbc, 0x99, 0x57, 0xd2, 0x59, 0x73, 0x4e,
- 0x12, 0x32, 0xbf, 0xcf, 0xd6, 0x06, 0xf5, 0x01, 0xd9, 0x74, 0xac, 0xba,
- 0xdb, 0x2f, 0x33, 0x1d, 0xba, 0x85, 0x36, 0xae, 0xe4, 0x77, 0x5d, 0x61,
- 0xad, 0x96, 0x0b, 0x63, 0x70, 0x07, 0xfd, 0x37, 0xb6, 0x1f, 0xba, 0x4b,
- 0x5b, 0x95, 0x3f, 0x2b, 0xc1, 0x44, 0xc7, 0x1e, 0x96, 0x02, 0x8d, 0xca,
- 0x9b, 0xb2, 0x94, 0x41, 0x24, 0x12, 0x2f, 0xcd, 0xec, 0x37, 0xe7, 0xdf,
- 0x13, 0xbe, 0xb2, 0x54, 0x4c, 0xba, 0xce, 0x60, 0x5c, 0x25, 0x87, 0xe9,
- 0xee, 0x4a, 0x6e, 0x49, 0xf0, 0xd3, 0x72, 0x95, 0x29, 0x24, 0x03, 0xa8,
- 0x1d, 0xb9, 0x3b, 0x7b, 0x7b, 0x60, 0xef, 0x43, 0x5d, 0x29, 0x88, 0xdb,
- 0x8b, 0x72, 0x33, 0x65, 0x5e, 0x25, 0xee, 0x17, 0x7b, 0x10, 0x05, 0xac,
- 0x0d, 0x89, 0xdb, 0x83, 0x85, 0x8c, 0x5a, 0x78, 0x66, 0x9a, 0x58, 0xdd,
- 0x20, 0x9f, 0x3b, 0x9f, 0xac, 0x3b, 0xd5, 0xdb, 0xb9, 0x4a, 0xd5, 0xa9,
- 0x00, 0xfb, 0x40, 0xac, 0xbf, 0x98, 0xbe, 0x31, 0x9a, 0xab, 0x73, 0x42,
- 0xde, 0x80, 0xc7, 0x87, 0xa9, 0x2b, 0x6c, 0x10, 0xe0, 0x28, 0xbe, 0xe0,
- 0xec, 0x47, 0xa7, 0xfb, 0x62, 0x9b, 0x94, 0x9a, 0xa9, 0xd6, 0x72, 0xa8,
- 0x95, 0x90, 0x33, 0x73, 0x72, 0xd6, 0x86, 0x2e, 0x69, 0x92, 0xbc, 0xcb,
- 0x61, 0x76, 0xf9, 0x52, 0x54, 0x6f, 0xa7, 0xd8, 0x92, 0x3d, 0x14, 0x31,
- 0x03, 0x76, 0x3b, 0x4d, 0xe4, 0xcc, 0xcd, 0x23, 0x58, 0xbb, 0x8d, 0xa2,
- 0xe9, 0x04, 0xd9, 0x20, 0x04, 0x8d, 0xbd, 0x76, 0xc4, 0xf3, 0x2a, 0x55,
- 0x33, 0x44, 0x4c, 0xf6, 0x22, 0xe5, 0x27, 0xa6, 0xae, 0xa2, 0xe4, 0xa0,
- 0x96, 0x44, 0x72, 0x6e, 0x0d, 0x85, 0xcd, 0x87, 0x6b, 0x5e, 0xff, 0x00,
- 0xbe, 0x3d, 0xa6, 0x9a, 0x94, 0x98, 0xa7, 0xcb, 0x4a, 0x4c, 0xb4, 0x16,
- 0x14, 0x9b, 0xe6, 0x01, 0xcf, 0x2d, 0xb5, 0xdf, 0x50, 0x41, 0x89, 0x54,
- 0x8c, 0xa3, 0xc2, 0xa1, 0x3d, 0x50, 0x65, 0xee, 0x12, 0x85, 0x81, 0x62,
- 0x6c, 0x2d, 0x62, 0x49, 0xdc, 0x65, 0x6d, 0xd2, 0x44, 0x5c, 0x1e, 0xcf,
- 0x3d, 0x5a, 0x62, 0xa4, 0xe5, 0x3e, 0xa5, 0x50, 0xa7, 0xd2, 0xdd, 0x49,
- 0xd2, 0x84, 0xbc, 0xd6, 0x95, 0x39, 0xcd, 0x82, 0x6f, 0x7b, 0xf1, 0xce,
- 0xe0, 0x7a, 0xe1, 0x83, 0x20, 0xbf, 0xd4, 0x0a, 0xad, 0x42, 0x4b, 0xd5,
- 0x6c, 0xe0, 0xf1, 0x66, 0x24, 0xe6, 0xee, 0xcb, 0x6d, 0x20, 0x02, 0x9b,
- 0x82, 0x52, 0xab, 0x0f, 0x4d, 0x88, 0xf7, 0xc1, 0x8c, 0xd5, 0x2e, 0x8a,
- 0x7a, 0x5d, 0x4e, 0x8b, 0x5b, 0x8e, 0xd2, 0xab, 0x06, 0xea, 0x50, 0x6d,
- 0x3b, 0xa1, 0xb2, 0xa3, 0xa0, 0x58, 0x7f, 0xcc, 0x50, 0xb5, 0x80, 0xdc,
- 0x83, 0xbe, 0x24, 0xbd, 0x36, 0xcc, 0x33, 0xb2, 0xcd, 0x54, 0x25, 0x42,
- 0x4a, 0x5a, 0x2e, 0x02, 0x96, 0xdc, 0x90, 0x4a, 0x55, 0x7d, 0x89, 0xb7,
- 0x04, 0x81, 0xff, 0x00, 0xd6, 0xf8, 0x54, 0xad, 0xe1, 0x4a, 0x6d, 0x38,
- 0x07, 0x19, 0x69, 0x20, 0x1b, 0xe4, 0x52, 0x2f, 0x96, 0xe0, 0xf2, 0x3b,
- 0x7d, 0x61, 0xaf, 0x0d, 0x62, 0x79, 0x8a, 0xb0, 0x52, 0x1c, 0x02, 0xe9,
- 0x09, 0xcc, 0x68, 0x4a, 0x85, 0xed, 0xa7, 0xf9, 0x0d, 0xc7, 0x8e, 0xd1,
- 0xd8, 0x64, 0xff, 0x00, 0xc5, 0xb4, 0xd3, 0x68, 0x05, 0x28, 0x0a, 0x5a,
- 0x92, 0x4f, 0xe5, 0x4b, 0x97, 0xb7, 0xe8, 0x71, 0x1a, 0xab, 0xfe, 0x21,
- 0x29, 0xd4, 0x7e, 0xa5, 0xce, 0xca, 0x35, 0xea, 0x64, 0x91, 0x09, 0x01,
- 0x05, 0x12, 0xda, 0x40, 0x50, 0x4e, 0xa1, 0xdd, 0x3c, 0xd8, 0x7a, 0xef,
- 0x8a, 0xc5, 0x36, 0xa9, 0x0e, 0x44, 0x84, 0xe8, 0x73, 0xfb, 0x59, 0x2c,
- 0x29, 0x4d, 0xa7, 0xbf, 0x65, 0x7f, 0xa1, 0xc7, 0x13, 0xf5, 0x06, 0x9b,
- 0x52, 0xac, 0xfe, 0x20, 0x6a, 0x90, 0x20, 0x45, 0x91, 0x2a, 0x5b, 0x8b,
- 0x6d, 0xb6, 0x19, 0x6c, 0x5d, 0x4b, 0xb2, 0x78, 0x1f, 0xbe, 0xfc, 0x0c,
- 0x21, 0x61, 0xb9, 0x66, 0xa7, 0xdb, 0xb3, 0xa7, 0x44, 0x2b, 0x43, 0x6b,
- 0x10, 0xb4, 0x81, 0xec, 0x77, 0xb8, 0xcc, 0xc1, 0xa7, 0xf8, 0x99, 0x48,
- 0x36, 0xce, 0xe0, 0x67, 0xc8, 0x85, 0x1f, 0xa6, 0xa2, 0x3a, 0x3b, 0x33,
- 0xe4, 0x8c, 0x85, 0xd4, 0x46, 0xda, 0xae, 0x52, 0xc4, 0x07, 0x64, 0x2e,
- 0xc0, 0x49, 0x61, 0x00, 0x2b, 0xe8, 0xbb, 0x6f, 0xbe, 0x14, 0xab, 0xb9,
- 0x30, 0x50, 0x22, 0xff, 0x00, 0x0f, 0xfe, 0x13, 0x18, 0x7c, 0x72, 0x96,
- 0xc0, 0x90, 0x41, 0x29, 0x41, 0x50, 0xb0, 0xbf, 0x1e, 0x5e, 0x76, 0xdb,
- 0xdc, 0xfa, 0xb5, 0xf4, 0xeb, 0x24, 0x53, 0x7a, 0x71, 0x45, 0x7a, 0xa1,
- 0x5b, 0xa8, 0x32, 0x89, 0xd3, 0x96, 0xda, 0xa5, 0x25, 0xb5, 0xf9, 0x1b,
- 0x08, 0x3a, 0x92, 0x80, 0x7f, 0x32, 0xb5, 0x5a, 0xea, 0xf6, 0xb0, 0xbe,
- 0x06, 0x75, 0x3e, 0xa9, 0x5a, 0xce, 0x51, 0xa1, 0xc3, 0xa7, 0xb0, 0x61,
- 0xc5, 0x5c, 0x80, 0x59, 0x52, 0x8d, 0x9c, 0x58, 0x48, 0x24, 0x1b, 0x7e,
- 0x54, 0xef, 0xdf, 0x72, 0x71, 0xda, 0x98, 0xf4, 0xe8, 0x9f, 0xec, 0xa5,
- 0x9d, 0x2e, 0x32, 0x35, 0xb8, 0xc8, 0x78, 0x03, 0xe9, 0xa6, 0xa7, 0x6b,
- 0x46, 0x87, 0xc3, 0x45, 0xae, 0x35, 0xa4, 0x5f, 0x9e, 0xff, 0x00, 0xbf,
- 0xa6, 0x9b, 0xc2, 0xfc, 0xa9, 0xf1, 0x13, 0x97, 0xbc, 0x4a, 0x32, 0x2e,
- 0xd4, 0x0b, 0xb4, 0xa0, 0x11, 0xa7, 0xcc, 0xd3, 0x89, 0x52, 0x94, 0x94,
- 0x8b, 0x00, 0x2f, 0x72, 0x3d, 0xb1, 0x36, 0xeb, 0x1c, 0x07, 0x28, 0xd3,
- 0x6b, 0xb4, 0xc9, 0x4e, 0x15, 0x25, 0x82, 0xb5, 0x31, 0xa4, 0xdd, 0x29,
- 0x4a, 0x9c, 0x43, 0xa9, 0x23, 0xfc, 0xaa, 0xfd, 0xf1, 0xbb, 0x2e, 0x55,
- 0x6a, 0x87, 0x1a, 0xbc, 0x89, 0x20, 0x29, 0x69, 0x63, 0x5a, 0x52, 0xb0,
- 0x6c, 0x51, 0xa1, 0x40, 0xf1, 0xea, 0x06, 0x06, 0x67, 0xc9, 0x92, 0x33,
- 0x14, 0x36, 0xe4, 0xcb, 0x5f, 0x8a, 0xec, 0x9a, 0x6c, 0x7b, 0xab, 0x48,
- 0x04, 0xff, 0x00, 0x62, 0x11, 0xfb, 0x14, 0xe2, 0xb3, 0x88, 0x78, 0x7f,
- 0x01, 0x26, 0xb3, 0xa8, 0x03, 0xe9, 0xfa, 0x46, 0x4f, 0x85, 0x0c, 0x3c,
- 0xa9, 0xba, 0xd4, 0xba, 0x45, 0xc2, 0xc5, 0xc5, 0xb5, 0xe2, 0xb1, 0xb7,
- 0xce, 0xde, 0x71, 0x36, 0xa6, 0x4b, 0xaa, 0xbf, 0x20, 0x98, 0xaf, 0x68,
- 0x69, 0xb4, 0xdf, 0x4d, 0xb6, 0xb0, 0xf6, 0xe4, 0x93, 0x87, 0x95, 0xaa,
- 0x38, 0xa5, 0x44, 0x4a, 0x81, 0xf8, 0xd4, 0xeb, 0x32, 0x1d, 0x1b, 0x21,
- 0x49, 0x36, 0x29, 0xb0, 0xf5, 0x1b, 0xdc, 0xfd, 0x30, 0x0f, 0x2d, 0xd1,
- 0xd3, 0x0d, 0xa6, 0xde, 0xa8, 0xb8, 0x12, 0xb0, 0x2f, 0x60, 0x0a, 0x83,
- 0x7b, 0x6f, 0x6b, 0x72, 0xac, 0x36, 0xd2, 0xa8, 0x46, 0xbb, 0x1e, 0x4c,
- 0xa8, 0x92, 0x22, 0xa0, 0x34, 0xc9, 0x71, 0xa6, 0x0b, 0xa1, 0x4a, 0x3d,
- 0xbc, 0xd6, 0x3b, 0x2b, 0x93, 0x7e, 0x01, 0xdb, 0x9c, 0x28, 0x4c, 0xad,
- 0x2e, 0x2a, 0xc8, 0x02, 0xdc, 0xe2, 0xc1, 0x46, 0x2f, 0x50, 0x25, 0x7f,
- 0x11, 0x50, 0x75, 0x5c, 0x4a, 0xff, 0x00, 0x16, 0xef, 0xa7, 0x5b, 0xe9,
- 0xd3, 0x6d, 0xf3, 0xc8, 0x6e, 0xf4, 0xff, 0x00, 0x3d, 0x4c, 0xca, 0xf9,
- 0x88, 0x7c, 0x2c, 0x1d, 0x46, 0x63, 0x29, 0x6c, 0xa4, 0x27, 0x40, 0xb2,
- 0x38, 0x59, 0xf5, 0x27, 0x7f, 0xd7, 0x1d, 0x08, 0xce, 0x65, 0x6e, 0xa7,
- 0x54, 0xa7, 0x4f, 0xac, 0xa6, 0x3c, 0x79, 0x29, 0x7e, 0x13, 0xc8, 0x49,
- 0x50, 0x05, 0x45, 0xd0, 0xa4, 0xad, 0x36, 0xfc, 0xdc, 0x03, 0x8e, 0x7d,
- 0x32, 0xa0, 0x57, 0xa9, 0x52, 0x6a, 0xeb, 0x52, 0x19, 0xaa, 0x46, 0x8a,
- 0x52, 0x96, 0xb4, 0x24, 0x2d, 0xc2, 0x15, 0xdf, 0xe8, 0x07, 0x1c, 0x91,
- 0xfa, 0x63, 0xa0, 0xf3, 0x25, 0x39, 0x0e, 0x51, 0x29, 0x12, 0xc2, 0x59,
- 0xb3, 0x52, 0x60, 0x91, 0x74, 0x0b, 0xdb, 0xc3, 0x3d, 0xff, 0x00, 0x4c,
- 0x14, 0xa5, 0x29, 0x69, 0x70, 0x24, 0x69, 0xcb, 0xce, 0x13, 0xa6, 0xa7,
- 0x45, 0x49, 0xf7, 0x5d, 0x75, 0x20, 0x29, 0x79, 0x65, 0xb0, 0xd2, 0xde,
- 0x62, 0x21, 0xff, 0x00, 0x88, 0xf6, 0x9b, 0xa9, 0x52, 0x2a, 0xb2, 0xa1,
- 0x21, 0x6d, 0x21, 0x55, 0x37, 0x96, 0xce, 0xa1, 0xa4, 0xe8, 0x52, 0xc1,
- 0xbe, 0x9e, 0xc2, 0xd7, 0xdb, 0x12, 0x9e, 0x9c, 0xd2, 0xe6, 0xd5, 0x5f,
- 0x31, 0xe1, 0x34, 0xeb, 0xce, 0xa9, 0x77, 0x5a, 0x95, 0xe6, 0x48, 0x48,
- 0x16, 0x25, 0x46, 0xf6, 0x03, 0x91, 0x8b, 0xa6, 0x64, 0xa0, 0x53, 0xb3,
- 0x35, 0x3e, 0x43, 0x55, 0x17, 0x8b, 0x4d, 0x25, 0xe2, 0xe2, 0x8a, 0x57,
- 0xa7, 0x6b, 0x9b, 0x8b, 0x8c, 0x20, 0x55, 0xf3, 0xad, 0x03, 0x2c, 0x43,
- 0x5e, 0x5a, 0xca, 0x8c, 0xc6, 0x6e, 0xc7, 0x77, 0xd1, 0x65, 0x24, 0x2b,
- 0xde, 0xff, 0x00, 0x3e, 0x29, 0x53, 0xb4, 0xa6, 0x9e, 0x71, 0x2f, 0xbc,
- 0xab, 0x21, 0x09, 0x00, 0xff, 0x00, 0x3f, 0x66, 0x3e, 0x6d, 0xa0, 0xe2,
- 0x09, 0xa6, 0xd8, 0x5c, 0x8c, 0x8b, 0x65, 0x4f, 0x95, 0xa8, 0xdf, 0xf2,
- 0xa4, 0x13, 0xaf, 0xcf, 0x28, 0x6c, 0x8e, 0xec, 0x2c, 0xa7, 0x0d, 0x98,
- 0xad, 0x3d, 0xfc, 0x46, 0xa5, 0x21, 0x21, 0xa4, 0x45, 0x8e, 0x92, 0x55,
- 0xb7, 0x01, 0x29, 0xf4, 0xdc, 0xf9, 0x8f, 0xfa, 0x63, 0xe2, 0xa1, 0x42,
- 0xcc, 0xf5, 0x67, 0x04, 0xfa, 0xac, 0x96, 0xd8, 0x75, 0x2b, 0x40, 0x6a,
- 0x1b, 0x67, 0x59, 0x66, 0xff, 0x00, 0x4f, 0x99, 0x7f, 0xb0, 0xf7, 0xc0,
- 0x8c, 0x9b, 0x51, 0xa7, 0x46, 0xa6, 0xaa, 0x5c, 0xe9, 0xaf, 0x3d, 0x52,
- 0x99, 0xaf, 0xc5, 0x74, 0x2e, 0xca, 0x52, 0x38, 0xb1, 0x3f, 0x30, 0x16,
- 0xbe, 0xc2, 0xc3, 0x7c, 0x51, 0x1e, 0xcd, 0xd4, 0xc5, 0x25, 0xa8, 0xca,
- 0x9d, 0x09, 0x98, 0xcd, 0xa5, 0xb6, 0x8a, 0x84, 0x93, 0xad, 0x56, 0x1c,
- 0x9b, 0x26, 0xfe, 0xbb, 0x8e, 0x6f, 0x85, 0xaa, 0x96, 0x21, 0x2a, 0x4f,
- 0xe1, 0xa4, 0xc7, 0x0a, 0x34, 0xbe, 0xe7, 0xa7, 0x21, 0xef, 0x0e, 0x94,
- 0x6c, 0x22, 0xdc, 0xab, 0x9f, 0x8d, 0x9d, 0x3d, 0xac, 0xc1, 0xcc, 0x93,
- 0x98, 0x1d, 0x07, 0x84, 0x44, 0x73, 0x33, 0xd3, 0xe9, 0x30, 0x26, 0x95,
- 0xbb, 0xe3, 0x04, 0xb6, 0x94, 0x3e, 0x82, 0x2d, 0x72, 0x97, 0x08, 0xbe,
- 0xde, 0x84, 0x1c, 0x51, 0xba, 0x0d, 0x3d, 0x72, 0x29, 0x25, 0x6c, 0x48,
- 0x5b, 0x5a, 0x96, 0x97, 0x2e, 0xa2, 0x12, 0x1b, 0x00, 0x8b, 0xf3, 0x7b,
- 0xdf, 0xb6, 0x17, 0xb3, 0x4c, 0x5a, 0x6d, 0x43, 0x2d, 0x66, 0x37, 0x20,
- 0xba, 0x99, 0x29, 0x44, 0x67, 0x9c, 0x2e, 0x24, 0x6c, 0x56, 0x97, 0x8a,
- 0xbf, 0xf8, 0xd8, 0xfd, 0xf1, 0xf5, 0xf8, 0x7d, 0x6c, 0x38, 0x66, 0x43,
- 0x4a, 0x1d, 0xf0, 0x8b, 0xc1, 0xd0, 0x7c, 0x3b, 0xa5, 0x28, 0xd3, 0x7b,
- 0x0b, 0x5f, 0xbe, 0xd6, 0x27, 0x1e, 0x63, 0x04, 0x36, 0x4b, 0x2e, 0xb7,
- 0xba, 0x47, 0xb4, 0x3e, 0xcf, 0xa5, 0x60, 0xa0, 0xab, 0x74, 0x88, 0x1f,
- 0x4d, 0x6a, 0x75, 0x5a, 0x85, 0x98, 0xe0, 0xb0, 0x94, 0x95, 0x49, 0x75,
- 0xb6, 0xc0, 0xe6, 0xc0, 0x5a, 0xdb, 0xfa, 0x5b, 0x9c, 0x13, 0xc9, 0xf5,
- 0xea, 0x5f, 0x4b, 0xa2, 0x4c, 0xa8, 0xc4, 0x9e, 0xc2, 0x6b, 0x13, 0x9b,
- 0x51, 0x54, 0x94, 0xb4, 0x16, 0xea, 0x49, 0x04, 0x14, 0xb6, 0x54, 0x3c,
- 0xa9, 0x17, 0xed, 0xb9, 0x3e, 0x98, 0x0f, 0x42, 0x62, 0xa9, 0x22, 0x74,
- 0xb8, 0x14, 0xe9, 0x11, 0x23, 0xc7, 0x92, 0xe0, 0x52, 0xca, 0x95, 0xa0,
- 0x71, 0x62, 0x9d, 0x86, 0xff, 0x00, 0x41, 0x6b, 0xf0, 0x4e, 0x08, 0x37,
- 0xd1, 0x25, 0x57, 0x67, 0x99, 0x55, 0x4c, 0xd8, 0xb5, 0xb8, 0xad, 0x92,
- 0x94, 0x37, 0xa7, 0x48, 0xec, 0x07, 0x60, 0x31, 0x96, 0x6b, 0x15, 0x52,
- 0x29, 0xf2, 0xad, 0x05, 0xaa, 0xee, 0x84, 0x81, 0xa1, 0x36, 0xc8, 0x5e,
- 0xff, 0x00, 0x7e, 0xd1, 0x3c, 0x6b, 0x0b, 0x55, 0xa7, 0x66, 0x5e, 0xba,
- 0xb8, 0x18, 0x52, 0xf8, 0xb2, 0x20, 0x15, 0x1d, 0xb3, 0xfb, 0xf3, 0x3a,
- 0x0a, 0x8d, 0x2e, 0xa1, 0x99, 0xd9, 0x12, 0x98, 0xab, 0x13, 0x50, 0x64,
- 0x87, 0x9b, 0xf1, 0x1c, 0xb0, 0x48, 0xd4, 0x76, 0x1f, 0xdd, 0x1e, 0xa7,
- 0xe8, 0x37, 0xbe, 0x1b, 0xe9, 0x35, 0x68, 0x53, 0x99, 0x55, 0x32, 0x7c,
- 0x66, 0x51, 0x53, 0x41, 0x0e, 0x3c, 0xeb, 0x29, 0x1e, 0x1b, 0x8d, 0x95,
- 0x69, 0x0b, 0xd8, 0xec, 0x49, 0x3f, 0x4d, 0xb0, 0x73, 0x2e, 0xf4, 0x5f,
- 0x24, 0xd0, 0x90, 0xbf, 0x8e, 0xcd, 0x32, 0x8b, 0x65, 0x43, 0xc4, 0x02,
- 0x62, 0x12, 0x92, 0x47, 0xaf, 0x9a, 0xe7, 0xe9, 0x86, 0x58, 0x39, 0x6b,
- 0xa3, 0x14, 0x79, 0xc9, 0x9a, 0xe5, 0x4a, 0x13, 0xb2, 0xda, 0x01, 0x21,
- 0xc7, 0x65, 0xeb, 0xb0, 0x1c, 0x6c, 0x4e, 0x9b, 0x62, 0x73, 0x52, 0xc5,
- 0xcd, 0x4d, 0x3a, 0x57, 0xc2, 0xb5, 0x93, 0xc9, 0x3f, 0xc6, 0x50, 0xf7,
- 0x23, 0x4e, 0x44, 0xab, 0x61, 0xb6, 0x80, 0x00, 0x6c, 0x9f, 0xd8, 0x6b,
- 0xce, 0x1b, 0x24, 0x43, 0x99, 0x1a, 0x65, 0x00, 0x38, 0xb5, 0x29, 0x25,
- 0xa5, 0xb4, 0xbb, 0x7a, 0xea, 0x40, 0xfe, 0x98, 0xf0, 0xae, 0xcd, 0xc9,
- 0x3d, 0x32, 0x7a, 0xa7, 0x99, 0x24, 0x31, 0x09, 0x35, 0x49, 0x48, 0x4a,
- 0x65, 0xc9, 0x2b, 0x25, 0xd2, 0x81, 0xc2, 0x4a, 0xbf, 0x28, 0x3f, 0xdc,
- 0x4e, 0xe4, 0xf3, 0x7c, 0x22, 0x75, 0xaf, 0xad, 0x59, 0x7e, 0x9b, 0x0e,
- 0x9f, 0x13, 0x2c, 0x4c, 0x6e, 0x6c, 0xf2, 0xfa, 0x34, 0xe8, 0x21, 0xd0,
- 0x11, 0xbe, 0xa2, 0x42, 0x4d, 0xf7, 0xd8, 0x0e, 0x09, 0x3c, 0x71, 0x88,
- 0xd6, 0x70, 0xcd, 0x31, 0xf3, 0x25, 0x41, 0x2e, 0xd5, 0x68, 0x95, 0x29,
- 0xe9, 0x4a, 0x8a, 0xc3, 0x0b, 0x49, 0x4a, 0x50, 0xa3, 0xed, 0xdc, 0xf6,
- 0xb9, 0xdf, 0x18, 0xf0, 0xa6, 0x0d, 0xa8, 0x55, 0x07, 0x6a, 0xb5, 0x76,
- 0x4d, 0xd8, 0x85, 0x0c, 0xee, 0x41, 0x37, 0xb5, 0xad, 0xa1, 0xf1, 0xcb,
- 0x2d, 0xe3, 0xde, 0xa9, 0x5b, 0x6a, 0x59, 0x09, 0x41, 0x69, 0x4e, 0x2f,
- 0x50, 0x00, 0x16, 0xbe, 0xd7, 0x37, 0xca, 0xc3, 0x61, 0x99, 0xbe, 0xd0,
- 0xe3, 0x37, 0xac, 0xc9, 0xcd, 0xb9, 0x8d, 0x72, 0x65, 0xca, 0x8d, 0x1a,
- 0x9f, 0x1d, 0xc0, 0x98, 0xa8, 0x20, 0x0d, 0x42, 0xe4, 0x03, 0x63, 0xb8,
- 0x16, 0x37, 0xb7, 0x3f, 0xd0, 0x3d, 0x2b, 0xa9, 0x52, 0xa8, 0xb5, 0x1b,
- 0xc2, 0x9e, 0xa9, 0x3e, 0x0a, 0xac, 0xea, 0x96, 0x92, 0xef, 0x8e, 0x02,
- 0x48, 0xb6, 0xc3, 0x6d, 0xcf, 0x3e, 0xc3, 0x1e, 0x39, 0x2a, 0x3c, 0x19,
- 0xad, 0x95, 0x46, 0xc8, 0xae, 0xb0, 0x11, 0x75, 0x17, 0x9d, 0x6d, 0x94,
- 0x22, 0xd7, 0xb5, 0xb5, 0x38, 0x40, 0xf6, 0xe4, 0x9f, 0x6c, 0x13, 0x55,
- 0x4e, 0xbe, 0x89, 0x0e, 0xb1, 0x0b, 0x25, 0x25, 0xf0, 0xcb, 0xab, 0x6c,
- 0x3a, 0xd8, 0x6d, 0x68, 0x5d, 0xb7, 0xd8, 0xa4, 0xd8, 0xd8, 0x11, 0x72,
- 0x0d, 0xb1, 0x5d, 0x63, 0x05, 0xca, 0xa1, 0x29, 0x42, 0x5c, 0xb0, 0x1a,
- 0x00, 0x3f, 0x7b, 0xf9, 0x98, 0x4a, 0xfe, 0xb9, 0x5b, 0x71, 0xc2, 0x96,
- 0xa4, 0x14, 0xa2, 0x79, 0xe5, 0x97, 0x90, 0xb5, 0xba, 0x46, 0xf3, 0x75,
- 0x37, 0x73, 0x65, 0x1e, 0xb1, 0x53, 0x96, 0xd2, 0x51, 0x25, 0xe8, 0x2a,
- 0x43, 0x89, 0x4b, 0x6a, 0x4e, 0xe1, 0xb2, 0x01, 0x37, 0xee, 0x7f, 0x7b,
- 0x13, 0x8d, 0x2a, 0xad, 0x06, 0xac, 0xed, 0x0f, 0x2f, 0xcd, 0x85, 0x49,
- 0x95, 0x22, 0x3b, 0xb4, 0xb6, 0x42, 0x5c, 0x61, 0xa5, 0x2c, 0x13, 0xa4,
- 0x13, 0x7b, 0x0d, 0x8d, 0xcf, 0x7c, 0x7d, 0x48, 0x77, 0xa8, 0xd2, 0xe9,
- 0xef, 0xf8, 0x39, 0x6d, 0x2c, 0xc7, 0x28, 0x50, 0x71, 0x20, 0x04, 0xdd,
- 0x36, 0xdc, 0x12, 0x2e, 0x78, 0xf4, 0xdf, 0x1e, 0x1d, 0x31, 0xce, 0x99,
- 0xaa, 0x9b, 0x96, 0xc5, 0x39, 0xfa, 0xb5, 0x3a, 0x0e, 0x95, 0xa9, 0xa6,
- 0x93, 0xf1, 0x0a, 0x42, 0x96, 0x80, 0x4d, 0xb5, 0x24, 0x0b, 0x0b, 0x5e,
- 0xc0, 0x92, 0x36, 0x03, 0x1a, 0xeb, 0xf4, 0xd0, 0xe4, 0xa3, 0x52, 0xa8,
- 0x24, 0xf0, 0xee, 0x6c, 0x32, 0x1c, 0xc9, 0xb0, 0x83, 0x38, 0x0e, 0x7a,
- 0xa5, 0x86, 0x2a, 0x53, 0x35, 0x2a, 0x8b, 0x25, 0x01, 0xdd, 0x12, 0x02,
- 0x95, 0x9f, 0x44, 0x82, 0x72, 0x19, 0xe9, 0x68, 0x13, 0x23, 0x20, 0x67,
- 0x9a, 0xa2, 0xd2, 0x5a, 0xa5, 0xaa, 0x24, 0x72, 0x6c, 0x16, 0xf1, 0xd3,
- 0x72, 0x76, 0x16, 0xc3, 0x36, 0x42, 0xe9, 0x8e, 0x68, 0xa5, 0x3a, 0xec,
- 0x31, 0x5e, 0xa2, 0x35, 0x2a, 0x45, 0x99, 0x0d, 0xf8, 0xda, 0x9c, 0x4a,
- 0xb7, 0x16, 0x00, 0x7e, 0x6d, 0xef, 0xf5, 0x03, 0x04, 0x17, 0x54, 0xcc,
- 0x09, 0x74, 0x3e, 0xac, 0xcd, 0x1d, 0x85, 0x83, 0xa8, 0x29, 0x0b, 0x2a,
- 0x50, 0xf7, 0x1e, 0x71, 0x8d, 0x79, 0xf9, 0x8e, 0xb7, 0xf0, 0x4e, 0xd3,
- 0x0e, 0x64, 0x68, 0xb6, 0xe5, 0xd0, 0xa9, 0xa1, 0xd8, 0xed, 0xad, 0x77,
- 0x37, 0x2a, 0xb6, 0x92, 0xb2, 0x77, 0x3c, 0xaa, 0xfe, 0xf8, 0x0a, 0xde,
- 0x16, 0x9c, 0x29, 0xe0, 0x20, 0x01, 0xd4, 0x7d, 0x2f, 0x05, 0x2a, 0xbf,
- 0x13, 0xe8, 0x73, 0x93, 0x05, 0xd2, 0x54, 0xe2, 0x8f, 0x81, 0x00, 0x0f,
- 0x00, 0x48, 0x19, 0x72, 0xd4, 0xc1, 0x8c, 0xbf, 0xd0, 0xc9, 0x10, 0xa5,
- 0x2e, 0x54, 0x9c, 0xe1, 0x19, 0x84, 0xa9, 0x65, 0x4a, 0x07, 0x65, 0x13,
- 0xde, 0xfa, 0xad, 0x7d, 0xfd, 0x71, 0x4a, 0xcf, 0x79, 0x96, 0x83, 0x46,
- 0xca, 0xb1, 0x62, 0xbb, 0x5c, 0x8b, 0x29, 0xf8, 0xcf, 0x32, 0xe2, 0xfc,
- 0x35, 0x02, 0x43, 0x6d, 0x24, 0xdd, 0x4a, 0xb6, 0xc3, 0xf2, 0x8d, 0xf9,
- 0x27, 0x10, 0x77, 0x17, 0x45, 0xf1, 0x94, 0x26, 0x66, 0xb9, 0x4f, 0xac,
- 0x9e, 0x4a, 0x91, 0x73, 0xf7, 0xb1, 0xc7, 0xb5, 0x7b, 0x2a, 0x51, 0x6a,
- 0x79, 0x3e, 0x5c, 0xc8, 0x95, 0x19, 0xcf, 0xa9, 0xa4, 0xeb, 0xb2, 0x9f,
- 0x51, 0x06, 0xde, 0xa3, 0x83, 0x82, 0xac, 0xe1, 0xa9, 0x86, 0x7b, 0xe9,
- 0x29, 0xe2, 0xea, 0x4f, 0xd2, 0x03, 0x2f, 0xe2, 0x75, 0x19, 0xa7, 0x12,
- 0x7b, 0x27, 0x2d, 0x71, 0x6e, 0xe8, 0x02, 0xfb, 0x5c, 0xdc, 0x9b, 0x40,
- 0x2c, 0xcf, 0x57, 0xa5, 0xc9, 0x6e, 0x75, 0x35, 0x55, 0xa5, 0xb1, 0x19,
- 0xc7, 0x54, 0x7c, 0x26, 0x93, 0x7b, 0x79, 0x89, 0xb0, 0x3b, 0x6d, 0x85,
- 0x08, 0xd4, 0x6c, 0xa4, 0xf4, 0x84, 0x80, 0x9a, 0x9c, 0x85, 0x13, 0x62,
- 0xb2, 0xda, 0x95, 0xfa, 0x01, 0x8e, 0x87, 0x43, 0xf1, 0x29, 0x61, 0x8a,
- 0x76, 0x5c, 0xc9, 0xf4, 0x09, 0x50, 0x62, 0x46, 0x6c, 0x27, 0xc6, 0x6c,
- 0xba, 0xe3, 0xde, 0x51, 0xa9, 0x45, 0x77, 0xe4, 0x9b, 0xf0, 0x0f, 0xdf,
- 0x18, 0xff, 0x00, 0x54, 0x59, 0xa4, 0x7f, 0x66, 0x3a, 0x74, 0xc4, 0x37,
- 0x00, 0xf9, 0xda, 0x4a, 0x54, 0x01, 0xf6, 0xf2, 0x7f, 0xa8, 0x18, 0x2d,
- 0x3f, 0x3d, 0x34, 0x5b, 0x4a, 0x9e, 0x65, 0x27, 0xc8, 0x9b, 0x75, 0x17,
- 0xfa, 0x43, 0xf4, 0xae, 0x1a, 0x69, 0x94, 0x87, 0x99, 0x96, 0x48, 0x0b,
- 0xef, 0x1b, 0x01, 0xbe, 0xe7, 0x33, 0x6f, 0x41, 0x12, 0x68, 0xb9, 0x4d,
- 0x86, 0x23, 0x7c, 0x44, 0x6a, 0x0d, 0x5a, 0x53, 0x62, 0xca, 0xf2, 0xc5,
- 0x74, 0x5c, 0x7d, 0x54, 0x9b, 0x71, 0xef, 0x82, 0xf0, 0x32, 0x95, 0x69,
- 0x6f, 0x29, 0x11, 0xb2, 0x24, 0x97, 0xd2, 0x4d, 0xd2, 0x5f, 0x6c, 0xa4,
- 0xe9, 0x3c, 0x5c, 0x0b, 0x8c, 0x33, 0x2b, 0xac, 0x14, 0x79, 0x95, 0x37,
- 0x6a, 0x2b, 0xca, 0x2e, 0xbb, 0x31, 0x0b, 0x4b, 0x8a, 0x2a, 0x71, 0xd2,
- 0x02, 0xbb, 0x10, 0x92, 0x42, 0x47, 0x1c, 0x01, 0x82, 0x8b, 0xeb, 0x4e,
- 0x66, 0x76, 0x58, 0x71, 0x14, 0xe9, 0x11, 0x12, 0xf0, 0xd4, 0x35, 0x35,
- 0x74, 0xda, 0xc3, 0x72, 0x49, 0x36, 0xda, 0xdc, 0xe1, 0x69, 0x58, 0x8d,
- 0x6d, 0x9e, 0xe8, 0x48, 0xe8, 0x91, 0x1d, 0x84, 0xc2, 0x19, 0x3c, 0x29,
- 0x09, 0x1e, 0x9f, 0x40, 0x60, 0x2b, 0x99, 0x1f, 0xa9, 0x12, 0x68, 0x52,
- 0xa0, 0xc4, 0xa0, 0xc3, 0xa7, 0x46, 0x76, 0x3a, 0xdb, 0x5a, 0x02, 0x14,
- 0x14, 0xa4, 0x11, 0xba, 0x45, 0xc5, 0x85, 0xfd, 0x70, 0x13, 0xa5, 0xd9,
- 0x39, 0xd8, 0xcb, 0xf0, 0x5a, 0x9d, 0x32, 0x9a, 0xea, 0xd6, 0x59, 0x90,
- 0x1a, 0x59, 0x2a, 0x4a, 0xfd, 0x2c, 0x38, 0xb5, 0xb1, 0xd1, 0x7d, 0x1c,
- 0xcd, 0x33, 0xb3, 0x35, 0x0d, 0xea, 0x9c, 0x97, 0x94, 0xb2, 0xd4, 0xa2,
- 0xc3, 0x8d, 0xad, 0x20, 0x8b, 0x69, 0x06, 0xe0, 0x81, 0xf5, 0x18, 0x8b,
- 0xe7, 0x5f, 0x8a, 0xa4, 0x75, 0x36, 0xac, 0x23, 0xad, 0x49, 0x40, 0x9e,
- 0x56, 0x50, 0xa2, 0x40, 0x20, 0x80, 0x47, 0x18, 0x15, 0x58, 0x9f, 0x76,
- 0x71, 0xa4, 0xba, 0xb5, 0x5c, 0x79, 0x0f, 0xbd, 0x20, 0x7c, 0xea, 0xbf,
- 0x11, 0x72, 0x75, 0x1f, 0x28, 0x97, 0x3a, 0xc5, 0x52, 0xb5, 0x29, 0x70,
- 0x68, 0xb2, 0xdc, 0x8f, 0x31, 0x0d, 0x97, 0x95, 0xe1, 0x91, 0x7d, 0xd4,
- 0x76, 0xbd, 0xf6, 0xb5, 0xb9, 0xde, 0xfb, 0x61, 0x36, 0xb9, 0xfc, 0xcf,
- 0x47, 0x7c, 0xb5, 0x57, 0x7e, 0xb3, 0xc6, 0xea, 0x4c, 0x85, 0x14, 0x1f,
- 0xdf, 0x0d, 0x9d, 0x3b, 0x8f, 0x36, 0x99, 0x9b, 0xeb, 0x4b, 0x1a, 0x89,
- 0x6a, 0x31, 0xb1, 0x4f, 0x3a, 0x49, 0x2b, 0xb8, 0x27, 0xd8, 0x7e, 0xa7,
- 0x1e, 0x39, 0x6b, 0xa9, 0x5f, 0x1c, 0xfb, 0xb1, 0x6b, 0xd1, 0x14, 0xe2,
- 0x5c, 0x73, 0x50, 0x79, 0xb4, 0xa5, 0x6a, 0x48, 0x1c, 0x02, 0x95, 0x6c,
- 0xa0, 0x2f, 0xc6, 0x1b, 0xa9, 0x32, 0xf2, 0x32, 0xf2, 0x4d, 0xad, 0x49,
- 0x4f, 0x12, 0xaf, 0x9a, 0x80, 0x39, 0xf9, 0xe9, 0x12, 0x49, 0xfa, 0xa5,
- 0x4c, 0x4f, 0xbc, 0x86, 0x87, 0x1b, 0x68, 0xb6, 0x40, 0xd8, 0x8b, 0xf2,
- 0x84, 0x96, 0xaa, 0xce, 0xc8, 0x64, 0xc4, 0x65, 0x87, 0x54, 0xca, 0xc5,
- 0x94, 0x84, 0xb2, 0x92, 0x55, 0xbd, 0xcf, 0x98, 0xdc, 0xfe, 0xf8, 0xd9,
- 0x4b, 0xae, 0x34, 0x14, 0xf2, 0xe8, 0x0c, 0x21, 0x29, 0xdc, 0xf8, 0x82,
- 0xc7, 0xf4, 0xbe, 0x2a, 0xa7, 0x28, 0xb1, 0x2d, 0x46, 0xab, 0x95, 0xaa,
- 0x10, 0x52, 0xf2, 0x95, 0xe2, 0xa5, 0xa4, 0x37, 0x76, 0xaf, 0x6e, 0x34,
- 0x9d, 0xc7, 0xaf, 0xd7, 0x08, 0x35, 0x18, 0xf2, 0x20, 0xd4, 0x16, 0xc5,
- 0x5d, 0x2a, 0x65, 0xf0, 0x8b, 0x8f, 0x35, 0xc1, 0xed, 0xa8, 0x11, 0xee,
- 0x38, 0xc7, 0x5a, 0x85, 0x4e, 0xa9, 0x4f, 0x1c, 0x69, 0x42, 0x78, 0x79,
- 0x81, 0xf7, 0x6f, 0x94, 0x68, 0xa3, 0xcc, 0x53, 0x6a, 0xaa, 0x2d, 0xa5,
- 0x44, 0x2f, 0x74, 0x9b, 0x83, 0xe3, 0xd6, 0x19, 0xfa, 0x3f, 0x06, 0x8b,
- 0x5b, 0xcf, 0xf4, 0x09, 0x4f, 0xc0, 0x43, 0x5e, 0x12, 0x1d, 0x79, 0x2d,
- 0xa1, 0x45, 0x20, 0xba, 0x84, 0x9d, 0x17, 0x23, 0x7b, 0x03, 0x63, 0xf6,
- 0xb6, 0x3a, 0x0e, 0xbb, 0xd3, 0xa6, 0x44, 0x24, 0x0c, 0xbd, 0x3d, 0xba,
- 0x6c, 0xb2, 0xd8, 0x21, 0xb5, 0x30, 0x85, 0xa1, 0x47, 0xd4, 0x02, 0x2e,
- 0x2f, 0xed, 0x8e, 0x7e, 0xfc, 0x3c, 0x32, 0xb7, 0xb3, 0xe5, 0x27, 0x72,
- 0xa4, 0x21, 0x52, 0x75, 0x90, 0x3e, 0x54, 0xe8, 0x51, 0xfe, 0x98, 0x6c,
- 0xfc, 0x47, 0xe7, 0xdc, 0xd7, 0x94, 0xb3, 0xed, 0x1d, 0xda, 0x05, 0x5d,
- 0x71, 0xdb, 0x11, 0x0a, 0x8b, 0x7a, 0x02, 0x9b, 0x76, 0xe4, 0x6c, 0xb4,
- 0x91, 0xb8, 0xed, 0x89, 0xee, 0x39, 0x99, 0xaa, 0xb9, 0x88, 0xd8, 0x44,
- 0x8b, 0xe5, 0xb2, 0x5a, 0x0a, 0xf0, 0xdf, 0x23, 0xcf, 0x6d, 0x61, 0xef,
- 0x0d, 0x38, 0xdc, 0x9d, 0x35, 0xc5, 0x9f, 0xca, 0xb2, 0x0e, 0xe6, 0xd7,
- 0x00, 0x7c, 0xe0, 0x1f, 0x50, 0x8f, 0x55, 0xf2, 0xa3, 0xaa, 0x45, 0x4a,
- 0x04, 0x79, 0xb0, 0x55, 0xb8, 0x91, 0x19, 0x8d, 0x4d, 0xaa, 0xde, 0xa3,
- 0x80, 0x47, 0xd3, 0x09, 0xea, 0xae, 0xf5, 0x11, 0x6d, 0xa5, 0xc7, 0x1c,
- 0x99, 0x15, 0xbd, 0x65, 0x01, 0x49, 0x8b, 0xa0, 0x6a, 0xb5, 0xf4, 0x8b,
- 0x27, 0x9d, 0x8f, 0xe9, 0x8b, 0x87, 0x4c, 0xba, 0xd9, 0x4b, 0xce, 0x4d,
- 0xff, 0x00, 0x07, 0xcc, 0x94, 0x71, 0x16, 0x72, 0x80, 0x05, 0x6d, 0x5d,
- 0x71, 0xdd, 0x27, 0x61, 0x71, 0xc8, 0x37, 0x3d, 0xef, 0xcf, 0x38, 0x79,
- 0x9f, 0x93, 0x8c, 0x58, 0x4e, 0xd4, 0x68, 0xf2, 0x4b, 0x4c, 0xdb, 0x53,
- 0x8c, 0x2c, 0x6a, 0x09, 0x23, 0x6f, 0x29, 0x3b, 0x8f, 0x4f, 0xbe, 0x04,
- 0x9c, 0x77, 0x52, 0x92, 0x58, 0x97, 0xa9, 0xdd, 0x2a, 0xe6, 0x0e, 0x47,
- 0xd2, 0x0e, 0x25, 0x2e, 0x4c, 0x27, 0x8d, 0xa7, 0x8d, 0x8e, 0xd7, 0xb7,
- 0x95, 0xf5, 0xf5, 0xf5, 0x89, 0x1f, 0x47, 0xa4, 0x67, 0x06, 0x27, 0x4a,
- 0x35, 0xc7, 0x25, 0x86, 0xd4, 0xd1, 0x08, 0xf1, 0x52, 0x52, 0x1c, 0xba,
- 0x55, 0x71, 0xbf, 0xd0, 0x1f, 0xbe, 0x00, 0xaf, 0x5c, 0xa8, 0x5a, 0x94,
- 0x10, 0x5a, 0x84, 0xcb, 0x81, 0x5c, 0x27, 0x48, 0xf1, 0xd4, 0x3e, 0xe4,
- 0x95, 0x7b, 0x9f, 0xd3, 0x14, 0x2f, 0xe6, 0xaa, 0x6d, 0x4d, 0x6c, 0xd3,
- 0xdb, 0x42, 0x5a, 0x79, 0x32, 0x1d, 0x2a, 0x4a, 0x2e, 0x92, 0x2c, 0x40,
- 0xb6, 0xae, 0x49, 0xb0, 0xb9, 0x3e, 0xf8, 0x47, 0xcc, 0xb4, 0xc3, 0x4a,
- 0x6d, 0x6b, 0x2e, 0x25, 0xc2, 0xe4, 0xa7, 0xc1, 0x08, 0xb8, 0x03, 0x4b,
- 0xa4, 0xff, 0x00, 0xa1, 0x18, 0x6f, 0xa9, 0xce, 0x2e, 0x6a, 0x8a, 0xda,
- 0x9c, 0x37, 0x25, 0x47, 0xdb, 0xf9, 0x87, 0x1c, 0x20, 0xa3, 0xda, 0x25,
- 0xc3, 0x9a, 0x80, 0x56, 0xb9, 0x9d, 0xb7, 0x85, 0x77, 0xe9, 0xb4, 0xfa,
- 0xab, 0x28, 0x11, 0xe7, 0x2e, 0x39, 0x24, 0x85, 0xad, 0x06, 0xc1, 0x06,
- 0xfe, 0xd7, 0xfb, 0xed, 0x82, 0x39, 0x17, 0x2c, 0xd0, 0xd9, 0x9e, 0xf4,
- 0x3c, 0xcf, 0x54, 0x5f, 0x88, 0xbb, 0x18, 0x8b, 0x5b, 0xc4, 0xb6, 0xbd,
- 0xf9, 0x0a, 0x1d, 0xfd, 0xb6, 0xf4, 0xb6, 0x25, 0x94, 0xb9, 0x92, 0x62,
- 0x49, 0x75, 0xd8, 0xce, 0xa9, 0xb5, 0x29, 0xc5, 0x6d, 0x7d, 0xb9, 0x3b,
- 0x1c, 0x51, 0x28, 0x4e, 0x48, 0xaa, 0xd2, 0x5e, 0x79, 0xf8, 0xbe, 0x46,
- 0x52, 0x95, 0x2c, 0x84, 0xdd, 0x04, 0x15, 0x69, 0xe7, 0xd6, 0xfd, 0xb0,
- 0x15, 0xd3, 0x31, 0x2c, 0x9b, 0x71, 0x92, 0x9e, 0xb0, 0x2a, 0x5d, 0x9a,
- 0x26, 0x2b, 0x50, 0x2a, 0x68, 0x31, 0x30, 0xad, 0xc0, 0x04, 0x28, 0xfb,
- 0x67, 0xd7, 0x3f, 0x13, 0x15, 0xe8, 0x99, 0x07, 0x2d, 0x48, 0x6d, 0x0d,
- 0xc5, 0x61, 0x12, 0xdc, 0x5b, 0x6e, 0x5d, 0xa5, 0x2f, 0xec, 0x13, 0xb8,
- 0x3c, 0x1b, 0x0d, 0xf7, 0xbd, 0xce, 0x05, 0xc1, 0xa4, 0x39, 0x43, 0xca,
- 0x15, 0x0a, 0x3b, 0xad, 0x84, 0x2e, 0x3b, 0x6f, 0xb4, 0x42, 0x56, 0x5c,
- 0x06, 0xc5, 0x44, 0x79, 0xac, 0x2e, 0x34, 0xdb, 0x7b, 0x0c, 0x2b, 0x65,
- 0x9a, 0xcd, 0x47, 0x2d, 0xa0, 0xaa, 0x33, 0xea, 0x72, 0x1b, 0xab, 0xb2,
- 0xa3, 0xea, 0x1a, 0xae, 0x3c, 0xd7, 0x07, 0xe6, 0xb5, 0xff, 0x00, 0xec,
- 0x61, 0xd2, 0x7e, 0x67, 0x6b, 0x30, 0x49, 0x9a, 0xb0, 0x9f, 0x04, 0x2c,
- 0x36, 0x1f, 0xb6, 0xc0, 0x21, 0x68, 0x20, 0x8d, 0xb8, 0xb5, 0xb0, 0xc7,
- 0x84, 0x66, 0x82, 0xa7, 0x14, 0x39, 0xa4, 0xfd, 0x22, 0x3f, 0xf1, 0x5f,
- 0x0e, 0xcc, 0x52, 0x24, 0xd0, 0xdb, 0x80, 0x1b, 0x2d, 0x26, 0xe3, 0x96,
- 0x63, 0xe7, 0x1a, 0xf4, 0xf9, 0xb2, 0xe3, 0xe5, 0xb9, 0x2f, 0xb6, 0x99,
- 0x09, 0x53, 0x71, 0xf4, 0x25, 0xc4, 0x70, 0x8b, 0x2b, 0x7b, 0xff, 0x00,
- 0x97, 0xd3, 0x08, 0x59, 0x5f, 0xab, 0x71, 0xd2, 0xa5, 0xc5, 0xae, 0x53,
- 0x64, 0x25, 0xbd, 0x56, 0xf8, 0x86, 0x5e, 0x2a, 0x5a, 0x2c, 0x6f, 0x7b,
- 0x1e, 0x37, 0xdf, 0x6c, 0x58, 0xd2, 0xdd, 0x2e, 0xa5, 0xd2, 0x9a, 0x1f,
- 0xf0, 0xc2, 0xcf, 0xc5, 0xae, 0x0b, 0xc2, 0x62, 0x19, 0xf9, 0x8d, 0xd3,
- 0xb2, 0x96, 0x3e, 0xa9, 0xef, 0x8e, 0x46, 0x7d, 0x6b, 0x8b, 0x52, 0x93,
- 0x09, 0xc4, 0x95, 0xa1, 0x0f, 0xad, 0x36, 0x1c, 0xde, 0xe4, 0x6d, 0x83,
- 0x75, 0x4a, 0x93, 0xe8, 0x29, 0x71, 0xbc, 0xb6, 0x3e, 0x36, 0x8a, 0x83,
- 0xd5, 0xe9, 0x96, 0x29, 0xb2, 0x4e, 0xb2, 0x78, 0x41, 0x4d, 0x88, 0x23,
- 0x5b, 0x00, 0x05, 0xf7, 0xd8, 0xe9, 0x1d, 0x04, 0xec, 0xac, 0xbb, 0x9a,
- 0xa0, 0xae, 0x45, 0x3a, 0xb4, 0x15, 0x2d, 0xb2, 0x16, 0xd1, 0x69, 0x94,
- 0xb6, 0xf2, 0x8d, 0xff, 0x00, 0x38, 0xb5, 0x96, 0x07, 0x3c, 0x5f, 0x1f,
- 0x12, 0x8e, 0x69, 0x0d, 0x33, 0x26, 0xa0, 0x83, 0x52, 0x84, 0x96, 0xf4,
- 0x78, 0x91, 0xd0, 0x94, 0x92, 0x9b, 0x8f, 0x99, 0x36, 0xb1, 0xe3, 0x8d,
- 0xb0, 0x1f, 0xa4, 0x19, 0x3e, 0x7c, 0x69, 0x10, 0xf3, 0x0b, 0x8c, 0x7c,
- 0x38, 0x68, 0x97, 0x63, 0xb0, 0xf1, 0xf3, 0xba, 0x46, 0xe0, 0x1e, 0x39,
- 0xf4, 0xed, 0x83, 0x15, 0xac, 0xf6, 0xed, 0x26, 0x24, 0x88, 0x34, 0x94,
- 0xaf, 0xc6, 0xd4, 0x4b, 0xcb, 0x6d, 0x37, 0xd1, 0x7d, 0xac, 0x3d, 0xf9,
- 0xdb, 0x9c, 0x63, 0x5c, 0x8c, 0xac, 0xcc, 0xa9, 0x76, 0x75, 0x01, 0xbe,
- 0x56, 0xca, 0xfe, 0x50, 0xc0, 0xd2, 0x18, 0x9a, 0x94, 0x33, 0x33, 0xcd,
- 0x04, 0x11, 0xbd, 0xed, 0x97, 0x80, 0xd7, 0xa0, 0xb1, 0x31, 0x7b, 0xe9,
- 0x12, 0xe8, 0xec, 0xe5, 0x1b, 0xd3, 0x65, 0x25, 0x2b, 0x7e, 0x38, 0x94,
- 0xb2, 0xa5, 0x15, 0x0b, 0x8d, 0x8d, 0xc6, 0xd6, 0x20, 0x1d, 0xc0, 0xe0,
- 0x8c, 0x47, 0xfa, 0xd7, 0x35, 0x11, 0x33, 0xed, 0x55, 0xe7, 0x8b, 0x6a,
- 0xd4, 0x84, 0xb8, 0x46, 0xab, 0x0b, 0x80, 0x47, 0xef, 0x6c, 0x6c, 0xf4,
- 0x0a, 0x53, 0xf3, 0xe4, 0xd4, 0x59, 0xbc, 0x86, 0x5b, 0x4c, 0x72, 0xd8,
- 0x4b, 0xbb, 0x06, 0xf5, 0x21, 0x57, 0x1f, 0x5b, 0x81, 0x7c, 0x2a, 0x7e,
- 0x26, 0x9b, 0x7e, 0x36, 0x64, 0x8b, 0xe6, 0x4b, 0xa8, 0x98, 0xd2, 0x3c,
- 0xac, 0x82, 0xa2, 0xa0, 0x9b, 0x77, 0x23, 0x6d, 0xf7, 0xc2, 0x83, 0xbc,
- 0x0b, 0x68, 0x34, 0x9d, 0x02, 0xb2, 0xe9, 0x09, 0xce, 0x80, 0x86, 0x94,
- 0xb4, 0x1b, 0x8b, 0x9d, 0x75, 0xb5, 0xf2, 0x8d, 0x18, 0x68, 0x47, 0xf3,
- 0x58, 0x60, 0x04, 0x24, 0x96, 0x46, 0xab, 0xaa, 0xdb, 0x59, 0x69, 0x23,
- 0x7e, 0xe4, 0xf6, 0x18, 0x8c, 0x65, 0x88, 0x92, 0xe5, 0xd7, 0xfe, 0x12,
- 0x23, 0x0b, 0x79, 0xd5, 0x28, 0xa7, 0x4a, 0x47, 0xbf, 0xed, 0x8b, 0x58,
- 0x8b, 0x1d, 0x59, 0xe9, 0xb6, 0xd6, 0xa0, 0xd2, 0x1c, 0x80, 0x95, 0x6c,
- 0x6c, 0x51, 0xe6, 0x26, 0xff, 0x00, 0x6e, 0x70, 0x0e, 0xa7, 0x99, 0x72,
- 0xbe, 0x49, 0x79, 0xf6, 0x29, 0x30, 0x99, 0x9c, 0xe3, 0xaa, 0xd6, 0xe0,
- 0x4a, 0x8a, 0x75, 0x2b, 0x7b, 0x82, 0x46, 0xf6, 0x3d, 0xc6, 0x1e, 0xa4,
- 0xe4, 0x91, 0x35, 0x4c, 0x61, 0x4e, 0x2a, 0xc9, 0x48, 0x37, 0xf5, 0x88,
- 0xd4, 0xe4, 0xeb, 0xb2, 0xb5, 0x59, 0x86, 0xd8, 0x41, 0x5a, 0xd4, 0x13,
- 0x6e, 0x43, 0x5c, 0xc9, 0xf3, 0x86, 0x4c, 0xb5, 0x16, 0x9f, 0x93, 0x61,
- 0x8a, 0x85, 0x46, 0xa4, 0xc7, 0x8e, 0xa4, 0xa8, 0x2d, 0x09, 0x57, 0x97,
- 0x56, 0xdb, 0x7b, 0x9d, 0xb0, 0xbd, 0x9d, 0x69, 0xd5, 0x4c, 0xc7, 0x25,
- 0xea, 0xab, 0x2c, 0x06, 0xda, 0x6e, 0x3a, 0xec, 0x93, 0xf3, 0x2a, 0xf6,
- 0x55, 0xcd, 0xb8, 0xe0, 0x58, 0x5c, 0xfb, 0xde, 0xf8, 0x9b, 0xe6, 0x0c,
- 0xd3, 0x2b, 0x30, 0xd5, 0x05, 0x4a, 0xa4, 0xab, 0xbf, 0xa9, 0x21, 0x0d,
- 0x36, 0x90, 0x96, 0x9a, 0x48, 0xb5, 0x92, 0x00, 0x1e, 0x82, 0xd8, 0x7d,
- 0x9d, 0xd4, 0x5a, 0x62, 0xe8, 0x72, 0x22, 0xc7, 0x6d, 0xe5, 0x3a, 0xe4,
- 0x52, 0xd0, 0x48, 0x05, 0x37, 0x51, 0xb0, 0xd4, 0x3d, 0x3b, 0xfe, 0xd8,
- 0xc7, 0x51, 0x9f, 0x79, 0xf6, 0x44, 0xac, 0x93, 0x47, 0x83, 0xa1, 0x37,
- 0xb7, 0xdf, 0x58, 0xdf, 0x45, 0xa1, 0xa1, 0x89, 0x83, 0x3f, 0x38, 0xbe,
- 0x27, 0x8f, 0x90, 0x17, 0xe5, 0x19, 0xf8, 0x7e, 0xa9, 0x7f, 0x0c, 0xcf,
- 0x74, 0xe6, 0x41, 0x4a, 0xd2, 0xeb, 0xce, 0xb3, 0xa8, 0xde, 0xe0, 0x68,
- 0x5e, 0xff, 0x00, 0xed, 0x86, 0xef, 0xc4, 0xae, 0x57, 0xad, 0x66, 0x9c,
- 0xf5, 0x96, 0xa9, 0x99, 0x7a, 0x9d, 0x22, 0xa3, 0x2d, 0xe8, 0xaa, 0x40,
- 0x08, 0x48, 0x09, 0x16, 0x37, 0x25, 0x44, 0xec, 0x91, 0x6d, 0xee, 0x48,
- 0x18, 0x40, 0xe9, 0x72, 0x97, 0x1f, 0x38, 0xd0, 0xe4, 0x4c, 0x01, 0x82,
- 0xed, 0x49, 0xc4, 0x5d, 0xc5, 0x00, 0x2e, 0xa4, 0xe9, 0x1b, 0xf1, 0xc9,
- 0xb6, 0x3a, 0x7f, 0x38, 0x67, 0x5a, 0x2e, 0x59, 0xa6, 0xa5, 0xe0, 0x17,
- 0x2e, 0xa6, 0xb8, 0xfa, 0x52, 0xdb, 0x00, 0xd8, 0x26, 0xfb, 0x6b, 0x20,
- 0x5c, 0xef, 0xc2, 0x45, 0xf0, 0x93, 0x8e, 0x17, 0x35, 0x2b, 0x5d, 0x93,
- 0x71, 0x96, 0x8a, 0xd6, 0x59, 0x02, 0xde, 0x3d, 0xe1, 0xed, 0xbc, 0x50,
- 0xb0, 0xeb, 0x0d, 0xcd, 0x53, 0xdf, 0x6c, 0x1d, 0x56, 0x6f, 0xe5, 0x63,
- 0xf4, 0x85, 0xbe, 0x94, 0xf4, 0x72, 0x85, 0xd3, 0xd8, 0x08, 0xcc, 0xb9,
- 0x96, 0x4b, 0x33, 0xab, 0x2c, 0xd8, 0x87, 0x41, 0xbc, 0x68, 0x8b, 0xec,
- 0x1b, 0x07, 0xff, 0x00, 0x51, 0x63, 0xfb, 0xdd, 0xbb, 0x0e, 0xf8, 0xdb,
- 0xcc, 0xd9, 0xc6, 0x7d, 0x6e, 0x97, 0x22, 0x99, 0x97, 0xdc, 0x30, 0xd2,
- 0xa6, 0xd4, 0x18, 0x23, 0xe7, 0x70, 0xff, 0x00, 0x7d, 0x44, 0xf0, 0x2f,
- 0xe9, 0xbd, 0xed, 0xef, 0x88, 0x96, 0x6e, 0xcd, 0xdd, 0x45, 0xce, 0x15,
- 0x44, 0x29, 0xea, 0x7c, 0xe4, 0x42, 0x6a, 0xe1, 0xa6, 0x49, 0x08, 0xda,
- 0xe7, 0x7b, 0x5f, 0xcb, 0x7f, 0x41, 0xe9, 0xdf, 0x07, 0xa9, 0xaf, 0xe7,
- 0x01, 0x14, 0xb6, 0xb8, 0x4d, 0x0f, 0x11, 0x21, 0x09, 0x40, 0x76, 0xe5,
- 0x24, 0xef, 0x60, 0x07, 0xdf, 0x6c, 0x0f, 0x6b, 0x07, 0xd4, 0xa6, 0xdd,
- 0x13, 0x53, 0xa8, 0x2b, 0x5e, 0xc2, 0xdd, 0xd4, 0xf4, 0x82, 0xcd, 0x87,
- 0x52, 0x9e, 0xce, 0x55, 0xb2, 0x40, 0xde, 0xc7, 0xda, 0xff, 0x00, 0x3f,
- 0xe6, 0x14, 0xb2, 0x2c, 0x09, 0x51, 0x33, 0x8c, 0x66, 0x96, 0xe1, 0x7d,
- 0xc5, 0x2d, 0xc4, 0x94, 0x29, 0xcb, 0xf9, 0x86, 0xc6, 0xe4, 0x5e, 0xdd,
- 0xf0, 0x56, 0x6c, 0xc9, 0x93, 0x95, 0x53, 0x69, 0x65, 0xc7, 0x52, 0xcc,
- 0xa7, 0x94, 0x02, 0xd5, 0xa8, 0xa0, 0x6b, 0xde, 0xde, 0xbd, 0xbf, 0x4c,
- 0x39, 0xe4, 0xec, 0x9f, 0x57, 0x77, 0x33, 0x35, 0x50, 0x9f, 0x4e, 0x44,
- 0x25, 0x34, 0xab, 0xa5, 0xd0, 0x8d, 0x3a, 0x81, 0xd8, 0x85, 0x71, 0xc7,
- 0x37, 0xe4, 0x93, 0x84, 0x99, 0x2f, 0xb0, 0xd5, 0x72, 0xae, 0x88, 0xe8,
- 0x7a, 0x4a, 0xdb, 0x98, 0xf0, 0x75, 0x09, 0x68, 0x9d, 0x0a, 0xd5, 0xb0,
- 0xbf, 0x1b, 0xdb, 0x0e, 0x75, 0x19, 0x29, 0x84, 0x51, 0xd0, 0x85, 0xa0,
- 0xf1, 0xf1, 0xde, 0xdb, 0xd8, 0x8f, 0xda, 0x1b, 0xb0, 0xc3, 0x8c, 0xc8,
- 0x9f, 0xee, 0x94, 0x1b, 0x04, 0x2b, 0xfc, 0x8d, 0xb6, 0x1b, 0x9e, 0x86,
- 0x13, 0x32, 0xee, 0x51, 0x95, 0x26, 0x62, 0x97, 0x2b, 0xca, 0x85, 0x38,
- 0x74, 0x36, 0x8d, 0xd4, 0xab, 0x9d, 0xbe, 0x98, 0x69, 0xa8, 0xfc, 0x0d,
- 0x1c, 0x22, 0x1c, 0x55, 0x32, 0x08, 0x1b, 0xa5, 0x0e, 0x6a, 0x08, 0xf5,
- 0x04, 0x8e, 0x4f, 0x7d, 0xb1, 0xf9, 0x3a, 0x8f, 0x99, 0xea, 0x68, 0x4a,
- 0x63, 0xc8, 0x85, 0x01, 0xbe, 0x74, 0x97, 0x81, 0xd3, 0x7f, 0x5b, 0x72,
- 0x71, 0xa3, 0x1b, 0xa7, 0x33, 0x18, 0x92, 0xdb, 0x95, 0x3a, 0xd3, 0x84,
- 0xba, 0x82, 0xa1, 0xe0, 0x46, 0x71, 0x6a, 0x29, 0xe3, 0xb0, 0x36, 0xc6,
- 0x54, 0xe1, 0xea, 0x8c, 0xd0, 0x0b, 0x75, 0x36, 0x1c, 0xb2, 0x10, 0xa0,
- 0xf7, 0xc4, 0x6c, 0x37, 0x86, 0xc1, 0x96, 0xa4, 0x1e, 0x35, 0x0c, 0x8a,
- 0xc8, 0xb9, 0x3d, 0x32, 0xf6, 0xc8, 0x43, 0x2e, 0x4d, 0x99, 0x97, 0xd4,
- 0x5c, 0x4d, 0x69, 0x97, 0x3c, 0x55, 0x0b, 0xa6, 0x42, 0xaf, 0x66, 0xc6,
- 0x92, 0x6c, 0x12, 0x0d, 0xbe, 0xfe, 0xbd, 0xf0, 0xcf, 0x05, 0xa8, 0x4e,
- 0xd6, 0x27, 0x1a, 0x5b, 0xc8, 0x2c, 0x08, 0x8d, 0x82, 0xb6, 0x55, 0x70,
- 0xa5, 0x00, 0xaf, 0x5e, 0xdb, 0xe1, 0x61, 0x8e, 0x9b, 0x44, 0x0a, 0x68,
- 0xbd, 0x5a, 0x7d, 0x69, 0x28, 0x05, 0x2a, 0x5a, 0xc8, 0xf2, 0xfa, 0x7b,
- 0x7d, 0x30, 0xdd, 0x95, 0xa9, 0x54, 0xbc, 0xb6, 0xc4, 0x8b, 0xcf, 0x69,
- 0x48, 0x5f, 0x9c, 0xf9, 0x49, 0x3b, 0x0b, 0x6e, 0x7b, 0xe1, 0x86, 0x83,
- 0x40, 0x98, 0x91, 0x9b, 0x0f, 0x39, 0x60, 0x90, 0x0e, 0xf1, 0x1b, 0xc6,
- 0xf8, 0xe6, 0x56, 0xbb, 0x28, 0xa4, 0xa5, 0x4a, 0x53, 0x84, 0x8d, 0x41,
- 0xd8, 0xc6, 0x8e, 0x49, 0x2b, 0xfe, 0x58, 0xa4, 0x2c, 0x3a, 0xb4, 0x07,
- 0x1a, 0x2d, 0x2e, 0xcb, 0x29, 0xbe, 0x95, 0x91, 0xcf, 0xf9, 0x86, 0x34,
- 0x1b, 0xc8, 0xf4, 0x8c, 0xaf, 0x5e, 0x7b, 0x30, 0xd7, 0x5a, 0x69, 0xe4,
- 0x15, 0xf8, 0x89, 0x2e, 0x3a, 0x34, 0x81, 0xea, 0x07, 0xae, 0x0e, 0xf4,
- 0xc1, 0xba, 0x5d, 0x63, 0xa7, 0xae, 0xc4, 0x55, 0x72, 0x1c, 0x19, 0xf0,
- 0x66, 0x38, 0x02, 0x5f, 0x41, 0xf9, 0x54, 0x41, 0x1c, 0x6f, 0x6f, 0x70,
- 0x0e, 0xe2, 0xc7, 0x1e, 0x95, 0x1c, 0xa7, 0x95, 0x6a, 0x8f, 0x78, 0x99,
- 0xa7, 0x38, 0xbb, 0x31, 0x60, 0xec, 0xdc, 0x55, 0x04, 0xb2, 0x91, 0xed,
- 0xab, 0x73, 0xf5, 0x23, 0x1e, 0xf3, 0x75, 0x49, 0x44, 0x23, 0x3e, 0xf2,
- 0x92, 0x4d, 0x87, 0x99, 0xce, 0x3e, 0x82, 0xa0, 0x54, 0x25, 0x95, 0x47,
- 0x96, 0xed, 0x52, 0x14, 0xb4, 0x0c, 0xae, 0x0e, 0x47, 0x63, 0x7d, 0xad,
- 0x7f, 0x13, 0xf3, 0x08, 0x59, 0xa7, 0xa9, 0x90, 0xe7, 0xd4, 0x3f, 0x87,
- 0xd3, 0xd6, 0x44, 0x73, 0xb1, 0x7d, 0x46, 0xca, 0xb7, 0x64, 0x8b, 0x7c,
- 0xa3, 0x8d, 0x86, 0xe7, 0xb9, 0xed, 0x80, 0xd4, 0x1a, 0xac, 0x04, 0xb8,
- 0xe1, 0x71, 0x0b, 0xd2, 0xb7, 0x09, 0xdc, 0xdf, 0x49, 0xdf, 0x6b, 0x1f,
- 0xad, 0xcf, 0xed, 0x8a, 0xe2, 0x32, 0x5e, 0x40, 0x85, 0x1d, 0x89, 0x14,
- 0xa8, 0x54, 0xea, 0xb8, 0x52, 0x94, 0x1c, 0x0f, 0x4f, 0x53, 0x3e, 0x1f,
- 0xf7, 0x46, 0xc8, 0x37, 0x36, 0xbd, 0xed, 0xc6, 0x18, 0xa9, 0xf4, 0xfe,
- 0x9a, 0xa6, 0x12, 0x14, 0xfd, 0x0c, 0x31, 0x25, 0x0a, 0x21, 0xe6, 0x58,
- 0x43, 0xce, 0x83, 0xb6, 0xc5, 0x2e, 0x5b, 0x71, 0xfa, 0x61, 0x36, 0xa1,
- 0x3e, 0x26, 0x94, 0x4b, 0xae, 0x0f, 0x33, 0x18, 0x26, 0x3b, 0x79, 0xb7,
- 0x4a, 0x9e, 0x70, 0x78, 0x00, 0x32, 0x1e, 0xa7, 0xde, 0x37, 0x7a, 0x17,
- 0xe0, 0x3b, 0x48, 0x42, 0x53, 0xe0, 0x3a, 0xfb, 0xa9, 0x5b, 0xee, 0x29,
- 0xa1, 0xc9, 0x06, 0xc7, 0x9e, 0xc0, 0x5b, 0x02, 0x7f, 0x12, 0x50, 0xd2,
- 0xdd, 0x7e, 0x93, 0x25, 0x20, 0x05, 0x29, 0x82, 0x90, 0x37, 0xb1, 0xb1,
- 0x1e, 0x9f, 0x43, 0x86, 0xaa, 0x5d, 0x7f, 0x25, 0x51, 0x5d, 0x0b, 0xa7,
- 0x50, 0xaa, 0x37, 0x00, 0x68, 0x09, 0x69, 0x66, 0xc3, 0xef, 0x84, 0xbe,
- 0xa7, 0xe6, 0x98, 0xb9, 0xb2, 0xbf, 0x16, 0x33, 0x50, 0x64, 0xc2, 0xf8,
- 0x26, 0xff, 0x00, 0xe7, 0x24, 0xa5, 0x4a, 0x4f, 0xae, 0xe3, 0x8d, 0xf9,
- 0xe3, 0x6c, 0x60, 0x4b, 0x8c, 0xf6, 0x25, 0x01, 0x60, 0xaa, 0xf7, 0xc8,
- 0xc6, 0x57, 0x18, 0xec, 0x90, 0x45, 0xf2, 0xf1, 0xb7, 0xca, 0xe6, 0x24,
- 0x3d, 0x41, 0x97, 0x21, 0x1f, 0x0d, 0xf0, 0x4e, 0xa2, 0x3c, 0xc7, 0x96,
- 0x4e, 0xa5, 0x10, 0x0f, 0x86, 0x05, 0x92, 0x8b, 0x9f, 0xca, 0x76, 0xfd,
- 0x31, 0x3c, 0x10, 0xaa, 0xae, 0xbe, 0xaf, 0xfc, 0xad, 0x97, 0x97, 0x7d,
- 0xce, 0x92, 0xa3, 0xfa, 0xe2, 0xae, 0x8a, 0x4c, 0x1a, 0xef, 0x50, 0x69,
- 0x54, 0x9a, 0x83, 0xc9, 0x62, 0x3f, 0xc0, 0xba, 0xf1, 0x71, 0x36, 0x3a,
- 0x52, 0x3e, 0x5d, 0xcf, 0xa0, 0x37, 0xbe, 0x07, 0xe6, 0x8c, 0x85, 0x9a,
- 0xe3, 0xcf, 0x28, 0xc9, 0xd5, 0x29, 0xb5, 0x66, 0x42, 0x43, 0x88, 0x44,
- 0x72, 0xa2, 0xbd, 0x2a, 0xbd, 0xb9, 0xdd, 0x5c, 0x1b, 0x73, 0xf5, 0xc5,
- 0x33, 0x0d, 0xb6, 0xf3, 0x34, 0xd0, 0xe7, 0x19, 0xb1, 0xb9, 0x00, 0x01,
- 0x90, 0xb9, 0x1a, 0xab, 0x2f, 0x28, 0x57, 0x55, 0x29, 0xb7, 0xc2, 0xa6,
- 0x0a, 0x49, 0xd8, 0xdb, 0x5c, 0xa0, 0x05, 0x1f, 0x29, 0x54, 0xdd, 0xa7,
- 0xa9, 0xe7, 0xe3, 0x53, 0xa2, 0x10, 0x9b, 0xb7, 0xe2, 0x4f, 0x09, 0x2e,
- 0x0b, 0x5e, 0xe0, 0x04, 0x2a, 0xff, 0x00, 0xb6, 0x3c, 0x19, 0xcb, 0xd9,
- 0xd9, 0x45, 0x3f, 0x0d, 0x47, 0x8e, 0x9d, 0x48, 0x4a, 0xbc, 0xa5, 0x2a,
- 0xb5, 0xc6, 0xd7, 0xb9, 0x36, 0x3e, 0xd8, 0x0e, 0x89, 0x59, 0xb5, 0x89,
- 0x4b, 0x82, 0xa9, 0x72, 0xe3, 0xb8, 0x83, 0x65, 0x24, 0xf9, 0x74, 0x9f,
- 0x43, 0xb6, 0xc7, 0xeb, 0x82, 0xb4, 0xea, 0x6e, 0x75, 0x9e, 0xca, 0xa5,
- 0x36, 0xed, 0x49, 0xc4, 0xa1, 0x5a, 0x54, 0x52, 0x6f, 0xc7, 0x3c, 0x63,
- 0x43, 0xb8, 0xa9, 0xa6, 0xcf, 0x0a, 0x8a, 0xc5, 0xbf, 0xf3, 0xf7, 0xe8,
- 0x04, 0x71, 0x6e, 0x9f, 0x4a, 0x51, 0xcd, 0x0b, 0x3d, 0x48, 0xfa, 0xde,
- 0x33, 0x30, 0xe5, 0xec, 0xe9, 0x12, 0x9a, 0x89, 0xd5, 0x86, 0x99, 0x6a,
- 0x34, 0x75, 0x78, 0x88, 0xd4, 0x05, 0x8a, 0x86, 0xe1, 0x36, 0xb7, 0x7b,
- 0x7d, 0x31, 0xeb, 0x53, 0xa8, 0x67, 0xc8, 0x49, 0x65, 0x6e, 0x39, 0x22,
- 0x13, 0x2a, 0x17, 0x65, 0x41, 0xb5, 0xb4, 0x9b, 0x13, 0xdb, 0x55, 0x88,
- 0x1b, 0xf7, 0xc3, 0xfd, 0x0e, 0x44, 0xc7, 0xa8, 0x2c, 0xc1, 0xac, 0x34,
- 0x92, 0xb6, 0x27, 0xc7, 0x6d, 0x68, 0x51, 0xb8, 0x3c, 0x1d, 0xc7, 0x62,
- 0x45};
-} // namespace
--- /dev/null
+/*
+ * Copyright 2018 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>
+
+namespace test_vendor_lib {
+
+class LeAdvertisement {
+ public:
+ enum class AdvertisementType : uint8_t {
+ ADV_IND = 0, // Connectable and scannable
+ ADV_DIRECT_IND = 1, // Connectable directed
+ ADV_SCAN_IND = 2, // Scannable undirected
+ ADV_NONCONN_IND = 3, // Non connectable undirected
+ SCAN_RESPONSE = 4,
+ };
+ enum class AddressType : uint8_t {
+ PUBLIC = 0,
+ RANDOM = 1,
+ PUBLIC_IDENTITY = 2,
+ RANDOM_IDENTITY = 3,
+ };
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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
+
+namespace test_vendor_lib {
+class Link {
+ public:
+ static constexpr size_t kSizeBytes = sizeof(uint32_t);
+ static constexpr size_t kTypeBytes = sizeof(uint8_t);
+
+ enum class PacketType : uint8_t {
+ UNKNOWN,
+ ACL,
+ COMMAND,
+ DISCONNECT,
+ ENCRYPT_CONNECTION,
+ ENCRYPT_CONNECTION_RESPONSE,
+ EVENT,
+ INQUIRY,
+ INQUIRY_RESPONSE,
+ IO_CAPABILITY_REQUEST,
+ IO_CAPABILITY_RESPONSE,
+ IO_CAPABILITY_NEGATIVE_RESPONSE,
+ LE_ADVERTISEMENT,
+ LE_SCAN,
+ LE_SCAN_RESPONSE,
+ PAGE,
+ PAGE_RESPONSE,
+ RESPONSE,
+ SCO,
+ };
+};
+} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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 <vector>
-
-#include "bt_address.h"
-#include "hci/include/hci_hal.h"
-
-namespace test_vendor_lib {
-
-const size_t kReservedZero = 0;
-
-// Abstract base class that is subclassed to provide type-specifc accessors on
-// data. Manages said data's memory and guarantees the data's persistence for IO
-// operations.
-class Packet {
- public:
- virtual ~Packet() = default;
-
- // Returns the size in octets of the entire packet, which consists of the type
- // octet, the header, and the payload.
- size_t GetPacketSize() const;
-
- const std::vector<uint8_t>& GetPayload() const;
-
- size_t GetPayloadSize() const;
-
- const std::vector<uint8_t>& GetHeader() const;
-
- uint8_t GetHeaderSize() const;
-
- serial_data_type_t GetType() const;
-
- // Add |octets| bytes to the payload. Return true if:
- // - the size of |bytes| is equal to |octets| and
- // - the new size of the payload is still < |kMaxPayloadOctets|
- bool AddPayloadOctets(size_t octets, const std::vector<uint8_t>& bytes);
-
- private:
- // Add |octets| bytes to the payload. Return true if:
- // - the value of |value| fits in |octets| bytes and
- // - the new size of the payload is still < |kMaxPayloadOctets|
- bool AddPayloadOctets(size_t octets, uint64_t value);
-
- public:
- // Add type-checking versions
- bool AddPayloadOctets1(uint8_t value) { return AddPayloadOctets(1, value); }
- bool AddPayloadOctets2(uint16_t value) { return AddPayloadOctets(2, value); }
- bool AddPayloadOctets3(uint32_t value) { return AddPayloadOctets(3, value); }
- bool AddPayloadOctets4(uint32_t value) { return AddPayloadOctets(4, value); }
- bool AddPayloadOctets6(uint64_t value) { return AddPayloadOctets(6, value); }
- bool AddPayloadOctets8(uint64_t value) { return AddPayloadOctets(8, value); }
-
- // Add |address| to the payload. Return true if:
- // - the new size of the payload is still < |kMaxPayloadOctets|
- bool AddPayloadBtAddress(const BtAddress& address);
-
- // Return true if |num_bytes| can be added to the payload.
- bool CanAddPayloadOctets(size_t num_bytes) const {
- return GetPayloadSize() + num_bytes <= kMaxPayloadOctets;
- }
-
- protected:
- // Constructs an empty packet of type |type| and header |header|
- Packet(serial_data_type_t type, std::vector<uint8_t> header);
-
- bool IncrementPayloadCounter(size_t index);
- bool IncrementPayloadCounter(size_t index, uint8_t max_val);
-
- private:
- const size_t kMaxPayloadOctets = 256; // Includes the size byte.
-
- // Underlying containers for storing the actual packet
-
- // The packet type is one of DATA_TYPE_ACL, DATA_TYPE_COMMAND,
- // DATA_TYPE_EVENT, or DATA_TYPE_SCO.
- serial_data_type_t type_;
-
- std::vector<uint8_t> header_;
-
- std::vector<uint8_t> payload_;
-};
-
-} // namespace test_vendor_lib
+++ /dev/null
-//
-// 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 <vector>
-
-#include "command_packet.h"
-#include "event_packet.h"
-#include "packet.h"
-
-namespace test_vendor_lib {
-
-// Provides abstractions for IO with Packet objects. Used to receive commands
-// and data from the HCI and to send controller events back to the host.
-class PacketStream {
- public:
- PacketStream() = default;
-
- virtual ~PacketStream() = default;
-
- // Reads a command packet from the file descriptor at |fd| and returns the
- // packet back to the caller, along with the responsibility of managing the
- // packet.
- std::unique_ptr<CommandPacket> ReceiveCommand(int fd) const;
-
- // Reads a single octet from |fd| and interprets it as a packet type octet.
- // Validates the type octet for correctness.
- serial_data_type_t ReceivePacketType(int fd) const;
-
- // Sends an event to file descriptor |fd|. The ownership of the event is left
- // with the caller.
- bool SendEvent(std::unique_ptr<EventPacket> event, int fd) const;
-
- private:
- // Checks if |type| is in the valid range from DATA_TYPE_COMMAND to
- // DATA_TYPE_SCO.
- bool ValidateTypeOctet(serial_data_type_t type) const;
-
- // Attempts to receive |num_octets_to_receive| into |destination| from |fd|,
- // returning false if an error occurs.
- bool ReceiveAll(std::vector<uint8_t>& destination,
- size_t num_octets_to_receive, int fd) const;
-
- // Attempts to send |num_octets_to_send| from |source| to |fd|, returning
- // false if an error occurs.
- bool SendAll(const std::vector<uint8_t>& source, size_t num_octets_to_send,
- int fd) const;
-};
-
-} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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
+
+namespace test_vendor_lib {
+
+class Phy {
+ public:
+ enum class Type {
+ LOW_ENERGY,
+ BR_EDR,
+ };
+};
+} // namespace test_vendor_lib
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright 2018 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.
#pragma once
#include <cstdint>
-#include <string>
-#include <vector>
-
-#include "packet.h"
namespace test_vendor_lib {
+namespace sco {
// SCO data packets are specified in the Bluetooth Core Specification Version
// 4.2, Volume 2, Part E, Section 5.4.3
-class ScoPacket : public Packet {
- public:
- virtual ~ScoPacket() override = default;
- typedef enum {
- CorrectlyReceived,
- PossiblyIncomplete,
- NoData,
- PartiallyLost
- } PacketStatusFlags;
-
- uint16_t GetChannel() const;
-
- PacketStatusFlags GetPacketStatusFlags() const;
-
- explicit ScoPacket(uint16_t channel, PacketStatusFlags status_flags);
+enum class PacketStatusFlagsType : uint8_t {
+ CORRECTLY_RECEIVED = 0,
+ POSSIBLY_INCOMPLETE = 1,
+ NO_DATA = 2,
+ PARTIALLY_LOST = 3
};
-
+} // namespace sco
} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "acl_connection"
+
+#include "acl_connection.h"
+
+#include "base/logging.h"
+
+#include "osi/include/log.h"
+
+using std::shared_ptr;
+
+namespace test_vendor_lib {} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "types/address.h"
+
+namespace test_vendor_lib {
+
+// Model the connection of a device to the controller.
+class AclConnection {
+ public:
+ AclConnection(const Address& addr) : address_(addr), connected_(false), encrypted_(false) {}
+
+ virtual ~AclConnection() = default;
+
+ void SetConnected(bool connected) {
+ connected_ = connected;
+ };
+ bool IsConnected() const {
+ return connected_;
+ };
+
+ void Encrypt() {
+ encrypted_ = true;
+ };
+ bool IsEncrypted() const {
+ return encrypted_;
+ };
+
+ const Address& GetAddress() const {
+ return address_;
+ }
+ void SetAddress(const Address& address) {
+ address_ = address;
+ }
+
+ private:
+ Address address_;
+
+ // State variables
+ bool connected_;
+ bool encrypted_;
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "acl_connection_handler"
+
+#include "acl_connection_handler.h"
+
+#include "base/logging.h"
+
+#include "osi/include/log.h"
+#include "types/address.h"
+
+using std::shared_ptr;
+
+namespace test_vendor_lib {
+
+bool AclConnectionHandler::HasHandle(uint16_t handle) const {
+ if (acl_connections_.count(handle) == 0) {
+ return false;
+ }
+ return true;
+}
+
+uint16_t AclConnectionHandler::GetUnusedHandle() {
+ static uint16_t sNextHandle = acl::kReservedHandle - 2;
+ while (acl_connections_.count(sNextHandle) == 1) {
+ sNextHandle = (sNextHandle + 1) % acl::kReservedHandle;
+ }
+ uint16_t unused_handle = sNextHandle;
+ sNextHandle = (sNextHandle + 1) % acl::kReservedHandle;
+ return unused_handle;
+}
+
+bool AclConnectionHandler::CreatePendingConnection(const Address& addr) {
+ if ((pending_connections_.size() + 1 > max_pending_connections_) || HasPendingConnection(addr)) {
+ return false;
+ }
+ pending_connections_.insert(addr);
+ return true;
+}
+
+bool AclConnectionHandler::HasPendingConnection(const Address& addr) {
+ return pending_connections_.count(addr) == 1;
+}
+
+bool AclConnectionHandler::CancelPendingConnection(const Address& addr) {
+ if (!HasPendingConnection(addr)) {
+ return false;
+ }
+ pending_connections_.erase(addr);
+ return true;
+}
+
+uint16_t AclConnectionHandler::CreateConnection(const Address& addr) {
+ if (CancelPendingConnection(addr)) {
+ uint16_t handle = GetUnusedHandle();
+ acl_connections_.emplace(handle, addr);
+ SetConnected(handle, true);
+ return handle;
+ }
+ return acl::kReservedHandle;
+}
+
+bool AclConnectionHandler::Disconnect(uint16_t handle) {
+ return acl_connections_.erase(handle) > 0;
+}
+
+uint16_t AclConnectionHandler::GetHandle(const Address& addr) const {
+ for (auto pair : acl_connections_) {
+ if (std::get<AclConnection>(pair).GetAddress() == addr) {
+ return std::get<0>(pair);
+ }
+ }
+ return acl::kReservedHandle;
+}
+
+const Address& AclConnectionHandler::GetAddress(uint16_t handle) const {
+ CHECK(HasHandle(handle)) << "Handle unknown " << handle;
+ return acl_connections_.at(handle).GetAddress();
+}
+
+void AclConnectionHandler::SetConnected(uint16_t handle, bool connected) {
+ if (!HasHandle(handle)) {
+ return;
+ }
+ acl_connections_.at(handle).SetConnected(connected);
+}
+
+bool AclConnectionHandler::IsConnected(uint16_t handle) const {
+ if (!HasHandle(handle)) {
+ return false;
+ }
+ return acl_connections_.at(handle).IsConnected();
+}
+
+void AclConnectionHandler::Encrypt(uint16_t handle) {
+ if (!HasHandle(handle)) {
+ return;
+ }
+ acl_connections_.at(handle).Encrypt();
+}
+
+bool AclConnectionHandler::IsEncrypted(uint16_t handle) const {
+ if (!HasHandle(handle)) {
+ return false;
+ }
+ return acl_connections_.at(handle).IsEncrypted();
+}
+
+void AclConnectionHandler::SetAddress(uint16_t handle, const Address& address) {
+ if (!HasHandle(handle)) {
+ return;
+ }
+ acl_connections_.at(handle).SetAddress(address);
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <set>
+#include <unordered_map>
+
+#include "acl_connection.h"
+#include "include/acl.h"
+#include "types/address.h"
+
+namespace test_vendor_lib {
+
+class AclConnectionHandler {
+ public:
+ AclConnectionHandler(size_t max_pending_connections = 1) : max_pending_connections_(max_pending_connections) {}
+
+ virtual ~AclConnectionHandler() = default;
+
+ bool CreatePendingConnection(const Address& addr);
+ bool HasPendingConnection(const Address& addr);
+ bool CancelPendingConnection(const Address& addr);
+
+ uint16_t CreateConnection(const Address& addr);
+ bool Disconnect(uint16_t handle);
+ bool HasHandle(uint16_t handle) const;
+
+ uint16_t GetHandle(const Address& addr) const;
+ const Address& GetAddress(uint16_t handle) const;
+
+ void SetConnected(uint16_t handle, bool connected);
+ bool IsConnected(uint16_t handle) const;
+
+ void Encrypt(uint16_t handle);
+ bool IsEncrypted(uint16_t handle) const;
+
+ void SetAddress(uint16_t handle, const Address& address);
+
+ private:
+ std::unordered_map<uint16_t, AclConnection> acl_connections_;
+ size_t max_pending_connections_;
+ std::set<Address> pending_connections_;
+ uint16_t GetUnusedHandle();
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * 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 "dual_mode_controller"
+
+#include "dual_mode_controller.h"
+
+#include <memory>
+
+#include <base/files/file_util.h>
+#include <base/json/json_reader.h>
+#include <base/logging.h>
+#include <base/values.h>
+
+#include "osi/include/log.h"
+#include "osi/include/osi.h"
+
+#include "hci.h"
+#include "packets/hci/acl_packet_view.h"
+#include "packets/hci/command_packet_view.h"
+#include "packets/hci/event_packet_builder.h"
+#include "packets/hci/sco_packet_view.h"
+
+using std::vector;
+using test_vendor_lib::hci::EventCode;
+using test_vendor_lib::hci::OpCode;
+
+namespace {
+
+size_t LastNonZero(test_vendor_lib::packets::PacketView<true> view) {
+ for (size_t i = view.size() - 1; i > 0; i--) {
+ if (view[i] != 0) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+} // namespace
+
+namespace test_vendor_lib {
+constexpr char DualModeController::kControllerPropertiesFile[];
+constexpr uint16_t DualModeController::kSecurityManagerNumKeys;
+
+// Device methods.
+void DualModeController::Initialize(const std::vector<std::string>& args) {
+ if (args.size() < 2) return;
+
+ Address addr;
+ if (Address::FromString(args[1], addr)) properties_.SetAddress(addr);
+};
+
+std::string DualModeController::GetTypeString() const {
+ return "Simulated Bluetooth Controller";
+}
+
+void DualModeController::IncomingPacket(packets::LinkLayerPacketView incoming) {
+ link_layer_controller_.IncomingPacket(incoming);
+}
+
+void DualModeController::TimerTick() {
+ link_layer_controller_.TimerTick();
+}
+
+void DualModeController::SendLinkLayerPacket(std::shared_ptr<packets::LinkLayerPacketBuilder> to_send,
+ Phy::Type phy_type) {
+ for (auto phy_pair : phy_layers_) {
+ auto phy_list = std::get<1>(phy_pair);
+ if (phy_type != std::get<0>(phy_pair)) {
+ continue;
+ }
+ for (auto phy : phy_list) {
+ phy->Send(to_send);
+ }
+ }
+}
+
+/*
+void DualModeController::AddConnectionAction(const TaskCallback& task,
+ uint16_t handle) {
+ for (size_t i = 0; i < connections_.size(); i++)
+ if (connections_[i]->GetHandle() == handle)
+connections_[i]->AddAction(task);
+}
+*/
+
+void DualModeController::SendCommandCompleteSuccess(OpCode command_opcode) const {
+ send_event_(packets::EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(command_opcode, hci::Status::SUCCESS)
+ ->ToVector());
+}
+
+void DualModeController::SendCommandCompleteUnknownOpCodeEvent(uint16_t command_opcode) const {
+ send_event_(packets::EventPacketBuilder::CreateCommandCompleteUnknownOpCodeEvent(command_opcode)->ToVector());
+}
+
+void DualModeController::SendCommandCompleteOnlyStatus(OpCode command_opcode, hci::Status status) const {
+ send_event_(packets::EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(command_opcode, status)->ToVector());
+}
+
+void DualModeController::SendCommandCompleteStatusAndAddress(OpCode command_opcode, hci::Status status,
+ const Address& address) const {
+ send_event_(packets::EventPacketBuilder::CreateCommandCompleteStatusAndAddressEvent(command_opcode, status, address)
+ ->ToVector());
+}
+
+void DualModeController::SendCommandStatus(hci::Status status, OpCode command_opcode) const {
+ send_event_(packets::EventPacketBuilder::CreateCommandStatusEvent(status, command_opcode)->ToVector());
+}
+
+void DualModeController::SendCommandStatusSuccess(OpCode command_opcode) const {
+ SendCommandStatus(hci::Status::SUCCESS, command_opcode);
+}
+
+DualModeController::DualModeController(const std::string& properties_filename, uint16_t num_keys)
+ : Device(properties_filename), security_manager_(num_keys) {
+ loopback_mode_ = hci::LoopbackMode::NO;
+
+ Address public_address;
+ CHECK(Address::FromString("3C:5A:B4:04:05:06", public_address));
+ properties_.SetAddress(public_address);
+
+ link_layer_controller_.RegisterRemoteChannel(
+ [this](std::shared_ptr<packets::LinkLayerPacketBuilder> packet, Phy::Type phy_type) {
+ DualModeController::SendLinkLayerPacket(packet, phy_type);
+ });
+
+#define SET_HANDLER(opcode, method) \
+ active_hci_commands_[static_cast<uint16_t>(opcode)] = [this](packets::PacketView<true> param) { method(param); };
+ SET_HANDLER(OpCode::RESET, HciReset);
+ SET_HANDLER(OpCode::READ_BUFFER_SIZE, HciReadBufferSize);
+ SET_HANDLER(OpCode::HOST_BUFFER_SIZE, HciHostBufferSize);
+ SET_HANDLER(OpCode::SNIFF_SUBRATING, HciSniffSubrating);
+ SET_HANDLER(OpCode::READ_LOCAL_VERSION_INFORMATION, HciReadLocalVersionInformation);
+ SET_HANDLER(OpCode::READ_BD_ADDR, HciReadBdAddr);
+ SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_COMMANDS, HciReadLocalSupportedCommands);
+ SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_CODECS, HciReadLocalSupportedCodecs);
+ SET_HANDLER(OpCode::READ_LOCAL_EXTENDED_FEATURES, HciReadLocalExtendedFeatures);
+ SET_HANDLER(OpCode::READ_REMOTE_EXTENDED_FEATURES, HciReadRemoteExtendedFeatures);
+ SET_HANDLER(OpCode::READ_REMOTE_SUPPORTED_FEATURES, HciReadRemoteSupportedFeatures);
+ SET_HANDLER(OpCode::READ_CLOCK_OFFSET, HciReadClockOffset);
+ SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_REPLY, HciIoCapabilityRequestReply);
+ SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_REPLY, HciUserConfirmationRequestReply);
+ SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, HciUserConfirmationRequestNegativeReply);
+ SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, HciIoCapabilityRequestNegativeReply);
+ SET_HANDLER(OpCode::WRITE_SIMPLE_PAIRING_MODE, HciWriteSimplePairingMode);
+ SET_HANDLER(OpCode::WRITE_LE_HOST_SUPPORT, HciWriteLeHostSupport);
+ SET_HANDLER(OpCode::SET_EVENT_MASK, HciSetEventMask);
+ SET_HANDLER(OpCode::WRITE_INQUIRY_MODE, HciWriteInquiryMode);
+ SET_HANDLER(OpCode::WRITE_PAGE_SCAN_TYPE, HciWritePageScanType);
+ SET_HANDLER(OpCode::WRITE_INQUIRY_SCAN_TYPE, HciWriteInquiryScanType);
+ SET_HANDLER(OpCode::AUTHENTICATION_REQUESTED, HciAuthenticationRequested);
+ SET_HANDLER(OpCode::SET_CONNECTION_ENCRYPTION, HciSetConnectionEncryption);
+ SET_HANDLER(OpCode::WRITE_AUTHENTICATION_ENABLE, HciWriteAuthenticationEnable);
+ SET_HANDLER(OpCode::READ_AUTHENTICATION_ENABLE, HciReadAuthenticationEnable);
+ SET_HANDLER(OpCode::WRITE_CLASS_OF_DEVICE, HciWriteClassOfDevice);
+ SET_HANDLER(OpCode::WRITE_PAGE_TIMEOUT, HciWritePageTimeout);
+ SET_HANDLER(OpCode::WRITE_LINK_SUPERVISION_TIMEOUT, HciWriteLinkSupervisionTimeout);
+ SET_HANDLER(OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS, HciWriteDefaultLinkPolicySettings);
+ SET_HANDLER(OpCode::WRITE_LINK_POLICY_SETTINGS, HciWriteLinkPolicySettings);
+ SET_HANDLER(OpCode::CHANGE_CONNECTION_PACKET_TYPE, HciChangeConnectionPacketType);
+ SET_HANDLER(OpCode::WRITE_LOCAL_NAME, HciWriteLocalName);
+ SET_HANDLER(OpCode::READ_LOCAL_NAME, HciReadLocalName);
+ SET_HANDLER(OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE, HciWriteExtendedInquiryResponse);
+ SET_HANDLER(OpCode::WRITE_VOICE_SETTING, HciWriteVoiceSetting);
+ SET_HANDLER(OpCode::WRITE_CURRENT_IAC_LAP, HciWriteCurrentIacLap);
+ SET_HANDLER(OpCode::WRITE_INQUIRY_SCAN_ACTIVITY, HciWriteInquiryScanActivity);
+ SET_HANDLER(OpCode::WRITE_SCAN_ENABLE, HciWriteScanEnable);
+ SET_HANDLER(OpCode::SET_EVENT_FILTER, HciSetEventFilter);
+ SET_HANDLER(OpCode::INQUIRY, HciInquiry);
+ SET_HANDLER(OpCode::INQUIRY_CANCEL, HciInquiryCancel);
+ SET_HANDLER(OpCode::ACCEPT_CONNECTION_REQUEST, HciAcceptConnectionRequest);
+ SET_HANDLER(OpCode::REJECT_CONNECTION_REQUEST, HciRejectConnectionRequest);
+ SET_HANDLER(OpCode::LINK_KEY_REQUEST_REPLY, HciLinkKeyRequestReply);
+ SET_HANDLER(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, HciLinkKeyRequestNegativeReply);
+ SET_HANDLER(OpCode::DELETE_STORED_LINK_KEY, HciDeleteStoredLinkKey);
+ SET_HANDLER(OpCode::REMOTE_NAME_REQUEST, HciRemoteNameRequest);
+ SET_HANDLER(OpCode::LE_SET_EVENT_MASK, HciLeSetEventMask);
+ SET_HANDLER(OpCode::LE_READ_BUFFER_SIZE, HciLeReadBufferSize);
+ SET_HANDLER(OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES, HciLeReadLocalSupportedFeatures);
+ SET_HANDLER(OpCode::LE_SET_RANDOM_ADDRESS, HciLeSetRandomAddress);
+ SET_HANDLER(OpCode::LE_SET_ADVERTISING_DATA, HciLeSetAdvertisingData);
+ SET_HANDLER(OpCode::LE_SET_ADVERTISING_PARAMETERS, HciLeSetAdvertisingParameters);
+ SET_HANDLER(OpCode::LE_SET_SCAN_PARAMETERS, HciLeSetScanParameters);
+ SET_HANDLER(OpCode::LE_SET_SCAN_ENABLE, HciLeSetScanEnable);
+ SET_HANDLER(OpCode::LE_CREATE_CONNECTION, HciLeCreateConnection);
+ SET_HANDLER(OpCode::CREATE_CONNECTION, HciCreateConnection);
+ SET_HANDLER(OpCode::DISCONNECT, HciDisconnect);
+ SET_HANDLER(OpCode::LE_CREATE_CONNECTION_CANCEL, HciLeConnectionCancel);
+ SET_HANDLER(OpCode::LE_READ_WHITE_LIST_SIZE, HciLeReadWhiteListSize);
+ SET_HANDLER(OpCode::LE_CLEAR_WHITE_LIST, HciLeClearWhiteList);
+ SET_HANDLER(OpCode::LE_ADD_DEVICE_TO_WHITE_LIST, HciLeAddDeviceToWhiteList);
+ SET_HANDLER(OpCode::LE_REMOVE_DEVICE_FROM_WHITE_LIST, HciLeRemoveDeviceFromWhiteList);
+ SET_HANDLER(OpCode::LE_RAND, HciLeRand);
+ SET_HANDLER(OpCode::LE_READ_SUPPORTED_STATES, HciLeReadSupportedStates);
+ SET_HANDLER(OpCode::LE_GET_VENDOR_CAPABILITIES, HciLeVendorCap);
+ SET_HANDLER(OpCode::LE_MULTI_ADVT, HciLeVendorMultiAdv);
+ SET_HANDLER(OpCode::LE_ADV_FILTER, HciLeAdvertisingFilter);
+ SET_HANDLER(OpCode::LE_ENERGY_INFO, HciLeEnergyInfo);
+ SET_HANDLER(OpCode::LE_EXTENDED_SCAN_PARAMS, HciLeExtendedScanParams);
+ SET_HANDLER(OpCode::LE_READ_REMOTE_FEATURES, HciLeReadRemoteFeatures);
+ SET_HANDLER(OpCode::READ_REMOTE_VERSION_INFORMATION, HciReadRemoteVersionInformation);
+ SET_HANDLER(OpCode::LE_CONNECTION_UPDATE, HciLeConnectionUpdate);
+ SET_HANDLER(OpCode::LE_START_ENCRYPTION, HciLeStartEncryption);
+ // Testing Commands
+ SET_HANDLER(OpCode::READ_LOOPBACK_MODE, HciReadLoopbackMode);
+ SET_HANDLER(OpCode::WRITE_LOOPBACK_MODE, HciWriteLoopbackMode);
+#undef SET_HANDLER
+}
+
+void DualModeController::HciSniffSubrating(packets::PacketView<true> args) {
+ CHECK(args.size() == 8) << __func__ << " size=" << args.size();
+
+ uint16_t handle = args.begin().extract<uint16_t>();
+
+ send_event_(packets::EventPacketBuilder::CreateSniffSubratingEvent(hci::Status::SUCCESS, handle)->ToVector());
+}
+
+void DualModeController::RegisterTaskScheduler(
+ std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> oneshot_scheduler) {
+ link_layer_controller_.RegisterTaskScheduler(oneshot_scheduler);
+}
+
+void DualModeController::RegisterPeriodicTaskScheduler(
+ std::function<AsyncTaskId(std::chrono::milliseconds, std::chrono::milliseconds, const TaskCallback&)>
+ periodic_scheduler) {
+ link_layer_controller_.RegisterPeriodicTaskScheduler(periodic_scheduler);
+}
+
+void DualModeController::RegisterTaskCancel(std::function<void(AsyncTaskId)> task_cancel) {
+ link_layer_controller_.RegisterTaskCancel(task_cancel);
+}
+
+void DualModeController::HandleAcl(std::shared_ptr<std::vector<uint8_t>> packet) {
+ auto acl_packet = packets::AclPacketView::Create(packet);
+ if (loopback_mode_ == hci::LoopbackMode::LOCAL) {
+ uint16_t handle = acl_packet.GetHandle();
+ send_acl_(packet);
+ send_event_(packets::EventPacketBuilder::CreateNumberOfCompletedPacketsEvent(handle, 1)->ToVector());
+ return;
+ }
+
+ link_layer_controller_.SendAclToRemote(acl_packet);
+}
+
+void DualModeController::HandleSco(std::shared_ptr<std::vector<uint8_t>> packet) {
+ auto sco_packet = packets::ScoPacketView::Create(packet);
+ if (loopback_mode_ == hci::LoopbackMode::LOCAL) {
+ uint16_t handle = sco_packet.GetHandle();
+ send_sco_(packet);
+ send_event_(packets::EventPacketBuilder::CreateNumberOfCompletedPacketsEvent(handle, 1)->ToVector());
+ return;
+ }
+}
+
+void DualModeController::HandleCommand(std::shared_ptr<std::vector<uint8_t>> packet) {
+ auto command_packet = packets::CommandPacketView::Create(packet);
+ uint16_t opcode = command_packet.GetOpcode();
+ hci::OpCode op = static_cast<hci::OpCode>(opcode);
+
+ if (loopback_mode_ == hci::LoopbackMode::LOCAL &&
+ // Loopback exceptions.
+ op != OpCode::RESET && op != OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL && op != OpCode::HOST_BUFFER_SIZE &&
+ op != OpCode::HOST_NUM_COMPLETED_PACKETS && op != OpCode::READ_BUFFER_SIZE && op != OpCode::READ_LOOPBACK_MODE &&
+ op != OpCode::WRITE_LOOPBACK_MODE) {
+ send_event_(packets::EventPacketBuilder::CreateLoopbackCommandEvent(op, command_packet.GetPayload())->ToVector());
+ } else if (active_hci_commands_.count(opcode) > 0) {
+ active_hci_commands_[opcode](command_packet.GetPayload());
+ } else {
+ SendCommandCompleteUnknownOpCodeEvent(opcode);
+ LOG_INFO(LOG_TAG, "Command opcode: 0x%04X, OGF: 0x%04X, OCF: 0x%04X", opcode, opcode & 0xFC00, opcode & 0x03FF);
+ }
+}
+
+void DualModeController::RegisterEventChannel(
+ const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
+ link_layer_controller_.RegisterEventChannel(callback);
+ send_event_ = callback;
+}
+
+void DualModeController::RegisterAclChannel(
+ const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
+ link_layer_controller_.RegisterAclChannel(callback);
+ send_acl_ = callback;
+}
+
+void DualModeController::RegisterScoChannel(
+ const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
+ link_layer_controller_.RegisterScoChannel(callback);
+ send_sco_ = callback;
+}
+
+void DualModeController::HciReset(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ link_layer_controller_.Reset();
+
+ SendCommandCompleteSuccess(OpCode::RESET);
+}
+
+void DualModeController::HciReadBufferSize(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteReadBufferSize(
+ hci::Status::SUCCESS, properties_.GetAclDataPacketSize(), properties_.GetSynchronousDataPacketSize(),
+ properties_.GetTotalNumAclDataPackets(), properties_.GetTotalNumSynchronousDataPackets());
+
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciHostBufferSize(packets::PacketView<true> args) {
+ CHECK(args.size() == 7) << __func__ << " size=" << args.size();
+ SendCommandCompleteSuccess(OpCode::HOST_BUFFER_SIZE);
+}
+
+void DualModeController::HciReadLocalVersionInformation(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteReadLocalVersionInformation(
+ hci::Status::SUCCESS, properties_.GetVersion(), properties_.GetRevision(), properties_.GetLmpPalVersion(),
+ properties_.GetManufacturerName(), properties_.GetLmpPalSubversion());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciReadRemoteVersionInformation(packets::PacketView<true> args) {
+ CHECK(args.size() == 2) << __func__ << " size=" << args.size();
+
+ uint16_t handle = args.begin().extract<uint16_t>();
+
+ hci::Status status =
+ link_layer_controller_.SendCommandToRemoteByHandle(OpCode::READ_REMOTE_VERSION_INFORMATION, args, handle);
+
+ SendCommandStatus(status, OpCode::READ_REMOTE_VERSION_INFORMATION);
+}
+
+void DualModeController::HciReadBdAddr(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteReadBdAddr(hci::Status::SUCCESS, properties_.GetAddress());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciReadLocalSupportedCommands(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteReadLocalSupportedCommands(hci::Status::SUCCESS,
+ properties_.GetSupportedCommands());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciReadLocalSupportedCodecs(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteReadLocalSupportedCodecs(
+ hci::Status::SUCCESS, properties_.GetSupportedCodecs(), properties_.GetVendorSpecificCodecs());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciReadLocalExtendedFeatures(packets::PacketView<true> args) {
+ CHECK(args.size() == 1) << __func__ << " size=" << args.size();
+ uint8_t page_number = args.begin().extract<uint8_t>();
+ send_event_(packets::EventPacketBuilder::CreateCommandCompleteReadLocalExtendedFeatures(
+ hci::Status::SUCCESS, page_number, properties_.GetExtendedFeaturesMaximumPageNumber(),
+ properties_.GetExtendedFeatures(page_number))
+ ->ToVector());
+}
+
+void DualModeController::HciReadRemoteExtendedFeatures(packets::PacketView<true> args) {
+ CHECK(args.size() == 3) << __func__ << " size=" << args.size();
+
+ uint16_t handle = args.begin().extract<uint16_t>();
+
+ hci::Status status =
+ link_layer_controller_.SendCommandToRemoteByHandle(OpCode::READ_REMOTE_EXTENDED_FEATURES, args, handle);
+
+ SendCommandStatus(status, OpCode::READ_REMOTE_EXTENDED_FEATURES);
+}
+
+void DualModeController::HciReadRemoteSupportedFeatures(packets::PacketView<true> args) {
+ CHECK(args.size() == 2) << __func__ << " size=" << args.size();
+
+ uint16_t handle = args.begin().extract<uint16_t>();
+
+ hci::Status status =
+ link_layer_controller_.SendCommandToRemoteByHandle(OpCode::READ_REMOTE_SUPPORTED_FEATURES, args, handle);
+
+ SendCommandStatus(status, OpCode::READ_REMOTE_SUPPORTED_FEATURES);
+}
+
+void DualModeController::HciReadClockOffset(packets::PacketView<true> args) {
+ CHECK(args.size() == 2) << __func__ << " size=" << args.size();
+
+ uint16_t handle = args.begin().extract<uint16_t>();
+
+ hci::Status status = link_layer_controller_.SendCommandToRemoteByHandle(OpCode::READ_CLOCK_OFFSET, args, handle);
+
+ SendCommandStatus(status, OpCode::READ_CLOCK_OFFSET);
+}
+
+void DualModeController::HciIoCapabilityRequestReply(packets::PacketView<true> args) {
+ CHECK(args.size() == 9) << __func__ << " size=" << args.size();
+
+ auto args_itr = args.begin();
+ Address peer = args_itr.extract<Address>();
+ uint8_t io_capability = args_itr.extract<uint8_t>();
+ uint8_t oob_data_present_flag = args_itr.extract<uint8_t>();
+ uint8_t authentication_requirements = args_itr.extract<uint8_t>();
+
+ hci::Status status = link_layer_controller_.IoCapabilityRequestReply(peer, io_capability, oob_data_present_flag,
+ authentication_requirements);
+
+ SendCommandCompleteStatusAndAddress(OpCode::IO_CAPABILITY_REQUEST_REPLY, status, peer);
+}
+
+void DualModeController::HciUserConfirmationRequestReply(packets::PacketView<true> args) {
+ CHECK(args.size() == 6) << __func__ << " size=" << args.size();
+
+ Address peer = args.begin().extract<Address>();
+
+ hci::Status status = link_layer_controller_.UserConfirmationRequestReply(peer);
+
+ SendCommandCompleteStatusAndAddress(OpCode::USER_CONFIRMATION_REQUEST_REPLY, status, peer);
+}
+
+void DualModeController::HciUserConfirmationRequestNegativeReply(packets::PacketView<true> args) {
+ CHECK(args.size() == 6) << __func__ << " size=" << args.size();
+
+ Address peer = args.begin().extract<Address>();
+
+ hci::Status status = link_layer_controller_.UserConfirmationRequestNegativeReply(peer);
+
+ SendCommandCompleteStatusAndAddress(OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, status, peer);
+}
+
+void DualModeController::HciUserPasskeyRequestReply(packets::PacketView<true> args) {
+ CHECK(args.size() == 10) << __func__ << " size=" << args.size();
+
+ auto args_itr = args.begin();
+ Address peer = args_itr.extract<Address>();
+ uint32_t numeric_value = args_itr.extract<uint32_t>();
+
+ hci::Status status = link_layer_controller_.UserPasskeyRequestReply(peer, numeric_value);
+
+ SendCommandCompleteStatusAndAddress(OpCode::USER_PASSKEY_REQUEST_REPLY, status, peer);
+}
+
+void DualModeController::HciUserPasskeyRequestNegativeReply(packets::PacketView<true> args) {
+ CHECK(args.size() == 6) << __func__ << " size=" << args.size();
+
+ Address peer = args.begin().extract<Address>();
+
+ hci::Status status = link_layer_controller_.UserPasskeyRequestNegativeReply(peer);
+
+ SendCommandCompleteStatusAndAddress(OpCode::USER_PASSKEY_REQUEST_NEGATIVE_REPLY, status, peer);
+}
+
+void DualModeController::HciRemoteOobDataRequestReply(packets::PacketView<true> args) {
+ CHECK(args.size() == 38) << __func__ << " size=" << args.size();
+
+ auto args_itr = args.begin();
+ Address peer = args_itr.extract<Address>();
+ std::vector<uint8_t> c;
+ std::vector<uint8_t> r;
+ for (size_t i = 0; i < 16; i++) {
+ c.push_back(args_itr.extract<uint8_t>());
+ }
+ for (size_t i = 0; i < 16; i++) {
+ r.push_back(args_itr.extract<uint8_t>());
+ }
+ hci::Status status = link_layer_controller_.RemoteOobDataRequestReply(peer, c, r);
+
+ SendCommandCompleteStatusAndAddress(OpCode::REMOTE_OOB_DATA_REQUEST_REPLY, status, peer);
+}
+
+void DualModeController::HciRemoteOobDataRequestNegativeReply(packets::PacketView<true> args) {
+ CHECK(args.size() == 6) << __func__ << " size=" << args.size();
+
+ Address peer = args.begin().extract<Address>();
+
+ hci::Status status = link_layer_controller_.RemoteOobDataRequestNegativeReply(peer);
+
+ SendCommandCompleteStatusAndAddress(OpCode::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY, status, peer);
+}
+
+void DualModeController::HciIoCapabilityRequestNegativeReply(packets::PacketView<true> args) {
+ CHECK(args.size() == 7) << __func__ << " size=" << args.size();
+
+ auto args_itr = args.begin();
+ Address peer = args_itr.extract<Address>();
+ hci::Status reason = args_itr.extract<hci::Status>();
+
+ hci::Status status = link_layer_controller_.IoCapabilityRequestNegativeReply(peer, reason);
+
+ SendCommandCompleteStatusAndAddress(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, status, peer);
+}
+
+void DualModeController::HciWriteSimplePairingMode(packets::PacketView<true> args) {
+ CHECK(args.size() == 1) << __func__ << " size=" << args.size();
+ CHECK(args[0] == 1 || args[0] == 0);
+ link_layer_controller_.WriteSimplePairingMode(args[0] == 1);
+ SendCommandCompleteSuccess(OpCode::WRITE_SIMPLE_PAIRING_MODE);
+}
+
+void DualModeController::HciChangeConnectionPacketType(packets::PacketView<true> args) {
+ CHECK(args.size() == 4) << __func__ << " size=" << args.size();
+ auto args_itr = args.begin();
+ uint16_t handle = args_itr.extract<uint16_t>();
+ uint16_t packet_type = args_itr.extract<uint16_t>();
+
+ hci::Status status = link_layer_controller_.ChangeConnectionPacketType(handle, packet_type);
+
+ SendCommandStatus(status, OpCode::CHANGE_CONNECTION_PACKET_TYPE);
+}
+
+void DualModeController::HciWriteLeHostSupport(packets::PacketView<true> args) {
+ CHECK(args.size() == 2) << __func__ << " size=" << args.size();
+ SendCommandCompleteSuccess(OpCode::WRITE_LE_HOST_SUPPORT);
+}
+
+void DualModeController::HciSetEventMask(packets::PacketView<true> args) {
+ CHECK(args.size() == 8) << __func__ << " size=" << args.size();
+ SendCommandCompleteSuccess(OpCode::SET_EVENT_MASK);
+}
+
+void DualModeController::HciWriteInquiryMode(packets::PacketView<true> args) {
+ CHECK(args.size() == 1) << __func__ << " size=" << args.size();
+ link_layer_controller_.SetInquiryMode(args[0]);
+ SendCommandCompleteSuccess(OpCode::WRITE_INQUIRY_MODE);
+}
+
+void DualModeController::HciWritePageScanType(packets::PacketView<true> args) {
+ CHECK(args.size() == 1) << __func__ << " size=" << args.size();
+ SendCommandCompleteSuccess(OpCode::WRITE_PAGE_SCAN_TYPE);
+}
+
+void DualModeController::HciWriteInquiryScanType(packets::PacketView<true> args) {
+ CHECK(args.size() == 1) << __func__ << " size=" << args.size();
+ SendCommandCompleteSuccess(OpCode::WRITE_INQUIRY_SCAN_TYPE);
+}
+
+void DualModeController::HciAuthenticationRequested(packets::PacketView<true> args) {
+ CHECK(args.size() == 2) << __func__ << " size=" << args.size();
+ uint16_t handle = args.begin().extract<uint16_t>();
+ hci::Status status = link_layer_controller_.AuthenticationRequested(handle);
+
+ SendCommandStatus(status, OpCode::AUTHENTICATION_REQUESTED);
+}
+
+void DualModeController::HciSetConnectionEncryption(packets::PacketView<true> args) {
+ CHECK(args.size() == 3) << __func__ << " size=" << args.size();
+ auto args_itr = args.begin();
+ uint16_t handle = args_itr.extract<uint16_t>();
+ uint8_t encryption_enable = args_itr.extract<uint8_t>();
+ hci::Status status = link_layer_controller_.SetConnectionEncryption(handle, encryption_enable);
+
+ SendCommandStatus(status, OpCode::SET_CONNECTION_ENCRYPTION);
+}
+
+void DualModeController::HciWriteAuthenticationEnable(packets::PacketView<true> args) {
+ CHECK(args.size() == 1) << __func__ << " size=" << args.size();
+ properties_.SetAuthenticationEnable(args[0]);
+ SendCommandCompleteSuccess(OpCode::WRITE_AUTHENTICATION_ENABLE);
+}
+
+void DualModeController::HciReadAuthenticationEnable(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteReadAuthenticationEnable(hci::Status::SUCCESS,
+ properties_.GetAuthenticationEnable());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciWriteClassOfDevice(packets::PacketView<true> args) {
+ CHECK(args.size() == 3) << __func__ << " size=" << args.size();
+ properties_.SetClassOfDevice(args[0], args[1], args[2]);
+ SendCommandCompleteSuccess(OpCode::WRITE_CLASS_OF_DEVICE);
+}
+
+void DualModeController::HciWritePageTimeout(packets::PacketView<true> args) {
+ CHECK(args.size() == 2) << __func__ << " size=" << args.size();
+ SendCommandCompleteSuccess(OpCode::WRITE_PAGE_TIMEOUT);
+}
+
+void DualModeController::HciWriteDefaultLinkPolicySettings(packets::PacketView<true> args) {
+ CHECK(args.size() == 2) << __func__ << " size=" << args.size();
+ SendCommandCompleteSuccess(OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS);
+}
+
+void DualModeController::HciWriteLinkPolicySettings(packets::PacketView<true> args) {
+ CHECK(args.size() == 4) << __func__ << " size=" << args.size();
+
+ auto args_itr = args.begin();
+ uint16_t handle = args_itr.extract<uint16_t>();
+ uint16_t settings = args_itr.extract<uint16_t>();
+
+ hci::Status status = link_layer_controller_.WriteLinkPolicySettings(handle, settings);
+
+ send_event_(packets::EventPacketBuilder::CreateCommandCompleteWriteLinkPolicySettings(status, handle)->ToVector());
+}
+
+void DualModeController::HciWriteLinkSupervisionTimeout(packets::PacketView<true> args) {
+ CHECK(args.size() == 4) << __func__ << " size=" << args.size();
+
+ auto args_itr = args.begin();
+ uint16_t handle = args_itr.extract<uint16_t>();
+ uint16_t timeout = args_itr.extract<uint16_t>();
+
+ hci::Status status = link_layer_controller_.WriteLinkSupervisionTimeout(handle, timeout);
+
+ send_event_(
+ packets::EventPacketBuilder::CreateCommandCompleteWriteLinkSupervisionTimeout(status, handle)->ToVector());
+}
+
+void DualModeController::HciReadLocalName(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteReadLocalName(hci::Status::SUCCESS, properties_.GetName());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciWriteLocalName(packets::PacketView<true> args) {
+ CHECK(args.size() == 248) << __func__ << " size=" << args.size();
+ std::vector<uint8_t> clipped(args.begin(), args.begin() + LastNonZero(args) + 1);
+ properties_.SetName(clipped);
+ SendCommandCompleteSuccess(OpCode::WRITE_LOCAL_NAME);
+}
+
+void DualModeController::HciWriteExtendedInquiryResponse(packets::PacketView<true> args) {
+ CHECK(args.size() == 241) << __func__ << " size=" << args.size();
+ // Strip FEC byte and trailing zeros
+ std::vector<uint8_t> clipped(args.begin() + 1, args.begin() + LastNonZero(args) + 1);
+ properties_.SetExtendedInquiryData(clipped);
+ LOG_WARN(LOG_TAG, "Write EIR Inquiry - Size = %d (%d)", static_cast<int>(properties_.GetExtendedInquiryData().size()),
+ static_cast<int>(clipped.size()));
+ SendCommandCompleteSuccess(OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE);
+}
+
+void DualModeController::HciWriteVoiceSetting(packets::PacketView<true> args) {
+ CHECK(args.size() == 2) << __func__ << " size=" << args.size();
+ SendCommandCompleteSuccess(OpCode::WRITE_VOICE_SETTING);
+}
+
+void DualModeController::HciWriteCurrentIacLap(packets::PacketView<true> args) {
+ CHECK(args.size() > 0);
+ CHECK(args.size() == 1 + (3 * args[0])); // count + 3-byte IACs
+
+ SendCommandCompleteSuccess(OpCode::WRITE_CURRENT_IAC_LAP);
+}
+
+void DualModeController::HciWriteInquiryScanActivity(packets::PacketView<true> args) {
+ CHECK(args.size() == 4) << __func__ << " size=" << args.size();
+ SendCommandCompleteSuccess(OpCode::WRITE_INQUIRY_SCAN_ACTIVITY);
+}
+
+void DualModeController::HciWriteScanEnable(packets::PacketView<true> args) {
+ CHECK(args.size() == 1) << __func__ << " size=" << args.size();
+ link_layer_controller_.SetInquiryScanEnable(args[0] & 0x1);
+ link_layer_controller_.SetPageScanEnable(args[0] & 0x2);
+ SendCommandCompleteSuccess(OpCode::WRITE_SCAN_ENABLE);
+}
+
+void DualModeController::HciSetEventFilter(packets::PacketView<true> args) {
+ CHECK(args.size() > 0);
+ SendCommandCompleteSuccess(OpCode::SET_EVENT_FILTER);
+}
+
+void DualModeController::HciInquiry(packets::PacketView<true> args) {
+ CHECK(args.size() == 5) << __func__ << " size=" << args.size();
+ link_layer_controller_.SetInquiryLAP(args[0] | (args[1] << 8) | (args[2] << 16));
+ link_layer_controller_.SetInquiryMaxResponses(args[4]);
+ link_layer_controller_.StartInquiry(std::chrono::milliseconds(args[3] * 1280));
+
+ SendCommandStatusSuccess(OpCode::INQUIRY);
+}
+
+void DualModeController::HciInquiryCancel(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ link_layer_controller_.InquiryCancel();
+ SendCommandCompleteSuccess(OpCode::INQUIRY_CANCEL);
+}
+
+void DualModeController::HciAcceptConnectionRequest(packets::PacketView<true> args) {
+ CHECK(args.size() == 7) << __func__ << " size=" << args.size();
+ Address addr = args.begin().extract<Address>();
+ bool try_role_switch = args[6] == 0;
+ hci::Status status = link_layer_controller_.AcceptConnectionRequest(addr, try_role_switch);
+ SendCommandStatus(status, OpCode::ACCEPT_CONNECTION_REQUEST);
+}
+
+void DualModeController::HciRejectConnectionRequest(packets::PacketView<true> args) {
+ CHECK(args.size() == 7) << __func__ << " size=" << args.size();
+ auto args_itr = args.begin();
+ Address addr = args_itr.extract<Address>();
+ uint8_t reason = args_itr.extract<uint8_t>();
+ hci::Status status = link_layer_controller_.RejectConnectionRequest(addr, reason);
+ SendCommandStatus(status, OpCode::REJECT_CONNECTION_REQUEST);
+}
+
+void DualModeController::HciLinkKeyRequestReply(packets::PacketView<true> args) {
+ CHECK(args.size() == 22) << __func__ << " size=" << args.size();
+ Address addr = args.begin().extract<Address>();
+ packets::PacketView<true> key = args.SubViewLittleEndian(6, 22);
+ hci::Status status = link_layer_controller_.LinkKeyRequestReply(addr, key);
+ send_event_(packets::EventPacketBuilder::CreateCommandCompleteLinkKeyRequestReply(status, addr)->ToVector());
+}
+
+void DualModeController::HciLinkKeyRequestNegativeReply(packets::PacketView<true> args) {
+ CHECK(args.size() == 6) << __func__ << " size=" << args.size();
+ Address addr = args.begin().extract<Address>();
+ hci::Status status = link_layer_controller_.LinkKeyRequestNegativeReply(addr);
+ send_event_(packets::EventPacketBuilder::CreateCommandCompleteLinkKeyRequestNegativeReply(status, addr)->ToVector());
+}
+
+void DualModeController::HciDeleteStoredLinkKey(packets::PacketView<true> args) {
+ CHECK(args.size() == 7) << __func__ << " size=" << args.size();
+
+ uint16_t deleted_keys = 0;
+
+ if (args[6] == 0) {
+ Address addr = args.begin().extract<Address>();
+ deleted_keys = security_manager_.DeleteKey(addr);
+ }
+
+ if (args[6] == 1) {
+ security_manager_.DeleteAllKeys();
+ }
+
+ send_event_(packets::EventPacketBuilder::CreateCommandCompleteDeleteStoredLinkKey(hci::Status::SUCCESS, deleted_keys)
+ ->ToVector());
+}
+
+void DualModeController::HciRemoteNameRequest(packets::PacketView<true> args) {
+ CHECK(args.size() == 10) << __func__ << " size=" << args.size();
+
+ Address remote_addr = args.begin().extract<Address>();
+
+ hci::Status status =
+ link_layer_controller_.SendCommandToRemoteByAddress(OpCode::REMOTE_NAME_REQUEST, args, remote_addr, false);
+
+ SendCommandStatus(status, OpCode::REMOTE_NAME_REQUEST);
+}
+
+void DualModeController::HciLeSetEventMask(packets::PacketView<true> args) {
+ CHECK(args.size() == 8) << __func__ << " size=" << args.size();
+ /*
+ uint64_t mask = args.begin().extract<uint64_t>();
+ link_layer_controller_.SetLeEventMask(mask);
+ */
+ SendCommandCompleteSuccess(OpCode::LE_SET_EVENT_MASK);
+}
+
+void DualModeController::HciLeReadBufferSize(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteLeReadBufferSize(
+ hci::Status::SUCCESS, properties_.GetLeDataPacketLength(), properties_.GetTotalNumLeDataPackets());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciLeReadLocalSupportedFeatures(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteLeReadLocalSupportedFeatures(
+ hci::Status::SUCCESS, properties_.GetLeSupportedFeatures());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciLeSetRandomAddress(packets::PacketView<true> args) {
+ CHECK(args.size() == 6) << __func__ << " size=" << args.size();
+ properties_.SetLeAddress(args.begin().extract<Address>());
+ SendCommandCompleteSuccess(OpCode::LE_SET_RANDOM_ADDRESS);
+}
+
+void DualModeController::HciLeSetAdvertisingParameters(packets::PacketView<true> args) {
+ CHECK(args.size() == 15) << __func__ << " size=" << args.size();
+
+ SendCommandCompleteSuccess(OpCode::LE_SET_ADVERTISING_PARAMETERS);
+}
+
+void DualModeController::HciLeSetAdvertisingData(packets::PacketView<true> args) {
+ CHECK(args.size() > 0);
+ SendCommandCompleteSuccess(OpCode::LE_SET_ADVERTISING_DATA);
+}
+
+void DualModeController::HciLeSetScanParameters(packets::PacketView<true> args) {
+ CHECK(args.size() == 7) << __func__ << " size=" << args.size();
+ link_layer_controller_.SetLeScanType(args[0]);
+ link_layer_controller_.SetLeScanInterval(args[1] | (args[2] << 8));
+ link_layer_controller_.SetLeScanWindow(args[3] | (args[4] << 8));
+ link_layer_controller_.SetLeAddressType(args[5]);
+ link_layer_controller_.SetLeScanFilterPolicy(args[6]);
+ SendCommandCompleteSuccess(OpCode::LE_SET_SCAN_PARAMETERS);
+}
+
+void DualModeController::HciLeSetScanEnable(packets::PacketView<true> args) {
+ CHECK(args.size() == 2) << __func__ << " size=" << args.size();
+ LOG_INFO(LOG_TAG, "SetScanEnable: %d %d", args[0], args[1]);
+ link_layer_controller_.SetLeScanEnable(args[0]);
+ link_layer_controller_.SetLeFilterDuplicates(args[1]);
+ SendCommandCompleteSuccess(OpCode::LE_SET_SCAN_ENABLE);
+}
+
+void DualModeController::HciLeCreateConnection(packets::PacketView<true> args) {
+ CHECK(args.size() == 25) << __func__ << " size=" << args.size();
+ auto args_itr = args.begin();
+ link_layer_controller_.SetLeScanInterval(args_itr.extract<uint16_t>());
+ link_layer_controller_.SetLeScanWindow(args_itr.extract<uint16_t>());
+ uint8_t initiator_filter_policy = args_itr.extract<uint8_t>();
+ link_layer_controller_.SetLeInitiatorFilterPolicy(initiator_filter_policy);
+
+ if (initiator_filter_policy == 0) { // White list not used
+ uint8_t peer_address_type = args_itr.extract<uint8_t>();
+ Address peer_address = args_itr.extract<Address>();
+ link_layer_controller_.SetLePeerAddressType(peer_address_type);
+ link_layer_controller_.SetLePeerAddress(peer_address);
+ }
+ link_layer_controller_.SetLeAddressType(args_itr.extract<uint8_t>());
+ link_layer_controller_.SetLeConnectionIntervalMin(args_itr.extract<uint16_t>());
+ link_layer_controller_.SetLeConnectionIntervalMax(args_itr.extract<uint16_t>());
+ link_layer_controller_.SetLeConnectionLatency(args_itr.extract<uint16_t>());
+ link_layer_controller_.SetLeSupervisionTimeout(args_itr.extract<uint16_t>());
+ link_layer_controller_.SetLeMinimumCeLength(args_itr.extract<uint16_t>());
+ link_layer_controller_.SetLeMaximumCeLength(args_itr.extract<uint16_t>());
+
+ hci::Status status = link_layer_controller_.SetLeConnect(true);
+
+ SendCommandStatus(status, OpCode::LE_CREATE_CONNECTION);
+}
+
+void DualModeController::HciLeConnectionUpdate(packets::PacketView<true> args) {
+ CHECK(args.size() == 14) << __func__ << " size=" << args.size();
+
+ SendCommandStatus(hci::Status::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR, OpCode::LE_CONNECTION_UPDATE);
+
+ send_event_(packets::EventPacketBuilder::CreateLeConnectionUpdateCompleteEvent(hci::Status::SUCCESS, 0x0002, 0x0006,
+ 0x0000, 0x01f4)
+ ->ToVector());
+}
+
+void DualModeController::HciCreateConnection(packets::PacketView<true> args) {
+ CHECK(args.size() == 13) << __func__ << " size=" << args.size();
+
+ auto args_itr = args.begin();
+ Address address = args_itr.extract<Address>();
+ uint16_t packet_type = args_itr.extract<uint16_t>();
+ uint8_t page_scan_mode = args_itr.extract<uint8_t>();
+ uint16_t clock_offset = args_itr.extract<uint16_t>();
+ uint8_t allow_role_switch = args_itr.extract<uint8_t>();
+
+ hci::Status status =
+ link_layer_controller_.CreateConnection(address, packet_type, page_scan_mode, clock_offset, allow_role_switch);
+
+ SendCommandStatus(status, OpCode::CREATE_CONNECTION);
+}
+
+void DualModeController::HciDisconnect(packets::PacketView<true> args) {
+ CHECK(args.size() == 3) << __func__ << " size=" << args.size();
+
+ auto args_itr = args.begin();
+ uint16_t handle = args_itr.extract<uint16_t>();
+ uint8_t reason = args_itr.extract<uint8_t>();
+
+ hci::Status status = link_layer_controller_.Disconnect(handle, reason);
+
+ SendCommandStatus(status, OpCode::DISCONNECT);
+}
+
+void DualModeController::HciLeConnectionCancel(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ link_layer_controller_.SetLeConnect(false);
+ SendCommandStatusSuccess(OpCode::LE_CREATE_CONNECTION_CANCEL);
+ /* For testing Jakub's patch: Figure out a neat way to call this without
+ recompiling. I'm thinking about a bad device. */
+ /*
+ SendCommandCompleteOnlyStatus(OpCode::LE_CREATE_CONNECTION_CANCEL,
+ Status::ERR_COMMAND_DISALLOWED);
+ */
+}
+
+void DualModeController::HciLeReadWhiteListSize(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteLeReadWhiteListSize(hci::Status::SUCCESS,
+ properties_.GetLeWhiteListSize());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciLeClearWhiteList(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ link_layer_controller_.LeWhiteListClear();
+ SendCommandCompleteSuccess(OpCode::LE_CLEAR_WHITE_LIST);
+}
+
+void DualModeController::HciLeAddDeviceToWhiteList(packets::PacketView<true> args) {
+ CHECK(args.size() == 7) << __func__ << " size=" << args.size();
+
+ if (link_layer_controller_.LeWhiteListFull()) {
+ SendCommandCompleteOnlyStatus(OpCode::LE_ADD_DEVICE_TO_WHITE_LIST, hci::Status::MEMORY_CAPACITY_EXCEEDED);
+ return;
+ }
+ auto args_itr = args.begin();
+ uint8_t addr_type = args_itr.extract<uint8_t>();
+ Address address = args_itr.extract<Address>();
+ link_layer_controller_.LeWhiteListAddDevice(address, addr_type);
+ SendCommandCompleteSuccess(OpCode::LE_ADD_DEVICE_TO_WHITE_LIST);
+}
+
+void DualModeController::HciLeRemoveDeviceFromWhiteList(packets::PacketView<true> args) {
+ CHECK(args.size() == 7) << __func__ << " size=" << args.size();
+
+ auto args_itr = args.begin();
+ uint8_t addr_type = args_itr.extract<uint8_t>();
+ Address address = args_itr.extract<Address>();
+ link_layer_controller_.LeWhiteListRemoveDevice(address, addr_type);
+ SendCommandCompleteSuccess(OpCode::LE_REMOVE_DEVICE_FROM_WHITE_LIST);
+}
+
+/*
+void DualModeController::HciLeReadRemoteUsedFeaturesRsp(uint16_t handle,
+ uint64_t features) {
+ std::shared_ptr<packets::EventPacketBuilder> event =
+ packets::EventPacketBuilder::CreateLeRemoteUsedFeaturesEvent(
+ hci::Status::SUCCESS, handle, features);
+ send_event_(event->ToVector());
+}
+*/
+
+void DualModeController::HciLeReadRemoteFeatures(packets::PacketView<true> args) {
+ CHECK(args.size() == 2) << __func__ << " size=" << args.size();
+
+ uint16_t handle = args.begin().extract<uint16_t>();
+
+ hci::Status status =
+ link_layer_controller_.SendCommandToRemoteByHandle(OpCode::LE_READ_REMOTE_FEATURES, args, handle);
+
+ SendCommandStatus(status, OpCode::LE_READ_REMOTE_FEATURES);
+}
+
+void DualModeController::HciLeRand(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ uint64_t random_val = 0;
+ for (size_t rand_bytes = 0; rand_bytes < sizeof(uint64_t); rand_bytes += sizeof(RAND_MAX)) {
+ random_val = (random_val << (8 * sizeof(RAND_MAX))) | random();
+ }
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteLeRand(hci::Status::SUCCESS, random_val);
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciLeReadSupportedStates(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteLeReadSupportedStates(hci::Status::SUCCESS,
+ properties_.GetLeSupportedStates());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciLeVendorCap(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ vector<uint8_t> caps = properties_.GetLeVendorCap();
+ if (caps.size() == 0) {
+ SendCommandCompleteOnlyStatus(OpCode::LE_GET_VENDOR_CAPABILITIES, hci::Status::UNKNOWN_COMMAND);
+ return;
+ }
+
+ std::shared_ptr<packets::EventPacketBuilder> command_complete =
+ packets::EventPacketBuilder::CreateCommandCompleteLeGetVendorCapabilities(hci::Status::SUCCESS,
+ properties_.GetLeVendorCap());
+ send_event_(command_complete->ToVector());
+}
+
+void DualModeController::HciLeVendorMultiAdv(packets::PacketView<true> args) {
+ CHECK(args.size() > 0);
+ SendCommandCompleteOnlyStatus(OpCode::LE_MULTI_ADVT, hci::Status::UNKNOWN_COMMAND);
+}
+
+void DualModeController::HciLeAdvertisingFilter(packets::PacketView<true> args) {
+ CHECK(args.size() > 0);
+ SendCommandCompleteOnlyStatus(OpCode::LE_ADV_FILTER, hci::Status::UNKNOWN_COMMAND);
+}
+
+void DualModeController::HciLeEnergyInfo(packets::PacketView<true> args) {
+ CHECK(args.size() > 0);
+ SendCommandCompleteOnlyStatus(OpCode::LE_ENERGY_INFO, hci::Status::UNKNOWN_COMMAND);
+}
+
+void DualModeController::HciLeExtendedScanParams(packets::PacketView<true> args) {
+ CHECK(args.size() > 0);
+ SendCommandCompleteOnlyStatus(OpCode::LE_EXTENDED_SCAN_PARAMS, hci::Status::UNKNOWN_COMMAND);
+}
+
+void DualModeController::HciLeStartEncryption(packets::PacketView<true> args) {
+ CHECK(args.size() == 28) << __func__ << " size=" << args.size();
+
+ auto args_itr = args.begin();
+ uint16_t handle = args_itr.extract<uint16_t>();
+ // uint64_t random_number = args_itr.extract<uint64_t>();
+ // uint16_t encrypted_diversifier = args_itr.extract<uint16_t>();
+ // std::vector<uint8_t> long_term_key;
+ // for (size_t i = 0; i < 16; i++) {
+ // long_term_key.push_back(args_itr.extract<uint18_t>();
+ // }
+ SendCommandStatus(hci::Status::SUCCESS, OpCode::LE_START_ENCRYPTION);
+
+ send_event_(packets::EventPacketBuilder::CreateEncryptionChange(hci::Status::SUCCESS, handle, 0x01)->ToVector());
+#if 0
+
+ std::shared_ptr<packets::AclPacketBuilder> encryption_information =
+ std::make_shared<packets::AclPacketBuilder>(
+ 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
+ std::vector<uint8_t>({}));
+
+ encryption_information->AddPayloadOctets2(0x0011);
+ encryption_information->AddPayloadOctets2(0x0006);
+ encryption_information->AddPayloadOctets1(0x06);
+ encryption_information->AddPayloadOctets8(0x0706050403020100);
+ encryption_information->AddPayloadOctets8(0x0F0E0D0C0B0A0908);
+
+ send_acl_(encryption_information);
+
+ encryption_information = std::make_shared<packets::AclPacketBuilder>(
+ 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
+ std::vector<uint8_t>({}));
+
+ encryption_information->AddPayloadOctets2(0x000B);
+ encryption_information->AddPayloadOctets2(0x0006);
+ encryption_information->AddPayloadOctets1(0x07);
+ encryption_information->AddPayloadOctets2(0xBEEF);
+ encryption_information->AddPayloadOctets8(0x0706050403020100);
+
+ send_acl_(encryption_information);
+
+ encryption_information = std::make_shared<packets::AclPacketBuilder>(
+ 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
+ std::vector<uint8_t>({}));
+
+ encryption_information->AddPayloadOctets2(0x0011);
+ encryption_information->AddPayloadOctets2(0x0006);
+ encryption_information->AddPayloadOctets1(0x08);
+ encryption_information->AddPayloadOctets8(0x0F0E0D0C0B0A0908);
+ encryption_information->AddPayloadOctets8(0x0706050403020100);
+
+ send_acl_(encryption_information);
+
+ encryption_information = std::make_shared<packets::AclPacketBuilder>(
+ 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
+ std::vector<uint8_t>({}));
+
+ encryption_information->AddPayloadOctets2(0x0008);
+ encryption_information->AddPayloadOctets2(0x0006);
+ encryption_information->AddPayloadOctets1(0x09);
+ encryption_information->AddPayloadOctets1(0x01);
+ encryption_information->AddPayloadOctets6(0xDEADBEEFF00D);
+ send_acl_(encryption_information);
+ // send_event_(packets::EventPacketBuilder::CreateLeStartEncryption()->ToVector());
+
+#endif
+}
+
+void DualModeController::HciReadLoopbackMode(packets::PacketView<true> args) {
+ CHECK(args.size() == 0) << __func__ << " size=" << args.size();
+ send_event_(packets::EventPacketBuilder::CreateCommandCompleteReadLoopbackMode(hci::Status::SUCCESS, loopback_mode_)
+ ->ToVector());
+}
+
+void DualModeController::HciWriteLoopbackMode(packets::PacketView<true> args) {
+ CHECK(args.size() == 1) << __func__ << " size=" << args.size();
+ loopback_mode_ = static_cast<hci::LoopbackMode>(args[0]);
+ // ACL channel
+ uint16_t acl_handle = 0x123;
+ send_event_(packets::EventPacketBuilder::CreateConnectionCompleteEvent(
+ hci::Status::SUCCESS, acl_handle, properties_.GetAddress(), hci::LinkType::ACL, false)
+ ->ToVector());
+ // SCO channel
+ uint16_t sco_handle = 0x345;
+ send_event_(packets::EventPacketBuilder::CreateConnectionCompleteEvent(
+ hci::Status::SUCCESS, sco_handle, properties_.GetAddress(), hci::LinkType::SCO, false)
+ ->ToVector());
+ SendCommandCompleteSuccess(OpCode::WRITE_LOOPBACK_MODE);
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * 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 <unistd.h>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "base/time/time.h"
+#include "link_layer_controller.h"
+#include "model/devices/device.h"
+#include "model/setup/async_manager.h"
+#include "security_manager.h"
+#include "types/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 DualModeController : public Device {
+ // The location of the config file loaded to populate controller attributes.
+ static constexpr char kControllerPropertiesFile[] = "/etc/bluetooth/controller_properties.json";
+ static constexpr uint16_t kSecurityManagerNumKeys = 15;
+
+ public:
+ // Sets all of the methods to be used as callbacks in the HciHandler.
+ DualModeController(const std::string& properties_filename = std::string(kControllerPropertiesFile),
+ uint16_t num_keys = kSecurityManagerNumKeys);
+
+ ~DualModeController() = default;
+
+ // Device methods.
+ virtual void Initialize(const std::vector<std::string>& args) override;
+
+ virtual std::string GetTypeString() const override;
+
+ virtual void IncomingPacket(packets::LinkLayerPacketView incoming) override;
+
+ virtual void TimerTick() override;
+
+ // Send packets to remote devices
+ void SendLinkLayerPacket(std::shared_ptr<packets::LinkLayerPacketBuilder> to_send, Phy::Type phy_type);
+
+ // Route commands and data from the stack.
+ void HandleAcl(std::shared_ptr<std::vector<uint8_t>> acl_packet);
+ void HandleCommand(std::shared_ptr<std::vector<uint8_t>> command_packet);
+ void HandleSco(std::shared_ptr<std::vector<uint8_t>> sco_packet);
+
+ // Set the callbacks for scheduling tasks.
+ void RegisterTaskScheduler(std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> evtScheduler);
+
+ void RegisterPeriodicTaskScheduler(
+ std::function<AsyncTaskId(std::chrono::milliseconds, std::chrono::milliseconds, const TaskCallback&)>
+ periodicEvtScheduler);
+
+ void RegisterTaskCancel(std::function<void(AsyncTaskId)> cancel);
+
+ // 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);
+
+ // Controller commands. For error codes, see the Bluetooth Core Specification,
+ // Version 4.2, Volume 2, Part D (page 370).
+
+ // Link Control Commands
+ // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1
+
+ // 7.1.1
+ void HciInquiry(packets::PacketView<true> args);
+
+ // 7.1.2
+ void HciInquiryCancel(packets::PacketView<true> args);
+
+ // 7.1.5
+ void HciCreateConnection(packets::PacketView<true> args);
+
+ // 7.1.6
+ void HciDisconnect(packets::PacketView<true> args);
+
+ // 7.1.8
+ void HciAcceptConnectionRequest(packets::PacketView<true> args);
+
+ // 7.1.9
+ void HciRejectConnectionRequest(packets::PacketView<true> args);
+
+ // 7.1.10
+ void HciLinkKeyRequestReply(packets::PacketView<true> args);
+
+ // 7.1.11
+ void HciLinkKeyRequestNegativeReply(packets::PacketView<true> args);
+
+ // 7.1.14
+ void HciChangeConnectionPacketType(packets::PacketView<true> args);
+
+ // 7.1.15
+ void HciAuthenticationRequested(packets::PacketView<true> args);
+
+ // 7.1.16
+ void HciSetConnectionEncryption(packets::PacketView<true> args);
+
+ // 7.1.19
+ void HciRemoteNameRequest(packets::PacketView<true> args);
+
+ // 7.1.21
+ void HciReadRemoteSupportedFeatures(packets::PacketView<true> args);
+
+ // 7.1.22
+ void HciReadRemoteExtendedFeatures(packets::PacketView<true> args);
+
+ // 7.1.23
+ void HciReadRemoteVersionInformation(packets::PacketView<true> args);
+
+ // 7.1.24
+ void HciReadClockOffset(packets::PacketView<true> args);
+
+ // 7.1.29
+ void HciIoCapabilityRequestReply(packets::PacketView<true> args);
+
+ // 7.1.30
+ void HciUserConfirmationRequestReply(packets::PacketView<true> args);
+
+ // 7.1.31
+ void HciUserConfirmationRequestNegativeReply(packets::PacketView<true> args);
+
+ // 7.1.32
+ void HciUserPasskeyRequestReply(packets::PacketView<true> args);
+
+ // 7.1.33
+ void HciUserPasskeyRequestNegativeReply(packets::PacketView<true> args);
+
+ // 7.1.34
+ void HciRemoteOobDataRequestReply(packets::PacketView<true> args);
+
+ // 7.1.35
+ void HciRemoteOobDataRequestNegativeReply(packets::PacketView<true> args);
+
+ // 7.1.36
+ void HciIoCapabilityRequestNegativeReply(packets::PacketView<true> args);
+
+ // Link Policy Commands
+ // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.2
+
+ // 7.2.10
+ void HciWriteLinkPolicySettings(packets::PacketView<true> args);
+
+ // 7.2.12
+ void HciWriteDefaultLinkPolicySettings(packets::PacketView<true> args);
+
+ // 7.2.14
+ void HciSniffSubrating(packets::PacketView<true> args);
+
+ // Link Controller Commands
+ // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3
+
+ // 7.3.1
+ void HciSetEventMask(packets::PacketView<true> args);
+
+ // 7.3.2
+ void HciReset(packets::PacketView<true> args);
+
+ // 7.3.3
+ void HciSetEventFilter(packets::PacketView<true> args);
+
+ // 7.3.10
+ void HciDeleteStoredLinkKey(packets::PacketView<true> args);
+
+ // 7.3.11
+ void HciWriteLocalName(packets::PacketView<true> args);
+
+ // 7.3.12
+ void HciReadLocalName(packets::PacketView<true> args);
+
+ // 7.3.16
+ void HciWritePageTimeout(packets::PacketView<true> args);
+
+ // 7.3.18
+ void HciWriteScanEnable(packets::PacketView<true> args);
+
+ // 7.3.22
+ void HciWriteInquiryScanActivity(packets::PacketView<true> args);
+
+ // 7.3.23
+ void HciReadAuthenticationEnable(packets::PacketView<true> args);
+
+ // 7.3.24
+ void HciWriteAuthenticationEnable(packets::PacketView<true> args);
+
+ // 7.3.26
+ void HciWriteClassOfDevice(packets::PacketView<true> args);
+
+ // 7.3.28
+ void HciWriteVoiceSetting(packets::PacketView<true> args);
+
+ // 7.3.39
+ void HciHostBufferSize(packets::PacketView<true> args);
+
+ // 7.3.42
+ void HciWriteLinkSupervisionTimeout(packets::PacketView<true> args);
+
+ // 7.3.45
+ void HciWriteCurrentIacLap(packets::PacketView<true> args);
+
+ // 7.3.48
+ void HciWriteInquiryScanType(packets::PacketView<true> args);
+
+ // 7.3.50
+ void HciWriteInquiryMode(packets::PacketView<true> args);
+
+ // 7.3.52
+ void HciWritePageScanType(packets::PacketView<true> args);
+
+ // 7.3.56
+ void HciWriteExtendedInquiryResponse(packets::PacketView<true> args);
+
+ // 7.3.59
+ void HciWriteSimplePairingMode(packets::PacketView<true> args);
+
+ // 7.3.79
+ void HciWriteLeHostSupport(packets::PacketView<true> args);
+
+ // Informational Parameters Commands
+ // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4
+
+ // 7.4.5
+ void HciReadBufferSize(packets::PacketView<true> args);
+
+ // 7.4.1
+ void HciReadLocalVersionInformation(packets::PacketView<true> args);
+
+ // 7.4.6
+ void HciReadBdAddr(packets::PacketView<true> args);
+
+ // 7.4.2
+ void HciReadLocalSupportedCommands(packets::PacketView<true> args);
+
+ // 7.4.4
+ void HciReadLocalExtendedFeatures(packets::PacketView<true> args);
+
+ // 7.4.8
+ void HciReadLocalSupportedCodecs(packets::PacketView<true> args);
+
+ // Status Parameters Commands
+ // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.5
+
+ // Test Commands
+ // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.7
+
+ // 7.7.1
+ void HciReadLoopbackMode(packets::PacketView<true> args);
+
+ // 7.7.2
+ void HciWriteLoopbackMode(packets::PacketView<true> args);
+
+ // LE Controller Commands
+ // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8
+
+ // 7.8.1
+ void HciLeSetEventMask(packets::PacketView<true> args);
+
+ // 7.8.2
+ void HciLeReadBufferSize(packets::PacketView<true> args);
+
+ // 7.8.3
+ void HciLeReadLocalSupportedFeatures(packets::PacketView<true> args);
+
+ // 7.8.4
+ void HciLeSetRandomAddress(packets::PacketView<true> args);
+
+ // 7.8.5
+ void HciLeSetAdvertisingParameters(packets::PacketView<true> args);
+
+ // 7.8.7
+ void HciLeSetAdvertisingData(packets::PacketView<true> args);
+
+ // 7.8.10
+ void HciLeSetScanParameters(packets::PacketView<true> args);
+
+ // 7.8.11
+ void HciLeSetScanEnable(packets::PacketView<true> args);
+
+ // 7.8.12
+ void HciLeCreateConnection(packets::PacketView<true> args);
+
+ // 7.8.18
+ void HciLeConnectionUpdate(packets::PacketView<true> args);
+
+ // 7.8.13
+ void HciLeConnectionCancel(packets::PacketView<true> args);
+
+ // 7.8.14
+ void HciLeReadWhiteListSize(packets::PacketView<true> args);
+
+ // 7.8.15
+ void HciLeClearWhiteList(packets::PacketView<true> args);
+
+ // 7.8.16
+ void HciLeAddDeviceToWhiteList(packets::PacketView<true> args);
+
+ // 7.8.17
+ void HciLeRemoveDeviceFromWhiteList(packets::PacketView<true> args);
+
+ // 7.8.21
+ void HciLeReadRemoteFeatures(packets::PacketView<true> args);
+
+ // 7.8.23
+ void HciLeRand(packets::PacketView<true> args);
+
+ // 7.8.24
+ void HciLeStartEncryption(packets::PacketView<true> args);
+
+ // 7.8.27
+ void HciLeReadSupportedStates(packets::PacketView<true> args);
+
+ // Vendor-specific Commands
+
+ void HciLeVendorSleepMode(packets::PacketView<true> args);
+ void HciLeVendorCap(packets::PacketView<true> args);
+ void HciLeVendorMultiAdv(packets::PacketView<true> args);
+ void HciLeVendor155(packets::PacketView<true> args);
+ void HciLeVendor157(packets::PacketView<true> args);
+ void HciLeEnergyInfo(packets::PacketView<true> args);
+ void HciLeAdvertisingFilter(packets::PacketView<true> args);
+ void HciLeExtendedScanParams(packets::PacketView<true> args);
+
+ void SetTimerPeriod(std::chrono::milliseconds new_period);
+ void StartTimer();
+ void StopTimer();
+
+ protected:
+ LinkLayerController link_layer_controller_{properties_};
+
+ private:
+ // Set a timer for a future action
+ void AddControllerEvent(std::chrono::milliseconds, const TaskCallback& callback);
+
+ void AddConnectionAction(const TaskCallback& callback, uint16_t handle);
+
+ // Creates a command complete event and sends it back to the HCI.
+ void SendCommandComplete(hci::OpCode command_opcode, const std::vector<uint8_t>& return_parameters) const;
+
+ // Sends a command complete event with no return parameters.
+ void SendCommandCompleteSuccess(hci::OpCode command_opcode) const;
+
+ void SendCommandCompleteUnknownOpCodeEvent(uint16_t command_opcode) const;
+
+ // Sends a command complete event with no return parameters.
+ void SendCommandCompleteOnlyStatus(hci::OpCode command_opcode, hci::Status status) const;
+
+ void SendCommandCompleteStatusAndAddress(hci::OpCode command_opcode, hci::Status status,
+ const Address& address) const;
+
+ // Creates a command status event and sends it back to the HCI.
+ void SendCommandStatus(hci::Status status, hci::OpCode command_opcode) const;
+
+ // Sends a command status event with default event parameters.
+ void SendCommandStatusSuccess(hci::OpCode command_opcode) const;
+
+ // 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_;
+
+ // Maintains the commands to be registered and used in the HciHandler object.
+ // Keys are command opcodes and values are the callbacks to handle each
+ // command.
+ std::unordered_map<uint16_t, std::function<void(packets::PacketView<true>)>> active_hci_commands_;
+
+ hci::LoopbackMode loopback_mode_;
+
+ SecurityManager security_manager_;
+
+ DualModeController(const DualModeController& cmdPckt) = delete;
+ DualModeController& operator=(const DualModeController& cmdPckt) = delete;
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * 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.
+ */
+
+#define LOG_TAG "link_layer_controller"
+
+#include "link_layer_controller.h"
+
+#include <base/logging.h>
+
+#include "hci.h"
+#include "osi/include/log.h"
+#include "packets/hci/acl_packet_builder.h"
+#include "packets/hci/command_packet_view.h"
+#include "packets/hci/event_packet_builder.h"
+#include "packets/hci/sco_packet_builder.h"
+#include "packets/link_layer/command_builder.h"
+#include "packets/link_layer/command_view.h"
+#include "packets/link_layer/disconnect_view.h"
+#include "packets/link_layer/encrypt_connection_view.h"
+#include "packets/link_layer/inquiry_response_view.h"
+#include "packets/link_layer/inquiry_view.h"
+#include "packets/link_layer/io_capability_view.h"
+#include "packets/link_layer/le_advertisement_view.h"
+#include "packets/link_layer/page_response_view.h"
+#include "packets/link_layer/page_view.h"
+#include "packets/link_layer/response_view.h"
+
+using std::vector;
+using namespace std::chrono;
+using namespace test_vendor_lib::packets;
+
+namespace test_vendor_lib {
+
+// TODO: Model Rssi?
+static uint8_t GetRssi() {
+ static uint8_t rssi = 0;
+ rssi += 5;
+ if (rssi > 128) {
+ rssi = rssi % 7;
+ }
+ return -(rssi);
+}
+
+void LinkLayerController::SendLELinkLayerPacket(std::shared_ptr<LinkLayerPacketBuilder> packet) {
+ if (schedule_task_) {
+ schedule_task_(milliseconds(50), [this, packet]() { send_to_remote_(packet, Phy::Type::LOW_ENERGY); });
+ } else {
+ send_to_remote_(packet, Phy::Type::LOW_ENERGY);
+ }
+}
+
+void LinkLayerController::SendLinkLayerPacket(std::shared_ptr<LinkLayerPacketBuilder> packet) {
+ if (schedule_task_) {
+ schedule_task_(milliseconds(50), [this, packet]() { send_to_remote_(packet, Phy::Type::BR_EDR); });
+ } else {
+ send_to_remote_(packet, Phy::Type::BR_EDR);
+ }
+}
+
+hci::Status LinkLayerController::SendCommandToRemoteByAddress(hci::OpCode opcode, PacketView<true> args,
+ const Address& remote, bool use_public_address) {
+ std::shared_ptr<LinkLayerPacketBuilder> command;
+ Address local_address;
+ if (use_public_address) {
+ local_address = properties_.GetAddress();
+ } else {
+ local_address = properties_.GetLeAddress();
+ }
+ command = LinkLayerPacketBuilder::WrapCommand(CommandBuilder::Create(static_cast<uint16_t>(opcode), args),
+ local_address, remote);
+ SendLinkLayerPacket(std::move(command));
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::SendCommandToRemoteByHandle(hci::OpCode opcode, PacketView<true> args,
+ uint16_t handle) {
+ // TODO: Handle LE connections
+ bool use_public_address = true;
+ if (!classic_connections_.HasHandle(handle)) {
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+ return SendCommandToRemoteByAddress(opcode, args, classic_connections_.GetAddress(handle), use_public_address);
+}
+
+hci::Status LinkLayerController::SendAclToRemote(AclPacketView acl_packet) {
+ // TODO: Handle LE connections
+ uint16_t handle = acl_packet.GetHandle();
+ if (!classic_connections_.HasHandle(handle)) {
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+
+ std::unique_ptr<ViewForwarderBuilder> acl_builder = ViewForwarderBuilder::Create(acl_packet);
+
+ std::shared_ptr<LinkLayerPacketBuilder> acl = LinkLayerPacketBuilder::WrapAcl(
+ std::move(acl_builder), properties_.GetAddress(), classic_connections_.GetAddress(handle));
+
+ LOG_INFO(LOG_TAG, "%s(%s): handle 0x%x size %d", __func__, properties_.GetAddress().ToString().c_str(), handle,
+ static_cast<int>(acl_packet.size()));
+
+ schedule_task_(milliseconds(5), [this, handle]() {
+ send_event_(EventPacketBuilder::CreateNumberOfCompletedPacketsEvent(handle, 1)->ToVector());
+ });
+ SendLinkLayerPacket(acl);
+ return hci::Status::SUCCESS;
+}
+
+void LinkLayerController::IncomingPacket(LinkLayerPacketView incoming) {
+ // TODO: Resolvable private addresses?
+ if (incoming.GetDestinationAddress() != properties_.GetAddress() &&
+ incoming.GetDestinationAddress() != properties_.GetLeAddress() &&
+ incoming.GetDestinationAddress() != Address::kEmpty) {
+ // Drop packets not addressed to me
+ return;
+ }
+
+ switch (incoming.GetType()) {
+ case Link::PacketType::ACL:
+ IncomingAclPacket(incoming);
+ break;
+ case Link::PacketType::COMMAND:
+ IncomingCommandPacket(incoming);
+ break;
+ case Link::PacketType::DISCONNECT:
+ IncomingDisconnectPacket(incoming);
+ break;
+ case Link::PacketType::ENCRYPT_CONNECTION:
+ IncomingEncryptConnection(incoming);
+ break;
+ case Link::PacketType::ENCRYPT_CONNECTION_RESPONSE:
+ IncomingEncryptConnectionResponse(incoming);
+ break;
+ case Link::PacketType::INQUIRY:
+ if (inquiry_scans_enabled_) {
+ IncomingInquiryPacket(incoming);
+ }
+ break;
+ case Link::PacketType::INQUIRY_RESPONSE:
+ IncomingInquiryResponsePacket(incoming);
+ break;
+ case Link::PacketType::IO_CAPABILITY_REQUEST:
+ IncomingIoCapabilityRequestPacket(incoming);
+ break;
+ case Link::PacketType::IO_CAPABILITY_RESPONSE:
+ IncomingIoCapabilityResponsePacket(incoming);
+ break;
+ case Link::PacketType::IO_CAPABILITY_NEGATIVE_RESPONSE:
+ IncomingIoCapabilityNegativeResponsePacket(incoming);
+ break;
+ case Link::PacketType::LE_ADVERTISEMENT:
+ if (le_scan_enable_ || le_connect_) {
+ IncomingLeAdvertisementPacket(incoming);
+ }
+ break;
+ case Link::PacketType::LE_SCAN:
+ // TODO: Check Advertising flags and see if we are scannable.
+ IncomingLeScanPacket(incoming);
+ break;
+ case Link::PacketType::LE_SCAN_RESPONSE:
+ if (le_scan_enable_ && le_scan_type_ == 1) {
+ IncomingLeScanResponsePacket(incoming);
+ }
+ break;
+ case Link::PacketType::PAGE:
+ if (page_scans_enabled_) {
+ IncomingPagePacket(incoming);
+ }
+ break;
+ case Link::PacketType::PAGE_RESPONSE:
+ IncomingPageResponsePacket(incoming);
+ break;
+ case Link::PacketType::RESPONSE:
+ IncomingResponsePacket(incoming);
+ break;
+ default:
+ LOG_WARN(LOG_TAG, "Dropping unhandled packet of type %d", static_cast<int32_t>(incoming.GetType()));
+ }
+}
+
+void LinkLayerController::IncomingAclPacket(LinkLayerPacketView incoming) {
+ LOG_INFO(LOG_TAG, "Acl Packet %s -> %s", incoming.GetSourceAddress().ToString().c_str(),
+ incoming.GetDestinationAddress().ToString().c_str());
+ AclPacketView acl_view = AclPacketView::Create(incoming.GetPayload());
+ LOG_INFO(LOG_TAG, "%s: remote handle 0x%x size %d", __func__, acl_view.GetHandle(),
+ static_cast<int>(acl_view.size()));
+ uint16_t local_handle = classic_connections_.GetHandle(incoming.GetSourceAddress());
+ LOG_INFO(LOG_TAG, "%s: local handle 0x%x", __func__, local_handle);
+
+ acl::PacketBoundaryFlagsType boundary_flags = acl_view.GetPacketBoundaryFlags();
+ acl::BroadcastFlagsType broadcast_flags = acl_view.GetBroadcastFlags();
+ std::unique_ptr<ViewForwarderBuilder> builder = ViewForwarderBuilder::Create(acl_view.GetPayload());
+ std::unique_ptr<AclPacketBuilder> local_acl =
+ AclPacketBuilder::Create(local_handle, boundary_flags, broadcast_flags, std::move(builder));
+ send_acl_(local_acl->ToVector());
+}
+
+void LinkLayerController::IncomingCommandPacket(LinkLayerPacketView incoming) {
+ // TODO: Check the destination address to see if this packet is for me.
+ CommandView command = CommandView::GetCommand(incoming);
+ hci::OpCode opcode = static_cast<hci::OpCode>(command.GetOpcode());
+ auto args = command.GetData();
+ std::vector<uint64_t> response_data;
+
+ switch (opcode) {
+ case (hci::OpCode::REMOTE_NAME_REQUEST): {
+ std::vector<uint8_t> name = properties_.GetName();
+ LOG_INFO(LOG_TAG, "Remote Name (Local Name) %d", static_cast<int>(name.size()));
+ response_data.push_back(static_cast<uint8_t>(hci::Status::SUCCESS));
+ response_data.push_back(name.size());
+ uint64_t word = 0;
+ for (size_t i = 0; i < name.size(); i++) {
+ if (i > 0 && (i % 8 == 0)) {
+ response_data.push_back(word);
+ word = 0;
+ }
+ word |= static_cast<uint64_t>(name[i]) << (8 * (i % 8));
+ }
+ response_data.push_back(word);
+ } break;
+ case (hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES):
+ LOG_INFO(LOG_TAG, "(%s) Remote Supported Features Requested by: %s %x",
+ incoming.GetDestinationAddress().ToString().c_str(), incoming.GetSourceAddress().ToString().c_str(),
+ static_cast<int>(properties_.GetSupportedFeatures()));
+ response_data.push_back(static_cast<uint8_t>(hci::Status::SUCCESS));
+ response_data.push_back(properties_.GetSupportedFeatures());
+ break;
+ case (hci::OpCode::READ_REMOTE_EXTENDED_FEATURES): {
+ uint8_t page_number = (args + 2).extract<uint8_t>(); // skip the handle
+ LOG_INFO(LOG_TAG, "(%s) Remote Extended Features %d Requested by: %s",
+ incoming.GetDestinationAddress().ToString().c_str(), page_number,
+ incoming.GetSourceAddress().ToString().c_str());
+ uint8_t max_page_number = properties_.GetExtendedFeaturesMaximumPageNumber();
+ if (page_number > max_page_number) {
+ response_data.push_back(static_cast<uint8_t>(hci::Status::INVALID_HCI_COMMAND_PARAMETERS));
+ response_data.push_back(page_number);
+ response_data.push_back(max_page_number);
+ response_data.push_back(0);
+ } else {
+ response_data.push_back(static_cast<uint8_t>(hci::Status::SUCCESS));
+ response_data.push_back(page_number);
+ response_data.push_back(max_page_number);
+ response_data.push_back(properties_.GetExtendedFeatures(page_number));
+ }
+ } break;
+ case (hci::OpCode::READ_REMOTE_VERSION_INFORMATION):
+ response_data.push_back(static_cast<uint8_t>(hci::Status::SUCCESS));
+ response_data.push_back(properties_.GetLmpPalVersion());
+ response_data.push_back(properties_.GetManufacturerName());
+ response_data.push_back(properties_.GetLmpPalSubversion());
+ break;
+ case (hci::OpCode::READ_CLOCK_OFFSET):
+ response_data.push_back(static_cast<uint8_t>(hci::Status::SUCCESS));
+ response_data.push_back(properties_.GetClockOffset());
+ break;
+ default:
+ LOG_INFO(LOG_TAG, "Dropping unhandled command 0x%04x", static_cast<uint16_t>(opcode));
+ return;
+ }
+ SendLinkLayerPacket(
+ LinkLayerPacketBuilder::WrapResponse(ResponseBuilder::Create(static_cast<uint16_t>(opcode), response_data),
+ properties_.GetAddress(), incoming.GetSourceAddress()));
+}
+
+void LinkLayerController::IncomingDisconnectPacket(LinkLayerPacketView incoming) {
+ LOG_INFO(LOG_TAG, "Disconnect Packet");
+ DisconnectView disconnect = DisconnectView::GetDisconnect(incoming);
+ Address peer = incoming.GetSourceAddress();
+ uint16_t handle = classic_connections_.GetHandle(peer);
+ if (handle == acl::kReservedHandle) {
+ LOG_INFO(LOG_TAG, "%s: Unknown connection @%s", __func__, peer.ToString().c_str());
+ return;
+ }
+ CHECK(classic_connections_.Disconnect(handle)) << "GetHandle() returned invalid handle " << handle;
+
+ uint8_t reason = disconnect.GetReason();
+ schedule_task_(milliseconds(20), [this, handle, reason]() { DisconnectCleanup(handle, reason); });
+}
+
+void LinkLayerController::IncomingEncryptConnection(LinkLayerPacketView incoming) {
+ LOG_INFO(LOG_TAG, "%s", __func__);
+ // TODO: Check keys
+ Address peer = incoming.GetSourceAddress();
+ uint16_t handle = classic_connections_.GetHandle(peer);
+ if (handle == acl::kReservedHandle) {
+ LOG_INFO(LOG_TAG, "%s: Unknown connection @%s", __func__, peer.ToString().c_str());
+ return;
+ }
+ send_event_(EventPacketBuilder::CreateEncryptionChange(hci::Status::SUCCESS, handle, 1)->ToVector());
+ SendLinkLayerPacket(LinkLayerPacketBuilder::WrapEncryptConnectionResponse(
+ EncryptConnectionBuilder::Create(security_manager_.GetKey(peer)), properties_.GetAddress(), peer));
+}
+
+void LinkLayerController::IncomingEncryptConnectionResponse(LinkLayerPacketView incoming) {
+ LOG_INFO(LOG_TAG, "%s", __func__);
+ // TODO: Check keys
+ uint16_t handle = classic_connections_.GetHandle(incoming.GetSourceAddress());
+ if (handle == acl::kReservedHandle) {
+ LOG_INFO(LOG_TAG, "%s: Unknown connection @%s", __func__, incoming.GetSourceAddress().ToString().c_str());
+ return;
+ }
+ send_event_(EventPacketBuilder::CreateEncryptionChange(hci::Status::SUCCESS, handle, 1)->ToVector());
+}
+
+void LinkLayerController::IncomingInquiryPacket(LinkLayerPacketView incoming) {
+ InquiryView inquiry = InquiryView::GetInquiry(incoming);
+ std::unique_ptr<InquiryResponseBuilder> inquiry_response;
+ switch (inquiry.GetType()) {
+ case (Inquiry::InquiryType::STANDARD):
+ inquiry_response = InquiryResponseBuilder::CreateStandard(
+ properties_.GetPageScanRepetitionMode(), properties_.GetClassOfDevice(), properties_.GetClockOffset());
+ break;
+
+ case (Inquiry::InquiryType::RSSI):
+ inquiry_response =
+ InquiryResponseBuilder::CreateRssi(properties_.GetPageScanRepetitionMode(), properties_.GetClassOfDevice(),
+ properties_.GetClockOffset(), GetRssi());
+ break;
+
+ case (Inquiry::InquiryType::EXTENDED):
+ inquiry_response = InquiryResponseBuilder::CreateExtended(
+ properties_.GetPageScanRepetitionMode(), properties_.GetClassOfDevice(), properties_.GetClockOffset(),
+ GetRssi(), properties_.GetExtendedInquiryData());
+ break;
+ default:
+ LOG_WARN(LOG_TAG, "Unhandled Incoming Inquiry of type %d", static_cast<int>(inquiry.GetType()));
+ return;
+ }
+ SendLinkLayerPacket(LinkLayerPacketBuilder::WrapInquiryResponse(std::move(inquiry_response), properties_.GetAddress(),
+ incoming.GetSourceAddress()));
+ // TODO: Send an Inquriy Response Notification Event 7.7.74
+}
+
+void LinkLayerController::IncomingInquiryResponsePacket(LinkLayerPacketView incoming) {
+ InquiryResponseView inquiry_response = InquiryResponseView::GetInquiryResponse(incoming);
+ std::vector<uint8_t> eir;
+
+ switch (inquiry_response.GetType()) {
+ case (Inquiry::InquiryType::STANDARD): {
+ LOG_WARN(LOG_TAG, "Incoming Standard Inquiry Response");
+ // TODO: Support multiple inquiries in the same packet.
+ std::unique_ptr<EventPacketBuilder> inquiry_result = EventPacketBuilder::CreateInquiryResultEvent();
+ bool result_added =
+ inquiry_result->AddInquiryResult(incoming.GetSourceAddress(), inquiry_response.GetPageScanRepetitionMode(),
+ inquiry_response.GetClassOfDevice(), inquiry_response.GetClockOffset());
+ CHECK(result_added);
+ send_event_(inquiry_result->ToVector());
+ } break;
+
+ case (Inquiry::InquiryType::RSSI):
+ LOG_WARN(LOG_TAG, "Incoming RSSI Inquiry Response");
+ send_event_(EventPacketBuilder::CreateExtendedInquiryResultEvent(
+ incoming.GetSourceAddress(), inquiry_response.GetPageScanRepetitionMode(),
+ inquiry_response.GetClassOfDevice(), inquiry_response.GetClockOffset(), GetRssi(), eir)
+ ->ToVector());
+ break;
+
+ case (Inquiry::InquiryType::EXTENDED): {
+ LOG_WARN(LOG_TAG, "Incoming Extended Inquiry Response");
+ auto eir_itr = inquiry_response.GetExtendedData();
+ size_t eir_bytes = eir_itr.NumBytesRemaining();
+ LOG_WARN(LOG_TAG, "Payload size = %d", static_cast<int>(eir_bytes));
+ for (size_t i = 0; i < eir_bytes; i++) {
+ eir.push_back(eir_itr.extract<uint8_t>());
+ }
+ send_event_(EventPacketBuilder::CreateExtendedInquiryResultEvent(
+ incoming.GetSourceAddress(), inquiry_response.GetPageScanRepetitionMode(),
+ inquiry_response.GetClassOfDevice(), inquiry_response.GetClockOffset(), GetRssi(), eir)
+ ->ToVector());
+ } break;
+ default:
+ LOG_WARN(LOG_TAG, "Unhandled Incoming Inquiry Response of type %d", static_cast<int>(inquiry_response.GetType()));
+ }
+}
+
+void LinkLayerController::IncomingIoCapabilityRequestPacket(LinkLayerPacketView incoming) {
+ LOG_DEBUG(LOG_TAG, "%s", __func__);
+ if (!simple_pairing_mode_enabled_) {
+ LOG_WARN(LOG_TAG, "%s: Only simple pairing mode is implemented", __func__);
+ return;
+ }
+ auto request = IoCapabilityView::GetIoCapability(incoming);
+ Address peer = incoming.GetSourceAddress();
+
+ uint8_t io_capability = request.GetIoCapability();
+ uint8_t oob_data_present = request.GetOobDataPresent();
+ uint8_t authentication_requirements = request.GetAuthenticationRequirements();
+
+ uint16_t handle = classic_connections_.GetHandle(peer);
+ if (handle == acl::kReservedHandle) {
+ LOG_INFO(LOG_TAG, "%s: Device not connected %s", __func__, peer.ToString().c_str());
+ return;
+ }
+
+ security_manager_.AuthenticationRequest(peer, handle);
+
+ security_manager_.SetPeerIoCapability(peer, io_capability, oob_data_present, authentication_requirements);
+
+ send_event_(EventPacketBuilder::CreateIoCapabilityResponseEvent(peer, io_capability, oob_data_present,
+ authentication_requirements)
+ ->ToVector());
+
+ StartSimplePairing(peer);
+}
+
+void LinkLayerController::IncomingIoCapabilityResponsePacket(LinkLayerPacketView incoming) {
+ LOG_DEBUG(LOG_TAG, "%s", __func__);
+ auto response = IoCapabilityView::GetIoCapability(incoming);
+ Address peer = incoming.GetSourceAddress();
+ uint8_t io_capability = response.GetIoCapability();
+ uint8_t oob_data_present = response.GetOobDataPresent();
+ uint8_t authentication_requirements = response.GetAuthenticationRequirements();
+
+ security_manager_.SetPeerIoCapability(peer, io_capability, oob_data_present, authentication_requirements);
+
+ send_event_(EventPacketBuilder::CreateIoCapabilityResponseEvent(peer, io_capability, oob_data_present,
+ authentication_requirements)
+ ->ToVector());
+
+ PairingType pairing_type = security_manager_.GetSimplePairingType();
+ if (pairing_type != PairingType::INVALID) {
+ schedule_task_(milliseconds(5), [this, peer, pairing_type]() { AuthenticateRemoteStage1(peer, pairing_type); });
+ } else {
+ LOG_INFO(LOG_TAG, "%s: Security Manager returned INVALID", __func__);
+ }
+}
+
+void LinkLayerController::IncomingIoCapabilityNegativeResponsePacket(LinkLayerPacketView incoming) {
+ LOG_DEBUG(LOG_TAG, "%s", __func__);
+ Address peer = incoming.GetSourceAddress();
+
+ CHECK(security_manager_.GetAuthenticationAddress() == peer);
+
+ security_manager_.InvalidateIoCapabilities();
+}
+
+void LinkLayerController::IncomingLeAdvertisementPacket(LinkLayerPacketView incoming) {
+ LOG_INFO(LOG_TAG, "LE Advertisement Packet");
+ // TODO: Handle multiple advertisements per packet.
+
+ LeAdvertisementView advertisement = LeAdvertisementView::GetLeAdvertisementView(incoming);
+ LeAdvertisement::AdvertisementType adv_type = advertisement.GetAdvertisementType();
+ LeAdvertisement::AddressType addr_type = advertisement.GetAddressType();
+
+ if (le_scan_enable_) {
+ vector<uint8_t> ad;
+ auto itr = advertisement.GetData();
+ size_t ad_size = itr.NumBytesRemaining();
+ LOG_INFO(LOG_TAG, "Sending advertisement %d", static_cast<int>(ad_size));
+ for (size_t i = 0; i < ad_size; i++) {
+ ad.push_back(itr.extract<uint8_t>());
+ }
+ std::unique_ptr<EventPacketBuilder> le_adverts = EventPacketBuilder::CreateLeAdvertisingReportEvent();
+
+ if (!le_adverts->AddLeAdvertisingReport(adv_type, addr_type, incoming.GetSourceAddress(), ad, GetRssi())) {
+ LOG_INFO(LOG_TAG, "Couldn't add the advertising report.");
+ } else {
+ send_event_(le_adverts->ToVector());
+ }
+ }
+
+#if 0
+ // Connect
+ if (le_connect_ && (adv_type == BTM_BLE_CONNECT_EVT ||
+ adv_type == BTM_BLE_CONNECT_DIR_EVT)) {
+ LOG_INFO(LOG_TAG, "Connecting to device %d", static_cast<int>(dev));
+ if (le_peer_address_ == addr && le_peer_address_type_ == addr_type &&
+ remote_devices_[dev]->LeConnect()) {
+ uint16_t handle = LeGetHandle();
+ send_event_(EventPacketBuilder::CreateLeConnectionCompleteEvent(
+ hci::Status::SUCCESS, handle, HCI_ROLE_MASTER, addr_type, addr, 1,
+ 2, 3)->ToVector());
+
+ // TODO: LeGetConnInterval(), LeGetConnLatency(),
+ // LeGetSupervisionTimeout()));
+ le_connect_ = false;
+
+ std::shared_ptr<Connection> new_connection =
+ std::make_shared<Connection>(remote_devices_[dev], handle);
+ /*
+ connections_.push_back(new_connection);
+
+ remote_devices_[dev]->SetConnection(new_connection);
+ */
+ }
+
+ if (LeWhiteListContainsDevice(addr, addr_type) &&
+ remote_devices_[dev]->LeConnect()) {
+ LOG_INFO(LOG_TAG, "White List Connecting to device %d",
+ static_cast<int>(dev));
+ uint16_t handle = LeGetHandle();
+ send_event_(EventPacketBuilder::CreateLeConnectionCompleteEvent(
+ hci::Status::SUCCESS, handle, HCI_ROLE_MASTER, addr_type, addr, 1,
+ 2, 3)->ToVector());
+ // TODO: LeGetConnInterval(), LeGetConnLatency(),
+ // LeGetSupervisionTimeout()));
+ le_connect_ = false;
+
+ std::shared_ptr<Connection> new_connection =
+ std::make_shared<Connection>(remote_devices_[dev], handle);
+ /*
+ connections_.push_back(new_connection);
+ remote_devices_[dev]->SetConnection(new_connection);
+ */
+ }
+ }
+#endif
+
+ // Active scanning
+ if (le_scan_enable_ && le_scan_type_ == 1) {
+ LOG_INFO(LOG_TAG, "Send Scan Packet");
+ std::shared_ptr<LinkLayerPacketBuilder> to_send =
+ LinkLayerPacketBuilder::WrapLeScan(properties_.GetLeAddress(), incoming.GetSourceAddress());
+ SendLELinkLayerPacket(to_send);
+ }
+}
+
+void LinkLayerController::IncomingLeScanPacket(LinkLayerPacketView incoming) {
+ LOG_INFO(LOG_TAG, "LE Scan Packet");
+ std::unique_ptr<LeAdvertisementBuilder> response = LeAdvertisementBuilder::Create(
+ static_cast<LeAdvertisement::AddressType>(properties_.GetLeAddressType()),
+ static_cast<LeAdvertisement::AdvertisementType>(properties_.GetLeAdvertisementType()),
+ properties_.GetLeScanResponse());
+ std::shared_ptr<LinkLayerPacketBuilder> to_send = LinkLayerPacketBuilder::WrapLeScanResponse(
+ std::move(response), properties_.GetLeAddress(), incoming.GetSourceAddress());
+ SendLELinkLayerPacket(to_send);
+}
+
+void LinkLayerController::IncomingLeScanResponsePacket(LinkLayerPacketView incoming) {
+ LOG_INFO(LOG_TAG, "LE Scan Response Packet");
+ LeAdvertisementView scan_response = LeAdvertisementView::GetLeAdvertisementView(incoming);
+ vector<uint8_t> ad;
+ auto itr = scan_response.GetData();
+ size_t scan_size = itr.NumBytesRemaining();
+ for (size_t i = 0; i < scan_size; i++) {
+ ad.push_back(itr.extract<uint8_t>());
+ }
+
+ std::unique_ptr<EventPacketBuilder> le_adverts = EventPacketBuilder::CreateLeAdvertisingReportEvent();
+
+ if (!le_adverts->AddLeAdvertisingReport(scan_response.GetAdvertisementType(), scan_response.GetAddressType(),
+ incoming.GetSourceAddress(), ad, GetRssi())) {
+ LOG_INFO(LOG_TAG, "Couldn't add the scan response.");
+ } else {
+ LOG_INFO(LOG_TAG, "Sending scan response");
+ send_event_(le_adverts->ToVector());
+ }
+}
+
+void LinkLayerController::IncomingPagePacket(LinkLayerPacketView incoming) {
+ PageView page = PageView::GetPage(incoming);
+ LOG_INFO(LOG_TAG, "%s from %s", __func__, incoming.GetSourceAddress().ToString().c_str());
+
+ if (!classic_connections_.CreatePendingConnection(incoming.GetSourceAddress())) {
+ // Send a response to indicate that we're busy, or drop the packet?
+ LOG_WARN(LOG_TAG, "%s: Failed to create a pending connection", __func__);
+ }
+
+ send_event_(EventPacketBuilder::CreateConnectionRequestEvent(incoming.GetSourceAddress(), page.GetClassOfDevice(),
+ hci::LinkType::ACL)
+ ->ToVector());
+}
+
+void LinkLayerController::IncomingPageResponsePacket(LinkLayerPacketView incoming) {
+ LOG_INFO(LOG_TAG, "%s: %s", __func__, incoming.GetSourceAddress().ToString().c_str());
+ uint16_t handle = classic_connections_.CreateConnection(incoming.GetSourceAddress());
+ if (handle == acl::kReservedHandle) {
+ LOG_WARN(LOG_TAG, "%s: No free handles", __func__);
+ return;
+ }
+ LOG_INFO(LOG_TAG, "%s: Sending CreateConnectionComplete", __func__);
+ send_event_(EventPacketBuilder::CreateConnectionCompleteEvent(hci::Status::SUCCESS, handle,
+ incoming.GetSourceAddress(), hci::LinkType::ACL, false)
+ ->ToVector());
+}
+
+void LinkLayerController::IncomingResponsePacket(LinkLayerPacketView incoming) {
+ ResponseView response = ResponseView::GetResponse(incoming);
+
+ // TODO: Check to see if I'm expecting this response.
+
+ hci::OpCode opcode = static_cast<hci::OpCode>(response.GetOpcode());
+ auto args = response.GetResponseData();
+ hci::Status status = static_cast<hci::Status>(args.extract<uint64_t>());
+
+ uint16_t handle = classic_connections_.GetHandle(incoming.GetSourceAddress());
+
+ switch (opcode) {
+ case (hci::OpCode::REMOTE_NAME_REQUEST): {
+ std::string remote_name = "";
+ size_t length = args.extract<uint64_t>();
+ uint64_t word = 0;
+ for (size_t b = 0; b < length; b++) {
+ size_t byte = b % 8;
+ if (byte == 0) {
+ word = args.extract<uint64_t>();
+ }
+ remote_name += static_cast<uint8_t>(word >> (byte * 8));
+ }
+ send_event_(
+ EventPacketBuilder::CreateRemoteNameRequestCompleteEvent(status, incoming.GetSourceAddress(), remote_name)
+ ->ToVector());
+ } break;
+ case (hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES): {
+ send_event_(
+ EventPacketBuilder::CreateRemoteSupportedFeaturesEvent(status, handle, args.extract<uint64_t>())->ToVector());
+ } break;
+ case (hci::OpCode::READ_REMOTE_EXTENDED_FEATURES): {
+ if (status == hci::Status::SUCCESS) {
+ send_event_(EventPacketBuilder::CreateReadRemoteExtendedFeaturesEvent(
+ status, handle, args.extract<uint64_t>(), args.extract<uint64_t>(), args.extract<uint64_t>())
+ ->ToVector());
+ } else {
+ send_event_(EventPacketBuilder::CreateReadRemoteExtendedFeaturesEvent(status, handle, 0, 0, 0)->ToVector());
+ }
+ } break;
+ case (hci::OpCode::READ_REMOTE_VERSION_INFORMATION): {
+ send_event_(EventPacketBuilder::CreateReadRemoteVersionInformationEvent(
+ status, handle, args.extract<uint64_t>(), args.extract<uint64_t>(), args.extract<uint64_t>())
+ ->ToVector());
+ LOG_INFO(LOG_TAG, "Read remote version handle 0x%04x", handle);
+ } break;
+ case (hci::OpCode::READ_CLOCK_OFFSET): {
+ send_event_(EventPacketBuilder::CreateReadClockOffsetEvent(status, handle, args.extract<uint64_t>())->ToVector());
+ } break;
+ default:
+ LOG_INFO(LOG_TAG, "Unhandled response to command 0x%04x", static_cast<uint16_t>(opcode));
+ }
+}
+
+void LinkLayerController::TimerTick() {
+ if (inquiry_state_ == Inquiry::InquiryState::INQUIRY) Inquiry();
+ if (inquiry_state_ == Inquiry::InquiryState::INQUIRY) PageScan();
+ Connections();
+}
+
+void LinkLayerController::Connections() {
+ // TODO: Keep connections alive?
+}
+
+void LinkLayerController::RegisterEventChannel(
+ const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
+ send_event_ = callback;
+}
+
+void LinkLayerController::RegisterAclChannel(
+ const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
+ send_acl_ = callback;
+}
+
+void LinkLayerController::RegisterScoChannel(
+ const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
+ send_sco_ = callback;
+}
+
+void LinkLayerController::RegisterRemoteChannel(
+ const std::function<void(std::shared_ptr<LinkLayerPacketBuilder>, Phy::Type)>& callback) {
+ send_to_remote_ = callback;
+}
+
+void LinkLayerController::RegisterTaskScheduler(
+ std::function<AsyncTaskId(milliseconds, const TaskCallback&)> event_scheduler) {
+ schedule_task_ = event_scheduler;
+}
+
+void LinkLayerController::RegisterPeriodicTaskScheduler(
+ std::function<AsyncTaskId(milliseconds, milliseconds, const TaskCallback&)> periodic_event_scheduler) {
+ schedule_periodic_task_ = periodic_event_scheduler;
+}
+
+void LinkLayerController::RegisterTaskCancel(std::function<void(AsyncTaskId)> task_cancel) {
+ cancel_task_ = task_cancel;
+}
+
+void LinkLayerController::AddControllerEvent(milliseconds delay, const TaskCallback& task) {
+ controller_events_.push_back(schedule_task_(delay, task));
+}
+
+void LinkLayerController::WriteSimplePairingMode(bool enabled) {
+ CHECK(enabled) << "The spec says don't disable this!";
+ simple_pairing_mode_enabled_ = enabled;
+}
+
+void LinkLayerController::StartSimplePairing(const Address& address) {
+ // IO Capability Exchange (See the Diagram in the Spec)
+ send_event_(EventPacketBuilder::CreateIoCapabilityRequestEvent(address)->ToVector());
+
+ // Get a Key, then authenticate
+ // PublicKeyExchange(address);
+ // AuthenticateRemoteStage1(address);
+ // AuthenticateRemoteStage2(address);
+}
+
+void LinkLayerController::AuthenticateRemoteStage1(const Address& peer, PairingType pairing_type) {
+ CHECK(security_manager_.GetAuthenticationAddress() == peer);
+ // TODO: Public key exchange first?
+ switch (pairing_type) {
+ case PairingType::AUTO_CONFIRMATION:
+ send_event_(EventPacketBuilder::CreateUserConfirmationRequestEvent(peer, 123456)->ToVector());
+ break;
+ case PairingType::CONFIRM_Y_N:
+ CHECK(false) << __func__ << "Unimplemented PairingType" << static_cast<int>(pairing_type);
+ break;
+ case PairingType::DISPLAY_PIN:
+ CHECK(false) << __func__ << "Unimplemented PairingType" << static_cast<int>(pairing_type);
+ break;
+ case PairingType::DISPLAY_AND_CONFIRM:
+ CHECK(false) << __func__ << "Unimplemented PairingType" << static_cast<int>(pairing_type);
+ break;
+ case PairingType::INPUT_PIN:
+ CHECK(false) << __func__ << "Unimplemented PairingType" << static_cast<int>(pairing_type);
+ break;
+ case PairingType::INVALID:
+ CHECK(false) << __func__ << "Unimplemented PairingType" << static_cast<int>(pairing_type);
+ break;
+ default:
+ CHECK(false) << __func__ << ": Invalid PairingType " << static_cast<int>(pairing_type);
+ }
+}
+
+void LinkLayerController::AuthenticateRemoteStage2(const Address& peer) {
+ uint16_t handle = security_manager_.GetAuthenticationHandle();
+ CHECK(security_manager_.GetAuthenticationAddress() == peer);
+ // Check key in security_manager_ ?
+ send_event_(EventPacketBuilder::CreateAuthenticationCompleteEvent(hci::Status::SUCCESS, handle)->ToVector());
+}
+
+hci::Status LinkLayerController::LinkKeyRequestReply(const Address& peer, PacketView<true> key) {
+ std::vector<uint8_t> key_vec(key.begin(), key.end());
+ security_manager_.WriteKey(peer, key_vec);
+ security_manager_.AuthenticationRequestFinished();
+
+ schedule_task_(milliseconds(5), [this, peer]() { AuthenticateRemoteStage2(peer); });
+
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::LinkKeyRequestNegativeReply(const Address& address) {
+ security_manager_.DeleteKey(address);
+ // Simple pairing to get a key
+ uint16_t handle = classic_connections_.GetHandle(address);
+ if (handle == acl::kReservedHandle) {
+ LOG_INFO(LOG_TAG, "%s: Device not connected %s", __func__, address.ToString().c_str());
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+
+ security_manager_.AuthenticationRequest(address, handle);
+
+ schedule_task_(milliseconds(5), [this, address]() { StartSimplePairing(address); });
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::IoCapabilityRequestReply(const Address& peer, uint8_t io_capability,
+ uint8_t oob_data_present_flag,
+ uint8_t authentication_requirements) {
+ security_manager_.SetLocalIoCapability(peer, io_capability, oob_data_present_flag, authentication_requirements);
+
+ PairingType pairing_type = security_manager_.GetSimplePairingType();
+ if (pairing_type != PairingType::INVALID) {
+ schedule_task_(milliseconds(5), [this, peer, pairing_type]() { AuthenticateRemoteStage1(peer, pairing_type); });
+ SendLinkLayerPacket(LinkLayerPacketBuilder::WrapIoCapabilityResponse(
+ IoCapabilityBuilder::Create(io_capability, oob_data_present_flag, authentication_requirements),
+ properties_.GetAddress(), peer));
+ } else {
+ LOG_INFO(LOG_TAG, "%s: Requesting remote capability", __func__);
+ SendLinkLayerPacket(LinkLayerPacketBuilder::WrapIoCapabilityRequest(
+ IoCapabilityBuilder::Create(io_capability, oob_data_present_flag, authentication_requirements),
+ properties_.GetAddress(), peer));
+ }
+
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::IoCapabilityRequestNegativeReply(const Address& peer, hci::Status reason) {
+ if (security_manager_.GetAuthenticationAddress() != peer) {
+ return hci::Status::AUTHENTICATION_FAILURE;
+ }
+
+ security_manager_.InvalidateIoCapabilities();
+
+ SendLinkLayerPacket(LinkLayerPacketBuilder::WrapIoCapabilityNegativeResponse(
+ IoCapabilityNegativeResponseBuilder::Create(static_cast<uint8_t>(reason)), properties_.GetAddress(), peer));
+
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::UserConfirmationRequestReply(const Address& peer) {
+ if (security_manager_.GetAuthenticationAddress() != peer) {
+ return hci::Status::AUTHENTICATION_FAILURE;
+ }
+ // TODO: Key could be calculated here.
+ std::vector<uint8_t> key_vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+ security_manager_.WriteKey(peer, key_vec);
+
+ security_manager_.AuthenticationRequestFinished();
+
+ schedule_task_(milliseconds(5), [this, peer]() { AuthenticateRemoteStage2(peer); });
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::UserConfirmationRequestNegativeReply(const Address& peer) {
+ if (security_manager_.GetAuthenticationAddress() != peer) {
+ return hci::Status::AUTHENTICATION_FAILURE;
+ }
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::UserPasskeyRequestReply(const Address& peer, uint32_t numeric_value) {
+ if (security_manager_.GetAuthenticationAddress() != peer) {
+ return hci::Status::AUTHENTICATION_FAILURE;
+ }
+ LOG_INFO(LOG_TAG, "TODO:Do something with the passkey %06d", numeric_value);
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::UserPasskeyRequestNegativeReply(const Address& peer) {
+ if (security_manager_.GetAuthenticationAddress() != peer) {
+ return hci::Status::AUTHENTICATION_FAILURE;
+ }
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::RemoteOobDataRequestReply(const Address& peer, const std::vector<uint8_t>& c,
+ const std::vector<uint8_t>& r) {
+ if (security_manager_.GetAuthenticationAddress() != peer) {
+ return hci::Status::AUTHENTICATION_FAILURE;
+ }
+ LOG_INFO(LOG_TAG, "TODO:Do something with the OOB data c=%d r=%d", c[0], r[0]);
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::RemoteOobDataRequestNegativeReply(const Address& peer) {
+ if (security_manager_.GetAuthenticationAddress() != peer) {
+ return hci::Status::AUTHENTICATION_FAILURE;
+ }
+ return hci::Status::SUCCESS;
+}
+
+void LinkLayerController::HandleAuthenticationRequest(const Address& address, uint16_t handle) {
+ if (simple_pairing_mode_enabled_ == true) {
+ security_manager_.AuthenticationRequest(address, handle);
+ send_event_(EventPacketBuilder::CreateLinkKeyRequestEvent(address)->ToVector());
+ } else { // Should never happen for our phones
+ // Check for a key, try to authenticate, ask for a PIN.
+ send_event_(
+ EventPacketBuilder::CreateAuthenticationCompleteEvent(hci::Status::AUTHENTICATION_FAILURE, handle)->ToVector());
+ }
+}
+
+hci::Status LinkLayerController::AuthenticationRequested(uint16_t handle) {
+ if (!classic_connections_.HasHandle(handle)) {
+ LOG_INFO(LOG_TAG, "Authentication Requested for unknown handle %04x", handle);
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+
+ Address remote = classic_connections_.GetAddress(handle);
+
+ schedule_task_(milliseconds(5), [this, remote, handle]() { HandleAuthenticationRequest(remote, handle); });
+
+ return hci::Status::SUCCESS;
+}
+
+void LinkLayerController::HandleSetConnectionEncryption(const Address& peer, uint16_t handle,
+ uint8_t encryption_enable) {
+ // TODO: Block ACL traffic or at least guard against it
+
+ if (classic_connections_.IsEncrypted(handle) && encryption_enable) {
+ send_event_(
+ EventPacketBuilder::CreateEncryptionChange(hci::Status::SUCCESS, handle, encryption_enable)->ToVector());
+ return;
+ }
+
+ SendLinkLayerPacket(LinkLayerPacketBuilder::WrapEncryptConnection(
+ EncryptConnectionBuilder::Create(security_manager_.GetKey(peer)), properties_.GetAddress(), peer));
+}
+
+hci::Status LinkLayerController::SetConnectionEncryption(uint16_t handle, uint8_t encryption_enable) {
+ if (!classic_connections_.HasHandle(handle)) {
+ LOG_INFO(LOG_TAG, "Authentication Requested for unknown handle %04x", handle);
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+
+ if (classic_connections_.IsEncrypted(handle) && !encryption_enable) {
+ return hci::Status::ENCRYPTION_MODE_NOT_ACCEPTABLE;
+ }
+ Address remote = classic_connections_.GetAddress(handle);
+
+ schedule_task_(milliseconds(5), [this, remote, handle, encryption_enable]() {
+ HandleSetConnectionEncryption(remote, handle, encryption_enable);
+ });
+
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::AcceptConnectionRequest(const Address& addr, bool try_role_switch) {
+ if (!classic_connections_.HasPendingConnection(addr)) {
+ LOG_INFO(LOG_TAG, "%s: No pending connection", __func__);
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+
+ LOG_INFO(LOG_TAG, "%s: Accept in 200ms", __func__);
+ schedule_task_(milliseconds(200), [this, addr, try_role_switch]() {
+ LOG_INFO(LOG_TAG, "%s: Accepted", __func__);
+ MakeSlaveConnection(addr, try_role_switch);
+ });
+
+ return hci::Status::SUCCESS;
+}
+
+void LinkLayerController::MakeSlaveConnection(const Address& addr, bool try_role_switch) {
+ std::shared_ptr<LinkLayerPacketBuilder> to_send = LinkLayerPacketBuilder::WrapPageResponse(
+ PageResponseBuilder::Create(try_role_switch), properties_.GetAddress(), addr);
+ LOG_INFO(LOG_TAG, "%s sending page response to %s", __func__, addr.ToString().c_str());
+ SendLinkLayerPacket(to_send);
+
+ uint16_t handle = classic_connections_.CreateConnection(addr);
+ if (handle == acl::kReservedHandle) {
+ LOG_INFO(LOG_TAG, "%s CreateConnection failed", __func__);
+ return;
+ }
+ LOG_INFO(LOG_TAG, "%s CreateConnection returned handle 0x%x", __func__, handle);
+ send_event_(
+ EventPacketBuilder::CreateConnectionCompleteEvent(hci::Status::SUCCESS, handle, addr, hci::LinkType::ACL, false)
+ ->ToVector());
+}
+
+hci::Status LinkLayerController::RejectConnectionRequest(const Address& addr, uint8_t reason) {
+ if (!classic_connections_.HasPendingConnection(addr)) {
+ LOG_INFO(LOG_TAG, "%s: No pending connection", __func__);
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+
+ LOG_INFO(LOG_TAG, "%s: Reject in 200ms", __func__);
+ schedule_task_(milliseconds(200), [this, addr, reason]() {
+ LOG_INFO(LOG_TAG, "%s: Reject", __func__);
+ RejectSlaveConnection(addr, reason);
+ });
+
+ return hci::Status::SUCCESS;
+}
+
+void LinkLayerController::RejectSlaveConnection(const Address& addr, uint8_t reason) {
+ CHECK(reason > 0x0f || reason < 0x0d);
+ send_event_(EventPacketBuilder::CreateConnectionCompleteEvent(static_cast<hci::Status>(reason), 0xeff, addr,
+ hci::LinkType::ACL, false)
+ ->ToVector());
+}
+
+hci::Status LinkLayerController::CreateConnection(const Address& addr, uint16_t, uint8_t, uint16_t,
+ uint8_t allow_role_switch) {
+ if (!classic_connections_.CreatePendingConnection(addr)) {
+ return hci::Status::CONTROLLER_BUSY;
+ }
+
+ std::unique_ptr<PageBuilder> page = PageBuilder::Create(properties_.GetClassOfDevice(), allow_role_switch);
+ SendLinkLayerPacket(LinkLayerPacketBuilder::WrapPage(std::move(page), properties_.GetAddress(), addr));
+
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::CreateConnectionCancel(const Address& addr) {
+ if (!classic_connections_.CancelPendingConnection(addr)) {
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::Disconnect(uint16_t handle, uint8_t reason) {
+ // TODO: Handle LE
+ if (!classic_connections_.HasHandle(handle)) {
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+
+ const Address& remote = classic_connections_.GetAddress(handle);
+ std::shared_ptr<LinkLayerPacketBuilder> to_send =
+ LinkLayerPacketBuilder::WrapDisconnect(DisconnectBuilder::Create(reason), properties_.GetAddress(), remote);
+ SendLinkLayerPacket(to_send);
+ CHECK(classic_connections_.Disconnect(handle)) << "Disconnecting " << handle;
+
+ schedule_task_(milliseconds(20), [this, handle]() {
+ DisconnectCleanup(handle, static_cast<uint8_t>(hci::Status::CONNECTION_TERMINATED_BY_LOCAL_HOST));
+ });
+
+ return hci::Status::SUCCESS;
+}
+
+void LinkLayerController::DisconnectCleanup(uint16_t handle, uint8_t reason) {
+ // TODO: Clean up other connection state.
+ send_event_(EventPacketBuilder::CreateDisconnectionCompleteEvent(hci::Status::SUCCESS, handle, reason)->ToVector());
+}
+
+hci::Status LinkLayerController::ChangeConnectionPacketType(uint16_t handle, uint16_t types) {
+ if (!classic_connections_.HasHandle(handle)) {
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+ std::unique_ptr<EventPacketBuilder> packet =
+ EventPacketBuilder::CreateConnectionPacketTypeChangedEvent(hci::Status::SUCCESS, handle, types);
+ std::shared_ptr<std::vector<uint8_t>> raw_packet = packet->ToVector();
+ if (schedule_task_) {
+ schedule_task_(milliseconds(20), [this, raw_packet]() { send_event_(raw_packet); });
+ } else {
+ send_event_(raw_packet);
+ }
+
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::WriteLinkPolicySettings(uint16_t handle, uint16_t) {
+ if (!classic_connections_.HasHandle(handle)) {
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+ return hci::Status::SUCCESS;
+}
+
+hci::Status LinkLayerController::WriteLinkSupervisionTimeout(uint16_t handle, uint16_t) {
+ if (!classic_connections_.HasHandle(handle)) {
+ return hci::Status::UNKNOWN_CONNECTION;
+ }
+ return hci::Status::SUCCESS;
+}
+
+void LinkLayerController::LeWhiteListClear() {
+ le_white_list_.clear();
+}
+
+void LinkLayerController::LeWhiteListAddDevice(Address addr, uint8_t addr_type) {
+ std::tuple<Address, uint8_t> new_tuple = std::make_tuple(addr, addr_type);
+ for (auto dev : le_white_list_) {
+ if (dev == new_tuple) {
+ return;
+ }
+ }
+ le_white_list_.emplace_back(new_tuple);
+}
+
+void LinkLayerController::LeWhiteListRemoveDevice(Address addr, uint8_t addr_type) {
+ // TODO: Add checks to see if advertising, scanning, or a connection request
+ // with the white list is ongoing.
+ std::tuple<Address, uint8_t> erase_tuple = std::make_tuple(addr, addr_type);
+ for (size_t i = 0; i < le_white_list_.size(); i++) {
+ if (le_white_list_[i] == erase_tuple) {
+ le_white_list_.erase(le_white_list_.begin() + i);
+ }
+ }
+}
+
+bool LinkLayerController::LeWhiteListContainsDevice(Address addr, uint8_t addr_type) {
+ std::tuple<Address, uint8_t> sought_tuple = std::make_tuple(addr, addr_type);
+ for (size_t i = 0; i < le_white_list_.size(); i++) {
+ if (le_white_list_[i] == sought_tuple) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LinkLayerController::LeWhiteListFull() {
+ return le_white_list_.size() >= properties_.GetLeWhiteListSize();
+}
+
+void LinkLayerController::Reset() {
+ inquiry_state_ = Inquiry::InquiryState::STANDBY;
+ last_inquiry_ = steady_clock::now();
+ le_scan_enable_ = 0;
+ le_connect_ = 0;
+}
+
+void LinkLayerController::PageScan() {}
+
+void LinkLayerController::StartInquiry(milliseconds timeout) {
+ schedule_task_(milliseconds(timeout), [this]() { LinkLayerController::InquiryTimeout(); });
+ inquiry_state_ = Inquiry::InquiryState::INQUIRY;
+ LOG_INFO(LOG_TAG, "InquiryState = %d ", static_cast<int>(inquiry_state_));
+}
+
+void LinkLayerController::InquiryCancel() {
+ CHECK(inquiry_state_ == Inquiry::InquiryState::INQUIRY);
+ inquiry_state_ = Inquiry::InquiryState::STANDBY;
+}
+
+void LinkLayerController::InquiryTimeout() {
+ if (inquiry_state_ == Inquiry::InquiryState::INQUIRY) {
+ inquiry_state_ = Inquiry::InquiryState::STANDBY;
+ send_event_(EventPacketBuilder::CreateInquiryCompleteEvent(hci::Status::SUCCESS)->ToVector());
+ }
+}
+
+void LinkLayerController::SetInquiryMode(uint8_t mode) {
+ inquiry_mode_ = static_cast<Inquiry::InquiryType>(mode);
+}
+
+void LinkLayerController::SetInquiryLAP(uint64_t lap) {
+ inquiry_lap_ = lap;
+}
+
+void LinkLayerController::SetInquiryMaxResponses(uint8_t max) {
+ inquiry_max_responses_ = max;
+}
+
+void LinkLayerController::Inquiry() {
+ steady_clock::time_point now = steady_clock::now();
+ if (duration_cast<milliseconds>(now - last_inquiry_) < milliseconds(2000)) {
+ return;
+ }
+ LOG_INFO(LOG_TAG, "Inquiry ");
+ std::unique_ptr<InquiryBuilder> inquiry = InquiryBuilder::Create(inquiry_mode_);
+ std::shared_ptr<LinkLayerPacketBuilder> to_send =
+ LinkLayerPacketBuilder::WrapInquiry(std::move(inquiry), properties_.GetAddress());
+ SendLinkLayerPacket(to_send);
+ last_inquiry_ = now;
+}
+
+void LinkLayerController::SetInquiryScanEnable(bool enable) {
+ inquiry_scans_enabled_ = enable;
+}
+
+void LinkLayerController::SetPageScanEnable(bool enable) {
+ page_scans_enabled_ = enable;
+}
+
+/* TODO: Connection handling
+ // TODO: Handle in the link manager.
+ uint16_t handle = LeGetHandle();
+
+ std::shared_ptr<Connection> new_connection =
+ std::make_shared<Connection>(peer, handle);
+ connections_.push_back(new_connection);
+ peer->SetConnection(new_connection);
+
+ send_event_(EventPacketBuilder::CreateLeEnhancedConnectionCompleteEvent(
+ hci::Status::SUCCESS, handle, 0x00, // role
+ le_peer_address_type_, le_peer_address_, Address::kEmpty,
+ Address::kEmpty, 0x0024, 0x0000, 0x01f4)->ToVector());
+*/
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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.
+ */
+
+#define LOG_TAG "security_manager"
+
+#include "security_manager.h"
+
+#include "base/logging.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+uint16_t SecurityManager::DeleteAllKeys() {
+ uint16_t size = key_store_.size();
+ key_store_.clear();
+ return size;
+}
+
+uint16_t SecurityManager::DeleteKey(const Address& addr) {
+ uint16_t count = key_store_.count(addr.ToString());
+ if (count) {
+ key_store_.erase(addr.ToString());
+ }
+ return count;
+}
+
+uint16_t SecurityManager::ReadAllKeys() const {
+ return key_store_.size();
+}
+
+uint16_t SecurityManager::ReadKey(const Address& addr) const {
+ return key_store_.count(addr.ToString());
+}
+
+uint16_t SecurityManager::WriteKey(const Address& addr, const std::vector<uint8_t>& key) {
+ if (key_store_.size() >= max_keys_) {
+ return 0;
+ }
+ key_store_[addr.ToString()] = key;
+ return 1;
+}
+
+const std::vector<uint8_t>& SecurityManager::GetKey(const Address& addr) const {
+ CHECK(ReadKey(addr)) << "No such key";
+ return key_store_.at(addr.ToString());
+}
+
+void SecurityManager::AuthenticationRequest(const Address& addr, uint16_t handle) {
+ authenticating_ = true;
+ current_handle_ = handle;
+ peer_address_ = addr;
+}
+
+void SecurityManager::AuthenticationRequestFinished() {
+ authenticating_ = false;
+}
+
+bool SecurityManager::AuthenticationInProgress() {
+ return authenticating_;
+}
+
+uint16_t SecurityManager::GetAuthenticationHandle() {
+ return current_handle_;
+}
+
+Address SecurityManager::GetAuthenticationAddress() {
+ return peer_address_;
+}
+
+void SecurityManager::SetPeerIoCapability(const Address& addr, uint8_t io_capability, uint8_t oob_present_flag,
+ uint8_t authentication_requirements) {
+ CHECK_EQ(addr, peer_address_);
+ peer_capabilities_valid_ = true;
+ if (io_capability <= static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT)) {
+ peer_io_capability_ = static_cast<IoCapabilityType>(io_capability);
+ } else {
+ peer_io_capability_ = IoCapabilityType::INVALID;
+ peer_capabilities_valid_ = false;
+ }
+ peer_oob_present_flag_ = (oob_present_flag == 1);
+ if (authentication_requirements <= static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM)) {
+ peer_authentication_requirements_ = static_cast<AuthenticationType>(authentication_requirements);
+ } else {
+ peer_authentication_requirements_ = AuthenticationType::INVALID;
+ peer_capabilities_valid_ = false;
+ }
+}
+
+void SecurityManager::SetLocalIoCapability(const Address& peer, uint8_t io_capability, uint8_t oob_present_flag,
+ uint8_t authentication_requirements) {
+ CHECK_EQ(peer, peer_address_);
+ CHECK(io_capability <= static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT))
+ << "io_capability = " << io_capability;
+ CHECK(oob_present_flag <= 1) << "oob_present_flag = " << oob_present_flag;
+ CHECK(authentication_requirements <= static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM))
+ << "authentication_requirements = " << authentication_requirements;
+ host_io_capability_ = static_cast<IoCapabilityType>(io_capability);
+ host_oob_present_flag_ = (oob_present_flag == 1);
+ host_authentication_requirements_ = static_cast<AuthenticationType>(authentication_requirements);
+ host_capabilities_valid_ = true;
+}
+
+void SecurityManager::InvalidateIoCapabilities() {
+ host_capabilities_valid_ = false;
+ peer_capabilities_valid_ = false;
+}
+
+PairingType SecurityManager::GetSimplePairingType() {
+ if (!host_capabilities_valid_ || !peer_capabilities_valid_) {
+ return PairingType::INVALID;
+ }
+ bool host_requires_mitm = (host_authentication_requirements_ == AuthenticationType::NO_BONDING_MITM) ||
+ (host_authentication_requirements_ == AuthenticationType::DEDICATED_BONDING_MITM) ||
+ (host_authentication_requirements_ == AuthenticationType::GENERAL_BONDING_MITM);
+ bool peer_requires_mitm = (peer_authentication_requirements_ == AuthenticationType::NO_BONDING_MITM) ||
+ (peer_authentication_requirements_ == AuthenticationType::DEDICATED_BONDING_MITM) ||
+ (peer_authentication_requirements_ == AuthenticationType::GENERAL_BONDING_MITM);
+ if (!(peer_requires_mitm || host_requires_mitm)) {
+ return PairingType::AUTO_CONFIRMATION;
+ }
+ return PairingType::INVALID;
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * 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 <cstdint>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "types/address.h"
+
+namespace test_vendor_lib {
+
+enum class PairingType : uint8_t {
+ AUTO_CONFIRMATION,
+ CONFIRM_Y_N,
+ DISPLAY_PIN,
+ DISPLAY_AND_CONFIRM,
+ INPUT_PIN,
+ INVALID = 0xff,
+};
+
+enum class IoCapabilityType : uint8_t {
+ DISPLAY_ONLY = 0,
+ DISPLAY_YES_NO = 1,
+ KEYBOARD_ONLY = 2,
+ NO_INPUT_NO_OUTPUT = 3,
+ INVALID = 0xff,
+};
+
+enum class AuthenticationType : uint8_t {
+ NO_BONDING = 0,
+ NO_BONDING_MITM = 1,
+ DEDICATED_BONDING = 2,
+ DEDICATED_BONDING_MITM = 3,
+ GENERAL_BONDING = 4,
+ GENERAL_BONDING_MITM = 5,
+ INVALID = 0xff,
+};
+
+// Encapsulate the details of storing and retrieving keys.
+class SecurityManager {
+ public:
+ SecurityManager(uint16_t num_keys) : max_keys_(num_keys) {}
+ virtual ~SecurityManager() = default;
+
+ uint16_t DeleteAllKeys();
+ uint16_t DeleteKey(const Address& addr);
+ uint16_t ReadAllKeys() const;
+ uint16_t ReadKey(const Address& addr) const;
+ uint16_t WriteKey(const Address& addr, const std::vector<uint8_t>& key);
+ uint16_t ReadCapacity() const {
+ return max_keys_;
+ };
+
+ const std::vector<uint8_t>& GetKey(const Address& addr) const;
+
+ void AuthenticationRequest(const Address& addr, uint16_t handle);
+ void AuthenticationRequestFinished();
+
+ bool AuthenticationInProgress();
+ uint16_t GetAuthenticationHandle();
+ Address GetAuthenticationAddress();
+
+ void SetPeerIoCapability(const Address& addr, uint8_t io_capability, uint8_t oob_present_flag,
+ uint8_t authentication_requirements);
+ void SetLocalIoCapability(const Address& peer, uint8_t io_capability, uint8_t oob_present_flag,
+ uint8_t authentication_requirements);
+
+ PairingType GetSimplePairingType();
+
+ void InvalidateIoCapabilities();
+
+ private:
+ uint16_t max_keys_;
+ std::unordered_map<std::string, std::vector<uint8_t>> key_store_;
+
+ bool peer_capabilities_valid_{false};
+ IoCapabilityType peer_io_capability_;
+ bool peer_oob_present_flag_;
+ AuthenticationType peer_authentication_requirements_;
+
+ bool host_capabilities_valid_{false};
+ IoCapabilityType host_io_capability_;
+ bool host_oob_present_flag_;
+ AuthenticationType host_authentication_requirements_;
+
+ bool authenticating_{false};
+ uint16_t current_handle_;
+ Address peer_address_;
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2016 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 "beacon"
+
+#include "beacon.h"
+
+#include "le_advertisement.h"
+#include "model/setup/device_boutique.h"
+#include "osi/include/log.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+bool Beacon::registered_ = DeviceBoutique::Register(LOG_TAG, &Beacon::Create);
+
+Beacon::Beacon() {
+ advertising_interval_ms_ = std::chrono::milliseconds(1280);
+ properties_.SetLeAdvertisementType(BTM_BLE_NON_CONNECT_EVT);
+ properties_.SetLeAdvertisement({0x0F, // Length
+ BTM_BLE_AD_TYPE_NAME_CMPL, 'g', 'D', 'e', 'v', 'i', 'c', 'e', '-', 'b', 'e', 'a', 'c',
+ 'o', 'n',
+ 0x02, // Length
+ BTM_BLE_AD_TYPE_FLAG, BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG});
+
+ properties_.SetLeScanResponse({0x05, // Length
+ BTM_BLE_AD_TYPE_NAME_SHORT, 'b', 'e', 'a', 'c'});
+}
+
+std::string Beacon::GetTypeString() const {
+ return "beacon";
+}
+
+std::string Beacon::ToString() const {
+ std::string dev = GetTypeString() + "@" + properties_.GetLeAddress().ToString();
+
+ return dev;
+}
+
+void Beacon::Initialize(const vector<std::string>& args) {
+ if (args.size() < 2) return;
+
+ Address addr;
+ if (Address::FromString(args[1], addr)) properties_.SetLeAddress(addr);
+
+ if (args.size() < 3) return;
+
+ SetAdvertisementInterval(std::chrono::milliseconds(std::stoi(args[2])));
+}
+
+void Beacon::TimerTick() {
+ LOG_INFO(LOG_TAG, "TimerTick()");
+ if (IsAdvertisementAvailable(std::chrono::milliseconds(5000))) {
+ LOG_INFO(LOG_TAG, "Generating Advertisement %d", static_cast<int>(properties_.GetLeAdvertisement().size()));
+ std::unique_ptr<packets::LeAdvertisementBuilder> ad = packets::LeAdvertisementBuilder::Create(
+ LeAdvertisement::AddressType::PUBLIC,
+ static_cast<LeAdvertisement::AdvertisementType>(properties_.GetLeAdvertisementType()),
+ properties_.GetLeAdvertisement());
+ std::shared_ptr<packets::LinkLayerPacketBuilder> to_send =
+ packets::LinkLayerPacketBuilder::WrapLeAdvertisement(std::move(ad), properties_.GetLeAddress());
+ std::vector<std::shared_ptr<PhyLayer>> le_phys = phy_layers_[Phy::Type::LOW_ENERGY];
+ for (std::shared_ptr<PhyLayer> phy : le_phys) {
+ LOG_INFO(LOG_TAG, "Sending Advertisement on a Phy");
+ phy->Send(to_send);
+ }
+ }
+}
+
+void Beacon::IncomingPacket(packets::LinkLayerPacketView packet) {
+ LOG_INFO(LOG_TAG, "Got a packet of type %d", static_cast<int>(packet.GetType()));
+ if (packet.GetDestinationAddress() == properties_.GetLeAddress() && packet.GetType() == Link::PacketType::LE_SCAN) {
+ LOG_INFO(LOG_TAG, "Got a scan");
+ std::unique_ptr<packets::LeAdvertisementBuilder> scan_response = packets::LeAdvertisementBuilder::Create(
+ LeAdvertisement::AddressType::PUBLIC, LeAdvertisement::AdvertisementType::SCAN_RESPONSE,
+ properties_.GetLeScanResponse());
+ std::shared_ptr<packets::LinkLayerPacketBuilder> to_send = packets::LinkLayerPacketBuilder::WrapLeScanResponse(
+ std::move(scan_response), properties_.GetLeAddress(), packet.GetSourceAddress());
+ std::vector<std::shared_ptr<PhyLayer>> le_phys = phy_layers_[Phy::Type::LOW_ENERGY];
+ for (auto phy : le_phys) {
+ LOG_INFO(LOG_TAG, "Sending a Scan Response on a Phy");
+ phy->Send(to_send);
+ }
+ }
+}
+
+} // namespace test_vendor_lib
#include <cstdint>
#include <vector>
-#include "bt_address.h"
#include "device.h"
#include "stack/include/btm_ble_api.h"
Beacon();
virtual ~Beacon() = default;
+ static std::shared_ptr<Device> Create() {
+ return std::make_shared<Beacon>();
+ }
+
// Return a string representation of the type of device.
- virtual std::string GetTypeString() const override { return "beacon"; }
+ virtual std::string GetTypeString() const override;
+
+ // Return a string representation of the device.
+ virtual std::string ToString() const override;
// Set the address and advertising interval from string args.
virtual void Initialize(const std::vector<std::string>& args) override;
+
+ virtual void IncomingPacket(packets::LinkLayerPacketView packet) override;
+
+ virtual void TimerTick() override;
+
+ private:
+ static bool registered_;
};
} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2016 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 "beacon_swarm"
+
+#include "beacon_swarm.h"
+
+#include "model/setup/device_boutique.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+bool BeaconSwarm::registered_ = DeviceBoutique::Register(LOG_TAG, &BeaconSwarm::Create);
+
+BeaconSwarm::BeaconSwarm() {
+ advertising_interval_ms_ = std::chrono::milliseconds(1280);
+ properties_.SetLeAdvertisementType(BTM_BLE_NON_CONNECT_EVT);
+ properties_.SetLeAdvertisement({
+ 0x15, // Length
+ BTM_BLE_AD_TYPE_NAME_CMPL,
+ 'g',
+ 'D',
+ 'e',
+ 'v',
+ 'i',
+ 'c',
+ 'e',
+ '-',
+ 'b',
+ 'e',
+ 'a',
+ 'c',
+ 'o',
+ 'n',
+ '_',
+ 's',
+ 'w',
+ 'a',
+ 'r',
+ 'm',
+ 0x02, // Length
+ BTM_BLE_AD_TYPE_FLAG,
+ BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG,
+ });
+
+ properties_.SetLeScanResponse({0x06, // Length
+ BTM_BLE_AD_TYPE_NAME_SHORT, 'c', 'b', 'e', 'a', 'c'});
+}
+
+void BeaconSwarm::Initialize(const vector<std::string>& args) {
+ if (args.size() < 2) return;
+
+ Address addr;
+ if (Address::FromString(args[1], addr)) properties_.SetLeAddress(addr);
+
+ if (args.size() < 3) return;
+
+ SetAdvertisementInterval(std::chrono::milliseconds(std::stoi(args[2])));
+}
+
+void BeaconSwarm::TimerTick() {
+ Address beacon_addr = properties_.GetLeAddress();
+ uint8_t* low_order_byte = (uint8_t*)(&beacon_addr);
+ *low_order_byte += 1;
+ properties_.SetLeAddress(beacon_addr);
+ Beacon::TimerTick();
+}
+
+} // namespace test_vendor_lib
#include <cstdint>
#include <vector>
-#include "bt_address.h"
-#include "device.h"
-#include "stack/include/btm_ble_api.h"
+#include "beacon.h"
namespace test_vendor_lib {
// Pretend to be a lot of beacons by changing the advertising address.
-class BeaconSwarm : public Device {
+class BeaconSwarm : public Beacon {
public:
BeaconSwarm();
virtual ~BeaconSwarm() = default;
+ static std::shared_ptr<Device> Create() {
+ return std::make_shared<BeaconSwarm>();
+ }
+
+ // Return a string representation of the type of device.
+ virtual std::string GetTypeString() const override {
+ return "beacon_swarm";
+ }
+
// Set the address and advertising interval from string args.
virtual void Initialize(const std::vector<std::string>& args) override;
- // Return a string representation of the type of device.
- virtual std::string GetTypeString() const override { return "beacon_swarm"; }
+ virtual void TimerTick() override;
- void TimerTick() override;
+ private:
+ static bool registered_;
};
} // namespace test_vendor_lib
#include "broken_adv.h"
+#include "model/setup/device_boutique.h"
#include "osi/include/log.h"
-#include "stack/include/hcidefs.h"
using std::vector;
namespace test_vendor_lib {
+bool BrokenAdv::registered_ = DeviceBoutique::Register(LOG_TAG, &BrokenAdv::Create);
+
BrokenAdv::BrokenAdv() {
advertising_interval_ms_ = std::chrono::milliseconds(1280);
- advertising_type_ = BTM_BLE_NON_CONNECT_EVT;
- adv_data_ = {
+ properties_.SetLeAdvertisementType(BTM_BLE_NON_CONNECT_EVT);
+ constant_adv_data_ = {
0x02, // Length
BTM_BLE_AD_TYPE_FLAG,
BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG,
'd',
'v',
};
+ properties_.SetLeAdvertisement(constant_adv_data_);
+
+ properties_.SetLeScanResponse({0x0b, // Length
+ BTM_BLE_AD_TYPE_NAME_SHORT, 'b', 'r', 'o', 'k', 'e', 'n', 'n', 'e', 's', 's'});
- constant_adv_data_ = adv_data_;
-
- scan_response_present_ = true;
- scan_data_ = {0x0b, // Length
- BTM_BLE_AD_TYPE_NAME_SHORT,
- 'b',
- 'r',
- 'o',
- 'k',
- 'e',
- 'n',
- 'n',
- 'e',
- 's',
- 's'};
-
- extended_inquiry_data_ = {0x07, // Length
- BT_EIR_COMPLETE_LOCAL_NAME_TYPE,
- 'B',
- 'R',
- '0',
- 'K',
- '3',
- 'N'};
- page_scan_repetition_mode_ = 0;
+ properties_.SetExtendedInquiryData({0x07, // Length
+ BT_EIR_COMPLETE_LOCAL_NAME_TYPE, 'B', 'R', '0', 'K', '3', 'N'});
+ properties_.SetPageScanRepetitionMode(0);
page_scan_delay_ms_ = std::chrono::milliseconds(600);
}
void BrokenAdv::Initialize(const vector<std::string>& args) {
if (args.size() < 2) return;
- BtAddress addr;
- if (addr.FromString(args[1])) SetBtAddress(addr);
+ Address addr;
+ if (Address::FromString(args[1], addr)) properties_.SetLeAddress(addr);
if (args.size() < 3) return;
}
void BrokenAdv::UpdateAdvertisement() {
- adv_data_.clear();
- for (size_t i = 0; i < constant_adv_data_.size(); i++)
- adv_data_.push_back(constant_adv_data_[i]);
+ std::vector<uint8_t> adv_data;
+ for (size_t i = 0; i < constant_adv_data_.size(); i++) adv_data.push_back(constant_adv_data_[i]);
- RandomizeAdvertisement(adv_data_, 31 - adv_data_.size());
+ RandomizeAdvertisement(adv_data, 31 - adv_data.size());
+ properties_.SetLeAdvertisement(adv_data);
- RandomizeAdvertisement(scan_data_, 31);
+ adv_data.clear();
+ RandomizeAdvertisement(adv_data, 31);
+ properties_.SetLeScanResponse(adv_data);
- std::vector<uint8_t> curr_addr;
- BtAddress next_addr;
- GetBtAddress().ToVector(curr_addr);
- curr_addr[0]++;
- next_addr.FromVector(curr_addr);
-
- SetBtAddress(next_addr);
+ Address le_addr = properties_.GetLeAddress();
+ uint8_t* low_order_byte = (uint8_t*)(&le_addr);
+ *low_order_byte += 1;
+ properties_.SetLeAddress(le_addr);
}
std::string BrokenAdv::ToString() const {
- std::string str = Device::ToString() + std::string(": Interval = ") +
- std::to_string(advertising_interval_ms_.count());
+ std::string str =
+ Device::ToString() + std::string(": Interval = ") + std::to_string(advertising_interval_ms_.count());
return str;
}
void BrokenAdv::UpdatePageScan() {
- std::vector<uint8_t> broken_addr;
- RandomizeAdvertisement(scan_data_, 31);
-
- BtAddress next_addr;
- GetBtAddress().ToVector(broken_addr);
- broken_addr[1]++;
- next_addr.FromVector(broken_addr);
+ RandomizeAdvertisement(constant_scan_data_, 31);
- SetBtAddress(next_addr);
+ Address page_addr = properties_.GetAddress();
+ uint8_t* low_order_byte = (uint8_t*)(&page_addr);
+ *low_order_byte += 1;
+ properties_.SetAddress(page_addr);
}
void BrokenAdv::TimerTick() {
#include <cstdint>
#include <vector>
-#include "bt_address.h"
#include "device.h"
namespace test_vendor_lib {
BrokenAdv();
~BrokenAdv() = default;
+ static std::shared_ptr<Device> Create() {
+ return std::make_shared<BrokenAdv>();
+ }
+
// Initialize the device based on the values of |args|.
virtual void Initialize(const std::vector<std::string>& args) override;
// Return a string representation of the type of device.
- virtual std::string GetTypeString() const override { return "broken_adv"; }
+ virtual std::string GetTypeString() const override {
+ return "broken_adv";
+ }
// Return the string representation of the device.
virtual std::string ToString() const override;
private:
std::vector<uint8_t> constant_adv_data_;
+ std::vector<uint8_t> constant_scan_data_;
+ static bool registered_;
};
} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "car_kit"
+
+#include "car_kit.h"
+
+#include "osi/include/log.h"
+
+#include "model/setup/device_boutique.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+bool CarKit::registered_ = DeviceBoutique::Register(LOG_TAG, &CarKit::Create);
+
+CarKit::CarKit() : Device(kCarKitPropertiesFile) {
+ advertising_interval_ms_ = std::chrono::milliseconds(0);
+
+ page_scan_delay_ms_ = std::chrono::milliseconds(600);
+
+ // Stub in packet handling for now
+ link_layer_controller_.RegisterAclChannel([](std::shared_ptr<std::vector<uint8_t>>) {});
+ link_layer_controller_.RegisterEventChannel([](std::shared_ptr<std::vector<uint8_t>>) {});
+ link_layer_controller_.RegisterScoChannel([](std::shared_ptr<std::vector<uint8_t>>) {});
+ link_layer_controller_.RegisterRemoteChannel(
+ [this](std::shared_ptr<packets::LinkLayerPacketBuilder> packet, Phy::Type phy_type) {
+ CarKit::SendLinkLayerPacket(packet, phy_type);
+ });
+
+ properties_.SetPageScanRepetitionMode(0);
+ properties_.SetClassOfDevice(0x600420);
+ properties_.SetSupportedFeatures(0x8779ff9bfe8defff);
+ properties_.SetExtendedInquiryData({
+ 16, // length
+ 9, // Type: Device Name
+ 'g', 'D', 'e', 'v', 'i', 'c', 'e', '-', 'c', 'a', 'r', '_', 'k', 'i', 't',
+ 7, // length
+ 3, // Type: 16-bit UUIDs
+ 0x0e, // AVRC
+ 0x11,
+ 0x0B, // Audio Sink
+ 0x11,
+ 0x00, // PnP Information
+ 0x12,
+ });
+ properties_.SetName({
+ 'g',
+ 'D',
+ 'e',
+ 'v',
+ 'i',
+ 'c',
+ 'e',
+ '-',
+ 'C',
+ 'a',
+ 'r',
+ '_',
+ 'K',
+ 'i',
+ 't',
+ });
+}
+
+void CarKit::Initialize(const vector<std::string>& args) {
+ if (args.size() < 2) return;
+
+ Address addr;
+ if (Address::FromString(args[1], addr)) properties_.SetAddress(addr);
+ LOG_INFO(LOG_TAG, "%s SetAddress %s", ToString().c_str(), addr.ToString().c_str());
+
+ if (args.size() < 3) return;
+
+ properties_.SetClockOffset(std::stoi(args[2]));
+}
+
+void CarKit::TimerTick() {
+ link_layer_controller_.TimerTick();
+}
+
+void CarKit::IncomingPacket(packets::LinkLayerPacketView packet) {
+ LOG_WARN(LOG_TAG, "Incoming Packet");
+ link_layer_controller_.IncomingPacket(packet);
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "device.h"
+#include "model/controller/link_layer_controller.h"
+
+namespace {
+const std::string kCarKitPropertiesFile = "/etc/bluetooth/car_kit_controller_properties.json";
+} // namespace
+
+namespace test_vendor_lib {
+
+class CarKit : public Device {
+ public:
+ CarKit();
+ ~CarKit() = default;
+
+ static std::shared_ptr<CarKit> Create() {
+ return std::make_shared<CarKit>();
+ }
+
+ // Initialize the device based on the values of |args|.
+ virtual void Initialize(const std::vector<std::string>& args) override;
+
+ // Return a string representation of the type of device.
+ virtual std::string GetTypeString() const override {
+ return "car_kit";
+ }
+
+ virtual void IncomingPacket(packets::LinkLayerPacketView packet) override;
+
+ virtual void TimerTick() override;
+
+ private:
+ LinkLayerController link_layer_controller_{properties_};
+ static bool registered_;
+};
+
+} // namespace test_vendor_lib
#define LOG_TAG "classic"
#include "classic.h"
+#include "model/setup/device_boutique.h"
#include "osi/include/log.h"
-#include "stack/include/hcidefs.h"
using std::vector;
namespace test_vendor_lib {
+bool Classic::registered_ = DeviceBoutique::Register(LOG_TAG, &Classic::Create);
+
Classic::Classic() {
advertising_interval_ms_ = std::chrono::milliseconds(0);
- device_class_ = 0x30201;
-
- extended_inquiry_data_ = {0x10, // Length
- BT_EIR_COMPLETE_LOCAL_NAME_TYPE,
- 'g',
- 'D',
- 'e',
- 'v',
- 'i',
- 'c',
- 'e',
- '-',
- 'c',
- 'l',
- 'a',
- 's',
- 's',
- 'i',
- 'c'};
- page_scan_repetition_mode_ = 0;
+ properties_.SetClassOfDevice(0x30201);
+
+ properties_.SetExtendedInquiryData({0x10, // Length
+ BT_EIR_COMPLETE_LOCAL_NAME_TYPE, // Type
+ 'g', 'D', 'e', 'v', 'i', 'c', 'e', '-', 'c', 'l', 'a', 's', 's', 'i', 'c',
+ '\0'}); // End of data
+ properties_.SetPageScanRepetitionMode(0);
+ properties_.SetSupportedFeatures(0x87593F9bFE8FFEFF);
+
page_scan_delay_ms_ = std::chrono::milliseconds(600);
}
void Classic::Initialize(const vector<std::string>& args) {
if (args.size() < 2) return;
- BtAddress addr;
- if (addr.FromString(args[1])) SetBtAddress(addr);
+ Address addr;
+ if (Address::FromString(args[1], addr)) properties_.SetAddress(addr);
if (args.size() < 3) return;
- SetClockOffset(std::stoi(args[2]));
+ properties_.SetClockOffset(std::stoi(args[2]));
}
} // namespace test_vendor_lib
#include <cstdint>
#include <vector>
-#include "bt_address.h"
#include "device.h"
namespace test_vendor_lib {
Classic();
~Classic() = default;
+ static std::shared_ptr<Device> Create() {
+ return std::make_shared<Classic>();
+ }
+
// Initialize the device based on the values of |args|.
virtual void Initialize(const std::vector<std::string>& args) override;
// Return a string representation of the type of device.
- virtual std::string GetTypeString() const override { return "classic"; }
+ virtual std::string GetTypeString() const override {
+ return "classic";
+ }
+
+ private:
+ static bool registered_;
};
} // namespace test_vendor_lib
namespace test_vendor_lib {
std::string Device::ToString() const {
- std::string dev = "(" + GetTypeString() + ")" + "@" + address_.ToString();
+ std::string dev = GetTypeString() + "@" + properties_.GetAddress().ToString();
return dev;
}
-bool Device::IsAdvertisementAvailable(
- std::chrono::milliseconds scan_time) const {
+void Device::RegisterPhyLayer(std::shared_ptr<PhyLayer> phy) {
+ phy_layers_[phy->GetType()].push_back(phy);
+}
+
+void Device::UnregisterPhyLayer(std::shared_ptr<PhyLayer> phy) {
+ for (auto phy_pair : phy_layers_) {
+ auto phy_list = std::get<1>(phy_pair);
+ for (size_t i = 0; i < phy_list.size(); i++) {
+ if (phy == phy_list[i]) {
+ phy_list.erase(phy_list.begin() + i);
+ }
+ }
+ }
+}
+
+bool Device::IsAdvertisementAvailable(std::chrono::milliseconds scan_time) const {
if (advertising_interval_ms_ == std::chrono::milliseconds(0)) return false;
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point last_interval =
- ((now - time_stamp_) / advertising_interval_ms_) *
- advertising_interval_ms_ +
- time_stamp_;
+ ((now - time_stamp_) / advertising_interval_ms_) * advertising_interval_ms_ + time_stamp_;
- std::chrono::steady_clock::time_point next_interval =
- last_interval + advertising_interval_ms_;
+ std::chrono::steady_clock::time_point next_interval = last_interval + advertising_interval_ms_;
return ((now + scan_time) >= next_interval);
}
-bool Device::IsPageScanAvailable() const { return true; }
+void Device::SendLinkLayerPacket(std::shared_ptr<packets::LinkLayerPacketBuilder> to_send, Phy::Type phy_type) {
+ auto phy_list = phy_layers_[phy_type];
+ for (auto phy : phy_list) {
+ phy->Send(to_send);
+ }
+}
} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2016 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 <chrono>
+#include <cstdint>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "model/devices/device_properties.h"
+#include "model/setup/phy_layer.h"
+#include "packets/link_layer/link_layer_packet_builder.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+#include "types/address.h"
+
+#include "stack/include/btm_ble_api.h"
+
+namespace test_vendor_lib {
+
+// Represent a Bluetooth Device
+// - Provide Get*() and Set*() functions for device attributes.
+class Device {
+ public:
+ Device(const std::string properties_filename = "")
+ : time_stamp_(std::chrono::steady_clock::now()), properties_(properties_filename) {}
+ virtual ~Device() = default;
+
+ // Initialize the device based on the values of |args|.
+ virtual void Initialize(const std::vector<std::string>& args) = 0;
+
+ // Return a string representation of the type of device.
+ virtual std::string GetTypeString() const = 0;
+
+ // Return the string representation of the device.
+ virtual std::string ToString() const;
+
+ // Decide whether to accept a connection request
+ // May need to be extended to check peer address & type, and other
+ // connection parameters.
+ // Return true if the device accepts the connection request.
+ virtual bool LeConnect() {
+ return false;
+ }
+
+ // Set the advertisement interval in milliseconds.
+ void SetAdvertisementInterval(std::chrono::milliseconds ms) {
+ advertising_interval_ms_ = ms;
+ }
+
+ // Returns true if the host could see an advertisement in the next
+ // |scan_time| milliseconds.
+ virtual bool IsAdvertisementAvailable(std::chrono::milliseconds scan_time) const;
+
+ // Let the device know that time has passed.
+ virtual void TimerTick() {}
+
+ void RegisterPhyLayer(std::shared_ptr<PhyLayer> phy);
+
+ void UnregisterPhyLayer(std::shared_ptr<PhyLayer> phy);
+
+ virtual void IncomingPacket(packets::LinkLayerPacketView){};
+
+ virtual void SendLinkLayerPacket(std::shared_ptr<packets::LinkLayerPacketBuilder> packet, Phy::Type phy_type);
+
+ protected:
+ std::map<Phy::Type, std::vector<std::shared_ptr<PhyLayer>>> phy_layers_;
+
+ std::chrono::steady_clock::time_point time_stamp_;
+
+ // The time between page scans.
+ std::chrono::milliseconds page_scan_delay_ms_;
+
+ // The spec defines the advertising interval as a 16-bit value, but since it
+ // is never sent in packets, we use std::chrono::milliseconds.
+ std::chrono::milliseconds advertising_interval_ms_;
+
+ DeviceProperties properties_;
+};
+
+} // namespace test_vendor_lib
#include "base/json/json_reader.h"
#include "base/values.h"
+#include "hci.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
-#include "stack/include/hcidefs.h"
using std::vector;
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) {
+ : acl_data_packet_size_(1024), sco_data_packet_size_(255), num_acl_data_packets_(10), num_sco_data_packets_(10),
+ version_(static_cast<uint8_t>(hci::Version::V4_1)), revision_(0),
+ lmp_pal_version_(static_cast<uint8_t>(hci::Version::V4_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("BB:BB:BB:BB:BB:AD", address_));
+ CHECK(Address::FromString("BB:BB:BB:BB:AD:1E", le_address_));
+ name_ = {'D', 'e', 'f', 'a', 'u', 'l', 't'};
- CHECK(address_.FromString("01:02:03:04:05:06"));
- local_name_ = "DefaultName";
-
- supported_codecs_ = {1};
+ supported_codecs_ = {0}; // Only SBC is supported.
vendor_specific_codecs_ = {};
- for (int i = 0; i < 64; i++) local_supported_commands_.push_back(0xff);
+ for (int i = 0; i < 64; i++) 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 (file_name.size() == 0) {
+ return;
+ }
+ 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);
+ 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.");
+ 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::JSONValueConverter<DeviceProperties> converter;
if (!converter.Convert(properties_dictionary, this))
- LOG_INFO(LOG_TAG,
- "Error converting JSON properties into Properties object.");
+ LOG_INFO(LOG_TAG, "Error converting JSON properties into Properties object.");
}
// static
-void DeviceProperties::RegisterJSONConverter(
- base::JSONValueConverter<DeviceProperties>* converter) {
+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);
+ 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);
+ 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_);
--- /dev/null
+/*
+ * 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 <string>
+#include <vector>
+
+#include "base/json/json_value_converter.h"
+#include "types/address.h"
+#include "types/class_of_device.h"
+
+namespace test_vendor_lib {
+
+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>& GetVersionInformation() const;
+
+ // Specification Version 4.2, Volume 2, Part E, Section 7.4.2
+ const std::vector<uint8_t>& GetSupportedCommands() const {
+ return supported_commands_;
+ }
+
+ // Specification Version 4.2, Volume 2, Part E, Section 7.4.3
+ uint64_t GetSupportedFeatures() const {
+ return extended_features_[0];
+ }
+
+ void SetSupportedFeatures(uint64_t features) {
+ extended_features_[0] = features;
+ }
+
+ // Specification Version 4.2, Volume 2, Part E, Section 7.4.4
+ uint8_t GetExtendedFeaturesMaximumPageNumber() const {
+ return extended_features_.size() - 1;
+ }
+
+ uint64_t GetExtendedFeatures(uint8_t page_number) const {
+ CHECK(page_number < extended_features_.size());
+ return 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 Address& GetAddress() const {
+ return address_;
+ }
+
+ void SetAddress(const Address& address) {
+ address_ = 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_;
+ }
+
+ 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_;
+ }
+
+ uint8_t GetAuthenticationEnable() const {
+ return authentication_enable_;
+ }
+
+ void SetAuthenticationEnable(uint8_t enable) {
+ authentication_enable_ = enable;
+ }
+
+ ClassOfDevice GetClassOfDevice() const {
+ return class_of_device_;
+ }
+
+ void SetClassOfDevice(uint8_t b0, uint8_t b1, uint8_t b2) {
+ class_of_device_.cod[0] = b0;
+ class_of_device_.cod[1] = b1;
+ class_of_device_.cod[2] = b2;
+ }
+
+ void SetClassOfDevice(uint32_t class_of_device) {
+ class_of_device_.cod[0] = class_of_device & 0xff;
+ class_of_device_.cod[1] = (class_of_device >> 8) & 0xff;
+ class_of_device_.cod[2] = (class_of_device >> 16) & 0xff;
+ }
+
+ void SetName(const std::vector<uint8_t>& name) {
+ name_ = name;
+ }
+
+ const std::vector<uint8_t>& GetName() const {
+ return name_;
+ }
+
+ void SetExtendedInquiryData(const std::vector<uint8_t>& eid) {
+ extended_inquiry_data_ = eid;
+ }
+
+ const std::vector<uint8_t>& GetExtendedInquiryData() const {
+ return extended_inquiry_data_;
+ }
+
+ uint8_t GetPageScanRepetitionMode() const {
+ return page_scan_repetition_mode_;
+ }
+
+ void SetPageScanRepetitionMode(uint8_t mode) {
+ page_scan_repetition_mode_ = mode;
+ }
+
+ uint16_t GetClockOffset() const {
+ return clock_offset_;
+ }
+
+ void SetClockOffset(uint16_t offset) {
+ clock_offset_ = offset;
+ }
+
+ // Low-Energy functions
+ const Address& GetLeAddress() const {
+ return le_address_;
+ }
+
+ void SetLeAddress(const Address& address) {
+ le_address_ = address;
+ }
+
+ uint8_t GetLeAddressType() const {
+ return le_address_type_;
+ }
+
+ void SetLeAddressType(uint8_t addr_type) {
+ le_address_type_ = addr_type;
+ }
+
+ uint8_t GetLeAdvertisementType() const {
+ return le_advertisement_type_;
+ }
+
+ void SetLeAdvertisementType(uint8_t ad_type) {
+ le_advertisement_type_ = ad_type;
+ }
+
+ void SetLeAdvertisement(const std::vector<uint8_t>& ad) {
+ le_advertisement_ = ad;
+ }
+
+ const std::vector<uint8_t>& GetLeAdvertisement() const {
+ return le_advertisement_;
+ }
+
+ void SetLeScanResponse(const std::vector<uint8_t>& response) {
+ le_scan_response_ = response;
+ }
+
+ const std::vector<uint8_t>& GetLeScanResponse() const {
+ return le_scan_response_;
+ }
+
+ // 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 GetLeSupportedFeatures() const {
+ return le_supported_features_;
+ }
+
+ void SetLeSupportedFeatures(uint64_t features) {
+ le_supported_features_ = 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
+ const std::vector<uint8_t>& GetLeVendorCap() const {
+ return le_vendor_cap_;
+ }
+
+ static void RegisterJSONConverter(base::JSONValueConverter<DeviceProperties>* converter);
+
+ private:
+ // Classic
+ 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_;
+ uint64_t supported_features_;
+ uint8_t authentication_enable_;
+ std::vector<uint8_t> supported_codecs_;
+ std::vector<uint32_t> vendor_specific_codecs_;
+ std::vector<uint8_t> supported_commands_;
+ std::vector<uint64_t> extended_features_{{0x875b3fd8fe8ffeff, 0x07}};
+ ClassOfDevice class_of_device_{{0, 0, 0}};
+ std::vector<uint8_t> extended_inquiry_data_;
+ std::vector<uint8_t> name_;
+ Address address_;
+ uint8_t page_scan_repetition_mode_;
+ uint16_t clock_offset_;
+
+ // Low Energy
+ uint16_t le_data_packet_length_;
+ uint8_t num_le_data_packets_;
+ uint8_t le_white_list_size_;
+ uint64_t le_supported_features_{0x075b3fd8fe8ffeff};
+ uint64_t le_supported_states_;
+ std::vector<uint8_t> le_vendor_cap_;
+ Address le_address_;
+ uint8_t le_address_type_;
+ uint8_t le_advertisement_type_;
+ std::vector<uint8_t> le_advertisement_;
+ std::vector<uint8_t> le_scan_response_;
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+//
+// 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.
+//
+
+#include "h4_packetizer.h"
+
+#define LOG_TAG "h4_packetizer"
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <log/log.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+namespace test_vendor_lib {
+namespace hci {
+constexpr size_t H4Packetizer::COMMAND_PREAMBLE_SIZE;
+constexpr size_t H4Packetizer::COMMAND_LENGTH_OFFSET;
+constexpr size_t H4Packetizer::ACL_PREAMBLE_SIZE;
+constexpr size_t H4Packetizer::ACL_LENGTH_OFFSET;
+constexpr size_t H4Packetizer::SCO_PREAMBLE_SIZE;
+constexpr size_t H4Packetizer::SCO_LENGTH_OFFSET;
+constexpr size_t H4Packetizer::EVENT_PREAMBLE_SIZE;
+constexpr size_t H4Packetizer::EVENT_LENGTH_OFFSET;
+
+constexpr size_t H4Packetizer::PREAMBLE_SIZE_MAX;
+
+size_t H4Packetizer::HciGetPacketLengthForType(hci::PacketType type, const uint8_t* preamble) {
+ static const size_t packet_length_offset[static_cast<size_t>(hci::PacketType::EVENT) + 1] = {
+ 0,
+ H4Packetizer::COMMAND_LENGTH_OFFSET,
+ H4Packetizer::ACL_LENGTH_OFFSET,
+ H4Packetizer::SCO_LENGTH_OFFSET,
+ H4Packetizer::EVENT_LENGTH_OFFSET,
+ };
+
+ size_t offset = packet_length_offset[static_cast<size_t>(type)];
+ if (type != hci::PacketType::ACL) return preamble[offset];
+ return (((preamble[offset + 1]) << 8) | preamble[offset]);
+}
+
+H4Packetizer::H4Packetizer(int fd, PacketReadCallback command_cb, PacketReadCallback event_cb,
+ PacketReadCallback acl_cb, PacketReadCallback sco_cb)
+ : uart_fd_(fd), command_cb_(command_cb), event_cb_(event_cb), acl_cb_(acl_cb), sco_cb_(sco_cb) {}
+
+size_t H4Packetizer::Send(uint8_t type, const uint8_t* data, size_t length) {
+ struct iovec iov[] = {{&type, sizeof(type)}, {const_cast<uint8_t*>(data), length}};
+ ssize_t ret = 0;
+ do {
+ ret = TEMP_FAILURE_RETRY(writev(uart_fd_, iov, sizeof(iov) / sizeof(iov[0])));
+ } while (-1 == ret && EAGAIN == errno);
+
+ if (ret == -1) {
+ ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
+ } else if (ret < static_cast<ssize_t>(length + 1)) {
+ ALOGE("%s: %d / %d bytes written - something went wrong...", __func__, static_cast<int>(ret),
+ static_cast<int>(length + 1));
+ }
+ return ret;
+}
+
+void H4Packetizer::OnPacketReady() {
+ ALOGE("%s: before switch", __func__);
+ switch (hci_packet_type_) {
+ case hci::PacketType::COMMAND:
+ command_cb_(packet_);
+ break;
+ case hci::PacketType::ACL:
+ acl_cb_(packet_);
+ break;
+ case hci::PacketType::SCO:
+ sco_cb_(packet_);
+ break;
+ case hci::PacketType::EVENT:
+ event_cb_(packet_);
+ break;
+ default:
+ LOG_ALWAYS_FATAL("%s: Unimplemented packet type %d", __func__, static_cast<int>(hci_packet_type_));
+ }
+ // Get ready for the next type byte.
+ hci_packet_type_ = hci::PacketType::UNKNOWN;
+}
+
+void H4Packetizer::OnDataReady(int fd) {
+ if (hci_packet_type_ == hci::PacketType::UNKNOWN) {
+ uint8_t buffer[1] = {0};
+ ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, 1));
+ if (bytes_read != 1) {
+ if (bytes_read == 0) {
+ ALOGI("%s: Nothing ready, will retry!", __func__);
+ return;
+ } else if (bytes_read < 0) {
+ if (errno == EAGAIN) {
+ // No data, try again later.
+ return;
+ } else {
+ LOG_ALWAYS_FATAL("%s: Read packet type error: %s", __func__, strerror(errno));
+ }
+ } else {
+ LOG_ALWAYS_FATAL("%s: More bytes read than expected (%u)!", __func__, static_cast<unsigned int>(bytes_read));
+ }
+ }
+ hci_packet_type_ = static_cast<hci::PacketType>(buffer[0]);
+ if (hci_packet_type_ != hci::PacketType::ACL && hci_packet_type_ != hci::PacketType::SCO &&
+ hci_packet_type_ != hci::PacketType::COMMAND && hci_packet_type_ != hci::PacketType::EVENT) {
+ LOG_ALWAYS_FATAL("%s: Unimplemented packet type %d", __func__, static_cast<int>(hci_packet_type_));
+ }
+ } else {
+ static const size_t preamble_size[static_cast<size_t>(hci::PacketType::EVENT) + 1] = {
+ 0,
+ H4Packetizer::COMMAND_PREAMBLE_SIZE,
+ H4Packetizer::ACL_PREAMBLE_SIZE,
+ H4Packetizer::SCO_PREAMBLE_SIZE,
+ H4Packetizer::EVENT_PREAMBLE_SIZE,
+ };
+
+ switch (state_) {
+ case HCI_PREAMBLE: {
+ size_t preamble_bytes = preamble_size[static_cast<size_t>(hci_packet_type_)];
+ ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, preamble_ + bytes_read_, preamble_bytes - bytes_read_));
+ if (bytes_read == 0) {
+ ALOGE("%s: Will try again to read the header!", __func__);
+ return;
+ }
+ if (bytes_read < 0) {
+ // Ignore temporary failures.
+ if (errno == EAGAIN) {
+ return;
+ }
+ LOG_ALWAYS_FATAL("%s: Read header error: %s", __func__, strerror(errno));
+ }
+ bytes_read_ += bytes_read;
+ if (bytes_read_ == preamble_bytes) {
+ size_t packet_length = HciGetPacketLengthForType(hci_packet_type_, preamble_);
+ packet_.resize(preamble_bytes + packet_length);
+ memcpy(packet_.data(), preamble_, preamble_bytes);
+ ALOGI("%s: Read a preamble of size %d length %d %0x %0x %0x", __func__, static_cast<int>(bytes_read_),
+ static_cast<int>(packet_length), preamble_[0], preamble_[1], preamble_[2]);
+ bytes_remaining_ = packet_length;
+ if (bytes_remaining_ == 0) {
+ OnPacketReady();
+ state_ = HCI_PREAMBLE;
+ bytes_read_ = 0;
+ } else {
+ state_ = HCI_PAYLOAD;
+ bytes_read_ = 0;
+ }
+ }
+ break;
+ }
+
+ case HCI_PAYLOAD: {
+ size_t preamble_bytes = preamble_size[static_cast<size_t>(hci_packet_type_)];
+ ssize_t bytes_read =
+ TEMP_FAILURE_RETRY(read(fd, packet_.data() + preamble_bytes + bytes_read_, bytes_remaining_));
+ if (bytes_read == 0) {
+ ALOGI("%s: Will try again to read the payload!", __func__);
+ return;
+ }
+ if (bytes_read < 0) {
+ // Ignore temporary failures.
+ if (errno == EAGAIN) {
+ return;
+ }
+ LOG_ALWAYS_FATAL("%s: Read payload error: %s", __func__, strerror(errno));
+ }
+ bytes_remaining_ -= bytes_read;
+ bytes_read_ += bytes_read;
+ if (bytes_remaining_ == 0) {
+ OnPacketReady();
+ state_ = HCI_PREAMBLE;
+ bytes_read_ = 0;
+ }
+ break;
+ }
+ }
+ }
+}
+
+} // namespace hci
+} // namespace test_vendor_lib
--- /dev/null
+//
+// 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 <functional>
+#include <vector>
+
+#include "hci.h"
+#include "hci_protocol.h"
+
+namespace test_vendor_lib {
+namespace hci {
+
+using HciPacketReadyCallback = std::function<void(void)>;
+
+class H4Packetizer : public HciProtocol {
+ public:
+ H4Packetizer(int fd, PacketReadCallback command_cb, PacketReadCallback event_cb, PacketReadCallback acl_cb,
+ PacketReadCallback sco_cb);
+
+ size_t Send(uint8_t type, const uint8_t* data, size_t length);
+
+ void OnPacketReady();
+
+ void OnDataReady(int fd);
+
+ private:
+ int uart_fd_;
+
+ PacketReadCallback command_cb_;
+ PacketReadCallback event_cb_;
+ PacketReadCallback acl_cb_;
+ PacketReadCallback sco_cb_;
+
+ hci::PacketType hci_packet_type_{hci::PacketType::UNKNOWN};
+
+ // 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1)
+ static constexpr size_t COMMAND_PREAMBLE_SIZE = 3;
+ static constexpr size_t COMMAND_LENGTH_OFFSET = 2;
+
+ // 2 bytes for handle, 2 bytes for data length (Volume 2, Part E, 5.4.2)
+ static constexpr size_t ACL_PREAMBLE_SIZE = 4;
+ static constexpr size_t ACL_LENGTH_OFFSET = 2;
+
+ // 2 bytes for handle, 1 byte for data length (Volume 2, Part E, 5.4.3)
+ static constexpr size_t SCO_PREAMBLE_SIZE = 3;
+ static constexpr size_t SCO_LENGTH_OFFSET = 2;
+
+ // 1 byte for event code, 1 byte for parameter length (Volume 2, Part
+ // E, 5.4.4)
+ static constexpr size_t EVENT_PREAMBLE_SIZE = 2;
+ static constexpr size_t EVENT_LENGTH_OFFSET = 1;
+
+ static constexpr size_t PREAMBLE_SIZE_MAX = ACL_PREAMBLE_SIZE;
+
+ size_t HciGetPacketLengthForType(hci::PacketType type, const uint8_t* preamble);
+
+ enum State { HCI_PREAMBLE, HCI_PAYLOAD };
+ State state_{HCI_PREAMBLE};
+ uint8_t preamble_[PREAMBLE_SIZE_MAX];
+ std::vector<uint8_t> packet_;
+ size_t bytes_remaining_{0};
+ size_t bytes_read_{0};
+};
+
+} // namespace hci
+} // namespace test_vendor_lib
--- /dev/null
+//
+// 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.
+//
+
+#include "h4_protocol.h"
+
+#define LOG_TAG "hci-h4_protocol"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <log/log.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+namespace test_vendor_lib {
+namespace hci {
+
+H4Protocol::H4Protocol(int fd, PacketReadCallback command_cb, PacketReadCallback event_cb, PacketReadCallback acl_cb,
+ PacketReadCallback sco_cb)
+ : uart_fd_(fd), command_cb_(command_cb), event_cb_(event_cb), acl_cb_(acl_cb), sco_cb_(sco_cb),
+ hci_packetizer_([this]() {
+ ALOGI("in lambda");
+ this->OnPacketReady();
+ }) {}
+
+size_t H4Protocol::Send(uint8_t type, const uint8_t* data, size_t length) {
+ struct iovec iov[] = {{&type, sizeof(type)}, {const_cast<uint8_t*>(data), length}};
+ ssize_t ret = 0;
+ do {
+ ret = TEMP_FAILURE_RETRY(writev(uart_fd_, iov, sizeof(iov) / sizeof(iov[0])));
+ } while (-1 == ret && EAGAIN == errno);
+
+ if (ret == -1) {
+ ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
+ } else if (ret < static_cast<ssize_t>(length + 1)) {
+ ALOGE("%s: %d / %d bytes written - something went wrong...", __func__, static_cast<int>(ret),
+ static_cast<int>(length + 1));
+ }
+ return ret;
+}
+
+void H4Protocol::OnPacketReady() {
+ ALOGE("%s: before switch", __func__);
+ switch (hci_packet_type_) {
+ case hci::PacketType::COMMAND:
+ command_cb_(hci_packetizer_.GetPacket());
+ break;
+ case hci::PacketType::ACL:
+ acl_cb_(hci_packetizer_.GetPacket());
+ break;
+ case hci::PacketType::SCO:
+ sco_cb_(hci_packetizer_.GetPacket());
+ break;
+ case hci::PacketType::EVENT:
+ event_cb_(hci_packetizer_.GetPacket());
+ break;
+ default:
+ LOG_ALWAYS_FATAL("%s: Unimplemented packet type %d", __func__, static_cast<int>(hci_packet_type_));
+ }
+ // Get ready for the next type byte.
+ hci_packet_type_ = hci::PacketType::UNKNOWN;
+}
+
+void H4Protocol::OnDataReady(int fd) {
+ if (hci_packet_type_ == hci::PacketType::UNKNOWN) {
+ uint8_t buffer[1] = {0};
+ ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, 1));
+ if (bytes_read != 1) {
+ if (bytes_read == 0) {
+ ALOGI("%s: Nothing ready, will retry!", __func__);
+ return;
+ } else if (bytes_read < 0) {
+ if (errno == EAGAIN) {
+ // No data, try again later.
+ return;
+ } else {
+ LOG_ALWAYS_FATAL("%s: Read packet type error: %s", __func__, strerror(errno));
+ }
+ } else {
+ LOG_ALWAYS_FATAL("%s: More bytes read than expected (%u)!", __func__, static_cast<unsigned int>(bytes_read));
+ }
+ }
+ hci_packet_type_ = static_cast<hci::PacketType>(buffer[0]);
+ if (hci_packet_type_ != hci::PacketType::ACL && hci_packet_type_ != hci::PacketType::SCO &&
+ hci_packet_type_ != hci::PacketType::COMMAND && hci_packet_type_ != hci::PacketType::EVENT) {
+ LOG_ALWAYS_FATAL("%s: Unimplemented packet type %d", __func__, static_cast<int>(hci_packet_type_));
+ }
+ } else {
+ hci_packetizer_.OnDataReady(fd, hci_packet_type_);
+ }
+}
+
+} // namespace hci
+} // namespace test_vendor_lib
--- /dev/null
+//
+// 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 "hci_protocol.h"
+#include "include/hci.h"
+
+namespace test_vendor_lib {
+namespace hci {
+
+class H4Protocol : public HciProtocol {
+ public:
+ H4Protocol(int fd, PacketReadCallback command_cb, PacketReadCallback event_cb, PacketReadCallback acl_cb,
+ PacketReadCallback sco_cb);
+
+ size_t Send(uint8_t type, const uint8_t* data, size_t length);
+
+ void OnPacketReady();
+
+ void OnDataReady(int fd);
+
+ private:
+ int uart_fd_;
+
+ PacketReadCallback command_cb_;
+ PacketReadCallback event_cb_;
+ PacketReadCallback acl_cb_;
+ PacketReadCallback sco_cb_;
+
+ hci::PacketType hci_packet_type_{hci::PacketType::UNKNOWN};
+ hci::HciPacketizer hci_packetizer_;
+};
+
+} // namespace hci
+} // namespace test_vendor_lib
--- /dev/null
+//
+// 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.
+//
+
+#include "hci_packetizer.h"
+
+#define LOG_TAG "hci_packetizer"
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <log/log.h>
+#include <unistd.h>
+
+namespace test_vendor_lib {
+namespace hci {
+constexpr size_t HciPacketizer::COMMAND_PREAMBLE_SIZE;
+constexpr size_t HciPacketizer::COMMAND_LENGTH_OFFSET;
+constexpr size_t HciPacketizer::ACL_PREAMBLE_SIZE;
+constexpr size_t HciPacketizer::ACL_LENGTH_OFFSET;
+constexpr size_t HciPacketizer::SCO_PREAMBLE_SIZE;
+constexpr size_t HciPacketizer::SCO_LENGTH_OFFSET;
+constexpr size_t HciPacketizer::EVENT_PREAMBLE_SIZE;
+constexpr size_t HciPacketizer::EVENT_LENGTH_OFFSET;
+
+constexpr size_t HciPacketizer::PREAMBLE_SIZE_MAX;
+
+size_t HciPacketizer::HciGetPacketLengthForType(hci::PacketType type, const uint8_t* preamble) {
+ static const size_t packet_length_offset[static_cast<size_t>(hci::PacketType::EVENT) + 1] = {
+ 0,
+ HciPacketizer::COMMAND_LENGTH_OFFSET,
+ HciPacketizer::ACL_LENGTH_OFFSET,
+ HciPacketizer::SCO_LENGTH_OFFSET,
+ HciPacketizer::EVENT_LENGTH_OFFSET,
+ };
+
+ size_t offset = packet_length_offset[static_cast<size_t>(type)];
+ if (type != hci::PacketType::ACL) return preamble[offset];
+ return (((preamble[offset + 1]) << 8) | preamble[offset]);
+}
+
+const std::vector<uint8_t>& HciPacketizer::GetPacket() const {
+ return packet_;
+}
+
+void HciPacketizer::OnDataReady(int fd, hci::PacketType packet_type) {
+ static const size_t preamble_size[static_cast<size_t>(hci::PacketType::EVENT) + 1] = {
+ 0,
+ HciPacketizer::COMMAND_PREAMBLE_SIZE,
+ HciPacketizer::ACL_PREAMBLE_SIZE,
+ HciPacketizer::SCO_PREAMBLE_SIZE,
+ HciPacketizer::EVENT_PREAMBLE_SIZE,
+ };
+
+ switch (state_) {
+ case HCI_PREAMBLE: {
+ ssize_t bytes_read = TEMP_FAILURE_RETRY(
+ read(fd, preamble_ + bytes_read_, preamble_size[static_cast<uint8_t>(packet_type)] - bytes_read_));
+ if (bytes_read == 0) {
+ ALOGE("%s: Will try again to read the header!", __func__);
+ return;
+ }
+ if (bytes_read < 0) {
+ // Ignore temporary failures.
+ if (errno == EAGAIN) {
+ return;
+ }
+ LOG_ALWAYS_FATAL("%s: Read header error: %s", __func__, strerror(errno));
+ }
+ bytes_read_ += bytes_read;
+ if (bytes_read_ == preamble_size[static_cast<uint8_t>(packet_type)]) {
+ size_t packet_length = HciGetPacketLengthForType(packet_type, preamble_);
+ packet_.resize(preamble_size[static_cast<uint8_t>(packet_type)] + packet_length);
+ memcpy(packet_.data(), preamble_, preamble_size[static_cast<uint8_t>(packet_type)]);
+ ALOGI("%s: Read a preamble of size %d length %d %0x %0x %0x", __func__, static_cast<int>(bytes_read_),
+ static_cast<int>(packet_length), preamble_[0], preamble_[1], preamble_[2]);
+ bytes_remaining_ = packet_length;
+ if (bytes_remaining_ == 0) {
+ packet_ready_cb_();
+ state_ = HCI_PREAMBLE;
+ bytes_read_ = 0;
+ } else {
+ state_ = HCI_PAYLOAD;
+ bytes_read_ = 0;
+ }
+ }
+ break;
+ }
+
+ case HCI_PAYLOAD: {
+ ssize_t bytes_read = TEMP_FAILURE_RETRY(
+ read(fd, packet_.data() + preamble_size[static_cast<uint8_t>(packet_type)] + bytes_read_, bytes_remaining_));
+ if (bytes_read == 0) {
+ ALOGI("%s: Will try again to read the payload!", __func__);
+ return;
+ }
+ if (bytes_read < 0) {
+ // Ignore temporary failures.
+ if (errno == EAGAIN) {
+ return;
+ }
+ LOG_ALWAYS_FATAL("%s: Read payload error: %s", __func__, strerror(errno));
+ }
+ bytes_remaining_ -= bytes_read;
+ bytes_read_ += bytes_read;
+ if (bytes_remaining_ == 0) {
+ packet_ready_cb_();
+ state_ = HCI_PREAMBLE;
+ bytes_read_ = 0;
+ }
+ break;
+ }
+ }
+}
+
+} // namespace hci
+} // namespace test_vendor_lib
--- /dev/null
+//
+// 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 <functional>
+#include <vector>
+
+#include "include/hci.h"
+
+namespace test_vendor_lib {
+namespace hci {
+
+using HciPacketReadyCallback = std::function<void(void)>;
+
+class HciPacketizer {
+ public:
+ HciPacketizer(HciPacketReadyCallback packet_cb) : packet_ready_cb_(packet_cb){};
+ void OnDataReady(int fd, hci::PacketType packet_type);
+ const std::vector<uint8_t>& GetPacket() const;
+
+ private:
+ // 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1)
+ static constexpr size_t COMMAND_PREAMBLE_SIZE = 3;
+ static constexpr size_t COMMAND_LENGTH_OFFSET = 2;
+
+ // 2 bytes for handle, 2 bytes for data length (Volume 2, Part E, 5.4.2)
+ static constexpr size_t ACL_PREAMBLE_SIZE = 4;
+ static constexpr size_t ACL_LENGTH_OFFSET = 2;
+
+ // 2 bytes for handle, 1 byte for data length (Volume 2, Part E, 5.4.3)
+ static constexpr size_t SCO_PREAMBLE_SIZE = 3;
+ static constexpr size_t SCO_LENGTH_OFFSET = 2;
+
+ // 1 byte for event code, 1 byte for parameter length (Volume 2, Part
+ // E, 5.4.4)
+ static constexpr size_t EVENT_PREAMBLE_SIZE = 2;
+ static constexpr size_t EVENT_LENGTH_OFFSET = 1;
+
+ static constexpr size_t PREAMBLE_SIZE_MAX = ACL_PREAMBLE_SIZE;
+
+ size_t HciGetPacketLengthForType(hci::PacketType type, const uint8_t* preamble);
+
+ protected:
+ enum State { HCI_PREAMBLE, HCI_PAYLOAD };
+ State state_{HCI_PREAMBLE};
+ uint8_t preamble_[PREAMBLE_SIZE_MAX];
+ std::vector<uint8_t> packet_;
+ size_t bytes_remaining_{0};
+ size_t bytes_read_{0};
+ HciPacketReadyCallback packet_ready_cb_;
+};
+
+} // namespace hci
+} // namespace test_vendor_lib
--- /dev/null
+//
+// 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.
+//
+
+#include "hci_protocol.h"
+
+#define LOG_TAG "hci-hci_protocol"
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <log/log.h>
+#include <unistd.h>
+
+namespace test_vendor_lib {
+namespace hci {
+
+size_t HciProtocol::WriteSafely(int fd, const uint8_t* data, size_t length) {
+ size_t transmitted_length = 0;
+ while (length > 0) {
+ ssize_t ret = TEMP_FAILURE_RETRY(write(fd, data + transmitted_length, length));
+
+ if (ret == -1) {
+ if (errno == EAGAIN) continue;
+ ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
+ break;
+
+ } else if (ret == 0) {
+ // Nothing written :(
+ ALOGE("%s zero bytes written - something went wrong...", __func__);
+ break;
+ }
+
+ transmitted_length += ret;
+ length -= ret;
+ }
+
+ return transmitted_length;
+}
+
+} // namespace hci
+} // namespace test_vendor_lib
--- /dev/null
+//
+// 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 "hci.h"
+#include "hci_packetizer.h"
+
+namespace test_vendor_lib {
+namespace hci {
+
+using PacketReadCallback = std::function<void(const std::vector<uint8_t>&)>;
+
+// Implementation of HCI protocol bits common to different transports
+class HciProtocol {
+ public:
+ HciProtocol() = default;
+ virtual ~HciProtocol(){};
+
+ // Protocol-specific implementation of sending packets.
+ virtual size_t Send(uint8_t type, const uint8_t* data, size_t length) = 0;
+
+ protected:
+ static size_t WriteSafely(int fd, const uint8_t* data, size_t length);
+};
+
+} // namespace hci
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "hci_socket_device"
+
+#include "hci_socket_device.h"
+
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+#include "osi/include/log.h"
+
+#include "model/setup/device_boutique.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+HciSocketDevice::HciSocketDevice(int file_descriptor) : socket_file_descriptor_(file_descriptor) {
+ advertising_interval_ms_ = std::chrono::milliseconds(0);
+
+ page_scan_delay_ms_ = std::chrono::milliseconds(600);
+
+ properties_.SetPageScanRepetitionMode(0);
+ properties_.SetClassOfDevice(0x600420);
+ properties_.SetExtendedInquiryData({
+ 16, // length
+ 9, // Type: Device Name
+ 'g',
+ 'D',
+ 'e',
+ 'v',
+ 'i',
+ 'c',
+ 'e',
+ '-',
+ 'h',
+ 'c',
+ 'i',
+ '_',
+ 'n',
+ 'e',
+ 't',
+ });
+ properties_.SetName({
+ 'g',
+ 'D',
+ 'e',
+ 'v',
+ 'i',
+ 'c',
+ 'e',
+ '-',
+ 'H',
+ 'C',
+ 'I',
+ '_',
+ 'N',
+ 'e',
+ 't',
+ });
+
+ h4_ = hci::H4Packetizer(
+ socket_file_descriptor_,
+ [this](const std::vector<uint8_t>& raw_command) {
+ LOG_INFO(LOG_TAG, "Rx Command");
+ std::shared_ptr<std::vector<uint8_t>> packet_copy = std::make_shared<std::vector<uint8_t>>(raw_command);
+ HandleCommand(packet_copy);
+ },
+ [](const std::vector<uint8_t>&) { CHECK(false) << "Unexpected Event in HciSocketDevice!"; },
+ [this](const std::vector<uint8_t>& raw_acl) {
+ LOG_INFO(LOG_TAG, "Rx ACL");
+ std::shared_ptr<std::vector<uint8_t>> packet_copy = std::make_shared<std::vector<uint8_t>>(raw_acl);
+ HandleAcl(packet_copy);
+ },
+ [this](const std::vector<uint8_t>& raw_sco) {
+ LOG_INFO(LOG_TAG, "Rx SCO");
+ std::shared_ptr<std::vector<uint8_t>> packet_copy = std::make_shared<std::vector<uint8_t>>(raw_sco);
+ HandleSco(packet_copy);
+ });
+
+ RegisterEventChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
+ LOG_INFO(LOG_TAG, "Tx Event");
+ SendHci(hci::PacketType::EVENT, packet);
+ });
+ RegisterAclChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
+ LOG_INFO(LOG_TAG, "Tx ACL");
+ SendHci(hci::PacketType::ACL, packet);
+ });
+ RegisterScoChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
+ LOG_INFO(LOG_TAG, "Tx SCO");
+ SendHci(hci::PacketType::SCO, packet);
+ });
+}
+
+void HciSocketDevice::TimerTick() {
+ LOG_INFO(LOG_TAG, "TimerTick fd = %d", socket_file_descriptor_);
+ h4_.OnDataReady(socket_file_descriptor_);
+ DualModeController::TimerTick();
+}
+
+void HciSocketDevice::SendHci(hci::PacketType packet_type, const std::shared_ptr<std::vector<uint8_t>> packet) {
+ if (socket_file_descriptor_ == -1) {
+ LOG_INFO(LOG_TAG, "socket_file_descriptor == -1");
+ return;
+ }
+ uint8_t type = static_cast<uint8_t>(packet_type);
+ int bytes_written;
+ bytes_written = write(socket_file_descriptor_, &type, sizeof(type));
+ if (bytes_written != sizeof(type)) {
+ LOG_INFO(LOG_TAG, "bytes_written %d != sizeof(type)", bytes_written);
+ }
+ bytes_written = write(socket_file_descriptor_, packet->data(), packet->size());
+ if (static_cast<size_t>(bytes_written) != packet->size()) {
+ LOG_INFO(LOG_TAG, "bytes_written %d != packet->size", bytes_written);
+ }
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "model/controller/dual_mode_controller.h"
+#include "model/devices/h4_packetizer.h"
+
+namespace {
+const std::string kHciSocketDevicePropertiesFile = "/etc/bluetooth/hci_socket_device_controller_properties.json";
+} // namespace
+
+namespace test_vendor_lib {
+
+class HciSocketDevice : public DualModeController {
+ public:
+ HciSocketDevice(int socket_fd);
+ ~HciSocketDevice() = default;
+
+ static std::shared_ptr<HciSocketDevice> Create(int socket_fd) {
+ return std::make_shared<HciSocketDevice>(socket_fd);
+ }
+
+ virtual std::string GetTypeString() const override {
+ return "hci_socket_device";
+ }
+
+ virtual void TimerTick() override;
+
+ void SendHci(hci::PacketType packet_type, const std::shared_ptr<std::vector<uint8_t>> packet);
+
+ private:
+ int socket_file_descriptor_{-1};
+ hci::H4Packetizer h4_{socket_file_descriptor_, [](const std::vector<uint8_t>&) {}, [](const std::vector<uint8_t>&) {},
+ [](const std::vector<uint8_t>&) {}, [](const std::vector<uint8_t>&) {}};
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2016 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 "keyboard"
+
+#include "keyboard.h"
+
+#include "model/setup/device_boutique.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+bool Keyboard::registered_ = DeviceBoutique::Register(LOG_TAG, &Keyboard::Create);
+
+Keyboard::Keyboard() {
+ properties_.SetLeAdvertisementType(BTM_BLE_CONNECT_EVT);
+ properties_.SetLeAdvertisement({0x11, // Length
+ BTM_BLE_AD_TYPE_NAME_CMPL,
+ 'g',
+ 'D',
+ 'e',
+ 'v',
+ 'i',
+ 'c',
+ 'e',
+ '-',
+ 'k',
+ 'e',
+ 'y',
+ 'b',
+ 'o',
+ 'a',
+ 'r',
+ 'd',
+ 0x03, // Length
+ 0x19,
+ 0xC1,
+ 0x03,
+ 0x03, // Length
+ 0x03,
+ 0x12,
+ 0x18,
+ 0x02, // Length
+ BTM_BLE_AD_TYPE_FLAG,
+ BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG});
+
+ properties_.SetLeScanResponse({0x04, // Length
+ BTM_BLE_AD_TYPE_NAME_SHORT, 'k', 'e', 'y'});
+}
+
+std::string Keyboard::GetTypeString() const {
+ return "keyboard";
+}
+
+void Keyboard::Initialize(const vector<std::string>& args) {
+ if (args.size() < 2) return;
+
+ Address addr;
+ if (Address::FromString(args[1], addr)) properties_.SetLeAddress(addr);
+
+ if (args.size() < 3) return;
+
+ SetAdvertisementInterval(std::chrono::milliseconds(std::stoi(args[2])));
+}
+
+void Keyboard::TimerTick() {
+ if (!connected_) {
+ Beacon::TimerTick();
+ }
+}
+
+void Keyboard::IncomingPacket(packets::LinkLayerPacketView packet) {
+ if (!connected_) {
+ Beacon::IncomingPacket(packet);
+ }
+}
+
+} // namespace test_vendor_lib
#include <cstdint>
#include <vector>
-#include "bt_address.h"
#include "device.h"
+#include "beacon.h"
+
namespace test_vendor_lib {
-class Keyboard : public Device {
+class Keyboard : public Beacon {
public:
Keyboard();
virtual ~Keyboard() = default;
- // Initialize the device based on the values of |args|.
- virtual void Initialize(const std::vector<std::string>& args) override;
+ static std::shared_ptr<Device> Create() {
+ return std::make_shared<Keyboard>();
+ }
// Return a string representation of the type of device.
virtual std::string GetTypeString() const override;
- virtual bool LeConnect();
+ // Initialize the device based on the values of |args|.
+ virtual void Initialize(const std::vector<std::string>& args) override;
+
+ virtual void IncomingPacket(packets::LinkLayerPacketView packet) override;
- virtual bool IsPageScanAvailable() const override;
-};
+ virtual void TimerTick() override;
+ private:
+ bool connected_{false};
+ static bool registered_;
+};
} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "link_layer_socket_device"
+
+#include "link_layer_socket_device.h"
+
+#include <unistd.h>
+
+#include "osi/include/log.h"
+#include "packets/link_layer/link_layer_packet_builder.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+#include "packets/view.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+LinkLayerSocketDevice::LinkLayerSocketDevice(int socket_fd, Phy::Type phy_type)
+ : socket_(socket_fd), phy_type_(phy_type) {}
+
+void LinkLayerSocketDevice::TimerTick() {
+ if (bytes_left_ == 0) {
+ received_ = std::make_shared<std::vector<uint8_t>>(Link::kSizeBytes);
+ size_t bytes_received = socket_.TryReceive(Link::kSizeBytes, received_->data());
+ if (bytes_received == 0) {
+ return;
+ }
+ CHECK(bytes_received == Link::kSizeBytes) << "bytes_received == " << bytes_received;
+ packets::PacketView<true> size({packets::View(received_, 0, Link::kSizeBytes)});
+ bytes_left_ = size.begin().extract<uint32_t>();
+ received_->resize(Link::kSizeBytes + bytes_left_);
+ offset_ = Link::kSizeBytes;
+ }
+ size_t bytes_received = socket_.TryReceive(bytes_left_, received_->data() + offset_);
+ if (bytes_received == 0) {
+ return;
+ }
+ bytes_left_ -= bytes_received;
+ offset_ += bytes_received;
+ if (bytes_left_ == 0) {
+ SendLinkLayerPacket(packets::LinkLayerPacketBuilder::ReWrap(received_), phy_type_);
+ offset_ = 0;
+ received_.reset();
+ }
+}
+
+void LinkLayerSocketDevice::IncomingPacket(packets::LinkLayerPacketView packet) {
+ socket_.TrySend(packet);
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "device.h"
+#include "include/link.h"
+#include "include/phy.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+#include "polled_socket.h"
+
+namespace test_vendor_lib {
+
+class LinkLayerSocketDevice : public Device {
+ public:
+ LinkLayerSocketDevice(int socket_fd, Phy::Type phy_type);
+ LinkLayerSocketDevice(LinkLayerSocketDevice&& s) = default;
+ virtual ~LinkLayerSocketDevice() = default;
+
+ static std::shared_ptr<Device> Create(int socket_fd, Phy::Type phy_type) {
+ return std::make_shared<LinkLayerSocketDevice>(socket_fd, phy_type);
+ }
+
+ virtual std::string GetTypeString() const override {
+ return "link_layer_socket_device";
+ }
+
+ virtual void Initialize(const std::vector<std::string>&) override {}
+
+ virtual void IncomingPacket(packets::LinkLayerPacketView packet) override;
+
+ virtual void TimerTick() override;
+
+ private:
+ net::PolledSocket socket_;
+ Phy::Type phy_type_;
+ size_t bytes_left_{0};
+ size_t offset_;
+ std::shared_ptr<std::vector<uint8_t>> received_;
+ std::vector<packets::LinkLayerPacketView> packet_queue_;
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2016 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 "loopback"
+
+#include "loopback.h"
+
+#include "le_advertisement.h"
+#include "model/setup/device_boutique.h"
+#include "osi/include/log.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+bool Loopback::registered_ = DeviceBoutique::Register(LOG_TAG, &Loopback::Create);
+
+Loopback::Loopback() {
+ advertising_interval_ms_ = std::chrono::milliseconds(1280);
+ properties_.SetLeAdvertisementType(BTM_BLE_NON_CONNECT_EVT);
+ properties_.SetLeAdvertisement({0x11, // Length
+ BTM_BLE_AD_TYPE_NAME_CMPL,
+ 'g',
+ 'D',
+ 'e',
+ 'v',
+ 'i',
+ 'c',
+ 'e',
+ '-',
+ 'l',
+ 'o',
+ 'o',
+ 'p',
+ 'b',
+ 'a',
+ 'c',
+ 'k',
+ 0x02, // Length
+ BTM_BLE_AD_TYPE_FLAG,
+ BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG});
+
+ properties_.SetLeScanResponse({0x05, // Length
+ BTM_BLE_AD_TYPE_NAME_SHORT, 'l', 'o', 'o', 'p'});
+}
+
+std::string Loopback::GetTypeString() const {
+ return "loopback";
+}
+
+std::string Loopback::ToString() const {
+ std::string dev = GetTypeString() + "@" + properties_.GetLeAddress().ToString();
+
+ return dev;
+}
+
+void Loopback::Initialize(const vector<std::string>& args) {
+ if (args.size() < 2) return;
+
+ Address addr;
+ if (Address::FromString(args[1], addr)) properties_.SetLeAddress(addr);
+
+ if (args.size() < 3) return;
+
+ SetAdvertisementInterval(std::chrono::milliseconds(std::stoi(args[2])));
+}
+
+void Loopback::TimerTick() {}
+
+void Loopback::IncomingPacket(packets::LinkLayerPacketView packet) {
+ LOG_INFO(LOG_TAG, "Got a packet of type %d", static_cast<int>(packet.GetType()));
+ if (packet.GetDestinationAddress() == properties_.GetLeAddress() && packet.GetType() == Link::PacketType::LE_SCAN) {
+ LOG_INFO(LOG_TAG, "Got a scan");
+ std::unique_ptr<packets::LeAdvertisementBuilder> scan_response = packets::LeAdvertisementBuilder::Create(
+ LeAdvertisement::AddressType::PUBLIC, LeAdvertisement::AdvertisementType::SCAN_RESPONSE,
+ properties_.GetLeScanResponse());
+ std::shared_ptr<packets::LinkLayerPacketBuilder> to_send = packets::LinkLayerPacketBuilder::WrapLeScanResponse(
+ std::move(scan_response), properties_.GetLeAddress(), packet.GetSourceAddress());
+ std::vector<std::shared_ptr<PhyLayer>> le_phys = phy_layers_[Phy::Type::LOW_ENERGY];
+ for (auto phy : le_phys) {
+ LOG_INFO(LOG_TAG, "Sending a Scan Response on a Phy");
+ phy->Send(to_send);
+ }
+ }
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2016 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 <vector>
+
+#include "device.h"
+
+namespace test_vendor_lib {
+
+// A simple device that advertises periodically and is not connectable.
+class Loopback : public Device {
+ public:
+ Loopback();
+ virtual ~Loopback() = default;
+
+ static std::shared_ptr<Device> Create() {
+ return std::make_shared<Loopback>();
+ }
+
+ // Return a string representation of the type of device.
+ virtual std::string GetTypeString() const override;
+
+ // Return a string representation of the device.
+ virtual std::string ToString() const override;
+
+ // Set the address and advertising interval from string args.
+ virtual void Initialize(const std::vector<std::string>& args) override;
+
+ virtual void IncomingPacket(packets::LinkLayerPacketView packet) override;
+
+ virtual void TimerTick() override;
+
+ private:
+ static bool registered_;
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "polled_socket"
+
+#include "polled_socket.h"
+
+#include <base/logging.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include "osi/include/log.h"
+
+namespace test_vendor_lib {
+namespace net {
+
+PolledSocket::PolledSocket(int file_descriptor) : file_descriptor_(file_descriptor) {}
+
+PolledSocket::PolledSocket(PolledSocket&& p) : file_descriptor_(p.file_descriptor_) {
+ p.file_descriptor_ = -1;
+}
+
+PolledSocket::~PolledSocket() {
+ CleanUp();
+}
+
+void PolledSocket::CleanUp() {
+ if (file_descriptor_ != -1) {
+ WHILE_EINTR(close(file_descriptor_));
+ }
+ file_descriptor_ = -1;
+}
+
+size_t PolledSocket::TrySend(packets::PacketView<true> packet) {
+ if (file_descriptor_ == -1) {
+ return 0;
+ }
+ // Could skip this copy if the packet is guaranteed to be contiguous.
+ std::vector<uint8_t> copy;
+ copy.reserve(packet.size());
+ for (const auto&& c : packet) {
+ copy.push_back(c);
+ }
+ int ret = write(file_descriptor_, copy.data(), copy.size());
+ if (ret == -1) {
+ ALOGW("%s error %s", __func__, strerror(errno));
+ return 0;
+ } else {
+ return static_cast<size_t>(ret);
+ }
+}
+
+/*
+void PolledSocket::TrySendVector(
+ const std::vector<std::vector<uint8_t>&>& raw_vectors) {
+if (file_descriptor_ < 0) {
+ return;
+}
+for (const std::vector<uint8_t>& v : raw_vectors) {
+ Send(v);
+}
+ std::vector<struct iovec> iovecs;
+ for (auto v : raw_vectors) {
+ struct iovec one_iovec;
+ one_iovec.iov_base = v.data();
+ one_iovec.iov_base = v.size();
+ iovecs.push_back(one_iovec);
+ }
+ int ret = writev(file_descriptor_, iovecs.data(), iovecs.size());
+ if (ret == -1) {
+ return 0;
+ } else {
+ return static_cast<size_t>(ret);
+ }
+}
+*/
+
+size_t PolledSocket::TryReceive(size_t num_bytes, uint8_t* data) {
+ if (file_descriptor_ == -1) return 0;
+ int ret;
+ WHILE_EINTR(ret = read(file_descriptor_, data, num_bytes));
+ if (ret < 0) {
+ if (errno == EAGAIN) {
+ return 0;
+ } else {
+ ALOGW("%s error %s", __func__, strerror(errno));
+ CleanUp();
+ return 0;
+ }
+ }
+ return ret;
+}
+
+} // namespace net
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <string>
+#include <vector>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace net {
+
+#define WHILE_EINTR(fn) \
+ do { \
+ } while ((fn) == -1 && errno == EINTR)
+
+class PolledSocket {
+ public:
+ PolledSocket(int file_descriptor);
+ PolledSocket(PolledSocket&& p);
+ virtual ~PolledSocket();
+
+ size_t TrySend(packets::PacketView<true> packet);
+ // size_t TrySendVector(const std::vector<const std::vector<uint8_t>&>& data);
+ size_t TryReceive(size_t num_bytes, uint8_t* data);
+
+ private:
+ void CleanUp();
+ int file_descriptor_{-1};
+};
+
+} // namespace net
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "remote_loopback_device"
+
+#include "remote_loopback_device.h"
+
+#include "model/setup/device_boutique.h"
+
+#include "osi/include/log.h"
+#include "packets/link_layer/link_layer_packet_builder.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+using packets::LinkLayerPacketBuilder;
+using packets::LinkLayerPacketView;
+using packets::PageResponseBuilder;
+
+bool RemoteLoopbackDevice::registered_ = DeviceBoutique::Register(LOG_TAG, &RemoteLoopbackDevice::Create);
+
+RemoteLoopbackDevice::RemoteLoopbackDevice() {}
+
+std::string RemoteLoopbackDevice::ToString() const {
+ return GetTypeString() + " (no address)";
+}
+
+void RemoteLoopbackDevice::Initialize(const std::vector<std::string>& args) {
+ if (args.size() < 2) return;
+
+ Address addr;
+ if (Address::FromString(args[1], addr)) properties_.SetAddress(addr);
+}
+
+void RemoteLoopbackDevice::IncomingPacket(LinkLayerPacketView packet) {
+ // TODO: Check sender?
+ // TODO: Handle other packet types
+ Phy::Type phy_type = Phy::Type::BR_EDR;
+
+ Link::PacketType type = packet.GetType();
+ switch (type) {
+ case Link::PacketType::PAGE:
+ SendLinkLayerPacket(LinkLayerPacketBuilder::WrapPageResponse(
+ PageResponseBuilder::Create(true), packet.GetSourceAddress(), packet.GetSourceAddress()),
+ Phy::Type::BR_EDR);
+ break;
+ default: {
+ ALOGW("Resend = %d", static_cast<int>(packet.size()));
+ std::shared_ptr<std::vector<uint8_t>> extracted_packet = std::make_shared<std::vector<uint8_t>>();
+ extracted_packet->reserve(packet.size());
+ for (const auto byte : packet) {
+ extracted_packet->push_back(byte);
+ }
+
+ SendLinkLayerPacket(LinkLayerPacketBuilder::ReWrap(extracted_packet), phy_type);
+ }
+ }
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "device.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+
+namespace test_vendor_lib {
+
+class RemoteLoopbackDevice : public Device {
+ public:
+ RemoteLoopbackDevice();
+ virtual ~RemoteLoopbackDevice() = default;
+
+ static std::shared_ptr<Device> Create() {
+ return std::make_shared<RemoteLoopbackDevice>();
+ }
+
+ virtual std::string GetTypeString() const override {
+ return "remote_loopback_device";
+ }
+
+ virtual std::string ToString() const override;
+
+ virtual void Initialize(const std::vector<std::string>& args) override;
+
+ virtual void IncomingPacket(packets::LinkLayerPacketView packet) override;
+
+ private:
+ static bool registered_;
+};
+
+} // namespace test_vendor_lib
* limitations under the License.
*/
-#define LOG_TAG "test_channel_transport"
+#define LOG_TAG "server_port_factory"
-#include "test_channel_transport.h"
+#include "server_port_factory.h"
#include <base/logging.h>
using std::vector;
namespace test_vendor_lib {
+namespace net {
-int TestChannelTransport::SetUp(int port) {
+ServerPortFactory::ServerPortFactory(int port, std::function<void(int fd)>& callback) {
+ port_ = port;
+ callback_ = callback;
+}
+
+int ServerPortFactory::SetUp(int port) {
struct sockaddr_in listen_address;
socklen_t sockaddr_in_size = sizeof(struct sockaddr_in);
memset(&listen_address, 0, sockaddr_in_size);
listen_address.sin_port = htons(port);
listen_address.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bind(listen_fd_, reinterpret_cast<sockaddr*>(&listen_address),
- sockaddr_in_size) < 0) {
+ if (bind(listen_fd_, reinterpret_cast<sockaddr*>(&listen_address), sockaddr_in_size) < 0) {
LOG_INFO(LOG_TAG, "Error binding test channel listener socket to address.");
close(listen_fd_);
return -1;
return listen_fd_;
}
-void TestChannelTransport::CleanUp() {
+void ServerPortFactory::CleanUp() {
if (listen_fd_ == -1) {
return;
}
listen_fd_ = -1;
}
-int TestChannelTransport::Accept(int listen_fd_) {
+int ServerPortFactory::Accept(int listen_fd_) {
int accept_fd = -1;
struct sockaddr_in test_channel_address;
socklen_t sockaddr_in_size = sizeof(struct sockaddr_in);
memset(&test_channel_address, 0, sockaddr_in_size);
- OSI_NO_INTR(accept_fd =
- accept(listen_fd_,
- reinterpret_cast<sockaddr*>(&test_channel_address),
- &sockaddr_in_size));
+ OSI_NO_INTR(accept_fd = accept(listen_fd_, reinterpret_cast<sockaddr*>(&test_channel_address), &sockaddr_in_size));
if (accept_fd < 0) {
- LOG_INFO(LOG_TAG, "Error accepting test channel connection errno=%d (%s).",
- errno, strerror(errno));
+ LOG_INFO(LOG_TAG, "Error accepting test channel connection errno=%d (%s).", errno, strerror(errno));
if (errno != EAGAIN && errno != EWOULDBLOCK) {
LOG_ERROR(LOG_TAG, "Closing listen_fd_ (won't try again).");
return accept_fd;
}
-void TestChannelTransport::OnCommandReady(int fd,
- std::function<void(void)> unwatch) {
+void ServerPortFactory::OnCommandReady(int fd, std::function<void(void)> unwatch) {
uint8_t command_name_size = 0;
read(fd, &command_name_size, 1);
vector<uint8_t> command_name_raw;
command_name_raw.resize(command_name_size);
read(fd, &command_name_raw[0], command_name_size);
std::string command_name(command_name_raw.begin(), command_name_raw.end());
- LOG_INFO(LOG_TAG, "Received command from test channel: %s",
- command_name.data());
if (command_name == "CLOSE_TEST_CHANNEL" || command_name == "") {
LOG_INFO(LOG_TAG, "Test channel closed");
uint8_t num_args = 0;
read(fd, &num_args, 1);
- LOG_INFO(LOG_TAG, "num_args: %d", num_args);
vector<std::string> args;
for (uint8_t i = 0; i < num_args; ++i) {
uint8_t arg_size = 0;
args.push_back(std::string(arg.begin(), arg.end()));
}
- for (size_t i = 0; i < args.size(); ++i)
- LOG_INFO(LOG_TAG, "Command argument %zu: %s", i, args[i].data());
-
command_handler_(command_name, args);
}
-void TestChannelTransport::RegisterCommandHandler(
- const std::function<void(const std::string&, const vector<std::string>&)>&
- callback) {
+void ServerPortFactory::SendResponse(int fd, const std::string& response) const {
+ size_t size = response.size();
+ // Cap to 64K
+ if (size > 0xffff) {
+ size = 0xffff;
+ }
+ char size_buf[4] = {static_cast<uint8_t>(size & 0xff), static_cast<uint8_t>((size >> 8) & 0xff),
+ static_cast<uint8_t>((size >> 16) & 0xff), static_cast<uint8_t>((size >> 24) & 0xff)};
+ int written = write(fd, size_buf, 4);
+ CHECK(written == 4) << "What happened? written = " << written << "errno =" << errno;
+ written = write(fd, response.c_str(), size);
+ CHECK(written == static_cast<int>(size)) << "What happened? written = " << written << "errno =" << errno;
+}
+
+void ServerPortFactory::RegisterCommandHandler(
+ const std::function<void(const std::string&, const std::vector<std::string>&)>& callback) {
command_handler_ = callback;
}
+} // namespace net
} // namespace test_vendor_lib
--- /dev/null
+/*
+ * 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 <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace test_vendor_lib {
+namespace net {
+
+// Starts a server and calls the registered lambda for each connection.
+class ServerPortFactory {
+ public:
+ // Opens a server port and sets the listen file descriptor.
+ ServerPortFactory(int port, std::function<void(int fd)>& on_connection);
+
+ // Closes the port (if succesfully opened in SetUp).
+ ~ServerPortFactory() {}
+
+ // Waits for a connection request and returns the file descriptor to watch.
+ // Returns -1 on an error.
+ void Accept(int listen_fd);
+
+ private:
+ std::function<void(int fd)> on_connection_;
+
+ int port;
+ int listen_fd_ = -1;
+
+ ServerPortFactory(const ServerPortFactory&) = delete;
+ ServerPortFactory& operator=(const ServerPortFactory&) = delete;
+};
+
+} // namespace net
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "sniffer"
+
+#include "sniffer.h"
+
+#include "osi/include/log.h"
+
+#include "model/setup/device_boutique.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+bool Sniffer::registered_ = DeviceBoutique::Register(LOG_TAG, &Sniffer::Create);
+
+Sniffer::Sniffer() {}
+
+void Sniffer::Initialize(const vector<std::string>& args) {
+ if (args.size() < 2) return;
+
+ if (Address::FromString(args[1], device_to_sniff_)) {
+ properties_.SetAddress(device_to_sniff_);
+ }
+
+ if (args.size() < 3) return;
+}
+
+void Sniffer::TimerTick() {}
+
+void Sniffer::IncomingPacket(packets::LinkLayerPacketView packet) {
+ Address source = packet.GetSourceAddress();
+ Address dest = packet.GetDestinationAddress();
+ bool match_source = device_to_sniff_ == source;
+ bool match_dest = device_to_sniff_ == dest;
+ if (!match_source && !match_dest) {
+ return;
+ }
+ LOG_INFO(LOG_TAG, "%s %s -> %s (Type %d)", (match_source ? (match_dest ? "<->" : "<--") : "-->"),
+ source.ToString().c_str(), dest.ToString().c_str(), static_cast<int>(packet.GetType()));
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "device.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+#include "types/address.h"
+
+namespace test_vendor_lib {
+
+class Sniffer : public Device {
+ public:
+ Sniffer();
+ ~Sniffer() = default;
+
+ static std::shared_ptr<Sniffer> Create() {
+ return std::make_shared<Sniffer>();
+ }
+
+ // Initialize the device based on the values of |args|.
+ virtual void Initialize(const std::vector<std::string>& args) override;
+
+ // Return a string representation of the type of device.
+ virtual std::string GetTypeString() const override {
+ return "sniffer";
+ }
+
+ virtual void IncomingPacket(packets::LinkLayerPacketView packet) override;
+
+ virtual void TimerTick() override;
+
+ private:
+ static bool registered_;
+ Address device_to_sniff_;
+};
+
+} // namespace test_vendor_lib
// This number also states the maximum number of scheduled tasks we can handle
// at a given time
-static const uint16_t kMaxTaskId =
- -1; /* 2^16 - 1, permisible ids are {1..2^16-1}*/
+static const uint16_t kMaxTaskId = -1; /* 2^16 - 1, permisible ids are {1..2^16-1}*/
static inline AsyncTaskId NextAsyncTaskId(const AsyncTaskId id) {
return (id == kMaxTaskId) ? 1 : id + 1;
}
// Async File Descriptor Watcher Implementation:
class AsyncManager::AsyncFdWatcher {
public:
- int WatchFdForNonBlockingReads(
- int file_descriptor, const ReadCallback& on_read_fd_ready_callback) {
+ int WatchFdForNonBlockingReads(int file_descriptor, const ReadCallback& on_read_fd_ready_callback) {
// add file descriptor and callback
{
std::unique_lock<std::mutex> guard(internal_mutex_);
if (std::this_thread::get_id() != thread_.get_id()) {
thread_.join();
} else {
- LOG_WARN(LOG_TAG,
- "%s: Starting thread stop from inside the reading thread itself",
- __func__);
+ LOG_WARN(LOG_TAG, "%s: Starting thread stop from inside the reading thread itself", __func__);
}
{
int notifyThread() {
char buffer = '0';
if (TEMP_FAILURE_RETRY(write(notification_write_fd_, &buffer, 1)) < 0) {
- LOG_ERROR(LOG_TAG, "%s: Unable to send message to reading thread",
- __func__);
+ LOG_ERROR(LOG_TAG, "%s: Unable to send message to reading thread", __func__);
return -1;
}
return 0;
bool consumeThreadNotifications(fd_set& read_fds) {
if (FD_ISSET(notification_listen_fd_, &read_fds)) {
char buffer[kNotificationBufferSize];
- while (TEMP_FAILURE_RETRY(read(notification_listen_fd_, buffer,
- kNotificationBufferSize)) ==
+ while (TEMP_FAILURE_RETRY(read(notification_listen_fd_, buffer, kNotificationBufferSize)) ==
kNotificationBufferSize) {
}
return true;
if (retval <= 0) { // there was some error or a timeout
LOG_ERROR(LOG_TAG,
"%s: There was an error while waiting for data on the file "
- "descriptors",
- __func__);
+ "descriptors: %s",
+ __func__, strerror(errno));
continue;
}
// Async task manager implementation
class AsyncManager::AsyncTaskManager {
public:
- AsyncTaskId ExecAsync(std::chrono::milliseconds delay,
- const TaskCallback& callback) {
- return scheduleTask(std::make_shared<Task>(
- std::chrono::steady_clock::now() + delay, callback));
+ AsyncTaskId ExecAsync(std::chrono::milliseconds delay, const TaskCallback& callback) {
+ return scheduleTask(std::make_shared<Task>(std::chrono::steady_clock::now() + delay, callback));
}
- AsyncTaskId ExecAsyncPeriodically(std::chrono::milliseconds delay,
- std::chrono::milliseconds period,
+ AsyncTaskId ExecAsyncPeriodically(std::chrono::milliseconds delay, std::chrono::milliseconds period,
const TaskCallback& callback) {
- return scheduleTask(std::make_shared<Task>(
- std::chrono::steady_clock::now() + delay, period, callback));
+ return scheduleTask(std::make_shared<Task>(std::chrono::steady_clock::now() + delay, period, callback));
}
bool CancelAsyncTask(AsyncTaskId async_task_id) {
if (std::this_thread::get_id() != thread_.get_id()) {
thread_.join();
} else {
- LOG_WARN(LOG_TAG,
- "%s: Starting thread stop from inside the task thread itself",
- __func__);
+ LOG_WARN(LOG_TAG, "%s: Starting thread stop from inside the task thread itself", __func__);
}
return 0;
}
// Holds the data for each task
class Task {
public:
- Task(std::chrono::steady_clock::time_point time,
- std::chrono::milliseconds period, const TaskCallback& callback)
- : time(time),
- periodic(true),
- period(period),
- callback(callback),
- task_id(kInvalidTaskId) {}
- Task(std::chrono::steady_clock::time_point time,
- const TaskCallback& callback)
- : time(time),
- periodic(false),
- callback(callback),
- task_id(kInvalidTaskId) {}
+ Task(std::chrono::steady_clock::time_point time, std::chrono::milliseconds period, const TaskCallback& callback)
+ : time(time), periodic(true), period(period), callback(callback), task_id(kInvalidTaskId) {}
+ Task(std::chrono::steady_clock::time_point time, const TaskCallback& callback)
+ : time(time), periodic(false), callback(callback), task_id(kInvalidTaskId) {}
// Operators needed to be in a collection
bool operator<(const Task& another) const {
- return std::make_pair(time, task_id) <
- std::make_pair(another.time, another.task_id);
+ return std::make_pair(time, task_id) < std::make_pair(another.time, another.task_id);
}
- bool isPeriodic() const { return periodic; }
+ bool isPeriodic() const {
+ return periodic;
+ }
// These fields should no longer be public if the class ever becomes
// public or gets more complex
// A comparator class to put shared pointers to tasks in an ordered set
struct task_p_comparator {
- bool operator()(const std::shared_ptr<Task>& t1,
- const std::shared_ptr<Task>& t2) const {
+ bool operator()(const std::shared_ptr<Task>& t1, const std::shared_ptr<Task>& t2) const {
return *t1 < *t2;
}
};
};
// Async Manager Implementation:
-AsyncManager::AsyncManager()
- : fdWatcher_p_(new AsyncFdWatcher()),
- taskManager_p_(new AsyncTaskManager()) {}
+AsyncManager::AsyncManager() : fdWatcher_p_(new AsyncFdWatcher()), taskManager_p_(new AsyncTaskManager()) {}
AsyncManager::~AsyncManager() {
// Make sure the threads are stopped before destroying the object.
taskManager_p_->stopThread();
}
-int AsyncManager::WatchFdForNonBlockingReads(
- int file_descriptor, const ReadCallback& on_read_fd_ready_callback) {
- return fdWatcher_p_->WatchFdForNonBlockingReads(file_descriptor,
- on_read_fd_ready_callback);
+int AsyncManager::WatchFdForNonBlockingReads(int file_descriptor, const ReadCallback& on_read_fd_ready_callback) {
+ return fdWatcher_p_->WatchFdForNonBlockingReads(file_descriptor, on_read_fd_ready_callback);
}
void AsyncManager::StopWatchingFileDescriptor(int file_descriptor) {
fdWatcher_p_->StopWatchingFileDescriptor(file_descriptor);
}
-AsyncTaskId AsyncManager::ExecAsync(std::chrono::milliseconds delay,
- const TaskCallback& callback) {
+AsyncTaskId AsyncManager::ExecAsync(std::chrono::milliseconds delay, const TaskCallback& callback) {
return taskManager_p_->ExecAsync(delay, callback);
}
-AsyncTaskId AsyncManager::ExecAsyncPeriodically(
- std::chrono::milliseconds delay, std::chrono::milliseconds period,
- const TaskCallback& callback) {
+AsyncTaskId AsyncManager::ExecAsyncPeriodically(std::chrono::milliseconds delay, std::chrono::milliseconds period,
+ const TaskCallback& callback) {
return taskManager_p_->ExecAsyncPeriodically(delay, period, callback);
}
// made about when in the future the callback will be called, in particular,
// it is perfectly possible to have it called before this function returns. A
// return of 0 means success, an error code is returned otherwise.
- int WatchFdForNonBlockingReads(int file_descriptor,
- const ReadCallback& on_read_fd_ready_callback);
+ int WatchFdForNonBlockingReads(int file_descriptor, const ReadCallback& on_read_fd_ready_callback);
// If the fd was not being watched before the call will be ignored.
void StopWatchingFileDescriptor(int file_descriptor);
// Schedules an action to occur in the future. Even if the delay given is not
// positive the callback will be called asynchronously.
- AsyncTaskId ExecAsync(std::chrono::milliseconds delay,
- const TaskCallback& callback);
+ AsyncTaskId ExecAsync(std::chrono::milliseconds delay, const TaskCallback& callback);
// Schedules an action to occur periodically in the future. If the delay given
// is not positive the callback will be asynchronously called once for each
// time in the past that it should have been called and then scheduled for
// future times.
- AsyncTaskId ExecAsyncPeriodically(std::chrono::milliseconds delay,
- std::chrono::milliseconds period,
+ AsyncTaskId ExecAsyncPeriodically(std::chrono::milliseconds delay, std::chrono::milliseconds period,
const TaskCallback& callback);
// Cancels the/every future ocurrence of the action specified by this id. It
--- /dev/null
+/*
+ * Copyright 2018 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_boutique"
+
+#include "device_boutique.h"
+
+#include "base/logging.h"
+#include "osi/include/log.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+std::unordered_map<std::string, std::function<std::shared_ptr<Device>()>>& DeviceBoutique::GetMap() {
+ static std::unordered_map<std::string, std::function<std::shared_ptr<Device>()>> impl;
+ return impl;
+}
+
+// Register a constructor for a device type.
+bool DeviceBoutique::Register(const std::string& device_type,
+ const std::function<std::shared_ptr<Device>()> device_constructor) {
+ LOG_INFO(LOG_TAG, "Registering %s", device_type.c_str());
+ GetMap()[device_type] = device_constructor;
+ return true;
+}
+
+std::shared_ptr<Device> DeviceBoutique::Create(const vector<std::string>& args) {
+ CHECK(!args.empty());
+
+ if (GetMap().find(args[0]) == GetMap().end()) {
+ LOG_WARN(LOG_TAG, "No constructor registered for %s", args[0].c_str());
+ return std::shared_ptr<Device>(nullptr);
+ }
+
+ std::shared_ptr<Device> new_device = GetMap()[args[0]]();
+ if (new_device != nullptr) new_device->Initialize(args);
+
+ return new_device;
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "model/devices/device.h"
+
+namespace test_vendor_lib {
+
+// Create customized devices from a centralized shop.
+class DeviceBoutique {
+ public:
+ DeviceBoutique();
+ virtual ~DeviceBoutique() = default;
+
+ // Register a constructor for a device type.
+ static bool Register(const std::string& device_type, const std::function<std::shared_ptr<Device>()> method);
+
+ // Call the constructor that matches arg[0], then call dev->Initialize(args).
+ static std::shared_ptr<Device> Create(const std::vector<std::string>& args);
+
+ template <typename D>
+ struct Registrar {
+ explicit Registrar(std::string const& name) {
+ DeviceBoutique::Register(name, &D::Create);
+ }
+ static Registrar<D> registrar_;
+ };
+
+ private:
+ static std::unordered_map<std::string, std::function<std::shared_ptr<Device>()>>& GetMap();
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "include/phy.h"
+#include "packets/link_layer/link_layer_packet_builder.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+
+namespace test_vendor_lib {
+
+class PhyLayer {
+ public:
+ PhyLayer(Phy::Type phy_type, uint32_t id, const std::function<void(packets::LinkLayerPacketView)>& device_receive)
+ : phy_type_(phy_type), id_(id), transmit_to_device_(device_receive) {}
+
+ virtual void Send(const std::shared_ptr<packets::LinkLayerPacketBuilder> packet) = 0;
+
+ virtual void Receive(packets::LinkLayerPacketView packet) = 0;
+
+ virtual void TimerTick() = 0;
+
+ Phy::Type GetType() {
+ return phy_type_;
+ }
+
+ uint32_t GetId() {
+ return id_;
+ }
+
+ virtual ~PhyLayer() = default;
+
+ private:
+ Phy::Type phy_type_;
+ uint32_t id_;
+
+ protected:
+ const std::function<void(packets::LinkLayerPacketView)> transmit_to_device_;
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "phy_layer_factory"
+
+#include "phy_layer_factory.h"
+
+#include "base/logging.h"
+
+#include "osi/include/log.h"
+
+namespace test_vendor_lib {
+
+PhyLayerFactory::PhyLayerFactory(Phy::Type phy_type) : phy_type_(phy_type) {}
+
+Phy::Type PhyLayerFactory::GetType() {
+ return phy_type_;
+}
+
+std::shared_ptr<PhyLayer> PhyLayerFactory::GetPhyLayer(
+ const std::function<void(packets::LinkLayerPacketView)>& device_receive) {
+ std::shared_ptr<PhyLayer> new_phy =
+ std::make_shared<PhyLayerImpl>(phy_type_, next_id_++, device_receive, std::shared_ptr<PhyLayerFactory>(this));
+ phy_layers_.push_back(new_phy);
+ return new_phy;
+}
+
+void PhyLayerFactory::UnregisterPhyLayer(uint32_t id) {
+ for (auto it = phy_layers_.begin(); it != phy_layers_.end(); it++) {
+ if ((*it)->GetId() == id) {
+ phy_layers_.erase(it);
+ }
+ }
+}
+
+void PhyLayerFactory::Send(const std::shared_ptr<packets::LinkLayerPacketBuilder> packet, uint32_t id) {
+ // Convert from a Builder to a View
+ std::shared_ptr<std::vector<uint8_t>> serialized_packet =
+ std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>());
+ std::back_insert_iterator<std::vector<uint8_t>> itr(*serialized_packet);
+ serialized_packet->reserve(packet->size());
+ packet->Serialize(itr);
+ packets::LinkLayerPacketView packet_view = packets::LinkLayerPacketView::Create(serialized_packet);
+
+ for (const auto phy : phy_layers_) {
+ if (id != phy->GetId()) {
+ phy->Receive(packet_view);
+ }
+ }
+}
+
+void PhyLayerFactory::TimerTick() {
+ for (auto phy : phy_layers_) {
+ phy->TimerTick();
+ }
+}
+
+std::string PhyLayerFactory::ToString() const {
+ switch (phy_type_) {
+ case Phy::Type::LOW_ENERGY:
+ return "LOW_ENERGY";
+ break;
+ case Phy::Type::BR_EDR:
+ return "BR_EDR";
+ break;
+ default:
+ return "Unknown";
+ }
+}
+
+PhyLayerImpl::PhyLayerImpl(Phy::Type phy_type, uint32_t id,
+ const std::function<void(packets::LinkLayerPacketView)>& device_receive,
+ const std::shared_ptr<PhyLayerFactory>& factory)
+ : PhyLayer(phy_type, id, device_receive), factory_(factory) {}
+
+PhyLayerImpl::~PhyLayerImpl() {
+ factory_->UnregisterPhyLayer(GetId());
+ PhyLayer::~PhyLayer();
+}
+
+void PhyLayerImpl::Send(const std::shared_ptr<packets::LinkLayerPacketBuilder> packet) {
+ factory_->Send(packet, GetId());
+}
+
+void PhyLayerImpl::Receive(packets::LinkLayerPacketView packet) {
+ transmit_to_device_(packet);
+}
+
+void PhyLayerImpl::TimerTick() {}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <memory>
+#include <vector>
+
+#include "include/phy.h"
+#include "packets/link_layer/link_layer_packet_builder.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+#include "phy_layer.h"
+
+namespace test_vendor_lib {
+
+class PhyLayerFactory {
+ friend class PhyLayerImpl;
+
+ public:
+ PhyLayerFactory(Phy::Type phy_type);
+
+ virtual ~PhyLayerFactory() = default;
+
+ Phy::Type GetType();
+
+ std::shared_ptr<PhyLayer> GetPhyLayer(const std::function<void(packets::LinkLayerPacketView)>& device_receive);
+
+ void UnregisterPhyLayer(uint32_t id);
+
+ virtual void TimerTick();
+
+ virtual std::string ToString() const;
+
+ protected:
+ virtual void Send(const std::shared_ptr<packets::LinkLayerPacketBuilder> packet, uint32_t id);
+
+ private:
+ Phy::Type phy_type_;
+ std::vector<std::shared_ptr<PhyLayer>> phy_layers_;
+ uint32_t next_id_{1};
+};
+
+class PhyLayerImpl : public PhyLayer {
+ public:
+ PhyLayerImpl(Phy::Type phy_type, uint32_t id, const std::function<void(packets::LinkLayerPacketView)>& device_receive,
+ const std::shared_ptr<PhyLayerFactory>& factory);
+ virtual ~PhyLayerImpl() override;
+
+ virtual void Send(const std::shared_ptr<packets::LinkLayerPacketBuilder> packet) override;
+ virtual void Receive(packets::LinkLayerPacketView packet) override;
+ virtual void TimerTick() override;
+
+ private:
+ std::shared_ptr<PhyLayerFactory> factory_;
+};
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * 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 "test_channel_transport"
+
+#include "test_channel_transport.h"
+
+#include <base/logging.h>
+
+#include "osi/include/log.h"
+#include "osi/include/osi.h"
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+int TestChannelTransport::SetUp(int port) {
+ struct sockaddr_in listen_address;
+ socklen_t sockaddr_in_size = sizeof(struct sockaddr_in);
+ memset(&listen_address, 0, sockaddr_in_size);
+
+ OSI_NO_INTR(listen_fd_ = socket(AF_INET, SOCK_STREAM, 0));
+ if (listen_fd_ < 0) {
+ LOG_INFO(LOG_TAG, "Error creating socket for test channel.");
+ return -1;
+ }
+
+ LOG_INFO(LOG_TAG, "port: %d", port);
+ listen_address.sin_family = AF_INET;
+ listen_address.sin_port = htons(port);
+ listen_address.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if (bind(listen_fd_, reinterpret_cast<sockaddr*>(&listen_address), sockaddr_in_size) < 0) {
+ LOG_INFO(LOG_TAG, "Error binding test channel listener socket to address.");
+ close(listen_fd_);
+ return -1;
+ }
+
+ if (listen(listen_fd_, 1) < 0) {
+ LOG_INFO(LOG_TAG, "Error listening for test channel.");
+ close(listen_fd_);
+ return -1;
+ }
+ return listen_fd_;
+}
+
+void TestChannelTransport::CleanUp() {
+ if (listen_fd_ == -1) {
+ return;
+ }
+ if (close(listen_fd_)) {
+ LOG_ERROR(LOG_TAG, "Error closing listen_fd_.");
+ }
+ listen_fd_ = -1;
+}
+
+int TestChannelTransport::Accept(int listen_fd_) {
+ int accept_fd = -1;
+
+ OSI_NO_INTR(accept_fd = accept(listen_fd_, NULL, NULL));
+
+ if (accept_fd < 0) {
+ LOG_INFO(LOG_TAG, "Error accepting test channel connection errno=%d (%s).", errno, strerror(errno));
+
+ if (errno != EAGAIN && errno != EWOULDBLOCK) {
+ LOG_ERROR(LOG_TAG, "Closing listen_fd_ (won't try again).");
+ close(listen_fd_);
+ return -1;
+ }
+ }
+
+ LOG_INFO(LOG_TAG, "accept_fd = %d.", accept_fd);
+
+ return accept_fd;
+}
+
+void TestChannelTransport::OnCommandReady(int fd, std::function<void(void)> unwatch) {
+ uint8_t command_name_size = 0;
+ int bytes_read = read(fd, &command_name_size, 1);
+ if (bytes_read != 1) {
+ LOG_INFO(LOG_TAG, "Unexpected (command_name_size) bytes_read: %d != %d", bytes_read, 1);
+ }
+ vector<uint8_t> command_name_raw;
+ command_name_raw.resize(command_name_size);
+ bytes_read = read(fd, &command_name_raw[0], command_name_size);
+ if (bytes_read != command_name_size) {
+ LOG_INFO(LOG_TAG, "Unexpected (command_name) bytes_read: %d != %d", bytes_read, command_name_size);
+ }
+ std::string command_name(command_name_raw.begin(), command_name_raw.end());
+
+ if (command_name == "CLOSE_TEST_CHANNEL" || command_name == "") {
+ LOG_INFO(LOG_TAG, "Test channel closed");
+ unwatch();
+ close(fd);
+ return;
+ }
+
+ uint8_t num_args = 0;
+ bytes_read = read(fd, &num_args, 1);
+ if (bytes_read != 1) {
+ LOG_INFO(LOG_TAG, "Unexpected (num_args) bytes_read: %d != %d", bytes_read, 1);
+ }
+ vector<std::string> args;
+ for (uint8_t i = 0; i < num_args; ++i) {
+ uint8_t arg_size = 0;
+ bytes_read = read(fd, &arg_size, 1);
+ if (bytes_read != 1) {
+ LOG_INFO(LOG_TAG, "Unexpected (arg_size) bytes_read: %d != %d", bytes_read, 1);
+ }
+ vector<uint8_t> arg;
+ arg.resize(arg_size);
+ bytes_read = read(fd, &arg[0], arg_size);
+ if (bytes_read != arg_size) {
+ LOG_INFO(LOG_TAG, "Unexpected (arg) bytes_read: %d != %d", bytes_read, arg_size);
+ }
+ args.push_back(std::string(arg.begin(), arg.end()));
+ }
+
+ command_handler_(command_name, args);
+}
+
+void TestChannelTransport::SendResponse(int fd, const std::string& response) const {
+ size_t size = response.size();
+ // Cap to 64K
+ if (size > 0xffff) {
+ size = 0xffff;
+ }
+ uint8_t size_buf[4] = {static_cast<uint8_t>(size & 0xff), static_cast<uint8_t>((size >> 8) & 0xff),
+ static_cast<uint8_t>((size >> 16) & 0xff), static_cast<uint8_t>((size >> 24) & 0xff)};
+ int written = write(fd, size_buf, 4);
+ CHECK(written == 4) << "What happened? written = " << written << "errno =" << errno;
+ written = write(fd, response.c_str(), size);
+ CHECK(written == static_cast<int>(size)) << "What happened? written = " << written << "errno =" << errno;
+}
+
+void TestChannelTransport::RegisterCommandHandler(
+ const std::function<void(const std::string&, const std::vector<std::string>&)>& callback) {
+ command_handler_ = callback;
+}
+
+} // namespace test_vendor_lib
#include <string>
#include <vector>
-#include "base/files/scoped_file.h"
+//#include "base/files/scoped_file.h"
namespace test_vendor_lib {
int Accept(int listen_fd);
// Sets the callback that fires when data is read in WatchFd().
- void RegisterCommandHandler(
- const std::function<void(const std::string&,
- const std::vector<std::string>&)>& callback);
+ void RegisterCommandHandler(const std::function<void(const std::string&, const std::vector<std::string>&)>& callback);
+
+ // Send data back to the test channel.
+ void SendResponse(int fd, const std::string&) const;
void OnCommandReady(int fd, std::function<void(void)> unwatch);
private:
- std::function<void(const std::string&, const std::vector<std::string>&)>
- command_handler_;
+ std::function<void(const std::string&, const std::vector<std::string>&)> command_handler_;
int listen_fd_ = -1;
--- /dev/null
+/*
+ * Copyright 2018 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 "test_command_handler"
+
+#include "test_command_handler.h"
+#include "device_boutique.h"
+#include "phy.h"
+
+#include <memory>
+
+#include <stdlib.h>
+
+#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"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+TestCommandHandler::TestCommandHandler(TestModel& test_model) : model_(test_model) {
+#define SET_HANDLER(command_name, method) \
+ active_commands_[command_name] = [this](const vector<std::string>& param) { method(param); };
+ SET_HANDLER("add", Add);
+ SET_HANDLER("add_remote", AddRemote);
+ SET_HANDLER("del", Del);
+ SET_HANDLER("add_phy", AddPhy);
+ SET_HANDLER("del_phy", DelPhy);
+ SET_HANDLER("add_device_to_phy", AddDeviceToPhy);
+ SET_HANDLER("del_device_from_phy", DelDeviceFromPhy);
+ SET_HANDLER("list", List);
+ SET_HANDLER("set_timer_period", SetTimerPeriod);
+ SET_HANDLER("start_timer", StartTimer);
+ SET_HANDLER("stop_timer", StopTimer);
+#undef SET_HANDLER
+}
+
+void TestCommandHandler::AddDefaults() {
+ // Add a phy for LE and one for BR/EDR
+ AddPhy({"LOW_ENERGY"});
+ AddPhy({"BR_EDR"});
+
+ // Add the controller to the Phys
+ AddDeviceToPhy({"0", "0"});
+ AddDeviceToPhy({"0", "1"});
+
+ // Add default test devices and add the devices to the phys
+ // Add({"beacon", "be:ac:10:00:00:01", "1000"});
+ // AddDeviceToPhy({"1", "0"});
+
+ // Add({"keyboard", "cc:1c:eb:0a:12:d1", "500"});
+ // AddDeviceToPhy({"2", "0"});
+
+ // Add({"classic", "c1:a5:51:c0:00:01", "22"});
+ // AddDeviceToPhy({"3", "1"});
+
+ // Add({"car_kit", "ca:12:1c:17:00:01", "238"});
+ // AddDeviceToPhy({"4", "1"});
+
+ // Add({"sniffer", "ca:12:1c:17:00:01"});
+ // AddDeviceToPhy({"5", "1"});
+
+ // Add({"sniffer", "3c:5a:b4:04:05:06"});
+ // AddDeviceToPhy({"1", "1"});
+ // Add({"remote_loopback_device", "10:0d:00:ba:c1:06"});
+ // AddDeviceToPhy({"2", "1"});
+ List({});
+
+ SetTimerPeriod({"10"});
+ StartTimer({});
+}
+
+void TestCommandHandler::HandleCommand(const std::string& name, const vector<std::string>& args) {
+ if (active_commands_.count(name) == 0) {
+ response_string_ = "Unhandled command: " + name;
+ send_response_(response_string_);
+ return;
+ }
+ active_commands_[name](args);
+}
+
+void TestCommandHandler::RegisterSendResponse(const std::function<void(const std::string&)> callback) {
+ send_response_ = callback;
+ send_response_("RegisterSendResponse called");
+}
+
+void TestCommandHandler::Add(const vector<std::string>& args) {
+ if (args.size() < 1) {
+ response_string_ = "TestCommandHandler 'add' takes an argument";
+ send_response_(response_string_);
+ return;
+ }
+ std::shared_ptr<Device> new_dev = DeviceBoutique::Create(args);
+
+ if (new_dev == NULL) {
+ response_string_ = "TestCommandHandler 'add' " + args[0] + " failed!";
+ send_response_(response_string_);
+ LOG_WARN(LOG_TAG, "%s", response_string_.c_str());
+ return;
+ }
+
+ LOG_INFO(LOG_TAG, "Add %s", new_dev->ToString().c_str());
+ size_t dev_index = model_.Add(new_dev);
+ response_string_ = std::to_string(dev_index) + std::string(":") + new_dev->ToString();
+ send_response_(response_string_);
+}
+
+void TestCommandHandler::AddRemote(const vector<std::string>& args) {
+ if (args.size() < 3) {
+ response_string_ = "TestCommandHandler usage: add_remote host port phy_type";
+ send_response_(response_string_);
+ return;
+ }
+
+ size_t port = std::stoi(args[1]);
+ Phy::Type phy_type = Phy::Type::BR_EDR;
+ if ("LOW_ENERGY" == args[2]) {
+ phy_type = Phy::Type::LOW_ENERGY;
+ }
+ if (port == 0 || port > 0xffff || args[0].size() < 2) {
+ response_string_ = "TestCommandHandler bad arguments to 'add_remote': ";
+ response_string_ += args[0];
+ response_string_ += "@";
+ response_string_ += args[1];
+ send_response_(response_string_);
+ return;
+ }
+
+ model_.AddRemote(args[0], port, phy_type);
+
+ response_string_ = args[0] + std::string("@") + std::to_string(port);
+ send_response_(response_string_);
+}
+
+void TestCommandHandler::Del(const vector<std::string>& args) {
+ size_t dev_index = std::stoi(args[0]);
+
+ model_.Del(dev_index);
+ response_string_ = "TestCommandHandler 'del' called with device at index " + std::to_string(dev_index);
+ send_response_(response_string_);
+}
+
+void TestCommandHandler::AddPhy(const vector<std::string>& args) {
+ if (args[0] == "LOW_ENERGY") {
+ std::shared_ptr<PhyLayerFactory> new_phy = std::make_shared<PhyLayerFactory>(Phy::Type::LOW_ENERGY);
+ model_.AddPhy(new_phy);
+ } else if (args[0] == "BR_EDR") {
+ std::shared_ptr<PhyLayerFactory> new_phy = std::make_shared<PhyLayerFactory>(Phy::Type::BR_EDR);
+ model_.AddPhy(new_phy);
+ } else {
+ response_string_ = "TestCommandHandler 'add_phy' with unrecognized type " + args[0];
+ send_response_(response_string_);
+ }
+}
+
+void TestCommandHandler::DelPhy(const vector<std::string>& args) {
+ size_t phy_index = std::stoi(args[0]);
+
+ model_.DelPhy(phy_index);
+ response_string_ = "TestCommandHandler 'del_phy' called with phy at index " + std::to_string(phy_index);
+ send_response_(response_string_);
+}
+
+void TestCommandHandler::AddDeviceToPhy(const vector<std::string>& args) {
+ if (args.size() != 2) {
+ response_string_ = "TestCommandHandler 'add_device_to_phy' takes two arguments";
+ send_response_(response_string_);
+ return;
+ }
+ size_t dev_index = std::stoi(args[0]);
+ size_t phy_index = std::stoi(args[1]);
+ model_.AddDeviceToPhy(dev_index, phy_index);
+ response_string_ = "TestCommandHandler 'add_device_to_phy' called with device " + std::to_string(dev_index) +
+ " and phy " + std::to_string(phy_index);
+ send_response_(response_string_);
+ return;
+}
+
+void TestCommandHandler::DelDeviceFromPhy(const vector<std::string>& args) {
+ if (args.size() != 2) {
+ response_string_ = "TestCommandHandler 'del_device_from_phy' takes two arguments";
+ send_response_(response_string_);
+ return;
+ }
+ size_t dev_index = std::stoi(args[0]);
+ size_t phy_index = std::stoi(args[1]);
+ model_.DelDeviceFromPhy(dev_index, phy_index);
+ response_string_ = "TestCommandHandler 'del_device_from_phy' called with device " + std::to_string(dev_index) +
+ " and phy " + std::to_string(phy_index);
+ send_response_(response_string_);
+ return;
+}
+
+void TestCommandHandler::List(const vector<std::string>& args) {
+ if (args.size() > 0) {
+ LOG_INFO(LOG_TAG, "Unused args: arg[0] = %s", args[0].c_str());
+ return;
+ }
+ send_response_(model_.List());
+}
+
+void TestCommandHandler::SetTimerPeriod(const vector<std::string>& args) {
+ if (args.size() != 1) {
+ LOG_INFO(LOG_TAG, "SetTimerPeriod takes 1 argument");
+ }
+ size_t period = std::stoi(args[0]);
+ model_.SetTimerPeriod(std::chrono::milliseconds(period));
+}
+
+void TestCommandHandler::StartTimer(const vector<std::string>& args) {
+ if (args.size() > 0) {
+ LOG_INFO(LOG_TAG, "Unused args: arg[0] = %s", args[0].c_str());
+ }
+ model_.StartTimer();
+}
+
+void TestCommandHandler::StopTimer(const vector<std::string>& args) {
+ if (args.size() > 0) {
+ LOG_INFO(LOG_TAG, "Unused args: arg[0] = %s", args[0].c_str());
+ }
+ model_.StopTimer();
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <unistd.h>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "model/devices/device.h"
+#include "phy_layer_factory.h"
+#include "test_channel_transport.h"
+#include "test_model.h"
+
+namespace test_vendor_lib {
+
+class TestCommandHandler {
+ public:
+ // Sets all of the methods to be used as callbacks in the HciHandler.
+ TestCommandHandler(TestModel& test_model);
+
+ ~TestCommandHandler() = default;
+
+ // Dispatches the action corresponding to the command specified by |name|.
+ void HandleCommand(const std::string& name, const std::vector<std::string>& args);
+
+ // Dispatches the action corresponding to the command specified by |name|.
+ void RegisterSendResponse(const std::function<void(const std::string&)> callback);
+
+ // Commands:
+
+ // Add a device
+ void Add(const std::vector<std::string>& args);
+
+ // Add a remote device
+ void AddRemote(const std::vector<std::string>& args);
+
+ // Remove devices by index
+ void Del(const std::vector<std::string>& args);
+
+ // Add phy
+ void AddPhy(const std::vector<std::string>& args);
+
+ // Remove phy by name
+ void DelPhy(const std::vector<std::string>& args);
+
+ // Add device to phy
+ void AddDeviceToPhy(const std::vector<std::string>& args);
+
+ // Remove device from phy
+ void DelDeviceFromPhy(const std::vector<std::string>& args);
+
+ // List the devices that the test knows about
+ void List(const std::vector<std::string>& args);
+
+ // Timer management functions
+ void SetTimerPeriod(const std::vector<std::string>& args);
+
+ void StartTimer(const std::vector<std::string>& args);
+
+ void StopTimer(const std::vector<std::string>& args);
+
+ // For manual testing
+ void AddDefaults();
+
+ private:
+ TestModel& model_;
+
+ std::string response_string_;
+
+ std::unordered_map<std::string, std::function<void(const std::vector<std::string>&)>> active_commands_;
+
+ std::function<void(const std::string&)> send_response_;
+
+ TestCommandHandler(const TestCommandHandler& cmdPckt) = delete;
+ TestCommandHandler& operator=(const TestCommandHandler& cmdPckt) = delete;
+};
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "test_model"
+
+#include "test_model.h"
+
+// TODO: Remove when registration works
+#include "model/devices/beacon.h"
+#include "model/devices/beacon_swarm.h"
+#include "model/devices/car_kit.h"
+#include "model/devices/classic.h"
+#include "model/devices/keyboard.h"
+#include "model/devices/remote_loopback_device.h"
+#include "model/devices/sniffer.h"
+
+#include <memory>
+
+#include <stdlib.h>
+
+#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 "device_boutique.h"
+#include "include/phy.h"
+#include "model/devices/hci_socket_device.h"
+#include "model/devices/link_layer_socket_device.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+TestModel::TestModel(
+ std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> event_scheduler,
+
+ std::function<AsyncTaskId(std::chrono::milliseconds, std::chrono::milliseconds, const TaskCallback&)>
+ periodic_event_scheduler,
+
+ std::function<void(AsyncTaskId)> cancel, std::function<int(const std::string&, int)> connect_to_remote)
+ : schedule_task_(event_scheduler), schedule_periodic_task_(periodic_event_scheduler), cancel_task_(cancel),
+ connect_to_remote_(connect_to_remote) {
+ // TODO: Remove when registration works!
+ example_devices_.push_back(std::make_shared<Beacon>());
+ example_devices_.push_back(std::make_shared<BeaconSwarm>());
+ example_devices_.push_back(std::make_shared<Keyboard>());
+ example_devices_.push_back(std::make_shared<CarKit>());
+ example_devices_.push_back(std::make_shared<Classic>());
+ example_devices_.push_back(std::make_shared<Sniffer>());
+ example_devices_.push_back(std::make_shared<RemoteLoopbackDevice>());
+}
+
+void TestModel::SetTimerPeriod(std::chrono::milliseconds new_period) {
+ timer_period_ = new_period;
+
+ if (timer_tick_task_ == kInvalidTaskId) return;
+
+ // Restart the timer with the new period
+ StopTimer();
+ StartTimer();
+}
+
+void TestModel::StartTimer() {
+ LOG_INFO(LOG_TAG, "StartTimer()");
+ timer_tick_task_ =
+ schedule_periodic_task_(std::chrono::milliseconds(0), timer_period_, [this]() { TestModel::TimerTick(); });
+}
+
+void TestModel::StopTimer() {
+ LOG_INFO(LOG_TAG, "StopTimer()");
+ cancel_task_(timer_tick_task_);
+ timer_tick_task_ = kInvalidTaskId;
+}
+
+size_t TestModel::Add(std::shared_ptr<Device> new_dev) {
+ devices_.push_back(new_dev);
+ return devices_.size() - 1;
+}
+
+void TestModel::Del(size_t dev_index) {
+ if (dev_index >= devices_.size()) {
+ LOG_WARN(LOG_TAG, "del: index out of range!");
+ return;
+ }
+ devices_.erase(devices_.begin() + dev_index);
+}
+
+size_t TestModel::AddPhy(std::shared_ptr<PhyLayerFactory> new_phy) {
+ phys_.push_back(new_phy);
+ return phys_.size() - 1;
+}
+
+void TestModel::DelPhy(size_t phy_index) {
+ if (phy_index >= phys_.size()) {
+ LOG_WARN(LOG_TAG, "del_phy: index %d out of range: ", static_cast<int>(phy_index));
+ return;
+ }
+}
+
+void TestModel::AddDeviceToPhy(size_t dev_index, size_t phy_index) {
+ if (dev_index >= devices_.size()) {
+ LOG_WARN(LOG_TAG, "add_device_to_phy: device out of range: ");
+ return;
+ }
+ if (phy_index >= phys_.size()) {
+ LOG_WARN(LOG_TAG, "add_device_to_phy: phy out of range: ");
+ return;
+ }
+ std::shared_ptr<Device> dev = devices_[dev_index];
+ dev->RegisterPhyLayer(
+ phys_[phy_index]->GetPhyLayer([dev](packets::LinkLayerPacketView packet) { dev->IncomingPacket(packet); }));
+}
+
+void TestModel::DelDeviceFromPhy(size_t dev_index, size_t phy_index) {
+ if (dev_index >= devices_.size()) {
+ LOG_WARN(LOG_TAG, "del_device_from_phy: device out of range: ");
+ return;
+ }
+ if (phy_index >= phys_.size()) {
+ LOG_WARN(LOG_TAG, "del_device_from_phy: phy out of range: ");
+ return;
+ }
+}
+
+void TestModel::AddLinkLayerConnection(int socket_fd, Phy::Type phy_type) {
+ std::shared_ptr<Device> dev = LinkLayerSocketDevice::Create(socket_fd, phy_type);
+ int index = Add(dev);
+ for (size_t phy_index = 0; phy_index < phys_.size(); phy_index++) {
+ if (phy_type == phys_[phy_index]->GetType()) {
+ AddDeviceToPhy(index, phy_index);
+ }
+ }
+}
+
+void TestModel::IncomingLinkLayerConnection(int socket_fd) {
+ // TODO: Handle other phys
+ AddLinkLayerConnection(socket_fd, Phy::Type::BR_EDR);
+}
+
+void TestModel::AddRemote(const std::string& server, int port, Phy::Type phy_type) {
+ int socket_fd = connect_to_remote_(server, port);
+ if (socket_fd < 0) {
+ return;
+ }
+ AddLinkLayerConnection(socket_fd, phy_type);
+}
+
+void TestModel::IncomingHciConnection(int socket_fd) {
+ std::shared_ptr<HciSocketDevice> dev = HciSocketDevice::Create(socket_fd);
+ // TODO: Auto-increment addresses?
+ static int hci_devs = 0;
+ int index = Add(std::static_pointer_cast<Device>(dev));
+ std::string addr = "da:4c:10:de:17:0"; // Da HCI dev
+ CHECK(hci_devs < 10) << "Why do you need more than 9?";
+ addr += '0' + hci_devs++;
+ dev->Initialize({"IgnoredTypeName", addr});
+ // TODO: Add device to all phys? For now, just the first two.
+ for (size_t phy = 0; phy < 2 && phy < phys_.size(); phy++) {
+ AddDeviceToPhy(index, phy);
+ }
+ dev->RegisterTaskScheduler(schedule_task_);
+ dev->RegisterTaskCancel(cancel_task_);
+}
+
+const std::string& TestModel::List() {
+ list_string_ = "";
+ list_string_ += " Devices: \r\n";
+ for (size_t dev = 0; dev < devices_.size(); dev++) {
+ list_string_ += " " + std::to_string(dev) + ":";
+ list_string_ += devices_[dev]->ToString() + " \r\n";
+ }
+ list_string_ += " Phys: \r\n";
+ for (size_t phy = 0; phy < phys_.size(); phy++) {
+ list_string_ += " " + std::to_string(phy) + ":";
+ list_string_ += phys_[phy]->ToString() + " \r\n";
+ }
+ return list_string_;
+}
+
+void TestModel::TimerTick() {
+ for (size_t dev = 0; dev < devices_.size(); dev++) {
+ devices_[dev]->TimerTick();
+ }
+}
+
+void TestModel::Reset() {
+ StopTimer();
+ devices_.clear();
+ phys_.clear();
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <unistd.h>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "async_manager.h"
+#include "model/devices/device.h"
+#include "phy_layer_factory.h"
+#include "test_channel_transport.h"
+
+namespace test_vendor_lib {
+
+class TestModel {
+ public:
+ TestModel(std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> evtScheduler,
+ std::function<AsyncTaskId(std::chrono::milliseconds, std::chrono::milliseconds, const TaskCallback&)>
+ periodicEvtScheduler,
+ std::function<void(AsyncTaskId)> cancel, std::function<int(const std::string&, int)> connect_to_remote);
+ ~TestModel() = default;
+
+ // Commands:
+
+ // Add a device, return its index
+ size_t Add(std::shared_ptr<Device> device);
+
+ // Remove devices by index
+ void Del(size_t device_index);
+
+ // Add phy, return its index
+ size_t AddPhy(std::shared_ptr<PhyLayerFactory> phy);
+
+ // Remove phy by index
+ void DelPhy(size_t phy_index);
+
+ // Add device to phy
+ void AddDeviceToPhy(size_t device_index, size_t phy_index);
+
+ // Remove device from phy
+ void DelDeviceFromPhy(size_t device_index, size_t phy_index);
+
+ // Handle incoming remote connections
+ void AddLinkLayerConnection(int socket_fd, Phy::Type phy_type);
+ void IncomingLinkLayerConnection(int socket_fd);
+ void IncomingHciConnection(int socket_fd);
+
+ // Connect to a remote device
+ void AddRemote(const std::string& server, int port, Phy::Type phy_type);
+
+ // Let devices know about the passage of time
+ void TimerTick();
+ void StartTimer();
+ void StopTimer();
+ void SetTimerPeriod(std::chrono::milliseconds new_period);
+
+ // List the devices that the test knows about
+ const std::string& List();
+
+ // Clear all devices and phys.
+ void Reset();
+
+ private:
+ std::vector<std::shared_ptr<PhyLayerFactory>> phys_;
+ std::vector<std::shared_ptr<Device>> devices_;
+ std::string list_string_;
+
+ // 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_;
+ std::function<int(const std::string&, int)> connect_to_remote_;
+
+ AsyncTaskId timer_tick_task_{kInvalidTaskId};
+ std::chrono::milliseconds timer_period_;
+
+ TestModel(TestModel& model) = delete;
+ TestModel& operator=(const TestModel& model) = delete;
+
+ std::vector<std::shared_ptr<Device>> example_devices_;
+};
+
+} // namespace test_vendor_lib
proprietary: true,
srcs: [
"iterator.cc",
+ "counted_builder.cc",
"packet_view.cc",
+ "raw_builder.cc",
"view.cc",
+ "hci/acl_packet_builder.cc",
+ "hci/acl_packet_view.cc",
+ "hci/command_packet_builder.cc",
+ "hci/command_packet_view.cc",
+ "hci/event_packet_builder.cc",
+ "hci/event_payload_builder.cc",
+ "hci/hci_packet_builder.cc",
+ "hci/le_meta_event_builder.cc",
+ "hci/sco_packet_builder.cc",
+ "hci/sco_packet_view.cc",
+ "link_layer/link_layer_packet_builder.cc",
+ "link_layer/link_layer_packet_view.cc",
],
cflags: [
"-fvisibility=hidden",
"clang_coverage_bin",
],
srcs: [
+ "test/link_layer_packet_builder_test.cc",
+ "test/packet_builder_test.cc",
"test/packet_view_test.cc",
+ "hci/test/acl_builder_test.cc",
+ "hci/test/event_builder_test.cc",
],
header_libs: [
"libbluetooth_headers",
"liblog",
],
static_libs: [
- "libbluetooth-types",
+ "libbt-rootcanal-types",
"libbt-rootcanal-packets",
],
}
virtual size_t size() const = 0;
// Write to the vector with the given iterator.
- virtual void Serialize(
- std::back_insert_iterator<std::vector<uint8_t>> it) const = 0;
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const = 0;
protected:
BasePacketBuilder() = default;
--- /dev/null
+/*
+ * Copyright 2018 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 "counted_builder.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+namespace packets {
+
+size_t CountedBuilder::size() const {
+ size_t payload_size = sizeof(uint8_t);
+ for (size_t i = 0; i < sub_builders_.size(); i++) {
+ payload_size += sub_builders_[i]->size();
+ }
+ return payload_size;
+}
+
+void CountedBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ insert(static_cast<uint8_t>(sub_builders_.size()), it);
+ for (size_t i = 0; i < sub_builders_.size(); i++) {
+ sub_builders_[i]->Serialize(it);
+ }
+}
+
+void CountedBuilder::Add(std::unique_ptr<BasePacketBuilder> builder) {
+ sub_builders_.push_back(std::move(builder));
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <forward_list>
+#include <memory>
+#include <vector>
+
+#include "packets/base_packet_builder.h"
+#include "packets/packet_builder.h"
+#include "packets/raw_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class CountedBuilder : public RawBuilder {
+ public:
+ CountedBuilder() = default;
+ virtual ~CountedBuilder() = default;
+
+ virtual size_t size() const override;
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override;
+
+ void Add(std::unique_ptr<BasePacketBuilder> builder);
+
+ private:
+ std::vector<std::unique_ptr<BasePacketBuilder>> sub_builders_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/acl_packet_builder.h"
+
+#include <base/logging.h>
+
+using std::vector;
+using test_vendor_lib::acl::BroadcastFlagsType;
+using test_vendor_lib::acl::PacketBoundaryFlagsType;
+
+namespace test_vendor_lib {
+namespace packets {
+
+AclPacketBuilder::AclPacketBuilder(uint16_t handle, PacketBoundaryFlagsType packet_boundary_flags,
+ BroadcastFlagsType broadcast_flags, std::unique_ptr<BasePacketBuilder> payload)
+ : handle_(handle), packet_boundary_flags_(packet_boundary_flags), broadcast_flags_(broadcast_flags),
+ payload_(std::move(payload)) {}
+
+std::unique_ptr<AclPacketBuilder> AclPacketBuilder::Create(uint16_t handle,
+ PacketBoundaryFlagsType packet_boundary_flags,
+ BroadcastFlagsType broadcast_flags,
+ std::unique_ptr<BasePacketBuilder> payload) {
+ return std::unique_ptr<AclPacketBuilder>(
+ new AclPacketBuilder(handle, packet_boundary_flags, broadcast_flags, std::move(payload)));
+}
+
+size_t AclPacketBuilder::size() const {
+ return 2 * sizeof(uint16_t) + payload_->size();
+}
+
+void AclPacketBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ insert(static_cast<uint16_t>((handle_ & 0xfff) | (static_cast<uint16_t>(packet_boundary_flags_) << 12) |
+ (static_cast<uint16_t>(broadcast_flags_) << 14)),
+ it);
+ uint16_t payload_size = payload_->size();
+
+ CHECK(static_cast<size_t>(payload_size) == payload_->size())
+ << "Payload too large for an ACL packet: " << payload_->size();
+ insert(payload_size, it);
+ payload_->Serialize(it);
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <base/logging.h>
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+#include "include/acl.h"
+#include "packets/hci/hci_packet_builder.h"
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+// ACL data packets are specified in the Bluetooth Core Specification Version
+// 4.2, Volume 2, Part E, Section 5.4.2
+class AclPacketBuilder : public HciPacketBuilder {
+ public:
+ virtual ~AclPacketBuilder() override = default;
+
+ static std::unique_ptr<AclPacketBuilder> Create(uint16_t handle, acl::PacketBoundaryFlagsType packet_boundary_flags,
+ acl::BroadcastFlagsType broadcast_flags,
+ std::unique_ptr<BasePacketBuilder> payload);
+
+ virtual size_t size() const override;
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const;
+
+ private:
+ AclPacketBuilder(uint16_t handle, acl::PacketBoundaryFlagsType packet_boundary_flags,
+ acl::BroadcastFlagsType broadcast_flags, std::unique_ptr<BasePacketBuilder> payload);
+ AclPacketBuilder() = delete;
+ uint16_t handle_;
+ acl::PacketBoundaryFlagsType packet_boundary_flags_;
+ acl::BroadcastFlagsType broadcast_flags_;
+ std::unique_ptr<BasePacketBuilder> payload_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/acl_packet_view.h"
+
+#include <base/logging.h>
+
+using std::vector;
+using test_vendor_lib::acl::BroadcastFlagsType;
+using test_vendor_lib::acl::PacketBoundaryFlagsType;
+
+namespace test_vendor_lib {
+namespace packets {
+
+AclPacketView::AclPacketView(std::shared_ptr<std::vector<uint8_t>> packet) : PacketView<true>(packet) {}
+
+AclPacketView::AclPacketView(PacketView<true> packet_view) : PacketView<true>(packet_view) {}
+
+AclPacketView AclPacketView::Create(std::shared_ptr<std::vector<uint8_t>> packet) {
+ return AclPacketView(packet);
+}
+
+AclPacketView AclPacketView::Create(PacketView<true> packet_view) {
+ return AclPacketView(packet_view);
+}
+
+uint16_t AclPacketView::GetHandle() const {
+ return begin().extract<uint16_t>() & 0xfff;
+}
+
+PacketBoundaryFlagsType AclPacketView::GetPacketBoundaryFlags() const {
+ return static_cast<PacketBoundaryFlagsType>(((begin() + 1).extract<uint8_t>() & 0x30) >> 4);
+}
+
+BroadcastFlagsType AclPacketView::GetBroadcastFlags() const {
+ return static_cast<BroadcastFlagsType>(((begin() + 1).extract<uint8_t>() & 0xc0) >> 6);
+}
+
+PacketView<true> AclPacketView::GetPayload() const {
+ uint16_t payload_size = (begin() + sizeof(uint16_t)).extract<uint16_t>();
+ CHECK(static_cast<uint16_t>(size() - 2 * sizeof(uint16_t)) == payload_size)
+ << "Malformed ACL packet payload_size " << payload_size << " + 4 != " << size();
+ return SubViewLittleEndian(2 * sizeof(uint16_t), size());
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "include/acl.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+// ACL data packets are specified in the Bluetooth Core Specification Version
+// 4.2, Volume 2, Part E, Section 5.4.2
+class AclPacketView : public PacketView<true> {
+ public:
+ virtual ~AclPacketView() override = default;
+
+ static AclPacketView Create(std::shared_ptr<std::vector<uint8_t>> packet);
+ static AclPacketView Create(PacketView<true> packet_view);
+
+ uint16_t GetHandle() const;
+ acl::PacketBoundaryFlagsType GetPacketBoundaryFlags() const;
+ acl::BroadcastFlagsType GetBroadcastFlags() const;
+ PacketView<true> GetPayload() const;
+
+ private:
+ AclPacketView(std::shared_ptr<std::vector<uint8_t>> packet);
+ AclPacketView(PacketView<true> packet_view);
+ AclPacketView() = delete;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/command_packet_builder.h"
+
+#include <base/logging.h>
+
+using std::vector;
+using test_vendor_lib::hci::OpCode;
+
+namespace test_vendor_lib {
+namespace packets {
+
+CommandPacketBuilder::CommandPacketBuilder(OpCode opcode, std::unique_ptr<BasePacketBuilder> payload)
+ : opcode_(opcode), payload_(std::move(payload)) {}
+
+size_t CommandPacketBuilder::size() const {
+ return sizeof(uint16_t) + sizeof(uint8_t) + payload_->size();
+}
+
+void CommandPacketBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ insert(static_cast<uint16_t>(opcode_), it);
+ uint8_t payload_size = static_cast<uint8_t>(payload_->size());
+
+ CHECK(static_cast<size_t>(payload_size) == payload_->size())
+ << "Payload too large for a command packet: " << payload_->size();
+ insert(payload_size, it);
+ payload_->Serialize(it);
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <base/logging.h>
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+#include "include/hci.h"
+#include "packets/hci/hci_packet_builder.h"
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+// ACL data packets are specified in the Bluetooth Core Specification Version
+// 4.2, Volume 2, Part E, Section 5.4.2
+class CommandPacketBuilder : public HciPacketBuilder {
+ public:
+ virtual ~CommandPacketBuilder() override = default;
+
+ static std::unique_ptr<CommandPacketBuilder> Create(hci::OpCode opcode, std::unique_ptr<BasePacketBuilder> payload);
+
+ virtual size_t size() const override;
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const;
+
+ private:
+ CommandPacketBuilder(hci::OpCode opcode, std::unique_ptr<BasePacketBuilder> payload);
+ CommandPacketBuilder() = delete;
+ hci::OpCode opcode_;
+ std::unique_ptr<BasePacketBuilder> payload_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/command_packet_view.h"
+
+#include <base/logging.h>
+
+using std::vector;
+
+namespace test_vendor_lib {
+namespace packets {
+
+CommandPacketView::CommandPacketView(std::shared_ptr<std::vector<uint8_t>> packet) : PacketView<true>(packet) {}
+
+CommandPacketView CommandPacketView::Create(std::shared_ptr<std::vector<uint8_t>> packet) {
+ return CommandPacketView(packet);
+}
+
+uint16_t CommandPacketView::GetOpcode() const {
+ return begin().extract<uint16_t>();
+}
+
+PacketView<true> CommandPacketView::GetPayload() const {
+ uint8_t payload_size = (begin() + sizeof(uint16_t)).extract<uint8_t>();
+ CHECK(static_cast<uint8_t>(size() - sizeof(uint16_t) - sizeof(uint8_t)) == payload_size)
+ << "Malformed Command packet payload_size " << payload_size << " + 2 != " << size();
+ return SubViewLittleEndian(sizeof(uint16_t) + sizeof(uint8_t), size());
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+// Command packets are specified in the Bluetooth Core Specification Version
+// 4.2, Volume 2, Part E, Section 5.4.1
+class CommandPacketView : public PacketView<true> {
+ public:
+ virtual ~CommandPacketView() override = default;
+
+ static CommandPacketView Create(std::shared_ptr<std::vector<uint8_t>> packet);
+
+ uint16_t GetOpcode() const;
+
+ PacketView<true> GetPayload() const;
+
+ private:
+ CommandPacketView(std::shared_ptr<std::vector<uint8_t>> packet);
+ CommandPacketView() = delete;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/event_packet_builder.h"
+
+#include <base/logging.h>
+#include "hci.h"
+#include "packets/hci/le_meta_event_builder.h"
+
+using std::vector;
+using test_vendor_lib::hci::EventCode;
+using test_vendor_lib::hci::OpCode;
+using test_vendor_lib::hci::Status;
+
+namespace test_vendor_lib {
+namespace packets {
+
+EventPacketBuilder::EventPacketBuilder(EventCode event_code)
+ : event_code_(event_code), payload_(std::make_unique<RawBuilder>()) {}
+
+EventPacketBuilder::EventPacketBuilder(EventCode event_code, std::unique_ptr<RawBuilder> payload)
+ : event_code_(event_code), payload_(std::move(payload)) {}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.1
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateInquiryCompleteEvent(hci::Status status) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::INQUIRY_COMPLETE));
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.14
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteEvent(
+ hci::OpCode command_opcode, const vector<uint8_t>& event_return_parameters) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::COMMAND_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(1)); // num_hci_command_packets
+ CHECK(evt_ptr->AddPayloadOctets2(static_cast<uint16_t>(command_opcode)));
+ CHECK(evt_ptr->AddPayloadOctets(event_return_parameters));
+
+ return evt_ptr;
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(hci::OpCode command_opcode,
+ hci::Status status) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::COMMAND_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(1)); // num_hci_command_packets
+ CHECK(evt_ptr->AddPayloadOctets2(static_cast<uint16_t>(command_opcode)));
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+
+ return evt_ptr;
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteStatusAndAddressEvent(
+ hci::OpCode command_opcode, hci::Status status, const Address& address) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::COMMAND_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(1)); // num_hci_command_packets
+ CHECK(evt_ptr->AddPayloadOctets2(static_cast<uint16_t>(command_opcode)));
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddPayloadAddress(address));
+
+ return evt_ptr;
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteUnknownOpCodeEvent(
+ uint16_t command_opcode) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::COMMAND_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(1)); // num_hci_command_packets
+ CHECK(evt_ptr->AddPayloadOctets2(static_cast<uint16_t>(command_opcode)));
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(Status::UNKNOWN_COMMAND)));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.15
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandStatusEvent(hci::Status status,
+ hci::OpCode command_opcode) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::COMMAND_STATUS));
+
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddPayloadOctets1(1)); // num_hci_command_packets
+ CHECK(evt_ptr->AddPayloadOctets2(static_cast<uint16_t>(command_opcode)));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.19
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateNumberOfCompletedPacketsEvent(
+ uint16_t handle, uint16_t num_completed_packets) {
+ std::unique_ptr<RawBuilder> payload = std::make_unique<CountedBuilder>();
+ std::unique_ptr<EventPacketBuilder> evt_ptr = std::unique_ptr<EventPacketBuilder>(
+ new EventPacketBuilder(EventCode::NUMBER_OF_COMPLETED_PACKETS, std::move(payload)));
+
+ evt_ptr->AddCompletedPackets(handle, num_completed_packets);
+
+ return evt_ptr;
+}
+
+void EventPacketBuilder::AddCompletedPackets(uint16_t handle, uint16_t num_completed_packets) {
+ CHECK(event_code_ == EventCode::NUMBER_OF_COMPLETED_PACKETS);
+
+ std::unique_ptr<RawBuilder> handle_pair = std::make_unique<RawBuilder>();
+ CHECK(handle_pair->AddOctets2(handle));
+ CHECK(handle_pair->AddOctets2(num_completed_packets));
+ AddBuilder(std::move(handle_pair));
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.10
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteDeleteStoredLinkKey(
+ hci::Status status, uint16_t num_keys_deleted) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::DELETE_STORED_LINK_KEY, status);
+
+ CHECK(evt_ptr->AddPayloadOctets2(num_keys_deleted));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.12
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteReadLocalName(
+ hci::Status status, const std::vector<uint8_t>& local_name) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::READ_LOCAL_NAME, status);
+
+ size_t len = local_name.size();
+ if (len > 247) {
+ len = 247;
+ }
+ CHECK(evt_ptr->AddPayloadOctets(len, local_name));
+ CHECK(evt_ptr->AddPayloadOctets1(0)); // Null terminated
+ for (size_t i = 0; i < 248 - len - 1; i++) CHECK(evt_ptr->AddPayloadOctets1(0xFF));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.23
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteReadAuthenticationEnable(
+ hci::Status status, uint8_t enable) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::READ_LOCAL_NAME, status);
+ CHECK(evt_ptr->AddPayloadOctets1(enable));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.1
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteReadLocalVersionInformation(
+ hci::Status status, uint8_t hci_version, uint16_t hci_revision, uint8_t lmp_pal_version, uint16_t manufacturer_name,
+ uint16_t lmp_pal_subversion) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::READ_LOCAL_VERSION_INFORMATION, status);
+
+ CHECK(evt_ptr->AddPayloadOctets1(hci_version));
+ CHECK(evt_ptr->AddPayloadOctets2(hci_revision));
+ CHECK(evt_ptr->AddPayloadOctets1(lmp_pal_version));
+ CHECK(evt_ptr->AddPayloadOctets2(manufacturer_name));
+ CHECK(evt_ptr->AddPayloadOctets2(lmp_pal_subversion));
+
+ return evt_ptr;
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateReadRemoteVersionInformationEvent(
+ hci::Status status, uint16_t connection_handle, uint8_t lmp_pal_version, uint16_t manufacturer_name,
+ uint16_t lmp_pal_subversion) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddPayloadOctets2(connection_handle));
+ CHECK(evt_ptr->AddPayloadOctets1(lmp_pal_version));
+ CHECK(evt_ptr->AddPayloadOctets2(manufacturer_name));
+ CHECK(evt_ptr->AddPayloadOctets2(lmp_pal_subversion));
+
+ return evt_ptr;
+}
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.2
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteReadLocalSupportedCommands(
+ hci::Status status, const vector<uint8_t>& supported_commands) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::READ_LOCAL_SUPPORTED_COMMANDS, status);
+
+ CHECK(evt_ptr->AddPayloadOctets(64, supported_commands));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.4
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteReadLocalExtendedFeatures(
+ hci::Status status, uint8_t page_number, uint8_t maximum_page_number, uint64_t extended_lmp_features) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::READ_LOCAL_EXTENDED_FEATURES, status);
+
+ CHECK(evt_ptr->AddPayloadOctets1(page_number));
+ CHECK(evt_ptr->AddPayloadOctets1(maximum_page_number));
+ CHECK(evt_ptr->AddPayloadOctets8(extended_lmp_features));
+
+ return evt_ptr;
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateReadRemoteExtendedFeaturesEvent(
+ hci::Status status, uint16_t handle, uint8_t page_number, uint8_t maximum_page_number,
+ uint64_t extended_lmp_features) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+ CHECK(evt_ptr->AddPayloadOctets1(page_number));
+ CHECK(evt_ptr->AddPayloadOctets1(maximum_page_number));
+ CHECK(evt_ptr->AddPayloadOctets8(extended_lmp_features));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.5
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteReadBufferSize(
+ hci::Status status, uint16_t hc_acl_data_packet_length, uint8_t hc_synchronous_data_packet_length,
+ uint16_t hc_total_num_acl_data_packets, uint16_t hc_total_synchronous_data_packets) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::READ_BUFFER_SIZE, status);
+
+ CHECK(evt_ptr->AddPayloadOctets2(hc_acl_data_packet_length));
+ CHECK(evt_ptr->AddPayloadOctets1(hc_synchronous_data_packet_length));
+ CHECK(evt_ptr->AddPayloadOctets2(hc_total_num_acl_data_packets));
+ CHECK(evt_ptr->AddPayloadOctets2(hc_total_synchronous_data_packets));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.6
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteReadBdAddr(hci::Status status,
+ const Address& address) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::READ_BD_ADDR, status);
+
+ CHECK(evt_ptr->AddPayloadAddress(address));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.8
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteReadLocalSupportedCodecs(
+ hci::Status status, const vector<uint8_t>& supported_codecs, const vector<uint32_t>& vendor_specific_codecs) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::READ_LOCAL_SUPPORTED_CODECS, status);
+
+ CHECK(evt_ptr->AddPayloadOctets1(supported_codecs.size()));
+ CHECK(evt_ptr->AddPayloadOctets(supported_codecs));
+ CHECK(evt_ptr->AddPayloadOctets1(vendor_specific_codecs.size()));
+ for (size_t i = 0; i < vendor_specific_codecs.size(); i++)
+ CHECK(evt_ptr->AddPayloadOctets4(vendor_specific_codecs[i]));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.6.1
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteReadLoopbackMode(hci::Status status,
+ hci::LoopbackMode mode) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::READ_LOOPBACK_MODE, status);
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(mode)));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.2
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateInquiryResultEvent() {
+ std::unique_ptr<RawBuilder> payload = std::unique_ptr<RawBuilder>(new CountedBuilder());
+ std::unique_ptr<EventPacketBuilder> evt_ptr(new EventPacketBuilder(EventCode::INQUIRY_RESULT, std::move(payload)));
+
+ return evt_ptr;
+}
+
+bool EventPacketBuilder::AddInquiryResult(const Address& address, uint8_t page_scan_repetition_mode,
+ ClassOfDevice class_of_device, uint16_t clock_offset) {
+ CHECK(event_code_ == EventCode::INQUIRY_RESULT);
+
+ if (!CanAddPayloadOctets(14)) return false;
+
+ std::unique_ptr<RawBuilder> result = std::make_unique<RawBuilder>();
+
+ CHECK(result->AddAddress(address));
+ CHECK(result->AddOctets1(page_scan_repetition_mode));
+ CHECK(result->AddOctets2(0)); // Reserved
+ CHECK(result->AddOctets1(class_of_device.cod[0]));
+ CHECK(result->AddOctets1(class_of_device.cod[1]));
+ CHECK(result->AddOctets1(class_of_device.cod[2]));
+ CHECK(!(clock_offset & 0x8000));
+ CHECK(result->AddOctets2(clock_offset));
+ AddBuilder(std::move(result));
+ return true;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.3
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateConnectionCompleteEvent(
+ hci::Status status, uint16_t handle, const Address& address, hci::LinkType link_type, bool encryption_enabled) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::CONNECTION_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK((handle & 0xf000) == 0); // Handles are 12-bit values.
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+ CHECK(evt_ptr->AddPayloadAddress(address));
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(link_type)));
+ CHECK(evt_ptr->AddPayloadOctets1(encryption_enabled ? 1 : 0));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.4
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateConnectionRequestEvent(const Address& address,
+ ClassOfDevice class_of_device,
+ hci::LinkType link_type) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::CONNECTION_REQUEST));
+
+ CHECK(evt_ptr->AddPayloadAddress(address));
+ CHECK(evt_ptr->AddPayloadOctets1(class_of_device.cod[0]));
+ CHECK(evt_ptr->AddPayloadOctets1(class_of_device.cod[1]));
+ CHECK(evt_ptr->AddPayloadOctets1(class_of_device.cod[2]));
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(link_type)));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.5
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateDisconnectionCompleteEvent(hci::Status status,
+ uint16_t handle,
+ uint8_t reason) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::DISCONNECTION_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK((handle & 0xf000) == 0); // Handles are 12-bit values.
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+ CHECK(evt_ptr->AddPayloadOctets1(reason));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.6
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateAuthenticationCompleteEvent(hci::Status status,
+ uint16_t handle) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::AUTHENTICATION_COMPLETE));
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK((handle & 0xf000) == 0); // Handles are 12-bit values.
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.7
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateRemoteNameRequestCompleteEvent(
+ hci::Status status, const Address& address, const std::string& remote_name) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::REMOTE_NAME_REQUEST_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddPayloadAddress(address));
+ for (size_t i = 0; i < remote_name.length(); i++) CHECK(evt_ptr->AddPayloadOctets1(remote_name[i]));
+ CHECK(evt_ptr->AddPayloadOctets1(0)); // Null terminated
+ for (size_t i = 0; i < 248 - remote_name.length() - 1; i++) CHECK(evt_ptr->AddPayloadOctets1(0xFF));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.23
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateLinkKeyRequestEvent(const Address& remote) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::LINK_KEY_REQUEST));
+ CHECK(evt_ptr->AddPayloadAddress(remote));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.24
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateLinkKeyNotificationEvent(const Address& remote,
+ const std::vector<uint8_t>& key,
+ uint8_t key_type) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::LINK_KEY_NOTIFICATION));
+ CHECK(evt_ptr->AddPayloadAddress(remote));
+ CHECK(key.size() == 16);
+ CHECK(evt_ptr->AddPayloadOctets(key));
+ CHECK(evt_ptr->AddPayloadOctets1(key_type));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.25
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateLoopbackCommandEvent(hci::OpCode opcode,
+ PacketView<true> payload) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::LOOPBACK_COMMAND));
+ CHECK(evt_ptr->AddPayloadOctets2(static_cast<uint16_t>(opcode)));
+ for (const auto& payload_byte : payload) // Fill the packet.
+ evt_ptr->AddPayloadOctets1(payload_byte);
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.28
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateReadClockOffsetEvent(hci::Status status, uint16_t handle,
+ uint16_t offset) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::READ_CLOCK_OFFSET_COMPLETE));
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+ CHECK(evt_ptr->AddPayloadOctets2(offset));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.29
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateConnectionPacketTypeChangedEvent(hci::Status status,
+ uint16_t handle,
+ uint16_t packet_type) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::CONNECTION_PACKET_TYPE_CHANGE));
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+ CHECK(evt_ptr->AddPayloadOctets2(packet_type));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.37
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateSniffSubratingEvent(const hci::Status status,
+ uint16_t handle) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::SNIFF_SUBRATING, status);
+
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.38
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateExtendedInquiryResultEvent(
+ const Address& address, uint8_t page_scan_repetition_mode, ClassOfDevice class_of_device, uint16_t clock_offset,
+ uint8_t rssi, const vector<uint8_t>& extended_inquiry_response) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::EXTENDED_INQUIRY_RESULT));
+
+ CHECK(evt_ptr->AddPayloadOctets1(1)); // Always contains a single response
+
+ CHECK(evt_ptr->AddPayloadAddress(address));
+ CHECK(evt_ptr->AddPayloadOctets1(page_scan_repetition_mode));
+ CHECK(evt_ptr->AddPayloadOctets1(0)); // Reserved
+ CHECK(evt_ptr->AddPayloadOctets1(class_of_device.cod[0]));
+ CHECK(evt_ptr->AddPayloadOctets1(class_of_device.cod[1]));
+ CHECK(evt_ptr->AddPayloadOctets1(class_of_device.cod[2]));
+ CHECK(!(clock_offset & 0x8000));
+ CHECK(evt_ptr->AddPayloadOctets2(clock_offset));
+ CHECK(evt_ptr->AddPayloadOctets1(rssi));
+ CHECK(evt_ptr->AddPayloadOctets(extended_inquiry_response));
+ evt_ptr->AddPayloadOctets1(0x00); // End marker
+ while (evt_ptr->AddPayloadOctets1(0x00))
+ ; // Fill packet
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.40
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateIoCapabilityRequestEvent(const Address& peer) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::IO_CAPABILITY_REQUEST));
+
+ CHECK(evt_ptr->AddPayloadAddress(peer));
+ return evt_ptr;
+} // namespace packets
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.41
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateIoCapabilityResponseEvent(
+ const Address& peer, uint8_t io_capability, bool oob_data_present, uint8_t authentication_requirements) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::IO_CAPABILITY_RESPONSE));
+
+ CHECK(evt_ptr->AddPayloadAddress(peer));
+ CHECK(evt_ptr->AddPayloadOctets1(io_capability));
+ CHECK(evt_ptr->AddPayloadOctets1(oob_data_present));
+ CHECK(evt_ptr->AddPayloadOctets1(authentication_requirements));
+ return evt_ptr;
+} // namespace test_vendor_lib
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.42
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateUserConfirmationRequestEvent(const Address& peer,
+ uint32_t numeric_value) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::USER_CONFIRMATION_REQUEST));
+
+ CHECK(evt_ptr->AddPayloadAddress(peer));
+ CHECK(evt_ptr->AddPayloadOctets4(numeric_value));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.43
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateUserPasskeyRequestEvent(const Address& peer) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::USER_PASSKEY_REQUEST));
+
+ CHECK(evt_ptr->AddPayloadAddress(peer));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.44
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateRemoteOobDataRequestEvent(const Address& peer) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::REMOTE_OOB_DATA_REQUEST));
+
+ CHECK(evt_ptr->AddPayloadAddress(peer));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.45
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateSimplePairingCompleteEvent(hci::Status status,
+ const Address& peer) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::SIMPLE_PAIRING_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddPayloadAddress(peer));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.48
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateUserPasskeyNotificationEvent(const Address& peer,
+ uint32_t passkey) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::USER_PASSKEY_NOTIFICATION));
+
+ CHECK(evt_ptr->AddPayloadAddress(peer));
+ CHECK(evt_ptr->AddPayloadOctets4(passkey));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.49
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateKeypressNotificationEvent(const Address& peer,
+ uint8_t notification_type) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::KEYPRESS_NOTIFICATION));
+
+ CHECK(evt_ptr->AddPayloadAddress(peer));
+ CHECK(evt_ptr->AddPayloadOctets1(notification_type));
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.65.1
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateLeConnectionCompleteEvent(
+ hci::Status status, uint16_t handle, uint8_t role, uint8_t peer_address_type, const Address& peer,
+ uint16_t interval, uint16_t latency, uint16_t supervision_timeout) {
+ std::unique_ptr<RawBuilder> meta_evt = LeMetaEventBuilder::CreateLeConnectionCompleteEvent(
+ status, handle, role, peer_address_type, peer, interval, latency, supervision_timeout);
+
+ return std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::LE_META_EVENT, std::move(meta_evt)));
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateLeEnhancedConnectionCompleteEvent(
+ hci::Status status, uint16_t handle, uint8_t role, uint8_t peer_address_type, const Address& peer,
+ const Address& local_private_address, const Address& peer_private_address, uint16_t interval, uint16_t latency,
+ uint16_t supervision_timeout) {
+ std::unique_ptr<RawBuilder> meta_evt = LeMetaEventBuilder::CreateLeEnhancedConnectionCompleteEvent(
+ status, handle, role, peer_address_type, peer, local_private_address, peer_private_address, interval, latency,
+ supervision_timeout);
+
+ return std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::LE_META_EVENT, std::move(meta_evt)));
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateLeConnectionUpdateCompleteEvent(
+ hci::Status status, uint16_t handle, uint16_t interval, uint16_t latency, uint16_t supervision_timeout) {
+ std::unique_ptr<RawBuilder> meta_evt =
+ LeMetaEventBuilder::CreateLeConnectionUpdateCompleteEvent(status, handle, interval, latency, supervision_timeout);
+
+ return std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::LE_META_EVENT, std::move(meta_evt)));
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.65.2
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateLeAdvertisingReportEvent() {
+ std::unique_ptr<RawBuilder> meta_evt = LeMetaEventBuilder::CreateLeAdvertisingReportEvent();
+
+ return std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::LE_META_EVENT, std::move(meta_evt)));
+}
+
+bool EventPacketBuilder::AddLeAdvertisingReport(LeAdvertisement::AdvertisementType event_type,
+ LeAdvertisement::AddressType addr_type, const Address& addr,
+ const vector<uint8_t>& data, uint8_t rssi) {
+ CHECK(event_code_ == EventCode::LE_META_EVENT);
+
+ // Upcast the payload to add the next report.
+ LeMetaEventBuilder* meta_ptr = static_cast<LeMetaEventBuilder*>(payload_.get());
+ return meta_ptr->AddLeAdvertisingReport(event_type, addr_type, addr, data, rssi);
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.65.4
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateLeRemoteUsedFeaturesEvent(hci::Status status,
+ uint16_t handle,
+ uint64_t features) {
+ std::unique_ptr<RawBuilder> meta_evt = LeMetaEventBuilder::CreateLeRemoteUsedFeaturesEvent(status, handle, features);
+ return std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::LE_META_EVENT, std::move(meta_evt)));
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateRemoteSupportedFeaturesEvent(hci::Status status,
+ uint16_t handle,
+ uint64_t features) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+ CHECK(evt_ptr->AddPayloadOctets8(features));
+
+ return evt_ptr;
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteLinkKeyRequestReply(hci::Status status,
+ Address address) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::LINK_KEY_REQUEST_REPLY, status);
+
+ CHECK(evt_ptr->AddPayloadAddress(address));
+
+ return evt_ptr;
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteLinkKeyRequestNegativeReply(
+ hci::Status status, Address address) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, status);
+
+ CHECK(evt_ptr->AddPayloadAddress(address));
+
+ return evt_ptr;
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteWriteLinkPolicySettings(hci::Status status,
+ uint16_t handle) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::WRITE_LINK_POLICY_SETTINGS, status);
+
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+
+ return evt_ptr;
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteWriteLinkSupervisionTimeout(
+ hci::Status status, uint16_t handle) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::WRITE_LINK_SUPERVISION_TIMEOUT, status);
+
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.2
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteLeReadBufferSize(
+ hci::Status status, uint16_t hc_le_data_packet_length, uint8_t hc_total_num_le_data_packets) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::LE_READ_BUFFER_SIZE, status);
+
+ CHECK(evt_ptr->AddPayloadOctets2(hc_le_data_packet_length));
+ CHECK(evt_ptr->AddPayloadOctets1(hc_total_num_le_data_packets));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.3
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteLeReadLocalSupportedFeatures(
+ hci::Status status, uint64_t le_features) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES, status);
+
+ CHECK(evt_ptr->AddPayloadOctets8(le_features));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.14
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteLeReadWhiteListSize(
+ hci::Status status, uint8_t white_list_size) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::LE_READ_WHITE_LIST_SIZE, status);
+
+ CHECK(evt_ptr->AddPayloadOctets8(white_list_size));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.23
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteLeRand(hci::Status status,
+ uint64_t random_val) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::LE_RAND, status);
+
+ CHECK(evt_ptr->AddPayloadOctets8(random_val));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.27
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteLeReadSupportedStates(hci::Status status,
+ uint64_t le_states) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::LE_READ_SUPPORTED_STATES, status);
+
+ CHECK(evt_ptr->AddPayloadOctets8(le_states));
+
+ return evt_ptr;
+}
+
+// Vendor-specific commands
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateCommandCompleteLeGetVendorCapabilities(
+ hci::Status status, const vector<uint8_t>& vendor_cap) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ EventPacketBuilder::CreateCommandCompleteOnlyStatusEvent(OpCode::LE_GET_VENDOR_CAPABILITIES, status);
+
+ CHECK(evt_ptr->AddPayloadOctets(vendor_cap));
+
+ return evt_ptr;
+}
+
+std::unique_ptr<EventPacketBuilder> EventPacketBuilder::CreateEncryptionChange(hci::Status status, uint16_t handle,
+ uint8_t encryption_enable) {
+ std::unique_ptr<EventPacketBuilder> evt_ptr =
+ std::unique_ptr<EventPacketBuilder>(new EventPacketBuilder(EventCode::ENCRYPTION_CHANGE));
+
+ CHECK(evt_ptr->AddPayloadOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddPayloadOctets2(handle));
+ CHECK(evt_ptr->AddPayloadOctets1(encryption_enable));
+
+ return evt_ptr;
+}
+
+size_t EventPacketBuilder::size() const {
+ size_t header_size = 2; // Event code and payload size
+ return header_size + payload_->size();
+}
+
+void EventPacketBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ insert(static_cast<uint8_t>(event_code_), it);
+ uint8_t payload_size = size() - 2; // Event code and payload size
+ CHECK(size() - 2 == static_cast<size_t>(payload_size)) << "Payload too large for an event: " << size();
+ insert(payload_size, it);
+ payload_->Serialize(it);
+}
+
+bool EventPacketBuilder::CanAddPayloadOctets(size_t octets) {
+ return payload_->CanAddOctets(octets);
+}
+
+bool EventPacketBuilder::AddPayloadOctets(size_t octets, const std::vector<uint8_t>& bytes) {
+ return payload_->AddOctets(octets, bytes);
+}
+
+bool EventPacketBuilder::AddPayloadOctets(const std::vector<uint8_t>& bytes) {
+ return payload_->AddOctets(bytes);
+}
+
+bool EventPacketBuilder::AddPayloadOctets1(uint8_t value) {
+ return payload_->AddOctets1(value);
+}
+
+bool EventPacketBuilder::AddPayloadOctets2(uint16_t value) {
+ return payload_->AddOctets2(value);
+}
+
+bool EventPacketBuilder::AddPayloadOctets3(uint32_t value) {
+ return payload_->AddOctets3(value);
+}
+
+bool EventPacketBuilder::AddPayloadOctets4(uint32_t value) {
+ return payload_->AddOctets4(value);
+}
+
+bool EventPacketBuilder::AddPayloadOctets6(uint64_t value) {
+ return payload_->AddOctets6(value);
+}
+
+bool EventPacketBuilder::AddPayloadOctets8(uint64_t value) {
+ return payload_->AddOctets8(value);
+}
+
+bool EventPacketBuilder::AddPayloadAddress(Address address) {
+ return payload_->AddAddress(address);
+}
+
+bool EventPacketBuilder::AddBuilder(std::unique_ptr<BasePacketBuilder> builder) {
+ // Upcast the payload to add the next builder.
+ CountedBuilder* temp_ptr = static_cast<CountedBuilder*>(payload_.get());
+ temp_ptr->Add(std::move(builder));
+ return true;
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <base/logging.h>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "include/hci.h"
+#include "include/le_advertisement.h"
+#include "packets/counted_builder.h"
+#include "packets/hci/hci_packet_builder.h"
+#include "packets/packet_builder.h"
+#include "packets/packet_view.h"
+#include "packets/raw_builder.h"
+#include "types/address.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+// Event Packets are specified in the Bluetooth Core Specification Version 4.2,
+// Volume 2, Part E, Section 5.4.4 (page 477). Event Packets begin with a 2
+// octet header formatted as follows:
+// - Event Code: 1 octet
+// - Parameter Total Length: 1 octet
+class EventPacketBuilder : public HciPacketBuilder {
+ public:
+ virtual ~EventPacketBuilder() override = default;
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.1
+ static std::unique_ptr<EventPacketBuilder> CreateInquiryCompleteEvent(hci::Status status);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.14
+ // This should only be used for testing to send non-standard packets
+ // Most code should use the more specific functions that follow
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteEvent(
+ hci::OpCode command_opcode, const std::vector<uint8_t>& event_return_parameters);
+
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteOnlyStatusEvent(hci::OpCode command_opcode,
+ hci::Status status);
+
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteStatusAndAddressEvent(hci::OpCode command_opcode,
+ hci::Status status,
+ const Address& address);
+
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteUnknownOpCodeEvent(uint16_t command_opcode);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.15
+ static std::unique_ptr<EventPacketBuilder> CreateCommandStatusEvent(hci::Status status, hci::OpCode command_opcode);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.19
+ static std::unique_ptr<EventPacketBuilder> CreateNumberOfCompletedPacketsEvent(uint16_t handle,
+ uint16_t num_completed_packets);
+
+ void AddCompletedPackets(uint16_t handle, uint16_t num_completed_packets);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.1.10
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteLinkKeyRequestReply(hci::Status status,
+ Address address);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.1.11
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteLinkKeyRequestNegativeReply(hci::Status status,
+ Address address);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.2.10
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteWriteLinkPolicySettings(hci::Status status,
+ uint16_t handle);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.10
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteDeleteStoredLinkKey(hci::Status status,
+ uint16_t num_keys_deleted);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.12
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteReadLocalName(hci::Status status,
+ const std::vector<uint8_t>& local_name);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.23
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteReadAuthenticationEnable(hci::Status status,
+ uint8_t enable);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.42
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteWriteLinkSupervisionTimeout(hci::Status status,
+ uint16_t handle);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.1
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteReadLocalVersionInformation(
+ hci::Status status, uint8_t hci_version, uint16_t hci_revision, uint8_t lmp_pal_version,
+ uint16_t manufacturer_name, uint16_t lmp_pal_subversion);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.2
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteReadLocalSupportedCommands(
+ hci::Status status, const std::vector<uint8_t>& supported_commands);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.4
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteReadLocalExtendedFeatures(
+ hci::Status status, uint8_t page_number, uint8_t maximum_page_number, uint64_t extended_lmp_features);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.5
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteReadBufferSize(
+ hci::Status status, uint16_t hc_acl_data_packet_length, uint8_t hc_synchronous_data_packet_length,
+ uint16_t hc_total_num_acl_data_packets, uint16_t hc_total_synchronous_data_packets);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.6
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteReadBdAddr(hci::Status status,
+ const Address& bt_address);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.8
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteReadLocalSupportedCodecs(
+ hci::Status status, const std::vector<uint8_t>& supported_codecs,
+ const std::vector<uint32_t>& vendor_specific_codecs);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.6.1
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteReadLoopbackMode(hci::Status status,
+ hci::LoopbackMode mode);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.2
+ static std::unique_ptr<EventPacketBuilder> CreateInquiryResultEvent();
+
+ // Returns true if the result can be added to the event packet.
+ bool AddInquiryResult(const Address& bt_address, uint8_t page_scan_repetition_mode, ClassOfDevice class_of_device,
+ uint16_t clock_offset);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.3
+ static std::unique_ptr<EventPacketBuilder> CreateConnectionCompleteEvent(hci::Status status, uint16_t handle,
+ const Address& address,
+ hci::LinkType link_type,
+ bool encryption_enabled);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.4
+ static std::unique_ptr<EventPacketBuilder> CreateConnectionRequestEvent(const Address& address,
+ ClassOfDevice class_of_device,
+ hci::LinkType link_type);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.5
+ static std::unique_ptr<EventPacketBuilder> CreateDisconnectionCompleteEvent(hci::Status status, uint16_t handle,
+ uint8_t reason);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.6
+ static std::unique_ptr<EventPacketBuilder> CreateAuthenticationCompleteEvent(hci::Status status, uint16_t handle);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.7
+ static std::unique_ptr<EventPacketBuilder> CreateRemoteNameRequestCompleteEvent(hci::Status status,
+ const Address& bt_address,
+ const std::string& name);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.11
+ static std::unique_ptr<EventPacketBuilder> CreateRemoteSupportedFeaturesEvent(hci::Status status, uint16_t handle,
+ uint64_t features);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.12
+ static std::unique_ptr<EventPacketBuilder> CreateReadRemoteVersionInformationEvent(hci::Status status,
+ uint16_t connection_handle,
+ uint8_t lmp_pal_version,
+ uint16_t manufacturer_name,
+ uint16_t lmp_pal_subversion);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.23
+ static std::unique_ptr<EventPacketBuilder> CreateLinkKeyRequestEvent(const Address& remote);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.24
+ static std::unique_ptr<EventPacketBuilder> CreateLinkKeyNotificationEvent(const Address& remote,
+ const std::vector<uint8_t>& key,
+ uint8_t key_type);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.25
+ static std::unique_ptr<EventPacketBuilder> CreateLoopbackCommandEvent(hci::OpCode opcode, PacketView<true> payload);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.28
+ static std::unique_ptr<EventPacketBuilder> CreateReadClockOffsetEvent(hci::Status status, uint16_t handle,
+ uint16_t packet_type);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.29
+ static std::unique_ptr<EventPacketBuilder> CreateConnectionPacketTypeChangedEvent(hci::Status status, uint16_t handle,
+ uint16_t offset);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.34
+ static std::unique_ptr<EventPacketBuilder> CreateReadRemoteExtendedFeaturesEvent(hci::Status status, uint16_t handle,
+ uint8_t page_number,
+ uint8_t maximum_page_number,
+ uint64_t extended_lmp_features);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.37
+ static std::unique_ptr<EventPacketBuilder> CreateSniffSubratingEvent(hci::Status status, uint16_t handle);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.38
+ static std::unique_ptr<EventPacketBuilder> CreateExtendedInquiryResultEvent(
+ const Address& bt_address, uint8_t page_scan_repetition_mode, ClassOfDevice class_of_device,
+ uint16_t clock_offset, uint8_t rssi, const std::vector<uint8_t>& extended_inquiry_response);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.40
+ static std::unique_ptr<EventPacketBuilder> CreateIoCapabilityRequestEvent(const Address& peer);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.41
+ static std::unique_ptr<EventPacketBuilder> CreateIoCapabilityResponseEvent(const Address& peer, uint8_t io_capability,
+ bool oob_data_present,
+ uint8_t authentication_requirements);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.42
+ static std::unique_ptr<EventPacketBuilder> CreateUserConfirmationRequestEvent(const Address& peer,
+ uint32_t numeric_value);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.43
+ static std::unique_ptr<EventPacketBuilder> CreateUserPasskeyRequestEvent(const Address& peer);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.44
+ static std::unique_ptr<EventPacketBuilder> CreateRemoteOobDataRequestEvent(const Address& peer);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.45
+ static std::unique_ptr<EventPacketBuilder> CreateSimplePairingCompleteEvent(hci::Status status, const Address& peer);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.48
+ static std::unique_ptr<EventPacketBuilder> CreateUserPasskeyNotificationEvent(const Address& peer, uint32_t passkey);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.49
+ static std::unique_ptr<EventPacketBuilder> CreateKeypressNotificationEvent(const Address& peer,
+ uint8_t notification_type);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
+ // 7.7.65.1
+ static std::unique_ptr<EventPacketBuilder> CreateLeConnectionCompleteEvent(hci::Status status, uint16_t handle,
+ uint8_t role, uint8_t peer_address_type,
+ const Address& peer, uint16_t interval,
+ uint16_t latency,
+ uint16_t supervision_timeout);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
+ // 7.7.65.2
+ static std::unique_ptr<EventPacketBuilder> CreateLeAdvertisingReportEvent();
+
+ // Returns true if the report can be added to the event packet.
+ bool AddLeAdvertisingReport(LeAdvertisement::AdvertisementType event_type, LeAdvertisement::AddressType addr_type,
+ const Address& addr, const std::vector<uint8_t>& data, uint8_t rssi);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
+ // 7.7.65.3
+ static std::unique_ptr<EventPacketBuilder> CreateLeConnectionUpdateCompleteEvent(hci::Status status, uint16_t handle,
+ uint16_t interval, uint16_t latency,
+ uint16_t supervision_timeout);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
+ // 7.7.65.4
+ static std::unique_ptr<EventPacketBuilder> CreateLeRemoteUsedFeaturesEvent(hci::Status status, uint16_t handle,
+ uint64_t features);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
+ // 7.7.65.10
+ static std::unique_ptr<EventPacketBuilder> CreateLeEnhancedConnectionCompleteEvent(
+ hci::Status status, uint16_t handle, uint8_t role, uint8_t peer_address_type, const Address& peer,
+ const Address& local_private_address, const Address& peer_private_address, uint16_t interval, uint16_t latency,
+ uint16_t supervision_timeout);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.2
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteLeReadBufferSize(
+ hci::Status status, uint16_t hc_le_data_packet_length, uint8_t hc_total_num_le_data_packets);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.3
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteLeReadLocalSupportedFeatures(hci::Status status,
+ uint64_t le_features);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.14
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteLeReadWhiteListSize(hci::Status status,
+ uint8_t white_list_size);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.23
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteLeRand(hci::Status status, uint64_t random_val);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.27
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteLeReadSupportedStates(hci::Status status,
+ uint64_t le_states);
+
+ /*
+ static std::unique_ptr<EventPacketBuilder>
+ CreateLeStartEncryption(hci::Status status, uint8_t encryption_enable);
+*/
+ static std::unique_ptr<EventPacketBuilder> CreateEncryptionChange(hci::Status status, uint16_t handle,
+ uint8_t encryption_enable);
+
+ // Vendor-specific commands
+
+ static std::unique_ptr<EventPacketBuilder> CreateCommandCompleteLeGetVendorCapabilities(
+ hci::Status status, const std::vector<uint8_t>& vendor_cap);
+
+ virtual size_t size() const override;
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override;
+
+ bool CanAddPayloadOctets(size_t octets);
+
+ bool AddPayloadOctets(size_t octets, const std::vector<uint8_t>& bytes);
+
+ bool AddPayloadOctets(const std::vector<uint8_t>& bytes);
+
+ bool AddPayloadOctets1(uint8_t value);
+ bool AddPayloadOctets2(uint16_t value);
+ bool AddPayloadOctets3(uint32_t value);
+ bool AddPayloadOctets4(uint32_t value);
+ bool AddPayloadOctets6(uint64_t value);
+ bool AddPayloadOctets8(uint64_t value);
+
+ bool AddPayloadAddress(Address address);
+
+ bool AddBuilder(std::unique_ptr<BasePacketBuilder> builder);
+
+ private:
+ explicit EventPacketBuilder(hci::EventCode event_code);
+ explicit EventPacketBuilder(hci::EventCode event_code, std::unique_ptr<RawBuilder> payload);
+ hci::EventCode event_code_;
+ std::unique_ptr<RawBuilder> payload_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "event_payload_builder.h"
+
+#include <base/logging.h>
+#include <algorithm>
+
+using std::vector;
+
+namespace test_vendor_lib {
+namespace packets {
+
+EventPayloadBuilder::EventPayloadBuilder(size_t max_bytes) : max_bytes_(max_bytes) {}
+
+bool EventPayloadBuilder::AddPayloadOctets(size_t octets, const vector<uint8_t>& bytes) {
+ if (payload_.size() + octets > max_bytes_) return false;
+
+ if (octets != bytes.size()) return false;
+
+ payload_.insert(payload_.end(), bytes.begin(), bytes.end());
+
+ return true;
+}
+
+bool EventPayloadBuilder::AddPayloadOctets(const vector<uint8_t>& bytes) {
+ return AddPayloadOctets(bytes.size(), bytes);
+}
+
+bool EventPayloadBuilder::AddPayloadOctets(size_t octets, uint64_t value) {
+ vector<uint8_t> val_vector;
+
+ uint64_t v = value;
+
+ if (octets > sizeof(uint64_t)) return false;
+
+ for (size_t i = 0; i < octets; i++) {
+ val_vector.push_back(v & 0xff);
+ v = v >> 8;
+ }
+
+ if (v != 0) return false;
+
+ return AddPayloadOctets(octets, val_vector);
+}
+
+bool EventPayloadBuilder::AddPayloadAddress(const Address& address) {
+ if (payload_.size() + Address::kLength > max_bytes_) return false;
+
+ for (size_t i = 0; i < Address::kLength; i++) {
+ payload_.push_back(address.address[i]);
+ }
+ return true;
+}
+
+bool EventPayloadBuilder::AddPayloadOctets1(uint8_t value) {
+ return AddPayloadOctets(1, value);
+}
+
+bool EventPayloadBuilder::AddPayloadOctets2(uint16_t value) {
+ return AddPayloadOctets(2, value);
+}
+
+bool EventPayloadBuilder::AddPayloadOctets3(uint32_t value) {
+ return AddPayloadOctets(3, value);
+}
+
+bool EventPayloadBuilder::AddPayloadOctets4(uint32_t value) {
+ return AddPayloadOctets(4, value);
+}
+
+bool EventPayloadBuilder::AddPayloadOctets6(uint64_t value) {
+ return AddPayloadOctets(6, value);
+}
+
+bool EventPayloadBuilder::AddPayloadOctets8(uint64_t value) {
+ return AddPayloadOctets(8, value);
+}
+
+bool EventPayloadBuilder::CanAddPayloadOctets(size_t num_bytes) const {
+ return payload_.size() + num_bytes <= max_bytes_;
+}
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "packets/packet_builder.h"
+#include "types/address.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class EventPayloadBuilder : public PacketBuilder<true> {
+ public:
+ EventPayloadBuilder() = default;
+ EventPayloadBuilder(size_t max_bytes);
+ virtual ~EventPayloadBuilder() = default;
+
+ virtual size_t size() const override;
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const;
+
+ // Add |octets| bytes to the payload. Return true if:
+ // - the size of |bytes| is equal to |octets| and
+ // - the new size of the payload is still < |max_bytes_|
+ bool AddPayloadOctets(size_t octets, const std::vector<uint8_t>& bytes);
+
+ bool AddPayloadOctets(const std::vector<uint8_t>& bytes);
+
+ bool AddPayloadOctets1(uint8_t value);
+ bool AddPayloadOctets2(uint16_t value);
+ bool AddPayloadOctets3(uint32_t value);
+ bool AddPayloadOctets4(uint32_t value);
+ bool AddPayloadOctets6(uint64_t value);
+ bool AddPayloadOctets8(uint64_t value);
+
+ private:
+ // Add |octets| bytes to the payload. Return true if:
+ // - the value of |value| fits in |octets| bytes and
+ // - the new size of the payload is still < |max_bytes_|
+ bool AddPayloadOctets(size_t octets, uint64_t value);
+
+ // Add |address| to the payload. Return true if:
+ // - the new size of the payload is still < |max_bytes_|
+ bool AddPayloadAddress(const Address& address);
+
+ // Return true if |num_bytes| can be added to the payload.
+ bool CanAddPayloadOctets(size_t num_bytes) const;
+
+ size_t max_bytes_{255};
+
+ // Underlying containers for storing the actual packet
+ std::vector<uint8_t> payload_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/hci_packet_builder.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+namespace packets {
+
+std::shared_ptr<std::vector<uint8_t>> HciPacketBuilder::ToVector() {
+ std::shared_ptr<std::vector<uint8_t>> to_return = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*to_return);
+ Serialize(it);
+ return to_return;
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright 2018 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.
#pragma once
#include <cstdint>
-#include <string>
-#include <vector>
-#include "device.h"
+#include "packets/packet_builder.h"
namespace test_vendor_lib {
+namespace packets {
-// Encapsulate the details of supported devices to hide them from the
-// Controller.
-class DeviceFactory {
+// Base packet for HCI packets specified in the Bluetooth Core Specification
+// Version 4.2, Volume 2, Part E, Section 5.4
+class HciPacketBuilder : public PacketBuilder<true> {
public:
- DeviceFactory();
- virtual ~DeviceFactory() = default;
+ virtual ~HciPacketBuilder() override = default;
- // Call the constructor for the matching device type (arg[0]) and then call
- // the matching Initialize() function with args.
- static std::shared_ptr<Device> Create(const std::vector<std::string>& args);
+ std::shared_ptr<std::vector<uint8_t>> ToVector();
+
+ protected:
+ HciPacketBuilder() = default;
};
+} // namespace packets
} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/le_meta_event_builder.h"
+
+#include <base/logging.h>
+
+using std::vector;
+using test_vendor_lib::hci::LeSubEventCode;
+using test_vendor_lib::hci::Status;
+
+namespace test_vendor_lib {
+namespace packets {
+
+LeMetaEventBuilder::LeMetaEventBuilder(LeSubEventCode sub_event_code)
+ : sub_event_code_(sub_event_code), payload_(std::make_unique<RawBuilder>()) {}
+
+LeMetaEventBuilder::LeMetaEventBuilder(LeSubEventCode sub_event_code, std::unique_ptr<RawBuilder> payload)
+ : sub_event_code_(sub_event_code), payload_(std::move(payload)) {}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.65.1
+std::unique_ptr<LeMetaEventBuilder> LeMetaEventBuilder::CreateLeConnectionCompleteEvent(
+ Status status, uint16_t handle, uint8_t role, uint8_t peer_address_type, const Address& peer, uint16_t interval,
+ uint16_t latency, uint16_t supervision_timeout) {
+ std::unique_ptr<LeMetaEventBuilder> evt_ptr =
+ std::unique_ptr<LeMetaEventBuilder>(new LeMetaEventBuilder(LeSubEventCode::CONNECTION_COMPLETE));
+
+ CHECK(evt_ptr->AddOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddOctets2(handle));
+ CHECK(evt_ptr->AddOctets1(role));
+ CHECK(evt_ptr->AddOctets1(peer_address_type));
+ CHECK(evt_ptr->AddAddress(peer));
+ CHECK(evt_ptr->AddOctets2(interval));
+ CHECK(evt_ptr->AddOctets2(latency));
+ CHECK(evt_ptr->AddOctets2(supervision_timeout));
+ CHECK(evt_ptr->AddOctets1(0x00)); // Master Clock Accuracy (unused for master)
+
+ return evt_ptr;
+}
+
+std::unique_ptr<LeMetaEventBuilder> LeMetaEventBuilder::CreateLeEnhancedConnectionCompleteEvent(
+ Status status, uint16_t handle, uint8_t role, uint8_t peer_address_type, const Address& peer,
+ const Address& local_private_address, const Address& peer_private_address, uint16_t interval, uint16_t latency,
+ uint16_t supervision_timeout) {
+ std::unique_ptr<LeMetaEventBuilder> evt_ptr =
+ std::unique_ptr<LeMetaEventBuilder>(new LeMetaEventBuilder(LeSubEventCode::ENHANCED_CONNECTION_COMPLETE));
+
+ CHECK(evt_ptr->AddOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddOctets2(handle));
+ CHECK(evt_ptr->AddOctets1(role));
+ CHECK(evt_ptr->AddOctets1(peer_address_type));
+ CHECK(evt_ptr->AddAddress(peer));
+ CHECK(evt_ptr->AddAddress(local_private_address));
+ CHECK(evt_ptr->AddAddress(peer_private_address));
+ CHECK(evt_ptr->AddOctets2(interval));
+ CHECK(evt_ptr->AddOctets2(latency));
+ CHECK(evt_ptr->AddOctets2(supervision_timeout));
+ CHECK(evt_ptr->AddOctets1(0x00)); // Master Clock Accuracy (unused for master)
+
+ return evt_ptr;
+}
+
+std::unique_ptr<LeMetaEventBuilder> LeMetaEventBuilder::CreateLeConnectionUpdateCompleteEvent(
+ Status status, uint16_t handle, uint16_t interval, uint16_t latency, uint16_t supervision_timeout) {
+ std::unique_ptr<LeMetaEventBuilder> evt_ptr =
+ std::unique_ptr<LeMetaEventBuilder>(new LeMetaEventBuilder(LeSubEventCode::CONNECTION_UPDATE_COMPLETE));
+
+ CHECK(evt_ptr->AddOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddOctets2(handle));
+ CHECK(evt_ptr->AddOctets2(interval));
+ CHECK(evt_ptr->AddOctets2(latency));
+ CHECK(evt_ptr->AddOctets2(supervision_timeout));
+
+ return evt_ptr;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.65.2
+std::unique_ptr<LeMetaEventBuilder> LeMetaEventBuilder::CreateLeAdvertisingReportEvent() {
+ std::unique_ptr<LeMetaEventBuilder> evt_ptr = std::unique_ptr<LeMetaEventBuilder>(
+ new LeMetaEventBuilder(LeSubEventCode::ADVERTISING_REPORT, std::unique_ptr<RawBuilder>(new CountedBuilder())));
+
+ return evt_ptr;
+}
+
+bool LeMetaEventBuilder::AddLeAdvertisingReport(LeAdvertisement::AdvertisementType event_type,
+ LeAdvertisement::AddressType addr_type, const Address& addr,
+ const vector<uint8_t>& data, uint8_t rssi) {
+ if (!CanAddOctets(10 + data.size())) return false;
+
+ CHECK(sub_event_code_ == LeSubEventCode::ADVERTISING_REPORT);
+
+ std::unique_ptr<RawBuilder> ad = std::make_unique<RawBuilder>();
+
+ CHECK(ad->AddOctets1(static_cast<uint8_t>(event_type)));
+ CHECK(ad->AddOctets1(static_cast<uint8_t>(addr_type)));
+ CHECK(ad->AddAddress(addr));
+ CHECK(ad->AddOctets1(data.size()));
+ CHECK(ad->AddOctets(data));
+ CHECK(ad->AddOctets1(rssi));
+ AddBuilder(std::move(ad));
+ return true;
+}
+
+// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.65.4
+std::unique_ptr<LeMetaEventBuilder> LeMetaEventBuilder::CreateLeRemoteUsedFeaturesEvent(Status status, uint16_t handle,
+ uint64_t features) {
+ std::unique_ptr<LeMetaEventBuilder> evt_ptr =
+ std::unique_ptr<LeMetaEventBuilder>(new LeMetaEventBuilder(LeSubEventCode::READ_REMOTE_FEATURES_COMPLETE));
+
+ CHECK(evt_ptr->AddOctets1(static_cast<uint8_t>(status)));
+ CHECK(evt_ptr->AddOctets2(handle));
+ CHECK(evt_ptr->AddOctets8(features));
+
+ return evt_ptr;
+}
+
+size_t LeMetaEventBuilder::size() const {
+ return 1 + payload_->size(); // Add the sub_event_code
+}
+
+void LeMetaEventBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ insert(static_cast<uint8_t>(sub_event_code_), it);
+ uint8_t payload_size = size() - sizeof(uint8_t);
+ CHECK(size() - sizeof(uint8_t) == static_cast<size_t>(payload_size)) << "Payload too large for an event: " << size();
+ payload_->Serialize(it);
+}
+
+bool LeMetaEventBuilder::AddBuilder(std::unique_ptr<BasePacketBuilder> builder) {
+ // Upcast the payload to add the next builder.
+ CountedBuilder* temp_ptr = static_cast<CountedBuilder*>(payload_.get());
+ temp_ptr->Add(std::move(builder));
+ return true;
+}
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <base/logging.h>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "include/hci.h"
+#include "include/le_advertisement.h"
+#include "packets/counted_builder.h"
+#include "packets/hci/hci_packet_builder.h"
+#include "packets/packet_builder.h"
+#include "packets/packet_view.h"
+#include "packets/raw_builder.h"
+#include "types/address.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+// LE Meta Event Packets are specified in the Bluetooth Core Specification
+// Version 4.2, Volume 2, Part E, Section 7.7.65. The first byte is the
+// Subevent_Code.
+class LeMetaEventBuilder : public RawBuilder {
+ public:
+ virtual ~LeMetaEventBuilder() override = default;
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
+ // 7.7.65.1
+ static std::unique_ptr<LeMetaEventBuilder> CreateLeConnectionCompleteEvent(hci::Status status, uint16_t handle,
+ uint8_t role, uint8_t peer_address_type,
+ const Address& peer, uint16_t interval,
+ uint16_t latency,
+ uint16_t supervision_timeout);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
+ // 7.7.65.2
+ static std::unique_ptr<LeMetaEventBuilder> CreateLeAdvertisingReportEvent();
+
+ // Returns true if the report can be added to the event packet.
+ bool AddLeAdvertisingReport(LeAdvertisement::AdvertisementType event_type, LeAdvertisement::AddressType addr_type,
+ const Address& addr, const std::vector<uint8_t>& data, uint8_t rssi);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
+ // 7.7.65.3
+ static std::unique_ptr<LeMetaEventBuilder> CreateLeConnectionUpdateCompleteEvent(hci::Status status, uint16_t handle,
+ uint16_t interval, uint16_t latency,
+ uint16_t supervision_timeout);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
+ // 7.7.65.4
+ static std::unique_ptr<LeMetaEventBuilder> CreateLeRemoteUsedFeaturesEvent(hci::Status status, uint16_t handle,
+ uint64_t features);
+
+ // Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section
+ // 7.7.65.10
+ static std::unique_ptr<LeMetaEventBuilder> CreateLeEnhancedConnectionCompleteEvent(
+ hci::Status status, uint16_t handle, uint8_t role, uint8_t peer_address_type, const Address& peer,
+ const Address& local_private_address, const Address& peer_private_address, uint16_t interval, uint16_t latency,
+ uint16_t supervision_timeout);
+
+ virtual size_t size() const override;
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override;
+
+ bool AddBuilder(std::unique_ptr<BasePacketBuilder> builder);
+
+ private:
+ explicit LeMetaEventBuilder(hci::LeSubEventCode sub_event_code);
+ explicit LeMetaEventBuilder(hci::LeSubEventCode sub_event_code, std::unique_ptr<RawBuilder> payload);
+ hci::LeSubEventCode sub_event_code_;
+ std::unique_ptr<RawBuilder> payload_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/sco_packet_builder.h"
+
+#include <base/logging.h>
+
+using std::vector;
+using test_vendor_lib::sco::PacketStatusFlagsType;
+
+namespace test_vendor_lib {
+namespace packets {
+
+ScoPacketBuilder::ScoPacketBuilder(uint16_t handle, PacketStatusFlagsType packet_status_flags,
+ std::unique_ptr<BasePacketBuilder> payload)
+ : handle_(handle), packet_status_flags_(packet_status_flags), payload_(std::move(payload)) {}
+
+size_t ScoPacketBuilder::size() const {
+ return 2 * sizeof(uint16_t) + payload_->size();
+}
+
+void ScoPacketBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ insert(static_cast<uint16_t>((handle_ & 0xfff) | (static_cast<uint16_t>(packet_status_flags_) << 12)), it);
+ uint8_t payload_size = payload_->size();
+
+ CHECK(static_cast<size_t>(payload_size) == payload_->size())
+ << "Payload too large for a SCO packet: " << payload_->size();
+ insert(payload_size, it);
+ payload_->Serialize(it);
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <base/logging.h>
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+#include "include/sco.h"
+#include "packets/hci/hci_packet_builder.h"
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+// SCO data packets are specified in the Bluetooth Core Specification Version
+// 4.2, Volume 2, Part E, Section 5.4.3
+class ScoPacketBuilder : public HciPacketBuilder {
+ public:
+ virtual ~ScoPacketBuilder() override = default;
+
+ static std::unique_ptr<ScoPacketBuilder> Create(uint16_t handle, sco::PacketStatusFlagsType packet_status_flags,
+ std::unique_ptr<BasePacketBuilder> payload);
+
+ virtual size_t size() const override;
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override;
+
+ private:
+ ScoPacketBuilder(uint16_t handle, sco::PacketStatusFlagsType packet_status_flags,
+ std::unique_ptr<BasePacketBuilder> payload);
+ ScoPacketBuilder() = delete;
+ uint16_t handle_;
+ sco::PacketStatusFlagsType packet_status_flags_;
+ std::unique_ptr<BasePacketBuilder> payload_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/sco_packet_view.h"
+
+#include <base/logging.h>
+
+using test_vendor_lib::sco::PacketStatusFlagsType;
+
+namespace test_vendor_lib {
+namespace packets {
+
+ScoPacketView::ScoPacketView(std::shared_ptr<std::vector<uint8_t>> packet) : PacketView<true>(packet) {}
+
+ScoPacketView ScoPacketView::Create(std::shared_ptr<std::vector<uint8_t>> packet) {
+ return ScoPacketView(packet);
+}
+
+uint16_t ScoPacketView::GetHandle() const {
+ return begin().extract<uint16_t>() & 0xfff;
+}
+
+PacketStatusFlagsType ScoPacketView::GetPacketStatusFlags() const {
+ return static_cast<PacketStatusFlagsType>(((begin() + 1).extract<uint8_t>() & 0x30) >> 4);
+}
+
+PacketView<true> ScoPacketView::GetPayload() const {
+ uint8_t payload_size = (begin() + sizeof(uint16_t)).extract<uint8_t>();
+ CHECK(static_cast<uint8_t>(size() - sizeof(uint16_t) - sizeof(uint8_t)) == payload_size)
+ << "Malformed SCO packet payload_size " << payload_size << " + 4 != " << size();
+ return SubViewLittleEndian(sizeof(uint16_t) + sizeof(uint8_t), size());
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <base/logging.h>
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+#include "include/sco.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+// SCO data packets are specified in the Bluetooth Core Specification Version
+// 4.2, Volume 2, Part E, Section 5.4.3
+class ScoPacketView : public PacketView<true> {
+ public:
+ virtual ~ScoPacketView() override = default;
+
+ static ScoPacketView Create(std::shared_ptr<std::vector<uint8_t>> packet);
+
+ uint16_t GetHandle() const;
+ sco::PacketStatusFlagsType GetPacketStatusFlags() const;
+ PacketView<true> GetPayload() const;
+
+ private:
+ ScoPacketView(std::shared_ptr<std::vector<uint8_t>> packet);
+ ScoPacketView() = delete;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/acl_packet_builder.h"
+#include "packets/hci/acl_packet_view.h"
+#include "packets/raw_builder.h"
+
+#include <gtest/gtest.h>
+#include <forward_list>
+#include <memory>
+
+#include "types/address.h"
+
+using std::vector;
+using test_vendor_lib::acl::BroadcastFlagsType;
+using test_vendor_lib::acl::PacketBoundaryFlagsType;
+
+namespace {
+vector<uint8_t> count = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+};
+
+vector<uint8_t> information_request = {
+ 0xfe, 0x2e, 0x0a, 0x00, 0x06, 0x00, 0x01, 0x00, 0x0a, 0x02, 0x02, 0x00, 0x02, 0x00,
+};
+
+} // namespace
+
+namespace test_vendor_lib {
+namespace packets {
+
+class AclBuilderTest : public ::testing::Test {
+ public:
+ AclBuilderTest() = default;
+ ~AclBuilderTest() = default;
+};
+
+TEST(AclBuilderTest, buildAclCountTest) {
+ uint16_t handle = 0x0102;
+ PacketBoundaryFlagsType packet_boundary_flags = PacketBoundaryFlagsType::FIRST_AUTOMATICALLY_FLUSHABLE;
+ BroadcastFlagsType broadcast_flags = BroadcastFlagsType::ACTIVE_SLAVE_BROADCAST;
+
+ std::unique_ptr<RawBuilder> count_payload = std::make_unique<RawBuilder>();
+ count_payload->AddOctets(count);
+ ASSERT_EQ(count.size(), count_payload->size());
+
+ std::unique_ptr<AclPacketBuilder> count_packet =
+ AclPacketBuilder::Create(handle, packet_boundary_flags, broadcast_flags, std::move(count_payload));
+
+ ASSERT_EQ(count.size() + 4, count_packet->size());
+
+ std::shared_ptr<std::vector<uint8_t>> count_packet_bytes = count_packet->ToVector();
+ AclPacketView count_packet_view = AclPacketView::Create(count_packet_bytes);
+
+ ASSERT_EQ(handle, count_packet_view.GetHandle());
+ ASSERT_EQ(packet_boundary_flags, count_packet_view.GetPacketBoundaryFlags());
+ ASSERT_EQ(broadcast_flags, count_packet_view.GetBroadcastFlags());
+ PacketView<true> count_view = count_packet_view.GetPayload();
+
+ ASSERT_EQ(count_view.size(), count.size());
+ for (size_t i = 0; i < count_view.size(); i++) {
+ ASSERT_EQ(count_view[i], count[i]);
+ }
+}
+
+TEST(AclBuilderTest, buildInformationRequest) {
+ uint16_t handle = 0x0efe;
+ PacketBoundaryFlagsType packet_boundary_flags = PacketBoundaryFlagsType::FIRST_AUTOMATICALLY_FLUSHABLE;
+ BroadcastFlagsType broadcast_flags = BroadcastFlagsType::POINT_TO_POINT;
+
+ std::vector<uint8_t> payload_bytes(information_request.begin() + 4, information_request.end());
+ std::unique_ptr<RawBuilder> payload = std::make_unique<RawBuilder>();
+ payload->AddOctets(payload_bytes);
+ ASSERT_EQ(payload_bytes.size(), payload->size());
+
+ std::unique_ptr<AclPacketBuilder> packet =
+ AclPacketBuilder::Create(handle, packet_boundary_flags, broadcast_flags, std::move(payload));
+
+ ASSERT_EQ(information_request.size(), packet->size());
+
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes = packet->ToVector();
+ AclPacketView packet_view = AclPacketView::Create(packet_bytes);
+
+ ASSERT_EQ(packet_bytes->size(), information_request.size());
+ for (size_t i = 0; i < packet_bytes->size(); i++) {
+ ASSERT_EQ((*packet_bytes)[i], information_request[i]);
+ }
+
+ ASSERT_EQ(handle, packet_view.GetHandle());
+ ASSERT_EQ(packet_boundary_flags, packet_view.GetPacketBoundaryFlags());
+ ASSERT_EQ(broadcast_flags, packet_view.GetBroadcastFlags());
+ PacketView<true> payload_view = packet_view.GetPayload();
+
+ ASSERT_EQ(payload_view.size(), payload_bytes.size());
+ for (size_t i = 0; i < payload_view.size(); i++) {
+ ASSERT_EQ(payload_view[i], payload_bytes[i]);
+ }
+
+ ASSERT_EQ(packet_view.size(), information_request.size());
+ for (size_t i = 0; i < packet_view.size(); i++) {
+ ASSERT_EQ(packet_view[i], information_request[i]);
+ }
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/hci/event_packet_builder.h"
+
+#include <gtest/gtest.h>
+#include <forward_list>
+#include <memory>
+
+#include "types/address.h"
+
+using std::vector;
+
+namespace {
+vector<uint8_t> count = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+};
+
+} // namespace
+
+namespace test_vendor_lib {
+namespace packets {
+
+class EventBuilderTest : public ::testing::Test {
+ public:
+ EventBuilderTest() = default;
+ ~EventBuilderTest() = default;
+};
+
+TEST(EventBuilderTest, buildLeAdvertisementSmallTest) {
+ LeAdvertisement::AdvertisementType adv_type = LeAdvertisement::AdvertisementType::ADV_SCAN_IND;
+ LeAdvertisement::AddressType addr_type = LeAdvertisement::AddressType::RANDOM;
+ std::unique_ptr<EventPacketBuilder> le_adv = EventPacketBuilder::CreateLeAdvertisingReportEvent();
+ Address addr({1, 2, 3, 4, 5, 6});
+ uint8_t rssi = -93;
+
+ std::vector<uint8_t> payload({0x23});
+ le_adv->AddLeAdvertisingReport(adv_type, addr_type, addr, {payload}, rssi);
+
+ uint8_t payload_size = payload.size();
+ uint8_t event_size = payload_size + sizeof(Address) + sizeof(rssi) + 5;
+ std::vector<uint8_t> expected({
+ 0x3e, // HCI LE Event
+ event_size,
+ 0x02, // LE Advertising subevent code
+ 0x01, // Number of responses
+ 0x02, // Event type is scannable undirected
+ 0x01, // Address type is random
+ 0x01, // Address
+ 0x02, // Address
+ 0x03, // Address
+ 0x04, // Address
+ 0x05, // Address
+ 0x06, // Address
+ payload_size, // Length of the data
+ });
+
+ expected.push_back(payload[0]);
+ expected.push_back(rssi);
+
+ ASSERT_EQ(expected.size(), le_adv->size());
+ ASSERT_EQ(expected, *le_adv->ToVector());
+}
+
+TEST(EventBuilderTest, buildLeAdvertisementTest) {
+ LeAdvertisement::AdvertisementType adv_type = LeAdvertisement::AdvertisementType::ADV_SCAN_IND;
+ LeAdvertisement::AddressType addr_type = LeAdvertisement::AddressType::RANDOM;
+ std::unique_ptr<EventPacketBuilder> le_adv = EventPacketBuilder::CreateLeAdvertisingReportEvent();
+ Address addr({1, 2, 3, 4, 5, 6});
+ uint8_t rssi = -93;
+
+ le_adv->AddLeAdvertisingReport(adv_type, addr_type, addr, count, rssi);
+
+ uint8_t count_size = static_cast<uint8_t>(count.size());
+ uint8_t event_size = count_size + sizeof(Address) + sizeof(rssi) + 5;
+ std::vector<uint8_t> expected({
+ 0x3e, // HCI LE Event
+ event_size,
+ 0x02, // LE Advertising subevent code
+ 0x01, // Number of responses
+ 0x02, // Event type is scannable undirected
+ 0x01, // Address type is random
+ 0x01, // Address
+ 0x02, // Address
+ 0x03, // Address
+ 0x04, // Address
+ 0x05, // Address
+ 0x06, // Address
+ count_size, // Length of the data
+ });
+
+ for (size_t i = 0; i < count.size(); i++) {
+ expected.push_back(count[i]);
+ }
+ expected.push_back(rssi);
+
+ std::shared_ptr<std::vector<uint8_t>> raw_adv = le_adv->ToVector();
+ ASSERT_EQ(expected, *raw_adv);
+}
+
+TEST(EventBuilderTest, buildNumberOfCompletedPackets) {
+ uint16_t handle = 0x0102;
+ uint16_t num_packets = 0x0304;
+
+ std::unique_ptr<EventPacketBuilder> event =
+ EventPacketBuilder::CreateNumberOfCompletedPacketsEvent(handle, num_packets);
+
+ uint8_t number_of_handles = 1;
+ uint8_t event_size = sizeof(uint8_t) + number_of_handles * 2 * sizeof(uint16_t);
+ std::vector<uint8_t> expected({
+ 0x13, // HCI Number Of Completed Packets Event code
+ event_size, number_of_handles, //
+ 0x02, 0x01, // handle
+ 0x04, 0x03, // count
+ });
+
+ std::shared_ptr<std::vector<uint8_t>> raw_event = event->ToVector();
+ ASSERT_EQ(expected, *raw_event);
+}
+
+TEST(EventBuilderTest, buildNumberOfCompletedPacketsMultiple) {
+ uint16_t handle = 0x0102;
+ uint16_t num_packets = 0x0304;
+ uint16_t handle2 = 0x0506;
+ uint16_t num_packets2 = 0x0708;
+
+ std::unique_ptr<EventPacketBuilder> event =
+ EventPacketBuilder::CreateNumberOfCompletedPacketsEvent(handle, num_packets);
+ event->AddCompletedPackets(handle2, num_packets2);
+
+ uint8_t number_of_handles = 2;
+ uint8_t event_size = sizeof(uint8_t) + number_of_handles * 2 * sizeof(uint16_t);
+ std::vector<uint8_t> expected({
+ 0x13, // HCI Number Of Completed Packets Event code
+ event_size, number_of_handles, //
+ 0x02, 0x01, // handle
+ 0x04, 0x03, // count
+ 0x06, 0x05, // handle
+ 0x08, 0x07, // count
+ });
+
+ std::shared_ptr<std::vector<uint8_t>> raw_event = event->ToVector();
+ ASSERT_EQ(expected, *raw_event);
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
}
template <bool little_endian>
-Iterator<little_endian>& Iterator<little_endian>::operator=(
- const Iterator<little_endian>& itr) {
+Iterator<little_endian>& Iterator<little_endian>::operator=(const Iterator<little_endian>& itr) {
data_ = itr.data_;
index_ = itr.index_;
}
template <bool little_endian>
-bool Iterator<little_endian>::operator==(
- const Iterator<little_endian>& itr) const {
+bool Iterator<little_endian>::operator==(const Iterator<little_endian>& itr) const {
return index_ == itr.index_;
}
template <bool little_endian>
-bool Iterator<little_endian>::operator!=(
- const Iterator<little_endian>& itr) const {
+bool Iterator<little_endian>::operator!=(const Iterator<little_endian>& itr) const {
return !(*this == itr);
}
template <bool little_endian>
-bool Iterator<little_endian>::operator<(
- const Iterator<little_endian>& itr) const {
+bool Iterator<little_endian>::operator<(const Iterator<little_endian>& itr) const {
return index_ < itr.index_;
}
template <bool little_endian>
-bool Iterator<little_endian>::operator>(
- const Iterator<little_endian>& itr) const {
+bool Iterator<little_endian>::operator>(const Iterator<little_endian>& itr) const {
return index_ > itr.index_;
}
template <bool little_endian>
-bool Iterator<little_endian>::operator<=(
- const Iterator<little_endian>& itr) const {
+bool Iterator<little_endian>::operator<=(const Iterator<little_endian>& itr) const {
return index_ <= itr.index_;
}
template <bool little_endian>
-bool Iterator<little_endian>::operator>=(
- const Iterator<little_endian>& itr) const {
+bool Iterator<little_endian>::operator>=(const Iterator<little_endian>& itr) const {
return index_ >= itr.index_;
}
template <bool little_endian>
uint8_t Iterator<little_endian>::operator*() const {
- CHECK(index_ < length_) << "Index " << index_
- << " out of bounds: " << length_;
+ CHECK(index_ < length_) << "Index " << index_ << " out of bounds: " << length_;
size_t index = index_;
for (auto view : data_) {
#include <cstdint>
#include <forward_list>
-#include "types/raw_address.h"
+#include "types/address.h"
#include "view.h"
namespace test_vendor_lib {
// Templated Iterator for endianness
template <bool little_endian>
-class Iterator
- : public std::iterator<std::random_access_iterator_tag, uint8_t> {
+class Iterator : public std::iterator<std::random_access_iterator_tag, uint8_t> {
public:
Iterator(std::forward_list<View> data, size_t offset);
Iterator(const Iterator& itr) = default;
// Get the next sizeof(FixedWidthPODType) bytes and return the filled type
template <typename FixedWidthPODType>
FixedWidthPODType extract() {
- static_assert(std::is_pod<FixedWidthPODType>::value,
- "Iterator::extract requires an fixed type.");
+ static_assert(std::is_pod<FixedWidthPODType>::value, "Iterator::extract requires an fixed type.");
FixedWidthPODType extracted_value;
uint8_t* value_ptr = (uint8_t*)&extracted_value;
--- /dev/null
+/*
+ * Copyright 2018 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 "base/logging.h"
+
+#include "packets/packet_builder.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class CommandBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~CommandBuilder() = default;
+
+ static std::unique_ptr<CommandBuilder> Create(uint16_t opcode, PacketView<true> args) {
+ return std::unique_ptr<CommandBuilder>(new CommandBuilder(opcode, args));
+ }
+
+ virtual size_t size() const override {
+ return sizeof(opcode_) + args_.size();
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ insert(opcode_, it);
+ for (const auto&& byte : args_) {
+ insert(byte, it);
+ }
+ }
+
+ private:
+ explicit CommandBuilder(uint16_t opcode, PacketView<true> args) : opcode_(opcode), args_(args) {}
+ uint16_t opcode_;
+ PacketView<true> args_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <log/log.h>
+
+#include "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class CommandView : public PacketView<true> {
+ public:
+ CommandView(const CommandView&) = default;
+ virtual ~CommandView() = default;
+
+ static CommandView GetCommand(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::COMMAND);
+ return CommandView(view.GetPayload());
+ }
+
+ uint16_t GetOpcode() {
+ return begin().extract<uint16_t>();
+ }
+
+ Iterator<true> GetData() {
+ return begin() + sizeof(uint16_t);
+ }
+
+ private:
+ CommandView() = delete;
+ CommandView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "base/logging.h"
+
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class DisconnectBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~DisconnectBuilder() = default;
+
+ static std::unique_ptr<DisconnectBuilder> Create(uint8_t reason) {
+ return std::unique_ptr<DisconnectBuilder>(new DisconnectBuilder(reason));
+ }
+
+ virtual size_t size() const override {
+ return sizeof(reason_);
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ *it++ = reason_;
+ }
+
+ private:
+ explicit DisconnectBuilder(uint8_t reason) : reason_(reason) {}
+ uint8_t reason_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class DisconnectView : public PacketView<true> {
+ public:
+ DisconnectView(const DisconnectView&) = default;
+ virtual ~DisconnectView() = default;
+
+ static DisconnectView GetDisconnect(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::DISCONNECT);
+ return DisconnectView(view.GetPayload());
+ }
+
+ uint8_t GetReason() {
+ return at(0);
+ }
+
+ private:
+ DisconnectView() = delete;
+ DisconnectView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <memory>
+
+#include "base/logging.h"
+
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class EncryptConnectionBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~EncryptConnectionBuilder() = default;
+
+ static std::unique_ptr<EncryptConnectionBuilder> Create(const std::vector<uint8_t>& key) {
+ return std::unique_ptr<EncryptConnectionBuilder>(new EncryptConnectionBuilder(key));
+ }
+
+ virtual size_t size() const override {
+ return key_.size();
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ insert_vector(key_, it);
+ }
+
+ private:
+ explicit EncryptConnectionBuilder(const std::vector<uint8_t>& key) : key_(key.begin(), key.begin() + 16) {}
+ std::vector<uint8_t> key_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class EncryptConnectionView : public PacketView<true> {
+ public:
+ EncryptConnectionView(const EncryptConnectionView&) = default;
+ virtual ~EncryptConnectionView() = default;
+
+ static EncryptConnectionView GetEncryptConnection(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::ENCRYPT_CONNECTION ||
+ view.GetType() == Link::PacketType::ENCRYPT_CONNECTION_RESPONSE);
+ return EncryptConnectionView(view.GetPayload());
+ }
+
+ Iterator<true> GetKey() {
+ return begin();
+ }
+
+ private:
+ EncryptConnectionView() = delete;
+ EncryptConnectionView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "base/logging.h"
+
+#include "inquiry.h"
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class InquiryBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~InquiryBuilder() = default;
+
+ static std::unique_ptr<InquiryBuilder> Create(Inquiry::InquiryType inquiry_type) {
+ return std::unique_ptr<InquiryBuilder>(new InquiryBuilder(inquiry_type));
+ }
+
+ virtual size_t size() const override {
+ return sizeof(uint8_t);
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ insert(static_cast<uint8_t>(inquiry_type_), it);
+ }
+
+ private:
+ explicit InquiryBuilder(Inquiry::InquiryType inquiry_type) : inquiry_type_(inquiry_type) {}
+ Inquiry::InquiryType inquiry_type_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "base/logging.h"
+
+#include "include/inquiry.h"
+#include "packets/packet_builder.h"
+#include "types/class_of_device.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class InquiryResponseBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~InquiryResponseBuilder() = default;
+
+ static std::unique_ptr<InquiryResponseBuilder> CreateStandard(uint8_t page_scan_repetition_mode,
+ const ClassOfDevice& class_of_device,
+ uint16_t clock_offset) {
+ return std::unique_ptr<InquiryResponseBuilder>(new InquiryResponseBuilder(
+ Inquiry::InquiryType::STANDARD, page_scan_repetition_mode, class_of_device, clock_offset));
+ }
+ static std::unique_ptr<InquiryResponseBuilder> CreateRssi(uint8_t page_scan_repetition_mode,
+ const ClassOfDevice& class_of_device, uint16_t clock_offset,
+ uint8_t rssi) {
+ return std::unique_ptr<InquiryResponseBuilder>(new InquiryResponseBuilder(
+ Inquiry::InquiryType::RSSI, page_scan_repetition_mode, class_of_device, clock_offset, rssi));
+ }
+ static std::unique_ptr<InquiryResponseBuilder> CreateExtended(uint8_t page_scan_repetition_mode,
+ const ClassOfDevice& class_of_device,
+ uint16_t clock_offset, uint8_t rssi,
+ const std::vector<uint8_t>& extended_data) {
+ return std::unique_ptr<InquiryResponseBuilder>(new InquiryResponseBuilder(
+ Inquiry::InquiryType::EXTENDED, page_scan_repetition_mode, class_of_device, clock_offset, rssi, extended_data));
+ }
+
+ virtual size_t size() const override {
+ size_t inquiry_size =
+ sizeof(inquiry_type_) + sizeof(page_scan_repetition_mode_) + sizeof(class_of_device_) + sizeof(clock_offset_);
+ if (inquiry_type_ == Inquiry::InquiryType::STANDARD) {
+ return inquiry_size;
+ }
+ inquiry_size += sizeof(rssi_);
+ if (inquiry_type_ == Inquiry::InquiryType::RSSI) {
+ return inquiry_size;
+ }
+
+ return inquiry_size + extended_data_.size();
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ insert(static_cast<uint8_t>(inquiry_type_), it);
+ insert(page_scan_repetition_mode_, it);
+ insert_class_of_device(class_of_device_, it);
+ insert(clock_offset_, it);
+ if (inquiry_type_ == Inquiry::InquiryType::STANDARD) {
+ return;
+ }
+ insert(rssi_, it);
+ if (inquiry_type_ == Inquiry::InquiryType::RSSI) {
+ return;
+ }
+ insert_vector(extended_data_, it);
+ }
+
+ private:
+ Inquiry::InquiryType inquiry_type_;
+ uint8_t page_scan_repetition_mode_;
+ ClassOfDevice class_of_device_;
+ uint16_t clock_offset_;
+ uint8_t rssi_{0xff};
+ std::vector<uint8_t> extended_data_;
+ explicit InquiryResponseBuilder(Inquiry::InquiryType inquiry_type, uint8_t page_scan_repetition_mode,
+ const ClassOfDevice& class_of_device, uint16_t clock_offset)
+ : inquiry_type_(inquiry_type), page_scan_repetition_mode_(page_scan_repetition_mode),
+ class_of_device_(class_of_device), clock_offset_(clock_offset) {}
+ explicit InquiryResponseBuilder(Inquiry::InquiryType inquiry_type, uint8_t page_scan_repetition_mode,
+ const ClassOfDevice& class_of_device, uint16_t clock_offset, uint8_t rssi)
+ : inquiry_type_(inquiry_type), page_scan_repetition_mode_(page_scan_repetition_mode),
+ class_of_device_(class_of_device), clock_offset_(clock_offset), rssi_(rssi) {}
+ explicit InquiryResponseBuilder(Inquiry::InquiryType inquiry_type, uint8_t page_scan_repetition_mode,
+ const ClassOfDevice& class_of_device, uint16_t clock_offset, uint8_t rssi,
+ const std::vector<uint8_t>& extended_data)
+ : inquiry_type_(inquiry_type), page_scan_repetition_mode_(page_scan_repetition_mode),
+ class_of_device_(class_of_device), clock_offset_(clock_offset), rssi_(rssi), extended_data_(extended_data) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "include/inquiry.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class InquiryResponseView : public PacketView<true> {
+ public:
+ InquiryResponseView(const InquiryResponseView&) = default;
+ virtual ~InquiryResponseView() = default;
+
+ static InquiryResponseView GetInquiryResponse(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::INQUIRY_RESPONSE);
+ return InquiryResponseView(view.GetPayload());
+ }
+
+ Inquiry::InquiryType GetType() {
+ return static_cast<Inquiry::InquiryType>(at(0));
+ }
+
+ uint8_t GetPageScanRepetitionMode() {
+ return at(1);
+ }
+
+ ClassOfDevice GetClassOfDevice() {
+ size_t offset = 2 * sizeof(uint8_t);
+ return (begin() + offset).extract<ClassOfDevice>();
+ }
+
+ uint16_t GetClockOffset() {
+ size_t offset = 2 * sizeof(uint8_t) + 3;
+ return (begin() + offset).extract<uint16_t>();
+ }
+
+ uint8_t GetRssi() {
+ size_t offset = 2 * sizeof(uint8_t) + 3 + sizeof(uint16_t);
+ return at(offset);
+ }
+
+ Iterator<true> GetExtendedData() {
+ size_t offset = 2 * sizeof(uint8_t) + 3 + sizeof(uint16_t) + sizeof(uint8_t);
+ return begin() + offset;
+ }
+
+ private:
+ InquiryResponseView() = delete;
+ InquiryResponseView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "inquiry.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class InquiryView : public PacketView<true> {
+ public:
+ InquiryView(const InquiryView&) = default;
+ virtual ~InquiryView() = default;
+
+ static InquiryView GetInquiry(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::INQUIRY);
+ return InquiryView(view.GetPayload());
+ }
+
+ Inquiry::InquiryType GetType() {
+ return static_cast<Inquiry::InquiryType>(at(0));
+ }
+
+ private:
+ InquiryView() = delete;
+ InquiryView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <memory>
+
+#include "base/logging.h"
+
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class IoCapabilityBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~IoCapabilityBuilder() = default;
+
+ static std::unique_ptr<IoCapabilityBuilder> Create(uint8_t io_capability, uint8_t oob_data_present,
+ uint8_t authentication_requirements) {
+ return std::unique_ptr<IoCapabilityBuilder>(
+ new IoCapabilityBuilder(io_capability, oob_data_present, authentication_requirements));
+ }
+
+ virtual size_t size() const override {
+ return sizeof(io_capability_) + sizeof(oob_data_present_) + sizeof(authentication_requirements_);
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ insert(io_capability_, it);
+ insert(oob_data_present_, it);
+ insert(authentication_requirements_, it);
+ }
+
+ private:
+ explicit IoCapabilityBuilder(uint8_t io_capability, uint8_t oob_data_present, uint8_t authentication_requirements)
+ : io_capability_(io_capability), oob_data_present_(oob_data_present),
+ authentication_requirements_(authentication_requirements) {}
+ uint8_t io_capability_;
+ uint8_t oob_data_present_;
+ uint8_t authentication_requirements_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <memory>
+
+#include "base/logging.h"
+
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class IoCapabilityNegativeResponseBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~IoCapabilityNegativeResponseBuilder() = default;
+
+ static std::unique_ptr<IoCapabilityNegativeResponseBuilder> Create(uint8_t reason) {
+ return std::unique_ptr<IoCapabilityNegativeResponseBuilder>(new IoCapabilityNegativeResponseBuilder(reason));
+ }
+
+ virtual size_t size() const override {
+ return sizeof(reason_);
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ insert(reason_, it);
+ }
+
+ private:
+ explicit IoCapabilityNegativeResponseBuilder(uint8_t reason) : reason_(reason) {}
+ uint8_t reason_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class IoCapabilityNegativeResponseView : public PacketView<true> {
+ public:
+ IoCapabilityNegativeResponseView(const IoCapabilityNegativeResponseView&) = default;
+ virtual ~IoCapabilityNegativeResponseView() = default;
+
+ static IoCapabilityNegativeResponseView GetIoCapabilityNegativeResponse(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::IO_CAPABILITY_NEGATIVE_RESPONSE);
+ return IoCapabilityNegativeResponseView(view.GetPayload());
+ }
+
+ uint8_t GetReason() {
+ return at(0);
+ }
+
+ private:
+ IoCapabilityNegativeResponseView() = delete;
+ IoCapabilityNegativeResponseView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class IoCapabilityView : public PacketView<true> {
+ public:
+ IoCapabilityView(const IoCapabilityView&) = default;
+ virtual ~IoCapabilityView() = default;
+
+ static IoCapabilityView GetIoCapability(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::IO_CAPABILITY_RESPONSE ||
+ view.GetType() == Link::PacketType::IO_CAPABILITY_REQUEST);
+ return IoCapabilityView(view.GetPayload());
+ }
+
+ uint8_t GetIoCapability() {
+ return at(0);
+ }
+ uint8_t GetOobDataPresent() {
+ return at(1);
+ }
+ uint8_t GetAuthenticationRequirements() {
+ return at(2);
+ }
+
+ private:
+ IoCapabilityView() = delete;
+ IoCapabilityView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "base/logging.h"
+
+#include "include/le_advertisement.h"
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class LeAdvertisementBuilder : public PacketBuilder<true>, public LeAdvertisement {
+ public:
+ virtual ~LeAdvertisementBuilder() = default;
+
+ static std::unique_ptr<LeAdvertisementBuilder> Create(AddressType address_type, AdvertisementType advertisement_type,
+ const std::vector<uint8_t>& advertisement) {
+ return std::unique_ptr<LeAdvertisementBuilder>(
+ new LeAdvertisementBuilder(address_type, advertisement_type, advertisement));
+ }
+
+ virtual size_t size() const override {
+ return sizeof(address_type_) + sizeof(advertisement_type_) + advertisement_.size();
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ insert(static_cast<uint8_t>(address_type_), it);
+ insert(static_cast<uint8_t>(advertisement_type_), it);
+ insert_vector(advertisement_, it);
+ }
+
+ private:
+ LeAdvertisementBuilder() = delete;
+ explicit LeAdvertisementBuilder(AddressType address_type, AdvertisementType advertisement_type,
+ const std::vector<uint8_t>& advertisement)
+ : address_type_(address_type), advertisement_type_(advertisement_type), advertisement_(advertisement) {}
+ AddressType address_type_;
+ AdvertisementType advertisement_type_;
+ std::vector<uint8_t> advertisement_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <log/log.h>
+
+#include "include/link.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class LeAdvertisementView : public PacketView<true>, public LeAdvertisement {
+ public:
+ LeAdvertisementView(const LeAdvertisementView&) = default;
+ virtual ~LeAdvertisementView() = default;
+
+ static LeAdvertisementView GetLeAdvertisementView(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::LE_ADVERTISEMENT || view.GetType() == Link::PacketType::LE_SCAN_RESPONSE);
+ return LeAdvertisementView(view.GetPayload());
+ }
+
+ AddressType GetAddressType() {
+ return static_cast<AddressType>(at(0));
+ }
+ AdvertisementType GetAdvertisementType() {
+ return static_cast<AdvertisementType>(at(1));
+ }
+ Iterator<true> GetData() {
+ return begin() + 2 * sizeof(uint8_t);
+ }
+
+ private:
+ LeAdvertisementView() = delete;
+ LeAdvertisementView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "link_layer_packet_builder.h"
+#include "link_layer_packet_view.h"
+
+#include "base/logging.h"
+
+using std::vector;
+
+namespace test_vendor_lib {
+
+namespace packets {
+
+LinkLayerPacketBuilder::LinkLayerPacketBuilder(Link::PacketType type, const Address& source, const Address& dest)
+ : type_(type), source_addr_(source), dest_addr_(dest) {}
+
+LinkLayerPacketBuilder::LinkLayerPacketBuilder(Link::PacketType type, std::unique_ptr<PacketBuilder> packet,
+ const Address& source)
+ : type_(type), source_addr_(source), dest_addr_(Address::kEmpty), builder_(std::move(packet)) {}
+
+LinkLayerPacketBuilder::LinkLayerPacketBuilder(Link::PacketType type, std::unique_ptr<PacketBuilder> packet,
+ const Address& source, const Address& dest)
+ : type_(type), source_addr_(source), dest_addr_(dest), builder_(std::move(packet)) {}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapAcl(std::unique_ptr<ViewForwarderBuilder> acl,
+ const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::ACL, std::move(acl), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapCommand(std::unique_ptr<CommandBuilder> command,
+ const Address& source,
+ const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::COMMAND, std::move(command), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapDisconnect(
+ std::unique_ptr<DisconnectBuilder> disconnect, const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::DISCONNECT, std::move(disconnect), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapEncryptConnection(
+ std::unique_ptr<EncryptConnectionBuilder> encrypt_connection, const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::ENCRYPT_CONNECTION, std::move(encrypt_connection), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapEncryptConnectionResponse(
+ std::unique_ptr<EncryptConnectionBuilder> encrypt_connection, const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(new LinkLayerPacketBuilder(
+ Link::PacketType::ENCRYPT_CONNECTION_RESPONSE, std::move(encrypt_connection), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapInquiry(std::unique_ptr<InquiryBuilder> inquiry,
+ const Address& source) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::INQUIRY, std::move(inquiry), source));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapInquiryResponse(
+ std::unique_ptr<InquiryResponseBuilder> inquiry_response, const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::INQUIRY_RESPONSE, std::move(inquiry_response), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapIoCapabilityRequest(
+ std::unique_ptr<IoCapabilityBuilder> io_capability, const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::IO_CAPABILITY_REQUEST, std::move(io_capability), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapIoCapabilityResponse(
+ std::unique_ptr<IoCapabilityBuilder> io_capability, const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::IO_CAPABILITY_RESPONSE, std::move(io_capability), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapIoCapabilityNegativeResponse(
+ std::unique_ptr<IoCapabilityNegativeResponseBuilder> io_capability_negative_response, const Address& source,
+ const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(new LinkLayerPacketBuilder(
+ Link::PacketType::IO_CAPABILITY_NEGATIVE_RESPONSE, std::move(io_capability_negative_response), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapLeAdvertisement(
+ std::unique_ptr<LeAdvertisementBuilder> advertisement, const Address& source) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::LE_ADVERTISEMENT, std::move(advertisement), source));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapLeScan(const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(new LinkLayerPacketBuilder(Link::PacketType::LE_SCAN, source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapLeScanResponse(
+ std::unique_ptr<LeAdvertisementBuilder> scan_response, const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::LE_SCAN_RESPONSE, std ::move(scan_response), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapPage(std::unique_ptr<PageBuilder> page,
+ const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::PAGE, std::move(page), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapPageResponse(
+ std::unique_ptr<PageResponseBuilder> page_response, const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::PAGE_RESPONSE, std::move(page_response), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapResponse(std::unique_ptr<ResponseBuilder> response,
+ const Address& source,
+ const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::RESPONSE, std::move(response), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::WrapSco(std::unique_ptr<ViewForwarderBuilder> sco,
+ const Address& source, const Address& dest) {
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(Link::PacketType::SCO, std::move(sco), source, dest));
+}
+
+std::shared_ptr<LinkLayerPacketBuilder> LinkLayerPacketBuilder::ReWrap(
+ const std::shared_ptr<std::vector<uint8_t>> raw_packet) {
+ LinkLayerPacketView received = LinkLayerPacketView::Create(raw_packet);
+ Link::PacketType packet_type = received.GetType();
+ Address source = received.GetSourceAddress();
+ Address dest = received.GetDestinationAddress();
+ PacketView<true> payload = received.GetPayload();
+ std::unique_ptr<PacketBuilder> builder = ViewForwarderBuilder::Create(payload);
+ return std::shared_ptr<LinkLayerPacketBuilder>(
+ new LinkLayerPacketBuilder(packet_type, std::move(builder), source, dest));
+}
+
+size_t LinkLayerPacketBuilder::size() const {
+ size_t builder_size = (builder_ ? builder_->size() : 0);
+ return Link::kTypeBytes + Link::kSizeBytes + 2 * Address::kLength + builder_size;
+}
+
+void LinkLayerPacketBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ insert(static_cast<uint32_t>(size() - Link::kSizeBytes), it);
+ insert(static_cast<uint8_t>(type_), it);
+ insert_address(source_addr_.address, it);
+ insert_address(dest_addr_.address, it);
+ if (builder_) {
+ builder_->Serialize(it);
+ }
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <string>
+#include <vector>
+
+#include "link.h"
+#include "packets/link_layer/command_builder.h"
+#include "packets/link_layer/disconnect_builder.h"
+#include "packets/link_layer/encrypt_connection_builder.h"
+#include "packets/link_layer/inquiry_builder.h"
+#include "packets/link_layer/inquiry_response_builder.h"
+#include "packets/link_layer/io_capability_builder.h"
+#include "packets/link_layer/io_capability_negative_response_builder.h"
+#include "packets/link_layer/le_advertisement_builder.h"
+#include "packets/link_layer/page_builder.h"
+#include "packets/link_layer/page_response_builder.h"
+#include "packets/link_layer/response_builder.h"
+#include "packets/link_layer/view_forwarder_builder.h"
+#include "packets/packet_builder.h"
+#include "types/address.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+// Link-layer packets are an abstraction of LMP PDUs.
+class LinkLayerPacketBuilder : PacketBuilder<true> {
+ public:
+ virtual ~LinkLayerPacketBuilder() = default;
+
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapAcl(std::unique_ptr<ViewForwarderBuilder> acl,
+ const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapCommand(std::unique_ptr<CommandBuilder> command,
+ const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapDisconnect(std::unique_ptr<DisconnectBuilder> disconnect,
+ const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapEncryptConnection(
+ std::unique_ptr<EncryptConnectionBuilder> encrypt_connection, const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapEncryptConnectionResponse(
+ std::unique_ptr<EncryptConnectionBuilder> encrypt_connection, const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapInquiry(std::unique_ptr<InquiryBuilder> inquiry,
+ const Address& source);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapInquiryResponse(
+ std::unique_ptr<InquiryResponseBuilder> inquiry_response, const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapIoCapabilityRequest(
+ std::unique_ptr<IoCapabilityBuilder> io_capability, const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapIoCapabilityResponse(
+ std::unique_ptr<IoCapabilityBuilder> io_capability, const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapIoCapabilityNegativeResponse(
+ std::unique_ptr<IoCapabilityNegativeResponseBuilder> io_capability_negative_response, const Address& source,
+ const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapLeAdvertisement(
+ std::unique_ptr<LeAdvertisementBuilder> advertisement, const Address& source);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapLeScan(const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapLeScanResponse(
+ std::unique_ptr<LeAdvertisementBuilder> scan_response, const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapPage(std::unique_ptr<PageBuilder> page, const Address& source,
+ const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapPageResponse(std::unique_ptr<PageResponseBuilder> page_response,
+ const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapResponse(const std::unique_ptr<ResponseBuilder> response,
+ const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> WrapSco(std::unique_ptr<ViewForwarderBuilder> sco,
+ const Address& source, const Address& dest);
+ static std::shared_ptr<LinkLayerPacketBuilder> ReWrap(const std::shared_ptr<std::vector<uint8_t>> raw_packet);
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override;
+
+ virtual size_t size() const override;
+
+ private:
+ LinkLayerPacketBuilder(const LinkLayerPacketBuilder&) = delete;
+ LinkLayerPacketBuilder() = delete;
+ LinkLayerPacketBuilder(Link::PacketType type, const Address& source, const Address& dest);
+ LinkLayerPacketBuilder(Link::PacketType type, std::unique_ptr<PacketBuilder> builder, const Address& source,
+ const Address& dest);
+ LinkLayerPacketBuilder(Link::PacketType type, std::unique_ptr<PacketBuilder> builder, const Address& source);
+ Link::PacketType type_;
+ Address source_addr_;
+ Address dest_addr_;
+ std::unique_ptr<PacketBuilder> builder_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "link_layer_packet_view.h"
+#include "base/logging.h"
+
+namespace test_vendor_lib {
+constexpr size_t Link::kSizeBytes;
+constexpr size_t Link::kTypeBytes;
+
+namespace packets {
+LinkLayerPacketView::LinkLayerPacketView(std::shared_ptr<std::vector<uint8_t>> raw) : PacketView<true>(raw) {}
+
+LinkLayerPacketView LinkLayerPacketView::Create(std::shared_ptr<std::vector<uint8_t>> raw) {
+ CHECK(raw->size() >= Link::kSizeBytes + Link::kTypeBytes + 2 * Address::kLength);
+ return LinkLayerPacketView(raw);
+}
+
+Link::PacketType LinkLayerPacketView::GetType() const {
+ return static_cast<Link::PacketType>(at(Link::kSizeBytes));
+}
+
+Address LinkLayerPacketView::GetSourceAddress() const {
+ size_t offset = Link::kSizeBytes + Link::kTypeBytes;
+ return (begin() + offset).extract<Address>();
+}
+
+Address LinkLayerPacketView::GetDestinationAddress() const {
+ size_t offset = Link::kSizeBytes + Link::kTypeBytes + Address::kLength;
+ return (begin() + offset).extract<Address>();
+}
+
+PacketView<true> LinkLayerPacketView::GetPayload() const {
+ return SubViewLittleEndian(Link::kSizeBytes + Link::kTypeBytes + 2 * Address::kLength, size());
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <string>
+#include <vector>
+
+#include "include/link.h"
+#include "packets/packet_view.h"
+#include "types/address.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+// Link-layer packets are an abstraction of LMP PDUs.
+class LinkLayerPacketView : public PacketView<true> {
+ public:
+ LinkLayerPacketView(const LinkLayerPacketView&) = default;
+ virtual ~LinkLayerPacketView() = default;
+
+ static LinkLayerPacketView Create(std::shared_ptr<std::vector<uint8_t>> raw);
+
+ Link::PacketType GetType() const;
+ Address GetSourceAddress() const;
+ Address GetDestinationAddress() const;
+ PacketView<true> GetPayload() const;
+
+ private:
+ LinkLayerPacketView() = delete;
+ LinkLayerPacketView(std::shared_ptr<std::vector<uint8_t>> raw);
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <base/logging.h>
+
+#include "packets/packet_builder.h"
+#include "types/class_of_device.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class PageBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~PageBuilder() = default;
+
+ static std::unique_ptr<PageBuilder> Create(const ClassOfDevice& class_of_device, uint8_t allow_role_switch) {
+ return std::unique_ptr<PageBuilder>(new PageBuilder(class_of_device, allow_role_switch));
+ }
+
+ virtual size_t size() const override {
+ return sizeof(class_of_device_) + sizeof(allow_role_switch_);
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ insert_class_of_device(class_of_device_, it);
+ insert(allow_role_switch_, it);
+ }
+
+ private:
+ explicit PageBuilder(const ClassOfDevice& class_of_device, uint8_t allow_role_switch)
+ : class_of_device_(class_of_device), allow_role_switch_(allow_role_switch) {}
+ ClassOfDevice class_of_device_;
+ uint8_t allow_role_switch_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "base/logging.h"
+
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class PageResponseBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~PageResponseBuilder() = default;
+
+ static std::unique_ptr<PageResponseBuilder> Create(uint8_t try_role_switch) {
+ return std::unique_ptr<PageResponseBuilder>(new PageResponseBuilder(try_role_switch));
+ }
+
+ virtual size_t size() const override {
+ return sizeof(try_role_switch_);
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ insert(try_role_switch_, it);
+ }
+
+ private:
+ explicit PageResponseBuilder(uint8_t try_role_switch) : try_role_switch_(try_role_switch) {}
+ uint8_t try_role_switch_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class PageResponseView : public PacketView<true> {
+ public:
+ PageResponseView(const PageResponseView&) = default;
+ virtual ~PageResponseView() = default;
+
+ static PageResponseView GetPageResponse(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::PAGE_RESPONSE);
+ return PageResponseView(view.GetPayload());
+ }
+
+ uint8_t GetTryRoleSwitch() {
+ return at(0);
+ }
+
+ private:
+ PageResponseView() = delete;
+ PageResponseView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class PageView : public PacketView<true> {
+ public:
+ PageView(const PageView&) = default;
+ virtual ~PageView() = default;
+
+ static PageView GetPage(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::PAGE);
+ return PageView(view.GetPayload());
+ }
+
+ ClassOfDevice GetClassOfDevice() {
+ return begin().extract<ClassOfDevice>();
+ }
+
+ uint8_t GetAllowRoleSwitch() {
+ return at(3);
+ }
+
+ private:
+ PageView() = delete;
+ PageView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "packets/packet_builder.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class ResponseBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~ResponseBuilder() = default;
+
+ static std::unique_ptr<ResponseBuilder> Create(uint16_t opcode, const std::vector<uint64_t>& data) {
+ return std::unique_ptr<ResponseBuilder>(new ResponseBuilder(opcode, data));
+ }
+
+ virtual size_t size() const override {
+ return sizeof(opcode_) + data_.size() * sizeof(uint64_t);
+ }
+
+ protected:
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ insert(opcode_, it);
+ insert_vector(data_, it);
+ }
+
+ private:
+ explicit ResponseBuilder(uint16_t opcode, const std::vector<uint64_t> data) : opcode_(opcode), data_(data) {}
+ uint16_t opcode_;
+ std::vector<uint64_t> data_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <log/log.h>
+
+#include "packets/link_layer/link_layer_packet_view.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class ResponseView : public PacketView<true> {
+ public:
+ ResponseView(const ResponseView&) = default;
+ virtual ~ResponseView() = default;
+
+ static ResponseView GetResponse(const LinkLayerPacketView& view) {
+ CHECK(view.GetType() == Link::PacketType::RESPONSE);
+ return ResponseView(view.GetPayload());
+ }
+
+ uint16_t GetOpcode() {
+ return begin().extract<uint16_t>();
+ }
+
+ Iterator<true> GetResponseData() {
+ return begin() + sizeof(uint16_t);
+ }
+
+ private:
+ ResponseView() = delete;
+ ResponseView(const PacketView<true>& view) : PacketView(view) {}
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "base/logging.h"
+
+#include "packets/packet_builder.h"
+#include "packets/packet_view.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class ViewForwarderBuilder : public PacketBuilder<true> {
+ public:
+ virtual ~ViewForwarderBuilder() = default;
+
+ static std::unique_ptr<ViewForwarderBuilder> Create(PacketView<true> view) {
+ return std::unique_ptr<ViewForwarderBuilder>(new ViewForwarderBuilder(view));
+ }
+
+ virtual size_t size() const override {
+ return view_.size();
+ }
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ for (size_t i = 0; i < view_.size(); i++) {
+ insert(view_[i], it);
+ }
+ }
+
+ private:
+ explicit ViewForwarderBuilder(PacketView<true> view) : view_(view) {}
+ PacketView<true> view_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
#include <vector>
#include "base_packet_builder.h"
-#include "types/raw_address.h"
+#include "types/address.h"
+#include "types/class_of_device.h"
namespace test_vendor_lib {
namespace packets {
protected:
// Write sizeof(FixedWidthIntegerType) bytes using the iterator
- template <typename FixedWidthIntegerType>
- void insert(FixedWidthIntegerType value,
- std::back_insert_iterator<std::vector<uint8_t>> it) const {
- static_assert(std::is_integral<FixedWidthIntegerType>::value,
- "PacketBuilder::insert requires an integral type.");
+ template <typename FixedWidthIntegerType,
+ typename std::enable_if<std::is_integral<FixedWidthIntegerType>::value, int>::type = 0>
+ void insert(FixedWidthIntegerType value, std::back_insert_iterator<std::vector<uint8_t>> it) const {
for (size_t i = 0; i < sizeof(FixedWidthIntegerType); i++) {
if (little_endian == true) {
*it = static_cast<uint8_t>(value >> (i * 8));
} else {
- *it = static_cast<uint8_t>(
- value >> ((sizeof(FixedWidthIntegerType) - i - 1) * 8));
+ *it = static_cast<uint8_t>(value >> ((sizeof(FixedWidthIntegerType) - i - 1) * 8));
}
it++;
}
}
+ // Specialized insert that allows inserting enums without casting
+ template <typename Enum, typename std::enable_if<std::is_enum_v<Enum>, int>::type = 0>
+ inline void insert(Enum value, std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ using enum_type = typename std::underlying_type_t<Enum>;
+ static_assert(std::is_unsigned_v<enum_type>, "Enum type is signed. Did you forget to specify the enum size?");
+ insert<enum_type>(static_cast<enum_type>(value), it);
+ }
+
// Write a vector of FixedWidthIntegerType using the iterator
template <typename FixedWidthIntegerType>
void insert_vector(const std::vector<FixedWidthIntegerType>& vec,
}
}
- void insert_address(
- const RawAddress& addr,
- std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ void insert_address(const Address& addr, std::back_insert_iterator<std::vector<uint8_t>> it) const {
for (const auto& element : addr.address) {
insert(element, it);
}
}
+
+ void insert_class_of_device(const ClassOfDevice& cod, std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ for (const auto& element : cod.cod) {
+ insert(element, it);
+ }
+ }
};
} // namespace packets
namespace packets {
template <bool little_endian>
-PacketView<little_endian>::PacketView(
- const std::forward_list<class View> fragments)
+PacketView<little_endian>::PacketView(const std::forward_list<class View> fragments)
: fragments_(fragments), length_(0) {
for (auto fragment : fragments_) {
length_ += fragment.size();
}
template <bool little_endian>
-PacketView<little_endian>::PacketView(
- std::shared_ptr<std::vector<uint8_t>> packet)
+PacketView<little_endian>::PacketView(std::shared_ptr<std::vector<uint8_t>> packet)
: fragments_({View(packet, 0, packet->size())}), length_(packet->size()) {}
template <bool little_endian>
}
template <bool little_endian>
-std::forward_list<View> PacketView<little_endian>::SubViewList(
- size_t begin, size_t end) const {
+std::forward_list<View> PacketView<little_endian>::SubViewList(size_t begin, size_t end) const {
CHECK(begin <= end) << "Begin " << begin << " is past end";
CHECK(end <= length_) << "End " << end << " is too large";
std::forward_list<View> view_list;
if (begin >= fragment.size()) {
begin -= fragment.size();
} else {
- View view(fragment, begin,
- begin + std::min(length, fragment.size() - begin));
+ View view(fragment, begin, begin + std::min(length, fragment.size() - begin));
length -= view.size();
it = view_list.insert_after(it, view);
begin = 0;
}
template <bool little_endian>
-PacketView<true> PacketView<little_endian>::SubViewLittleEndian(
- size_t begin, size_t end) const {
+PacketView<true> PacketView<little_endian>::SubViewLittleEndian(size_t begin, size_t end) const {
return PacketView<true>(SubViewList(begin, end));
}
template <bool little_endian>
-PacketView<false> PacketView<little_endian>::SubViewBigEndian(
- size_t begin, size_t end) const {
+PacketView<false> PacketView<little_endian>::SubViewBigEndian(size_t begin, size_t end) const {
return PacketView<false>(SubViewList(begin, end));
}
--- /dev/null
+/*
+ * Copyright 2018 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 "raw_builder.h"
+
+#include <base/logging.h>
+#include <algorithm>
+
+using std::vector;
+
+namespace test_vendor_lib {
+namespace packets {
+
+RawBuilder::RawBuilder(size_t max_bytes) : max_bytes_(max_bytes) {}
+
+bool RawBuilder::AddOctets(size_t octets, const vector<uint8_t>& bytes) {
+ if (payload_.size() + octets > max_bytes_) return false;
+
+ if (octets != bytes.size()) return false;
+
+ payload_.insert(payload_.end(), bytes.begin(), bytes.end());
+
+ return true;
+}
+
+bool RawBuilder::AddOctets(const vector<uint8_t>& bytes) {
+ return AddOctets(bytes.size(), bytes);
+}
+
+bool RawBuilder::AddOctets(size_t octets, uint64_t value) {
+ vector<uint8_t> val_vector;
+
+ uint64_t v = value;
+
+ if (octets > sizeof(uint64_t)) return false;
+
+ for (size_t i = 0; i < octets; i++) {
+ val_vector.push_back(v & 0xff);
+ v = v >> 8;
+ }
+
+ if (v != 0) return false;
+
+ return AddOctets(octets, val_vector);
+}
+
+bool RawBuilder::AddAddress(const Address& address) {
+ if (payload_.size() + Address::kLength > max_bytes_) return false;
+
+ for (size_t i = 0; i < Address::kLength; i++) {
+ payload_.push_back(address.address[i]);
+ }
+ return true;
+}
+
+bool RawBuilder::AddOctets1(uint8_t value) {
+ return AddOctets(1, value);
+}
+
+bool RawBuilder::AddOctets2(uint16_t value) {
+ return AddOctets(2, value);
+}
+
+bool RawBuilder::AddOctets3(uint32_t value) {
+ return AddOctets(3, value);
+}
+
+bool RawBuilder::AddOctets4(uint32_t value) {
+ return AddOctets(4, value);
+}
+
+bool RawBuilder::AddOctets6(uint64_t value) {
+ return AddOctets(6, value);
+}
+
+bool RawBuilder::AddOctets8(uint64_t value) {
+ return AddOctets(8, value);
+}
+
+bool RawBuilder::CanAddOctets(size_t num_bytes) const {
+ return payload_.size() + num_bytes <= max_bytes_;
+}
+
+void RawBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
+ for (const auto& val : payload_) {
+ insert(val, it);
+ }
+}
+
+size_t RawBuilder::size() const {
+ return payload_.size();
+}
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 <vector>
+
+#include "packets/packet_builder.h"
+#include "types/address.h"
+
+namespace test_vendor_lib {
+namespace packets {
+
+class RawBuilder : public PacketBuilder<true> {
+ public:
+ RawBuilder() = default;
+ RawBuilder(size_t max_bytes);
+ virtual ~RawBuilder() = default;
+
+ virtual size_t size() const override;
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const;
+
+ // Add |address| to the payload. Return true if:
+ // - the new size of the payload is still <= |max_bytes_|
+ bool AddAddress(const Address& address);
+
+ // Return true if |num_bytes| can be added to the payload.
+ bool CanAddOctets(size_t num_bytes) const;
+
+ // Add |octets| bytes to the payload. Return true if:
+ // - the size of |bytes| is equal to |octets| and
+ // - the new size of the payload is still <= |max_bytes_|
+ bool AddOctets(size_t octets, const std::vector<uint8_t>& bytes);
+
+ bool AddOctets(const std::vector<uint8_t>& bytes);
+
+ bool AddOctets1(uint8_t value);
+ bool AddOctets2(uint16_t value);
+ bool AddOctets3(uint32_t value);
+ bool AddOctets4(uint32_t value);
+ bool AddOctets6(uint64_t value);
+ bool AddOctets8(uint64_t value);
+
+ private:
+ // Add |octets| bytes to the payload. Return true if:
+ // - the value of |value| fits in |octets| bytes and
+ // - the new size of the payload is still <= |max_bytes_|
+ bool AddOctets(size_t octets, uint64_t value);
+
+ size_t max_bytes_{255};
+
+ // Underlying containers for storing the actual packet
+ std::vector<uint8_t> payload_;
+};
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/counted_builder.h"
+
+#include <gtest/gtest.h>
+#include <forward_list>
+#include <memory>
+
+#include "types/address.h"
+
+using std::vector;
+
+namespace {
+vector<uint8_t> count = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+};
+
+} // namespace
+
+namespace test_vendor_lib {
+namespace packets {
+
+class CountedBuilderTest : public ::testing::Test {
+ public:
+ CountedBuilderTest() = default;
+ ~CountedBuilderTest() = default;
+};
+
+TEST(CountedBuilderTest, buildCountTest) {
+ std::unique_ptr<CountedBuilder> count_builder = std::make_unique<CountedBuilder>();
+ ASSERT_EQ(1u, count_builder->size());
+ std::unique_ptr<RawBuilder> raw1 = std::make_unique<RawBuilder>();
+ std::unique_ptr<RawBuilder> raw2 = std::make_unique<RawBuilder>();
+ std::unique_ptr<RawBuilder> raw3 = std::make_unique<RawBuilder>();
+ std::unique_ptr<RawBuilder> raw4 = std::make_unique<RawBuilder>();
+ std::unique_ptr<RawBuilder> raw5 = std::make_unique<RawBuilder>();
+ std::unique_ptr<RawBuilder> raw6 = std::make_unique<RawBuilder>();
+ std::unique_ptr<RawBuilder> raw7 = std::make_unique<RawBuilder>();
+ raw1->AddOctets8(0x0706050403020100);
+ raw2->AddOctets4(0x0b0a0908);
+ raw3->AddOctets2(0x0d0c);
+ raw4->AddOctets1(0x0e);
+ raw5->AddOctets1(0x0f);
+ raw6->AddAddress(Address({0x10, 0x11, 0x12, 0x13, 0x14, 0x15}));
+ std::vector<uint8_t> count_subset(count.begin() + 0x16, count.end());
+ raw7->AddOctets(count_subset);
+
+ count_builder->Add(std::move(raw1));
+ count_builder->Add(std::move(raw2));
+ count_builder->Add(std::move(raw3));
+ count_builder->Add(std::move(raw4));
+ count_builder->Add(std::move(raw5));
+ count_builder->Add(std::move(raw6));
+ count_builder->Add(std::move(raw7));
+
+ ASSERT_EQ(count.size(), count_builder->size() - 1);
+
+ std::vector<uint8_t> packet;
+ std::back_insert_iterator<std::vector<uint8_t>> it(packet);
+
+ count_builder->Serialize(it);
+ ASSERT_EQ(7u, packet[0]);
+ std::vector<uint8_t> payload_packet(packet.begin() + 1, packet.end());
+
+ ASSERT_EQ(count, payload_packet);
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/link_layer/link_layer_packet_builder.h"
+
+#include <gtest/gtest.h>
+#include <forward_list>
+#include <memory>
+
+#include "link.h"
+#include "packets/link_layer/command_view.h"
+#include "packets/link_layer/disconnect_view.h"
+#include "packets/link_layer/encrypt_connection_view.h"
+#include "packets/link_layer/inquiry_response_view.h"
+#include "packets/link_layer/inquiry_view.h"
+#include "packets/link_layer/io_capability_negative_response_view.h"
+#include "packets/link_layer/io_capability_view.h"
+#include "packets/link_layer/le_advertisement_view.h"
+#include "packets/link_layer/page_response_view.h"
+#include "packets/link_layer/page_view.h"
+#include "packets/link_layer/response_view.h"
+
+#include "base/logging.h"
+
+using std::vector;
+
+namespace {
+vector<uint8_t> count = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+};
+
+} // namespace
+
+namespace test_vendor_lib {
+namespace packets {
+
+class LinkLayerPacketBuilderTest : public ::testing::Test {
+ public:
+ LinkLayerPacketBuilderTest() = default;
+ ~LinkLayerPacketBuilderTest() = default;
+
+ Address source_{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+ Address dest_{{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}};
+};
+
+TEST_F(LinkLayerPacketBuilderTest, constructorTest) {
+ uint8_t reason = 0xf2;
+ auto disconnect = DisconnectBuilder::Create(reason);
+ ASSERT_EQ(disconnect->size(), sizeof(reason));
+ auto wrapped_disconnect = LinkLayerPacketBuilder::WrapDisconnect(std::move(disconnect), source_, dest_);
+
+ size_t wrapped_size = sizeof(uint8_t) + sizeof(uint32_t) + 2 * sizeof(Address) + sizeof(reason);
+ ASSERT_EQ(wrapped_disconnect->size(), wrapped_size);
+ std::vector<uint8_t> wrapped_vect;
+ std::back_insert_iterator<std::vector<uint8_t>> it(wrapped_vect);
+ wrapped_disconnect->Serialize(it);
+ ASSERT_EQ(wrapped_size, wrapped_vect.size());
+
+ std::vector<uint8_t> hand_wrapped_vect;
+ // Add the size
+ hand_wrapped_vect.push_back(sizeof(uint8_t) + 2 * sizeof(Address) + sizeof(reason));
+ hand_wrapped_vect.push_back(0);
+ hand_wrapped_vect.push_back(0);
+ hand_wrapped_vect.push_back(0);
+
+ hand_wrapped_vect.push_back(static_cast<uint8_t>(Link::PacketType::DISCONNECT));
+
+ for (auto byte : source_.address) {
+ hand_wrapped_vect.push_back(byte);
+ }
+ for (auto byte : dest_.address) {
+ hand_wrapped_vect.push_back(byte);
+ }
+ hand_wrapped_vect.push_back(reason);
+ ASSERT_EQ(wrapped_vect, hand_wrapped_vect);
+}
+
+TEST_F(LinkLayerPacketBuilderTest, disconnectTest) {
+ uint8_t reason = 0x32;
+ auto disconnect_builder = DisconnectBuilder::Create(reason);
+ auto wrapped_disconnect = LinkLayerPacketBuilder::WrapDisconnect(std::move(disconnect_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_disconnect->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_disconnect->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::DISCONNECT);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ DisconnectView disconnect = DisconnectView::GetDisconnect(view);
+ ASSERT_EQ(disconnect.GetReason(), reason);
+}
+
+TEST_F(LinkLayerPacketBuilderTest, encryptConnectionTest) {
+ std::vector<uint8_t> key = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+ auto encrypt_connection_builder = EncryptConnectionBuilder::Create(key);
+ auto wrapped_encrypt_connection =
+ LinkLayerPacketBuilder::WrapEncryptConnection(std::move(encrypt_connection_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_encrypt_connection->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_encrypt_connection->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::ENCRYPT_CONNECTION);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ EncryptConnectionView encrypt_connection = EncryptConnectionView::GetEncryptConnection(view);
+ auto key_itr = encrypt_connection.GetKey();
+ ASSERT_EQ(key_itr.NumBytesRemaining(), key.size());
+ for (size_t i = 0; i < key.size(); i++) {
+ ASSERT_EQ(key[i], key_itr.extract<uint8_t>());
+ }
+}
+
+TEST_F(LinkLayerPacketBuilderTest, encryptConnectionResponseTest) {
+ std::vector<uint8_t> key = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+ auto encrypt_connection_builder = EncryptConnectionBuilder::Create(key);
+ auto wrapped_encrypt_connection_response =
+ LinkLayerPacketBuilder::WrapEncryptConnectionResponse(std::move(encrypt_connection_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_encrypt_connection_response->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_encrypt_connection_response->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::ENCRYPT_CONNECTION_RESPONSE);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ EncryptConnectionView encrypt_connection = EncryptConnectionView::GetEncryptConnection(view);
+ auto key_itr = encrypt_connection.GetKey();
+ ASSERT_EQ(key_itr.NumBytesRemaining(), key.size());
+ for (size_t i = 0; i < key.size(); i++) {
+ ASSERT_EQ(key[i], key_itr.extract<uint8_t>());
+ }
+}
+
+TEST_F(LinkLayerPacketBuilderTest, inquiryTest) {
+ Inquiry::InquiryType inquiry_type = Inquiry::InquiryType::RSSI;
+ auto inquiry_builder = InquiryBuilder::Create(inquiry_type);
+ auto wrapped_inquiry = LinkLayerPacketBuilder::WrapInquiry(std::move(inquiry_builder), source_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_inquiry->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_inquiry->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::INQUIRY);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(Address::kEmpty, view.GetDestinationAddress());
+ ASSERT_EQ(InquiryView::GetInquiry(view).GetType(), inquiry_type);
+}
+
+TEST_F(LinkLayerPacketBuilderTest, standardInquiryResponseTest) {
+ uint8_t mode = 23;
+ ClassOfDevice class_of_device{{0x11, 0x22, 0x33}};
+ uint16_t offset = 0x3456;
+ auto inquiry_response_builder = InquiryResponseBuilder::CreateStandard(mode, class_of_device, offset);
+ auto wrapped_inquiry =
+ LinkLayerPacketBuilder::WrapInquiryResponse(std::move(inquiry_response_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_inquiry->Serialize(it);
+ ASSERT_EQ(packet_ptr->size(), 24u);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_inquiry->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::INQUIRY_RESPONSE);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ ASSERT_EQ(view.GetPayload().size(), 7u);
+ InquiryResponseView inquiry_response = InquiryResponseView::GetInquiryResponse(view);
+ ASSERT_EQ(inquiry_response.GetClockOffset(), offset);
+ ASSERT_EQ(inquiry_response.GetType(), Inquiry::InquiryType::STANDARD);
+ ASSERT_EQ(inquiry_response.GetPageScanRepetitionMode(), mode);
+ ASSERT_EQ(inquiry_response.GetClassOfDevice(), class_of_device);
+ ASSERT_EQ(inquiry_response.GetClockOffset(), offset);
+}
+
+TEST_F(LinkLayerPacketBuilderTest, rssiInquiryResponseTest) {
+ uint8_t mode = 23;
+ ClassOfDevice class_of_device{{0x11, 0x22, 0x33}};
+ uint16_t offset = 0x3456;
+ uint8_t rssi = 0x78;
+ auto inquiry_response_builder = InquiryResponseBuilder::CreateRssi(mode, class_of_device, offset, rssi);
+ auto wrapped_inquiry =
+ LinkLayerPacketBuilder::WrapInquiryResponse(std::move(inquiry_response_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_inquiry->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_inquiry->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::INQUIRY_RESPONSE);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ InquiryResponseView inquiry_response = InquiryResponseView::GetInquiryResponse(view);
+ ASSERT_EQ(inquiry_response.GetClockOffset(), offset);
+ ASSERT_EQ(inquiry_response.GetType(), Inquiry::InquiryType::RSSI);
+ ASSERT_EQ(inquiry_response.GetPageScanRepetitionMode(), mode);
+ ASSERT_EQ(inquiry_response.GetClassOfDevice(), class_of_device);
+ ASSERT_EQ(inquiry_response.GetClockOffset(), offset);
+ ASSERT_EQ(inquiry_response.GetRssi(), rssi);
+}
+
+TEST_F(LinkLayerPacketBuilderTest, extendedInquiryResponseTest) {
+ uint8_t mode = 23;
+ ClassOfDevice class_of_device{{0x11, 0x22, 0x33}};
+ uint16_t offset = 0x3456;
+ uint8_t rssi = 0x78;
+ auto inquiry_response_builder = InquiryResponseBuilder::CreateExtended(mode, class_of_device, offset, rssi, count);
+ auto wrapped_inquiry =
+ LinkLayerPacketBuilder::WrapInquiryResponse(std::move(inquiry_response_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_inquiry->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_inquiry->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::INQUIRY_RESPONSE);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ InquiryResponseView inquiry_response = InquiryResponseView::GetInquiryResponse(view);
+ ASSERT_EQ(inquiry_response.GetClockOffset(), offset);
+ ASSERT_EQ(inquiry_response.GetType(), Inquiry::InquiryType::EXTENDED);
+ ASSERT_EQ(inquiry_response.GetPageScanRepetitionMode(), mode);
+ ASSERT_EQ(inquiry_response.GetClassOfDevice(), class_of_device);
+ ASSERT_EQ(inquiry_response.GetClockOffset(), offset);
+ ASSERT_EQ(inquiry_response.GetRssi(), rssi);
+ auto ext_it = inquiry_response.GetExtendedData();
+ ASSERT_EQ(ext_it.NumBytesRemaining(), count.size());
+ for (size_t i = 0; i < count.size(); i++) {
+ ASSERT_EQ(count[i], *(ext_it++));
+ }
+}
+
+TEST_F(LinkLayerPacketBuilderTest, ioCapabilityRequestTest) {
+ uint8_t io_cap = 0x2;
+ uint8_t oob_data_present = 0x1;
+ uint8_t authentication_requirements = 0x5;
+ auto io_capability_builder = IoCapabilityBuilder::Create(io_cap, oob_data_present, authentication_requirements);
+ auto wrapped_io_capability_request =
+ LinkLayerPacketBuilder::WrapIoCapabilityRequest(std::move(io_capability_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_io_capability_request->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_io_capability_request->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::IO_CAPABILITY_REQUEST);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ IoCapabilityView io_capability = IoCapabilityView::GetIoCapability(view);
+ ASSERT_EQ(io_capability.GetIoCapability(), io_cap);
+ ASSERT_EQ(io_capability.GetOobDataPresent(), oob_data_present);
+ ASSERT_EQ(io_capability.GetAuthenticationRequirements(), authentication_requirements);
+}
+
+TEST_F(LinkLayerPacketBuilderTest, ioCapabilityResponseTest) {
+ uint8_t io_cap = 0x2;
+ uint8_t oob_data_present = 0x1;
+ uint8_t authentication_requirements = 0x5;
+ auto io_capability_builder = IoCapabilityBuilder::Create(io_cap, oob_data_present, authentication_requirements);
+ auto wrapped_io_capability_response =
+ LinkLayerPacketBuilder::WrapIoCapabilityResponse(std::move(io_capability_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_io_capability_response->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_io_capability_response->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::IO_CAPABILITY_RESPONSE);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ IoCapabilityView io_capability = IoCapabilityView::GetIoCapability(view);
+ ASSERT_EQ(io_capability.GetIoCapability(), io_cap);
+ ASSERT_EQ(io_capability.GetOobDataPresent(), oob_data_present);
+ ASSERT_EQ(io_capability.GetAuthenticationRequirements(), authentication_requirements);
+}
+
+TEST_F(LinkLayerPacketBuilderTest, ioCapabilityNegativeResponseTest) {
+ uint8_t reason = 23;
+ auto io_capability_negative_response_builder = IoCapabilityNegativeResponseBuilder::Create(reason);
+ auto wrapped_io_capability_negative_response = LinkLayerPacketBuilder::WrapIoCapabilityNegativeResponse(
+ std::move(io_capability_negative_response_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_io_capability_negative_response->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_io_capability_negative_response->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::IO_CAPABILITY_NEGATIVE_RESPONSE);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ IoCapabilityNegativeResponseView io_capability_negative_response =
+ IoCapabilityNegativeResponseView::GetIoCapabilityNegativeResponse(view);
+ ASSERT_EQ(io_capability_negative_response.GetReason(), reason);
+}
+
+TEST_F(LinkLayerPacketBuilderTest, pageTest) {
+ uint8_t allow_role_switch = 1;
+ ClassOfDevice class_of_device{{0x11, 0x22, 0x33}};
+ auto page_builder = PageBuilder::Create(class_of_device, allow_role_switch);
+ auto wrapped_page = LinkLayerPacketBuilder::WrapPage(std::move(page_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_page->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_page->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::PAGE);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ PageView page = PageView::GetPage(view);
+ ASSERT_EQ(page.GetAllowRoleSwitch(), allow_role_switch);
+ ASSERT_EQ(page.GetClassOfDevice(), class_of_device);
+}
+
+TEST_F(LinkLayerPacketBuilderTest, pageResponseTest) {
+ uint8_t try_role_switch = 2;
+ auto page_response_builder = PageResponseBuilder::Create(try_role_switch);
+ auto wrapped_page_response =
+ LinkLayerPacketBuilder::WrapPageResponse(std::move(page_response_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_page_response->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_page_response->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::PAGE_RESPONSE);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ PageResponseView page_response = PageResponseView::GetPageResponse(view);
+ ASSERT_EQ(page_response.GetTryRoleSwitch(), try_role_switch);
+}
+
+TEST_F(LinkLayerPacketBuilderTest, responseTest) {
+ uint16_t opcode = 0x1234;
+ std::vector<uint64_t> data{
+ 0x7060504030201000, 0x7161514131211101, 0x7262524232221202, 0x7363534333231303,
+ 0x7464544434241404, 0x7565554535251505, 0x7666564636261606, 0x7767574737271707,
+ 0x7868584838281808, 0x7969594939291909, 0x7a6a5a4a3a2a1a0a, 0x7b6b5b4b3b2b1b0b,
+ 0x7c6c5c4c3c2c1c0c, 0x7d6d5d4d3d2d1d0d, 0x7e6e5e4e3e2e1e0e, 0x7f6f5f4f3f2f1f0f,
+ };
+ auto response_builder = ResponseBuilder::Create(opcode, data);
+ auto wrapped_response = LinkLayerPacketBuilder::WrapResponse(std::move(response_builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_response->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_response->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::RESPONSE);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ ResponseView response = ResponseView::GetResponse(view);
+ ASSERT_EQ(opcode, response.GetOpcode());
+ auto data_it = response.GetResponseData();
+ ASSERT_EQ(data.size(), data_it.NumBytesRemaining() / sizeof(uint64_t));
+ ASSERT_EQ(0u, data_it.NumBytesRemaining() % sizeof(uint64_t));
+ for (size_t i = 0; i < data.size(); i++) {
+ ASSERT_EQ(data[i], data_it.extract<uint64_t>());
+ }
+}
+
+TEST_F(LinkLayerPacketBuilderTest, wrapAclTest) {
+ std::shared_ptr<std::vector<uint8_t>> count_shared = std::make_shared<std::vector<uint8_t>>(count);
+ View count_view(count_shared, 0, count_shared->size());
+ PacketView<true> count_packet_view({count_view});
+ auto builder = ViewForwarderBuilder::Create(count_packet_view);
+ auto wrapped_acl = LinkLayerPacketBuilder::WrapAcl(std::move(builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_acl->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_acl->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::ACL);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ auto acl_view = view.GetPayload();
+ ASSERT_EQ(acl_view.size(), count_view.size());
+ for (size_t i = 0; i < count_view.size(); i++) {
+ ASSERT_EQ(acl_view[i], count_view[i]);
+ }
+}
+
+TEST_F(LinkLayerPacketBuilderTest, wrapCommandTest) {
+ uint16_t opcode = 0x0102;
+ std::shared_ptr<std::vector<uint8_t>> count_shared = std::make_shared<std::vector<uint8_t>>(count);
+ View count_view(count_shared, 0, count_shared->size());
+ PacketView<true> args({count_view});
+ auto builder = CommandBuilder::Create(opcode, args);
+ auto wrapped_command = LinkLayerPacketBuilder::WrapCommand(std::move(builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_command->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_command->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::COMMAND);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ auto command_view = CommandView::GetCommand(view);
+ ASSERT_EQ(opcode, command_view.GetOpcode());
+ auto args_itr = command_view.GetData();
+ ASSERT_EQ(args_itr.NumBytesRemaining(), count.size());
+ for (size_t i = 0; i < count.size(); i++) {
+ ASSERT_EQ(*args_itr++, count[i]);
+ }
+}
+
+TEST_F(LinkLayerPacketBuilderTest, wrapLeAdvertisementTest) {
+ LeAdvertisement::AddressType address_type = LeAdvertisement::AddressType::RANDOM;
+ LeAdvertisement::AdvertisementType advertisement_type = LeAdvertisement::AdvertisementType::ADV_NONCONN_IND;
+ auto builder = LeAdvertisementBuilder::Create(address_type, advertisement_type, count);
+ auto wrapped_le_advertisement = LinkLayerPacketBuilder::WrapLeAdvertisement(std::move(builder), source_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_le_advertisement->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_le_advertisement->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::LE_ADVERTISEMENT);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(Address::kEmpty, view.GetDestinationAddress());
+ LeAdvertisementView le_advertisement_view = LeAdvertisementView::GetLeAdvertisementView(view);
+ ASSERT_EQ(address_type, le_advertisement_view.GetAddressType());
+ ASSERT_EQ(advertisement_type, le_advertisement_view.GetAdvertisementType());
+ auto le_advertisement_itr = le_advertisement_view.GetData();
+ ASSERT_EQ(le_advertisement_itr.NumBytesRemaining(), count.size());
+ for (size_t i = 0; i < count.size(); i++) {
+ ASSERT_EQ(*(le_advertisement_itr++), count[i]);
+ }
+}
+
+TEST_F(LinkLayerPacketBuilderTest, wrapLeScanTest) {
+ auto le_scan = LinkLayerPacketBuilder::WrapLeScan(source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ le_scan->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), le_scan->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::LE_SCAN);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ auto le_scan_view = view.GetPayload();
+ ASSERT_EQ(0u, le_scan_view.size());
+}
+
+TEST_F(LinkLayerPacketBuilderTest, wrapLeScanResponseTest) {
+ LeAdvertisement::AddressType address_type = LeAdvertisement::AddressType::PUBLIC_IDENTITY;
+ LeAdvertisement::AdvertisementType advertisement_type = LeAdvertisement::AdvertisementType::SCAN_RESPONSE;
+ auto builder = LeAdvertisementBuilder::Create(address_type, advertisement_type, count);
+ auto wrapped_scan_response = LinkLayerPacketBuilder::WrapLeScanResponse(std::move(builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_scan_response->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_scan_response->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::LE_SCAN_RESPONSE);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ LeAdvertisementView le_advertisement_view = LeAdvertisementView::GetLeAdvertisementView(view);
+ ASSERT_EQ(address_type, le_advertisement_view.GetAddressType());
+ ASSERT_EQ(advertisement_type, le_advertisement_view.GetAdvertisementType());
+ auto scan_response_itr = le_advertisement_view.GetData();
+ ASSERT_EQ(scan_response_itr.NumBytesRemaining(), count.size());
+ for (size_t i = 0; i < count.size(); i++) {
+ ASSERT_EQ((*scan_response_itr++), count[i]);
+ }
+}
+
+TEST_F(LinkLayerPacketBuilderTest, wrapScoTest) {
+ std::shared_ptr<std::vector<uint8_t>> count_shared = std::make_shared<std::vector<uint8_t>>(count);
+ View count_view(count_shared, 0, count_shared->size());
+ PacketView<true> count_packet_view({count_view});
+ auto builder = ViewForwarderBuilder::Create(count_packet_view);
+ auto wrapped_sco = LinkLayerPacketBuilder::WrapSco(std::move(builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_sco->Serialize(it);
+
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ ASSERT_EQ(view.size(), wrapped_sco->size());
+ ASSERT_EQ(view.GetType(), Link::PacketType::SCO);
+ ASSERT_EQ(source_, view.GetSourceAddress());
+ ASSERT_EQ(dest_, view.GetDestinationAddress());
+ auto sco_view = view.GetPayload();
+ ASSERT_EQ(sco_view.size(), count.size());
+ for (size_t i = 0; i < count.size(); i++) {
+ ASSERT_EQ(sco_view[i], count[i]);
+ }
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/packet_builder.h"
+
+#include <gtest/gtest.h>
+#include <forward_list>
+#include <memory>
+
+using std::vector;
+
+namespace {
+vector<uint8_t> count_all = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+};
+
+vector<uint8_t> count_1 = {
+ 0x00,
+ 0x01,
+ 0x02,
+};
+
+vector<uint8_t> count_2 = {
+ 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
+};
+
+vector<uint8_t> count_3 = {
+ 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+};
+} // namespace
+
+namespace test_vendor_lib {
+namespace packets {
+
+template <bool little_endian>
+class EndianBuilder : public PacketBuilder<little_endian> {
+ public:
+ EndianBuilder(uint8_t byte, uint16_t two_bytes, uint32_t four_bytes, uint64_t eight_bytes)
+ : byte_(byte), two_bytes_(two_bytes), four_bytes_(four_bytes), eight_bytes_(eight_bytes) {}
+ ~EndianBuilder() = default;
+
+ virtual size_t size() const override {
+ return sizeof(signature_) + sizeof(byte_) + sizeof(two_bytes_) + sizeof(four_bytes_) + sizeof(eight_bytes_);
+ }
+
+ virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
+ std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
+ packet->reserve(size());
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
+ Serialize(it);
+ return packet;
+ }
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ PacketBuilder<little_endian>::insert(signature_, it);
+ PacketBuilder<little_endian>::insert(byte_, it);
+ PacketBuilder<little_endian>::insert(two_bytes_, it);
+ PacketBuilder<little_endian>::insert(four_bytes_, it);
+ PacketBuilder<little_endian>::insert(eight_bytes_, it);
+ }
+
+ private:
+ uint32_t signature_{(little_endian ? 0x03020100 : 0x00010203)};
+ uint8_t byte_;
+ uint16_t two_bytes_;
+ uint32_t four_bytes_;
+ uint64_t eight_bytes_;
+};
+
+class PacketBuilderEndianTest : public ::testing::Test {
+ public:
+ PacketBuilderEndianTest() = default;
+ ~PacketBuilderEndianTest() = default;
+};
+
+TEST(PacketBuilderEndianTest, insertTest) {
+ EndianBuilder<true> little(0x04, 0x0605, 0x0a090807, 0x1211100f0e0d0c0b);
+ EndianBuilder<false> big(0x04, 0x0506, 0x0708090a, 0x0b0c0d0e0f101112);
+ ASSERT_EQ(*big.FinalPacket(), *little.FinalPacket());
+}
+
+template <typename T>
+class VectorBuilder : public PacketBuilder<true> {
+ public:
+ VectorBuilder(std::vector<uint64_t> vect) {
+ for (uint64_t element : vect) {
+ vect.push_back(static_cast<T>(element));
+ }
+ }
+ ~VectorBuilder() = default;
+
+ virtual size_t size() const override {
+ return vect_.size() * sizeof(T);
+ }
+
+ virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
+ std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
+ packet->reserve(size());
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
+ Serialize(it);
+ return packet;
+ }
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ PacketBuilder<true>::insert_vector(vect_, it);
+ }
+
+ private:
+ std::vector<T> vect_;
+};
+
+template <typename T>
+class InsertElementsBuilder : public PacketBuilder<true> {
+ public:
+ InsertElementsBuilder(std::vector<uint64_t> vect) {
+ for (uint64_t element : vect) {
+ vect.push_back(static_cast<T>(element));
+ }
+ }
+ virtual ~InsertElementsBuilder() = default;
+
+ virtual size_t size() const override {
+ return vect_.size() * sizeof(T);
+ }
+
+ virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
+ std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
+ packet->reserve(size());
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
+ Serialize(it);
+ return packet;
+ }
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ for (T elem : vect_) {
+ PacketBuilder<true>::insert(elem, it);
+ }
+ }
+
+ private:
+ std::vector<T> vect_;
+};
+
+std::vector<uint64_t> vector_data{
+ 0x7060504030201000, 0x7161514131211101, 0x7262524232221202, 0x7363534333231303, 0x7464544434241404,
+ 0x7565554535251505, 0x7666564636261606, 0x7767574737271707, 0x7868584838281808,
+};
+
+template <typename T>
+class VectorBuilderTest : public ::testing::Test {
+ public:
+ VectorBuilderTest() = default;
+ ~VectorBuilderTest() = default;
+
+ void SetUp() {
+ packet_1_ = std::shared_ptr<VectorBuilder<T>>(new VectorBuilder<T>(vector_data));
+ packet_2_ = std::shared_ptr<InsertElementsBuilder<T>>(new InsertElementsBuilder<T>(vector_data));
+ }
+
+ void TearDown() {
+ packet_1_.reset();
+ packet_2_.reset();
+ }
+
+ std::shared_ptr<VectorBuilder<T>> packet_1_;
+ std::shared_ptr<InsertElementsBuilder<T>> packet_2_;
+};
+
+using VectorBaseTypes = ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t>;
+TYPED_TEST_CASE(VectorBuilderTest, VectorBaseTypes);
+
+TYPED_TEST(VectorBuilderTest, insertVectorTest) {
+ ASSERT_EQ(*(this->packet_1_->FinalPacket()), *(this->packet_2_->FinalPacket()));
+}
+
+class NestedBuilder : public PacketBuilder<true> {
+ public:
+ ~NestedBuilder() = default;
+
+ virtual size_t size() const override {
+ size_t payload_size = (payload_ ? payload_->size() : 0);
+ return 1 + payload_size;
+ }
+
+ static std::unique_ptr<NestedBuilder> Create(uint8_t level) {
+ return std::unique_ptr<NestedBuilder>(new NestedBuilder(level));
+ }
+
+ static std::unique_ptr<NestedBuilder> CreateNested(std::unique_ptr<BasePacketBuilder> payload, uint8_t level) {
+ return std::unique_ptr<NestedBuilder>(new NestedBuilder(std::move(payload), level));
+ }
+
+ virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
+ std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
+ packet->reserve(size());
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
+ Serialize(it);
+ return packet;
+ }
+
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ PacketBuilder<true>::insert(level_, it);
+ if (payload_) {
+ payload_->Serialize(it);
+ }
+ }
+
+ private:
+ std::unique_ptr<BasePacketBuilder> payload_;
+ uint8_t level_;
+
+ NestedBuilder(std::unique_ptr<BasePacketBuilder> inner, uint8_t level) : payload_(std::move(inner)), level_(level) {}
+ NestedBuilder(uint8_t level) : level_(level) {}
+};
+
+class BuilderBuilderTest : public ::testing::Test {};
+
+TEST(BuilderBuilderTest, nestingTest) {
+ std::unique_ptr<BasePacketBuilder> innermost = NestedBuilder::Create(0);
+ std::unique_ptr<BasePacketBuilder> number_1 = NestedBuilder::CreateNested(std::move(innermost), 1);
+ std::unique_ptr<BasePacketBuilder> number_2 = NestedBuilder::CreateNested(std::move(number_1), 2);
+ std::unique_ptr<BasePacketBuilder> number_3 = NestedBuilder::CreateNested(std::move(number_2), 3);
+ std::unique_ptr<BasePacketBuilder> number_4 = NestedBuilder::CreateNested(std::move(number_3), 4);
+ std::unique_ptr<NestedBuilder> number_5 = NestedBuilder::CreateNested(std::move(number_4), 5);
+
+ std::vector<uint8_t> count_down{5, 4, 3, 2, 1, 0};
+ ASSERT_EQ(*number_5->FinalPacket(), count_down);
+}
+} // namespace packets
+} // namespace test_vendor_lib
#include <forward_list>
#include <memory>
-#include "types/raw_address.h"
+#include "types/address.h"
using std::vector;
namespace {
vector<uint8_t> count_all = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
- 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
- 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
};
vector<uint8_t> count_1 = {
};
vector<uint8_t> count_3 = {
- 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
- 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
};
} // namespace
~IteratorTest() = default;
void SetUp() {
- packet = std::shared_ptr<T>(
- new T({View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())}));
+ packet = std::shared_ptr<T>(new T({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())}));
}
- void TearDown() { packet.reset(); }
+ void TearDown() {
+ packet.reset();
+ }
std::shared_ptr<T> packet;
};
};
TEST(IteratorExtractTest, extractLeTest) {
- PacketView<true> packet(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ PacketView<true> packet({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
auto general_case = packet.begin();
ASSERT_EQ(0x00, general_case.extract<uint8_t>());
ASSERT_EQ(0x06050403u, general_case.extract<uint32_t>());
ASSERT_EQ(0x0e0d0c0b0a090807u, general_case.extract<uint64_t>());
ASSERT_EQ(0x0f, general_case.extract<uint8_t>());
- RawAddress raw({0x10, 0x11, 0x12, 0x13, 0x14, 0x15});
- ASSERT_EQ(raw, general_case.extract<RawAddress>());
+ Address raw({0x10, 0x11, 0x12, 0x13, 0x14, 0x15});
+ ASSERT_EQ(raw, general_case.extract<Address>());
ASSERT_EQ(0x16, general_case.extract<uint8_t>());
}
TEST(IteratorExtractTest, extractBeTest) {
- PacketView<false> packet(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ PacketView<false> packet({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
auto general_case = packet.begin();
ASSERT_EQ(0x00, general_case.extract<uint8_t>());
ASSERT_EQ(0x03040506u, general_case.extract<uint32_t>());
ASSERT_EQ(0x0708090a0b0c0d0eu, general_case.extract<uint64_t>());
ASSERT_EQ(0x0f, general_case.extract<uint8_t>());
- RawAddress raw({0x15, 0x14, 0x13, 0x12, 0x11, 0x10});
- ASSERT_EQ(raw, general_case.extract<RawAddress>());
+ Address raw({0x15, 0x14, 0x13, 0x12, 0x11, 0x10});
+ ASSERT_EQ(raw, general_case.extract<Address>());
ASSERT_EQ(0x16, general_case.extract<uint8_t>());
}
TYPED_TEST(IteratorTest, plusEqTest) {
auto plus_eq = this->packet->begin();
for (size_t i = 0; i < count_all.size(); i += 2) {
- ASSERT_EQ(count_all[i], *plus_eq)
- << "+= test: Dereferenced iterator does not equal expected at index "
- << i;
+ ASSERT_EQ(count_all[i], *plus_eq) << "+= test: Dereferenced iterator does not equal expected at index " << i;
plus_eq += 2;
}
}
TYPED_TEST(IteratorTest, preIncrementTest) {
auto plus_plus = this->packet->begin();
for (size_t i = 0; i < count_all.size() - 1; i++) {
- ASSERT_EQ(count_all[i + 1], *(++plus_plus))
- << "Pre-increment test: Dereferenced iterator does not equal expected "
- << "at index " << i;
+ ASSERT_EQ(count_all[i + 1], *(++plus_plus)) << "Pre-increment test: Dereferenced iterator does not equal expected "
+ << "at index " << i;
}
}
TYPED_TEST(IteratorTest, postIncrementTest) {
auto plus_plus = this->packet->begin();
for (size_t i = 0; i < count_all.size(); i++) {
- ASSERT_EQ(count_all[i], *(plus_plus++))
- << "Post-increment test: Dereferenced iterator does not equal expected "
- << "at index " << i;
+ ASSERT_EQ(count_all[i], *(plus_plus++)) << "Post-increment test: Dereferenced iterator does not equal expected "
+ << "at index " << i;
}
}
TYPED_TEST(IteratorTest, additionTest) {
auto plus = this->packet->begin();
for (size_t i = 0; i < count_all.size(); i++) {
- ASSERT_EQ(count_all[i], *plus)
- << "+ test: Dereferenced iterator does not equal expected at index "
- << i;
+ ASSERT_EQ(count_all[i], *plus) << "+ test: Dereferenced iterator does not equal expected at index " << i;
plus = plus + 1;
}
}
size_t index = count_all.size() - 1;
for (size_t i = 0; index > i; i++) {
ASSERT_EQ(count_all[index], *minus_eq)
- << "-= test: Dereferenced iterator does not equal expected at index "
- << index;
+ << "-= test: Dereferenced iterator does not equal expected at index " << index;
index -= i;
minus_eq -= i;
}
auto minus_minus = this->packet->end();
minus_minus--;
for (size_t i = count_all.size() - 1; i > 0; i--) {
- ASSERT_EQ(count_all[i], *(minus_minus--))
- << "Post-decrement test: Dereferenced iterator does not equal expected "
- << "at index " << i;
+ ASSERT_EQ(count_all[i], *(minus_minus--)) << "Post-decrement test: Dereferenced iterator does not equal expected "
+ << "at index " << i;
}
}
auto minus = this->packet->end();
minus = minus - 1;
for (size_t i = count_all.size() - 1; i > 0; i--) {
- ASSERT_EQ(count_all[i], *minus)
- << "- test: Dereferenced iterator does not equal expected at index "
- << i;
+ ASSERT_EQ(count_all[i], *minus) << "- test: Dereferenced iterator does not equal expected at index " << i;
minus = minus - 1;
}
}
TEST_P(SubViewPassTest, subViewTest) {
auto header = GetParam().first;
auto tail = GetParam().second;
- SubPacketView single_view(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ SubPacketView single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
SubPacketView multi_view({
View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
chopomatic, SubViewPassTest,
::testing::Values(
// {begin, end} pairs for subsets into the PacketView
- SubViewTestParam{0, 0}, SubViewTestParam{0, boundary_1},
- SubViewTestParam{0, boundary_1 + 1}, SubViewTestParam{0, boundary_2},
- SubViewTestParam{0, boundary_2 + 1},
- SubViewTestParam{0, count_all.size()},
- SubViewTestParam{boundary_1 - 1, boundary_1},
- SubViewTestParam{boundary_1 - 1, boundary_1 + 1},
- SubViewTestParam{boundary_1 - 1, boundary_2},
- SubViewTestParam{boundary_1 - 1, boundary_2 + 1},
- SubViewTestParam{boundary_1 - 1, count_all.size()},
- SubViewTestParam{boundary_1, boundary_1},
- SubViewTestParam{boundary_1, boundary_2},
- SubViewTestParam{boundary_1, boundary_2 + 1},
- SubViewTestParam{boundary_1, count_all.size()},
- SubViewTestParam{boundary_2 - 1, boundary_2},
- SubViewTestParam{boundary_2 - 1, boundary_2 + 1},
- SubViewTestParam{boundary_2 - 1, count_all.size()},
- SubViewTestParam{boundary_2, boundary_2},
- SubViewTestParam{boundary_2, boundary_2 + 1},
- SubViewTestParam{boundary_2, count_all.size()},
- SubViewTestParam{count_all.size() - 1, count_all.size()},
+ SubViewTestParam{0, 0}, SubViewTestParam{0, boundary_1}, SubViewTestParam{0, boundary_1 + 1},
+ SubViewTestParam{0, boundary_2}, SubViewTestParam{0, boundary_2 + 1}, SubViewTestParam{0, count_all.size()},
+ SubViewTestParam{boundary_1 - 1, boundary_1}, SubViewTestParam{boundary_1 - 1, boundary_1 + 1},
+ SubViewTestParam{boundary_1 - 1, boundary_2}, SubViewTestParam{boundary_1 - 1, boundary_2 + 1},
+ SubViewTestParam{boundary_1 - 1, count_all.size()}, SubViewTestParam{boundary_1, boundary_1},
+ SubViewTestParam{boundary_1, boundary_2}, SubViewTestParam{boundary_1, boundary_2 + 1},
+ SubViewTestParam{boundary_1, count_all.size()}, SubViewTestParam{boundary_2 - 1, boundary_2},
+ SubViewTestParam{boundary_2 - 1, boundary_2 + 1}, SubViewTestParam{boundary_2 - 1, count_all.size()},
+ SubViewTestParam{boundary_2, boundary_2}, SubViewTestParam{boundary_2, boundary_2 + 1},
+ SubViewTestParam{boundary_2, count_all.size()}, SubViewTestParam{count_all.size() - 1, count_all.size()},
SubViewTestParam{count_all.size(), count_all.size()}));
class SubViewDeathTest : public SubViewBaseTest {};
TEST_P(SubViewDeathTest, subViewDeathTest) {
auto header = GetParam().first;
auto tail = GetParam().second;
- SubPacketView single_view(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ SubPacketView single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
SubPacketView multi_view({
View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
ASSERT_DEATH(auto multi_slice = multi_view.Slice(header, tail), "");
}
-INSTANTIATE_TEST_CASE_P(
- chopomaticDeath, SubViewDeathTest,
- ::testing::Values(
- // {begin, end} pairs for subsets into the PacketView
- SubViewTestParam{1, 0},
- SubViewTestParam{count_all.size(), count_all.size() - 1},
- SubViewTestParam{count_all.size(), count_all.size() + 1}));
+INSTANTIATE_TEST_CASE_P(chopomaticDeath, SubViewDeathTest,
+ ::testing::Values(
+ // {begin, end} pairs for subsets into the PacketView
+ SubViewTestParam{1, 0}, SubViewTestParam{count_all.size(), count_all.size() - 1},
+ SubViewTestParam{count_all.size(), count_all.size() + 1}));
TEST(SubViewTest, simpleSubViewTest) {
- PacketView<true> view(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ PacketView<true> view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
PacketView<true> sub_1_view = view.SubViewLittleEndian(0, view.size());
- PacketView<true> sub_2_view =
- sub_1_view.SubViewLittleEndian(0, sub_1_view.size());
- PacketView<true> sub_3_view =
- sub_2_view.SubViewLittleEndian(0, sub_2_view.size());
- PacketView<true> sub_4_view =
- sub_3_view.SubViewLittleEndian(0, sub_3_view.size());
+ PacketView<true> sub_2_view = sub_1_view.SubViewLittleEndian(0, sub_1_view.size());
+ PacketView<true> sub_3_view = sub_2_view.SubViewLittleEndian(0, sub_2_view.size());
+ PacketView<true> sub_4_view = sub_3_view.SubViewLittleEndian(0, sub_3_view.size());
ASSERT_EQ(sub_1_view.size(), view.size());
ASSERT_EQ(sub_2_view.size(), view.size());
ASSERT_EQ(sub_3_view.size(), view.size());
}
TEST(SubViewTest, realSubViewTest) {
- PacketView<true> view(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ PacketView<true> view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
std::vector<PacketView<true>> sub_views{view};
for (size_t i = 1; i < 6; i++) {
size_t parent_size = sub_views[i - 1].size();
- sub_views.push_back(
- sub_views[i - 1].SubViewLittleEndian(1, parent_size - 1));
+ sub_views.push_back(sub_views[i - 1].SubViewLittleEndian(1, parent_size - 1));
ASSERT_EQ(sub_views[i][0], i);
ASSERT_EQ(sub_views[i].size(), parent_size - 2);
}
}
TEST(SubViewTest, subSubViewTest) {
- PacketView<true> single_view(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
PacketView<true> multi_view({
View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
});
ASSERT_EQ(single_view.size(), multi_view.size());
for (size_t i = 0; i < count_all.size() / 2; i++) {
- PacketView<true> sub_single_view =
- single_view.SubViewLittleEndian(i, count_all.size() - i);
- PacketView<true> sub_multi_view =
- multi_view.SubViewLittleEndian(i, count_all.size() - i);
+ PacketView<true> sub_single_view = single_view.SubViewLittleEndian(i, count_all.size() - i);
+ PacketView<true> sub_multi_view = multi_view.SubViewLittleEndian(i, count_all.size() - i);
ASSERT_EQ(count_all.size() - 2 * i, sub_single_view.size());
ASSERT_EQ(sub_single_view.size(), sub_multi_view.size());
for (size_t j = 0; j < sub_single_view.size() / 2; j++) {
- PacketView<true> sub_sub_single_view =
- sub_single_view.SubViewLittleEndian(j, sub_single_view.size() - j);
- PacketView<true> sub_sub_multi_view =
- sub_multi_view.SubViewLittleEndian(j, sub_multi_view.size() - j);
+ PacketView<true> sub_sub_single_view = sub_single_view.SubViewLittleEndian(j, sub_single_view.size() - j);
+ PacketView<true> sub_sub_multi_view = sub_multi_view.SubViewLittleEndian(j, sub_multi_view.size() - j);
ASSERT_EQ(sub_single_view.size() - 2 * j, sub_sub_single_view.size());
ASSERT_EQ(sub_sub_single_view.size(), sub_sub_multi_view.size());
}
}
TEST(PacketViewMultiViewTest, sizeTest) {
- PacketView<true> single_view(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
PacketView<true> multi_view({
View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
}
TEST(PacketViewMultiViewTest, dereferenceTestLittleEndian) {
- PacketView<true> single_view(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
PacketView<true> multi_view({
View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
}
TEST(PacketViewMultiViewTest, dereferenceTestBigEndian) {
- PacketView<false> single_view(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ PacketView<false> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
PacketView<false> multi_view({
View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
}
TEST(PacketViewMultiViewTest, arrayOperatorTest) {
- PacketView<true> single_view(
- {View(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size())});
+ PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
PacketView<true> multi_view({
View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
}
TEST(ViewTest, arrayOperatorTest) {
- View view_all(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size());
+ View view_all(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
size_t past_end = view_all.size();
for (size_t i = 0; i < past_end; i++) {
ASSERT_EQ(view_all[i], count_all[i]);
size_t header_size = 2;
size_t tail_size = 3;
- View view_subset(std::make_shared<const vector<uint8_t>>(count_all),
- header_size, count_all.size() - tail_size);
+ View view_subset(std::make_shared<const vector<uint8_t>>(count_all), header_size, count_all.size() - tail_size);
View view_subset2(view_all, header_size, count_all.size() - tail_size);
size_t subset_length = view_subset.size();
for (size_t i = 0; i < subset_length; i++) {
}
TEST(ViewTest, earlySubSubViewTest) {
- View view(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size());
+ View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
View sub_1_view(view, view.size() - 3, view.size() - 1);
View sub_2_view(sub_1_view, 1, 2);
ASSERT_EQ(sub_1_view.size(), 2u);
}
TEST(ViewTest, subSubViewTest) {
- View view(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size());
+ View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
std::vector<View> sub_views{view};
for (size_t i = 1; i < 6; i++) {
size_t parent_size = sub_views[i - 1].size();
}
TEST(ViewTest, zeroSubViewTest) {
- View view(std::make_shared<const vector<uint8_t>>(count_all), 0,
- count_all.size());
+ View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
View subview(view, view.size(), view.size() + 1);
ASSERT_EQ(subview.size(), 0u);
}
--- /dev/null
+/*
+ * Copyright 2018 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 "packets/raw_builder.h"
+
+#include <gtest/gtest.h>
+#include <forward_list>
+#include <memory>
+
+#include "types/address.h"
+
+using std::vector;
+
+namespace {
+vector<uint8_t> count = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+};
+
+} // namespace
+
+namespace test_vendor_lib {
+namespace packets {
+
+class RawBuilderTest : public ::testing::Test {
+ public:
+ RawBuilderTest() = default;
+ ~RawBuilderTest() = default;
+};
+
+TEST(RawBuilderTest, buildCountTest) {
+ std::unique_ptr<RawBuilder> count_builder = std::make_unique<RawBuilder>();
+ ASSERT_EQ(0u, count_builder->size());
+ count_builder->AddOctets8(0x0706050403020100);
+ count_builder->AddOctets4(0x0b0a0908);
+ count_builder->AddOctets2(0x0d0c);
+ count_builder->AddOctets1(0x0e);
+ count_builder->AddOctets1(0x0f);
+ count_builder->AddAddress(Address({0x10, 0x11, 0x12, 0x13, 0x14, 0x15}));
+ std::vector<uint8_t> count_subset(count.begin() + 0x16, count.end());
+ count_builder->AddOctets(count_subset);
+
+ ASSERT_EQ(count.size(), count_builder->size());
+
+ std::vector<uint8_t> packet;
+ std::back_insert_iterator<std::vector<uint8_t>> it(packet);
+
+ count_builder->Serialize(it);
+
+ ASSERT_EQ(count, packet);
+}
+
+} // namespace packets
+} // namespace test_vendor_lib
namespace test_vendor_lib {
namespace packets {
-View::View(std::shared_ptr<const std::vector<uint8_t>> data, size_t begin,
- size_t end)
- : data_(data),
- begin_(begin < data_->size() ? begin : data_->size()),
+View::View(std::shared_ptr<const std::vector<uint8_t>> data, size_t begin, size_t end)
+ : data_(data), begin_(begin < data_->size() ? begin : data_->size()),
end_(end < data_->size() ? end : data_->size()) {}
View::View(const View& view, size_t begin, size_t end) : data_(view.data_) {
return data_->operator[](i + begin_);
}
-size_t View::size() const { return end_ - begin_; }
+size_t View::size() const {
+ return end_ - begin_;
+}
} // namespace packets
} // namespace test_vendor_lib
// Base class that holds a shared pointer to data with bounds.
class View {
public:
- View(std::shared_ptr<const std::vector<uint8_t>> data, size_t begin,
- size_t end);
+ View(std::shared_ptr<const std::vector<uint8_t>> data, size_t begin, size_t end);
View(const View& view, size_t begin, size_t end);
View(const View& view) = default;
virtual ~View() = default;
# See the License for the specific language governing permissions and
# limitations under the License.
#
-
"""Script for sending testing parameters and commands to a Bluetooth device.
This script provides a simple shell interface for sending data at run-time to a
DEVICE_NAME_LENGTH = 6
DEVICE_ADDRESS_LENGTH = 6
+
# Used to generate fake device names and addresses during discovery.
def generate_random_name():
return ''.join(random.SystemRandom().choice(string.ascii_uppercase + \
string.digits) for _ in range(DEVICE_NAME_LENGTH))
+
def generate_random_address():
return ''.join(random.SystemRandom().choice(string.digits) for _ in \
range(DEVICE_ADDRESS_LENGTH))
+
class Connection(object):
"""Simple wrapper class for a socket object.
def send(self, data):
self._socket.sendall(data)
+ def receive(self, size):
+ return self._socket.recv(size)
+
+
class TestChannel(object):
"""Checks outgoing commands and sends them once verified.
Attributes:
connection: The connection to the test vendor library that commands are sent
- on.
+ on.
"""
def __init__(self, port):
self._connection = Connection(port)
- self._discovered_devices = DeviceManager()
-
- def discover_new_device(self, name=None, address=None):
- device = Device(name, address)
- self._discovered_devices.add_device(device)
- return device
+ self._closed = False
def close(self):
self._connection.close()
+ self._closed = True
def send_command(self, name, args):
name_size = len(name)
encoded_name = chr(name_size) + name
encoded_args = chr(args_size) + ''.join(chr(len(arg)) + arg for arg in args)
command = encoded_name + encoded_args
+ if self._closed:
+ return
self._connection.send(command)
+ if name != 'CLOSE_TEST_CHANNEL':
+ print self.receive_response()
+
+ def receive_response(self):
+ if self._closed:
+ return
+ size_chars = self._connection.receive(4)
+ size_bytes = bytearray(size_chars)
+ if not size_chars:
+ print 'No response, assuming that the connection is broken'
+ return False
+ response_size = 0
+ for i in range(0, len(size_chars) - 1):
+ response_size |= ord(size_chars[i]) << (8 * i)
+ response = self._connection.receive(response_size)
+ return response
def lint_command(self, name, args, name_size, args_size):
assert name_size == len(name) and args_size == len(args)
if len(arg) > 255:
raise ValueError # Size must be encodable in one octet.
-class DeviceManager(object):
- """Maintains the active fake devices that have been "discovered".
-
- Attributes:
- device_list: Maps device addresses (keys) to devices (values).
- """
-
- def __init__(self):
- self.device_list = {}
-
- def add_device(self, device):
- self.device_list[device.get_address()] = device
-
-class Device(object):
- """A fake device to be returned in inquiry and scan results. Note that if an
- explicit name or address is not provided, a random string of characters
- is used.
-
- Attributes:
- name: The device name for use in extended results.
- address: The BD address of the device.
- """
-
- def __init__(self, name=None, address=None):
- # TODO(dennischeng): Generate device properties more robustly.
- self._name = generate_random_name() if name is None else name
- self._address = generate_random_address() if address is None else address
-
- def get_name(self):
- return self._name
-
- def get_address(self):
- return self._address
class TestChannelShell(cmd.Cmd):
"""Shell for sending test channel data to controller.
"""
def __init__(self, test_channel):
- print 'Type \'help\' for more information.'
cmd.Cmd.__init__(self)
self._test_channel = test_channel
def do_add(self, args):
- """
- Arguments: dev_type_str
- Add a new device of type dev_type_str.
+ """Arguments: dev_type_str Add a new device of type dev_type_str.
+
"""
self._test_channel.send_command('add', args.split())
def do_del(self, args):
- """
- Arguments: device index
- Delete the device with the specified index.
+ """Arguments: device index Delete the device with the specified index.
+
"""
self._test_channel.send_command('del', args.split())
- def do_get(self, args):
+ def do_add_phy(self, args):
+ """Arguments: dev_type_str Add a new device of type dev_type_str.
+
+ """
+ self._test_channel.send_command('add_phy', args.split())
+
+ def do_del_phy(self, args):
+ """Arguments: phy index Delete the phy with the specified index.
+
+ """
+ self._test_channel.send_command('del_phy', args.split())
+
+ def do_add_device_to_phy(self, args):
+ """Arguments: device index phy index Add a new device of type dev_type_str.
+
+ """
+ self._test_channel.send_command('add_device_to_phy', args.split())
+
+ def do_del_device_from_phy(self, args):
+ """Arguments: phy index Delete the phy with the specified index.
+
"""
- Arguments: dev_num attr_str
- Get the value of the attribute attr_str from device dev_num.
+ self._test_channel.send_command('del_device_from_phy', args.split())
+
+ def do_add_remote(self, args):
+ """Arguments: dev_type_str Connect to a remote device at arg1@arg2.
+
+ """
+ self._test_channel.send_command('add_remote', args.split())
+
+ def do_get(self, args):
+ """Arguments: dev_num attr_str Get the value of the attribute attr_str from device dev_num.
+
"""
self._test_channel.send_command('get', args.split())
def do_set(self, args):
- """
- Arguments: dev_num attr_str val
- Set the value of the attribute attr_str from device dev_num equal to val.
+ """Arguments: dev_num attr_str val Set the value of the attribute attr_str from device dev_num equal to val.
+
"""
self._test_channel.send_command('set', args.split())
def do_list(self, args):
- """
- Arguments: [dev_num [attr]]
- List the devices from the controller, optionally filtered by device and attr.
+ """Arguments: [dev_num [attr]] List the devices from the controller, optionally filtered by device and attr.
+
"""
self._test_channel.send_command('list', args.split())
def do_quit(self, args):
- """
- Arguments: None.
+ """Arguments: None.
+
Exits the test channel.
"""
self._test_channel.send_command('CLOSE_TEST_CHANNEL', [])
return True
def do_help(self, args):
+ """Arguments: [dev_num [attr]] List the commands available, optionally filtered by device and attr.
+
"""
- Arguments: [dev_num [attr]]
- List the commands available, optionally filtered by device and attr.
- """
- self._test_channel.send_command('help', args.split())
if (len(args) == 0):
cmd.Cmd.do_help(self, args)
+ else:
+ self._test_channel.send_command('help', args.split())
+
+ def preloop(self):
+ """Clear out the buffer
+
+ """
+ response = self._test_channel.receive_response()
+
+ #def postcmd(self, stop, line):
+ #"""
+ #Called after each command
+ #stop : whether we will stop after this command
+ #line : the previous input line
+ #Return True to stop, False to continue
+ #"""
+ #if stop:
+ #return True
+ #response = self._test_channel.receive_response()
+ #if not response:
+ #return True
+ #print response
+ #return False
+
def main(argv):
if len(argv) != 2:
else:
test_channel_shell = TestChannelShell(test_channel)
test_channel_shell.prompt = '$ '
- test_channel_shell.cmdloop()
+ test_channel_shell.cmdloop('Welcome to the RootCanal Console \n' +
+ 'Type \'help\' for more information.')
+
if __name__ == '__main__':
main(sys.argv)
+++ /dev/null
-/*
- * 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.
- */
-
-#define LOG_TAG "acl_packet"
-
-#include "acl_packet.h"
-
-#include "base/logging.h"
-#include "osi/include/log.h"
-#include "stack/include/hcidefs.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-
-AclPacket::AclPacket(uint16_t channel,
- AclPacket::PacketBoundaryFlags packet_boundary,
- AclPacket::BroadcastFlags broadcast)
- : raw_packet_({static_cast<uint8_t>(channel & 0xff),
- static_cast<uint8_t>(((channel >> 8) & 0x0f) |
- ((packet_boundary & 0x3) << 4) |
- (broadcast & 0x3) << 6),
- 0x00, 0x00}) {}
-
-void AclPacket::AddPayloadOctets(size_t octets, const vector<uint8_t>& bytes) {
- CHECK(bytes.size() == octets);
-
- raw_packet_.insert(raw_packet_.end(), bytes.begin(), bytes.end());
-
- raw_packet_[2] =
- static_cast<uint8_t>((raw_packet_.size() - kHeaderSize) & 0xff);
- raw_packet_[3] =
- static_cast<uint8_t>(((raw_packet_.size() - kHeaderSize) >> 8) & 0xff);
-}
-
-void AclPacket::AddPayloadOctets(size_t octets, uint64_t value) {
- vector<uint8_t> val_vector;
-
- uint64_t v = value;
-
- CHECK(octets <= sizeof(uint64_t));
-
- for (size_t i = 0; i < octets; i++) {
- val_vector.push_back(v & 0xff);
- v = v >> 8;
- }
-
- CHECK(v == 0);
-
- AddPayloadOctets(octets, val_vector);
-}
-
-size_t AclPacket::GetPacketSize() const { return raw_packet_.size(); }
-
-const std::vector<uint8_t>& AclPacket::GetPacket() const { return raw_packet_; }
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * Copyright 2016 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 "beacon"
-
-#include "beacon.h"
-#include "stack/include/hcidefs.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-Beacon::Beacon() {
- advertising_interval_ms_ = std::chrono::milliseconds(1280);
- advertising_type_ = BTM_BLE_NON_CONNECT_EVT;
- adv_data_ = {0x0F, // Length
- BTM_BLE_AD_TYPE_NAME_CMPL,
- 'g',
- 'D',
- 'e',
- 'v',
- 'i',
- 'c',
- 'e',
- '-',
- 'b',
- 'e',
- 'a',
- 'c',
- 'o',
- 'n',
- 0x02, // Length
- BTM_BLE_AD_TYPE_FLAG,
- BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG};
-
- scan_data_ = {0x05, // Length
- BTM_BLE_AD_TYPE_NAME_SHORT,
- 'b',
- 'e',
- 'a',
- 'c'};
-}
-
-void Beacon::Initialize(const vector<std::string>& args) {
- if (args.size() < 2) return;
-
- BtAddress addr;
- if (addr.FromString(args[1])) SetBtAddress(addr);
-
- if (args.size() < 3) return;
-
- SetAdvertisementInterval(std::chrono::milliseconds(std::stoi(args[2])));
-}
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * Copyright 2016 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 "beacon_swarm"
-
-#include "beacon_swarm.h"
-#include "stack/include/hcidefs.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-BeaconSwarm::BeaconSwarm() {
- advertising_interval_ms_ = std::chrono::milliseconds(1280);
- advertising_type_ = BTM_BLE_NON_CONNECT_EVT;
- adv_data_ = {0x02, // Length
- BTM_BLE_AD_TYPE_FLAG,
- BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG,
- 0x15,
- BTM_BLE_AD_TYPE_NAME_CMPL,
- 'g',
- 'D',
- 'e',
- 'v',
- 'i',
- 'c',
- 'e',
- '-',
- 'b',
- 'e',
- 'a',
- 'c',
- 'o',
- 'n',
- '_',
- 's',
- 'w',
- 'a',
- 'r',
- 'm'};
-
- scan_response_present_ = true;
- scan_data_ = {0x06, // Length
- BTM_BLE_AD_TYPE_NAME_SHORT,
- 'c',
- 'b',
- 'e',
- 'a',
- 'c'};
-}
-
-void BeaconSwarm::Initialize(const vector<std::string>& args) {
- if (args.size() < 2) return;
-
- BtAddress addr;
- if (addr.FromString(args[1])) SetBtAddress(addr);
-
- if (args.size() < 3) return;
-
- SetAdvertisementInterval(std::chrono::milliseconds(std::stoi(args[2])));
-}
-
-void BeaconSwarm::TimerTick() {
- std::vector<uint8_t> beacon_addr;
- GetBtAddress().ToVector(beacon_addr);
- beacon_addr[0]++;
- BtAddress next_addr;
- next_addr.FromVector(beacon_addr);
-
- SetBtAddress(next_addr);
-}
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * Copyright 2016 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 "bt_address.h"
-#include <iomanip>
-#include <vector>
-using std::vector;
-
-#include <base/logging.h>
-
-namespace test_vendor_lib {
-
-bool BtAddress::IsValid(const std::string& addr) {
- if (addr.length() < kStringLength) return false;
-
- for (size_t i = 0; i < kStringLength; i++) {
- if (i % 3 == 2) { // Every third character must be ':'
- if (addr[i] != ':') return false;
- } else { // The rest must be hexadecimal digits
- if (!isxdigit(addr[i])) return false;
- }
- }
- return true;
-}
-
-bool BtAddress::FromString(const std::string& str) {
- std::string tok;
- std::istringstream iss(str);
-
- if (!IsValid(str)) return false;
-
- address_ = 0;
- for (size_t i = 0; i < kOctets; i++) {
- getline(iss, tok, ':');
- uint64_t octet = std::stoi(tok, nullptr, 16);
- address_ |= (octet << (8 * ((kOctets - 1) - i)));
- }
- return true;
-}
-
-bool BtAddress::FromVector(const vector<uint8_t>& octets) {
- if (octets.size() < kOctets) return false;
-
- address_ = 0;
- for (size_t i = 0; i < kOctets; i++) {
- uint64_t to_shift = octets[i];
- address_ |= to_shift << (8 * i);
- }
- return true;
-}
-
-void BtAddress::ToVector(vector<uint8_t>& octets) const {
- for (size_t i = 0; i < kOctets; i++) {
- octets.push_back(address_ >> (8 * i));
- }
-}
-
-std::string BtAddress::ToString() const {
- std::stringstream ss;
-
- ss << std::hex << std::setfill('0') << std::setw(2);
- for (size_t i = 0; i < kOctets; i++) {
- uint64_t octet = (address_ >> (8 * ((kOctets - 1) - i))) & 0xff;
- ss << std::hex << std::setfill('0') << std::setw(2) << octet;
- if (i != kOctets - 1) ss << std::string(":");
- }
-
- return ss.str();
-}
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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 "command_packet"
-
-#include "command_packet.h"
-
-#include "hci/include/hci_hal.h"
-#include "osi/include/log.h"
-#include "stack/include/hcidefs.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-
-CommandPacket::CommandPacket(vector<uint8_t> header)
- : Packet(DATA_TYPE_COMMAND, std::move(header)) {}
-
-CommandPacket::CommandPacket(uint16_t opcode)
- : Packet(DATA_TYPE_COMMAND, {static_cast<uint8_t>(opcode),
- static_cast<uint8_t>(opcode >> 8)}) {}
-
-CommandPacket::CommandPacket(vector<uint8_t> header, vector<uint8_t> payload)
- : Packet(DATA_TYPE_COMMAND, std::move(header)) {
- AddPayloadOctets(payload.size(), std::move(payload));
-}
-
-uint16_t CommandPacket::GetOpcode() const {
- return 0 | (GetHeader()[0] | (GetHeader()[1] << 8));
-}
-
-uint8_t CommandPacket::GetOGF() const { return HCI_OGF(GetOpcode()); }
-
-uint16_t CommandPacket::GetOCF() const { return HCI_OCF(GetOpcode()); }
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * Copyright 2016 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 "connection"
-
-#include "connection.h"
-
-#include "base/logging.h"
-
-#include "osi/include/log.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-
-// Add an action from the controller.
-void Connection::AddAction(const TaskCallback& task) { actions_.push(task); }
-
-// Model the quality of the downstream connection
-void Connection::SendToDevice() {
- while (actions_.size() > 0) {
- // Execute the first action
- actions_.front()();
- actions_.pop();
- }
-}
-
-// Add a message from the device to the controller.
-void Connection::AddMessage(const vector<uint8_t>& data) {
- messages_.push(data);
-}
-
-// Model the quality of the upstream connection
-bool Connection::ReceiveFromDevice(vector<uint8_t>& data) {
- if (messages_.size() > 0) {
- data = messages_.front();
- messages_.pop();
-
- return true;
- }
- return false;
-}
-
-const std::string Connection::ToString() {
- return "connection " + std::to_string(handle_) + " to " + dev_->ToString();
-}
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * Copyright 2016 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_factory"
-
-#include "device_factory.h"
-#include "beacon.h"
-#include "beacon_swarm.h"
-#include "broken_adv.h"
-#include "classic.h"
-#include "device.h"
-#include "keyboard.h"
-
-#include "base/logging.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-
-std::shared_ptr<Device> DeviceFactory::Create(const vector<std::string>& args) {
- CHECK(!args.empty());
-
- std::shared_ptr<Device> new_device = nullptr;
-
- if (args[0] == "beacon") new_device = std::make_shared<Beacon>();
- if (args[0] == "beacon_swarm") new_device = std::make_shared<BeaconSwarm>();
- if (args[0] == "broken_adv") new_device = std::make_shared<BrokenAdv>();
- if (args[0] == "classic") new_device = std::make_shared<Classic>();
- if (args[0] == "keyboard") new_device = std::make_shared<Keyboard>();
-
- if (new_device != nullptr) new_device->Initialize(args);
-
- return new_device;
-}
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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 "dual_mode_controller"
-
-#include "dual_mode_controller.h"
-#include "device_factory.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 {
-
-// Included in certain events to indicate success (specific to the event
-// context).
-const uint8_t kSuccessStatus = 0;
-
-const uint8_t kUnknownHciCommand = 1;
-
-// The location of the config file loaded to populate controller attributes.
-const std::string kControllerPropertiesFile = "/vendor/etc/bluetooth/controller_properties.json";
-
-void LogCommand(const char* command) {
- LOG_INFO(LOG_TAG, "Controller performing command: %s", command);
-}
-
-} // namespace
-
-namespace test_vendor_lib {
-
-void DualModeController::AddControllerEvent(std::chrono::milliseconds delay,
- const TaskCallback& task) {
- controller_events_.push_back(schedule_task_(delay, task));
-}
-
-void DualModeController::AddConnectionAction(const TaskCallback& task,
- uint16_t handle) {
- for (size_t i = 0; i < connections_.size(); i++)
- if (*connections_[i] == handle) connections_[i]->AddAction(task);
-}
-
-void DualModeController::SendCommandCompleteSuccess(
- uint16_t command_opcode) const {
- send_event_(EventPacket::CreateCommandCompleteOnlyStatusEvent(
- command_opcode, kSuccessStatus));
-}
-
-void DualModeController::SendCommandCompleteOnlyStatus(uint16_t command_opcode,
- uint8_t status) const {
- send_event_(EventPacket::CreateCommandCompleteOnlyStatusEvent(command_opcode,
- status));
-}
-
-void DualModeController::SendCommandStatus(uint8_t status,
- uint16_t command_opcode) const {
- send_event_(EventPacket::CreateCommandStatusEvent(status, command_opcode));
-}
-
-void DualModeController::SendCommandStatusSuccess(
- uint16_t command_opcode) const {
- SendCommandStatus(kSuccessStatus, command_opcode);
-}
-
-DualModeController::DualModeController()
- : state_(kStandby), properties_(kControllerPropertiesFile) {
- devices_ = {};
-
- vector<std::string> beacon = {"beacon", "be:ac:10:00:00:01", "1000"};
- TestChannelAdd(beacon);
-
- vector<std::string> classic = {std::string("classic"),
- std::string("c1:a5:51:c0:00:01")};
- TestChannelAdd(classic);
-
- vector<std::string> keyboard = {std::string("keyboard"),
- std::string("cc:1c:eb:0a:12:d1"),
- std::string("500")};
- TestChannelAdd(keyboard);
-
- le_scan_enable_ = 0;
- le_connect_ = false;
-
- loopback_mode_ = 0;
-
-#define SET_HANDLER(opcode, method) \
- active_hci_commands_[opcode] = [this](const vector<uint8_t>& param) { \
- method(param); \
- };
- SET_HANDLER(HCI_RESET, HciReset);
- SET_HANDLER(HCI_READ_BUFFER_SIZE, HciReadBufferSize);
- SET_HANDLER(HCI_HOST_BUFFER_SIZE, HciHostBufferSize);
- SET_HANDLER(HCI_READ_LOCAL_VERSION_INFO, HciReadLocalVersionInformation);
- SET_HANDLER(HCI_READ_BD_ADDR, HciReadBdAddr);
- SET_HANDLER(HCI_READ_LOCAL_SUPPORTED_CMDS, HciReadLocalSupportedCommands);
- SET_HANDLER(HCI_READ_LOCAL_SUPPORTED_CODECS, HciReadLocalSupportedCodecs);
- SET_HANDLER(HCI_READ_LOCAL_EXT_FEATURES, HciReadLocalExtendedFeatures);
- SET_HANDLER(HCI_WRITE_SIMPLE_PAIRING_MODE, HciWriteSimplePairingMode);
- SET_HANDLER(HCI_WRITE_LE_HOST_SUPPORT, HciWriteLeHostSupport);
- SET_HANDLER(HCI_SET_EVENT_MASK, HciSetEventMask);
- SET_HANDLER(HCI_WRITE_INQUIRY_MODE, HciWriteInquiryMode);
- SET_HANDLER(HCI_WRITE_PAGESCAN_TYPE, HciWritePageScanType);
- SET_HANDLER(HCI_WRITE_INQSCAN_TYPE, HciWriteInquiryScanType);
- SET_HANDLER(HCI_WRITE_CLASS_OF_DEVICE, HciWriteClassOfDevice);
- SET_HANDLER(HCI_WRITE_PAGE_TOUT, HciWritePageTimeout);
- SET_HANDLER(HCI_WRITE_DEF_POLICY_SETTINGS, HciWriteDefaultLinkPolicySettings);
- SET_HANDLER(HCI_READ_LOCAL_NAME, HciReadLocalName);
- SET_HANDLER(HCI_CHANGE_LOCAL_NAME, HciWriteLocalName);
- SET_HANDLER(HCI_WRITE_EXT_INQ_RESPONSE, HciWriteExtendedInquiryResponse);
- SET_HANDLER(HCI_WRITE_VOICE_SETTINGS, HciWriteVoiceSetting);
- SET_HANDLER(HCI_WRITE_CURRENT_IAC_LAP, HciWriteCurrentIacLap);
- SET_HANDLER(HCI_WRITE_INQUIRYSCAN_CFG, HciWriteInquiryScanActivity);
- SET_HANDLER(HCI_WRITE_SCAN_ENABLE, HciWriteScanEnable);
- SET_HANDLER(HCI_SET_EVENT_FILTER, HciSetEventFilter);
- SET_HANDLER(HCI_INQUIRY, HciInquiry);
- SET_HANDLER(HCI_INQUIRY_CANCEL, HciInquiryCancel);
- SET_HANDLER(HCI_DELETE_STORED_LINK_KEY, HciDeleteStoredLinkKey);
- SET_HANDLER(HCI_RMT_NAME_REQUEST, HciRemoteNameRequest);
- SET_HANDLER(HCI_BLE_SET_EVENT_MASK, HciLeSetEventMask);
- SET_HANDLER(HCI_BLE_READ_BUFFER_SIZE, HciLeReadBufferSize);
- SET_HANDLER(HCI_BLE_READ_LOCAL_SPT_FEAT, HciLeReadLocalSupportedFeatures);
- SET_HANDLER(HCI_BLE_WRITE_RANDOM_ADDR, HciLeSetRandomAddress);
- SET_HANDLER(HCI_BLE_WRITE_ADV_DATA, HciLeSetAdvertisingData);
- SET_HANDLER(HCI_BLE_WRITE_ADV_PARAMS, HciLeSetAdvertisingParameters);
- SET_HANDLER(HCI_BLE_WRITE_SCAN_PARAMS, HciLeSetScanParameters);
- SET_HANDLER(HCI_BLE_WRITE_SCAN_ENABLE, HciLeSetScanEnable);
- SET_HANDLER(HCI_BLE_CREATE_LL_CONN, HciLeCreateConnection);
- SET_HANDLER(HCI_BLE_CREATE_CONN_CANCEL, HciLeConnectionCancel);
- SET_HANDLER(HCI_BLE_READ_WHITE_LIST_SIZE, HciLeReadWhiteListSize);
- SET_HANDLER(HCI_BLE_RAND, HciLeRand);
- SET_HANDLER(HCI_BLE_READ_SUPPORTED_STATES, HciLeReadSupportedStates);
- SET_HANDLER((HCI_GRP_VENDOR_SPECIFIC | 0x27), HciBleVendorSleepMode);
- SET_HANDLER(HCI_BLE_VENDOR_CAP_OCF, HciBleVendorCap);
- SET_HANDLER(HCI_BLE_MULTI_ADV_OCF, HciBleVendorMultiAdv);
- SET_HANDLER((HCI_GRP_VENDOR_SPECIFIC | 0x155), HciBleVendor155);
- SET_HANDLER(HCI_BLE_ADV_FILTER_OCF, HciBleAdvertisingFilter);
- SET_HANDLER(HCI_BLE_ENERGY_INFO_OCF, HciBleEnergyInfo);
- SET_HANDLER(HCI_BLE_EXTENDED_SCAN_PARAMS_OCF, HciBleExtendedScanParams);
- // Testing Commands
- SET_HANDLER(HCI_READ_LOOPBACK_MODE, HciReadLoopbackMode);
- SET_HANDLER(HCI_WRITE_LOOPBACK_MODE, HciWriteLoopbackMode);
-#undef SET_HANDLER
-
-#define SET_TEST_HANDLER(command_name, method) \
- active_test_channel_commands_[command_name] = \
- [this](const vector<std::string>& param) { method(param); };
- SET_TEST_HANDLER("add", TestChannelAdd);
- SET_TEST_HANDLER("del", TestChannelDel);
- SET_TEST_HANDLER("list", TestChannelList);
-#undef SET_TEST_HANDLER
-}
-
-void DualModeController::RegisterTaskScheduler(
- std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)>
- oneshotScheduler) {
- schedule_task_ = oneshotScheduler;
-}
-
-void DualModeController::RegisterPeriodicTaskScheduler(
- std::function<AsyncTaskId(std::chrono::milliseconds,
- std::chrono::milliseconds, const TaskCallback&)>
- periodicScheduler) {
- schedule_periodic_task_ = periodicScheduler;
-}
-
-void DualModeController::RegisterTaskCancel(
- std::function<void(AsyncTaskId)> task_cancel) {
- cancel_task_ = task_cancel;
-}
-
-void DualModeController::HandleTestChannelCommand(
- const std::string& name, const vector<std::string>& args) {
- if (active_test_channel_commands_.count(name) == 0) return;
- active_test_channel_commands_[name](args);
-}
-
-void DualModeController::HandleAcl(std::unique_ptr<AclPacket> acl_packet) {
- if (loopback_mode_ == HCI_LOOPBACK_MODE_LOCAL) {
- uint16_t channel = acl_packet->GetChannel();
- send_acl_(std::move(acl_packet));
- send_event_(EventPacket::CreateNumberOfCompletedPacketsEvent(channel, 1));
- return;
- }
-}
-
-void DualModeController::HandleSco(std::unique_ptr<ScoPacket> sco_packet) {
- if (loopback_mode_ == HCI_LOOPBACK_MODE_LOCAL) {
- uint16_t channel = sco_packet->GetChannel();
- send_sco_(std::move(sco_packet));
- send_event_(EventPacket::CreateNumberOfCompletedPacketsEvent(channel, 1));
- return;
- }
-}
-
-void DualModeController::HandleCommand(
- std::unique_ptr<CommandPacket> command_packet) {
- uint16_t opcode = command_packet->GetOpcode();
- LOG_INFO(LOG_TAG, "Command opcode: 0x%04X, OGF: 0x%04X, OCF: 0x%04X", opcode,
- command_packet->GetOGF(), command_packet->GetOCF());
-
- if (loopback_mode_ == HCI_LOOPBACK_MODE_LOCAL &&
- // Loopback exceptions.
- opcode != HCI_RESET && opcode != HCI_SET_HC_TO_HOST_FLOW_CTRL &&
- opcode != HCI_HOST_BUFFER_SIZE && opcode != HCI_HOST_NUM_PACKETS_DONE &&
- opcode != HCI_READ_BUFFER_SIZE && opcode != HCI_READ_LOOPBACK_MODE &&
- opcode != HCI_WRITE_LOOPBACK_MODE) {
- send_event_(EventPacket::CreateLoopbackCommandEvent(
- opcode, command_packet->GetPayload()));
- } else if (active_hci_commands_.count(opcode) > 0) {
- active_hci_commands_[opcode](command_packet->GetPayload());
- } else {
- SendCommandCompleteOnlyStatus(opcode, kUnknownHciCommand);
- }
-}
-
-void DualModeController::RegisterEventChannel(
- const std::function<void(std::unique_ptr<EventPacket>)>& callback) {
- send_event_ = callback;
-}
-
-void DualModeController::RegisterAclChannel(
- const std::function<void(std::unique_ptr<AclPacket>)>& callback) {
- send_acl_ = callback;
-}
-
-void DualModeController::RegisterScoChannel(
- const std::function<void(std::unique_ptr<ScoPacket>)>& callback) {
- send_sco_ = callback;
-}
-
-void DualModeController::HandleTimerTick() {
- if (state_ == kInquiry) PageScan();
- if (le_scan_enable_ || le_connect_) LeScan();
- Connections();
- for (size_t dev = 0; dev < devices_.size(); dev++) devices_[dev]->TimerTick();
-}
-
-void DualModeController::SetTimerPeriod(std::chrono::milliseconds new_period) {
- timer_period_ = new_period;
-
- if (timer_tick_task_ == kInvalidTaskId) return;
-
- // Restart the timer with the new period
- StopTimer();
- StartTimer();
-}
-
-static uint8_t GetRssi(size_t dev) {
- // TODO: Model rssi somehow
- return -((dev * 16) % 127);
-}
-
-static uint8_t LeGetHandle() {
- static int handle = 0;
- return handle++;
-}
-
-static uint8_t LeGetConnInterval() { return 1; }
-
-static uint8_t LeGetConnLatency() { return 2; }
-
-static uint8_t LeGetSupervisionTimeout() { return 3; }
-
-void DualModeController::Connections() {
- for (size_t i = 0; i < connections_.size(); i++) {
- if (connections_[i]->Connected()) {
- connections_[i]->SendToDevice();
- vector<uint8_t> data;
- connections_[i]->ReceiveFromDevice(data);
- // HandleConnectionData(data);
- }
- }
-}
-
-void DualModeController::LeScan() {
- std::unique_ptr<EventPacket> le_adverts =
- EventPacket::CreateLeAdvertisingReportEvent();
- vector<uint8_t> ad;
- for (size_t dev = 0; dev < devices_.size(); dev++) {
- uint8_t adv_type;
- const BtAddress addr = devices_[dev]->GetBtAddress();
- uint8_t addr_type = devices_[dev]->GetAddressType();
- ad.clear();
-
- // Listen for Advertisements
- if (devices_[dev]->IsAdvertisementAvailable(
- std::chrono::milliseconds(le_scan_window_))) {
- ad = devices_[dev]->GetAdvertisement();
- adv_type = devices_[dev]->GetAdvertisementType();
- if (le_scan_enable_ && !le_adverts->AddLeAdvertisingReport(
- adv_type, addr_type, addr, ad, GetRssi(dev))) {
- send_event_(std::move(le_adverts));
- le_adverts = EventPacket::CreateLeAdvertisingReportEvent();
- CHECK(le_adverts->AddLeAdvertisingReport(adv_type, addr_type, addr, ad,
- GetRssi(dev)));
- }
-
- // Connect
- if (le_connect_ && (adv_type == BTM_BLE_CONNECT_EVT ||
- adv_type == BTM_BLE_CONNECT_DIR_EVT)) {
- LOG_INFO(LOG_TAG, "Connecting to device %d", static_cast<int>(dev));
- if (peer_address_ == addr && peer_address_type_ == addr_type &&
- devices_[dev]->LeConnect()) {
- uint16_t handle = LeGetHandle();
- std::unique_ptr<EventPacket> event =
- EventPacket::CreateLeConnectionCompleteEvent(
- kSuccessStatus, handle, HCI_ROLE_MASTER, addr_type, addr,
- LeGetConnInterval(), LeGetConnLatency(),
- LeGetSupervisionTimeout());
- send_event_(std::move(event));
- le_connect_ = false;
-
- connections_.push_back(
- std::make_shared<Connection>(devices_[dev], handle));
- }
-
- // TODO: Handle the white list (if (InWhiteList(dev)))
- }
-
- // Active scanning
- if (le_scan_enable_ && le_scan_type_ == 1) {
- ad.clear();
- if (devices_[dev]->HasScanResponse()) {
- ad = devices_[dev]->GetScanResponse();
- if (!le_adverts->AddLeAdvertisingReport(
- BTM_BLE_SCAN_RSP_EVT, addr_type, addr, ad, GetRssi(dev))) {
- send_event_(std::move(le_adverts));
- le_adverts = EventPacket::CreateLeAdvertisingReportEvent();
- CHECK(le_adverts->AddLeAdvertisingReport(
- BTM_BLE_SCAN_RSP_EVT, addr_type, addr, ad, GetRssi(dev)));
- }
- }
- }
- }
- }
-
- if (le_scan_enable_) send_event_(std::move(le_adverts));
-}
-
-void DualModeController::PageScan() {
- // Inquiry modes for specifiying inquiry result formats.
- static const uint8_t kStandardInquiry = 0x00;
- static const uint8_t kRssiInquiry = 0x01;
- static const uint8_t kExtendedOrRssiInquiry = 0x02;
-
- switch (inquiry_mode_) {
- case (kStandardInquiry): {
- std::unique_ptr<EventPacket> inquiry_result =
- EventPacket::CreateInquiryResultEvent();
- for (size_t dev = 0; dev < devices_.size(); dev++)
- // Scan for devices
- if (devices_[dev]->IsPageScanAvailable()) {
- bool result_added = inquiry_result->AddInquiryResult(
- devices_[dev]->GetBtAddress(),
- devices_[dev]->GetPageScanRepetitionMode(),
- devices_[dev]->GetDeviceClass(), devices_[dev]->GetClockOffset());
- if (!result_added) {
- send_event_(std::move(inquiry_result));
- inquiry_result = EventPacket::CreateInquiryResultEvent();
- result_added = inquiry_result->AddInquiryResult(
- devices_[dev]->GetBtAddress(),
- devices_[dev]->GetPageScanRepetitionMode(),
- devices_[dev]->GetDeviceClass(),
- devices_[dev]->GetClockOffset());
- CHECK(result_added);
- }
- }
- } break;
-
- case (kRssiInquiry):
- LOG_INFO(LOG_TAG, "RSSI Inquiry Mode currently not supported.");
- break;
-
- case (kExtendedOrRssiInquiry):
- for (size_t dev = 0; dev < devices_.size(); dev++)
- if (devices_[dev]->IsPageScanAvailable()) {
- send_event_(EventPacket::CreateExtendedInquiryResultEvent(
- devices_[dev]->GetBtAddress(),
- devices_[dev]->GetPageScanRepetitionMode(),
- devices_[dev]->GetDeviceClass(), devices_[dev]->GetClockOffset(),
- GetRssi(dev), devices_[dev]->GetExtendedInquiryData()));
- }
- break;
- }
-}
-
-void DualModeController::StartTimer() {
- LOG_ERROR(LOG_TAG, "StartTimer");
- timer_tick_task_ = schedule_periodic_task_(
- std::chrono::milliseconds(0), timer_period_,
- [this]() { DualModeController::HandleTimerTick(); });
-}
-
-void DualModeController::StopTimer() {
- LOG_ERROR(LOG_TAG, "StopTimer");
- cancel_task_(timer_tick_task_);
- timer_tick_task_ = kInvalidTaskId;
-}
-
-void DualModeController::SetEventDelay(int64_t delay) {
- if (delay < 0) delay = 0;
-}
-
-void DualModeController::TestChannelAdd(const vector<std::string>& args) {
- LogCommand("TestChannel 'add'");
-
- std::shared_ptr<Device> new_dev = DeviceFactory::Create(args);
-
- if (new_dev == NULL) {
- LOG_ERROR(LOG_TAG, "TestChannel 'add' failed!");
- return;
- }
-
- devices_.push_back(new_dev);
-}
-
-void DualModeController::TestChannelDel(const vector<std::string>& args) {
- LogCommand("TestChannel 'del'");
-
- size_t dev_index = std::stoi(args[0]);
-
- if (dev_index >= devices_.size()) {
- LOG_INFO(LOG_TAG, "TestChannel 'del': index %d out of range!",
- static_cast<int>(dev_index));
- } else {
- devices_.erase(devices_.begin() + dev_index);
- }
-}
-
-void DualModeController::TestChannelList(
- UNUSED_ATTR const vector<std::string>& args) const {
- LogCommand("TestChannel 'list'");
- LOG_INFO(LOG_TAG, "Devices:");
- for (size_t dev = 0; dev < devices_.size(); dev++) {
- LOG_INFO(LOG_TAG, "%d:", static_cast<int>(dev));
- devices_[dev]->ToString();
- }
-}
-
-void DualModeController::HciReset(const vector<uint8_t>& args) {
- LogCommand("Reset");
- CHECK(args[0] == 0); // No arguments
- state_ = kStandby;
- if (timer_tick_task_ != kInvalidTaskId) {
- LOG_INFO(LOG_TAG, "The timer was already running!");
- StopTimer();
- }
- LOG_INFO(LOG_TAG, "Starting timer.");
- StartTimer();
-
- SendCommandCompleteSuccess(HCI_RESET);
-}
-
-void DualModeController::HciReadBufferSize(const vector<uint8_t>& args) {
- LogCommand("Read Buffer Size");
- CHECK(args[0] == 0); // No arguments
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteReadBufferSize(
- kSuccessStatus, properties_.GetAclDataPacketSize(),
- properties_.GetSynchronousDataPacketSize(),
- properties_.GetTotalNumAclDataPackets(),
- properties_.GetTotalNumSynchronousDataPackets());
-
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciHostBufferSize(const vector<uint8_t>& args) {
- LogCommand("Host Buffer Size");
- CHECK(args[0] == 7); // No arguments
- SendCommandCompleteSuccess(HCI_HOST_BUFFER_SIZE);
-}
-
-void DualModeController::HciReadLocalVersionInformation(
- const vector<uint8_t>& args) {
- LogCommand("Read Local Version Information");
- CHECK(args[0] == 0); // No arguments
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteReadLocalVersionInformation(
- kSuccessStatus, properties_.GetVersion(), properties_.GetRevision(),
- properties_.GetLmpPalVersion(), properties_.GetManufacturerName(),
- properties_.GetLmpPalSubversion());
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciReadBdAddr(const vector<uint8_t>& args) {
- CHECK(args[0] == 0); // No arguments
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteReadBdAddr(kSuccessStatus,
- properties_.GetAddress());
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciReadLocalSupportedCommands(
- const vector<uint8_t>& args) {
- LogCommand("Read Local Supported Commands");
- CHECK(args[0] == 0); // No arguments
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteReadLocalSupportedCommands(
- kSuccessStatus, properties_.GetLocalSupportedCommands());
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciReadLocalSupportedCodecs(
- const vector<uint8_t>& args) {
- LogCommand("Read Local Supported Codecs");
- CHECK(args[0] == 0); // No arguments
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteReadLocalSupportedCodecs(
- kSuccessStatus, properties_.GetSupportedCodecs(),
- properties_.GetVendorSpecificCodecs());
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciReadLocalExtendedFeatures(
- const vector<uint8_t>& args) {
- LogCommand("Read Local Extended Features");
- CHECK(args.size() == 2);
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteReadLocalExtendedFeatures(
- kSuccessStatus, args[1],
- properties_.GetLocalExtendedFeaturesMaximumPageNumber(),
- properties_.GetLocalExtendedFeatures(args[1]));
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciWriteSimplePairingMode(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Simple Pairing Mode");
- SendCommandCompleteSuccess(HCI_WRITE_SIMPLE_PAIRING_MODE);
-}
-
-void DualModeController::HciWriteLeHostSupport(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Le Host Support");
- SendCommandCompleteSuccess(HCI_WRITE_LE_HOST_SUPPORT);
-}
-
-void DualModeController::HciSetEventMask(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Set Event Mask");
- SendCommandCompleteSuccess(HCI_SET_EVENT_MASK);
-}
-
-void DualModeController::HciWriteInquiryMode(const vector<uint8_t>& args) {
- LogCommand("Write Inquiry Mode");
- CHECK(args.size() == 2);
- inquiry_mode_ = args[1];
- SendCommandCompleteSuccess(HCI_WRITE_INQUIRY_MODE);
-}
-
-void DualModeController::HciWritePageScanType(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Page Scan Type");
- SendCommandCompleteSuccess(HCI_WRITE_PAGESCAN_TYPE);
-}
-
-void DualModeController::HciWriteInquiryScanType(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Inquiry Scan Type");
- SendCommandCompleteSuccess(HCI_WRITE_INQSCAN_TYPE);
-}
-
-void DualModeController::HciWriteClassOfDevice(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Class Of Device");
- SendCommandCompleteSuccess(HCI_WRITE_CLASS_OF_DEVICE);
-}
-
-void DualModeController::HciWritePageTimeout(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Page Timeout");
- SendCommandCompleteSuccess(HCI_WRITE_PAGE_TOUT);
-}
-
-void DualModeController::HciWriteDefaultLinkPolicySettings(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Default Link Policy Settings");
- SendCommandCompleteSuccess(HCI_WRITE_DEF_POLICY_SETTINGS);
-}
-
-void DualModeController::HciReadLocalName(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Get Local Name");
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteReadLocalName(
- kSuccessStatus, properties_.GetLocalName());
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciWriteLocalName(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Local Name");
- SendCommandCompleteSuccess(HCI_CHANGE_LOCAL_NAME);
-}
-
-void DualModeController::HciWriteExtendedInquiryResponse(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Extended Inquiry Response");
- SendCommandCompleteSuccess(HCI_WRITE_EXT_INQ_RESPONSE);
-}
-
-void DualModeController::HciWriteVoiceSetting(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Voice Setting");
- SendCommandCompleteSuccess(HCI_WRITE_VOICE_SETTINGS);
-}
-
-void DualModeController::HciWriteCurrentIacLap(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Current IAC LAP");
- SendCommandCompleteSuccess(HCI_WRITE_CURRENT_IAC_LAP);
-}
-
-void DualModeController::HciWriteInquiryScanActivity(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Inquiry Scan Activity");
- SendCommandCompleteSuccess(HCI_WRITE_INQUIRYSCAN_CFG);
-}
-
-void DualModeController::HciWriteScanEnable(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Write Scan Enable");
- SendCommandCompleteSuccess(HCI_WRITE_SCAN_ENABLE);
-}
-
-void DualModeController::HciSetEventFilter(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Set Event Filter");
- SendCommandCompleteSuccess(HCI_SET_EVENT_FILTER);
-}
-
-void DualModeController::HciInquiry(const vector<uint8_t>& args) {
- LogCommand("Inquiry");
- CHECK(args.size() == 6);
- state_ = kInquiry;
- SendCommandStatusSuccess(HCI_INQUIRY);
- inquiry_lap_[0] = args[1];
- inquiry_lap_[1] = args[2];
- inquiry_lap_[2] = args[3];
-
- AddControllerEvent(std::chrono::milliseconds(args[4] * 1280),
- [this]() { DualModeController::InquiryTimeout(); });
-
- if (args[5] > 0) {
- inquiry_responses_limited_ = true;
- inquiry_num_responses_ = args[5];
- }
-}
-
-void DualModeController::HciInquiryCancel(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Inquiry Cancel");
- CHECK(state_ == kInquiry);
- state_ = kStandby;
- SendCommandCompleteSuccess(HCI_INQUIRY_CANCEL);
-}
-
-void DualModeController::InquiryTimeout() {
- LOG_INFO(LOG_TAG, "InquiryTimer fired");
- if (state_ == kInquiry) {
- state_ = kStandby;
- inquiry_responses_limited_ = false;
- send_event_(EventPacket::CreateInquiryCompleteEvent(kSuccessStatus));
- }
-}
-
-void DualModeController::HciDeleteStoredLinkKey(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Delete Stored Link Key");
- /* Check the last octect in |args|. If it is 0, delete only the link key for
- * the given BD_ADDR. If is is 1, delete all stored link keys. */
- uint16_t deleted_keys = 1;
-
- send_event_(EventPacket::CreateCommandCompleteDeleteStoredLinkKey(
- kSuccessStatus, deleted_keys));
-}
-
-void DualModeController::HciRemoteNameRequest(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("Remote Name Request");
- SendCommandStatusSuccess(HCI_RMT_NAME_REQUEST);
-}
-
-void DualModeController::HciLeSetEventMask(const vector<uint8_t>& args) {
- LogCommand("LE SetEventMask");
- le_event_mask_ = args;
- SendCommandCompleteSuccess(HCI_BLE_SET_EVENT_MASK);
-}
-
-void DualModeController::HciLeReadBufferSize(
- UNUSED_ATTR const vector<uint8_t>& args) {
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteLeReadBufferSize(
- kSuccessStatus, properties_.GetLeDataPacketLength(),
- properties_.GetTotalNumLeDataPackets());
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciLeReadLocalSupportedFeatures(
- UNUSED_ATTR const vector<uint8_t>& args) {
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteLeReadLocalSupportedFeatures(
- kSuccessStatus, properties_.GetLeLocalSupportedFeatures());
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciLeSetRandomAddress(const vector<uint8_t>& args) {
- LogCommand("LE SetRandomAddress");
- CHECK(args.size() == 7);
- vector<uint8_t> new_addr = {args[1], args[2], args[3],
- args[4], args[5], args[6]};
- CHECK(le_random_address_.FromVector(new_addr));
- SendCommandCompleteSuccess(HCI_BLE_WRITE_RANDOM_ADDR);
-}
-
-void DualModeController::HciLeSetAdvertisingParameters(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("LE SetAdvertisingParameters");
- SendCommandCompleteSuccess(HCI_BLE_WRITE_ADV_PARAMS);
-}
-
-void DualModeController::HciLeSetAdvertisingData(
- UNUSED_ATTR const vector<uint8_t>& args) {
- LogCommand("LE SetAdvertisingData");
- SendCommandCompleteSuccess(HCI_BLE_WRITE_ADV_DATA);
-}
-
-void DualModeController::HciLeSetScanParameters(const vector<uint8_t>& args) {
- LogCommand("LE SetScanParameters");
- CHECK(args.size() == 8);
- le_scan_type_ = args[1];
- le_scan_interval_ = args[2] | (args[3] << 8);
- le_scan_window_ = args[4] | (args[5] << 8);
- own_address_type_ = args[6];
- scanning_filter_policy_ = args[7];
- SendCommandCompleteSuccess(HCI_BLE_WRITE_SCAN_PARAMS);
-}
-
-void DualModeController::HciLeSetScanEnable(const vector<uint8_t>& args) {
- LogCommand("LE SetScanEnable");
- CHECK(args.size() == 3);
- le_scan_enable_ = args[1];
- filter_duplicates_ = args[2];
- SendCommandCompleteSuccess(HCI_BLE_WRITE_SCAN_ENABLE);
-}
-
-void DualModeController::HciLeCreateConnection(const vector<uint8_t>& args) {
- LogCommand("LE CreateConnection");
- le_connect_ = true;
- le_scan_interval_ = args[1] | (args[2] << 8);
- le_scan_window_ = args[3] | (args[4] << 8);
- initiator_filter_policy_ = args[5];
-
- if (initiator_filter_policy_ == 0) { // White list not used
- peer_address_type_ = args[6];
- vector<uint8_t> peer_addr = {args[7], args[8], args[9],
- args[10], args[11], args[12]};
- peer_address_.FromVector(peer_addr);
- }
-
- SendCommandStatusSuccess(HCI_BLE_CREATE_LL_CONN);
-}
-
-void DualModeController::HciLeConnectionCancel(const vector<uint8_t>& args) {
- LogCommand("LE ConnectionCancel");
- CHECK(args[0] == 0); // No arguments
- le_connect_ = false;
- SendCommandStatusSuccess(HCI_BLE_CREATE_CONN_CANCEL);
-}
-
-void DualModeController::HciLeReadWhiteListSize(const vector<uint8_t>& args) {
- LogCommand("LE ReadWhiteListSize");
- CHECK(args[0] == 0); // No arguments
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteLeReadWhiteListSize(
- kSuccessStatus, properties_.GetLeWhiteListSize());
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciLeReadRemoteUsedFeaturesB(uint16_t handle) {
- uint64_t features;
- LogCommand("LE ReadRemoteUsedFeatures Bottom half");
-
- for (size_t i = 0; i < connections_.size(); i++)
- if (*connections_[i] == handle)
- // TODO:
- // features = connections_[i]->GetDevice()->GetUsedFeatures();
- features = 0xffffffffffffffff;
-
- std::unique_ptr<EventPacket> event =
- EventPacket::CreateLeRemoteUsedFeaturesEvent(kSuccessStatus, handle,
- features);
- send_event_(std::move(event));
-}
-
-void DualModeController::HciLeReadRemoteUsedFeatures(
- const vector<uint8_t>& args) {
- LogCommand("LE ReadRemoteUsedFeatures");
- CHECK(args.size() == 3);
-
- uint16_t handle = args[1] | (args[2] << 8);
-
- AddConnectionAction(
- [this, handle]() {
- DualModeController::HciLeReadRemoteUsedFeaturesB(handle);
- },
- handle);
-
- SendCommandStatusSuccess(HCI_BLE_READ_REMOTE_FEAT);
-}
-
-void DualModeController::HciLeRand(UNUSED_ATTR const vector<uint8_t>& args) {
- uint64_t random_val = rand();
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteLeRand(kSuccessStatus, random_val);
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciLeReadSupportedStates(
- UNUSED_ATTR const vector<uint8_t>& args) {
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteLeReadSupportedStates(
- kSuccessStatus, properties_.GetLeSupportedStates());
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciBleVendorSleepMode(
- UNUSED_ATTR const vector<uint8_t>& args) {
- SendCommandCompleteOnlyStatus(HCI_GRP_VENDOR_SPECIFIC | 0x27,
- kUnknownHciCommand);
-}
-
-void DualModeController::HciBleVendorCap(
- UNUSED_ATTR const vector<uint8_t>& args) {
- vector<uint8_t> caps = properties_.GetLeVendorCap();
- if (caps.size() == 0) {
- SendCommandCompleteOnlyStatus(HCI_BLE_VENDOR_CAP_OCF, kUnknownHciCommand);
- return;
- }
-
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteLeVendorCap(
- kSuccessStatus, properties_.GetLeVendorCap());
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciBleVendorMultiAdv(
- UNUSED_ATTR const vector<uint8_t>& args) {
- SendCommandCompleteOnlyStatus(HCI_BLE_MULTI_ADV_OCF, kUnknownHciCommand);
-}
-
-void DualModeController::HciBleVendor155(
- UNUSED_ATTR const vector<uint8_t>& args) {
- SendCommandCompleteOnlyStatus(HCI_GRP_VENDOR_SPECIFIC | 0x155,
- kUnknownHciCommand);
-}
-
-void DualModeController::HciBleAdvertisingFilter(
- UNUSED_ATTR const vector<uint8_t>& args) {
- SendCommandCompleteOnlyStatus(HCI_BLE_ADV_FILTER_OCF, kUnknownHciCommand);
-}
-
-void DualModeController::HciBleEnergyInfo(
- UNUSED_ATTR const vector<uint8_t>& args) {
- SendCommandCompleteOnlyStatus(HCI_BLE_ENERGY_INFO_OCF, kUnknownHciCommand);
-}
-
-void DualModeController::HciBleExtendedScanParams(
- UNUSED_ATTR const vector<uint8_t>& args) {
- SendCommandCompleteOnlyStatus(HCI_BLE_EXTENDED_SCAN_PARAMS_OCF,
- kUnknownHciCommand);
-}
-
-void DualModeController::HciReadLoopbackMode(const vector<uint8_t>& args) {
- CHECK(args[0] == 0); // No arguments
- std::unique_ptr<EventPacket> command_complete =
- EventPacket::CreateCommandCompleteReadLoopbackMode(kSuccessStatus,
- loopback_mode_);
- send_event_(std::move(command_complete));
-}
-
-void DualModeController::HciWriteLoopbackMode(const vector<uint8_t>& args) {
- CHECK(args[0] == 1);
- loopback_mode_ = args[1];
- // ACL channel
- uint16_t acl_handle = 0x123;
- send_event_(EventPacket::CreateConnectionCompleteEvent(
- kSuccessStatus, acl_handle, properties_.GetAddress(), HCI_LINK_TYPE_ACL,
- false));
- // SCO channel
- uint16_t sco_handle = 0x345;
- send_event_(EventPacket::CreateConnectionCompleteEvent(
- kSuccessStatus, sco_handle, properties_.GetAddress(), HCI_LINK_TYPE_SCO,
- false));
- SendCommandCompleteSuccess(HCI_WRITE_LOOPBACK_MODE);
-}
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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 "event_packet"
-
-#include "event_packet.h"
-
-#include "osi/include/log.h"
-#include "stack/include/hcidefs.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-
-EventPacket::EventPacket(uint8_t event_code)
- : Packet(DATA_TYPE_EVENT, {event_code}) {}
-
-uint8_t EventPacket::GetEventCode() const { return GetHeader()[0]; }
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.1
-std::unique_ptr<EventPacket> EventPacket::CreateInquiryCompleteEvent(
- uint8_t status) {
- std::unique_ptr<EventPacket> evt_ptr =
- std::unique_ptr<EventPacket>(new EventPacket(HCI_INQUIRY_COMP_EVT));
- CHECK(evt_ptr->AddPayloadOctets1(status));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.14
-std::unique_ptr<EventPacket> EventPacket::CreateCommandCompleteEvent(
- uint16_t command_opcode, const vector<uint8_t>& event_return_parameters) {
- std::unique_ptr<EventPacket> evt_ptr =
- std::unique_ptr<EventPacket>(new EventPacket(HCI_COMMAND_COMPLETE_EVT));
-
- CHECK(evt_ptr->AddPayloadOctets1(1)); // num_hci_command_packets
- CHECK(evt_ptr->AddPayloadOctets2(command_opcode));
- CHECK(evt_ptr->AddPayloadOctets(event_return_parameters.size(),
- event_return_parameters));
-
- return evt_ptr;
-}
-
-std::unique_ptr<EventPacket> EventPacket::CreateCommandCompleteOnlyStatusEvent(
- uint16_t command_opcode, uint8_t status) {
- std::unique_ptr<EventPacket> evt_ptr =
- std::unique_ptr<EventPacket>(new EventPacket(HCI_COMMAND_COMPLETE_EVT));
-
- CHECK(evt_ptr->AddPayloadOctets1(1)); // num_hci_command_packets
- CHECK(evt_ptr->AddPayloadOctets2(command_opcode));
- CHECK(evt_ptr->AddPayloadOctets1(status));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.15
-std::unique_ptr<EventPacket> EventPacket::CreateCommandStatusEvent(
- uint8_t status, uint16_t command_opcode) {
- std::unique_ptr<EventPacket> evt_ptr =
- std::unique_ptr<EventPacket>(new EventPacket(HCI_COMMAND_STATUS_EVT));
-
- CHECK(evt_ptr->AddPayloadOctets1(status));
- CHECK(evt_ptr->AddPayloadOctets1(1)); // num_hci_command_packets
- CHECK(evt_ptr->AddPayloadOctets2(command_opcode));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.19
-std::unique_ptr<EventPacket> EventPacket::CreateNumberOfCompletedPacketsEvent(
- uint16_t handle, uint16_t num_completed_packets) {
- std::unique_ptr<EventPacket> evt_ptr = std::unique_ptr<EventPacket>(
- new EventPacket(HCI_NUM_COMPL_DATA_PKTS_EVT));
-
- CHECK(evt_ptr->AddPayloadOctets1(0)); // Number of handles.
- evt_ptr->AddCompletedPackets(handle, num_completed_packets);
-
- return evt_ptr;
-}
-
-void EventPacket::AddCompletedPackets(uint16_t handle,
- uint16_t num_completed_packets) {
- CHECK(AddPayloadOctets2(handle));
- CHECK(AddPayloadOctets2(num_completed_packets));
- CHECK(IncrementPayloadCounter(1)); // Increment the number of handles.
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.10
-std::unique_ptr<EventPacket>
-EventPacket::CreateCommandCompleteDeleteStoredLinkKey(
- uint8_t status, uint16_t num_keys_deleted) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(
- HCI_DELETE_STORED_LINK_KEY, status);
-
- CHECK(evt_ptr->AddPayloadOctets2(num_keys_deleted));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.3.12
-std::unique_ptr<EventPacket> EventPacket::CreateCommandCompleteReadLocalName(
- uint8_t status, const std::string& local_name) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(HCI_READ_LOCAL_NAME,
- status);
-
- for (size_t i = 0; i < local_name.length(); i++)
- CHECK(evt_ptr->AddPayloadOctets1(local_name[i]));
- CHECK(evt_ptr->AddPayloadOctets1(0)); // Null terminated
- for (size_t i = 0; i < 248 - local_name.length() - 1; i++)
- CHECK(evt_ptr->AddPayloadOctets1(0xFF));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.1
-std::unique_ptr<EventPacket>
-EventPacket::CreateCommandCompleteReadLocalVersionInformation(
- uint8_t status, uint8_t hci_version, uint16_t hci_revision,
- uint8_t lmp_pal_version, uint16_t manufacturer_name,
- uint16_t lmp_pal_subversion) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(
- HCI_READ_LOCAL_VERSION_INFO, status);
-
- CHECK(evt_ptr->AddPayloadOctets1(hci_version));
- CHECK(evt_ptr->AddPayloadOctets2(hci_revision));
- CHECK(evt_ptr->AddPayloadOctets1(lmp_pal_version));
- CHECK(evt_ptr->AddPayloadOctets2(manufacturer_name));
- CHECK(evt_ptr->AddPayloadOctets2(lmp_pal_subversion));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.2
-std::unique_ptr<EventPacket>
-EventPacket::CreateCommandCompleteReadLocalSupportedCommands(
- uint8_t status, const vector<uint8_t>& supported_commands) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(
- HCI_READ_LOCAL_SUPPORTED_CMDS, status);
-
- CHECK(evt_ptr->AddPayloadOctets(64, supported_commands));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.4
-std::unique_ptr<EventPacket>
-EventPacket::CreateCommandCompleteReadLocalExtendedFeatures(
- uint8_t status, uint8_t page_number, uint8_t maximum_page_number,
- uint64_t extended_lmp_features) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(
- HCI_READ_LOCAL_EXT_FEATURES, status);
-
- CHECK(evt_ptr->AddPayloadOctets1(page_number));
- CHECK(evt_ptr->AddPayloadOctets1(maximum_page_number));
- CHECK(evt_ptr->AddPayloadOctets8(extended_lmp_features));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.5
-std::unique_ptr<EventPacket> EventPacket::CreateCommandCompleteReadBufferSize(
- uint8_t status, uint16_t hc_acl_data_packet_length,
- uint8_t hc_synchronous_data_packet_length,
- uint16_t hc_total_num_acl_data_packets,
- uint16_t hc_total_synchronous_data_packets) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(HCI_READ_BUFFER_SIZE,
- status);
-
- CHECK(evt_ptr->AddPayloadOctets2(hc_acl_data_packet_length));
- CHECK(evt_ptr->AddPayloadOctets1(hc_synchronous_data_packet_length));
- CHECK(evt_ptr->AddPayloadOctets2(hc_total_num_acl_data_packets));
- CHECK(evt_ptr->AddPayloadOctets2(hc_total_synchronous_data_packets));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.6
-std::unique_ptr<EventPacket> EventPacket::CreateCommandCompleteReadBdAddr(
- uint8_t status, const BtAddress& address) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(HCI_READ_BD_ADDR,
- status);
-
- CHECK(evt_ptr->AddPayloadBtAddress(address));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.4.8
-std::unique_ptr<EventPacket>
-EventPacket::CreateCommandCompleteReadLocalSupportedCodecs(
- uint8_t status, const vector<uint8_t>& supported_codecs,
- const vector<uint32_t>& vendor_specific_codecs) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(
- HCI_READ_LOCAL_SUPPORTED_CODECS, status);
-
- CHECK(evt_ptr->AddPayloadOctets(supported_codecs.size(), supported_codecs));
- for (size_t i = 0; i < vendor_specific_codecs.size(); i++)
- CHECK(evt_ptr->AddPayloadOctets4(vendor_specific_codecs[i]));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.6.1
-std::unique_ptr<EventPacket> EventPacket::CreateCommandCompleteReadLoopbackMode(
- uint8_t status, uint8_t mode) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(HCI_READ_LOOPBACK_MODE,
- status);
- CHECK(evt_ptr->AddPayloadOctets1(mode));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.2
-std::unique_ptr<EventPacket> EventPacket::CreateInquiryResultEvent() {
- std::unique_ptr<EventPacket> evt_ptr =
- std::unique_ptr<EventPacket>(new EventPacket(HCI_INQUIRY_RESULT_EVT));
-
- CHECK(evt_ptr->AddPayloadOctets1(0)); // Start with no responses
- return evt_ptr;
-}
-
-bool EventPacket::AddInquiryResult(const BtAddress& address,
- uint8_t page_scan_repetition_mode,
- uint32_t class_of_device,
- uint16_t clock_offset) {
- CHECK(GetEventCode() == HCI_INQUIRY_RESULT_EVT);
-
- if (!CanAddPayloadOctets(14)) return false;
-
- CHECK(IncrementPayloadCounter(1)); // Increment the number of responses
-
- CHECK(AddPayloadBtAddress(address));
- CHECK(AddPayloadOctets1(page_scan_repetition_mode));
- CHECK(AddPayloadOctets2(kReservedZero));
- CHECK(AddPayloadOctets3(class_of_device));
- CHECK(!(clock_offset & 0x8000));
- CHECK(AddPayloadOctets2(clock_offset));
- return true;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.3
-std::unique_ptr<EventPacket> EventPacket::CreateConnectionCompleteEvent(
- uint8_t status, uint16_t handle, const BtAddress& address,
- uint8_t link_type, bool encryption_enabled) {
- std::unique_ptr<EventPacket> evt_ptr =
- std::unique_ptr<EventPacket>(new EventPacket(HCI_CONNECTION_COMP_EVT));
-
- CHECK(evt_ptr->AddPayloadOctets1(status));
- CHECK((handle & 0xf000) == 0); // Handles are 12-bit values.
- CHECK(evt_ptr->AddPayloadOctets2(handle));
- CHECK(evt_ptr->AddPayloadBtAddress(address));
- CHECK(evt_ptr->AddPayloadOctets1(link_type));
- CHECK(evt_ptr->AddPayloadOctets1(encryption_enabled ? 1 : 0));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.25
-std::unique_ptr<EventPacket> EventPacket::CreateLoopbackCommandEvent(
- uint16_t opcode, const vector<uint8_t>& payload) {
- std::unique_ptr<EventPacket> evt_ptr =
- std::unique_ptr<EventPacket>(new EventPacket(HCI_LOOPBACK_COMMAND_EVT));
- CHECK(evt_ptr->AddPayloadOctets2(opcode));
- for (const auto& payload_byte : payload) // Fill the packet.
- evt_ptr->AddPayloadOctets1(payload_byte);
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.38
-std::unique_ptr<EventPacket> EventPacket::CreateExtendedInquiryResultEvent(
- const BtAddress& address, uint8_t page_scan_repetition_mode,
- uint32_t class_of_device, uint16_t clock_offset, uint8_t rssi,
- const vector<uint8_t>& extended_inquiry_response) {
- std::unique_ptr<EventPacket> evt_ptr = std::unique_ptr<EventPacket>(
- new EventPacket(HCI_EXTENDED_INQUIRY_RESULT_EVT));
-
- CHECK(evt_ptr->AddPayloadOctets1(1)); // Always contains a single response
-
- CHECK(evt_ptr->AddPayloadBtAddress(address));
- CHECK(evt_ptr->AddPayloadOctets1(page_scan_repetition_mode));
- CHECK(evt_ptr->AddPayloadOctets1(kReservedZero));
- CHECK(evt_ptr->AddPayloadOctets3(class_of_device));
- CHECK(!(clock_offset & 0x8000));
- CHECK(evt_ptr->AddPayloadOctets2(clock_offset));
- CHECK(evt_ptr->AddPayloadOctets1(rssi));
- CHECK(evt_ptr->AddPayloadOctets(extended_inquiry_response.size(),
- extended_inquiry_response));
- while (evt_ptr->AddPayloadOctets1(0xff))
- ; // Fill packet
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.65.1
-std::unique_ptr<EventPacket> EventPacket::CreateLeConnectionCompleteEvent(
- uint8_t status, uint16_t handle, uint8_t role, uint8_t peer_address_type,
- const BtAddress& peer, uint16_t interval, uint16_t latency,
- uint16_t supervision_timeout) {
- std::unique_ptr<EventPacket> evt_ptr =
- std::unique_ptr<EventPacket>(new EventPacket(HCI_BLE_EVENT));
-
- CHECK(evt_ptr->AddPayloadOctets1(HCI_BLE_CONN_COMPLETE_EVT));
- CHECK(evt_ptr->AddPayloadOctets1(status));
- CHECK(evt_ptr->AddPayloadOctets2(handle));
- CHECK(evt_ptr->AddPayloadOctets1(role));
- CHECK(evt_ptr->AddPayloadOctets1(peer_address_type));
- CHECK(evt_ptr->AddPayloadBtAddress(peer));
- CHECK(evt_ptr->AddPayloadOctets2(interval));
- CHECK(evt_ptr->AddPayloadOctets2(latency));
- CHECK(evt_ptr->AddPayloadOctets2(supervision_timeout));
- CHECK(evt_ptr->AddPayloadOctets1(
- 0x00)); // Master Clock Accuracy (unused for master)
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.65.2
-std::unique_ptr<EventPacket> EventPacket::CreateLeAdvertisingReportEvent() {
- std::unique_ptr<EventPacket> evt_ptr =
- std::unique_ptr<EventPacket>(new EventPacket(HCI_BLE_EVENT));
-
- CHECK(evt_ptr->AddPayloadOctets1(HCI_BLE_ADV_PKT_RPT_EVT));
-
- CHECK(evt_ptr->AddPayloadOctets1(0)); // Start with an empty report
-
- return evt_ptr;
-}
-
-bool EventPacket::AddLeAdvertisingReport(uint8_t event_type, uint8_t addr_type,
- const BtAddress& addr,
- const vector<uint8_t>& data,
- uint8_t rssi) {
- if (!CanAddPayloadOctets(10 + data.size())) return false;
-
- CHECK(GetEventCode() == HCI_BLE_EVENT);
-
- CHECK(IncrementPayloadCounter(2)); // Increment the number of responses
-
- CHECK(AddPayloadOctets1(event_type));
- CHECK(AddPayloadOctets1(addr_type));
- CHECK(AddPayloadBtAddress(addr));
- CHECK(AddPayloadOctets1(data.size()));
- CHECK(AddPayloadOctets(data.size(), data));
- CHECK(AddPayloadOctets1(rssi));
- return true;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.7.65.4
-std::unique_ptr<EventPacket> EventPacket::CreateLeRemoteUsedFeaturesEvent(
- uint8_t status, uint16_t handle, uint64_t features) {
- std::unique_ptr<EventPacket> evt_ptr =
- std::unique_ptr<EventPacket>(new EventPacket(HCI_BLE_EVENT));
-
- CHECK(evt_ptr->AddPayloadOctets1(HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT));
-
- CHECK(evt_ptr->AddPayloadOctets1(status));
- CHECK(evt_ptr->AddPayloadOctets2(handle));
- CHECK(evt_ptr->AddPayloadOctets8(features));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.2
-std::unique_ptr<EventPacket> EventPacket::CreateCommandCompleteLeReadBufferSize(
- uint8_t status, uint16_t hc_le_data_packet_length,
- uint8_t hc_total_num_le_data_packets) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(
- HCI_BLE_READ_BUFFER_SIZE, status);
-
- CHECK(evt_ptr->AddPayloadOctets2(hc_le_data_packet_length));
- CHECK(evt_ptr->AddPayloadOctets1(hc_total_num_le_data_packets));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.3
-std::unique_ptr<EventPacket>
-EventPacket::CreateCommandCompleteLeReadLocalSupportedFeatures(
- uint8_t status, uint64_t le_features) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(
- HCI_BLE_READ_LOCAL_SPT_FEAT, status);
-
- CHECK(evt_ptr->AddPayloadOctets8(le_features));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.14
-std::unique_ptr<EventPacket>
-EventPacket::CreateCommandCompleteLeReadWhiteListSize(uint8_t status,
- uint8_t white_list_size) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(
- HCI_BLE_READ_WHITE_LIST_SIZE, status);
-
- CHECK(evt_ptr->AddPayloadOctets8(white_list_size));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.23
-std::unique_ptr<EventPacket> EventPacket::CreateCommandCompleteLeRand(
- uint8_t status, uint64_t random_val) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(HCI_BLE_RAND, status);
-
- CHECK(evt_ptr->AddPayloadOctets8(random_val));
-
- return evt_ptr;
-}
-
-// Bluetooth Core Specification Version 4.2, Volume 2, Part E, Section 7.8.27
-std::unique_ptr<EventPacket>
-EventPacket::CreateCommandCompleteLeReadSupportedStates(uint8_t status,
- uint64_t le_states) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(
- HCI_BLE_READ_SUPPORTED_STATES, status);
-
- CHECK(evt_ptr->AddPayloadOctets8(le_states));
-
- return evt_ptr;
-}
-
-// Vendor-specific commands (see hcidefs.h)
-
-std::unique_ptr<EventPacket> EventPacket::CreateCommandCompleteLeVendorCap(
- uint8_t status, const vector<uint8_t>& vendor_cap) {
- std::unique_ptr<EventPacket> evt_ptr =
- EventPacket::CreateCommandCompleteOnlyStatusEvent(HCI_BLE_VENDOR_CAP_OCF,
- status);
-
- CHECK(evt_ptr->AddPayloadOctets(vendor_cap.size(), vendor_cap));
-
- return evt_ptr;
-}
-
-} // namespace test_vendor_lib
+++ /dev/null
-#include "hci_packet.h"
-
-namespace test_vendor_lib {
-
-// Iterator Functions
-Iterator::Iterator(std::shared_ptr<HciPacket> packet, size_t i) {
- hci_packet_ = packet;
- index_ = i;
-}
-
-Iterator::Iterator(const Iterator& itr) { *this = itr; }
-
-Iterator::operator bool() const { return hci_packet_ != nullptr; }
-
-Iterator Iterator::operator+(size_t offset) {
- auto itr(*this);
-
- return itr += offset;
-}
-
-Iterator& Iterator::operator+=(size_t offset) {
- size_t new_offset = index_ + offset;
- index_ = new_offset >= hci_packet_->get_length() ? hci_packet_->get_length()
- : new_offset;
- return *this;
-}
-
-Iterator Iterator::operator++(int) {
- auto itr(*this);
- index_++;
-
- if (index_ >= hci_packet_->get_length()) index_ = hci_packet_->get_length();
-
- return itr;
-}
-
-Iterator& Iterator::operator++() {
- index_++;
-
- if (index_ >= hci_packet_->get_length()) index_ = hci_packet_->get_length();
-
- return *this;
-}
-
-Iterator Iterator::operator-(size_t offset) {
- auto itr(*this);
-
- return itr -= offset;
-}
-
-int Iterator::operator-(Iterator& itr) { return index_ - itr.index_; }
-
-Iterator& Iterator::operator-=(size_t offset) {
- index_ = offset > index_ ? 0 : index_ - offset;
-
- return *this;
-}
-
-Iterator Iterator::operator--(int) {
- auto itr(*this);
- if (index_ != 0) index_--;
-
- return itr;
-}
-
-Iterator& Iterator::operator--() {
- if (index_ != 0) index_--;
-
- return *this;
-}
-
-Iterator& Iterator::operator=(const Iterator& itr) {
- hci_packet_ = itr.hci_packet_;
- index_ = itr.index_;
-
- return *this;
-}
-
-bool Iterator::operator==(Iterator& itr) {
- return ((hci_packet_ == itr.hci_packet_) && (index_ == itr.index_));
-}
-
-bool Iterator::operator!=(Iterator& itr) { return !(*this == itr); }
-
-bool Iterator::operator<(Iterator& itr) {
- return ((hci_packet_ == itr.hci_packet_) && (index_ < itr.index_));
-}
-
-bool Iterator::operator>(Iterator& itr) {
- return ((hci_packet_ == itr.hci_packet_) && (index_ > itr.index_));
-}
-
-bool Iterator::operator<=(Iterator& itr) {
- return ((hci_packet_ == itr.hci_packet_) && (index_ <= itr.index_));
-}
-
-bool Iterator::operator>=(Iterator& itr) {
- return ((hci_packet_ == itr.hci_packet_) && (index_ >= itr.index_));
-}
-
-uint8_t& Iterator::operator*() const {
- CHECK(index_ != hci_packet_->get_length());
-
- return hci_packet_->get_at_index(index_);
-}
-
-uint8_t* Iterator::operator->() const {
- return &hci_packet_->get_at_index(index_);
-}
-
-// BtPacket Functions
-Iterator HciPacket::get_begin() {
- Iterator itr(shared_from_this(), 0);
-
- return itr;
-}
-
-Iterator HciPacket::get_end() {
- Iterator itr(shared_from_this(), get_length());
-
- return itr;
-}
-
-uint8_t HciPacket::operator[](size_t i) { return get_at_index(i); }
-}; // namespace test_vendor_lib
+++ /dev/null
-/*
- * Copyright 2016 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 "keyboard"
-
-#include "keyboard.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-Keyboard::Keyboard() {
- advertising_type_ = BTM_BLE_CONNECT_EVT;
- adv_data_ = {0x11, // Length
- BTM_BLE_AD_TYPE_NAME_CMPL,
- 'g',
- 'D',
- 'e',
- 'v',
- 'i',
- 'c',
- 'e',
- '-',
- 'k',
- 'e',
- 'y',
- 'b',
- 'o',
- 'a',
- 'r',
- 'd',
- 0x03, // Length
- 0x19,
- 0xC1,
- 0x03,
- 0x03, // Length
- 0x03,
- 0x12,
- 0x18,
- 0x02, // Length
- BTM_BLE_AD_TYPE_FLAG,
- BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG};
-
- scan_data_ = {0x04, // Length
- BTM_BLE_AD_TYPE_NAME_SHORT, 'k', 'e', 'y'};
-}
-
-std::string Keyboard::GetTypeString() const { return "keyboard"; }
-
-void Keyboard::Initialize(const vector<std::string>& args) {
- if (args.size() < 2) return;
-
- BtAddress addr;
- if (addr.FromString(args[1])) SetBtAddress(addr);
-
- if (args.size() < 3) return;
-
- SetAdvertisementInterval(std::chrono::milliseconds(std::stoi(args[2])));
-}
-
-bool Keyboard::LeConnect() { return true; }
-
-bool Keyboard::IsPageScanAvailable() const { return false; }
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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.
- */
-
-#define LOG_TAG "l2cap_packet"
-
-#include "l2cap_packet.h"
-
-#include <algorithm>
-
-#include "osi/include/log.h"
-
-namespace test_vendor_lib {
-
-const size_t kL2capHeaderLength = 4;
-const size_t kSduFirstHeaderLength = 8;
-const size_t kSduStandardHeaderLength = 6;
-const size_t kFcsBytes = 2;
-const uint16_t kSduTxSeqBits = 0x007E;
-const uint8_t kSduFirstReqseq = 0x40;
-const uint8_t kSduContinuationReqseq = 0xC0;
-const uint8_t kSduEndReqseq = 0x80;
-
-std::shared_ptr<L2capPacket> L2capPacket::assemble(
- const std::vector<std::shared_ptr<L2capSdu> >& sdu_packets) {
- std::shared_ptr<L2capPacket> built_l2cap_packet(new L2capPacket());
- uint16_t l2cap_payload_length = 0;
- uint16_t first_packet_channel_id = 0;
- uint16_t total_expected_l2cap_length;
- uint8_t txseq_start;
-
- if (sdu_packets.size() == 0) {
- LOG_DEBUG(LOG_TAG, "%s: No SDU received.", __func__);
- return nullptr;
- }
- if (sdu_packets.size() == 1 &&
- !L2capSdu::is_complete_l2cap(*sdu_packets[0])) {
- LOG_DEBUG(LOG_TAG, "%s: Unsegmented SDU has incorrect SAR bits.", __func__);
- return nullptr;
- }
-
- first_packet_channel_id = sdu_packets[0]->get_channel_id();
-
- built_l2cap_packet->l2cap_packet_.resize(kL2capHeaderLength);
-
- for (size_t i = 0; i < sdu_packets.size(); i++) {
- uint16_t payload_length = sdu_packets[i]->get_payload_length();
-
- // TODO(jruthe): Remove these checks when ACL packets have been
- // implemented. Once those are done, that will be the only way to create
- // L2capSdu objects and these checks will be moved there instead.
- //
- // Check the integrity of the packet length, if it is zero, it is invalid.
- // The maximum size of a single, segmented L2CAP payload is 1016 bytes.
- if ((payload_length <= 0) ||
- (payload_length != sdu_packets[i]->get_vector_size() - 4)) {
- LOG_DEBUG(LOG_TAG, "%s: SDU payload length incorrect.", __func__);
- return nullptr;
- }
-
- uint16_t fcs_check = sdu_packets[i]->get_fcs();
-
- if (sdu_packets[i]->calculate_fcs() != fcs_check) {
- LOG_DEBUG(LOG_TAG, "%s: SDU fcs is incorrect.", __func__);
- return nullptr;
- }
-
- uint16_t controls = sdu_packets[i]->get_controls();
-
- if (sdu_packets[i]->get_channel_id() != first_packet_channel_id) {
- LOG_DEBUG(LOG_TAG, "%s: SDU CID does not match expected.", __func__);
- return nullptr;
- }
-
- if (i == 0) txseq_start = controls & kSduTxSeqBits;
-
- // Bluetooth Specification version 4.2 volume 3 part A 3.3.2:
- // If there is only a single SDU, the first two bits of the control must be
- // set to 00b, representing an unsegmented SDU. If the SDU is segmented,
- // there is a begin and an end. The first segment must have the first two
- // control bits set to 01b and the ending segment must have them set to 10b.
- // Meanwhile all segments in between the start and end must have the bits
- // set to 11b.
- size_t starting_index;
- uint8_t txseq = controls & kSduTxSeqBits;
- if (sdu_packets.size() > 1 && i == 0 &&
- !L2capSdu::is_starting_sdu(*sdu_packets[i])) {
- LOG_DEBUG(LOG_TAG, "%s: First segmented SDU has incorrect SAR bits.",
- __func__);
- return nullptr;
- }
- if (i != 0 && L2capSdu::is_starting_sdu(*sdu_packets[i])) {
- LOG_DEBUG(LOG_TAG,
- "%s: SAR bits set to first segmented SDU on "
- "non-starting SDU.",
- __func__);
- return nullptr;
- }
- if (txseq != (txseq_start + (static_cast<uint8_t>(i) << 1))) {
- LOG_DEBUG(LOG_TAG, "%s: TxSeq incorrect.", __func__);
- return nullptr;
- }
- if (sdu_packets.size() > 1 && i == sdu_packets.size() - 1 &&
- !L2capSdu::is_ending_sdu(*sdu_packets[i])) {
- LOG_DEBUG(LOG_TAG, "%s: Final segmented SDU has incorrect SAR bits.",
- __func__);
- return nullptr;
- }
-
- // Subtract the control and fcs from every SDU payload length.
- l2cap_payload_length += (payload_length - 4);
-
- if (L2capSdu::is_starting_sdu(*sdu_packets[i])) {
- starting_index = kSduFirstHeaderLength;
- total_expected_l2cap_length = sdu_packets[i]->get_total_l2cap_length();
-
- // Subtract the additional two bytes from the first packet of a segmented
- // SDU.
- l2cap_payload_length -= 2;
- } else {
- starting_index = kSduStandardHeaderLength;
- }
-
- Iterator payload_begin = sdu_packets[i]->get_begin() + starting_index;
- Iterator payload_end = sdu_packets[i]->get_end() - kFcsBytes;
-
- built_l2cap_packet->l2cap_packet_.insert(
- built_l2cap_packet->l2cap_packet_.end(), payload_begin, payload_end);
- }
-
- if (l2cap_payload_length != total_expected_l2cap_length &&
- sdu_packets.size() > 1) {
- LOG_DEBUG(LOG_TAG, "%s: Total expected L2CAP payload length incorrect.",
- __func__);
- return nullptr;
- }
-
- built_l2cap_packet->l2cap_packet_[0] = l2cap_payload_length & 0xFF;
- built_l2cap_packet->l2cap_packet_[1] = (l2cap_payload_length & 0xFF00) >> 8;
- built_l2cap_packet->l2cap_packet_[2] = first_packet_channel_id & 0xFF;
- built_l2cap_packet->l2cap_packet_[3] =
- (first_packet_channel_id & 0xFF00) >> 8;
-
- return built_l2cap_packet;
-} // Assemble
-
-uint16_t L2capPacket::get_l2cap_cid() const {
- return ((l2cap_packet_[3] << 8) | l2cap_packet_[2]);
-}
-
-std::vector<std::shared_ptr<L2capSdu> > L2capPacket::fragment(
- uint16_t maximum_sdu_size, uint8_t txseq, uint8_t reqseq) {
- std::vector<std::shared_ptr<L2capSdu> > sdu;
- if (!check_l2cap_packet()) return sdu;
-
- std::vector<uint8_t> current_sdu;
-
- Iterator current_iter = get_begin() + kL2capHeaderLength;
- Iterator end_iter = get_end();
-
- size_t number_of_packets = ceil((l2cap_packet_.size() - kL2capHeaderLength) /
- static_cast<float>(maximum_sdu_size));
-
- if (number_of_packets == 0) {
- current_sdu.resize(kSduStandardHeaderLength);
-
- set_sdu_header_length(current_sdu, kL2capHeaderLength);
-
- set_sdu_cid(current_sdu, get_l2cap_cid());
-
- reqseq = (reqseq & 0xF0) >> 4;
- set_sdu_control_bytes(current_sdu, txseq, reqseq);
-
- sdu.push_back(L2capSdu::L2capSduBuilder(current_sdu));
-
- return sdu;
- }
-
- uint16_t header_length = 0x0000;
-
- if (number_of_packets == 1) {
- current_sdu.clear();
- current_sdu.resize(kSduStandardHeaderLength);
-
- header_length = ((l2cap_packet_[1] & 0xFF) << 8) | l2cap_packet_[0];
- header_length += kL2capHeaderLength;
- set_sdu_header_length(current_sdu, header_length);
-
- set_sdu_cid(current_sdu, get_l2cap_cid());
-
- set_sdu_control_bytes(current_sdu, txseq, 0x00);
-
- current_sdu.insert(current_sdu.end(), current_iter, end_iter);
-
- sdu.push_back(L2capSdu::L2capSduBuilder(current_sdu));
-
- return sdu;
- }
-
- Iterator next_iter =
- current_iter + (maximum_sdu_size - (kSduFirstHeaderLength + 2));
-
- sdu.reserve(number_of_packets);
- sdu.clear();
-
- for (size_t i = 0; i <= number_of_packets; i++) {
- if (i == 0) {
- current_sdu.resize(kSduFirstHeaderLength);
-
- header_length = maximum_sdu_size - kL2capHeaderLength;
-
- reqseq = reqseq | kSduFirstReqseq;
-
- set_total_sdu_length(current_sdu, l2cap_packet_.size() - 4);
- } else {
- current_sdu.resize(kSduStandardHeaderLength);
-
- header_length = (next_iter - current_iter) + kL2capHeaderLength;
-
- reqseq = reqseq & 0x0F;
-
- if (i < number_of_packets) {
- reqseq |= kSduContinuationReqseq;
- } else {
- reqseq |= kSduEndReqseq;
- }
- }
- set_sdu_header_length(current_sdu, header_length);
-
- set_sdu_cid(current_sdu, get_l2cap_cid());
-
- set_sdu_control_bytes(current_sdu, txseq, reqseq);
- txseq += 2;
-
- // Txseq has a maximum of 0x3F. If it exceeds that, it restarts at 0x00.
- if (txseq > 0x3F) txseq = 0x00;
-
- current_sdu.insert(current_sdu.end(), current_iter, next_iter);
- current_iter = next_iter;
-
- next_iter = current_iter + (maximum_sdu_size - kSduFirstHeaderLength);
-
- sdu.push_back(L2capSdu::L2capSduBuilder(std::move(current_sdu)));
- }
-
- return sdu;
-} // fragment
-
-void L2capPacket::set_sdu_header_length(std::vector<uint8_t>& sdu,
- uint16_t length) {
- sdu[0] = length & 0xFF;
- sdu[1] = (length & 0xFF00) >> 8;
-}
-
-void L2capPacket::set_total_sdu_length(std::vector<uint8_t>& sdu,
- uint16_t total_sdu_length) {
- sdu[6] = total_sdu_length & 0xFF;
- sdu[7] = (total_sdu_length & 0xFF00) >> 8;
-}
-
-void L2capPacket::set_sdu_cid(std::vector<uint8_t>& sdu, uint16_t cid) {
- sdu[2] = cid & 0xFF;
- sdu[3] = (cid & 0xFF00) >> 8;
-}
-
-void L2capPacket::set_sdu_control_bytes(std::vector<uint8_t>& sdu,
- uint8_t txseq, uint8_t reqseq) {
- sdu[4] = txseq;
- sdu[5] = reqseq;
-}
-
-bool L2capPacket::check_l2cap_packet() const {
- uint16_t payload_length = ((l2cap_packet_[1] & 0xFF) << 8) | l2cap_packet_[0];
-
- if (l2cap_packet_.size() < 4) return false;
- if (payload_length != (l2cap_packet_.size() - 4)) return false;
-
- return true;
-}
-
-// HciPacket Functions
-size_t L2capPacket::get_length() { return l2cap_packet_.size(); }
-
-uint8_t& L2capPacket::get_at_index(size_t index) {
- return l2cap_packet_[index];
-}
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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.
- */
-
-#include "l2cap_sdu.h"
-
-#include <base/logging.h>
-
-namespace test_vendor_lib {
-
-const uint16_t kSduSarBits = 0xe000;
-
-// Define the LFSR table of precalculated values defined by the
-// Bluetooth specification version 4.2 volume 3 part A section 3.3.5.
-const uint16_t L2capSdu::lfsr_table_[256] = {
- 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601,
- 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0,
- 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81,
- 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941,
- 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01,
- 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0,
- 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081,
- 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
- 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00,
- 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0,
- 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981,
- 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41,
- 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700,
- 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0,
- 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281,
- 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
- 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01,
- 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1,
- 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80,
- 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541,
- 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101,
- 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0,
- 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481,
- 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
- 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801,
- 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1,
- 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581,
- 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341,
- 0x4100, 0x81c1, 0x8081, 0x4040,
-}; // lfsr_table
-
-L2capSdu::L2capSdu(std::vector<uint8_t>&& create_from) {
- sdu_data_ = create_from;
-}
-
-std::shared_ptr<L2capSdu> L2capSdu::L2capSduConstructor(
- std::vector<uint8_t> create_from) {
- L2capSdu packet(std::move(create_from));
-
- return std::make_shared<L2capSdu>(packet);
-}
-
-std::shared_ptr<L2capSdu> L2capSdu::L2capSduBuilder(
- std::vector<uint8_t> create_from) {
- L2capSdu packet(std::move(create_from));
-
- packet.sdu_data_.resize(packet.sdu_data_.size() + 2, 0x00);
-
- uint16_t fcs = packet.calculate_fcs();
-
- packet.sdu_data_[packet.sdu_data_.size() - 2] = fcs & 0xFF;
- packet.sdu_data_[packet.sdu_data_.size() - 1] = (fcs & 0xFF00) >> 8;
-
- return std::make_shared<L2capSdu>(packet);
-}
-
-uint16_t L2capSdu::convert_from_little_endian(
- const unsigned int starting_index) const {
- uint16_t convert = sdu_data_[starting_index + 1];
- convert = convert << 8;
- convert = convert | sdu_data_[starting_index];
-
- return convert;
-}
-
-uint16_t L2capSdu::calculate_fcs() const {
- // Starting state as directed by Bluetooth specification version 4.2 volume 3
- // part A 3.3.5.
- uint16_t lfsr = 0x0000;
-
- for (size_t i = 0; i < sdu_data_.size() - 2; i++) {
- uint8_t current_byte = sdu_data_[i];
- lfsr = ((lfsr >> 8) & 0xff) ^ lfsr_table_[(lfsr & 0xff) ^ current_byte];
- }
- return lfsr;
-}
-
-uint16_t L2capSdu::get_payload_length() const {
- return convert_from_little_endian(0);
-}
-
-uint16_t L2capSdu::get_fcs() const {
- return convert_from_little_endian(sdu_data_.size() - 2);
-}
-
-uint16_t L2capSdu::get_controls() const {
- return convert_from_little_endian(4);
-}
-
-uint16_t L2capSdu::get_total_l2cap_length() const {
- return convert_from_little_endian(6);
-}
-
-uint16_t L2capSdu::get_channel_id() const {
- return convert_from_little_endian(2);
-}
-
-size_t L2capSdu::get_vector_size() const { return sdu_data_.size(); }
-
-bool L2capSdu::is_complete_l2cap(const L2capSdu& sdu) {
- uint16_t sar_bits = (sdu.get_controls() & kSduSarBits);
-
- return (sar_bits == 0x0000);
-}
-
-bool L2capSdu::is_starting_sdu(const L2capSdu& sdu) {
- uint16_t sar_bits = (sdu.get_controls() & kSduSarBits);
-
- return (sar_bits == 0x4000);
-}
-
-bool L2capSdu::is_ending_sdu(const L2capSdu& sdu) {
- uint16_t sar_bits = (sdu.get_controls() & kSduSarBits);
-
- return (sar_bits == 0x8000);
-}
-
-// HciPacket functions.
-size_t L2capSdu::get_length() { return sdu_data_.size(); }
-uint8_t& L2capSdu::get_at_index(size_t index) { return sdu_data_[index]; }
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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 "packet"
-
-#include "packet.h"
-
-#include <algorithm>
-
-#include <base/logging.h>
-#include "osi/include/log.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-
-Packet::Packet(serial_data_type_t type, vector<uint8_t> header)
- : type_(type), header_(std::move(header)) {
- payload_ = {0};
-}
-
-bool Packet::AddPayloadOctets(size_t octets, const vector<uint8_t>& bytes) {
- if (GetPayloadSize() + octets > kMaxPayloadOctets) return false;
-
- if (octets != bytes.size()) return false;
-
- payload_.insert(payload_.end(), bytes.begin(), bytes.end());
- payload_[0] = payload_.size() - 1;
-
- return true;
-}
-
-bool Packet::AddPayloadOctets(size_t octets, uint64_t value) {
- vector<uint8_t> val_vector;
-
- uint64_t v = value;
-
- if (octets > sizeof(uint64_t)) return false;
-
- for (size_t i = 0; i < octets; i++) {
- val_vector.push_back(v & 0xff);
- v = v >> 8;
- }
-
- if (v != 0) return false;
-
- return AddPayloadOctets(octets, val_vector);
-}
-
-bool Packet::AddPayloadBtAddress(const BtAddress& address) {
- if (GetPayloadSize() + BtAddress::kOctets > kMaxPayloadOctets) return false;
-
- address.ToVector(payload_);
-
- payload_[0] = payload_.size() - 1;
-
- return true;
-}
-
-bool Packet::IncrementPayloadCounter(size_t index) {
- if (payload_.size() < index - 1) return false;
-
- payload_[index]++;
- return true;
-}
-
-bool Packet::IncrementPayloadCounter(size_t index, uint8_t max_val) {
- if (payload_.size() < index - 1) return false;
-
- if (payload_[index] + 1 > max_val) return false;
-
- payload_[index]++;
- return true;
-}
-
-const vector<uint8_t>& Packet::GetHeader() const {
- // Every packet must have a header.
- CHECK(GetHeaderSize() > 0);
- return header_;
-}
-
-uint8_t Packet::GetHeaderSize() const { return header_.size(); }
-
-size_t Packet::GetPacketSize() const {
- // Add one for the type octet.
- return 1 + header_.size() + payload_.size();
-}
-
-const vector<uint8_t>& Packet::GetPayload() const { return payload_; }
-
-size_t Packet::GetPayloadSize() const { return payload_.size(); }
-
-serial_data_type_t Packet::GetType() const { return type_; }
-
-} // namespace test_vendor_lib
+++ /dev/null
-//
-// 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 "packet_stream"
-
-#include "packet_stream.h"
-
-#include <base/logging.h>
-
-#include <errno.h>
-#include <unistd.h>
-
-#include "osi/include/log.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-
-std::unique_ptr<CommandPacket> PacketStream::ReceiveCommand(int fd) const {
- vector<uint8_t> header;
- vector<uint8_t> params_size;
- vector<uint8_t> payload;
-
- if (!ReceiveAll(header, CommandPacket::kCommandHeaderSize, fd)) {
- LOG_ERROR(LOG_TAG, "Error: receiving command header.");
- return std::unique_ptr<CommandPacket>(nullptr);
- }
-
- if (!ReceiveAll(params_size, 1, fd)) {
- LOG_ERROR(LOG_TAG, "Error: receiving params size.");
- return std::unique_ptr<CommandPacket>(nullptr);
- }
-
- if (!ReceiveAll(payload, params_size[0], fd)) {
- LOG_ERROR(LOG_TAG, "Error: receiving command payload.");
- return std::unique_ptr<CommandPacket>(nullptr);
- }
- return std::unique_ptr<CommandPacket>(new CommandPacket(header, payload));
-}
-
-serial_data_type_t PacketStream::ReceivePacketType(int fd) const {
- vector<uint8_t> raw_type_octet;
-
- if (!ReceiveAll(raw_type_octet, 1, fd)) {
- // TODO(dennischeng): Proper error handling.
- LOG_ERROR(LOG_TAG, "Error: Could not receive packet type.");
- }
-
- // Check that the type octet received is in the valid range, i.e. the packet
- // must be a command or data packet.
- const serial_data_type_t type =
- static_cast<serial_data_type_t>(raw_type_octet[0]);
- if (!ValidateTypeOctet(type)) {
- // TODO(dennischeng): Proper error handling.
- LOG_ERROR(LOG_TAG, "Error: Received invalid packet type.");
- }
- return type;
-}
-
-bool PacketStream::SendEvent(std::unique_ptr<EventPacket> event, int fd) const {
- if (event->GetPayload()[0] != event->GetPayloadSize() - 1)
- LOG_WARN(LOG_TAG, "Malformed event: 0x%04X, payload size %zu, reported %u",
- event->GetEventCode(), event->GetPacketSize(),
- event->GetPayload()[0]);
-
- if (!SendAll({static_cast<uint8_t>(event->GetType())}, 1, fd)) {
- LOG_ERROR(LOG_TAG, "Error: Could not send event type.");
- return false;
- }
-
- if (!SendAll(event->GetHeader(), event->GetHeaderSize(), fd)) {
- LOG_ERROR(LOG_TAG, "Error: Could not send event header.");
- return false;
- }
-
- if (!SendAll(event->GetPayload(), event->GetPayloadSize(), fd)) {
- LOG_ERROR(LOG_TAG, "Error: Could not send event payload.");
- return false;
- }
- return true;
-}
-
-bool PacketStream::ValidateTypeOctet(serial_data_type_t type) const {
- // The only types of packets that should be received from the HCI are command
- // packets and data packets.
- return (type >= DATA_TYPE_COMMAND) && (type <= DATA_TYPE_SCO);
-}
-
-bool PacketStream::ReceiveAll(vector<uint8_t>& destination,
- size_t num_octets_to_receive, int fd) const {
- destination.resize(num_octets_to_receive);
- size_t octets_remaining = num_octets_to_receive;
- while (octets_remaining > 0) {
- const int num_octets_received =
- read(fd, &destination[num_octets_to_receive - octets_remaining],
- octets_remaining);
- if (num_octets_received < 0) return false;
- octets_remaining -= num_octets_received;
- }
- return true;
-}
-
-bool PacketStream::SendAll(const vector<uint8_t>& source,
- size_t num_octets_to_send, int fd) const {
- CHECK(source.size() >= num_octets_to_send);
- size_t octets_remaining = num_octets_to_send;
- while (octets_remaining > 0) {
- const int num_octets_sent = write(
- fd, &source[num_octets_to_send - octets_remaining], octets_remaining);
- if (num_octets_sent < 0) return false;
- octets_remaining -= num_octets_sent;
- }
- return true;
-}
-
-} // namespace test_vendor_lib
+++ /dev/null
-/*
- * 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.
- */
-
-#define LOG_TAG "sco_packet"
-
-#include "sco_packet.h"
-
-#include "stack/include/hcidefs.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-
-ScoPacket::ScoPacket(uint16_t channel,
- ScoPacket::PacketStatusFlags packet_status)
- : Packet(DATA_TYPE_SCO,
- {static_cast<uint8_t>(channel & 0xff),
- static_cast<uint8_t>(((channel >> 8) & 0x0f) |
- (packet_status & 0x3 << 4))}) {}
-
-uint16_t ScoPacket::GetChannel() const {
- return (GetHeader()[0] | (GetHeader()[1] << 8)) & 0xfff;
-}
-
-ScoPacket::PacketStatusFlags ScoPacket::GetPacketStatusFlags() const {
- return static_cast<ScoPacket::PacketStatusFlags>((GetHeader()[1] >> 4) & 0x3);
-}
-
-} // namespace test_vendor_lib
* limitations under the License.
*/
-#include "async_manager.h"
+#include "model/setup/async_manager.h"
#include <gtest/gtest.h>
#include <cstdint>
#include <cstring>
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(kPort);
int reuse_flag = 1;
- EXPECT_FALSE(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag,
- sizeof(reuse_flag)) < 0);
+ EXPECT_FALSE(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag, sizeof(reuse_flag)) < 0);
EXPECT_FALSE(bind(fd, (sockaddr*)&serv_addr, sizeof(serv_addr)) < 0);
listen(fd, 1);
async_manager_.WatchFdForNonBlockingReads(socket_fd_, [this](int fd) {
int connection_fd = AcceptConnection(fd);
- async_manager_.WatchFdForNonBlockingReads(
- connection_fd, [this](int fd) { ReadIncomingMessage(fd); });
+ async_manager_.WatchFdForNonBlockingReads(connection_fd, [this](int fd) { ReadIncomingMessage(fd); });
});
}
serv_addr.sin_addr.s_addr = *(reinterpret_cast<in_addr_t*>(server->h_addr));
serv_addr.sin_port = htons(kPort);
- int result =
- connect(socket_cli_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
+ int result = connect(socket_cli_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
EXPECT_FALSE(result < 0);
return socket_cli_fd;
+++ /dev/null
-/******************************************************************************
- *
- * Copyright 2016 Google, Inc.
- *
- * 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 <gtest/gtest.h>
-#include <string>
-#include <vector>
-using std::vector;
-
-#include "bt_address.h"
-
-namespace {
-const std::string kTestAddr1 = "12:34:56:78:9a:bc";
-const std::string kTestAddr2 = "cb:a9:87:65:43:21";
-const std::string kTestAddr3 = "cb:a9:56:78:9a:bc";
-const std::string kUpperMask = "ff:ff:00:00:00:00";
-const std::string kLowerMask = "00:00:ff:ff:ff:ff";
-const std::string kZeros = "00:00:00:00:00:00";
-const vector<uint8_t> kZeros_octets = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-const vector<uint8_t> kTestAddr1_octets = {0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12};
-} // namespace
-
-namespace test_vendor_lib {
-
-class BtAddressTest : public ::testing::Test {
- public:
- BtAddressTest() {}
- ~BtAddressTest() {}
-};
-
-TEST_F(BtAddressTest, IsValid) {
- EXPECT_FALSE(BtAddress::IsValid(""));
- EXPECT_FALSE(BtAddress::IsValid("000000000000"));
- EXPECT_FALSE(BtAddress::IsValid("00:00:00:00:0000"));
- EXPECT_FALSE(BtAddress::IsValid("00:00:00:00:00:0"));
- EXPECT_FALSE(BtAddress::IsValid("00:00:00:00:00:0;"));
- EXPECT_FALSE(BtAddress::IsValid("00:00:000:00:00:0;"));
- EXPECT_TRUE(BtAddress::IsValid("00:00:00:00:00:00"));
- EXPECT_FALSE(BtAddress::IsValid("aB:cD:eF:Gh:iJ:Kl"));
- EXPECT_TRUE(BtAddress::IsValid(kTestAddr1));
- EXPECT_TRUE(BtAddress::IsValid(kTestAddr2));
- EXPECT_TRUE(BtAddress::IsValid(kTestAddr3));
-}
-
-TEST_F(BtAddressTest, test_comparisons) {
- BtAddress btaddr1;
- BtAddress btaddr1_copy;
- BtAddress btaddr2;
-
- EXPECT_TRUE(btaddr1.FromString(kTestAddr1));
- EXPECT_TRUE(btaddr1_copy.FromString(kTestAddr1));
- EXPECT_TRUE(btaddr2.FromString(kTestAddr2));
-
- EXPECT_TRUE(btaddr1 == btaddr1_copy);
- EXPECT_FALSE(btaddr1 == btaddr2);
-
- EXPECT_FALSE(btaddr1 != btaddr1_copy);
- EXPECT_TRUE(btaddr1 != btaddr2);
-
- EXPECT_FALSE(btaddr1 < btaddr1_copy);
- EXPECT_TRUE(btaddr1 < btaddr2);
- EXPECT_FALSE(btaddr2 < btaddr1);
-
- EXPECT_FALSE(btaddr1 > btaddr1_copy);
- EXPECT_FALSE(btaddr1 > btaddr2);
- EXPECT_TRUE(btaddr2 > btaddr1);
-
- EXPECT_TRUE(btaddr1 <= btaddr1_copy);
- EXPECT_TRUE(btaddr1 <= btaddr2);
- EXPECT_FALSE(btaddr2 <= btaddr1);
-
- EXPECT_TRUE(btaddr1 >= btaddr1_copy);
- EXPECT_FALSE(btaddr1 >= btaddr2);
- EXPECT_TRUE(btaddr2 >= btaddr1);
-}
-
-TEST_F(BtAddressTest, test_assignment) {
- BtAddress btaddr1;
- BtAddress btaddr2;
- BtAddress btaddr3;
-
- EXPECT_TRUE(btaddr1.FromString(kTestAddr1));
- EXPECT_TRUE(btaddr2.FromString(kTestAddr2));
- EXPECT_TRUE(btaddr3.FromString(kTestAddr3));
-
- EXPECT_TRUE(btaddr1 != btaddr2);
- EXPECT_TRUE(btaddr2 != btaddr3);
- EXPECT_TRUE(btaddr1 != btaddr3);
-
- btaddr1 = btaddr2;
- EXPECT_TRUE(btaddr1 == btaddr2);
- EXPECT_TRUE(btaddr2 != btaddr3);
- EXPECT_TRUE(btaddr1 != btaddr3);
-
- btaddr3 = btaddr2;
- EXPECT_TRUE(btaddr1 == btaddr2);
- EXPECT_TRUE(btaddr2 == btaddr3);
- EXPECT_TRUE(btaddr1 == btaddr3);
-}
-
-TEST_F(BtAddressTest, test_bitoperations) {
- BtAddress btaddr1;
- BtAddress btaddr2;
- BtAddress btaddr3;
- BtAddress btaddr_lowmask;
- BtAddress btaddr_upmask;
-
- EXPECT_TRUE(btaddr1.FromString(kTestAddr1));
- EXPECT_TRUE(btaddr2.FromString(kTestAddr2));
- EXPECT_TRUE(btaddr3.FromString(kTestAddr3));
- EXPECT_TRUE(btaddr_lowmask.FromString(kLowerMask));
- EXPECT_TRUE(btaddr_upmask.FromString(kUpperMask));
-
- EXPECT_TRUE(btaddr1 != btaddr2);
- EXPECT_TRUE(btaddr2 != btaddr3);
- btaddr1 &= btaddr_lowmask;
- btaddr2 &= btaddr_upmask;
- btaddr1 |= btaddr2;
- EXPECT_TRUE(btaddr1 == btaddr3);
-}
-
-TEST_F(BtAddressTest, FromString) {
- BtAddress btaddrA;
- BtAddress btaddrB;
- BtAddress btaddrC;
- EXPECT_TRUE(btaddrA.FromString(kTestAddr1));
- EXPECT_TRUE(btaddrA != btaddrB);
- EXPECT_TRUE(btaddrC == btaddrB);
- EXPECT_TRUE(btaddrB.FromString(kTestAddr1));
- EXPECT_TRUE(btaddrC.FromString(kTestAddr1));
- EXPECT_TRUE(btaddrA == btaddrB);
- EXPECT_TRUE(btaddrC == btaddrB);
-}
-
-TEST_F(BtAddressTest, FromVector) {
- BtAddress btaddr1;
- EXPECT_TRUE(btaddr1.FromString(kTestAddr1));
- BtAddress btaddrA;
- BtAddress btaddrB;
- EXPECT_TRUE(btaddrA.FromVector(kTestAddr1_octets));
- EXPECT_TRUE(btaddrA != btaddrB);
- EXPECT_TRUE(btaddrB.FromVector(kTestAddr1_octets));
- EXPECT_TRUE(btaddrA == btaddrB);
- EXPECT_TRUE(btaddr1 == btaddrB);
-}
-
-TEST_F(BtAddressTest, ToVector) {
- BtAddress btaddr1;
- BtAddress btaddr1_copy;
- BtAddress btaddr2;
- vector<uint8_t> octets1;
- vector<uint8_t> octets1_copy;
- vector<uint8_t> octets2;
- EXPECT_TRUE(btaddr1.FromString(kTestAddr1));
- EXPECT_TRUE(btaddr1_copy.FromString(kTestAddr1));
- EXPECT_TRUE(btaddr2.FromString(kTestAddr2));
- EXPECT_TRUE(btaddr1 == btaddr1_copy);
- EXPECT_TRUE(btaddr1 != btaddr2);
- btaddr1.ToVector(octets1);
- btaddr2.ToVector(octets2);
- btaddr1_copy.ToVector(octets1_copy);
- EXPECT_TRUE(octets1 != octets2);
- EXPECT_TRUE(octets1 == octets1_copy);
- EXPECT_TRUE(octets1.size() == BtAddress::kOctets);
- btaddr1.ToVector(octets1);
- EXPECT_TRUE(octets1.size() == (2 * BtAddress::kOctets));
-}
-
-TEST_F(BtAddressTest, ToString) {
- BtAddress btaddr_zeros;
- BtAddress btaddr1;
- EXPECT_TRUE(btaddr_zeros.FromString(kZeros));
- EXPECT_TRUE(btaddr1.FromString(kTestAddr1));
- EXPECT_TRUE(btaddr_zeros.ToString() == kZeros);
- EXPECT_TRUE(btaddr1.ToString() == kTestAddr1);
- EXPECT_TRUE(btaddr_zeros.ToString() != kTestAddr1);
- EXPECT_TRUE(btaddr1.ToString() != kZeros);
-}
-
-} // namespace test_vendor_lib
static std::shared_ptr<TestPacket> make_new_packet(vector<uint8_t> v) {
return std::shared_ptr<TestPacket>(new TestPacket(v));
}
- size_t get_length() { return test_vector_.size(); }
- uint8_t& get_at_index(size_t index) { return test_vector_[index]; }
+ size_t get_length() {
+ return test_vector_.size();
+ }
+ uint8_t& get_at_index(size_t index) {
+ return test_vector_[index];
+ }
private:
- TestPacket(vector<uint8_t> v) { test_vector_ = v; }
+ TestPacket(vector<uint8_t> v) {
+ test_vector_ = v;
+ }
vector<uint8_t> test_vector_;
};
IteratorTest() = default;
~IteratorTest() = default;
- void SetUp() { packet = TestPacket::make_new_packet(complete_l2cap_packet); }
+ void SetUp() {
+ packet = TestPacket::make_new_packet(complete_l2cap_packet);
+ }
- void TearDown() { packet.reset(); }
+ void TearDown() {
+ packet.reset();
+ }
std::shared_ptr<TestPacket> packet;
};
Iterator plus_eq = packet->get_begin();
for (size_t i = 0; i < complete_l2cap_packet.size(); i += 2) {
ASSERT_EQ(complete_l2cap_packet[i], *plus_eq)
- << "+= test: Dereferenced iterator does not equal expected at index "
- << i;
+ << "+= test: Dereferenced iterator does not equal expected at index " << i;
plus_eq += 2;
}
}
Iterator plus = packet->get_begin();
for (size_t i = 0; i < complete_l2cap_packet.size(); i++) {
ASSERT_EQ(complete_l2cap_packet[i], *plus)
- << "+ test: Dereferenced iterator does not equal expected at index "
- << i;
+ << "+ test: Dereferenced iterator does not equal expected at index " << i;
plus = plus + static_cast<size_t>(1);
}
}
minus_eq -= 1;
for (size_t i = complete_l2cap_packet.size() - 1; i > 0; i -= 2) {
ASSERT_EQ(complete_l2cap_packet[i], *minus_eq)
- << "-= test: Dereferenced iterator does not equal expected at index "
- << i;
+ << "-= test: Dereferenced iterator does not equal expected at index " << i;
minus_eq -= 2;
}
}
minus = minus - static_cast<size_t>(1);
for (size_t i = complete_l2cap_packet.size() - 1; i > 0; i--) {
ASSERT_EQ(complete_l2cap_packet[i], *minus)
- << "- test: Dereferenced iterator does not equal expected at index "
- << i;
+ << "- test: Dereferenced iterator does not equal expected at index " << i;
minus = minus - static_cast<size_t>(1);
}
}
plus_eq--;
for (size_t i = 0; i < 100; i++) {
plus_eq += i;
- ASSERT_EQ(packet->get_end(), plus_eq)
- << "+= test: Iterator exceeded the upper bound set by get_length()";
+ ASSERT_EQ(packet->get_end(), plus_eq) << "+= test: Iterator exceeded the upper bound set by get_length()";
}
}
Iterator plus_plus = packet->get_end();
plus_plus--;
for (size_t i = 0; i < 100; i++) {
- ASSERT_EQ(packet->get_end(), ++plus_plus)
- << "Pre-increment test: Iterator exceeded the upper bound set "
- "by get_length()";
+ ASSERT_EQ(packet->get_end(), ++plus_plus) << "Pre-increment test: Iterator exceeded the upper bound set "
+ "by get_length()";
}
}
Iterator plus_plus = packet->get_end();
plus_plus--;
for (size_t i = 0; i < 100; i++) {
- ASSERT_EQ(packet->get_end(), plus_plus++)
- << "Post-increment test: Iterator exceeded the upper bound set "
- "by get_length()";
+ ASSERT_EQ(packet->get_end(), plus_plus++) << "Post-increment test: Iterator exceeded the upper bound set "
+ "by get_length()";
}
}
plus--;
for (size_t i = 0; i < 100; i++) {
plus = plus + static_cast<size_t>(i);
- ASSERT_EQ(packet->get_end(), plus)
- << "+ test: Iterator exceeded the upper bound set by get_length()";
+ ASSERT_EQ(packet->get_end(), plus) << "+ test: Iterator exceeded the upper bound set by get_length()";
}
}
Iterator minus_eq = packet->get_begin();
for (size_t i = 0; i < 100; i++) {
minus_eq -= i;
- ASSERT_EQ(complete_l2cap_packet[0], *minus_eq)
- << "-= test: Iterator is less than the lower bound set by "
- "packet->get_begin()";
+ ASSERT_EQ(complete_l2cap_packet[0], *minus_eq) << "-= test: Iterator is less than the lower bound set by "
+ "packet->get_begin()";
}
}
Iterator minus = packet->get_begin();
for (size_t i = 0; i < 100; i++) {
minus = minus - static_cast<size_t>(i);
- ASSERT_EQ(complete_l2cap_packet[0], *minus)
- << "- test: Iterator is less than the lower bound set "
- "by packet->get_begin()";
+ ASSERT_EQ(complete_l2cap_packet[0], *minus) << "- test: Iterator is less than the lower bound set "
+ "by packet->get_begin()";
}
}
}; // namespace test_vendor_lib
namespace test_vendor_lib {
-std::shared_ptr<L2capSdu> packet_1 =
- L2capSdu::L2capSduConstructor(l2cap_test_packet_1);
-std::shared_ptr<L2capSdu> packet_2 =
- L2capSdu::L2capSduConstructor(l2cap_test_packet_2);
-std::shared_ptr<L2capSdu> packet_3 =
- L2capSdu::L2capSduConstructor(l2cap_test_packet_3);
-std::shared_ptr<L2capSdu> packet_4 =
- L2capSdu::L2capSduConstructor(l2cap_test_packet_4);
-std::shared_ptr<L2capSdu> packet_5 =
- L2capSdu::L2capSduConstructor(l2cap_test_packet_5);
-std::shared_ptr<L2capSdu> packet_6 =
- L2capSdu::L2capSduConstructor(l2cap_test_packet_6);
-std::shared_ptr<L2capSdu> packet_7 =
- L2capSdu::L2capSduConstructor(l2cap_test_packet_7);
-std::shared_ptr<L2capSdu> packet_8 =
- L2capSdu::L2capSduConstructor(l2cap_test_packet_8);
-std::shared_ptr<L2capSdu> packet_9 =
- L2capSdu::L2capSduConstructor(l2cap_test_packet_9);
+std::shared_ptr<L2capSdu> packet_1 = L2capSdu::L2capSduConstructor(l2cap_test_packet_1);
+std::shared_ptr<L2capSdu> packet_2 = L2capSdu::L2capSduConstructor(l2cap_test_packet_2);
+std::shared_ptr<L2capSdu> packet_3 = L2capSdu::L2capSduConstructor(l2cap_test_packet_3);
+std::shared_ptr<L2capSdu> packet_4 = L2capSdu::L2capSduConstructor(l2cap_test_packet_4);
+std::shared_ptr<L2capSdu> packet_5 = L2capSdu::L2capSduConstructor(l2cap_test_packet_5);
+std::shared_ptr<L2capSdu> packet_6 = L2capSdu::L2capSduConstructor(l2cap_test_packet_6);
+std::shared_ptr<L2capSdu> packet_7 = L2capSdu::L2capSduConstructor(l2cap_test_packet_7);
+std::shared_ptr<L2capSdu> packet_8 = L2capSdu::L2capSduConstructor(l2cap_test_packet_8);
+std::shared_ptr<L2capSdu> packet_9 = L2capSdu::L2capSduConstructor(l2cap_test_packet_9);
class L2capSduTest : public ::testing::Test {
public:
class TestPacket : public HciPacket {
public:
- TestPacket(const std::vector<uint8_t>& packet) { complete_packet_ = packet; }
+ TestPacket(const std::vector<uint8_t>& packet) {
+ complete_packet_ = packet;
+ }
TestPacket() = default;
private:
std::vector<uint8_t> complete_packet_;
- size_t get_length() { return complete_packet_.size(); }
- uint8_t& get_at_index(size_t index) { return complete_packet_[index]; }
+ size_t get_length() {
+ return complete_packet_.size();
+ }
+ uint8_t& get_at_index(size_t index) {
+ return complete_packet_[index];
+ }
};
class L2capTest : public ::testing::Test {
return L2capSdu::L2capSduBuilder(sdu);
}
- void compare_packets(shared_ptr<HciPacket> expected,
- shared_ptr<HciPacket> received) {
+ void compare_packets(shared_ptr<HciPacket> expected, shared_ptr<HciPacket> received) {
Iterator expected_begin = expected->get_begin();
Iterator expected_end = expected->get_end();
sdu = l2cap_expected->fragment(16, 0x02, 0x41);
l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr)
- << "packet reassembly failed after fragment" << std::endl
- << "Test1: Small Segment request" << std::endl
- << "sdu used: good_sdu" << std::endl
- << "function call: fragment(16, 0x02, 0x41)" << std::endl;
+ ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
+ << "Test1: Small Segment request" << std::endl
+ << "sdu used: good_sdu" << std::endl
+ << "function call: fragment(16, 0x02, 0x41)" << std::endl;
compare_packets(l2cap_expected, l2cap_received);
sdu = l2cap_expected->fragment(1024, 0x02, 0x41);
l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr)
- << "packet reassembly failed after fragment" << std::endl
- << "Test2: Large Segment request" << std::endl
- << "sdu used: l2cap_test_packet[1-9]" << std::endl
- << "function call: fragment(1024, 0x02, 0x41)" << std::endl;
+ ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
+ << "Test2: Large Segment request" << std::endl
+ << "sdu used: l2cap_test_packet[1-9]" << std::endl
+ << "function call: fragment(1024, 0x02, 0x41)" << std::endl;
compare_packets(l2cap_expected, l2cap_received);
sdu = l2cap_expected->fragment(24, 0x08, 0x41);
l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr)
- << "packet reassembly failed after fragment" << std::endl
- << "Test3: Non-zero starting TxSeq" << std::endl
- << "sdu used: good_sdu" << std::endl
- << "function call: fragment(24, 0x08, 0x41)" << std::endl;
+ ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
+ << "Test3: Non-zero starting TxSeq" << std::endl
+ << "sdu used: good_sdu" << std::endl
+ << "function call: fragment(24, 0x08, 0x41)" << std::endl;
compare_packets(l2cap_expected, l2cap_received);
sdu = l2cap_expected->fragment(16, 0x02, 0x41);
l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr)
- << "packet reassembly failed after fragment" << std::endl
- << "Test4: Packet with no payload" << std::endl
- << "sdu used: empty_sdu_payload" << std::endl
- << "function call: fragment(16, 0x02, 0x41)" << std::endl;
+ ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
+ << "Test4: Packet with no payload" << std::endl
+ << "sdu used: empty_sdu_payload" << std::endl
+ << "function call: fragment(16, 0x02, 0x41)" << std::endl;
compare_packets(l2cap_expected, l2cap_received);
sdu = l2cap_expected->fragment(256, 0x02, 0x41);
l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr)
- << "packet reassembly failed after fragment" << std::endl
- << "Test5: Segment size > Payload" << std::endl
- << "sdu used: good_sdu" << std::endl
- << "function call: fragment(256, 0x02, 0x41)" << std::endl;
+ ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
+ << "Test5: Segment size > Payload" << std::endl
+ << "sdu used: good_sdu" << std::endl
+ << "function call: fragment(256, 0x02, 0x41)" << std::endl;
compare_packets(l2cap_expected, l2cap_received);
sdu = l2cap_expected->fragment(512, 0x02, 0x41);
l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr)
- << "packet reassembly failed after fragment" << std::endl
- << "Test6: Small Segment request on large packet" << std::endl
- << "sdu used: l2cap_test_packet_[1-9]" << std::endl
- << "function call: fragment(64, 0x02, 0x41)" << std::endl;
+ ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
+ << "Test6: Small Segment request on large packet" << std::endl
+ << "sdu used: l2cap_test_packet_[1-9]" << std::endl
+ << "function call: fragment(64, 0x02, 0x41)" << std::endl;
compare_packets(l2cap_expected, l2cap_received);
--- /dev/null
+/*
+ * Copyright 2016 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 "model/devices/link_layer_socket_device.h"
+
+#include <gtest/gtest.h>
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "include/link.h"
+#include "model/setup/async_manager.h"
+#include "packets/link_layer/command_view.h"
+#include "packets/link_layer/link_layer_packet_builder.h"
+#include "packets/link_layer/link_layer_packet_view.h"
+
+std::vector<uint8_t> count = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+};
+
+using test_vendor_lib::packets::CommandBuilder;
+using test_vendor_lib::packets::CommandView;
+using test_vendor_lib::packets::LinkLayerPacketBuilder;
+using test_vendor_lib::packets::LinkLayerPacketView;
+using test_vendor_lib::packets::PacketView;
+using test_vendor_lib::packets::View;
+
+static const size_t kMaxConnections = 300;
+
+namespace test_vendor_lib {
+
+class LinkLayerSocketDeviceTest : public ::testing::Test {
+ public:
+ static const uint16_t kPort = 6123;
+
+ protected:
+ class MockPhyLayer : public PhyLayer {
+ public:
+ MockPhyLayer(const std::function<void(std::shared_ptr<LinkLayerPacketBuilder>)>& on_receive)
+ : PhyLayer(Phy::Type::LOW_ENERGY, 0, [](LinkLayerPacketView) {}), on_receive_(on_receive) {}
+ virtual void Send(const std::shared_ptr<LinkLayerPacketBuilder> packet) override {
+ on_receive_(packet);
+ }
+ virtual void Receive(LinkLayerPacketView) override {}
+ virtual void TimerTick() override {}
+
+ private:
+ std::function<void(std::shared_ptr<LinkLayerPacketBuilder>)> on_receive_;
+ };
+
+ int StartServer() {
+ struct sockaddr_in serv_addr;
+ int fd = socket(AF_INET, SOCK_STREAM, 0);
+ EXPECT_FALSE(fd < 0);
+
+ memset(&serv_addr, 0, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = INADDR_ANY;
+ serv_addr.sin_port = htons(kPort);
+ int reuse_flag = 1;
+ EXPECT_FALSE(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag, sizeof(reuse_flag)) < 0);
+ EXPECT_FALSE(bind(fd, (sockaddr*)&serv_addr, sizeof(serv_addr)) < 0);
+
+ listen(fd, 1);
+ return fd;
+ }
+
+ int AcceptConnection(int fd) {
+ return accept(fd, NULL, NULL);
+ }
+
+ void ValidatePacket(size_t index, bool at_server, std::shared_ptr<LinkLayerPacketBuilder> received) {
+ /* Convert the Builder into a View */
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ received->Serialize(it);
+ LinkLayerPacketView received_view = LinkLayerPacketView::Create(packet_ptr);
+
+ /* Validate received packet */
+ ASSERT_EQ(received_view.GetSourceAddress(), source_);
+ ASSERT_EQ(received_view.GetDestinationAddress(), dest_);
+ ASSERT_EQ(Link::PacketType::COMMAND, received_view.GetType());
+ CommandView command_view = CommandView::GetCommand(received_view);
+ if (at_server) {
+ ASSERT_EQ(client_opcodes_[index], command_view.GetOpcode());
+ } else {
+ ASSERT_EQ(server_opcodes_[index], command_view.GetOpcode());
+ }
+ auto args_itr = command_view.GetData();
+ ASSERT_EQ(args_itr.NumBytesRemaining(), count.size());
+ for (size_t i = 0; i < count.size(); i++) {
+ ASSERT_EQ(*args_itr++, count[i]);
+ }
+ if (at_server) {
+ validated_client_packets_[index]++;
+ } else {
+ validated_server_packets_[index]++;
+ }
+ }
+
+ void SetUp() override {
+ servers_.reserve(kMaxConnections);
+ clients_.reserve(kMaxConnections);
+ socket_fd_ = StartServer();
+
+ async_manager_.WatchFdForNonBlockingReads(socket_fd_, [this](int fd) {
+ int connection_fd = AcceptConnection(fd);
+ ASSERT_GE(connection_fd, 0);
+ size_t index = servers_.size();
+ servers_.emplace_back(connection_fd, Phy::Type::LOW_ENERGY);
+ ASSERT_EQ(servers_.size() - 1, index) << "Race condition";
+ std::shared_ptr<MockPhyLayer> mock_phy = std::make_shared<MockPhyLayer>(
+ [this, index](std::shared_ptr<LinkLayerPacketBuilder> received) { ValidatePacket(index, true, received); });
+ servers_[index].RegisterPhyLayer(mock_phy);
+ });
+ }
+
+ void TearDown() override {
+ async_manager_.StopWatchingFileDescriptor(socket_fd_);
+ close(socket_fd_);
+ }
+
+ int ConnectClient() {
+ int socket_cli_fd = socket(AF_INET, SOCK_STREAM, 0);
+ EXPECT_FALSE(socket_cli_fd < 0);
+
+ struct hostent* server;
+ server = gethostbyname("localhost");
+ EXPECT_FALSE(server == NULL);
+
+ struct sockaddr_in serv_addr;
+ memset((void*)&serv_addr, 0, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = INADDR_ANY;
+ serv_addr.sin_port = htons(kPort);
+
+ int result = connect(socket_cli_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
+ EXPECT_FALSE(result < 0);
+
+ EXPECT_GE(socket_cli_fd, 0);
+
+ return socket_cli_fd;
+ }
+
+ void ValidateConnection(size_t pair_id) {
+ ASSERT_GT(clients_.size(), pair_id);
+ ASSERT_GT(servers_.size(), pair_id);
+ }
+
+ size_t CreateConnection() {
+ int fd = ConnectClient();
+ size_t index = clients_.size();
+ clients_.emplace_back(fd, Phy::Type::LOW_ENERGY);
+ std::shared_ptr<MockPhyLayer> mock_phy = std::make_shared<MockPhyLayer>(
+ [this, index](std::shared_ptr<LinkLayerPacketBuilder> received) { ValidatePacket(index, false, received); });
+ clients_[index].RegisterPhyLayer(mock_phy);
+ for (size_t timeout = 10; timeout > 0 && clients_.size() > servers_.size(); timeout--) {
+ sleep(0); // Wait for server to be created
+ }
+ ValidateConnection(index);
+ return index;
+ }
+
+ LinkLayerPacketView NextPacket() {
+ std::shared_ptr<std::vector<uint8_t>> count_shared = std::make_shared<std::vector<uint8_t>>(count);
+ View count_view(count_shared, 0, count_shared->size());
+ PacketView<true> args({count_view});
+ auto builder = CommandBuilder::Create(packet_id_++, args);
+ auto wrapped_command = LinkLayerPacketBuilder::WrapCommand(std::move(builder), source_, dest_);
+ std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
+ std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
+ wrapped_command->Serialize(it);
+ LinkLayerPacketView view = LinkLayerPacketView::Create(packet_ptr);
+ return view;
+ }
+
+ void SendFromClient(size_t pair_id) {
+ ASSERT_GT(clients_.size(), pair_id);
+ LinkLayerPacketView view = NextPacket();
+ client_opcodes_[pair_id] = CommandView::GetCommand(view).GetOpcode();
+ clients_[pair_id].IncomingPacket(view);
+ }
+
+ void SendFromServer(size_t pair_id) {
+ ASSERT_GT(servers_.size(), pair_id);
+ LinkLayerPacketView view = NextPacket();
+ server_opcodes_[pair_id] = CommandView::GetCommand(view).GetOpcode();
+ servers_[pair_id].IncomingPacket(view);
+ }
+
+ void ReadFromClient(size_t pair_id) {
+ ASSERT_GT(clients_.size(), pair_id);
+ size_t validated_packets = validated_server_packets_[pair_id];
+ for (size_t tries = 0; tries < 10 && validated_server_packets_[pair_id] == validated_packets; tries++) {
+ clients_[pair_id].TimerTick();
+ }
+ ASSERT_EQ(validated_server_packets_[pair_id], validated_packets + 1);
+ }
+
+ void ReadFromServer(size_t pair_id) {
+ ASSERT_GT(servers_.size(), pair_id);
+ size_t validated_packets = validated_client_packets_[pair_id];
+ for (size_t tries = 0; tries < 10 && validated_client_packets_[pair_id] == validated_packets; tries++) {
+ servers_[pair_id].TimerTick();
+ }
+ ASSERT_EQ(validated_client_packets_[pair_id], validated_packets + 1);
+ }
+
+ private:
+ uint16_t packet_id_{1};
+ AsyncManager async_manager_;
+ int socket_fd_;
+ std::vector<LinkLayerSocketDevice> servers_;
+ std::vector<LinkLayerSocketDevice> clients_;
+ uint16_t server_opcodes_[kMaxConnections]{0};
+ uint16_t client_opcodes_[kMaxConnections]{0};
+ size_t validated_server_packets_[kMaxConnections]{0};
+ size_t validated_client_packets_[kMaxConnections]{0};
+ Address source_{{1, 2, 3, 4, 5, 6}};
+ Address dest_{{6, 5, 4, 3, 2, 1}};
+};
+
+TEST_F(LinkLayerSocketDeviceTest, TestClientFirst) {
+ size_t pair_id = CreateConnection();
+ ASSERT_EQ(pair_id, 0u);
+ ValidateConnection(pair_id);
+
+ SendFromClient(pair_id);
+ ReadFromServer(pair_id);
+}
+
+TEST_F(LinkLayerSocketDeviceTest, TestServerFirst) {
+ size_t pair_id = CreateConnection();
+ ASSERT_EQ(pair_id, 0u);
+
+ SendFromServer(pair_id);
+ ReadFromClient(pair_id);
+}
+
+TEST_F(LinkLayerSocketDeviceTest, TestMultiplePackets) {
+ static const int num_packets = 30;
+ size_t pair_id = CreateConnection();
+ ASSERT_EQ(pair_id, 0u);
+ for (int i = 0; i < num_packets; i++) {
+ SendFromClient(pair_id);
+ SendFromServer(pair_id);
+ ReadFromServer(pair_id);
+ ReadFromClient(pair_id);
+ }
+}
+
+TEST_F(LinkLayerSocketDeviceTest, TestMultipleConnectionsFromServer) {
+ static size_t last_pair_id = -1;
+ size_t pair_id;
+ for (size_t i = 0; i < kMaxConnections; i++) {
+ pair_id = CreateConnection();
+ ASSERT_EQ(pair_id, last_pair_id + 1);
+ last_pair_id = pair_id;
+ SendFromServer(pair_id);
+ ReadFromClient(pair_id);
+ }
+}
+
+TEST_F(LinkLayerSocketDeviceTest, TestMultipleConnectionsFromClient) {
+ for (size_t i = 0; i < kMaxConnections; i++) {
+ size_t pair_id = CreateConnection();
+ ASSERT_EQ(pair_id, i);
+ SendFromClient(pair_id);
+ ReadFromServer(pair_id);
+ }
+}
+
+TEST_F(LinkLayerSocketDeviceTest, TestMultipleConnections) {
+ for (size_t i = 0; i < kMaxConnections; i++) {
+ size_t pair_id = CreateConnection();
+ ASSERT_EQ(pair_id, i);
+ SendFromClient(pair_id);
+ SendFromServer(pair_id);
+ ReadFromClient(pair_id);
+ ReadFromServer(pair_id);
+ }
+}
+
+} // namespace test_vendor_lib
namespace {
vector<uint8_t> count_all = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
- 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
- 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
};
vector<uint8_t> count_1 = {
};
vector<uint8_t> count_3 = {
- 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
- 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
};
} // namespace
template <bool little_endian>
class EndianBuilder : public PacketBuilder<little_endian> {
public:
- EndianBuilder(uint8_t byte, uint16_t two_bytes, uint32_t four_bytes,
- uint64_t eight_bytes)
- : byte_(byte),
- two_bytes_(two_bytes),
- four_bytes_(four_bytes),
- eight_bytes_(eight_bytes) {}
+ EndianBuilder(uint8_t byte, uint16_t two_bytes, uint32_t four_bytes, uint64_t eight_bytes)
+ : byte_(byte), two_bytes_(two_bytes), four_bytes_(four_bytes), eight_bytes_(eight_bytes) {}
~EndianBuilder() = default;
virtual size_t size() const override {
- return sizeof(signature_) + sizeof(byte_) + sizeof(two_bytes_) +
- sizeof(four_bytes_) + sizeof(eight_bytes_);
+ return sizeof(signature_) + sizeof(byte_) + sizeof(two_bytes_) + sizeof(four_bytes_) + sizeof(eight_bytes_);
}
virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet =
- std::make_unique<std::vector<uint8_t>>();
+ std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
packet->reserve(size());
std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
Serialize(it);
return packet;
}
- virtual void Serialize(
- std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
PacketBuilder<little_endian>::insert(signature_, it);
PacketBuilder<little_endian>::insert(byte_, it);
PacketBuilder<little_endian>::insert(two_bytes_, it);
}
~VectorBuilder() = default;
- virtual size_t size() const override { return vect_.size() * sizeof(T); }
+ virtual size_t size() const override {
+ return vect_.size() * sizeof(T);
+ }
virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet =
- std::make_unique<std::vector<uint8_t>>();
+ std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
packet->reserve(size());
std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
Serialize(it);
return packet;
}
- virtual void Serialize(
- std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
PacketBuilder<true>::insert_vector(vect_, it);
}
}
virtual ~InsertElementsBuilder() = default;
- virtual size_t size() const override { return vect_.size() * sizeof(T); }
+ virtual size_t size() const override {
+ return vect_.size() * sizeof(T);
+ }
virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet =
- std::make_unique<std::vector<uint8_t>>();
+ std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
packet->reserve(size());
std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
Serialize(it);
return packet;
}
- virtual void Serialize(
- std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
for (T elem : vect_) {
PacketBuilder<true>::insert(elem, it);
}
};
std::vector<uint64_t> vector_data{
- 0x7060504030201000, 0x7161514131211101, 0x7262524232221202,
- 0x7363534333231303, 0x7464544434241404, 0x7565554535251505,
- 0x7666564636261606, 0x7767574737271707, 0x7868584838281808,
+ 0x7060504030201000, 0x7161514131211101, 0x7262524232221202, 0x7363534333231303, 0x7464544434241404,
+ 0x7565554535251505, 0x7666564636261606, 0x7767574737271707, 0x7868584838281808,
};
template <typename T>
~VectorBuilderTest() = default;
void SetUp() {
- packet_1_ =
- std::shared_ptr<VectorBuilder<T>>(new VectorBuilder<T>(vector_data));
- packet_2_ = std::shared_ptr<InsertElementsBuilder<T>>(
- new InsertElementsBuilder<T>(vector_data));
+ packet_1_ = std::shared_ptr<VectorBuilder<T>>(new VectorBuilder<T>(vector_data));
+ packet_2_ = std::shared_ptr<InsertElementsBuilder<T>>(new InsertElementsBuilder<T>(vector_data));
}
void TearDown() {
std::shared_ptr<InsertElementsBuilder<T>> packet_2_;
};
-using VectorBaseTypes = ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t,
- int8_t, int16_t, int32_t, int64_t>;
+using VectorBaseTypes = ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t>;
TYPED_TEST_CASE(VectorBuilderTest, VectorBaseTypes);
TYPED_TEST(VectorBuilderTest, insertVectorTest) {
- ASSERT_EQ(*(this->packet_1_->FinalPacket()),
- *(this->packet_2_->FinalPacket()));
+ ASSERT_EQ(*(this->packet_1_->FinalPacket()), *(this->packet_2_->FinalPacket()));
}
class NestedBuilder : public PacketBuilder<true> {
return std::unique_ptr<NestedBuilder>(new NestedBuilder(level));
}
- static std::unique_ptr<NestedBuilder> CreateNested(
- std::unique_ptr<BasePacketBuilder> payload, uint8_t level) {
- return std::unique_ptr<NestedBuilder>(
- new NestedBuilder(std::move(payload), level));
+ static std::unique_ptr<NestedBuilder> CreateNested(std::unique_ptr<BasePacketBuilder> payload, uint8_t level) {
+ return std::unique_ptr<NestedBuilder>(new NestedBuilder(std::move(payload), level));
}
virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet =
- std::make_unique<std::vector<uint8_t>>();
+ std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
packet->reserve(size());
std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
Serialize(it);
return packet;
}
- virtual void Serialize(
- std::back_insert_iterator<std::vector<uint8_t>> it) const override {
+ virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
PacketBuilder<true>::insert(level_, it);
if (payload_) {
payload_->Serialize(it);
std::unique_ptr<BasePacketBuilder> payload_;
uint8_t level_;
- NestedBuilder(std::unique_ptr<BasePacketBuilder> inner, uint8_t level)
- : payload_(std::move(inner)), level_(level) {}
+ NestedBuilder(std::unique_ptr<BasePacketBuilder> inner, uint8_t level) : payload_(std::move(inner)), level_(level) {}
NestedBuilder(uint8_t level) : level_(level) {}
};
TEST(BuilderBuilderTest, nestingTest) {
std::unique_ptr<BasePacketBuilder> innermost = NestedBuilder::Create(0);
- std::unique_ptr<BasePacketBuilder> number_1 =
- NestedBuilder::CreateNested(std::move(innermost), 1);
- std::unique_ptr<BasePacketBuilder> number_2 =
- NestedBuilder::CreateNested(std::move(number_1), 2);
- std::unique_ptr<BasePacketBuilder> number_3 =
- NestedBuilder::CreateNested(std::move(number_2), 3);
- std::unique_ptr<BasePacketBuilder> number_4 =
- NestedBuilder::CreateNested(std::move(number_3), 4);
- std::unique_ptr<NestedBuilder> number_5 =
- NestedBuilder::CreateNested(std::move(number_4), 5);
+ std::unique_ptr<BasePacketBuilder> number_1 = NestedBuilder::CreateNested(std::move(innermost), 1);
+ std::unique_ptr<BasePacketBuilder> number_2 = NestedBuilder::CreateNested(std::move(number_1), 2);
+ std::unique_ptr<BasePacketBuilder> number_3 = NestedBuilder::CreateNested(std::move(number_2), 3);
+ std::unique_ptr<BasePacketBuilder> number_4 = NestedBuilder::CreateNested(std::move(number_3), 4);
+ std::unique_ptr<NestedBuilder> number_5 = NestedBuilder::CreateNested(std::move(number_4), 5);
std::vector<uint8_t> count_down{5, 4, 3, 2, 1, 0};
ASSERT_EQ(*number_5->FinalPacket(), count_down);
write(socketpair_fds_[1], &packet[1], packet.size());
// Read the command packet.
- std::unique_ptr<CommandPacket> command =
- packet_stream_.ReceiveCommand(socketpair_fds_[0]);
+ std::unique_ptr<CommandPacket> command = packet_stream_.ReceiveCommand(socketpair_fds_[0]);
const vector<uint8_t> received_payload = command->GetPayload();
EXPECT_EQ(opcode, command->GetOpcode());
EXPECT_EQ(static_cast<size_t>(payload_size + 1), command->GetPayloadSize());
EXPECT_EQ(payload_size, received_payload[0]);
- for (int i = 0; i < payload_size; ++i)
- EXPECT_EQ(packet[4 + i], received_payload[i + 1]);
+ for (int i = 0; i < payload_size; ++i) EXPECT_EQ(packet[4 + i], received_payload[i + 1]);
}
void CheckedSendEvent(std::unique_ptr<EventPacket> event) {
EXPECT_EQ(expected_size, sizeof(event_header) + return_parameters_size + 1);
EXPECT_EQ(DATA_TYPE_EVENT, event_header[0]);
EXPECT_EQ(expected_code, event_header[1]);
- EXPECT_EQ(expected_payload_size,
- static_cast<size_t>(return_parameters_size) + 1);
- for (int i = 0; i < return_parameters_size; ++i)
- EXPECT_EQ(expected_payload[i + 1], return_parameters[i]);
+ EXPECT_EQ(expected_payload_size, static_cast<size_t>(return_parameters_size) + 1);
+ for (int i = 0; i < return_parameters_size; ++i) EXPECT_EQ(expected_payload[i + 1], return_parameters[i]);
}
protected:
TEST_F(PacketStreamTest, SendEvent) {
const vector<uint8_t> return_parameters = {0};
- CheckedSendEvent(
- EventPacket::CreateCommandCompleteEvent(HCI_RESET, return_parameters));
+ CheckedSendEvent(EventPacket::CreateCommandCompleteEvent(HCI_RESET, return_parameters));
}
} // namespace test_vendor_lib
--- /dev/null
+/*
+ * Copyright 2018 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 "polled_socket.h"
+
+#include <gtest/gtest.h>
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace test_vendor_lib {
+namespace net {
+
+class PolledSocketTest : public ::testing::Test {
+ public:
+ static const uint16_t kPort = 6124;
+ static const size_t kBufferSize = 16;
+
+ protected:
+ void SetUp() override {
+ server_.Initialize(kPort);
+ client_.SetServerName("localhost");
+ client_.Initialize(kPort);
+ }
+
+ void TearDown() override {}
+
+ void ConnectClient() {}
+
+ PolledSocketServer server_;
+ PolledSocketClient client_;
+
+ private:
+ std::vector<uint8_t> server_buffer_;
+ std::vector<uint8_t> client_buffer_;
+};
+
+TEST_F(PolledSocketTest, SetUpTearDown) {}
+
+TEST_F(PolledSocketTest, TestOneConnection) {
+ std::vector<uint8_t> tx_buf = {'1', '2', '3'};
+ std::vector<uint8_t> rx_buf(10);
+
+ client_.Send(tx_buf);
+ server_.Receive(3, rx_buf.data());
+ client_.Send(tx_buf);
+ server_.Receive(3, rx_buf.data());
+ EXPECT_EQ(rx_buf.size(), tx_buf.size());
+}
+
+#if 0
+TEST_F(PolledSocketTest, TestRepeatedConnections) {
+ static const int num_connections = 300;
+ for (int i = 0; i < num_connections; i++) {
+ int socket_cli_fd = ConnectClient();
+ WriteFromClient(socket_cli_fd);
+ AwaitServerResponse(socket_cli_fd);
+ close(socket_cli_fd);
+ }
+}
+
+TEST_F(PolledSocketTest, TestMultipleConnections) {
+ static const int num_connections = 300;
+ int socket_cli_fd[num_connections];
+ for (int i = 0; i < num_connections; i++) {
+ socket_cli_fd[i] = ConnectClient();
+ EXPECT_TRUE(socket_cli_fd[i] > 0);
+ WriteFromClient(socket_cli_fd[i]);
+ }
+ for (int i = 0; i < num_connections; i++) {
+ AwaitServerResponse(socket_cli_fd[i]);
+ close(socket_cli_fd[i]);
+ }
+}
+
+#endif
+} // namespace net
+} // namespace test_vendor_lib
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright 2017 Google, Inc.
+ *
+ * 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 <gtest/gtest.h>
+#include <string>
+#include <vector>
+using std::vector;
+
+#include "model/controller/security_manager.h"
+
+namespace {
+const std::string kTestAddr1 = "12:34:56:78:9a:bc";
+const std::string kTestAddr2 = "cb:a9:87:65:43:21";
+const std::string kTestAddr3 = "cb:a9:56:78:9a:bc";
+const std::string kTestAddr4 = "12:34:56:78:9a:bc";
+const vector<uint8_t> kZeros_octets = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+const vector<uint8_t> kTestAddr1_octets = {0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12};
+const vector<uint8_t> kTestKey = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
+} // namespace
+
+namespace test_vendor_lib {
+
+class SecurityManagerTest : public ::testing::Test {
+ public:
+ SecurityManagerTest() {}
+ ~SecurityManagerTest() {}
+};
+
+TEST_F(SecurityManagerTest, WriteKey) {
+ Address btaddr1;
+ Address btaddr2;
+ Address btaddr3;
+ Address btaddr4;
+ SecurityManager sm(3);
+
+ Address::FromString(kTestAddr1, btaddr1);
+ Address::FromString(kTestAddr2, btaddr2);
+ Address::FromString(kTestAddr3, btaddr3);
+ Address::FromString(kTestAddr4, btaddr4);
+
+ EXPECT_EQ(1, sm.WriteKey(btaddr1, kTestKey));
+ EXPECT_EQ(1, sm.WriteKey(btaddr2, kTestKey));
+ EXPECT_EQ(1, sm.WriteKey(btaddr3, kTestKey));
+ // Key storage is full.
+ EXPECT_EQ(0, sm.WriteKey(btaddr4, kTestKey));
+}
+
+TEST_F(SecurityManagerTest, ReadKey) {
+ Address btaddr1;
+ Address btaddr2;
+ Address btaddr3;
+ SecurityManager sm(3);
+
+ Address::FromString(kTestAddr1, btaddr1);
+ Address::FromString(kTestAddr2, btaddr2);
+ Address::FromString(kTestAddr3, btaddr3);
+
+ sm.WriteKey(btaddr1, kTestKey);
+ sm.WriteKey(btaddr2, kTestKey);
+
+ EXPECT_EQ(1, sm.ReadKey(btaddr1));
+ EXPECT_EQ(1, sm.ReadKey(btaddr2));
+ EXPECT_EQ(0, sm.ReadKey(btaddr3));
+}
+
+TEST_F(SecurityManagerTest, ReadAllKeys) {
+ Address btaddr1;
+ Address btaddr2;
+ SecurityManager sm(3);
+
+ EXPECT_EQ(0, sm.ReadAllKeys());
+
+ Address::FromString(kTestAddr1, btaddr1);
+ Address::FromString(kTestAddr2, btaddr1);
+ Address::FromString(kTestAddr3, btaddr1);
+
+ sm.WriteKey(btaddr1, kTestKey);
+
+ EXPECT_EQ(1, sm.ReadAllKeys());
+
+ sm.WriteKey(btaddr2, kTestKey);
+
+ EXPECT_EQ(2, sm.ReadAllKeys());
+}
+
+TEST_F(SecurityManagerTest, DeleteKey) {
+ Address btaddr1;
+ Address btaddr2;
+ Address btaddr3;
+ SecurityManager sm(3);
+
+ Address::FromString(kTestAddr1, btaddr1);
+ Address::FromString(kTestAddr2, btaddr2);
+ Address::FromString(kTestAddr3, btaddr3);
+
+ EXPECT_EQ(0, sm.DeleteKey(btaddr2));
+
+ sm.WriteKey(btaddr1, kTestKey);
+
+ EXPECT_EQ(1, sm.ReadAllKeys());
+
+ EXPECT_EQ(1, sm.DeleteKey(btaddr1));
+
+ EXPECT_EQ(0, sm.ReadAllKeys());
+
+ sm.WriteKey(btaddr1, kTestKey);
+ sm.WriteKey(btaddr2, kTestKey);
+
+ EXPECT_EQ(2, sm.ReadAllKeys());
+
+ EXPECT_EQ(1, sm.DeleteKey(btaddr2));
+
+ EXPECT_EQ(1, sm.ReadAllKeys());
+
+ EXPECT_EQ(0, sm.DeleteKey(btaddr2));
+
+ EXPECT_EQ(1, sm.ReadAllKeys());
+}
+
+TEST_F(SecurityManagerTest, DeleteAllKeys) {
+ Address btaddr1;
+ Address btaddr2;
+ Address btaddr3;
+ SecurityManager sm(3);
+
+ Address::FromString(kTestAddr1, btaddr1);
+ Address::FromString(kTestAddr2, btaddr2);
+ Address::FromString(kTestAddr3, btaddr3);
+
+ EXPECT_EQ(0, sm.DeleteAllKeys());
+
+ sm.WriteKey(btaddr1, kTestKey);
+
+ EXPECT_EQ(1, sm.ReadAllKeys());
+
+ EXPECT_EQ(1, sm.DeleteAllKeys());
+
+ EXPECT_EQ(0, sm.ReadAllKeys());
+
+ sm.WriteKey(btaddr1, kTestKey);
+ sm.WriteKey(btaddr2, kTestKey);
+
+ EXPECT_EQ(2, sm.ReadAllKeys());
+
+ EXPECT_EQ(2, sm.DeleteAllKeys());
+
+ EXPECT_EQ(0, sm.ReadAllKeys());
+}
+
+} // namespace test_vendor_lib
--- /dev/null
+// Bluetooth types
+cc_library_headers {
+ name: "libbt-rootcanal-types-header",
+ export_include_dirs: ["./"],
+ vendor_available: true,
+ host_supported: true,
+}
+
+cc_library_static {
+ name: "libbt-rootcanal-types",
+ vendor_available: true,
+ defaults: ["fluoride_types_defaults"],
+ cflags: [
+ /* we export all classes, so change default visibility, instead of having EXPORT_SYMBOL on each class*/
+ "-fvisibility=default",
+ ],
+ host_supported: true,
+ srcs: [
+ "class_of_device.cc",
+ "address.cc",
+ "bluetooth/uuid.cc",
+ ],
+ header_libs: ["libbt-rootcanal-types-header"],
+ export_header_lib_headers: ["libbt-rootcanal-types-header"],
+}
+
+// ========================================================
+cc_test {
+ name: "rootcanal-test_types",
+ test_suites: ["device-tests"],
+ defaults: ["fluoride_defaults"],
+ host_supported: true,
+ srcs: [
+ "test/class_of_device_unittest.cc",
+ "test/address_unittest.cc",
+ "test/bluetooth/uuid_unittest.cc",
+ ],
+ static_libs: [
+ "libbt-rootcanal-types",
+ ],
+}
--- /dev/null
+#
+# Copyright 2017 Google, Inc.
+#
+# 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.
+#
+
+static_library("types") {
+ cflags = [
+ "-fvisibility=default",
+ ]
+
+ sources = [
+ "bluetooth/uuid.cc",
+ "le_address.cc",
+ "address.cc",
+ ]
+
+ include_dirs = [
+ "//",
+ ]
+
+ deps = [
+ "//third_party/libchrome:base",
+ ]
+}
+
+executable("types_unittests") {
+ testonly = true
+ sources = [
+ "test/address_unittest.cc",
+ "test/bluetooth/uuid_unittest.cc",
+ ]
+
+ include_dirs = [
+ "//",
+ ]
+
+ libs = [
+ "-ldl",
+ "-lpthread",
+ "-lresolv",
+ "-lrt",
+ "-lz",
+ "-latomic",
+ ]
+
+ deps = [
+ "//types",
+ "//third_party/googletest:gmock_main",
+ "//third_party/libchrome:base",
+ ]
+}
--- /dev/null
+/******************************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#include "address.h"
+
+#include <base/strings/string_split.h>
+#include <base/strings/stringprintf.h>
+#include <stdint.h>
+#include <algorithm>
+#include <vector>
+
+static_assert(sizeof(Address) == 6, "Address must be 6 bytes long!");
+
+const Address Address::kAny{{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
+const Address Address::kEmpty{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+
+Address::Address(const uint8_t (&addr)[6]) {
+ std::copy(addr, addr + kLength, address);
+};
+
+std::string Address::ToString() const {
+ return base::StringPrintf("%02x:%02x:%02x:%02x:%02x:%02x", address[5], address[4], address[3], address[2], address[1],
+ address[0]);
+}
+
+bool Address::FromString(const std::string& from, Address& to) {
+ Address new_addr;
+ if (from.length() != 17) return false;
+
+ std::vector<std::string> byte_tokens = base::SplitString(from, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+
+ if (byte_tokens.size() != 6) return false;
+
+ for (int i = 0; i < 6; i++) {
+ const auto& token = byte_tokens[i];
+
+ if (token.length() != 2) return false;
+
+ char* temp = nullptr;
+ new_addr.address[5 - i] = strtol(token.c_str(), &temp, 16);
+ if (*temp != '\0') return false;
+ }
+
+ to = new_addr;
+ return true;
+}
+
+size_t Address::FromOctets(const uint8_t* from) {
+ std::copy(from, from + kLength, address);
+ return kLength;
+};
+
+bool Address::IsValidAddress(const std::string& address) {
+ Address tmp;
+ return Address::FromString(address, tmp);
+}
--- /dev/null
+/******************************************************************************
+ *
+ * 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 <string>
+
+/** Bluetooth Address */
+class Address final {
+ public:
+ static constexpr unsigned int kLength = 6;
+
+ uint8_t address[kLength];
+
+ Address() = default;
+ Address(const uint8_t (&addr)[6]);
+
+ bool operator<(const Address& rhs) const {
+ return (std::memcmp(address, rhs.address, sizeof(address)) < 0);
+ }
+ bool operator==(const Address& rhs) const {
+ return (std::memcmp(address, rhs.address, sizeof(address)) == 0);
+ }
+ bool operator>(const Address& rhs) const {
+ return (rhs < *this);
+ }
+ bool operator<=(const Address& rhs) const {
+ return !(*this > rhs);
+ }
+ bool operator>=(const Address& rhs) const {
+ return !(*this < rhs);
+ }
+ bool operator!=(const Address& rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool IsEmpty() const {
+ return *this == kEmpty;
+ }
+
+ std::string ToString() const;
+
+ // Converts |string| to Address and places it in |to|. If |from| does
+ // not represent a Bluetooth address, |to| is not modified and this function
+ // returns false. Otherwise, it returns true.
+ static bool FromString(const std::string& from, Address& to);
+
+ // Copies |from| raw Bluetooth address octets to the local object.
+ // Returns the number of copied octets - should be always Address::kLength
+ size_t FromOctets(const uint8_t* from);
+
+ static bool IsValidAddress(const std::string& address);
+
+ static const Address kEmpty; // 00:00:00:00:00:00
+ static const Address kAny; // FF:FF:FF:FF:FF:FF
+};
+
+inline std::ostream& operator<<(std::ostream& os, const Address& a) {
+ os << a.ToString();
+ return os;
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 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.
+ *
+ ******************************************************************************/
+
+#include "uuid.h"
+
+#include <base/rand_util.h>
+#include <base/strings/stringprintf.h>
+#include <algorithm>
+
+namespace bluetooth {
+
+static_assert(sizeof(Uuid) == 16, "Uuid must be 16 bytes long!");
+
+using UUID128Bit = Uuid::UUID128Bit;
+
+const Uuid Uuid::kEmpty = Uuid::From128BitBE(UUID128Bit{{0x00}});
+
+namespace {
+constexpr Uuid kBase = Uuid::From128BitBE(
+ UUID128Bit{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb}});
+} // namespace
+
+size_t Uuid::GetShortestRepresentationSize() const {
+ if (memcmp(uu.data() + kNumBytes32, kBase.uu.data() + kNumBytes32, kNumBytes128 - kNumBytes32) != 0) {
+ return kNumBytes128;
+ }
+
+ if (uu[0] == 0 && uu[1] == 0) return kNumBytes16;
+
+ return kNumBytes32;
+}
+
+bool Uuid::Is16Bit() const {
+ return GetShortestRepresentationSize() == kNumBytes16;
+}
+
+uint16_t Uuid::As16Bit() const {
+ return (((uint16_t)uu[2]) << 8) + uu[3];
+}
+
+uint32_t Uuid::As32Bit() const {
+ return (((uint32_t)uu[0]) << 24) + (((uint32_t)uu[1]) << 16) + (((uint32_t)uu[2]) << 8) + uu[3];
+}
+
+Uuid Uuid::FromString(const std::string& uuid, bool* is_valid) {
+ if (is_valid) *is_valid = false;
+ Uuid ret = kBase;
+
+ if (uuid.empty()) return ret;
+
+ uint8_t* p = ret.uu.data();
+ if (uuid.size() == kString128BitLen) {
+ if (uuid[8] != '-' || uuid[13] != '-' || uuid[18] != '-' || uuid[23] != '-') {
+ return ret;
+ }
+
+ int c;
+ int rc = sscanf(uuid.c_str(),
+ "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx"
+ "-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%n",
+ &p[0], &p[1], &p[2], &p[3], &p[4], &p[5], &p[6], &p[7], &p[8], &p[9], &p[10], &p[11], &p[12],
+ &p[13], &p[14], &p[15], &c);
+ if (rc != 16) return ret;
+ if (c != kString128BitLen) return ret;
+
+ if (is_valid) *is_valid = true;
+ } else if (uuid.size() == 8) {
+ int c;
+ int rc = sscanf(uuid.c_str(), "%02hhx%02hhx%02hhx%02hhx%n", &p[0], &p[1], &p[2], &p[3], &c);
+ if (rc != 4) return ret;
+ if (c != 8) return ret;
+
+ if (is_valid) *is_valid = true;
+ } else if (uuid.size() == 4) {
+ int c;
+ int rc = sscanf(uuid.c_str(), "%02hhx%02hhx%n", &p[2], &p[3], &c);
+ if (rc != 2) return ret;
+ if (c != 4) return ret;
+
+ if (is_valid) *is_valid = true;
+ }
+
+ return ret;
+}
+
+Uuid Uuid::From16Bit(uint16_t uuid16) {
+ Uuid u = kBase;
+
+ u.uu[2] = (uint8_t)((0xFF00 & uuid16) >> 8);
+ u.uu[3] = (uint8_t)(0x00FF & uuid16);
+ return u;
+}
+
+Uuid Uuid::From32Bit(uint32_t uuid32) {
+ Uuid u = kBase;
+
+ u.uu[0] = (uint8_t)((0xFF000000 & uuid32) >> 24);
+ u.uu[1] = (uint8_t)((0x00FF0000 & uuid32) >> 16);
+ u.uu[2] = (uint8_t)((0x0000FF00 & uuid32) >> 8);
+ u.uu[3] = (uint8_t)(0x000000FF & uuid32);
+ return u;
+}
+
+Uuid Uuid::From128BitBE(const uint8_t* uuid) {
+ UUID128Bit tmp;
+ memcpy(tmp.data(), uuid, kNumBytes128);
+ return From128BitBE(tmp);
+}
+
+Uuid Uuid::From128BitLE(const UUID128Bit& uuid) {
+ Uuid u;
+ std::reverse_copy(uuid.data(), uuid.data() + kNumBytes128, u.uu.begin());
+ return u;
+}
+
+Uuid Uuid::From128BitLE(const uint8_t* uuid) {
+ UUID128Bit tmp;
+ memcpy(tmp.data(), uuid, kNumBytes128);
+ return From128BitLE(tmp);
+}
+
+const UUID128Bit Uuid::To128BitLE() const {
+ UUID128Bit le;
+ std::reverse_copy(uu.data(), uu.data() + kNumBytes128, le.begin());
+ return le;
+}
+
+const UUID128Bit& Uuid::To128BitBE() const {
+ return uu;
+}
+
+Uuid Uuid::GetRandom() {
+ Uuid uuid;
+ base::RandBytes(uuid.uu.data(), uuid.uu.size());
+ return uuid;
+}
+
+bool Uuid::IsEmpty() const {
+ return *this == kEmpty;
+}
+
+bool Uuid::operator<(const Uuid& rhs) const {
+ return std::lexicographical_compare(uu.begin(), uu.end(), rhs.uu.begin(), rhs.uu.end());
+}
+
+bool Uuid::operator==(const Uuid& rhs) const {
+ return uu == rhs.uu;
+}
+
+bool Uuid::operator!=(const Uuid& rhs) const {
+ return uu != rhs.uu;
+}
+
+std::string Uuid::ToString() const {
+ return base::StringPrintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", uu[0], uu[1], uu[2],
+ uu[3], uu[4], uu[5], uu[6], uu[7], uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14],
+ uu[15]);
+}
+} // namespace bluetooth
\ No newline at end of file
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 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 <stdint.h>
+#include <array>
+#include <string>
+
+namespace bluetooth {
+
+// This class is representing Bluetooth UUIDs across whole stack.
+// Here are some general endianness rules:
+// 1. UUID is internally kept as as Big Endian.
+// 2. Bytes representing UUID coming from upper layers, Java or Binder, are Big
+// Endian.
+// 3. Bytes representing UUID coming from lower layer, HCI packets, are Little
+// Endian.
+// 4. UUID in storage is always string.
+class Uuid final {
+ public:
+ static constexpr size_t kNumBytes128 = 16;
+ static constexpr size_t kNumBytes32 = 4;
+ static constexpr size_t kNumBytes16 = 2;
+
+ static constexpr size_t kString128BitLen = 36;
+
+ static const Uuid kEmpty; // 00000000-0000-0000-0000-000000000000
+
+ using UUID128Bit = std::array<uint8_t, kNumBytes128>;
+
+ Uuid() = default;
+
+ // Creates and returns a random 128-bit UUID.
+ static Uuid GetRandom();
+
+ // Returns the shortest possible representation of this UUID in bytes. Either
+ // kNumBytes16, kNumBytes32, or kNumBytes128
+ size_t GetShortestRepresentationSize() const;
+
+ // Returns true if this UUID can be represented as 16 bit.
+ bool Is16Bit() const;
+
+ // Returns 16 bit Little Endian representation of this UUID. Use
+ // GetShortestRepresentationSize() or Is16Bit() before using this method.
+ uint16_t As16Bit() const;
+
+ // Returns 32 bit Little Endian representation of this UUID. Use
+ // GetShortestRepresentationSize() before using this method.
+ uint32_t As32Bit() const;
+
+ // Converts string representing 128, 32, or 16 bit UUID in
+ // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, xxxxxxxx, or xxxx format to UUID. If
+ // set, optional is_valid parameter will be set to true if conversion is
+ // successfull, false otherwise.
+ static Uuid FromString(const std::string& uuid, bool* is_valid = nullptr);
+
+ // Converts 16bit Little Endian representation of UUID to UUID
+ static Uuid From16Bit(uint16_t uuid16bit);
+
+ // Converts 32bit Little Endian representation of UUID to UUID
+ static Uuid From32Bit(uint32_t uuid32bit);
+
+ // Converts 128 bit Big Endian array representing UUID to UUID.
+ static constexpr Uuid From128BitBE(const UUID128Bit& uuid) {
+ Uuid u(uuid);
+ return u;
+ }
+
+ // Converts 128 bit Big Endian array representing UUID to UUID. |uuid| points
+ // to beginning of array.
+ static Uuid From128BitBE(const uint8_t* uuid);
+
+ // Converts 128 bit Little Endian array representing UUID to UUID.
+ static Uuid From128BitLE(const UUID128Bit& uuid);
+
+ // Converts 128 bit Little Endian array representing UUID to UUID. |uuid|
+ // points to beginning of array.
+ static Uuid From128BitLE(const uint8_t* uuid);
+
+ // Returns 128 bit Little Endian representation of this UUID
+ const UUID128Bit To128BitLE() const;
+
+ // Returns 128 bit Big Endian representation of this UUID
+ const UUID128Bit& To128BitBE() const;
+
+ // Returns string representing this UUID in
+ // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format, lowercase.
+ std::string ToString() const;
+
+ // Returns true if this UUID is equal to kEmpty
+ bool IsEmpty() const;
+
+ bool operator<(const Uuid& rhs) const;
+ bool operator==(const Uuid& rhs) const;
+ bool operator!=(const Uuid& rhs) const;
+
+ private:
+ constexpr Uuid(const UUID128Bit& val) : uu{val} {};
+
+ // Network-byte-ordered ID (Big Endian).
+ UUID128Bit uu;
+};
+} // namespace bluetooth
+
+inline std::ostream& operator<<(std::ostream& os, const bluetooth::Uuid& a) {
+ os << a.ToString();
+ return os;
+}
+
+// Custom std::hash specialization so that bluetooth::UUID can be used as a key
+// in std::unordered_map.
+namespace std {
+
+template <>
+struct hash<bluetooth::Uuid> {
+ std::size_t operator()(const bluetooth::Uuid& key) const {
+ const auto& uuid_bytes = key.To128BitBE();
+ std::hash<std::string> hash_fn;
+ return hash_fn(std::string(reinterpret_cast<const char*>(uuid_bytes.data()), uuid_bytes.size()));
+ }
+};
+
+} // namespace std
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright 2018 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 "class_of_device.h"
+
+#include <base/strings/string_split.h>
+#include <base/strings/stringprintf.h>
+#include <stdint.h>
+#include <algorithm>
+#include <vector>
+
+static_assert(sizeof(ClassOfDevice) == ClassOfDevice::kLength, "ClassOfDevice must be 3 bytes long!");
+
+ClassOfDevice::ClassOfDevice(const uint8_t (&class_of_device)[kLength]) {
+ std::copy(class_of_device, class_of_device + kLength, cod);
+};
+
+std::string ClassOfDevice::ToString() const {
+ return base::StringPrintf("%03x-%01x-%02x", (static_cast<uint16_t>(cod[2]) << 4) | cod[1] >> 4, cod[1] & 0x0f,
+ cod[0]);
+}
+
+bool ClassOfDevice::FromString(const std::string& from, ClassOfDevice& to) {
+ ClassOfDevice new_cod;
+ if (from.length() != 8) return false;
+
+ std::vector<std::string> byte_tokens = base::SplitString(from, "-", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+
+ if (byte_tokens.size() != 3) return false;
+ if (byte_tokens[0].length() != 3) return false;
+ if (byte_tokens[1].length() != 1) return false;
+ if (byte_tokens[2].length() != 2) return false;
+
+ uint16_t values[3];
+
+ for (size_t i = 0; i < kLength; i++) {
+ const auto& token = byte_tokens[i];
+
+ char* temp = nullptr;
+ values[i] = strtol(token.c_str(), &temp, 16);
+ if (*temp != '\0') return false;
+ }
+
+ new_cod.cod[0] = values[2];
+ new_cod.cod[1] = values[1] | ((values[0] & 0xf) << 4);
+ new_cod.cod[2] = values[0] >> 4;
+
+ to = new_cod;
+ return true;
+}
+
+size_t ClassOfDevice::FromOctets(const uint8_t* from) {
+ std::copy(from, from + kLength, cod);
+ return kLength;
+};
+
+bool ClassOfDevice::IsValid(const std::string& cod) {
+ ClassOfDevice tmp;
+ return ClassOfDevice::FromString(cod, tmp);
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright 2018 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 <string>
+
+/** Bluetooth Class of Device */
+class ClassOfDevice final {
+ public:
+ static constexpr unsigned int kLength = 3;
+
+ uint8_t cod[kLength];
+
+ ClassOfDevice() = default;
+ ClassOfDevice(const uint8_t (&class_of_device)[kLength]);
+
+ bool operator==(const ClassOfDevice& rhs) const {
+ return (std::memcmp(cod, rhs.cod, sizeof(cod)) == 0);
+ }
+
+ std::string ToString() const;
+
+ // Converts |string| to ClassOfDevice and places it in |to|. If |from| does
+ // not represent a Class of Device, |to| is not modified and this function
+ // returns false. Otherwise, it returns true.
+ static bool FromString(const std::string& from, ClassOfDevice& to);
+
+ // Copies |from| raw Class of Device octets to the local object.
+ // Returns the number of copied octets (always ClassOfDevice::kLength)
+ size_t FromOctets(const uint8_t* from);
+
+ static bool IsValid(const std::string& class_of_device);
+};
+
+inline std::ostream& operator<<(std::ostream& os, const ClassOfDevice& c) {
+ os << c.ToString();
+ return os;
+}
--- /dev/null
+/******************************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#include <gtest/gtest.h>
+
+#include "address.h"
+
+static const char* test_addr = "bc:9a:78:56:34:12";
+static const char* test_addr2 = "21:43:65:87:a9:cb";
+
+TEST(AddressUnittest, test_constructor_array) {
+ Address bdaddr({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc});
+
+ ASSERT_EQ(0x12, bdaddr.address[0]);
+ ASSERT_EQ(0x34, bdaddr.address[1]);
+ ASSERT_EQ(0x56, bdaddr.address[2]);
+ ASSERT_EQ(0x78, bdaddr.address[3]);
+ ASSERT_EQ(0x9A, bdaddr.address[4]);
+ ASSERT_EQ(0xBC, bdaddr.address[5]);
+
+ std::string ret = bdaddr.ToString();
+
+ ASSERT_STREQ(test_addr, ret.c_str());
+}
+
+TEST(AddressUnittest, test_is_empty) {
+ Address empty;
+ Address::FromString("00:00:00:00:00:00", empty);
+ ASSERT_TRUE(empty.IsEmpty());
+
+ Address not_empty;
+ Address::FromString("00:00:00:00:00:01", not_empty);
+ ASSERT_FALSE(not_empty.IsEmpty());
+}
+
+TEST(AddressUnittest, test_to_from_str) {
+ Address bdaddr;
+ Address::FromString(test_addr, bdaddr);
+
+ ASSERT_EQ(0x12, bdaddr.address[0]);
+ ASSERT_EQ(0x34, bdaddr.address[1]);
+ ASSERT_EQ(0x56, bdaddr.address[2]);
+ ASSERT_EQ(0x78, bdaddr.address[3]);
+ ASSERT_EQ(0x9A, bdaddr.address[4]);
+ ASSERT_EQ(0xBC, bdaddr.address[5]);
+
+ std::string ret = bdaddr.ToString();
+
+ ASSERT_STREQ(test_addr, ret.c_str());
+}
+
+TEST(AddressUnittest, test_from_octets) {
+ static const uint8_t test_addr_array[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc};
+
+ Address bdaddr;
+ size_t expected_result = Address::kLength;
+ ASSERT_EQ(expected_result, bdaddr.FromOctets(test_addr_array));
+
+ ASSERT_EQ(0x12, bdaddr.address[0]);
+ ASSERT_EQ(0x34, bdaddr.address[1]);
+ ASSERT_EQ(0x56, bdaddr.address[2]);
+ ASSERT_EQ(0x78, bdaddr.address[3]);
+ ASSERT_EQ(0x9A, bdaddr.address[4]);
+ ASSERT_EQ(0xBC, bdaddr.address[5]);
+
+ std::string ret = bdaddr.ToString();
+
+ ASSERT_STREQ(test_addr, ret.c_str());
+}
+
+TEST(AddressTest, test_equals) {
+ Address bdaddr1;
+ Address bdaddr2;
+ Address bdaddr3;
+ Address::FromString(test_addr, bdaddr1);
+ Address::FromString(test_addr, bdaddr2);
+ EXPECT_TRUE(bdaddr1 == bdaddr2);
+ EXPECT_FALSE(bdaddr1 != bdaddr2);
+ EXPECT_TRUE(bdaddr1 == bdaddr1);
+ EXPECT_FALSE(bdaddr1 != bdaddr1);
+
+ Address::FromString(test_addr2, bdaddr3);
+ EXPECT_FALSE(bdaddr2 == bdaddr3);
+ EXPECT_TRUE(bdaddr2 != bdaddr3);
+}
+
+TEST(AddressTest, test_less_than) {
+ Address bdaddr1;
+ Address bdaddr2;
+ Address bdaddr3;
+ Address::FromString(test_addr, bdaddr1);
+ Address::FromString(test_addr, bdaddr2);
+ EXPECT_FALSE(bdaddr1 < bdaddr2);
+ EXPECT_FALSE(bdaddr1 < bdaddr1);
+
+ Address::FromString(test_addr2, bdaddr3);
+ EXPECT_TRUE(bdaddr2 < bdaddr3);
+ EXPECT_FALSE(bdaddr3 < bdaddr2);
+}
+
+TEST(AddressTest, test_more_than) {
+ Address bdaddr1;
+ Address bdaddr2;
+ Address bdaddr3;
+ Address::FromString(test_addr, bdaddr1);
+ Address::FromString(test_addr, bdaddr2);
+ EXPECT_FALSE(bdaddr1 > bdaddr2);
+ EXPECT_FALSE(bdaddr1 > bdaddr1);
+
+ Address::FromString(test_addr2, bdaddr3);
+ EXPECT_FALSE(bdaddr2 > bdaddr3);
+ EXPECT_TRUE(bdaddr3 > bdaddr2);
+}
+
+TEST(AddressTest, test_less_than_or_equal) {
+ Address bdaddr1;
+ Address bdaddr2;
+ Address bdaddr3;
+ Address::FromString(test_addr, bdaddr1);
+ Address::FromString(test_addr, bdaddr2);
+ EXPECT_TRUE(bdaddr1 <= bdaddr2);
+ EXPECT_TRUE(bdaddr1 <= bdaddr1);
+
+ Address::FromString(test_addr2, bdaddr3);
+ EXPECT_TRUE(bdaddr2 <= bdaddr3);
+ EXPECT_FALSE(bdaddr3 <= bdaddr2);
+}
+
+TEST(AddressTest, test_more_than_or_equal) {
+ Address bdaddr1;
+ Address bdaddr2;
+ Address bdaddr3;
+ Address::FromString(test_addr, bdaddr1);
+ Address::FromString(test_addr, bdaddr2);
+ EXPECT_TRUE(bdaddr1 >= bdaddr2);
+ EXPECT_TRUE(bdaddr1 >= bdaddr1);
+
+ Address::FromString(test_addr2, bdaddr3);
+ EXPECT_FALSE(bdaddr2 >= bdaddr3);
+ EXPECT_TRUE(bdaddr3 >= bdaddr2);
+}
+
+TEST(AddressTest, test_copy) {
+ Address bdaddr1;
+ Address bdaddr2;
+ Address::FromString(test_addr, bdaddr1);
+ bdaddr2 = bdaddr1;
+
+ EXPECT_TRUE(bdaddr1 == bdaddr2);
+}
+
+TEST(AddressTest, IsValidAddress) {
+ EXPECT_FALSE(Address::IsValidAddress(""));
+ EXPECT_FALSE(Address::IsValidAddress("000000000000"));
+ EXPECT_FALSE(Address::IsValidAddress("00:00:00:00:0000"));
+ EXPECT_FALSE(Address::IsValidAddress("00:00:00:00:00:0"));
+ EXPECT_FALSE(Address::IsValidAddress("00:00:00:00:00:0;"));
+ EXPECT_TRUE(Address::IsValidAddress("00:00:00:00:00:00"));
+ EXPECT_TRUE(Address::IsValidAddress("AB:cd:00:00:00:00"));
+ EXPECT_FALSE(Address::IsValidAddress("aB:cD:eF:Gh:iJ:Kl"));
+}
+
+TEST(AddressTest, BdAddrFromString) {
+ Address addr;
+ memset(&addr, 0, sizeof(addr));
+
+ EXPECT_TRUE(Address::FromString("00:00:00:00:00:00", addr));
+ const Address result0 = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+ EXPECT_EQ(0, memcmp(&addr, &result0, sizeof(addr)));
+
+ EXPECT_TRUE(Address::FromString("ab:01:4C:d5:21:9f", addr));
+ const Address result1 = {{0x9f, 0x21, 0xd5, 0x4c, 0x01, 0xab}};
+ EXPECT_EQ(0, memcmp(&addr, &result1, sizeof(addr)));
+}
+
+TEST(AddressTest, BdAddrFromStringToStringEquivalent) {
+ std::string address = "c1:c2:c3:d1:d2:d3";
+ Address addr;
+
+ EXPECT_TRUE(Address::FromString(address, addr));
+ EXPECT_EQ(addr.ToString(), address);
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2017 Google, Inc.
+ *
+ * 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 <bluetooth/uuid.h>
+#include <gtest/gtest.h>
+
+using bluetooth::Uuid;
+
+static const Uuid ONES = Uuid::From128BitBE(
+ Uuid::UUID128Bit{{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}});
+
+static const Uuid SEQUENTIAL = Uuid::From128BitBE(
+ Uuid::UUID128Bit{{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89}});
+
+constexpr Uuid kBase = Uuid::From128BitBE(
+ Uuid::UUID128Bit{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb}});
+
+TEST(UuidTest, IsEmpty) {
+ EXPECT_TRUE(Uuid::kEmpty.IsEmpty());
+ EXPECT_FALSE(kBase.IsEmpty());
+}
+
+TEST(UuidTest, GetShortestRepresentationSize) {
+ EXPECT_TRUE(Uuid::kNumBytes16 == kBase.GetShortestRepresentationSize());
+ EXPECT_TRUE(Uuid::kNumBytes32 == Uuid::From32Bit(0x01234567).GetShortestRepresentationSize());
+ EXPECT_TRUE(Uuid::kNumBytes128 == Uuid::kEmpty.GetShortestRepresentationSize());
+}
+
+TEST(UuidTest, As16Bit) {
+ // Even though this is is not 16bit UUID, we should be able to get proper bits
+ EXPECT_EQ((uint16_t)0x1111, ONES.As16Bit());
+ EXPECT_EQ((uint16_t)0x4567, SEQUENTIAL.As16Bit());
+ EXPECT_EQ((uint16_t)0x0000, kBase.As16Bit());
+}
+
+TEST(UuidTest, As32Bit) {
+ // Even though this is is not 32bit UUID, we should be able to get proper bits
+ EXPECT_EQ((uint32_t)0x11111111, ONES.As32Bit());
+ EXPECT_EQ((uint32_t)0x01234567, SEQUENTIAL.As32Bit());
+ EXPECT_EQ((uint32_t)0x00000000, kBase.As32Bit());
+ EXPECT_EQ((uint32_t)0x12345678, Uuid::From32Bit(0x12345678).As32Bit());
+}
+
+TEST(UuidTest, Is16Bit) {
+ EXPECT_FALSE(ONES.Is16Bit());
+ EXPECT_FALSE(SEQUENTIAL.Is16Bit());
+ EXPECT_TRUE(kBase.Is16Bit());
+ EXPECT_TRUE(Uuid::FromString("1ae8").Is16Bit());
+}
+
+TEST(UuidTest, From16Bit) {
+ EXPECT_EQ(Uuid::From16Bit(0x0000), kBase);
+
+ const uint8_t u2[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+ Uuid uuid = Uuid::From16Bit(0x0001);
+ EXPECT_TRUE(memcmp(&uuid, u2, sizeof(u2)) == 0);
+
+ const uint8_t u3[] = {0x00, 0x00, 0x55, 0x3e, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+ uuid = Uuid::From16Bit(0x553e);
+ EXPECT_TRUE(memcmp(&uuid, u3, sizeof(u3)) == 0);
+
+ const uint8_t u4[] = {0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+ uuid = Uuid::From16Bit(0xffff);
+ EXPECT_TRUE(memcmp(&uuid, u4, sizeof(u4)) == 0);
+}
+
+TEST(UuidTest, From32Bit) {
+ EXPECT_EQ(Uuid::From32Bit(0x00000000), kBase);
+
+ const uint8_t u2[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+ Uuid uuid = Uuid::From32Bit(0x00000001);
+ EXPECT_TRUE(memcmp(&uuid, u2, sizeof(u2)) == 0);
+
+ const uint8_t u3[] = {0x33, 0x44, 0x55, 0x3e, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+ uuid = Uuid::From32Bit(0x3344553e);
+ EXPECT_TRUE(memcmp(&uuid, u3, sizeof(u3)) == 0);
+
+ const uint8_t u4[] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+ uuid = Uuid::From32Bit(0xffffffff);
+ EXPECT_TRUE(memcmp(&uuid, u4, sizeof(u4)) == 0);
+}
+
+TEST(UuidTest, ToString) {
+ const std::string UUID_BASE_STR = "00000000-0000-1000-8000-00805f9b34fb";
+ const std::string UUID_EMP_STR = "00000000-0000-0000-0000-000000000000";
+ const std::string UUID_ONES_STR = "11111111-1111-1111-1111-111111111111";
+ const std::string UUID_SEQ_STR = "01234567-89ab-cdef-abcd-ef0123456789";
+
+ EXPECT_EQ(UUID_BASE_STR, kBase.ToString());
+ EXPECT_EQ(UUID_EMP_STR, Uuid::kEmpty.ToString());
+ EXPECT_EQ(UUID_ONES_STR, ONES.ToString());
+ EXPECT_EQ(UUID_SEQ_STR, SEQUENTIAL.ToString());
+
+ Uuid uuid = Uuid::From32Bit(0x12345678);
+ EXPECT_EQ("12345678-0000-1000-8000-00805f9b34fb", uuid.ToString());
+}
+
+TEST(BtifStorageTest, test_string_to_uuid) {
+ const uint8_t u1[] = {0xe3, 0x9c, 0x62, 0x85, 0x86, 0x7f, 0x4b, 0x1d, 0x9d, 0xb0, 0x35, 0xfb, 0xd9, 0xae, 0xbf, 0x22};
+ bool is_valid = false;
+ Uuid uuid = Uuid::FromString("e39c6285-867f-4b1d-9db0-35fbd9aebf22", &is_valid);
+ EXPECT_TRUE(is_valid);
+ EXPECT_TRUE(memcmp(&uuid, u1, sizeof(u1)) == 0);
+
+ const uint8_t u2[] = {0x00, 0x00, 0x1a, 0xe8, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+ is_valid = false;
+ uuid = Uuid::FromString("1Ae8", &is_valid);
+ EXPECT_TRUE(is_valid);
+ EXPECT_TRUE(memcmp(&uuid, u2, sizeof(u2)) == 0);
+
+ const uint8_t u3[] = {0x12, 0x34, 0x11, 0x28, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+ is_valid = false;
+ uuid = Uuid::FromString("12341128", &is_valid);
+ EXPECT_TRUE(is_valid);
+ EXPECT_TRUE(memcmp(&uuid, u3, sizeof(u3)) == 0);
+}
+
+TEST(BtifStorageTest, test_string_to_uuid_invalid) {
+ bool is_valid = false;
+ Uuid uuid = Uuid::FromString("This is not a UUID", &is_valid);
+ EXPECT_FALSE(is_valid);
+
+ uuid = Uuid::FromString("11212", &is_valid);
+ EXPECT_FALSE(is_valid);
+
+ uuid = Uuid::FromString("1121 ", &is_valid);
+ EXPECT_FALSE(is_valid);
+
+ uuid = Uuid::FromString("AGFE", &is_valid);
+ EXPECT_FALSE(is_valid);
+
+ uuid = Uuid::FromString("ABFG", &is_valid);
+ EXPECT_FALSE(is_valid);
+
+ uuid = Uuid::FromString("e39c6285867f14b1d9db035fbd9aebf22", &is_valid);
+ EXPECT_FALSE(is_valid);
+
+ uuid = Uuid::FromString("12234567-89ab-cdef-abcd-ef01234567ZZ", &is_valid);
+ EXPECT_FALSE(is_valid);
+}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright 2018 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 <gtest/gtest.h>
+
+#include "class_of_device.h"
+
+static const char* test_class = "efc-d-ab";
+static const uint8_t test_bytes[]{0xab, 0xcd, 0xef};
+
+TEST(ClassOfDeviceUnittest, test_constructor_array) {
+ ClassOfDevice cod(test_bytes);
+
+ ASSERT_EQ(test_bytes[0], cod.cod[0]);
+ ASSERT_EQ(test_bytes[1], cod.cod[1]);
+ ASSERT_EQ(test_bytes[2], cod.cod[2]);
+
+ std::string ret = cod.ToString();
+
+ ASSERT_STREQ(test_class, ret.c_str());
+}
+
+TEST(ClassOfDeviceUnittest, test_to_from_str) {
+ ClassOfDevice cod;
+ ClassOfDevice::FromString(test_class, cod);
+
+ ASSERT_EQ(test_bytes[0], cod.cod[0]);
+ ASSERT_EQ(test_bytes[1], cod.cod[1]);
+ ASSERT_EQ(test_bytes[2], cod.cod[2]);
+
+ std::string ret = cod.ToString();
+
+ ASSERT_STREQ(test_class, ret.c_str());
+}
+
+TEST(ClassOfDeviceUnittest, test_from_octets) {
+ ClassOfDevice cod;
+ size_t expected_result = ClassOfDevice::kLength;
+ ASSERT_EQ(expected_result, cod.FromOctets(test_bytes));
+
+ ASSERT_EQ(test_bytes[0], cod.cod[0]);
+ ASSERT_EQ(test_bytes[1], cod.cod[1]);
+ ASSERT_EQ(test_bytes[2], cod.cod[2]);
+
+ std::string ret = cod.ToString();
+
+ ASSERT_STREQ(test_class, ret.c_str());
+}
+
+TEST(ClassOfDeviceTest, test_copy) {
+ ClassOfDevice cod1;
+ ClassOfDevice cod2;
+ ClassOfDevice::FromString(test_class, cod1);
+ cod2 = cod1;
+
+ ASSERT_EQ(cod1.cod[0], cod2.cod[0]);
+ ASSERT_EQ(cod1.cod[1], cod2.cod[1]);
+ ASSERT_EQ(cod1.cod[2], cod2.cod[2]);
+}
+
+TEST(ClassOfDeviceTest, IsValid) {
+ EXPECT_FALSE(ClassOfDevice::IsValid(""));
+ EXPECT_FALSE(ClassOfDevice::IsValid("000000"));
+ EXPECT_FALSE(ClassOfDevice::IsValid("00-00-00"));
+ EXPECT_FALSE(ClassOfDevice::IsValid("000-0-0"));
+ EXPECT_TRUE(ClassOfDevice::IsValid("000-0-00"));
+ EXPECT_TRUE(ClassOfDevice::IsValid("ABc-d-00"));
+ EXPECT_TRUE(ClassOfDevice::IsValid("aBc-D-eF"));
+}
+
+TEST(ClassOfDeviceTest, classOfDeviceFromString) {
+ ClassOfDevice cod;
+
+ EXPECT_TRUE(ClassOfDevice::FromString("000-0-00", cod));
+ const ClassOfDevice result0 = {{0x00, 0x00, 0x00}};
+ EXPECT_EQ(0, memcmp(&cod, &result0, sizeof(cod)));
+
+ EXPECT_TRUE(ClassOfDevice::FromString("ab2-1-4C", cod));
+ const ClassOfDevice result1 = {{0x4c, 0x21, 0xab}};
+ EXPECT_EQ(0, memcmp(&cod, &result1, sizeof(cod)));
+}