Loading system/test/rootcanal/bluetooth_hci.cc +3 −0 Original line number Original line Diff line number Diff line Loading @@ -190,6 +190,9 @@ Return<void> BluetoothHci::initialize_impl( test_channel_.AddDeviceToPhy({"2", "1"}); test_channel_.AddDeviceToPhy({"2", "1"}); test_channel_.Add({"beacon", "be:ac:10:00:00:02", "1000"}); test_channel_.Add({"beacon", "be:ac:10:00:00:02", "1000"}); test_channel_.AddDeviceToPhy({"3", "1"}); test_channel_.AddDeviceToPhy({"3", "1"}); test_channel_.Add( {"scripted_beacon", "5b:ea:c1:00:00:03", "path_to_config.log"}); test_channel_.AddDeviceToPhy({"4", "1"}); unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) { unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) { if (death_recipient->getHasDied()) if (death_recipient->getHasDied()) Loading system/vendor_libs/test_vendor_lib/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,7 @@ cc_library_static { "model/devices/loopback.cc", "model/devices/loopback.cc", "model/devices/polled_socket.cc", "model/devices/polled_socket.cc", "model/devices/remote_loopback_device.cc", "model/devices/remote_loopback_device.cc", "model/devices/scripted_beacon.cc", "model/devices/sniffer.cc", "model/devices/sniffer.cc", "model/setup/async_manager.cc", "model/setup/async_manager.cc", "model/setup/device_boutique.cc", "model/setup/device_boutique.cc", Loading system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.cc 0 → 100644 +176 −0 Original line number Original line Diff line number Diff line /* * 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 "scripted_beacon.h" // #include "hci/hci_packets.h" // To use error-checking packets #include "model/setup/device_boutique.h" using std::vector; namespace test_vendor_lib { bool ScriptedBeacon::registered_ = DeviceBoutique::Register("scripted_beacon", &ScriptedBeacon::Create); ScriptedBeacon::ScriptedBeacon() { advertising_interval_ms_ = std::chrono::milliseconds(1280); properties_.SetLeAdvertisementType(0x03 /* NON_CONNECT */); properties_.SetLeAdvertisement({ 0x18, // Length 0x09 /* TYPE_NAME_CMPL */, 'g', 'D', 'e', 'v', 'i', 'c', 'e', '-', 's', 'c', 'r', 'i', 'p', 't', 'e', 'd', '-', 'b', 'e', 'a', 'c', 'o', 'n', 0x02, // Length 0x01 /* TYPE_FLAG */, 0x4 /* BREDR_NOT_SPT */ | 0x2 /* GEN_DISC_FLAG */, }); properties_.SetLeScanResponse({0x06, // Length 0x07, // TYPE_NAME_SHORT 'g', 'b', 'e', 'a'}); } void ScriptedBeacon::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; config_file_ = args[2]; } void ScriptedBeacon::TimerTick() { if (!scanned_once_) { Beacon::TimerTick(); } else { std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send; std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); elapsed_time_ += now - last_timer_tick_; while (next_ad_.ad_time < now) { auto ad = model::packets::LeAdvertisementBuilder::Create( next_ad_.address, Address::kEmpty /* Destination */, model::packets::AddressType::RANDOM, model::packets::AdvertisementType::ADV_NONCONN_IND, next_ad_.ad); to_send = std::move(ad); for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) { phy->Send(to_send); } get_next_advertisement(); } last_timer_tick_ = now; } } void ScriptedBeacon::IncomingPacket( model::packets::LinkLayerPacketView packet) { if (!scanned_once_) { if (packet.GetDestinationAddress() == properties_.GetLeAddress() && packet.GetType() == model::packets::PacketType::LE_SCAN) { auto scan_response = model::packets::LeScanResponseBuilder::Create( properties_.GetLeAddress(), packet.GetSourceAddress(), static_cast<model::packets::AddressType>( properties_.GetLeAddressType()), model::packets::AdvertisementType::SCAN_RESPONSE, properties_.GetLeScanResponse()); std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send = std::move(scan_response); scanned_once_ = true; Address::FromString("12:34:56:78:9A:BC", next_ad_.address); open_config_file(); for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) { phy->Send(to_send); } } } } void ScriptedBeacon::get_next_advertisement() { next_ad_.address.address[2]++; /* For more recent versions: * using bluetooth::hci::GapData; * using bluetooth::hci::GapDataType; * GapData flags; * flags.data_type_ = GapDataType::FLAGS; * flags.data_ = {0x1A}; * GapData service; * service.data_type_ = GapDataType::COMPLETE_LIST_16_BIT_UUIDS; * service.data_ = {0x6F, 0xFD}; // 0xFD6F Contact Detection Service * GapData proximity_id; * proximity_id.data_type = GapDataType::SERVICE_DATA_128_BIT_UUIDS; * proximity_id.data_ = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, * 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, * }; */ // For older/all versions: next_ad_.ad = { 0x02, // Size 0x01, // Flag 0x1A, 0x03, // Size 0x03, // Complete 16-bit Service UUID 0x6F, 0xFD, 0x13, // Size 0x16, // Service Data - 16 bit UUID 0x6F, // FD6F 0xFD, 0x00, // ID 0x01, next_ad_.address.address[2], // make it different from the others 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, }; } void ScriptedBeacon::open_config_file() { // Open the config file and read it all? } } // namespace test_vendor_lib system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.h 0 → 100644 +70 −0 Original line number Original line Diff line number Diff line /* * Copyright 2020 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 "beacon.h" namespace test_vendor_lib { // Pretend to be a lot of beacons by advertising from a file. class ScriptedBeacon : public Beacon { public: ScriptedBeacon(); virtual ~ScriptedBeacon() = default; static std::shared_ptr<Device> Create() { return std::make_shared<ScriptedBeacon>(); } // Return a string representation of the type of device. virtual std::string GetTypeString() const override { return "scripted_beacon"; } virtual std::string ToString() const override { return "scripted_beacon " + config_file_; } // Set the address and advertising interval from string args. void Initialize(const std::vector<std::string>& args) override; void TimerTick() override; void IncomingPacket(model::packets::LinkLayerPacketView packet_view) override; private: static bool registered_; bool scanned_once_{false}; std::chrono::steady_clock::duration elapsed_time_{}; std::chrono::steady_clock::time_point last_timer_tick_{}; std::string config_file_{}; void open_config_file(); struct Advertisement { std::vector<uint8_t> ad; Address address; std::chrono::steady_clock::time_point ad_time; }; void get_next_advertisement(); Advertisement next_ad_{}; }; } // namespace test_vendor_lib system/vendor_libs/test_vendor_lib/model/setup/test_model.cc +2 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "model/devices/classic.h" #include "model/devices/classic.h" #include "model/devices/keyboard.h" #include "model/devices/keyboard.h" #include "model/devices/remote_loopback_device.h" #include "model/devices/remote_loopback_device.h" #include "model/devices/scripted_beacon.h" #include "model/devices/sniffer.h" #include "model/devices/sniffer.h" #include <memory> #include <memory> Loading Loading @@ -63,6 +64,7 @@ TestModel::TestModel( example_devices_.push_back(std::make_shared<CarKit>()); example_devices_.push_back(std::make_shared<CarKit>()); example_devices_.push_back(std::make_shared<Classic>()); example_devices_.push_back(std::make_shared<Classic>()); example_devices_.push_back(std::make_shared<Sniffer>()); example_devices_.push_back(std::make_shared<Sniffer>()); example_devices_.push_back(std::make_shared<ScriptedBeacon>()); example_devices_.push_back(std::make_shared<RemoteLoopbackDevice>()); example_devices_.push_back(std::make_shared<RemoteLoopbackDevice>()); } } Loading Loading
system/test/rootcanal/bluetooth_hci.cc +3 −0 Original line number Original line Diff line number Diff line Loading @@ -190,6 +190,9 @@ Return<void> BluetoothHci::initialize_impl( test_channel_.AddDeviceToPhy({"2", "1"}); test_channel_.AddDeviceToPhy({"2", "1"}); test_channel_.Add({"beacon", "be:ac:10:00:00:02", "1000"}); test_channel_.Add({"beacon", "be:ac:10:00:00:02", "1000"}); test_channel_.AddDeviceToPhy({"3", "1"}); test_channel_.AddDeviceToPhy({"3", "1"}); test_channel_.Add( {"scripted_beacon", "5b:ea:c1:00:00:03", "path_to_config.log"}); test_channel_.AddDeviceToPhy({"4", "1"}); unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) { unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) { if (death_recipient->getHasDied()) if (death_recipient->getHasDied()) Loading
system/vendor_libs/test_vendor_lib/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,7 @@ cc_library_static { "model/devices/loopback.cc", "model/devices/loopback.cc", "model/devices/polled_socket.cc", "model/devices/polled_socket.cc", "model/devices/remote_loopback_device.cc", "model/devices/remote_loopback_device.cc", "model/devices/scripted_beacon.cc", "model/devices/sniffer.cc", "model/devices/sniffer.cc", "model/setup/async_manager.cc", "model/setup/async_manager.cc", "model/setup/device_boutique.cc", "model/setup/device_boutique.cc", Loading
system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.cc 0 → 100644 +176 −0 Original line number Original line Diff line number Diff line /* * 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 "scripted_beacon.h" // #include "hci/hci_packets.h" // To use error-checking packets #include "model/setup/device_boutique.h" using std::vector; namespace test_vendor_lib { bool ScriptedBeacon::registered_ = DeviceBoutique::Register("scripted_beacon", &ScriptedBeacon::Create); ScriptedBeacon::ScriptedBeacon() { advertising_interval_ms_ = std::chrono::milliseconds(1280); properties_.SetLeAdvertisementType(0x03 /* NON_CONNECT */); properties_.SetLeAdvertisement({ 0x18, // Length 0x09 /* TYPE_NAME_CMPL */, 'g', 'D', 'e', 'v', 'i', 'c', 'e', '-', 's', 'c', 'r', 'i', 'p', 't', 'e', 'd', '-', 'b', 'e', 'a', 'c', 'o', 'n', 0x02, // Length 0x01 /* TYPE_FLAG */, 0x4 /* BREDR_NOT_SPT */ | 0x2 /* GEN_DISC_FLAG */, }); properties_.SetLeScanResponse({0x06, // Length 0x07, // TYPE_NAME_SHORT 'g', 'b', 'e', 'a'}); } void ScriptedBeacon::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; config_file_ = args[2]; } void ScriptedBeacon::TimerTick() { if (!scanned_once_) { Beacon::TimerTick(); } else { std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send; std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); elapsed_time_ += now - last_timer_tick_; while (next_ad_.ad_time < now) { auto ad = model::packets::LeAdvertisementBuilder::Create( next_ad_.address, Address::kEmpty /* Destination */, model::packets::AddressType::RANDOM, model::packets::AdvertisementType::ADV_NONCONN_IND, next_ad_.ad); to_send = std::move(ad); for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) { phy->Send(to_send); } get_next_advertisement(); } last_timer_tick_ = now; } } void ScriptedBeacon::IncomingPacket( model::packets::LinkLayerPacketView packet) { if (!scanned_once_) { if (packet.GetDestinationAddress() == properties_.GetLeAddress() && packet.GetType() == model::packets::PacketType::LE_SCAN) { auto scan_response = model::packets::LeScanResponseBuilder::Create( properties_.GetLeAddress(), packet.GetSourceAddress(), static_cast<model::packets::AddressType>( properties_.GetLeAddressType()), model::packets::AdvertisementType::SCAN_RESPONSE, properties_.GetLeScanResponse()); std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send = std::move(scan_response); scanned_once_ = true; Address::FromString("12:34:56:78:9A:BC", next_ad_.address); open_config_file(); for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) { phy->Send(to_send); } } } } void ScriptedBeacon::get_next_advertisement() { next_ad_.address.address[2]++; /* For more recent versions: * using bluetooth::hci::GapData; * using bluetooth::hci::GapDataType; * GapData flags; * flags.data_type_ = GapDataType::FLAGS; * flags.data_ = {0x1A}; * GapData service; * service.data_type_ = GapDataType::COMPLETE_LIST_16_BIT_UUIDS; * service.data_ = {0x6F, 0xFD}; // 0xFD6F Contact Detection Service * GapData proximity_id; * proximity_id.data_type = GapDataType::SERVICE_DATA_128_BIT_UUIDS; * proximity_id.data_ = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, * 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, * }; */ // For older/all versions: next_ad_.ad = { 0x02, // Size 0x01, // Flag 0x1A, 0x03, // Size 0x03, // Complete 16-bit Service UUID 0x6F, 0xFD, 0x13, // Size 0x16, // Service Data - 16 bit UUID 0x6F, // FD6F 0xFD, 0x00, // ID 0x01, next_ad_.address.address[2], // make it different from the others 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, }; } void ScriptedBeacon::open_config_file() { // Open the config file and read it all? } } // namespace test_vendor_lib
system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.h 0 → 100644 +70 −0 Original line number Original line Diff line number Diff line /* * Copyright 2020 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 "beacon.h" namespace test_vendor_lib { // Pretend to be a lot of beacons by advertising from a file. class ScriptedBeacon : public Beacon { public: ScriptedBeacon(); virtual ~ScriptedBeacon() = default; static std::shared_ptr<Device> Create() { return std::make_shared<ScriptedBeacon>(); } // Return a string representation of the type of device. virtual std::string GetTypeString() const override { return "scripted_beacon"; } virtual std::string ToString() const override { return "scripted_beacon " + config_file_; } // Set the address and advertising interval from string args. void Initialize(const std::vector<std::string>& args) override; void TimerTick() override; void IncomingPacket(model::packets::LinkLayerPacketView packet_view) override; private: static bool registered_; bool scanned_once_{false}; std::chrono::steady_clock::duration elapsed_time_{}; std::chrono::steady_clock::time_point last_timer_tick_{}; std::string config_file_{}; void open_config_file(); struct Advertisement { std::vector<uint8_t> ad; Address address; std::chrono::steady_clock::time_point ad_time; }; void get_next_advertisement(); Advertisement next_ad_{}; }; } // namespace test_vendor_lib
system/vendor_libs/test_vendor_lib/model/setup/test_model.cc +2 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "model/devices/classic.h" #include "model/devices/classic.h" #include "model/devices/keyboard.h" #include "model/devices/keyboard.h" #include "model/devices/remote_loopback_device.h" #include "model/devices/remote_loopback_device.h" #include "model/devices/scripted_beacon.h" #include "model/devices/sniffer.h" #include "model/devices/sniffer.h" #include <memory> #include <memory> Loading Loading @@ -63,6 +64,7 @@ TestModel::TestModel( example_devices_.push_back(std::make_shared<CarKit>()); example_devices_.push_back(std::make_shared<CarKit>()); example_devices_.push_back(std::make_shared<Classic>()); example_devices_.push_back(std::make_shared<Classic>()); example_devices_.push_back(std::make_shared<Sniffer>()); example_devices_.push_back(std::make_shared<Sniffer>()); example_devices_.push_back(std::make_shared<ScriptedBeacon>()); example_devices_.push_back(std::make_shared<RemoteLoopbackDevice>()); example_devices_.push_back(std::make_shared<RemoteLoopbackDevice>()); } } Loading