22 #if defined(__GNUC__) // GCC compiler
23 # pragma GCC diagnostic push // Save warning levels for later restoration
24 # pragma GCC diagnostic ignored "-Wpragmas"
25 # pragma GCC diagnostic ignored "-Wsign-conversion"
26 # pragma GCC diagnostic ignored "-Wold-style-cast"
27 # pragma GCC diagnostic ignored "-Wdeprecated-copy"
28 # pragma GCC diagnostic ignored "-Wshadow"
29 # pragma GCC diagnostic ignored "-Wparentheses"
30 # pragma GCC diagnostic ignored "-Wcast-align"
31 # pragma GCC diagnostic ignored "-Wstrict-overflow"
32 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
38 #if defined(__GNUC__) // GCC compiler
39 # pragma GCC diagnostic pop // Restore previous warning levels
58 std::random_device rd;
59 std::default_random_engine mt(rd());
60 std::uint32_t teleIdCounter = mt();
61 std::vector<VisionaryAutoIPScan::DeviceInfo> deviceList;
63 std::unique_ptr<UdpSocket> pTransport(
new UdpSocket());
71 std::string broadcastAddress{};
73 constexpr std::size_t kIpAddrVectorSize{4u};
74 for (std::size_t
i = 0;
i < kIpAddrVectorSize; ++
i)
77 std::to_string((~maskVector[
i] & 0xff) | ipAddrVector[
i]) + (
i + 1u == kIpAddrVectorSize ?
"" :
".");
79 if (pTransport->connect(broadcastAddress, port) != 0)
86 autoIpPacket.push_back(0x10);
87 autoIpPacket.push_back(0x00);
89 autoIpPacket.push_back(0x00);
90 autoIpPacket.push_back(0x08);
92 autoIpPacket.push_back(0xFF);
93 autoIpPacket.push_back(0xFF);
94 autoIpPacket.push_back(0xFF);
95 autoIpPacket.push_back(0xFF);
96 autoIpPacket.push_back(0xFF);
97 autoIpPacket.push_back(0xFF);
99 autoIpPacket.push_back(0x0);
100 autoIpPacket.push_back(0x0);
101 autoIpPacket.push_back(0x0);
102 autoIpPacket.push_back(0x0);
105 autoIpPacket.push_back(0x01);
106 autoIpPacket.push_back(0x0);
109 autoIpPacket.insert(autoIpPacket.end(), ipAddrVector.begin(), ipAddrVector.end());
112 autoIpPacket.insert(autoIpPacket.end(), maskVector.begin(), maskVector.end());
115 std::uint32_t curtelegramID = teleIdCounter++;
116 writeUnalignBigEndian<std::uint32_t>(autoIpPacket.data() + 10u,
sizeof(curtelegramID), curtelegramID);
119 pTransport->send(autoIpPacket);
122 const std::chrono::steady_clock::time_point startTime(std::chrono::steady_clock::now());
126 const std::chrono::steady_clock::time_point now(std::chrono::steady_clock::now());
127 if ((now - startTime) > std::chrono::milliseconds(timeOut))
129 std::cout << __FUNCTION__ <<
" Timeout" <<
'\n';
132 if (pTransport->recv(receiveBuffer, 1400) > 16)
134 unsigned int pos = 0;
138 deviceList.push_back(dI);
145 std::uint16_t payLoadSize = readUnalignBigEndian<std::uint16_t>(receiveBuffer.data() + pos);
148 std::uint32_t recvTelegramID = readUnalignBigEndian<std::uint32_t>(receiveBuffer.data() + pos);
151 if (recvTelegramID != curtelegramID)
157 if (receiveBuffer.size() >= pos + payLoadSize)
159 std::stringstream stringStream(std::string(
reinterpret_cast<char*
>(&receiveBuffer[pos]), payLoadSize));
163 deviceList.push_back(dI);
171 std::cout << __FUNCTION__ <<
"Received invalid AutoIP Packet" <<
'\n';
183 const std::string& macAddress = tree.
get_child(
"NetScanResult.<xmlattr>.MACAddr").
get_value<std::string>();
184 std::string ipAddress;
187 std::string deviceType;
189 for (
const auto& it : tree.
get_child(
"NetScanResult"))
191 if (it.first !=
"<xmlattr>")
193 const std::string& key = it.second.get<std::string>(
"<xmlattr>.key");
194 const std::string& value = it.second.get<std::string>(
"<xmlattr>.value");
195 if (key ==
"IPAddress")
205 if (key ==
"HostPortNo")
210 if (key ==
"DeviceType")
220 std::size_t idx = 0u;
221 unsigned long portul = std::stoul(port, &idx);
222 if ((idx < port.length()) || (portul > std::numeric_limits<std::uint16_t>::max()) || (portul == 0u))
225 std::cerr <<
"invalid port number '" << port <<
"' (must be an unsigned number in range 1..65535) for "
226 << deviceType <<
" device at ip " << ipAddress << std::endl;
231 dI.
port =
static_cast<std::uint16_t
>(portul);
250 auto cidNameLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
253 for (
int i = 0;
i < cidNameLen; ++
i)
255 cidName += readUnalignBigEndian<char>(buffer.data() + offset);
278 auto deviceNameLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
280 std::string deviceName(
reinterpret_cast<const char*
>(buffer.data() + offset), deviceNameLen);
281 offset += deviceNameLen;
284 auto appNameLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
286 std::string appName(
reinterpret_cast<const char*
>(buffer.data() + offset), appNameLen);
287 offset += appNameLen;
290 auto projNameLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
292 std::string projName(
reinterpret_cast<const char*
>(buffer.data() + offset), projNameLen);
293 offset += projNameLen;
296 auto serialNumLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
298 std::string serialNum(
reinterpret_cast<const char*
>(buffer.data() + offset), serialNumLen);
299 offset += serialNumLen;
302 auto typeCodeLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
304 std::string typeCode(
reinterpret_cast<const char*
>(buffer.data() + offset), typeCodeLen);
305 offset += typeCodeLen;
308 auto firmwareVersionLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
310 std::string firmwareVersion(
reinterpret_cast<const char*
>(buffer.data() + offset), firmwareVersionLen);
311 offset += firmwareVersionLen;
314 auto orderNumberLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
316 std::string orderNumber(
reinterpret_cast<const char*
>(buffer.data() + offset), orderNumberLen);
317 offset += orderNumberLen;
322 auto auxArrayLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
325 for (
int i = 0;
i < auxArrayLen; ++
i)
328 for (
int k = 0; k < 4; ++k)
330 key += readUnalignBigEndian<char>(buffer.data() + offset);
333 auto innerArrayLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
335 for (
int j = 0; j < innerArrayLen; ++j)
341 auto scanIfLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
343 for (
int i = 0;
i < scanIfLen; ++
i)
347 auto ifaceNameLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
349 std::string ifaceName(
reinterpret_cast<const char*
>(buffer.data() + offset), ifaceNameLen);
350 offset += ifaceNameLen;
352 auto comSettingsLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
355 for (
int i = 0;
i < comSettingsLen; ++
i)
358 for (
int k = 0; k < 4; ++k)
360 key += readUnalignBigEndian<char>(buffer.data() + offset);
363 auto innerArrayLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
374 for (
int k = 0; k < 4; ++k)
376 ipAddr += std::to_string(
static_cast<unsigned>(readUnalignBigEndian<uint8_t>(buffer.data() + offset)));
389 for (
int k = 0; k < 4; ++k)
391 subNet += std::to_string(
static_cast<unsigned>(readUnalignBigEndian<uint8_t>(buffer.data() + offset)));
398 deviceInfo.
subNet = subNet;
404 for (
int k = 0; k < 4; ++k)
406 stdGw += std::to_string(
static_cast<unsigned>(readUnalignBigEndian<char>(buffer.data() + offset)));
427 for (
int j = 0; j < innerArrayLen; ++j)
433 auto endPointsLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
436 std::vector<std::uint16_t> ports;
437 for (
int i = 0;
i < endPointsLen; ++
i)
441 auto innerArrayLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
443 for (
int j = 0; j < innerArrayLen; ++j)
445 std::string key(
reinterpret_cast<const char*
>(buffer.data() + offset), 4u);
448 auto mostInnerArrayLen = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
453 auto port = readUnalignBigEndian<std::uint16_t>(buffer.data() + offset);
455 ports.push_back(port);
459 for (
int k = 0; k < mostInnerArrayLen; ++k)
469 deviceInfo.
port = ports[0];
484 std::bitset<32> hostPrefix(0xffffffffull << (32u - prefixLength));
485 std::bitset<32> mask(0xff000000);
487 std::string hostMask{};
489 constexpr std::size_t kIpAddressLength{32u};
490 for (std::size_t
i = 0;
i < kIpAddressLength;
i += 8u)
493 std::to_string((((hostPrefix <<
i & mask) >> 24u).to_ulong())) + (
i + 8u == kIpAddressLength ?
"" :
".");
501 std::vector<std::uint8_t> ipInts;
502 std::istringstream ss(address);
506 if (!getline(ss, token,
'.'))
508 ipInts.push_back(
static_cast<uint8_t
>(std::stoi(token)));
515 const std::string& ipAddr,
516 std::uint8_t prefixLength,
517 const std::string& ipGateway,
519 unsigned int timeout)
521 if (colaVer != ProtocolType::COLA_B && colaVer != ProtocolType::COLA_2)
529 if (colaVer == ProtocolType::COLA_B)
531 std::string dhcpString =
"FALSE";
536 std::string request =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
538 "<Item key=\"IPAddress\" value=\"" + ipAddr +
"\" />"
539 "<Item key=\"IPMask\" value=\"" + ipMask +
"\" />"
540 "<Item key=\"IPGateway\" value=\"" + ipGateway +
"\" />"
541 "<Item key=\"DHCPClientEnabled\" value=\"" + dhcpString +
"\" /></IPconfig>";
543 payload.insert(payload.end(), request.c_str(), request.c_str() + request.size());
545 else if (colaVer ==
COLA_2)
548 payload.insert(payload.end(), ipAddrVector.begin(), ipAddrVector.end());
551 payload.insert(payload.end(), ipMaskVector.begin(), ipMaskVector.end());
554 payload.insert(payload.end(), ipGatewayVector.begin(), ipGatewayVector.end());
556 payload.push_back(dhcp);
560 std::random_device rd;
561 std::default_random_engine mt(rd());
562 unsigned int teleIdCounter = mt();
564 std::unique_ptr<UdpSocket> pTransport(
new UdpSocket());
569 std::string broadcastAddress{};
571 constexpr std::size_t kIpAddrVectorSize{4u};
572 for (std::size_t
i = 0;
i < kIpAddrVectorSize; ++
i)
575 std::to_string((~maskVector[
i] & 0xff) | addrVector[
i]) + (
i + 1u == kIpAddrVectorSize ?
"" :
".");
578 if (pTransport->connect(broadcastAddress,
DEFAULT_PORT) != 0)
585 autoIpPacket.push_back(0x11);
586 autoIpPacket.push_back(0x0);
589 std::uint8_t blockLenght[2];
591 autoIpPacket.insert(autoIpPacket.end(), blockLenght, blockLenght + 2u);
594 autoIpPacket.insert(autoIpPacket.end(), destinationMac.
macAddress, destinationMac.
macAddress + 6u);
597 unsigned int curtelegramID = teleIdCounter++;
600 autoIpPacket.insert(autoIpPacket.end(), b, b + 4u);
603 autoIpPacket.push_back(0x01);
604 autoIpPacket.push_back(0x00);
607 autoIpPacket.insert(autoIpPacket.end(), payload.begin(), payload.end());
609 pTransport->send(autoIpPacket);
611 const std::chrono::steady_clock::time_point startTime(std::chrono::steady_clock::now());
615 const std::chrono::steady_clock::time_point now(std::chrono::steady_clock::now());
616 if ((now - startTime) > std::chrono::milliseconds(timeout))
618 std::cout << __FUNCTION__ <<
" Timeout" <<
'\n';
621 if (pTransport->recv(receiveBuffer, 1400) > 16)
635 std::vector<std::uint8_t> ipInts;
636 std::istringstream ss(basicString);
643 if (!getline(ss, token,
':'))
645 macAddress.macAddress[
i] =
static_cast<std::uint8_t
>(std::stoi(token, &pos, 16));
653 std::string macAddrString;
654 for (
int k = 0; k < 6; ++k)
656 std::stringstream ss;
657 ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned>(macAddress.
macAddress[k]);
659 macAddrString += ss.str();
662 macAddrString +=
":";
665 return macAddrString;