• 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 #define LOG_TAG "test_model"
18 
19 #include "test_model.h"
20 
21 // TODO: Remove when registration works
22 #include "model/devices/beacon.h"
23 #include "model/devices/beacon_swarm.h"
24 #include "model/devices/car_kit.h"
25 #include "model/devices/classic.h"
26 #include "model/devices/keyboard.h"
27 #include "model/devices/remote_loopback_device.h"
28 #include "model/devices/sniffer.h"
29 
30 #include <memory>
31 
32 #include <stdlib.h>
33 
34 #include <base/logging.h>
35 #include "base/files/file_util.h"
36 #include "base/json/json_reader.h"
37 #include "base/values.h"
38 
39 #include "osi/include/log.h"
40 #include "osi/include/osi.h"
41 
42 #include "device_boutique.h"
43 #include "include/phy.h"
44 #include "model/devices/hci_socket_device.h"
45 #include "model/devices/link_layer_socket_device.h"
46 
47 using std::vector;
48 
49 namespace test_vendor_lib {
50 
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)51 TestModel::TestModel(
52     std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> event_scheduler,
53 
54     std::function<AsyncTaskId(std::chrono::milliseconds, std::chrono::milliseconds, const TaskCallback&)>
55         periodic_event_scheduler,
56 
57     std::function<void(AsyncTaskId)> cancel, std::function<int(const std::string&, int)> connect_to_remote)
58     : schedule_task_(event_scheduler), schedule_periodic_task_(periodic_event_scheduler), cancel_task_(cancel),
59       connect_to_remote_(connect_to_remote) {
60   // TODO: Remove when registration works!
61   example_devices_.push_back(std::make_shared<Beacon>());
62   example_devices_.push_back(std::make_shared<BeaconSwarm>());
63   example_devices_.push_back(std::make_shared<Keyboard>());
64   example_devices_.push_back(std::make_shared<CarKit>());
65   example_devices_.push_back(std::make_shared<Classic>());
66   example_devices_.push_back(std::make_shared<Sniffer>());
67   example_devices_.push_back(std::make_shared<RemoteLoopbackDevice>());
68 }
69 
SetTimerPeriod(std::chrono::milliseconds new_period)70 void TestModel::SetTimerPeriod(std::chrono::milliseconds new_period) {
71   timer_period_ = new_period;
72 
73   if (timer_tick_task_ == kInvalidTaskId) return;
74 
75   // Restart the timer with the new period
76   StopTimer();
77   StartTimer();
78 }
79 
StartTimer()80 void TestModel::StartTimer() {
81   LOG_INFO(LOG_TAG, "StartTimer()");
82   timer_tick_task_ =
83       schedule_periodic_task_(std::chrono::milliseconds(0), timer_period_, [this]() { TestModel::TimerTick(); });
84 }
85 
StopTimer()86 void TestModel::StopTimer() {
87   LOG_INFO(LOG_TAG, "StopTimer()");
88   cancel_task_(timer_tick_task_);
89   timer_tick_task_ = kInvalidTaskId;
90 }
91 
Add(std::shared_ptr<Device> new_dev)92 size_t TestModel::Add(std::shared_ptr<Device> new_dev) {
93   devices_.push_back(new_dev);
94   return devices_.size() - 1;
95 }
96 
Del(size_t dev_index)97 void TestModel::Del(size_t dev_index) {
98   if (dev_index >= devices_.size()) {
99     LOG_WARN(LOG_TAG, "del: index out of range!");
100     return;
101   }
102   devices_.erase(devices_.begin() + dev_index);
103 }
104 
AddPhy(std::shared_ptr<PhyLayerFactory> new_phy)105 size_t TestModel::AddPhy(std::shared_ptr<PhyLayerFactory> new_phy) {
106   phys_.push_back(new_phy);
107   return phys_.size() - 1;
108 }
109 
DelPhy(size_t phy_index)110 void TestModel::DelPhy(size_t phy_index) {
111   if (phy_index >= phys_.size()) {
112     LOG_WARN(LOG_TAG, "del_phy: index %d out of range: ", static_cast<int>(phy_index));
113     return;
114   }
115 }
116 
AddDeviceToPhy(size_t dev_index,size_t phy_index)117 void TestModel::AddDeviceToPhy(size_t dev_index, size_t phy_index) {
118   if (dev_index >= devices_.size()) {
119     LOG_WARN(LOG_TAG, "add_device_to_phy: device out of range: ");
120     return;
121   }
122   if (phy_index >= phys_.size()) {
123     LOG_WARN(LOG_TAG, "add_device_to_phy: phy out of range: ");
124     return;
125   }
126   std::shared_ptr<Device> dev = devices_[dev_index];
127   dev->RegisterPhyLayer(
128       phys_[phy_index]->GetPhyLayer([dev](packets::LinkLayerPacketView packet) { dev->IncomingPacket(packet); }));
129 }
130 
DelDeviceFromPhy(size_t dev_index,size_t phy_index)131 void TestModel::DelDeviceFromPhy(size_t dev_index, size_t phy_index) {
132   if (dev_index >= devices_.size()) {
133     LOG_WARN(LOG_TAG, "del_device_from_phy: device out of range: ");
134     return;
135   }
136   if (phy_index >= phys_.size()) {
137     LOG_WARN(LOG_TAG, "del_device_from_phy: phy out of range: ");
138     return;
139   }
140 }
141 
AddLinkLayerConnection(int socket_fd,Phy::Type phy_type)142 void TestModel::AddLinkLayerConnection(int socket_fd, Phy::Type phy_type) {
143   std::shared_ptr<Device> dev = LinkLayerSocketDevice::Create(socket_fd, phy_type);
144   int index = Add(dev);
145   for (size_t phy_index = 0; phy_index < phys_.size(); phy_index++) {
146     if (phy_type == phys_[phy_index]->GetType()) {
147       AddDeviceToPhy(index, phy_index);
148     }
149   }
150 }
151 
IncomingLinkLayerConnection(int socket_fd)152 void TestModel::IncomingLinkLayerConnection(int socket_fd) {
153   // TODO: Handle other phys
154   AddLinkLayerConnection(socket_fd, Phy::Type::BR_EDR);
155 }
156 
AddRemote(const std::string & server,int port,Phy::Type phy_type)157 void TestModel::AddRemote(const std::string& server, int port, Phy::Type phy_type) {
158   int socket_fd = connect_to_remote_(server, port);
159   if (socket_fd < 0) {
160     return;
161   }
162   AddLinkLayerConnection(socket_fd, phy_type);
163 }
164 
IncomingHciConnection(int socket_fd)165 void TestModel::IncomingHciConnection(int socket_fd) {
166   std::shared_ptr<HciSocketDevice> dev = HciSocketDevice::Create(socket_fd);
167   // TODO: Auto-increment addresses?
168   static int hci_devs = 0;
169   int index = Add(std::static_pointer_cast<Device>(dev));
170   std::string addr = "da:4c:10:de:17:0";  // Da HCI dev
171   CHECK(hci_devs < 10) << "Why do you need more than 9?";
172   addr += '0' + hci_devs++;
173   dev->Initialize({"IgnoredTypeName", addr});
174   // TODO: Add device to all phys?  For now, just the first two.
175   for (size_t phy = 0; phy < 2 && phy < phys_.size(); phy++) {
176     AddDeviceToPhy(index, phy);
177   }
178   dev->RegisterTaskScheduler(schedule_task_);
179   dev->RegisterTaskCancel(cancel_task_);
180 }
181 
List()182 const std::string& TestModel::List() {
183   list_string_ = "";
184   list_string_ += " Devices: \r\n";
185   for (size_t dev = 0; dev < devices_.size(); dev++) {
186     list_string_ += "  " + std::to_string(dev) + ":";
187     list_string_ += devices_[dev]->ToString() + " \r\n";
188   }
189   list_string_ += " Phys: \r\n";
190   for (size_t phy = 0; phy < phys_.size(); phy++) {
191     list_string_ += "  " + std::to_string(phy) + ":";
192     list_string_ += phys_[phy]->ToString() + " \r\n";
193   }
194   return list_string_;
195 }
196 
TimerTick()197 void TestModel::TimerTick() {
198   for (size_t dev = 0; dev < devices_.size(); dev++) {
199     devices_[dev]->TimerTick();
200   }
201 }
202 
Reset()203 void TestModel::Reset() {
204   StopTimer();
205   devices_.clear();
206   phys_.clear();
207 }
208 
209 }  // namespace test_vendor_lib
210