/* Sends 'request' to 'rpc' then waits for a reply. The return value is 0 if * successful, in which case '*replyp' is set to the reply, which the caller * must eventually free with jsonrpc_msg_destroy(). Otherwise returns a status * value (see jsonrpc_get_status()). * * Discards any message received on 'rpc' that is not a reply to 'request' * (based on message id). * * Always takes ownership of 'request', regardless of success. */ int jsonrpc_transact_block(struct jsonrpc *rpc, struct jsonrpc_msg *request, struct jsonrpc_msg **replyp) { struct jsonrpc_msg *reply = NULL; struct json *id; int error; id = json_clone(request->id); error = jsonrpc_send_block(rpc, request); if (!error) { for (;;) { error = jsonrpc_recv_block(rpc, &reply); if (error) { break; } if ((reply->type == JSONRPC_REPLY || reply->type == JSONRPC_ERROR) && json_equal(id, reply->id)) { break; } jsonrpc_msg_destroy(reply); } } *replyp = error ? NULL : reply; json_destroy(id); return error; }
static int handle_rpc(struct jsonrpc *rpc, struct jsonrpc_msg *msg, bool *done) { if (msg->type == JSONRPC_REQUEST) { struct jsonrpc_msg *reply = NULL; if (!strcmp(msg->method, "echo")) { reply = jsonrpc_create_reply(json_clone(msg->params), msg->id); } else { struct json *error = json_object_create(); json_object_put_string(error, "error", "unknown method"); reply = jsonrpc_create_error(error, msg->id); ovs_error(0, "unknown request %s", msg->method); } jsonrpc_send(rpc, reply); return 0; } else if (msg->type == JSONRPC_NOTIFY) { if (!strcmp(msg->method, "shutdown")) { *done = true; return 0; } else { ovs_error(0, "unknown notification %s", msg->method); return ENOTTY; } } else { ovs_error(0, "unsolicited JSON-RPC reply or error"); return EPROTO; } }
struct jsonrpc_msg * jsonrpc_session_recv(struct jsonrpc_session *s) { if (s->rpc) { struct jsonrpc_msg *msg; jsonrpc_recv(s->rpc, &msg); if (msg) { reconnect_received(s->reconnect, time_msec()); if (msg->type == JSONRPC_REQUEST && !strcmp(msg->method, "echo")) { /* Echo request. Send reply. */ struct jsonrpc_msg *reply; reply = jsonrpc_create_reply(json_clone(msg->params), msg->id); jsonrpc_session_send(s, reply); } else if (msg->type == JSONRPC_REPLY && msg->id && msg->id->type == JSON_STRING && !strcmp(msg->id->u.string, "echo")) { /* It's a reply to our echo request. Suppress it. */ } else { return msg; } jsonrpc_msg_destroy(msg); } } return NULL; }
struct jsonrpc_msg * jsonrpc_create_request(const char *method, struct json *params, struct json **idp) { struct json *id = jsonrpc_create_id(); if (idp) { *idp = json_clone(id); } return jsonrpc_create(JSONRPC_REQUEST, method, params, NULL, NULL, id); }
static void table_print_json__(const struct table *table, const struct table_style *style) { struct json *json, *headings, *data; size_t x, y; char *s; json = json_object_create(); if (table->caption) { json_object_put_string(json, "caption", table->caption); } if (table->timestamp) { char *s = table_format_timestamp__(); json_object_put_string(json, "time", s); free(s); } headings = json_array_create_empty(); for (x = 0; x < table->n_columns; x++) { const struct column *column = &table->columns[x]; json_array_add(headings, json_string_create(column->heading)); } json_object_put(json, "headings", headings); data = json_array_create_empty(); for (y = 0; y < table->n_rows; y++) { struct json *row = json_array_create_empty(); for (x = 0; x < table->n_columns; x++) { const struct cell *cell = table_cell__(table, y, x); if (cell->text) { json_array_add(row, json_string_create(cell->text)); } else if (cell->json) { json_array_add(row, json_clone(cell->json)); } else { json_array_add(row, json_null_create()); } } json_array_add(data, row); } json_object_put(json, "data", data); s = json_to_string(json, style->json_flags); json_destroy(json); puts(s); free(s); }
struct jsonrpc_msg * jsonrpc_session_recv(struct jsonrpc_session *s) { if (s->rpc) { unsigned int received_bytes; struct jsonrpc_msg *msg; received_bytes = jsonrpc_get_received_bytes(s->rpc); jsonrpc_recv(s->rpc, &msg); if (received_bytes != jsonrpc_get_received_bytes(s->rpc)) { /* Data was successfully received. * * Previously we only counted receiving a full message as activity, * but with large messages or a slow connection that policy could * time out the session mid-message. */ reconnect_activity(s->reconnect, time_msec()); } if (msg) { if (msg->type == JSONRPC_REQUEST && !strcmp(msg->method, "echo")) { /* Echo request. Send reply. */ struct jsonrpc_msg *reply; reply = jsonrpc_create_reply(json_clone(msg->params), msg->id); jsonrpc_session_send(s, reply); } else if (msg->type == JSONRPC_REPLY && msg->id && msg->id->type == JSON_STRING && !strcmp(msg->id->u.string, "echo")) { /* It's a reply to our echo request. Suppress it. */ } else { return msg; } jsonrpc_msg_destroy(msg); } } return NULL; }
struct jsonrpc_msg * jsonrpc_create_error(struct json *error, const struct json *id) { return jsonrpc_create(JSONRPC_REPLY, NULL, NULL, NULL, error, json_clone(id)); }
struct jsonrpc_msg * jsonrpc_create_reply(struct json *result, const struct json *id) { return jsonrpc_create(JSONRPC_REPLY, NULL, NULL, result, NULL, json_clone(id)); }