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];
31 print "%s txtoscount [-i|-r] TinyOS BlinkToLED" % 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]=="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):
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"):
75 freq=eval(sys.argv[2]);
77 client.RF_setfreq(freq);
79 client.RF_setchan(freq);
80 print "Listening on %f MHz." % (client.RF_getfreq()/10.0**6);
82 client.strobe(0x02); #Calibrate
87 #client.strobe(0x03); #SRXON
88 rssi=client.RF_getrssi();
89 #client.CC_RFST_IDLE(); #idle
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"):
97 client.RF_promiscuity(1);
101 freq=eval(sys.argv[2]);
103 client.RF_setfreq(freq);
105 client.RF_setchan(freq);
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.
113 packet=client.RF_rxpacket();
114 if sys.argv[1]=="sniffdissect":
115 client.printdissect(packet);
117 client.printpacket(packet);
119 if(sys.argv[1]=="bsniff"):
121 client.RF_promiscuity(0);
122 client.RF_setsmac(0xFFFFFFFF);
123 client.RF_autocrc(1);
126 freq=eval(sys.argv[2]);
128 client.RF_setfreq(freq);
130 client.RF_setchan(freq);
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.
138 packet=client.RF_rxpacket();
139 client.printpacket(packet);
142 if(sys.argv[1]=="txtest"):
144 freq=eval(sys.argv[2]);
146 client.RF_setfreq(freq);
148 client.RF_setchan(freq);
149 print "Transmitting DEADBEEF as %010x on %i MHz" % (
151 client.RF_getfreq()/10**6);
154 client.RF_txpacket([0x0f, 0x01, 0x08, 0x82,
155 0xff, 0xff, 0xff, 0xff,
156 0xde, 0xad, 0xbe, 0xef,
158 if(sys.argv[1]=="txtoscount"):
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.
163 if (len(sys.argv)<=3):
164 print "Provide -r to work via replays or -i to work via incrementing itself.";
166 if (sys.argv[3]=="-r"):
167 client.RF_promiscuity(1);
168 client.RF_autocrc(1);
170 freq=eval(sys.argv[2]);
172 client.RF_setfreq(freq);
174 client.RF_setchan(freq);
175 if (sys.argv[3]=="-r"):
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"):
181 countpkt = [0x0f, 0x41, 0x88, 0xFF, 0x22, 0x00, 0xff, 0xff, 0x01, 0x00, 0x3f, 0x06, 0x00, 0xFF];
183 if (sys.argv[3]=="-r"): #give -r to do via replays from the other device
186 packet=client.RF_rxpacket();
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:
194 client.RF_txpacket(pkt);
199 if(sys.argv[1]=="txpiptest" or sys.argv[1]=="txpipscapy"):
201 freq=eval(sys.argv[2]);
203 client.RF_setfreq(freq);
205 client.RF_setchan(freq);
206 print "Transmitting on as %010x on %i MHz" % (
208 client.RF_getfreq()/10**6);
210 client.RF_setsync(0xFFFF);
213 if(sys.argv[1]=="txpiptest"):
216 #Real header, must begin with SFD.
221 0x1f, 0x01, 0x08, 0x82,
222 0xDF, 0xff, 0xff, 0xff,
223 0xde, 0xad, 0xbe, 0xef,
229 0x00, 0xA7, #CC2420 SFD
231 0x0f, 0x01, 0x08, 0x82,
232 0xff, 0xff, 0xff, 0xff,
233 0xde, 0xad, 0xbe, 0xef,
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,
244 elif(sys.argv[1]=="txpipscapy"):
246 from scapy.all import Dot15d4, Dot15d4FCS, Dot15d4Data, Raw
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
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
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)
271 if(sys.argv[1]=="peek"):
274 start=int(sys.argv[2],16);
277 stop=int(sys.argv[3],16);
278 print "Peeking from %04x to %04x." % (start,stop);
280 print "%04x: 0x%04x" % (start,client.peek(start));
282 if(sys.argv[1]=="poke"):
286 start=int(sys.argv[2],16);
288 val=int(sys.argv[3],16);
289 print "Poking r%02x to become 0x%04x." % (start,val);
291 client.poke(start,val);