3 #GoodFET SPI Flash Client
11 from GoodFETNRF import GoodFETNRF;
12 from intelhex import IntelHex;
15 regnames=["CONFIG","EN_AA","EN_RXADDR","SETUP_AW","SETUP_RET",
16 "RF_CH","RF_SETUP","STATUS","OBSERVE_TX","RPD",
17 "RX_ADDR_P0","RX_ADDR_P1","RX_ADDR_P2","RX_ADDR_P3","RX_ADDR_P4","RX_ADDR_P5",
19 "RX_PW_P0","RX_PW_P1","RX_PW_P2","RX_PW_P3","RX_PW_P4","RX_PW_P5",
21 "?","?","?","DYNPD","FEATURE","AGC_CONFIG","?","?",
22 "?","?","?","?","?","?","?","?"];
24 def printpacket(packet):
29 if i>client.packetlen: break;
30 s="%s %02x" % (s,ord(foo));
36 def printmspacket(packet,offset=1):
37 """Decodes a Microsoft keyboard packet and maintains the typed strings."""
38 global mskbstring, oldseq;
39 keyword=client.RF_getsmac();
40 #print "keyword=%010x" % key;
43 for foo in range(0,5):
44 key.append(keyword&0xFF);
46 #print "Keybyte %02x" % key[foo];
52 ct.append(ord(foo)^key[(i+offset)%5]);
53 s="%s %02x" % (s,ord(foo)^key[(i+offset)%5]);
56 s="%s %02x" % (s,ord(foo));
58 #Uncomment this to print the raw packet, kinda noisy.
63 if ct[0]==0x0a and ct[1]==0x78 and seq!=oldseq:
65 #TODO replace this with a dictionary, and support modifiers.
67 #Key up event, not worth logging.
69 elif ct[9]>=4 and ct[9]<0x1E:
70 letter=ct[9]+ord('A')-4;
71 elif ct[9]>=0x1E and ct[9]<0x27:
72 letter=ct[9]+ord('1')-0x1E;
91 print "Unknown character 0x%02x." % ct[9];
94 mskbstring="%s%c" % (mskbstring,letter);
95 print "# %s" % mskbstring
97 print "Encoding %s" % client.RF_getenc();
98 print "Freq %10i MHz" % (client.RF_getfreq()/10**6);
99 print "Rate %10i kbps" % (client.RF_getrate()/1000);
100 print "PacketLen %02i bytes" % client.RF_getpacketlen();
101 #print "MacLen %2i bytes" % client.RF_getmaclen();
102 print "SMAC 0x%010x" % client.RF_getsmac();
103 print "TMAC 0x%010x" % client.RF_gettmac();
106 if(len(sys.argv)==1):
107 print "Usage: %s verb [objects]\n" % sys.argv[0];
108 print "%s info" % sys.argv[0];
109 print "%s test" % sys.argv[0];
110 print "%s regs" % sys.argv[0];
111 print "%s regbits" % sys.argv[0];
112 print "%s pyregs" % sys.argv[0];
114 print "%s tune aa|55,mac,r5,r6\n\tTunes to a configuration." % sys.argv[0];
115 print "%s sniff\n\tSniffs packets by current config." % sys.argv[0];
116 print "%s sniffob\n\tSniffs OpenBeacon traffic." % sys.argv[0];
117 print "%s snifftp\n\tSniffs Turning Point Clicker traffic." % sys.argv[0];
118 print "%s sniffsf\n\tSniffs SparkFun Dongle traffic." % sys.argv[0];
119 print "%s sniffmskb\n\tSniffs Microsoft Keyboard traffic." % sys.argv[0];
121 print "%s sniffmacs \n\tSniffs for MAC addresses on the present channel." % sys.argv[0];
122 print "%s sniffprom [0xaa|0x55]\n\tSniffs promiscuously for a preamble of 0xAA or 0x55" % sys.argv[0];
123 print "%s autotune\n\tSearches for a valid destination address." % sys.argv[0];
125 print "%s carrier [freq]\n\tHolds a carrier on [freq] Hz." % sys.argv[0];
128 #Initialize FET and set baud rate
134 if(sys.argv[1]=="info"):
137 if(sys.argv[1]=="test"):
138 print "Old registers:"
141 # Set PWR_UP=1 and PRIM_RX=0 in CONFIG.
143 #Delay of 1.5ms by round-trip.
148 for foo in [250*10**3,
151 client.RF_setrate(foo);
152 if(client.RF_getrate()!=foo):
153 print "ERROR Rate %i not supported. Got %i instead." % (
155 client.RF_getrate());
158 client.poke(0x0A,0xDEADBEEF,5);
159 #print "SMAC set to %010x" % client.RF_getsmac();
160 if client.RF_getsmac()!=0xdeadbeef:
161 print "ERROR: Failed to set MAC address.";
162 print "Final registers:"
165 if(sys.argv[1]=="carrier"):
167 client.RF_setfreq(eval(sys.argv[2]));
170 print "\nHolding a carrier wave.";
174 if(sys.argv[1]=="tune"):
176 client.tune(sys.argv[2]);
178 print "Specify a tuning, such as 'aa,c78c65805e,14,09'";
179 if(sys.argv[1]=="regs"):
180 for r in range(0,0x20):
181 print "r[0x%02x]=0x%010x //%16s " % (r,client.peek(r),regnames[r]);
182 if(sys.argv[1]=="pyregs"):
183 for r in range(0,0x20):
184 print "client.set(0x%02x,0x%010x); #%16s " % (r,client.peek(r),regnames[r]);
186 if(sys.argv[1]=="peek"):
189 start=int(sys.argv[2],16);
192 stop=int(sys.argv[3],16);
193 print "Peeking from %02x to %02x." % (start,stop);
195 print "%02x: %010x" % (start,client.peek(start));
197 if(sys.argv[1]=="poke"):
201 start=int(sys.argv[2],16);
203 val=int(sys.argv[3],16);
204 print "Poking %02x to become %010x." % (start,val);
206 client.poke(start,val);
207 print "Poked to %04x" % client.peek(start);
209 if(sys.argv[1]=="sniffob"):
210 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
211 #TODO remove all poke() calls.
213 client.poke(0x00,0x00); #Stop nRF
214 client.poke(0x01,0x00); #Disable Shockburst
215 client.poke(0x02,0x01); #Set RX Pipe 0
217 client.RF_setfreq(2481 * 10**6);
218 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
219 client.poke(0x07,0x78); #Reset status register
221 #OpenBeacon defines these in little endian as follows.
222 client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
223 #0x01, 0x02, 0x03, 0x02, 0x01
224 client.RF_setsmac(0x0102030201);
225 #'O', 'C', 'A', 'E', 'B'
226 client.RF_settmac(0x424541434F);
228 #Set packet length of 16.
229 client.RF_setpacketlen(16);
231 #Power radio, prime for RX, one-byte checksum.
232 client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
234 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
235 client.RF_getfreq()/10**6);
236 #Now we're ready to get packets.
241 packet=client.RF_rxpacket();
245 if(sys.argv[1]=="regbits"):
246 print "Scanning registers to determine which bits are valid."
247 regbits=range(0,0x30);
248 for r in range(0,0x30):
250 #Which bits can be set?
253 #Which bits can be clear?
255 zeroes=client.peek(r);
256 regbits[r]=(ones & (~zeroes));
257 for r in range(0,0x30):
259 print "r[0x%02x] masked %02x // %s" % (r,regbits[r], regnames[r]);
260 if(sys.argv[1]=="sniffprom"):
261 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
262 #TODO remove all poke() calls.
264 client.poke(0x00,0x00); #Stop nRF
265 client.poke(0x01,0x00); #Disable Shockburst
266 client.poke(0x02,0x01); #Set RX Pipe 0
268 #client.RF_setfreq(2481 * 10**6);
269 #client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
270 client.poke(0x07,0x78); #Reset status register
272 #OpenBeacon defines these in little endian as follows.
273 client.RF_setmaclen(2); # SETUP_AW for shortest
275 #It's better to have a known fragment, when one is available.
276 #client.RF_setsmac(0x00AA);
277 #client.RF_setsmac(0x0055);
279 #Should end in 55 or AA depending upon the packet.
282 tail=int(sys.argv[2],16);
284 print "Please specify a tail of 0xAA or 0x55.";
286 client.RF_setsmac(tail);
289 client.RF_setpacketlen(32);
291 #Power radio, prime for RX, no checksum
292 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
294 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
295 client.RF_getfreq()/10**6);
296 #Now we're ready to get packets.
301 packet=client.RF_rxpacket();
306 """This guesses addresses by searching through packets."""
310 #Limits on search space, because you usually know what you're looking for.
316 startch=0; #Useful for forcing an early match.
317 def init(self,goodfet,
318 rate=True,chan=True,sync=True, macreject=True, printing=False):
319 """Initializes a link to the GoodFET for autotuning."""
324 self.macreject=macreject;
325 self.printing=printing;
327 client.poke(0x00,0x00); #Stop nRF
328 client.poke(0x01,0x00); #Disable Shockburst
329 client.poke(0x02,0x01); #Set RX Pipe 0
332 client.poke(0x1C,0x00);
333 client.poke(0x1D,0x00);
335 client.RF_setmaclen(2); # SETUP_AW for shortest
338 #client.RF_setsmac(0x00AA);
339 #client.RF_setsmac(0x0055);
341 client.poke(0x00,0x70|0x03); #prime radio.
344 def packetaddr(self,packet,justmac=False):
345 """Returns a loaded packet address, including channel and rate."""
347 sync=self.client.RF_getsmac()&0xFF;
352 mac="%s%02x" % (mac,ord(packet[i]));
355 ch=self.client.peek(0x05);
356 rate=self.client.peek(0x06);
357 return "%02x,%s,%02x,%02x" % (
359 def validmac(self,packet):
360 sync=self.client.RF_getsmac()&0xFF;
361 mac=self.packetaddr(packet,justmac=True);
363 #BT preamble is A or 5.
364 #Fix this to work on the smallest bit, not the highest.
365 if ((ord(packet[0])&0x80)^(sync&0x80)) and self.macreject:
366 #print "%02x%02x invalid entry." % (sync,ord(packet[0]));
367 #This is a special kind of failure. Freq is probably right, but MAC is wrong.
369 if mac=='5555555555' or mac=='aaaaaaaaaa' or mac=='0000000000' or mac=='ffffffffff':
373 def handle(self,packet):
374 """Handles a packet."""
378 if not self.validmac(packet):
379 #print "Dropped packet from %s" % self.packetaddr(packet,justmac=True);
380 #printpacket(packet);
383 addr=self.packetaddr(packet);
385 #Increment the address count.
388 count=self.addresses[addr];
391 self.addresses[addr]=count+1;
392 rate=count*1.0/len(self.addresses);
393 if self.addresses[addr]>1 or rate>0.01:
394 print "'%s' looks valid\t%i\t%0.5f" % (
398 def selftune(self,threshold=2,forever=False,
400 """Tunes to the first strong signal.
401 It's important that this not get triggered by false positives."""
405 start=time.mktime(time.localtime());
407 while (time.mktime(time.localtime())-start) < delay:
410 packet=client.RF_rxpacket();
411 addr=guesser.handle(packet);
413 count=self.addresses[addr];
416 if count>threshold and forever==False:
423 """Tunes to another channel or preamble looking for the next packet."""
424 count=self.tunecount;
425 self.tunecount=count+1;
427 #Swap the SYNC value most often.
432 self.client.RF_setsmac(sync);
439 #This swaps between 1Mbps and 2Mbps.
440 #TODO add support for 256kbps, if anyone uses it.
443 #print "Setting rate to 0x%02x" % rate;
446 self.client.poke(0x06,rate);
450 self.client.poke(0x05,
451 (count+self.startch)&0x7f);
452 print "Tuned to %i MHz" % (
453 self.client.RF_getfreq()
455 #Grab two packets to clear buffers.
456 #Should retune only after a few packets to reduce this delay.
457 packet=client.RF_rxpacket();
458 packet=client.RF_rxpacket();
462 if(sys.argv[1]=="autotune"):
463 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
464 #TODO remove all poke() calls.
466 guesser.init(client,rate=True,sync=True,chan=True);
469 #client.RF_setfreq(2481 * 10**6);
470 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
471 client.poke(0x07,0x78); #Reset status register
473 #This is determined by the MAC, which we don't yet know.
476 client.RF_setpacketlen(32);
478 #Power radio, prime for RX, no checksum
479 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
481 print "Autotuning on %i MHz" % (
482 client.RF_getfreq()/10**6);
483 print "sync,mac,r5,r6";
484 #Now we're ready to get packets.
485 guesser.selftune(threshold=2,
488 if(sys.argv[1]=="autotunebt"):
489 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
490 #TODO remove all poke() calls.
492 guesser.init(client,rate=True,sync=False,chan=True,
493 macreject=False, printing=True);
496 #client.RF_setfreq(2481 * 10**6);
497 client.poke(0x06,0x00); #1MBps
498 client.poke(0x07,0x78); #Reset status register
500 #Bluetooth preamble is 0xA; BTLE is 0xAA.
501 client.RF_setsmac(0x000A);
504 client.RF_setpacketlen(32);
506 #Power radio, prime for RX, no checksum
507 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
509 print "Autotuning on %i MHz" % (
510 client.RF_getfreq()/10**6);
511 print "sync,mac,r5,r6";
512 #Now we're ready to get packets.
513 guesser.selftune(threshold=2,
516 if(sys.argv[1]=="sniffmacs"):
517 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
518 #TODO remove all poke() calls.
520 guesser.init(client,rate=False,sync=True,chan=False);
523 client.RF_setpacketlen(32);
525 #Power radio, prime for RX, no checksum
526 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
528 print "Holding autotune on %i MHz" % (
529 client.RF_getfreq()/10**6);
530 print "sync,mac,r5,r6";
531 #Now we're ready to get packets.
532 guesser.selftune(threshold=2,
535 if(sys.argv[1]=="sniffmskb"):
537 #TODO remove all poke() calls.
539 client.poke(0x00,0x00); #Stop nRF
540 client.poke(0x01,0x00); #Disable Shockburst
541 client.poke(0x02,0x01); #Set RX Pipe 0
543 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
544 client.poke(0x07,0x78); #Reset status register
546 #This is the address of a specific keyboard.
547 #Other keyboards will be different.
549 client.RF_setmaclen(5);
551 #Known pairs. The channel and the low address bytes must match.
552 #client.RF_setfreq((2400+0x13) * 10**6);
553 #client.RF_setsmac(0xc00a3598cd);
555 #client.RF_setfreq((2400+0x15) * 10**6);
556 #client.RF_setsmac(0xc10446facd);
558 #Mac packet length, illegally 0-length address field.
559 client.RF_setpacketlen(16);
563 client.tune(sys.argv[2]);
566 print "Searching for a keyboard.";
569 guesser.init(client, rate=False, sync=True, chan=True);
570 guesser.selftune(threshold=4,forever=False,
573 client.poke(0x00,0x00); #Stop nRF
574 client.poke(0x01,0x00); #Disable Shockburst
575 client.poke(0x02,0x01); #Set RX Pipe 0
576 client.RF_setmaclen(5);
578 #Finally, dynamic payload lengths need to be enabled.
579 #client.poke(0x01,0x01);
580 client.poke(0x1C,0x01);
581 client.poke(0x1D,0x06);
583 client.poke(0x00,0x70|0x03); #prime radio.
584 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
585 client.RF_getfreq()/10**6);
586 #Now we're ready to get packets.
591 packet=client.RF_rxpacket();
593 printmspacket(packet);
596 if(sys.argv[1]=="sniffant"):
597 #Prototyped on Garmin device.
598 #Channel hopping is pretty damned fast, hard to follow.
599 #This doesn't really work yet, still experimenting.
601 #Might be more effective to sniff knowing the MFG ID and Dev. ID,
602 #as these predict a lot of the MAC address.
604 client.poke(0x00,0x00); #Stop nRF
605 client.poke(0x01,0x00); #Disable Shockburst
606 client.poke(0x02,0x01); #Set RX Pipe 0
608 client.poke(0x05,57); #broadcast-only channel
609 client.poke(0x06,0x00); #1MBps
610 client.poke(0x07,0x78); #Reset status register
612 #Is this appropriate? Might be 3.
613 client.RF_setmaclen(5);
616 #Mac packet length, illegally 0-length address field.
617 client.RF_setpacketlen(16);
620 client.tune(sys.argv[2]);
623 print "Searching for ANT+.";
626 guesser.init(client, rate=False, sync=True, chan=True);
627 guesser.selftune(threshold=2,forever=False,
630 client.poke(0x00,0x00); #Stop nRF
631 client.poke(0x01,0x00); #Disable Shockburst
632 client.poke(0x02,0x01); #Set RX Pipe 0
633 client.RF_setmaclen(5);
636 client.poke(0x00,0x70|0x03); #prime radio.
637 print "Dumping ANT as %010x on %i MHz" % (client.RF_getsmac(),
638 client.RF_getfreq()/10**6);
639 #Now we're ready to get packets.
644 packet=client.RF_rxpacket();
652 if(sys.argv[1]=="sniffsf"):
653 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
654 #TODO remove all poke() calls.
656 client.poke(0x00,0x00); #Stop nRF
657 client.poke(0x01,0x00); #Disable Shockburst
658 client.poke(0x02,0x01); #Set RX Pipe 0
660 client.RF_setfreq(2402 * 10**6);
661 client.poke(0x06,0x07); #1Mbps
662 client.poke(0x07,0x78); #Reset status register
664 #OpenBeacon defines these in little endian as follows.
665 client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
666 client.RF_setsmac(0xe7e7e7e7e7);
667 client.RF_settmac(0xe7e7e7e7e7);
669 #Set packet length of 16.
670 client.RF_setpacketlen(4);
672 #Power radio, prime for RX, one-byte checksum.
673 client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
675 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
676 client.RF_getfreq()/10**6);
677 #Now we're ready to get packets.
682 packet=client.RF_rxpacket();
686 if(sys.argv[1]=="sniffnike"):
687 #TODO remove all poke() calls.
689 client.poke(0x00,0x00); #Stop nRF
690 client.poke(0x01,0x00); #Disable Shockburst
691 client.poke(0x02,0x01); #Set RX Pipe 0
693 client.RF_setfreq(2425 * 10**6);
694 client.poke(0x06,0x20|0x06); #250 kbps
695 client.poke(0x07,0x78); #Reset status register
698 client.RF_setmaclen(2); # Illegal by datasheet, but it works!
699 client.RF_setsmac(0xc2bd);
700 client.RF_settmac(0xc2bd); #Should we forge data?
702 client.RF_setpacketlen(32); #No idea what the length is.
704 #Power radio, prime for RX, two-byte checksum.
705 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two bytes.
707 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
708 client.RF_getfreq()/10**6);
709 print "Expect some false-positives.";
711 #Now we're ready to get packets.
716 packet=client.RF_rxpacket();
720 if(sys.argv[1]=="snifftp"):
721 client.poke(0x00,0x00); #Stop nRF
722 client.poke(0x01,0x00); #Disable Shockburst
723 client.poke(0x02,0x01); #Set RX Pipe 0
726 client.poke(0x1C,0x00);
727 client.poke(0x1D,0x00);
729 client.RF_setfreq((2400+0x29) * 10**6);
730 client.poke(0x06,0x00); #1Mbps
731 client.poke(0x07,0x78); #Reset status register
733 client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
734 client.RF_setsmac(0x123456);
735 client.RF_setpacketlen(4);
737 #Power radio, prime for RX, two-byte checksum.
738 client.poke(0x00,0x70|0x03|0x04|0x08);
740 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
741 client.RF_getfreq()/10**6);
742 #Now we're ready to get packets.
747 packet=client.RF_rxpacket();
752 if(sys.argv[1]=="sniff"):
754 print "Set MAC to %s" % sys.argv[2];
755 client.tune(sys.argv[2]);
756 client.RF_setmaclen(5);
758 #client.poke(0x00,0x00); #Stop nRF
759 client.poke(0x07,0x78); #Reset status register
761 #Power radio, prime for RX, no checksum.
762 client.poke(0x00,0x70|0x03);
764 client.RF_setpacketlen(32);
766 #client.RF_setmaclen(3); # SETUP_AW for shortest
768 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
769 client.RF_getfreq()/10**6);
770 #Now we're ready to get packets.
776 packet=client.RF_rxpacket();
779 if(sys.argv[1]=="explore"):
780 #client.poke(0x00,0x00); #Stop nRF
781 client.poke(0x07,0x78); #Reset status register
783 #Power radio, prime for RX, no checksum.
784 client.poke(0x00,0x70|0x03);
786 #Set packet length of 32.
787 #Without checksums, extra data will mix in.
788 client.RF_setpacketlen(32);
789 client.RF_setmaclen(3); # shortest address length
791 #Now we're ready to get packets.
792 for smac in [0x0102030201, 0]:
793 client.RF_setsmac(smac);
794 for chan in range(0,0x80):
795 client.RF_setfreq((2400+chan) * 10**6);
797 packet=client.RF_rxpacket();
799 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
800 client.RF_getfreq()/10**6);