#include #include "rpc_base.h" rpc_result_t rpc_sendpacket(rpc_ostream_t *stream, RPCCommand msgtype, const pb_field_t *fields, void *msg) { pb_ostream_t sizestream = {0}; if (!pb_encode(&sizestream, fields, msg)) return RPC_ENCODE_FAILED; int length = sizestream.bytes_written + 2; if (length > 65535) return RPC_PACKET_TOO_LARGE; if (!rpc_ostream_start(stream, msgtype, length)) return RPC_MIDWAY_ERROR; if (!pb_encode(&stream->stream, fields, msg)) return RPC_MIDWAY_ERROR; if (!rpc_ostream_end(stream)) return RPC_MIDWAY_ERROR; return RPC_OK; } bool rpc_response(rpc_ostream_t *stream, RPCCommand msgtype, const pb_field_t *fields, void *msg) { rpc_result_t status = rpc_sendpacket(stream, msgtype, fields, msg); if (status == RPC_ENCODE_FAILED) { return rpc_error_protocol(stream, "Encode failed"); } if (status == RPC_PACKET_TOO_LARGE) { return rpc_error_protocol(stream, "Packet too large"); } return status == RPC_OK; } bool rpc_response_empty(rpc_ostream_t *stream, RPCCommand msgtype) { char response[] = {0x00, 0x02, msgtype, 0xFF ^ msgtype}; return fwrite(response, 1, sizeof(response), stream->file) == sizeof(response); } bool rpc_error(rpc_ostream_t *stream, ErrorResponse *error) { return rpc_sendpacket(stream, RPCCommand_Error, ErrorResponse_fields, error) == RPC_OK; } bool rpc_error_protocol(rpc_ostream_t *stream, const char *message) { ErrorResponse error = {0}; error.scope = ErrorResponse_ErrorScope_PROTOCOL; error.message.funcs.encode = &pb_enc_string; error.message.arg = (void*)message; return rpc_error(stream, &error); } bool rpc_error_resources(rpc_ostream_t *stream, const char *message) { ErrorResponse error = {0}; error.scope = ErrorResponse_ErrorScope_RESOURCES; error.message.funcs.encode = &pb_enc_string; error.message.arg = (void*)message; return rpc_error(stream, &error); }