49 #include <sys/socket.h> 50 #include <sys/types.h> 52 #include <arpa/inet.h> 73 sockets_(
SocketType::createAndBindForAllInterfaces(3956))
77 socket.enableBroadcast();
78 socket.enableNonBlocking();
89 std::vector<uint8_t> discovery_cmd{0x42, 0x11, 0, 0x02, 0, 0, 0, 0};
94 std::tie(discovery_cmd[6], discovery_cmd[7]) =
req_nums_.back();
98 socket.send(discovery_cmd);
108 int timeout_per_socket)
113 tv.tv_sec=timeout_per_socket/1000;
114 tv.tv_usec=(timeout_per_socket%1000)*1000;
120 std::vector<std::future<DeviceInfo>> futures;
123 futures.push_back(std::async(std::launch::async, [&socket, &tv, &req_nums]
125 DeviceInfo device_info(socket.getIfaceName());
136 while (!device_info.isValid() && count > 0)
140 if (select(sock+1, &fds, NULL, NULL, &tv) > 0)
146 struct sockaddr_in addr;
148 int naddr =
sizeof(addr);
150 socklen_t naddr =
sizeof(addr);
152 memset(&addr, 0, naddr);
154 long n = recvfrom(sock,
155 reinterpret_cast<char *>(p),
sizeof(p), 0,
156 reinterpret_cast<struct sockaddr *>(&addr), &naddr);
162 if (p[0] == 0 && p[1] == 0 && p[2] == 0 &&
165 if (std::find(req_nums.begin(), req_nums.end(),
166 std::make_tuple(p[6], p[7])) != req_nums.end())
168 size_t len=(
static_cast<size_t>(p[4])<<8)|p[5];
170 if (static_cast<size_t>(n) >= len+8)
174 device_info.set(p+8, len);
192 for (
auto &f : futures)
194 info.push_back(f.get());
195 ret |= info.back().isValid();
std::vector< SocketType > sockets_
Discover()
Initializes a socket ready for broadcasting requests.
void clear()
Clears all information.
std::vector< std::tuple< std::uint8_t, std::uint8_t > > req_nums_
int SocketType
Type representing the native socket handle type.
Exception representing a Network Unreachable error (code 101 on Unix).
void broadcastRequest()
Broadcasts a discovery command request.
bool getResponse(std::vector< DeviceInfo > &info, int timeout_per_socket=1000)
Returns a discovery response.
Socket implementation for Linux.
static std::tuple< uint8_t, uint8_t > getNext()
Returns the next request number.