Class: OpenC3::CmdResponseProtocol

Inherits:
Protocol show all
Defined in:
lib/openc3/interfaces/protocols/cmd_response_protocol.rb

Overview

Protocol that waits for a response for any commands with a defined response packet. The response packet is identified but not defined by the protocol.

Instance Attribute Summary

Attributes inherited from Protocol

#allow_empty_data, #extra, #interface

Instance Method Summary collapse

Methods inherited from Protocol

#protocol_cmd, #read_data, #reset, #write_data

Constructor Details

#initialize(response_timeout = 5.0, response_polling_period = 0.02, raise_exceptions = false, allow_empty_data = nil) ⇒ CmdResponseProtocol

Returns a new instance of CmdResponseProtocol.

Parameters:

  • response_timeout (Float) (defaults to: 5.0)

    Number of seconds to wait before timing out when waiting for a response

  • response_polling_period (Float) (defaults to: 0.02)

    Number of seconds to wait between polling for a response

  • raise_exceptions (String) (defaults to: false)

    Whether to raise exceptions when errors occur in the protocol like unexpected responses or response timeouts.

  • allow_empty_data (true/false/nil) (defaults to: nil)

    See Protocol#initialize



35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/openc3/interfaces/protocols/cmd_response_protocol.rb', line 35

def initialize(
  response_timeout = 5.0,
  response_polling_period = 0.02,
  raise_exceptions = false,
  allow_empty_data = nil
)
  super(allow_empty_data)
  @response_timeout = ConfigParser.handle_nil(response_timeout)
  @response_timeout = @response_timeout.to_f if @response_timeout
  @response_polling_period = response_polling_period.to_f
  @raise_exceptions = ConfigParser.handle_true_false(raise_exceptions)
  @write_block_queue = Queue.new
  @response_packet = nil
end

Instance Method Details

#connect_resetObject



50
51
52
53
# File 'lib/openc3/interfaces/protocols/cmd_response_protocol.rb', line 50

def connect_reset
  super()
  @write_block_queue.clear
end

#disconnect_resetObject



55
56
57
58
# File 'lib/openc3/interfaces/protocols/cmd_response_protocol.rb', line 55

def disconnect_reset
  super()
  @write_block_queue << nil # Unblock the write block queue
end

#handle_error(msg) ⇒ Object



111
112
113
114
# File 'lib/openc3/interfaces/protocols/cmd_response_protocol.rb', line 111

def handle_error(msg)
  Logger.error(msg)
  raise msg if @raise_exceptions
end

#post_write_interface(packet, data, extra = nil) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/openc3/interfaces/protocols/cmd_response_protocol.rb', line 88

def post_write_interface(packet, data, extra = nil)
  if @response_packet
    if @response_timeout
      response_timeout_time = Time.now + @response_timeout
    else
      response_timeout_time = nil
    end

    # Block the write until the response is received
    begin
      @write_block_queue.pop(true)
    rescue
      sleep(@response_polling_period)
      retry if !response_timeout_time
      retry if response_timeout_time and Time.now < response_timeout_time
      handle_error("#{@interface ? @interface.name : ""}: Timeout waiting for response")
    end

    @response_packet = nil
  end
  return super(packet, data, extra)
end

#read_packet(packet) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/openc3/interfaces/protocols/cmd_response_protocol.rb', line 60

def read_packet(packet)
  if @response_packet
    # Grab the response packet specified in the command
    result_packet = System.telemetry.packet(@response_packet[0], @response_packet[1]).clone
    result_packet.buffer = packet.buffer
    result_packet.received_time = nil
    result_packet.stored = packet.stored
    result_packet.extra = packet.extra

    # Release the write
    @write_block_queue << nil

    # This returns the fully identified and defined packet
    # Received time is handled by the interface microservice
    return result_packet
  else
    return packet
  end
end

#write_packet(packet) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/openc3/interfaces/protocols/cmd_response_protocol.rb', line 80

def write_packet(packet)
  # Setup the response packet (if there is one)
  # This primes waiting for the response in post_write_interface
  @response_packet = packet.response

  return packet
end