3 #GoodFET Chipcon SPI Client
4 # (C) 2011 Travis Goodspeed
5 # Additions 2011-2012 Ryan Speers ryan@rmspeers.com
8 #Might be CC2420 Specific
14 from GoodFETCCSPI import GoodFETCCSPI;
17 print "Usage: %s verb [objects]\n" % sys.argv[0];
18 print "%s info" % sys.argv[0];
19 print "%s regs" % sys.argv[0];
20 print "%s test" % sys.argv[0];
21 print "%s peek 0x$start [0x$stop]" % sys.argv[0];
22 print "%s poke 0x$adr 0x$val" % sys.argv[0];
23 print "%s txtest" % sys.argv[0];
25 print "\n%s rssi" % sys.argv[0];
26 print "%s sniff [chan]" % sys.argv[0];
27 print "%s bsniff [chan]" % sys.argv[0];
28 print "%s sniffdissect" % sys.argv[0];
30 print "\n%s txtoscount [-i|-r] TinyOS BlinkToLED" % sys.argv[0];
31 print "%s reflexjam [channel=11] [delay=0]" % sys.argv[0];
35 #Initialize FET and set baud rate
36 client=GoodFETCCSPI();
42 #Might read as all ones if chip has a startup delay.
44 if(sys.argv[1]=="carrier"):
46 client.RF_setfreq(eval(sys.argv[2]));
52 if(sys.argv[1]=="modulated_spectrum"):
54 client.RF_setfreq(eval(sys.argv[2]));
56 client.RF_modulated_spectrum();
60 if(sys.argv[1]=="reflexjam" or sys.argv[1]=="reflexjamack"):
61 #Setup the radio to listen promiscously on a frequency
62 client.RF_promiscuity(1);
65 freq=eval(sys.argv[2]);
67 client.RF_setfreq(freq);
69 client.RF_setchan(freq);
72 duration=eval(sys.argv[3]);
74 print "Reflexively jamming on %i MHz" % (client.RF_getfreq()/10**6);
75 #Now we let the firmware take over, watching for packets and jamming them.
76 #Standard reflexive jam is done with duration=0.
77 #To selectively jam packets that are above a certain length, set duration
78 # to the number of milliseconds needed to jam frames of that length.
79 # Api-Do project has script available to tune/test this duration.
80 # code.google.com/p/zigbeesecurity (rmspeers)
81 if sys.argv[1]=="reflexjam":
82 client.RF_reflexjam(duration);
83 elif sys.argv[1]=="reflexjamack":
84 client.RF_reflexjam_autoack();
86 if(sys.argv[1]=="info"):
87 print "Found %s" % client.identstr();
88 print "Freq: %05f MHz" % (client.RF_getfreq()/(10**6));
89 print "Status: %s" % client.status();
90 if(sys.argv[1]=="regs"):
91 for adr in range(0x10,0x40): #*1024):
93 print "%04x:=0x%04x" % (adr,val);
94 if(sys.argv[1]=="test"):
95 data=client.trans([0x20, 0xde, 0xad]);
96 print "%02x %02x" % (ord(data[1]), ord(data[2]));
97 data=client.trans([0x40|0x20, 0xde, 0xad]);
98 print "%02x %02x" % (ord(data[1]), ord(data[2]));
99 if(sys.argv[1]=="rssi"):
101 freq=eval(sys.argv[2]);
103 client.RF_setfreq(freq);
105 client.RF_setchan(freq);
106 print "Listening on %f MHz." % (client.RF_getfreq()/10.0**6);
108 client.strobe(0x02); #Calibrate
113 #client.strobe(0x03); #SRXON
114 rssi=client.RF_getrssi();
115 #client.CC_RFST_IDLE(); #idle
118 for foo in range(0,rssi>>2):
119 string=("%s."%string);
120 print "%02x %04i %s" % (rssi,rssi, string);
122 if(sys.argv[1]=="sniff" or sys.argv[1]=="sniffdissect"):
124 client.RF_promiscuity(1);
125 client.RF_autocrc(0);
128 freq=eval(sys.argv[2]);
130 client.RF_setfreq(freq);
132 client.RF_setfreq(freq*1000000);
134 client.RF_setchan(freq);
136 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
137 client.RF_getfreq()/10**6);
138 #Now we're ready to get packets.
142 packet=client.RF_rxpacket();
143 if sys.argv[1]=="sniffdissect":
144 client.printdissect(packet);
146 client.printpacket(packet);
149 if(sys.argv[1]=="bsniff"):
151 client.RF_promiscuity(0);
152 client.RF_setsmac(0xFFFFFFFF);
153 client.RF_autocrc(1);
156 freq=eval(sys.argv[2]);
158 client.RF_setfreq(freq);
160 client.RF_setchan(freq);
162 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
163 client.RF_getfreq()/10**6);
164 #Now we're ready to get packets.
168 packet=client.RF_rxpacket();
169 client.printpacket(packet);
172 if(sys.argv[1]=="txtest"):
174 freq=eval(sys.argv[2]);
176 client.RF_setfreq(freq);
178 client.RF_setchan(freq);
179 print "Transmitting DEADBEEF as %010x on %i MHz" % (
181 client.RF_getfreq()/10**6);
184 client.RF_txpacket([0x0f, 0x01, 0x08, 0x82,
185 0xff, 0xff, 0xff, 0xff,
186 0xde, 0xad, 0xbe, 0xef,
189 if(sys.argv[1]=="txtoscount"):
191 Clone of what TinyOS's RadioCountToLeds demo code does. Specify a
192 channel a TinyOS mote programmed with RadioCountToLeds is on, and
193 this will act as the second device. (ryan@rmspeers.com)
195 if (len(sys.argv)<=3):
196 print "Provide -r to work via replays or -i to work via incrementing itself.";
198 if (sys.argv[3]=="-r"):
199 client.RF_promiscuity(1);
200 client.RF_autocrc(1);
202 freq=eval(sys.argv[2]);
204 client.RF_setfreq(freq);
206 client.RF_setchan(freq);
207 if (sys.argv[3]=="-r"):
209 print "Listening as %010x on %i MHz" % (client.RF_getsmac(), client.RF_getfreq()/10**6);
210 print "Transmitting like the TinyOS CountToRadio program on %i MHz" % (client.RF_getfreq()/10**6);
211 if (sys.argv[3]=="-i"):
213 countpkt = [0x0f, 0x41, 0x88, 0xFF, 0x22, 0x00, 0xff, 0xff, 0x01, 0x00, 0x3f, 0x06, 0x00, 0xFF];
215 if (sys.argv[3]=="-r"): #give -r to do via replays from the other device
218 packet=client.RF_rxpacket();
220 client.RF_txpacket(pkt);
221 elif (sys.argv[3]=="-i"): #give -i to have it increment and send
222 #Use this code for it to actually do increments itself:
226 client.RF_txpacket(pkt);
231 if(sys.argv[1]=="txpiptest" or sys.argv[1]=="txpipscapy"):
233 freq=eval(sys.argv[2]);
235 client.RF_setfreq(freq);
237 client.RF_setchan(freq);
238 print "Transmitting on as %010x on %i MHz" % (
240 client.RF_getfreq()/10**6);
242 client.RF_setsync(0xFFFF);
245 if(sys.argv[1]=="txpiptest"):
248 #Real header, must begin with SFD.
253 0x1f, 0x01, 0x08, 0x82,
254 0xDF, 0xff, 0xff, 0xff,
255 0xde, 0xad, 0xbe, 0xef,
261 0x00, 0xA7, #CC2420 SFD
263 0x0f, 0x01, 0x08, 0x82,
264 0xff, 0xff, 0xff, 0xff,
265 0xde, 0xad, 0xbe, 0xef,
268 0xff, 0xff, 0xff, 0xff,
269 0xff, 0xff, 0xff, 0xff,
270 0xff, 0xff, 0xff, 0xff,
271 0xff, 0xff, 0xff, 0xff,
272 0xff, 0xff, 0xff, 0xff,
273 0xff, 0xff, 0xff, 0xff,
274 0xff, 0xff, 0xff, 0xff,
276 elif(sys.argv[1]=="txpipscapy"):
277 # NB: Requires Scapy with dot15d4.py layer. (rmspeers)
279 from scapy.all import Dot15d4, Dot15d4FCS, Dot15d4Data, Raw
282 print "To use packet building, Scapy must be installed and have the dot15d4 layer present."
283 print "try: hg clone http://hg.secdev.org/scapy-com";
284 print " sudo ./setup.py install";
285 #Overall method is to build from the inner packet outwards in the pkt string
287 scapyinner = Dot15d4FCS(seqnum=130)/Dot15d4Data()/Raw('\xde\xad\xbe\xef');
288 pkt = str(scapyinner); #build inner pkt to bytes, adding FCS automatically
289 pkt = struct.pack('b', len(pkt)) + pkt #prepend with its length
290 pkt = "\x00\x00\x00\x00\xA7" + pkt #add preamble and SFD to inner packet
291 # Make outer (wrapping) packet
292 scapyouter = Dot15d4(seqnum=130)/Dot15d4Data(dest_panid=0xffdf)/Raw('\xde\xad\xbe\xef\xba\xbe\xc0') #TODO why need these last 3 bytes?
293 pkt = str(scapyouter) + pkt
294 pkt = struct.pack('b', len(pkt)) + pkt #prepend with its length
295 pkt = '\x00\x00\x00\x00\xA7' + pkt + ('\xff'*28) #start with preamble/SFD and add 0xff fill at end
296 pkt = struct.pack('b', len(pkt)) + pkt #prepend with its length (originally used \x7f)
297 client.printpacket(pkt)
298 client.RF_autocrc(1);
299 client.RF_txpacket(pkt)
301 if(sys.argv[1]=="peek"):
304 start=int(sys.argv[2],16);
307 stop=int(sys.argv[3],16);
308 print "Peeking from %04x to %04x." % (start,stop);
310 print "%04x: 0x%04x" % (start,client.peek(start));
312 if(sys.argv[1]=="poke"):
316 start=int(sys.argv[2],16);
318 val=int(sys.argv[3],16);
319 print "Poking r%02x to become 0x%04x." % (start,val);
321 client.poke(start,val);