>From a8a648e51bb35f5a067a3aeaed8a0c43f8869e2e Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 23 Apr 2014 03:01:21 +0200 Subject: [PATCH 5/9] SBUS: Implement org.freedesktop.DBus.Properties.Get for primitive types This patch implements type-safe getters for primitive types and their arrays. The patch includes unit tests of all supported types and arrays of these types. All getter are synchronous. The getters never fail, instead, they return a default or 'not defined' value. Making the getters synchronous and always returning a value will make it significantly easier to implement the GetAll method. --- src/sbus/sbus_codegen | 114 ++++--- src/sbus/sssd_dbus_meta.h | 2 + src/sbus/sssd_dbus_properties.c | 75 +++++ src/tests/sbus_codegen_tests.c | 490 ++++++++++++++++++++++++++++- src/tests/sbus_codegen_tests.xml | 26 ++ src/tests/sbus_codegen_tests_generated.c | 522 +++++++++++++++++++++++++++++++ src/tests/sbus_codegen_tests_generated.h | 44 +++ 7 files changed, 1229 insertions(+), 44 deletions(-) diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen index 96248a62886ad03439b4a4996f4668c1b610d990..a8f91b784ffaa5a17620792df7285df4b508749f 100755 --- a/src/sbus/sbus_codegen +++ b/src/sbus/sbus_codegen @@ -187,6 +187,16 @@ class Property(Typed): raise DBusXmlException('Invalid access type %s'%self.access) def fq_c_name(self): return "%s_%s" % (self.iface.c_name(), self.c_name()) + def getter_name(self): + return "%s_get_%s" % (self.iface.c_name(), self.c_name()) + def getter_invoker_name(self): + return "invoke_get_%s" % self.type + def getter_signature(self, name): + sig = "void (*%s)(struct sbus_request *, void *data, %s *" % (name, self.sssd_type) + if self.is_array: + sig += " *, int *" + sig += ")" + return sig class Interface(Base): def __init__(self, name): @@ -237,6 +247,9 @@ def method_function_pointer(meth, name, with_names=False): with_names and "data" or "", method_arg_types(meth.in_args, with_names)) +def property_handlers(prop): + return prop.getter_signature(prop.getter_name()) + def forward_method_invoker(signature, args): out("") out("/* invokes a handler with a '%s' DBus signature */", signature) @@ -280,49 +293,36 @@ def source_method_invoker(signature, args): def source_getter_invoker(prop): out("") - out("/* invokes a getter with a '%s' DBus type */", type) - out("static int invoke_%s_getter(struct sbus_request *request, struct sbus_interface *intf, void *function_ptr)", prop.type) + if prop.is_array: + out("/* invokes a getter with an array of '%s' DBus type */", prop.dbus_type) + else: + out("/* invokes a getter with a '%s' DBus type */", prop.dbus_type) + out("static int %s(struct sbus_request *dbus_req, void *function_ptr)", + prop.getter_invoker_name()) out("{") - out(" DBusError error = DBUS_ERROR_INIT;") - out(" int ret;") - for i in range(0, len(args)): - arg = args[i] - if arg.is_array: - out(" %s *arg_%d;", arg.dbus_type, i) - out(" int len_%d;", i) - else: - out(" %s arg_%d;", arg.dbus_type, i) - out(" int (*handler)(struct sbus_request *, void *%s) = function_ptr;", method_arg_types(args)) + 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) out("") - out(" if (!dbus_message_get_args(request->message, &error,") - for i in range(0, len(args)): - arg = args[i] - if arg.is_array: - out(" DBUS_TYPE_ARRAY, %s, &arg_%d, &len_%d,", - arg.dbus_constant, i, i) - else: - out(" %s, &arg_%d,", arg.dbus_constant, i) - out(" DBUS_TYPE_INVALID)) {") - out(" ret = sbus_request_fail_and_finish(request, error.name, error.message);") - out(" dbus_error_free(&error);") - out(" return ret;") - out(" }") + out(" %s", prop.getter_signature("handler"), new_line=False) + out(" = function_ptr;") out("") - out(" ret = (handler)(request, intf", new_line=False) - for i in range(0, len(args)): - arg = args[i] - out(",\n arg_%d", i, new_line=False) - if arg.is_array: - out(",\n len_%d", i, new_line=False) + out(" (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val", new_line=False) + if prop.is_array: + out(", &prop_len", new_line=False) out(");") - out("") - for i in range(0, len(args)): - arg = args[i] - if arg.type in ["as", "ao"]: - out(" dbus_free_string_array((char **)arg_%d);", i) - out(" return ret;") + out("") + out(" out_val = prop_val;") + if prop.is_array: + out(" return sbus_request_return_array_as_variant(dbus_req, %s, (uint8_t*)out_val, prop_len, sizeof(%s));", prop.dbus_constant, prop.sssd_type) + else: + out(" return sbus_request_return_as_variant(dbus_req, %s, &out_val);", prop.dbus_constant) out("}") def forward_method_invokers(ifaces): @@ -342,6 +342,27 @@ def source_method_invokers(invokers): for (signature, meth) in invokers.items(): source_method_invoker(signature, meth.in_args) +def forward_prop_invoker(prop): + out("static int %s(struct sbus_request *dbus_req, void *function_ptr);", + prop.getter_invoker_name()) + +def forward_prop_invokers(ifaces): + invokers = { } + for iface in ifaces: + for prop in iface.properties: + if not prop.is_basic: + continue + if prop.type in invokers: + continue + forward_prop_invoker(prop) + invokers[prop.type] = prop + return invokers + +def source_prop_invokers(invokers): + for (type, prop) in invokers.items(): + if prop.readable: + source_getter_invoker(prop) + def source_finisher(meth): out("") out("int %s_finish(struct sbus_request *req%s)", @@ -438,6 +459,7 @@ def source_signals(iface, signals): def source_properties(iface, properties): out("") out("/* property info for %s */", iface.name) + out("const struct sbus_property_meta %s__properties[] = {", iface.c_name()) for prop in properties: out(" {") @@ -451,6 +473,14 @@ def source_properties(iface, properties): out(" SBUS_PROPERTY_WRITABLE,") else: assert False, "should not be reached" + if prop.readable: + out(" offsetof(struct %s, %s),", iface.c_name(), prop.getter_name()) + out(" %s,", prop.getter_invoker_name()) + else: + out(" 0, /* not readable */") + out(" NULL, /* no invoker */") + out(" 0, /* not writable */") + out(" NULL, /* no invoker */") out(" },") out(" { NULL, }") out("};") @@ -491,7 +521,8 @@ def generate_source(ifaces, filename, include_header=None): if include_header: out("#include \"%s\"", os.path.basename(include_header)) - invokers = forward_method_invokers(ifaces) + meth_invokers = forward_method_invokers(ifaces) + prop_invokers = forward_prop_invokers(ifaces) for iface in ifaces: @@ -510,7 +541,8 @@ def generate_source(ifaces, filename, include_header=None): # The sbus_interface structure source_interface(iface) - source_method_invokers(invokers) + source_method_invokers(meth_invokers) + source_prop_invokers(prop_invokers) def header_finisher(iface, meth): if meth.use_raw_handler(): @@ -529,6 +561,8 @@ def header_vtable(iface, methods): # All methods for meth in iface.methods: out(" %s;", method_function_pointer(meth, meth.c_name(), with_names=True)) + for prop in iface.properties: + out(" %s;", property_handlers(prop)) out("};") @@ -584,7 +618,7 @@ def generate_header(ifaces, filename): out(" */") for iface in ifaces: - if iface.methods: + if iface.methods or iface.properties: header_vtable(iface, iface.methods) for meth in iface.methods: header_finisher(iface, meth) diff --git a/src/sbus/sssd_dbus_meta.h b/src/sbus/sssd_dbus_meta.h index 0ad21df97f8cb321628896f0e06088db4533101a..4e170b7d6ce5fb8f68109e496ab96cfdf889d864 100644 --- a/src/sbus/sssd_dbus_meta.h +++ b/src/sbus/sssd_dbus_meta.h @@ -60,6 +60,8 @@ struct sbus_property_meta { const char *name; const char *type; int flags; + size_t vtable_offset_get; + sbus_method_invoker_fn invoker_get; size_t vtable_offset_set; sbus_method_invoker_fn invoker_set; }; diff --git a/src/sbus/sssd_dbus_properties.c b/src/sbus/sssd_dbus_properties.c index 835b3078b5abd124ab98265401aa48533a306ee3..bdd5b432fe57ca66a4d06f98720578b3a175a65c 100644 --- a/src/sbus/sssd_dbus_properties.c +++ b/src/sbus/sssd_dbus_properties.c @@ -105,6 +105,77 @@ dispatch_properties_set(struct sbus_connection *conn, return EOK; } +static int +dispatch_properties_get(struct sbus_connection *conn, + struct sbus_interface *intf, + DBusMessage *message) +{ + struct sbus_request *req; + const char *signature; + const struct sbus_interface_meta *meta; + DBusMessageIter iter; + sbus_msg_handler_fn handler_fn; + const struct sbus_property_meta *property; + const char *interface_name; + const char *property_name; + + req = sbus_new_request(conn, intf, message); + if (req == NULL) { + return ENOMEM; + } + + meta = intf->vtable->meta; + + signature = dbus_message_get_signature(message); + /* Interface name, property name */ + if (strcmp(signature, "ss") != 0) { + return sbus_request_fail_and_finish(req, + sbus_error_new(req, + DBUS_ERROR_INVALID_ARGS, + "Invalid argument types passed to Get method")); + } + + dbus_message_iter_init(message, &iter); + dbus_message_iter_get_basic(&iter, &interface_name); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &property_name); + + if (strcmp(interface_name, meta->name) != 0) { + return sbus_request_fail_and_finish(req, + sbus_error_new(req, + DBUS_ERROR_UNKNOWN_INTERFACE, + "No such interface")); + } + + property = sbus_meta_find_property(intf->vtable->meta, property_name); + if (property == NULL) { + return sbus_request_fail_and_finish(req, + sbus_error_new(req, + DBUS_ERROR_UNKNOWN_PROPERTY, + "No such property")); + } + + if (!(property->flags & SBUS_PROPERTY_READABLE)) { + return sbus_request_fail_and_finish(req, + sbus_error_new(req, + DBUS_ERROR_ACCESS_DENIED, + "Property is not readable")); + } + + handler_fn = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (!handler_fn) { + return sbus_request_fail_and_finish(req, + sbus_error_new(req, + DBUS_ERROR_NOT_SUPPORTED, + "Not implemented")); + } + + sbus_request_invoke_or_finish(req, handler_fn, + intf->instance_data, + property->invoker_get); + return EOK; +} + int sbus_properties_dispatch(struct sbus_request *dbus_req) { const char *member; @@ -116,6 +187,10 @@ int sbus_properties_dispatch(struct sbus_request *dbus_req) return dispatch_properties_set(dbus_req->conn, dbus_req->intf, dbus_req->message); + } else if (strcmp (member, "Get") == 0) { + return dispatch_properties_get(dbus_req->conn, + dbus_req->intf, + dbus_req->message); } return ERR_SBUS_NOSUP; diff --git a/src/tests/sbus_codegen_tests.c b/src/tests/sbus_codegen_tests.c index a88bbac38e7d4f89ec92043061cf25bb4ed7b972..fa31ad64dae578470cc004c0be066771d07ef2bf 100644 --- a/src/tests/sbus_codegen_tests.c +++ b/src/tests/sbus_codegen_tests.c @@ -33,6 +33,9 @@ #include "tests/sbus_codegen_tests_generated.h" #include "util/util_errors.h" +#define N_ELEMENTS(arr) \ + (sizeof(arr) / sizeof(arr[0])) + /* The following 2 macros were taken from check's project source files (0.9.10) * http://check.sourceforge.net/ */ @@ -329,12 +332,225 @@ static int eject_handler(struct sbus_request *req, void *instance_data, arg_object_path_array, len_object_path_array); } -#define N_ELEMENTS(arr) \ - (sizeof(arr) / sizeof(arr[0])) +#define getter_body(in, out) do { \ + ck_assert(dbus_req != NULL); \ + ck_assert(out != NULL); \ + *out = in; \ +} while(0); -struct test_pilot pilot_methods = { +static const bool pilot_bool = true; +void pilot_get_boolean_handler(struct sbus_request *dbus_req, + void *instance_data, + bool *val) +{ + getter_body(pilot_bool, val); +} + +static const char *pilot_full_name = "Turanga Leela"; +void pilot_get_full_name_handler(struct sbus_request *dbus_req, + void *instance_data, + const char **name) +{ + getter_body(pilot_full_name, name); +} + +static const uint8_t pilot_byte = 42; +void pilot_get_byte_handler(struct sbus_request *dbus_req, + void *instance_data, + uint8_t *byte) +{ + getter_body(pilot_byte, byte); +} + +static const int16_t pilot_int16 = -123; +void pilot_get_int16_handler(struct sbus_request *dbus_req, + void *instance_data, + int16_t *int16) +{ + getter_body(pilot_int16, int16); +} + +static const uint16_t pilot_uint16 = 123; +void pilot_get_uint16_handler(struct sbus_request *dbus_req, + void *instance_data, + uint16_t *uint16) +{ + getter_body(pilot_uint16, uint16); +} + +static const int32_t pilot_int32 = -456; +void pilot_get_int32_handler(struct sbus_request *dbus_req, + void *instance_data, + int32_t *int32) +{ + getter_body(pilot_int32, int32); +} + +static const uint32_t pilot_uint32 = 456; +void pilot_get_uint32_handler(struct sbus_request *dbus_req, + void *instance_data, + uint32_t *uint32) +{ + getter_body(pilot_uint32, uint32); +} + +static const int64_t pilot_int64 = -456; +void pilot_get_int64_handler(struct sbus_request *dbus_req, + void *instance_data, + int64_t *int64) +{ + getter_body(pilot_int64, int64); +} + +static const uint64_t pilot_uint64 = 456; +void pilot_get_uint64_handler(struct sbus_request *dbus_req, + void *instance_data, + uint64_t *uint64) +{ + getter_body(pilot_uint64, uint64); +} + +static const double pilot_double = 3.14; +void pilot_get_double_handler(struct sbus_request *dbus_req, + void *instance_data, + double *double_val) +{ + getter_body(pilot_double, double_val); +} + +static const char *pilot_string = "leela"; +void pilot_get_string_handler(struct sbus_request *dbus_req, + void *instance_data, + const char **string_val) +{ + *string_val = pilot_string; +} + +static const char *pilot_path = "/path/leela"; +void pilot_get_objpath_handler(struct sbus_request *dbus_req, + void *instance_data, + const char **path_val) +{ + *path_val = pilot_path; +} + +#define array_getter_body(in, out, outlen) do { \ + ck_assert(dbus_req != NULL); \ + ck_assert(out != NULL); \ + ck_assert(outlen != NULL); \ + *out = in; \ + *outlen = N_ELEMENTS(in); \ +} while(0); + +static uint8_t pilot_byte_array[] = { 42, 0 }; +void pilot_get_byte_array_handler(struct sbus_request *dbus_req, + void *instance_data, + uint8_t **arr_out, int *arr_len) +{ + array_getter_body(pilot_byte_array, arr_out, arr_len); +} + +static int16_t pilot_int16_array[] = { -123, 0 }; +void pilot_get_int16_array_handler(struct sbus_request *dbus_req, + void *instance_data, + int16_t **arr_out, int *arr_len) +{ + array_getter_body(pilot_int16_array, arr_out, arr_len); +} + +static uint16_t pilot_uint16_array[] = { 123, 0 }; +void pilot_get_uint16_array_handler(struct sbus_request *dbus_req, + void *instance_data, + uint16_t **arr_out, int *arr_len) +{ + array_getter_body(pilot_uint16_array, arr_out, arr_len); +} + +static int32_t pilot_int32_array[] = { -456, 0 }; +void pilot_get_int32_array_handler(struct sbus_request *dbus_req, + void *instance_data, + int32_t **arr_out, int *arr_len) +{ + array_getter_body(pilot_int32_array, arr_out, arr_len); +} + +static uint32_t pilot_uint32_array[] = { 456, 0 }; +void pilot_get_uint32_array_handler(struct sbus_request *dbus_req, + void *instance_data, + uint32_t **arr_out, int *arr_len) +{ + array_getter_body(pilot_uint32_array, arr_out, arr_len); +} + +static int64_t pilot_int64_array[] = { -789, 0 }; +void pilot_get_int64_array_handler(struct sbus_request *dbus_req, + void *instance_data, + int64_t **arr_out, int *arr_len) +{ + array_getter_body(pilot_int64_array, arr_out, arr_len); +} + +static uint64_t pilot_uint64_array[] = { 789, 0 }; +void pilot_get_uint64_array_handler(struct sbus_request *dbus_req, + void *instance_data, + uint64_t **arr_out, int *arr_len) +{ + array_getter_body(pilot_uint64_array, arr_out, arr_len); +} + +static double pilot_double_array[] = { 3.14, 0 }; +void pilot_get_double_array_handler(struct sbus_request *dbus_req, + void *instance_data, + double **arr_out, int *arr_len) +{ + array_getter_body(pilot_double_array, arr_out, arr_len); +} + +static const char *pilot_string_array[] = { "Turanga", "Leela" }; +void pilot_get_string_array_handler(struct sbus_request *dbus_req, + void *data, + const char ***arr_out, + int *arr_len) +{ + array_getter_body(pilot_string_array, arr_out, arr_len); +} + +static const char *pilot_path_array[] = { "/some/path", "/another/path" }; +void pilot_get_path_array_handler(struct sbus_request *dbus_req, + void *data, + const char ***arr_out, + int *arr_len) +{ + array_getter_body(pilot_path_array, arr_out, arr_len); +} + +struct test_pilot pilot_iface = { { &test_pilot_meta, 0 }, .Eject = eject_handler, + + .test_pilot_get_FullName = pilot_get_full_name_handler, + .test_pilot_get_byte = pilot_get_byte_handler, + .test_pilot_get_boolean = pilot_get_boolean_handler, + .test_pilot_get_int16 = pilot_get_int16_handler, + .test_pilot_get_uint16 = pilot_get_uint16_handler, + .test_pilot_get_int32 = pilot_get_int32_handler, + .test_pilot_get_uint32 = pilot_get_uint32_handler, + .test_pilot_get_int64 = pilot_get_int64_handler, + .test_pilot_get_uint64 = pilot_get_uint64_handler, + .test_pilot_get_double = pilot_get_double_handler, + .test_pilot_get_string = pilot_get_string_handler, + .test_pilot_get_object_path = pilot_get_objpath_handler, + + .test_pilot_get_byte_array = pilot_get_byte_array_handler, + .test_pilot_get_int16_array = pilot_get_int16_array_handler, + .test_pilot_get_uint16_array = pilot_get_uint16_array_handler, + .test_pilot_get_int32_array = pilot_get_int32_array_handler, + .test_pilot_get_uint32_array = pilot_get_uint32_array_handler, + .test_pilot_get_int64_array = pilot_get_int64_array_handler, + .test_pilot_get_uint64_array = pilot_get_uint64_array_handler, + .test_pilot_get_double_array = pilot_get_double_array_handler, + .test_pilot_get_string_array = pilot_get_string_array_handler, + .test_pilot_get_object_path_array = pilot_get_path_array_handler, }; static int pilot_test_server_init(struct sbus_connection *server, void *unused) @@ -343,7 +559,7 @@ static int pilot_test_server_init(struct sbus_connection *server, void *unused) ret = sbus_conn_add_interface(server, sbus_new_interface(server, "/test/leela", - &pilot_methods.vtable, + &pilot_iface.vtable, "Crash into the billboard")); ck_assert_int_eq(ret, EOK); @@ -526,11 +742,277 @@ START_TEST(test_marshal_basic_types) } END_TEST +static void parse_get_reply(DBusMessage *reply, const int type, void *val) +{ + DBusMessageIter iter; + DBusMessageIter variter; + dbus_bool_t dbret; + + dbret = dbus_message_iter_init(reply, &iter); + ck_assert(dbret == TRUE); + ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_VARIANT); + dbus_message_iter_recurse(&iter, &variter); + ck_assert_int_eq(dbus_message_iter_get_arg_type(&variter), type); + dbus_message_iter_get_basic(&variter, val); +} + +static void call_get(DBusConnection *client, + const char *object_path, + const char *iface, + const char *prop, + int type, + void *val) +{ + DBusMessage *reply; + DBusError error = DBUS_ERROR_INIT; + + reply = test_dbus_call_sync(client, + object_path, + DBUS_PROPERTIES_INTERFACE, + "Get", + &error, + DBUS_TYPE_STRING, &iface, + DBUS_TYPE_STRING, &prop, + DBUS_TYPE_INVALID); + ck_assert(reply != NULL); + parse_get_reply(reply, type, val); +} + +START_TEST(test_get_basic_types) +{ + TALLOC_CTX *ctx; + DBusConnection *client; + 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; + + ctx = talloc_new(NULL); + client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); + + call_get(client, "/test/leela", test_pilot_meta.name, "boolean", + DBUS_TYPE_BOOLEAN, &bool_val); + ck_assert(bool_val == pilot_bool); + + call_get(client, "/test/leela", test_pilot_meta.name, "FullName", + DBUS_TYPE_STRING, &string_val); + ck_assert_str_eq(string_val, pilot_full_name); + + call_get(client, "/test/leela", test_pilot_meta.name, "byte", + DBUS_TYPE_BYTE, &byte_val); + ck_assert_int_eq(byte_val, pilot_byte); + + call_get(client, "/test/leela", test_pilot_meta.name, "int16", + DBUS_TYPE_INT16, &int16_val); + ck_assert_int_eq(int16_val, pilot_int16); + + call_get(client, "/test/leela", test_pilot_meta.name, "uint16", + DBUS_TYPE_UINT16, &uint16_val); + ck_assert_int_eq(uint16_val, pilot_uint16); + + call_get(client, "/test/leela", test_pilot_meta.name, "int32", + DBUS_TYPE_INT32, &int32_val); + ck_assert_int_eq(int32_val, pilot_int32); + + call_get(client, "/test/leela", test_pilot_meta.name, "uint32", + DBUS_TYPE_UINT32, &uint32_val); + ck_assert_int_eq(uint32_val, pilot_uint32); + + call_get(client, "/test/leela", test_pilot_meta.name, "int64", + DBUS_TYPE_INT64, &int64_val); + ck_assert_int_eq(int64_val, pilot_int64); + + call_get(client, "/test/leela", test_pilot_meta.name, "uint64", + DBUS_TYPE_UINT64, &uint64_val); + ck_assert_int_eq(uint64_val, pilot_uint64); + + call_get(client, "/test/leela", test_pilot_meta.name, "double", + DBUS_TYPE_DOUBLE, &double_val); + ck_assert_int_eq(double_val, pilot_double); + + call_get(client, "/test/leela", test_pilot_meta.name, "string", + DBUS_TYPE_STRING, &string_val); + ck_assert_str_eq(string_val, pilot_string); + + call_get(client, "/test/leela", test_pilot_meta.name, "object_path", + DBUS_TYPE_OBJECT_PATH, &path_val); + ck_assert_str_eq(path_val, pilot_path); +} +END_TEST + +static void parse_get_array_reply(DBusMessage *reply, const int type, + void **values, int *nels) +{ + DBusMessageIter iter; + DBusMessageIter variter; + DBusMessageIter arriter; + dbus_bool_t dbret; + + dbret = dbus_message_iter_init(reply, &iter); + ck_assert(dbret == TRUE); + ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_VARIANT); + dbus_message_iter_recurse(&iter, &variter); + ck_assert_int_eq(dbus_message_iter_get_arg_type(&variter), DBUS_TYPE_ARRAY); + ck_assert_int_eq(dbus_message_iter_get_element_type(&variter), type); + dbus_message_iter_recurse(&variter, &arriter); + if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) { + int n = 0, i = 0;; + const char **strings; + 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)); + + *nels = n; + *values = strings; + } else { + /* Fixed types are easy */ + dbus_message_iter_get_fixed_array(&arriter, values, nels); + } +} + +static void call_get_array(DBusConnection *client, + const char *object_path, + const char *iface, + const char *prop, + int type, + void **values, + int *nels) +{ + DBusMessage *reply; + DBusError error = DBUS_ERROR_INIT; + + reply = test_dbus_call_sync(client, + object_path, + DBUS_PROPERTIES_INTERFACE, + "Get", + &error, + DBUS_TYPE_STRING, &iface, + DBUS_TYPE_STRING, &prop, + DBUS_TYPE_INVALID); + ck_assert(reply != NULL); + parse_get_array_reply(reply, type, values, nels); +} + +#define _check_array(reply, len, known, fn) do { \ + fn(len, 2); \ + fn(reply[0], known[0]); \ + fn(reply[1], known[1]); \ +} while(0); \ + +#define check_int_array(reply, len, known) \ + _check_array(reply, len, known, ck_assert_int_eq) +#define check_uint_array(reply, len, known) \ + _check_array(reply, len, known, ck_assert_uint_eq) + +START_TEST(test_get_basic_array_types) +{ + TALLOC_CTX *ctx; + DBusConnection *client; + const char **string_arr_val; + int string_arr_len; + const char **path_arr_val; + int path_arr_len; + uint8_t *byte_arr_val; + int byte_arr_len; + int16_t *int16_arr_val; + int int16_arr_len; + uint16_t *uint16_arr_val; + int uint16_arr_len; + int32_t *int32_arr_val; + int int32_arr_len; + uint32_t *uint32_arr_val; + int uint32_arr_len; + int64_t *int64_arr_val; + int int64_arr_len; + uint64_t *uint64_arr_val; + int uint64_arr_len; + double *double_arr_val; + int double_arr_len; + + ctx = talloc_new(NULL); + client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "byte_array", + DBUS_TYPE_BYTE, (void **) &byte_arr_val, &byte_arr_len); + check_uint_array(byte_arr_val, byte_arr_len, pilot_byte_array); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "int16_array", + DBUS_TYPE_INT16, (void **) &int16_arr_val, &int16_arr_len); + check_int_array(int16_arr_val, int16_arr_len, pilot_int16_array); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "uint16_array", + DBUS_TYPE_UINT16, (void **) &uint16_arr_val, &uint16_arr_len); + check_uint_array(uint16_arr_val, uint16_arr_len, pilot_uint16_array); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "int32_array", + DBUS_TYPE_INT32, (void **) &int32_arr_val, &int32_arr_len); + check_int_array(int32_arr_val, int32_arr_len, pilot_int32_array); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "uint32_array", + DBUS_TYPE_UINT32, (void **) &uint32_arr_val, &uint32_arr_len); + check_uint_array(uint32_arr_val, uint32_arr_len, pilot_uint32_array); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "int64_array", + DBUS_TYPE_INT64, (void **) &int64_arr_val, &int64_arr_len); + check_int_array(int64_arr_val, int64_arr_len, pilot_int64_array); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "uint64_array", + DBUS_TYPE_UINT64, (void **) &uint64_arr_val, &uint64_arr_len); + check_uint_array(uint64_arr_val, uint64_arr_len, pilot_uint64_array); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "double_array", + DBUS_TYPE_DOUBLE, (void **) &double_arr_val, &double_arr_len); + check_int_array(double_arr_val, double_arr_len, pilot_double_array); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "string_array", + DBUS_TYPE_STRING, (void **) &string_arr_val, &string_arr_len); + ck_assert_int_eq(string_arr_len, 2); + ck_assert_str_eq(string_arr_val[0], pilot_string_array[0]); + ck_assert_str_eq(string_arr_val[1], pilot_string_array[1]); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "string_array", + DBUS_TYPE_STRING, (void **) &string_arr_val, &string_arr_len); + ck_assert_int_eq(string_arr_len, 2); + ck_assert_str_eq(string_arr_val[0], pilot_string_array[0]); + ck_assert_str_eq(string_arr_val[1], pilot_string_array[1]); + + call_get_array(client, "/test/leela", test_pilot_meta.name, "object_path_array", + DBUS_TYPE_OBJECT_PATH, (void **) &path_arr_val, &path_arr_len); + ck_assert_int_eq(path_arr_len, 2); + ck_assert_str_eq(path_arr_val[0], pilot_path_array[0]); + ck_assert_str_eq(path_arr_val[1], pilot_path_array[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_get_basic_array_types); return tc; } diff --git a/src/tests/sbus_codegen_tests.xml b/src/tests/sbus_codegen_tests.xml index 83807b9c287f633ad59398519a7520e667003f00..74037cc4002198f8c8d4b6a8c12edbd34fe338ef 100755 --- a/src/tests/sbus_codegen_tests.xml +++ b/src/tests/sbus_codegen_tests.xml @@ -107,6 +107,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/sbus_codegen_tests_generated.c b/src/tests/sbus_codegen_tests_generated.c index 40d40cdc471b90f6b0d3fb52033f7ec9817c1772..4ace0365044ac1edec3c8774da2231c82e054017 100644 --- a/src/tests/sbus_codegen_tests_generated.c +++ b/src/tests/sbus_codegen_tests_generated.c @@ -16,6 +16,27 @@ static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr); /* invokes a handler with a 'ybnqiuxtdsoayanaqaiauaxatadasao' DBus signature */ static int invoke_ybnqiuxtdsoayanaqaiauaxatadasao_method(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_s(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_y(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_b(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_n(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_q(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_i(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_u(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_x(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_t(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_d(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_o(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_ay(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_an(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_aq(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_ai(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_au(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_ax(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_at(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_ad(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_as(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_ao(struct sbus_request *dbus_req, void *function_ptr); /* arguments for com.planetexpress.Ship.MoveUniverse */ const struct sbus_arg_meta com_planetexpress_Ship_MoveUniverse__in[] = { @@ -96,6 +117,10 @@ const struct sbus_property_meta com_planetexpress_Ship__properties[] = { "Color", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, + offsetof(struct com_planetexpress_Ship, com_planetexpress_Ship_get_Color), + invoke_get_s, + 0, /* not writable */ + NULL, /* no invoker */ }, { NULL, } }; @@ -233,6 +258,199 @@ const struct sbus_property_meta test_pilot__properties[] = { "FullName", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE | SBUS_PROPERTY_WRITABLE, + offsetof(struct test_pilot, test_pilot_get_FullName), + invoke_get_s, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "byte", /* name */ + "y", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_byte), + invoke_get_y, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "boolean", /* name */ + "b", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_boolean), + invoke_get_b, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "int16", /* name */ + "n", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_int16), + invoke_get_n, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "uint16", /* name */ + "q", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_uint16), + invoke_get_q, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "int32", /* name */ + "i", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_int32), + invoke_get_i, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "uint32", /* name */ + "u", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_uint32), + invoke_get_u, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "int64", /* name */ + "x", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_int64), + invoke_get_x, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "uint64", /* name */ + "t", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_uint64), + invoke_get_t, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "double", /* name */ + "d", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_double), + invoke_get_d, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "string", /* name */ + "s", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_string), + invoke_get_s, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "object_path", /* name */ + "o", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_object_path), + invoke_get_o, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "byte_array", /* name */ + "ay", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_byte_array), + invoke_get_ay, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "int16_array", /* name */ + "an", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_int16_array), + invoke_get_an, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "uint16_array", /* name */ + "aq", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_uint16_array), + invoke_get_aq, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "int32_array", /* name */ + "ai", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_int32_array), + invoke_get_ai, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "uint32_array", /* name */ + "au", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_uint32_array), + invoke_get_au, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "int64_array", /* name */ + "ax", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_int64_array), + invoke_get_ax, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "uint64_array", /* name */ + "at", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_uint64_array), + invoke_get_at, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "double_array", /* name */ + "ad", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_double_array), + invoke_get_ad, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "string_array", /* name */ + "as", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_string_array), + invoke_get_as, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "object_path_array", /* name */ + "ao", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_pilot, test_pilot_get_object_path_array), + invoke_get_ao, + 0, /* not writable */ + NULL, /* no invoker */ }, { NULL, } }; @@ -391,3 +609,307 @@ static int invoke_ybnqiuxtdsoayanaqaiauaxatadasao_method(struct sbus_request *db arg_20, len_20); } + +/* invokes a getter with an array of 'uint16_t' DBus type */ +static int invoke_get_aq(struct sbus_request *dbus_req, void *function_ptr) +{ + uint16_t *prop_val; + int prop_len; + uint16_t *out_val; + + void (*handler)(struct sbus_request *, void *data, uint16_t * *, int *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val, &prop_len); + + out_val = prop_val; + return sbus_request_return_array_as_variant(dbus_req, DBUS_TYPE_UINT16, (uint8_t*)out_val, prop_len, sizeof(uint16_t)); +} + +/* invokes a getter with a 'dbus_bool_t' DBus type */ +static int invoke_get_b(struct sbus_request *dbus_req, void *function_ptr) +{ + bool prop_val; + dbus_bool_t out_val; + + void (*handler)(struct sbus_request *, void *data, bool *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_BOOLEAN, &out_val); +} + +/* invokes a getter with a 'double' DBus type */ +static int invoke_get_d(struct sbus_request *dbus_req, void *function_ptr) +{ + double prop_val; + double out_val; + + void (*handler)(struct sbus_request *, void *data, double *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_DOUBLE, &out_val); +} + +/* invokes a getter with an array of 'const char *' DBus type */ +static int invoke_get_ao(struct sbus_request *dbus_req, void *function_ptr) +{ + const char * *prop_val; + int prop_len; + const char * *out_val; + + void (*handler)(struct sbus_request *, void *data, const char * * *, int *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val, &prop_len); + + out_val = prop_val; + return sbus_request_return_array_as_variant(dbus_req, DBUS_TYPE_OBJECT_PATH, (uint8_t*)out_val, prop_len, sizeof(const char *)); +} + +/* invokes a getter with a 'int32_t' DBus type */ +static int invoke_get_i(struct sbus_request *dbus_req, void *function_ptr) +{ + int32_t prop_val; + int32_t out_val; + + void (*handler)(struct sbus_request *, void *data, int32_t *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_INT32, &out_val); +} + +/* invokes a getter with an array of 'const char *' DBus type */ +static int invoke_get_as(struct sbus_request *dbus_req, void *function_ptr) +{ + const char * *prop_val; + int prop_len; + const char * *out_val; + + void (*handler)(struct sbus_request *, void *data, const char * * *, int *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val, &prop_len); + + out_val = prop_val; + return sbus_request_return_array_as_variant(dbus_req, DBUS_TYPE_STRING, (uint8_t*)out_val, prop_len, sizeof(const char *)); +} + +/* invokes a getter with a 'const char *' DBus type */ +static int invoke_get_o(struct sbus_request *dbus_req, void *function_ptr) +{ + const char * prop_val; + const char * out_val; + + void (*handler)(struct sbus_request *, void *data, const char * *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_OBJECT_PATH, &out_val); +} + +/* invokes a getter with a 'int16_t' DBus type */ +static int invoke_get_n(struct sbus_request *dbus_req, void *function_ptr) +{ + int16_t prop_val; + int16_t out_val; + + void (*handler)(struct sbus_request *, void *data, int16_t *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_INT16, &out_val); +} + +/* invokes a getter with a 'uint16_t' DBus type */ +static int invoke_get_q(struct sbus_request *dbus_req, void *function_ptr) +{ + uint16_t prop_val; + uint16_t out_val; + + void (*handler)(struct sbus_request *, void *data, uint16_t *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_UINT16, &out_val); +} + +/* invokes a getter with an array of 'uint8_t' DBus type */ +static int invoke_get_ay(struct sbus_request *dbus_req, void *function_ptr) +{ + uint8_t *prop_val; + int prop_len; + uint8_t *out_val; + + void (*handler)(struct sbus_request *, void *data, uint8_t * *, int *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val, &prop_len); + + out_val = prop_val; + return sbus_request_return_array_as_variant(dbus_req, DBUS_TYPE_BYTE, (uint8_t*)out_val, prop_len, sizeof(uint8_t)); +} + +/* invokes a getter with a 'const char *' DBus type */ +static int invoke_get_s(struct sbus_request *dbus_req, void *function_ptr) +{ + const char * prop_val; + const char * out_val; + + void (*handler)(struct sbus_request *, void *data, const char * *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_STRING, &out_val); +} + +/* invokes a getter with a 'uint32_t' DBus type */ +static int invoke_get_u(struct sbus_request *dbus_req, void *function_ptr) +{ + uint32_t prop_val; + uint32_t out_val; + + void (*handler)(struct sbus_request *, void *data, uint32_t *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_UINT32, &out_val); +} + +/* invokes a getter with a 'uint64_t' DBus type */ +static int invoke_get_t(struct sbus_request *dbus_req, void *function_ptr) +{ + uint64_t prop_val; + uint64_t out_val; + + void (*handler)(struct sbus_request *, void *data, uint64_t *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_UINT64, &out_val); +} + +/* invokes a getter with an array of 'int64_t' DBus type */ +static int invoke_get_ax(struct sbus_request *dbus_req, void *function_ptr) +{ + int64_t *prop_val; + int prop_len; + int64_t *out_val; + + void (*handler)(struct sbus_request *, void *data, int64_t * *, int *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val, &prop_len); + + out_val = prop_val; + return sbus_request_return_array_as_variant(dbus_req, DBUS_TYPE_INT64, (uint8_t*)out_val, prop_len, sizeof(int64_t)); +} + +/* invokes a getter with a 'uint8_t' DBus type */ +static int invoke_get_y(struct sbus_request *dbus_req, void *function_ptr) +{ + uint8_t prop_val; + uint8_t out_val; + + void (*handler)(struct sbus_request *, void *data, uint8_t *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_BYTE, &out_val); +} + +/* invokes a getter with a 'int64_t' DBus type */ +static int invoke_get_x(struct sbus_request *dbus_req, void *function_ptr) +{ + int64_t prop_val; + int64_t out_val; + + void (*handler)(struct sbus_request *, void *data, int64_t *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_INT64, &out_val); +} + +/* invokes a getter with an array of 'uint32_t' DBus type */ +static int invoke_get_au(struct sbus_request *dbus_req, void *function_ptr) +{ + uint32_t *prop_val; + int prop_len; + uint32_t *out_val; + + void (*handler)(struct sbus_request *, void *data, uint32_t * *, int *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val, &prop_len); + + out_val = prop_val; + return sbus_request_return_array_as_variant(dbus_req, DBUS_TYPE_UINT32, (uint8_t*)out_val, prop_len, sizeof(uint32_t)); +} + +/* invokes a getter with an array of 'int16_t' DBus type */ +static int invoke_get_an(struct sbus_request *dbus_req, void *function_ptr) +{ + int16_t *prop_val; + int prop_len; + int16_t *out_val; + + void (*handler)(struct sbus_request *, void *data, int16_t * *, int *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val, &prop_len); + + out_val = prop_val; + return sbus_request_return_array_as_variant(dbus_req, DBUS_TYPE_INT16, (uint8_t*)out_val, prop_len, sizeof(int16_t)); +} + +/* invokes a getter with an array of 'double' DBus type */ +static int invoke_get_ad(struct sbus_request *dbus_req, void *function_ptr) +{ + double *prop_val; + int prop_len; + double *out_val; + + void (*handler)(struct sbus_request *, void *data, double * *, int *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val, &prop_len); + + out_val = prop_val; + return sbus_request_return_array_as_variant(dbus_req, DBUS_TYPE_DOUBLE, (uint8_t*)out_val, prop_len, sizeof(double)); +} + +/* invokes a getter with an array of 'int32_t' DBus type */ +static int invoke_get_ai(struct sbus_request *dbus_req, void *function_ptr) +{ + int32_t *prop_val; + int prop_len; + int32_t *out_val; + + void (*handler)(struct sbus_request *, void *data, int32_t * *, int *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val, &prop_len); + + out_val = prop_val; + return sbus_request_return_array_as_variant(dbus_req, DBUS_TYPE_INT32, (uint8_t*)out_val, prop_len, sizeof(int32_t)); +} + +/* invokes a getter with an array of 'uint64_t' DBus type */ +static int invoke_get_at(struct sbus_request *dbus_req, void *function_ptr) +{ + uint64_t *prop_val; + int prop_len; + uint64_t *out_val; + + void (*handler)(struct sbus_request *, void *data, uint64_t * *, int *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val, &prop_len); + + out_val = prop_val; + return sbus_request_return_array_as_variant(dbus_req, DBUS_TYPE_UINT64, (uint8_t*)out_val, prop_len, sizeof(uint64_t)); +} diff --git a/src/tests/sbus_codegen_tests_generated.h b/src/tests/sbus_codegen_tests_generated.h index 137dab8a08502b482b445f254c42095202047526..9599091dd0627c7af84fb211858d918d9128ecf0 100644 --- a/src/tests/sbus_codegen_tests_generated.h +++ b/src/tests/sbus_codegen_tests_generated.h @@ -24,6 +24,27 @@ #define TEST_PILOT_BLINK "Blink" #define TEST_PILOT_EJECT "Eject" #define TEST_PILOT_FULLNAME "FullName" +#define TEST_PILOT_BYTE "byte" +#define TEST_PILOT_BOOLEAN "boolean" +#define TEST_PILOT_INT16 "int16" +#define TEST_PILOT_UINT16 "uint16" +#define TEST_PILOT_INT32 "int32" +#define TEST_PILOT_UINT32 "uint32" +#define TEST_PILOT_INT64 "int64" +#define TEST_PILOT_UINT64 "uint64" +#define TEST_PILOT_DOUBLE "double" +#define TEST_PILOT_STRING "string" +#define TEST_PILOT_OBJECT_PATH "object_path" +#define TEST_PILOT_BYTE_ARRAY "byte_array" +#define TEST_PILOT_INT16_ARRAY "int16_array" +#define TEST_PILOT_UINT16_ARRAY "uint16_array" +#define TEST_PILOT_INT32_ARRAY "int32_array" +#define TEST_PILOT_UINT32_ARRAY "uint32_array" +#define TEST_PILOT_INT64_ARRAY "int64_array" +#define TEST_PILOT_UINT64_ARRAY "uint64_array" +#define TEST_PILOT_DOUBLE_ARRAY "double_array" +#define TEST_PILOT_STRING_ARRAY "string_array" +#define TEST_PILOT_OBJECT_PATH_ARRAY "object_path_array" /* ------------------------------------------------------------------------ * DBus handlers @@ -49,6 +70,7 @@ struct com_planetexpress_Ship { int (*MoveUniverse)(struct sbus_request *req, void *data, bool arg_smoothly, uint32_t arg_speed_factor); int (*crash_now)(struct sbus_request *req, void *data, const char *arg_where); sbus_msg_handler_fn Land; + void (*com_planetexpress_Ship_get_Color)(struct sbus_request *, void *data, const char * *); }; /* finish function for MoveUniverse */ @@ -62,6 +84,28 @@ struct test_pilot { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*Blink)(struct sbus_request *req, void *data, uint32_t arg_duration); int (*Eject)(struct sbus_request *req, void *data, uint8_t arg_byte, bool arg_boolean, int16_t arg_int16, uint16_t arg_uint16, int32_t arg_int32, uint32_t arg_uint32, int64_t arg_int64, uint64_t arg_uint64, double arg_double, const char *arg_string, const char *arg_object_path, uint8_t arg_byte_array[], int len_byte_array, int16_t arg_int16_array[], int len_int16_array, uint16_t arg_uint16_array[], int len_uint16_array, int32_t arg_int32_array[], int len_int32_array, uint32_t arg_uint32_array[], int len_uint32_array, int64_t arg_int64_array[], int len_int64_array, uint64_t arg_uint64_array[], int len_uint64_array, double arg_double_array[], int len_double_array, const char *arg_string_array[], int len_string_array, const char *arg_object_path_array[], int len_object_path_array); + void (*test_pilot_get_FullName)(struct sbus_request *, void *data, const char * *); + void (*test_pilot_get_byte)(struct sbus_request *, void *data, uint8_t *); + void (*test_pilot_get_boolean)(struct sbus_request *, void *data, bool *); + void (*test_pilot_get_int16)(struct sbus_request *, void *data, int16_t *); + void (*test_pilot_get_uint16)(struct sbus_request *, void *data, uint16_t *); + void (*test_pilot_get_int32)(struct sbus_request *, void *data, int32_t *); + void (*test_pilot_get_uint32)(struct sbus_request *, void *data, uint32_t *); + void (*test_pilot_get_int64)(struct sbus_request *, void *data, int64_t *); + void (*test_pilot_get_uint64)(struct sbus_request *, void *data, uint64_t *); + void (*test_pilot_get_double)(struct sbus_request *, void *data, double *); + void (*test_pilot_get_string)(struct sbus_request *, void *data, const char * *); + void (*test_pilot_get_object_path)(struct sbus_request *, void *data, const char * *); + void (*test_pilot_get_byte_array)(struct sbus_request *, void *data, uint8_t * *, int *); + void (*test_pilot_get_int16_array)(struct sbus_request *, void *data, int16_t * *, int *); + void (*test_pilot_get_uint16_array)(struct sbus_request *, void *data, uint16_t * *, int *); + void (*test_pilot_get_int32_array)(struct sbus_request *, void *data, int32_t * *, int *); + void (*test_pilot_get_uint32_array)(struct sbus_request *, void *data, uint32_t * *, int *); + void (*test_pilot_get_int64_array)(struct sbus_request *, void *data, int64_t * *, int *); + void (*test_pilot_get_uint64_array)(struct sbus_request *, void *data, uint64_t * *, int *); + void (*test_pilot_get_double_array)(struct sbus_request *, void *data, double * *, int *); + void (*test_pilot_get_string_array)(struct sbus_request *, void *data, const char * * *, int *); + void (*test_pilot_get_object_path_array)(struct sbus_request *, void *data, const char * * *, int *); }; /* finish function for Blink */ -- 1.9.0