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;
93 print "Unknown character 0x%02x." % ct[9];
96 mskbstring="%s%c" % (mskbstring,letter);
97 print "# %s" % mskbstring
99 print "Encoding %s" % client.RF_getenc();
100 print "Freq %10i MHz" % (client.RF_getfreq()/10**6);
101 print "Rate %10i kbps" % (client.RF_getrate()/1000);
102 print "PacketLen %02i bytes" % client.RF_getpacketlen();
103 #print "MacLen %2i bytes" % client.RF_getmaclen();
104 print "SMAC 0x%010x" % client.RF_getsmac();
105 print "TMAC 0x%010x" % client.RF_gettmac();
108 if(len(sys.argv)==1):
109 print "Usage: %s verb [objects]\n" % sys.argv[0];
110 print "%s info" % sys.argv[0];
111 print "%s test" % sys.argv[0];
112 print "%s regs" % sys.argv[0];
113 print "%s regbits" % sys.argv[0];
114 print "%s pyregs" % sys.argv[0];
116 print "%s tune aa|55,mac,r5,r6\n\tTunes to a configuration." % sys.argv[0];
117 print "%s sniff\n\tSniffs packets by current config." % sys.argv[0];
118 print "%s sniffob\n\tSniffs OpenBeacon traffic." % sys.argv[0];
119 print "%s snifftp\n\tSniffs Turning Point Clicker traffic." % sys.argv[0];
120 print "%s sniffsf\n\tSniffs SparkFun Dongle traffic." % sys.argv[0];
121 print "%s sniffmskb\n\tSniffs Microsoft Keyboard traffic." % sys.argv[0];
123 print "%s sniffmacs \n\tSniffs for MAC addresses on the present channel." % sys.argv[0];
124 print "%s sniffprom [0xaa|0x55]\n\tSniffs promiscuously for a preamble of 0xAA or 0x55" % sys.argv[0];
125 print "%s autotune\n\tSearches for a valid destination address." % sys.argv[0];
127 print "%s carrier [freq]\n\tHolds a carrier on [freq] Hz." % sys.argv[0];
130 #Initialize FET and set baud rate
136 if(sys.argv[1]=="info"):
139 if(sys.argv[1]=="test"):
140 print "Old registers:"
143 # Set PWR_UP=1 and PRIM_RX=0 in CONFIG.
145 #Delay of 1.5ms by round-trip.
150 for foo in [250*10**3,
153 client.RF_setrate(foo);
154 if(client.RF_getrate()!=foo):
155 print "ERROR Rate %i not supported. Got %i instead." % (
157 client.RF_getrate());
160 client.poke(0x0A,0xDEADBEEF,5);
161 #print "SMAC set to %010x" % client.RF_getsmac();
162 if client.RF_getsmac()!=0xdeadbeef:
163 print "ERROR: Failed to set MAC address.";
164 print "Final registers:"
167 if(sys.argv[1]=="carrier"):
169 client.RF_setfreq(eval(sys.argv[2]));
172 print "\nHolding a carrier wave.";
176 if(sys.argv[1]=="tune"):
178 client.tune(sys.argv[2]);
180 print "Specify a tuning, such as 'aa,c78c65805e,14,09'";
181 if(sys.argv[1]=="regs"):
182 for r in range(0,0x20):
183 print "r[0x%02x]=0x%010x //%16s " % (r,client.peek(r),regnames[r]);
184 if(sys.argv[1]=="pyregs"):
185 for r in range(0,0x20):
186 print "client.set(0x%02x,0x%010x); #%16s " % (r,client.peek(r),regnames[r]);
188 if(sys.argv[1]=="peek"):
191 start=int(sys.argv[2],16);
194 stop=int(sys.argv[3],16);
195 print "Peeking from %02x to %02x." % (start,stop);
197 print "%02x: %010x" % (start,client.peek(start));
199 if(sys.argv[1]=="poke"):
203 start=int(sys.argv[2],16);
205 val=int(sys.argv[3],16);
206 print "Poking %02x to become %010x." % (start,val);
208 client.poke(start,val);
209 print "Poked to %04x" % client.peek(start);
211 if(sys.argv[1]=="sniffob"):
212 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
213 #TODO remove all poke() calls.
215 client.poke(0x00,0x00); #Stop nRF
216 client.poke(0x01,0x00); #Disable Shockburst
217 client.poke(0x02,0x01); #Set RX Pipe 0
219 client.RF_setfreq(2481 * 10**6);
220 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
221 client.poke(0x07,0x78); #Reset status register
223 #OpenBeacon defines these in little endian as follows.
224 client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
225 #0x01, 0x02, 0x03, 0x02, 0x01
226 client.RF_setsmac(0x0102030201);
227 #'O', 'C', 'A', 'E', 'B'
228 client.RF_settmac(0x424541434F);
230 #Set packet length of 16.
231 client.RF_setpacketlen(16);
233 #Power radio, prime for RX, one-byte checksum.
234 client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
236 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
237 client.RF_getfreq()/10**6);
238 #Now we're ready to get packets.
243 packet=client.RF_rxpacket();
247 if(sys.argv[1]=="regbits"):
248 print "Scanning registers to determine which bits are valid."
249 regbits=range(0,0x30);
250 for r in range(0,0x30):
252 #Which bits can be set?
255 #Which bits can be clear?
257 zeroes=client.peek(r);
258 regbits[r]=(ones & (~zeroes));
259 for r in range(0,0x30):
261 print "r[0x%02x] masked %02x // %s" % (r,regbits[r], regnames[r]);
262 if(sys.argv[1]=="sniffprom"):
263 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
264 #TODO remove all poke() calls.
266 client.poke(0x00,0x00); #Stop nRF
267 client.poke(0x01,0x00); #Disable Shockburst
268 client.poke(0x02,0x01); #Set RX Pipe 0
270 #client.RF_setfreq(2481 * 10**6);
271 #client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
272 client.poke(0x07,0x78); #Reset status register
274 #OpenBeacon defines these in little endian as follows.
275 client.RF_setmaclen(2); # SETUP_AW for shortest
277 #It's better to have a known fragment, when one is available.
278 #client.RF_setsmac(0x00AA);
279 #client.RF_setsmac(0x0055);
281 #Should end in 55 or AA depending upon the packet.
284 tail=int(sys.argv[2],16);
286 print "Please specify a tail of 0xAA or 0x55.";
288 client.RF_setsmac(tail);
291 client.RF_setpacketlen(32);
293 #Power radio, prime for RX, no checksum
294 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
296 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
297 client.RF_getfreq()/10**6);
298 #Now we're ready to get packets.
303 packet=client.RF_rxpacket();
308 """This guesses addresses by searching through packets."""
312 #Limits on search space, because you usually know what you're looking for.
318 startch=0; #Useful for forcing an early match.
319 maclen=5; #Some are shorter.
320 def init(self,goodfet,
321 rate=True,chan=True,sync=True,
322 macreject=True, printing=False,
324 """Initializes a link to the GoodFET for autotuning."""
329 self.macreject=macreject;
330 self.printing=printing;
333 client.poke(0x00,0x00); #Stop nRF
334 client.poke(0x01,0x00); #Disable Shockburst
335 client.poke(0x02,0x01); #Set RX Pipe 0
338 client.poke(0x1C,0x00);
339 client.poke(0x1D,0x00);
341 client.RF_setmaclen(2); # SETUP_AW for shortest
344 #client.RF_setsmac(0x00AA);
345 #client.RF_setsmac(0x0055);
347 client.poke(0x00,0x70|0x03); #prime radio.
351 def packetaddr(self,packet,justmac=False):
352 """Returns a loaded packet address, including channel and rate."""
354 sync=self.client.RF_getsmac()&0xFF;
358 for i in range(0,self.maclen):
359 mac="%s%02x" % (mac,ord(packet[i]));
362 ch=self.client.peek(0x05);
363 rate=self.client.peek(0x06);
364 return "%02x,%s,%02x,%02x" % (
366 def validmac(self,packet):
367 sync=self.client.RF_getsmac()&0xFF;
368 mac=self.packetaddr(packet,justmac=True);
370 #BT preamble is A or 5.
371 #Fix this to work on the smallest bit, not the highest.
372 if ((ord(packet[0])&0x80)^(sync&0x80)) and self.macreject:
373 #print "%02x%02x invalid entry." % (sync,ord(packet[0]));
374 #This is a special kind of failure. Freq is probably right, but MAC is wrong.
376 blacklist=['5555555555', 'aaaaaaaaaa',
377 '0000000000', 'ffffffffff',
378 '55555555', 'aaaaaaaa',
379 '00000000', 'ffffffff',
382 '7fffff', 'aaffff', 'aaaaff',
383 'afffff', 'abffff', '5fffff'];
384 for foo in blacklist:
389 def handle(self,packet):
390 """Handles a packet."""
394 if not self.validmac(packet):
395 #print "Dropped packet from %s" % self.packetaddr(packet,justmac=True);
396 #printpacket(packet);
399 addr=self.packetaddr(packet);
401 #Increment the address count.
404 count=self.addresses[addr];
407 self.addresses[addr]=count+1;
408 rate=count*1.0/len(self.addresses);
409 if self.addresses[addr]>1 or rate>0.01:
410 print "'%s' looks valid\t%i\t%0.5f" % (
414 def selftune(self,threshold=2,forever=False,
416 """Tunes to the first strong signal.
417 It's important that this not get triggered by false positives."""
421 start=time.mktime(time.localtime());
423 while (time.mktime(time.localtime())-start) < delay:
426 packet=client.RF_rxpacket();
427 addr=guesser.handle(packet);
429 count=self.addresses[addr];
432 if count>threshold and forever==False:
439 """Tunes to another channel or preamble looking for the next packet."""
440 count=self.tunecount;
441 self.tunecount=count+1;
443 #Swap the SYNC value most often.
448 self.client.RF_setsmac(sync);
455 #This swaps between 1Mbps and 2Mbps.
456 #TODO add support for 256kbps, if anyone uses it.
462 print "Setting rate to 0x%02x" % rate;
463 self.client.poke(0x06,rate);
467 self.client.poke(0x05,
468 (count+self.startch)&0x7f);
469 print "Tuned to %i MHz" % (
470 self.client.RF_getfreq()
472 #Grab two packets to clear buffers.
473 #Should retune only after a few packets to reduce this delay.
474 packet=client.RF_rxpacket();
475 packet=client.RF_rxpacket();
479 if(sys.argv[1]=="autotune"):
480 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
481 #TODO remove all poke() calls.
483 guesser.init(client,rate=True,sync=True,chan=True);
486 #client.RF_setfreq(2481 * 10**6);
487 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
488 client.poke(0x07,0x78); #Reset status register
490 #This is determined by the MAC, which we don't yet know.
493 client.RF_setpacketlen(32);
495 #Power radio, prime for RX, no checksum
496 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
498 print "Autotuning on %i MHz" % (
499 client.RF_getfreq()/10**6);
500 print "sync,mac,r5,r6";
501 #Now we're ready to get packets.
503 guesser.selftune(threshold=2,
507 if(sys.argv[1]=="autotunebt"):
508 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
509 #TODO remove all poke() calls.
511 guesser.init(client,rate=True,sync=False,chan=True,
512 macreject=False, printing=True);
515 #client.RF_setfreq(2481 * 10**6);
516 client.poke(0x06,0x00); #1MBps
517 client.poke(0x07,0x78); #Reset status register
519 #Bluetooth preamble is 0xA; BTLE is 0xAA.
520 client.RF_setsmac(0x000A);
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 "Autotuning 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]=="sniffmacs"):
536 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
537 #TODO remove all poke() calls.
539 guesser.init(client,rate=False,sync=True,chan=False);
542 client.RF_setpacketlen(32);
544 #Power radio, prime for RX, no checksum
545 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
547 print "Holding autotune on %i MHz" % (
548 client.RF_getfreq()/10**6);
549 print "sync,mac,r5,r6";
550 #Now we're ready to get packets.
551 guesser.selftune(threshold=2,
554 if(sys.argv[1]=="sniffmskb"):
556 #TODO remove all poke() calls.
558 client.poke(0x00,0x00); #Stop nRF
559 client.poke(0x01,0x00); #Disable Shockburst
560 client.poke(0x02,0x01); #Set RX Pipe 0
562 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
563 client.poke(0x07,0x78); #Reset status register
565 #This is the address of a specific keyboard.
566 #Other keyboards will be different.
568 client.RF_setmaclen(5);
570 #Known pairs. The channel and the low address bytes must match.
571 #client.RF_setfreq((2400+0x13) * 10**6);
572 #client.RF_setsmac(0xc00a3598cd);
574 #client.RF_setfreq((2400+0x15) * 10**6);
575 #client.RF_setsmac(0xc10446facd);
577 #Mac packet length, illegally 0-length address field.
578 client.RF_setpacketlen(16);
582 client.tune(sys.argv[2]);
585 print "Searching for a keyboard.";
588 guesser.init(client, rate=False, sync=True, chan=True);
589 guesser.selftune(threshold=4,forever=False,
592 client.poke(0x00,0x00); #Stop nRF
593 client.poke(0x01,0x00); #Disable Shockburst
594 client.poke(0x02,0x01); #Set RX Pipe 0
595 client.RF_setmaclen(5);
597 #Finally, dynamic payload lengths need to be enabled.
598 #client.poke(0x01,0x01);
599 client.poke(0x1C,0x01);
600 client.poke(0x1D,0x06);
602 client.poke(0x00,0x70|0x03); #prime radio.
603 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
604 client.RF_getfreq()/10**6);
605 #Now we're ready to get packets.
610 packet=client.RF_rxpacket();
612 printmspacket(packet);
615 if(sys.argv[1]=="sniffant"):
616 #Prototyped on Garmin device.
617 #Channel hopping is pretty damned fast, hard to follow.
618 #This doesn't really work yet, still experimenting.
620 #Might be more effective to sniff knowing the MFG ID and Dev. ID,
621 #as these predict a lot of the MAC address.
623 client.poke(0x00,0x00); #Stop nRF
624 client.poke(0x01,0x00); #Disable Shockburst
625 client.poke(0x02,0x01); #Set RX Pipe 0
627 client.poke(0x05,57); #broadcast-only channel
628 client.poke(0x06,0x00); #1MBps
629 client.poke(0x07,0x78); #Reset status register
631 #Is this appropriate? Might be 3.
632 client.RF_setmaclen(5);
635 #Mac packet length, illegally 0-length address field.
636 client.RF_setpacketlen(16);
639 client.tune(sys.argv[2]);
642 print "Searching for ANT+.";
645 guesser.init(client, rate=False, sync=True, chan=True);
646 guesser.selftune(threshold=2,forever=False,
649 client.poke(0x00,0x00); #Stop nRF
650 client.poke(0x01,0x00); #Disable Shockburst
651 client.poke(0x02,0x01); #Set RX Pipe 0
652 client.RF_setmaclen(5);
655 client.poke(0x00,0x70|0x03); #prime radio.
656 print "Dumping ANT as %010x on %i MHz" % (client.RF_getsmac(),
657 client.RF_getfreq()/10**6);
658 #Now we're ready to get packets.
663 packet=client.RF_rxpacket();
671 if(sys.argv[1]=="sniffsf"):
672 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
673 #TODO remove all poke() calls.
675 client.poke(0x00,0x00); #Stop nRF
676 client.poke(0x01,0x00); #Disable Shockburst
677 client.poke(0x02,0x01); #Set RX Pipe 0
679 client.RF_setfreq(2402 * 10**6);
680 client.poke(0x06,0x07); #1Mbps
681 client.poke(0x07,0x78); #Reset status register
683 #OpenBeacon defines these in little endian as follows.
684 client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
685 client.RF_setsmac(0xe7e7e7e7e7);
686 client.RF_settmac(0xe7e7e7e7e7);
688 #Set packet length of 16.
689 client.RF_setpacketlen(4);
691 #Power radio, prime for RX, one-byte checksum.
692 client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
694 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
695 client.RF_getfreq()/10**6);
696 #Now we're ready to get packets.
701 packet=client.RF_rxpacket();
705 if(sys.argv[1]=="sniffnike"):
706 #TODO remove all poke() calls.
708 client.poke(0x00,0x00); #Stop nRF
709 client.poke(0x01,0x00); #Disable Shockburst
710 client.poke(0x02,0x01); #Set RX Pipe 0
712 client.RF_setfreq(2425 * 10**6);
713 client.poke(0x06,0x20|0x06); #250 kbps
714 client.poke(0x07,0x78); #Reset status register
717 client.RF_setmaclen(2); # Illegal by datasheet, but it works!
718 client.RF_setsmac(0xc2bd);
719 client.RF_settmac(0xc2bd); #Should we forge data?
721 client.RF_setpacketlen(32); #No idea what the length is.
723 #Power radio, prime for RX, two-byte checksum.
724 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two bytes.
726 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
727 client.RF_getfreq()/10**6);
728 print "Expect some false-positives.";
730 #Now we're ready to get packets.
735 packet=client.RF_rxpacket();
739 if(sys.argv[1]=="snifftp"):
740 client.poke(0x00,0x00); #Stop nRF
741 client.poke(0x01,0x00); #Disable Shockburst
742 client.poke(0x02,0x01); #Set RX Pipe 0
745 client.poke(0x1C,0x00);
746 client.poke(0x1D,0x00);
748 client.RF_setfreq((2400+0x29) * 10**6);
749 client.poke(0x06,0x00); #1Mbps
750 client.poke(0x07,0x78); #Reset status register
752 client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
753 client.RF_setsmac(0x123456);
754 client.RF_setpacketlen(4);
756 #Power radio, prime for RX, two-byte checksum.
757 #client.poke(0x00,0x70|0x03|0x04|0x08);
759 #Power radio, prime for RX, no checksum.
760 client.poke(0x00,0x70|0x03);
763 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
764 client.RF_getfreq()/10**6);
765 #Now we're ready to get packets.
770 packet=client.RF_rxpacket();
775 if(sys.argv[1]=="sniff"):
777 print "Set MAC to %s" % sys.argv[2];
778 client.tune(sys.argv[2]);
779 client.RF_setmaclen(5);
781 #client.poke(0x00,0x00); #Stop nRF
782 client.poke(0x07,0x78); #Reset status register
784 #Power radio, prime for RX, no checksum.
785 client.poke(0x00,0x70|0x03);
787 client.RF_setpacketlen(32);
789 #client.RF_setmaclen(3); # SETUP_AW for shortest
791 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
792 client.RF_getfreq()/10**6);
793 #Now we're ready to get packets.
799 packet=client.RF_rxpacket();
802 if(sys.argv[1]=="explore"):
803 #client.poke(0x00,0x00); #Stop nRF
804 client.poke(0x07,0x78); #Reset status register
806 #Power radio, prime for RX, no checksum.
807 client.poke(0x00,0x70|0x03);
809 #Set packet length of 32.
810 #Without checksums, extra data will mix in.
811 client.RF_setpacketlen(32);
812 client.RF_setmaclen(3); # shortest address length
814 #Now we're ready to get packets.
815 for smac in [0x0102030201, 0]:
816 client.RF_setsmac(smac);
817 for chan in range(0,0x80):
818 client.RF_setfreq((2400+chan) * 10**6);
820 packet=client.RF_rxpacket();
822 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
823 client.RF_getfreq()/10**6);