e8de384b8cfd1db425281988ef2f599b7c9dd3be
[goodfet] / client / goodfet.cc
1 #!/usr/bin/env python
2 # GoodFET Chipcon Example
3
4 # (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
5 #
6 # This code is being rewritten and refactored.  You've been warned!
7
8 import sys;
9 import binascii, time;
10
11 from GoodFETCC import GoodFETCC;
12 from GoodFETConsole import GoodFETConsole;
13 from intelhex import IntelHex;
14
15
16 def printpacket(packet):
17     s="";
18     i=0;
19     #print "Printing packet."
20     for foo in packet:
21         i=i+1;
22         #if i>packet[0]+1: break;
23         s="%s %02x" % (s,foo);
24     print "%s" %s;
25
26 def handlesimplicitipacket(packet):
27     s="";
28     i=0;
29     
30     for foo in packet:
31         i=i+1;
32         #if i>packet[0]+1: break;
33         s="%s %02x" % (s,foo);
34     print "\n%s" %s;
35     
36     
37     len=packet[0];
38     if len<12: return;
39     
40     dst=[packet[1],
41              packet[2],
42              packet[3],
43              packet[4]];
44     src=[packet[5],
45              packet[6],
46              packet[7],
47              packet[8]];
48     port=packet[9];
49     info=packet[10];
50     seq=packet[11];
51     #payload begins at byte 12.
52     
53     
54     
55     if port==0x03:
56         #print "Join request.";
57         if packet[12]!=1:
58             print "Not a join request.  WTF?";
59             return;
60         tid=packet[13];
61         reply=[0x12, #reply is one byte shorter
62                src[0], src[1], src[2], src[3],
63                1,1,1,1,           #my address
64                port, 0x21, seq,
65                0x81, tid,         #reply, tid
66                
67                1,1,1,1,
68                #4,3,2,1,           #default join token
69                #8,7,6,5,          #default link token
70                #0xFF,0xFF,0xFF,0xFF,
71                0x00];             #no security
72         printpacket(reply);
73         client.RF_txpacket(reply);
74
75     elif port==0x04:
76         print "Security request.";
77     elif port==0x05:
78         print "Frequency request.";
79     elif port==0x06:
80         print "Management request.";
81     else:
82         print "Unknown Port %02x" %port;
83     
84 if(len(sys.argv)==1):
85     print "Usage: %s verb [objects]\n" % sys.argv[0];
86     print "%s erase" % sys.argv[0];
87     print "%s flash $foo.hex" % sys.argv[0];
88     print "%s test" % sys.argv[0];
89     print "%s term" % sys.argv[0];
90     print "%s info" % sys.argv[0];
91     print "%s halt"  % sys.argv[0];
92     print "%s regs" % sys.argv[0];
93     print "%s dumpcode $foo.hex [0x$start 0x$stop]" % sys.argv[0];
94     print "%s dumpdata $foo.hex [0x$start 0x$stop]" % sys.argv[0];
95     print "%s writedata $foo.hex [0x$start 0x$stop]" % sys.argv[0];
96     print "%s verify $foo.hex [0x$start 0x$stop]" % sys.argv[0];
97     print "%s peekdata 0x$start [0x$stop]" % sys.argv[0];
98     print "%s pokedata 0x$adr 0x$val" % sys.argv[0];
99     print "%s peek 0x$iram" % sys.argv[0];
100     print "%s poke 0x$iram 0x$val" % sys.argv[0];
101     print "%s peekcode 0x$start [0x$stop]" % sys.argv[0];
102     print "\n"
103     print "%s rssi [freq]\n\tGraphs signal strength on [freq] Hz." % sys.argv[0];
104     print "%s carrier [freq]\n\tHolds a carrier on [freq] Hz." % sys.argv[0];
105     print "%s reflex [freq]\n\tJams on [freq] Hz." % sys.argv[0];
106     print "%s sniffsimpliciti [us|eu|lf]\n\tSniffs SimpliciTI packets." % sys.argv[0];
107     
108     sys.exit();
109
110 #Initailize FET and set baud rate
111 #client=GoodFET.GoodFETCC.GoodFETCC();
112 client=GoodFETCC();
113 client.serInit()
114
115 #Connect to target
116 client.setup();
117 client.start();
118
119
120
121 if(sys.argv[1]=="carrier"):
122     if len(sys.argv)>2:
123         client.RF_setfreq(eval(sys.argv[2]));
124     client.RF_carrier();
125     while(1):
126         time.sleep(1);
127
128 if(sys.argv[1]=="reflex"):
129     client.CC1110_crystal();
130     client.RF_idle();
131     
132     client.config_simpliciti();
133     
134     threshold=100;
135     if len(sys.argv)>2:
136         client.RF_setfreq(eval(sys.argv[2]));
137     print "Listening on %f MHz." % (client.RF_getfreq()/10**6);
138     print "Jamming if RSSI>=%i" % threshold;
139     
140     client.pokebyte(0xFE00,threshold,"xdata"); #Write threshold to shellcode.
141     client.shellcodefile("reflex.ihx");
142     rssi=0;
143     while 1:
144         while(0==client.ishalted()):
145             rssi=0;
146         rssi=client.peek8(0xFE00,"xdata");
147         print "Activated jamming with RSSI of %i, going again for another packet." % rssi;
148         client.resume();
149     
150     RFST=0xDFE1
151     client.CC_RFST_CAL(); #SCAL
152     time.sleep(1);
153     
154     maxrssi=0;
155     while 1:
156         client.CC_RFST_RX(); #SRX
157         rssi=client.RF_getrssi();
158         client.CC_RFST_IDLE(); #idle
159         time.sleep(0.01);
160         string="";
161         for foo in range(0,rssi>>2):
162             string=("%s."%string);
163         print "%02x %04i %04i %s" % (rssi,rssi, maxrssi, string); 
164         if rssi>maxrssi:
165             maxrssi=(rssi);
166         if rssi>threshold:
167             #print "Triggered jamming for 1s.";
168             client.RF_carrier();
169             time.sleep(1);
170             print "JAMMING JAMMING JAMMING JAMMING";
171 if(sys.argv[1]=="rssi"):
172     client.CC1110_crystal();
173     client.RF_idle();
174     
175     client.config_simpliciti();
176     
177     if len(sys.argv)>2:
178         client.RF_setfreq(eval(sys.argv[2]));
179     print "Listening on %f MHz." % (client.RF_getfreq()/10.0**6);
180         
181     #FIXME, ugly
182     RFST=0xDFE1
183     client.CC_RFST_CAL();
184     time.sleep(1);
185     
186     while 1:
187         client.CC_RFST_RX();
188         rssi=client.RF_getrssi();
189         client.CC_RFST_IDLE(); #idle
190         time.sleep(0.01);
191         string="";
192         for foo in range(0,rssi>>2):
193             string=("%s."%string);
194         print "%02x %04i %s" % (rssi,rssi, string); 
195
196 if(sys.argv[1]=="sniffsimpliciti"):
197     #TODO remove all poke() calls.
198     region="us";
199     if len(sys.argv)>2:
200         region=sys.argv[2];
201     
202     client.CC1110_crystal();
203     client.RF_idle();
204     
205     client.config_simpliciti(region);
206     
207     print "Listening as %x on %f MHz" % (client.RF_getsmac(),
208                                            client.RF_getfreq()/10.0**6);
209     #Now we're ready to get packets.
210     while 1:
211         packet=None;
212         while packet==None:
213             packet=client.RF_rxpacket();
214         printpacket(packet);
215         sys.stdout.flush();
216
217 if(sys.argv[1]=="simpliciti"):
218     #TODO remove all poke() calls.
219     region="us";
220     if len(sys.argv)>2:
221         region=sys.argv[2];
222     
223     client.CC1110_crystal();
224     client.RF_idle();
225     
226     client.config_simpliciti(region);
227     
228     print "Listening as %x on %f MHz" % (client.RF_getsmac(),
229                                            client.RF_getfreq()/10.0**6);
230     #Now we're ready to get packets.
231     while 1:
232         packet=None;
233         while packet==None:
234             packet=client.RF_rxpacket();
235         handlesimplicitipacket(packet);
236         sys.stdout.flush();
237
238
239
240 if(sys.argv[1]=="term"):
241     GoodFETConsole(client).run();
242 if(sys.argv[1]=="test"):
243     client.test();
244 if(sys.argv[1]=="deadtest"):
245     for i in range(1,10):
246         print "IDENT as %s" % client.CCidentstr();
247 if(sys.argv[1]=="dumpcode"):
248     f = sys.argv[2];
249     start=0x0000;
250     stop=0xFFFF;
251     if(len(sys.argv)>3):
252         start=int(sys.argv[3],16);
253     if(len(sys.argv)>4):
254         stop=int(sys.argv[4],16);
255     
256     print "Dumping code from %04x to %04x as %s." % (start,stop,f);
257     h = IntelHex(None);
258     i=start;
259     while i<=stop:
260         h[i]=client.CCpeekcodebyte(i);
261         if(i%0x100==0):
262             print "Dumped %04x."%i;
263         i+=1;
264     h.write_hex_file(f);
265 if(sys.argv[1]=="dumpdata"):
266     f = sys.argv[2];
267     start=0xE000;
268     stop=0xFFFF;
269     if(len(sys.argv)>3):
270         start=int(sys.argv[3],16);
271     if(len(sys.argv)>4):
272         stop=int(sys.argv[4],16);
273     
274     print "Dumping data from %04x to %04x as %s." % (start,stop,f);
275     h = IntelHex(None);
276     i=start;
277     while i<=stop:
278         h[i]=client.CCpeekdatabyte(i);
279         if(i%0x100==0):
280             print "Dumped %04x."%i;
281         i+=1;
282     h.write_hex_file(f);
283 if(sys.argv[1]=="status"):
284     print "Status: %s" %client.status();
285 if(sys.argv[1]=="halt"):
286     print "Halting CPU."
287     client.halt();
288 if(sys.argv[1]=="info"):
289     print "Ident   %s" % client.CCidentstr();
290     
291     try:
292         print "Freq    %10.3f MHz" % (client.RF_getfreq()/10**6);
293         print "RSSI    %02x" % client.RF_getrssi();
294     except:
295         print "Freq, RSSI, etc unknown.  Install SmartRF7.";
296     #print "Rate    %10i kbps" % (client.RF_getrate()/1000);
297     #print "PacketLen %02i bytes" % client.RF_getpacketlen();
298     #print "SMAC  0x%010x" % client.RF_getsmac();
299     #print "TMAC  0x%010x" % client.RF_gettmac();
300
301 if(sys.argv[1]=="regs"):
302     client.CMDrs();
303
304 if(sys.argv[1]=="erase"):
305     print "Status: %s" % client.status();
306     client.CCchiperase();
307     print "Status: %s" %client.status();
308
309 if(sys.argv[1]=="peekinfo"):
310     print "Select info flash."
311     client.CCwr_config(1);
312     print "Config is %02x" % client.CCrd_config();
313     
314     start=0x0000;
315     if(len(sys.argv)>2):
316         start=int(sys.argv[2],16);
317     stop=start;
318     if(len(sys.argv)>3):
319         stop=int(sys.argv[3],16);
320     print "Peeking from %04x to %04x." % (start,stop);
321     while start<=stop:
322         print "%04x: %02x" % (start,client.CCpeekcodebyte(start));
323         start=start+1;
324 if(sys.argv[1]=="poke"):
325     client.CCpokeirambyte(int(sys.argv[2],16),
326                           int(sys.argv[3],16));
327 if(sys.argv[1]=="randtest"):
328     #Seed RNG
329     client.CCpokeirambyte(0xBD,0x01); #RNDH=0x01
330     client.CCpokeirambyte(0xB4,0x04); #ADCCON1=0x04
331     client.CCpokeirambyte(0xBD,0x01); #RNDH=0x01
332     client.CCpokeirambyte(0xB4,0x04); #ADCCON1=0x04
333     
334     #Dump values
335     for foo in range(1,10):
336         print "%02x" % client.CCpeekirambyte(0xBD); #RNDH
337         client.CCpokeirambyte(0xB4,0x04); #ADCCON1=0x04
338         client.CCreleasecpu();
339         client.CChaltcpu();
340     print "%02x" % client.CCpeekdatabyte(0xDF61); #CHIP ID
341 if(sys.argv[1]=="adctest"):
342     # ADCTest 0xDF3A 0xDF3B
343     print "ADC TEST %02x%02x" % (
344         client.CCpeekdatabyte(0xDF3A),
345         client.CCpeekdatabyte(0xDF3B));
346 if(sys.argv[1]=="config"):
347     print "Config is %02x" % client.CCrd_config();
348
349 if(sys.argv[1]=="flash"):
350      f=sys.argv[2];
351      start=0;
352      stop=0xFFFF;
353      if(len(sys.argv)>3):
354          start=int(sys.argv[3],16);
355      if(len(sys.argv)>4):
356          stop=int(sys.argv[4],16);
357    
358      client.flash(f);
359 if(sys.argv[1]=="lock"):
360     print "Status: %s" %client.status();
361     client.CClockchip();
362     print "Status: %s" %client.status();
363 if(sys.argv[1]=="flashpage"):
364     target=0;
365     if(len(sys.argv)>2):
366         target=int(sys.argv[2],16);
367     print "Writing a page of flash from 0xF000 in XDATA"
368     client.CCflashpage(target);
369 if(sys.argv[1]=="erasebuffer"):
370     print "Erasing flash buffer.";
371     client.CCeraseflashbuffer();
372
373 if(sys.argv[1]=="writedata"):
374     f=sys.argv[2];
375     start=0;
376     stop=0xFFFF;
377     if(len(sys.argv)>3):
378         start=int(sys.argv[3],16);
379     if(len(sys.argv)>4):
380         stop=int(sys.argv[4],16);
381     
382     h = IntelHex(f);
383     
384     for i in h._buf.keys():
385         if(i>=start and i<=stop):
386             client.CCpokedatabyte(i,h[i]);
387             if(i%0x100==0):
388                 print "%04x" % i;
389 #if(sys.argv[1]=="flashtest"):
390 #    client.CCflashtest();
391 if(sys.argv[1]=="peekdata"):
392     start=0x0000;
393     if(len(sys.argv)>2):
394         start=int(sys.argv[2],16);
395     stop=start;
396     if(len(sys.argv)>3):
397         stop=int(sys.argv[3],16);
398     print "Peeking from %04x to %04x." % (start,stop);
399     while start<=stop:
400         print "%04x: %02x" % (start,client.CCpeekdatabyte(start));
401         start=start+1;
402 if(sys.argv[1]=="peek"):
403     start=0x0000;
404     if(len(sys.argv)>2):
405         start=int(sys.argv[2],16);
406     stop=start;
407     if(len(sys.argv)>3):
408         stop=int(sys.argv[3],16);
409     print "Peeking from %04x to %04x." % (start,stop);
410     while start<=stop:
411         print "%04x: %02x" % (start,client.CCpeekirambyte(start));
412         start=start+1;
413 if(sys.argv[1]=="verify"):
414     f=sys.argv[2];
415     start=0;
416     stop=0xFFFF;
417     if(len(sys.argv)>3):
418         start=int(sys.argv[3],16);
419     if(len(sys.argv)>4):
420         stop=int(sys.argv[4],16);
421     
422     h = IntelHex(f);
423     for i in h._buf.keys():
424         if(i>=start and i<stop):
425             peek=client.CCpeekcodebyte(i)
426             if(h[i]!=peek):
427                 print "ERROR at %04x, found %02x not %02x"%(i,peek,h[i]);
428             if(i%0x100==0):
429                 print "%04x" % i;
430 if(sys.argv[1]=="peekcode"):
431     start=0x0000;
432     if(len(sys.argv)>2):
433         start=int(sys.argv[2],16);
434     stop=start;
435     if(len(sys.argv)>3):
436         stop=int(sys.argv[3],16);
437     print "Peeking from %04x to %04x." % (start,stop);
438     while start<=stop:
439         print "%04x: %02x" % (start,client.CCpeekcodebyte(start));
440         start=start+1;
441 if(sys.argv[1]=="pokedata"):
442     start=0x0000;
443     val=0x00;
444     if(len(sys.argv)>2):
445         start=int(sys.argv[2],16);
446     if(len(sys.argv)>3):
447         val=int(sys.argv[3],16);
448     print "Poking %04x to become %02x." % (start,val);
449     client.CCpokedatabyte(start,val);
450
451 client.stop();