Пример #1
0
    def HRECV(self, fsm, net, mac):
        """HRECV state; manage incoming traffic from MAC protocol.

        :param net: Associated `NET`.
        :param mac: Associated `MAC`.

        Based on the value of `htype`, this method will invoke the appropriate
        message handler to classify and handle traffic from `mac` to `net`.
        """
        if isinstance(net, Reference): net = net._deref
        if isinstance(mac, Reference): mac = mac._deref
        errmsg = "[ARP]: Must be connected to (%s,%s) to RECV!"%(net,mac)
        assert self.connected(net) and self.connected(mac), errmsg
        # get message from rxport
        rxport = self.getport((mac, "RX"))
        yield rxport.recv(fsm, 1)
        errmsg = "[ARP]: Error in receiving from mac 'RX' port in RECV!"
        assert fsm.acquired(rxport) and (len(fsm.got)==1), errmsg
        # send packet to appropriate message handler
        p = fsm.got[0]
        fname = "ARPTX.%s(%s)"%(self.traceid, p.traceid)
        if (mac.htype==const.ARP_HTYPE_ETHERNET):
            f = FSM(name=fname)
            f.goto(self.ETHRECV, net, mac, p)
            f.start()
        else:
            f = FSM(name=fname)
            f.goto(self.HERRRECV, net, mac, p)
            f.start()
        # continue in HRECV
        yield fsm.goto(self.HRECV, net, mac)
Пример #2
0
    def PSEND(self, fsm, net, mac):
        """PSEND state; Manage outgoing traffic from network protocol.

        Based on the value of `ptype`, this method will invoke the appropriate
        message handler to forward traffic from `net` to `mac`.
        """
        if isinstance(net, Reference): net = net._deref
        if isinstance(mac, Reference): mac = mac._deref
        errmsg = "[ARP]: Must be connected to (%s,%s) to SEND!"%(net,mac)
        assert self.connected(net) and self.connected(mac), errmsg
        # get message from rxport
        rxport = self.getport((net,"RX"))
        yield rxport.recv(fsm, 1)
        errmsg = "[ARP]: Error in receiving from net 'RX' port in SEND!"
        assert fsm.acquired(rxport) and (len(fsm.got)==1), errmsg
        # send packet to appropriate message handler
        p = fsm.got[0]
        fname = "ARPTX.%s(%s)"%(self.traceid, p.traceid)
        if (net.ptype==const.ARP_PTYPE_IP):
            f = FSM(name=fname)
            f.goto(self.IPSEND, net, mac, p)
            f.start()
        else:
            f = FSM(name=fname)
            f.goto(self.PERRSEND, net, mac, p)
            f.start()
        # continue in PSEND
        yield fsm.goto(self.PSEND, net, mac)
Пример #3
0
 def LISTEN(self, fsm, cif, rxport):
     """Listen to traffic sent by `ChannelInterface` on `rxport`."""
     assert (self.hasport(rxport) is not None), \
             "[CHANNEL]: Cannot listen on invalid Port!"
     # get data from rxport
     yield rxport.recv(fsm, 1)
     assert fsm.acquired(rxport) and (len(fsm.got)==1), \
             "[CHANNEL]: Error occurred during LISTEN on %s!"%(rxport)
     # forward on all outgoing edge
     p, u = fsm.got[0], cif
     neighbors = [str(c.traceid) for c in self.graph.neighbors(u) ]
     errmsg = "[CHANNEL]: Cannot forward non-Packet!"
     assert isinstance(p, Packet), errmsg
     for v in self.graph[u]:
         cmodel = self.graph[u][v]['model']
         errmsg = "[CHANNEL]: Cannot find corresponding TX Port!"
         assert (self.hasport((v, "TX") ) is not None)
         # if channel model for link is not active -> ignore packet
         if not cmodel.active: continue
         # filter packets using channel model
         drop = self.apply_filter(cmodel, p, u, v)
         if drop:
             self.log("drp",p,drop=drop,src=u.traceid,dst=v.traceid)
             continue            # continue with next link
         # copy and mark annotations
         c, txport = p.copy(), self.getport((v, "TX") )
         c.setanno('cif-src', u, ref=True)
         c.setanno('cif-dst', v, ref=True)
         # apply channel model
         propdelay = None
         r = self.apply_model(cmodel, c, u, v)
         if cmodel.verbose>CHANNEL_VERBOSE:
             cmodel.log_forward(c, src=u.traceid, dst=v.traceid)
         if ANNO.supports(r, 'cm-delay'):
             propdelay = r.getanno('cm-delay')
         # forward to destination
         if (r is None):
             self.log("drp",c,action="dropped by %s"%(cmodel.traceid) )
         elif (propdelay>0):
             # apply propagation delay
             f = FSM()
             f.goto(self.FORWARD, txport, [r])
             f.start(delay=propdelay)
         else:
             # send immediately (no delay)
             yield txport.send(fsm, [r])
     if self.verbose>CHANNEL_VERBOSE:
         self.log("fwd", p, dest="%s"%(neighbors) )
     # continue in LISTEN
     yield fsm.goto(self.LISTEN, cif, rxport)
Пример #4
0
 def LISTEN(self, fsm):
     """LISTEN state; monitor `radio` and manage packet detection."""
     r = self.radio
     assert isinstance(r, Radio), "[DOT11A]: Cannot find radio in LISTEN!"
     while fsm.active():
         # check rxenergy -> set csbusy?
         rxenergy = r.rxenergy()
         rxhigh = r.inreceive and (r.rxenergy() > DOT11A_CSTHRESHOLD)
         if rxhigh:
             self.set_csbusy(rxenergy="high, %.2f dBm" % (rxenergy), rxbuffer=[x.traceid for x in r.rxbuffer])
         else:
             self.set_csidle(rxenergy="%.2f dBm" % (rxenergy))
         # monitor events and RXD port
         yield self.RXD.recv(fsm, 1, renege=(r.rxdata, r.rxdone, r.txdata, r.txdone, self.detect))
         # RXD -> ignore incoming packets in LISTEN
         if fsm.acquired(self.RXD):
             assert len(fsm.got) == 1, (
                 "[DOT11A]: Received unexpected " + "number of packets from 'RXD' port in LISTEN state!"
             )
             p = fsm.got[0]
             self.log_drop(p, drop="not detected in LISTEN")
         # rxdata -> start DETECT thread
         if r.rxdata in fsm.eventsFired:
             p = r.rxdata.signalparam
             fname = "detect(%s)" % (p._id)
             ### XXX ####
             f = FSM()
             # f = self.newchild(fname, FSM, tracename=fname.upper() )
             f.goto(self.DETECT, p)
             f.start()
         # detect -> set csbusy -> goto DECODE
         if self.detect in fsm.eventsFired:
             p = self.detect.signalparam
             rxenergy = "%.2f dBm" % (r.rxenergy())
             sinr = "%.2f dB" % (self.sinr(p))
             self.set_csbusy(p, detect=True, rxenergy=rxenergy)
             danno = "dot11a-detect"
             errmsg = "[DOT11A]: Cannot find 'dot11a-detect' " + "annotation in detected packet!"
             assert ANNO.supports(p, danno) and p.getanno(danno), errmsg
             # yield hold, fsm, 0
             self.log("detect", p, rxenergy=rxenergy, sinr=sinr, rxbuffer=[x.traceid for x in r.rxbuffer])
             yield fsm.goto(self.DECODE, p)
         # ignore otherwise
         ignore = r.txdata in fsm.eventsFired
         ignore = ignore or (r.txdone in fsm.eventsFired)
         ignore = ignore or (r.rxdone in fsm.eventsFired)
         if ignore:
             pass
     return
Пример #5
0
    def RECV(self, fsm):
        """Manage upstream (or incoming) traffic.

        This method spawn worker processes to simulate the capture of each
        packet. These worker processes manage 'cif-drp' and 'cif-collision'
        annotations; along with simulating packet 'cif-duration'.
        """
        yield self.RXD.recv(fsm, 1)
        errmsg = "[CHANNELIF]: RECV() error occurred during recv() from RXD!"
        assert fsm.acquired(self.RXD) and (len(fsm.got)==1), errmsg
        # start capture thread
        for p in fsm.got:
            w = FSM()
            w.goto(self.CAPTURE, p)
            w.start(prior=True)
        # continue in RECV
        yield fsm.goto(self.RECV)
        assert False, "State transition failed!"