'Called by portal sessions for relaying data coming
in from the protocol to the server.
Args:
session (PortalSession): Session receiving data.
Kwargs:
kwargs (any): Other data from protocol.
Notes:
Data is serialized before passed on.'

def data_in(self, session, **kwargs):

    try:
        text = kwargs['text']
        if ((_MAX_CHAR_LIMIT > 0) and (len(text) > _MAX_CHAR_LIMIT)):
            if session:
                self.data_out(session, text=[[_ERROR_MAX_CHAR], {}])
            return
    except Exception:
        pass
    if session:
        now = time.time()
        if (self.command_counter > _MAX_COMMAND_RATE > 0):
            delta_time = (now - self.command_counter_reset)
            self.command_counter = 0
            self.command_counter_reset = now
            self.command_overflow = (delta_time < 1.0)
            if self.command_overflow:
                reactor.callLater(1.0, self.data_in, None)
        if self.command_overflow:
            self.data_out(session, text=[[_ERROR_COMMAND_OVERFLOW], {}])
            return
        kwargs = self.clean_senddata(session, kwargs)
        self.command_counter += 1
        session.cmd_last = now
        self.portal.amp_protocol.send_MsgPortal2Server(session, **kwargs)
    elif self.command_overflow:
        self.command_overflow = False
        reactor.callLater(1.0, self.data_in, None)
