Class: Takagi::Message

Inherits:
Object
  • Object
show all
Defined in:
lib/takagi/message.rb

Class Method Summary collapse

Class Method Details

.build_response(code, payload, token) ⇒ Object



18
19
20
21
22
23
24
25
26
# File 'lib/takagi/message.rb', line 18

def self.build_response(code, payload, token)
  message_id = rand(0..0xFFFF)
  response_code = coap_method_to_code(code)
  header = [0x60 | (token.bytesize & 0x0F), response_code, (message_id >> 8) & 0xFF, message_id & 0xFF].pack("C*")

  payload_marker = "\xFF".b
  payload_data = payload.to_json.force_encoding("ASCII-8BIT")
  header + token + payload_marker + payload_data
end

.coap_code_to_method(code) ⇒ Object



28
29
30
31
32
33
34
35
36
# File 'lib/takagi/message.rb', line 28

def self.coap_code_to_method(code)
  case code
  when 1 then "GET"
  when 2 then "POST"
  when 3 then "PUT"
  when 4 then "DELETE"
  else "UNKNOWN"
  end
end

.coap_method_to_code(code) ⇒ Object



38
39
40
41
42
43
44
# File 'lib/takagi/message.rb', line 38

def self.coap_method_to_code(code)
  case code
  when 2.05 then 69  # 2.05 Content
  when 4.04 then 132 # 4.04 Not Found
  else 160 # Generic response
  end
end

.extract_uri_path(bytes) ⇒ Object



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
# File 'lib/takagi/message.rb', line 46

def self.extract_uri_path(bytes)
  path_segments = [] # Místo prostého stringu uložíme segmenty do pole
  options_start = 0
  last_option = 0

  while options_start < bytes.length && bytes[options_start] != 255 # 0xFF = start payloadu
    delta = (bytes[options_start] >> 4) & 0x0F  # Číslo opce
    len = bytes[options_start] & 0x0F           # Délka dat
    options_start += 1

    option_number = last_option + delta
    if option_number == 11 # Uri-Path (11 znamená část cesty)
      segment = bytes[options_start, len].pack("C*").b
      path_segments << segment # Ukládáme jednotlivé segmenty do pole
      puts "Parsed path segment: #{segment}" # Debug výpis
    end

    options_start += len
    last_option = option_number
  end

  # Spojíme segmenty pomocí `/` a zajistíme, že začne `/`
  path = "/#{path_segments.join("/")}"

  path.force_encoding("UTF-8") if path.valid_encoding?
  puts "Final parsed path: #{path}" # Debug výpis celé cesty
  path
end

.parse(data) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/takagi/message.rb', line 5

def self.parse(data)
  version_type_tkl = data.bytes[0]
  code = data.bytes[1]
  data.bytes[2..3].pack("C*").unpack1("n")
  token_length = version_type_tkl & 0x0F
  token = data[4, token_length] || "".b
  path = extract_uri_path(data.bytes[(4 + token_length)..])
  payload_start = data.index("\xFF".b)
  payload = payload_start ? data[(payload_start + 1)..].force_encoding("ASCII-8BIT") : nil

  { method: coap_code_to_method(code), path: path, token: token, payload: payload }
end