예제 #1
0
    def _on_read(self, future):
        """ Appends bytes read from socket to a buffer. Once the full packet
        has been read the parser is invoked and the buffers is cleared. The
        parsed packet is then passed to the suitable method or dropped if the
        packet type in unknown. """

        try:
            line = future.result()
            self.__buffer = self.__buffer + line
        except StreamClosedError as stream_ex:
            self.log.error(stream_ex)
            return

        hdr = HEADER.parse(self.__buffer)

        if len(self.__buffer) < hdr.length:
            remaining = hdr.length - len(self.__buffer)
            future = self.stream.read_bytes(remaining)
            future.add_done_callback(self._on_read)
            return

        try:
            self._trigger_message(hdr)
        except Exception as ex:
            self.log.exception(ex)
            self.stream.close()

        if not self.stream.closed():
            self._wait()
예제 #2
0
    def _trigger_message(self, hdr):

        if hdr.type == E_TYPE_SINGLE:
            event = E_SINGLE.parse(self.__buffer[HEADER.sizeof():])
            offset = HEADER.sizeof() + E_SINGLE.sizeof()
        elif hdr.type == E_TYPE_SCHED:
            event = E_SCHED.parse(self.__buffer[HEADER.sizeof():])
            offset = HEADER.sizeof() + E_SCHED.sizeof()
        elif hdr.type == E_TYPE_TRIG:
            event = E_TRIG.parse(self.__buffer[HEADER.sizeof():])
            offset = HEADER.sizeof() + E_TRIG.sizeof()
        else:
            self.log.error("Unknown event %u", hdr.type)
            return

        msg_type = event.action

        if msg_type not in self.server.pt_types:
            self.log.error("Unknown message type %u", msg_type)
            return

        if self.server.pt_types[msg_type]:

            self.log.info("Got message type %u (%s)", msg_type,
                          self.server.pt_types[msg_type].name)

            msg = self.server.pt_types[msg_type].parse(self.__buffer[offset:])
            addr = hex_to_ether(hdr.enbid)

            try:
                vbs = RUNTIME.vbses[addr]
            except KeyError:
                self.log.error("Unknown VBS %s, closing connection", addr)
                self.stream.close()
                return

            name = self.server.pt_types[msg_type].name
            handler_name = "_handle_%s" % name

            if hasattr(self, handler_name):
                self.log.info("%s from %s VBS %s seq %u", name, self.addr[0],
                              vbs.addr, hdr.seq)
                handler = getattr(self, handler_name)
                handler(vbs, hdr, event, msg)

            if msg_type in self.server.pt_types_handlers:
                for handler in self.server.pt_types_handlers[msg_type]:
                    handler(vbs, hdr, event, msg)
예제 #3
0
    def _on_read(self, line):
        """ Appends bytes read from socket to a buffer. Once the full packet
        has been read the parser is invoked and the buffers is cleared. The
        parsed packet is then passed to the suitable method or dropped if the
        packet type in unknown. """

        self.__buffer = self.__buffer + line
        hdr = HEADER.parse(self.__buffer)

        if len(self.__buffer) < hdr.length:
            remaining = hdr.length - len(self.__buffer)
            self.stream.read_bytes(remaining, self._on_read)
            return

        try:
            self._trigger_message(hdr)
        except Exception as ex:
            LOG.exception(ex)
            self.stream.close()

        if not self.stream.closed():
            self._wait()
예제 #4
0
    def _wait(self):
        """ Wait for incoming packets on signalling channel """

        self.__buffer = b''
        self.stream.read_bytes(HEADER.sizeof(), self._on_read)
예제 #5
0
    def _trigger_message(self, hdr):

        if hdr.type == E_TYPE_SINGLE:
            event = E_SINGLE.parse(self.__buffer[HEADER.sizeof():])
            offset = HEADER.sizeof() + E_SINGLE.sizeof()
        elif hdr.type == E_TYPE_SCHED:
            event = E_SCHED.parse(self.__buffer[HEADER.sizeof():])
            offset = HEADER.sizeof() + E_SCHED.sizeof()
        elif hdr.type == E_TYPE_TRIG:
            event = E_TRIG.parse(self.__buffer[HEADER.sizeof():])
            offset = HEADER.sizeof() + E_TRIG.sizeof()
        else:
            self.log.error("Unknown event %u", hdr.type)
            return

        msg_type = event.action

        if msg_type not in self.server.pt_types:
            self.log.error("Unknown message type %u", msg_type)
            return

        if self.server.pt_types[msg_type]:

            msg = self.server.pt_types[msg_type].parse(self.__buffer[offset:])
            msg_name = self.server.pt_types[msg_type].name

            addr = EtherAddress(hdr.enbid[2:8])

            try:
                vbs = RUNTIME.vbses[addr]
            except KeyError:
                self.log.error("Unknown VBS %s, closing connection", addr)
                self.stream.close()
                return

            if not self.vbs:
                self.vbs = vbs

            valid = [EP_ACT_HELLO]
            if not self.vbs.is_connected() and msg_type not in valid:
                self.log.info("Got %s message from disconnected VBS %s seq %u",
                              msg_name, addr, hdr.seq)
                return

            valid = [EP_ACT_HELLO, EP_ACT_CAPS]
            if not self.vbs.is_online() and msg_type not in valid:
                self.log.info("Got %s message from offline VBS %s seq %u",
                              msg_name, addr, hdr.seq)
                return

            self.log.info("Got %s message from %s seq %u xid %u",
                          msg_name, self.vbs.addr, hdr.seq, hdr.xid)

            handler_name = "_handle_%s" % msg_name

            if hasattr(self, handler_name):
                handler = getattr(self, handler_name)
                handler(vbs, hdr, event, msg)

            if msg_type in self.server.pt_types_handlers:
                for handler in self.server.pt_types_handlers[msg_type]:
                    handler(vbs, hdr, event, msg)
예제 #6
0
    def _wait(self):
        """ Wait for incoming packets on signalling channel """

        self.__buffer = b''
        future = self.stream.read_bytes(HEADER.sizeof())
        future.add_done_callback(self._on_read)