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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e08346b6205e3f8b1c5297021ff879beb1cf8957ea1a1f3773237863dd74ba7
4
- data.tar.gz: 638d3e6bd7fd19153b2b2b96bd42c075aebb355a4f5d7162f23bc02330e75659
3
+ metadata.gz: 4782a5ea26c616b61254cbc43ba1fa0fbee4f71890b48ac3b0197a0586965356
4
+ data.tar.gz: 987fdf3e321dd0790ca1f059c483a045bcee5239f63ba5f2bfbd065e5f85c24f
5
5
  SHA512:
6
- metadata.gz: 63d02cdda5b215eb281743795dde177210fa27285fa3855c30b563c5c46c06474c7e45a3371094f12d67b984a54b08cd93323ba3ccdc04abdef9931a5d64d72d
7
- data.tar.gz: 795586b4f0edf6b8802b5dafbc94baf72eb3c6ca3c6bc8ca91e4ce59dfe55a77d597df68a68a095470a69b153492968625c16183072c48c7fe73867bab820b88
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.516]:001 >>> PWN.help
40
+ pwn[v0.5.518]:001 >>> PWN.help
41
41
  ```
42
42
 
43
43
  [![Installing the pwn Security Automation Framework](https://raw.githubusercontent.com/0dayInc/pwn/master/documentation/pwn_install.png)](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.516]:001 >>> PWN.help
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.516]:001 >>> PWN.help
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
@@ -8,6 +8,7 @@ module PWN
8
8
  # Deocder Module for SDR signals.
9
9
  module Decoder
10
10
  autoload :GSM, 'pwn/sdr/decoder/gsm'
11
+ autoload :RDS, 'pwn/sdr/decoder/rds'
11
12
 
12
13
  # Display a List of Every PWN::AI Module
13
14
 
@@ -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
- private_class_method def self.gqrx_cmd(opts = {})
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.to_i.cast_to_pretty_hz if response_str.match?(/^\d+$/) && response_str.to_i.positive?
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].to_s.cast_to_raw_hz
180
- freq = freq.to_i.cast_to_pretty_hz
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].to_s.cast_to_raw_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.to_s.cast_to_raw_hz == hz
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.to_s.cast_to_raw_hz,
280
- freq: hz.to_i.cast_to_pretty_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.to_s.cast_to_raw_hz,
306
- freq: hz.to_i.cast_to_pretty_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].to_s.cast_to_raw_hz }
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].to_s.cast_to_raw_hz }
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].to_s.cast_to_raw_hz
432
- end_of_signal_hz = candidate_signals.last[:hz].to_s.cast_to_raw_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.to_i.cast_to_pretty_hz} Hz - #{end_of_signal_hz.to_i.cast_to_pretty_hz} 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].to_i.cast_to_pretty_hz} => #{best_sample[:strength_db]} dBFS, consecutive best count: #{consecutive_best}"
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.to_s.cast_to_raw_hz
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 = decode_rds(gqrx_sock: gqrx_sock) if rds
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.to_s.cast_to_raw_hz
671
+ hz_start = PWN::SDR.hz_to_i(start_freq)
744
672
 
745
673
  target_freq = opts[:target_freq]
746
- hz_target = target_freq.to_s.cast_to_raw_hz
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.to_i.cast_to_pretty_hz}-#{hz_target.to_i.cast_to_pretty_hz}_#{log_timestamp}.json"
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.to_s.cast_to_raw_hz
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.to_i.cast_to_pretty_hz} to #{hz_target.to_i.cast_to_pretty_hz} in steps of #{step_hz_direction.abs.to_i.cast_to_pretty_hz} Hz."
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].to_i.cast_to_pretty_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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PWN
4
- VERSION = '0.5.516'
4
+ VERSION = '0.5.518'
5
5
  end
@@ -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.516
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