Projects STRLCPY CatSniffer Commits c159a291
🤬
  • ■ ■ ■ ■ ■ ■
    firmware/pycatsniffer/devpycatsniffer.py
     1 +import serial
     2 +import time
     3 +import sys
     4 + 
     5 +import binascii
     6 +import threading
     7 +import logging.handlers
     8 +import struct
     9 + 
     10 +__version__ = '0.0.1'
     11 + 
     12 +defaults = {
     13 + 'hex_file': 'ccsniffpiper.hexdump',
     14 + 'out_fifo': '/tmp/ccsniffpiper',
     15 + 'pcap_file': 'ccsniffpiper.pcap',
     16 + 'debug_level': 'WARNING',
     17 + 'log_level': 'INFO',
     18 + 'log_file': 'ccsniffpiper.log',
     19 + 'channel': 11,
     20 +}
     21 + 
     22 +logger = logging.getLogger(__name__)
     23 +stats = {}
     24 + 
     25 +class CC1352:
     26 + 
     27 + DEFAULT_CHANNEL = 0x0B # 11
     28 + 
     29 + DATA_EP = 0x83
     30 + DATA_TIMEOUT = 2500
     31 + 
     32 + DIR_OUT = 0x40
     33 + DIR_IN = 0xc0
     34 + 
     35 + GET_IDENT = 0xc0
     36 + SET_POWER = 0xc5
     37 + GET_POWER = 0xc6
     38 + 
     39 + SET_START = 0xd0 # bulk in starts
     40 + SET_STOP = 0xd1 # bulk in stops
     41 + SET_CHAN = 0xd2 # 0x0d (idx 0) + data)0x00 (idx 1)
     42 + 
     43 + HEARTBEAT_FRAME = 0x01
     44 + COMMAND_FRAME = 0x00
     45 + 
     46 + def __init__(self, callback, port):
     47 + 
     48 + stats['Captured'] = 0
     49 + stats['Non-Frame'] = 0
     50 + 
     51 + self.callback = callback
     52 + self.thread = None
     53 + self.running = False
     54 + self.serial_port = serial.Serial(port, 921600, 8, 'N', 1, timeout=1)
     55 +
     56 + def close(self):
     57 + self.serial_port.close()
     58 + 
     59 + def start(self):
     60 + # start sniffing
     61 + self.running = True
     62 + #self.dev.ctrl_transfer(CC2531.DIR_OUT, CC2531.SET_START)
     63 + self.thread = threading.Thread(target=self.recv)
     64 + self.thread.daemon = True
     65 + self.thread.start()
     66 + 
     67 + def stop(self):
     68 + # end sniffing
     69 + self.running = False
     70 + self.thread.join()
     71 + #self.dev.ctrl_transfer(CC2531.DIR_OUT, CC2531.SET_STOP)
     72 + 
     73 + def isRunning(self):
     74 + return self.running
     75 + 
     76 + def recv(self):
     77 + 
     78 + while self.running:
     79 + 
     80 + if self.serial_port.in_waiting > 0:
     81 + bytesteam = self.serial_port.read(self.serial_port.in_waiting)
     82 + #print(bytesteam.hex())
     83 + print ("RECV>> %s" % binascii.hexlify(bytesteam))
     84 + 
     85 + if len(bytesteam) >= 3:
     86 + (cmd, cmdLen) = struct.unpack_from("<BH", bytesteam)
     87 + payload = bytesteam[3:]
     88 + if len(payload) == cmdLen:
     89 + # buffer contains the correct number of bytes
     90 + if CC1352.COMMAND_FRAME == cmd:
     91 + logger.info(f'Read a frame of size {cmdLen}')
     92 + stats['Captured'] += 1
     93 + (timestamp,
     94 + pktLen) = struct.unpack_from("<IB", payload)
     95 + frame = payload[5:]
     96 + 
     97 + if len(frame) == pktLen:
     98 + self.callback(timestamp, frame.tobytes())
     99 + else:
     100 + logger.warning(
     101 + f'Received a frame with incorrect length, pktLen:{pktLen}, len(frame):{len(frame)}'
     102 + )
     103 + 
     104 + # elif cmd == CC2531.COMMAND_CHANNEL:
     105 + # logger.info('Received a command response: [%02x %02x]' % (cmd, payload[0]))
     106 + # # We'll only ever see this if the user asked for it, so we are
     107 + # # running interactive.
     108 + elif CC1352.HEARTBEAT_FRAME == cmd:
     109 + logger.debug(f'Heartbeat - {payload[0]}')
     110 + else:
     111 + logger.warning(
     112 + 'Received a command response with unknown code - CMD:{:02x} byte:{}'
     113 + .format(cmd, bytesteam))
     114 + 
     115 + def set_channel(self, channel):
     116 + was_running = self.running
     117 + 
     118 + if channel >= 11 and channel <= 26:
     119 + if self.running:
     120 + self.stop()
     121 + 
     122 + self.channel = channel
     123 + 
     124 + # set channel command
     125 + #self.dev.ctrl_transfer(CC2531.DIR_OUT, CC2531.SET_CHAN, 0, 0,
     126 + # [channel])
     127 + #self.dev.ctrl_transfer(CC2531.DIR_OUT, CC2531.SET_CHAN, 0, 1,
     128 + # [0x00])
     129 + 
     130 + self.get_channel()
     131 + 
     132 + if was_running:
     133 + self.start()
     134 + 
     135 + else:
     136 + raise ValueError("Channel must be between 11 and 26")
     137 + 
     138 + def get_channel(self):
     139 + return self.channel
     140 + 
     141 + def __repr__(self):
     142 + 
     143 + if self.dev:
     144 + return "%s <Channel: %d>" % (self.name, self.channel)
     145 + else:
     146 + return "Not connected"
     147 + 
  • ■ ■ ■ ■ ■ ■
    firmware/pycatsniffer/pingcatsniffer.py
     1 +import serial
     2 +import time
     3 +import sys
     4 + 
     5 +ser = serial.Serial()
     6 +ser.port = '/dev/ttyACM0'
     7 +ser.baudrate = 921600
     8 +ser.bytesize = serial.EIGHTBITS
     9 +ser.parity = serial.PARITY_NONE
     10 +ser.stopbits = serial.STOPBITS_ONE
     11 +ser.timeout = 1
     12 + 
     13 +cmd = bytearray([0x40, 0x53, 0x40, 0x00, 0x00, 0x40, 0x40, 0x45])
     14 + 
     15 +time.sleep(1)
     16 +ser.open()
     17 + 
     18 +ser.write(cmd)
     19 + 
     20 +while(ser.in_waiting == 0):
     21 + pass
     22 +
     23 +time.sleep(0.01)
     24 +
     25 +if ser.in_waiting > 0:
     26 + msg = ser.read(ser.in_waiting)
     27 + print (msg.hex())
     28 +
     29 +ser.flush()
     30 +time.sleep(2)
     31 + 
     32 +ser.close()
     33 + 
     34 + 
Please wait...
Page is in error, reload to recover