80
80
81
81
#ifdef BRIDGE_OVER_SERIAL
82
82
#define SERIAL_PKT_MAGIC 0xcafe
83
-
84
- struct SerialPacket {
85
- uint16_t magic, len, crc;
86
- uint8_t payload[MAX_TRANS_UNIT];
87
- SerialPacket () : magic(SERIAL_PKT_MAGIC), len(0 ), crc(0 ) {}
88
- };
89
-
90
- // Fletcher-16
91
- // https://en.wikipedia.org/wiki/Fletcher%27s_checksum
92
- static uint16_t fletcher16 (const uint8_t *bytes, const size_t len) {
93
- uint8_t sum1 = 0 , sum2 = 0 ;
94
-
95
- for (size_t i = 0 ; i < len; i++) {
96
- sum1 = (sum1 + bytes[i]) % 255 ;
97
- sum2 = (sum2 + sum1) % 255 ;
98
- }
99
-
100
- return (sum2 << 8 ) | sum1;
101
- };
102
83
#endif
103
84
104
85
#define REQ_TYPE_GET_STATUS 0x01 // same as _GET_STATS
@@ -267,6 +248,89 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
267
248
#endif
268
249
}
269
250
251
+ #ifdef BRIDGE_OVER_SERIAL
252
+ struct SerialPacket {
253
+ uint16_t magic, len, crc;
254
+ uint8_t payload[MAX_TRANS_UNIT];
255
+ SerialPacket () : magic(SERIAL_PKT_MAGIC), len(0 ), crc(0 ) {}
256
+ };
257
+
258
+ // Fletcher-16
259
+ // https://en.wikipedia.org/wiki/Fletcher%27s_checksum
260
+ inline static uint16_t fletcher16 (const uint8_t *bytes, const size_t len) {
261
+ uint8_t sum1 = 0 , sum2 = 0 ;
262
+
263
+ for (size_t i = 0 ; i < len; i++) {
264
+ sum1 = (sum1 + bytes[i]) % 255 ;
265
+ sum2 = (sum2 + sum1) % 255 ;
266
+ }
267
+
268
+ return (sum2 << 8 ) | sum1;
269
+ };
270
+
271
+ inline void serialBridgeSendPkt (const mesh::Packet *pkt) {
272
+ SerialPacket spkt;
273
+ spkt.len = pkt->writeTo (spkt.payload );
274
+ spkt.crc = fletcher16 (spkt.payload , spkt.len );
275
+ BRIDGE_OVER_SERIAL.write ((uint8_t *)&spkt, sizeof (SerialPacket));
276
+
277
+ #if MESH_PACKET_LOGGING
278
+ Serial.printf (" %s: BRIDGE: TX, len=%d crc=0x%04x\n " , getLogDateTime (), spkt.len , spkt.crc );
279
+ #endif
280
+ }
281
+
282
+ inline void serialBridgeReceivePkt () {
283
+ static constexpr uint16_t size = sizeof (SerialPacket) + 1 ;
284
+ static uint8_t buffer[size];
285
+ static uint16_t tail = 0 ;
286
+
287
+ while (BRIDGE_OVER_SERIAL.available ()) {
288
+ buffer[tail] = (uint8_t )BRIDGE_OVER_SERIAL.read ();
289
+ MESH_DEBUG_PRINT (" %02x " , buffer[tail]);
290
+ tail = (tail + 1 ) % size;
291
+
292
+ // Check for complete packet by looking back to where the magic number should be
293
+ const uint16_t head = (tail - sizeof (SerialPacket) + size) % size;
294
+ if ((buffer[head] | (buffer[(head + 1 ) % size] << 8 )) != SERIAL_PKT_MAGIC) {
295
+ return ;
296
+ }
297
+
298
+ uint8_t bytes[MAX_TRANS_UNIT];
299
+ const uint16_t len = buffer[(head + 2 ) % size] | (buffer[(head + 3 ) % size] << 8 );
300
+
301
+ if (len == 0 || len > sizeof (bytes)) {
302
+ MESH_DEBUG_PRINTLN (" %s: BRIDGE: RX, invalid packet len" , getLogDateTime ());
303
+ return ;
304
+ }
305
+
306
+ for (size_t i = 0 ; i < len; i++) {
307
+ bytes[i] = buffer[(head + 6 + i) % size];
308
+ }
309
+
310
+ const uint16_t crc = buffer[(head + 4 ) % size] | (buffer[(head + 5 ) % size] << 8 );
311
+ const uint16_t f16 = fletcher16 (bytes, len);
312
+
313
+ #if MESH_PACKET_LOGGING
314
+ Serial.printf (" %s: BRIDGE: RX, len=%d crc=0x%04x\n " , getLogDateTime (), len, crc);
315
+ #endif
316
+
317
+ if ((f16 != crc)) {
318
+ MESH_DEBUG_PRINTLN (" %s: BRIDGE: RX, invalid packet checksum" , getLogDateTime ());
319
+ return ;
320
+ }
321
+
322
+ mesh::Packet *pkt = _mgr->allocNew ();
323
+ if (pkt == NULL ) {
324
+ MESH_DEBUG_PRINTLN (" %s: BRIDGE: RX, no unused packets available" , getLogDateTime ());
325
+ return ;
326
+ }
327
+
328
+ pkt->readFrom (bytes, len);
329
+ _mgr->queueInbound (pkt, futureMillis (0 ));
330
+ }
331
+ }
332
+ #endif
333
+
270
334
protected:
271
335
float getAirtimeBudgetFactor () const override {
272
336
return _prefs.airtime_factor ;
@@ -316,21 +380,10 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
316
380
}
317
381
void logTx (mesh::Packet* pkt, int len) override {
318
382
#ifdef BRIDGE_OVER_SERIAL
319
- SerialPacket serialpkt;
320
- size_t seriallen = pkt->writeTo (serialpkt.payload );
321
-
322
- if (seriallen - 1 < MAX_TRANS_UNIT - 1 ) {
323
- serialpkt.len = seriallen;
324
- serialpkt.crc = fletcher16 (serialpkt.payload , serialpkt.len );
325
- BRIDGE_OVER_SERIAL.write ((uint8_t *)&serialpkt, sizeof (SerialPacket));
326
-
327
- #if MESH_PACKET_LOGGING
328
- Serial.print (getLogDateTime ());
329
- Serial.printf (" : BRIDGE: Write to serial len=%d crc=0x%04x\n " , serialpkt.len , serialpkt.crc );
330
- #endif
383
+ if (!pkt->isMarkedDoNotRetransmit ()) {
384
+ serialBridgeSendPkt (pkt);
331
385
}
332
386
#endif
333
-
334
387
if (_logging) {
335
388
File f = openAppend (PACKET_LOG_FILE);
336
389
if (f) {
@@ -747,53 +800,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
747
800
748
801
void loop () {
749
802
#ifdef BRIDGE_OVER_SERIAL
750
- static constexpr uint16_t size = sizeof (SerialPacket) + 1 ;
751
- static uint8_t buffer[size];
752
- static uint16_t tail = 0 ;
753
-
754
- while (BRIDGE_OVER_SERIAL.available ()) {
755
- buffer[tail] = (uint8_t )BRIDGE_OVER_SERIAL.read ();
756
- MESH_DEBUG_PRINT (" %02x " , buffer[tail]);
757
- tail = (tail + 1 ) % size;
758
-
759
- // Check for complete packet by looking back to where the magic number should be
760
- uint16_t head = (tail - sizeof (SerialPacket) + size) % size;
761
- const uint16_t magic = buffer[head] | (buffer[(head + 1 ) % size] << 8 );
762
-
763
- if (magic == SERIAL_PKT_MAGIC) {
764
- uint8_t bytes[MAX_TRANS_UNIT];
765
- const uint16_t len = buffer[(head + 2 ) % size] | (buffer[(head + 3 ) % size] << 8 );
766
- const uint16_t crc = buffer[(head + 4 ) % size] | (buffer[(head + 5 ) % size] << 8 );
767
-
768
- if (len - 1 < MAX_TRANS_UNIT - 1 ) {
769
- for (size_t i = 0 ; i < len; i++) {
770
- bytes[i] = buffer[(head + 6 + i) % size];
771
- }
772
-
773
- uint16_t f16 = fletcher16 (bytes, len);
774
-
775
- #if MESH_PACKET_LOGGING
776
- Serial.print (getLogDateTime ());
777
- Serial.printf (" : BRIDGE: Read from serial len=%d crc=0x%04x valid=%s\n " , len, crc,
778
- (f16 == crc) ? " true" : " false" );
779
- #endif
780
-
781
- if (f16 == crc) {
782
- mesh::Packet *pkt = _mgr->allocNew ();
783
-
784
- if (pkt == NULL ) {
785
- #if MESH_PACKET_LOGGING
786
- Serial.print (getLogDateTime ());
787
- Serial.printf (" : BRIDGE: Unable to allocate new Packet *pkt\n " );
788
- #endif
789
- } else {
790
- pkt->readFrom (bytes, len);
791
- _mgr->queueInbound (pkt, millis ());
792
- }
793
- }
794
- }
795
- }
796
- }
803
+ serialBridgeReceivePkt ();
797
804
#endif
798
805
799
806
mesh::Mesh::loop ();
@@ -829,6 +836,7 @@ static char command[80];
829
836
830
837
void setup () {
831
838
Serial.begin (115200 );
839
+ delay (1000 );
832
840
833
841
#ifdef BRIDGE_OVER_SERIAL
834
842
#if defined(ESP32)
@@ -842,13 +850,9 @@ void setup() {
842
850
#else
843
851
#error SerialBridge was not tested on the current platform
844
852
#endif
845
-
846
853
BRIDGE_OVER_SERIAL.begin (115200 );
847
- MESH_DEBUG_PRINTLN (" Bridge over serial: enabled" );
848
854
#endif
849
855
850
- delay (1000 );
851
-
852
856
board.begin ();
853
857
854
858
#ifdef DISPLAY_CLASS
0 commit comments