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));
34 def printmspacket(packet,offset=1):
35 keyword=client.RF_getsmac();
36 #print "keyword=%010x" % key;
39 for foo in range(0,5):
40 key.append(keyword&0xFF);
42 #print "Keybyte %02x" % key[foo];
48 ct.append(ord(foo)^key[(i+offset)%5]);
49 s="%s %02x" % (s,ord(foo)^key[(i+offset)%5]);
52 s="%s %02x" % (s,ord(foo));
56 if ct[0]==0x0a and ct[1]==0x78 and ct[9]!=0:
57 letter=ct[9]+ord('A')-4;
60 print "Encoding %s" % client.RF_getenc();
61 print "Freq %10i MHz" % (client.RF_getfreq()/10**6);
62 print "Rate %10i kbps" % (client.RF_getrate()/1000);
63 print "PacketLen %02i bytes" % client.RF_getpacketlen();
64 #print "MacLen %2i bytes" % client.RF_getmaclen();
65 print "SMAC 0x%010x" % client.RF_getsmac();
66 print "TMAC 0x%010x" % client.RF_gettmac();
70 print "Usage: %s verb [objects]\n" % sys.argv[0];
71 print "%s info" % sys.argv[0];
72 print "%s test" % sys.argv[0];
73 print "%s regs" % sys.argv[0];
74 print "%s regbits" % sys.argv[0];
75 print "%s pyregs" % sys.argv[0];
77 print "%s tune aa|55,mac,r5,r6\n\tTunes to a configuration." % sys.argv[0];
78 print "%s sniff\n\tSniffs packets by current config." % sys.argv[0];
79 print "%s sniffob\n\tSniffs OpenBeacon traffic." % sys.argv[0];
80 print "%s snifftp\n\tSniffs Turning Point Clicker traffic." % sys.argv[0];
81 print "%s sniffsf\n\tSniffs SparkFun Dongle traffic." % sys.argv[0];
83 print "%s sniffmacs \n\tSniffs for MAC addresses on the present channel." % sys.argv[0];
84 print "%s sniffprom [0xaa|0x55]\n\tSniffs promiscuously for a preamble of 0xAA or 0x55" % sys.argv[0];
85 print "%s autotune\n\tSearches for a valid destination address." % sys.argv[0];
87 print "%s sniffskybrake\n\tSniffs skybrake. [broken?]" % sys.argv[0];
88 print "%s sniffmskb\n\tSniffs MS KB. [broken?]" % sys.argv[0];
90 print "%s hosttp\n\tHosts Turning Point Clicker traffic." % sys.argv[0];
92 print "%s carrier [freq]\n\tHolds a carrier on [freq] Hz." % sys.argv[0];
95 #Initialize FET and set baud rate
101 if(sys.argv[1]=="info"):
104 if(sys.argv[1]=="test"):
105 print "Old registers:"
108 # Set PWR_UP=1 and PRIM_RX=0 in CONFIG.
110 #Delay of 1.5ms by round-trip.
115 for foo in [250*10**3,
118 client.RF_setrate(foo);
119 if(client.RF_getrate()!=foo):
120 print "ERROR Rate %i not supported. Got %i instead." % (foo,
121 client.RF_getrate());
124 client.poke(0x0A,0xDEADBEEF,5);
125 #print "SMAC set to %010x" % client.RF_getsmac();
126 if client.RF_getsmac()!=0xdeadbeef:
127 print "ERROR: Failed to set MAC address.";
128 print "Final registers:"
131 if(sys.argv[1]=="carrier"):
133 client.RF_setfreq(eval(sys.argv[2]));
136 print "\nHolding a carrier wave.";
140 if(sys.argv[1]=="tune"):
142 client.tune(sys.argv[2]);
144 print "Specify a tuning, such as 'aa,c78c65805e,14,09'";
145 if(sys.argv[1]=="regs"):
146 for r in range(0,0x20):
147 print "r[0x%02x]=0x%010x //%16s " % (r,client.peek(r),regnames[r]);
148 if(sys.argv[1]=="pyregs"):
149 for r in range(0,0x20):
150 print "client.set(0x%02x,0x%010x); #%16s " % (r,client.peek(r),regnames[r]);
152 if(sys.argv[1]=="peek"):
155 start=int(sys.argv[2],16);
158 stop=int(sys.argv[3],16);
159 print "Peeking from %02x to %02x." % (start,stop);
161 print "%02x: %010x" % (start,client.peek(start));
163 if(sys.argv[1]=="poke"):
167 start=int(sys.argv[2],16);
169 val=int(sys.argv[3],16);
170 print "Poking %02x to become %010x." % (start,val);
172 client.poke(start,val);
173 print "Poked to %04x" % client.peek(start);
175 if(sys.argv[1]=="sniffob"):
176 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
177 #TODO remove all poke() calls.
179 client.poke(0x00,0x00); #Stop nRF
180 client.poke(0x01,0x00); #Disable Shockburst
181 client.poke(0x02,0x01); #Set RX Pipe 0
183 client.RF_setfreq(2481 * 10**6);
184 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
185 client.poke(0x07,0x78); #Reset status register
187 #OpenBeacon defines these in little endian as follows.
188 client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
189 #0x01, 0x02, 0x03, 0x02, 0x01
190 client.RF_setsmac(0x0102030201);
191 #'O', 'C', 'A', 'E', 'B'
192 client.RF_settmac(0x424541434F);
194 #Set packet length of 16.
195 client.RF_setpacketlen(16);
197 #Power radio, prime for RX, one-byte checksum.
198 client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
200 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
201 client.RF_getfreq()/10**6);
202 #Now we're ready to get packets.
207 packet=client.RF_rxpacket();
211 if(sys.argv[1]=="regbits"):
212 print "Scanning registers to determine which bits are valid."
213 regbits=range(0,0x30);
214 for r in range(0,0x30):
216 #Which bits can be set?
219 #Which bits can be clear?
221 zeroes=client.peek(r);
222 regbits[r]=(ones & (~zeroes));
223 for r in range(0,0x30):
225 print "r[0x%02x] masked %02x // %s" % (r,regbits[r], regnames[r]);
226 if(sys.argv[1]=="sniffprom"):
227 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
228 #TODO remove all poke() calls.
230 client.poke(0x00,0x00); #Stop nRF
231 client.poke(0x01,0x00); #Disable Shockburst
232 client.poke(0x02,0x01); #Set RX Pipe 0
234 #client.RF_setfreq(2481 * 10**6);
235 #client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
236 client.poke(0x07,0x78); #Reset status register
238 #OpenBeacon defines these in little endian as follows.
239 client.RF_setmaclen(2); # SETUP_AW for shortest
241 #It's better to have a known fragment, when one is available.
242 #client.RF_setsmac(0x00AA);
243 #client.RF_setsmac(0x0055);
245 #Should end in 55 or AA depending upon the packet.
248 tail=int(sys.argv[2],16);
250 print "Please specify a tail of 0xAA or 0x55.";
252 client.RF_setsmac(tail);
255 client.RF_setpacketlen(32);
257 #Power radio, prime for RX, no checksum
258 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
260 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
261 client.RF_getfreq()/10**6);
262 #Now we're ready to get packets.
267 packet=client.RF_rxpacket();
272 """This guesses addresses by searching through packets."""
276 #Limits on search space, because you usually know what you're looking for.
280 startch=0; #Useful for forcing an early match.
281 def init(self,goodfet,
282 rate=True,chan=True,sync=True):
283 """Initializes a link to the GoodFET for autotuning."""
289 client.poke(0x00,0x00); #Stop nRF
290 client.poke(0x01,0x00); #Disable Shockburst
291 client.poke(0x02,0x01); #Set RX Pipe 0
294 client.poke(0x1C,0x00);
295 client.poke(0x1D,0x00);
297 client.RF_setmaclen(2); # SETUP_AW for shortest
300 #client.RF_setsmac(0x00AA);
301 #client.RF_setsmac(0x0055);
303 client.poke(0x00,0x70|0x03); #prime radio.
306 def packetaddr(self,packet,justmac=False):
307 """Returns a loaded packet address, including channel and rate."""
309 sync=self.client.RF_getsmac()&0xFF;
314 mac="%s%02x" % (mac,ord(packet[i]));
317 ch=self.client.peek(0x05);
318 rate=self.client.peek(0x06);
319 return "%02x,%s,%02x,%02x" % (
321 def validmac(self,packet):
322 sync=self.client.RF_getsmac()&0xFF;
323 mac=self.packetaddr(packet,justmac=True);
324 if (ord(packet[0])&0x80)^(sync&0x80):
325 #print "%02x%02x invalid entry." % (sync,ord(packet[0]));
326 #This is a special kind of failure. Freq is probably right, but MAC is wrong.
328 if mac=='5555555555' or mac=='aaaaaaaaaa' or mac=='0000000000':
332 def handle(self,packet):
333 """Handles a packet."""
334 #printpacket(packet);
336 if not self.validmac(packet):
337 #print "Dropped packet from %s" % self.packetaddr(packet,justmac=True);
338 #printpacket(packet);
341 addr=self.packetaddr(packet);
343 #Increment the address count.
346 count=self.addresses[addr];
349 self.addresses[addr]=count+1;
350 rate=count*1.0/len(self.addresses);
351 if self.addresses[addr]>1 or rate>0.01:
352 print "'%s' looks valid\t%i\t%0.5f" % (
356 def selftune(self,threshold=2,forever=False,
358 """Tunes to the first strong signal.
359 It's important that this not get triggered by false positives."""
363 start=time.mktime(time.localtime());
365 while (time.mktime(time.localtime())-start) < delay:
368 packet=client.RF_rxpacket();
369 addr=guesser.handle(packet);
371 count=self.addresses[addr];
374 if count>threshold and forever==False:
381 """Tunes to another channel or preamble looking for the next packet."""
382 count=self.tunecount;
383 self.tunecount=count+1;
385 #Swap the SYNC value most often.
390 self.client.RF_setsmac(sync);
397 #This swaps between 1Mbps and 2Mbps.
398 #TODO add support for 256kbps, if anyone uses it.
401 #print "Setting rate to 0x%02x" % rate;
404 self.client.poke(0x06,rate);
408 self.client.poke(0x05,
409 (count+self.startch)&0x7f);
410 print "Tuned to %i MHz" % (
411 self.client.RF_getfreq()
413 #Grab two packets to clear buffers.
414 #Should retune only after a few packets to reduce this delay.
415 packet=client.RF_rxpacket();
416 packet=client.RF_rxpacket();
420 if(sys.argv[1]=="autotune"):
421 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
422 #TODO remove all poke() calls.
424 guesser.init(client,rate=True,sync=True,chan=True);
427 #client.RF_setfreq(2481 * 10**6);
428 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
429 client.poke(0x07,0x78); #Reset status register
431 #This is determined by the MAC, which we don't yet know.
434 client.RF_setpacketlen(32);
436 #Power radio, prime for RX, no checksum
437 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
439 print "Autotuning on %i MHz" % (
440 client.RF_getfreq()/10**6);
441 print "sync,mac,r5,r6";
442 #Now we're ready to get packets.
443 guesser.selftune(threshold=2,
446 if(sys.argv[1]=="sniffmacs"):
447 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
448 #TODO remove all poke() calls.
450 guesser.init(client,rate=False,sync=True,chan=False);
453 client.RF_setpacketlen(32);
455 #Power radio, prime for RX, no checksum
456 client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
458 print "Holding autotune on %i MHz" % (
459 client.RF_getfreq()/10**6);
460 print "sync,mac,r5,r6";
461 #Now we're ready to get packets.
462 guesser.selftune(threshold=2,
465 if(sys.argv[1]=="sniffmskb"):
467 #TODO remove all poke() calls.
469 client.poke(0x00,0x00); #Stop nRF
470 client.poke(0x01,0x00); #Disable Shockburst
471 client.poke(0x02,0x01); #Set RX Pipe 0
473 client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
474 client.poke(0x07,0x78); #Reset status register
476 #This is the address of a specific keyboard.
477 #Other keyboards will be different.
479 client.RF_setmaclen(5);
481 #Known pairs. The channel and the low address bytes must match.
482 #client.RF_setfreq((2400+0x13) * 10**6);
483 #client.RF_setsmac(0xc00a3598cd);
485 #client.RF_setfreq((2400+0x15) * 10**6);
486 #client.RF_setsmac(0xc10446facd);
488 #Mac packet length, illegally 0-length address field.
489 client.RF_setpacketlen(16);
493 client.tune(sys.argv[2]);
496 print "Searching for a keyboard.";
499 guesser.init(client, rate=False, sync=True, chan=True);
500 guesser.selftune(threshold=4,forever=False,
503 client.poke(0x00,0x00); #Stop nRF
504 client.poke(0x01,0x00); #Disable Shockburst
505 client.poke(0x02,0x01); #Set RX Pipe 0
506 client.RF_setmaclen(5);
508 #Finally, dynamic payload lengths need to be enabled.
509 #client.poke(0x01,0x01);
510 client.poke(0x1C,0x01);
511 client.poke(0x1D,0x06);
513 client.poke(0x00,0x70|0x03); #prime radio.
514 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
515 client.RF_getfreq()/10**6);
516 #Now we're ready to get packets.
521 packet=client.RF_rxpacket();
523 printmspacket(packet);
526 if(sys.argv[1]=="sniffant"):
527 #Prototyped on Garmin device.
528 #Channel hopping is pretty damned fast, hard to follow.
529 #This doesn't really work yet, still experimenting.
531 #Might be more effective to sniff knowing the MFG ID and Dev. ID,
532 #as these predict a lot of the MAC address.
534 client.poke(0x00,0x00); #Stop nRF
535 client.poke(0x01,0x00); #Disable Shockburst
536 client.poke(0x02,0x01); #Set RX Pipe 0
538 client.poke(0x05,57); #broadcast-only channel
539 client.poke(0x06,0x00); #1MBps
540 client.poke(0x07,0x78); #Reset status register
542 #Is this appropriate? Might be 3.
543 client.RF_setmaclen(5);
546 #Mac packet length, illegally 0-length address field.
547 client.RF_setpacketlen(16);
550 client.tune(sys.argv[2]);
553 print "Searching for ANT+.";
556 guesser.init(client, rate=False, sync=True, chan=True);
557 guesser.selftune(threshold=2,forever=False,
560 client.poke(0x00,0x00); #Stop nRF
561 client.poke(0x01,0x00); #Disable Shockburst
562 client.poke(0x02,0x01); #Set RX Pipe 0
563 client.RF_setmaclen(5);
566 client.poke(0x00,0x70|0x03); #prime radio.
567 print "Dumping ANT as %010x on %i MHz" % (client.RF_getsmac(),
568 client.RF_getfreq()/10**6);
569 #Now we're ready to get packets.
574 packet=client.RF_rxpacket();
581 if(sys.argv[1]=="sniffskybrake"):
582 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
583 #TODO remove all poke() calls.
585 client.poke(0x00,0x00); #Stop nRF
586 client.poke(0x01,0x00); #Disable Shockburst
587 client.poke(0x02,0x01); #Set RX Pipe 0
589 client.RF_setfreq(2439 * 10**6);
590 client.poke(0x06,0x00); #1MBps
591 client.poke(0x07,0x78); #Reset status register
593 #OpenBeacon defines these in little endian as follows.
594 client.RF_setmaclen(2); # SETUP_AW for 3-byte addresses.
595 #0x01, 0x02, 0x03, 0x02, 0x01
597 client.RF_setsmac(0x070700d2c4); #reversed
599 #client.RF_setsmac(0xd2c4);
600 #client.RF_setsmac(0);
602 #Mac packet length, illegally 0-length address field.
603 client.RF_setpacketlen(32);
605 #Power radio, prime for RX, one-byte checksum.
606 client.poke(0x00,0x70|0x03); #0x08 for one byte, 0x04 for two.
608 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
609 client.RF_getfreq()/10**6);
610 print "%i byte mac match." % client.RF_getmaclen();
611 #Now we're ready to get packets.
616 packet=client.RF_rxpacket();
620 if(sys.argv[1]=="sniffsf"):
621 #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
622 #TODO remove all poke() calls.
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.RF_setfreq(2402 * 10**6);
629 client.poke(0x06,0x07); #1Mbps
630 client.poke(0x07,0x78); #Reset status register
632 #OpenBeacon defines these in little endian as follows.
633 client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
634 client.RF_setsmac(0xe7e7e7e7e7);
635 client.RF_settmac(0xe7e7e7e7e7);
637 #Set packet length of 16.
638 client.RF_setpacketlen(4);
640 #Power radio, prime for RX, one-byte checksum.
641 client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
643 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
644 client.RF_getfreq()/10**6);
645 #Now we're ready to get packets.
650 packet=client.RF_rxpacket();
654 if(sys.argv[1]=="snifftp"):
655 client.poke(0x00,0x00); #Stop nRF
656 client.poke(0x01,0x00); #Disable Shockburst
657 client.poke(0x02,0x01); #Set RX Pipe 0
660 client.poke(0x1C,0x00);
661 client.poke(0x1D,0x00);
663 client.RF_setfreq((2400+0x29) * 10**6);
664 client.poke(0x06,0x00); #1Mbps
665 client.poke(0x07,0x78); #Reset status register
667 client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
668 client.RF_setsmac(0x123456);
669 client.RF_setpacketlen(4);
671 #Power radio, prime for RX, two-byte checksum.
672 client.poke(0x00,0x70|0x03|0x04|0x08);
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]=="hosttp"):
686 client.poke(0x00,0x00); #Stop nRF
687 client.poke(0x01,0x00); #Disable Shockburst
688 client.poke(0x02,0x01); #Set RX Pipe 0
692 client.RF_setfreq((2400+chan) * 10**6);
693 client.poke(0x06,0x00); #1Mbps
694 client.poke(0x07,0x78); #Reset status register
696 client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
697 client.RF_setsmac(0x123456);
698 client.RF_setpacketlen(4);
700 #Power radio, prime for RX, two-byte checksum.
701 client.poke(0x00,0x70|0x03|0x04|0x08);
703 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
704 client.RF_getfreq()/10**6);
705 #Now we're ready to get packets.
709 packet=client.RF_rxpacket();
710 mac=((ord(packet[0])<<16)+
714 print "%c from %06x" % (key,mac);
717 if(sys.argv[1]=="sniff"):
719 print "Set MAC to %s" % sys.argv[2];
720 client.tune(sys.argv[2]);
721 client.RF_setmaclen(5);
723 #client.poke(0x00,0x00); #Stop nRF
724 client.poke(0x07,0x78); #Reset status register
726 #Power radio, prime for RX, no checksum.
727 client.poke(0x00,0x70|0x03);
729 client.RF_setpacketlen(32);
731 #client.RF_setmaclen(3); # SETUP_AW for shortest
733 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
734 client.RF_getfreq()/10**6);
735 #Now we're ready to get packets.
741 packet=client.RF_rxpacket();
744 if(sys.argv[1]=="explore"):
745 #client.poke(0x00,0x00); #Stop nRF
746 client.poke(0x07,0x78); #Reset status register
748 #Power radio, prime for RX, no checksum.
749 client.poke(0x00,0x70|0x03);
751 #Set packet length of 32.
752 #Without checksums, extra data will mix in.
753 client.RF_setpacketlen(32);
754 client.RF_setmaclen(3); # shortest address length
756 #Now we're ready to get packets.
757 for smac in [0x0102030201, 0]:
758 client.RF_setsmac(smac);
759 for chan in range(0,0x80):
760 client.RF_setfreq((2400+chan) * 10**6);
762 packet=client.RF_rxpacket();
764 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
765 client.RF_getfreq()/10**6);