meshtastic 0.0.179 → 0.0.181

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/documentation/README.md +3 -2
  4. data/documentation/admin-channel.md +64 -0
  5. data/documentation/admin-config.md +59 -0
  6. data/documentation/admin-firmware-nordic.md +86 -0
  7. data/documentation/admin-firmware-serial.md +180 -0
  8. data/documentation/admin-firmware.md +126 -0
  9. data/documentation/admin.md +88 -35
  10. data/documentation/atak.md +93 -10
  11. data/documentation/channel.md +1 -28
  12. data/documentation/config.md +1 -27
  13. data/documentation/mesh-interface.md +7 -0
  14. data/documentation/meshtastic.md +2 -2
  15. data/lib/meshtastic/admin/channel.rb +164 -0
  16. data/lib/meshtastic/admin/config.rb +213 -0
  17. data/lib/meshtastic/admin/firmware/ble.rb +207 -0
  18. data/lib/meshtastic/admin/firmware/nordic_dfu.rb +218 -0
  19. data/lib/meshtastic/admin/firmware/serial_bootloader.rb +233 -0
  20. data/lib/meshtastic/admin/firmware.rb +288 -0
  21. data/lib/meshtastic/admin.rb +688 -34
  22. data/lib/meshtastic/apponly.rb +19 -7
  23. data/lib/meshtastic/atak.rb +295 -17
  24. data/lib/meshtastic/bluetooth/bluez.rb +20 -1
  25. data/lib/meshtastic/bluetooth.rb +70 -59
  26. data/lib/meshtastic/cannedmessages.rb +13 -6
  27. data/lib/meshtastic/channel.rb +3 -25
  28. data/lib/meshtastic/clientonly.rb +19 -7
  29. data/lib/meshtastic/config.rb +3 -24
  30. data/lib/meshtastic/config_pb.rb +2 -1
  31. data/lib/meshtastic/connection_status.rb +12 -5
  32. data/lib/meshtastic/deviceonly.rb +19 -7
  33. data/lib/meshtastic/localonly.rb +19 -7
  34. data/lib/meshtastic/mesh_interface.rb +19 -0
  35. data/lib/meshtastic/module_config.rb +13 -7
  36. data/lib/meshtastic/mqtt.rb +72 -35
  37. data/lib/meshtastic/paxcount.rb +17 -6
  38. data/lib/meshtastic/portnums.rb +13 -6
  39. data/lib/meshtastic/position.rb +16 -6
  40. data/lib/meshtastic/remote_hardware.rb +27 -11
  41. data/lib/meshtastic/rtttl.rb +17 -8
  42. data/lib/meshtastic/serial.rb +81 -70
  43. data/lib/meshtastic/storeforward.rb +13 -6
  44. data/lib/meshtastic/storeforward_pb.rb +1 -1
  45. data/lib/meshtastic/stream_interface.rb +11 -0
  46. data/lib/meshtastic/tcp.rb +73 -22
  47. data/lib/meshtastic/telemetry.rb +15 -6
  48. data/lib/meshtastic/traceroute.rb +15 -6
  49. data/lib/meshtastic/util.rb +3 -1
  50. data/lib/meshtastic/version.rb +1 -1
  51. data/lib/meshtastic/xmodem.rb +12 -5
  52. data/lib/meshtastic.rb +22 -3
  53. data/spec/conventions_spec.rb +321 -0
  54. data/spec/lib/meshtastic/admin/channel_spec.rb +202 -0
  55. data/spec/lib/meshtastic/admin/config_spec.rb +114 -0
  56. data/spec/lib/meshtastic/admin/firmware/ble_spec.rb +170 -0
  57. data/spec/lib/meshtastic/admin/firmware/nordic_dfu_spec.rb +248 -0
  58. data/spec/lib/meshtastic/admin/firmware/serial_bootloader_spec.rb +263 -0
  59. data/spec/lib/meshtastic/admin/firmware_spec.rb +315 -0
  60. data/spec/lib/meshtastic/admin_spec.rb +412 -1
  61. data/spec/lib/meshtastic/apponly_spec.rb +1 -1
  62. data/spec/lib/meshtastic/atak_spec.rb +129 -4
  63. data/spec/lib/meshtastic/bluetooth_spec.rb +1 -1
  64. data/spec/lib/meshtastic/channel_spec.rb +2 -20
  65. data/spec/lib/meshtastic/config_spec.rb +2 -20
  66. data/spec/lib/meshtastic/connection_status_spec.rb +1 -1
  67. data/spec/lib/meshtastic/deviceonly_spec.rb +1 -1
  68. data/spec/lib/meshtastic/localonly_spec.rb +1 -1
  69. data/spec/lib/meshtastic/mesh_interface_spec.rb +31 -0
  70. data/spec/lib/meshtastic/portnums_spec.rb +2 -2
  71. metadata +24 -6
@@ -4,7 +4,7 @@ require 'meshtastic/mesh_pb'
4
4
 
5
5
  module Meshtastic
6
6
  class Position
7
- def self.build(opts = {})
7
+ public_class_method def self.build(opts = {})
8
8
  position = new
9
9
  position.latitude_i = (opts.fetch(:lat).to_f * 10_000_000).round
10
10
  position.longitude_i = (opts.fetch(:lon).to_f * 10_000_000).round
@@ -13,7 +13,7 @@ module Meshtastic
13
13
  position
14
14
  end
15
15
 
16
- def self.transmit(opts = {})
16
+ public_class_method def self.transmit(opts = {})
17
17
  data = Meshtastic::Data.new(
18
18
  portnum: :POSITION_APP,
19
19
  payload: build(opts).to_proto
@@ -21,14 +21,24 @@ module Meshtastic
21
21
  Meshtastic.deliver_data(opts.merge(data: data, port_num: Meshtastic::PortNum::POSITION_APP))
22
22
  end
23
23
 
24
- def self.authors
24
+ public_class_method def self.authors
25
25
  "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
26
26
  end
27
27
 
28
- def self.help
29
- puts "USAGE:
30
- #{self}.transmit(serial_obj: serial_obj, lat: 37.7749, lon: -122.4194, altitude: 10)
28
+ public_class_method def self.help
29
+ puts " USAGE:
30
+ # Run the build class method for this module.
31
+ #{self}.build(
32
+ altitude: 'optional - value for altitude passed into build',
33
+ time: 'optional - value for time passed into build'
34
+ )
35
+
36
+ # Run the transmit class method for this module.
37
+ #{self}.transmit
38
+
39
+ # Run the authors class method for this module.
31
40
  #{self}.authors
41
+
32
42
  "
33
43
  end
34
44
  end
@@ -4,7 +4,7 @@ require 'meshtastic/mesh_pb'
4
4
 
5
5
  module Meshtastic
6
6
  module RemoteHardware
7
- def self.encode(opts = {})
7
+ public_class_method def self.encode(opts = {})
8
8
  message = Meshtastic::HardwareMessage.new
9
9
  message.type = opts.fetch(:type, :READ_GPIOS)
10
10
  message.gpio_mask = opts.fetch(:gpio_mask, 0)
@@ -12,7 +12,7 @@ module Meshtastic
12
12
  message
13
13
  end
14
14
 
15
- def self.send(opts = {})
15
+ public_class_method def self.send(opts = {})
16
16
  data = Meshtastic::Data.new(
17
17
  portnum: :REMOTE_HARDWARE_APP,
18
18
  payload: encode(opts).to_proto,
@@ -21,28 +21,44 @@ module Meshtastic
21
21
  Meshtastic.deliver_data(opts.merge(data: data, port_num: Meshtastic::PortNum::REMOTE_HARDWARE_APP))
22
22
  end
23
23
 
24
- def self.read_gpios(opts = {})
24
+ public_class_method def self.read_gpios(opts = {})
25
25
  send(opts.merge(type: :READ_GPIOS))
26
26
  end
27
27
 
28
- def self.write_gpios(opts = {})
28
+ public_class_method def self.write_gpios(opts = {})
29
29
  send(opts.merge(type: :WRITE_GPIOS, want_response: false))
30
30
  end
31
31
 
32
- def self.watch_gpios(opts = {})
32
+ public_class_method def self.watch_gpios(opts = {})
33
33
  send(opts.merge(type: :WATCH_GPIOS))
34
34
  end
35
35
 
36
- def self.authors
36
+ public_class_method def self.authors
37
37
  "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
38
38
  end
39
39
 
40
- def self.help
41
- puts "USAGE:
42
- #{self}.read_gpios(serial_obj: serial_obj, gpio_mask: 0x01)
43
- #{self}.write_gpios(serial_obj: serial_obj, gpio_mask: 0x01, gpio_value: 0x01)
44
- #{self}.watch_gpios(serial_obj: serial_obj, gpio_mask: 0x01)
40
+ public_class_method def self.help
41
+ puts " USAGE:
42
+ # Run the encode class method for this module.
43
+ #{self}.encode(
44
+ gpio_value: 'optional - value for gpio_value passed into encode'
45
+ )
46
+
47
+ # Run the send class method for this module.
48
+ #{self}.send
49
+
50
+ # Run the read_gpios class method for this module.
51
+ #{self}.read_gpios
52
+
53
+ # Run the write_gpios class method for this module.
54
+ #{self}.write_gpios
55
+
56
+ # Run the watch_gpios class method for this module.
57
+ #{self}.watch_gpios
58
+
59
+ # Run the authors class method for this module.
45
60
  #{self}.authors
61
+
46
62
  "
47
63
  end
48
64
  end
@@ -4,29 +4,38 @@ require 'meshtastic/rtttl_pb'
4
4
 
5
5
  module Meshtastic
6
6
  module RTTTL
7
- def self.encode(opts = {})
7
+ public_class_method def self.encode(opts = {})
8
8
  config = Meshtastic::RTTTLConfig.new
9
9
  config.ringtone = opts.fetch(:ringtone, '')
10
10
  config
11
11
  end
12
12
 
13
- def self.set(opts = {})
13
+ public_class_method def self.set(opts = {})
14
14
  Admin.send(opts.merge(set_ringtone_message: opts.fetch(:ringtone)))
15
15
  end
16
16
 
17
- def self.get(opts = {})
17
+ public_class_method def self.get(opts = {})
18
18
  Admin.send(opts.merge(get_ringtone_request: true))
19
19
  end
20
20
 
21
- def self.authors
21
+ public_class_method def self.authors
22
22
  "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
23
23
  end
24
24
 
25
- def self.help
26
- puts "USAGE:
27
- #{self}.set(serial_obj: serial_obj, ringtone: 'Mario:d=4,o=5,b=125:16e6')
28
- #{self}.get(serial_obj: serial_obj)
25
+ public_class_method def self.help
26
+ puts " USAGE:
27
+ # Run the encode class method for this module.
28
+ #{self}.encode
29
+
30
+ # Run the set class method for this module.
31
+ #{self}.set
32
+
33
+ # Run the get class method for this module.
34
+ #{self}.get
35
+
36
+ # Run the authors class method for this module.
29
37
  #{self}.authors
38
+
30
39
  "
31
40
  end
32
41
  end
@@ -16,11 +16,11 @@ module Meshtastic
16
16
  module Serial # rubocop:disable Metrics/ModuleLength
17
17
  @last_serial_obj = nil
18
18
 
19
- module_function
20
19
 
21
20
  # ---- low-level IO helpers ------------------------------------------------
22
21
 
23
- def self.clear_hupcl(block_dev)
22
+ private_class_method def self.clear_hupcl(opts = {})
23
+ block_dev = opts[:block_dev]
24
24
  # Prevent device reboot on open by clearing HUPCL (same as Python pyserial path).
25
25
  return unless defined?(Termios)
26
26
 
@@ -34,7 +34,6 @@ module Meshtastic
34
34
  # Best-effort — uart.open will still work without this.
35
35
  nil
36
36
  end
37
- private_class_method :clear_hupcl
38
37
 
39
38
  # Supported Method Parameters::
40
39
  # proto_thread = init_rx_thread(
@@ -74,7 +73,7 @@ module Meshtastic
74
73
  # looking for START1
75
74
  unless c == Meshtastic::START1
76
75
  rx_buf = empty.dup
77
- append_console_byte(chunk, debug_out, serial_obj)
76
+ append_console_byte(chunk: chunk, debug_out: debug_out, serial_obj: serial_obj)
78
77
  end
79
78
  elsif ptr == 1
80
79
  # looking for START2
@@ -110,7 +109,10 @@ module Meshtastic
110
109
  end
111
110
 
112
111
 
113
- private_class_method def self.append_console_byte(chunk, debug_out, serial_obj)
112
+ private_class_method def self.append_console_byte(opts = {})
113
+ chunk = opts[:chunk]
114
+ debug_out = opts[:debug_out]
115
+ serial_obj = opts[:serial_obj]
114
116
  if debug_out
115
117
  begin
116
118
  debug_out.write(chunk.force_encoding('UTF-8'))
@@ -259,7 +261,7 @@ module Meshtastic
259
261
 
260
262
  mode = "#{data_bits}#{parity_char}#{stop_bits}"
261
263
 
262
- clear_hupcl(block_dev)
264
+ clear_hupcl(block_dev: block_dev)
263
265
 
264
266
  serial_conn = UART.open(block_dev, baud, mode)
265
267
 
@@ -329,7 +331,7 @@ module Meshtastic
329
331
  # stdout_data = Meshtastic::Serial.dump_stdout_data(
330
332
  # type: 'required - :proto or :console'
331
333
  # )
332
- public_class_method def self.dump_stdout_data(opts = {}, &)
334
+ public_class_method def self.dump_stdout_data(opts = {})
333
335
  type = opts[:type]
334
336
  valid_types = %i[proto console]
335
337
  raise "ERROR: Invalid type: #{type}. Supported types are :proto or :console" unless valid_types.include?(type)
@@ -342,7 +344,7 @@ module Meshtastic
342
344
  end
343
345
  return data unless block_given?
344
346
 
345
- (type == :proto ? data : data.split("\n")).each(&)
347
+ (type == :proto ? data : data.split("\n")).each { |row| yield row } # rubocop:disable Style/ExplicitBlockArgument
346
348
  nil
347
349
  end
348
350
 
@@ -705,100 +707,109 @@ module Meshtastic
705
707
  # Display Usage for this Module
706
708
 
707
709
  public_class_method def self.help
708
- puts "Send and receive Meshtastic messages over a framed serial (USB/UART) connection.
709
-
710
- USAGE:
711
- serial_obj = #{self}.connect(
712
- block_dev: 'optional - serial block device path (defaults to /dev/ttyUSB0)',
713
- baud: 'optional - (defaults to 115200)',
714
- data_bits: 'optional - (defaults to 8)',
715
- stop_bits: 'optional - (defaults to 1)',
716
- parity: 'optional - :even|:odd|:none (defaults to :none)',
717
- debug_out: 'optional - IO receiving non-protobuf debug console bytes',
718
- want_config: 'optional - request full node DB after connect (default: true)'
710
+ puts " USAGE:
711
+ # Run the request class method for this module.
712
+ #{self}.request(
713
+ serial_obj: 'optional - value for serial_obj passed into request',
714
+ payload: 'optional - value for payload passed into request'
719
715
  )
720
716
 
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)'
717
+ # Run the send_to_radio class method for this module.
718
+ #{self}.send_to_radio(
719
+ serial_obj: 'optional - value for serial_obj passed into send_to_radio',
720
+ to_radio: 'optional - value for to_radio passed into send_to_radio'
724
721
  )
725
722
 
726
- #{self}.wake_up_device(
727
- serial_obj: 'required - serial_obj returned from #connect method'
723
+ # Run the connect class method for this module.
724
+ #{self}.connect(
725
+ block_dev: 'optional - value for block_dev passed into connect',
726
+ baud: 'optional - value for baud passed into connect',
727
+ data_bits: 'optional - value for data_bits passed into connect',
728
+ stop_bits: 'optional - value for stop_bits passed into connect',
729
+ parity: 'optional - value for parity passed into connect',
730
+ debug_out: 'optional - value for debug_out passed into connect'
728
731
  )
729
732
 
730
- #{self}.request(
731
- serial_obj: 'required serial_obj returned from #connect method',
732
- payload: 'required - array of bytes OR string to write to serial device'
733
+ # Run the wait_for_config class method for this module.
734
+ #{self}.wait_for_config(
735
+ serial_obj: 'optional - value for serial_obj passed into wait_for_config'
733
736
  )
734
737
 
735
- #{self}.send_to_radio(
736
- serial_obj: 'required - serial_obj returned from #connect method',
737
- to_radio: 'required - Meshtastic::ToRadio OR serialized String'
738
+ # Run the wake_up_device class method for this module.
739
+ #{self}.wake_up_device(
740
+ serial_obj: 'optional - value for serial_obj passed into wake_up_device'
738
741
  )
739
742
 
740
- from_radio = #{self}.recv_from_radio(
741
- serial_obj: 'optional - serial_obj (default: most recently opened connection)',
742
- timeout: 'optional - seconds (default: 5; 0 = poll; nil = block forever)'
743
+ # Run the dump_stdout_data class method for this module.
744
+ #{self}.dump_stdout_data(
745
+ type: 'optional - value for type passed into dump_stdout_data',
746
+ serial_obj: 'optional - value for serial_obj passed into dump_stdout_data'
743
747
  )
744
748
 
745
- msgs = #{self}.drain_from_radio(serial_obj: serial_obj, max: 256)
749
+ # Run the flush_data class method for this module.
750
+ #{self}.flush_data(
751
+ type: 'optional - value for type passed into flush_data',
752
+ serial_obj: 'optional - value for serial_obj passed into flush_data'
753
+ )
746
754
 
747
- stdout_data = #{self}.dump_stdout_data(
748
- serial_obj: 'optional - serial_obj (default: most recently opened connection)',
749
- type: 'required - :proto or :console'
755
+ # Run the drain_from_radio class method for this module.
756
+ #{self}.drain_from_radio(
757
+ max: 'optional - value for max passed into drain_from_radio',
758
+ serial_obj: 'optional - value for serial_obj passed into drain_from_radio'
750
759
  )
751
760
 
752
- #{self}.flush_data(
753
- serial_obj: 'optional - serial_obj (default: most recently opened connection)',
754
- type: 'required - :console or :proto'
761
+ # Run the recv_from_radio class method for this module.
762
+ #{self}.recv_from_radio(
763
+ serial_obj: 'optional - value for serial_obj passed into recv_from_radio'
755
764
  )
756
765
 
766
+ # Run the monitor_stdout class method for this module.
757
767
  #{self}.monitor_stdout(
758
- serial_obj: 'required - serial_obj returned from #connect method',
759
- type: 'required - :proto or :console',
760
- refresh: 'optional - refresh interval (default: 3)',
761
- include: 'optional - comma-delimited string(s) to include in message',
762
- exclude: 'optional - comma-delimited string(s) to exclude in message'
768
+ serial_obj: 'optional - value for serial_obj passed into monitor_stdout',
769
+ type: 'optional - value for type passed into monitor_stdout',
770
+ refresh: 'optional - value for refresh passed into monitor_stdout',
771
+ include: 'optional - value for include passed into monitor_stdout',
772
+ exclude: 'optional - value for exclude passed into monitor_stdout'
763
773
  )
764
774
 
775
+ # Run the subscribe class method for this module.
765
776
  #{self}.subscribe(
766
- serial_obj: 'required - serial_obj returned from #connect method',
767
- psks: 'optional - hash of :channel_id => psk (default: { LongFast: \"AQ==\" })',
768
- exclude: 'optional - comma-delimited string(s) to exclude',
769
- include: 'optional - comma-delimited string(s) to include',
770
- gps_metadata: 'optional - include GPS metadata (default: false)',
771
- include_raw: 'optional - include raw packet bytes (default: false)',
772
- timeout: 'optional - seconds per pop (default: nil = forever)'
777
+ serial_obj: 'optional - value for serial_obj passed into subscribe',
778
+ psks: 'optional - value for psks passed into subscribe',
779
+ exclude: 'optional - value for exclude passed into subscribe',
780
+ include: 'optional - value for include passed into subscribe',
781
+ gps_metadata: 'optional - value for gps_metadata passed into subscribe',
782
+ include_raw: 'optional - value for include_raw passed into subscribe',
783
+ timeout: 'optional - value for timeout passed into subscribe'
773
784
  )
774
785
 
786
+ # Run the send_text class method for this module.
775
787
  #{self}.send_text(
776
- serial_obj: 'required - serial_obj returned from #connect method',
777
- from: 'optional - From ID (Default: local my_node_num or 0 for firmware-assigned)',
778
- to: 'optional - Destination ID (Default: \"!ffffffff\")',
779
- channel: 'optional - channel index (Default: 0)',
780
- text: 'optional - Text Message (Default: SYN)',
781
- want_ack: 'optional - Want Acknowledgement (Default: false)',
782
- want_response: 'optional - Want Response (Default: false)',
783
- hop_limit: 'optional - Hop Limit (Default: 3)'
788
+ serial_obj: 'optional - value for serial_obj passed into send_text',
789
+ via: 'optional - value for via passed into send_text',
790
+ channel: 'optional - value for channel passed into send_text',
791
+ from: 'optional - value for from passed into send_text',
792
+ psks: 'optional - value for psks passed into send_text',
793
+ text: 'optional - value for text passed into send_text'
784
794
  )
785
795
 
796
+ # Run the send_data class method for this module.
786
797
  #{self}.send_data(
787
- serial_obj: 'required - serial_obj returned from #connect method',
788
- from: 'optional - From ID',
789
- to: 'optional - Destination ID (Default: \"!ffffffff\")',
790
- channel: 'optional - channel index (Default: 0)',
791
- data: 'required - Meshtastic::Data',
792
- want_ack: 'optional - Want Acknowledgement (Default: false)',
793
- hop_limit: 'optional - Hop Limit (Default: 3)',
794
- port_num: 'optional - PortNum (Default: PRIVATE_APP)'
798
+ serial_obj: 'optional - value for serial_obj passed into send_data',
799
+ via: 'optional - value for via passed into send_data',
800
+ channel: 'optional - value for channel passed into send_data',
801
+ psks: 'optional - value for psks passed into send_data',
802
+ from: 'optional - value for from passed into send_data'
795
803
  )
796
804
 
797
- serial_obj = #{self}.disconnect(
798
- serial_obj: 'required - serial_obj returned from #connect method'
805
+ # Run the disconnect class method for this module.
806
+ #{self}.disconnect(
807
+ serial_obj: 'optional - value for serial_obj passed into disconnect'
799
808
  )
800
809
 
810
+ # Run the authors class method for this module.
801
811
  #{self}.authors
812
+
802
813
  "
803
814
  end
804
815
  end
@@ -4,13 +4,13 @@ require 'meshtastic/storeforward_pb'
4
4
 
5
5
  module Meshtastic
6
6
  module Storeforward
7
- def self.encode(opts = {})
7
+ public_class_method def self.encode(opts = {})
8
8
  message = Meshtastic::StoreAndForward.new
9
9
  message.rr = opts.fetch(:rr, :ROUTER_HEARTBEAT)
10
10
  message
11
11
  end
12
12
 
13
- def self.send(opts = {})
13
+ public_class_method def self.send(opts = {})
14
14
  data = Meshtastic::Data.new(
15
15
  portnum: :STORE_FORWARD_APP,
16
16
  payload: encode(opts).to_proto
@@ -18,14 +18,21 @@ module Meshtastic
18
18
  Meshtastic.deliver_data(opts.merge(data: data, port_num: Meshtastic::PortNum::STORE_FORWARD_APP))
19
19
  end
20
20
 
21
- def self.authors
21
+ public_class_method def self.authors
22
22
  "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
23
23
  end
24
24
 
25
- def self.help
26
- puts "USAGE:
27
- #{self}.send(serial_obj: serial_obj, rr: :CLIENT_HISTORY)
25
+ public_class_method def self.help
26
+ puts " USAGE:
27
+ # Run the encode class method for this module.
28
+ #{self}.encode
29
+
30
+ # Run the send class method for this module.
31
+ #{self}.send
32
+
33
+ # Run the authors class method for this module.
28
34
  #{self}.authors
35
+
29
36
  "
30
37
  end
31
38
  end
@@ -5,7 +5,7 @@
5
5
  require 'google/protobuf'
6
6
 
7
7
 
8
- descriptor_data = "\n\x1dmeshtastic/storeforward.proto\x12\nmeshtastic\"\x9c\x07\n\x0fStoreAndForward\x12\x37\n\x02rr\x18\x01 \x01(\x0e\x32+.meshtastic.StoreAndForward.RequestResponse\x12\x37\n\x05stats\x18\x02 \x01(\x0b\x32&.meshtastic.StoreAndForward.StatisticsH\x00\x12\x36\n\x07history\x18\x03 \x01(\x0b\x32#.meshtastic.StoreAndForward.HistoryH\x00\x12:\n\theartbeat\x18\x04 \x01(\x0b\x32%.meshtastic.StoreAndForward.HeartbeatH\x00\x12\x0e\n\x04text\x18\x05 \x01(\x0cH\x00\x1a\xcd\x01\n\nStatistics\x12\x16\n\x0emessages_total\x18\x01 \x01(\r\x12\x16\n\x0emessages_saved\x18\x02 \x01(\r\x12\x14\n\x0cmessages_max\x18\x03 \x01(\r\x12\x0f\n\x07up_time\x18\x04 \x01(\r\x12\x10\n\x08requests\x18\x05 \x01(\r\x12\x18\n\x10requests_history\x18\x06 \x01(\r\x12\x11\n\theartbeat\x18\x07 \x01(\x08\x12\x12\n\nreturn_max\x18\x08 \x01(\r\x12\x15\n\rreturn_window\x18\t \x01(\r\x1aI\n\x07History\x12\x18\n\x10history_messages\x18\x01 \x01(\r\x12\x0e\n\x06window\x18\x02 \x01(\r\x12\x14\n\x0clast_request\x18\x03 \x01(\r\x1a.\n\tHeartbeat\x12\x0e\n\x06period\x18\x01 \x01(\r\x12\x11\n\tsecondary\x18\x02 \x01(\r\"\xbc\x02\n\x0fRequestResponse\x12\t\n\x05UNSET\x10\x00\x12\x10\n\x0cROUTER_ERROR\x10\x01\x12\x14\n\x10ROUTER_HEARTBEAT\x10\x02\x12\x0f\n\x0bROUTER_PING\x10\x03\x12\x0f\n\x0bROUTER_PONG\x10\x04\x12\x0f\n\x0bROUTER_BUSY\x10\x05\x12\x12\n\x0eROUTER_HISTORY\x10\x06\x12\x10\n\x0cROUTER_STATS\x10\x07\x12\x16\n\x12ROUTER_TEXT_DIRECT\x10\x08\x12\x19\n\x15ROUTER_TEXT_BROADCAST\x10\t\x12\x10\n\x0c\x43LIENT_ERROR\x10@\x12\x12\n\x0e\x43LIENT_HISTORY\x10\x41\x12\x10\n\x0c\x43LIENT_STATS\x10\x42\x12\x0f\n\x0b\x43LIENT_PING\x10\x43\x12\x0f\n\x0b\x43LIENT_PONG\x10\x44\x12\x10\n\x0c\x43LIENT_ABORT\x10jB\t\n\x07variantBk\n\x14org.meshtastic.protoB\x15StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
8
+ descriptor_data = "\n\x1dmeshtastic/storeforward.proto\x12\nmeshtastic\"\xb1\x07\n\x0fStoreAndForward\x12\x37\n\x02rr\x18\x01 \x01(\x0e\x32+.meshtastic.StoreAndForward.RequestResponse\x12\x37\n\x05stats\x18\x02 \x01(\x0b\x32&.meshtastic.StoreAndForward.StatisticsH\x00\x12\x36\n\x07history\x18\x03 \x01(\x0b\x32#.meshtastic.StoreAndForward.HistoryH\x00\x12:\n\theartbeat\x18\x04 \x01(\x0b\x32%.meshtastic.StoreAndForward.HeartbeatH\x00\x12\x0e\n\x04text\x18\x05 \x01(\x0cH\x00\x12\x13\n\x0boriginal_id\x18\x06 \x01(\r\x1a\xcd\x01\n\nStatistics\x12\x16\n\x0emessages_total\x18\x01 \x01(\r\x12\x16\n\x0emessages_saved\x18\x02 \x01(\r\x12\x14\n\x0cmessages_max\x18\x03 \x01(\r\x12\x0f\n\x07up_time\x18\x04 \x01(\r\x12\x10\n\x08requests\x18\x05 \x01(\r\x12\x18\n\x10requests_history\x18\x06 \x01(\r\x12\x11\n\theartbeat\x18\x07 \x01(\x08\x12\x12\n\nreturn_max\x18\x08 \x01(\r\x12\x15\n\rreturn_window\x18\t \x01(\r\x1aI\n\x07History\x12\x18\n\x10history_messages\x18\x01 \x01(\r\x12\x0e\n\x06window\x18\x02 \x01(\r\x12\x14\n\x0clast_request\x18\x03 \x01(\r\x1a.\n\tHeartbeat\x12\x0e\n\x06period\x18\x01 \x01(\r\x12\x11\n\tsecondary\x18\x02 \x01(\r\"\xbc\x02\n\x0fRequestResponse\x12\t\n\x05UNSET\x10\x00\x12\x10\n\x0cROUTER_ERROR\x10\x01\x12\x14\n\x10ROUTER_HEARTBEAT\x10\x02\x12\x0f\n\x0bROUTER_PING\x10\x03\x12\x0f\n\x0bROUTER_PONG\x10\x04\x12\x0f\n\x0bROUTER_BUSY\x10\x05\x12\x12\n\x0eROUTER_HISTORY\x10\x06\x12\x10\n\x0cROUTER_STATS\x10\x07\x12\x16\n\x12ROUTER_TEXT_DIRECT\x10\x08\x12\x19\n\x15ROUTER_TEXT_BROADCAST\x10\t\x12\x10\n\x0c\x43LIENT_ERROR\x10@\x12\x12\n\x0e\x43LIENT_HISTORY\x10\x41\x12\x10\n\x0c\x43LIENT_STATS\x10\x42\x12\x0f\n\x0b\x43LIENT_PING\x10\x43\x12\x0f\n\x0b\x43LIENT_PONG\x10\x44\x12\x10\n\x0c\x43LIENT_ABORT\x10jB\t\n\x07variantBk\n\x14org.meshtastic.protoB\x15StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
9
9
 
10
10
  pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
11
  pool.add_serialized_file(descriptor_data)
@@ -128,5 +128,16 @@ module Meshtastic
128
128
  #{self}.authors
129
129
  "
130
130
  end
131
+
132
+ public_class_method def self.authors
133
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
134
+ end
135
+
136
+ public_class_method def self.help
137
+ puts "USAGE:
138
+ # Print the AUTHOR(S) string for this module.
139
+ #{self}.authors
140
+ "
141
+ end
131
142
  end
132
143
  end
@@ -8,7 +8,7 @@ module Meshtastic
8
8
  module TCP
9
9
  DEFAULT_PORT = 4403
10
10
 
11
- def self.connect(opts = {})
11
+ public_class_method def self.connect(opts = {})
12
12
  host = opts[:host] ||= '127.0.0.1'
13
13
  port = opts[:port] ||= DEFAULT_PORT
14
14
  tcp_obj = nil
@@ -45,57 +45,108 @@ module Meshtastic
45
45
  raise
46
46
  end
47
47
 
48
- def self.wait_for_config(opts = {})
48
+ public_class_method def self.wait_for_config(opts = {})
49
49
  Meshtastic::Serial.wait_for_config(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
50
50
  end
51
51
 
52
- def self.send_to_radio(opts = {})
52
+ public_class_method def self.send_to_radio(opts = {})
53
53
  Meshtastic::Serial.send_to_radio(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
54
54
  end
55
55
 
56
- def self.send_text(opts = {})
56
+ public_class_method def self.send_text(opts = {})
57
57
  Meshtastic::Serial.send_text(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
58
58
  end
59
59
 
60
- def self.send_data(opts = {})
60
+ public_class_method def self.send_data(opts = {})
61
61
  Meshtastic::Serial.send_data(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
62
62
  end
63
63
 
64
- def self.recv_from_radio(opts = {})
64
+ public_class_method def self.recv_from_radio(opts = {})
65
65
  Meshtastic::Serial.recv_from_radio(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
66
66
  end
67
67
 
68
- def self.drain_from_radio(opts = {})
68
+ public_class_method def self.drain_from_radio(opts = {})
69
69
  Meshtastic::Serial.drain_from_radio(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
70
70
  end
71
71
 
72
- def self.subscribe(opts = {}, &)
73
- Meshtastic::Serial.subscribe(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]), &)
72
+ public_class_method def self.subscribe(opts = {})
73
+ merged = opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj])
74
+ if block_given?
75
+ Meshtastic::Serial.subscribe(merged) { |msg| yield msg } # rubocop:disable Style/ExplicitBlockArgument
76
+ else
77
+ Meshtastic::Serial.subscribe(merged)
78
+ end
74
79
  end
75
80
 
76
- def self.disconnect(opts = {})
81
+ public_class_method def self.disconnect(opts = {})
77
82
  Meshtastic::Serial.disconnect(serial_obj: opts[:tcp_obj] || opts[:serial_obj])
78
83
  end
79
84
 
80
- def self.authors
85
+ public_class_method def self.authors
81
86
  "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
82
87
  end
83
88
 
84
- def self.help
85
- puts "Send and receive Meshtastic messages over TCP (default port #{DEFAULT_PORT}).
89
+ public_class_method def self.help
90
+ puts " USAGE:
91
+ # Run the connect class method for this module.
92
+ #{self}.connect(
93
+ host: 'optional - value for host passed into connect',
94
+ port: 'optional - value for port passed into connect',
95
+ socket: 'optional - value for socket passed into connect',
96
+ debug_out: 'optional - value for debug_out passed into connect'
97
+ )
86
98
 
87
- USAGE:
88
- tcp_obj = #{self}.connect(
89
- host: 'optional - (default: 127.0.0.1)',
90
- port: 'optional - (default: 4403)',
91
- want_config: 'optional - request full node DB after connect (default: true)'
99
+ # Run the wait_for_config class method for this module.
100
+ #{self}.wait_for_config(
101
+ tcp_obj: 'optional - value for tcp_obj passed into wait_for_config',
102
+ serial_obj: 'optional - value for serial_obj passed into wait_for_config'
92
103
  )
93
104
 
94
- #{self}.wait_for_config(tcp_obj: tcp_obj, timeout: 10)
95
- #{self}.send_text(tcp_obj: tcp_obj, to: '!ffffffff', channel: 0, text: 'Hello over TCP!')
96
- #{self}.subscribe(tcp_obj: tcp_obj, include: 'TEXT_MESSAGE_APP')
97
- #{self}.disconnect(tcp_obj: tcp_obj)
105
+ # Run the send_to_radio class method for this module.
106
+ #{self}.send_to_radio(
107
+ tcp_obj: 'optional - value for tcp_obj passed into send_to_radio',
108
+ serial_obj: 'optional - value for serial_obj passed into send_to_radio'
109
+ )
110
+
111
+ # Run the send_text class method for this module.
112
+ #{self}.send_text(
113
+ tcp_obj: 'optional - value for tcp_obj passed into send_text',
114
+ serial_obj: 'optional - value for serial_obj passed into send_text'
115
+ )
116
+
117
+ # Run the send_data class method for this module.
118
+ #{self}.send_data(
119
+ tcp_obj: 'optional - value for tcp_obj passed into send_data',
120
+ serial_obj: 'optional - value for serial_obj passed into send_data'
121
+ )
122
+
123
+ # Run the recv_from_radio class method for this module.
124
+ #{self}.recv_from_radio(
125
+ tcp_obj: 'optional - value for tcp_obj passed into recv_from_radio',
126
+ serial_obj: 'optional - value for serial_obj passed into recv_from_radio'
127
+ )
128
+
129
+ # Run the drain_from_radio class method for this module.
130
+ #{self}.drain_from_radio(
131
+ tcp_obj: 'optional - value for tcp_obj passed into drain_from_radio',
132
+ serial_obj: 'optional - value for serial_obj passed into drain_from_radio'
133
+ )
134
+
135
+ # Run the subscribe class method for this module.
136
+ #{self}.subscribe(
137
+ tcp_obj: 'optional - value for tcp_obj passed into subscribe',
138
+ serial_obj: 'optional - value for serial_obj passed into subscribe'
139
+ )
140
+
141
+ # Run the disconnect class method for this module.
142
+ #{self}.disconnect(
143
+ tcp_obj: 'optional - value for tcp_obj passed into disconnect',
144
+ serial_obj: 'optional - value for serial_obj passed into disconnect'
145
+ )
146
+
147
+ # Run the authors class method for this module.
98
148
  #{self}.authors
149
+
99
150
  "
100
151
  end
101
152
  end