rcdiscover_reset.cc
Go to the documentation of this file.
1 /*
2  * rcdiscover - the network discovery tool for Roboception devices
3  *
4  * Copyright (c) 2018 Roboception GmbH
5  * All rights reserved
6  *
7  * Author: Raphael Schaller
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the copyright holder nor the names of its contributors
20  * may be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include "rcdiscover_reset.h"
37 
38 #include "cli_utils.h"
39 
40 #include <rcdiscover/discover.h>
41 #include <rcdiscover/wol.h>
42 
43 #include <stdexcept>
44 #include <iostream>
45 #include <algorithm>
46 #include <map>
47 
49 {
50  std::string description;
51  std::string action;
52  std::uint8_t id;
53 };
54 
55 static const std::map<std::string, ResetCommand> reset_commands
56  {
57  {"parameters", {"Reset parameters", "Resetting parameters", 0xAA}},
58  {"network", {"Reset network parameters", "Resetting parameters", 0xBB}},
59  {"all", {"Reset parameters and network parameters", "Resetting all", 0xFF}},
60  {"switch-partition", {"Switch partition", "Switching partition", 0xCC}}
61  };
62 
63 static void printHelp(std::ostream &os, const std::string &command)
64 {
65  os << "Usage: ";
66  os << command << " <operation> [<args>]\n";
67  os << '\n';
68  os << "Available operations are:\n";
69  const int max_command_len = getMaxCommandLen(reset_commands);
70  for (const auto &cmd : reset_commands)
71  {
72  const int min_padding = 3;
73  const int padding = max_command_len + min_padding -
74  static_cast<int>(cmd.first.length());
75  os << " " << cmd.first;
76  os << std::string(static_cast<std::size_t>(padding), ' ');
77  os << cmd.second.description << '\n';
78  }
79  os << '\n';
80  os << "Available arguments are:\n";
81  os << " -h, --help Show this help and exit\n";
82  os << " -f name=<name> Filter by name\n";
83  os << " -f serial=<serial> Filter by serial number\n";
84  os << " -f mac=<mac> Filter by MAC address\n";
85  os << " -f iface=<mac> Filter by interface name\n";
86  os << " -f model=<model> Filter by model name\n";
87  os << " -y Assume 'yes' for all queries\n";
88 }
89 
90 int runReset(const std::string &command, int argc, char **argv)
91 {
92  DeviceFilter device_filter{};
93  bool yes = false;
94 
95  if (argc == 0)
96  {
97  std::cerr << "No operation specified\n";
98  printHelp(std::cerr, command);
99  return 1;
100  }
101 
102  const std::string argv_0 = argv[0];
103  if (argv_0 == "-h" || argv_0 == "--help")
104  {
105  printHelp(std::cout, command);
106  return 0;
107  }
108 
109  const auto reset_command = reset_commands.find(argv_0);
110  if (reset_command == std::end(reset_commands))
111  {
112  std::cout << "Invalid operation specified\n";
113  printHelp(std::cerr, command);
114  return 1;
115  }
116 
117  int i = 1;
118  while (i < argc)
119  {
120  std::string p = argv[i++];
121 
122  if (p == "-y")
123  {
124  yes = true;
125  }
126  else if (p == "-f")
127  {
128  try
129  {
130  i += parseFilterArguments(argc - i, argv + i, device_filter);
131  }
132  catch (const std::invalid_argument &ex)
133  {
134  std::cerr << ex.what() << std::endl;
135  printHelp(std::cerr, command);
136  return 1;
137  }
138  }
139  else if (p == "-h" || p == "--help")
140  {
141  printHelp(std::cout, command);
142  return 0;
143  }
144  else
145  {
146  std::cerr << "Invalid argument: " << p << '\n';
147  printHelp(std::cerr, command);
148  return 1;
149  }
150  }
151 
152  if (device_filter.mac.empty() &&
153  device_filter.name.empty() &&
154  device_filter.serial.empty())
155  {
156  std::cerr << "No filter set" << std::endl;
157  printHelp(std::cerr, command);
158  return 1;
159  }
160  const auto devices = discoverWithFilter(device_filter);
161 
162  if (devices.empty())
163  {
164  std::cout << "No device found" << std::endl;
165  return 0;
166  }
167 
168  std::cout << reset_command->second.action << " of the following devices:\n";
169  printDeviceTable(std::cout, devices, true, false, false);
170 
171  if (!yes)
172  {
173  std::cout << "Are you sure? [y/N] ";
174  std::string answer;
175  std::getline(std::cin, answer);
176  if (answer != "y" && answer != "Y")
177  {
178  std::cout << "Cancel" << std::endl;
179  return 0;
180  }
181  }
182 
183  for (const auto &device : devices)
184  {
185  rcdiscover::WOL wol(device.getMAC(), 9);
186  wol.send({{0xEE, 0xEE, 0xEE, reset_command->second.id}});
187  }
188 
189  std::cout << "Done" << std::endl;
190 
191  return 0;
192 }
std::vector< rcdiscover::DeviceInfo > discoverWithFilter(const DeviceFilter &filter)
Definition: cli_utils.cc:110
void printDeviceTable(std::ostream &oss, const std::vector< rcdiscover::DeviceInfo > &devices, bool print_header, bool iponly, bool serialonly)
Definition: cli_utils.cc:174
int runReset(const std::string &command, int argc, char **argv)
static void printHelp(std::ostream &os, const std::string &command)
int getMaxCommandLen(const std::map< K, V > &commands)
Definition: cli_utils.h:70
std::string description
Class for Magic Packet (Wake-on-Lan (WOL)) reset of device.
Definition: wol.h:62
int parseFilterArguments(int argc, char **argv, DeviceFilter &filter)
Definition: cli_utils.cc:44
static const std::map< std::string, ResetCommand > reset_commands
std::string action
std::uint8_t id
void send() const
Send Magic Packet without any data ("password").
Definition: wol.cc:59


rcdiscover
Author(s): Heiko Hirschmueller , Raphael Schaller
autogenerated on Sun Apr 18 2021 02:16:32