| 269 | } |
| 270 | |
| 271 | bool PanadapterStream::rebindToEphemeralPort(RadioConnection* conn) |
| 272 | { |
| 273 | if (!m_socket) { |
| 274 | qCWarning(lcVita49) << "PanadapterStream: cannot rebind UDP socket before init"; |
| 275 | return false; |
| 276 | } |
| 277 | |
| 278 | if (m_routedPrimeTimer) |
| 279 | m_routedPrimeTimer->stop(); |
| 280 | |
| 281 | if (m_socket->state() != QAbstractSocket::UnconnectedState) |
| 282 | m_socket->close(); |
| 283 | |
| 284 | resetAudioStreamStats(); |
| 285 | m_isWanMode = false; |
| 286 | m_hasReceivedPacket = false; |
| 287 | |
| 288 | QHostAddress chosenAddress; |
| 289 | QString chosenReason; |
| 290 | RadioBindMode bindMode = RadioBindMode::Auto; |
| 291 | const QHostAddress bindAddr = chooseLanBindAddress(conn, &chosenReason, &chosenAddress, &bindMode); |
| 292 | const QString bindReason = chosenReason.isEmpty() ? QStringLiteral("auto") : chosenReason; |
| 293 | |
| 294 | const bool bound = m_socket->bind(bindAddr, 0, kLanVitaBindMode); |
| 295 | if (!bound) { |
| 296 | qCWarning(lcVita49) << "PanadapterStream: failed to rebind UDP socket after port collision:" |
| 297 | << m_socket->errorString() |
| 298 | << "mode=" << (bindMode == RadioBindMode::Explicit ? "Explicit" : "Auto") |
| 299 | << "chosen=" << (chosenAddress.isNull() ? QStringLiteral("<none>") |
| 300 | : chosenAddress.toString()); |
| 301 | return false; |
| 302 | } |
| 303 | |
| 304 | applyReceiveBufferSize(); // #3810 — absorb VITA-49 bursts so they don't drop |
| 305 | m_localAddress = m_socket->localAddress(); |
| 306 | m_localPort = m_socket->localPort(); |
| 307 | m_radioAddress = conn ? conn->radioAddress() : QHostAddress(); |
| 308 | m_radioPort = 4991; |
| 309 | m_conn = conn; |
| 310 | |
| 311 | qCWarning(lcVita49).noquote() |
| 312 | << "PanadapterStream: LAN VITA UDP bind" |
| 313 | << QStringLiteral("addr=%1").arg(bindAddr.toString()) |
| 314 | << QStringLiteral("port=%1").arg(m_localPort) |
| 315 | << QStringLiteral("flags=DontShareAddress") |
| 316 | << QStringLiteral("reason=%1").arg(bindReason); |
| 317 | |
| 318 | if (!m_radioAddress.isNull()) { |
| 319 | const QByteArray reg(1, '\x00'); |
| 320 | const qint64 sent = m_socket->writeDatagram(reg, m_radioAddress, 4992); |
| 321 | if (sent == 1) { |
| 322 | m_totalTxBytes.fetch_add(sent); |
| 323 | qCDebug(lcVita49) << "PanadapterStream: sent UDP registration to" |
| 324 | << m_radioAddress.toString() << ":4992"; |
| 325 | m_routedPrimeElapsed.restart(); |
| 326 | m_routedPrimeTimer->start(250); |
| 327 | } else { |
| 328 | qCWarning(lcVita49) << "PanadapterStream: UDP registration send failed after rebind:" |
no test coverage detected