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;
94 print "Unknown character 0x%02x." % ct[9];
97 mskbstring="%s%c" % (mskbstring,letter);
98 print "# %s" % mskbstring
100 print "Encoding %s" % client.RF_getenc();
101 print "Freq %10i MHz" % (client.RF_getfreq()/10**6);
102 print "Rate %10i kbps" % (client.RF_getrate()/1000);
103 print "PacketLen %02i bytes" % client.RF_getpacketlen();
104 #print "MacLen %2i bytes" % client.RF_getmaclen();
105 print "SMAC 0x%010x" % client.RF_getsmac();
106 print "TMAC 0x%010x" % client.RF_gettmac();
109 if(len(sys.argv)==1):
110 print "Usage: %s verb [objects]\n" % sys.argv[0];
111 print "%s info" % sys.argv[0];
112 print "%s test" % sys.argv[0];
113 print "%s regs" % sys.argv[0];
114 print "%s regbits" % sys.argv[0];
115 print "%s pyregs" % sys.argv[0];
117 print "%s tune aa|55,mac,r5,r6\n\tTunes to a configuration." % sys.argv[0];
118 print "%s sniff\n\tSniffs packets by current config." % sys.argv[0];
119 print "%s sniffob\n\tSniffs OpenBeacon traffic." % sys.argv[0];
120 print "%s snifftp\n\tSniffs Turning Point Clicker traffic." % sys.argv[0];
121 print "%s sniffsf\n\tSniffs SparkFun Dongle traffic." % sys.argv[0];
122 print "%s sniffmskb\n\tSniffs Microsoft Keyboard traffic." % sys.argv[0];
124 print "%s sniffmacs \n\tSniffs for MAC addresses on the present channel." % sys.argv[0];
125 print "%s sniffprom [0xaa|0x55]\n\tSniffs promiscuously for a preamble of 0xAA or 0x55" % sys.argv[0];
126 print "%s autotune\n\tSearches for a valid destination address." % sys.argv[0];
128 print "%s carrier [freq]\n\tHolds a carrier on [freq] Hz." % sys.argv[0];
131 #Initialize FET and set baud rate
137 if(sys.argv[1]=="info"):
140 if(sys.argv[1]=="test"):
141 print "Old registers:"
144 # Set PWR_UP=1 and PRIM_RX=0 in CONFIG.
146 #Delay of 1.5ms by round-trip.
151 for foo in [250*10**3,
154 client.RF_setrate(foo);
155 if(client.RF_getrate()!=foo):
156 print "ERROR Rate %i not supported. Got %i instead." % (
158 client.RF_getrate());
161 client.poke(0x0A,0xDEADBEEF,5);
162 #print "SMAC set to %010x" % client.RF_getsmac();
163 if client.RF_getsmac()!=0xdeadbeef:
164 print "ERROR: Failed to set MAC address.";
165 print "Final registers:"
168 if(sys.argv[1]=="carrier"):
170 client.RF_setfreq(eval(sys.argv[2]));
173 print "\nHolding a carrier wave.";
177 if(sys.argv[1]=="tune"):
179 client.tune(sys.argv[2]);
181 print "Specify a tuning, such as 'aa,c78c65805e,14,09'";
182 if(sys.argv[1]=="regs"):
183 for r in range(0,0x20):
184 print "r[0x%02x]=0x%010x //%16s " % (r,client.peek(r),regnames[r]);
185 if(sys.argv[1]=="pyregs"):
186 for r in range(0,0x20):
187 print "client.set(0x%02x,0x%010x); #%16s " % (r,client.peek(r),regnames[r]);
189 if(sys.argv[1]=="peek"):
192 start=int(sys.argv[2],16);
195 stop=int(sys.argv[3],16);
196 print "Peeking from %02x to %02x." % (start,stop);
198 print "%02x: %010x" % (start,client.peek(start));
200 if(sys.argv[1]=="poke"):
204 start=int(sys.argv[2],16);
206 val=int(sys.argv[3],16);
207 print "Poking %02x to become %010x." % (start,val);
209 client.poke(start,val);
210 print "Poked to %04x" % client.peek(start);
212 if(sys.argv[1]=="sniffob"):
213 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
214 #TODO remove all poke() calls.
216 client.poke(0x00,0x00); #Stop nRF
217 client.poke(0x01,0x00); #Disable Shockburst
218 client.poke(0x02,0x01); #Set RX Pipe 0
220 client.RF_setfreq(2481 * 10**6);
221 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
222 client.poke(0x07,0x78); #Reset status register
224 #OpenBeacon defines these in little endian as follows.
225 client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
226 #0x01, 0x02, 0x03, 0x02, 0x01
227 client.RF_setsmac(0x0102030201);
228 #'O', 'C', 'A', 'E', 'B'
229 client.RF_settmac(0x424541434F);
231 #Set packet length of 16.
232 client.RF_setpacketlen(16);
234 #Power radio, prime for RX, one-byte checksum.
235 client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
237 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
238 client.RF_getfreq()/10**6);
239 #Now we're ready to get packets.
244 packet=client.RF_rxpacket();
248 if(sys.argv[1]=="regbits"):
249 print "Scanning registers to determine which bits are valid."
250 regbits=range(0,0x30);
251 for r in range(0,0x30):
253 #Which bits can be set?
256 #Which bits can be clear?
258 zeroes=client.peek(r);
259 regbits[r]=(ones & (~zeroes));
260 for r in range(0,0x30):
262 print "r[0x%02x] masked %02x // %s" % (r,regbits[r], regnames[r]);
263 if(sys.argv[1]=="sniffprom"):
264 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
265 #TODO remove all poke() calls.
267 client.poke(0x00,0x00); #Stop nRF
268 client.poke(0x01,0x00); #Disable Shockburst
269 client.poke(0x02,0x01); #Set RX Pipe 0
271 #client.RF_setfreq(2481 * 10**6);
272 #client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
273 client.poke(0x07,0x78); #Reset status register
275 #OpenBeacon defines these in little endian as follows.
276 client.RF_setmaclen(2); # SETUP_AW for shortest
278 #It's better to have a known fragment, when one is available.
279 #client.RF_setsmac(0x00AA);
280 #client.RF_setsmac(0x0055);
282 #Should end in 55 or AA depending upon the packet.
285 tail=int(sys.argv[2],16);
287 print "Please specify a tail of 0xAA or 0x55.";
289 client.RF_setsmac(tail);
292 client.RF_setpacketlen(32);
294 #Power radio, prime for RX, no checksum
295 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
297 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
298 client.RF_getfreq()/10**6);
299 #Now we're ready to get packets.
304 packet=client.RF_rxpacket();
309 """This guesses addresses by searching through packets."""
313 #Limits on search space, because you usually know what you're looking for.
319 startch=0; #Useful for forcing an early match.
320 maclen=5; #Some are shorter.
321 def init(self,goodfet,
322 rate=True,chan=True,sync=True,
323 macreject=True, printing=False,
325 """Initializes a link to the GoodFET for autotuning."""
330 self.macreject=macreject;
331 self.printing=printing;
334 client.poke(0x00,0x00); #Stop nRF
335 client.poke(0x01,0x00); #Disable Shockburst
336 client.poke(0x02,0x01); #Set RX Pipe 0
339 client.poke(0x1C,0x00);
340 client.poke(0x1D,0x00);
342 client.RF_setmaclen(2); # SETUP_AW for shortest
345 #client.RF_setsmac(0x00AA);
346 #client.RF_setsmac(0x0055);
348 client.poke(0x00,0x70|0x03); #prime radio.
352 def packetaddr(self,packet,justmac=False):
353 """Returns a loaded packet address, including channel and rate."""
355 sync=self.client.RF_getsmac()&0xFF;
359 for i in range(0,self.maclen):
360 mac="%s%02x" % (mac,ord(packet[i]));
363 ch=self.client.peek(0x05);
364 rate=self.client.peek(0x06);
365 return "%02x,%s,%02x,%02x" % (
367 def validmac(self,packet):
368 sync=self.client.RF_getsmac()&0xFF;
369 mac=self.packetaddr(packet,justmac=True);
371 #BT preamble is A or 5.
372 #Fix this to work on the smallest bit, not the highest.
373 if ((ord(packet[0])&0x80)^(sync&0x80)) and self.macreject:
374 #print "%02x%02x invalid entry." % (sync,ord(packet[0]));
375 #This is a special kind of failure. Freq is probably right, but MAC is wrong.
377 blacklist=['5555555555', 'aaaaaaaaaa',
378 '0000000000', 'ffffffffff',
379 '55555555', 'aaaaaaaa',
380 '00000000', 'ffffffff',
383 '7fffff', 'aaffff', 'aaaaff',
384 'afffff', 'abffff', '5fffff'];
385 for foo in blacklist:
390 def handle(self,packet):
391 """Handles a packet."""
395 if not self.validmac(packet):
396 #print "Dropped packet from %s" % self.packetaddr(packet,justmac=True);
397 #printpacket(packet);
400 addr=self.packetaddr(packet);
402 #Increment the address count.
405 count=self.addresses[addr];
408 self.addresses[addr]=count+1;
409 rate=count*1.0/len(self.addresses);
410 if self.addresses[addr]>1 or rate>0.01:
411 print "'%s' looks valid\t%i\t%0.5f" % (
415 def selftune(self,threshold=2,forever=False,
417 """Tunes to the first strong signal.
418 It's important that this not get triggered by false positives."""
422 start=time.mktime(time.localtime());
424 while (time.mktime(time.localtime())-start) < delay:
427 packet=client.RF_rxpacket();
428 addr=guesser.handle(packet);
430 count=self.addresses[addr];
433 if count>threshold and forever==False:
440 """Tunes to another channel or preamble looking for the next packet."""
441 count=self.tunecount;
442 self.tunecount=count+1;
444 #Swap the SYNC value most often.
449 self.client.RF_setsmac(sync);
456 #This swaps between 1Mbps and 2Mbps.
457 #TODO add support for 256kbps, if anyone uses it.
463 print "Setting rate to 0x%02x" % rate;
464 self.client.poke(0x06,rate);
468 self.client.poke(0x05,
469 (count+self.startch)&0x7f);
470 print "Tuned to %i MHz" % (
471 self.client.RF_getfreq()
473 #Grab two packets to clear buffers.
474 #Should retune only after a few packets to reduce this delay.
475 packet=client.RF_rxpacket();
476 packet=client.RF_rxpacket();
480 if(sys.argv[1]=="autotune"):
481 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
482 #TODO remove all poke() calls.
484 guesser.init(client,rate=True,sync=True,chan=True);
487 #client.RF_setfreq(2481 * 10**6);
488 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
489 client.poke(0x07,0x78); #Reset status register
491 #This is determined by the MAC, which we don't yet know.
494 client.RF_setpacketlen(32);
496 #Power radio, prime for RX, no checksum
497 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
499 print "Autotuning on %i MHz" % (
500 client.RF_getfreq()/10**6);
501 print "sync,mac,r5,r6";
502 #Now we're ready to get packets.
504 guesser.selftune(threshold=2,
508 if(sys.argv[1]=="autotunebt"):
509 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
510 #TODO remove all poke() calls.
512 guesser.init(client,rate=True,sync=False,chan=True,
513 macreject=False, printing=True);
516 #client.RF_setfreq(2481 * 10**6);
517 client.poke(0x06,0x00); #1MBps
518 client.poke(0x07,0x78); #Reset status register
520 #Bluetooth preamble is 0xA; BTLE is 0xAA.
521 client.RF_setsmac(0x000A);
524 client.RF_setpacketlen(32);
526 #Power radio, prime for RX, no checksum
527 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
529 print "Autotuning on %i MHz" % (
530 client.RF_getfreq()/10**6);
531 print "sync,mac,r5,r6";
532 #Now we're ready to get packets.
533 guesser.selftune(threshold=2,
536 if(sys.argv[1]=="sniffmacs"):
537 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
538 #TODO remove all poke() calls.
540 guesser.init(client,rate=False,sync=True,chan=False);
543 client.RF_setpacketlen(32);
545 #Power radio, prime for RX, no checksum
546 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
548 print "Holding autotune on %i MHz" % (
549 client.RF_getfreq()/10**6);
550 print "sync,mac,r5,r6";
551 #Now we're ready to get packets.
552 guesser.selftune(threshold=2,
555 if(sys.argv[1]=="sniffmskb"):
557 #TODO remove all poke() calls.
559 client.poke(0x00,0x00); #Stop nRF
560 client.poke(0x01,0x00); #Disable Shockburst
561 client.poke(0x02,0x01); #Set RX Pipe 0
563 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
564 client.poke(0x07,0x78); #Reset status register
566 #This is the address of a specific keyboard.
567 #Other keyboards will be different.
569 client.RF_setmaclen(5);
571 #Known pairs. The channel and the low address bytes must match.
572 #client.RF_setfreq((2400+0x13) * 10**6);
573 #client.RF_setsmac(0xc00a3598cd);
575 #client.RF_setfreq((2400+0x15) * 10**6);
576 #client.RF_setsmac(0xc10446facd);
578 #Mac packet length, illegally 0-length address field.
579 client.RF_setpacketlen(16);
583 client.tune(sys.argv[2]);
586 print "Searching for a keyboard.";
589 guesser.init(client, rate=False, sync=True, chan=True);
590 guesser.selftune(threshold=4,forever=False,
593 client.poke(0x00,0x00); #Stop nRF
594 client.poke(0x01,0x00); #Disable Shockburst
595 client.poke(0x02,0x01); #Set RX Pipe 0
596 client.RF_setmaclen(5);
598 #Finally, dynamic payload lengths need to be enabled.
599 #client.poke(0x01,0x01);
600 client.poke(0x1C,0x01);
601 client.poke(0x1D,0x06);
603 client.poke(0x00,0x70|0x03); #prime radio.
604 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
605 client.RF_getfreq()/10**6);
606 #Now we're ready to get packets.
611 packet=client.RF_rxpacket();
613 printmspacket(packet);
616 if(sys.argv[1]=="sniffant"):
617 #Prototyped on Garmin device.
618 #Channel hopping is pretty damned fast, hard to follow.
619 #This doesn't really work yet, still experimenting.
621 #Might be more effective to sniff knowing the MFG ID and Dev. ID,
622 #as these predict a lot of the MAC address.
624 client.poke(0x00,0x00); #Stop nRF
625 client.poke(0x01,0x00); #Disable Shockburst
626 client.poke(0x02,0x01); #Set RX Pipe 0
628 client.poke(0x05,57); #broadcast-only channel
629 client.poke(0x06,0x00); #1MBps
630 client.poke(0x07,0x78); #Reset status register
632 #Is this appropriate? Might be 3.
633 client.RF_setmaclen(5);
636 #Mac packet length, illegally 0-length address field.
637 client.RF_setpacketlen(16);
640 client.tune(sys.argv[2]);
643 print "Searching for ANT+.";
646 guesser.init(client, rate=False, sync=True, chan=True);
647 guesser.selftune(threshold=2,forever=False,
650 client.poke(0x00,0x00); #Stop nRF
651 client.poke(0x01,0x00); #Disable Shockburst
652 client.poke(0x02,0x01); #Set RX Pipe 0
653 client.RF_setmaclen(5);
656 client.poke(0x00,0x70|0x03); #prime radio.
657 print "Dumping ANT as %010x on %i MHz" % (client.RF_getsmac(),
658 client.RF_getfreq()/10**6);
659 #Now we're ready to get packets.
664 packet=client.RF_rxpacket();
672 if(sys.argv[1]=="sniffsf"):
673 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
674 #TODO remove all poke() calls.
676 client.poke(0x00,0x00); #Stop nRF
677 client.poke(0x01,0x00); #Disable Shockburst
678 client.poke(0x02,0x01); #Set RX Pipe 0
680 client.RF_setfreq(2402 * 10**6);
681 client.poke(0x06,0x07); #1Mbps
682 client.poke(0x07,0x78); #Reset status register
684 #OpenBeacon defines these in little endian as follows.
685 client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
686 client.RF_setsmac(0xe7e7e7e7e7);
687 client.RF_settmac(0xe7e7e7e7e7);
689 #Set packet length of 16.
690 client.RF_setpacketlen(4);
692 #Power radio, prime for RX, one-byte checksum.
693 client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
695 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
696 client.RF_getfreq()/10**6);
697 #Now we're ready to get packets.
702 packet=client.RF_rxpacket();
706 if(sys.argv[1]=="sniffnike"):
707 #TODO remove all poke() calls.
709 client.poke(0x00,0x00); #Stop nRF
710 client.poke(0x01,0x00); #Disable Shockburst
711 client.poke(0x02,0x01); #Set RX Pipe 0
713 client.RF_setfreq(2425 * 10**6);
714 client.poke(0x06,0x20|0x06); #250 kbps
715 client.poke(0x07,0x78); #Reset status register
718 client.RF_setmaclen(2); # Illegal by datasheet, but it works!
719 client.RF_setsmac(0xc2bd);
720 client.RF_settmac(0xc2bd); #Should we forge data?
722 client.RF_setpacketlen(32); #No idea what the length is.
724 #Power radio, prime for RX, two-byte checksum.
725 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two bytes.
727 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
728 client.RF_getfreq()/10**6);
729 print "Expect some false-positives.";
731 #Now we're ready to get packets.
736 packet=client.RF_rxpacket();
740 if(sys.argv[1]=="snifftp"):
741 client.poke(0x00,0x00); #Stop nRF
742 client.poke(0x01,0x00); #Disable Shockburst
743 client.poke(0x02,0x01); #Set RX Pipe 0
746 client.poke(0x1C,0x00);
747 client.poke(0x1D,0x00);
749 client.RF_setfreq((2400+0x29) * 10**6);
750 client.poke(0x06,0x00); #1Mbps
751 client.poke(0x07,0x78); #Reset status register
753 client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
754 client.RF_setsmac(0x123456);
755 client.RF_setpacketlen(4);
757 #Power radio, prime for RX, two-byte checksum.
758 #client.poke(0x00,0x70|0x03|0x04|0x08);
760 #Power radio, prime for RX, no checksum.
761 client.poke(0x00,0x70|0x03);
764 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
765 client.RF_getfreq()/10**6);
766 #Now we're ready to get packets.
771 packet=client.RF_rxpacket();
776 if(sys.argv[1]=="sniff"):
778 print "Set MAC to %s" % sys.argv[2];
779 client.tune(sys.argv[2]);
780 client.RF_setmaclen(5);
782 #client.poke(0x00,0x00); #Stop nRF
783 client.poke(0x07,0x78); #Reset status register
785 #Power radio, prime for RX, no checksum.
786 client.poke(0x00,0x70|0x03);
788 client.RF_setpacketlen(32);
790 #client.RF_setmaclen(3); # SETUP_AW for shortest
792 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
793 client.RF_getfreq()/10**6);
794 #Now we're ready to get packets.
800 packet=client.RF_rxpacket();
803 if(sys.argv[1]=="explore"):
804 #client.poke(0x00,0x00); #Stop nRF
805 client.poke(0x07,0x78); #Reset status register
807 #Power radio, prime for RX, no checksum.
808 client.poke(0x00,0x70|0x03);
810 #Set packet length of 32.
811 #Without checksums, extra data will mix in.
812 client.RF_setpacketlen(32);
813 client.RF_setmaclen(3); # shortest address length
815 #Now we're ready to get packets.
816 for smac in [0x0102030201, 0]:
817 client.RF_setsmac(smac);
818 for chan in range(0,0x80):
819 client.RF_setfreq((2400+chan) * 10**6);
821 packet=client.RF_rxpacket();
823 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
824 client.RF_getfreq()/10**6);