>From d83d66656dd094d2576f436c9c77dc2714b7da1f Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 21 May 2014 21:29:15 +0200 Subject: [PATCH 4/5] SBUS: Implement org.freedesktop.DBus.Properties.GetAll for primitive types This patch implements the GetAll method of the org.freedesktop.DBus.Properties interface by iterating over the available getters and putting all the results into a single getter. The patch includes a unit test that exercies all currently supported array types. --- src/monitor/monitor_iface_generated.c | 58 +++- src/providers/data_provider_iface_generated.c | 58 +++- src/responder/ifp/ifp_iface_generated.c | 29 +- src/sbus/sbus_codegen | 100 ++++++- src/sbus/sssd_dbus_properties.c | 2 +- src/tests/sbus_codegen_tests.c | 301 +++++++++++++++++++ src/tests/sbus_codegen_tests_generated.c | 415 +++++++++++++++++++++++++- src/tests/sbus_tests.c | 1 + 8 files changed, 947 insertions(+), 17 deletions(-) diff --git a/src/monitor/monitor_iface_generated.c b/src/monitor/monitor_iface_generated.c index e9c3c1d52468ac6969498e79491a1d62dc75cc71..ee59242c1bc3b7b30fb5e086a142aedd6be71319 100644 --- a/src/monitor/monitor_iface_generated.c +++ b/src/monitor/monitor_iface_generated.c @@ -24,12 +24,39 @@ const struct sbus_method_meta mon_srv_iface__methods[] = { { NULL, } }; +/* invokes GetAll for the 'org.freedesktop.sssd.monitor' interface */ +static int invoke_mon_srv_iface_get_all(struct sbus_request *dbus_req, void *function_ptr) +{ + DBusMessage *reply; + dbus_bool_t dbret; + DBusMessageIter iter; + DBusMessageIter iter_dict; + + reply = dbus_message_new_method_return(dbus_req->message); + if (!reply) return ENOMEM; + dbus_message_iter_init_append(reply, &iter); + dbret = dbus_message_iter_open_container( + &iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &iter_dict); + if (!dbret) return ENOMEM; + + dbret = dbus_message_iter_close_container(&iter, &iter_dict); + if (!dbret) return ENOMEM; + + return sbus_request_finish(dbus_req, reply); +} + /* interface info for org.freedesktop.sssd.monitor */ const struct sbus_interface_meta mon_srv_iface_meta = { "org.freedesktop.sssd.monitor", /* name */ mon_srv_iface__methods, NULL, /* no signals */ - NULL, /* no propetries */ + NULL, /* no properties */ + invoke_mon_srv_iface_get_all, /* GetAll invoker */ }; /* methods for org.freedesktop.sssd.service */ @@ -93,10 +120,37 @@ const struct sbus_method_meta mon_cli_iface__methods[] = { { NULL, } }; +/* invokes GetAll for the 'org.freedesktop.sssd.service' interface */ +static int invoke_mon_cli_iface_get_all(struct sbus_request *dbus_req, void *function_ptr) +{ + DBusMessage *reply; + dbus_bool_t dbret; + DBusMessageIter iter; + DBusMessageIter iter_dict; + + reply = dbus_message_new_method_return(dbus_req->message); + if (!reply) return ENOMEM; + dbus_message_iter_init_append(reply, &iter); + dbret = dbus_message_iter_open_container( + &iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &iter_dict); + if (!dbret) return ENOMEM; + + dbret = dbus_message_iter_close_container(&iter, &iter_dict); + if (!dbret) return ENOMEM; + + return sbus_request_finish(dbus_req, reply); +} + /* interface info for org.freedesktop.sssd.service */ const struct sbus_interface_meta mon_cli_iface_meta = { "org.freedesktop.sssd.service", /* name */ mon_cli_iface__methods, NULL, /* no signals */ - NULL, /* no propetries */ + NULL, /* no properties */ + invoke_mon_cli_iface_get_all, /* GetAll invoker */ }; diff --git a/src/providers/data_provider_iface_generated.c b/src/providers/data_provider_iface_generated.c index e7eca7def576772a695457444de7aaf99795fb65..58813762570c12b17c26f8116ced347de540b263 100644 --- a/src/providers/data_provider_iface_generated.c +++ b/src/providers/data_provider_iface_generated.c @@ -59,12 +59,39 @@ const struct sbus_method_meta data_provider_iface__methods[] = { { NULL, } }; +/* invokes GetAll for the 'org.freedesktop.sssd.dataprovider' interface */ +static int invoke_data_provider_iface_get_all(struct sbus_request *dbus_req, void *function_ptr) +{ + DBusMessage *reply; + dbus_bool_t dbret; + DBusMessageIter iter; + DBusMessageIter iter_dict; + + reply = dbus_message_new_method_return(dbus_req->message); + if (!reply) return ENOMEM; + dbus_message_iter_init_append(reply, &iter); + dbret = dbus_message_iter_open_container( + &iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &iter_dict); + if (!dbret) return ENOMEM; + + dbret = dbus_message_iter_close_container(&iter, &iter_dict); + if (!dbret) return ENOMEM; + + return sbus_request_finish(dbus_req, reply); +} + /* interface info for org.freedesktop.sssd.dataprovider */ const struct sbus_interface_meta data_provider_iface_meta = { "org.freedesktop.sssd.dataprovider", /* name */ data_provider_iface__methods, NULL, /* no signals */ - NULL, /* no propetries */ + NULL, /* no properties */ + invoke_data_provider_iface_get_all, /* GetAll invoker */ }; /* methods for org.freedesktop.sssd.dataprovider_rev */ @@ -86,10 +113,37 @@ const struct sbus_method_meta data_provider_rev_iface__methods[] = { { NULL, } }; +/* invokes GetAll for the 'org.freedesktop.sssd.dataprovider_rev' interface */ +static int invoke_data_provider_rev_iface_get_all(struct sbus_request *dbus_req, void *function_ptr) +{ + DBusMessage *reply; + dbus_bool_t dbret; + DBusMessageIter iter; + DBusMessageIter iter_dict; + + reply = dbus_message_new_method_return(dbus_req->message); + if (!reply) return ENOMEM; + dbus_message_iter_init_append(reply, &iter); + dbret = dbus_message_iter_open_container( + &iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &iter_dict); + if (!dbret) return ENOMEM; + + dbret = dbus_message_iter_close_container(&iter, &iter_dict); + if (!dbret) return ENOMEM; + + return sbus_request_finish(dbus_req, reply); +} + /* interface info for org.freedesktop.sssd.dataprovider_rev */ const struct sbus_interface_meta data_provider_rev_iface_meta = { "org.freedesktop.sssd.dataprovider_rev", /* name */ data_provider_rev_iface__methods, NULL, /* no signals */ - NULL, /* no propetries */ + NULL, /* no properties */ + invoke_data_provider_rev_iface_get_all, /* GetAll invoker */ }; diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c index d3cb4990cf13fd51621b7606371cdf3175bc789a..91efda251491216fee41663d88fd67b687d3a2cd 100644 --- a/src/responder/ifp/ifp_iface_generated.c +++ b/src/responder/ifp/ifp_iface_generated.c @@ -66,12 +66,39 @@ const struct sbus_method_meta infopipe_iface__methods[] = { { NULL, } }; +/* invokes GetAll for the 'org.freedesktop.sssd.infopipe' interface */ +static int invoke_infopipe_iface_get_all(struct sbus_request *dbus_req, void *function_ptr) +{ + DBusMessage *reply; + dbus_bool_t dbret; + DBusMessageIter iter; + DBusMessageIter iter_dict; + + reply = dbus_message_new_method_return(dbus_req->message); + if (!reply) return ENOMEM; + dbus_message_iter_init_append(reply, &iter); + dbret = dbus_message_iter_open_container( + &iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &iter_dict); + if (!dbret) return ENOMEM; + + dbret = dbus_message_iter_close_container(&iter, &iter_dict); + if (!dbret) return ENOMEM; + + return sbus_request_finish(dbus_req, reply); +} + /* interface info for org.freedesktop.sssd.infopipe */ const struct sbus_interface_meta infopipe_iface_meta = { "org.freedesktop.sssd.infopipe", /* name */ infopipe_iface__methods, NULL, /* no signals */ - NULL, /* no propetries */ + NULL, /* no properties */ + invoke_infopipe_iface_get_all, /* GetAll invoker */ }; /* invokes a handler with a 's' DBus signature */ diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen index 6507753f2797b354da8aaa2503b7d9bd701668c8..15a6cadacc62e6809a9c807d30a48d6689ec0fd5 100755 --- a/src/sbus/sbus_codegen +++ b/src/sbus/sbus_codegen @@ -291,6 +291,21 @@ def source_method_invoker(signature, args): out(");") out("}") +def source_prop_types(prop, type_prefix=False): + prefix = "%s_" % prop.type if type_prefix else "" + if prop.is_array: + out(" %s *%sprop_val;", prop.sssd_type, prefix) + out(" int %sprop_len;", prefix) + out(" %s *%sout_val;", prop.dbus_type, prefix) + else: + out(" %s %sprop_val;", prop.sssd_type, prefix) + out(" %s %sout_val;", prop.dbus_type, prefix) + +def source_prop_handler(prop, type_prefix=False): + prefix = "%s_" % prop.type if type_prefix else "" + out(" %s", prop.getter_signature("%shandler" % prefix), new_line=False) + out(";") + def source_getter_invoker(prop): out("") if prop.is_array: @@ -300,13 +315,9 @@ def source_getter_invoker(prop): out("static int %s(struct sbus_request *dbus_req, void *function_ptr)", prop.getter_invoker_name()) out("{") - if prop.is_array: - out(" %s *prop_val;", prop.sssd_type) - out(" int prop_len;") - out(" %s *out_val;", prop.dbus_type) - else: - out(" %s prop_val;", prop.sssd_type) - out(" %s out_val;", prop.dbus_type) + + source_prop_types(prop) + out("") out(" %s", prop.getter_signature("handler"), new_line=False) out(" = function_ptr;") @@ -330,6 +341,73 @@ def source_getter_invoker(prop): out(" return sbus_request_return_as_variant(dbus_req, %s, &out_val);", prop.dbus_constant) out("}") +def source_getall_invoker(iface, prop_invokers): + out("") + out("/* invokes GetAll for the '%s' interface */", iface.name) + out("static int invoke_%s_get_all(struct sbus_request *dbus_req, void *function_ptr)", + iface.c_name()) + out("{") + out(" DBusMessage *reply;") + out(" dbus_bool_t dbret;") + out(" DBusMessageIter iter;") + out(" DBusMessageIter iter_dict;") + if iface.properties: + out(" int ret;") + out(" struct sbus_interface *intf = dbus_req->intf;") + out(" const struct sbus_property_meta *property;") + + iface_types = [ p.type for p in iface.properties ] + for prop in [ p for p in prop_invokers.values() if p.type in iface_types ]: + source_prop_types(prop, type_prefix=True) + source_prop_handler(prop, type_prefix=True) + out("") + + out(" reply = dbus_message_new_method_return(dbus_req->message);") + out(" if (!reply) return ENOMEM;") + out(" dbus_message_iter_init_append(reply, &iter);") + out(" dbret = dbus_message_iter_open_container(") + out(" &iter, DBUS_TYPE_ARRAY,") + out(" DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING") + out(" DBUS_TYPE_STRING_AS_STRING") + out(" DBUS_TYPE_VARIANT_AS_STRING") + out(" DBUS_DICT_ENTRY_END_CHAR_AS_STRING,") + out(" &iter_dict);") + out(" if (!dbret) return ENOMEM;") + out("") + + for prop in iface.properties: + out(" property = sbus_meta_find_property(intf->vtable->meta, \"%s\");", prop.c_name()) + out(" if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {") + out(" %s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);", prop.type) + out(" if (%s_handler) {", prop.type) + out(" (%s_handler)(dbus_req, dbus_req->intf->instance_data, &%s_prop_val", prop.type, prop.type, new_line=False) + if prop.is_array: + out(", &%s_prop_len", prop.type, new_line=False) + out(");") + if prop.type == "s": + out(" %s_out_val = %s_prop_val == NULL ? \"\" : %s_prop_val;", + prop.type, prop.type, prop.type) + elif prop.type == "o": + out(" %s_out_val = %s_prop_val == NULL ? \"/\" : %s_prop_val;", + prop.type, prop.type, prop.type) + else: + out(" %s_out_val = %s_prop_val;", prop.type, prop.type) + if prop.is_array: + out(" ret = sbus_add_array_as_variant_to_dict(&iter_dict, \"%s\", %s, (uint8_t*)%s_out_val, %s_prop_len, sizeof(%s));", prop.c_name(), prop.dbus_constant, prop.type, prop.type, prop.sssd_type) + else: + out(" ret = sbus_add_variant_to_dict(&iter_dict, \"%s\", %s, &%s_out_val);", prop.c_name(), prop.dbus_constant, prop.type) + out(" if (ret != EOK) return ret;") + out(" }") + out(" }") + out("") + + out(" dbret = dbus_message_iter_close_container(&iter, &iter_dict);") + out(" if (!dbret) return ENOMEM;") + out("") + + out(" return sbus_request_finish(dbus_req, reply);") + out("}") + def forward_method_invokers(ifaces): invokers = { } for iface in ifaces: @@ -509,9 +587,10 @@ def source_interface(iface): else: out(" NULL, /* no signals */") if iface.properties: - out(" %s__properties", iface.c_name()) + out(" %s__properties,", iface.c_name()) else: - out(" NULL, /* no propetries */") + out(" NULL, /* no properties */") + out(" invoke_%s_get_all, /* GetAll invoker */", iface.c_name()) out("};") def generate_source(ifaces, filename, include_header=None): @@ -543,6 +622,9 @@ def generate_source(ifaces, filename, include_header=None): if iface.properties: source_properties(iface, iface.properties) + # always generate getall, for interfaces without properties + # let's return an empty array + source_getall_invoker(iface, prop_invokers) # The sbus_interface structure source_interface(iface) diff --git a/src/sbus/sssd_dbus_properties.c b/src/sbus/sssd_dbus_properties.c index a85f0d6e2e5ec40c50a960e0266d97326e1096a1..703f6eb81d8d788b7e9e46d68265b4e6136c0089 100644 --- a/src/sbus/sssd_dbus_properties.c +++ b/src/sbus/sssd_dbus_properties.c @@ -345,7 +345,7 @@ dispatch_properties_get_all(struct sbus_connection *conn, sbus_error_new(req, DBUS_ERROR_INVALID_ARGS, "Invalid argument types passed " \ - "to Set method")); + "to GetAll method")); } dbus_message_iter_init(message, &iter); diff --git a/src/tests/sbus_codegen_tests.c b/src/tests/sbus_codegen_tests.c index c7da414fe30f46d9d317f3a4205ab38c4e905081..ba972a9ea89dff501df6ada021004725d9005797 100644 --- a/src/tests/sbus_codegen_tests.c +++ b/src/tests/sbus_codegen_tests.c @@ -1033,12 +1033,313 @@ START_TEST(test_get_basic_array_types) } END_TEST +struct prop_test { + const char *name; + bool handled; + int length; + int type; + union prop_value { + bool bool_val; + const char *string_val; + const char *path_val; + uint8_t byte_val; + int16_t int16_val; + uint16_t uint16_val; + int32_t int32_val; + uint32_t uint32_val; + int64_t int64_val; + uint64_t uint64_val; + double double_val; + + const char **string_arr_val; + const char **path_arr_val; + uint8_t *byte_arr_val; + int16_t *int16_arr_val; + uint16_t *uint16_arr_val; + int32_t *int32_arr_val; + uint32_t *uint32_arr_val; + int64_t *int64_arr_val; + uint64_t *uint64_arr_val; + double *double_arr_val; + } value; +}; + +void check_prop(DBusMessageIter *variter, struct prop_test *p) +{ + dbus_bool_t bool_val; + const char *string_val; + const char *path_val; + uint8_t byte_val; + int16_t int16_val; + uint16_t uint16_val; + int32_t int32_val; + uint32_t uint32_val; + int64_t int64_val; + uint64_t uint64_val; + double double_val; + int type; + + type = dbus_message_iter_get_arg_type(variter); + + /* No property should be returned twice */ + ck_assert(p->handled == false); + ck_assert(p->type == type); + switch (p->type) { + case DBUS_TYPE_BOOLEAN: + dbus_message_iter_get_basic(variter, &bool_val); + ck_assert(bool_val == p->value.bool_val); + break; + case DBUS_TYPE_STRING: + dbus_message_iter_get_basic(variter, &string_val); + ck_assert_str_eq(string_val, p->value.string_val); + break; + case DBUS_TYPE_BYTE: + dbus_message_iter_get_basic(variter, &byte_val); + ck_assert_int_eq(byte_val, p->value.byte_val); + break; + case DBUS_TYPE_INT16: + dbus_message_iter_get_basic(variter, &int16_val); + ck_assert_int_eq(int16_val, p->value.int16_val); + break; + case DBUS_TYPE_UINT16: + dbus_message_iter_get_basic(variter, &uint16_val); + ck_assert_int_eq(uint16_val, p->value.uint16_val); + break; + case DBUS_TYPE_INT32: + dbus_message_iter_get_basic(variter, &int32_val); + ck_assert_int_eq(int32_val, p->value.int32_val); + break; + case DBUS_TYPE_UINT32: + dbus_message_iter_get_basic(variter, &uint32_val); + ck_assert_int_eq(uint32_val, p->value.uint32_val); + break; + case DBUS_TYPE_INT64: + dbus_message_iter_get_basic(variter, &int64_val); + ck_assert_int_eq(int64_val, p->value.int64_val); + break; + case DBUS_TYPE_UINT64: + dbus_message_iter_get_basic(variter, &uint64_val); + ck_assert_int_eq(uint64_val, p->value.uint64_val); + break; + case DBUS_TYPE_DOUBLE: + dbus_message_iter_get_basic(variter, &double_val); + ck_assert_int_eq(double_val, p->value.double_val); + break; + case DBUS_TYPE_OBJECT_PATH: + dbus_message_iter_get_basic(variter, &path_val); + ck_assert_str_eq(path_val, p->value.path_val); + break; + default: + /* Not handled */ + return; + } + + /* This attribute was handled, get the next one */ + p->handled = true; +} + +void check_arr_prop(DBusMessageIter *variter, struct prop_test *p) +{ + DBusMessageIter arriter; + const char **strings = NULL; + uint8_t *byte_arr_val; + int16_t *int16_arr_val; + uint16_t *uint16_arr_val; + int32_t *int32_arr_val; + uint32_t *uint32_arr_val; + int64_t *int64_arr_val; + uint64_t *uint64_arr_val; + double *double_arr_val; + int len; + int type; + + ck_assert_int_eq(dbus_message_iter_get_arg_type(variter), DBUS_TYPE_ARRAY); + type = dbus_message_iter_get_element_type(variter); + ck_assert_int_eq(type, p->type); + + dbus_message_iter_recurse(variter, &arriter); + if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) { + int n = 0, i = 0;; + const char *s; + + do { + n++; + } while (dbus_message_iter_next(&arriter)); + + /* Allocating on NULL is bad, but this is unit test */ + strings = talloc_array(NULL, const char *, n); + ck_assert(strings != NULL); + + dbus_message_iter_recurse(variter, &arriter); + do { + dbus_message_iter_get_basic(&arriter, &s); + strings[i] = talloc_strdup(strings, s); + ck_assert(strings[i] != NULL); + i++; + } while (dbus_message_iter_next(&arriter)); + + len = n; + } + + switch (p->type) { + case DBUS_TYPE_STRING: + ck_assert_int_eq(len, 2); + ck_assert(strings != NULL); + ck_assert_str_eq(strings[0], pilot_string_array[0]); + ck_assert_str_eq(strings[1], pilot_string_array[1]); + break; + case DBUS_TYPE_BYTE: + dbus_message_iter_get_fixed_array(&arriter, &byte_arr_val, &len); + check_uint_array(byte_arr_val, len, p->value.byte_arr_val); + break; + case DBUS_TYPE_INT16: + dbus_message_iter_get_fixed_array(&arriter, &int16_arr_val, &len); + check_int_array(int16_arr_val, len, p->value.int16_arr_val); + break; + case DBUS_TYPE_UINT16: + dbus_message_iter_get_fixed_array(&arriter, &uint16_arr_val, &len); + check_uint_array(uint16_arr_val, len, p->value.uint16_arr_val); + break; + case DBUS_TYPE_INT32: + dbus_message_iter_get_fixed_array(&arriter, &int32_arr_val, &len); + check_int_array(int32_arr_val, len, p->value.int32_arr_val); + break; + case DBUS_TYPE_UINT32: + dbus_message_iter_get_fixed_array(&arriter, &uint32_arr_val, &len); + check_uint_array(uint32_arr_val, len, p->value.uint32_arr_val); + break; + case DBUS_TYPE_INT64: + dbus_message_iter_get_fixed_array(&arriter, &int64_arr_val, &len); + check_int_array(int64_arr_val, len, p->value.int64_arr_val); + break; + case DBUS_TYPE_UINT64: + dbus_message_iter_get_fixed_array(&arriter, &uint64_arr_val, &len); + check_uint_array(uint64_arr_val, len, p->value.uint64_arr_val); + break; + case DBUS_TYPE_DOUBLE: + dbus_message_iter_get_fixed_array(&arriter, &double_arr_val, &len); + check_int_array(double_arr_val, len, p->value.double_arr_val); + break; + case DBUS_TYPE_OBJECT_PATH: + ck_assert_int_eq(len, 2); + ck_assert(strings != NULL); + ck_assert_str_eq(strings[0], pilot_path_array[0]); + ck_assert_str_eq(strings[1], pilot_path_array[1]); + break; + default: + /* Not handled */ + return; + } + + + p->handled = true; +} + +START_TEST(test_getall_basic_types) +{ + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter arriter; + DBusMessageIter dictiter; + DBusMessageIter variter; + dbus_bool_t dbret; + DBusError error = DBUS_ERROR_INIT; + TALLOC_CTX *ctx; + DBusConnection *client; + char *attr_name; + int i; + int num_prop; + + struct prop_test pilot_properties[] = { + { "boolean", false, 0, DBUS_TYPE_BOOLEAN, { .bool_val = pilot_bool } }, + { "FullName", false, 0, DBUS_TYPE_STRING, { .string_val = pilot_full_name } }, + { "byte", false, 0, DBUS_TYPE_BYTE, { .byte_val = pilot_byte } }, + { "int16", false, 0, DBUS_TYPE_INT16, { .int16_val = pilot_int16 } }, + { "uint16", false, 0, DBUS_TYPE_UINT16, { .uint16_val = pilot_uint16 } }, + { "int32", false, 0, DBUS_TYPE_INT32, { .int32_val = pilot_int32 } }, + { "uint32", false, 0, DBUS_TYPE_UINT32, { .uint32_val = pilot_uint32 } }, + { "int64", false, 0, DBUS_TYPE_INT64, { .int64_val = pilot_int64 } }, + { "uint64", false, 0, DBUS_TYPE_UINT64, { .uint64_val = pilot_uint64 } }, + { "double", false, 0, DBUS_TYPE_DOUBLE, { .double_val = pilot_double } }, + { "string", false, 0, DBUS_TYPE_STRING, { .string_val = pilot_string } }, + { "object_path", false, 0, DBUS_TYPE_OBJECT_PATH, { .path_val = pilot_path } }, + { "null_string", false, 0, DBUS_TYPE_STRING, { .string_val = "" } }, + { "null_path", false, 0, DBUS_TYPE_OBJECT_PATH, { .path_val = "/" } }, + + { "byte_array", false, N_ELEMENTS(pilot_byte_array), DBUS_TYPE_BYTE, { .byte_arr_val = pilot_byte_array } }, + { "int16_array", false, N_ELEMENTS(pilot_int16_array), DBUS_TYPE_INT16, { .int16_arr_val = pilot_int16_array } }, + { "uint16_array", false, N_ELEMENTS(pilot_uint16_array), DBUS_TYPE_UINT16, { .uint16_arr_val = pilot_uint16_array } }, + { "int32_array", false, N_ELEMENTS(pilot_int32_array), DBUS_TYPE_INT32, { .int32_arr_val = pilot_int32_array } }, + { "uint32_array", false, N_ELEMENTS(pilot_uint32_array), DBUS_TYPE_UINT32, { .uint32_arr_val = pilot_uint32_array } }, + { "int64_array", false, N_ELEMENTS(pilot_int64_array), DBUS_TYPE_INT64, { .int64_arr_val = pilot_int64_array } }, + { "uint64_array", false, N_ELEMENTS(pilot_uint64_array), DBUS_TYPE_UINT64, { .uint64_arr_val = pilot_uint64_array } }, + { "double_array", false, N_ELEMENTS(pilot_double_array), DBUS_TYPE_DOUBLE, { .double_arr_val = pilot_double_array } }, + { "string_array", false, N_ELEMENTS(pilot_string_array), DBUS_TYPE_STRING, { .string_arr_val = pilot_string_array } }, + { "object_path_array", false, N_ELEMENTS(pilot_path_array), DBUS_TYPE_OBJECT_PATH, { .path_arr_val = pilot_path_array } }, + + { NULL, false, 0, 0, { .bool_val = false } }}; + + ctx = talloc_new(NULL); + client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); + + reply = test_dbus_call_sync(client, + "/test/leela", + DBUS_PROPERTIES_INTERFACE, + "GetAll", + &error, + DBUS_TYPE_STRING, + &test_pilot_meta.name, + DBUS_TYPE_INVALID); + ck_assert(reply != NULL); + + /* GetAll reply is an array of dictionaries */ + dbret = dbus_message_iter_init(reply, &iter); + ck_assert(dbret == TRUE); + ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_ARRAY); + + dbus_message_iter_recurse(&iter, &arriter); + num_prop = 0; + do { + ck_assert_int_eq(dbus_message_iter_get_arg_type(&arriter), + DBUS_TYPE_DICT_ENTRY); + dbus_message_iter_recurse(&arriter, &dictiter); + dbus_message_iter_get_basic(&dictiter, &attr_name); + ck_assert(dbus_message_iter_next(&dictiter) == TRUE); + ck_assert_int_eq(dbus_message_iter_get_arg_type(&dictiter), + DBUS_TYPE_VARIANT); + + dbus_message_iter_recurse(&dictiter, &variter); + + for (i=0; pilot_properties[i].name; i++) { + if (strcmp(attr_name, pilot_properties[i].name) == 0) { + if (dbus_message_iter_get_arg_type(&variter) == DBUS_TYPE_ARRAY) { + check_arr_prop(&variter, &pilot_properties[i]); + } else { + check_prop(&variter, &pilot_properties[i]); + } + break; + } + } + + num_prop++; + } while(dbus_message_iter_next(&arriter)); + + /* All known properties must be handled now */ + for (i=0; pilot_properties[i].name; i++) { + ck_assert(pilot_properties[i].handled == true); + } + /* Also all properties returned from the bus must be accounted for */ + ck_assert_uint_eq(num_prop, N_ELEMENTS(pilot_properties)-1); +} +END_TEST + TCase *create_handler_tests(void) { TCase *tc = tcase_create("handler"); tcase_add_test(tc, test_marshal_basic_types); tcase_add_test(tc, test_get_basic_types); + tcase_add_test(tc, test_getall_basic_types); tcase_add_test(tc, test_get_basic_array_types); return tc; diff --git a/src/tests/sbus_codegen_tests_generated.c b/src/tests/sbus_codegen_tests_generated.c index 70302daff7c7a7f5b042428be7d994fa0cdd660a..502d6ce8a0436d5651e27e0ae6e8b87daa8715e3 100644 --- a/src/tests/sbus_codegen_tests_generated.c +++ b/src/tests/sbus_codegen_tests_generated.c @@ -125,12 +125,56 @@ const struct sbus_property_meta com_planetexpress_Ship__properties[] = { { NULL, } }; +/* invokes GetAll for the 'com.planetexpress.Ship' interface */ +static int invoke_com_planetexpress_Ship_get_all(struct sbus_request *dbus_req, void *function_ptr) +{ + DBusMessage *reply; + dbus_bool_t dbret; + DBusMessageIter iter; + DBusMessageIter iter_dict; + int ret; + struct sbus_interface *intf = dbus_req->intf; + const struct sbus_property_meta *property; + const char * s_prop_val; + const char * s_out_val; + void (*s_handler)(struct sbus_request *, void *data, const char * *); + + reply = dbus_message_new_method_return(dbus_req->message); + if (!reply) return ENOMEM; + dbus_message_iter_init_append(reply, &iter); + dbret = dbus_message_iter_open_container( + &iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &iter_dict); + if (!dbret) return ENOMEM; + + property = sbus_meta_find_property(intf->vtable->meta, "Color"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (s_handler) { + (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val); + s_out_val = s_prop_val == NULL ? "" : s_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "Color", DBUS_TYPE_STRING, &s_out_val); + if (ret != EOK) return ret; + } + } + + dbret = dbus_message_iter_close_container(&iter, &iter_dict); + if (!dbret) return ENOMEM; + + return sbus_request_finish(dbus_req, reply); +} + /* interface info for com.planetexpress.Ship */ const struct sbus_interface_meta com_planetexpress_Ship_meta = { "com.planetexpress.Ship", /* name */ com_planetexpress_Ship__methods, com_planetexpress_Ship__signals, - com_planetexpress_Ship__properties + com_planetexpress_Ship__properties, + invoke_com_planetexpress_Ship_get_all, /* GetAll invoker */ }; /* arguments for com.planetexpress.Pilot.Blink */ @@ -473,12 +517,379 @@ const struct sbus_property_meta test_pilot__properties[] = { { NULL, } }; +/* invokes GetAll for the 'com.planetexpress.Pilot' interface */ +static int invoke_test_pilot_get_all(struct sbus_request *dbus_req, void *function_ptr) +{ + DBusMessage *reply; + dbus_bool_t dbret; + DBusMessageIter iter; + DBusMessageIter iter_dict; + int ret; + struct sbus_interface *intf = dbus_req->intf; + const struct sbus_property_meta *property; + uint16_t *aq_prop_val; + int aq_prop_len; + uint16_t *aq_out_val; + void (*aq_handler)(struct sbus_request *, void *data, uint16_t * *, int *); + bool b_prop_val; + dbus_bool_t b_out_val; + void (*b_handler)(struct sbus_request *, void *data, bool *); + double d_prop_val; + double d_out_val; + void (*d_handler)(struct sbus_request *, void *data, double *); + const char * *ao_prop_val; + int ao_prop_len; + const char * *ao_out_val; + void (*ao_handler)(struct sbus_request *, void *data, const char * * *, int *); + int32_t i_prop_val; + int32_t i_out_val; + void (*i_handler)(struct sbus_request *, void *data, int32_t *); + const char * *as_prop_val; + int as_prop_len; + const char * *as_out_val; + void (*as_handler)(struct sbus_request *, void *data, const char * * *, int *); + const char * o_prop_val; + const char * o_out_val; + void (*o_handler)(struct sbus_request *, void *data, const char * *); + int16_t n_prop_val; + int16_t n_out_val; + void (*n_handler)(struct sbus_request *, void *data, int16_t *); + uint16_t q_prop_val; + uint16_t q_out_val; + void (*q_handler)(struct sbus_request *, void *data, uint16_t *); + uint8_t *ay_prop_val; + int ay_prop_len; + uint8_t *ay_out_val; + void (*ay_handler)(struct sbus_request *, void *data, uint8_t * *, int *); + const char * s_prop_val; + const char * s_out_val; + void (*s_handler)(struct sbus_request *, void *data, const char * *); + uint32_t u_prop_val; + uint32_t u_out_val; + void (*u_handler)(struct sbus_request *, void *data, uint32_t *); + uint64_t t_prop_val; + uint64_t t_out_val; + void (*t_handler)(struct sbus_request *, void *data, uint64_t *); + int64_t *ax_prop_val; + int ax_prop_len; + int64_t *ax_out_val; + void (*ax_handler)(struct sbus_request *, void *data, int64_t * *, int *); + uint8_t y_prop_val; + uint8_t y_out_val; + void (*y_handler)(struct sbus_request *, void *data, uint8_t *); + int64_t x_prop_val; + int64_t x_out_val; + void (*x_handler)(struct sbus_request *, void *data, int64_t *); + uint32_t *au_prop_val; + int au_prop_len; + uint32_t *au_out_val; + void (*au_handler)(struct sbus_request *, void *data, uint32_t * *, int *); + int16_t *an_prop_val; + int an_prop_len; + int16_t *an_out_val; + void (*an_handler)(struct sbus_request *, void *data, int16_t * *, int *); + double *ad_prop_val; + int ad_prop_len; + double *ad_out_val; + void (*ad_handler)(struct sbus_request *, void *data, double * *, int *); + int32_t *ai_prop_val; + int ai_prop_len; + int32_t *ai_out_val; + void (*ai_handler)(struct sbus_request *, void *data, int32_t * *, int *); + uint64_t *at_prop_val; + int at_prop_len; + uint64_t *at_out_val; + void (*at_handler)(struct sbus_request *, void *data, uint64_t * *, int *); + + reply = dbus_message_new_method_return(dbus_req->message); + if (!reply) return ENOMEM; + dbus_message_iter_init_append(reply, &iter); + dbret = dbus_message_iter_open_container( + &iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &iter_dict); + if (!dbret) return ENOMEM; + + property = sbus_meta_find_property(intf->vtable->meta, "FullName"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (s_handler) { + (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val); + s_out_val = s_prop_val == NULL ? "" : s_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "FullName", DBUS_TYPE_STRING, &s_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "byte"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + y_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (y_handler) { + (y_handler)(dbus_req, dbus_req->intf->instance_data, &y_prop_val); + y_out_val = y_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "byte", DBUS_TYPE_BYTE, &y_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "boolean"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + b_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (b_handler) { + (b_handler)(dbus_req, dbus_req->intf->instance_data, &b_prop_val); + b_out_val = b_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "boolean", DBUS_TYPE_BOOLEAN, &b_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "int16"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + n_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (n_handler) { + (n_handler)(dbus_req, dbus_req->intf->instance_data, &n_prop_val); + n_out_val = n_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "int16", DBUS_TYPE_INT16, &n_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "uint16"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + q_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (q_handler) { + (q_handler)(dbus_req, dbus_req->intf->instance_data, &q_prop_val); + q_out_val = q_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "uint16", DBUS_TYPE_UINT16, &q_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "int32"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + i_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (i_handler) { + (i_handler)(dbus_req, dbus_req->intf->instance_data, &i_prop_val); + i_out_val = i_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "int32", DBUS_TYPE_INT32, &i_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "uint32"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + u_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (u_handler) { + (u_handler)(dbus_req, dbus_req->intf->instance_data, &u_prop_val); + u_out_val = u_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "uint32", DBUS_TYPE_UINT32, &u_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "int64"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + x_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (x_handler) { + (x_handler)(dbus_req, dbus_req->intf->instance_data, &x_prop_val); + x_out_val = x_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "int64", DBUS_TYPE_INT64, &x_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "uint64"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + t_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (t_handler) { + (t_handler)(dbus_req, dbus_req->intf->instance_data, &t_prop_val); + t_out_val = t_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "uint64", DBUS_TYPE_UINT64, &t_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "double"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + d_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (d_handler) { + (d_handler)(dbus_req, dbus_req->intf->instance_data, &d_prop_val); + d_out_val = d_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "double", DBUS_TYPE_DOUBLE, &d_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "string"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (s_handler) { + (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val); + s_out_val = s_prop_val == NULL ? "" : s_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "string", DBUS_TYPE_STRING, &s_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "object_path"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + o_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (o_handler) { + (o_handler)(dbus_req, dbus_req->intf->instance_data, &o_prop_val); + o_out_val = o_prop_val == NULL ? "/" : o_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "object_path", DBUS_TYPE_OBJECT_PATH, &o_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "null_string"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (s_handler) { + (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val); + s_out_val = s_prop_val == NULL ? "" : s_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "null_string", DBUS_TYPE_STRING, &s_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "null_path"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + o_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (o_handler) { + (o_handler)(dbus_req, dbus_req->intf->instance_data, &o_prop_val); + o_out_val = o_prop_val == NULL ? "/" : o_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "null_path", DBUS_TYPE_OBJECT_PATH, &o_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "byte_array"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + ay_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (ay_handler) { + (ay_handler)(dbus_req, dbus_req->intf->instance_data, &ay_prop_val, &ay_prop_len); + ay_out_val = ay_prop_val; + ret = sbus_add_array_as_variant_to_dict(&iter_dict, "byte_array", DBUS_TYPE_BYTE, (uint8_t*)ay_out_val, ay_prop_len, sizeof(uint8_t)); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "int16_array"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + an_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (an_handler) { + (an_handler)(dbus_req, dbus_req->intf->instance_data, &an_prop_val, &an_prop_len); + an_out_val = an_prop_val; + ret = sbus_add_array_as_variant_to_dict(&iter_dict, "int16_array", DBUS_TYPE_INT16, (uint8_t*)an_out_val, an_prop_len, sizeof(int16_t)); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "uint16_array"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + aq_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (aq_handler) { + (aq_handler)(dbus_req, dbus_req->intf->instance_data, &aq_prop_val, &aq_prop_len); + aq_out_val = aq_prop_val; + ret = sbus_add_array_as_variant_to_dict(&iter_dict, "uint16_array", DBUS_TYPE_UINT16, (uint8_t*)aq_out_val, aq_prop_len, sizeof(uint16_t)); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "int32_array"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + ai_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (ai_handler) { + (ai_handler)(dbus_req, dbus_req->intf->instance_data, &ai_prop_val, &ai_prop_len); + ai_out_val = ai_prop_val; + ret = sbus_add_array_as_variant_to_dict(&iter_dict, "int32_array", DBUS_TYPE_INT32, (uint8_t*)ai_out_val, ai_prop_len, sizeof(int32_t)); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "uint32_array"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + au_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (au_handler) { + (au_handler)(dbus_req, dbus_req->intf->instance_data, &au_prop_val, &au_prop_len); + au_out_val = au_prop_val; + ret = sbus_add_array_as_variant_to_dict(&iter_dict, "uint32_array", DBUS_TYPE_UINT32, (uint8_t*)au_out_val, au_prop_len, sizeof(uint32_t)); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "int64_array"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + ax_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (ax_handler) { + (ax_handler)(dbus_req, dbus_req->intf->instance_data, &ax_prop_val, &ax_prop_len); + ax_out_val = ax_prop_val; + ret = sbus_add_array_as_variant_to_dict(&iter_dict, "int64_array", DBUS_TYPE_INT64, (uint8_t*)ax_out_val, ax_prop_len, sizeof(int64_t)); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "uint64_array"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + at_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (at_handler) { + (at_handler)(dbus_req, dbus_req->intf->instance_data, &at_prop_val, &at_prop_len); + at_out_val = at_prop_val; + ret = sbus_add_array_as_variant_to_dict(&iter_dict, "uint64_array", DBUS_TYPE_UINT64, (uint8_t*)at_out_val, at_prop_len, sizeof(uint64_t)); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "double_array"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + ad_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (ad_handler) { + (ad_handler)(dbus_req, dbus_req->intf->instance_data, &ad_prop_val, &ad_prop_len); + ad_out_val = ad_prop_val; + ret = sbus_add_array_as_variant_to_dict(&iter_dict, "double_array", DBUS_TYPE_DOUBLE, (uint8_t*)ad_out_val, ad_prop_len, sizeof(double)); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "string_array"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + as_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (as_handler) { + (as_handler)(dbus_req, dbus_req->intf->instance_data, &as_prop_val, &as_prop_len); + as_out_val = as_prop_val; + ret = sbus_add_array_as_variant_to_dict(&iter_dict, "string_array", DBUS_TYPE_STRING, (uint8_t*)as_out_val, as_prop_len, sizeof(const char *)); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "object_path_array"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + ao_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (ao_handler) { + (ao_handler)(dbus_req, dbus_req->intf->instance_data, &ao_prop_val, &ao_prop_len); + ao_out_val = ao_prop_val; + ret = sbus_add_array_as_variant_to_dict(&iter_dict, "object_path_array", DBUS_TYPE_OBJECT_PATH, (uint8_t*)ao_out_val, ao_prop_len, sizeof(const char *)); + if (ret != EOK) return ret; + } + } + + dbret = dbus_message_iter_close_container(&iter, &iter_dict); + if (!dbret) return ENOMEM; + + return sbus_request_finish(dbus_req, reply); +} + /* interface info for com.planetexpress.Pilot */ const struct sbus_interface_meta test_pilot_meta = { "com.planetexpress.Pilot", /* name */ test_pilot__methods, NULL, /* no signals */ - test_pilot__properties + test_pilot__properties, + invoke_test_pilot_get_all, /* GetAll invoker */ }; /* invokes a handler with a 'bu' DBus signature */ diff --git a/src/tests/sbus_tests.c b/src/tests/sbus_tests.c index d2725cf0e542f20bc1d22db91fa04e80392e7fa9..8572f3263e7b7386f0e7497b22c4790388128daa 100644 --- a/src/tests/sbus_tests.c +++ b/src/tests/sbus_tests.c @@ -98,6 +98,7 @@ const struct sbus_interface_meta pilot_meta = { pilot_methods, NULL, /* no signals */ NULL, /* no properties */ + NULL, /* no GetAll invoker */ }; static int blink_handler(struct sbus_request *req, void *data) -- 1.9.0