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