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 self.fname = fname
00140 self.sport = serial.Serial(fname, self.BAUDRATE, timeout=10)
00141 self.sport.open()
00142 self.RxThread=threading.Thread(target = self.__rx__)
00143 self.RxThread.setDaemon(1)
00144 self.RxThread.start()
00145 self.init()
00146
00147 def reset(self):
00148 self.sport.write("\n\nidle\n")
00149
00150 def init(self):
00151 self.sport.write("\n\nidle\n")
00152 self.update_hw_status()
00153 t = int(time.time())
00154 self.sport.write("timeset %s\n" % t)
00155 self.timebase = t
00156 self.sport.write("sniff\n")
00157
00158 def update_hw_status(self):
00159 self.sport.write("\n\nidle\n")
00160 self.sport.write("parms\n")
00161 time.sleep(.5)
00162 for l in self.get_text_queue():
00163 if l.find("PLATFORM")>=0:
00164 self.platform = l.split(":")[1].strip()
00165 if l.find("SUPP_CMSK")>=0:
00166 self.clist = self.get_channels(eval(l.split(":")[1]))
00167 if l.find("CURR_CHAN")>=0:
00168 self.channel = eval(l.split(":")[1])
00169 if l.find("TIMER_SCALE")>=0:
00170 self.tscale = eval(l.split(":")[1])
00171 if l.find("TICK_NUMBER")>=0:
00172 self.ticknb = eval(l.split(":")[1])
00173 if l.find("CURR_RATE")>=0:
00174 self.crate = l.split(":")[1].strip()
00175 if l.find("SUPP_RATES")>=0:
00176 self.rates = l.split(":")[1].strip()
00177
00178
00179 def get_text_queue(self):
00180 ret = ""
00181 while not self.TextQueue.empty():
00182 ret += self.TextQueue.get()
00183 ret = ret.replace('\x0b',"")
00184 return ret.split("\n")
00185
00186 def get_channels(self,cmask):
00187 ret = []
00188 cidx = 0
00189 while cmask != 0:
00190 if cmask & 1:
00191 ret.append(cidx)
00192 cidx += 1
00193 cmask /=2
00194 return ret
00195
00196 def close(self):
00197 if self.RxThread != None:
00198 self.RxThread.join(self.TMO)
00199 self.RxThread = None
00200 self.sport.close()
00201
00202 def info(self):
00203 self.update_hw_status()
00204 ret = {'type' : 'port',
00205 'chan' : self.channel,
00206 'port' : self.sport.port,
00207 'clist' : self.clist,
00208 'tscale' : self.tscale,
00209 'ticknb' : self.ticknb,
00210 'crate' : self.crate,
00211 'rates' : self.rates,
00212 'platform' : self.platform,
00213 }
00214 self.sport.write("sniff\n")
00215 return ret
00216
00217 def __rx__(self):
00218 frm = ""
00219 while 1:
00220 try:
00221 sdata = self.sport.read(1)
00222 n = self.sport.inWaiting()
00223 if n:
00224 sdata += self.sport.read(n)
00225 except RxErrors:
00226 break
00227 except:
00228 traceback.print_exc()
00229 break
00230 frm += sdata
00231 if self.state == self.UNSYNC:
00232 self.TextQueue.put(sdata)
00233 p = self.sync_search(frm)
00234 if type(p) != None:
00235 frm = frm[p:]
00236 self.state = self.SYNCED
00237 if self.state == self.SYNCED:
00238 self.state,frm = self.packetizer(frm)
00239 self.message(2,"state sync after packetizer(), state=%d, len_frm=%d",self.state, len(frm))
00240
00241 def sync_search(self,frm):
00242 ret = None
00243 p = 0
00244 nbstartpos = frm.count('\x01')
00245 dlen = len(frm)
00246 if nbstartpos:
00247 self.message(2,"syncsearch : dlen=%d, nbstarts=%d" ,dlen,nbstartpos)
00248 for idx in range(nbstartpos):
00249 try:
00250 p += frm[p:].index('\x01')
00251 plen = ord(frm[p+1])
00252 pe = p + plen + 2
00253 self.message(2,"syncing : idx=%d, packet=%d:%d, plen=%d dlen=%d", idx,p,pe,plen,dlen)
00254
00255 if pe <= dlen:
00256 self.message(2,"packet : %s " , str(map(lambda i,f=frm: hex(ord(f[i])), (p,p+1,pe-1,pe) )))
00257 if(frm[pe] == '\x04'):
00258 ret = p
00259 self.message(1,"synced : idx=%d, packet=%d:%d, plen=%d dlen=%d", idx,p,pe,plen,dlen)
00260 raise Exception, "Synced"
00261 p += 1
00262 except IndexError:
00263
00264 break
00265 except Exception:
00266 break
00267 except:
00268 self.exc_handler("sync_search")
00269 break
00270 return ret
00271
00272 def packetizer(self,frm):
00273 state = self.SYNCED
00274 while 1:
00275 frmlen = len(frm)
00276 if len(frm) < 3:
00277
00278 break
00279 if frm[0] != '\x01':
00280 state = self.UNSYNC
00281 break
00282 pktlen = ord(frm[1])
00283 if (pktlen+3) > frmlen:
00284
00285 break
00286 if frm[pktlen+2] != '\x04':
00287 state = self.UNSYNC
00288 break
00289 packet,frm = frm[:pktlen+3],frm[pktlen+3:]
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 fl = pktlen - 8
00300 ticks,pkt = packet[2:10], packet[10:-1]
00301 ticks = struct.unpack('LL',ticks)
00302 tstamp = ((ticks[0]*self.ticknb) + ticks[1]) * self.tscale
00303 t_sec = int(tstamp)
00304 t_usec = int((tstamp-t_sec)*1.0e6)
00305 ts = struct.pack('LL',(t_sec+self.timebase),t_usec)
00306 lenfield = struct.pack("LL",fl,fl)
00307 packet = ts+lenfield+pkt
00308
00309 if self.FCNT < self.maxpackets or self.maxpackets == 0:
00310 self.RxQueue.put(packet)
00311 self.FCNT += 1
00312 self.message(1,"Found Packet l=%d qsize: %d:\npkt: %s",
00313 pktlen, self.RxQueue.qsize(),
00314 " ".join(map(lambda s: '%02x' %s,map(ord,packet))))
00315 else:
00316 self.message(1,"Discard Packet l=%d qsize: %d", pktlen,self.RxQueue.qsize())
00317 return state,frm
00318
00319 def set_channel(self, channel):
00320 if channel in self.clist:
00321 self.channel = channel
00322 time.sleep(0.1)
00323 self.sport.write("chan %d\n" % channel)
00324 else:
00325 print "Unsupported channel %d not in %s" % (channel,self.clist)
00326
00327 def set_rate(self, rate):
00328 if rate in self.rates:
00329 self.rate = rate
00330 self.sport.write("\nidle\ndrate %s\nsniff\n" % self.rate)
00331 else:
00332 print "Unsupported data rate %s not in %s" % (rate, self.rates)
00333
00334 def read_packet(self):
00335 if self.RxQueue.empty():
00336 ret = None
00337 else:
00338 ret = self.RxQueue.get()
00339 return ret
00340
00341