Class: Meshtastic::StreamInterface

Inherits:
Object
  • Object
show all
Defined in:
lib/meshtastic/stream_interface.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ StreamInterface

Returns a new instance of StreamInterface.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/meshtastic/stream_interface.rb', line 14

def initialize(opts = {})
  debug_out = opts[:debug_out]
  no_proto = false if opts[:no_proto].nil?
  no_proto = true if opts[:no_proto]

  connect_now = true if opts[:connect_now].nil?
  connect_now = false if opts[:connect_now]

  no_nodes = false if opts[:no_nodes].nil?
  no_nodes = true if opts[:no_nodes]
  # Note: In Ruby, we don't need to explicitly define a type hint for self.
  raise Exception("StreamInterface is now abstract (to update existing code create SerialInterface instead)") if !defined?(@stream) && !no_proto

  @stream = nil
  @rx_buf = []
  @want_exit = false
  @is_windows11 = RUBY_PLATFORM =~ /win32/
  @cur_log_line = ""

  # Note: Ruby's threading API is different from Python. We use the Thread class instead of threading.Thread.
  rx_thread = Thread.new do
    reader
  end

  if connect_now
    connect
    unless no_proto
      wait_for_config
    end
  end
rescue StandardError => e
  raise e
end

Instance Attribute Details

#cur_log_lineObject

Returns the value of attribute cur_log_line.



8
9
10
# File 'lib/meshtastic/stream_interface.rb', line 8

def cur_log_line
  @cur_log_line
end

#is_windows11Object

Returns the value of attribute is_windows11.



8
9
10
# File 'lib/meshtastic/stream_interface.rb', line 8

def is_windows11
  @is_windows11
end

#rx_bufObject

Returns the value of attribute rx_buf.



8
9
10
# File 'lib/meshtastic/stream_interface.rb', line 8

def rx_buf
  @rx_buf
end

#streamObject

Returns the value of attribute stream.



8
9
10
# File 'lib/meshtastic/stream_interface.rb', line 8

def stream
  @stream
end

#want_exitObject

Returns the value of attribute want_exit.



8
9
10
# File 'lib/meshtastic/stream_interface.rb', line 8

def want_exit
  @want_exit
end

Instance Method Details

#authorsObject

Author(s)

0day Inc. <[email protected]>



116
117
118
119
120
# File 'lib/meshtastic/stream_interface.rb', line 116

def authors
  "AUTHOR(S):
    0day Inc. <[email protected]>
  "
end

#closeObject



108
109
110
111
112
# File 'lib/meshtastic/stream_interface.rb', line 108

def close
  @want_exit = true
  @rx_thread.join if @rx_thread && @rx_thread != Thread.current
  @stream&.close
end

#connect(opts = {}) ⇒ Object

Supported Method Parameters

packet_id = Meshtastic.generate_packet_id(

last_packet_id: 'optional - Last Packet ID (Default: 0)'

)



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/meshtastic/stream_interface.rb', line 52

def connect(opts = {})
  # Send some bogus UART characters to force a sleeping device to wake, and
  # if the reading statemachine was parsing a bad packet make sure we write enough start bytes to force it to resync (we don't use START1 because we want to ensure it is looking for START1)
  p = [START2] * 32
  self._write_bytes(p)

  sleep(0.1) # wait 100ms to give device time to start running

  @rx_thread.start
  mui = Meshtastic::MeshInterface.new
  mui.start_config
rescue StandardError => e
  raise e
end

#helpObject

Display Usage for this Module



124
125
126
127
128
129
130
# File 'lib/meshtastic/stream_interface.rb', line 124

def help
  puts "USAGE:
    #{self}.connect

    #{self}.authors
  "
end

#read_bytes(opts = {}) ⇒ Object



93
94
95
96
# File 'lib/meshtastic/stream_interface.rb', line 93

def read_bytes(opts = {})
  length = opts[:length]
  @stream.read(length) if @stream
end

#readerObject

Supported Method Parameters

Meshtastic::StreamInterface.reader



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/meshtastic/stream_interface.rb', line 69

def reader
  loop do
    break if @want_exit
    # Read from stream and handle data
    # This should be implemented based on how you handle reading from @stream
    data = @stream.read(1) # Example: read one byte at a time
    @rx_buf << data if data

    # Here you would parse the data according to your protocol
    # This is just a placeholder for the actual reading logic

    # Yield for other threads
    sleep(0.01)
  end
rescue StandardError => e
  raise e
end

#send_to_radio_impl(opts = {}) ⇒ Object



98
99
100
101
102
103
104
105
106
# File 'lib/meshtastic/stream_interface.rb', line 98

def send_to_radio_impl(opts = {})
  to_radio = opts[:to_radio]
  # Convert to_radio to bytes, assuming it's a proto message in Ruby
  # This example assumes `to_radio` has a method to serialize to string
  b = to_radio.to_s
  buf_len = b.length
  header = [0x94, 0xC3, (buf_len >> 8) & 0xFF, buf_len & 0xFF].pack('C*')
  write_bytes(header + b)
end

#write_bytes(opts = {}) ⇒ Object



87
88
89
90
91
# File 'lib/meshtastic/stream_interface.rb', line 87

def write_bytes(opts = {})
  bytes = opts[:bytes]
  @stream.write(bytes) if @stream
  @stream.flush if @stream
end