pwn 0.5.516 → 0.5.518
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.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/lib/pwn/sdr/decoder/rds.rb +123 -0
- data/lib/pwn/sdr/decoder.rb +1 -0
- data/lib/pwn/sdr/frequency_allocation.rb +0 -80
- data/lib/pwn/sdr/gqrx.rb +33 -99
- data/lib/pwn/sdr.rb +13 -0
- data/lib/pwn/version.rb +1 -1
- data/spec/lib/pwn/sdr/decoder/rds_spec.rb +15 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4782a5ea26c616b61254cbc43ba1fa0fbee4f71890b48ac3b0197a0586965356
|
|
4
|
+
data.tar.gz: 987fdf3e321dd0790ca1f059c483a045bcee5239f63ba5f2bfbd065e5f85c24f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4417e4d4bbcffc1596d854c0d37eb2911b65456257c8d5520afeb1706bda670f1cb4881f312ca521951ae8d47eba063af98ac4f89d981c34b50f5e2acc052c7b
|
|
7
|
+
data.tar.gz: c989b552b031669fb6a2a96580d53ad4f240607d68f7ee2d4b9f65a9b0e48c6d1b5666613782a356a5edb11fb5d2178b30501a7e3bfa2fc6057eda39d3a70299
|
data/README.md
CHANGED
|
@@ -37,7 +37,7 @@ $ cd /opt/pwn
|
|
|
37
37
|
$ ./install.sh
|
|
38
38
|
$ ./install.sh ruby-gem
|
|
39
39
|
$ pwn
|
|
40
|
-
pwn[v0.5.
|
|
40
|
+
pwn[v0.5.518]:001 >>> PWN.help
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
[](https://youtu.be/G7iLUY4FzsI)
|
|
@@ -52,7 +52,7 @@ $ rvm use ruby-3.4.7@pwn
|
|
|
52
52
|
$ gem uninstall --all --executables pwn
|
|
53
53
|
$ gem install --verbose pwn
|
|
54
54
|
$ pwn
|
|
55
|
-
pwn[v0.5.
|
|
55
|
+
pwn[v0.5.518]:001 >>> PWN.help
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
If you're using a multi-user install of RVM do:
|
|
@@ -62,7 +62,7 @@ $ rvm use ruby-3.4.7@pwn
|
|
|
62
62
|
$ rvmsudo gem uninstall --all --executables pwn
|
|
63
63
|
$ rvmsudo gem install --verbose pwn
|
|
64
64
|
$ pwn
|
|
65
|
-
pwn[v0.5.
|
|
65
|
+
pwn[v0.5.518]:001 >>> PWN.help
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
PWN periodically upgrades to the latest version of Ruby which is reflected in `/opt/pwn/.ruby-version`. The easiest way to upgrade to the latest version of Ruby from a previous PWN installation is to run the following script:
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PWN
|
|
4
|
+
module SDR
|
|
5
|
+
module Decoder
|
|
6
|
+
# RDS Decoder Module for FM Radio Signals
|
|
7
|
+
module RDS
|
|
8
|
+
# Supported Method Parameters::
|
|
9
|
+
# rds_resp = PWN::SDR::GQRX.decode_rds(
|
|
10
|
+
# gqrx_sock: 'required - GQRX socket object returned from #connect method'
|
|
11
|
+
# )
|
|
12
|
+
|
|
13
|
+
# private_class_method def self.rds(opts = {})
|
|
14
|
+
public_class_method def self.decode(opts = {})
|
|
15
|
+
gqrx_sock = opts[:gqrx_sock]
|
|
16
|
+
|
|
17
|
+
# We toggle RDS off and on to reset the decoder
|
|
18
|
+
rds_resp = PWN::SDR::GQRX.gqrx_cmd(
|
|
19
|
+
gqrx_sock: gqrx_sock,
|
|
20
|
+
cmd: 'U RDS 0',
|
|
21
|
+
resp_ok: 'RPRT 0'
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
rds_resp = PWN::SDR::GQRX.gqrx_cmd(
|
|
25
|
+
gqrx_sock: gqrx_sock,
|
|
26
|
+
cmd: 'U RDS 1',
|
|
27
|
+
resp_ok: 'RPRT 0'
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
rds_resp = {}
|
|
31
|
+
attempts = 0
|
|
32
|
+
max_attempts = 120
|
|
33
|
+
skip_rds = "\n"
|
|
34
|
+
print 'INFO: Decoding FM radio RDS data (Press ENTER to skip)...'
|
|
35
|
+
max_attempts.times do
|
|
36
|
+
attempts += 1
|
|
37
|
+
rds_resp[:rds_pi] = PWN::SDR::GQRX.gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_PI')
|
|
38
|
+
rds_resp[:rds_ps_name] = PWN::SDR::GQRX.gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_PS_NAME')
|
|
39
|
+
rds_resp[:rds_radiotext] = PWN::SDR::GQRX.gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_RADIOTEXT')
|
|
40
|
+
|
|
41
|
+
# Break if ENTER key pressed
|
|
42
|
+
# This is useful if no RDS data is available
|
|
43
|
+
# on the current frequency (e.g. false+)
|
|
44
|
+
break if $stdin.ready? && $stdin.read_nonblock(1) == skip_rds
|
|
45
|
+
|
|
46
|
+
break if rds_resp[:rds_pi] != '0000' && !rds_resp[:rds_ps_name].empty? && !rds_resp[:rds_radiotext].empty?
|
|
47
|
+
|
|
48
|
+
print '.'
|
|
49
|
+
sleep 0.1
|
|
50
|
+
end
|
|
51
|
+
puts 'complete.'
|
|
52
|
+
rds_resp
|
|
53
|
+
rescue StandardError => e
|
|
54
|
+
raise e
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Starts the live decoding thread.
|
|
58
|
+
def self.start(opts = {})
|
|
59
|
+
freq_obj = opts[:freq_obj]
|
|
60
|
+
raise ':ERROR: :freq_obj is required' unless freq_obj.is_a?(Hash)
|
|
61
|
+
|
|
62
|
+
gqrx_sock = freq_obj[:gqrx_sock]
|
|
63
|
+
freq = freq_obj[:freq]
|
|
64
|
+
bandwidth = freq_obj[:bandwidth].to_i
|
|
65
|
+
record_path = freq_obj[:record_path]
|
|
66
|
+
|
|
67
|
+
sleep 0.1 until File.exist?(record_path)
|
|
68
|
+
|
|
69
|
+
header = File.binread(record_path, HEADER_SIZE)
|
|
70
|
+
raise 'Invalid WAV header' unless header.start_with?('RIFF') && header.include?('WAVE')
|
|
71
|
+
|
|
72
|
+
bytes_read = HEADER_SIZE
|
|
73
|
+
|
|
74
|
+
puts "GSM Decoder started for freq: #{freq}, bandwidth: #{bandwidth}"
|
|
75
|
+
|
|
76
|
+
Thread.new do
|
|
77
|
+
loop do
|
|
78
|
+
sleep 1
|
|
79
|
+
end
|
|
80
|
+
rescue StandardError => e
|
|
81
|
+
puts "Decoder error: #{e.message}"
|
|
82
|
+
ensure
|
|
83
|
+
cleanup(record_path: record_path)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Stops the decoding thread.
|
|
88
|
+
def self.stop(opts = {})
|
|
89
|
+
freq_obj = opts[:freq_obj]
|
|
90
|
+
raise 'ERROR: :freq_obj is required' unless freq_obj.is_a?(Hash)
|
|
91
|
+
|
|
92
|
+
decoder_thread = freq_obj[:decoder_thread]
|
|
93
|
+
decoder_thread.kill if decoder_thread.is_a?(Thread)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Author(s):: 0day Inc. <support@0dayinc.com>
|
|
97
|
+
|
|
98
|
+
public_class_method def self.authors
|
|
99
|
+
"AUTHOR(S):
|
|
100
|
+
0day Inc. <support@0dayinc.com>
|
|
101
|
+
"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Display Usage for this Module
|
|
105
|
+
|
|
106
|
+
public_class_method def self.help
|
|
107
|
+
puts "USAGE:
|
|
108
|
+
gsm_decoder_thread = #{self}.start(
|
|
109
|
+
freq_obj: 'required - freq_obj returned from PWN::SDR::Receiver::GQRX.init_freq method'
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# To stop the decoder thread:
|
|
113
|
+
#{self}.stop(
|
|
114
|
+
freq_obj: 'required - freq_obj returned from PWN::SDR::Receiver::GQRX.init_freq method'
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
#{self}.authors
|
|
118
|
+
"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
data/lib/pwn/sdr/decoder.rb
CHANGED
|
@@ -12,7 +12,6 @@ module PWN
|
|
|
12
12
|
start_freq: '978.000.000',
|
|
13
13
|
target_freq: '979.000.000',
|
|
14
14
|
demodulator_mode: :RAW,
|
|
15
|
-
rds: false,
|
|
16
15
|
bandwidth: '100.000',
|
|
17
16
|
precision: 5
|
|
18
17
|
},
|
|
@@ -20,7 +19,6 @@ module PWN
|
|
|
20
19
|
start_freq: '1.090.000.000',
|
|
21
20
|
target_freq: '1.091.000.000',
|
|
22
21
|
demodulator_mode: :RAW,
|
|
23
|
-
rds: false,
|
|
24
22
|
bandwidth: '100.000',
|
|
25
23
|
precision: 5
|
|
26
24
|
},
|
|
@@ -28,7 +26,6 @@ module PWN
|
|
|
28
26
|
start_freq: '200.000',
|
|
29
27
|
target_freq: '415.000',
|
|
30
28
|
demodulator_mode: :AM,
|
|
31
|
-
rds: false,
|
|
32
29
|
bandwidth: '10.000',
|
|
33
30
|
precision: 3
|
|
34
31
|
},
|
|
@@ -36,7 +33,6 @@ module PWN
|
|
|
36
33
|
start_freq: '285.000',
|
|
37
34
|
target_freq: '325.000',
|
|
38
35
|
demodulator_mode: :AM,
|
|
39
|
-
rds: false,
|
|
40
36
|
bandwidth: '10.000',
|
|
41
37
|
precision: 3
|
|
42
38
|
},
|
|
@@ -44,7 +40,6 @@ module PWN
|
|
|
44
40
|
start_freq: '222.000.000',
|
|
45
41
|
target_freq: '225.000.000',
|
|
46
42
|
demodulator_mode: :FM,
|
|
47
|
-
rds: false,
|
|
48
43
|
bandwidth: '25.000',
|
|
49
44
|
precision: 4
|
|
50
45
|
},
|
|
@@ -52,7 +47,6 @@ module PWN
|
|
|
52
47
|
start_freq: '1.800.000',
|
|
53
48
|
target_freq: '2.000.000',
|
|
54
49
|
demodulator_mode: :LSB,
|
|
55
|
-
rds: false,
|
|
56
50
|
bandwidth: '2.700',
|
|
57
51
|
precision: 6
|
|
58
52
|
},
|
|
@@ -60,7 +54,6 @@ module PWN
|
|
|
60
54
|
start_freq: '144.000.000',
|
|
61
55
|
target_freq: '148.000.000',
|
|
62
56
|
demodulator_mode: :FM,
|
|
63
|
-
rds: false,
|
|
64
57
|
bandwidth: '15.000',
|
|
65
58
|
precision: 4
|
|
66
59
|
},
|
|
@@ -68,7 +61,6 @@ module PWN
|
|
|
68
61
|
start_freq: '10.100.000',
|
|
69
62
|
target_freq: '10.150.000',
|
|
70
63
|
demodulator_mode: :CW,
|
|
71
|
-
rds: false,
|
|
72
64
|
bandwidth: '150',
|
|
73
65
|
precision: 3
|
|
74
66
|
},
|
|
@@ -76,7 +68,6 @@ module PWN
|
|
|
76
68
|
start_freq: '5.351.500',
|
|
77
69
|
target_freq: '5.366.500',
|
|
78
70
|
demodulator_mode: :USB,
|
|
79
|
-
rds: false,
|
|
80
71
|
bandwidth: '2.700',
|
|
81
72
|
precision: 6
|
|
82
73
|
},
|
|
@@ -84,7 +75,6 @@ module PWN
|
|
|
84
75
|
start_freq: '50.000.000',
|
|
85
76
|
target_freq: '54.000.000',
|
|
86
77
|
demodulator_mode: :USB,
|
|
87
|
-
rds: false,
|
|
88
78
|
bandwidth: '2.700',
|
|
89
79
|
precision: 6
|
|
90
80
|
},
|
|
@@ -92,7 +82,6 @@ module PWN
|
|
|
92
82
|
start_freq: '420.000.000',
|
|
93
83
|
target_freq: '450.000.000',
|
|
94
84
|
demodulator_mode: :FM,
|
|
95
|
-
rds: false,
|
|
96
85
|
bandwidth: '25.000',
|
|
97
86
|
precision: 4
|
|
98
87
|
},
|
|
@@ -100,7 +89,6 @@ module PWN
|
|
|
100
89
|
start_freq: '470.000.000',
|
|
101
90
|
target_freq: '890.000.000',
|
|
102
91
|
demodulator_mode: :WFM_ST,
|
|
103
|
-
rds: false,
|
|
104
92
|
bandwidth: '600.000',
|
|
105
93
|
precision: 5
|
|
106
94
|
},
|
|
@@ -108,7 +96,6 @@ module PWN
|
|
|
108
96
|
start_freq: '54.000.000',
|
|
109
97
|
target_freq: '216.000.000',
|
|
110
98
|
demodulator_mode: :WFM_ST,
|
|
111
|
-
rds: false,
|
|
112
99
|
bandwidth: '600.000',
|
|
113
100
|
precision: 5
|
|
114
101
|
},
|
|
@@ -116,7 +103,6 @@ module PWN
|
|
|
116
103
|
start_freq: '540.000',
|
|
117
104
|
target_freq: '1.700.000',
|
|
118
105
|
demodulator_mode: :AM,
|
|
119
|
-
rds: false,
|
|
120
106
|
bandwidth: '10.000',
|
|
121
107
|
precision: 4
|
|
122
108
|
},
|
|
@@ -124,7 +110,6 @@ module PWN
|
|
|
124
110
|
start_freq: '108.000.000',
|
|
125
111
|
target_freq: '118.000.000',
|
|
126
112
|
demodulator_mode: :AM,
|
|
127
|
-
rds: false,
|
|
128
113
|
bandwidth: '25.000',
|
|
129
114
|
precision: 4
|
|
130
115
|
},
|
|
@@ -132,7 +117,6 @@ module PWN
|
|
|
132
117
|
start_freq: '118.000.000',
|
|
133
118
|
target_freq: '137.000.000',
|
|
134
119
|
demodulator_mode: :AM,
|
|
135
|
-
rds: false,
|
|
136
120
|
bandwidth: '25.000',
|
|
137
121
|
precision: 4
|
|
138
122
|
},
|
|
@@ -140,7 +124,6 @@ module PWN
|
|
|
140
124
|
start_freq: '1.710.000.000',
|
|
141
125
|
target_freq: '1.755.000.000',
|
|
142
126
|
demodulator_mode: :RAW,
|
|
143
|
-
rds: false,
|
|
144
127
|
bandwidth: '200.000',
|
|
145
128
|
precision: 6
|
|
146
129
|
},
|
|
@@ -148,7 +131,6 @@ module PWN
|
|
|
148
131
|
start_freq: '2.402.000.000',
|
|
149
132
|
target_freq: '2.480.000.000',
|
|
150
133
|
demodulator_mode: :RAW,
|
|
151
|
-
rds: false,
|
|
152
134
|
bandwidth: '1.000.000',
|
|
153
135
|
precision: 5
|
|
154
136
|
},
|
|
@@ -156,7 +138,6 @@ module PWN
|
|
|
156
138
|
start_freq: '26.965.000',
|
|
157
139
|
target_freq: '27.405.000',
|
|
158
140
|
demodulator_mode: :AM,
|
|
159
|
-
rds: false,
|
|
160
141
|
bandwidth: '10.000',
|
|
161
142
|
precision: 3
|
|
162
143
|
},
|
|
@@ -164,7 +145,6 @@ module PWN
|
|
|
164
145
|
start_freq: '824.000.000',
|
|
165
146
|
target_freq: '849.000.000',
|
|
166
147
|
demodulator_mode: :RAW,
|
|
167
|
-
rds: false,
|
|
168
148
|
bandwidth: '1.250.000',
|
|
169
149
|
precision: 6
|
|
170
150
|
},
|
|
@@ -172,7 +152,6 @@ module PWN
|
|
|
172
152
|
start_freq: '14.000.000',
|
|
173
153
|
target_freq: '14.350.000',
|
|
174
154
|
demodulator_mode: :CW,
|
|
175
|
-
rds: false,
|
|
176
155
|
bandwidth: '150',
|
|
177
156
|
precision: 3
|
|
178
157
|
},
|
|
@@ -180,7 +159,6 @@ module PWN
|
|
|
180
159
|
start_freq: '7.000.000',
|
|
181
160
|
target_freq: '7.300.000',
|
|
182
161
|
demodulator_mode: :CW,
|
|
183
|
-
rds: false,
|
|
184
162
|
bandwidth: '150',
|
|
185
163
|
precision: 3
|
|
186
164
|
},
|
|
@@ -188,7 +166,6 @@ module PWN
|
|
|
188
166
|
start_freq: '3.500.000',
|
|
189
167
|
target_freq: '3.800.000',
|
|
190
168
|
demodulator_mode: :CW,
|
|
191
|
-
rds: false,
|
|
192
169
|
bandwidth: '150',
|
|
193
170
|
precision: 3
|
|
194
171
|
},
|
|
@@ -196,7 +173,6 @@ module PWN
|
|
|
196
173
|
start_freq: '1.880.000.000',
|
|
197
174
|
target_freq: '1.900.000.000',
|
|
198
175
|
demodulator_mode: :RAW,
|
|
199
|
-
rds: false,
|
|
200
176
|
bandwidth: '100.000',
|
|
201
177
|
precision: 5
|
|
202
178
|
},
|
|
@@ -212,7 +188,6 @@ module PWN
|
|
|
212
188
|
start_freq: '462.562.500',
|
|
213
189
|
target_freq: '467.725.000',
|
|
214
190
|
demodulator_mode: :FM,
|
|
215
|
-
rds: false,
|
|
216
191
|
bandwidth: '200.000',
|
|
217
192
|
precision: 3
|
|
218
193
|
},
|
|
@@ -220,7 +195,6 @@ module PWN
|
|
|
220
195
|
start_freq: '462.550.000',
|
|
221
196
|
target_freq: '467.725.000',
|
|
222
197
|
demodulator_mode: :FM,
|
|
223
|
-
rds: false,
|
|
224
198
|
bandwidth: '200.000',
|
|
225
199
|
precision: 3
|
|
226
200
|
},
|
|
@@ -228,7 +202,6 @@ module PWN
|
|
|
228
202
|
start_freq: '880.000.000',
|
|
229
203
|
target_freq: '915.000.000',
|
|
230
204
|
demodulator_mode: :RAW,
|
|
231
|
-
rds: false,
|
|
232
205
|
bandwidth: '171.200',
|
|
233
206
|
precision: 4
|
|
234
207
|
},
|
|
@@ -236,7 +209,6 @@ module PWN
|
|
|
236
209
|
start_freq: '1.574.420.000',
|
|
237
210
|
target_freq: '1.576.420.000',
|
|
238
211
|
demodulator_mode: :RAW,
|
|
239
|
-
rds: false,
|
|
240
212
|
bandwidth: '30.000.000',
|
|
241
213
|
precision: 6
|
|
242
214
|
},
|
|
@@ -244,7 +216,6 @@ module PWN
|
|
|
244
216
|
start_freq: '1.226.600.000',
|
|
245
217
|
target_freq: '1.228.600.000',
|
|
246
218
|
demodulator_mode: :RAW,
|
|
247
|
-
rds: false,
|
|
248
219
|
bandwidth: '11.000.000',
|
|
249
220
|
precision: 6
|
|
250
221
|
},
|
|
@@ -252,7 +223,6 @@ module PWN
|
|
|
252
223
|
start_freq: '824.000.000',
|
|
253
224
|
target_freq: '894.000.000',
|
|
254
225
|
demodulator_mode: :RAW,
|
|
255
|
-
rds: false,
|
|
256
226
|
bandwidth: '200.000',
|
|
257
227
|
precision: 4
|
|
258
228
|
},
|
|
@@ -260,7 +230,6 @@ module PWN
|
|
|
260
230
|
start_freq: '13.560.000',
|
|
261
231
|
target_freq: '13.570.000',
|
|
262
232
|
demodulator_mode: :RAW,
|
|
263
|
-
rds: false,
|
|
264
233
|
bandwidth: '400.000',
|
|
265
234
|
precision: 3
|
|
266
235
|
},
|
|
@@ -268,7 +237,6 @@ module PWN
|
|
|
268
237
|
start_freq: '1.616.000.000',
|
|
269
238
|
target_freq: '1.626.500.000',
|
|
270
239
|
demodulator_mode: :RAW,
|
|
271
|
-
rds: false,
|
|
272
240
|
bandwidth: '704.000',
|
|
273
241
|
precision: 6
|
|
274
242
|
},
|
|
@@ -276,7 +244,6 @@ module PWN
|
|
|
276
244
|
start_freq: '5.725.000.000',
|
|
277
245
|
target_freq: '5.875.000.000',
|
|
278
246
|
demodulator_mode: :RAW,
|
|
279
|
-
rds: false,
|
|
280
247
|
bandwidth: '150.000.000',
|
|
281
248
|
precision: 7
|
|
282
249
|
},
|
|
@@ -284,7 +251,6 @@ module PWN
|
|
|
284
251
|
start_freq: '902.000.000',
|
|
285
252
|
target_freq: '928.000.000',
|
|
286
253
|
demodulator_mode: :RAW,
|
|
287
|
-
rds: false,
|
|
288
254
|
bandwidth: '26.000.000',
|
|
289
255
|
precision: 3
|
|
290
256
|
},
|
|
@@ -292,7 +258,6 @@ module PWN
|
|
|
292
258
|
start_freq: '300.000.000',
|
|
293
259
|
target_freq: '300.100.000',
|
|
294
260
|
demodulator_mode: :RAW,
|
|
295
|
-
rds: false,
|
|
296
261
|
bandwidth: '50.000',
|
|
297
262
|
precision: 4
|
|
298
263
|
},
|
|
@@ -300,7 +265,6 @@ module PWN
|
|
|
300
265
|
start_freq: '310.000.000',
|
|
301
266
|
target_freq: '310.100.000',
|
|
302
267
|
demodulator_mode: :RAW,
|
|
303
|
-
rds: false,
|
|
304
268
|
bandwidth: '50.000',
|
|
305
269
|
precision: 4
|
|
306
270
|
},
|
|
@@ -308,7 +272,6 @@ module PWN
|
|
|
308
272
|
start_freq: '315.000.000',
|
|
309
273
|
target_freq: '315.100.000',
|
|
310
274
|
demodulator_mode: :RAW,
|
|
311
|
-
rds: false,
|
|
312
275
|
bandwidth: '50.000',
|
|
313
276
|
precision: 4
|
|
314
277
|
},
|
|
@@ -316,7 +279,6 @@ module PWN
|
|
|
316
279
|
start_freq: '390.000.000',
|
|
317
280
|
target_freq: '390.100.000',
|
|
318
281
|
demodulator_mode: :RAW,
|
|
319
|
-
rds: false,
|
|
320
282
|
bandwidth: '50.000',
|
|
321
283
|
precision: 4
|
|
322
284
|
},
|
|
@@ -324,7 +286,6 @@ module PWN
|
|
|
324
286
|
start_freq: '433.000.000',
|
|
325
287
|
target_freq: '434.000.000',
|
|
326
288
|
demodulator_mode: :RAW,
|
|
327
|
-
rds: false,
|
|
328
289
|
bandwidth: '50.000',
|
|
329
290
|
precision: 4
|
|
330
291
|
},
|
|
@@ -332,7 +293,6 @@ module PWN
|
|
|
332
293
|
start_freq: '868.000.000',
|
|
333
294
|
target_freq: '869.000.000',
|
|
334
295
|
demodulator_mode: :RAW,
|
|
335
|
-
rds: false,
|
|
336
296
|
bandwidth: '50.000',
|
|
337
297
|
precision: 4
|
|
338
298
|
},
|
|
@@ -340,7 +300,6 @@ module PWN
|
|
|
340
300
|
start_freq: '450.000.000',
|
|
341
301
|
target_freq: '470.000.000',
|
|
342
302
|
demodulator_mode: :FM,
|
|
343
|
-
rds: false,
|
|
344
303
|
bandwidth: '25.000',
|
|
345
304
|
precision: 4
|
|
346
305
|
},
|
|
@@ -348,7 +307,6 @@ module PWN
|
|
|
348
307
|
start_freq: '150.000.000',
|
|
349
308
|
target_freq: '174.000.000',
|
|
350
309
|
demodulator_mode: :FM,
|
|
351
|
-
rds: false,
|
|
352
310
|
bandwidth: '25.000',
|
|
353
311
|
precision: 4
|
|
354
312
|
},
|
|
@@ -356,7 +314,6 @@ module PWN
|
|
|
356
314
|
start_freq: '148.500',
|
|
357
315
|
target_freq: '283.500',
|
|
358
316
|
demodulator_mode: :AM,
|
|
359
|
-
rds: false,
|
|
360
317
|
bandwidth: '10.000',
|
|
361
318
|
precision: 3
|
|
362
319
|
},
|
|
@@ -364,7 +321,6 @@ module PWN
|
|
|
364
321
|
start_freq: '432.000.000',
|
|
365
322
|
target_freq: '434.000.000',
|
|
366
323
|
demodulator_mode: :RAW,
|
|
367
|
-
rds: false,
|
|
368
324
|
bandwidth: '500.000',
|
|
369
325
|
precision: 3
|
|
370
326
|
},
|
|
@@ -372,7 +328,6 @@ module PWN
|
|
|
372
328
|
start_freq: '902.000.000',
|
|
373
329
|
target_freq: '928.000.000',
|
|
374
330
|
demodulator_mode: :RAW,
|
|
375
|
-
rds: false,
|
|
376
331
|
bandwidth: '500.000',
|
|
377
332
|
precision: 3
|
|
378
333
|
},
|
|
@@ -380,7 +335,6 @@ module PWN
|
|
|
380
335
|
start_freq: '125.000',
|
|
381
336
|
target_freq: '134.000',
|
|
382
337
|
demodulator_mode: :RAW,
|
|
383
|
-
rds: false,
|
|
384
338
|
bandwidth: '40.000',
|
|
385
339
|
precision: 1
|
|
386
340
|
},
|
|
@@ -388,7 +342,6 @@ module PWN
|
|
|
388
342
|
start_freq: '156.000.000',
|
|
389
343
|
target_freq: '162.000.000',
|
|
390
344
|
demodulator_mode: :FM,
|
|
391
|
-
rds: false,
|
|
392
345
|
bandwidth: '25.000',
|
|
393
346
|
precision: 4
|
|
394
347
|
},
|
|
@@ -396,7 +349,6 @@ module PWN
|
|
|
396
349
|
start_freq: '415.000',
|
|
397
350
|
target_freq: '535.000',
|
|
398
351
|
demodulator_mode: :USB,
|
|
399
|
-
rds: false,
|
|
400
352
|
bandwidth: '2.700',
|
|
401
353
|
precision: 6
|
|
402
354
|
},
|
|
@@ -404,7 +356,6 @@ module PWN
|
|
|
404
356
|
start_freq: '162.400.000',
|
|
405
357
|
target_freq: '162.550.000',
|
|
406
358
|
demodulator_mode: :FM,
|
|
407
|
-
rds: false,
|
|
408
359
|
bandwidth: '16.000',
|
|
409
360
|
precision: 4
|
|
410
361
|
},
|
|
@@ -412,7 +363,6 @@ module PWN
|
|
|
412
363
|
start_freq: '929.000.000',
|
|
413
364
|
target_freq: '932.000.000',
|
|
414
365
|
demodulator_mode: :FM,
|
|
415
|
-
rds: false,
|
|
416
366
|
bandwidth: '12.500',
|
|
417
367
|
precision: 4
|
|
418
368
|
},
|
|
@@ -420,7 +370,6 @@ module PWN
|
|
|
420
370
|
start_freq: '1.850.000.000',
|
|
421
371
|
target_freq: '1.990.000.000',
|
|
422
372
|
demodulator_mode: :RAW,
|
|
423
|
-
rds: false,
|
|
424
373
|
bandwidth: '200.000',
|
|
425
374
|
precision: 6
|
|
426
375
|
},
|
|
@@ -428,7 +377,6 @@ module PWN
|
|
|
428
377
|
start_freq: '698.000.000',
|
|
429
378
|
target_freq: '806.000.000',
|
|
430
379
|
demodulator_mode: :FM,
|
|
431
|
-
rds: false,
|
|
432
380
|
bandwidth: '25.000',
|
|
433
381
|
precision: 4
|
|
434
382
|
},
|
|
@@ -436,7 +384,6 @@ module PWN
|
|
|
436
384
|
start_freq: '14.000.000',
|
|
437
385
|
target_freq: '14.350.000',
|
|
438
386
|
demodulator_mode: :FM,
|
|
439
|
-
rds: false,
|
|
440
387
|
bandwidth: '170',
|
|
441
388
|
precision: 3
|
|
442
389
|
},
|
|
@@ -444,7 +391,6 @@ module PWN
|
|
|
444
391
|
start_freq: '7.000.000',
|
|
445
392
|
target_freq: '7.300.000',
|
|
446
393
|
demodulator_mode: :FM,
|
|
447
|
-
rds: false,
|
|
448
394
|
bandwidth: '170',
|
|
449
395
|
precision: 3
|
|
450
396
|
},
|
|
@@ -452,7 +398,6 @@ module PWN
|
|
|
452
398
|
start_freq: '3.500.000',
|
|
453
399
|
target_freq: '3.800.000',
|
|
454
400
|
demodulator_mode: :FM,
|
|
455
|
-
rds: false,
|
|
456
401
|
bandwidth: '170',
|
|
457
402
|
precision: 3
|
|
458
403
|
},
|
|
@@ -460,7 +405,6 @@ module PWN
|
|
|
460
405
|
start_freq: '5.900.000',
|
|
461
406
|
target_freq: '6.200.000',
|
|
462
407
|
demodulator_mode: :AM_SYNC,
|
|
463
|
-
rds: false,
|
|
464
408
|
bandwidth: '10.000',
|
|
465
409
|
precision: 4
|
|
466
410
|
},
|
|
@@ -468,7 +412,6 @@ module PWN
|
|
|
468
412
|
start_freq: '7.200.000',
|
|
469
413
|
target_freq: '7.450.000',
|
|
470
414
|
demodulator_mode: :AM_SYNC,
|
|
471
|
-
rds: false,
|
|
472
415
|
bandwidth: '10.000',
|
|
473
416
|
precision: 4
|
|
474
417
|
},
|
|
@@ -476,7 +419,6 @@ module PWN
|
|
|
476
419
|
start_freq: '9.400.000',
|
|
477
420
|
target_freq: '9.900.000',
|
|
478
421
|
demodulator_mode: :AM_SYNC,
|
|
479
|
-
rds: false,
|
|
480
422
|
bandwidth: '10.000',
|
|
481
423
|
precision: 4
|
|
482
424
|
},
|
|
@@ -484,7 +426,6 @@ module PWN
|
|
|
484
426
|
start_freq: '11.600.000',
|
|
485
427
|
target_freq: '12.100.000',
|
|
486
428
|
demodulator_mode: :AM_SYNC,
|
|
487
|
-
rds: false,
|
|
488
429
|
bandwidth: '10.000',
|
|
489
430
|
precision: 4
|
|
490
431
|
},
|
|
@@ -492,7 +433,6 @@ module PWN
|
|
|
492
433
|
start_freq: '13.570.000',
|
|
493
434
|
target_freq: '13.870.000',
|
|
494
435
|
demodulator_mode: :AM_SYNC,
|
|
495
|
-
rds: false,
|
|
496
436
|
bandwidth: '10.000',
|
|
497
437
|
precision: 4
|
|
498
438
|
},
|
|
@@ -500,7 +440,6 @@ module PWN
|
|
|
500
440
|
start_freq: '15.100.000',
|
|
501
441
|
target_freq: '15.800.000',
|
|
502
442
|
demodulator_mode: :AM_SYNC,
|
|
503
|
-
rds: false,
|
|
504
443
|
bandwidth: '10.000',
|
|
505
444
|
precision: 4
|
|
506
445
|
},
|
|
@@ -508,7 +447,6 @@ module PWN
|
|
|
508
447
|
start_freq: '28.000.000',
|
|
509
448
|
target_freq: '29.700.000',
|
|
510
449
|
demodulator_mode: :USB,
|
|
511
|
-
rds: false,
|
|
512
450
|
bandwidth: '3.000',
|
|
513
451
|
precision: 6
|
|
514
452
|
},
|
|
@@ -516,7 +454,6 @@ module PWN
|
|
|
516
454
|
start_freq: '24.890.000',
|
|
517
455
|
target_freq: '24.990.000',
|
|
518
456
|
demodulator_mode: :USB,
|
|
519
|
-
rds: false,
|
|
520
457
|
bandwidth: '3.000',
|
|
521
458
|
precision: 6
|
|
522
459
|
},
|
|
@@ -524,7 +461,6 @@ module PWN
|
|
|
524
461
|
start_freq: '21.000.000',
|
|
525
462
|
target_freq: '21.450.000',
|
|
526
463
|
demodulator_mode: :USB,
|
|
527
|
-
rds: false,
|
|
528
464
|
bandwidth: '3.000',
|
|
529
465
|
precision: 6
|
|
530
466
|
},
|
|
@@ -532,7 +468,6 @@ module PWN
|
|
|
532
468
|
start_freq: '18.068.000',
|
|
533
469
|
target_freq: '18.168.000',
|
|
534
470
|
demodulator_mode: :USB,
|
|
535
|
-
rds: false,
|
|
536
471
|
bandwidth: '3.000',
|
|
537
472
|
precision: 6
|
|
538
473
|
},
|
|
@@ -540,7 +475,6 @@ module PWN
|
|
|
540
475
|
start_freq: '14.000.000',
|
|
541
476
|
target_freq: '14.350.000',
|
|
542
477
|
demodulator_mode: :USB,
|
|
543
|
-
rds: false,
|
|
544
478
|
bandwidth: '3.000',
|
|
545
479
|
precision: 6
|
|
546
480
|
},
|
|
@@ -548,7 +482,6 @@ module PWN
|
|
|
548
482
|
start_freq: '7.000.000',
|
|
549
483
|
target_freq: '7.300.000',
|
|
550
484
|
demodulator_mode: :LSB,
|
|
551
|
-
rds: false,
|
|
552
485
|
bandwidth: '3.000',
|
|
553
486
|
precision: 6
|
|
554
487
|
},
|
|
@@ -556,7 +489,6 @@ module PWN
|
|
|
556
489
|
start_freq: '3.500.000',
|
|
557
490
|
target_freq: '3.800.000',
|
|
558
491
|
demodulator_mode: :LSB,
|
|
559
|
-
rds: false,
|
|
560
492
|
bandwidth: '3.000',
|
|
561
493
|
precision: 6
|
|
562
494
|
},
|
|
@@ -564,7 +496,6 @@ module PWN
|
|
|
564
496
|
start_freq: '1.800.000',
|
|
565
497
|
target_freq: '2.000.000',
|
|
566
498
|
demodulator_mode: :LSB,
|
|
567
|
-
rds: false,
|
|
568
499
|
bandwidth: '3.000',
|
|
569
500
|
precision: 6
|
|
570
501
|
},
|
|
@@ -572,7 +503,6 @@ module PWN
|
|
|
572
503
|
start_freq: '400.000.000',
|
|
573
504
|
target_freq: '430.000.000',
|
|
574
505
|
demodulator_mode: :WFM,
|
|
575
|
-
rds: false,
|
|
576
506
|
bandwidth: '6.000.000',
|
|
577
507
|
precision: 4
|
|
578
508
|
},
|
|
@@ -580,7 +510,6 @@ module PWN
|
|
|
580
510
|
start_freq: '174.000.000',
|
|
581
511
|
target_freq: '216.000.000',
|
|
582
512
|
demodulator_mode: :WFM_ST,
|
|
583
|
-
rds: false,
|
|
584
513
|
bandwidth: '6.000.000',
|
|
585
514
|
precision: 5
|
|
586
515
|
},
|
|
@@ -588,7 +517,6 @@ module PWN
|
|
|
588
517
|
start_freq: '54.000.000',
|
|
589
518
|
target_freq: '88.000.000',
|
|
590
519
|
demodulator_mode: :WFM_ST,
|
|
591
|
-
rds: false,
|
|
592
520
|
bandwidth: '6.000.000',
|
|
593
521
|
precision: 5
|
|
594
522
|
},
|
|
@@ -596,7 +524,6 @@ module PWN
|
|
|
596
524
|
start_freq: '470.000.000',
|
|
597
525
|
target_freq: '698.000.000',
|
|
598
526
|
demodulator_mode: :WFM_ST,
|
|
599
|
-
rds: false,
|
|
600
527
|
bandwidth: '6.000.000',
|
|
601
528
|
precision: 5
|
|
602
529
|
},
|
|
@@ -604,7 +531,6 @@ module PWN
|
|
|
604
531
|
start_freq: '860.000.000',
|
|
605
532
|
target_freq: '960.000.000',
|
|
606
533
|
demodulator_mode: :RAW,
|
|
607
|
-
rds: false,
|
|
608
534
|
bandwidth: '400.000',
|
|
609
535
|
precision: 5
|
|
610
536
|
},
|
|
@@ -612,7 +538,6 @@ module PWN
|
|
|
612
538
|
start_freq: '1.920.000.000',
|
|
613
539
|
target_freq: '2.170.000.000',
|
|
614
540
|
demodulator_mode: :RAW,
|
|
615
|
-
rds: false,
|
|
616
541
|
bandwidth: '5.000.000',
|
|
617
542
|
precision: 6
|
|
618
543
|
},
|
|
@@ -620,7 +545,6 @@ module PWN
|
|
|
620
545
|
start_freq: '137.000.000',
|
|
621
546
|
target_freq: '138.000.000',
|
|
622
547
|
demodulator_mode: :FM,
|
|
623
|
-
rds: false,
|
|
624
548
|
bandwidth: '15.000',
|
|
625
549
|
precision: 5
|
|
626
550
|
},
|
|
@@ -628,7 +552,6 @@ module PWN
|
|
|
628
552
|
start_freq: '2.400.000.000',
|
|
629
553
|
target_freq: '2.500.000.000',
|
|
630
554
|
demodulator_mode: :RAW,
|
|
631
|
-
rds: false,
|
|
632
555
|
bandwidth: '20.000.000',
|
|
633
556
|
precision: 7
|
|
634
557
|
},
|
|
@@ -636,7 +559,6 @@ module PWN
|
|
|
636
559
|
start_freq: '5.150.000.000',
|
|
637
560
|
target_freq: '5.850.000.000',
|
|
638
561
|
demodulator_mode: :RAW,
|
|
639
|
-
rds: false,
|
|
640
562
|
bandwidth: '20.000.000',
|
|
641
563
|
precision: 7
|
|
642
564
|
},
|
|
@@ -644,7 +566,6 @@ module PWN
|
|
|
644
566
|
start_freq: '5.925.000.000',
|
|
645
567
|
target_freq: '7.125.000.000',
|
|
646
568
|
demodulator_mode: :RAW,
|
|
647
|
-
rds: false,
|
|
648
569
|
bandwidth: '20.000.000',
|
|
649
570
|
precision: 7
|
|
650
571
|
},
|
|
@@ -652,7 +573,6 @@ module PWN
|
|
|
652
573
|
start_freq: '2.405.000.000',
|
|
653
574
|
target_freq: '2.485.000.000',
|
|
654
575
|
demodulator_mode: :RAW,
|
|
655
|
-
rds: false,
|
|
656
576
|
bandwidth: '2.000.000',
|
|
657
577
|
precision: 7
|
|
658
578
|
}
|
data/lib/pwn/sdr/gqrx.rb
CHANGED
|
@@ -7,29 +7,6 @@ module PWN
|
|
|
7
7
|
module SDR
|
|
8
8
|
# This plugin interacts with the remote control interface of GQRX.
|
|
9
9
|
module GQRX
|
|
10
|
-
# Monkey patches for frequency handling
|
|
11
|
-
String.class_eval do
|
|
12
|
-
def cast_to_raw_hz
|
|
13
|
-
gsub('.', '').to_i
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
Integer.class_eval do
|
|
18
|
-
# Should always return format of X.XXX.XXX.XXX
|
|
19
|
-
# So 002_450_000_000 becomes 2.450.000.000 = 2.45 GHz
|
|
20
|
-
# So 2_450_000_000 becomes 2.450.000.000 = 2.45 GHz
|
|
21
|
-
# So 960_000_000 becomes 960.000.000 = 960 MHz
|
|
22
|
-
# 1000 should be 1.000 = 1 kHz
|
|
23
|
-
def cast_to_pretty_hz
|
|
24
|
-
str_hz = to_s
|
|
25
|
-
# Nuke leading zeros
|
|
26
|
-
# E.g., 002450000000 -> 2450000000
|
|
27
|
-
str_hz = str_hz.sub(/^0+/, '') unless str_hz == '0'
|
|
28
|
-
# Insert dots every 3 digits from the right
|
|
29
|
-
str_hz.reverse.scan(/.{1,3}/).join('.').reverse
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
10
|
# Supported Method Parameters::
|
|
34
11
|
# gqrx_resp = PWN::SDR::GQRX.gqrx_cmd(
|
|
35
12
|
# gqrx_sock: 'required - GQRX socket object returned from #connect method',
|
|
@@ -37,7 +14,7 @@ module PWN
|
|
|
37
14
|
# resp_ok: 'optional - Expected response from GQRX to indicate success'
|
|
38
15
|
# )
|
|
39
16
|
|
|
40
|
-
|
|
17
|
+
public_class_method def self.gqrx_cmd(opts = {})
|
|
41
18
|
gqrx_sock = opts[:gqrx_sock]
|
|
42
19
|
cmd = opts[:cmd]
|
|
43
20
|
resp_ok = opts[:resp_ok]
|
|
@@ -154,7 +131,7 @@ module PWN
|
|
|
154
131
|
raise "ERROR!!! Command: #{cmd} Expected Resp: #{resp_ok}, Got: #{response_str}" if resp_ok && response_str != resp_ok
|
|
155
132
|
|
|
156
133
|
# Reformat positive integer frequency responses (e.g., from 'f')
|
|
157
|
-
response_str = response_str
|
|
134
|
+
response_str = PWN::SDR.hz_to_s(response_str) if response_str.match?(/^\d+$/) && response_str.to_i.positive?
|
|
158
135
|
|
|
159
136
|
response_str
|
|
160
137
|
rescue RuntimeError => e
|
|
@@ -176,8 +153,8 @@ module PWN
|
|
|
176
153
|
# )
|
|
177
154
|
private_class_method def self.measure_signal_strength(opts = {})
|
|
178
155
|
gqrx_sock = opts[:gqrx_sock]
|
|
179
|
-
freq = opts[:freq]
|
|
180
|
-
freq = freq
|
|
156
|
+
freq = PWN::SDR.hz_to_i(opts[:freq])
|
|
157
|
+
freq = PWN::SDR.hz_to_s(freq)
|
|
181
158
|
|
|
182
159
|
strength_lock = opts[:strength_lock] ||= -70.0
|
|
183
160
|
phase = opts[:phase] ||= :find_candidates
|
|
@@ -198,7 +175,7 @@ module PWN
|
|
|
198
175
|
unique_samples = samples.uniq
|
|
199
176
|
if unique_samples.length > 1
|
|
200
177
|
prev_strength_db = unique_samples[-2]
|
|
201
|
-
distance_between_unique_samples = (strength_db - prev_strength_db).abs
|
|
178
|
+
distance_between_unique_samples = (strength_db - prev_strength_db).abs.round(2)
|
|
202
179
|
strength_measured = true if distance_between_unique_samples.positive? && strength_lock > strength_db
|
|
203
180
|
end
|
|
204
181
|
strength_measured = true if distance_between_unique_samples.positive? && distance_between_unique_samples < 5
|
|
@@ -224,7 +201,7 @@ module PWN
|
|
|
224
201
|
# )
|
|
225
202
|
private_class_method def self.tune_to(opts = {})
|
|
226
203
|
gqrx_sock = opts[:gqrx_sock]
|
|
227
|
-
hz = opts[:hz]
|
|
204
|
+
hz = PWN::SDR.hz_to_i(opts[:hz])
|
|
228
205
|
|
|
229
206
|
current_freq = 0
|
|
230
207
|
attempts = 0
|
|
@@ -241,7 +218,7 @@ module PWN
|
|
|
241
218
|
cmd: 'f'
|
|
242
219
|
)
|
|
243
220
|
|
|
244
|
-
break if current_freq
|
|
221
|
+
break if PWN::SDR.hz_to_i(current_freq) == hz
|
|
245
222
|
end
|
|
246
223
|
# puts "Tuned to #{current_freq} in #{attempts} attempt(s)."
|
|
247
224
|
rescue StandardError => e
|
|
@@ -276,8 +253,8 @@ module PWN
|
|
|
276
253
|
phase: :edge_left
|
|
277
254
|
)
|
|
278
255
|
candidate = {
|
|
279
|
-
hz: hz
|
|
280
|
-
freq: hz
|
|
256
|
+
hz: PWN::SDR.hz_to_i(hz),
|
|
257
|
+
freq: PWN::SDR.hz_to_s(hz),
|
|
281
258
|
strength: strength_db,
|
|
282
259
|
edge: :left
|
|
283
260
|
}
|
|
@@ -302,8 +279,8 @@ module PWN
|
|
|
302
279
|
phase: :edge_right
|
|
303
280
|
)
|
|
304
281
|
candidate = {
|
|
305
|
-
hz: hz
|
|
306
|
-
freq: hz
|
|
282
|
+
hz: PWN::SDR.hz_to_i(hz),
|
|
283
|
+
freq: PWN::SDR.hz_to_s(hz),
|
|
307
284
|
strength: strength_db,
|
|
308
285
|
edge: :right
|
|
309
286
|
}
|
|
@@ -332,9 +309,9 @@ module PWN
|
|
|
332
309
|
timestamp_start = opts[:timestamp_start]
|
|
333
310
|
scan_log = opts[:scan_log]
|
|
334
311
|
|
|
335
|
-
signals = signals_arr.sort_by { |s| s[:freq]
|
|
312
|
+
signals = signals_arr.sort_by { |s| PWN::SDR.hz_to_i(s[:freq]) }
|
|
336
313
|
# Unique signals by frequency
|
|
337
|
-
signals.uniq! { |s| s[:freq]
|
|
314
|
+
signals.uniq! { |s| PWN::SDR.hz_to_i(s[:freq]) }
|
|
338
315
|
|
|
339
316
|
timestamp_end = Time.now.strftime('%Y-%m-%d %H:%M:%S%z')
|
|
340
317
|
duration_secs = Time.parse(timestamp_end).to_f - Time.parse(timestamp_start).to_f
|
|
@@ -367,54 +344,6 @@ module PWN
|
|
|
367
344
|
raise e
|
|
368
345
|
end
|
|
369
346
|
|
|
370
|
-
# Supported Method Parameters::
|
|
371
|
-
# rds_resp = PWN::SDR::GQRX.decode_rds(
|
|
372
|
-
# gqrx_sock: 'required - GQRX socket object returned from #connect method'
|
|
373
|
-
# )
|
|
374
|
-
|
|
375
|
-
private_class_method def self.decode_rds(opts = {})
|
|
376
|
-
gqrx_sock = opts[:gqrx_sock]
|
|
377
|
-
|
|
378
|
-
# We toggle RDS off and on to reset the decoder
|
|
379
|
-
rds_resp = gqrx_cmd(
|
|
380
|
-
gqrx_sock: gqrx_sock,
|
|
381
|
-
cmd: 'U RDS 0',
|
|
382
|
-
resp_ok: 'RPRT 0'
|
|
383
|
-
)
|
|
384
|
-
|
|
385
|
-
rds_resp = gqrx_cmd(
|
|
386
|
-
gqrx_sock: gqrx_sock,
|
|
387
|
-
cmd: 'U RDS 1',
|
|
388
|
-
resp_ok: 'RPRT 0'
|
|
389
|
-
)
|
|
390
|
-
|
|
391
|
-
rds_resp = {}
|
|
392
|
-
attempts = 0
|
|
393
|
-
max_attempts = 120
|
|
394
|
-
skip_rds = "\n"
|
|
395
|
-
print 'INFO: Decoding FM radio RDS data (Press ENTER to skip)...'
|
|
396
|
-
max_attempts.times do
|
|
397
|
-
attempts += 1
|
|
398
|
-
rds_resp[:rds_pi] = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_PI')
|
|
399
|
-
rds_resp[:rds_ps_name] = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_PS_NAME')
|
|
400
|
-
rds_resp[:rds_radiotext] = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_RADIOTEXT')
|
|
401
|
-
|
|
402
|
-
# Break if ENTER key pressed
|
|
403
|
-
# This is useful if no RDS data is available
|
|
404
|
-
# on the current frequency (e.g. false+)
|
|
405
|
-
break if $stdin.ready? && $stdin.read_nonblock(1) == skip_rds
|
|
406
|
-
|
|
407
|
-
break if rds_resp[:rds_pi] != '0000' && !rds_resp[:rds_ps_name].empty? && !rds_resp[:rds_radiotext].empty?
|
|
408
|
-
|
|
409
|
-
print '.'
|
|
410
|
-
sleep 0.1
|
|
411
|
-
end
|
|
412
|
-
puts 'complete.'
|
|
413
|
-
rds_resp
|
|
414
|
-
rescue StandardError => e
|
|
415
|
-
raise e
|
|
416
|
-
end
|
|
417
|
-
|
|
418
347
|
# Supported Method Parameters::
|
|
419
348
|
# best_peak = PWN::SDR::GQRX.find_best_peak(
|
|
420
349
|
# gqrx_sock: 'required - GQRX socket object returned from #connect method',
|
|
@@ -428,10 +357,10 @@ module PWN
|
|
|
428
357
|
step_hz = opts[:step_hz]
|
|
429
358
|
strength_lock = opts[:strength_lock]
|
|
430
359
|
|
|
431
|
-
beg_of_signal_hz = candidate_signals.first[:hz]
|
|
432
|
-
end_of_signal_hz = candidate_signals.last[:hz]
|
|
360
|
+
beg_of_signal_hz = PWN::SDR.hz_to_i(candidate_signals.first[:hz])
|
|
361
|
+
end_of_signal_hz = PWN::SDR.hz_to_i(candidate_signals.last[:hz])
|
|
433
362
|
|
|
434
|
-
puts "*** Analyzing Best Peak in Frequency Range: #{beg_of_signal_hz
|
|
363
|
+
puts "*** Analyzing Best Peak in Frequency Range: #{PWN::SDR.hz_to_s(beg_of_signal_hz)} Hz - #{PWN::SDR.hz_to_s(end_of_signal_hz)} Hz"
|
|
435
364
|
# puts JSON.pretty_generate(candidate_signals)
|
|
436
365
|
|
|
437
366
|
samples = []
|
|
@@ -466,9 +395,6 @@ module PWN
|
|
|
466
395
|
phase: :find_best_peak
|
|
467
396
|
)
|
|
468
397
|
samples.push({ hz: hz, strength_db: strength_db })
|
|
469
|
-
|
|
470
|
-
# current_hz = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'f').to_s.cast_to_raw_hz
|
|
471
|
-
# puts "Sampled Frequency: #{current_hz.to_i.cast_to_pretty_hz} => Strength: #{strength_db} dBFS"
|
|
472
398
|
end
|
|
473
399
|
|
|
474
400
|
# Compute fresh averaged_samples from all cumulative samples
|
|
@@ -513,7 +439,7 @@ module PWN
|
|
|
513
439
|
# Dup to avoid reference issues
|
|
514
440
|
prev_best_sample = best_sample.dup
|
|
515
441
|
|
|
516
|
-
puts "Pass #{pass_count}: Best #{best_sample[:hz]
|
|
442
|
+
puts "Pass #{pass_count}: Best #{PWN::SDR.hz_to_s(best_sample[:hz])} => #{best_sample[:strength_db]} dBFS, consecutive best count: #{consecutive_best}"
|
|
517
443
|
|
|
518
444
|
# Break if we have a stable best sample or only one sample remains
|
|
519
445
|
break if consecutive_best.positive? || averaged_samples.length == 1
|
|
@@ -592,7 +518,7 @@ module PWN
|
|
|
592
518
|
)
|
|
593
519
|
|
|
594
520
|
mode_str = demodulator_mode.to_s.upcase
|
|
595
|
-
passband_hz = bandwidth
|
|
521
|
+
passband_hz = PWN::SDR.hz_to_i(bandwidth)
|
|
596
522
|
gqrx_cmd(
|
|
597
523
|
gqrx_sock: gqrx_sock,
|
|
598
524
|
cmd: "M #{mode_str} #{passband_hz}",
|
|
@@ -647,7 +573,7 @@ module PWN
|
|
|
647
573
|
)
|
|
648
574
|
|
|
649
575
|
rds_resp = nil
|
|
650
|
-
rds_resp =
|
|
576
|
+
rds_resp = PWN::SDR::Decoder::RDS.decode(gqrx_sock: gqrx_sock) if rds
|
|
651
577
|
|
|
652
578
|
freq_obj[:audio_gain_db] = audio_gain_db
|
|
653
579
|
freq_obj[:demod_mode_n_passband] = demod_n_passband
|
|
@@ -667,6 +593,8 @@ module PWN
|
|
|
667
593
|
case decoder
|
|
668
594
|
when :gsm
|
|
669
595
|
decoder_module = PWN::SDR::Decoder::GSM
|
|
596
|
+
when :rds
|
|
597
|
+
decoder_module = PWN::SDR::Decoder::RDS
|
|
670
598
|
else
|
|
671
599
|
raise "ERROR: Unknown decoder key: #{decoder}. Supported: :gsm"
|
|
672
600
|
end
|
|
@@ -740,10 +668,10 @@ module PWN
|
|
|
740
668
|
gqrx_sock = opts[:gqrx_sock]
|
|
741
669
|
|
|
742
670
|
start_freq = opts[:start_freq]
|
|
743
|
-
hz_start = start_freq
|
|
671
|
+
hz_start = PWN::SDR.hz_to_i(start_freq)
|
|
744
672
|
|
|
745
673
|
target_freq = opts[:target_freq]
|
|
746
|
-
hz_target = target_freq
|
|
674
|
+
hz_target = PWN::SDR.hz_to_i(target_freq)
|
|
747
675
|
|
|
748
676
|
demodulator_mode = opts[:demodulator_mode]
|
|
749
677
|
rds = opts[:rds] ||= false
|
|
@@ -753,7 +681,7 @@ module PWN
|
|
|
753
681
|
precision = opts[:precision] ||= 1
|
|
754
682
|
strength_lock = opts[:strength_lock] ||= -70.0
|
|
755
683
|
squelch = opts[:squelch] ||= (strength_lock - 3.0)
|
|
756
|
-
scan_log = opts[:scan_log] ||= "/tmp/pwn_sdr_gqrx_scan_#{hz_start
|
|
684
|
+
scan_log = opts[:scan_log] ||= "/tmp/pwn_sdr_gqrx_scan_#{PWN::SDR.hz_to_s(hz_start)}-#{PWN::SDR.hz_to_s(hz_target)}_#{log_timestamp}.json"
|
|
757
685
|
location = opts[:location] ||= 'United States'
|
|
758
686
|
|
|
759
687
|
step_hz = 10**(precision - 1)
|
|
@@ -779,7 +707,7 @@ module PWN
|
|
|
779
707
|
|
|
780
708
|
# Set demodulator mode & passband once for the scan
|
|
781
709
|
mode_str = demodulator_mode.to_s.upcase
|
|
782
|
-
passband_hz = bandwidth
|
|
710
|
+
passband_hz = PWN::SDR.hz_to_i(bandwidth)
|
|
783
711
|
gqrx_cmd(
|
|
784
712
|
gqrx_sock: gqrx_sock,
|
|
785
713
|
cmd: "M #{mode_str} #{passband_hz}",
|
|
@@ -834,7 +762,7 @@ module PWN
|
|
|
834
762
|
# Begin scanning range
|
|
835
763
|
puts "\n"
|
|
836
764
|
puts '-' * 86
|
|
837
|
-
puts "INFO: Scanning from #{hz_start
|
|
765
|
+
puts "INFO: Scanning from #{PWN::SDR.hz_to_s(hz_start)} to #{PWN::SDR.hz_to_s(hz_target)} in steps of #{PWN::SDR.hz_to_s(step_hz_direction.abs)} Hz."
|
|
838
766
|
puts "If scans are slow and/or you're experiencing false positives/negatives,"
|
|
839
767
|
puts 'consider adjusting the following:'
|
|
840
768
|
puts "1. The SDR's sample rate in GQRX"
|
|
@@ -878,7 +806,7 @@ module PWN
|
|
|
878
806
|
|
|
879
807
|
if best_peak[:hz] && best_peak[:strength_db] > strength_lock
|
|
880
808
|
puts "\n**** Detected Signal ****"
|
|
881
|
-
best_freq = best_peak[:hz]
|
|
809
|
+
best_freq = PWN::SDR.hz_to_s(best_peak[:hz])
|
|
882
810
|
best_strength_db = best_peak[:strength_db]
|
|
883
811
|
prev_freq_obj = init_freq(
|
|
884
812
|
gqrx_sock: gqrx_sock,
|
|
@@ -1020,6 +948,12 @@ module PWN
|
|
|
1020
948
|
port: 'optional - GQRX target port (defaults to 7356)'
|
|
1021
949
|
)
|
|
1022
950
|
|
|
951
|
+
gqrx_resp = #{self}.gqrx_cmd(
|
|
952
|
+
gqrx_sock: 'required - GQRX socket object returned from #connect method',
|
|
953
|
+
cmd: 'required - GQRX command to send',
|
|
954
|
+
resp_ok: 'optional - Expected OK response (defaults to nil / no check)'
|
|
955
|
+
)
|
|
956
|
+
|
|
1023
957
|
freq_obj = #{self}.init_freq(
|
|
1024
958
|
gqrx_sock: 'required - GQRX socket object returned from #connect method',
|
|
1025
959
|
freq: 'required - Frequency to set',
|
data/lib/pwn/sdr.rb
CHANGED
|
@@ -12,6 +12,19 @@ module PWN
|
|
|
12
12
|
autoload :RFIDler, 'pwn/sdr/rfidler'
|
|
13
13
|
autoload :SonMicroRFID, 'pwn/sdr/son_micro_rfid'
|
|
14
14
|
|
|
15
|
+
public_class_method def self.hz_to_s(freq)
|
|
16
|
+
str_hz = freq.to_s
|
|
17
|
+
# Nuke leading zeros
|
|
18
|
+
# E.g., 002450000000 -> 2450000000
|
|
19
|
+
str_hz = str_hz.sub(/^0+/, '') unless str_hz == '0'
|
|
20
|
+
# Insert dots every 3 digits from the right
|
|
21
|
+
str_hz.reverse.scan(/.{1,3}/).join('.').reverse
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
public_class_method def self.hz_to_i(freq)
|
|
25
|
+
freq.to_s.gsub('.', '').to_i
|
|
26
|
+
end
|
|
27
|
+
|
|
15
28
|
# Display a List of Every PWN::AI Module
|
|
16
29
|
|
|
17
30
|
public_class_method def self.help
|
data/lib/pwn/version.rb
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe PWN::SDR::Decoder::RDS do
|
|
6
|
+
it 'should display information for authors' do
|
|
7
|
+
authors_response = PWN::SDR::Decoder::RDS
|
|
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::RDS
|
|
13
|
+
expect(help_response).to respond_to :help
|
|
14
|
+
end
|
|
15
|
+
end
|
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.
|
|
4
|
+
version: 0.5.518
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- 0day Inc.
|
|
@@ -2002,6 +2002,7 @@ files:
|
|
|
2002
2002
|
- lib/pwn/sdr.rb
|
|
2003
2003
|
- lib/pwn/sdr/decoder.rb
|
|
2004
2004
|
- lib/pwn/sdr/decoder/gsm.rb
|
|
2005
|
+
- lib/pwn/sdr/decoder/rds.rb
|
|
2005
2006
|
- lib/pwn/sdr/flipper_zero.rb
|
|
2006
2007
|
- lib/pwn/sdr/frequency_allocation.rb
|
|
2007
2008
|
- lib/pwn/sdr/gqrx.rb
|
|
@@ -2358,6 +2359,7 @@ files:
|
|
|
2358
2359
|
- spec/lib/pwn/sast/window_location_hash_spec.rb
|
|
2359
2360
|
- spec/lib/pwn/sast_spec.rb
|
|
2360
2361
|
- spec/lib/pwn/sdr/decoder/gsm_spec.rb
|
|
2362
|
+
- spec/lib/pwn/sdr/decoder/rds_spec.rb
|
|
2361
2363
|
- spec/lib/pwn/sdr/decoder_spec.rb
|
|
2362
2364
|
- spec/lib/pwn/sdr/flipper_zero_spec.rb
|
|
2363
2365
|
- spec/lib/pwn/sdr/frequency_allocation_spec.rb
|