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 <string> // for string 25 #include <vector> // for vector 26 #include <optional> 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( 43 std::function<AsyncUserId()> get_user_id, 44 std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds, 45 const TaskCallback&)> 46 event_scheduler, 47 std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds, 48 std::chrono::milliseconds, const TaskCallback&)> 49 periodic_event_scheduler, 50 std::function<void(AsyncUserId)> cancel_tasks_from_user, 51 std::function<void(AsyncTaskId)> cancel, 52 std::function<std::shared_ptr<Device>(const std::string&, int, Phy::Type)> 53 connect_to_remote, 54 std::array<uint8_t, 5> bluetooth_address_prefix = {0xda, 0x4c, 0x10, 0xde, 55 0x17}); 56 virtual ~TestModel(); 57 58 TestModel(TestModel& model) = delete; 59 TestModel& operator=(const TestModel& model) = delete; 60 SetReuseDeviceAddresses(bool reuse_device_addresses)61 void SetReuseDeviceAddresses(bool reuse_device_addresses) { 62 reuse_device_addresses_ = reuse_device_addresses; 63 } 64 65 // Allow derived classes to use custom phy layer. 66 virtual std::unique_ptr<PhyLayer> CreatePhyLayer(PhyLayer::Identifier id, 67 Phy::Type type); 68 69 // Allow derived classes to use custom phy devices. 70 virtual std::shared_ptr<PhyDevice> CreatePhyDevice( 71 std::string type, std::shared_ptr<Device> device); 72 73 // Test model commands 74 75 PhyDevice::Identifier AddDevice(std::shared_ptr<Device> device); 76 void RemoveDevice(PhyDevice::Identifier id); 77 PhyLayer::Identifier AddPhy(Phy::Type type); 78 void RemovePhy(PhyLayer::Identifier id); 79 void AddDeviceToPhy(PhyDevice::Identifier device_id, 80 PhyLayer::Identifier phy_id); 81 void RemoveDeviceFromPhy(PhyDevice::Identifier device_id, 82 PhyLayer::Identifier phy_id); 83 84 // Runtime implementation. 85 86 // Handle incoming remote connections 87 void AddLinkLayerConnection(std::shared_ptr<Device> dev, Phy::Type phy_type); 88 // Add an HCI device, return its index 89 PhyDevice::Identifier AddHciConnection(std::shared_ptr<HciDevice> dev, 90 std::optional<Address> address = {}); 91 // Handle closed remote connections (both hci & link layer) 92 void OnConnectionClosed(PhyDevice::Identifier device_id, AsyncUserId user_id); 93 94 // Connect to a remote device 95 void AddRemote(const std::string& server, int port, Phy::Type phy_type); 96 97 // Set the device's Bluetooth address 98 void SetDeviceAddress(PhyDevice::Identifier device_id, 99 Address device_address); 100 101 void SetDeviceConfiguration(PhyDevice::Identifier device_id, 102 rootcanal::configuration::Controller const& configuration); 103 104 // Let devices know about the passage of time 105 void Tick(); 106 void StartTimer(); 107 void StopTimer(); 108 void SetTimerPeriod(std::chrono::milliseconds new_period); 109 110 // List the devices that the test knows about 111 const std::string& List(); 112 113 // Clear all devices and phys. 114 void Reset(); 115 116 private: 117 Address GenerateBluetoothAddress(uint32_t device_id) const; 118 119 std::map<PhyLayer::Identifier, std::shared_ptr<PhyLayer>> phy_layers_; 120 std::map<PhyDevice::Identifier, std::shared_ptr<PhyDevice>> phy_devices_; 121 std::string list_string_; 122 123 // Generator for device identifiers. 124 bool reuse_device_addresses_{true}; 125 126 // Prefix used to generate public device addresses for hosts 127 // connecting over TCP. 128 std::array<uint8_t, 5> bluetooth_address_prefix_; 129 130 // Callbacks to schedule tasks. 131 std::function<AsyncUserId()> get_user_id_; 132 std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds, 133 const TaskCallback&)> 134 schedule_task_; 135 std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds, 136 std::chrono::milliseconds, const TaskCallback&)> 137 schedule_periodic_task_; 138 std::function<void(AsyncTaskId)> cancel_task_; 139 std::function<void(AsyncUserId)> cancel_tasks_from_user_; 140 std::function<std::shared_ptr<Device>(const std::string&, int, Phy::Type)> 141 connect_to_remote_; 142 143 AsyncUserId model_user_id_; 144 AsyncTaskId timer_tick_task_{kInvalidTaskId}; 145 std::chrono::milliseconds timer_period_{}; 146 }; 147 148 } // namespace rootcanal 149