8
8
import json
9
9
import logging
10
10
import random
11
+ import sys
11
12
12
13
import click
13
14
import zigpy .state
@@ -251,10 +252,19 @@ async def change_channel(app, channel):
251
252
)
252
253
@click .option ("-p" , "--channel-hop-period" , type = float , default = 5.0 )
253
254
@click .option ("-o" , "--output" , type = click .File ("wb" ), required = True )
255
+ @click .option ("--interleave" , is_flag = True , type = bool , default = False )
254
256
@click_coroutine
255
257
async def packet_capture (
256
- app , channel_hop_randomly , channels , channel_hop_period , output
258
+ app ,
259
+ channel_hop_randomly ,
260
+ channels ,
261
+ channel_hop_period ,
262
+ output ,
263
+ interleave ,
257
264
):
265
+ if output .name == "<stdout>" and not interleave :
266
+ output = sys .stdout .buffer .raw
267
+
258
268
if not channel_hop_randomly :
259
269
channels_iter = itertools .cycle (channels )
260
270
else :
@@ -270,8 +280,9 @@ def channels_iter_func():
270
280
271
281
await app .connect ()
272
282
273
- writer = PcapWriter (output )
274
- writer .write_header ()
283
+ if not interleave :
284
+ writer = PcapWriter (output )
285
+ writer .write_header ()
275
286
276
287
async with asyncio .TaskGroup () as tg :
277
288
channel_hopper_task = None
@@ -287,7 +298,21 @@ async def channel_hopper():
287
298
channel_hopper_task = tg .create_task (channel_hopper ())
288
299
289
300
LOGGER .debug ("Got a packet %s" , packet )
290
- writer .write_packet (packet )
291
301
292
- if output .name == "<stdout>" : # Surely there's a better way?
302
+ if not interleave :
303
+ writer .write_packet (packet )
304
+ else :
305
+ # To do line interleaving, encode the packets as JSON
306
+ output .write (
307
+ json .dumps (
308
+ {
309
+ "timestamp" : packet .timestamp .isoformat (),
310
+ "rssi" : packet .rssi ,
311
+ "lqi" : packet .lqi ,
312
+ "channel" : packet .channel ,
313
+ "data" : packet .data .hex (),
314
+ }
315
+ ).encode ("ascii" )
316
+ + b"\n "
317
+ )
293
318
output .flush ()
0 commit comments