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