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