@@ -16,6 +16,13 @@ size_t pb_size = 0; // Number of bytes currently in the buffer
16
16
// Wait this many msec if there's nothing new on the channel
17
17
#define NO_NEWS_PAUSE 25
18
18
19
+ // Serial connections require at least one ping every 15 minutes
20
+ // Otherwise the connection is closed, and packets will no longer be received
21
+ // We will send a ping every 60 seconds, which is what the web client does
22
+ // https://github.com/meshtastic/js/blob/715e35d2374276a43ffa93c628e3710875d43907/src/adapters/serialConnection.ts#L160
23
+ #define HEARTBEAT_INTERVAL_MS 60000
24
+ uint32_t last_heartbeat_at = 0 ;
25
+
19
26
// The ID of the current WANT_CONFIG request
20
27
uint32_t want_config_id = 0 ;
21
28
@@ -116,6 +123,18 @@ bool mt_send_text(const char * text, uint32_t dest, uint8_t channel_index) {
116
123
return _mt_send_toRadio (toRadio);
117
124
}
118
125
126
+ bool mt_send_heartbeat () {
127
+
128
+ d (" Sending heartbeat" );
129
+
130
+ meshtastic_ToRadio toRadio = meshtastic_ToRadio_init_default;
131
+ toRadio.which_payload_variant = meshtastic_ToRadio_heartbeat_tag;
132
+ toRadio.heartbeat = meshtastic_Heartbeat_init_default;
133
+
134
+ return _mt_send_toRadio (toRadio);
135
+
136
+ }
137
+
119
138
void set_text_message_callback (void (*callback)(uint32_t from, uint32_t to, uint8_t channel, const char * text)) {
120
139
text_message_callback = callback;
121
140
}
@@ -298,8 +317,16 @@ bool mt_loop(uint32_t now) {
298
317
return false ;
299
318
#endif
300
319
} else if (mt_serial_mode) {
320
+
301
321
rv = mt_serial_loop ();
302
322
if (rv) bytes_read = mt_serial_check_radio ((char *)pb_buf + pb_size, space_left);
323
+
324
+ // if heartbeat interval has passed, send a heartbeat to keep serial connection alive
325
+ if (now >= (last_heartbeat_at + HEARTBEAT_INTERVAL_MS)){
326
+ mt_send_heartbeat ();
327
+ last_heartbeat_at = now;
328
+ }
329
+
303
330
} else {
304
331
Serial.println (" mt_loop() called but it was never initialized" );
305
332
while (1 );
0 commit comments