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" or sys.argv[1]=="reflexjamack"):
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 if sys.argv[1]=="reflexjam":
73 client.RF_reflexjam();
74 elif sys.argv[1]=="reflexjamack":
75 client.RF_reflexjam_autoack();
77 if(sys.argv[1]=="info"):
78 print "Found %s" % client.identstr();
79 print "Freq: %05f MHz" % (client.RF_getfreq()/(10**6));
80 print "Status: %s" % client.status();
81 if(sys.argv[1]=="regs"):
82 for adr in range(0x10,0x40): #*1024):
84 print "%04x:=0x%04x" % (adr,val);
85 if(sys.argv[1]=="test"):
86 data=client.trans([0x20, 0xde, 0xad]);
87 print "%02x %02x" % (ord(data[1]), ord(data[2]));
88 data=client.trans([0x40|0x20, 0xde, 0xad]);
89 print "%02x %02x" % (ord(data[1]), ord(data[2]));
90 if(sys.argv[1]=="rssi"):
92 freq=eval(sys.argv[2]);
94 client.RF_setfreq(freq);
96 client.RF_setchan(freq);
97 print "Listening on %f MHz." % (client.RF_getfreq()/10.0**6);
99 client.strobe(0x02); #Calibrate
104 #client.strobe(0x03); #SRXON
105 rssi=client.RF_getrssi();
106 #client.CC_RFST_IDLE(); #idle
109 for foo in range(0,rssi>>2):
110 string=("%s."%string);
111 print "%02x %04i %s" % (rssi,rssi, string);
112 if(sys.argv[1]=="sniff" or sys.argv[1]=="sniffdissect"):
114 client.RF_promiscuity(1);
115 client.RF_autocrc(0);
118 freq=eval(sys.argv[2]);
120 client.RF_setfreq(freq);
122 client.RF_setchan(freq);
124 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
125 client.RF_getfreq()/10**6);
126 #Now we're ready to get packets.
130 packet=client.RF_rxpacket();
131 if sys.argv[1]=="sniffdissect":
132 client.printdissect(packet);
134 client.printpacket(packet);
136 if(sys.argv[1]=="bsniff"):
138 client.RF_promiscuity(0);
139 client.RF_setsmac(0xFFFFFFFF);
140 client.RF_autocrc(1);
143 freq=eval(sys.argv[2]);
145 client.RF_setfreq(freq);
147 client.RF_setchan(freq);
149 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
150 client.RF_getfreq()/10**6);
151 #Now we're ready to get packets.
155 packet=client.RF_rxpacket();
156 client.printpacket(packet);
159 if(sys.argv[1]=="txtest"):
161 freq=eval(sys.argv[2]);
163 client.RF_setfreq(freq);
165 client.RF_setchan(freq);
166 print "Transmitting DEADBEEF as %010x on %i MHz" % (
168 client.RF_getfreq()/10**6);
171 client.RF_txpacket([0x0f, 0x01, 0x08, 0x82,
172 0xff, 0xff, 0xff, 0xff,
173 0xde, 0xad, 0xbe, 0xef,
175 if(sys.argv[1]=="txtoscount"):
177 Clone of what TinyOS's RadioCountToLeds demo code does. Specify a
178 channel a TinyOS mote programmed with RadioCountToLeds is on, and
179 this will act as the second device.
181 if (len(sys.argv)<=3):
182 print "Provide -r to work via replays or -i to work via incrementing itself.";
184 if (sys.argv[3]=="-r"):
185 client.RF_promiscuity(1);
186 client.RF_autocrc(1);
188 freq=eval(sys.argv[2]);
190 client.RF_setfreq(freq);
192 client.RF_setchan(freq);
193 if (sys.argv[3]=="-r"):
195 print "Listening as %010x on %i MHz" % (client.RF_getsmac(), client.RF_getfreq()/10**6);
196 print "Transmitting like the TinyOS CountToRadio program on %i MHz" % (client.RF_getfreq()/10**6);
197 if (sys.argv[3]=="-i"):
199 countpkt = [0x0f, 0x41, 0x88, 0xFF, 0x22, 0x00, 0xff, 0xff, 0x01, 0x00, 0x3f, 0x06, 0x00, 0xFF];
201 if (sys.argv[3]=="-r"): #give -r to do via replays from the other device
204 packet=client.RF_rxpacket();
206 client.RF_txpacket(pkt);
207 elif (sys.argv[3]=="-i"): #give -i to have it increment and send
208 #Use this code for it to actually do increments itself:
212 client.RF_txpacket(pkt);
217 if(sys.argv[1]=="txpiptest" or sys.argv[1]=="txpipscapy"):
219 freq=eval(sys.argv[2]);
221 client.RF_setfreq(freq);
223 client.RF_setchan(freq);
224 print "Transmitting on as %010x on %i MHz" % (
226 client.RF_getfreq()/10**6);
228 client.RF_setsync(0xFFFF);
231 if(sys.argv[1]=="txpiptest"):
234 #Real header, must begin with SFD.
239 0x1f, 0x01, 0x08, 0x82,
240 0xDF, 0xff, 0xff, 0xff,
241 0xde, 0xad, 0xbe, 0xef,
247 0x00, 0xA7, #CC2420 SFD
249 0x0f, 0x01, 0x08, 0x82,
250 0xff, 0xff, 0xff, 0xff,
251 0xde, 0xad, 0xbe, 0xef,
254 0xff, 0xff, 0xff, 0xff,
255 0xff, 0xff, 0xff, 0xff,
256 0xff, 0xff, 0xff, 0xff,
257 0xff, 0xff, 0xff, 0xff,
258 0xff, 0xff, 0xff, 0xff,
259 0xff, 0xff, 0xff, 0xff,
260 0xff, 0xff, 0xff, 0xff,
262 elif(sys.argv[1]=="txpipscapy"):
264 from scapy.all import Dot15d4, Dot15d4FCS, Dot15d4Data, Raw
267 print "To use packet building, Scapy must be installed and have the dot15d4 extension present."
268 print "try: hg clone http://hg.secdev.org/scapy-com";
269 print " sudo ./setup.py install";
270 #Overall method is to build from the inner packet outwards in the pkt string
272 scapyinner = Dot15d4FCS(seqnum=130)/Dot15d4Data()/Raw('\xde\xad\xbe\xef');
273 #pkt = str(scapyinner)[:-2] + '\xba\xbe\xc0';
274 pkt = str(scapyinner); #build inner pkt to bytes, adding FCS automatically
276 pkt = struct.pack('b', len(pkt)) + pkt #prepend with its length
277 pkt = "\x00\x00\x00\x00\xA7" + pkt #add preamble and SFD to inner packet
278 # Make outer (wrapping) packet
279 scapyouter = Dot15d4(seqnum=130)/Dot15d4Data(dest_panid=0xffdf)/Raw('\xde\xad\xbe\xef\xba\xbe\xc0') #TODO why need these last 3 bytes?
280 pkt = str(scapyouter) + pkt
281 pkt = struct.pack('b', len(pkt)) + pkt #prepend with its length
282 pkt = '\x00\x00\x00\x00\xA7' + pkt + ('\xff'*28) #start with preamble/SFD and add 0xff fill at end
283 pkt = struct.pack('b', len(pkt)) + pkt #prepend with its length (originally used \x7f)
284 client.printpacket(pkt)
285 client.RF_autocrc(1);
286 client.RF_txpacket(pkt)
289 if(sys.argv[1]=="peek"):
292 start=int(sys.argv[2],16);
295 stop=int(sys.argv[3],16);
296 print "Peeking from %04x to %04x." % (start,stop);
298 print "%04x: 0x%04x" % (start,client.peek(start));
300 if(sys.argv[1]=="poke"):
304 start=int(sys.argv[2],16);
306 val=int(sys.argv[3],16);
307 print "Poking r%02x to become 0x%04x." % (start,val);
309 client.poke(start,val);