Class: PWN::SDR::Decoder::LTE::DemodIQ

Inherits:
Object
  • Object
show all
Defined in:
lib/pwn/sdr/decoder/lte.rb

Overview

Streaming PSS/SSS cell-search demod for Base.run_iq.

Instance Method Summary collapse

Constructor Details

#initialize(rate:) ⇒ DemodIQ

Returns a new instance of DemodIQ.



21
22
23
24
25
26
# File 'lib/pwn/sdr/decoder/lte.rb', line 21

def initialize(rate:)
  @rate = rate.to_f
  @buf  = []
  @seen = {}
  @pss  = build_pss
end

Instance Method Details

#feed_iq(samples, rate: nil) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/pwn/sdr/decoder/lte.rb', line 28

def feed_iq(samples, rate: nil)
  @rate = rate.to_f if rate
  r = PWN::SDR::Decoder::DSP.resample_iq(
    iq: samples, src_rate: @rate, dst_rate: FS_BASE
  )
  @buf.concat(r)
  # need ≥ one 5 ms half-frame @ 1.92 Msps = 9600 complex
  return if @buf.length < 9600 * 2 * 2

  hit = search_pss
  if hit
    nid1 = search_sss(hit)
    pci  = nid1 ? (3 * nid1) + hit[:nid2] : nil
    key  = pci || "N2=#{hit[:nid2]}"
    unless @seen[key]
      @seen[key] = true
      yield(
        protocol: 'LTE', event: 'cell', modulation: 'OFDMA',
        nid2: hit[:nid2], nid1: nid1, pci: pci,
        cfo_hz: hit[:cfo_hz], pss_peak_ratio: hit[:ratio],
        timing_sample: hit[:pos],
        summary: pci ? "LTE cell PCI=#{pci} (N_ID_1=#{nid1} N_ID_2=#{hit[:nid2]}) CFO=#{hit[:cfo_hz]}Hz" : "LTE PSS lock N_ID_2=#{hit[:nid2]} CFO=#{hit[:cfo_hz]}Hz (SSS pending)"
      )
    end
  end
  @buf.shift(@buf.length - (9600 * 2)) if @buf.length > 9600 * 4
end