■ ■ ■ ■ ■ ■
firmware/pycatsniffer/devpycatsniffer.py
| skipped 20 lines |
21 | 21 | | 'debug_level': 'WARNING', |
22 | 22 | | 'log_level': 'INFO', |
23 | 23 | | 'log_file': 'ccsniffpiper.log', |
24 | | - | 'channel': 11, |
| 24 | + | 'channel': 37, |
25 | 25 | | } |
26 | 26 | | |
27 | 27 | | logger = logging.getLogger(__name__) |
| skipped 6 lines |
34 | 34 | | initiator = bytearray([0x40, 0x53, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x40, 0x45]) |
35 | 35 | | letsgo = bytearray([0x40, 0x53, 0x41, 0x00, 0x00, 0x41, 0x40, 0x45]) |
36 | 36 | | |
| 37 | + | # channel:<frequency |
| 38 | + | channeldict = { |
| 39 | + | 37: [0x62, 0x09], |
| 40 | + | 38: [0x7a, 0x09], |
| 41 | + | 39: [0xb0, 0x09] |
| 42 | + | } |
37 | 43 | | |
38 | 44 | | class Frame(object): |
39 | 45 | | PCAP_FRAME_HDR_FMT = '<LLLL' |
| skipped 206 lines |
246 | 252 | | |
247 | 253 | | class CC1352: |
248 | 254 | | |
249 | | - | DEFAULT_CHANNEL = 0x0B # 11 |
250 | | - | |
251 | | - | DATA_EP = 0x83 |
252 | | - | DATA_TIMEOUT = 2500 |
253 | | - | |
254 | | - | DIR_OUT = 0x40 |
255 | | - | DIR_IN = 0xc0 |
256 | | - | |
257 | | - | GET_IDENT = 0xc0 |
258 | | - | SET_POWER = 0xc5 |
259 | | - | GET_POWER = 0xc6 |
| 255 | + | DEFAULT_CHANNEL = 0x25 # 371 |
260 | 256 | | |
261 | | - | SET_START = 0xd0 # bulk in starts |
262 | | - | SET_STOP = 0xd1 # bulk in stops |
263 | | - | SET_CHAN = 0xd2 # 0x0d (idx 0) + data)0x00 (idx 1) |
264 | | - | |
265 | | - | HEARTBEAT_FRAME = 0x01 |
266 | 257 | | START_FRAME = 0x5340 |
267 | 258 | | |
268 | | - | BYTE_STREAM = 0 |
269 | | - | |
270 | 259 | | def __init__(self, port, callback, channel=DEFAULT_CHANNEL): |
271 | 260 | | |
272 | 261 | | baudrate = 921600 |
| skipped 43 lines |
316 | 305 | | |
317 | 306 | | def initiatorc(self): |
318 | 307 | | self.serial_port.write(initiator) |
319 | | - | |
320 | | - | #def startc(self): |
321 | | - | # self.serial_port.write(letsgo) |
322 | | - | |
323 | 308 | | |
324 | 309 | | def startc(self): |
325 | 310 | | # start sniffing |
| skipped 23 lines |
349 | 334 | | if self.serial_port.in_waiting > 0: |
350 | 335 | | bytestream = self.serial_port.read(self.serial_port.in_waiting) |
351 | 336 | | |
352 | | - | # print ("RECV>> %s" % binascii.hexlify(bytestream)) |
| 337 | + | #print ("RECV>> %s" % binascii.hexlify(bytestream)) |
353 | 338 | | |
354 | 339 | | time.sleep(0.5) |
355 | 340 | | start_index = 0 |
| skipped 37 lines |
393 | 378 | | 'Received a command response with unknown code - CMD:{:02x} byte:{}' |
394 | 379 | | .format(cmd, substream)) |
395 | 380 | | |
396 | | - | #packet = self.parse_packet(substream) |
397 | | - | #if packet: |
398 | | - | #print("HELL O WORLD!") |
399 | | - | # self.callback(packet) |
400 | | - | |
401 | 381 | | # Set the start index to end_index + 2 (to skip over the 0x40 0x45 bytes) |
402 | 382 | | start_index = end_index + 2 |
403 | | - | |
404 | | - | |
405 | | - | #if bytestream[0:2] == bytes([0x40, 0x53]): |
406 | | - | # packet = self.parse_packet(bytestream) |
407 | | - | #if packet: |
408 | | - | # self.callback(packet) |
409 | 383 | | |
410 | 384 | | |
411 | 385 | | def set_channel(self, channel): |
412 | 386 | | was_running = self.running |
413 | 387 | | |
414 | | - | if channel >= 11 and channel <= 26: |
| 388 | + | if channel >= 37 and channel <= 39: |
415 | 389 | | if self.running: |
416 | 390 | | self.stop() |
417 | 391 | | |
418 | | - | self.channel = channel |
| 392 | + | chann = channeldict[channel] |
419 | 393 | | |
420 | | - | # set channel command |
421 | | - | #self.dev.ctrl_transfer(CC2531.DIR_OUT, CC2531.SET_CHAN, 0, 0, |
422 | | - | # [channel]) |
423 | | - | #self.dev.ctrl_transfer(CC2531.DIR_OUT, CC2531.SET_CHAN, 0, 1, |
424 | | - | # [0x00]) |
| 394 | + | cfgfreq[5:7] = bytearray(chann) |
| 395 | + | |
| 396 | + | #Add all bytes in these fields: Packet Info, Packet Length and Payload. |
| 397 | + | #AND the result from step 1 with 0xFF. |
| 398 | + | |
| 399 | + | fcs = 0 |
| 400 | + | for x in cfgfreq[2:-3]: |
| 401 | + | fcs = fcs + x |
| 402 | + | fcs = fcs & 0xFF |
| 403 | + | cfgfreq[-3] = fcs |
| 404 | + | |
| 405 | + | self.channel = channel |
425 | 406 | | |
426 | 407 | | self.get_channel() |
427 | 408 | | |
428 | 409 | | if was_running: |
429 | | - | self.start() |
| 410 | + | self.startc() |
430 | 411 | | |
431 | 412 | | else: |
432 | 413 | | raise ValueError("Channel must be between 11 and 26") |
| skipped 1 lines |
434 | 415 | | def get_channel(self): |
435 | 416 | | return self.channel |
436 | 417 | | |
437 | | - | def parse_packet(self, packet): |
438 | | - | |
439 | | - | #print("***HELL***") |
440 | | - | |
441 | | - | packetlen = packet[3:5] |
442 | | - | |
443 | | - | #if len(packet) - 3 != packetlen: |
444 | | - | # return None |
445 | | - | |
446 | | - | # unknown header produced by the radio chip |
447 | | - | header = packet[0:2] |
448 | | - | |
449 | | - | # the data in the payload |
450 | | - | payload = packet[11:-4] |
451 | | - | |
452 | | - | # length of the payload |
453 | | - | #payloadlen = packet[7] - 2 # without fcs |
454 | | - | |
455 | | - | #if len(payload) != payloadlen: |
456 | | - | # return None |
457 | | - | |
458 | | - | # current time |
459 | | - | timestamp = time.gmtime() |
460 | | - | |
461 | | - | # used to derive other values |
462 | | - | fcs1, fcs2 = packet[-4:-2] |
463 | | - | |
464 | | - | # rssi is the signed value at fcs1 |
465 | | - | rssi = (fcs1 + 2**7) % 2**8 - 2**7 - 73 |
466 | | - | |
467 | | - | # crc ok is the 7th bit in fcs2 |
468 | | - | crc_ok = fcs2 & (1 << 7) > 0 |
469 | | - | |
470 | | - | # correlation value is the unsigned 0th-6th bit in fcs2 |
471 | | - | corr = fcs2 & 0x7f |
472 | | - | |
473 | | - | return Packet(timestamp, self.channel, header, payload, rssi, crc_ok, corr) |
474 | | - | |
475 | | - | |
476 | | - | def __repr__(self): |
477 | | - | |
478 | | - | if self.dev: |
479 | | - | return "%s <Channel: %d>" % (self.name, self.channel) |
480 | | - | else: |
481 | | - | return "Not connected" |
482 | | - | |
483 | | - | class Packet: |
484 | | - | |
485 | | - | def __init__(self, timestamp, channel, header, payload, rssi, crc_ok, correlation): |
486 | | - | self.timestamp = timestamp |
487 | | - | self.channel = channel |
488 | | - | self.header = header |
489 | | - | self.payload = payload |
490 | | - | self.rssi = rssi |
491 | | - | self.crc_ok = crc_ok |
492 | | - | self.correlation = correlation |
493 | | - | |
494 | | - | def __repr__(self): |
495 | | - | |
496 | | - | ret = [] |
497 | | - | ret.append("Channel: %d" % self.channel) |
498 | | - | ret.append("Timestamp: %s" % time.strftime("%H:%M:%S", self.timestamp)) |
499 | | - | ret.append("Header: %s" % binascii.hexlify(self.header)) |
500 | | - | ret.append("RSSI: %d" % self.rssi) |
501 | | - | ret.append("CRC OK: %s" % self.crc_ok) |
502 | | - | ret.append("Correlation: %d" % self.correlation) |
503 | | - | ret.append("Payload: %s" % binascii.hexlify(self.payload)) |
504 | | - | |
505 | | - | return "\n".join(ret) |
506 | | - | |
507 | 418 | | def arg_parser(): |
508 | 419 | | debug_choices = ('DEBUG', 'INFO', 'WARNING', 'ERROR') |
509 | 420 | | |
| skipped 162 lines |
672 | 583 | | h.write('c: Print current RF Channel\n') |
673 | 584 | | h.write('n: Trigger new pcap header before the next frame\n') |
674 | 585 | | h.write('h,?: Print this message\n') |
675 | | - | h.write('[11,26]: Change RF channel\n') |
| 586 | + | h.write('[37,39]: Change RF channel\n') |
676 | 587 | | h.write('s: Start/stop the packet capture\n') |
677 | 588 | | h.write('q: Quit') |
678 | 589 | | h = h.getvalue() |
| skipped 44 lines |
723 | 634 | | if snifferDev.isRunning(): |
724 | 635 | | snifferDev.stop() |
725 | 636 | | else: |
| 637 | + | snifferDev.pingc() |
| 638 | + | snifferDev.stopc() |
| 639 | + | snifferDev.cfgphyc() |
| 640 | + | snifferDev.cfgfreqc() |
| 641 | + | snifferDev.initiatorc() |
726 | 642 | | snifferDev.startc() |
727 | | - | elif int(cmd) in range(11, 27): |
| 643 | + | print ("start") |
| 644 | + | elif int(cmd) in range(37, 40): |
728 | 645 | | snifferDev.set_channel(int(cmd)) |
| 646 | + | snifferDev.cfgfreqc() |
| 647 | + | #print(cfgfreq.hex()) |
729 | 648 | | else: |
730 | 649 | | raise ValueError |
731 | 650 | | # else: |
| skipped 12 lines |
744 | 663 | | snifferDev.stop() |
745 | 664 | | dump_stats() |
746 | 665 | | sys.exit(0) |
747 | | - | |
748 | | - | # if __name__ == "__main__": |
749 | | - | |
750 | | - | # def callback(packet): |
751 | | - | # print("-"*30) |
752 | | - | # print(packet) |
753 | | - | # print("-"*30) |
754 | | - | |
755 | | - | # sniffer = CC1352('/dev/ttyACM0', callback) |
756 | | - | # #sniffer = CC1352(callback) |
757 | | - | |
758 | | - | # #print(sniffer) |
759 | | - | # #sniffer.startc() |
760 | | - | # #sniffer.pingc() |
761 | | - | # #time.sleep(2) |
762 | | - | # #sniffer.stopc() |
763 | | - | |
764 | | - | # sniffer.pingc() |
765 | | - | # sniffer.stopc() |
766 | | - | # sniffer.cfgphyc() |
767 | | - | # sniffer.cfgfreqc() |
768 | | - | # sniffer.initiatorc() |
769 | | - | # sniffer.startc() |
770 | | - | # print ("start") |
771 | | - | # time.sleep(1) |
772 | | - | # sniffer.stop() |
773 | | - | # sniffer.close() |