dbus ws: add reply error and send signal [1/1]
PD#SWPL-187465
Problem:
add reply error and send signal
Solution:
add reply error and send signal
Verify:
local
Change-Id: Ibc481165c911ab7fcdf061a4bc7068491bfee01a
Signed-off-by: Daogao Xu <daogao.xu@amlogic.com>
diff --git a/aml_dbus_ws_br/jsonrpc-dbus.c b/aml_dbus_ws_br/jsonrpc-dbus.c
index f9cc25e..fd4dfc2 100644
--- a/aml_dbus_ws_br/jsonrpc-dbus.c
+++ b/aml_dbus_ws_br/jsonrpc-dbus.c
@@ -73,7 +73,7 @@
struct dbus_object_method {
struct dbus_object_method *next;
- sd_bus_message *reply;
+ sd_bus_message *msg_call;
struct dbus_maches *match;
uint64_t cookie;
};
@@ -642,9 +642,8 @@
struct dbus_maches *c = (struct dbus_maches *)userdata;
struct json_rpc_handle *jrpc = c->jrpc;
uint64_t cookie = 0LL;
- sd_bus_message *reply = NULL;
- if (sd_bus_message_get_cookie(m, &cookie) < 0 || sd_bus_message_new_method_return(m, &reply) < 0) {
- lwsl_info("object msg fail to get cookie or reply\n");
+ if (sd_bus_message_get_cookie(m, &cookie) < 0) {
+ lwsl_info("object msg fail to get cookie\n");
return 0;
}
int len = jrpc_append_reply(jrpc,
@@ -661,7 +660,7 @@
struct dbus_object_method *om = malloc(sizeof(*om));
om->next = jrpc->pending_object_call;
om->cookie = cookie;
- om->reply = reply;
+ om->msg_call = sd_bus_message_ref(m);
om->match = c;
jrpc->pending_object_call = om;
return 1;
@@ -689,39 +688,52 @@
static int json_rpc_call_send_reply(struct json_rpc_handle *jrpc, uint64_t id, struct json_value_base *params) {
struct json_value_base *jv_cookie = lws_json_object_get(params, "cookie");
- struct json_value_base *jv_sig = lws_json_object_get(params, "signature");
- struct json_value_base *jv_data = lws_json_object_get(params, "data");
- if (jv_cookie == NULL || jv_cookie->type != json_vt_string) {
+ if (jv_cookie == NULL || jv_cookie->type != json_vt_string)
goto not_found;
+ uint64_t cookie = strtoull(JV_CAST(string, jv_cookie)->val, NULL, 0);
+ struct dbus_object_method *om = jrpc->pending_object_call, *prev = NULL;
+ for (; om && om->cookie != cookie; prev = om, om = om->next)
+ ;
+ if (om == NULL)
+ goto not_found;
+ if (prev)
+ prev->next = om->next;
+ else
+ jrpc->pending_object_call = om->next;
+ int r;
+ sd_bus_message *reply = NULL;
+ struct json_value_base *jv_error = lws_json_object_get(params, "error");
+ sd_bus_error err;
+ if (jv_error && jv_error->type == json_vt_string) {
+ struct json_value_base *jv_msg = lws_json_object_get(params, "message");
+ const char *err_name = JV_CAST(string, jv_error)->val;
+ const char *err_msg = (jv_msg && jv_msg->type == json_vt_string) ? JV_CAST(string, jv_msg)->val : NULL;
+ err = SD_BUS_ERROR_MAKE_CONST(err_name, err_msg);
+ r = sd_bus_message_new_method_error(om->msg_call, &reply, &err);
} else {
- uint64_t cookie = strtoull(JV_CAST(string, jv_cookie)->val, NULL, 0);
- struct dbus_object_method *om = jrpc->pending_object_call, *prev = NULL;
- for (; om && om->cookie != cookie; prev = om, om = om->next)
- ;
- if (om == NULL)
- goto not_found;
- if (prev)
- prev->next = om->next;
- else
- jrpc->pending_object_call = om->next;
- int r;
- if (jv_sig && jv_sig->type == json_vt_string && jv_data) {
+ r = sd_bus_message_new_method_return(om->msg_call, &reply);
+ struct json_value_base *jv_sig = lws_json_object_get(params, "signature");
+ struct json_value_base *jv_data = lws_json_object_get(params, "data");
+ if (r >= 0 && jv_sig && jv_sig->type == json_vt_string && jv_data) {
const char *sig = JV_CAST(string, jv_sig)->val;
- r = msg_from_json(om->reply, sig, jv_data);
+ r = msg_from_json(reply, sig, jv_data);
if (r < 0) {
lwsl_warn("fail to create dbus message with sig %s from json (%d %s):\n", sig, r, strerror(-r));
lws_json_val_dump(stderr, jv_data, 0);
- goto param_error;
}
}
- r = sd_bus_send(jrpc->bus, om->reply, NULL);
- if (r < 0)
- json_rpc_reply_error(jrpc, id, -32603, strerror(-r));
- else
- json_rpc_reply_simple(jrpc, id, "%d", 0);
- sd_bus_message_unref(om->reply);
- free(om);
}
+ sd_bus_message_unref(om->msg_call);
+ if (r >= 0 && reply) {
+ r = sd_bus_send(jrpc->bus, reply, NULL);
+ }
+ if (reply)
+ sd_bus_message_unref(reply);
+ if (r < 0)
+ json_rpc_reply_error(jrpc, id, -32603, strerror(-r));
+ else
+ json_rpc_reply_simple(jrpc, id, "%d", 0);
+ free(om);
return 0;
not_found:
json_rpc_reply_error(jrpc, id, -32603, "sendReply cookie not found");
@@ -731,6 +743,46 @@
return 0;
}
+static int json_rpc_call_send_signal(struct json_rpc_handle *jrpc, uint64_t id, struct json_value_base *params) {
+ char errmsg[256];
+ struct json_value_base *jv_path = lws_json_object_get(params, "path");
+ struct json_value_base *jv_intf = lws_json_object_get(params, "interface");
+ struct json_value_base *jv_mem = lws_json_object_get(params, "member");
+ if (jv_path == NULL || jv_path->type != json_vt_string || jv_intf == NULL || jv_intf->type != json_vt_string ||
+ jv_mem == NULL || jv_mem->type != json_vt_string) {
+ goto param_error;
+ }
+ sd_bus_message *m = NULL;
+ int r = sd_bus_message_new_signal(jrpc->bus, &m, JV_CAST(string, jv_path)->val, JV_CAST(string, jv_intf)->val,
+ JV_CAST(string, jv_mem)->val);
+ if (r < 0) {
+ goto param_error;
+ }
+ struct json_value_base *jv_sig = lws_json_object_get(params, "signature");
+ struct json_value_base *jv_data = lws_json_object_get(params, "data");
+ if (jv_sig && jv_sig->type == json_vt_string && jv_data) {
+ const char *sig = JV_CAST(string, jv_sig)->val;
+ r = msg_from_json(m, sig, jv_data);
+ if (r < 0) {
+ lwsl_warn("fail to create dbus message with sig %s from json (%d %s):\n", sig, r, strerror(-r));
+ lws_json_val_dump(stderr, jv_data, 0);
+ }
+ }
+ if (r >= 0 && m) {
+ r = sd_bus_send(jrpc->bus, m, NULL);
+ }
+ if (m)
+ sd_bus_message_unref(m);
+ if (r < 0)
+ json_rpc_reply_error(jrpc, id, -32603, strerror(-r));
+ else
+ json_rpc_reply_simple(jrpc, id, "%d", 0);
+ return 0;
+param_error:
+ json_rpc_reply_error(jrpc, id, -32603, "sendSignal must provide valid path interface member");
+ return 0;
+}
+
static int json_rpc_call_remove_match(struct json_rpc_handle *jrpc, uint64_t id, uint64_t seq) {
struct dbus_maches *c = jrpc->matches, *prev = NULL;
for (; c && c->seq != seq; prev = c, c = c->next)
@@ -787,6 +839,8 @@
return json_rpc_call_remove_match(jrpc, id_val, JV_CAST(int, params)->val);
} else if (strcmp(method_str, "sendReply") == 0 && params) {
return json_rpc_call_send_reply(jrpc, id_val, params);
+ } else if (strcmp(method_str, "sendSignal") == 0 && params) {
+ return json_rpc_call_send_signal(jrpc, id_val, params);
}
char *dst = strtok_r(method_str, " ", &savedptr);
@@ -856,8 +910,8 @@
}
for (struct dbus_object_method *c = jrpc->pending_object_call, *n; c; c = n) {
n = c->next;
- if (c->reply)
- sd_bus_message_unref(c->reply);
+ if (c->msg_call)
+ sd_bus_message_unref(c->msg_call);
free(c);
}
free(jrpc);