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