1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/util.h" 7 #include "jsonrpc_internal.h" 8 9 static int 10 capture_version(const struct spdk_json_val *val, void *out) 11 { 12 const struct spdk_json_val **vptr = out; 13 14 if (spdk_json_strequal(val, "2.0") != true) { 15 return SPDK_JSON_PARSE_INVALID; 16 } 17 18 *vptr = val; 19 return 0; 20 } 21 22 static int 23 capture_id(const struct spdk_json_val *val, void *out) 24 { 25 const struct spdk_json_val **vptr = out; 26 27 if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NUMBER) { 28 return -EINVAL; 29 } 30 31 *vptr = val; 32 return 0; 33 } 34 35 static int 36 capture_any(const struct spdk_json_val *val, void *out) 37 { 38 const struct spdk_json_val **vptr = out; 39 40 *vptr = val; 41 return 0; 42 } 43 44 static const struct spdk_json_object_decoder jsonrpc_response_decoders[] = { 45 {"jsonrpc", offsetof(struct spdk_jsonrpc_client_response, version), capture_version}, 46 {"id", offsetof(struct spdk_jsonrpc_client_response, id), capture_id, true}, 47 {"result", offsetof(struct spdk_jsonrpc_client_response, result), capture_any, true}, 48 {"error", offsetof(struct spdk_jsonrpc_client_response, error), capture_any, true}, 49 }; 50 51 int 52 jsonrpc_parse_response(struct spdk_jsonrpc_client *client) 53 { 54 struct spdk_jsonrpc_client_response_internal *r; 55 ssize_t rc; 56 size_t buf_len; 57 size_t values_cnt; 58 void *end = NULL; 59 60 61 /* Check to see if we have received a full JSON value. */ 62 rc = spdk_json_parse(client->recv_buf, client->recv_offset, NULL, 0, &end, 0); 63 if (rc == SPDK_JSON_PARSE_INCOMPLETE) { 64 return 0; 65 } 66 67 SPDK_DEBUGLOG(rpc_client, "JSON string is :\n%s\n", client->recv_buf); 68 if (rc < 0 || rc > SPDK_JSONRPC_CLIENT_MAX_VALUES) { 69 SPDK_ERRLOG("JSON parse error (rc: %zd)\n", rc); 70 /* 71 * Can't recover from parse error (no guaranteed resync point in streaming JSON). 72 * Return an error to indicate that the connection should be closed. 73 */ 74 return -EINVAL; 75 } 76 77 values_cnt = rc; 78 79 r = calloc(1, sizeof(*r) + sizeof(struct spdk_json_val) * (values_cnt + 1)); 80 if (!r) { 81 return -errno; 82 } 83 84 if (client->resp) { 85 free(r); 86 return -ENOSPC; 87 } 88 89 client->resp = r; 90 91 r->buf = client->recv_buf; 92 buf_len = client->recv_offset; 93 r->values_cnt = values_cnt; 94 95 client->recv_buf_size = 0; 96 client->recv_offset = 0; 97 client->recv_buf = NULL; 98 99 /* Decode a second time now that there is a full JSON value available. */ 100 rc = spdk_json_parse(r->buf, buf_len, r->values, values_cnt, &end, 101 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE); 102 if (rc != (ssize_t)values_cnt) { 103 SPDK_ERRLOG("JSON parse error on second pass (rc: %zd, expected: %zu)\n", rc, values_cnt); 104 goto err; 105 } 106 107 assert(end != NULL); 108 109 if (r->values[0].type != SPDK_JSON_VAL_OBJECT_BEGIN) { 110 SPDK_ERRLOG("top-level JSON value was not object\n"); 111 goto err; 112 } 113 114 if (spdk_json_decode_object(r->values, jsonrpc_response_decoders, 115 SPDK_COUNTOF(jsonrpc_response_decoders), &r->jsonrpc)) { 116 goto err; 117 } 118 119 r->ready = 1; 120 return 1; 121 122 err: 123 client->resp = NULL; 124 spdk_jsonrpc_client_free_response(&r->jsonrpc); 125 return -EINVAL; 126 } 127 128 static int 129 jsonrpc_client_write_cb(void *cb_ctx, const void *data, size_t size) 130 { 131 struct spdk_jsonrpc_client_request *request = cb_ctx; 132 size_t new_size = request->send_buf_size; 133 134 while (new_size - request->send_len < size) { 135 if (new_size >= SPDK_JSONRPC_SEND_BUF_SIZE_MAX) { 136 SPDK_ERRLOG("Send buf exceeded maximum size (%zu)\n", 137 (size_t)SPDK_JSONRPC_SEND_BUF_SIZE_MAX); 138 return -ENOSPC; 139 } 140 141 new_size *= 2; 142 } 143 144 if (new_size != request->send_buf_size) { 145 uint8_t *new_buf; 146 147 new_buf = realloc(request->send_buf, new_size); 148 if (new_buf == NULL) { 149 SPDK_ERRLOG("Resizing send_buf failed (current size %zu, new size %zu)\n", 150 request->send_buf_size, new_size); 151 return -ENOMEM; 152 } 153 154 request->send_buf = new_buf; 155 request->send_buf_size = new_size; 156 } 157 158 memcpy(request->send_buf + request->send_len, data, size); 159 request->send_len += size; 160 161 return 0; 162 } 163 164 struct spdk_json_write_ctx * 165 spdk_jsonrpc_begin_request(struct spdk_jsonrpc_client_request *request, int32_t id, 166 const char *method) 167 { 168 struct spdk_json_write_ctx *w; 169 170 w = spdk_json_write_begin(jsonrpc_client_write_cb, request, 0); 171 if (w == NULL) { 172 return NULL; 173 } 174 175 spdk_json_write_object_begin(w); 176 spdk_json_write_named_string(w, "jsonrpc", "2.0"); 177 178 if (id >= 0) { 179 spdk_json_write_named_int32(w, "id", id); 180 } 181 182 if (method) { 183 spdk_json_write_named_string(w, "method", method); 184 } 185 186 return w; 187 } 188 189 void 190 spdk_jsonrpc_end_request(struct spdk_jsonrpc_client_request *request, struct spdk_json_write_ctx *w) 191 { 192 assert(w != NULL); 193 194 spdk_json_write_object_end(w); 195 spdk_json_write_end(w); 196 jsonrpc_client_write_cb(request, "\n", 1); 197 } 198 199 SPDK_LOG_REGISTER_COMPONENT(rpc_client) 200