1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2016 Intel Corporation. All rights reserved. 3 * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 */ 5 6 /** 7 * \file 8 * JSON-RPC 2.0 server implementation 9 */ 10 11 #ifndef SPDK_JSONRPC_H_ 12 #define SPDK_JSONRPC_H_ 13 14 #include "spdk/stdinc.h" 15 16 #include "spdk/json.h" 17 #include "spdk/log.h" 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 /* Defined error codes in JSON-RPC specification 2.0 */ 24 #define SPDK_JSONRPC_ERROR_PARSE_ERROR -32700 25 #define SPDK_JSONRPC_ERROR_INVALID_REQUEST -32600 26 #define SPDK_JSONRPC_ERROR_METHOD_NOT_FOUND -32601 27 #define SPDK_JSONRPC_ERROR_INVALID_PARAMS -32602 28 #define SPDK_JSONRPC_ERROR_INTERNAL_ERROR -32603 29 30 /* Custom error codes in SPDK 31 32 * Error codes from and including -32768 to -32000 are reserved for 33 * predefined errors, hence custom error codes must be outside of the range. 34 */ 35 #define SPDK_JSONRPC_ERROR_INVALID_STATE -1 36 37 struct spdk_jsonrpc_server; 38 struct spdk_jsonrpc_request; 39 40 struct spdk_jsonrpc_client; 41 struct spdk_jsonrpc_client_request; 42 43 struct spdk_jsonrpc_client_response { 44 struct spdk_json_val *version; 45 struct spdk_json_val *id; 46 struct spdk_json_val *result; 47 struct spdk_json_val *error; 48 }; 49 50 /** 51 * User callback to handle a single JSON-RPC request. 52 * 53 * The user should respond by calling one of spdk_jsonrpc_begin_result() or 54 * spdk_jsonrpc_send_error_response(). 55 * 56 * \param request JSON-RPC request to handle. 57 * \param method Function to handle the request. 58 * \param params Parameters passed to the function 'method'. 59 */ 60 typedef void (*spdk_jsonrpc_handle_request_fn)( 61 struct spdk_jsonrpc_request *request, 62 const struct spdk_json_val *method, 63 const struct spdk_json_val *params); 64 65 struct spdk_jsonrpc_server_conn; 66 67 typedef void (*spdk_jsonrpc_conn_closed_fn)(struct spdk_jsonrpc_server_conn *conn, void *arg); 68 69 /** 70 * Function for specific RPC method response parsing handlers. 71 * 72 * \param parser_ctx context where analysis are put. 73 * \param result json values responded to this method. 74 * 75 * \return 0 on success. 76 * SPDK_JSON_PARSE_INVALID on failure. 77 */ 78 typedef int (*spdk_jsonrpc_client_response_parser)( 79 void *parser_ctx, 80 const struct spdk_json_val *result); 81 82 /** 83 * Create a JSON-RPC server listening on the required address. 84 * 85 * \param domain Socket family. 86 * \param protocol Protocol. 87 * \param listen_addr Listening address. 88 * \param addrlen Length of address. 89 * \param handle_request User callback to handle a JSON-RPC request. 90 * 91 * \return a pointer to the JSON-RPC server. 92 */ 93 struct spdk_jsonrpc_server *spdk_jsonrpc_server_listen(int domain, int protocol, 94 struct sockaddr *listen_addr, socklen_t addrlen, spdk_jsonrpc_handle_request_fn handle_request); 95 96 /** 97 * Poll the requests to the JSON-RPC server. 98 * 99 * This function does accept, receive, handle the requests and reply to them. 100 * 101 * \param server JSON-RPC server. 102 * 103 * \return 0 on success. 104 */ 105 int spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server); 106 107 /** 108 * Shutdown the JSON-RPC server. 109 * 110 * \param server JSON-RPC server. 111 */ 112 void spdk_jsonrpc_server_shutdown(struct spdk_jsonrpc_server *server); 113 114 /** 115 * Return connection associated to \c request 116 * 117 * \param request JSON-RPC request 118 * \return JSON RPC server connection 119 */ 120 struct spdk_jsonrpc_server_conn *spdk_jsonrpc_get_conn(struct spdk_jsonrpc_request *request); 121 122 /** 123 * Add callback called when connection is closed. Pair of \c cb and \c ctx must be unique or error is returned. 124 * Registered callback is called only once and there is no need to call \c spdk_jsonrpc_conn_del_close_cb 125 * inside from \c cb. 126 * 127 * \note Current implementation allow only one close callback per connection. 128 * 129 * \param conn JSON RPC server connection 130 * \param cb callback function 131 * \param ctx argument for \c cb 132 * 133 * \return 0 on success, or negated errno code: 134 * -EEXIST \c cb and \c ctx is already registered 135 * -ENOTCONN Callback can't be added because connection is closed. 136 * -ENOSPC no more space to register callback. 137 */ 138 int spdk_jsonrpc_conn_add_close_cb(struct spdk_jsonrpc_server_conn *conn, 139 spdk_jsonrpc_conn_closed_fn cb, void *ctx); 140 141 /** 142 * Remove registered close callback. 143 * 144 * \param conn JSON RPC server connection 145 * \param cb callback function 146 * \param ctx argument for \c cb 147 * 148 * \return 0 on success, or negated errno code: 149 * -ENOENT \c cb and \c ctx pair is not registered 150 */ 151 int spdk_jsonrpc_conn_del_close_cb(struct spdk_jsonrpc_server_conn *conn, 152 spdk_jsonrpc_conn_closed_fn cb, void *ctx); 153 154 /** 155 * Begin building a response to a JSON-RPC request. 156 * 157 * If this function returns non-NULL, the user must call spdk_jsonrpc_end_result() 158 * on the request after writing the desired response object to the spdk_json_write_ctx. 159 * 160 * \param request JSON-RPC request to respond to. 161 162 * \return Non-NULL pointer to JSON write context to write the response object to. 163 */ 164 struct spdk_json_write_ctx *spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request); 165 166 /** 167 * Complete and send a JSON-RPC response. 168 * 169 * \param request Request to complete the response for. 170 * \param w JSON write context returned from spdk_jsonrpc_begin_result(). 171 */ 172 void spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w); 173 174 /** 175 * Complete a JSON-RPC response and write bool result. 176 * 177 * \param request Request to complete the response for. 178 * \param value Write bool result value. 179 */ 180 void spdk_jsonrpc_send_bool_response(struct spdk_jsonrpc_request *request, bool value); 181 182 /** 183 * Send an error response to a JSON-RPC request. 184 * 185 * This is shorthand for spdk_jsonrpc_begin_result() + spdk_jsonrpc_end_result() 186 * with an error object. 187 * 188 * \param request JSON-RPC request to respond to. 189 * \param error_code Integer error code to return (may be one of the 190 * SPDK_JSONRPC_ERROR_ errors, or a custom error code). 191 * \param msg String error message to return. 192 */ 193 void spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request, 194 int error_code, const char *msg); 195 196 /** 197 * Send an error response to a JSON-RPC request. 198 * 199 * This is shorthand for printf() + spdk_jsonrpc_send_error_response(). 200 * 201 * \param request JSON-RPC request to respond to. 202 * \param error_code Integer error code to return (may be one of the 203 * SPDK_JSONRPC_ERROR_ errors, or a custom error code). 204 * \param fmt Printf-like format string. 205 */ 206 void spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request, 207 int error_code, const char *fmt, ...) __attribute__((format(printf, 3, 4))); 208 209 /** 210 * Begin building a JSON-RPC request. 211 * 212 * If this function returns non-NULL, the user must call spdk_jsonrpc_end_request() 213 * on the request after writing the desired request object to the spdk_json_write_ctx. 214 * 215 * \param request JSON-RPC request. 216 * \param id ID index for the request. If < 0 skip ID. 217 * \param method Name of the RPC method. If NULL caller will have to create "method" key. 218 * 219 * \return JSON write context or NULL in case of error. 220 */ 221 struct spdk_json_write_ctx * 222 spdk_jsonrpc_begin_request(struct spdk_jsonrpc_client_request *request, int32_t id, 223 const char *method); 224 225 /** 226 * Complete a JSON-RPC request. 227 * 228 * \param request JSON-RPC request. 229 * \param w JSON write context returned from spdk_jsonrpc_begin_request(). 230 */ 231 void spdk_jsonrpc_end_request(struct spdk_jsonrpc_client_request *request, 232 struct spdk_json_write_ctx *w); 233 234 /** 235 * Connect to the specified RPC server. 236 * 237 * \param addr RPC socket address. 238 * \param addr_family Protocol families of address. 239 * 240 * \return JSON-RPC client on success, NULL on failure and errno set to indicate 241 * the cause of the error. 242 */ 243 struct spdk_jsonrpc_client *spdk_jsonrpc_client_connect(const char *addr, int addr_family); 244 245 /** 246 * Close JSON-RPC connection and free \c client object. 247 * 248 * This function is not thread safe and should only be called from one thread at 249 * a time while no other threads are actively \c client object. 250 * 251 * \param client JSON-RPC client. 252 */ 253 void spdk_jsonrpc_client_close(struct spdk_jsonrpc_client *client); 254 255 /** 256 * Create one JSON-RPC request. Returned request must be passed to 257 * \c spdk_jsonrpc_client_send_request when done or to \c spdk_jsonrpc_client_free_request 258 * if discaded. 259 * 260 * \return pointer to JSON-RPC request object. 261 */ 262 struct spdk_jsonrpc_client_request *spdk_jsonrpc_client_create_request(void); 263 264 /** 265 * Free one JSON-RPC request. 266 * 267 * \param req pointer to JSON-RPC request object. 268 */ 269 void spdk_jsonrpc_client_free_request(struct spdk_jsonrpc_client_request *req); 270 271 /** 272 * Send the JSON-RPC request in JSON-RPC client. Library takes ownership of the 273 * request object and will free it when done. 274 * 275 * This function is not thread safe and should only be called from one thread at 276 * a time while no other threads are actively \c client object. 277 * 278 * \param client JSON-RPC client. 279 * \param req JSON-RPC request. 280 * 281 * \return 0 on success or negative error code. 282 * -ENOSPC - no space left to queue another request. Try again later. 283 */ 284 int spdk_jsonrpc_client_send_request(struct spdk_jsonrpc_client *client, 285 struct spdk_jsonrpc_client_request *req); 286 287 /** 288 * Poll the JSON-RPC client. When any response is available use 289 * \c spdk_jsonrpc_client_get_response to retrieve it. 290 * 291 * This function is not thread safe and should only be called from one thread at 292 * a time while no other threads are actively \c client object. 293 * 294 * \param client JSON-RPC client. 295 * \param timeout Time in milliseconds this function will block. -1 block forever, 0 don't block. 296 * 297 * \return If no error occurred, this function returns a non-negative number indicating how 298 * many ready responses can be retrieved. If an error occurred, this function returns one of 299 * the following negated errno values: 300 * -ENOTCONN - not connected yet. Try again later. 301 * -EINVAL - response is detected to be invalid. Client connection should be terminated. 302 * -ENOSPC - no space to receive another response. User need to retrieve waiting responses. 303 * -EIO - connection terminated (or other critical error). Client connection should be terminated. 304 * -ENOMEM - out of memory 305 */ 306 int spdk_jsonrpc_client_poll(struct spdk_jsonrpc_client *client, int timeout); 307 308 /** 309 * Return JSON RPC response object representing next available response from client connection. 310 * Returned pointer must be freed using \c spdk_jsonrpc_client_free_response 311 * 312 * This function is not thread safe and should only be called from one thread at 313 * a time while no other threads are actively \c client object. 314 * 315 * \param client 316 * \return pointer to JSON RPC response object or NULL if no response available. 317 */ 318 struct spdk_jsonrpc_client_response *spdk_jsonrpc_client_get_response(struct spdk_jsonrpc_client 319 *client); 320 321 /** 322 * Free response object obtained from \c spdk_jsonrpc_client_get_response 323 * 324 * \param resp pointer to JSON RPC response object. If NULL no operation is performed. 325 */ 326 void spdk_jsonrpc_client_free_response(struct spdk_jsonrpc_client_response *resp); 327 328 /** 329 * Set the log level used by the JSON-RPC server to log RPC request and response objects. 330 * 331 * NOTE: This function should be called only before starting the JSON-RPC server. 332 * Users should set the level set by this function higher than the level set by 333 * spdk_log_set_print_level() or spdk_log_set_level(). 334 * 335 * \param level Log level used to log RPC objects. 336 */ 337 void spdk_jsonrpc_set_log_level(enum spdk_log_level level); 338 339 /** 340 * Set the log file used by the JSON-RPC server to log RPC request and response objects. 341 * 342 * NOTE: This function should be called only before starting the JSON-RPC server. 343 * 344 * \param file Log file pointer used to log RPC objects. 345 */ 346 void spdk_jsonrpc_set_log_file(FILE *file); 347 348 #ifdef __cplusplus 349 } 350 #endif 351 352 #endif 353