Class: Takagi::Message::Base
- Inherits:
-
Object
- Object
- Takagi::Message::Base
- Defined in:
- lib/takagi/message/base.rb,
sig/takagi/message/base.rbs
Overview
Base class for message
Instance Attribute Summary collapse
-
#code ⇒ Object
readonly
Returns the value of attribute code.
-
#message_id ⇒ Object
readonly
Returns the value of attribute message_id.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#payload ⇒ Object
readonly
Returns the value of attribute payload.
-
#token ⇒ Object
readonly
Returns the value of attribute token.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Instance Method Summary collapse
-
#coap_code_to_method(code) ⇒ String
Convert CoAP code number to method name using registry.
-
#coap_method_to_code(method) ⇒ Integer
Convert method name to CoAP code number using registry.
- #coerce_option_value(value) ⇒ Object
- #decode_extended_value(bytes, position, raw_value) ⇒ Object
- #extract_payload(data) ⇒ nil, untyped
-
#initialize(data = nil, transport: :udp) ⇒ Base
constructor
A new instance of Base.
- #parse(data) ⇒ Object
- #parse_options(bytes) ⇒ Object
- #store_option(options, option_number, value) ⇒ Object
Constructor Details
#initialize(data = nil, transport: :udp) ⇒ Base
Returns a new instance of Base.
9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/takagi/message/base.rb', line 9 def initialize(data = nil, transport: :udp) @transport = transport if data.is_a?(String) || data.is_a?(IO) case transport when :tcp parse_tcp(data) else parse(data) end end @data = data @logger = Takagi.logger end |
Instance Attribute Details
#code ⇒ Object (readonly)
Returns the value of attribute code.
7 8 9 |
# File 'lib/takagi/message/base.rb', line 7 def code @code end |
#message_id ⇒ Object (readonly)
Returns the value of attribute message_id.
7 8 9 |
# File 'lib/takagi/message/base.rb', line 7 def @message_id end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
7 8 9 |
# File 'lib/takagi/message/base.rb', line 7 def @options end |
#payload ⇒ Object (readonly)
Returns the value of attribute payload.
7 8 9 |
# File 'lib/takagi/message/base.rb', line 7 def payload @payload end |
#token ⇒ Object (readonly)
Returns the value of attribute token.
7 8 9 |
# File 'lib/takagi/message/base.rb', line 7 def token @token end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
7 8 9 |
# File 'lib/takagi/message/base.rb', line 7 def type @type end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
7 8 9 |
# File 'lib/takagi/message/base.rb', line 7 def version @version end |
Instance Method Details
#coap_code_to_method(code) ⇒ String
Convert CoAP code number to method name using registry
26 27 28 29 30 31 32 33 34 |
# File 'lib/takagi/message/base.rb', line 26 def coap_code_to_method(code) # Check if it's an OBSERVE request (GET with Observe option) if code == CoAP::Registries::Method::GET && @options && @options[CoAP::Registries::Option::OBSERVE] 'OBSERVE' else # Use CoAP registry to convert code to string CoAP::CodeHelpers.to_string(code) end end |
#coap_method_to_code(method) ⇒ Integer
Convert method name to CoAP code number using registry
39 40 41 |
# File 'lib/takagi/message/base.rb', line 39 def coap_method_to_code(method) CoAP::CodeHelpers.to_numeric(method) end |
#coerce_option_value(value) ⇒ Object
147 148 149 150 151 152 |
# File 'lib/takagi/message/base.rb', line 147 def coerce_option_value(value) ascii = value.dup.force_encoding('ASCII-8BIT') return ascii.force_encoding('UTF-8') if ascii.valid_encoding? ascii end |
#decode_extended_value(bytes, position, raw_value) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/takagi/message/base.rb', line 118 def decode_extended_value(bytes, position, raw_value) case raw_value when 13 [bytes[position] + 13, position + 1] when 14 extended = bytes[position, 2].pack('C*').unpack1('n') + 269 [extended, position + 2] else [raw_value, position] end end |
#extract_payload(data) ⇒ nil, untyped
108 109 110 111 112 113 114 115 116 |
# File 'lib/takagi/message/base.rb', line 108 def extract_payload(data) Takagi.logger.debug "Extracting payload: #{data.inspect}" payload_start = data.index("\xFF".b) return nil unless payload_start payload = data[(payload_start + 1)..].dup.force_encoding('ASCII-8BIT') utf8 = payload.dup.force_encoding('UTF-8') utf8.valid_encoding? ? utf8 : payload end |
#parse(data) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/takagi/message/base.rb', line 68 def parse(data) bytes = data.bytes @version = (bytes[0] >> 6) & 0b11 @type = (bytes[0] >> 4) & 0b11 token_length = bytes[0] & 0b1111 @code = bytes[1] @message_id = bytes[2..3].pack('C*').unpack1('n') @token = token_length.positive? ? bytes[4, token_length].pack('C*') : ''.b @options = (bytes[(4 + token_length)..]) @payload = extract_payload(data) end |
#parse_options(bytes) ⇒ Object
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 |
# File 'lib/takagi/message/base.rb', line 80 def (bytes) = {} position = 0 last_option_number = 0 while position < bytes.length && bytes[position] != 0xFF byte = bytes[position] position += 1 delta_raw = (byte >> 4) & 0x0F length_raw = byte & 0x0F delta, position = decode_extended_value(bytes, position, delta_raw) length, position = decode_extended_value(bytes, position, length_raw) option_number = last_option_number + delta value = bytes[position, length].pack('C*') position += length store_option(, option_number, value) last_option_number = option_number end Takagi.logger.debug "Parsed CoAP options: #{.inspect}" end |
#store_option(options, option_number, value) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/takagi/message/base.rb', line 130 def store_option(, option_number, value) formatted = coerce_option_value(value) # Uri-Path (11) and Uri-Query (15) are always stored as arrays case option_number when CoAP::Registries::Option::URI_PATH, CoAP::Registries::Option::URI_QUERY [option_number] ||= [] [option_number] << formatted else [option_number] = if .key?(option_number) Array([option_number]) << formatted else formatted end end end |