rmspeers on GoodFETCCSPI fixing RF_autocrc and adding support to act like a TinyOS...
[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." % (
154                 foo,
155                 client.RF_getrate());
156     
157     print "\n\n";
158     client.poke(0x0A,0xDEADBEEF,5);
159     #print "SMAC set to %010x" % client.RF_getsmac();
160     if client.RF_getsmac()!=0xdeadbeef:
161         print "ERROR: Failed to set MAC address.";
162     print "Final registers:"
163     printconfig();
164
165 if(sys.argv[1]=="carrier"):
166     if len(sys.argv)>2:
167         client.RF_setfreq(eval(sys.argv[2]));
168     client.RF_carrier();
169     printconfig();
170     print "\nHolding a carrier wave.";
171     while(1):
172         time.sleep(1);
173
174 if(sys.argv[1]=="tune"):
175     if len(sys.argv)>2:
176         client.tune(sys.argv[2]);
177     else:
178         print "Specify a tuning, such as 'aa,c78c65805e,14,09'";
179 if(sys.argv[1]=="regs"):
180     for r in range(0,0x20):
181         print "r[0x%02x]=0x%010x //%16s " % (r,client.peek(r),regnames[r]);
182 if(sys.argv[1]=="pyregs"):
183     for r in range(0,0x20):
184         print "client.set(0x%02x,0x%010x); #%16s " % (r,client.peek(r),regnames[r]);
185
186 if(sys.argv[1]=="peek"):
187     start=0x0000;
188     if(len(sys.argv)>2):
189         start=int(sys.argv[2],16);
190     stop=start;
191     if(len(sys.argv)>3):
192         stop=int(sys.argv[3],16);
193     print "Peeking from %02x to %02x." % (start,stop);
194     while start<=stop:
195         print "%02x: %010x" % (start,client.peek(start));
196         start=start+1;
197 if(sys.argv[1]=="poke"):
198     start=0x0000;
199     val=0x00;
200     if(len(sys.argv)>2):
201         start=int(sys.argv[2],16);
202     if(len(sys.argv)>3):
203         val=int(sys.argv[3],16);
204     print "Poking %02x to become %010x." % (start,val);
205     
206     client.poke(start,val);
207     print "Poked to %04x" % client.peek(start);
208
209 if(sys.argv[1]=="sniffob"):
210     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
211     #TODO remove all poke() calls.
212     
213     client.poke(0x00,0x00); #Stop nRF
214     client.poke(0x01,0x00); #Disable Shockburst
215     client.poke(0x02,0x01); #Set RX Pipe 0
216     
217     client.RF_setfreq(2481 * 10**6);
218     client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
219     client.poke(0x07,0x78); #Reset status register
220     
221     #OpenBeacon defines these in little endian as follows.
222     client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
223     #0x01, 0x02, 0x03, 0x02, 0x01
224     client.RF_setsmac(0x0102030201);
225     #'O', 'C', 'A', 'E', 'B'
226     client.RF_settmac(0x424541434F);
227     
228     #Set packet length of 16.
229     client.RF_setpacketlen(16);
230     
231     #Power radio, prime for RX, one-byte checksum.
232     client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
233     
234     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
235                                            client.RF_getfreq()/10**6);
236     #Now we're ready to get packets.
237     while 1:
238         packet=None;
239         while packet==None:
240             #time.sleep(0.1);
241             packet=client.RF_rxpacket();
242         printpacket(packet);
243         sys.stdout.flush();
244
245 if(sys.argv[1]=="regbits"):
246     print "Scanning registers to determine which bits are valid."
247     regbits=range(0,0x30);
248     for r in range(0,0x30):
249         old=client.peek(r);
250         #Which bits can be set?
251         client.poke(r,0xFF);
252         ones=client.peek(r);
253         #Which bits can be clear?
254         client.poke(r,0x00);
255         zeroes=client.peek(r);
256         regbits[r]=(ones & (~zeroes));
257     for r in range(0,0x30):
258         if regbits[r]!=0:
259             print "r[0x%02x] masked %02x // %s" % (r,regbits[r], regnames[r]);
260 if(sys.argv[1]=="sniffprom"):
261     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
262     #TODO remove all poke() calls.
263     
264     client.poke(0x00,0x00); #Stop nRF
265     client.poke(0x01,0x00); #Disable Shockburst
266     client.poke(0x02,0x01); #Set RX Pipe 0
267     
268     #client.RF_setfreq(2481 * 10**6);
269     #client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
270     client.poke(0x07,0x78); #Reset status register
271     
272     #OpenBeacon defines these in little endian as follows.
273     client.RF_setmaclen(2); # SETUP_AW for shortest
274     
275     #It's better to have a known fragment, when one is available.
276     #client.RF_setsmac(0x00AA);
277     #client.RF_setsmac(0x0055);
278     
279     #Should end in 55 or AA depending upon the packet.
280     tail=0x55
281     if(len(sys.argv)>2):
282         tail=int(sys.argv[2],16);
283     else:
284         print "Please specify a tail of 0xAA or 0x55.";
285         sys.exit(1);
286     client.RF_setsmac(tail);
287     
288     #Longest length.
289     client.RF_setpacketlen(32);
290     
291     #Power radio, prime for RX, no checksum
292     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
293     
294     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
295                                            client.RF_getfreq()/10**6);
296     #Now we're ready to get packets.
297     while 1:
298         packet=None;
299         while packet==None:
300             #time.sleep(0.1);
301             packet=client.RF_rxpacket();
302         printpacket(packet);
303         sys.stdout.flush();
304
305 class AutoTuner():
306     """This guesses addresses by searching through packets."""
307     addresses={};
308     client=None;
309     
310     #Limits on search space, because you usually know what you're looking for.
311     rate=False;
312     chan=False;
313     sync=False;
314     macreject=False;
315     printing=False;
316     startch=0; #Useful for forcing an early match.
317     def init(self,goodfet,
318              rate=True,chan=True,sync=True, macreject=True, printing=False):
319         """Initializes a link to the GoodFET for autotuning."""
320         self.client=goodfet;
321         self.rate=rate;
322         self.chan=chan;
323         self.sync=sync;
324         self.macreject=macreject;
325         self.printing=printing;
326         
327         client.poke(0x00,0x00); #Stop nRF
328         client.poke(0x01,0x00); #Disable Shockburst
329         client.poke(0x02,0x01); #Set RX Pipe 0
330         
331         #Disable shockburst.
332         client.poke(0x1C,0x00);
333         client.poke(0x1D,0x00);
334         
335         client.RF_setmaclen(2); # SETUP_AW for shortest
336         
337         #historic
338         #client.RF_setsmac(0x00AA);
339         #client.RF_setsmac(0x0055);
340         
341         client.poke(0x00,0x70|0x03); #prime radio.
342         
343         return;
344     def packetaddr(self,packet,justmac=False):
345         """Returns a loaded packet address, including channel and rate."""
346         
347         sync=self.client.RF_getsmac()&0xFF;
348         
349         mac="";
350         #MAC,RF_CH,RATE
351         for i in range(0,5):
352             mac="%s%02x" % (mac,ord(packet[i]));
353         if justmac:
354             return mac;
355         ch=self.client.peek(0x05);
356         rate=self.client.peek(0x06);
357         return "%02x,%s,%02x,%02x" % (
358             sync,mac,ch,rate);
359     def validmac(self,packet):
360         sync=self.client.RF_getsmac()&0xFF;
361         mac=self.packetaddr(packet,justmac=True);
362         
363         #BT preamble is A or 5.
364         #Fix this to work on the smallest bit, not the highest.
365         if ((ord(packet[0])&0x80)^(sync&0x80)) and self.macreject:
366             #print "%02x%02x invalid entry." % (sync,ord(packet[0]));
367             #This is a special kind of failure.  Freq is probably right, but MAC is wrong.
368             return False;
369         if mac=='5555555555' or mac=='aaaaaaaaaa' or mac=='0000000000' or mac=='ffffffffff':
370             return False;
371         return True;
372         
373     def handle(self,packet):
374         """Handles a packet."""
375         if self.printing:
376             printpacket(packet);
377         
378         if not self.validmac(packet):
379             #print "Dropped packet from %s" % self.packetaddr(packet,justmac=True);
380             #printpacket(packet);
381             return;
382         
383         addr=self.packetaddr(packet);
384         
385         #Increment the address count.
386         count=0;
387         try:
388             count=self.addresses[addr];
389         except:
390             pass;
391         self.addresses[addr]=count+1;
392         rate=count*1.0/len(self.addresses);
393         if self.addresses[addr]>1 or rate>0.01:
394             print "'%s' looks valid\t%i\t%0.5f" % (
395                 addr,count,rate);
396         return addr;
397     tunecount=0;
398     def selftune(self,threshold=2,forever=False,
399                  delay=5.0):
400         """Tunes to the first strong signal.
401         It's important that this not get triggered by false positives."""
402         
403         while 1:
404             self.retune();
405             start=time.mktime(time.localtime());
406             sys.stdout.flush();
407             while (time.mktime(time.localtime())-start) < delay:
408                 packet=None;
409                 while packet==None:
410                     packet=client.RF_rxpacket();
411                 addr=guesser.handle(packet);
412                 try:
413                     count=self.addresses[addr];
414                 except:
415                     count=0;
416                 if count>threshold and forever==False:
417                     #Tune it in here?
418                     client.tune(addr);
419                     return addr;
420             
421         
422     def retune(self):
423         """Tunes to another channel or preamble looking for the next packet."""
424         count=self.tunecount;
425         self.tunecount=count+1;
426         
427         #Swap the SYNC value most often.
428         if self.sync:
429             sync=0x00AA;
430             if count&1:
431                 sync=0x0055;
432             self.client.RF_setsmac(sync);
433             count=(count>>1);
434         
435         if self.rate:
436             #Then the data rate.
437             rate=0;
438             
439             #This swaps between 1Mbps and 2Mbps.
440             #TODO add support for 256kbps, if anyone uses it.
441             if count&1:
442                 rate=rate|0x08;
443             #print "Setting rate to 0x%02x" % rate;
444             if(rate==0x20):
445                 rate=0x08;
446             self.client.poke(0x06,rate);
447             count=(count>>1);
448         
449         if self.chan:
450             self.client.poke(0x05,
451                              (count+self.startch)&0x7f);
452             print "Tuned to %i MHz" % (
453                 self.client.RF_getfreq()
454                 /(10**6));
455         #Grab two packets to clear buffers.
456         #Should retune only after a few packets to reduce this delay.
457         packet=client.RF_rxpacket();
458         packet=client.RF_rxpacket();
459         return;
460         
461         
462 if(sys.argv[1]=="autotune"):
463     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
464     #TODO remove all poke() calls.
465     guesser=AutoTuner();
466     guesser.init(client,rate=True,sync=True,chan=True);
467     
468     
469     #client.RF_setfreq(2481 * 10**6);
470     client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
471     client.poke(0x07,0x78); #Reset status register
472     
473     #This is determined by the MAC, which we don't yet know.
474     
475     #Longest length.
476     client.RF_setpacketlen(32);
477     
478     #Power radio, prime for RX, no checksum
479     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
480     
481     print "Autotuning on %i MHz" % (
482         client.RF_getfreq()/10**6);
483     print "sync,mac,r5,r6";
484     #Now we're ready to get packets.
485     guesser.selftune(threshold=2,
486                      forever=True);
487
488 if(sys.argv[1]=="autotunebt"):
489     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
490     #TODO remove all poke() calls.
491     guesser=AutoTuner();
492     guesser.init(client,rate=True,sync=False,chan=True,
493                  macreject=False, printing=True);
494     
495     
496     #client.RF_setfreq(2481 * 10**6);
497     client.poke(0x06,0x00); #1MBps
498     client.poke(0x07,0x78); #Reset status register
499     
500     #Bluetooth preamble is 0xA; BTLE is 0xAA.
501     client.RF_setsmac(0x000A);
502     
503     #Longest length.
504     client.RF_setpacketlen(32);
505     
506     #Power radio, prime for RX, no checksum
507     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
508     
509     print "Autotuning on %i MHz" % (
510         client.RF_getfreq()/10**6);
511     print "sync,mac,r5,r6";
512     #Now we're ready to get packets.
513     guesser.selftune(threshold=2,
514                      forever=True);
515
516 if(sys.argv[1]=="sniffmacs"):
517     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
518     #TODO remove all poke() calls.
519     guesser=AutoTuner();
520     guesser.init(client,rate=False,sync=True,chan=False);
521     
522     #Longest length.
523     client.RF_setpacketlen(32);
524     
525     #Power radio, prime for RX, no checksum
526     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two.
527     
528     print "Holding autotune 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,
533                      forever=True);
534
535 if(sys.argv[1]=="sniffmskb"):
536     #MSWK 3000 v2.0
537     #TODO remove all poke() calls.
538     
539     client.poke(0x00,0x00); #Stop nRF
540     client.poke(0x01,0x00); #Disable Shockburst
541     client.poke(0x02,0x01); #Set RX Pipe 0
542     
543     client.poke(0x06,0x09); #2MBps, -18dBm in RF_SETUP
544     client.poke(0x07,0x78); #Reset status register
545     
546     #This is the address of a specific keyboard.
547     #Other keyboards will be different.
548     
549     client.RF_setmaclen(5);
550     
551     #Known pairs.  The channel and the low address bytes must match.
552     #client.RF_setfreq((2400+0x13) * 10**6);
553     #client.RF_setsmac(0xc00a3598cd);
554     
555     #client.RF_setfreq((2400+0x15) * 10**6);
556     #client.RF_setsmac(0xc10446facd);
557     
558     #Mac packet length, illegally 0-length address field.
559     client.RF_setpacketlen(16);
560     
561     #aa,c00a3598cd,13,09
562     if len(sys.argv)>2:
563         client.tune(sys.argv[2]);
564     else:
565         
566         print "Searching for a keyboard.";
567         
568         guesser=AutoTuner();
569         guesser.init(client, rate=False, sync=True, chan=True);
570         guesser.selftune(threshold=4,forever=False,
571                          delay=10.0);
572     
573     client.poke(0x00,0x00); #Stop nRF
574     client.poke(0x01,0x00); #Disable Shockburst
575     client.poke(0x02,0x01); #Set RX Pipe 0
576     client.RF_setmaclen(5);
577     
578     #Finally, dynamic payload lengths need to be enabled.
579     #client.poke(0x01,0x01);
580     client.poke(0x1C,0x01);
581     client.poke(0x1D,0x06);
582     
583     client.poke(0x00,0x70|0x03); #prime radio.
584     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
585                                            client.RF_getfreq()/10**6);
586     #Now we're ready to get packets.
587     while 1:
588         packet=None;
589         while packet==None:
590             #time.sleep(1);
591             packet=client.RF_rxpacket();
592             #print ".";
593         printmspacket(packet);
594         sys.stdout.flush();
595
596 if(sys.argv[1]=="sniffant"):
597     #Prototyped on Garmin device.
598     #Channel hopping is pretty damned fast, hard to follow.
599     #This doesn't really work yet, still experimenting.
600     
601     #Might be more effective to sniff knowing the MFG ID and Dev. ID,
602     #as these predict a lot of the MAC address.
603     
604     client.poke(0x00,0x00); #Stop nRF
605     client.poke(0x01,0x00); #Disable Shockburst
606     client.poke(0x02,0x01); #Set RX Pipe 0
607     
608     client.poke(0x05,57); #broadcast-only channel
609     client.poke(0x06,0x00); #1MBps
610     client.poke(0x07,0x78); #Reset status register
611     
612     #Is this appropriate?  Might be 3.
613     client.RF_setmaclen(5);
614     
615     
616     #Mac packet length, illegally 0-length address field.
617     client.RF_setpacketlen(16);
618     
619     if len(sys.argv)>2:
620         client.tune(sys.argv[2]);
621     else:
622         
623         print "Searching for ANT+.";
624         
625         guesser=AutoTuner();
626         guesser.init(client, rate=False, sync=True, chan=True);
627         guesser.selftune(threshold=2,forever=False,
628                          delay=9.0);
629     
630     client.poke(0x00,0x00); #Stop nRF
631     client.poke(0x01,0x00); #Disable Shockburst
632     client.poke(0x02,0x01); #Set RX Pipe 0
633     client.RF_setmaclen(5);
634     
635     
636     client.poke(0x00,0x70|0x03); #prime radio.
637     print "Dumping ANT as %010x on %i MHz" % (client.RF_getsmac(),
638                                               client.RF_getfreq()/10**6);
639     #Now we're ready to get packets.
640     while 1:
641         packet=None;
642         while packet==None:
643             #time.sleep(1);
644             packet=client.RF_rxpacket();
645             #print ".";
646         printpacket(packet);
647         sys.stdout.flush();
648
649
650
651
652 if(sys.argv[1]=="sniffsf"):
653     #Reversal of transmitter code from nRF_CMD.c of OpenBeacon
654     #TODO remove all poke() calls.
655     
656     client.poke(0x00,0x00); #Stop nRF
657     client.poke(0x01,0x00); #Disable Shockburst
658     client.poke(0x02,0x01); #Set RX Pipe 0
659     
660     client.RF_setfreq(2402 * 10**6);
661     client.poke(0x06,0x07); #1Mbps
662     client.poke(0x07,0x78); #Reset status register
663     
664     #OpenBeacon defines these in little endian as follows.
665     client.RF_setmaclen(5); # SETUP_AW for 5-byte addresses.
666     client.RF_setsmac(0xe7e7e7e7e7);
667     client.RF_settmac(0xe7e7e7e7e7);
668     
669     #Set packet length of 16.
670     client.RF_setpacketlen(4);
671     
672     #Power radio, prime for RX, one-byte checksum.
673     client.poke(0x00,0x70|0x03|0x08); #0x08 for one byte, 0x04 for two.
674     
675     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
676                                            client.RF_getfreq()/10**6);
677     #Now we're ready to get packets.
678     while 1:
679         packet=None;
680         while packet==None:
681             #time.sleep(0.1);
682             packet=client.RF_rxpacket();
683         printpacket(packet);
684         sys.stdout.flush();
685
686 if(sys.argv[1]=="sniffnike"):
687     #TODO remove all poke() calls.
688     
689     client.poke(0x00,0x00); #Stop nRF
690     client.poke(0x01,0x00); #Disable Shockburst
691     client.poke(0x02,0x01); #Set RX Pipe 0
692     
693     client.RF_setfreq(2425 * 10**6);
694     client.poke(0x06,0x20|0x06); #250 kbps
695     client.poke(0x07,0x78); #Reset status register
696     
697     #Nike Settings
698     client.RF_setmaclen(2); # Illegal by datasheet, but it works!
699     client.RF_setsmac(0xc2bd);
700     client.RF_settmac(0xc2bd); #Should we forge data?
701     
702     client.RF_setpacketlen(32); #No idea what the length is.
703     
704     #Power radio, prime for RX, two-byte checksum.
705     client.poke(0x00,0x70|0x03); #0x08 for checksum, 0x04 for two bytes.
706     
707     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
708                                            client.RF_getfreq()/10**6);
709     print "Expect some false-positives.";
710     
711     #Now we're ready to get packets.
712     while 1:
713         packet=None;
714         while packet==None:
715             #time.sleep(0.1);
716             packet=client.RF_rxpacket();
717         printpacket(packet);
718         sys.stdout.flush();
719
720 if(sys.argv[1]=="snifftp"):
721     client.poke(0x00,0x00); #Stop nRF
722     client.poke(0x01,0x00); #Disable Shockburst
723     client.poke(0x02,0x01); #Set RX Pipe 0
724     
725     #Disable shockburst.
726     client.poke(0x1C,0x00);
727     client.poke(0x1D,0x00);
728     
729     client.RF_setfreq((2400+0x29) * 10**6);
730     client.poke(0x06,0x00); #1Mbps
731     client.poke(0x07,0x78); #Reset status register
732     
733     client.RF_setmaclen(3); # SETUP_AW for 3-byte addresses.
734     client.RF_setsmac(0x123456);
735     client.RF_setpacketlen(4);
736     
737     #Power radio, prime for RX, two-byte checksum.
738     client.poke(0x00,0x70|0x03|0x04|0x08);
739     
740     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
741                                            client.RF_getfreq()/10**6);
742     #Now we're ready to get packets.
743     while 1:
744         packet=None;
745         while packet==None:
746             #time.sleep(0.1);
747             packet=client.RF_rxpacket();
748         printpacket(packet);
749         sys.stdout.flush();
750
751
752 if(sys.argv[1]=="sniff"):
753     if len(sys.argv)>2:
754         print "Set MAC to %s" % sys.argv[2];
755         client.tune(sys.argv[2]);
756         client.RF_setmaclen(5);
757         
758     #client.poke(0x00,0x00); #Stop nRF
759     client.poke(0x07,0x78); #Reset status register
760     
761     #Power radio, prime for RX, no checksum.
762     client.poke(0x00,0x70|0x03);
763     #Mac packet length.
764     client.RF_setpacketlen(32);
765     #Mac length, reduced
766     #client.RF_setmaclen(3); # SETUP_AW for shortest
767     
768     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
769                                            client.RF_getfreq()/10**6);
770     #Now we're ready to get packets.
771     
772     while 1:
773         packet=None;
774         while packet==None:
775             #time.sleep(0.1);
776             packet=client.RF_rxpacket();
777         printpacket(packet);
778         sys.stdout.flush();
779 if(sys.argv[1]=="explore"):
780     #client.poke(0x00,0x00); #Stop nRF
781     client.poke(0x07,0x78); #Reset status register
782     
783     #Power radio, prime for RX, no checksum.
784     client.poke(0x00,0x70|0x03);
785     
786     #Set packet length of 32.
787     #Without checksums, extra data will mix in.
788     client.RF_setpacketlen(32);
789     client.RF_setmaclen(3); # shortest address length
790     
791     #Now we're ready to get packets.
792     for smac in [0x0102030201, 0]:
793         client.RF_setsmac(smac);
794         for chan in range(0,0x80):
795             client.RF_setfreq((2400+chan) * 10**6);
796             time.sleep(1);
797             packet=client.RF_rxpacket();
798             if packet!=None:
799                 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
800                                                         client.RF_getfreq()/10**6);
801                 printpacket(packet);
802                 sys.stdout.flush();