def RESP(self, fsm): """RESP state; respond to received message; assume 'rxdata' happened.""" mrx = self.rxdata.param self.rxdata.clear(), self.csbusy.clear() meta = mrx['meta'] data = mrx['data'] # check crc - assume crc is last 32 bits of data crcok = self.check_crc32(str(data)) if not crcok: return fsm.goto(self.RESUME) # is data for me? d = Dot11Data(data) ucast = self.isforme(d) bcast = self.isbroadcast(d) ns = (self.IDLE,) if self.isdata(d) and (ucast or bcast): # forward data to upstream using sock dummy = Dot11Data() hlen = len(dummy) s = data[hlen:-4] self.sock.send(s) fsm.debug("wrote %d bytes to socket"%(len(s) ) ) dst = TUN.eth_ntoa(s[0:6]) src = TUN.eth_ntoa(s[6:12]) (ethertype, ) = struct.unpack(">H", s[12:14]) fsm.debug("dst = %s"%(dst) ) fsm.debug("src = %s"%(src) ) fsm.debug("ethertype = %04X"%(ethertype) ) if ucast: ns = (self.TXACK, d, meta) if crcok: # FIXME: Need to implement this if using reciprocity! # Log meta data if using reciprocity!! sender = d.addr2 return fsm.goto(*ns)
def IDLE(self, fsm): """IDLE state; wait on `csbusy`, `txdata`, and `rxdata`.""" self.datatosend = None self.retrycount = 0 self.cslot = None self.toidle.set() ns = self.IDLE # wait on events if fsm.waitonevents(self.txdata, self.csbusy, self.rxdata): if self.txdata.isSet(): s = self.txdata.param # assume frame is an Ethernet frame dst = TUN.eth_ntoa(s[0:6]) src = TUN.eth_ntoa(s[6:12]) #src = self.addr # use local address for source (ethertype, ) = struct.unpack(">H", s[12:14]) fsm.debug("dst = %s"%(dst) ) fsm.debug("src = %s"%(src) ) fsm.debug("ethertype = %04X"%(ethertype) ) fsm.datatosend = self.datamsg(payload=s, addr1=dst, addr2=src) # initialize backoff/retry parameters self.retry(count=0) self.txdata.clear() ns = self.BACKOFF elif self.rxdata.isSet(): ns = self.RESP elif self.csbusy.isSet(): ns = self.RECV self.toidle.clear() return fsm.goto(ns)