'goodfet.nrf autotunebt' gets some fragments of Bluetooth, but doesn't do error corre...
[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         else:
91             print "Unknown character 0x%02x." % ct[9];
92             letter=ord('?');
93     if letter!=None:
94         mskbstring="%s%c" % (mskbstring,letter);
95     print "# %s" % mskbstring
96 def printconfig():
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();
104
105
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];
113     print "";
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];
120     print "";
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];
124     print "";
125     print "%s carrier [freq]\n\tHolds a carrier on [freq] Hz." % sys.argv[0];
126     sys.exit();
127
128 #Initialize FET and set baud rate
129 client=GoodFETNRF();
130 client.serInit()
131
132 client.NRFsetup();
133
134 if(sys.argv[1]=="info"):
135     printconfig();
136
137 if(sys.argv[1]=="test"):
138     print "Old registers:"
139     printconfig();
140     
141     # Set PWR_UP=1 and PRIM_RX=0 in CONFIG.
142     client.poke(0x00,2);
143     #Delay of 1.5ms by round-trip.
144     
145     print "\n\n";
146     
147     #Try all data rates
148     for foo in [250*10**3,
149                 1*10**6,
150                 2*10**6]:
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());
155     
156     print "\n\n";
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:"
162     printconfig();
163
164 if(sys.argv[1]=="carrier"):
165     if len(sys.argv)>2:
166         client.RF_setfreq(eval(sys.argv[2]));
167     client.RF_carrier();
168     printconfig();
169     print "\nHolding a carrier wave.";
170     while(1):
171         time.sleep(1);
172
173 if(sys.argv[1]=="tune"):
174     if len(sys.argv)>2:
175         client.tune(sys.argv[2]);
176     else:
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]);
184
185 if(sys.argv[1]=="peek"):
186     start=0x0000;
187     if(len(sys.argv)>2):
188         start=int(sys.argv[2],16);
189     stop=start;
190     if(len(sys.argv)>3):
191         stop=int(sys.argv[3],16);
192     print "Peeking from %02x to %02x." % (start,stop);
193     while start<=stop:
194         print "%02x: %010x" % (start,client.peek(start));
195         start=start+1;
196 if(sys.argv[1]=="poke"):
197     start=0x0000;
198     val=0x00;
199     if(len(sys.argv)>2):
200         start=int(sys.argv[2],16);
201     if(len(sys.argv)>3):
202         val=int(sys.argv[3],16);
203     print "Poking %02x to become %010x." % (start,val);
204     
205     client.poke(start,val);
206     print "Poked to %04x" % client.peek(start);
207
208 if(sys.argv[1]=="sniffob"):
209     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
210     #TODO remove all poke() calls.
211     
212     client.poke(0x00,0x00); #Stop nRF
213     client.poke(0x01,0x00); #Disable Shockburst
214     client.poke(0x02,0x01); #Set RX Pipe 0
215     
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
219     
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);
226     
227     #Set packet length of 16.
228     client.RF_setpacketlen(16);
229     
230     #Power radio, prime for RX, one-byte checksum.
231     client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
232     
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.
236     while 1:
237         packet=None;
238         while packet==None:
239             #time.sleep(0.1);
240             packet=client.RF_rxpacket();
241         printpacket(packet);
242         sys.stdout.flush();
243
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):
248         old=client.peek(r);
249         #Which bits can be set?
250         client.poke(r,0xFF);
251         ones=client.peek(r);
252         #Which bits can be clear?
253         client.poke(r,0x00);
254         zeroes=client.peek(r);
255         regbits[r]=(ones & (~zeroes));
256     for r in range(0,0x30):
257         if regbits[r]!=0:
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.
262     
263     client.poke(0x00,0x00); #Stop nRF
264     client.poke(0x01,0x00); #Disable Shockburst
265     client.poke(0x02,0x01); #Set RX Pipe 0
266     
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
270     
271     #OpenBeacon defines these in little endian as follows.
272     client.RF_setmaclen(2); # SETUP_AW for shortest
273     
274     #It's better to have a known fragment, when one is available.
275     #client.RF_setsmac(0x00AA);
276     #client.RF_setsmac(0x0055);
277     
278     #Should end in 55 or AA depending upon the packet.
279     tail=0x55
280     if(len(sys.argv)>2):
281         tail=int(sys.argv[2],16);
282     else:
283         print "Please specify a tail of 0xAA or 0x55.";
284         sys.exit(1);
285     client.RF_setsmac(tail);
286     
287     #Longest length.
288     client.RF_setpacketlen(32);
289     
290     #Power radio, prime for RX, no checksum
291     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
292     
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.
296     while 1:
297         packet=None;
298         while packet==None:
299             #time.sleep(0.1);
300             packet=client.RF_rxpacket();
301         printpacket(packet);
302         sys.stdout.flush();
303
304 class AutoTuner():
305     """This guesses addresses by searching through packets."""
306     addresses={};
307     client=None;
308     
309     #Limits on search space, because you usually know what you're looking for.
310     rate=False;
311     chan=False;
312     sync=False;
313     macreject=False;
314     printing=False;
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."""
319         self.client=goodfet;
320         self.rate=rate;
321         self.chan=chan;
322         self.sync=sync;
323         self.macreject=macreject;
324         self.printing=printing;
325         
326         client.poke(0x00,0x00); #Stop nRF
327         client.poke(0x01,0x00); #Disable Shockburst
328         client.poke(0x02,0x01); #Set RX Pipe 0
329         
330         #Disable shockburst.
331         client.poke(0x1C,0x00);
332         client.poke(0x1D,0x00);
333         
334         client.RF_setmaclen(2); # SETUP_AW for shortest
335         
336         #historic
337         #client.RF_setsmac(0x00AA);
338         #client.RF_setsmac(0x0055);
339         
340         client.poke(0x00,0x70|0x03); #prime radio.
341         
342         return;
343     def packetaddr(self,packet,justmac=False):
344         """Returns a loaded packet address, including channel and rate."""
345         
346         sync=self.client.RF_getsmac()&0xFF;
347         
348         mac="";
349         #MAC,RF_CH,RATE
350         for i in range(0,5):
351             mac="%s%02x" % (mac,ord(packet[i]));
352         if justmac:
353             return mac;
354         ch=self.client.peek(0x05);
355         rate=self.client.peek(0x06);
356         return "%02x,%s,%02x,%02x" % (
357             sync,mac,ch,rate);
358     def validmac(self,packet):
359         sync=self.client.RF_getsmac()&0xFF;
360         mac=self.packetaddr(packet,justmac=True);
361         
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.
367             return False;
368         if mac=='5555555555' or mac=='aaaaaaaaaa' or mac=='0000000000' or mac=='ffffffffff':
369             return False;
370         return True;
371         
372     def handle(self,packet):
373         """Handles a packet."""
374         if self.printing:
375             printpacket(packet);
376         
377         if not self.validmac(packet):
378             #print "Dropped packet from %s" % self.packetaddr(packet,justmac=True);
379             #printpacket(packet);
380             return;
381         
382         addr=self.packetaddr(packet);
383         
384         #Increment the address count.
385         count=0;
386         try:
387             count=self.addresses[addr];
388         except:
389             pass;
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" % (
394                 addr,count,rate);
395         return addr;
396     tunecount=0;
397     def selftune(self,threshold=2,forever=False,
398                  delay=5.0):
399         """Tunes to the first strong signal.
400         It's important that this not get triggered by false positives."""
401         
402         while 1:
403             self.retune();
404             start=time.mktime(time.localtime());
405             sys.stdout.flush();
406             while (time.mktime(time.localtime())-start) < delay:
407                 packet=None;
408                 while packet==None:
409                     packet=client.RF_rxpacket();
410                 addr=guesser.handle(packet);
411                 try:
412                     count=self.addresses[addr];
413                 except:
414                     count=0;
415                 if count>threshold and forever==False:
416                     #Tune it in here?
417                     client.tune(addr);
418                     return addr;
419             
420         
421     def retune(self):
422         """Tunes to another channel or preamble looking for the next packet."""
423         count=self.tunecount;
424         self.tunecount=count+1;
425         
426         #Swap the SYNC value most often.
427         if self.sync:
428             sync=0x00AA;
429             if count&1:
430                 sync=0x0055;
431             self.client.RF_setsmac(sync);
432             count=(count>>1);
433         
434         if self.rate:
435             #Then the data rate.
436             rate=0;
437             
438             #This swaps between 1Mbps and 2Mbps.
439             #TODO add support for 256kbps, if anyone uses it.
440             if count&1:
441                 rate=rate|0x08;
442             #print "Setting rate to 0x%02x" % rate;
443             if(rate==0x20):
444                 rate=0x08;
445             self.client.poke(0x06,rate);
446             count=(count>>1);
447         
448         if self.chan:
449             self.client.poke(0x05,
450                              (count+self.startch)&0x7f);
451             print "Tuned to %i MHz" % (
452                 self.client.RF_getfreq()
453                 /(10**6));
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();
458         return;
459         
460         
461 if(sys.argv[1]=="autotune"):
462     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
463     #TODO remove all poke() calls.
464     guesser=AutoTuner();
465     guesser.init(client,rate=True,sync=True,chan=True);
466     
467     
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
471     
472     #This is determined by the MAC, which we don't yet know.
473     
474     #Longest length.
475     client.RF_setpacketlen(32);
476     
477     #Power radio, prime for RX, no checksum
478     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
479     
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,
485                      forever=True);
486
487 if(sys.argv[1]=="autotunebt"):
488     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
489     #TODO remove all poke() calls.
490     guesser=AutoTuner();
491     guesser.init(client,rate=True,sync=False,chan=True,
492                  macreject=False, printing=True);
493     
494     
495     #client.RF_setfreq(2481 * 10**6);
496     client.poke(0x06,0x00); #1MBps
497     client.poke(0x07,0x78); #Reset status register
498     
499     #Bluetooth preamble is 0xA; BTLE is 0xAA.
500     client.RF_setsmac(0x000A);
501     
502     #Longest length.
503     client.RF_setpacketlen(32);
504     
505     #Power radio, prime for RX, no checksum
506     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
507     
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,
513                      forever=True);
514
515 if(sys.argv[1]=="sniffmacs"):
516     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
517     #TODO remove all poke() calls.
518     guesser=AutoTuner();
519     guesser.init(client,rate=False,sync=True,chan=False);
520     
521     #Longest length.
522     client.RF_setpacketlen(32);
523     
524     #Power radio, prime for RX, no checksum
525     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
526     
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,
532                      forever=True);
533
534 if(sys.argv[1]=="sniffmskb"):
535     #MSWK 3000 v2.0
536     #TODO remove all poke() calls.
537     
538     client.poke(0x00,0x00); #Stop nRF
539     client.poke(0x01,0x00); #Disable Shockburst
540     client.poke(0x02,0x01); #Set RX Pipe 0
541     
542     client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
543     client.poke(0x07,0x78); #Reset status register
544     
545     #This is the address of a specific keyboard.
546     #Other keyboards will be different.
547     
548     client.RF_setmaclen(5);
549     
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);
553     
554     #client.RF_setfreq((2400+0x15) * 10**6);
555     #client.RF_setsmac(0xc10446facd);
556     
557     #Mac packet length, illegally 0-length address field.
558     client.RF_setpacketlen(16);
559     
560     #aa,c00a3598cd,13,09
561     if len(sys.argv)>2:
562         client.tune(sys.argv[2]);
563     else:
564         
565         print "Searching for a keyboard.";
566         
567         guesser=AutoTuner();
568         guesser.init(client, rate=False, sync=True, chan=True);
569         guesser.selftune(threshold=4,forever=False,
570                          delay=10.0);
571     
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);
576     
577     #Finally, dynamic payload lengths need to be enabled.
578     #client.poke(0x01,0x01);
579     client.poke(0x1C,0x01);
580     client.poke(0x1D,0x06);
581     
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.
586     while 1:
587         packet=None;
588         while packet==None:
589             #time.sleep(1);
590             packet=client.RF_rxpacket();
591             #print ".";
592         printmspacket(packet);
593         sys.stdout.flush();
594
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.
599     
600     #Might be more effective to sniff knowing the MFG ID and Dev. ID,
601     #as these predict a lot of the MAC address.
602     
603     client.poke(0x00,0x00); #Stop nRF
604     client.poke(0x01,0x00); #Disable Shockburst
605     client.poke(0x02,0x01); #Set RX Pipe 0
606     
607     client.poke(0x05,57); #broadcast-only channel
608     client.poke(0x06,0x00); #1MBps
609     client.poke(0x07,0x78); #Reset status register
610     
611     #Is this appropriate?  Might be 3.
612     client.RF_setmaclen(5);
613     
614     
615     #Mac packet length, illegally 0-length address field.
616     client.RF_setpacketlen(16);
617     
618     if len(sys.argv)>2:
619         client.tune(sys.argv[2]);
620     else:
621         
622         print "Searching for ANT+.";
623         
624         guesser=AutoTuner();
625         guesser.init(client, rate=False, sync=True, chan=True);
626         guesser.selftune(threshold=2,forever=False,
627                          delay=9.0);
628     
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);
633     
634     
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.
639     while 1:
640         packet=None;
641         while packet==None:
642             #time.sleep(1);
643             packet=client.RF_rxpacket();
644             #print ".";
645         printpacket(packet);
646         sys.stdout.flush();
647
648
649
650
651 if(sys.argv[1]=="sniffsf"):
652     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
653     #TODO remove all poke() calls.
654     
655     client.poke(0x00,0x00); #Stop nRF
656     client.poke(0x01,0x00); #Disable Shockburst
657     client.poke(0x02,0x01); #Set RX Pipe 0
658     
659     client.RF_setfreq(2402 * 10**6);
660     client.poke(0x06,0x07); #1Mbps
661     client.poke(0x07,0x78); #Reset status register
662     
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);
667     
668     #Set packet length of 16.
669     client.RF_setpacketlen(4);
670     
671     #Power radio, prime for RX, one-byte checksum.
672     client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
673     
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.
677     while 1:
678         packet=None;
679         while packet==None:
680             #time.sleep(0.1);
681             packet=client.RF_rxpacket();
682         printpacket(packet);
683         sys.stdout.flush();
684
685 if(sys.argv[1]=="snifftp"):
686     client.poke(0x00,0x00); #Stop nRF
687     client.poke(0x01,0x00); #Disable Shockburst
688     client.poke(0x02,0x01); #Set RX Pipe 0
689     
690     #Disable shockburst.
691     client.poke(0x1C,0x00);
692     client.poke(0x1D,0x00);
693     
694     client.RF_setfreq((2400+0x29) * 10**6);
695     client.poke(0x06,0x00); #1Mbps
696     client.poke(0x07,0x78); #Reset status register
697     
698     client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
699     client.RF_setsmac(0x123456);
700     client.RF_setpacketlen(4);
701     
702     #Power radio, prime for RX, two-byte checksum.
703     client.poke(0x00,0x70|0x03|0x04|0x08);
704     
705     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
706                                            client.RF_getfreq()/10**6);
707     #Now we're ready to get packets.
708     while 1:
709         packet=None;
710         while packet==None:
711             #time.sleep(0.1);
712             packet=client.RF_rxpacket();
713         printpacket(packet);
714         sys.stdout.flush();
715
716
717 if(sys.argv[1]=="sniff"):
718     if len(sys.argv)>2:
719         print "Set MAC to %s" % sys.argv[2];
720         client.tune(sys.argv[2]);
721         client.RF_setmaclen(5);
722         
723     #client.poke(0x00,0x00); #Stop nRF
724     client.poke(0x07,0x78); #Reset status register
725     
726     #Power radio, prime for RX, no checksum.
727     client.poke(0x00,0x70|0x03);
728     #Mac packet length.
729     client.RF_setpacketlen(32);
730     #Mac length, reduced
731     #client.RF_setmaclen(3); # SETUP_AW for shortest
732     
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.
736     
737     while 1:
738         packet=None;
739         while packet==None:
740             #time.sleep(0.1);
741             packet=client.RF_rxpacket();
742         printpacket(packet);
743         sys.stdout.flush();
744 if(sys.argv[1]=="explore"):
745     #client.poke(0x00,0x00); #Stop nRF
746     client.poke(0x07,0x78); #Reset status register
747     
748     #Power radio, prime for RX, no checksum.
749     client.poke(0x00,0x70|0x03);
750     
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
755     
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);
761             time.sleep(1);
762             packet=client.RF_rxpacket();
763             if packet!=None:
764                 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
765                                                         client.RF_getfreq()/10**6);
766                 printpacket(packet);
767                 sys.stdout.flush();