diff --git a/bridge/main.cpp b/bridge/main.cpp index 87dc574..b12caf5 100644 --- a/bridge/main.cpp +++ b/bridge/main.cpp @@ -79,6 +79,8 @@ constexpr uint8_t kConsoleIn = 0x06; // bytes typed at the node's UART constexpr uint8_t kConsoleOut = 0x07; // bytes the node printed constexpr uint8_t kChannelBusy = 0x08; // is another station on the air here? constexpr uint8_t kRadioStats = 0x09; // node -> host: what the chip has seen +constexpr uint8_t kFrameFailed = 0x0A; // host -> node: a frame locked onto and lost +constexpr uint8_t kCapFrameFailed = 0x01; // stats byte 47: this bridge takes kFrameFailed sock_t gFd = BAD_SOCK; std::deque gConsoleIn; @@ -250,6 +252,14 @@ int main(int argc, char** argv) { sim_hal.chip().inbox.push_back(std::move(payload)); break; + case kFrameFailed: + // The first byte is where it failed, as vsx_deliver_frame_failed numbers + // it: a header the receiver could not read is HeaderErr and nothing + // more, a payload it could not is RxDone beside CrcErr with the corrupt + // bytes in the buffer. Without this the firmware's error paths never run. + if (n >= 1) sim_hal.chip().deliverFrameFailed(payload.data() + 1, n - 1, payload[0]); + break; + case kTxDone: sim_hal.chip().transmitFinished(); break; @@ -338,7 +348,7 @@ int main(int argc, char** argv) { // make every comparison between them a comparison of our own code. auto& c = sim_hal.chip(); uint32_t st[4] = {c.irqReads(), c.busyReads(), c.busyMs(), c.spuriousRaises()}; - uint8_t sb[47]; + uint8_t sb[48]; for (int k = 0; k < 4; k++) { sb[k*4+0] = (uint8_t)(st[k] >> 24); sb[k*4+1] = (uint8_t)(st[k] >> 16); sb[k*4+2] = (uint8_t)(st[k] >> 8); sb[k*4+3] = (uint8_t)st[k]; @@ -379,6 +389,11 @@ int main(int argc, char** argv) { // channel, so without this count a firmware that never enabled // PREAMBLE_DETECTED and one that never heard a preamble look alike. put32(43, c.irqSuppressed()); + // What this bridge takes that an older one would hang up on. The + // engine sends kFrameFailed only to a node that says so here, because + // a bridge without that case ends its connection on a kind it does + // not know, and the engine cannot tell the two apart any other way. + sb[47] = kCapFrameFailed; writeMsg(gFd, kRadioStats, sb, sizeof(sb)); } if (!writeMsg(gFd, kAck, payload.data(), 4)) goto done;