1
2
3
4
5
6
7
8 import sys, time, string, cStringIO, struct, glob, os;
9
10 from GoodFET import GoodFET;
11
13 CCSPIAPP=0x51;
14 CCversions={0x233d: "CC2420",
15 }
17 """Move the FET into the CCSPI application."""
18 self.writecmd(self.CCSPIAPP,0x10,0,self.data);
19
20
21 self.strobe(0x01);
22 self.strobe(0x02);
23 self.poke(0x11, 0x0AC2 & (~0x0800));
24 self.poke(0x12, 0x0500);
25 self.poke(0x1C, 0x007F);
26 self.poke(0x19, 0x01C4);
27
28
29
31 return self.peek(0x1E);
33 manfidl=self.peek(0x1E);
34
35 try:
36 return "%s" % (self.CCversions[manfidl]);
37 except:
38 return "Unknown0x%04x" % manfidl;
40 """Read and write 8 bits by CCSPI."""
41 data=self.CCSPItrans([byte]);
42 return ord(data[0]);
43
50 """Strobes a strobe register, returning the status."""
51 data=[reg];
52 self.trans(data);
53 return ord(self.data[0]);
55 """Switch the radio to idle mode, clearing overflows and errors."""
56 self.strobe(0x06);
58 """Switch the radio to TX mode."""
59 self.strobe(0x04);
61 """Switch the radio to RX mode."""
62 self.strobe(0x03);
64 """Calibrate strobe the radio."""
65 self.strobe(0x02);
67 self.strobe(state);
68 return;
69 - def peek(self,reg,bytes=2):
70 """Read a CCSPI Register. For long regs, result is flipped."""
71
72
73 data=[reg,0,0];
74
75
76 bytes=2;
77
78 self.writecmd(self.CCSPIAPP,0x02,len(data),data);
79 try:
80 toret=( ord(self.data[2]) + (ord(self.data[1])<<8) );
81 except Exception as e:
82 print "issue in peeking for a register"
83 print e
84 toret=( (ord(self.data[1])<<8) );
85 return toret;
86 - def poke(self,reg,val,bytes=2):
87 """Write a CCSPI Register."""
88 data=[reg,(val>>8)&0xFF,val&0xFF];
89 self.writecmd(self.CCSPIAPP,0x03,len(data),data);
90 if self.peek(reg,bytes)!=val and reg!=0x18:
91 print "Warning, failed to set r%02x=0x%04x, got %02x." %(
92 reg,
93 val,
94 self.peek(reg,bytes));
95 return False;
96 return True;
97
99 """Read the status byte."""
100 statusbits={0x80: "?",
101 0x40: "XOSC16M_STABLE",
102 0x20: "TX_UNDERFLOW",
103 0x10: "ENC_BUSY",
104 0x08: "TX_ACTIVE",
105 0x04: "LOCK",
106 0x02: "RSSI_VALID",
107 0x01: "?"};
108 status=self.strobe(0x00);
109 i=1;
110 str="";
111 while i<0x100:
112 if status&i:
113 str="%s %s" % (statusbits[i],str);
114 i*=2;
115 return str;
116
117
119 """Set the encoding type."""
120 return code;
122 """Get the encoding type."""
123 return "802.15.4";
129 return self.peek(0x14);
131 """Set the SYNC preamble.
132 Use 0xA70F for 0xA7."""
133 self.poke(0x14,sync);
134 return;
135
137 """Sets the first key for encryption to the given argument."""
138 print "ERROR: Forgot to set the key.";
139
140 return;
142 """Sets the first key for encryption to the given argument."""
143 print "ERROR: Forgot to set the nonce.";
144
145 return;
146
148 """Set the frequency in Hz."""
149 mhz=frequency/1000000;
150
151 fsctrl=self.peek(0x18)&(~0x3FF);
152 fsctrl=fsctrl+int(mhz-2048)
153 self.poke(0x18,fsctrl);
154
155 self.strobe(0x02);
156 time.sleep(0.01);
157 self.strobe(0x03);
159 """Get the frequency in Hz."""
160 fsctrl=self.peek(0x18);
161 mhz=2048+(fsctrl&0x3ff)
162 return mhz*1000000;
164 """Set the ZigBee/802.15.4 channel number."""
165 if channel < 11 or channel > 26:
166 print "Only 802.15.4 channels 11 to 26 are currently supported.";
167 else:
168 self.RF_setfreq( ( (channel-11)*5 + 2405 ) * 1000000 );
170 """Return the source MAC address."""
171 return 0xdeadbeef;
173 """Set the source MAC address."""
174 return 0xdeadbeef;
176 """Return the target MAC address."""
177 return 0xdeadbeef;
179 """Set the target MAC address."""
180 return 0xdeadbeef;
182 """Returns the received signal strength, with a weird offset."""
183 rssival=self.peek(0x13)&0xFF;
184 return rssival^0x80;
185
199
200 lastpacket=range(0,0xff);
202 """Get a packet from the radio. Returns None if none is
203 waiting."""
204
205 data="\0";
206 self.data=data;
207 self.writecmd(self.CCSPIAPP,0x80,len(data),data);
208 buffer=self.data;
209
210 self.lastpacket=buffer;
211 if(len(buffer)==0):
212 return None;
213
214 return buffer;
216 """Gets packets from the radio, ignoring all future requests so as
217 not to waste time. Call RF_rxpacket() after this."""
218
219 self.writecmd(self.CCSPIAPP,0x91,0,None);
220 return None;
221
223 """Get and decrypt a packet from the radio. Returns None if
224 none is waiting."""
225
226 data="\0";
227 self.data=data;
228 self.writecmd(self.CCSPIAPP,0x90,len(data),data);
229 buffer=self.data;
230
231 self.lastpacket=buffer;
232 if(len(buffer)==0):
233 return None;
234
235 return buffer;
236
238 """Send a packet through the radio."""
239 self.writecmd(self.CCSPIAPP,0x81,len(packet),packet);
240
241
242 return;
243
245 """Place the device into reflexive jamming mode."""
246 data = [duration&0xff,
247 (duration>>8)&0xff];
248 self.writecmd(self.CCSPIAPP,0xA0,len(data),data);
249 return;
250
252 """Place the device into reflexive jamming mode
253 and that also sends a forged ACK if needed."""
254 data = "";
255 self.writecmd(self.CCSPIAPP,0xA1,len(data),data);
256 print "Got:", data, "and", self.data
257 return;
258
260 """Hold a carrier wave on the present frequency."""
261
262
263
264
265
266
267
268 mdmctrl1=self.peek(0x12);
269
270 mdmctrl1=mdmctrl1|0x00c0;
271 self.poke(0x12, mdmctrl1);
272
273 mdmctrl1=self.peek(0x12);
274
275
276
277
278 self.strobe(0x02);
279
280
281
282 self.strobe(0x09);
283
284
285 self.strobe(0x04);
286
287
289 """Hold a carrier wave on the present frequency."""
290
291
292
293
294
295
296
297
298 mdmctrl1=self.peek(0x12);
299
300 mdmctrl1=mdmctrl1|0x0080;
301 mdmctrl1=mdmctrl1&0x0080;
302 self.poke(0x12, mdmctrl1);
303
304 mdmctrl1=self.peek(0x12);
305
306
307 self.poke(0x2E, 0x1800);
308 dactst=self.peek(0x2E);
309
310
311
312 self.strobe(0x02);
313
314 self.strobe(0x09);
315
316
317 self.strobe(0x04);
318
319
321 mdmctrl0=self.peek(0x11);
322 if promiscuous>0:
323 mdmctrl0=mdmctrl0&(~0x800);
324 else:
325 mdmctrl0=mdmctrl0|0x800;
326 self.poke(0x11,mdmctrl0);
327 return;
329 mdmctrl0=self.peek(0x11);
330 if autocrc==0:
331 mdmctrl0=mdmctrl0&(~0x0020);
332 else:
333 mdmctrl0=mdmctrl0|0x0020;
334 self.poke(0x11,mdmctrl0);
335 return;
337 mdmctrl0=self.peek(0x11);
338 if autoack==0:
339 mdmctrl0=mdmctrl0&(~0x0010);
340 else:
341 mdmctrl0=mdmctrl0|0x0010;
342 self.poke(0x11,mdmctrl0);
343 return;
344 packetlen=16;
346 """Set the number of bytes in the expected payload."""
347
348 self.packetlen=len;
350 """Set the number of bytes in the expected payload."""
351
352 self.packetlen=len;
353 return len;
354 maclen=5;
356 """Get the number of bytes in the MAC address."""
357 choices=[0, 3, 4, 5];
358 choice=self.peek(0x03)&3;
359 self.maclen=choices[choice];
360 return self.maclen;
362 """Set the number of bytes in the MAC address."""
363 choices=["illegal", "illegal", "illegal",
364 1, 2, 3];
365 choice=choices[len];
366 self.poke(0x03,choice);
367 self.maclen=len;
371 s="";
372 i=0;
373 for foo in packet:
374 s="%s %02x" % (s,ord(foo));
375 return "%s%s" % (prefix,s);
376
378 try:
379 from scapy.all import Dot15d4
380 except ImportError:
381 print "To use packet disection, Scapy must be installed and have the Dot15d4 extension present."
382 print "try: hg clone http://hg.secdev.org/scapy-com";
383 print " sudo ./setup.py install";
384 self.printpacket(packet);
385 try:
386 scapyd = Dot15d4(packet[1:]);
387 scapyd.show();
388 except:
389 pass;
390