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." % (foo,
154 client.RF_getrate());
157 client.poke(0x0A,0xDEADBEEF,5);
158 #print "SMAC set to %010x" % client.RF_getsmac();
159 if client.RF_getsmac()!=0xdeadbeef:
160 print "ERROR: Failed to set MAC address.";
161 print "Final registers:"
164 if(sys.argv[1]=="carrier"):
166 client.RF_setfreq(eval(sys.argv[2]));
169 print "\nHolding a carrier wave.";
173 if(sys.argv[1]=="tune"):
175 client.tune(sys.argv[2]);
177 print "Specify a tuning, such as 'aa,c78c65805e,14,09'";
178 if(sys.argv[1]=="regs"):
179 for r in range(0,0x20):
180 print "r[0x%02x]=0x%010x //%16s " % (r,client.peek(r),regnames[r]);
181 if(sys.argv[1]=="pyregs"):
182 for r in range(0,0x20):
183 print "client.set(0x%02x,0x%010x); #%16s " % (r,client.peek(r),regnames[r]);
185 if(sys.argv[1]=="peek"):
188 start=int(sys.argv[2],16);
191 stop=int(sys.argv[3],16);
192 print "Peeking from %02x to %02x." % (start,stop);
194 print "%02x: %010x" % (start,client.peek(start));
196 if(sys.argv[1]=="poke"):
200 start=int(sys.argv[2],16);
202 val=int(sys.argv[3],16);
203 print "Poking %02x to become %010x." % (start,val);
205 client.poke(start,val);
206 print "Poked to %04x" % client.peek(start);
208 if(sys.argv[1]=="sniffob"):
209 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
210 #TODO remove all poke() calls.
212 client.poke(0x00,0x00); #Stop nRF
213 client.poke(0x01,0x00); #Disable Shockburst
214 client.poke(0x02,0x01); #Set RX Pipe 0
216 client.RF_setfreq(2481 * 10**6);
217 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
218 client.poke(0x07,0x78); #Reset status register
220 #OpenBeacon defines these in little endian as follows.
221 client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
222 #0x01, 0x02, 0x03, 0x02, 0x01
223 client.RF_setsmac(0x0102030201);
224 #'O', 'C', 'A', 'E', 'B'
225 client.RF_settmac(0x424541434F);
227 #Set packet length of 16.
228 client.RF_setpacketlen(16);
230 #Power radio, prime for RX, one-byte checksum.
231 client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
233 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
234 client.RF_getfreq()/10**6);
235 #Now we're ready to get packets.
240 packet=client.RF_rxpacket();
244 if(sys.argv[1]=="regbits"):
245 print "Scanning registers to determine which bits are valid."
246 regbits=range(0,0x30);
247 for r in range(0,0x30):
249 #Which bits can be set?
252 #Which bits can be clear?
254 zeroes=client.peek(r);
255 regbits[r]=(ones & (~zeroes));
256 for r in range(0,0x30):
258 print "r[0x%02x] masked %02x // %s" % (r,regbits[r], regnames[r]);
259 if(sys.argv[1]=="sniffprom"):
260 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
261 #TODO remove all poke() calls.
263 client.poke(0x00,0x00); #Stop nRF
264 client.poke(0x01,0x00); #Disable Shockburst
265 client.poke(0x02,0x01); #Set RX Pipe 0
267 #client.RF_setfreq(2481 * 10**6);
268 #client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
269 client.poke(0x07,0x78); #Reset status register
271 #OpenBeacon defines these in little endian as follows.
272 client.RF_setmaclen(2); # SETUP_AW for shortest
274 #It's better to have a known fragment, when one is available.
275 #client.RF_setsmac(0x00AA);
276 #client.RF_setsmac(0x0055);
278 #Should end in 55 or AA depending upon the packet.
281 tail=int(sys.argv[2],16);
283 print "Please specify a tail of 0xAA or 0x55.";
285 client.RF_setsmac(tail);
288 client.RF_setpacketlen(32);
290 #Power radio, prime for RX, no checksum
291 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
293 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
294 client.RF_getfreq()/10**6);
295 #Now we're ready to get packets.
300 packet=client.RF_rxpacket();
305 """This guesses addresses by searching through packets."""
309 #Limits on search space, because you usually know what you're looking for.
315 startch=0; #Useful for forcing an early match.
316 def init(self,goodfet,
317 rate=True,chan=True,sync=True, macreject=True, printing=False):
318 """Initializes a link to the GoodFET for autotuning."""
323 self.macreject=macreject;
324 self.printing=printing;
326 client.poke(0x00,0x00); #Stop nRF
327 client.poke(0x01,0x00); #Disable Shockburst
328 client.poke(0x02,0x01); #Set RX Pipe 0
331 client.poke(0x1C,0x00);
332 client.poke(0x1D,0x00);
334 client.RF_setmaclen(2); # SETUP_AW for shortest
337 #client.RF_setsmac(0x00AA);
338 #client.RF_setsmac(0x0055);
340 client.poke(0x00,0x70|0x03); #prime radio.
343 def packetaddr(self,packet,justmac=False):
344 """Returns a loaded packet address, including channel and rate."""
346 sync=self.client.RF_getsmac()&0xFF;
351 mac="%s%02x" % (mac,ord(packet[i]));
354 ch=self.client.peek(0x05);
355 rate=self.client.peek(0x06);
356 return "%02x,%s,%02x,%02x" % (
358 def validmac(self,packet):
359 sync=self.client.RF_getsmac()&0xFF;
360 mac=self.packetaddr(packet,justmac=True);
362 #BT preamble is A or 5.
363 #Fix this to work on the smallest bit, not the highest.
364 if ((ord(packet[0])&0x80)^(sync&0x80)) and self.macreject:
365 #print "%02x%02x invalid entry." % (sync,ord(packet[0]));
366 #This is a special kind of failure. Freq is probably right, but MAC is wrong.
368 if mac=='5555555555' or mac=='aaaaaaaaaa' or mac=='0000000000' or mac=='ffffffffff':
372 def handle(self,packet):
373 """Handles a packet."""
377 if not self.validmac(packet):
378 #print "Dropped packet from %s" % self.packetaddr(packet,justmac=True);
379 #printpacket(packet);
382 addr=self.packetaddr(packet);
384 #Increment the address count.
387 count=self.addresses[addr];
390 self.addresses[addr]=count+1;
391 rate=count*1.0/len(self.addresses);
392 if self.addresses[addr]>1 or rate>0.01:
393 print "'%s' looks valid\t%i\t%0.5f" % (
397 def selftune(self,threshold=2,forever=False,
399 """Tunes to the first strong signal.
400 It's important that this not get triggered by false positives."""
404 start=time.mktime(time.localtime());
406 while (time.mktime(time.localtime())-start) < delay:
409 packet=client.RF_rxpacket();
410 addr=guesser.handle(packet);
412 count=self.addresses[addr];
415 if count>threshold and forever==False:
422 """Tunes to another channel or preamble looking for the next packet."""
423 count=self.tunecount;
424 self.tunecount=count+1;
426 #Swap the SYNC value most often.
431 self.client.RF_setsmac(sync);
438 #This swaps between 1Mbps and 2Mbps.
439 #TODO add support for 256kbps, if anyone uses it.
442 #print "Setting rate to 0x%02x" % rate;
445 self.client.poke(0x06,rate);
449 self.client.poke(0x05,
450 (count+self.startch)&0x7f);
451 print "Tuned to %i MHz" % (
452 self.client.RF_getfreq()
454 #Grab two packets to clear buffers.
455 #Should retune only after a few packets to reduce this delay.
456 packet=client.RF_rxpacket();
457 packet=client.RF_rxpacket();
461 if(sys.argv[1]=="autotune"):
462 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
463 #TODO remove all poke() calls.
465 guesser.init(client,rate=True,sync=True,chan=True);
468 #client.RF_setfreq(2481 * 10**6);
469 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
470 client.poke(0x07,0x78); #Reset status register
472 #This is determined by the MAC, which we don't yet know.
475 client.RF_setpacketlen(32);
477 #Power radio, prime for RX, no checksum
478 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
480 print "Autotuning on %i MHz" % (
481 client.RF_getfreq()/10**6);
482 print "sync,mac,r5,r6";
483 #Now we're ready to get packets.
484 guesser.selftune(threshold=2,
487 if(sys.argv[1]=="autotunebt"):
488 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
489 #TODO remove all poke() calls.
491 guesser.init(client,rate=True,sync=False,chan=True,
492 macreject=False, printing=True);
495 #client.RF_setfreq(2481 * 10**6);
496 client.poke(0x06,0x00); #1MBps
497 client.poke(0x07,0x78); #Reset status register
499 #Bluetooth preamble is 0xA; BTLE is 0xAA.
500 client.RF_setsmac(0x000A);
503 client.RF_setpacketlen(32);
505 #Power radio, prime for RX, no checksum
506 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
508 print "Autotuning on %i MHz" % (
509 client.RF_getfreq()/10**6);
510 print "sync,mac,r5,r6";
511 #Now we're ready to get packets.
512 guesser.selftune(threshold=2,
515 if(sys.argv[1]=="sniffmacs"):
516 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
517 #TODO remove all poke() calls.
519 guesser.init(client,rate=False,sync=True,chan=False);
522 client.RF_setpacketlen(32);
524 #Power radio, prime for RX, no checksum
525 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
527 print "Holding autotune on %i MHz" % (
528 client.RF_getfreq()/10**6);
529 print "sync,mac,r5,r6";
530 #Now we're ready to get packets.
531 guesser.selftune(threshold=2,
534 if(sys.argv[1]=="sniffmskb"):
536 #TODO remove all poke() calls.
538 client.poke(0x00,0x00); #Stop nRF
539 client.poke(0x01,0x00); #Disable Shockburst
540 client.poke(0x02,0x01); #Set RX Pipe 0
542 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
543 client.poke(0x07,0x78); #Reset status register
545 #This is the address of a specific keyboard.
546 #Other keyboards will be different.
548 client.RF_setmaclen(5);
550 #Known pairs. The channel and the low address bytes must match.
551 #client.RF_setfreq((2400+0x13) * 10**6);
552 #client.RF_setsmac(0xc00a3598cd);
554 #client.RF_setfreq((2400+0x15) * 10**6);
555 #client.RF_setsmac(0xc10446facd);
557 #Mac packet length, illegally 0-length address field.
558 client.RF_setpacketlen(16);
562 client.tune(sys.argv[2]);
565 print "Searching for a keyboard.";
568 guesser.init(client, rate=False, sync=True, chan=True);
569 guesser.selftune(threshold=4,forever=False,
572 client.poke(0x00,0x00); #Stop nRF
573 client.poke(0x01,0x00); #Disable Shockburst
574 client.poke(0x02,0x01); #Set RX Pipe 0
575 client.RF_setmaclen(5);
577 #Finally, dynamic payload lengths need to be enabled.
578 #client.poke(0x01,0x01);
579 client.poke(0x1C,0x01);
580 client.poke(0x1D,0x06);
582 client.poke(0x00,0x70|0x03); #prime radio.
583 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
584 client.RF_getfreq()/10**6);
585 #Now we're ready to get packets.
590 packet=client.RF_rxpacket();
592 printmspacket(packet);
595 if(sys.argv[1]=="sniffant"):
596 #Prototyped on Garmin device.
597 #Channel hopping is pretty damned fast, hard to follow.
598 #This doesn't really work yet, still experimenting.
600 #Might be more effective to sniff knowing the MFG ID and Dev. ID,
601 #as these predict a lot of the MAC address.
603 client.poke(0x00,0x00); #Stop nRF
604 client.poke(0x01,0x00); #Disable Shockburst
605 client.poke(0x02,0x01); #Set RX Pipe 0
607 client.poke(0x05,57); #broadcast-only channel
608 client.poke(0x06,0x00); #1MBps
609 client.poke(0x07,0x78); #Reset status register
611 #Is this appropriate? Might be 3.
612 client.RF_setmaclen(5);
615 #Mac packet length, illegally 0-length address field.
616 client.RF_setpacketlen(16);
619 client.tune(sys.argv[2]);
622 print "Searching for ANT+.";
625 guesser.init(client, rate=False, sync=True, chan=True);
626 guesser.selftune(threshold=2,forever=False,
629 client.poke(0x00,0x00); #Stop nRF
630 client.poke(0x01,0x00); #Disable Shockburst
631 client.poke(0x02,0x01); #Set RX Pipe 0
632 client.RF_setmaclen(5);
635 client.poke(0x00,0x70|0x03); #prime radio.
636 print "Dumping ANT as %010x on %i MHz" % (client.RF_getsmac(),
637 client.RF_getfreq()/10**6);
638 #Now we're ready to get packets.
643 packet=client.RF_rxpacket();
651 if(sys.argv[1]=="sniffsf"):
652 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
653 #TODO remove all poke() calls.
655 client.poke(0x00,0x00); #Stop nRF
656 client.poke(0x01,0x00); #Disable Shockburst
657 client.poke(0x02,0x01); #Set RX Pipe 0
659 client.RF_setfreq(2402 * 10**6);
660 client.poke(0x06,0x07); #1Mbps
661 client.poke(0x07,0x78); #Reset status register
663 #OpenBeacon defines these in little endian as follows.
664 client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
665 client.RF_setsmac(0xe7e7e7e7e7);
666 client.RF_settmac(0xe7e7e7e7e7);
668 #Set packet length of 16.
669 client.RF_setpacketlen(4);
671 #Power radio, prime for RX, one-byte checksum.
672 client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
674 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
675 client.RF_getfreq()/10**6);
676 #Now we're ready to get packets.
681 packet=client.RF_rxpacket();
685 if(sys.argv[1]=="sniffnike"):
686 #TODO remove all poke() calls.
688 client.poke(0x00,0x00); #Stop nRF
689 client.poke(0x01,0x00); #Disable Shockburst
690 client.poke(0x02,0x01); #Set RX Pipe 0
692 client.RF_setfreq(2425 * 10**6);
693 client.poke(0x06,0x20|0x06); #250 kbps
694 client.poke(0x07,0x78); #Reset status register
697 client.RF_setmaclen(2); # Illegal by datasheet, but it works!
698 client.RF_setsmac(0xc2bd);
699 client.RF_settmac(0xc2bd); #Should we forge data?
701 client.RF_setpacketlen(32); #No idea what the length is.
703 #Power radio, prime for RX, two-byte checksum.
704 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two bytes.
706 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
707 client.RF_getfreq()/10**6);
708 print "Expect some false-positives.";
710 #Now we're ready to get packets.
715 packet=client.RF_rxpacket();
719 if(sys.argv[1]=="snifftp"):
720 client.poke(0x00,0x00); #Stop nRF
721 client.poke(0x01,0x00); #Disable Shockburst
722 client.poke(0x02,0x01); #Set RX Pipe 0
725 client.poke(0x1C,0x00);
726 client.poke(0x1D,0x00);
728 client.RF_setfreq((2400+0x29) * 10**6);
729 client.poke(0x06,0x00); #1Mbps
730 client.poke(0x07,0x78); #Reset status register
732 client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
733 client.RF_setsmac(0x123456);
734 client.RF_setpacketlen(4);
736 #Power radio, prime for RX, two-byte checksum.
737 client.poke(0x00,0x70|0x03|0x04|0x08);
739 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
740 client.RF_getfreq()/10**6);
741 #Now we're ready to get packets.
746 packet=client.RF_rxpacket();
751 if(sys.argv[1]=="sniff"):
753 print "Set MAC to %s" % sys.argv[2];
754 client.tune(sys.argv[2]);
755 client.RF_setmaclen(5);
757 #client.poke(0x00,0x00); #Stop nRF
758 client.poke(0x07,0x78); #Reset status register
760 #Power radio, prime for RX, no checksum.
761 client.poke(0x00,0x70|0x03);
763 client.RF_setpacketlen(32);
765 #client.RF_setmaclen(3); # SETUP_AW for shortest
767 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
768 client.RF_getfreq()/10**6);
769 #Now we're ready to get packets.
775 packet=client.RF_rxpacket();
778 if(sys.argv[1]=="explore"):
779 #client.poke(0x00,0x00); #Stop nRF
780 client.poke(0x07,0x78); #Reset status register
782 #Power radio, prime for RX, no checksum.
783 client.poke(0x00,0x70|0x03);
785 #Set packet length of 32.
786 #Without checksums, extra data will mix in.
787 client.RF_setpacketlen(32);
788 client.RF_setmaclen(3); # shortest address length
790 #Now we're ready to get packets.
791 for smac in [0x0102030201, 0]:
792 client.RF_setsmac(smac);
793 for chan in range(0,0x80):
794 client.RF_setfreq((2400+chan) * 10**6);
796 packet=client.RF_rxpacket();
798 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
799 client.RF_getfreq()/10**6);