| 101 | } |
| 102 | |
| 103 | void testFcsMatchesLibmodem() |
| 104 | { |
| 105 | lm::packet pkt("K5PTB", "BEACON", {"WIDE1-1"}, ">CRC cross-check"); |
| 106 | auto nrzi = makeNrziBitstream(pkt); |
| 107 | |
| 108 | // Break immediately when the frame closes so complete()/fcsValid() are |
| 109 | // still true (they are reset at the start of the *next* processBit call). |
| 110 | HdlcCodec codec; |
| 111 | bool gotFrame = false; |
| 112 | for (uint8_t bit : nrzi) { |
| 113 | if (codec.processBit(bit)) { |
| 114 | gotFrame = true; |
| 115 | break; |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | if (!gotFrame || !codec.fcsValid()) { |
| 120 | report("FCS cross-check: codec decoded frame", false); |
| 121 | return; |
| 122 | } |
| 123 | report("FCS cross-check: codec decoded frame", true); |
| 124 | |
| 125 | // libmodem's compute_crc over the frame body (excluding last 2 FCS bytes) |
| 126 | auto span = std::span<const uint8_t>(codec.frameData(), codec.frameSize() - 2); |
| 127 | auto libmodemFcs = lm::ax25::compute_crc(span.begin(), span.end()); |
| 128 | |
| 129 | report("FCS cross-check: CRC low byte matches libmodem", |
| 130 | codec.expectedFcs()[0] == libmodemFcs[0]); |
| 131 | report("FCS cross-check: CRC high byte matches libmodem", |
| 132 | codec.expectedFcs()[1] == libmodemFcs[1]); |
| 133 | report("FCS cross-check: actual FCS == expected FCS", |
| 134 | codec.actualFcs() == codec.expectedFcs()); |
| 135 | } |
| 136 | |
| 137 | void testBadFcs() |
| 138 | { |
no test coverage detected