1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <chrono> // for milliseconds 20 #include <cstddef> // for size_t 21 #include <functional> // for function 22 #include <map> 23 #include <memory> // for shared_ptr 24 #include <optional> 25 #include <string> // for string 26 #include <vector> // for vector 27 28 #include "hci/address.h" // for Address 29 #include "model/devices/hci_device.h" // for HciDevice 30 #include "model/setup/async_manager.h" // for AsyncUserId, AsyncTaskId 31 #include "phy.h" // for Phy, Phy::Type 32 #include "phy_layer.h" 33 #include "rootcanal/configuration.pb.h" 34 35 namespace rootcanal { 36 class Device; 37 38 using ::bluetooth::hci::Address; 39 40 class TestModel { 41 public: 42 TestModel(std::function<AsyncUserId()> get_user_id, 43 std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds, const TaskCallback&)> 44 event_scheduler, 45 std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds, 46 std::chrono::milliseconds, const TaskCallback&)> 47 periodic_event_scheduler, 48 std::function<void(AsyncUserId)> cancel_tasks_from_user, 49 std::function<void(AsyncTaskId)> cancel, 50 std::function<std::shared_ptr<Device>(const std::string&, int, Phy::Type)> 51 connect_to_remote, 52 std::array<uint8_t, 5> bluetooth_address_prefix = {0xda, 0x4c, 0x10, 0xde, 0x17}); 53 virtual ~TestModel(); 54 55 TestModel(TestModel& model) = delete; 56 TestModel& operator=(const TestModel& model) = delete; 57 SetReuseDeviceAddresses(bool reuse_device_addresses)58 void SetReuseDeviceAddresses(bool reuse_device_addresses) { 59 reuse_device_addresses_ = reuse_device_addresses; 60 } 61 62 // Allow derived classes to use custom phy layer. 63 virtual std::unique_ptr<PhyLayer> CreatePhyLayer(PhyLayer::Identifier id, Phy::Type type); 64 65 // Allow derived classes to use custom phy devices. 66 virtual std::shared_ptr<PhyDevice> CreatePhyDevice(std::string type, 67 std::shared_ptr<Device> device); 68 69 // Test model commands 70 71 PhyDevice::Identifier AddDevice(std::shared_ptr<Device> device); 72 void RemoveDevice(PhyDevice::Identifier id); 73 PhyLayer::Identifier AddPhy(Phy::Type type); 74 void RemovePhy(PhyLayer::Identifier id); 75 void AddDeviceToPhy(PhyDevice::Identifier device_id, PhyLayer::Identifier phy_id); 76 void RemoveDeviceFromPhy(PhyDevice::Identifier device_id, PhyLayer::Identifier phy_id); 77 78 // Runtime implementation. 79 80 // Handle incoming remote connections 81 void AddLinkLayerConnection(std::shared_ptr<Device> dev, Phy::Type phy_type); 82 // Add an HCI device, return its index 83 PhyDevice::Identifier AddHciConnection(std::shared_ptr<HciDevice> dev, 84 std::optional<Address> address = {}); 85 // Handle closed remote connections (both hci & link layer) 86 void OnConnectionClosed(PhyDevice::Identifier device_id, AsyncUserId user_id); 87 88 // Connect to a remote device 89 void AddRemote(const std::string& server, int port, Phy::Type phy_type); 90 91 // Set the device's Bluetooth address 92 void SetDeviceAddress(PhyDevice::Identifier device_id, Address device_address); 93 94 void SetDeviceConfiguration(PhyDevice::Identifier device_id, 95 rootcanal::configuration::Controller const& configuration); 96 97 // Let devices know about the passage of time 98 void Tick(); 99 void StartTimer(); 100 void StopTimer(); 101 void SetTimerPeriod(std::chrono::milliseconds new_period); 102 103 // List the devices that the test knows about 104 const std::string& List(); 105 106 // Clear all devices and phys. 107 void Reset(); 108 109 private: 110 Address GenerateBluetoothAddress(uint32_t device_id) const; 111 112 std::map<PhyLayer::Identifier, std::shared_ptr<PhyLayer>> phy_layers_; 113 std::map<PhyDevice::Identifier, std::shared_ptr<PhyDevice>> phy_devices_; 114 std::string list_string_; 115 116 // Generator for device identifiers. 117 bool reuse_device_addresses_{true}; 118 119 // Prefix used to generate public device addresses for hosts 120 // connecting over TCP. 121 std::array<uint8_t, 5> bluetooth_address_prefix_; 122 123 // Callbacks to schedule tasks. 124 std::function<AsyncUserId()> get_user_id_; 125 std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds, const TaskCallback&)> 126 schedule_task_; 127 std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds, std::chrono::milliseconds, 128 const TaskCallback&)> 129 schedule_periodic_task_; 130 std::function<void(AsyncTaskId)> cancel_task_; 131 std::function<void(AsyncUserId)> cancel_tasks_from_user_; 132 std::function<std::shared_ptr<Device>(const std::string&, int, Phy::Type)> connect_to_remote_; 133 134 AsyncUserId model_user_id_; 135 AsyncTaskId timer_tick_task_{kInvalidTaskId}; 136 std::chrono::milliseconds timer_period_{}; 137 }; 138 139 } // namespace rootcanal 140