@@ -16,14 +16,21 @@ size_t pb_size = 0; // Number of bytes currently in the buffer
1616// Wait this many msec if there's nothing new on the channel
1717#define NO_NEWS_PAUSE 25
1818
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+
1926// The ID of the current WANT_CONFIG request
2027uint32_t want_config_id = 0 ;
2128
2229// Node number of the MT node hosting our WiFi
2330uint32_t my_node_num = 0 ;
2431
2532bool mt_debugging = false ;
26- void (*text_message_callback)(uint32_t from, uint32_t to, const char * text) = NULL ;
33+ void (*text_message_callback)(uint32_t from, uint32_t to, uint8_t channel, const char * text) = NULL ;
2734void (*node_report_callback)(mt_node_t *, mt_nr_progress_t ) = NULL ;
2835mt_node_t node;
2936
@@ -116,7 +123,19 @@ bool mt_send_text(const char * text, uint32_t dest, uint8_t channel_index) {
116123 return _mt_send_toRadio (toRadio);
117124}
118125
119- void set_text_message_callback (void (*callback)(uint32_t from, uint32_t to, const char * text)) {
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+
138+ void set_text_message_callback (void (*callback)(uint32_t from, uint32_t to, uint8_t channel, const char * text)) {
120139 text_message_callback = callback;
121140}
122141
@@ -190,7 +209,7 @@ bool handle_mesh_packet(meshtastic_MeshPacket *meshPacket) {
190209 if (meshPacket->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
191210 if (meshPacket->decoded .portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) {
192211 if (text_message_callback != NULL )
193- text_message_callback (meshPacket->from , meshPacket->to , (const char *)meshPacket->decoded .payload .bytes );
212+ text_message_callback (meshPacket->from , meshPacket->to , meshPacket-> channel , (const char *)meshPacket->decoded .payload .bytes );
194213 } else {
195214 // TODO handle other portnums
196215 return false ;
@@ -308,8 +327,16 @@ bool mt_loop(uint32_t now) {
308327 return false ;
309328#endif
310329 } else if (mt_serial_mode) {
330+
311331 rv = mt_serial_loop ();
312332 if (rv) bytes_read = mt_serial_check_radio ((char *)pb_buf + pb_size, space_left);
333+
334+ // if heartbeat interval has passed, send a heartbeat to keep serial connection alive
335+ if (now >= (last_heartbeat_at + HEARTBEAT_INTERVAL_MS)){
336+ mt_send_heartbeat ();
337+ last_heartbeat_at = now;
338+ }
339+
313340 } else {
314341 Serial.println (" mt_loop() called but it was never initialized" );
315342 while (1 );
0 commit comments