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