00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 import sys, serial, time, threading, Queue, struct, os
00038 from ieee802154_base import PcapBase, UtilBase
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 class FileIn(PcapBase, UtilBase):
00055
00056
00057
00058 def open(self, fname):
00059 self.fname = fname
00060 self.fh = open(fname,'r')
00061 self.FCNT = 0
00062 d = self.fh.read()
00063 self.HEADER,self.frames = self.pcap_parse_data(d)
00064 print "nb frames", len(self.frames)
00065 self.frameidx = 0
00066
00067
00068 def close(self):
00069 self.fh.close()
00070
00071
00072 def pcap_get_header(self):
00073 return self.HEADER
00074
00075 def info(self):
00076 afn = os.path.abspath(self.fh.name)
00077 ret = {'type' : 'file',
00078 'file' : os.path.basename(afn),
00079 'dir' : os.path.dirname(afn),
00080 'frames' : self.FCNT,
00081 }
00082 return ret
00083
00084
00085
00086 def set_channel(self, channel):
00087 self.error("can not set channel on a file")
00088
00089
00090 def read_packet(self):
00091 try:
00092
00093 ret = self.frames[self.frameidx]
00094 self.frameidx += 1
00095 self.FCNT += 1
00096 print map(hex,map(ord,ret))
00097 except IndexError:
00098 ret = None
00099 except:
00100 import traceback
00101 traceback.print_exc()
00102 ret = None
00103 return ret
00104
00105
00106
00107 RxErrors = [Exception]
00108 try:
00109 import pywintypes
00110 RxErrors.append(pywintypes.error)
00111 except:
00112 pass
00113 RxErrors = tuple(RxErrors)
00114
00115
00116
00117
00118
00119 class PortIn(PcapBase, UtilBase):
00120 TMO = 1
00121 FCNT = 0
00122 UNSYNC = 0
00123 SYNCED = 1
00124 IDXERR = 0
00125 BAUDRATE = 38400
00126 def __init__(self):
00127 self.RxThread = None
00128 self.RxQueue = Queue.Queue()
00129 self.TextQueue = Queue.Queue()
00130 self.channel = None
00131 self.crate = None
00132 self.clist = []
00133 self.state = self.UNSYNC
00134 self.maxpackets = -1
00135
00136 def open(self, fname):
00137 if self.RxThread:
00138 self.RxThread.join()
00139 try:
00140 port,baud = fname.split(":")
00141 except:
00142 port = fname
00143 else:
00144 self.BAUDRATE = eval(baud)
00145 self.fname = port
00146 self.sport = serial.Serial(self.fname, self.BAUDRATE, timeout=10)
00147 self.sport.open()
00148 self.RxThread=threading.Thread(target = self.__rx__)
00149 self.RxThread.setDaemon(1)
00150 self.RxThread.start()
00151 self.init()
00152
00153 def reset(self):
00154 self.sport.write("\n\nidle\n")
00155
00156 def init(self):
00157 self.sport.write("\n\nidle\n")
00158 self.update_hw_status()
00159 t = int(time.time())
00160 self.sport.write("timeset %s\n" % t)
00161 self.timebase = t
00162 self.sport.write("sniff\n")
00163
00164 def update_hw_status(self):
00165 self.sport.write("\n\nidle\n")
00166 self.sport.write("parms\n")
00167 time.sleep(.5)
00168 for l in self.get_text_queue():
00169 if l.find("PLATFORM")>=0:
00170 self.platform = l.split(":")[1].strip()
00171 if l.find("SUPP_CMSK")>=0:
00172 self.clist = self.get_channels(eval(l.split(":")[1]))
00173 if l.find("CURR_CHAN")>=0:
00174 self.channel = eval(l.split(":")[1])
00175 if l.find("TIMER_SCALE")>=0:
00176 self.tscale = eval(l.split(":")[1])
00177 if l.find("TICK_NUMBER")>=0:
00178 self.ticknb = eval(l.split(":")[1])
00179 if l.find("CURR_RATE")>=0:
00180 self.crate = l.split(":")[1].strip()
00181 if l.find("SUPP_RATES")>=0:
00182 self.rates = l.split(":")[1].strip()
00183
00184
00185 def get_text_queue(self):
00186 ret = ""
00187 while not self.TextQueue.empty():
00188 ret += self.TextQueue.get()
00189 ret = ret.replace('\x0b',"")
00190 return ret.split("\n")
00191
00192 def get_channels(self,cmask):
00193 ret = []
00194 cidx = 0
00195 while cmask != 0:
00196 if cmask & 1:
00197 ret.append(cidx)
00198 cidx += 1
00199 cmask /=2
00200 return ret
00201
00202 def close(self):
00203 if self.RxThread != None:
00204 self.RxThread.join(self.TMO)
00205 self.RxThread = None
00206 self.sport.close()
00207
00208 def info(self):
00209 self.update_hw_status()
00210 ret = {'type' : 'port',
00211 'chan' : self.channel,
00212 'port' : self.sport.port,
00213 'clist' : self.clist,
00214 'tscale' : self.tscale,
00215 'ticknb' : self.ticknb,
00216 'crate' : self.crate,
00217 'rates' : self.rates,
00218 'platform' : self.platform,
00219 }
00220 self.sport.write("sniff\n")
00221 return ret
00222
00223 def __rx__(self):
00224 frm = ""
00225 while 1:
00226 try:
00227 sdata = self.sport.read(1)
00228 n = self.sport.inWaiting()
00229 if n:
00230 sdata += self.sport.read(n)
00231 except RxErrors:
00232 break
00233 except:
00234 traceback.print_exc()
00235 break
00236 frm += sdata
00237 if self.state == self.UNSYNC:
00238 self.TextQueue.put(sdata)
00239 p = self.sync_search(frm)
00240 if type(p) != None:
00241 frm = frm[p:]
00242 self.state = self.SYNCED
00243 if self.state == self.SYNCED:
00244 self.state,frm = self.packetizer(frm)
00245 self.message(2,"state sync after packetizer(), state=%d, len_frm=%d",self.state, len(frm))
00246
00247 def sync_search(self,frm):
00248 ret = None
00249 p = 0
00250 nbstartpos = frm.count('\x01')
00251 dlen = len(frm)
00252 if nbstartpos:
00253 self.message(2,"syncsearch : dlen=%d, nbstarts=%d" ,dlen,nbstartpos)
00254 for idx in range(nbstartpos):
00255 try:
00256 p += frm[p:].index('\x01')
00257 plen = ord(frm[p+1])
00258 pe = p + plen + 2
00259 self.message(2,"syncing : idx=%d, packet=%d:%d, plen=%d dlen=%d", idx,p,pe,plen,dlen)
00260
00261 if pe <= dlen:
00262 self.message(2,"packet : %s " , str(map(lambda i,f=frm: hex(ord(f[i])), (p,p+1,pe-1,pe) )))
00263 if(frm[pe] == '\x04'):
00264 ret = p
00265 self.message(1,"synced : idx=%d, packet=%d:%d, plen=%d dlen=%d", idx,p,pe,plen,dlen)
00266 raise Exception, "Synced"
00267 p += 1
00268 except IndexError:
00269
00270 break
00271 except Exception:
00272 break
00273 except:
00274 self.exc_handler("sync_search")
00275 break
00276 return ret
00277
00278 def packetizer(self,frm):
00279 state = self.SYNCED
00280 while 1:
00281 frmlen = len(frm)
00282 if len(frm) < 3:
00283
00284 break
00285 if frm[0] != '\x01':
00286 state = self.UNSYNC
00287 break
00288 pktlen = ord(frm[1])
00289 if (pktlen+3) > frmlen:
00290
00291 break
00292 if frm[pktlen+2] != '\x04':
00293 state = self.UNSYNC
00294 break
00295 packet,frm = frm[:pktlen+3],frm[pktlen+3:]
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 fl = pktlen - 8
00306 ticks,pkt = packet[2:10], packet[10:-1]
00307 ticks = struct.unpack('LL',ticks)
00308 tstamp = ((ticks[0]*self.ticknb) + ticks[1]) * self.tscale
00309 t_sec = int(tstamp)
00310 t_usec = int((tstamp-t_sec)*1.0e6)
00311 ts = struct.pack('LL',(t_sec+self.timebase),t_usec)
00312 lenfield = struct.pack("LL",fl,fl)
00313 packet = ts+lenfield+pkt
00314
00315 if self.FCNT < self.maxpackets or self.maxpackets == 0:
00316 self.RxQueue.put(packet)
00317 self.FCNT += 1
00318 self.message(1,"Found Packet l=%d qsize: %d:\npkt: %s",
00319 pktlen, self.RxQueue.qsize(),
00320 " ".join(map(lambda s: '%02x' %s,map(ord,packet))))
00321 else:
00322 self.message(1,"Discard Packet l=%d qsize: %d", pktlen,self.RxQueue.qsize())
00323 return state,frm
00324
00325 def set_channel(self, channel):
00326 if channel in self.clist:
00327 self.channel = channel
00328 time.sleep(0.1)
00329 self.sport.write("chan %d\n" % channel)
00330 else:
00331 print "Unsupported channel %d not in %s" % (channel,self.clist)
00332
00333 def set_rate(self, rate):
00334 if rate in self.rates:
00335 self.rate = rate
00336 self.sport.write("\nidle\ndrate %s\nsniff\n" % self.rate)
00337 else:
00338 print "Unsupported data rate %s not in %s" % (rate, self.rates)
00339
00340 def read_packet(self):
00341 if self.RxQueue.empty():
00342 ret = None
00343 else:
00344 ret = self.RxQueue.get()
00345 return ret
00346
00347