Package killerbee :: Module GoodFETatmel128
[hide private]
[frames] | no frames]

Source Code for Module killerbee.GoodFETatmel128

  1  # GoodFETclient to interface zigduino/atmel128 radio 
  2  # forked by bx from code by neighbor Travis Goodspeed 
  3  from GoodFETAVR import GoodFETAVR 
  4  import sys, binascii, os, array, time, glob, struct 
  5   
  6  fmt = ("B", "<H", None, "<L") 
  7   
8 -class GoodFETatmel128rfa1(GoodFETAVR):
9 ATMELRADIOAPP = 0x53 10 autocrc = 0 11 verbose = False 12 connected = 0 13 enable_AACK = False
14 - def serInit(self, port=None, timeout=2, attemptlimit=None):
15 if port==None: 16 port=os.environ.get("GOODFET"); 17 self.pyserInit(port, timeout, attemptlimit)
18
19 - def pyserInit(self, port, timeout, attemptlimit):
20 """Open the serial port""" 21 if self.connected == 0: 22 if (not (attemptlimit == None)) and (attemptlimit <= 1): 23 # it always takes at least 2 tries 24 attemptlimit == 2 25 26 # Make timeout None to wait forever, 0 for non-blocking mode. 27 import serial; 28 29 if os.name=='nt' and sys.version.find('64 bit')!=-1: 30 print "WARNING: PySerial requires a 32-bit Python build in Windows."; 31 32 if port is None and os.environ.get("GOODFET")!=None: 33 glob_list = glob.glob(os.environ.get("GOODFET")); 34 if len(glob_list) > 0: 35 port = glob_list[0]; 36 else: 37 port = os.environ.get("GOODFET"); 38 if port is None: 39 glob_list = glob.glob("/dev/tty.usbserial*"); 40 if len(glob_list) > 0: 41 port = glob_list[0]; 42 if port is None: 43 glob_list = glob.glob("/dev/ttyUSB*"); 44 if len(glob_list) > 0: 45 port = glob_list[0]; 46 if port is None: 47 glob_list = glob.glob("/dev/ttyU0"); 48 if len(glob_list) > 0: 49 port = glob_list[0]; 50 if port is None and os.name=='nt': 51 from scanwin32 import winScan; 52 scan=winScan(); 53 for order,comport,desc,hwid in sorted(scan.comports()): 54 try: 55 if hwid.index('FTDI')==0: 56 port=comport; 57 #print "Using FTDI port %s" % port 58 except: 59 #Do nothing. 60 a=1; 61 62 baud=115200; 63 64 self.serialport = serial.Serial( 65 port, 66 baud, 67 parity = serial.PARITY_NONE, 68 timeout=timeout 69 ) 70 71 self.verb=0; 72 self.data="" 73 attempts=0; 74 self.connected=0; 75 76 while self.connected==0: 77 self.serialport.setDTR(False) 78 while self.verb!=0x7F or self.data!="http://goodfet.sf.net/": 79 if attemptlimit is not None and attempts >= attemptlimit: 80 return 81 82 attempts=attempts+1; 83 self.readcmd(); #Read the first command. 84 if self.verbose: 85 print "Got %02x,%02x:'%s'" % (self.app,self.verb,self.data); 86 87 #Here we have a connection, but maybe not a good one. 88 #print "We have a connection." 89 for foo in range(1,30): 90 time.sleep(1) 91 if not self.monitorecho(): 92 self.connected = 0 93 if self.verbose: 94 print "Comm error on try %i." % (foo) 95 else: 96 self.connected = 1 97 break 98 if self.verbose: 99 print "Connected after %02i attempts." % attempts; 100 self.serialport.setTimeout(12);
101
102 - def serClose(self):
103 self.connected = 0 104 self.serialport.close()
105 106
107 - def writecmd(self, app, verb, count=0, data=[]):
108 """Write a command and some data to the GoodFET.""" 109 self.serialport.write(chr(app)); 110 self.serialport.write(chr(verb)); 111 if self.verbose: 112 print "Tx: ( 0x%02x, 0x%02x, %d )" % ( app, verb, count ) 113 if count > 0: 114 if(isinstance(data,list)): 115 old = data 116 data = [] 117 for i in range(0,count): 118 data += chr(old[i]); 119 outstr=''.join(data); 120 121 #little endian 16-bit length 122 count = len(outstr) 123 self.serialport.write(chr(count&0xFF)); 124 self.serialport.write(chr(count>>8)); 125 if count > 0: 126 if self.verbose: 127 print "sending: %s" %outstr.encode("hex") 128 self.serialport.write(outstr); 129 130 131 if not self.besilent: 132 out = self.readcmd() 133 if out and self.verbose: 134 print "read: " + out.encode("hex") 135 return out 136 else: 137 return None
138
139 - def readcmd(self):
140 141 """Read a reply from the GoodFET.""" 142 app = self.serialport.read(1) 143 144 if len(app) < 1: 145 if self.verbose: 146 print "Rx: None" 147 148 self.app = 0 149 self.verb = 0 150 self.count = 0 151 self.data = "" 152 return 153 154 self.app=ord(app); 155 156 v = self.serialport.read(1); 157 if v: 158 self.verb = ord(v) 159 else: 160 self.verb = 0 161 162 c1 = self.serialport.read(1) 163 c2 = self.serialport.read(1) 164 if (c1 and c2): 165 self.count= ord(c1) + (ord(c2)<<8) 166 else: 167 self.count = 0 168 if self.verbose: 169 print "Rx: ( 0x%02x, 0x%02x, %i )" % ( self.app, self.verb, self.count ) 170 171 #Debugging string; print, but wait. 172 if self.app==0xFF: 173 if self.verb==0xFF: 174 print "# DEBUG %s" % self.serialport.read(self.count) 175 elif self.verb==0xFE: 176 print "# DEBUG 0x%x" % struct.unpack(fmt[self.count-1], self.serialport.read(self.count))[0] 177 elif self.verb==0xFD: 178 #Do nothing, just wait so there's no timeout. 179 print "# NOP."; 180 return "" 181 else: 182 self.data=self.serialport.read(self.count); 183 return self.data;
184
185 - def RF_setchannel(self, chan):
186 if (chan < 11) or (chan > 26): 187 print "Channel out of range" 188 else: 189 self.poke(0x8, chan)
190
191 - def peek(self,reg,bytes=1):
192 """Read a Register. """ 193 #Automatically calibrate the len. 194 if bytes != 1: 195 print "Warning, currently cannot poke more than 1 byte" 196 bytes = 1 197 data = [reg, 0, bytes%255, bytes>>8] #+ ([0]*bytes) 198 self.data = None 199 self.writecmd(self.ATMELRADIOAPP,0x02,len(data),data); 200 toret=0; 201 #print self.data.encode("hex") 202 if self.data: 203 #for i in range(0,bytes): 204 # toret=toret|(ord(self.data[i+1])<<(8*i)); 205 #return toret; 206 # right now only works with a byte of data 207 return ord(self.data) 208 else: 209 return -1
210
211 - def poke(self,reg,val,bytes=1): # todo, support >1 byte
212 """Write an Register.""" 213 data = [reg, 0] #+ ([0]*bytes) 214 data=[reg, 0] 215 if bytes != 1: 216 print "Warning, currently cannot poke more than 1 byte" 217 bytes = 1 218 for i in range(0,bytes): 219 data=data+[(val>>(8*i))&0xFF]; 220 221 self.writecmd(self.ATMELRADIOAPP,0x03,len(data),data); 222 newval = self.peek(reg,bytes) 223 if newval!=val: 224 print "Warning, failed to set r%02x=%02x, got %02x." %( 225 reg, 226 val, 227 newval); 228 229 return;
230
231 - def setup(self):
232 self.RF_setup()
233
234 - def RF_setup(self):
235 self.writecmd(self.ATMELRADIOAPP, 0x10, 0, None)
236
237 - def RF_rxpacket(self):
238 """Get a packet from the radio. Returns None if none is waiting.""" 239 #doto: check if packet has arrived, flush if not new 240 self.writecmd(self.ATMELRADIOAPP, 0x80, 0, None) 241 data=self.data; 242 self.packetlen = len(data) 243 if (self.packetlen > 0): 244 return data; 245 else: 246 return None
247
248 - def RF_txpacket(self, payload):
249 if type(payload) == list: #convert to string 250 import array 251 payload = array.array('B', payload).tostring() 252 self.writecmd(self.ATMELRADIOAPP, 0x81, len(payload), payload)
253 254
255 - def RF_getrssi(self):
256 """Returns the received signal strength""" 257 base = -90 258 val = self.peek(0x7) & 0x7f # read rssi bits 259 if val == 0: 260 return base - 1 261 elif val < 0x53: 262 return val + base 263 else: 264 return 0x53 + base
265
266 - def RF_enable_AACK(self, enable = True):
267 if (enable and (not self.enable_AACK)): 268 self.enable_AACK = True 269 self.writecmd(self.ATMELRADIOAPP, 0x84) 270 elif ((not enable) and self.enable_AACK): 271 self.enable_AACK = False 272 self.writecmd(self.ATMELRADIOAPP, 0x85)
273 274
275 - def RF_autocrc(self, autocrc=1):
276 self.autocrc = autocrc 277 if autocrc: 278 self.writecmd(self.ATMELRADIOAPP, 0x86) 279 else: 280 self.writecmd(self.ATMELRADIOAPP, 0x87)
281