meshtastic 0.0.178 → 0.0.180

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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -175
  3. data/documentation/README.md +60 -0
  4. data/documentation/admin-channel.md +33 -0
  5. data/documentation/admin-config.md +28 -0
  6. data/documentation/admin-firmware.md +69 -0
  7. data/documentation/admin.md +55 -0
  8. data/documentation/apponly.md +22 -0
  9. data/documentation/atak.md +110 -0
  10. data/documentation/bluetooth-bluez.md +35 -0
  11. data/documentation/bluetooth.md +87 -0
  12. data/documentation/cannedmessages.md +25 -0
  13. data/documentation/channel.md +3 -0
  14. data/documentation/clientonly.md +21 -0
  15. data/documentation/config.md +3 -0
  16. data/documentation/connection-status.md +22 -0
  17. data/documentation/deviceonly.md +22 -0
  18. data/documentation/localonly.md +21 -0
  19. data/documentation/mesh-interface.md +52 -0
  20. data/documentation/meshtastic.md +45 -0
  21. data/documentation/module-config.md +26 -0
  22. data/documentation/mqtt.md +101 -0
  23. data/documentation/paxcount.md +25 -0
  24. data/documentation/portnums.md +67 -0
  25. data/documentation/position.md +34 -0
  26. data/documentation/protobufs.md +162 -0
  27. data/documentation/remote-hardware.md +33 -0
  28. data/documentation/rtttl.md +24 -0
  29. data/documentation/serial.md +78 -0
  30. data/documentation/storeforward.md +24 -0
  31. data/documentation/stream-interface.md +15 -0
  32. data/documentation/tcp.md +43 -0
  33. data/documentation/telemetry.md +32 -0
  34. data/documentation/traceroute.md +28 -0
  35. data/documentation/util.md +27 -0
  36. data/documentation/xmodem.md +22 -0
  37. data/lib/meshtastic/admin/channel.rb +90 -0
  38. data/lib/meshtastic/admin/config.rb +154 -0
  39. data/lib/meshtastic/admin/firmware.rb +173 -0
  40. data/lib/meshtastic/admin.rb +495 -7
  41. data/lib/meshtastic/apponly.rb +26 -8
  42. data/lib/meshtastic/atak.rb +298 -7
  43. data/lib/meshtastic/bluetooth/bluez.rb +20 -1
  44. data/lib/meshtastic/bluetooth.rb +70 -59
  45. data/lib/meshtastic/cannedmessages.rb +23 -8
  46. data/lib/meshtastic/channel.rb +3 -21
  47. data/lib/meshtastic/clientonly.rb +26 -8
  48. data/lib/meshtastic/config.rb +3 -21
  49. data/lib/meshtastic/connection_status.rb +13 -8
  50. data/lib/meshtastic/deviceonly.rb +23 -8
  51. data/lib/meshtastic/localonly.rb +23 -8
  52. data/lib/meshtastic/mesh_interface.rb +11 -0
  53. data/lib/meshtastic/module_config.rb +18 -9
  54. data/lib/meshtastic/mqtt.rb +72 -35
  55. data/lib/meshtastic/paxcount.rb +30 -9
  56. data/lib/meshtastic/portnums.rb +18 -8
  57. data/lib/meshtastic/position.rb +45 -0
  58. data/lib/meshtastic/remote_hardware.rb +50 -9
  59. data/lib/meshtastic/rtttl.rb +26 -8
  60. data/lib/meshtastic/serial.rb +81 -70
  61. data/lib/meshtastic/storeforward.rb +23 -8
  62. data/lib/meshtastic/stream_interface.rb +11 -0
  63. data/lib/meshtastic/tcp.rb +153 -0
  64. data/lib/meshtastic/telemetry.rb +27 -9
  65. data/lib/meshtastic/traceroute.rb +42 -0
  66. data/lib/meshtastic/util.rb +3 -1
  67. data/lib/meshtastic/version.rb +1 -1
  68. data/lib/meshtastic/xmodem.rb +17 -8
  69. data/lib/meshtastic.rb +46 -6
  70. data/spec/conventions_spec.rb +321 -0
  71. data/spec/lib/meshtastic/admin/channel_spec.rb +45 -0
  72. data/spec/lib/meshtastic/admin/config_spec.rb +48 -0
  73. data/spec/lib/meshtastic/admin/firmware_spec.rb +118 -0
  74. data/spec/lib/meshtastic/admin_pb_spec.rb +1 -1
  75. data/spec/lib/meshtastic/admin_spec.rb +79 -0
  76. data/spec/lib/meshtastic/apponly_pb_spec.rb +1 -1
  77. data/spec/lib/meshtastic/apponly_spec.rb +4 -0
  78. data/spec/lib/meshtastic/atak_pb_spec.rb +1 -1
  79. data/spec/lib/meshtastic/atak_spec.rb +147 -0
  80. data/spec/lib/meshtastic/bluetooth_spec.rb +1 -1
  81. data/spec/lib/meshtastic/cannedmessages_pb_spec.rb +1 -1
  82. data/spec/lib/meshtastic/cannedmessages_spec.rb +3 -0
  83. data/spec/lib/meshtastic/channel_pb_spec.rb +1 -1
  84. data/spec/lib/meshtastic/channel_spec.rb +3 -0
  85. data/spec/lib/meshtastic/clientonly_pb_spec.rb +1 -1
  86. data/spec/lib/meshtastic/clientonly_spec.rb +5 -0
  87. data/spec/lib/meshtastic/config_pb_spec.rb +1 -1
  88. data/spec/lib/meshtastic/config_spec.rb +4 -1
  89. data/spec/lib/meshtastic/connection_status_pb_spec.rb +1 -1
  90. data/spec/lib/meshtastic/connection_status_spec.rb +3 -0
  91. data/spec/lib/meshtastic/deviceonly_legacy_pb_spec.rb +1 -1
  92. data/spec/lib/meshtastic/deviceonly_pb_spec.rb +1 -1
  93. data/spec/lib/meshtastic/deviceonly_spec.rb +3 -0
  94. data/spec/lib/meshtastic/localonly_pb_spec.rb +1 -1
  95. data/spec/lib/meshtastic/localonly_spec.rb +3 -0
  96. data/spec/lib/meshtastic/mesh_beacon_pb_spec.rb +1 -1
  97. data/spec/lib/meshtastic/mesh_pb_spec.rb +1 -1
  98. data/spec/lib/meshtastic/module_config_pb_spec.rb +1 -1
  99. data/spec/lib/meshtastic/module_config_spec.rb +21 -0
  100. data/spec/lib/meshtastic/mqtt_pb_spec.rb +1 -1
  101. data/spec/lib/meshtastic/paxcount_pb_spec.rb +1 -1
  102. data/spec/lib/meshtastic/paxcount_spec.rb +23 -0
  103. data/spec/lib/meshtastic/portnums_pb_spec.rb +1 -1
  104. data/spec/lib/meshtastic/portnums_spec.rb +4 -0
  105. data/spec/lib/meshtastic/position_spec.rb +33 -0
  106. data/spec/lib/meshtastic/remote_hardware_pb_spec.rb +1 -1
  107. data/spec/lib/meshtastic/remote_hardware_spec.rb +24 -0
  108. data/spec/lib/meshtastic/rtttl_pb_spec.rb +1 -1
  109. data/spec/lib/meshtastic/rtttl_spec.rb +21 -0
  110. data/spec/lib/meshtastic/storeforward_pb_spec.rb +1 -1
  111. data/spec/lib/meshtastic/storeforward_spec.rb +21 -0
  112. data/spec/lib/meshtastic/tcp_spec.rb +48 -0
  113. data/spec/lib/meshtastic/telemetry_pb_spec.rb +1 -1
  114. data/spec/lib/meshtastic/telemetry_spec.rb +21 -0
  115. data/spec/lib/meshtastic/traceroute_spec.rb +27 -0
  116. data/spec/lib/meshtastic/xmodem_pb_spec.rb +1 -1
  117. data/spec/lib/meshtastic/xmodem_spec.rb +6 -1
  118. data/spec/lib/meshtastic_spec.rb +3 -0
  119. metadata +48 -1
@@ -2,22 +2,40 @@
2
2
 
3
3
  require 'meshtastic/rtttl_pb'
4
4
 
5
- # Plugin used to interact with Meshtastic nodes
6
5
  module Meshtastic
7
6
  module RTTTL
8
- # Author(s):: 0day Inc. <support@0dayinc.com>
7
+ public_class_method def self.encode(opts = {})
8
+ config = Meshtastic::RTTTLConfig.new
9
+ config.ringtone = opts.fetch(:ringtone, '')
10
+ config
11
+ end
9
12
 
10
- public_class_method def self.authors
11
- "AUTHOR(S):
12
- 0day Inc. <support@0dayinc.com>
13
- "
13
+ public_class_method def self.set(opts = {})
14
+ Admin.send(opts.merge(set_ringtone_message: opts.fetch(:ringtone)))
14
15
  end
15
16
 
16
- # Display Usage for this Module
17
+ public_class_method def self.get(opts = {})
18
+ Admin.send(opts.merge(get_ringtone_request: true))
19
+ end
20
+
21
+ public_class_method def self.authors
22
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
23
+ end
17
24
 
18
25
  public_class_method def self.help
19
- puts "USAGE:
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.
20
37
  #{self}.authors
38
+
21
39
  "
22
40
  end
23
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
@@ -2,22 +2,37 @@
2
2
 
3
3
  require 'meshtastic/storeforward_pb'
4
4
 
5
- # Plugin used to interact with Meshtastic nodes
6
5
  module Meshtastic
7
6
  module Storeforward
8
- # Author(s):: 0day Inc. <support@0dayinc.com>
7
+ public_class_method def self.encode(opts = {})
8
+ message = Meshtastic::StoreAndForward.new
9
+ message.rr = opts.fetch(:rr, :ROUTER_HEARTBEAT)
10
+ message
11
+ end
9
12
 
10
- public_class_method def self.authors
11
- "AUTHOR(S):
12
- 0day Inc. <support@0dayinc.com>
13
- "
13
+ public_class_method def self.send(opts = {})
14
+ data = Meshtastic::Data.new(
15
+ portnum: :STORE_FORWARD_APP,
16
+ payload: encode(opts).to_proto
17
+ )
18
+ Meshtastic.deliver_data(opts.merge(data: data, port_num: Meshtastic::PortNum::STORE_FORWARD_APP))
14
19
  end
15
20
 
16
- # Display Usage for this Module
21
+ public_class_method def self.authors
22
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
23
+ end
17
24
 
18
25
  public_class_method def self.help
19
- puts "USAGE:
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.
20
34
  #{self}.authors
35
+
21
36
  "
22
37
  end
23
38
  end
@@ -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
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'socket'
4
+
5
+ # Meshtastic client API over TCP. Framing matches Serial (START1/START2 + protobuf).
6
+ # Default port is 4403, same as the official TCP interface.
7
+ module Meshtastic
8
+ module TCP
9
+ DEFAULT_PORT = 4403
10
+
11
+ public_class_method def self.connect(opts = {})
12
+ host = opts[:host] ||= '127.0.0.1'
13
+ port = opts[:port] ||= DEFAULT_PORT
14
+ tcp_obj = nil
15
+ socket = opts[:socket] || TCPSocket.new(host, port)
16
+ socket.binmode
17
+
18
+ tcp_obj = {
19
+ serial_conn: socket,
20
+ tcp_socket: socket,
21
+ block_dev: "#{host}:#{port}",
22
+ host: host,
23
+ port: port,
24
+ tx_mutex: Mutex.new,
25
+ my_info: nil,
26
+ my_node_num: nil,
27
+ metadata: nil
28
+ }
29
+ tcp_obj[:rx_thread] = Meshtastic::Serial.send(
30
+ :init_rx_thread,
31
+ serial_conn: socket,
32
+ serial_obj: tcp_obj,
33
+ debug_out: opts[:debug_out]
34
+ )
35
+ Meshtastic::Serial.wake_up_device(serial_obj: tcp_obj)
36
+ if opts.fetch(:want_config, true)
37
+ mesh = Meshtastic::MeshInterface.new
38
+ bytes = mesh.start_config
39
+ tcp_obj[:config_id] = mesh.config_id
40
+ Meshtastic::Serial.send_to_radio(serial_obj: tcp_obj, to_radio: bytes)
41
+ end
42
+ tcp_obj
43
+ rescue StandardError
44
+ disconnect(tcp_obj: tcp_obj) if tcp_obj
45
+ raise
46
+ end
47
+
48
+ public_class_method def self.wait_for_config(opts = {})
49
+ Meshtastic::Serial.wait_for_config(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
50
+ end
51
+
52
+ public_class_method def self.send_to_radio(opts = {})
53
+ Meshtastic::Serial.send_to_radio(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
54
+ end
55
+
56
+ public_class_method def self.send_text(opts = {})
57
+ Meshtastic::Serial.send_text(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
58
+ end
59
+
60
+ public_class_method def self.send_data(opts = {})
61
+ Meshtastic::Serial.send_data(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
62
+ end
63
+
64
+ public_class_method def self.recv_from_radio(opts = {})
65
+ Meshtastic::Serial.recv_from_radio(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
66
+ end
67
+
68
+ public_class_method def self.drain_from_radio(opts = {})
69
+ Meshtastic::Serial.drain_from_radio(opts.merge(serial_obj: opts[:tcp_obj] || opts[:serial_obj]))
70
+ end
71
+
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
79
+ end
80
+
81
+ public_class_method def self.disconnect(opts = {})
82
+ Meshtastic::Serial.disconnect(serial_obj: opts[:tcp_obj] || opts[:serial_obj])
83
+ end
84
+
85
+ public_class_method def self.authors
86
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
87
+ end
88
+
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
+ )
98
+
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'
103
+ )
104
+
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.
148
+ #{self}.authors
149
+
150
+ "
151
+ end
152
+ end
153
+ end
@@ -2,22 +2,40 @@
2
2
 
3
3
  require 'meshtastic/telemetry_pb'
4
4
 
5
- # Plugin used to interact with Meshtastic nodes
6
5
  module Meshtastic
7
- module Telemetry
8
- # Author(s):: 0day Inc. <support@0dayinc.com>
6
+ class Telemetry
7
+ public_class_method def self.build(opts = {})
8
+ telemetry = new
9
+ telemetry.time = opts[:time].to_i if opts[:time]
10
+ telemetry
11
+ end
9
12
 
10
- public_class_method def self.authors
11
- "AUTHOR(S):
12
- 0day Inc. <support@0dayinc.com>
13
- "
13
+ public_class_method def self.request(opts = {})
14
+ data = Meshtastic::Data.new(
15
+ portnum: :TELEMETRY_APP,
16
+ payload: build(opts).to_proto,
17
+ want_response: true
18
+ )
19
+ Meshtastic.deliver_data(opts.merge(data: data, port_num: Meshtastic::PortNum::TELEMETRY_APP, want_response: true))
14
20
  end
15
21
 
16
- # Display Usage for this Module
22
+ public_class_method def self.authors
23
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
24
+ end
17
25
 
18
26
  public_class_method def self.help
19
- puts "USAGE:
27
+ puts " USAGE:
28
+ # Run the build class method for this module.
29
+ #{self}.build(
30
+ time: 'optional - value for time passed into build'
31
+ )
32
+
33
+ # Run the request class method for this module.
34
+ #{self}.request
35
+
36
+ # Run the authors class method for this module.
20
37
  #{self}.authors
38
+
21
39
  "
22
40
  end
23
41
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'meshtastic/mesh_pb'
4
+
5
+ module Meshtastic
6
+ module Traceroute
7
+ public_class_method def self.encode(opts = {})
8
+ discovery = Meshtastic::RouteDiscovery.new
9
+ Array(opts[:route]).each { |hop| discovery.route << hop }
10
+ discovery
11
+ end
12
+
13
+ public_class_method def self.send(opts = {})
14
+ data = Meshtastic::Data.new(
15
+ portnum: :TRACEROUTE_APP,
16
+ payload: encode(opts).to_proto,
17
+ want_response: true
18
+ )
19
+ Meshtastic.deliver_data(opts.merge(data: data, port_num: Meshtastic::PortNum::TRACEROUTE_APP, want_response: true))
20
+ end
21
+
22
+ public_class_method def self.authors
23
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
24
+ end
25
+
26
+ public_class_method def self.help
27
+ puts " USAGE:
28
+ # Run the encode class method for this module.
29
+ #{self}.encode(
30
+ route: 'optional - value for route passed into encode'
31
+ )
32
+
33
+ # Run the send class method for this module.
34
+ #{self}.send
35
+
36
+ # Run the authors class method for this module.
37
+ #{self}.authors
38
+
39
+ "
40
+ end
41
+ end
42
+ end
@@ -62,8 +62,10 @@ module Meshtastic
62
62
  # Display Usage for this Module
63
63
 
64
64
  public_class_method def self.help
65
- puts "USAGE:
65
+ puts " USAGE:
66
+ # Run the authors class method for this module.
66
67
  #{self}.authors
68
+
67
69
  "
68
70
  end
69
71
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Meshtastic
4
- VERSION = '0.0.178'
4
+ VERSION = '0.0.180'
5
5
  end
@@ -2,22 +2,31 @@
2
2
 
3
3
  require 'meshtastic/xmodem_pb'
4
4
 
5
- # Plugin used to interact with Meshtastic nodes
6
5
  module Meshtastic
7
6
  module Xmodem
8
- # Author(s):: 0day Inc. <support@0dayinc.com>
7
+ public_class_method def self.encode(opts = {})
8
+ packet = Meshtastic::XModem.new
9
+ packet.control = opts.fetch(:control, :SOH)
10
+ packet.seq = opts[:seq].to_i if opts[:seq]
11
+ packet.buffer = opts[:buffer] if opts[:buffer]
12
+ packet
13
+ end
9
14
 
10
15
  public_class_method def self.authors
11
- "AUTHOR(S):
12
- 0day Inc. <support@0dayinc.com>
13
- "
16
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
14
17
  end
15
18
 
16
- # Display Usage for this Module
17
-
18
19
  public_class_method def self.help
19
- puts "USAGE:
20
+ puts " USAGE:
21
+ # Run the encode class method for this module.
22
+ #{self}.encode(
23
+ seq: 'optional - value for seq passed into encode',
24
+ buffer: 'optional - value for buffer passed into encode'
25
+ )
26
+
27
+ # Run the authors class method for this module.
20
28
  #{self}.authors
29
+
21
30
  "
22
31
  end
23
32
  end