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