Module: PWN::SDR::Decoder::DECT
- Defined in:
- lib/pwn/sdr/decoder/dect.rb
Overview
DECT (ETSI EN 300 175) true-air decoder.
1.152 Mbit/s GFSK, 24-slot / 10 ms TDMA. I/Q → PWN::FFI::Liquid gmskdem (or DSP.fm_demod_iq→NRZ) → hunt 32-bit S-field (16-bit preamble + 16-bit sync 0xE98A FP / 0x1675 PP) → A-field (64 bits: 8-bit header + 40-bit tail + 16-bit R-CRC) → RFPI extraction on Nt/Qt tails. Emits role:, slot_est:, crc_ok:.
Defined Under Namespace
Classes: DemodIQ
Constant Summary collapse
- SYNC_FP =
0xAAAAE98A- SYNC_PP =
0x55551675- BAUD =
1_152_000- RCRC_POLY =
R-CRC-16 poly x^16+x^10+x^8+x^7+x^3+1 = 0x0589, init 0x0000.
0x0589- A_TA =
{ 0 => 'Ct', 1 => 'Ct', 2 => 'Nt', 3 => 'Nt', 4 => 'Qt', 5 => 'Nt', 6 => 'Mt', 7 => 'Pt' }.freeze
Class Method Summary collapse
-
.authors ⇒ Object
- Author(s)
0day Inc.
-
.decode(opts = {}) ⇒ Object
- Supported Method Parameters
PWN::SDR::Decoder::DECT.decode( freq_obj: 'required - freq_obj returned from PWN::SDR::GQRX.init_freq' ).
- .help ⇒ Object
- .parse_line(opts = {}) ⇒ Object
Class Method Details
.authors ⇒ Object
- Author(s)
0day Inc. support@0dayinc.com
136 137 138 |
# File 'lib/pwn/sdr/decoder/dect.rb', line 136 public_class_method def self. "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n" end |
.decode(opts = {}) ⇒ Object
- Supported Method Parameters
PWN::SDR::Decoder::DECT.decode( freq_obj: 'required - freq_obj returned from PWN::SDR::GQRX.init_freq' )
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/pwn/sdr/decoder/dect.rb', line 104 public_class_method def self.decode(opts = {}) freq_obj = opts[:freq_obj] hz = PWN::SDR.hz_to_i(freq: freq_obj[:freq]) # EU: carrier 0 = 1897.344 MHz, step 1.728 MHz down; US 1.9296 GHz. carrier = ((1_897_344_000 - hz) / 1_728_000.0).round rate = (opts[:sample_rate] || freq_obj[:iq_rate] || 2_304_000).to_i PWN::SDR::Decoder::Base.run_iq( freq_obj: freq_obj, protocol: 'DECT', sample_rate: rate, source: opts[:source], file: opts[:file], demod: DemodIQ.new(rate: rate, carrier: carrier), note: '1.152 Mbit/s GFSK — I/Q→gmskdem→S-field 0xE98A→A-field/RFPI/R-CRC.', describe: proc { |b| { modulation: 'GFSK', tdma_slots: (b[:duration_ms] / 0.417).round } } ) end |
.help ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/pwn/sdr/decoder/dect.rb', line 140 public_class_method def self.help puts "USAGE (true-air I/Q via PWN::FFI + detector fallback): #{self}.decode( freq_obj: 'required - freq_obj returned from PWN::SDR::GQRX.init_freq', source: 'optional - :auto|:rtlsdr|:adalm_pluto|:file', file: 'optional - .cu8/.cs16 capture (≥2.304 Msps)' ) #{self}.authors " end |
.parse_line(opts = {}) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/pwn/sdr/decoder/dect.rb', line 122 public_class_method def self.parse_line(opts = {}) line = opts[:line].to_s out = { protocol: 'DECT' } out[:rfpi] = ::Regexp.last_match(1).delete(' ') if line =~ /RFPI[:=]?\s*((?:[0-9A-Fa-f]{2}\s*){5})/ out[:slot] = ::Regexp.last_match(1) if line =~ /slot\s*(\d+)/i out[:carrier] = ::Regexp.last_match(1) if line =~ /carrier\s*(\d+)/i out[:rssi] = ::Regexp.last_match(1) if line =~ /RSSI[:=]?\s*(-?\d+)/i out[:role] = ::Regexp.last_match(1) if line =~ /\b(FP|PP)\b/ out[:summary] = "DECT RFPI=#{out[:rfpi]} slot=#{out[:slot]} carrier=#{out[:carrier]}" out.compact end |