def __init__(self):
     self._tcp_port = config.config()["network"]["port"]
     tcp_handlers = {"new_db": save_db_handler}
     self._tcp_net = ConnServer(("localhost", self._tcp_port), tcp_handlers)
     self._local_net = CANserver(config.config()["can_net"]["interface"], self.local_message_handler)
     self._conf_period = config.config()["can_net"]["confirmation_period"]
     # number of periods to wait:
     self._conf_timeout = config.config()["can_net"]["confirmation_timeout"] / self._conf_period
     self._conf_waiters = {}
     # _local_handlers struct: (message hanler, message decoder)
     self._local_handlers = {
         0: (self._handle_confirmation_msg, lprotocols.in_lvl2_confirmation),
         1: (self._handle_common_msg, lprotocols.in_lvl2_common),
     }
     self._points_manager = PointsManager(self.send_local_msg)
     self._log_sync = LogSynchronizer(self._tcp_net.server_out)
class Node:
    def __init__(self):
        self._tcp_port = config.config()["network"]["port"]
        tcp_handlers = {"new_db": save_db_handler}
        self._tcp_net = ConnServer(("localhost", self._tcp_port), tcp_handlers)
        self._local_net = CANserver(config.config()["can_net"]["interface"], self.local_message_handler)
        self._conf_period = config.config()["can_net"]["confirmation_period"]
        # number of periods to wait:
        self._conf_timeout = config.config()["can_net"]["confirmation_timeout"] / self._conf_period
        self._conf_waiters = {}
        # _local_handlers struct: (message hanler, message decoder)
        self._local_handlers = {
            0: (self._handle_confirmation_msg, lprotocols.in_lvl2_confirmation),
            1: (self._handle_common_msg, lprotocols.in_lvl2_common),
        }
        self._points_manager = PointsManager(self.send_local_msg)
        self._log_sync = LogSynchronizer(self._tcp_net.server_out)

    #### <local_handlers>
    def _handle_confirmation_msg(self, hw_addr, device_id, response_code):
        # TODO: log smth
        self._conf_waiters[(hw_addr, device_id)] = response_code

    def _handle_common_msg(self, hw_addr, device_id, lfb, data):
        # concatenate msgs (msgs must always be sended&recieved in order)
        id = (hw_addr, device_id)
        buffer = self._local_net.server_in.incomplete
        if not buffer.has_key(id):
            buffer[id] = []
        buffer[id].append(data)
        if lfb == 1:
            self._points_manager.process_msg(id[0], id[1], buffer[id])
            buffer[id] = []

    #### <\local_handlers>

    def send_local_msg(self, id, msg):
        self._local_net.server_out.send(msg)
        for i in range(0, int(self._conf_timeout)):
            time.sleep(self._conf_period)
            if self._conf_waiters.has_key(id):
                return self._conf_waiters.pop(id)
        return None

    def start(self):
        self._tcp_net.start_servers()
        self._local_net.server_in.start()
        self._log_sync.run()  # ~ this is Node loop
        # while True:

    def local_message_handler(self, msg_str):
        try:
            msg_int = struct.unpack("Q", msg_str)
            version, data = lprotocols.in_lvl1.unpack_msg(msg_int[0])
            handler = self._local_handlers[version]
            args = handler[1].unpack_msg(data)
            handler[0](*args)

        except Exception as exc:
            log.logger().error("failed to handle local message: " + traceback.format_exc())

    def stop(self):
        self._tcp_net.shutdown()
        log.logger().info("Node stopped.")