• 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 
29 using std::vector;
30 
31 namespace rootcanal {
32 
TestCommandHandler(TestModel & test_model)33 TestCommandHandler::TestCommandHandler(TestModel& test_model)
34     : model_(test_model) {
35 #define SET_HANDLER(command_name, method)                                     \
36   active_commands_[command_name] = [this](const vector<std::string>& param) { \
37     method(param);                                                            \
38   };
39   SET_HANDLER("add", AddDevice);
40   SET_HANDLER("add_remote", AddRemote);
41   SET_HANDLER("del", RemoveDevice);
42   SET_HANDLER("add_phy", AddPhy);
43   SET_HANDLER("del_phy", RemovePhy);
44   SET_HANDLER("add_device_to_phy", AddDeviceToPhy);
45   SET_HANDLER("del_device_from_phy", RemoveDeviceFromPhy);
46   SET_HANDLER("list", List);
47   SET_HANDLER("set_device_address", SetDeviceAddress);
48   SET_HANDLER("set_timer_period", SetTimerPeriod);
49   SET_HANDLER("start_timer", StartTimer);
50   SET_HANDLER("stop_timer", StopTimer);
51   SET_HANDLER("reset", Reset);
52 #undef SET_HANDLER
53   send_response_ = [](std::string const&) {};
54 }
55 
AddDefaults()56 void TestCommandHandler::AddDefaults() {
57   // Add a phy for LE and one for BR/EDR
58   AddPhy({"LOW_ENERGY"});
59   AddPhy({"BR_EDR"});
60 
61   // Add the controller to the Phys
62   AddDeviceToPhy({"1", "1"});
63   AddDeviceToPhy({"1", "2"});
64 
65   // Add default test devices and add the devices to the phys
66   //
67   // Add({"beacon", "be:ac:10:00:00:01", "1000"});
68   // AddDeviceToPhy({"2", "1"});
69   //
70   // Add({"sniffer", "ca:12:1c:17:00:01"});
71   // AddDeviceToPhy({"3", "2"});
72   //
73   // Add({"sniffer", "3c:5a:b4:04:05:06"});
74   // AddDeviceToPhy({"4", "2"});
75 
76   List({});
77 
78   SetTimerPeriod({"10"});
79   StartTimer({});
80 }
81 
HandleCommand(const std::string & name,const vector<std::string> & args)82 void TestCommandHandler::HandleCommand(const std::string& name,
83                                        const vector<std::string>& args) {
84   if (active_commands_.count(name) == 0) {
85     response_string_ = "Unhandled command: " + name;
86     send_response_(response_string_);
87     return;
88   }
89   active_commands_[name](args);
90 }
91 
RegisterSendResponse(const std::function<void (const std::string &)> callback)92 void TestCommandHandler::RegisterSendResponse(
93     const std::function<void(const std::string&)> callback) {
94   send_response_ = callback;
95   send_response_("RegisterSendResponse called");
96 }
97 
AddDevice(const vector<std::string> & args)98 void TestCommandHandler::AddDevice(const vector<std::string>& args) {
99   if (args.empty()) {
100     response_string_ = "TestCommandHandler 'add' takes an argument";
101     send_response_(response_string_);
102     return;
103   }
104   std::shared_ptr<Device> new_dev = DeviceBoutique::Create(args);
105 
106   if (new_dev == NULL) {
107     response_string_ = "TestCommandHandler 'add' " + args[0] + " failed!";
108     send_response_(response_string_);
109     LOG_WARN("%s", response_string_.c_str());
110     return;
111   }
112 
113   LOG_INFO("Add %s", new_dev->ToString().c_str());
114   size_t dev_index = model_.AddDevice(new_dev);
115   response_string_ =
116       std::to_string(dev_index) + std::string(":") + new_dev->ToString();
117   send_response_(response_string_);
118 }
119 
AddRemote(const vector<std::string> & args)120 void TestCommandHandler::AddRemote(const vector<std::string>& args) {
121   if (args.size() < 3) {
122     response_string_ =
123         "TestCommandHandler usage: add_remote host port phy_type";
124     send_response_(response_string_);
125     return;
126   }
127 
128   size_t port = std::stoi(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 = std::stoi(args[0]);
150 
151   model_.RemoveDevice(dev_index);
152   response_string_ = "TestCommandHandler 'del' called with device at index " +
153                      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_ =
168         "TestCommandHandler 'add_phy' with unrecognized type " + args[0];
169   }
170   send_response_(response_string_);
171 }
172 
RemovePhy(const vector<std::string> & args)173 void TestCommandHandler::RemovePhy(const vector<std::string>& args) {
174   size_t phy_index = std::stoi(args[0]);
175 
176   model_.RemovePhy(phy_index);
177   response_string_ = "TestCommandHandler 'del_phy' called with phy at index " +
178                      std::to_string(phy_index);
179   send_response_(response_string_);
180 }
181 
AddDeviceToPhy(const vector<std::string> & args)182 void TestCommandHandler::AddDeviceToPhy(const vector<std::string>& args) {
183   if (args.size() != 2) {
184     response_string_ =
185         "TestCommandHandler 'add_device_to_phy' takes two arguments";
186     send_response_(response_string_);
187     return;
188   }
189   size_t dev_index = std::stoi(args[0]);
190   size_t phy_index = std::stoi(args[1]);
191   model_.AddDeviceToPhy(dev_index, phy_index);
192   response_string_ =
193       "TestCommandHandler 'add_device_to_phy' called with device " +
194       std::to_string(dev_index) + " and phy " + std::to_string(phy_index);
195   send_response_(response_string_);
196 }
197 
RemoveDeviceFromPhy(const vector<std::string> & args)198 void TestCommandHandler::RemoveDeviceFromPhy(const vector<std::string>& args) {
199   if (args.size() != 2) {
200     response_string_ =
201         "TestCommandHandler 'del_device_from_phy' takes two arguments";
202     send_response_(response_string_);
203     return;
204   }
205   size_t dev_index = std::stoi(args[0]);
206   size_t phy_index = std::stoi(args[1]);
207   model_.RemoveDeviceFromPhy(dev_index, phy_index);
208   response_string_ =
209       "TestCommandHandler 'del_device_from_phy' called with device " +
210       std::to_string(dev_index) + " and phy " + std::to_string(phy_index);
211   send_response_(response_string_);
212 }
213 
List(const vector<std::string> & args)214 void TestCommandHandler::List(const vector<std::string>& args) {
215   if (!args.empty()) {
216     LOG_INFO("Unused args: arg[0] = %s", args[0].c_str());
217     return;
218   }
219   send_response_(model_.List());
220 }
221 
SetDeviceAddress(const vector<std::string> & args)222 void TestCommandHandler::SetDeviceAddress(const vector<std::string>& args) {
223   if (args.size() != 2) {
224     response_string_ =
225         "TestCommandHandler 'set_device_address' takes two arguments";
226     send_response_(response_string_);
227     return;
228   }
229   size_t device_id = std::stoi(args[0]);
230   Address device_address{};
231   Address::FromString(args[1], device_address);
232   model_.SetDeviceAddress(device_id, device_address);
233   response_string_ = "set_device_address " + args[0];
234   response_string_ += " ";
235   response_string_ += args[1];
236   send_response_(response_string_);
237 }
238 
SetTimerPeriod(const vector<std::string> & args)239 void TestCommandHandler::SetTimerPeriod(const vector<std::string>& args) {
240   if (args.size() != 1) {
241     LOG_INFO("SetTimerPeriod takes 1 argument");
242   }
243   size_t period = std::stoi(args[0]);
244   if (period != 0) {
245     response_string_ = "set timer period to ";
246     response_string_ += args[0];
247     model_.SetTimerPeriod(std::chrono::milliseconds(period));
248   } else {
249     response_string_ = "invalid timer period ";
250     response_string_ += args[0];
251   }
252   send_response_(response_string_);
253 }
254 
StartTimer(const vector<std::string> & args)255 void TestCommandHandler::StartTimer(const vector<std::string>& args) {
256   if (!args.empty()) {
257     LOG_INFO("Unused args: arg[0] = %s", args[0].c_str());
258   }
259   model_.StartTimer();
260   response_string_ = "timer started";
261   send_response_(response_string_);
262 }
263 
StopTimer(const vector<std::string> & args)264 void TestCommandHandler::StopTimer(const vector<std::string>& args) {
265   if (!args.empty()) {
266     LOG_INFO("Unused args: arg[0] = %s", args[0].c_str());
267   }
268   model_.StopTimer();
269   response_string_ = "timer stopped";
270   send_response_(response_string_);
271 }
272 
Reset(const std::vector<std::string> & args)273 void TestCommandHandler::Reset(const std::vector<std::string>& args) {
274   if (!args.empty()) {
275     LOG_INFO("Unused args: arg[0] = %s", args[0].c_str());
276   }
277   model_.Reset();
278   response_string_ = "model reset";
279   send_response_(response_string_);
280 }
281 
282 }  // namespace rootcanal
283