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()
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)
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()
def _wait(self): """ Wait for incoming packets on signalling channel """ self.__buffer = b'' self.stream.read_bytes(HEADER.sizeof(), self._on_read)
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)
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)