Class: Cosmos::TemplateStreamProtocol

Inherits:
TerminatedStreamProtocol show all
Defined in:
lib/cosmos/streams/template_stream_protocol.rb

Instance Attribute Summary

Attributes inherited from StreamProtocol

#bytes_read, #bytes_written, #interface, #post_read_data_callback, #post_read_packet_callback, #post_write_data_callback, #pre_write_packet_callback, #stream

Instance Method Summary collapse

Methods inherited from StreamProtocol

#connected?, #post_read_data, #post_read_packet, #write, #write_raw

Constructor Details

#initialize(write_termination_characters, read_termination_characters, ignore_lines = 0, initial_read_delay = nil, response_lines = 1, strip_read_termination = true, discard_leading_bytes = 0, sync_pattern = nil, fill_sync_pattern = false) ⇒ TemplateStreamProtocol

Returns a new instance of TemplateStreamProtocol.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/cosmos/streams/template_stream_protocol.rb', line 19

def initialize(write_termination_characters,
  read_termination_characters,
  ignore_lines = 0,
  initial_read_delay = nil,
  response_lines = 1,
  strip_read_termination = true,
  discard_leading_bytes = 0,
  sync_pattern = nil,
  fill_sync_pattern = false)
  super(write_termination_characters,
        read_termination_characters,
        strip_read_termination,
        discard_leading_bytes,
        sync_pattern,
        fill_sync_pattern)
  @response_template = nil
  @response_packet = nil
  @read_queue = Queue.new
  @ignore_lines = ignore_lines.to_i
  @response_lines = response_lines.to_i
  @initial_read_delay = ConfigParser.handle_nil(initial_read_delay)
  @initial_read_delay = @initial_read_delay.to_f if @initial_read_delay
end

Instance Method Details

#connect(stream) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/cosmos/streams/template_stream_protocol.rb', line 43

def connect(stream)
  # Empty the read queue
  begin
    @read_queue.pop(true) while @read_queue.length > 0
  rescue
  end

  super(stream)

  if @initial_read_delay
    sleep(@initial_read_delay)
    loop do
      break if @stream.read_nonblock.length <= 0
    end
  end
end

#disconnectObject



60
61
62
63
# File 'lib/cosmos/streams/template_stream_protocol.rb', line 60

def disconnect
  super()
  @read_queue << nil # Unblock the read queue in the interface thread
end

#post_write_data(packet, data) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/cosmos/streams/template_stream_protocol.rb', line 100

def post_write_data(packet, data)
  if @response_template && @response_packet
    @ignore_lines.times do
      read(false)
    end
    response_string = ''
    @response_lines.times do
      response = read(false)
      raise "No response received" unless response
      response_string << response.buffer
    end

    # Grab the response packet specified in the command
    result_packet = System.telemetry.packet(@interface.target_names[0], @response_packet).clone
    result_packet.received_time = nil

    # Convert the response template into a Regexp
    response_item_names = []
    response_template = @response_template.clone
    response_template_items = @response_template.scan(/<.*?>/)
    response_template_items.each do |item|
      response_item_names << item[1..-2]
      response_template.gsub!(item, "(.*)")
    end
    response_regexp = Regexp.new(response_template)

    # Scan the response for the variables in brackets <VARIABLE>
    # Write the packet value with each of the values received
    response_values = response_string.scan(response_regexp)[0]
    raise "Unexpected response received: #{response_string}" if !response_values or (response_values.length != response_item_names.length)
    response_values.each_with_index do |value, i|
      result_packet.write(response_item_names[i], value)
    end

    @read_queue << result_packet
  end
end

#pre_write_packet(packet) ⇒ Object

See StreamProtocol#pre_write_packet



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/cosmos/streams/template_stream_protocol.rb', line 74

def pre_write_packet(packet)
  # First grab the response template and response packet (if there is one)
  begin
    @response_template = packet.read("RSP_TEMPLATE").strip
    @response_packet = packet.read("RSP_PACKET").strip
  rescue
    # If there is no response template we set to nil
    @response_template = nil
    @response_packet = nil
  end

  # Grab the command template because that is all we eventually send
  template = packet.read("CMD_TEMPLATE")
  # Create a new empty packet to call super on
  raw_packet = Packet.new(nil, nil)
  raw_packet.buffer = template
  # Call super to allow the super classes to massage the packet data
  data = super(raw_packet)
  # Scan the template for variables in brackets <VARIABLE>
  # Read these values from the packet and substitute them in the template
  template.scan(/<(.*?)>/).each do |variable|
    data.gsub!("<#{variable[0]}>", packet.read(variable[0], :RAW).to_s)
  end
  data
end

#read(use_queue = true) ⇒ Object



65
66
67
68
69
70
71
# File 'lib/cosmos/streams/template_stream_protocol.rb', line 65

def read(use_queue = true)
  if use_queue
    return @read_queue.pop
  else
    return super()
  end
end