1
+ #ifdef SENSECAP_INDICATOR
2
+
3
+ #include " IndicatorSerial.h"
4
+ #include " ../modules/Telemetry/Sensor/IndicatorSensor.h"
5
+ #include " FakeUART.h"
6
+ #include < HardwareSerial.h>
7
+ #include < pb_decode.h>
8
+ #include < pb_encode.h>
9
+
10
+ extern IndicatorSensor indicatorSensor;
11
+
12
+ SensecapIndicator sensecapIndicator;
13
+
14
+ SensecapIndicator::SensecapIndicator () : OSThread(" SensecapIndicator" ) {}
15
+
16
+ void SensecapIndicator::begin (HardwareSerial serial)
17
+ {
18
+ if (!running) {
19
+ _serial = serial;
20
+ _serial.setRxBufferSize (PB_BUFSIZE);
21
+ _serial.begin (115200 );
22
+ running = true ;
23
+ LOG_DEBUG (" Start communication thread" );
24
+ }
25
+ }
26
+
27
+ int32_t SensecapIndicator::runOnce ()
28
+ {
29
+ if (running) {
30
+ size_t bytes_read = 0 ;
31
+
32
+ // See if there are any more bytes to add to our buffer.
33
+ size_t space_left = PB_BUFSIZE - pb_rx_size;
34
+
35
+ bytes_read = serial_check ((char *)pb_rx_buf + pb_rx_size, space_left);
36
+
37
+ pb_rx_size += bytes_read;
38
+ check_packet ();
39
+ return (10 );
40
+ } else {
41
+ LOG_DEBUG (" Not running" );
42
+ return (1000 );
43
+ }
44
+ }
45
+
46
+ bool SensecapIndicator::send_uplink (meshtastic_InterdeviceMessage message)
47
+ {
48
+ pb_tx_buf[0 ] = MT_MAGIC_0;
49
+ pb_tx_buf[1 ] = MT_MAGIC_1;
50
+
51
+ pb_ostream_t stream = pb_ostream_from_buffer (pb_tx_buf + MT_HEADER_SIZE, PB_BUFSIZE);
52
+ if (!pb_encode (&stream, meshtastic_InterdeviceMessage_fields, &message)) {
53
+ LOG_DEBUG (" pb_encode failed" );
54
+ return false ;
55
+ }
56
+
57
+ // Store the payload length in the header
58
+ pb_tx_buf[2 ] = stream.bytes_written / 256 ;
59
+ pb_tx_buf[3 ] = stream.bytes_written % 256 ;
60
+
61
+ bool rv = send ((const char *)pb_tx_buf, MT_HEADER_SIZE + stream.bytes_written );
62
+
63
+ return rv;
64
+ }
65
+
66
+ size_t SensecapIndicator::serial_check (char *buf, size_t space_left)
67
+ {
68
+ size_t bytes_read = 0 ;
69
+ while (_serial.available ()) {
70
+ char c = _serial.read ();
71
+ *buf++ = c;
72
+ if (++bytes_read >= space_left) {
73
+ LOG_DEBUG (" Serial overflow: %d > %d" , bytes_read, space_left);
74
+ break ;
75
+ }
76
+ }
77
+ return bytes_read;
78
+ }
79
+
80
+ void SensecapIndicator::check_packet ()
81
+ {
82
+ if (pb_rx_size < MT_HEADER_SIZE) {
83
+ // We don't even have a header yet
84
+ delay (NO_NEWS_PAUSE);
85
+ return ;
86
+ }
87
+
88
+ if (pb_rx_buf[0 ] != MT_MAGIC_0 || pb_rx_buf[1 ] != MT_MAGIC_1) {
89
+ LOG_DEBUG (" Got bad magic" );
90
+ memset (pb_rx_buf, 0 , PB_BUFSIZE);
91
+ pb_rx_size = 0 ;
92
+ return ;
93
+ }
94
+
95
+ uint16_t payload_len = pb_rx_buf[2 ] << 8 | pb_rx_buf[3 ];
96
+ if (payload_len > PB_BUFSIZE) {
97
+ LOG_DEBUG (" Got packet claiming to be ridiculous length" );
98
+ return ;
99
+ }
100
+
101
+ if ((size_t )(payload_len + 4 ) > pb_rx_size) {
102
+ delay (NO_NEWS_PAUSE);
103
+ return ;
104
+ }
105
+
106
+ // We have a complete packet, handle it
107
+ handle_packet (payload_len);
108
+ }
109
+
110
+ bool SensecapIndicator::handle_packet (size_t payload_len)
111
+ {
112
+ meshtastic_InterdeviceMessage message = meshtastic_InterdeviceMessage_init_zero;
113
+
114
+ // Decode the protobuf and shift forward any remaining bytes in the buffer
115
+ // (which, if present, belong to the packet that we're going to process on the
116
+ // next loop)
117
+ pb_istream_t stream = pb_istream_from_buffer (pb_rx_buf + MT_HEADER_SIZE, payload_len);
118
+ bool status = pb_decode (&stream, meshtastic_InterdeviceMessage_fields, &message);
119
+ memmove (pb_rx_buf, pb_rx_buf + MT_HEADER_SIZE + payload_len, PB_BUFSIZE - MT_HEADER_SIZE - payload_len);
120
+ pb_rx_size -= MT_HEADER_SIZE + payload_len;
121
+
122
+ if (!status) {
123
+ LOG_DEBUG (" Decoding failed" );
124
+ return false ;
125
+ }
126
+ switch (message.which_data ) {
127
+ case meshtastic_InterdeviceMessage_sensor_tag:
128
+ indicatorSensor.stuff_buffer (message.data .sensor );
129
+ return true ;
130
+ break ;
131
+ case meshtastic_InterdeviceMessage_nmea_tag:
132
+ // send String to NMEA processing
133
+ FakeSerial->stuff_buffer (message.data .nmea , strlen (message.data .nmea ));
134
+ return true ;
135
+ break ;
136
+ default :
137
+ // the other messages really only flow downstream
138
+ LOG_DEBUG (" Got a message of unexpected type" );
139
+ return false ;
140
+ }
141
+ }
142
+
143
+ bool SensecapIndicator::send (const char *buf, size_t len)
144
+ {
145
+ size_t wrote = _serial.write (buf, len);
146
+ if (wrote == len)
147
+ return true ;
148
+ return false ;
149
+ }
150
+
151
+ #endif // SENSECAP_INDICATOR
0 commit comments