| 109 | } |
| 110 | |
| 111 | long AddRemoteRoute(const std::string &remote, AmsNetId destNetId, |
| 112 | const std::string &destAddr, const std::string &routeName, |
| 113 | const std::string &remoteUsername, |
| 114 | const std::string &remotePassword) |
| 115 | { |
| 116 | Frame f{ 256 }; |
| 117 | uint32_t tagCount = 0; |
| 118 | tagCount += PrependUdpTag(f, destAddr, UdpTag::COMPUTERNAME); |
| 119 | tagCount += PrependUdpTag(f, remotePassword, UdpTag::PASSWORD); |
| 120 | tagCount += PrependUdpTag(f, remoteUsername, UdpTag::USERNAME); |
| 121 | tagCount += PrependUdpTag(f, destNetId, UdpTag::NETID); |
| 122 | tagCount += PrependUdpTag(f, routeName.empty() ? destAddr : routeName, |
| 123 | UdpTag::ROUTENAME); |
| 124 | f.prepend(htole(tagCount)); |
| 125 | |
| 126 | const auto myAddr = AmsAddr{ destNetId, 0 }; |
| 127 | f.prepend(&myAddr, sizeof(myAddr)); |
| 128 | |
| 129 | const auto status = SendRecv(remote, f, UdpServiceId::ADDROUTE); |
| 130 | if (status) { |
| 131 | return status; |
| 132 | } |
| 133 | |
| 134 | // We expect at least the AmsAddr and count fields |
| 135 | if (sizeof(AmsAddr) + sizeof(uint32_t) > f.capacity()) { |
| 136 | LOG_ERROR(__FUNCTION__ |
| 137 | << "(): frame too short to be AMS response '0x" |
| 138 | << std::hex << f.capacity() << "'\n"); |
| 139 | return ADSERR_DEVICE_INVALIDSIZE; |
| 140 | } |
| 141 | |
| 142 | // ignore AmsAddr in response |
| 143 | f.remove(sizeof(AmsAddr)); |
| 144 | |
| 145 | // process UDP discovery tags |
| 146 | auto count = f.pop_letoh<uint32_t>(); |
| 147 | while (count--) { |
| 148 | uint16_t tag; |
| 149 | uint16_t len; |
| 150 | if (sizeof(tag) + sizeof(len) > f.capacity()) { |
| 151 | LOG_ERROR( |
| 152 | __FUNCTION__ |
| 153 | << "(): frame too short to be AMS response '0x" |
| 154 | << std::hex << f.capacity() << "'\n"); |
| 155 | return ADSERR_DEVICE_INVALIDSIZE; |
| 156 | } |
| 157 | |
| 158 | tag = f.pop_letoh<uint16_t>(); |
| 159 | len = f.pop_letoh<uint16_t>(); |
| 160 | if (1 != tag) { |
| 161 | LOG_WARN(__FUNCTION__ |
| 162 | << "(): response contains tagId '0x" |
| 163 | << std::hex << tag << "' -> ignoring\n"); |
| 164 | f.remove(len); |
| 165 | continue; |
| 166 | } |
| 167 | if (sizeof(uint32_t) != len) { |
| 168 | LOG_ERROR( |
no test coverage detected