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 [channel=11] [delay=0]" % 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);
71 duration=eval(sys.argv[3]);
73 print "Reflexively jamming on %i MHz" % (client.RF_getfreq()/10**6);
74 #Now we let the firmware take over, watching for packets and jamming them.
75 if sys.argv[1]=="reflexjam":
76 client.RF_reflexjam(duration);
77 elif sys.argv[1]=="reflexjamack":
78 client.RF_reflexjam_autoack();
80 if(sys.argv[1]=="info"):
81 print "Found %s" % client.identstr();
82 print "Freq: %05f MHz" % (client.RF_getfreq()/(10**6));
83 print "Status: %s" % client.status();
84 if(sys.argv[1]=="regs"):
85 for adr in range(0x10,0x40): #*1024):
87 print "%04x:=0x%04x" % (adr,val);
88 if(sys.argv[1]=="test"):
89 data=client.trans([0x20, 0xde, 0xad]);
90 print "%02x %02x" % (ord(data[1]), ord(data[2]));
91 data=client.trans([0x40|0x20, 0xde, 0xad]);
92 print "%02x %02x" % (ord(data[1]), ord(data[2]));
93 if(sys.argv[1]=="rssi"):
95 freq=eval(sys.argv[2]);
97 client.RF_setfreq(freq);
99 client.RF_setchan(freq);
100 print "Listening on %f MHz." % (client.RF_getfreq()/10.0**6);
102 client.strobe(0x02); #Calibrate
107 #client.strobe(0x03); #SRXON
108 rssi=client.RF_getrssi();
109 #client.CC_RFST_IDLE(); #idle
112 for foo in range(0,rssi>>2):
113 string=("%s."%string);
114 print "%02x %04i %s" % (rssi,rssi, string);
115 if(sys.argv[1]=="sniff" or sys.argv[1]=="sniffdissect"):
117 client.RF_promiscuity(1);
118 client.RF_autocrc(0);
121 freq=eval(sys.argv[2]);
123 client.RF_setfreq(freq);
125 client.RF_setchan(freq);
127 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
128 client.RF_getfreq()/10**6);
129 #Now we're ready to get packets.
133 packet=client.RF_rxpacket();
134 if sys.argv[1]=="sniffdissect":
135 client.printdissect(packet);
137 client.printpacket(packet);
139 if(sys.argv[1]=="bsniff"):
141 client.RF_promiscuity(0);
142 client.RF_setsmac(0xFFFFFFFF);
143 client.RF_autocrc(1);
146 freq=eval(sys.argv[2]);
148 client.RF_setfreq(freq);
150 client.RF_setchan(freq);
152 print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
153 client.RF_getfreq()/10**6);
154 #Now we're ready to get packets.
158 packet=client.RF_rxpacket();
159 client.printpacket(packet);
162 if(sys.argv[1]=="txtest"):
164 freq=eval(sys.argv[2]);
166 client.RF_setfreq(freq);
168 client.RF_setchan(freq);
169 print "Transmitting DEADBEEF as %010x on %i MHz" % (
171 client.RF_getfreq()/10**6);
174 client.RF_txpacket([0x0f, 0x01, 0x08, 0x82,
175 0xff, 0xff, 0xff, 0xff,
176 0xde, 0xad, 0xbe, 0xef,
178 if(sys.argv[1]=="txtoscount"):
180 Clone of what TinyOS's RadioCountToLeds demo code does. Specify a
181 channel a TinyOS mote programmed with RadioCountToLeds is on, and
182 this will act as the second device.
184 if (len(sys.argv)<=3):
185 print "Provide -r to work via replays or -i to work via incrementing itself.";
187 if (sys.argv[3]=="-r"):
188 client.RF_promiscuity(1);
189 client.RF_autocrc(1);
191 freq=eval(sys.argv[2]);
193 client.RF_setfreq(freq);
195 client.RF_setchan(freq);
196 if (sys.argv[3]=="-r"):
198 print "Listening as %010x on %i MHz" % (client.RF_getsmac(), client.RF_getfreq()/10**6);
199 print "Transmitting like the TinyOS CountToRadio program on %i MHz" % (client.RF_getfreq()/10**6);
200 if (sys.argv[3]=="-i"):
202 countpkt = [0x0f, 0x41, 0x88, 0xFF, 0x22, 0x00, 0xff, 0xff, 0x01, 0x00, 0x3f, 0x06, 0x00, 0xFF];
204 if (sys.argv[3]=="-r"): #give -r to do via replays from the other device
207 packet=client.RF_rxpacket();
209 client.RF_txpacket(pkt);
210 elif (sys.argv[3]=="-i"): #give -i to have it increment and send
211 #Use this code for it to actually do increments itself:
215 client.RF_txpacket(pkt);
220 if(sys.argv[1]=="txpiptest" or sys.argv[1]=="txpipscapy"):
222 freq=eval(sys.argv[2]);
224 client.RF_setfreq(freq);
226 client.RF_setchan(freq);
227 print "Transmitting on as %010x on %i MHz" % (
229 client.RF_getfreq()/10**6);
231 client.RF_setsync(0xFFFF);
234 if(sys.argv[1]=="txpiptest"):
237 #Real header, must begin with SFD.
242 0x1f, 0x01, 0x08, 0x82,
243 0xDF, 0xff, 0xff, 0xff,
244 0xde, 0xad, 0xbe, 0xef,
250 0x00, 0xA7, #CC2420 SFD
252 0x0f, 0x01, 0x08, 0x82,
253 0xff, 0xff, 0xff, 0xff,
254 0xde, 0xad, 0xbe, 0xef,
257 0xff, 0xff, 0xff, 0xff,
258 0xff, 0xff, 0xff, 0xff,
259 0xff, 0xff, 0xff, 0xff,
260 0xff, 0xff, 0xff, 0xff,
261 0xff, 0xff, 0xff, 0xff,
262 0xff, 0xff, 0xff, 0xff,
263 0xff, 0xff, 0xff, 0xff,
265 elif(sys.argv[1]=="txpipscapy"):
267 from scapy.all import Dot15d4, Dot15d4FCS, Dot15d4Data, Raw
270 print "To use packet building, Scapy must be installed and have the dot15d4 extension present."
271 print "try: hg clone http://hg.secdev.org/scapy-com";
272 print " sudo ./setup.py install";
273 #Overall method is to build from the inner packet outwards in the pkt string
275 scapyinner = Dot15d4FCS(seqnum=130)/Dot15d4Data()/Raw('\xde\xad\xbe\xef');
276 #pkt = str(scapyinner)[:-2] + '\xba\xbe\xc0';
277 pkt = str(scapyinner); #build inner pkt to bytes, adding FCS automatically
279 pkt = struct.pack('b', len(pkt)) + pkt #prepend with its length
280 pkt = "\x00\x00\x00\x00\xA7" + pkt #add preamble and SFD to inner packet
281 # Make outer (wrapping) packet
282 scapyouter = Dot15d4(seqnum=130)/Dot15d4Data(dest_panid=0xffdf)/Raw('\xde\xad\xbe\xef\xba\xbe\xc0') #TODO why need these last 3 bytes?
283 pkt = str(scapyouter) + pkt
284 pkt = struct.pack('b', len(pkt)) + pkt #prepend with its length
285 pkt = '\x00\x00\x00\x00\xA7' + pkt + ('\xff'*28) #start with preamble/SFD and add 0xff fill at end
286 pkt = struct.pack('b', len(pkt)) + pkt #prepend with its length (originally used \x7f)
287 client.printpacket(pkt)
288 client.RF_autocrc(1);
289 client.RF_txpacket(pkt)
292 if(sys.argv[1]=="peek"):
295 start=int(sys.argv[2],16);
298 stop=int(sys.argv[3],16);
299 print "Peeking from %04x to %04x." % (start,stop);
301 print "%04x: 0x%04x" % (start,client.peek(start));
303 if(sys.argv[1]=="poke"):
307 start=int(sys.argv[2],16);
309 val=int(sys.argv[3],16);
310 print "Poking r%02x to become 0x%04x." % (start,val);
312 client.poke(start,val);