meshtastic 0.0.176 → 0.0.177

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,12 +13,8 @@ require 'uart'
13
13
  # Wire protocol matches the official Python client:
14
14
  # [START1=0x94][START2=0xC3][len_hi][len_lo] + protobuf(ToRadio|FromRadio)
15
15
  module Meshtastic
16
- module SerialInterface # rubocop:disable Metrics/ModuleLength
17
- @console_data = []
18
- @proto_data = []
19
- @from_radio_queue = nil
20
- @rx_mutex = Mutex.new
21
- @want_exit = false
16
+ module Serial # rubocop:disable Metrics/ModuleLength
17
+ @last_serial_obj = nil
22
18
 
23
19
  module_function
24
20
 
@@ -50,23 +46,25 @@ module Meshtastic
50
46
  serial_obj = opts[:serial_obj]
51
47
  debug_out = opts[:debug_out]
52
48
 
53
- @want_exit = false
54
- @from_radio_queue = Queue.new
55
- @console_data = []
56
- @proto_data = []
49
+ serial_obj[:from_radio_queue] = Queue.new
50
+ serial_obj[:config_queue] = Queue.new
51
+ serial_obj[:console_data] = []
52
+ serial_obj[:proto_data] = []
53
+ serial_obj[:rx_mutex] = Mutex.new
57
54
 
58
55
  Thread.new do
59
56
  Thread.current.abort_on_exception = false
60
57
  rx_buf = +''.b
61
58
  empty = +''.b
62
59
 
63
- until @want_exit
60
+ until serial_obj[:closing]
64
61
  begin
65
- chunk = serial_conn.read(1)
66
- if chunk.nil? || chunk.empty?
67
- sleep 0.01
68
- next
69
- end
62
+ next unless serial_conn.wait_readable(0.1)
63
+
64
+ chunk = serial_conn.read_nonblock(1, exception: false)
65
+ next if chunk == :wait_readable
66
+
67
+ raise EOFError, 'serial device disconnected' if chunk.nil? || chunk.empty?
70
68
 
71
69
  c = chunk.getbyte(0)
72
70
  rx_buf << chunk
@@ -76,11 +74,13 @@ module Meshtastic
76
74
  # looking for START1
77
75
  unless c == Meshtastic::START1
78
76
  rx_buf = empty.dup
79
- append_console_byte(chunk, debug_out)
77
+ append_console_byte(chunk, debug_out, serial_obj)
80
78
  end
81
79
  elsif ptr == 1
82
80
  # looking for START2
83
- rx_buf = empty.dup unless c == Meshtastic::START2
81
+ unless c == Meshtastic::START2
82
+ rx_buf = c == Meshtastic::START1 ? chunk.dup : empty.dup
83
+ end
84
84
  elsif ptr >= (Meshtastic::HEADER_LEN - 1)
85
85
  packet_len = (rx_buf.getbyte(2) << 8) + rx_buf.getbyte(3)
86
86
 
@@ -95,20 +95,22 @@ module Meshtastic
95
95
  handle_from_radio_bytes(payload: payload, serial_obj: serial_obj)
96
96
  end
97
97
  end
98
- rescue IOError, Errno::EBADF, Errno::EIO
99
- break if @want_exit
100
-
101
- sleep 0.05
98
+ rescue IOError, SystemCallError => e
99
+ serial_obj[:rx_error] = IOError.new("Serial receive failed: #{e.message}") unless serial_obj[:closing]
100
+ break
102
101
  rescue StandardError => e
103
- warn "Meshtastic::SerialInterface RX error: #{e.class}: #{e.message}" unless @want_exit
102
+ warn "Meshtastic::Serial RX error: #{e.class}: #{e.message}" unless serial_obj[:closing]
104
103
  sleep 0.05
105
104
  end
106
105
  end
106
+ ensure
107
+ serial_obj[:from_radio_queue].close
108
+ serial_obj[:config_queue].close
107
109
  end
108
110
  end
109
111
 
110
112
 
111
- private_class_method def self.append_console_byte(chunk, debug_out)
113
+ private_class_method def self.append_console_byte(chunk, debug_out, serial_obj)
112
114
  if debug_out
113
115
  begin
114
116
  debug_out.write(chunk.force_encoding('UTF-8'))
@@ -116,7 +118,7 @@ module Meshtastic
116
118
  debug_out.write('?')
117
119
  end
118
120
  else
119
- @rx_mutex.synchronize { @console_data << chunk.force_encoding('UTF-8') }
121
+ serial_obj[:rx_mutex].synchronize { serial_obj[:console_data] << chunk.force_encoding('UTF-8') }
120
122
  end
121
123
  end
122
124
 
@@ -128,8 +130,7 @@ module Meshtastic
128
130
  from_radio = Meshtastic::FromRadio.decode(payload)
129
131
  hash = from_radio.to_h
130
132
 
131
- @rx_mutex.synchronize { @proto_data << hash }
132
- @from_radio_queue << from_radio if @from_radio_queue
133
+ serial_obj[:rx_mutex].synchronize { serial_obj[:proto_data] << hash }
133
134
 
134
135
  # Cache useful device identity on the serial_obj handle.
135
136
  if serial_obj && from_radio.my_info
@@ -137,22 +138,27 @@ module Meshtastic
137
138
  serial_obj[:my_node_num] = from_radio.my_info.my_node_num
138
139
  end
139
140
  serial_obj[:metadata] = from_radio.metadata.to_h if serial_obj && from_radio.metadata
141
+ if from_radio.payload_variant == :config_complete_id && from_radio.config_complete_id == serial_obj[:config_id]
142
+ serial_obj[:config_complete] = true
143
+ serial_obj[:config_queue].close
144
+ end
140
145
 
141
146
  if from_radio.log_record
142
147
  msg = from_radio.log_record.message.to_s
143
- @rx_mutex.synchronize { @console_data << "#{msg}\n" } unless msg.empty?
148
+ serial_obj[:rx_mutex].synchronize { serial_obj[:console_data] << "#{msg}\n" } unless msg.empty?
144
149
  end
145
150
 
151
+ serial_obj[:from_radio_queue] << from_radio
146
152
  from_radio
147
153
  rescue Google::Protobuf::ParseError => e
148
- warn "Meshtastic::SerialInterface: failed to decode FromRadio (#{e.message})"
154
+ warn "Meshtastic::Serial: failed to decode FromRadio (#{e.message})"
149
155
  nil
150
156
  end
151
157
 
152
158
  # ---- public API ----------------------------------------------------------
153
159
 
154
160
  # Supported Method Parameters::
155
- # Meshtastic::SerialInterface.request(
161
+ # Meshtastic::Serial.request(
156
162
  # serial_obj: 'required serial_obj returned from #connect method',
157
163
  # payload: 'required - array of bytes OR string to write to serial device'
158
164
  # )
@@ -169,8 +175,17 @@ module Meshtastic
169
175
  raise "ERROR: Invalid payload type: #{payload.class}"
170
176
  end
171
177
 
172
- serial_conn.write(bytes)
173
- serial_conn.flush
178
+ serial_obj[:tx_mutex] ||= Mutex.new
179
+ serial_obj[:tx_mutex].synchronize do
180
+ offset = 0
181
+ while offset < bytes.bytesize
182
+ count = serial_conn.write(bytes.byteslice(offset, bytes.bytesize - offset))
183
+ raise IOError, 'serial write made no progress' unless count && count.positive?
184
+
185
+ offset += count
186
+ end
187
+ serial_conn.flush
188
+ end
174
189
  sleep 0.05
175
190
  bytes.bytesize
176
191
  rescue StandardError => e
@@ -179,7 +194,7 @@ module Meshtastic
179
194
  end
180
195
 
181
196
  # Supported Method Parameters::
182
- # Meshtastic::SerialInterface.send_to_radio(
197
+ # Meshtastic::Serial.send_to_radio(
183
198
  # serial_obj: 'required - serial_obj returned from #connect method',
184
199
  # to_radio: 'required - Meshtastic::ToRadio OR already-serialized String'
185
200
  # )
@@ -213,7 +228,7 @@ module Meshtastic
213
228
  end
214
229
 
215
230
  # Supported Method Parameters::
216
- # serial_obj = Meshtastic::SerialInterface.connect(
231
+ # serial_obj = Meshtastic::Serial.connect(
217
232
  # block_dev: 'optional - serial block device path (defaults to /dev/ttyUSB0)',
218
233
  # baud: 'optional - (defaults to 115200)',
219
234
  # data_bits: 'optional - (defaults to 8)',
@@ -252,6 +267,7 @@ module Meshtastic
252
267
  serial_conn: serial_conn,
253
268
  block_dev: block_dev,
254
269
  baud: baud,
270
+ tx_mutex: Mutex.new,
255
271
  my_info: nil,
256
272
  my_node_num: nil,
257
273
  metadata: nil
@@ -262,6 +278,7 @@ module Meshtastic
262
278
  serial_obj: serial_obj,
263
279
  debug_out: debug_out
264
280
  )
281
+ @last_serial_obj = serial_obj
265
282
 
266
283
  # Wake / resync the device's framing state-machine.
267
284
  wake_up_device(serial_obj: serial_obj)
@@ -269,6 +286,7 @@ module Meshtastic
269
286
  if want_config
270
287
  mui = Meshtastic::MeshInterface.new
271
288
  to_radio_bytes = mui.start_config
289
+ serial_obj[:config_id] = mui.config_id
272
290
  send_to_radio(serial_obj: serial_obj, to_radio: to_radio_bytes)
273
291
  end
274
292
 
@@ -278,6 +296,20 @@ module Meshtastic
278
296
  raise e
279
297
  end
280
298
 
299
+ # Wait for the requested configuration without consuming application messages.
300
+ # Raises Timeout::Error if the firmware does not complete the handshake.
301
+ public_class_method def self.wait_for_config(opts = {})
302
+ serial_obj = opts[:serial_obj]
303
+ raise ArgumentError, 'serial_obj with want_config enabled is required' unless serial_obj && serial_obj[:config_id]
304
+
305
+ serial_obj[:config_queue].pop(timeout: opts.fetch(:timeout, 10))
306
+ raise serial_obj[:rx_error] if serial_obj[:rx_error]
307
+ raise IOError, 'serial connection closed' if serial_obj[:closing]
308
+ raise Timeout::Error, "No configuration response from #{serial_obj[:block_dev]}" unless serial_obj[:config_complete]
309
+
310
+ serial_obj
311
+ end
312
+
281
313
  # Supported Method Parameters::
282
314
  # wake_up_device(
283
315
  # serial_obj: 'required - serial_obj returned from #connect method'
@@ -294,30 +326,28 @@ module Meshtastic
294
326
  end
295
327
 
296
328
  # Supported Method Parameters::
297
- # stdout_data = Meshtastic::SerialInterface.dump_stdout_data(
329
+ # stdout_data = Meshtastic::Serial.dump_stdout_data(
298
330
  # type: 'required - :proto or :console'
299
331
  # )
300
- public_class_method def self.dump_stdout_data(opts = {})
332
+ public_class_method def self.dump_stdout_data(opts = {}, &)
301
333
  type = opts[:type]
302
334
  valid_types = %i[proto console]
303
335
  raise "ERROR: Invalid type: #{type}. Supported types are :proto or :console" unless valid_types.include?(type)
304
336
 
305
- @rx_mutex.synchronize do
306
- if block_given?
307
- if type == :proto
308
- @proto_data.each { |proto_hash| yield proto_hash }
309
- else
310
- @console_data.join.split("\n").each { |line| yield line.force_encoding('UTF-8') }
311
- end
312
- nil
313
- else
314
- type == :proto ? @proto_data.dup : @console_data.join
315
- end
337
+ serial_obj = opts[:serial_obj] || @last_serial_obj
338
+ raise 'ERROR: call connect first' unless serial_obj
339
+
340
+ data = serial_obj[:rx_mutex].synchronize do
341
+ type == :proto ? serial_obj[:proto_data].dup : serial_obj[:console_data].join
316
342
  end
343
+ return data unless block_given?
344
+
345
+ (type == :proto ? data : data.split("\n")).each(&)
346
+ nil
317
347
  end
318
348
 
319
349
  # Supported Method Parameters::
320
- # Meshtastic::SerialInterface.flush_data(
350
+ # Meshtastic::Serial.flush_data(
321
351
  # type: 'required - :proto or :console'
322
352
  # )
323
353
  public_class_method def self.flush_data(opts = {}) # rubocop:disable Naming/PredicateMethod
@@ -325,9 +355,12 @@ module Meshtastic
325
355
  valid_types = %i[proto console]
326
356
  raise "ERROR: Invalid type: #{type}. Supported types are :proto or :console" unless valid_types.include?(type)
327
357
 
328
- @rx_mutex.synchronize do
329
- @console_data.clear if type == :console
330
- @proto_data.clear if type == :proto
358
+ serial_obj = opts[:serial_obj] || @last_serial_obj
359
+ raise 'ERROR: call connect first' unless serial_obj
360
+
361
+ serial_obj[:rx_mutex].synchronize do
362
+ serial_obj[:console_data].clear if type == :console
363
+ serial_obj[:proto_data].clear if type == :proto
331
364
  end
332
365
  true
333
366
  end
@@ -336,34 +369,40 @@ module Meshtastic
336
369
  public_class_method def self.drain_from_radio(opts = {})
337
370
  max = opts[:max] ||= 256
338
371
  msgs = []
339
- return msgs unless @from_radio_queue
372
+ serial_obj = opts[:serial_obj] || @last_serial_obj
373
+ queue = serial_obj && serial_obj[:from_radio_queue]
374
+ return msgs unless queue
340
375
 
341
376
  max.times do
342
- msgs << @from_radio_queue.pop(true)
377
+ message = queue.pop(true)
378
+ break unless message
379
+
380
+ msgs << message
343
381
  rescue ThreadError
344
- break
382
+ break
345
383
  end
346
384
  msgs
347
385
  end
348
386
 
349
387
  # Block until a FromRadio arrives or timeout (seconds). Returns FromRadio or nil.
350
388
  public_class_method def self.recv_from_radio(opts = {})
351
- timeout = opts[:timeout] ||= 5
352
- raise 'ERROR: RX queue not initialised — call connect first' unless @from_radio_queue
389
+ timeout = opts.fetch(:timeout, 5)
390
+ serial_obj = opts[:serial_obj] || @last_serial_obj
391
+ queue = serial_obj && serial_obj[:from_radio_queue]
392
+ raise 'ERROR: RX queue not initialised — call connect first' unless queue
393
+
394
+ message = if timeout.nil? || timeout.negative?
395
+ queue.pop
396
+ else
397
+ queue.pop(timeout: timeout)
398
+ end
399
+ raise serial_obj[:rx_error] if message.nil? && serial_obj[:rx_error]
353
400
 
354
- if timeout.nil? || timeout.negative?
355
- @from_radio_queue.pop
356
- else
357
- begin
358
- Timeout.timeout(timeout) { @from_radio_queue.pop }
359
- rescue Timeout::Error
360
- nil
361
- end
362
- end
401
+ message
363
402
  end
364
403
 
365
404
  # Supported Method Parameters::
366
- # Meshtastic::SerialInterface.monitor_stdout(
405
+ # Meshtastic::Serial.monitor_stdout(
367
406
  # serial_obj: 'required - serial_obj returned from #connect method',
368
407
  # type: 'required - :proto or :console',
369
408
  # refresh: 'optional - refresh interval (default: 3)',
@@ -384,15 +423,15 @@ module Meshtastic
384
423
  exclude_arr = exclude.to_s.split(',').map(&:strip)
385
424
  include_arr = include.to_s.split(',').map(&:strip)
386
425
 
387
- dump_stdout_data(type: type) do |data|
426
+ dump_stdout_data(serial_obj: serial_obj, type: type) do |data|
388
427
  data_s = data.is_a?(Hash) ? data.inspect : data.to_s
389
- disp = !exclude_arr.intersect?(data_s) && (
390
- include_arr.empty? ||
391
- include_arr.all? { |inc| data_s.include?(inc) }
392
- )
428
+ disp = exclude_arr.none? { |exc| data_s.include?(exc) } && (
429
+ include_arr.empty? ||
430
+ include_arr.all? { |inc| data_s.include?(inc) }
431
+ )
393
432
  puts data_s if disp
394
433
  end
395
- flush_data(type: type)
434
+ flush_data(serial_obj: serial_obj, type: type)
396
435
  sleep refresh
397
436
  end
398
437
  rescue Interrupt
@@ -457,7 +496,7 @@ module Meshtastic
457
496
  end
458
497
 
459
498
  # Supported Method Parameters::
460
- # Meshtastic::SerialInterface.subscribe(
499
+ # Meshtastic::Serial.subscribe(
461
500
  # serial_obj: 'required - serial_obj returned from #connect method',
462
501
  # psks: 'optional - hash of :channel_id => psk (default: { LongFast: "AQ==" })',
463
502
  # exclude: 'optional - comma-delimited substrings to hide',
@@ -491,12 +530,9 @@ module Meshtastic
491
530
  puts 'Subscribing to serial FromRadio stream...'
492
531
 
493
532
  loop do
494
- from_radio =
495
- if timeout
496
- recv_from_radio(timeout: timeout)
497
- else
498
- @from_radio_queue.pop
499
- end
533
+ from_radio = recv_from_radio(serial_obj: serial_obj, timeout: timeout)
534
+ break if from_radio.nil? && serial_obj[:from_radio_queue].closed?
535
+
500
536
  next if from_radio.nil?
501
537
 
502
538
  begin
@@ -536,7 +572,7 @@ module Meshtastic
536
572
  flat_message = flat_source.values.join(' ')
537
573
  flat_message = "#{flat_message} #{message.values.join(' ')}" if message.is_a?(Hash)
538
574
 
539
- disp = !exclude_arr.intersect?(flat_message) &&
575
+ disp = exclude_arr.none? { |exc| flat_message.include?(exc) } &&
540
576
  include_arr.all? { |inc| flat_message.include?(inc) }
541
577
 
542
578
  if disp
@@ -562,9 +598,9 @@ module Meshtastic
562
598
  end
563
599
 
564
600
  # Supported Method Parameters::
565
- # Meshtastic::SerialInterface.send_text(
601
+ # Meshtastic::Serial.send_text(
566
602
  # serial_obj: 'required - serial_obj returned from #connect method',
567
- # from: 'optional - From ID (Default: local my_node_num or "!00000b0b")',
603
+ # from: 'optional - From ID (Default: local my_node_num or 0 for firmware-assigned)',
568
604
  # to: 'optional - Destination ID (Default: "!ffffffff")',
569
605
  # channel: 'optional - channel index (Default: 0)',
570
606
  # text: 'optional - Text Message (Default: SYN)',
@@ -581,29 +617,22 @@ module Meshtastic
581
617
  opts[:via] = :radio
582
618
  opts[:channel] ||= 0
583
619
 
584
- if opts[:from].nil?
585
- opts[:from] =
586
- if serial_obj[:my_node_num]
587
- "!#{serial_obj[:my_node_num].to_s(16)}"
588
- else
589
- '!00000b0b'
590
- end
591
- end
620
+ opts[:from] = serial_obj[:my_node_num] || 0 if opts[:from].nil?
592
621
 
593
622
  # Device performs channel encryption for serial ToRadio packets.
594
- # Pass empty psks so MeshInterface leaves the payload in :decoded form.
623
+ # Pass nil psks so MeshInterface leaves the payload in :decoded form.
595
624
  opts[:psks] = nil
625
+ opts[:text] = opts.fetch(:text, 'SYN').to_s
626
+ max_len = Meshtastic::Constants::DATA_PAYLOAD_LEN
627
+ raise ArgumentError, "ERROR: Text Length > #{max_len} Bytes" if opts[:text].bytesize > max_len
596
628
 
597
629
  mui = Meshtastic::MeshInterface.new
598
630
  protobuf = mui.send_text(opts)
599
631
  send_to_radio(serial_obj: serial_obj, to_radio: protobuf)
600
- rescue StandardError => e
601
- disconnect(serial_obj: serial_obj) unless serial_obj.nil?
602
- raise e
603
632
  end
604
633
 
605
634
  # Supported Method Parameters::
606
- # Meshtastic::SerialInterface.send_data(
635
+ # Meshtastic::Serial.send_data(
607
636
  # serial_obj: 'required - serial_obj returned from #connect method',
608
637
  # ...same kwargs as MeshInterface#send_data (via forced to :radio)
609
638
  # )
@@ -615,25 +644,24 @@ module Meshtastic
615
644
  opts[:via] = :radio
616
645
  opts[:channel] ||= 0
617
646
  opts[:psks] = nil
618
- opts[:from] = "!#{serial_obj[:my_node_num].to_s(16)}" if opts[:from].nil? && serial_obj[:my_node_num]
647
+ opts[:from] = serial_obj[:my_node_num] || 0 if opts[:from].nil?
619
648
 
620
649
  mui = Meshtastic::MeshInterface.new
621
650
  protobuf = mui.send_data(opts)
622
651
  send_to_radio(serial_obj: serial_obj, to_radio: protobuf)
623
- rescue StandardError => e
624
- disconnect(serial_obj: serial_obj) unless serial_obj.nil?
625
- raise e
626
652
  end
627
653
 
628
654
  # Supported Method Parameters::
629
- # serial_obj = Meshtastic::SerialInterface.disconnect(
655
+ # serial_obj = Meshtastic::Serial.disconnect(
630
656
  # serial_obj: 'required - serial_obj returned from #connect method'
631
657
  # )
632
658
  public_class_method def self.disconnect(opts = {})
633
659
  serial_obj = opts[:serial_obj]
634
- return nil unless serial_obj
660
+ return nil if serial_obj.nil? || serial_obj[:closing]
635
661
 
636
- @want_exit = true
662
+ serial_obj[:closing] = true
663
+ serial_obj[:from_radio_queue]&.close
664
+ serial_obj[:config_queue]&.close
637
665
 
638
666
  # Ask device to release the link (best-effort).
639
667
  begin
@@ -677,7 +705,9 @@ module Meshtastic
677
705
  # Display Usage for this Module
678
706
 
679
707
  public_class_method def self.help
680
- puts "USAGE:
708
+ puts "Send and receive Meshtastic messages over a framed serial (USB/UART) connection.
709
+
710
+ USAGE:
681
711
  serial_obj = #{self}.connect(
682
712
  block_dev: 'optional - serial block device path (defaults to /dev/ttyUSB0)',
683
713
  baud: 'optional - (defaults to 115200)',
@@ -688,6 +718,11 @@ module Meshtastic
688
718
  want_config: 'optional - request full node DB after connect (default: true)'
689
719
  )
690
720
 
721
+ #{self}.wait_for_config(
722
+ serial_obj: 'required - serial_obj connected with want_config: true',
723
+ timeout: 'optional - seconds to await configuration (default: 10; raises Timeout::Error)'
724
+ )
725
+
691
726
  #{self}.wake_up_device(
692
727
  serial_obj: 'required - serial_obj returned from #connect method'
693
728
  )
@@ -703,16 +738,19 @@ module Meshtastic
703
738
  )
704
739
 
705
740
  from_radio = #{self}.recv_from_radio(
706
- timeout: 'optional - seconds (default: 5; nil = block forever)'
741
+ serial_obj: 'optional - serial_obj (default: most recently opened connection)',
742
+ timeout: 'optional - seconds (default: 5; 0 = poll; nil = block forever)'
707
743
  )
708
744
 
709
- msgs = #{self}.drain_from_radio(max: 256)
745
+ msgs = #{self}.drain_from_radio(serial_obj: serial_obj, max: 256)
710
746
 
711
747
  stdout_data = #{self}.dump_stdout_data(
748
+ serial_obj: 'optional - serial_obj (default: most recently opened connection)',
712
749
  type: 'required - :proto or :console'
713
750
  )
714
751
 
715
752
  #{self}.flush_data(
753
+ serial_obj: 'optional - serial_obj (default: most recently opened connection)',
716
754
  type: 'required - :console or :proto'
717
755
  )
718
756
 
@@ -736,7 +774,7 @@ module Meshtastic
736
774
 
737
775
  #{self}.send_text(
738
776
  serial_obj: 'required - serial_obj returned from #connect method',
739
- from: 'optional - From ID (Default: local my_node_num or \"!00000b0b\")',
777
+ from: 'optional - From ID (Default: local my_node_num or 0 for firmware-assigned)',
740
778
  to: 'optional - Destination ID (Default: \"!ffffffff\")',
741
779
  channel: 'optional - channel index (Default: 0)',
742
780
  text: 'optional - Text Message (Default: SYN)',
@@ -22,7 +22,7 @@ module Meshtastic
22
22
  no_nodes = false if opts[:no_nodes].nil?
23
23
  no_nodes = true if opts[:no_nodes]
24
24
  # Note: In Ruby, we don't need to explicitly define a type hint for self.
25
- raise Exception("StreamInterface is now abstract (to update existing code create SerialInterface instead)") if !defined?(@stream) && !no_proto
25
+ raise Exception("StreamInterface is now abstract (to update existing code use Meshtastic::Serial instead)") if !defined?(@stream) && !no_proto
26
26
 
27
27
  @stream = nil
28
28
  @rx_buf = []
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Meshtastic
4
- VERSION = '0.0.176'
4
+ VERSION = '0.0.177'
5
5
  end
data/lib/meshtastic.rb CHANGED
@@ -16,6 +16,7 @@ module Meshtastic
16
16
  require 'meshtastic/device_ui_pb'
17
17
  require 'meshtastic/interdevice_pb'
18
18
  require 'meshtastic/localonly_pb'
19
+ require 'meshtastic/lorawan_bridge_pb'
19
20
  require 'meshtastic/mesh_pb'
20
21
  require 'meshtastic/module_config_pb'
21
22
  require 'meshtastic/mqtt_pb'
@@ -35,6 +36,7 @@ module Meshtastic
35
36
  autoload :Admin, 'meshtastic/admin'
36
37
  autoload :Apponly, 'meshtastic/apponly'
37
38
  autoload :ATAK, 'meshtastic/atak'
39
+ autoload :Bluetooth, 'meshtastic/bluetooth'
38
40
  autoload :Cannedmessages, 'meshtastic/cannedmessages'
39
41
  autoload :Channel, 'meshtastic/channel'
40
42
  autoload :Clientonly, 'meshtastic/clientonly'
@@ -49,7 +51,7 @@ module Meshtastic
49
51
  autoload :Portnums, 'meshtastic/portnums'
50
52
  autoload :RemoteHardware, 'meshtastic/remote_hardware'
51
53
  autoload :RTTTL, 'meshtastic/rtttl'
52
- autoload :SerialInterface, 'meshtastic/serial_interface'
54
+ autoload :Serial, 'meshtastic/serial'
53
55
  autoload :Storeforward, 'meshtastic/storeforward'
54
56
  autoload :StreamInterface, 'meshtastic/stream_interface'
55
57
  autoload :Telemetry, 'meshtastic/telemetry'