Class: OpenC3::CrcProtocol
- Defined in:
- lib/openc3/interfaces/protocols/crc_protocol.rb
Overview
Creates a CRC on write and verifies a CRC on read
Constant Summary collapse
- ERROR =
on CRC mismatch
"ERROR"
- DISCONNECT =
on CRC mismatch
"DISCONNECT"
Instance Attribute Summary
Attributes inherited from Protocol
#allow_empty_data, #extra, #interface
Instance Method Summary collapse
-
#initialize(write_item_name = nil, strip_crc = false, bad_strategy = "ERROR", bit_offset = -32,, bit_size = 32, endianness = 'BIG_ENDIAN', poly = nil, seed = nil, xor = nil, reflect = nil, allow_empty_data = nil) ⇒ CrcProtocol
constructor
A new instance of CrcProtocol.
- #read_data(data, extra = nil) ⇒ Object
- #write_data(data, extra = nil) ⇒ Object
- #write_packet(packet) ⇒ Object
Methods inherited from Protocol
#connect_reset, #disconnect_reset, #post_write_interface, #protocol_cmd, #read_packet, #reset
Constructor Details
#initialize(write_item_name = nil, strip_crc = false, bad_strategy = "ERROR", bit_offset = -32,, bit_size = 32, endianness = 'BIG_ENDIAN', poly = nil, seed = nil, xor = nil, reflect = nil, allow_empty_data = nil) ⇒ CrcProtocol
Returns a new instance of CrcProtocol.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 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 99 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 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/openc3/interfaces/protocols/crc_protocol.rb', line 45 def initialize( write_item_name = nil, strip_crc = false, bad_strategy = "ERROR", bit_offset = -32, bit_size = 32, endianness = 'BIG_ENDIAN', poly = nil, seed = nil, xor = nil, reflect = nil, allow_empty_data = nil ) super(allow_empty_data) @write_item_name = ConfigParser.handle_nil(write_item_name) @strip_crc = ConfigParser.handle_true_false(strip_crc) raise "Invalid strip CRC of '#{strip_crc}'. Must be TRUE or FALSE." unless !!@strip_crc == @strip_crc case bad_strategy when ERROR, DISCONNECT @bad_strategy = bad_strategy else raise "Invalid bad CRC strategy of #{bad_strategy}. Must be ERROR or DISCONNECT." end case endianness.to_s.upcase when 'BIG_ENDIAN' @endianness = :BIG_ENDIAN # Convert to symbol for use in BinaryAccessor.write when 'LITTLE_ENDIAN' @endianness = :LITTLE_ENDIAN # Convert to symbol for use in BinaryAccessor.write else raise "Invalid endianness '#{endianness}'. Must be BIG_ENDIAN or LITTLE_ENDIAN." end begin @bit_offset = Integer(bit_offset) rescue raise "Invalid bit offset of #{bit_offset}. Must be a number." end raise "Invalid bit offset of #{bit_offset}. Must be divisible by 8." if @bit_offset % 8 != 0 poly = ConfigParser.handle_nil(poly) begin poly = Integer(poly) if poly rescue raise "Invalid polynomial of #{poly}. Must be a number." end seed = ConfigParser.handle_nil(seed) begin seed = Integer(seed) if seed rescue raise "Invalid seed of #{seed}. Must be a number." end xor = ConfigParser.handle_true_false_nil(xor) raise "Invalid XOR value of '#{xor}'. Must be TRUE or FALSE." if xor && !!xor != xor reflect = ConfigParser.handle_true_false_nil(reflect) if reflect raise "Invalid reflect value of '#{reflect}'. Must be TRUE or FALSE." if reflect && !!reflect != reflect # Built the CRC arguments array. All subsequent arguments are dependent # on the previous ones so we build it up incrementally. args = [] if poly args << poly if seed args << seed unless xor.nil? # Can't check raw variable because it could be false args << xor unless reflect.nil? # Can't check raw variable because it could be false args << reflect end end end end @bit_size = bit_size.to_i case @bit_size when 16 @pack = (@endianness == :BIG_ENDIAN) ? 'n' : 'v' if args.empty? @crc = Crc16.new else @crc = Crc16.new(*args) end when 32 @pack = (@endianness == :BIG_ENDIAN) ? 'N' : 'V' if args.empty? @crc = Crc32.new else @crc = Crc32.new(*args) end when 64 @pack = (@endianness == :BIG_ENDIAN) ? 'N' : 'V' if args.empty? @crc = Crc64.new else @crc = Crc64.new(*args) end else raise "Invalid bit size of #{bit_size}. Must be 16, 32, or 64." end end |
Instance Method Details
#read_data(data, extra = nil) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/openc3/interfaces/protocols/crc_protocol.rb', line 150 def read_data(data, extra = nil) return super(data, extra) if data.length <= 0 crc = BinaryAccessor.read(@bit_offset, @bit_size, :UINT, data, @endianness) calculated_crc = @crc.calc(data[0...(@bit_offset / 8)]) if calculated_crc != crc Logger.error "#{@interface ? @interface.name : ""}: Invalid CRC detected! Calculated 0x#{calculated_crc.to_s(16).upcase} vs found 0x#{crc.to_s(16).upcase}." if @bad_strategy == DISCONNECT return :DISCONNECT end end if @strip_crc new_data = data.dup new_data = new_data[0...(@bit_offset / 8)] end_range = (@bit_offset + @bit_size) / 8 new_data << data[end_range..-1] if end_range != 0 return new_data, extra end return data, extra end |
#write_data(data, extra = nil) ⇒ Object
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/openc3/interfaces/protocols/crc_protocol.rb', line 180 def write_data(data, extra = nil) unless @write_item_name if @bit_size == 64 crc = @crc.calc(data) data << ("\x00" * 8) BinaryAccessor.write((crc >> 32), -64, 32, :UINT, data, @endianness, :ERROR) BinaryAccessor.write((crc & 0xFFFFFFFF), -32, 32, :UINT, data, @endianness, :ERROR) else crc = @crc.calc(data) data << ("\x00" * (@bit_size / 8)) BinaryAccessor.write(crc, -@bit_size, @bit_size, :UINT, data, @endianness, :ERROR) end end return data, extra end |
#write_packet(packet) ⇒ Object
171 172 173 174 175 176 177 178 |
# File 'lib/openc3/interfaces/protocols/crc_protocol.rb', line 171 def write_packet(packet) if @write_item_name end_range = packet.get_item(@write_item_name).bit_offset / 8 crc = @crc.calc(packet.buffer(false)[0...end_range]) packet.write(@write_item_name, crc) end packet end |