• 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 #include "test_command_handler.h"
18 
19 #include <stdlib.h>
20 
21 #include <fstream>
22 #include <memory>
23 #include <regex>
24 
25 #include "device_boutique.h"
26 #include "log.h"
27 #include "phy.h"
28 #include "rootcanal/configuration.pb.h"
29 
30 using std::vector;
31 
32 namespace rootcanal {
33 
ParseIntParam(std::string const & in)34 static size_t ParseIntParam(std::string const& in) {
35   return static_cast<size_t>(std::strtoul(in.c_str(), nullptr, 0));
36 }
37 
TestCommandHandler(TestModel & test_model)38 TestCommandHandler::TestCommandHandler(TestModel& test_model) : model_(test_model) {
39 #define SET_HANDLER(command_name, method) \
40   active_commands_[command_name] = [this](const vector<std::string>& param) { method(param); };
41   SET_HANDLER("add", AddDevice);
42   SET_HANDLER("add_remote", AddRemote);
43   SET_HANDLER("del", RemoveDevice);
44   SET_HANDLER("add_phy", AddPhy);
45   SET_HANDLER("del_phy", RemovePhy);
46   SET_HANDLER("add_device_to_phy", AddDeviceToPhy);
47   SET_HANDLER("del_device_from_phy", RemoveDeviceFromPhy);
48   SET_HANDLER("list", List);
49   SET_HANDLER("set_device_address", SetDeviceAddress);
50   SET_HANDLER("set_device_configuration", SetDeviceConfiguration);
51   SET_HANDLER("set_timer_period", SetTimerPeriod);
52   SET_HANDLER("start_timer", StartTimer);
53   SET_HANDLER("stop_timer", StopTimer);
54   SET_HANDLER("reset", Reset);
55 #undef SET_HANDLER
56   send_response_ = [](std::string const&) {};
57 }
58 
AddDefaults()59 void TestCommandHandler::AddDefaults() {
60   // Add a phy for LE and one for BR/EDR
61   AddPhy({"LOW_ENERGY"});
62   AddPhy({"BR_EDR"});
63 
64   // Add the controller to the Phys
65   AddDeviceToPhy({"1", "1"});
66   AddDeviceToPhy({"1", "2"});
67 
68   // Add default test devices and add the devices to the phys
69   //
70   // Add({"beacon", "be:ac:10:00:00:01", "1000"});
71   // AddDeviceToPhy({"2", "1"});
72   //
73   // Add({"sniffer", "ca:12:1c:17:00:01"});
74   // AddDeviceToPhy({"3", "2"});
75   //
76   // Add({"sniffer", "3c:5a:b4:04:05:06"});
77   // AddDeviceToPhy({"4", "2"});
78 
79   List({});
80 
81   SetTimerPeriod({"10"});
82   StartTimer({});
83 }
84 
HandleCommand(const std::string & name,const vector<std::string> & args)85 void TestCommandHandler::HandleCommand(const std::string& name, const vector<std::string>& args) {
86   if (active_commands_.count(name) == 0) {
87     response_string_ = "Unhandled command: " + name;
88     send_response_(response_string_);
89     return;
90   }
91   active_commands_[name](args);
92 }
93 
RegisterSendResponse(const std::function<void (const std::string &)> callback)94 void TestCommandHandler::RegisterSendResponse(
95         const std::function<void(const std::string&)> callback) {
96   send_response_ = callback;
97   send_response_("RegisterSendResponse called");
98 }
99 
AddDevice(const vector<std::string> & args)100 void TestCommandHandler::AddDevice(const vector<std::string>& args) {
101   if (args.empty()) {
102     response_string_ = "TestCommandHandler 'add' takes an argument";
103     send_response_(response_string_);
104     return;
105   }
106   std::shared_ptr<Device> new_dev = DeviceBoutique::Create(args);
107 
108   if (new_dev == NULL) {
109     response_string_ = "TestCommandHandler 'add' " + args[0] + " failed!";
110     send_response_(response_string_);
111     WARNING("{}", response_string_);
112     return;
113   }
114 
115   INFO("Add {}", new_dev->ToString());
116   size_t dev_index = model_.AddDevice(new_dev);
117   response_string_ = std::to_string(dev_index) + std::string(":") + new_dev->ToString();
118   send_response_(response_string_);
119 }
120 
AddRemote(const vector<std::string> & args)121 void TestCommandHandler::AddRemote(const vector<std::string>& args) {
122   if (args.size() < 3) {
123     response_string_ = "TestCommandHandler usage: add_remote host port phy_type";
124     send_response_(response_string_);
125     return;
126   }
127 
128   size_t port = ParseIntParam(args[1]);
129   Phy::Type phy_type = Phy::Type::BR_EDR;
130   if ("LOW_ENERGY" == args[2]) {
131     phy_type = Phy::Type::LOW_ENERGY;
132   }
133   if (port == 0 || port > 0xffff || args[0].size() < 2) {
134     response_string_ = "TestCommandHandler bad arguments to 'add_remote': ";
135     response_string_ += args[0];
136     response_string_ += "@";
137     response_string_ += args[1];
138     send_response_(response_string_);
139     return;
140   }
141 
142   model_.AddRemote(args[0], port, phy_type);
143 
144   response_string_ = args[0] + std::string("@") + std::to_string(port);
145   send_response_(response_string_);
146 }
147 
RemoveDevice(const vector<std::string> & args)148 void TestCommandHandler::RemoveDevice(const vector<std::string>& args) {
149   size_t dev_index = ParseIntParam(args[0]);
150 
151   model_.RemoveDevice(dev_index);
152   response_string_ =
153           "TestCommandHandler 'del' called with device at index " + std::to_string(dev_index);
154   send_response_(response_string_);
155 }
156 
AddPhy(const vector<std::string> & args)157 void TestCommandHandler::AddPhy(const vector<std::string>& args) {
158   if (args.size() != 1) {
159     response_string_ = "TestCommandHandler 'add_phy' takes one argument";
160   } else if (args[0] == "LOW_ENERGY") {
161     model_.AddPhy(Phy::Type::LOW_ENERGY);
162     response_string_ = "TestCommandHandler 'add_phy' called with LOW_ENERGY";
163   } else if (args[0] == "BR_EDR") {
164     model_.AddPhy(Phy::Type::BR_EDR);
165     response_string_ = "TestCommandHandler 'add_phy' called with BR_EDR";
166   } else {
167     response_string_ = "TestCommandHandler 'add_phy' with unrecognized type " + args[0];
168   }
169   send_response_(response_string_);
170 }
171 
RemovePhy(const vector<std::string> & args)172 void TestCommandHandler::RemovePhy(const vector<std::string>& args) {
173   size_t phy_index = ParseIntParam(args[0]);
174 
175   model_.RemovePhy(phy_index);
176   response_string_ =
177           "TestCommandHandler 'del_phy' called with phy at index " + std::to_string(phy_index);
178   send_response_(response_string_);
179 }
180 
AddDeviceToPhy(const vector<std::string> & args)181 void TestCommandHandler::AddDeviceToPhy(const vector<std::string>& args) {
182   if (args.size() != 2) {
183     response_string_ = "TestCommandHandler 'add_device_to_phy' takes two arguments";
184     send_response_(response_string_);
185     return;
186   }
187   size_t dev_index = ParseIntParam(args[0]);
188   size_t phy_index = ParseIntParam(args[1]);
189   model_.AddDeviceToPhy(dev_index, phy_index);
190   response_string_ = "TestCommandHandler 'add_device_to_phy' called with device " +
191                      std::to_string(dev_index) + " and phy " + std::to_string(phy_index);
192   send_response_(response_string_);
193 }
194 
RemoveDeviceFromPhy(const vector<std::string> & args)195 void TestCommandHandler::RemoveDeviceFromPhy(const vector<std::string>& args) {
196   if (args.size() != 2) {
197     response_string_ = "TestCommandHandler 'del_device_from_phy' takes two arguments";
198     send_response_(response_string_);
199     return;
200   }
201   size_t dev_index = ParseIntParam(args[0]);
202   size_t phy_index = ParseIntParam(args[1]);
203   model_.RemoveDeviceFromPhy(dev_index, phy_index);
204   response_string_ = "TestCommandHandler 'del_device_from_phy' called with device " +
205                      std::to_string(dev_index) + " and phy " + std::to_string(phy_index);
206   send_response_(response_string_);
207 }
208 
List(const vector<std::string> & args)209 void TestCommandHandler::List(const vector<std::string>& args) {
210   if (!args.empty()) {
211     INFO("Unused args: arg[0] = {}", args[0]);
212     return;
213   }
214   send_response_(model_.List());
215 }
216 
SetDeviceAddress(const vector<std::string> & args)217 void TestCommandHandler::SetDeviceAddress(const vector<std::string>& args) {
218   if (args.size() != 2) {
219     response_string_ = "TestCommandHandler 'set_device_address' takes two arguments";
220     send_response_(response_string_);
221     return;
222   }
223   size_t device_id = ParseIntParam(args[0]);
224   Address device_address{};
225   Address::FromString(args[1], device_address);
226   model_.SetDeviceAddress(device_id, device_address);
227   response_string_ = "set_device_address " + args[0];
228   response_string_ += " ";
229   response_string_ += args[1];
230   send_response_(response_string_);
231 }
232 
SetDeviceConfiguration(const vector<std::string> & args)233 void TestCommandHandler::SetDeviceConfiguration(const vector<std::string>& args) {
234   if (args.size() != 2) {
235     response_string_ = "TestCommandHandler 'set_device_configuration' takes two arguments";
236     send_response_(response_string_);
237     return;
238   }
239   size_t device_id = ParseIntParam(args[0]);
240   rootcanal::configuration::ControllerPreset preset =
241           rootcanal::configuration::ControllerPreset::DEFAULT;
242 
243   if (args[1] == "default") {
244     preset = rootcanal::configuration::ControllerPreset::DEFAULT;
245   } else if (args[1] == "laird_bl654") {
246     preset = rootcanal::configuration::ControllerPreset::LAIRD_BL654;
247   } else if (args[1] == "csr_rck_pts_dongle") {
248     preset = rootcanal::configuration::ControllerPreset::CSR_RCK_PTS_DONGLE;
249   } else if (args[1] == "intel_be200") {
250     preset = rootcanal::configuration::ControllerPreset::INTEL_BE200;
251   } else {
252     response_string_ = "TestCommandHandler 'set_device_configuration' invalid configuration preset";
253     send_response_(response_string_);
254     return;
255   }
256 
257   rootcanal::configuration::Controller configuration;
258   configuration.set_preset(preset);
259   model_.SetDeviceConfiguration(device_id, configuration);
260   response_string_ = "set_device_configuration " + args[0];
261   response_string_ += " ";
262   response_string_ += args[1];
263   send_response_(response_string_);
264 }
265 
SetTimerPeriod(const vector<std::string> & args)266 void TestCommandHandler::SetTimerPeriod(const vector<std::string>& args) {
267   if (args.size() != 1) {
268     INFO("SetTimerPeriod takes 1 argument");
269   }
270   size_t period = ParseIntParam(args[0]);
271   if (period != 0) {
272     response_string_ = "set timer period to ";
273     response_string_ += args[0];
274     model_.SetTimerPeriod(std::chrono::milliseconds(period));
275   } else {
276     response_string_ = "invalid timer period ";
277     response_string_ += args[0];
278   }
279   send_response_(response_string_);
280 }
281 
StartTimer(const vector<std::string> & args)282 void TestCommandHandler::StartTimer(const vector<std::string>& args) {
283   if (!args.empty()) {
284     INFO("Unused args: arg[0] = {}", args[0]);
285   }
286   model_.StartTimer();
287   response_string_ = "timer started";
288   send_response_(response_string_);
289 }
290 
StopTimer(const vector<std::string> & args)291 void TestCommandHandler::StopTimer(const vector<std::string>& args) {
292   if (!args.empty()) {
293     INFO("Unused args: arg[0] = {}", args[0]);
294   }
295   model_.StopTimer();
296   response_string_ = "timer stopped";
297   send_response_(response_string_);
298 }
299 
Reset(const std::vector<std::string> & args)300 void TestCommandHandler::Reset(const std::vector<std::string>& args) {
301   if (!args.empty()) {
302     INFO("Unused args: arg[0] = {}", args[0]);
303   }
304   model_.Reset();
305   response_string_ = "model reset";
306   send_response_(response_string_);
307 }
308 
309 }  // namespace rootcanal
310