GoodFET NRF stuff.
[goodfet] / client / goodfet.nrf
1 #!/usr/bin/env python
2
3 #GoodFET SPI Flash Client
4 #by Travis Goodspeed
5
6 import sys;
7 import binascii;
8 import array;
9 import time;
10
11 from GoodFETNRF import GoodFETNRF;
12 from intelhex import IntelHex;
13
14
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",
18           "TX_ADDR",
19           "RX_PW_P0","RX_PW_P1","RX_PW_P2","RX_PW_P3","RX_PW_P4","RX_PW_P5",
20           "FIFO_STATUS","?",
21           "?","?","?","DYNPD","FEATURE","AGC_CONFIG","?","?",
22           "?","?","?","?","?","?","?","?"];
23
24 def printpacket(packet):
25     s="";
26     i=0;
27     for foo in packet:
28         i=i+1;
29         if i>client.packetlen: break;
30         s="%s %02x" % (s,ord(foo));
31     print "%s" % s;
32
33
34 mskbstring="";
35 oldseq=-1;
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;
41     key=[];
42     ct=[];
43     for foo in range(0,5):
44         key.append(keyword&0xFF);
45         keyword=(keyword>>8);
46         #print "Keybyte %02x" % key[foo];
47     i=0;
48     s="";
49     
50     for foo in packet:
51         if i>=4:
52             ct.append(ord(foo)^key[(i+offset)%5]);
53             s="%s %02x" % (s,ord(foo)^key[(i+offset)%5]);
54         else:
55             ct.append(ord(foo));
56             s="%s %02x" % (s,ord(foo));
57         i=i+1;
58     #Uncomment this to print the raw packet, kinda noisy.
59     print "%s" % (s);
60     
61     letter=None;
62     seq=ct[4];
63     if ct[0]==0x0a and ct[1]==0x78 and seq!=oldseq:
64         oldseq=seq;
65         #TODO replace this with a dictionary, and support modifiers.
66         if ct[9]==0:
67             #Key up event, not worth logging.
68             pass;
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;
73         elif ct[9]==0x27:
74             letter=ord('0');
75         elif ct[9]==0x29:
76             #escape
77             letter=ord('e');
78         elif ct[9]==0x2d:
79             letter=ord('-');
80         elif ct[9]==0x2e:
81             letter=ord('=');
82         elif ct[9]==0x35:
83             letter=ord('`');
84         elif ct[9]==0x2C:
85             letter=ord('_');
86         elif ct[9]==0x34:
87             letter=ord('\'');
88         elif ct[9]==0x36:
89             letter=ord(',');
90         elif ct[9]==0x37:
91             letter=ord('.');
92         
93         else:
94             print "Unknown character 0x%02x." % ct[9];
95             letter=ord('?');
96     if letter!=None:
97         mskbstring="%s%c" % (mskbstring,letter);
98     print "# %s" % mskbstring
99 def printconfig():
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();
107
108
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];
116     print "";
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];
123     print "";
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];
127     print "";
128     print "%s carrier [freq]\n\tHolds a carrier on [freq] Hz." % sys.argv[0];
129     sys.exit();
130
131 #Initialize FET and set baud rate
132 client=GoodFETNRF();
133 client.serInit()
134
135 client.NRFsetup();
136
137 if(sys.argv[1]=="info"):
138     printconfig();
139
140 if(sys.argv[1]=="test"):
141     print "Old registers:"
142     printconfig();
143     
144     # Set PWR_UP=1 and PRIM_RX=0 in CONFIG.
145     client.poke(0x00,2);
146     #Delay of 1.5ms by round-trip.
147     
148     print "\n\n";
149     
150     #Try all data rates
151     for foo in [250*10**3,
152                 1*10**6,
153                 2*10**6]:
154         client.RF_setrate(foo);
155         if(client.RF_getrate()!=foo):
156             print "ERROR Rate %i not supported.  Got %i instead." % (
157                 foo,
158                 client.RF_getrate());
159     
160     print "\n\n";
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:"
166     printconfig();
167
168 if(sys.argv[1]=="carrier"):
169     if len(sys.argv)>2:
170         client.RF_setfreq(eval(sys.argv[2]));
171     client.RF_carrier();
172     printconfig();
173     print "\nHolding a carrier wave.";
174     while(1):
175         time.sleep(1);
176
177 if(sys.argv[1]=="tune"):
178     if len(sys.argv)>2:
179         client.tune(sys.argv[2]);
180     else:
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]);
188
189 if(sys.argv[1]=="peek"):
190     start=0x0000;
191     if(len(sys.argv)>2):
192         start=int(sys.argv[2],16);
193     stop=start;
194     if(len(sys.argv)>3):
195         stop=int(sys.argv[3],16);
196     print "Peeking from %02x to %02x." % (start,stop);
197     while start<=stop:
198         print "%02x: %010x" % (start,client.peek(start));
199         start=start+1;
200 if(sys.argv[1]=="poke"):
201     start=0x0000;
202     val=0x00;
203     if(len(sys.argv)>2):
204         start=int(sys.argv[2],16);
205     if(len(sys.argv)>3):
206         val=int(sys.argv[3],16);
207     print "Poking %02x to become %010x." % (start,val);
208     
209     client.poke(start,val);
210     print "Poked to %04x" % client.peek(start);
211
212 if(sys.argv[1]=="sniffob"):
213     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
214     #TODO remove all poke() calls.
215     
216     client.poke(0x00,0x00); #Stop nRF
217     client.poke(0x01,0x00); #Disable Shockburst
218     client.poke(0x02,0x01); #Set RX Pipe 0
219     
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
223     
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);
230     
231     #Set packet length of 16.
232     client.RF_setpacketlen(16);
233     
234     #Power radio, prime for RX, one-byte checksum.
235     client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
236     
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.
240     while 1:
241         packet=None;
242         while packet==None:
243             #time.sleep(0.1);
244             packet=client.RF_rxpacket();
245         printpacket(packet);
246         sys.stdout.flush();
247
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):
252         old=client.peek(r);
253         #Which bits can be set?
254         client.poke(r,0xFF);
255         ones=client.peek(r);
256         #Which bits can be clear?
257         client.poke(r,0x00);
258         zeroes=client.peek(r);
259         regbits[r]=(ones & (~zeroes));
260     for r in range(0,0x30):
261         if regbits[r]!=0:
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.
266     
267     client.poke(0x00,0x00); #Stop nRF
268     client.poke(0x01,0x00); #Disable Shockburst
269     client.poke(0x02,0x01); #Set RX Pipe 0
270     
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
274     
275     #OpenBeacon defines these in little endian as follows.
276     client.RF_setmaclen(2); # SETUP_AW for shortest
277     
278     #It's better to have a known fragment, when one is available.
279     #client.RF_setsmac(0x00AA);
280     #client.RF_setsmac(0x0055);
281     
282     #Should end in 55 or AA depending upon the packet.
283     tail=0x55
284     if(len(sys.argv)>2):
285         tail=int(sys.argv[2],16);
286     else:
287         print "Please specify a tail of 0xAA or 0x55.";
288         sys.exit(1);
289     client.RF_setsmac(tail);
290     
291     #Longest length.
292     client.RF_setpacketlen(32);
293     
294     #Power radio, prime for RX, no checksum
295     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
296     
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.
300     while 1:
301         packet=None;
302         while packet==None:
303             #time.sleep(0.1);
304             packet=client.RF_rxpacket();
305         printpacket(packet);
306         sys.stdout.flush();
307
308 class AutoTuner():
309     """This guesses addresses by searching through packets."""
310     addresses={};
311     client=None;
312     
313     #Limits on search space, because you usually know what you're looking for.
314     rate=False;
315     chan=False;
316     sync=False;
317     macreject=False;
318     printing=False;
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,
324              maclen=5):
325         """Initializes a link to the GoodFET for autotuning."""
326         self.client=goodfet;
327         self.rate=rate;
328         self.chan=chan;
329         self.sync=sync;
330         self.macreject=macreject;
331         self.printing=printing;
332         self.maclen=maclen;
333         
334         client.poke(0x00,0x00); #Stop nRF
335         client.poke(0x01,0x00); #Disable Shockburst
336         client.poke(0x02,0x01); #Set RX Pipe 0
337         
338         #Disable shockburst.
339         client.poke(0x1C,0x00);
340         client.poke(0x1D,0x00);
341         
342         client.RF_setmaclen(2); # SETUP_AW for shortest
343         
344         #historic
345         #client.RF_setsmac(0x00AA);
346         #client.RF_setsmac(0x0055);
347         
348         client.poke(0x00,0x70|0x03); #prime radio.
349         
350         return;
351     
352     def packetaddr(self,packet,justmac=False):
353         """Returns a loaded packet address, including channel and rate."""
354         
355         sync=self.client.RF_getsmac()&0xFF;
356         
357         mac="";
358         #MAC,RF_CH,RATE
359         for i in range(0,self.maclen):
360             mac="%s%02x" % (mac,ord(packet[i]));
361         if justmac:
362             return mac;
363         ch=self.client.peek(0x05);
364         rate=self.client.peek(0x06);
365         return "%02x,%s,%02x,%02x" % (
366             sync,mac,ch,rate);
367     def validmac(self,packet):
368         sync=self.client.RF_getsmac()&0xFF;
369         mac=self.packetaddr(packet,justmac=True);
370         
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.
376             return False;
377         blacklist=['5555555555', 'aaaaaaaaaa',
378                    '0000000000', 'ffffffffff',
379                    '55555555',   'aaaaaaaa',
380                    '00000000',   'ffffffff',
381                    '555555',     'aaaaaa',
382                    '000000',     'ffffff',
383                    '7fffff', 'aaffff', 'aaaaff',
384                    'afffff', 'abffff', '5fffff'];
385         for foo in blacklist:
386             if mac==foo:
387                 return False;
388         return True;
389         
390     def handle(self,packet):
391         """Handles a packet."""
392         if self.printing:
393             printpacket(packet);
394         
395         if not self.validmac(packet):
396             #print "Dropped packet from %s" % self.packetaddr(packet,justmac=True);
397             #printpacket(packet);
398             return;
399         
400         addr=self.packetaddr(packet);
401         
402         #Increment the address count.
403         count=0;
404         try:
405             count=self.addresses[addr];
406         except:
407             pass;
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" % (
412                 addr,count,rate);
413         return addr;
414     tunecount=0;
415     def selftune(self,threshold=2,forever=False,
416                  delay=5.0):
417         """Tunes to the first strong signal.
418         It's important that this not get triggered by false positives."""
419         
420         while 1:
421             self.retune();
422             start=time.mktime(time.localtime());
423             sys.stdout.flush();
424             while (time.mktime(time.localtime())-start) < delay:
425                 packet=None;
426                 while packet==None:
427                     packet=client.RF_rxpacket();
428                 addr=guesser.handle(packet);
429                 try:
430                     count=self.addresses[addr];
431                 except:
432                     count=0;
433                 if count>threshold and forever==False:
434                     #Tune it in here?
435                     client.tune(addr);
436                     return addr;
437             
438         
439     def retune(self):
440         """Tunes to another channel or preamble looking for the next packet."""
441         count=self.tunecount;
442         self.tunecount=count+1;
443         
444         #Swap the SYNC value most often.
445         if self.sync:
446             sync=0x00AA;
447             if count&1:
448                 sync=0x0055;
449             self.client.RF_setsmac(sync);
450             count=(count>>1);
451         
452         if self.rate:
453             #Then the data rate.
454             rate=0;
455             
456             #This swaps between 1Mbps and 2Mbps.
457             #TODO add support for 256kbps, if anyone uses it.
458             if count&1:
459                 rate=rate|0x08;
460             
461             if(rate==0x20):
462                 rate=0x08;
463             print "Setting rate to 0x%02x" % rate;
464             self.client.poke(0x06,rate);
465             count=(count>>1);
466         
467         if self.chan:
468             self.client.poke(0x05,
469                              (count+self.startch)&0x7f);
470             print "Tuned to %i MHz" % (
471                 self.client.RF_getfreq()
472                 /(10**6));
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();
477         return;
478         
479         
480 if(sys.argv[1]=="autotune"):
481     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
482     #TODO remove all poke() calls.
483     guesser=AutoTuner();
484     guesser.init(client,rate=True,sync=True,chan=True);
485     
486     
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
490     
491     #This is determined by the MAC, which we don't yet know.
492     
493     #Longest length.
494     client.RF_setpacketlen(32);
495     
496     #Power radio, prime for RX, no checksum
497     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
498     
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.
503     guesser.startch=16;
504     guesser.selftune(threshold=2,
505                      delay=10,
506                      forever=True);
507
508 if(sys.argv[1]=="autotunebt"):
509     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
510     #TODO remove all poke() calls.
511     guesser=AutoTuner();
512     guesser.init(client,rate=True,sync=False,chan=True,
513                  macreject=False, printing=True);
514     
515     
516     #client.RF_setfreq(2481 * 10**6);
517     client.poke(0x06,0x00); #1MBps
518     client.poke(0x07,0x78); #Reset status register
519     
520     #Bluetooth preamble is 0xA; BTLE is 0xAA.
521     client.RF_setsmac(0x000A);
522     
523     #Longest length.
524     client.RF_setpacketlen(32);
525     
526     #Power radio, prime for RX, no checksum
527     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
528     
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,
534                      forever=True);
535
536 if(sys.argv[1]=="sniffmacs"):
537     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
538     #TODO remove all poke() calls.
539     guesser=AutoTuner();
540     guesser.init(client,rate=False,sync=True,chan=False);
541     
542     #Longest length.
543     client.RF_setpacketlen(32);
544     
545     #Power radio, prime for RX, no checksum
546     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
547     
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,
553                      forever=True);
554
555 if(sys.argv[1]=="sniffmskb"):
556     #MSWK 3000 v2.0
557     #TODO remove all poke() calls.
558     
559     client.poke(0x00,0x00); #Stop nRF
560     client.poke(0x01,0x00); #Disable Shockburst
561     client.poke(0x02,0x01); #Set RX Pipe 0
562     
563     client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
564     client.poke(0x07,0x78); #Reset status register
565     
566     #This is the address of a specific keyboard.
567     #Other keyboards will be different.
568     
569     client.RF_setmaclen(5);
570     
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);
574     
575     #client.RF_setfreq((2400+0x15) * 10**6);
576     #client.RF_setsmac(0xc10446facd);
577     
578     #Mac packet length, illegally 0-length address field.
579     client.RF_setpacketlen(16);
580     
581     #aa,c00a3598cd,13,09
582     if len(sys.argv)>2:
583         client.tune(sys.argv[2]);
584     else:
585         
586         print "Searching for a keyboard.";
587         
588         guesser=AutoTuner();
589         guesser.init(client, rate=False, sync=True, chan=True);
590         guesser.selftune(threshold=4,forever=False,
591                          delay=10.0);
592     
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);
597     
598     #Finally, dynamic payload lengths need to be enabled.
599     #client.poke(0x01,0x01);
600     client.poke(0x1C,0x01);
601     client.poke(0x1D,0x06);
602     
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.
607     while 1:
608         packet=None;
609         while packet==None:
610             #time.sleep(1);
611             packet=client.RF_rxpacket();
612             #print ".";
613         printmspacket(packet);
614         sys.stdout.flush();
615
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.
620     
621     #Might be more effective to sniff knowing the MFG ID and Dev. ID,
622     #as these predict a lot of the MAC address.
623     
624     client.poke(0x00,0x00); #Stop nRF
625     client.poke(0x01,0x00); #Disable Shockburst
626     client.poke(0x02,0x01); #Set RX Pipe 0
627     
628     client.poke(0x05,57); #broadcast-only channel
629     client.poke(0x06,0x00); #1MBps
630     client.poke(0x07,0x78); #Reset status register
631     
632     #Is this appropriate?  Might be 3.
633     client.RF_setmaclen(5);
634     
635     
636     #Mac packet length, illegally 0-length address field.
637     client.RF_setpacketlen(16);
638     
639     if len(sys.argv)>2:
640         client.tune(sys.argv[2]);
641     else:
642         
643         print "Searching for ANT+.";
644         
645         guesser=AutoTuner();
646         guesser.init(client, rate=False, sync=True, chan=True);
647         guesser.selftune(threshold=2,forever=False,
648                          delay=9.0);
649     
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);
654     
655     
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.
660     while 1:
661         packet=None;
662         while packet==None:
663             #time.sleep(1);
664             packet=client.RF_rxpacket();
665             #print ".";
666         printpacket(packet);
667         sys.stdout.flush();
668
669
670
671
672 if(sys.argv[1]=="sniffsf"):
673     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
674     #TODO remove all poke() calls.
675     
676     client.poke(0x00,0x00); #Stop nRF
677     client.poke(0x01,0x00); #Disable Shockburst
678     client.poke(0x02,0x01); #Set RX Pipe 0
679     
680     client.RF_setfreq(2402 * 10**6);
681     client.poke(0x06,0x07); #1Mbps
682     client.poke(0x07,0x78); #Reset status register
683     
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);
688     
689     #Set packet length of 16.
690     client.RF_setpacketlen(4);
691     
692     #Power radio, prime for RX, one-byte checksum.
693     client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
694     
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.
698     while 1:
699         packet=None;
700         while packet==None:
701             #time.sleep(0.1);
702             packet=client.RF_rxpacket();
703         printpacket(packet);
704         sys.stdout.flush();
705
706 if(sys.argv[1]=="sniffnike"):
707     #TODO remove all poke() calls.
708     
709     client.poke(0x00,0x00); #Stop nRF
710     client.poke(0x01,0x00); #Disable Shockburst
711     client.poke(0x02,0x01); #Set RX Pipe 0
712     
713     client.RF_setfreq(2425 * 10**6);
714     client.poke(0x06,0x20|0x06); #250 kbps
715     client.poke(0x07,0x78); #Reset status register
716     
717     #Nike Settings
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?
721     
722     client.RF_setpacketlen(32); #No idea what the length is.
723     
724     #Power radio, prime for RX, two-byte checksum.
725     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two bytes.
726     
727     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
728                                            client.RF_getfreq()/10**6);
729     print "Expect some false-positives.";
730     
731     #Now we're ready to get packets.
732     while 1:
733         packet=None;
734         while packet==None:
735             #time.sleep(0.1);
736             packet=client.RF_rxpacket();
737         printpacket(packet);
738         sys.stdout.flush();
739
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
744     
745     #Disable shockburst.
746     client.poke(0x1C,0x00);
747     client.poke(0x1D,0x00);
748     
749     client.RF_setfreq((2400+0x29) * 10**6);
750     client.poke(0x06,0x00); #1Mbps
751     client.poke(0x07,0x78); #Reset status register
752     
753     client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
754     client.RF_setsmac(0x123456);
755     client.RF_setpacketlen(4);
756     
757     #Power radio, prime for RX, two-byte checksum.
758     #client.poke(0x00,0x70|0x03|0x04|0x08);
759     
760     #Power radio, prime for RX, no checksum.
761     client.poke(0x00,0x70|0x03);
762     
763     
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.
767     while 1:
768         packet=None;
769         while packet==None:
770             #time.sleep(0.1);
771             packet=client.RF_rxpacket();
772         printpacket(packet);
773         sys.stdout.flush();
774
775
776 if(sys.argv[1]=="sniff"):
777     if len(sys.argv)>2:
778         print "Set MAC to %s" % sys.argv[2];
779         client.tune(sys.argv[2]);
780         client.RF_setmaclen(5);
781         
782     #client.poke(0x00,0x00); #Stop nRF
783     client.poke(0x07,0x78); #Reset status register
784     
785     #Power radio, prime for RX, no checksum.
786     client.poke(0x00,0x70|0x03);
787     #Mac packet length.
788     client.RF_setpacketlen(32);
789     #Mac length, reduced
790     #client.RF_setmaclen(3); # SETUP_AW for shortest
791     
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.
795     
796     while 1:
797         packet=None;
798         while packet==None:
799             #time.sleep(0.1);
800             packet=client.RF_rxpacket();
801         printpacket(packet);
802         sys.stdout.flush();
803 if(sys.argv[1]=="explore"):
804     #client.poke(0x00,0x00); #Stop nRF
805     client.poke(0x07,0x78); #Reset status register
806     
807     #Power radio, prime for RX, no checksum.
808     client.poke(0x00,0x70|0x03);
809     
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
814     
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);
820             time.sleep(1);
821             packet=client.RF_rxpacket();
822             if packet!=None:
823                 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
824                                                         client.RF_getfreq()/10**6);
825                 printpacket(packet);
826                 sys.stdout.flush();