pwn 0.5.620 → 0.5.621

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/documentation/Agent-Tool-Registry.md +2 -2
  4. data/documentation/Cron.md +13 -0
  5. data/documentation/Diagrams.md +1 -1
  6. data/documentation/Extrospection.md +71 -5
  7. data/documentation/Home.md +2 -2
  8. data/documentation/How-PWN-Works.md +1 -1
  9. data/documentation/Mistakes.md +2 -1
  10. data/documentation/Persistence.md +2 -1
  11. data/documentation/Skills-Memory-Learning.md +1 -0
  12. data/documentation/Transparent-Browser.md +18 -1
  13. data/documentation/diagrams/agent-tool-registry.svg +55 -54
  14. data/documentation/diagrams/ai-integration-tool-calling.svg +24 -24
  15. data/documentation/diagrams/aws-cloud-security.svg +25 -25
  16. data/documentation/diagrams/burp-vs-zap-preference.svg +12 -12
  17. data/documentation/diagrams/code-scanning-sast.svg +25 -25
  18. data/documentation/diagrams/cron-scheduling.svg +23 -23
  19. data/documentation/diagrams/dot/agent-tool-registry.dot +2 -2
  20. data/documentation/diagrams/dot/extrospection-world-awareness.dot +29 -8
  21. data/documentation/diagrams/dot/memory-skills-detailed.dot +4 -0
  22. data/documentation/diagrams/dot/overall-pwn-architecture.dot +2 -2
  23. data/documentation/diagrams/dot/persistence-filesystem.dot +2 -1
  24. data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +10 -4
  25. data/documentation/diagrams/driver-framework.svg +13 -13
  26. data/documentation/diagrams/extrospection-world-awareness.svg +229 -99
  27. data/documentation/diagrams/fuzzing-workflow.svg +24 -24
  28. data/documentation/diagrams/hardware-hacking.svg +18 -18
  29. data/documentation/diagrams/history-to-drivers.svg +18 -18
  30. data/documentation/diagrams/memory-skills-detailed.svg +124 -101
  31. data/documentation/diagrams/mistakes-negative-feedback.svg +55 -55
  32. data/documentation/diagrams/network-infra-testing.svg +27 -27
  33. data/documentation/diagrams/overall-pwn-architecture.svg +85 -85
  34. data/documentation/diagrams/penetration-testing-workflow.svg +30 -30
  35. data/documentation/diagrams/persistence-filesystem.svg +94 -85
  36. data/documentation/diagrams/plugin-ecosystem.svg +35 -35
  37. data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +226 -180
  38. data/documentation/diagrams/pwn-repl-prototyping.svg +20 -20
  39. data/documentation/diagrams/reporting-pipeline.svg +18 -18
  40. data/documentation/diagrams/reverse-engineering-flow.svg +21 -21
  41. data/documentation/diagrams/sdr-radio-flow.svg +31 -31
  42. data/documentation/diagrams/sessions-cron-automation.svg +18 -18
  43. data/documentation/diagrams/swarm-multi-agent.svg +39 -39
  44. data/documentation/diagrams/web-application-testing.svg +26 -26
  45. data/documentation/diagrams/zero-day-research-flow.svg +25 -25
  46. data/documentation/pwn-ai-Agent.md +1 -1
  47. data/lib/pwn/ai/agent/extrospection.rb +433 -4
  48. data/lib/pwn/ai/agent/tools/extrospection.rb +88 -3
  49. data/lib/pwn/sdr/decoder/adsb.rb +14 -33
  50. data/lib/pwn/sdr/decoder/apt.rb +97 -36
  51. data/lib/pwn/sdr/decoder/base.rb +258 -171
  52. data/lib/pwn/sdr/decoder/bluetooth.rb +13 -20
  53. data/lib/pwn/sdr/decoder/dect.rb +13 -27
  54. data/lib/pwn/sdr/decoder/dsp.rb +396 -0
  55. data/lib/pwn/sdr/decoder/flex.rb +177 -210
  56. data/lib/pwn/sdr/decoder/gps.rb +12 -21
  57. data/lib/pwn/sdr/decoder/gsm.rb +21 -73
  58. data/lib/pwn/sdr/decoder/iridium.rb +11 -26
  59. data/lib/pwn/sdr/decoder/lora.rb +16 -23
  60. data/lib/pwn/sdr/decoder/lte.rb +11 -32
  61. data/lib/pwn/sdr/decoder/morse.rb +95 -21
  62. data/lib/pwn/sdr/decoder/p25.rb +19 -16
  63. data/lib/pwn/sdr/decoder/pager.rb +22 -38
  64. data/lib/pwn/sdr/decoder/pocsag.rb +175 -68
  65. data/lib/pwn/sdr/decoder/rfid.rb +24 -33
  66. data/lib/pwn/sdr/decoder/rtl433.rb +21 -30
  67. data/lib/pwn/sdr/decoder/rtty.rb +100 -27
  68. data/lib/pwn/sdr/decoder/wifi.rb +21 -42
  69. data/lib/pwn/sdr/decoder/zigbee.rb +18 -40
  70. data/lib/pwn/sdr/decoder.rb +8 -0
  71. data/lib/pwn/version.rb +1 -1
  72. data/spec/lib/pwn/sdr/decoder/dsp_spec.rb +15 -0
  73. data/third_party/pwn_rdoc.jsonl +24 -3
  74. metadata +3 -1
@@ -1,26 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'shellwords'
4
-
5
3
  module PWN
6
4
  module SDR
7
5
  module Decoder
8
- # 802.11 (WiFi) beacon/probe decoder for the 2.4 / 5 / 6 GHz bands.
6
+ # Pure-Ruby 802.11 (WiFi) activity detector.
9
7
  #
10
- # 20+ MHz OFDM cannot be recovered from a general-purpose SDR at
11
- # bit-level in real time, so this module drives an existing monitor-mode
12
- # NIC via `tshark` (or `airodump-ng`) instead — freq_obj[:mon_iface]
13
- # selects the interface, freq_obj[:freq] is mapped to a WLAN channel.
8
+ # 20+ MHz OFDM cannot be demodulated in interpreted Ruby in real
9
+ # time. Native mode reports channel occupancy/duty and maps
10
+ # freq_obj to a WLAN channel number. `parse_line` retained for
11
+ # offline pipe-delimited tshark-fields analysis.
14
12
  module WiFi
15
13
  TSHARK_FIELDS = %w[
16
- frame.time_relative
17
- wlan.fc.type_subtype
18
- wlan.bssid
19
- wlan.sa
20
- wlan.da
21
- wlan_radio.channel
22
- wlan_radio.signal_dbm
23
- wlan.ssid
14
+ frame.time_relative wlan.fc.type_subtype wlan.bssid wlan.sa
15
+ wlan.da wlan_radio.channel wlan_radio.signal_dbm wlan.ssid
24
16
  ].freeze
25
17
 
26
18
  # Supported Method Parameters::
@@ -30,28 +22,20 @@ module PWN
30
22
 
31
23
  public_class_method def self.decode(opts = {})
32
24
  freq_obj = opts[:freq_obj]
33
- raise 'ERROR: :freq_obj is required' unless freq_obj.is_a?(Hash)
34
-
35
- iface = (freq_obj[:mon_iface] || 'wlan0mon').to_s
36
- hz = PWN::SDR.hz_to_i(freq: freq_obj[:freq])
37
- mhz = (hz / 1_000_000.0).round
38
-
39
- tshark = ['tshark', '-i', iface, '-I', '-l', '-n',
40
- '-Y', 'wlan.fc.type == 0',
41
- '-T', 'fields', '-E', 'separator=|']
42
- TSHARK_FIELDS.each { |f| tshark.push('-e', f) }
43
-
44
- inner = "iw dev #{Shellwords.escape(iface)} set freq #{mhz} 2>/dev/null; " \
45
- "exec #{Shellwords.join(tshark)}"
46
- direct_cmd = "bash -c #{Shellwords.escape(inner)}"
47
-
48
- PWN::SDR::Decoder::Base.run_pipeline(
25
+ hz = PWN::SDR.hz_to_i(freq: freq_obj[:freq])
26
+ mhz = (hz / 1_000_000.0).round
27
+ ch = case mhz
28
+ when 2412..2472 then ((mhz - 2412) / 5) + 1
29
+ when 2484 then 14
30
+ when 5000..5900 then (mhz - 5000) / 5
31
+ else 0
32
+ end
33
+ PWN::SDR::Decoder::Base.run_detector(
49
34
  freq_obj: freq_obj,
50
35
  protocol: 'WiFi-802.11',
51
- required_bins: %w[tshark iw],
52
- direct_cmd: direct_cmd,
53
- line_match: /\S/,
54
- parser: proc { |line| parse_line(line: line) }
36
+ note: '20+ MHz OFDM — native mode reports channel occupancy/duty only.',
37
+ threshold: 6.0,
38
+ describe: proc { |b| { modulation: 'OFDM', channel: ch, mhz: mhz, airtime_ms: b[:duration_ms] } }
55
39
  )
56
40
  end
57
41
 
@@ -61,8 +45,7 @@ module PWN
61
45
  public_class_method def self.parse_line(opts = {})
62
46
  f = opts[:line].to_s.split('|', -1)
63
47
  out = {
64
- protocol: 'WiFi',
65
- subtype: f[1], bssid: f[2], sa: f[3], da: f[4],
48
+ protocol: 'WiFi', subtype: f[1], bssid: f[2], sa: f[3], da: f[4],
66
49
  channel: f[5], rssi_dbm: f[6], ssid: f[7]
67
50
  }.reject { |_, v| v.to_s.empty? }
68
51
  out[:summary] = "WiFi ch#{out[:channel]} #{out[:bssid]} '#{out[:ssid]}' #{out[:rssi_dbm]}dBm"
@@ -78,15 +61,11 @@ module PWN
78
61
  # Display Usage for this Module
79
62
 
80
63
  public_class_method def self.help
81
- puts "USAGE:
64
+ puts "USAGE (ruby-native detector, no external binaries):
82
65
  #{self}.decode(
83
66
  freq_obj: 'required - freq_obj returned from PWN::SDR::GQRX.init_freq'
84
67
  )
85
68
 
86
- NOTE: Requires a monitor-mode WLAN interface (freq_obj[:mon_iface],
87
- default 'wlan0mon'), `iw`, and `tshark`. General SDRs cannot
88
- demodulate 802.11 OFDM in real time.
89
-
90
69
  #{self}.parse_line(line: '0.1|8|aa:bb:..|aa:bb:..|ff:ff:..|6|-42|linksys')
91
70
 
92
71
  #{self}.authors
@@ -1,26 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'shellwords'
4
-
5
3
  module PWN
6
4
  module SDR
7
5
  module Decoder
8
- # IEEE 802.15.4 / ZigBee decoder for the 2.405–2.480 GHz allocation.
9
- # 250 kbit/s O-QPSK requires raw I/Q; this drives KillerBee's `zbdump`
10
- # (with any supported adapter CC2531, ApiMote, RZUSB, HackRF via
11
- # gr-ieee802-15-4) or falls back to `whsniff` piped through `tshark`
12
- # for structured PAN/src/dst/cmd extraction.
6
+ # Pure-Ruby IEEE 802.15.4 / ZigBee activity detector.
7
+ #
8
+ # 250 kbit/s O-QPSK across 2 MHz channels native mode reports
9
+ # per-channel packet bursts and derives channel 11–26 from
10
+ # freq_obj. `parse_line` retained for offline pipe-delimited
11
+ # analysis.
13
12
  module ZigBee
14
13
  TSHARK_FIELDS = %w[
15
- frame.time_relative
16
- wpan.src16
17
- wpan.dst16
18
- wpan.src64
19
- wpan.dst64
20
- wpan.dst_pan
21
- wpan.frame_type
22
- zbee_nwk.cmd.id
23
- wpan.seq_no
14
+ frame.time_relative wpan.src16 wpan.dst16 wpan.src64 wpan.dst64
15
+ wpan.dst_pan wpan.frame_type zbee_nwk.cmd.id wpan.seq_no
24
16
  ].freeze
25
17
 
26
18
  # Supported Method Parameters::
@@ -30,25 +22,17 @@ module PWN
30
22
 
31
23
  public_class_method def self.decode(opts = {})
32
24
  freq_obj = opts[:freq_obj]
33
- raise 'ERROR: :freq_obj is required' unless freq_obj.is_a?(Hash)
34
-
35
25
  hz = PWN::SDR.hz_to_i(freq: freq_obj[:freq])
36
- # 802.15.4 ch11..26 → 2405 + 5*(ch-11) MHz
37
26
  ch = (((hz - 2_405_000_000) / 5_000_000.0).round + 11).clamp(11, 26)
38
-
39
- tshark = ['tshark', '-r', '-', '-l', '-T', 'fields', '-E', 'separator=|']
40
- TSHARK_FIELDS.each { |f| tshark.push('-e', f) }
41
-
42
- inner = "whsniff -c #{ch} 2>/dev/null | #{Shellwords.join(tshark)}"
43
- direct_cmd = "bash -c #{Shellwords.escape(inner)}"
44
-
45
- PWN::SDR::Decoder::Base.run_pipeline(
27
+ PWN::SDR::Decoder::Base.run_detector(
46
28
  freq_obj: freq_obj,
47
29
  protocol: 'ZigBee',
48
- required_bins: %w[whsniff tshark],
49
- direct_cmd: direct_cmd,
50
- line_match: /\S/,
51
- parser: proc { |line| parse_line(line: line) }
30
+ note: '250 kbit/s O-QPSK — native mode reports 802.15.4 packet bursts only.',
31
+ threshold: 8.0,
32
+ describe: proc { |b|
33
+ octets = (b[:duration_ms] * 250 / 8).round
34
+ { modulation: 'O-QPSK', channel: ch, est_octets: octets, classification: octets < 20 ? 'ACK/beacon' : 'data-frame' }
35
+ }
52
36
  )
53
37
  end
54
38
 
@@ -58,11 +42,8 @@ module PWN
58
42
  public_class_method def self.parse_line(opts = {})
59
43
  f = opts[:line].to_s.split('|', -1)
60
44
  out = {
61
- protocol: 'ZigBee',
62
- src16: f[1], dst16: f[2],
63
- src64: f[3], dst64: f[4],
64
- pan_id: f[5], frame_type: f[6],
65
- nwk_cmd: f[7], seq: f[8]
45
+ protocol: 'ZigBee', src16: f[1], dst16: f[2], src64: f[3], dst64: f[4],
46
+ pan_id: f[5], frame_type: f[6], nwk_cmd: f[7], seq: f[8]
66
47
  }.reject { |_, v| v.to_s.empty? }
67
48
  out[:summary] = "ZigBee PAN=#{out[:pan_id]} #{out[:src16] || out[:src64]}→#{out[:dst16] || out[:dst64]} type=#{out[:frame_type]}"
68
49
  out
@@ -77,14 +58,11 @@ module PWN
77
58
  # Display Usage for this Module
78
59
 
79
60
  public_class_method def self.help
80
- puts "USAGE:
61
+ puts "USAGE (ruby-native detector, no external binaries):
81
62
  #{self}.decode(
82
63
  freq_obj: 'required - freq_obj returned from PWN::SDR::GQRX.init_freq'
83
64
  )
84
65
 
85
- NOTE: Requires `whsniff` (CC2531) or KillerBee, plus `tshark`.
86
- Channel is derived from freq_obj[:freq] (11–26).
87
-
88
66
  #{self}.parse_line(line: '0.1|0x0001|0xffff||||0x01||42')
89
67
 
90
68
  #{self}.authors
@@ -9,12 +9,20 @@ module PWN
9
9
  # uniform `.decode(freq_obj:)` entry point (see PWN::SDR::Decoder::Base)
10
10
  # so PWN::SDR::GQRX can dispatch on a `decoder:` key from
11
11
  # PWN::SDR::FrequencyAllocation.band_plans.
12
+ #
13
+ # 100 % ruby-native — no decoder in this namespace shells out to an
14
+ # external binary. Audio-rate protocols (POCSAG, FLEX, Morse, RTTY,
15
+ # APT, Pager) are fully demodulated in Ruby via PWN::SDR::Decoder::DSP;
16
+ # wideband/I/Q-only protocols (ADS-B, GSM, LTE, GPS, LoRa, WiFi, DECT,
17
+ # ZigBee, Bluetooth, Iridium, P25, RFID, RTL433) run a native
18
+ # burst/energy characteriser (see Base.run_detector).
12
19
  module Decoder
13
20
  autoload :ADSB, 'pwn/sdr/decoder/adsb'
14
21
  autoload :APT, 'pwn/sdr/decoder/apt'
15
22
  autoload :Base, 'pwn/sdr/decoder/base'
16
23
  autoload :Bluetooth, 'pwn/sdr/decoder/bluetooth'
17
24
  autoload :DECT, 'pwn/sdr/decoder/dect'
25
+ autoload :DSP, 'pwn/sdr/decoder/dsp'
18
26
  autoload :Flex, 'pwn/sdr/decoder/flex'
19
27
  autoload :GPS, 'pwn/sdr/decoder/gps'
20
28
  autoload :GSM, 'pwn/sdr/decoder/gsm'
data/lib/pwn/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PWN
4
- VERSION = '0.5.620'
4
+ VERSION = '0.5.621'
5
5
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe PWN::SDR::Decoder::DSP do
6
+ it 'should display information for authors' do
7
+ authors_response = PWN::SDR::Decoder::DSP
8
+ expect(authors_response).to respond_to :authors
9
+ end
10
+
11
+ it 'should display information for existing help method' do
12
+ help_response = PWN::SDR::Decoder::DSP
13
+ expect(help_response).to respond_to :help
14
+ end
15
+ end
@@ -1547,10 +1547,15 @@
1547
1547
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::APT.decode Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::APT.decode`: Supported Method Parameters\n\nPWN::SDR::Decoder::APT.decode(\n\nfreq_obj: 'required - freq_obj returned from PWN::SDR::GQRX.init_freq'\n\n)\n"}]}
1548
1548
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::APT.help Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::APT.help`: "}]}
1549
1549
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.authors Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
1550
- {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.bin_available? Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.bin_available?`: Supported Method Parameters\n\nPWN::SDR::Decoder::Base.bin_available?(bin: ‘multimon-ng’)\n"}]}
1550
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.build_spinner Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.build_spinner`: Supported Method Parameters\n\nspinner, max_len = PWN::SDR::Decoder::Base.build_spinner(banner: ‘…’)\n"}]}
1551
1551
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.help Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.help`: "}]}
1552
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.log_path Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.log_path`: Supported Method Parameters\n\npath = PWN::SDR::Decoder::Base.log_path(protocol: ‘POCSAG’)\n"}]}
1552
1553
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.match_line? Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.match_line?`: Supported Method Parameters\n\nPWN::SDR::Decoder::Base.match_line?(line: str, matcher: Regexp|String|Array)\n"}]}
1553
- {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.run_pipeline Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.run_pipeline`: Supported Method Parameters\n\nPWN::SDR::Decoder::Base.run_pipeline(\n\nfreq_obj: 'required - freq_obj Hash from PWN::SDR::GQRX.init_freq',\nprotocol: 'required - short name used in banner / log filename',\ndecode_cmd: 'optional - shell pipeline reading 22 050 Hz s16le on stdin',\ndirect_cmd: 'optional - stand-alone shell cmd (owns the SDR itself)',\nline_match: 'optional - Regexp/String a stdout line must match',\nparser: 'optional - Proc.new { |line| Hash } to structure a line',\nrequired_bins: 'optional - Array of executables that must exist on PATH',\nresample_hz: 'optional - sox output rate for decode_cmd (default 22050)'\n\n)\n"}]}
1554
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.read_level Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.read_level`: Supported Method Parameters\n\nlvl = PWN::SDR::Decoder::Base.read_level(gqrx_sock:, udp_listener:)\n"}]}
1555
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.run_detector Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.run_detector`: Supported Method Parameters\n\nPWN::SDR::Decoder::Base.run_detector(\n\nfreq_obj: 'required - freq_obj Hash from PWN::SDR::GQRX.init_freq',\nprotocol: 'required - short name for banner / log filename',\nnote: 'optional - one-line explanation shown once',\nthreshold: 'optional - dBFS above rolling floor to call a burst (default 8.0)',\ndescribe: 'optional - Proc.new { |burst_hash| Hash } extra fields'\n\n)\n"}]}
1556
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.run_native Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.run_native`: Supported Method Parameters\n\nPWN::SDR::Decoder::Base.run_native(\n\nfreq_obj: 'required - freq_obj Hash from PWN::SDR::GQRX.init_freq',\nprotocol: 'required - short name for banner / log filename',\ndemod: 'required - object responding to #feed(samples,&emit)',\nrate: 'optional - assumed UDP sample rate (default 48000)'\n\n)\n"}]}
1557
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.strip_freq_obj Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.strip_freq_obj`: Supported Method Parameters\n\nh = PWN::SDR::Decoder::Base.strip_freq_obj(freq_obj: {…})\n"}]}
1558
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Base.wait_for_enter Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Base.wait_for_enter`: Supported Method Parameters\n\nPWN::SDR::Decoder::Base.wait_for_enter(spinner:, title_ref:)\n"}]}
1554
1559
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Bluetooth.authors Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Bluetooth.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
1555
1560
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Bluetooth.decode Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Bluetooth.decode`: Supported Method Parameters\n\nPWN::SDR::Decoder::Bluetooth.decode(\n\nfreq_obj: 'required - freq_obj returned from PWN::SDR::GQRX.init_freq'\n\n)\n"}]}
1556
1561
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Bluetooth.help Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Bluetooth.help`: "}]}
@@ -1559,6 +1564,22 @@
1559
1564
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DECT.decode Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DECT.decode`: Supported Method Parameters\n\nPWN::SDR::Decoder::DECT.decode(\n\nfreq_obj: 'required - freq_obj returned from PWN::SDR::GQRX.init_freq'\n\n)\n"}]}
1560
1565
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DECT.help Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DECT.help`: "}]}
1561
1566
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DECT.parse_line Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DECT.parse_line`: Supported Method Parameters\n\nPWN::SDR::Decoder::DECT.parse_line(line: ‘RFPI: 01 23 45 67 89 slot 4 carrier 3 RSSI -55’)\n"}]}
1567
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.authors Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
1568
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.baudot_decode Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.baudot_decode`: Supported Method Parameters\n\ntxt = PWN::SDR::Decoder::DSP.baudot_decode(bits: Array<0|1>) 5-bit ITA2 with LTRS(31)/FIGS(27) shift, LSB-first per character.\n"}]}
1569
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.bch_31_21_syndrome Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.bch_31_21_syndrome`: Supported Method Parameters\n\nsyn = PWN::SDR::Decoder::DSP.bch_31_21_syndrome(word: Integer)\n"}]}
1570
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.bits_to_int Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.bits_to_int`: Supported Method Parameters\n\nint = PWN::SDR::Decoder::DSP.bits_to_int(bits: [1,0,1,…])\n"}]}
1571
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.dc_block Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.dc_block`: Supported Method Parameters\n\ny = PWN::SDR::Decoder::DSP.dc_block(\n\nsamples: 'required - Array<Float>',\nalpha: 'optional - pole (default 0.995)'\n\n)\n"}]}
1572
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.envelope Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.envelope`: Supported Method Parameters\n\nenv = PWN::SDR::Decoder::DSP.envelope(\n\nsamples: 'required - Array<Float>',\nwindow: 'optional - moving-average window in samples (default 32)'\n\n)\n"}]}
1573
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.envelope_signed Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.envelope_signed`: Supported Method Parameters\n\ny = PWN::SDR::Decoder::DSP.envelope_signed(samples:, window:)\n"}]}
1574
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.even_parity_ok? Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.even_parity_ok?`: Supported Method Parameters\n\nok = PWN::SDR::Decoder::DSP.even_parity_ok?(word: Integer, width: 32)\n"}]}
1575
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.find_sync Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.find_sync`: Supported Method Parameters\n\nidx = PWN::SDR::Decoder::DSP.find_sync(\n\nbits: 'required - Array<0|1>',\npattern: 'required - Array<0|1> or Integer (MSB-first)',\nwidth: 'optional - bit-width when pattern is Integer',\nmax_err: 'optional - allowed bit errors (default 0)',\nfrom: 'optional - start index (default 0)'\n\n)\n"}]}
1576
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.fsk_slice Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.fsk_slice`: Supported Method Parameters\n\nbits = PWN::SDR::Decoder::DSP.fsk_slice(\n\nsamples: 'required - Array<Float>',\nrate: 'required - sample rate (Hz)',\nbaud: 'required - symbol rate',\nmark_hz: 'required - mark tone (bit=1)',\nspace_hz:'required - space tone (bit=0)'\n\n) Non-coherent 2-FSK: per-symbol Goertzel on mark/space, pick the winner.\n"}]}
1577
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.goertzel Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.goertzel`: Supported Method Parameters\n\npower = PWN::SDR::Decoder::DSP.goertzel(\n\nsamples: 'required - Array<Float>',\nrate: 'required - sample rate (Hz)',\nfreq: 'required - target tone frequency (Hz)'\n\n)\n"}]}
1578
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.help Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.help`: "}]}
1579
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.nrz_slice Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.nrz_slice`: Supported Method Parameters\n\nbits = PWN::SDR::Decoder::DSP.nrz_slice(\n\nsamples: 'required - Array<Float> (post-FM-discriminator baseband)',\nrate: 'required - sample rate (Hz)',\nbaud: 'required - symbol rate',\ninvert: 'optional - flip bit polarity (default false)'\n\n) Simple mid-bit sampler with zero-crossing resync. Returns Array<0|1>.\n"}]}
1580
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.resample Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.resample`: Supported Method Parameters\n\nout = PWN::SDR::Decoder::DSP.resample(\n\nsamples: 'required - Array<Float>',\nsrc_rate: 'required - input sample rate (Hz)',\ndst_rate: 'required - output sample rate (Hz)'\n\n)\n"}]}
1581
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.rms_dbfs Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.rms_dbfs`: Supported Method Parameters\n\ndbfs = PWN::SDR::Decoder::DSP.rms_dbfs(samples: Array<Float>)\n"}]}
1582
+ {"messages":[{"role":"user","content":"PWN::SDR::Decoder::DSP.unpack_s16le Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::DSP.unpack_s16le`: Supported Method Parameters\n\nsamples = PWN::SDR::Decoder::DSP.unpack_s16le(\n\ndata: 'required - raw String of little-endian signed 16-bit PCM'\n\n)\n"}]}
1562
1583
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Flex.authors Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Flex.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
1563
1584
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Flex.decode Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Flex.decode`: Supported Method Parameters\n\npocsag_resp = PWN::SDR::Decoder::Flex.decode(\n\nfreq_obj: 'required - GQRX socket object returned from #connect method'\n\n)\n"}]}
1564
1585
  {"messages":[{"role":"user","content":"PWN::SDR::Decoder::Flex.help Usage"},{"role":"assistant","content":"`PWN::SDR::Decoder::Flex.help`: "}]}
@@ -1639,7 +1660,7 @@
1639
1660
  {"messages":[{"role":"user","content":"PWN::SDR::GQRX.disconnect_udp Usage"},{"role":"assistant","content":"`PWN::SDR::GQRX.disconnect_udp`: Supported Method Parameters\n\nPWN::SDR::GQRX.disconnect_udp(\n\nudp_listener: 'required - UDP socket object returned from #listen_udp method'\n\n)\n"}]}
1640
1661
  {"messages":[{"role":"user","content":"PWN::SDR::GQRX.duration_between Usage"},{"role":"assistant","content":"`PWN::SDR::GQRX.duration_between`: Supported Method Parameters\n\nduration = PWN::SDR::GQRX.duration_between(\n\ntimestamp_start: 'required - Start timestamp',\ntimestamp_end: 'required - End timestamp'\n\n)\n"}]}
1641
1662
  {"messages":[{"role":"user","content":"PWN::SDR::GQRX.edge_detection Usage"},{"role":"assistant","content":"`PWN::SDR::GQRX.edge_detection`: Supported Method Parameters\n\ncandidate_signals = PWN::SDR::GQRX.edge_detection(\n\ngqrx_sock: 'required - GQRX socket object returned from #connect method',\nhz: 'required - Frequency to start edge detection from',\nprecision: 'required - Frequency step precision',\nstep_hz: 'required - Frequency step in Hz for edge detection',\nstrength_lock: 'required - Strength lock in dBFS to determine signal edges'\n\n)\n"}]}
1642
- {"messages":[{"role":"user","content":"PWN::SDR::GQRX.fast_scan_range Usage"},{"role":"assistant","content":"`PWN::SDR::GQRX.fast_scan_range`: Supported Method Parameters\n\nfast_resp = PWN::SDR::GQRX.fast_scan_range(\n\ngqrx_sock: 'required - GQRX socket object',\nranges: 'required - Array<Hash> of {start_freq:, target_freq: }',\nsample_rate: 'optional - Set this to GQRX visible input sample rate (the span width)',\nnfft: 'optional - FFT size',\navg: 'optional',\ncapture_secs: 'optional',\nstrength_lock: 'optional',\nmin_snr_db: 'optional - Minimum SNR in dB above per-chunk noise floor to report (defaults to 12.0)',\ndemodulator_mode: 'optional - Demodulator mode to attribute to detections (defaults to WFM)',\nbandwidth: 'optional - Passband bandwidth to attribute to detections (defaults to \"200.000\")',\nsquelch: 'optional - Squelch level (defaults to strength_lock - 3.0)',\ndecoder: 'optional - Decoder key (e.g. :gsm) to attribute to detections',\nlocation: 'optional - Location string for AI analysis',\nkeep_spectrum: 'optional - if true return raw spectrum arrays too (large)'\n\n)\n\nUses chunk-wise retuning where chunk = sample_rate so that the *entire visible band* (waterfall width) is captured via a single FFT each time rather than point-by-point hops. This yields near real-time panoramic coverage. Update rate is roughly (retune + capture + fft) per chunk.\n\nPer-signal output shape is INTENTIONALLY IDENTICAL to scan_range / init_freq (:freq, :demodulator_mode, :bandwidth, :strength_db, :decoder, :squelch, :strength_lock, :iteration, :ai_analysis) so that analyze_scan / analyze_log and downstream decoders behave the same regardless of which scan mode produced the log. FFT-specific extras (:hz, :bw_hz, :snr_db, :prominence_db, :noise_floor_db, :chunk_center, :method) are appended for provenance.\n"}]}
1663
+ {"messages":[{"role":"user","content":"PWN::SDR::GQRX.fast_scan_range Usage"},{"role":"assistant","content":"`PWN::SDR::GQRX.fast_scan_range`: Supported Method Parameters\n\nfast_resp = PWN::SDR::GQRX.fast_scan_range(\n\ngqrx_sock: 'required - GQRX socket object',\nranges: 'required - Array<Hash> of {start_freq:, target_freq: }',\nsample_rate: 'optional - Set this to GQRX visible input sample rate (the span width)',\nnfft: 'optional - FFT size',\navg: 'optional',\ncapture_secs: 'optional',\nstrength_lock: 'optional',\nmin_snr_db: 'optional - Minimum SNR in dB above per-chunk noise floor to report (defaults to 12.0)',\nprecision: 'optional - Band-plan channel raster; detections snapped to 10**(precision-1) Hz grid (defaults to 5)',\nmin_bw_ratio: 'optional - Reject FFT peaks narrower than min_bw_ratio * plan bandwidth as spurs (defaults to 0.30)',\ndemodulator_mode: 'optional - Demodulator mode to attribute to detections (defaults to WFM)',\nbandwidth: 'optional - Passband bandwidth to attribute to detections (defaults to \"200.000\")',\nsquelch: 'optional - Squelch level (defaults to strength_lock - 3.0)',\ndecoder: 'optional - Decoder key (e.g. :gsm) to attribute to detections',\nlocation: 'optional - Location string for AI analysis',\nkeep_spectrum: 'optional - if true return raw spectrum arrays too (large)'\n\n)\n\nUses chunk-wise retuning where chunk = sample_rate so that the *entire visible band* (waterfall width) is captured via a single FFT each time rather than point-by-point hops. This yields near real-time panoramic coverage. Update rate is roughly (retune + capture + fft) per chunk.\n\nPer-signal output shape is INTENTIONALLY IDENTICAL to scan_range / init_freq (:freq, :demodulator_mode, :bandwidth, :strength_db, :decoder, :squelch, :strength_lock, :iteration, :ai_analysis) so that analyze_scan / analyze_log and downstream decoders behave the same regardless of which scan mode produced the log. FFT-specific extras (:hz, :bw_hz, :snr_db, :prominence_db, :noise_floor_db, :chunk_center, :method) are appended for provenance.\n"}]}
1643
1664
  {"messages":[{"role":"user","content":"PWN::SDR::GQRX.find_best_peak Usage"},{"role":"assistant","content":"`PWN::SDR::GQRX.find_best_peak`: Supported Method Parameters\n\nbest_peak = PWN::SDR::GQRX.find_best_peak(\n\ngqrx_sock: 'required - GQRX socket object returned from #connect method',\ncandidate_signals: 'required - Array of candidate signals from edge_detection',\nstep_hz: 'required - Frequency step in Hz for peak finding',\nstrength_lock: 'required - Strength lock in dBFS to determine signal edges'\n\n)\n"}]}
1644
1665
  {"messages":[{"role":"user","content":"PWN::SDR::GQRX.get_spectrum_snapshot Usage"},{"role":"assistant","content":"`PWN::SDR::GQRX.get_spectrum_snapshot`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
1645
1666
  {"messages":[{"role":"user","content":"PWN::SDR::GQRX.help Usage"},{"role":"assistant","content":"`PWN::SDR::GQRX.help`: "}]}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.620
4
+ version: 0.5.621
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
@@ -2150,6 +2150,7 @@ files:
2150
2150
  - lib/pwn/sdr/decoder/base.rb
2151
2151
  - lib/pwn/sdr/decoder/bluetooth.rb
2152
2152
  - lib/pwn/sdr/decoder/dect.rb
2153
+ - lib/pwn/sdr/decoder/dsp.rb
2153
2154
  - lib/pwn/sdr/decoder/flex.rb
2154
2155
  - lib/pwn/sdr/decoder/gps.rb
2155
2156
  - lib/pwn/sdr/decoder/gsm.rb
@@ -2564,6 +2565,7 @@ files:
2564
2565
  - spec/lib/pwn/sdr/decoder/base_spec.rb
2565
2566
  - spec/lib/pwn/sdr/decoder/bluetooth_spec.rb
2566
2567
  - spec/lib/pwn/sdr/decoder/dect_spec.rb
2568
+ - spec/lib/pwn/sdr/decoder/dsp_spec.rb
2567
2569
  - spec/lib/pwn/sdr/decoder/flex_spec.rb
2568
2570
  - spec/lib/pwn/sdr/decoder/gps_spec.rb
2569
2571
  - spec/lib/pwn/sdr/decoder/gsm_spec.rb