def _handle_msg(self, req): """! @brief Handle received u-RPC message. @param req Request message stream. @return Response message stream. """ # Message ID defaults to 0 (Unknown) msg_id = 0 try: # Response stream res = None # Parse magic string and version magic_ver_byte = read_data(req, URPC_TYPE_U8) if (magic_ver_byte >> 4) != URPC_MAGIC: raise URPCError(URPC_ERR_BROKEN_MSG) if (magic_ver_byte & 0xf) != URPC_VERSION: raise URPCError(URPC_ERR_NO_SUPPORT) # Parse message ID and type msg_id = read_data(req, URPC_TYPE_U16) msg_type = read_data(req, URPC_TYPE_U8) # Call message handler msg_handler = _urpc_msg_handlers[msg_type] if not msg_handler: raise URPCError(URPC_ERR_NO_SUPPORT) return msg_handler(self, req, msg_id) # URPC error occured except URPCError as e: res = self._build_header(URPC_MSG_ERROR, "recv") # Write request message ID and error code write_data(res, msg_id, URPC_TYPE_U16) write_data(res, e.reason, URPC_TYPE_U8) # Return stream return res
def _handle_func_resp(self, res, msg_id): """! @brief u-RPC function query response handler. @param res Response message stream. @param msg_id Response message ID. """ # Request message ID req_msg_id = read_data(res, URPC_TYPE_U16) # Function handle handle = read_data(res, URPC_TYPE_U16) # Invoke callback self._invoke_callback(req_msg_id, handle)
def _handle_error(self, res, msg_id): """! @brief u-RPC error result handler. @param res Response message stream. @param msg_id Response message ID. """ # Request message ID and error number req_msg_id = read_data(res, URPC_TYPE_U16) error_num = read_data(res, URPC_TYPE_U8) # Invoke callback with error object callback = self._oper_callbacks[req_msg_id] callback(URPCError(error_num), None) # Remove callback function del self._oper_callbacks[req_msg_id]
def _handle_call(self, req, msg_id): """! @brief u-RPC function call handler. @param req Request message stream. @param msg_id Request message ID. @return A u-RPC response message. """ # Function handle handle = read_data(req, URPC_TYPE_U16) # Arguments and signature sig_args = read_vary(req) args = self._unmarshall(req, sig_args) # Lookup for function in store func = seq_get(self._funcs_store, handle) if not func: raise URPCError(URPC_ERR_NONEXIST) # Call function sig_rets, result = func(sig_args, args) if len(result) != len(sig_rets): raise URPCError(URPC_ERR_SIG_INCORRECT) # Response message res = self._build_header(URPC_MSG_CALL_RESULT, "recv") write_data(res, msg_id, URPC_TYPE_U16) # Return values and signature write_vary(res, sig_rets) self._marshall(res, sig_rets, result) return res
def _handle_call_result(self, res, msg_id): """! @brief u-RPC error result handler. @param res Response message stream. @param msg_id Response message ID. """ # Request message ID req_msg_id = read_data(res, URPC_TYPE_U16) # Result and signature sig_rets = read_vary(res) result = self._unmarshall(res, sig_rets) # Invoke callback self._invoke_callback(req_msg_id, result)
def _unmarshall(self, stream, sig): """! @brief Unmarshall objects from data stream. @param stream Data stream. @param sig Signature of objects. @return Objects in an array. """ objects = [] # Unmarshall arguments for obj_type in sig: obj = None # Read argument if obj_type == URPC_TYPE_VARY: obj = read_vary(stream, "H") else: obj = read_data(stream, obj_type) objects.append(obj) return objects