• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
27 #include "hci/address.h"                       // for Address
28 #include "model/devices/hci_device.h"          // for HciDevice
29 #include "model/setup/async_manager.h"         // for AsyncUserId, AsyncTaskId
30 #include "phy.h"                               // for Phy, Phy::Type
31 #include "phy_layer.h"
32 
33 namespace rootcanal {
34 class Device;
35 
36 using ::bluetooth::hci::Address;
37 
38 class TestModel {
39  public:
40   TestModel(
41       std::function<AsyncUserId()> get_user_id,
42       std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds,
43                                 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,
53                                                          0x17});
54   virtual ~TestModel();
55 
56   TestModel(TestModel& model) = delete;
57   TestModel& operator=(const TestModel& model) = delete;
58 
SetReuseDeviceIds(bool reuse_device_ids)59   void SetReuseDeviceIds(bool reuse_device_ids) {
60     reuse_device_ids_ = reuse_device_ids;
61   }
62 
63   // Allow derived classes to use custom phy layer.
64   virtual std::unique_ptr<PhyLayer> CreatePhyLayer(PhyLayer::Identifier id,
65                                                    Phy::Type type);
66 
67   // Allow derived classes to use custom phy devices.
68   virtual std::shared_ptr<PhyDevice> CreatePhyDevice(
69       PhyDevice::Identifier id, std::string type,
70       std::shared_ptr<Device> device);
71 
72   // Test model commands
73 
74   PhyDevice::Identifier AddDevice(std::shared_ptr<Device> device);
75   void RemoveDevice(PhyDevice::Identifier id);
76   PhyLayer::Identifier AddPhy(Phy::Type type);
77   void RemovePhy(PhyLayer::Identifier id);
78   void AddDeviceToPhy(PhyDevice::Identifier device_id,
79                       PhyLayer::Identifier phy_id);
80   void RemoveDeviceFromPhy(PhyDevice::Identifier device_id,
81                            PhyLayer::Identifier phy_id);
82 
83   // Runtime implementation.
84 
85   // Handle incoming remote connections
86   void AddLinkLayerConnection(std::shared_ptr<Device> dev, Phy::Type phy_type);
87   // Add an HCI device, return its index
88   PhyDevice::Identifier AddHciConnection(std::shared_ptr<HciDevice> dev);
89 
90   // Handle closed remote connections (both hci & link layer)
91   void OnConnectionClosed(PhyDevice::Identifier device_id, AsyncUserId user_id);
92 
93   // Connect to a remote device
94   void AddRemote(const std::string& server, int port, Phy::Type phy_type);
95 
96   // Set the device's Bluetooth address
97   void SetDeviceAddress(PhyDevice::Identifier device_id,
98                         Address device_address);
99 
100   // Let devices know about the passage of time
101   void Tick();
102   void StartTimer();
103   void StopTimer();
104   void SetTimerPeriod(std::chrono::milliseconds new_period);
105 
106   // List the devices that the test knows about
107   const std::string& List();
108 
109   // Clear all devices and phys.
110   void Reset();
111 
112  private:
113   std::map<PhyLayer::Identifier, std::shared_ptr<PhyLayer>> phy_layers_;
114   std::map<PhyDevice::Identifier, std::shared_ptr<PhyDevice>> phy_devices_;
115   std::string list_string_;
116 
117   // Generator for device identifiers.
118   PhyDevice::Identifier next_device_id_{0};
119   bool reuse_device_ids_{true};
120 
121   // Prefix used to generate public device addresses for hosts
122   // connecting over TCP.
123   std::array<uint8_t, 5> bluetooth_address_prefix_;
124 
125   // Callbacks to schedule tasks.
126   std::function<AsyncUserId()> get_user_id_;
127   std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds,
128                             const TaskCallback&)>
129       schedule_task_;
130   std::function<AsyncTaskId(AsyncUserId, std::chrono::milliseconds,
131                             std::chrono::milliseconds, const TaskCallback&)>
132       schedule_periodic_task_;
133   std::function<void(AsyncTaskId)> cancel_task_;
134   std::function<void(AsyncUserId)> cancel_tasks_from_user_;
135   std::function<std::shared_ptr<Device>(const std::string&, int, Phy::Type)>
136       connect_to_remote_;
137 
138   AsyncUserId model_user_id_;
139   AsyncTaskId timer_tick_task_{kInvalidTaskId};
140   std::chrono::milliseconds timer_period_{};
141 };
142 
143 }  // namespace rootcanal
144