pwn 0.5.507 → 0.5.508
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/frequency_allocation.rb +88 -44
- data/lib/pwn/sdr/gqrx.rb +72 -73
- data/lib/pwn/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8eb3082d541b6f77e340f82eaf0ae9812120dfc26083aad1543a74838ea00d6b
|
|
4
|
+
data.tar.gz: 9b00807a4e8dec539507c50238ac49a0aaef69eaaa2a90a0acf07a50f3dc8bc9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af54dc286346e35678c53b921eeaa64ab4ec0e4902dee96c8e9c240fb058069402ab43d7fa49aafeb73f4ca10aa8be26a4253eb0c3ccc59e97f9602d1bd4bb09
|
|
7
|
+
data.tar.gz: 9f5df8d0ffc7a4acd3410b5378ca1a9b5bbc522aa058f62d3ef1c2640079c2520c7b865e21bf4025b72feb26f00baffac2968fcc28345dc9e1ca5a79aaca6207
|
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.508]:001 >>> PWN.help
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
[](https://youtu.be/G7iLUY4FzsI)
|
|
@@ -52,7 +52,7 @@ $ rvm use ruby-3.4.4@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.508]: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.4@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.508]: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:
|
|
@@ -23,308 +23,352 @@ module PWN
|
|
|
23
23
|
target_freq: '979.000.000',
|
|
24
24
|
demodulator_mode: 'RAW',
|
|
25
25
|
bandwidth: 100_000,
|
|
26
|
-
precision: 5
|
|
26
|
+
precision: 5,
|
|
27
|
+
overlap_protection: true
|
|
27
28
|
},
|
|
28
29
|
ads_b1090: {
|
|
29
30
|
start_freq: '1.090.000.000',
|
|
30
31
|
target_freq: '1.091.000.000',
|
|
31
32
|
demodulator_mode: 'RAW',
|
|
32
33
|
bandwidth: 100_000,
|
|
33
|
-
precision: 5
|
|
34
|
+
precision: 5,
|
|
35
|
+
overlap_protection: true
|
|
34
36
|
},
|
|
35
37
|
analog_tv_vhf: {
|
|
36
38
|
start_freq: '54.000.000',
|
|
37
39
|
target_freq: '216.000.000',
|
|
38
40
|
demodulator_mode: 'WFM',
|
|
39
41
|
bandwidth: 600_000,
|
|
40
|
-
precision: 5
|
|
42
|
+
precision: 5,
|
|
43
|
+
overlap_protection: true
|
|
41
44
|
},
|
|
42
45
|
analog_tv_uhf: {
|
|
43
46
|
start_freq: '470.000.000',
|
|
44
47
|
target_freq: '890.000.000',
|
|
45
48
|
demodulator_mode: 'WFM',
|
|
46
49
|
bandwidth: 600_000,
|
|
47
|
-
precision: 5
|
|
50
|
+
precision: 5,
|
|
51
|
+
overlap_protection: true
|
|
48
52
|
},
|
|
49
53
|
am_radio: {
|
|
50
54
|
start_freq: '540.000',
|
|
51
55
|
target_freq: '1.700.000',
|
|
52
56
|
demodulator_mode: 'AM',
|
|
53
57
|
bandwidth: 10_000,
|
|
54
|
-
precision: 4
|
|
58
|
+
precision: 4,
|
|
59
|
+
overlap_protection: true
|
|
55
60
|
},
|
|
56
61
|
bluetooth: {
|
|
57
62
|
start_freq: '2.402.000.000',
|
|
58
63
|
target_freq: '2.480.000.000',
|
|
59
64
|
demodulator_mode: 'RAW',
|
|
60
65
|
bandwidth: 100_000,
|
|
61
|
-
precision: 5
|
|
66
|
+
precision: 5,
|
|
67
|
+
overlap_protection: true
|
|
62
68
|
},
|
|
63
69
|
cdma: {
|
|
64
70
|
start_freq: '824.000.000',
|
|
65
71
|
target_freq: '849.000.000',
|
|
66
72
|
demodulator_mode: 'RAW',
|
|
67
73
|
bandwidth: 125_000,
|
|
68
|
-
precision: 6
|
|
74
|
+
precision: 6,
|
|
75
|
+
overlap_protection: false
|
|
69
76
|
},
|
|
70
77
|
cw20: {
|
|
71
78
|
start_freq: '14.000.000',
|
|
72
79
|
target_freq: '14.350.000',
|
|
73
80
|
demodulator_mode: 'CW',
|
|
74
81
|
bandwidth: 150,
|
|
75
|
-
precision: 3
|
|
82
|
+
precision: 3,
|
|
83
|
+
overlap_protection: true
|
|
76
84
|
},
|
|
77
85
|
cw40: {
|
|
78
86
|
start_freq: '7.000.000',
|
|
79
87
|
target_freq: '7.300.000',
|
|
80
88
|
demodulator_mode: 'CW',
|
|
81
89
|
bandwidth: 150,
|
|
82
|
-
precision: 3
|
|
90
|
+
precision: 3,
|
|
91
|
+
overlap_protection: true
|
|
83
92
|
},
|
|
84
93
|
cw80: {
|
|
85
94
|
start_freq: '3.500.000',
|
|
86
95
|
target_freq: '3.800.000',
|
|
87
96
|
demodulator_mode: 'CW',
|
|
88
97
|
bandwidth: 150,
|
|
89
|
-
precision: 3
|
|
98
|
+
precision: 3,
|
|
99
|
+
overlap_protection: true
|
|
90
100
|
},
|
|
91
101
|
fm_radio: {
|
|
92
102
|
start_freq: '87.900.000',
|
|
93
103
|
target_freq: '108.000.000',
|
|
94
104
|
demodulator_mode: 'WFM',
|
|
95
105
|
bandwidth: 200_000,
|
|
96
|
-
precision: 6
|
|
106
|
+
precision: 6,
|
|
107
|
+
overlap_protection: true
|
|
97
108
|
},
|
|
98
109
|
frs: {
|
|
99
110
|
start_freq: '462.562.500',
|
|
100
111
|
target_freq: '467.725.000',
|
|
101
112
|
demodulator_mode: 'FM',
|
|
102
113
|
bandwidth: 200_000,
|
|
103
|
-
precision: 3
|
|
114
|
+
precision: 3,
|
|
115
|
+
overlap_protection: true
|
|
104
116
|
},
|
|
105
117
|
gmrs: {
|
|
106
118
|
start_freq: '462.550.000',
|
|
107
119
|
target_freq: '467.725.000',
|
|
108
120
|
demodulator_mode: 'FM',
|
|
109
121
|
bandwidth: 200_000,
|
|
110
|
-
precision: 3
|
|
122
|
+
precision: 3,
|
|
123
|
+
overlap_protection: true
|
|
111
124
|
},
|
|
112
125
|
gprs: {
|
|
113
126
|
start_freq: '880.000.000',
|
|
114
127
|
target_freq: '915.000.000',
|
|
115
128
|
demodulator_mode: 'RAW',
|
|
116
129
|
bandwidth: 200_000,
|
|
117
|
-
precision: 4
|
|
130
|
+
precision: 4,
|
|
131
|
+
overlap_protection: false
|
|
118
132
|
},
|
|
119
133
|
gps_l1: {
|
|
120
134
|
start_freq: '1.574.420.000',
|
|
121
135
|
target_freq: '1.576.420.000',
|
|
122
136
|
demodulator_mode: 'RAW',
|
|
123
137
|
bandwidth: 200_000,
|
|
124
|
-
precision: 6
|
|
138
|
+
precision: 6,
|
|
139
|
+
overlap_protection: false
|
|
125
140
|
},
|
|
126
141
|
gps_l2: {
|
|
127
142
|
start_freq: '1.226.600.000',
|
|
128
143
|
target_freq: '1.228.600.000',
|
|
129
144
|
demodulator_mode: 'RAW',
|
|
130
145
|
bandwidth: 200_000,
|
|
131
|
-
precision: 6
|
|
146
|
+
precision: 6,
|
|
147
|
+
overlap_protection: false
|
|
132
148
|
},
|
|
133
149
|
gsm: {
|
|
134
150
|
start_freq: '824.000.000',
|
|
135
151
|
target_freq: '894.000.000',
|
|
136
152
|
demodulator_mode: 'RAW',
|
|
137
153
|
bandwidth: 200_000,
|
|
138
|
-
precision: 4
|
|
154
|
+
precision: 4,
|
|
155
|
+
overlap_protection: false
|
|
139
156
|
},
|
|
140
157
|
high_rfid: {
|
|
141
158
|
start_freq: '13.560.000',
|
|
142
159
|
target_freq: '13.570.000',
|
|
143
160
|
demodulator_mode: 'RAW',
|
|
144
161
|
bandwidth: 200_000,
|
|
145
|
-
precision: 3
|
|
162
|
+
precision: 3,
|
|
163
|
+
overlap_protection: true
|
|
146
164
|
},
|
|
147
165
|
lora433: {
|
|
148
166
|
start_freq: '432.000.000',
|
|
149
167
|
target_freq: '434.000.000',
|
|
150
168
|
demodulator_mode: 'RAW',
|
|
151
169
|
bandwidth: 50_000,
|
|
152
|
-
precision: 3
|
|
170
|
+
precision: 3,
|
|
171
|
+
overlap_protection: true
|
|
153
172
|
},
|
|
154
173
|
lora915: {
|
|
155
174
|
start_freq: '902.000.000',
|
|
156
175
|
target_freq: '928.000.000',
|
|
157
176
|
demodulator_mode: 'RAW',
|
|
158
177
|
bandwidth: 50_000,
|
|
159
|
-
precision: 3
|
|
178
|
+
precision: 3,
|
|
179
|
+
overlap_protection: true
|
|
160
180
|
},
|
|
161
181
|
low_rfid: {
|
|
162
182
|
start_freq: '125.000',
|
|
163
183
|
target_freq: '134.000',
|
|
164
184
|
demodulator_mode: 'RAW',
|
|
165
185
|
bandwidth: 200_000,
|
|
166
|
-
precision: 1
|
|
186
|
+
precision: 1,
|
|
187
|
+
overlap_protection: true
|
|
167
188
|
},
|
|
168
189
|
keyfob300: {
|
|
169
190
|
start_freq: '300.000.000',
|
|
170
191
|
target_freq: '300.100.000',
|
|
171
192
|
demodulator_mode: 'RAW',
|
|
172
193
|
bandwidth: 50_000,
|
|
173
|
-
precision: 4
|
|
194
|
+
precision: 4,
|
|
195
|
+
overlap_protection: true
|
|
174
196
|
},
|
|
175
197
|
keyfob310: {
|
|
176
198
|
start_freq: '310.000.000',
|
|
177
199
|
target_freq: '310.100.000',
|
|
178
200
|
demodulator_mode: 'RAW',
|
|
179
201
|
bandwidth: 50_000,
|
|
180
|
-
precision: 4
|
|
202
|
+
precision: 4,
|
|
203
|
+
overlap_protection: true
|
|
181
204
|
},
|
|
182
205
|
keyfob315: {
|
|
183
206
|
start_freq: '315.000.000',
|
|
184
207
|
target_freq: '315.100.000',
|
|
185
208
|
demodulator_mode: 'RAW',
|
|
186
209
|
bandwidth: 50_000,
|
|
187
|
-
precision: 4
|
|
210
|
+
precision: 4,
|
|
211
|
+
overlap_protection: true
|
|
188
212
|
},
|
|
189
213
|
keyfob390: {
|
|
190
214
|
start_freq: '390.000.000',
|
|
191
215
|
target_freq: '390.100.000',
|
|
192
216
|
demodulator_mode: 'RAW',
|
|
193
217
|
bandwidth: 50_000,
|
|
194
|
-
precision: 4
|
|
218
|
+
precision: 4,
|
|
219
|
+
overlap_protection: true
|
|
195
220
|
},
|
|
196
221
|
keyfob433: {
|
|
197
222
|
start_freq: '433.000.000',
|
|
198
223
|
target_freq: '434.000.000',
|
|
199
224
|
demodulator_mode: 'RAW',
|
|
200
225
|
bandwidth: 50_000,
|
|
201
|
-
precision: 4
|
|
226
|
+
precision: 4,
|
|
227
|
+
overlap_protection: true
|
|
202
228
|
},
|
|
203
229
|
keyfob868: {
|
|
204
230
|
start_freq: '868.000.000',
|
|
205
231
|
target_freq: '869.000.000',
|
|
206
232
|
demodulator_mode: 'RAW',
|
|
207
233
|
bandwidth: 50_000,
|
|
208
|
-
precision: 4
|
|
234
|
+
precision: 4,
|
|
235
|
+
overlap_protection: true
|
|
209
236
|
},
|
|
210
237
|
rtty20: {
|
|
211
238
|
start_freq: '14.000.000',
|
|
212
239
|
target_freq: '14.350.000',
|
|
213
240
|
demodulator_mode: 'RTTY',
|
|
214
241
|
bandwidth: 170,
|
|
215
|
-
precision: 3
|
|
242
|
+
precision: 3,
|
|
243
|
+
overlap_protection: true
|
|
216
244
|
},
|
|
217
245
|
rtty40: {
|
|
218
246
|
start_freq: '7.000.000',
|
|
219
247
|
target_freq: '7.300.000',
|
|
220
248
|
demodulator_mode: 'RTTY',
|
|
221
249
|
bandwidth: 170,
|
|
222
|
-
precision: 3
|
|
250
|
+
precision: 3,
|
|
251
|
+
overlap_protection: true
|
|
223
252
|
},
|
|
224
253
|
rtty80: {
|
|
225
254
|
start_freq: '3.500.000',
|
|
226
255
|
target_freq: '3.800.000',
|
|
227
256
|
demodulator_mode: 'RTTY',
|
|
228
257
|
bandwidth: 170,
|
|
229
|
-
precision: 3
|
|
258
|
+
precision: 3,
|
|
259
|
+
overlap_protection: true
|
|
230
260
|
},
|
|
231
261
|
ssb10: {
|
|
232
262
|
start_freq: '28.000.000',
|
|
233
263
|
target_freq: '29.700.000',
|
|
234
264
|
demodulator_mode: 'USB',
|
|
235
265
|
bandwidth: 2_700,
|
|
236
|
-
precision: 6
|
|
266
|
+
precision: 6,
|
|
267
|
+
overlap_protection: true
|
|
237
268
|
},
|
|
238
269
|
ssb12: {
|
|
239
270
|
start_freq: '24.890.000',
|
|
240
271
|
target_freq: '24.990.000',
|
|
241
272
|
demodulator_mode: 'USB',
|
|
242
273
|
bandwidth: 2_700,
|
|
243
|
-
precision: 6
|
|
274
|
+
precision: 6,
|
|
275
|
+
overlap_protection: true
|
|
244
276
|
},
|
|
245
277
|
ssb15: {
|
|
246
278
|
start_freq: '21.000.000',
|
|
247
279
|
target_freq: '21.450.000',
|
|
248
280
|
demodulator_mode: 'USB',
|
|
249
281
|
bandwidth: 2_700,
|
|
250
|
-
precision: 6
|
|
282
|
+
precision: 6,
|
|
283
|
+
overlap_protection: true
|
|
251
284
|
},
|
|
252
285
|
ssb17: {
|
|
253
286
|
start_freq: '18.068.000',
|
|
254
287
|
target_freq: '18.168.000',
|
|
255
288
|
demodulator_mode: 'USB',
|
|
256
289
|
bandwidth: 2_700,
|
|
257
|
-
precision: 6
|
|
290
|
+
precision: 6,
|
|
291
|
+
overlap_protection: true
|
|
258
292
|
},
|
|
259
293
|
ssb20: {
|
|
260
294
|
start_freq: '14.000.000',
|
|
261
295
|
target_freq: '14.350.000',
|
|
262
296
|
demodulator_mode: 'USB',
|
|
263
297
|
bandwidth: 2_700,
|
|
264
|
-
precision: 6
|
|
298
|
+
precision: 6,
|
|
299
|
+
overlap_protection: true
|
|
265
300
|
},
|
|
266
301
|
ssb40: {
|
|
267
302
|
start_freq: '7.000.000',
|
|
268
303
|
target_freq: '7.300.000',
|
|
269
304
|
demodulator_mode: 'LSB',
|
|
270
305
|
bandwidth: 2_700,
|
|
271
|
-
precision: 6
|
|
306
|
+
precision: 6,
|
|
307
|
+
overlap_protection: true
|
|
272
308
|
},
|
|
273
309
|
ssb80: {
|
|
274
310
|
start_freq: '3.500.000',
|
|
275
311
|
target_freq: '3.800.000',
|
|
276
312
|
demodulator_mode: 'LSB',
|
|
277
313
|
bandwidth: 2_700,
|
|
278
|
-
precision: 6
|
|
314
|
+
precision: 6,
|
|
315
|
+
overlap_protection: true
|
|
279
316
|
},
|
|
280
317
|
ssb160: {
|
|
281
318
|
start_freq: '1.800.000',
|
|
282
319
|
target_freq: '2.000.000',
|
|
283
320
|
demodulator_mode: 'LSB',
|
|
284
321
|
bandwidth: 2_700,
|
|
285
|
-
precision: 6
|
|
322
|
+
precision: 6,
|
|
323
|
+
overlap_protection: true
|
|
286
324
|
},
|
|
287
325
|
tempest: {
|
|
288
326
|
start_freq: '400.000.000',
|
|
289
327
|
target_freq: '430.000.000',
|
|
290
328
|
demodulator_mode: 'WFM',
|
|
291
329
|
bandwidth: 200_000,
|
|
292
|
-
precision: 4
|
|
330
|
+
precision: 4,
|
|
331
|
+
overlap_protection: false
|
|
293
332
|
},
|
|
294
333
|
uhf_rfid: {
|
|
295
334
|
start_freq: '860.000.000',
|
|
296
335
|
target_freq: '960.000.000',
|
|
297
336
|
demodulator_mode: 'RAW',
|
|
298
337
|
bandwidth: 100_000,
|
|
299
|
-
precision: 5
|
|
338
|
+
precision: 5,
|
|
339
|
+
overlap_protection: true
|
|
300
340
|
},
|
|
301
341
|
wifi24: {
|
|
302
342
|
start_freq: '2.400.000.000',
|
|
303
343
|
target_freq: '2.500.000.000',
|
|
304
344
|
demodulator_mode: 'RAW',
|
|
305
345
|
bandwidth: 200_000,
|
|
306
|
-
precision: 7
|
|
346
|
+
precision: 7,
|
|
347
|
+
overlap_protection: true
|
|
307
348
|
},
|
|
308
349
|
wifi5: {
|
|
309
350
|
start_freq: '5.150.000.000',
|
|
310
351
|
target_freq: '5.850.000.000',
|
|
311
352
|
demodulator_mode: 'RAW',
|
|
312
353
|
bandwidth: 200_000,
|
|
313
|
-
precision: 7
|
|
354
|
+
precision: 7,
|
|
355
|
+
overlap_protection: true
|
|
314
356
|
},
|
|
315
357
|
wifi6: {
|
|
316
358
|
start_freq: '5.925.000.000',
|
|
317
359
|
target_freq: '7.125.000.000',
|
|
318
360
|
demodulator_mode: 'RAW',
|
|
319
361
|
bandwidth: 200_000,
|
|
320
|
-
precision: 7
|
|
362
|
+
precision: 7,
|
|
363
|
+
overlap_protection: true
|
|
321
364
|
},
|
|
322
365
|
zigbee: {
|
|
323
366
|
start_freq: '2.405.000.000',
|
|
324
367
|
target_freq: '2.485.000.000',
|
|
325
368
|
demodulator_mode: 'RAW',
|
|
326
369
|
bandwidth: 200_000,
|
|
327
|
-
precision: 7
|
|
370
|
+
precision: 7,
|
|
371
|
+
overlap_protection: true
|
|
328
372
|
}
|
|
329
373
|
}
|
|
330
374
|
rescue StandardError => e
|
data/lib/pwn/sdr/gqrx.rb
CHANGED
|
@@ -231,55 +231,10 @@ module PWN
|
|
|
231
231
|
cmd: 'f'
|
|
232
232
|
)
|
|
233
233
|
|
|
234
|
-
# Start recording and decoding if decoder provided
|
|
235
|
-
decoder_module = nil
|
|
236
|
-
decoder_thread = nil
|
|
237
|
-
record_path = nil
|
|
238
|
-
if decoder
|
|
239
|
-
# Resolve decoder module via case statement for extensibility
|
|
240
|
-
case decoder
|
|
241
|
-
when :gsm
|
|
242
|
-
decoder_module = PWN::SDR::Decoder::GSM
|
|
243
|
-
else
|
|
244
|
-
raise "ERROR: Unknown decoder key: #{decoder}. Supported: :gsm"
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
# Ensure recording is off before starting
|
|
248
|
-
record_status = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'u RECORD')
|
|
249
|
-
gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'U RECORD 0', resp_ok: 'RPRT 0') if record_status == '1'
|
|
250
|
-
|
|
251
|
-
# Start recording
|
|
252
|
-
gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'U RECORD 1', resp_ok: 'RPRT 0')
|
|
253
|
-
|
|
254
|
-
# Prepare for decoder
|
|
255
|
-
start_time = Time.now
|
|
256
|
-
expected_filename = "gqrx_#{start_time.strftime('%Y%m%d_%H%M%S')}_#{current_freq_raw}.wav"
|
|
257
|
-
record_path = File.join(record_dir, expected_filename)
|
|
258
|
-
|
|
259
|
-
# Build partial gqrx_obj for decoder start
|
|
260
|
-
gqrx_obj_partial = {
|
|
261
|
-
gqrx_sock: gqrx_sock,
|
|
262
|
-
record_path: record_path,
|
|
263
|
-
frequency: current_freq,
|
|
264
|
-
bandwidth: bandwidth,
|
|
265
|
-
demodulator_mode: demodulator_mode
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
# Initialize and start decoder (module style: .start returns thread)
|
|
269
|
-
decoder_thread = decoder_module.start(
|
|
270
|
-
gqrx_obj: gqrx_obj_partial,
|
|
271
|
-
**decoder_opts
|
|
272
|
-
)
|
|
273
|
-
end
|
|
274
|
-
|
|
275
234
|
init_freq_hash = {
|
|
276
235
|
demod_mode_n_passband: demod_n_passband,
|
|
277
236
|
frequency: current_freq,
|
|
278
|
-
bandwidth: bandwidth
|
|
279
|
-
decoder: decoder,
|
|
280
|
-
decoder_module: decoder_module,
|
|
281
|
-
decoder_thread: decoder_thread,
|
|
282
|
-
record_path: record_path
|
|
237
|
+
bandwidth: bandwidth
|
|
283
238
|
}
|
|
284
239
|
|
|
285
240
|
unless suppress_details
|
|
@@ -314,21 +269,58 @@ module PWN
|
|
|
314
269
|
cmd: 'l BB_GAIN'
|
|
315
270
|
)
|
|
316
271
|
|
|
317
|
-
init_freq_hash =
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
272
|
+
init_freq_hash[:audio_gain_db] = audio_gain_db
|
|
273
|
+
init_freq_hash[:squelch_set] = current_squelch
|
|
274
|
+
init_freq_hash[:rf_gain] = rf_gain
|
|
275
|
+
init_freq_hash[:if_gain] = if_gain
|
|
276
|
+
init_freq_hash[:bb_gain] = bb_gain
|
|
277
|
+
init_freq_hash[:strength_db] = strength_db
|
|
278
|
+
|
|
279
|
+
# Start recording and decoding if decoder provided
|
|
280
|
+
decoder_module = nil
|
|
281
|
+
decoder_thread = nil
|
|
282
|
+
record_path = nil
|
|
283
|
+
if decoder
|
|
284
|
+
# Resolve decoder module via case statement for extensibility
|
|
285
|
+
case decoder
|
|
286
|
+
when :gsm
|
|
287
|
+
decoder_module = PWN::SDR::Decoder::GSM
|
|
288
|
+
else
|
|
289
|
+
raise "ERROR: Unknown decoder key: #{decoder}. Supported: :gsm"
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# Ensure recording is off before starting
|
|
293
|
+
record_status = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'u RECORD')
|
|
294
|
+
gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'U RECORD 0', resp_ok: 'RPRT 0') if record_status == '1'
|
|
295
|
+
|
|
296
|
+
# Start recording
|
|
297
|
+
gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'U RECORD 1', resp_ok: 'RPRT 0')
|
|
298
|
+
|
|
299
|
+
# Prepare for decoder
|
|
300
|
+
start_time = Time.now
|
|
301
|
+
expected_filename = "gqrx_#{start_time.strftime('%Y%m%d_%H%M%S')}_#{current_freq_raw}.wav"
|
|
302
|
+
record_path = File.join(record_dir, expected_filename)
|
|
303
|
+
|
|
304
|
+
# Build partial gqrx_obj for decoder start
|
|
305
|
+
gqrx_obj_partial = {
|
|
306
|
+
gqrx_sock: gqrx_sock,
|
|
307
|
+
record_path: record_path,
|
|
308
|
+
frequency: current_freq,
|
|
309
|
+
bandwidth: bandwidth,
|
|
310
|
+
demodulator_mode: demodulator_mode
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
# Initialize and start decoder (module style: .start returns thread)
|
|
314
|
+
decoder_thread = decoder_module.start(
|
|
315
|
+
gqrx_obj: gqrx_obj_partial,
|
|
316
|
+
**decoder_opts
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
init_freq_hash[:decoder] = decoder
|
|
320
|
+
init_freq_hash[:decoder_module] = decoder_module
|
|
321
|
+
init_freq_hash[:decoder_thread] = decoder_thread
|
|
322
|
+
init_freq_hash[:record_path] = record_path
|
|
323
|
+
end
|
|
332
324
|
end
|
|
333
325
|
|
|
334
326
|
init_freq_hash
|
|
@@ -347,6 +339,7 @@ module PWN
|
|
|
347
339
|
# target_freq: 'required - Target frequency of scan range',
|
|
348
340
|
# demodulator_mode: 'optional - Demodulator mode (e.g. WFM, AM, FM, USB, LSB, RAW, CW, RTTY / defaults to WFM)',
|
|
349
341
|
# bandwidth: 'optional - Bandwidth in Hz (Defaults to 200_000)',
|
|
342
|
+
# overlap_protection: 'optional - Boolean to enable/disable bandwidth overlap protection (defaults to false)',
|
|
350
343
|
# precision: 'optional - Frequency step precision (number of digits; defaults to 1)',
|
|
351
344
|
# lock_freq_duration: 'optional - Lock frequency duration in seconds (defaults to 0.04)',
|
|
352
345
|
# strength_lock: 'optional - Strength lock in dBFS (defaults to -70.0)',
|
|
@@ -360,6 +353,7 @@ module PWN
|
|
|
360
353
|
target_freq = opts[:target_freq]
|
|
361
354
|
demodulator_mode = opts[:demodulator_mode]
|
|
362
355
|
bandwidth = opts[:bandwidth] ||= 200_000
|
|
356
|
+
overlap_protection = opts[:overlap_protection] || false
|
|
363
357
|
precision = opts[:precision] ||= 1
|
|
364
358
|
lock_freq_duration = opts[:lock_freq_duration] ||= 0.04
|
|
365
359
|
strength_lock = opts[:strength_lock] ||= -70.0
|
|
@@ -370,8 +364,7 @@ module PWN
|
|
|
370
364
|
|
|
371
365
|
hz_start = start_freq.to_s.raw_hz
|
|
372
366
|
hz_target = target_freq.to_s.raw_hz
|
|
373
|
-
|
|
374
|
-
step_hz = [10**(precision - 1), (bandwidth.to_i / 4)].max
|
|
367
|
+
step_hz = 10**(precision - 1)
|
|
375
368
|
step = hz_start > hz_target ? -step_hz : step_hz
|
|
376
369
|
|
|
377
370
|
# Set demodulator mode & passband once
|
|
@@ -518,7 +511,7 @@ module PWN
|
|
|
518
511
|
current_strength = (strength_history.sum / strength_history.size).round(1)
|
|
519
512
|
|
|
520
513
|
print '.'
|
|
521
|
-
|
|
514
|
+
puts "#{hz.pretty_hz} => #{strength_db}"
|
|
522
515
|
|
|
523
516
|
candidate = { hz: hz, freq: hz.pretty_hz, strength: current_strength }
|
|
524
517
|
candidate_signals.push(candidate)
|
|
@@ -528,8 +521,13 @@ module PWN
|
|
|
528
521
|
# Previous max step_hz was actually the top of the signal
|
|
529
522
|
top_of_signal_hz = candidate_signals.map { |s| s[:hz] }.max - step_hz
|
|
530
523
|
|
|
531
|
-
|
|
532
|
-
|
|
524
|
+
skip_signal = false
|
|
525
|
+
prev_frequency = prev_freq_hash[:frequency].to_s.raw_hz
|
|
526
|
+
distance_from_prev_detected_freq_hz = (beg_of_signal_hz - prev_frequency).abs
|
|
527
|
+
half_bandwidth = (bandwidth / 2).to_i
|
|
528
|
+
skip_signal = true if distance_from_prev_detected_freq_hz < half_bandwidth && overlap_protection
|
|
529
|
+
puts "Prev Dect Freq: #{prev_frequency} | New Freq Edge: #{beg_of_signal_hz} | Distance from Prev Dect Freq: #{distance_from_prev_detected_freq_hz} Hz | Step Hz: #{step_hz} | Bandwidth: #{bandwidth} Hz | Half Bandwidth: #{half_bandwidth} Hz | Overlap Protection? #{overlap_protection} | Skip Signal? #{skip_signal}"
|
|
530
|
+
next if skip_signal
|
|
533
531
|
|
|
534
532
|
best_peak = find_best_peak.call(
|
|
535
533
|
beg_of_signal_hz: beg_of_signal_hz,
|
|
@@ -537,7 +535,7 @@ module PWN
|
|
|
537
535
|
)
|
|
538
536
|
|
|
539
537
|
if best_peak[:hz] && best_peak[:strength_db] > strength_lock
|
|
540
|
-
|
|
538
|
+
prev_freq_hash = init_freq(
|
|
541
539
|
gqrx_sock: gqrx_sock,
|
|
542
540
|
freq: best_peak[:hz],
|
|
543
541
|
demodulator_mode: demodulator_mode,
|
|
@@ -545,19 +543,19 @@ module PWN
|
|
|
545
543
|
squelch: squelch,
|
|
546
544
|
suppress_details: true
|
|
547
545
|
)
|
|
548
|
-
|
|
549
|
-
|
|
546
|
+
prev_freq_hash[:lock_freq_duration] = lock_freq_duration
|
|
547
|
+
prev_freq_hash[:strength_lock] = strength_lock
|
|
550
548
|
|
|
551
549
|
system_role_content = "Analyze signal data captured by a software-defined-radio using GQRX at the following location: #{location}. Respond with just FCC information about the transmission if available. If the frequency is unlicensed or not found in FCC records, state that clearly. Be clear and concise in your analysis."
|
|
552
550
|
ai_analysis = PWN::AI::Introspection.reflect_on(
|
|
553
|
-
request:
|
|
551
|
+
request: prev_freq_hash.to_json,
|
|
554
552
|
system_role_content: system_role_content,
|
|
555
553
|
suppress_pii_warning: true
|
|
556
554
|
)
|
|
557
|
-
|
|
555
|
+
prev_freq_hash[:ai_analysis] = ai_analysis unless ai_analysis.nil?
|
|
558
556
|
puts "\n**** Detected Signal ****"
|
|
559
|
-
puts JSON.pretty_generate(
|
|
560
|
-
signals_arr.push(
|
|
557
|
+
puts JSON.pretty_generate(prev_freq_hash)
|
|
558
|
+
signals_arr.push(prev_freq_hash)
|
|
561
559
|
end
|
|
562
560
|
candidate_signals.clear
|
|
563
561
|
sleep lock_freq_duration
|
|
@@ -637,6 +635,7 @@ module PWN
|
|
|
637
635
|
target_freq: 'required - Target frequency',
|
|
638
636
|
demodulator_mode: 'optional - Demodulator mode (e.g. WFM, AM, FM, USB, LSB, RAW, CW, RTTY / defaults to WFM)',
|
|
639
637
|
bandwidth: 'optional - Bandwidth in Hz (Defaults to 200_000)',
|
|
638
|
+
overlap_protection: 'optional - Boolean to enable/disable bandwidth overlap protection (defaults to false)',
|
|
640
639
|
precision: 'optional - Precision (Defaults to 1)',
|
|
641
640
|
lock_freq_duration: 'optional - Lock frequency duration in seconds (defaults to 0.04)',
|
|
642
641
|
strength_lock: 'optional - Strength lock (defaults to -70.0)',
|
data/lib/pwn/version.rb
CHANGED