def encode(payload): ''' Encoding RCMP Frame Args: payload: payload('str' or 'utf-8 bytes' format) Returns: RCMP Frame Raises: EXP.VRException: An error occurred when encoding. ''' if isinstance(payload, str): raw_bytes = bytes(payload, 'utf-8') elif isinstance(payload, bytes): raw_bytes = payload elif not payload: raw_bytes = bytes() else: raise EXP.RCException(errno=ERR.ERROR, errmsg='invalid payload type: {}'.format( type(payload))) payloadSize = len(raw_bytes) if payloadSize > CONST.RCMP_MAXPAYLOAD: raise EXP.RCException(ERR.ERROR_INVALID, 'payload too large') frame_head = FRAME_HEAD_FMT.pack(CONST.RCMP_STARTFLAG, CONST.RCMP_VERSION, payloadSize) return frame_head + raw_bytes
def parse(rawbuf): ''' parse signaling from raw data Args: rawbuf: buffer Returns: (sig, frame_length) Raises: EXP.RCException: An error occurred when parse raw data. EXP.RCException_More_Data: Need more data ''' # parse frame payload from raw data frame_payload, frame_length = RCMPFrame.parse(rawbuf) # parse frame payload try: if isinstance(frame_payload, bytes): # decode buffer as 'utf-8' frame_payload = frame_payload.decode('utf-8') sig = json.loads(frame_payload) cmd = sig['cmd'] if cmd not in CONST.SIG_CMD_LIST: raise EXP.RCException(ERR.ERROR_UNSUPPORT, 'unsupport cmd: {}'.format(cmd)) except Exception as e: raise EXP.RCException(ERR.ERROR_INVALID, 'parse frame paload fail: {}'.format(e)) return (sig, frame_length)
def parse(rawbuf): ''' Parse RCMP Frame Args: param rawbuf: raw buffer Returns: (raw_payload, frame_length) Raises: EXP.VRException: An error occurred when parse raw data. EXP.RCException_More_Data: Need more data ''' bufsize = len(rawbuf) if bufsize < CONST.RCMP_FRAMEHEADSIZE: # Need more data raise EXP.RCException_More_Data(ERR.ERROR, 'need more data') # check start flag if rawbuf[0] != CONST.RCMP_STARTFLAG: raise EXP.RCException(ERR.ERROR_INVALID, 'invalid Start Flag') # parse buffer [_, version, payloadSize ] = FRAME_HEAD_FMT.unpack(rawbuf[:CONST.RCMP_FRAMEHEADSIZE]) # check version if version != CONST.RCMP_VERSION: raise EXP.RCException(ERR.ERROR_UNSUPPORT, 'unsupport version: {}'.format(version)) # check payload size if payloadSize > CONST.RCMP_MAXPAYLOAD: raise EXP.RCException(ERR.ERROR_INVALID, 'payload too large') # check buffer size if CONST.RCMP_FRAMEHEADSIZE + payloadSize > bufsize: # need more data raise EXP.RCException_More_Data(ERR.ERROR, 'need more data') frame_length = CONST.RCMP_FRAMEHEADSIZE + payloadSize if payloadSize > 0: raw_payload = rawbuf[CONST.RCMP_FRAMEHEADSIZE:frame_length] else: raw_payload = None return (raw_payload, frame_length)
def req(req_cmd, seq, payload=None): if req_cmd not in CONST.SIG_REQ_CMD_LIST: raise EXP.RCException(ERR.ERROR_INVALID, 'invalid req cmd id: {}'.format(req_cmd)) return { 'cmd': req_cmd, 'seq': seq, 'payload': payload }
def resp(resp_cmd, seq, errno, errmsg, payload=None): if resp_cmd not in CONST.SIG_RESP_CMD_LIST: raise EXP.RCException(ERR.ERROR_INVALID, 'invalid resp cmd id: {}'.format(resp_cmd)) return { 'cmd': resp_cmd, 'seq': seq, 'errno': errno, 'errmsg': errmsg, 'payload': payload }