Class: PWN::SDR::Decoder::Bluetooth::LinkLayer
- Inherits:
-
Object
- Object
- PWN::SDR::Decoder::Bluetooth::LinkLayer
- Defined in:
- lib/pwn/sdr/decoder/bluetooth.rb
Overview
Connected header/CTE and selected control fields, after CRC verification.
Class Method Summary collapse
Class Method Details
.parse(opts = {}) ⇒ Object
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/pwn/sdr/decoder/bluetooth.rb', line 247 public_class_method def self.parse(opts = {}) header = opts[:header] payload = opts[:payload] encrypted = opts[:encrypted] byte = header[0] if header.length == 3 cte = header[2] return nil unless (2..20).cover?(cte & 31) && cte.nobits?(0x20) && cte >> 6 != 3 end hex = payload.pack('C*').unpack1('H*').upcase fields = { pdu_type: byte.allbits?(3) ? 'LL_CONTROL' : 'LL_DATA', header_length: header.length, cte_info: header[2], llid: byte & 3, nesn: (byte >> 2) & 1, sn: (byte >> 3) & 1, md: (byte >> 4) & 1, encrypted: encrypted, payload_hex: encrypted ? nil : hex, ciphertext_hex: encrypted ? hex : nil } if !encrypted && byte.allbits?(3) return nil if payload.empty? fields[:control_opcode] = payload[0] if payload[0] == 1 return nil unless payload.length == 8 && payload[5].nobits?(0xE0) && payload[1, 5].sum { |v| v.to_s(2).count('1') } >= 2 fields[:channel_map_hex] = payload[1, 5].pack('C*').unpack1('H*').upcase fields[:instant] = payload[6] | (payload[7] << 8) end end fields end |