3 #GoodFET Chipcon SPI Client
4 # (C) 2011 Travis Goodspeed
7 #Might be CC2420 Specific
13 from GoodFETCCSPI import GoodFETCCSPI;
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];
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];
29 print "\n%s txtoscount [-i|-r] TinyOS BlinkToLED" % sys.argv[0];
30 print "%s reflexjam" % sys.argv[0];
34 #Initialize FET and set baud rate
35 client=GoodFETCCSPI();
41 #Might read as all ones if chip has a startup delay.
43 if(sys.argv[1]=="carrier"):
45 client.RF_setfreq(eval(sys.argv[2]));
51 if(sys.argv[1]=="modulated_spectrum"):
53 client.RF_setfreq(eval(sys.argv[2]));
55 client.RF_modulated_spectrum();
59 if(sys.argv[1]=="reflexjam"):
60 #Setup the radio to listen promiscously on a frequency
61 client.RF_promiscuity(1);
64 freq=eval(sys.argv[2]);
66 client.RF_setfreq(freq);
68 client.RF_setchan(freq);
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();
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):
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"):
89 freq=eval(sys.argv[2]);
91 client.RF_setfreq(freq);
93 client.RF_setchan(freq);
94 print "Listening on %f MHz." % (client.RF_getfreq()/10.0**6);
96 client.strobe(0x02); #Calibrate
101 #client.strobe(0x03); #SRXON
102 rssi=client.RF_getrssi();
103 #client.CC_RFST_IDLE(); #idle
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"):
111 client.RF_promiscuity(1);
112 client.RF_autocrc(0);
115 freq=eval(sys.argv[2]);
117 client.RF_setfreq(freq);
119 client.RF_setchan(freq);
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.
127 packet=client.RF_rxpacket();
128 if sys.argv[1]=="sniffdissect":
129 client.printdissect(packet);
131 client.printpacket(packet);
133 if(sys.argv[1]=="bsniff"):
135 client.RF_promiscuity(0);
136 client.RF_setsmac(0xFFFFFFFF);
137 client.RF_autocrc(1);
140 freq=eval(sys.argv[2]);
142 client.RF_setfreq(freq);
144 client.RF_setchan(freq);
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.
152 packet=client.RF_rxpacket();
153 client.printpacket(packet);
156 if(sys.argv[1]=="txtest"):
158 freq=eval(sys.argv[2]);
160 client.RF_setfreq(freq);
162 client.RF_setchan(freq);
163 print "Transmitting DEADBEEF as %010x on %i MHz" % (
165 client.RF_getfreq()/10**6);
168 client.RF_txpacket([0x0f, 0x01, 0x08, 0x82,
169 0xff, 0xff, 0xff, 0xff,
170 0xde, 0xad, 0xbe, 0xef,
172 if(sys.argv[1]=="txtoscount"):
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.
178 if (len(sys.argv)<=3):
179 print "Provide -r to work via replays or -i to work via incrementing itself.";
181 if (sys.argv[3]=="-r"):
182 client.RF_promiscuity(1);
183 client.RF_autocrc(1);
185 freq=eval(sys.argv[2]);
187 client.RF_setfreq(freq);
189 client.RF_setchan(freq);
190 if (sys.argv[3]=="-r"):
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"):
196 countpkt = [0x0f, 0x41, 0x88, 0xFF, 0x22, 0x00, 0xff, 0xff, 0x01, 0x00, 0x3f, 0x06, 0x00, 0xFF];
198 if (sys.argv[3]=="-r"): #give -r to do via replays from the other device
201 packet=client.RF_rxpacket();
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:
209 client.RF_txpacket(pkt);
214 if(sys.argv[1]=="txpiptest" or sys.argv[1]=="txpipscapy"):
216 freq=eval(sys.argv[2]);
218 client.RF_setfreq(freq);
220 client.RF_setchan(freq);
221 print "Transmitting on as %010x on %i MHz" % (
223 client.RF_getfreq()/10**6);
225 client.RF_setsync(0xFFFF);
228 if(sys.argv[1]=="txpiptest"):
231 #Real header, must begin with SFD.
236 0x1f, 0x01, 0x08, 0x82,
237 0xDF, 0xff, 0xff, 0xff,
238 0xde, 0xad, 0xbe, 0xef,
244 0x00, 0xA7, #CC2420 SFD
246 0x0f, 0x01, 0x08, 0x82,
247 0xff, 0xff, 0xff, 0xff,
248 0xde, 0xad, 0xbe, 0xef,
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,
259 elif(sys.argv[1]=="txpipscapy"):
261 from scapy.all import Dot15d4, Dot15d4FCS, Dot15d4Data, Raw
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
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
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)
286 if(sys.argv[1]=="peek"):
289 start=int(sys.argv[2],16);
292 stop=int(sys.argv[3],16);
293 print "Peeking from %04x to %04x." % (start,stop);
295 print "%04x: 0x%04x" % (start,client.peek(start));
297 if(sys.argv[1]=="poke"):
301 start=int(sys.argv[2],16);
303 val=int(sys.argv[3],16);
304 print "Poking r%02x to become 0x%04x." % (start,val);
306 client.poke(start,val);