88import json
99import logging
1010import random
11+ import sys
1112
1213import click
1314import zigpy .state
@@ -251,10 +252,19 @@ async def change_channel(app, channel):
251252)
252253@click .option ("-p" , "--channel-hop-period" , type = float , default = 5.0 )
253254@click .option ("-o" , "--output" , type = click .File ("wb" ), required = True )
255+ @click .option ("--interleave" , is_flag = True , type = bool , default = False )
254256@click_coroutine
255257async 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 ,
257264):
265+ if output .name == "<stdout>" and not interleave :
266+ output = sys .stdout .buffer .raw
267+
258268 if not channel_hop_randomly :
259269 channels_iter = itertools .cycle (channels )
260270 else :
@@ -270,8 +280,9 @@ def channels_iter_func():
270280
271281 await app .connect ()
272282
273- writer = PcapWriter (output )
274- writer .write_header ()
283+ if not interleave :
284+ writer = PcapWriter (output )
285+ writer .write_header ()
275286
276287 async with asyncio .TaskGroup () as tg :
277288 channel_hopper_task = None
@@ -287,7 +298,21 @@ async def channel_hopper():
287298 channel_hopper_task = tg .create_task (channel_hopper ())
288299
289300 LOGGER .debug ("Got a packet %s" , packet )
290- writer .write_packet (packet )
291301
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+ )
293318 output .flush ()
0 commit comments