Make GoodFETCCSPI.py return True if a register poke succeeds, else False. Also change...
[goodfet] / client / goodfet.ccspi
1 #!/usr/bin/env python
2
3 #GoodFET Chipcon SPI Client
4 # (C) 2011 Travis Goodspeed
5 # Additions 2011-2012 Ryan Speers ryan@rmspeers.com
6
7 #N.B.,
8 #Might be CC2420 Specific
9
10 import sys;
11 import binascii;
12 import array, time;
13
14 from GoodFETCCSPI import GoodFETCCSPI;
15
16 if(len(sys.argv)==1):
17     print "Usage: %s verb [objects]\n" % sys.argv[0];
18     print "%s info" % sys.argv[0];
19     print "%s regs" % sys.argv[0];
20     print "%s test" % sys.argv[0];
21     print "%s peek 0x$start [0x$stop]" % sys.argv[0];
22     print "%s poke 0x$adr 0x$val" % sys.argv[0];
23     print "%s txtest" % sys.argv[0];
24     
25     print "\n%s rssi" % sys.argv[0];
26     print "%s sniff [chan]" % sys.argv[0];
27     print "%s bsniff [chan]" % sys.argv[0];
28     print "%s sniffdissect" % sys.argv[0];
29     
30     print "\n%s txtoscount [-i|-r]   TinyOS BlinkToLED" % sys.argv[0];
31     print "%s reflexjam [channel=11] [delay=0]" % sys.argv[0];
32
33     sys.exit();
34
35 #Initialize FET and set baud rate
36 client=GoodFETCCSPI();
37 client.serInit()
38
39 client.setup();
40
41 #Dummy read.
42 #Might read as all ones if chip has a startup delay.
43
44 if(sys.argv[1]=="carrier"):
45     if len(sys.argv)>2:
46         client.RF_setfreq(eval(sys.argv[2]));
47     while 1:
48         client.RF_carrier();
49     while(1):
50         time.sleep(1);
51
52 if(sys.argv[1]=="modulated_spectrum"):
53     if len(sys.argv)>2:
54         client.RF_setfreq(eval(sys.argv[2]));
55     while 1:
56         client.RF_modulated_spectrum();
57     while(1):
58         time.sleep(1);
59
60 if(sys.argv[1]=="reflexjam" or sys.argv[1]=="reflexjamack"):
61     #Setup the radio to listen promiscously on a frequency
62     client.RF_promiscuity(1);
63     client.RF_autocrc(0);
64     if len(sys.argv)>2:
65         freq=eval(sys.argv[2]);
66         if freq>100:
67             client.RF_setfreq(freq);
68         else:
69             client.RF_setchan(freq);
70     duration=0;
71     if len(sys.argv)>3:
72         duration=eval(sys.argv[3]);
73     client.CC_RFST_RX();
74     print "Reflexively jamming on %i MHz" % (client.RF_getfreq()/10**6);
75     #Now we let the firmware take over, watching for packets and jamming them.
76     #Standard reflexive jam is done with duration=0.
77     #To selectively jam packets that are above a certain length, set duration
78     # to the number of milliseconds needed to jam frames of that length.
79     # Api-Do project has script available to tune/test this duration.
80     #  code.google.com/p/zigbeesecurity (rmspeers)
81     if sys.argv[1]=="reflexjam":
82         client.RF_reflexjam(duration);
83     elif sys.argv[1]=="reflexjamack":
84         client.RF_reflexjam_autoack();
85
86 if(sys.argv[1]=="info"):
87     print "Found   %s" % client.identstr();
88     print "Freq:   %05f MHz" % (client.RF_getfreq()/(10**6));
89     print "Status: %s" % client.status();
90 if(sys.argv[1]=="regs"):
91     for adr in range(0x10,0x40): #*1024):
92         val=client.peek(adr);
93         print "%04x:=0x%04x" % (adr,val);
94 if(sys.argv[1]=="test"):
95     data=client.trans([0x20, 0xde, 0xad]);
96     print "%02x %02x" % (ord(data[1]), ord(data[2]));
97     data=client.trans([0x40|0x20, 0xde, 0xad]);
98     print "%02x %02x" % (ord(data[1]), ord(data[2]));
99 if(sys.argv[1]=="rssi"):
100     if len(sys.argv)>2:
101         freq=eval(sys.argv[2]);
102         if freq>100:
103             client.RF_setfreq(freq);
104         else:
105             client.RF_setchan(freq);
106     print "Listening on %f MHz." % (client.RF_getfreq()/10.0**6);
107         
108     client.strobe(0x02); #Calibrate
109     time.sleep(1);
110     
111     while 1:
112         client.CC_RFST_RX();
113         #client.strobe(0x03); #SRXON
114         rssi=client.RF_getrssi();
115         #client.CC_RFST_IDLE(); #idle
116         time.sleep(0.01);
117         string="";
118         for foo in range(0,rssi>>2):
119             string=("%s."%string);
120         print "%02x %04i %s" % (rssi,rssi, string); 
121
122 if(sys.argv[1]=="sniff" or sys.argv[1]=="sniffdissect"):
123     #Promiscuous mode.
124     client.RF_promiscuity(1);
125     client.RF_autocrc(0);
126     
127     if len(sys.argv)>2:
128         freq=eval(sys.argv[2]);
129         if freq>100:
130             client.RF_setfreq(freq);
131         else:
132             client.RF_setchan(freq);
133     client.CC_RFST_RX();
134     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
135                                             client.RF_getfreq()/10**6);
136     #Now we're ready to get packets.
137     while 1:
138         packet=None;
139         while packet==None:
140             packet=client.RF_rxpacket();
141         if sys.argv[1]=="sniffdissect":
142             client.printdissect(packet);
143         else:
144             client.printpacket(packet);
145         sys.stdout.flush();
146
147 if(sys.argv[1]=="bsniff"):
148     #Just broadcast.
149     client.RF_promiscuity(0);
150     client.RF_setsmac(0xFFFFFFFF);
151     client.RF_autocrc(1);
152     
153     if len(sys.argv)>2:
154         freq=eval(sys.argv[2]);
155         if freq>100:
156             client.RF_setfreq(freq);
157         else:
158             client.RF_setchan(freq);
159     client.CC_RFST_RX();
160     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
161                                             client.RF_getfreq()/10**6);
162     #Now we're ready to get packets.
163     while 1:
164         packet=None;
165         while packet==None:
166             packet=client.RF_rxpacket();
167         client.printpacket(packet);
168         sys.stdout.flush();
169
170 if(sys.argv[1]=="txtest"):
171     if len(sys.argv)>2:
172         freq=eval(sys.argv[2]);
173         if freq>100:
174             client.RF_setfreq(freq);
175         else:
176             client.RF_setchan(freq);
177     print "Transmitting DEADBEEF as %010x on %i MHz" % (
178         client.RF_getsmac(),
179         client.RF_getfreq()/10**6);
180     
181     while 1:
182         client.RF_txpacket([0x0f, 0x01, 0x08, 0x82,
183                             0xff, 0xff, 0xff, 0xff,
184                             0xde, 0xad, 0xbe, 0xef,
185                             0xba, 0xbe, 0xc0]);
186
187 if(sys.argv[1]=="txtoscount"):
188     '''
189     Clone of what TinyOS's RadioCountToLeds demo code does.  Specify a
190     channel a TinyOS mote programmed with RadioCountToLeds is on, and
191     this will act as the second device. (ryan@rmspeers.com)
192     '''
193     if (len(sys.argv)<=3):
194         print "Provide -r to work via replays or -i to work via incrementing itself.";
195         sys.exit(1);
196     if (sys.argv[3]=="-r"):
197         client.RF_promiscuity(1);
198     client.RF_autocrc(1);
199     if len(sys.argv)>2:
200         freq=eval(sys.argv[2]);
201         if freq>100:
202             client.RF_setfreq(freq);
203         else:
204             client.RF_setchan(freq);
205     if (sys.argv[3]=="-r"):
206         client.CC_RFST_RX();
207         print "Listening as %010x on %i MHz" % (client.RF_getsmac(), client.RF_getfreq()/10**6);
208     print "Transmitting like the TinyOS CountToRadio program on %i MHz" % (client.RF_getfreq()/10**6);
209     if (sys.argv[3]=="-i"):
210         i = 0;
211         countpkt = [0x0f, 0x41, 0x88, 0xFF, 0x22, 0x00, 0xff, 0xff, 0x01, 0x00, 0x3f, 0x06, 0x00, 0xFF];
212     while 1:
213         if (sys.argv[3]=="-r"): #give -r to do via replays from the other device
214             packet=None;
215             while packet==None:
216                 packet=client.RF_rxpacket();
217             pkt = packet[:14];
218             client.RF_txpacket(pkt);
219         elif (sys.argv[3]=="-i"): #give -i to have it increment and send
220             #Use this code for it to actually do increments itself:
221             pkt = countpkt[:];
222             pkt[3] = i;
223             pkt[13] = i+1;
224             client.RF_txpacket(pkt);
225             if i >= 31: i = 0;
226             else:       i += 1;
227             time.sleep(0.5);
228
229 if(sys.argv[1]=="txpiptest" or sys.argv[1]=="txpipscapy"):
230     if len(sys.argv)>2:
231         freq=eval(sys.argv[2]);
232         if freq>100:
233             client.RF_setfreq(freq);
234         else:
235             client.RF_setchan(freq);
236     print "Transmitting on as %010x on %i MHz" % (
237         client.RF_getsmac(),
238         client.RF_getfreq()/10**6);
239     
240     client.RF_setsync(0xFFFF);
241     
242     while 1:
243         if(sys.argv[1]=="txpiptest"):
244             client.RF_txpacket([
245                     0x7f, 
246                     #Real header, must begin with SFD.
247                     0x00, 0x00, 0x00,
248                     0x00, 0xA7,
249                     
250                     #Length
251                     0x1f, 0x01, 0x08, 0x82,
252                     0xDF, 0xff, 0xff, 0xff,
253                     0xde, 0xad, 0xbe, 0xef,
254                     0xba, 0xbe, 0xc0,
255                     
256                     #Preamble
257                     0x00, 0x00, 0x00,
258                     #SFD
259                     0x00, 0xA7,  #CC2420 SFD
260                     #Packet In Packet
261                     0x0f, 0x01, 0x08, 0x82,
262                     0xff, 0xff, 0xff, 0xff,
263                     0xde, 0xad, 0xbe, 0xef,
264                     0xba, 0xbe, 0xc0,
265                     
266                     0xff, 0xff, 0xff, 0xff,
267                     0xff, 0xff, 0xff, 0xff,
268                     0xff, 0xff, 0xff, 0xff,
269                     0xff, 0xff, 0xff, 0xff,
270                     0xff, 0xff, 0xff, 0xff,
271                     0xff, 0xff, 0xff, 0xff,
272                     0xff, 0xff, 0xff, 0xff,
273                     ]);
274         elif(sys.argv[1]=="txpipscapy"):
275             # NB: Requires Scapy with dot15d4.py layer. (rmspeers)
276             try:
277                 from scapy.all import Dot15d4, Dot15d4FCS, Dot15d4Data, Raw
278                 import struct
279             except ImportError:
280                 print "To use packet building, Scapy must be installed and have the dot15d4 layer present."
281                 print "try: hg clone http://hg.secdev.org/scapy-com";
282                 print "     sudo ./setup.py install";
283             #Overall method is to build from the inner packet outwards in the pkt string
284             # Make inner packet
285             scapyinner = Dot15d4FCS(seqnum=130)/Dot15d4Data()/Raw('\xde\xad\xbe\xef');
286             pkt = str(scapyinner);                  #build inner pkt to bytes, adding FCS automatically
287             pkt = struct.pack('b', len(pkt)) + pkt  #prepend with its length
288             pkt = "\x00\x00\x00\x00\xA7" + pkt      #add preamble and SFD to inner packet
289             # Make outer (wrapping) packet
290             scapyouter = Dot15d4(seqnum=130)/Dot15d4Data(dest_panid=0xffdf)/Raw('\xde\xad\xbe\xef\xba\xbe\xc0') #TODO why need these last 3 bytes?
291             pkt = str(scapyouter) + pkt
292             pkt = struct.pack('b', len(pkt)) + pkt  #prepend with its length
293             pkt = '\x00\x00\x00\x00\xA7' + pkt + ('\xff'*28) #start with preamble/SFD and add 0xff fill at end
294             pkt = struct.pack('b', len(pkt)) + pkt  #prepend with its length (originally used \x7f)
295             client.printpacket(pkt)
296             client.RF_autocrc(1);
297             client.RF_txpacket(pkt)
298
299 if(sys.argv[1]=="peek"):
300     start=0x0000;
301     if(len(sys.argv)>2):
302         start=int(sys.argv[2],16);
303     stop=start;
304     if(len(sys.argv)>3):
305         stop=int(sys.argv[3],16);
306     print "Peeking from %04x to %04x." % (start,stop);
307     while start<=stop:
308         print "%04x: 0x%04x" % (start,client.peek(start));
309         start=start+1;
310 if(sys.argv[1]=="poke"):
311     start=0x0000;
312     val=0x00;
313     if(len(sys.argv)>2):
314         start=int(sys.argv[2],16);
315     if(len(sys.argv)>3):
316         val=int(sys.argv[3],16);
317     print "Poking r%02x to become 0x%04x." % (start,val);
318     
319     client.poke(start,val);
320