#!/usr/bin/env python
import sys
import signal
import os, tempfile

from killerbee import *

def usage():
    print >>sys.stderr, """
zbwireshark - sends IEEE 802.15.4 packets to Wireshark via a named pipe

Usage: zbwireshark [-fiwDchp] [-f channel] [-i devnumstring] [-p]
    """

def show_dev():
    print "Dev\tProduct String\tSerial Number"
    for dev in kbutils.devlist():
        print "%s\t%s\t%s" % (dev[0], dev[1], dev[2])

def interrupt(signum, frame):
    global packetcount
    global kb
    global pd
    global pipefname
    global tempdir
    kb.sniffer_off()
    kb.close()
    pd.close()
    os.remove(pipefname)
    os.rmdir(tempdir)
    print "%d packets captured" % packetcount
    sys.exit(0)

pipename = 'zbwireshark'
# Command-line arguments
arg_channel = None
arg_devstring = None
arg_count = -1
arg_ppi = False

# Global
packetcount = 0

while len(sys.argv) > 1:
    op = sys.argv.pop(1)
    if op == '-f':
        arg_channel = int(sys.argv.pop(1))
    elif op == '-i':
        arg_devstring = sys.argv.pop(1)
    elif op == '-h':
        usage()
        sys.exit(0)
    elif op == '-D':
        show_dev()
        sys.exit(0)
    elif op == '-c':
        arg_count = int(sys.argv.pop(1))
    elif op == '-p':
        arg_ppi = True
 
if arg_channel == None:
    print >>sys.stderr, "ERROR: Must specify a channel with -f"
    usage()
    sys.exit(1)
elif arg_channel < 11 or arg_channel > 26:
    print >>sys.stderr, "ERROR: Must specify a valid IEEE 802.15.4 channel between 11 and 26."
    sys.exit(1)
rf_freq_mhz = (arg_channel - 10) * 5 + 2400

# Make FIFO (named pipe)
tempdir = tempfile.mkdtemp()
pipefname = os.path.join(tempdir, pipename)
print "Point Wireshark to read from the pipe file:", pipefname
try:
    os.mkfifo(pipefname) #default mode 0666 (octal)
except OSError, e:
    print "Failed to create FIFO: %s" % e

pd = PcapDumper(DLT_IEEE802_15_4, pipefname, ppi=arg_ppi)

# Start KillerBee
kb = KillerBee(device=arg_devstring)
signal.signal(signal.SIGINT, interrupt)

kb.set_channel(arg_channel)
kb.sniffer_on()

print "zbwireshark: listening on \'%s\', sending to \'%s\'" % (kb.get_dev_info()[0], pipefname)

while arg_count != packetcount:
    packet = kb.pnext()
    if packet != None:
        packetcount+=1
        pd.pcap_dump(packet['bytes'], ant_dbm=packet['dbm'], freq_mhz=rf_freq_mhz)

interrupt(0, 0) #shutdown and exit
