#pragma once #include #include #include #include #include // Start handling RPC calls on the IO channel. // Exits when a RPC function calls rpc_abort(). void rpc_server(BaseChannel *io); /****************************************************************** * The functions below should be called only during the execution * * of a function called from rpc_server. * ******************************************************************/ // The rpc_t type contains a state machine. The functions should be used // in order, though not all calls are necessary. // // START -+-> rpc_receive() ---------FALSE------------------> END // | `-----TRUE---, ^ // | v | // `---> Do whatever the RPC call should do | // | | | // SUCCESS FAILURE | // v v | // rpc_prepare() -FALSE-> rpc_error() --------------+ // | | // TRUE | // v | // rpc_respond() -----------------------------------ยด typedef struct _rpc_t rpc_t; // Decode request packet payload using nanopb. // False means that pb_decode failed or the checksum of the packet was wrong. // If that happens, just return. rpc_protocol_error or rpc_abort has already // been called. bool rpc_receive(rpc_t *rpc, void *dest); // Compute response packet size. rpc_respond will call this automatically // if you don't do it manually. However, by doing it manually, you can still // recover if the pb_encode fails, as nothing has been transmitted. // Note: only for success responses. bool rpc_prepare(rpc_t *rpc, const void *src); // Send response packet. Payload is encoded using nanopb. // Pass NULL for the argument to send an empty response. // Note: only for success responses. // Returns false if pb_encode or write fails midway of the response. // Cleanup and return, rpc_abort has already been called. bool rpc_respond(rpc_t *rpc, const void *src); // Send error response. void rpc_error(rpc_t *rpc, const ErrorResponse *error); // Shortcuts for sending error messages of a specific type. void rpc_protocol_error(rpc_t *rpc, const char *message); void rpc_resources_error(rpc_t *rpc, const char *message); // Abort the RPC server. // The RPC server will exit after the current request is processed. void rpc_abort(rpc_t *rpc);