discover-thread.cc
Go to the documentation of this file.
1 /*
2  * rcdiscover - the network discovery tool for Roboception devices
3  *
4  * Copyright (c) 2017 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 // placed here to make sure to include winsock2.h before windows.h
37 #include "rcdiscover/discover.h"
38 #include "rcdiscover/ping.h"
39 
40 #include "discover-thread.h"
41 
42 #include "discover-frame.h"
43 #include "event-ids.h"
44 #include "rcdiscover/utils.h"
45 
46 #include <vector>
47 #include <algorithm>
48 #include <future>
49 
50 #include <wx/window.h>
51 
52 wxThread::ExitCode DiscoverThread::Entry()
53 {
54  std::vector<wxVector<wxVariant>> device_list;
55 
56  try
57  {
58  rcdiscover::Discover discover;
59  discover.broadcastRequest();
60 
61  std::vector<rcdiscover::DeviceInfo> infos;
62 
63  while (discover.getResponse(infos, 100))
64  {}
65 
66  std::sort(infos.begin(), infos.end());
67  const auto it = std::unique(infos.begin(), infos.end(),
68  [](const rcdiscover::DeviceInfo &lhs,
69  const rcdiscover::DeviceInfo &rhs)
70  {
71  return lhs.getMAC() == rhs.getMAC() &&
72  lhs.getIfaceName() ==
73  rhs.getIfaceName();
74  });
75  infos.erase(it, infos.end());
76 
77  std::vector<std::future<bool>> reachable(infos.size());
78  std::transform(
79  infos.begin(), infos.end(), reachable.begin(),
80  [](const rcdiscover::DeviceInfo &info) {
81  return info.isValid()
82  ? std::async(
83  std::launch::async,
84  [&info] { return checkReachabilityOfSensor(info); })
85  : std::future<bool>{};
86  });
87 
88  const rcdiscover::DeviceInfo *last_info = nullptr;
89 
90  size_t i = 0;
91  for (auto info_it = infos.cbegin(); info_it != infos.cend(); ++info_it, ++i)
92  {
93  const auto& info = *info_it;
94  if (!info.isValid())
95  {
96  continue;
97  }
98 
99  if (last_info && last_info->getMAC() == info.getMAC())
100  {
101  device_list.back()[DiscoverFrame::IFACE] = wxVariant(
102  device_list.back()[DiscoverFrame::IFACE].GetString() + ',' +
103  info.getIfaceName());
104  continue;
105  }
106 
107  last_info = &info;
108 
109  const std::string &name = info.getUserName().empty()
110  ? info.getModelName()
111  : info.getUserName();
112 
113  const std::string &manufacturer = info.getManufacturerName();
114 
115  wxVector<wxVariant> data(DiscoverFrame::NUM_COLUMNS);
116  data[DiscoverFrame::NAME] = wxVariant(name);
117  data[DiscoverFrame::MANUFACTURER] = wxVariant(manufacturer);
118  data[DiscoverFrame::MODEL] = wxVariant(info.getModelName());
119  data[DiscoverFrame::SERIAL] = wxVariant(info.getSerialNumber());
120  data[DiscoverFrame::IP] = wxVariant(ip2string(info.getIP()));
121  data[DiscoverFrame::MAC] = wxVariant(mac2string(info.getMAC()));
122  data[DiscoverFrame::IFACE] = wxVariant(info.getIfaceName());
123  data[DiscoverFrame::REACHABLE] = wxVariant(
124  reachable[i].get() ? L"\u2713" : L"\u2717");
125 
126  device_list.push_back(std::move(data));
127  }
128  }
129  catch (const std::exception &ex)
130  {
131  wxThreadEvent event(wxEVT_COMMAND_DISCOVERY_ERROR);
132  event.SetString(ex.what());
133  parent_->GetEventHandler()->QueueEvent(event.Clone());
134 
135  return ExitCode(1);
136  }
137 
138  wxThreadEvent event(wxEVT_COMMAND_DISCOVERY_COMPLETED);
139  event.SetPayload(device_list);
140  parent_->GetEventHandler()->QueueEvent(event.Clone());
141 
142  return ExitCode(0);
143 }
std::string ip2string(const uint32_t ip)
Definition: utils.h:57
void broadcastRequest()
Broadcasts a discovery command request.
Definition: discover.cc:85
std::string mac2string(const uint64_t mac)
Definition: utils.h:45
virtual ExitCode Entry() override
wxWindow * parent_
bool getResponse(std::vector< DeviceInfo > &info, int timeout_per_socket=1000)
Returns a discovery response.
Definition: discover.cc:107
uint64_t getMAC() const
Returns 6 bytes with the MAC address of the device.
Definition: deviceinfo.h:96
bool checkReachabilityOfSensor(const DeviceInfo &info)
Check whether an device is reachable via ICMP.
Definition: ping.cc:95
const std::string & getUserName() const
Returns the user name.
Definition: deviceinfo.h:168
const std::string & getIfaceName() const
Returns the name of the interface on which this device was found.
Definition: deviceinfo.h:180


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