diff --git a/Makefile.am b/Makefile.am index da0ba7df..8d5c8aa0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = eina eo eet evas ecore eio +SUBDIRS = eina eo eet evas ecore eio edbus examples: @$(MAKE) $(AM_MAKEFLAGS) -C eina examples @@ -9,6 +9,7 @@ examples: @$(MAKE) $(AM_MAKEFLAGS) -C evas examples @$(MAKE) $(AM_MAKEFLAGS) -C ecore examples @$(MAKE) $(AM_MAKEFLAGS) -C eio examples + @$(MAKE) $(AM_MAKEFLAGS) -C edbus examples install-examples: @$(MAKE) $(AM_MAKEFLAGS) -C eina install-examples @@ -17,3 +18,4 @@ install-examples: @$(MAKE) $(AM_MAKEFLAGS) -C evas install-examples @$(MAKE) $(AM_MAKEFLAGS) -C ecore install-examples @$(MAKE) $(AM_MAKEFLAGS) -C eio install-examples + @$(MAKE) $(AM_MAKEFLAGS) -C edbus install-examples diff --git a/edbus/Makefile.am b/edbus/Makefile.am new file mode 100644 index 00000000..33e8e80a --- /dev/null +++ b/edbus/Makefile.am @@ -0,0 +1,71 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/edbus \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/edbus \ +@EDBUS_CFLAGS@ + +EXAMPLES_LIBS = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/eina/libeina.la \ +$(top_builddir)/src/lib/edbus/libedbus2.la + +EXTRA_PROGRAMS = \ +connman-list-services \ +ofono-dial \ +banshee \ +complex-types \ +complex-types-server \ +server \ +client \ +simple-signal-emit \ +complex-types-client-eina-value + +connman_list_services_SOURCES = connman-list-services.c +connman_list_services_LDADD = $(EXAMPLES_LIBS) + +ofono_dial_SOURCES = ofono-dial.c +ofono_dial_LDADD = $(EXAMPLES_LIBS) + +banshee_SOURCES = banshee.c +banshee_LDADD = $(EXAMPLES_LIBS) + +complex_types_SOURCES = complex-types.c +complex_types_LDADD = $(EXAMPLES_LIBS) + +complex_types_server_SOURCES = complex-types-server.c +complex_types_server_LDADD = $(EXAMPLES_LIBS) + +server_SOURCES = server.c +server_LDADD = $(EXAMPLES_LIBS) + +client_SOURCES = client.c +client_LDADD = $(EXAMPLES_LIBS) + +simple_signal_emit_SOURCES = simple-signal-emit.c +simple_signal_emit_LDADD = $(EXAMPLES_LIBS) + +complex_types_client_eina_value_SOURCES = complex-types-client-eina-value.c +complex_types_client_eina_value_LDADD = $(EXAMPLES_LIBS) + +SRCS = $(EXTRA_PROGRAMS) + +examples: $(EXTRA_PROGRAMS) + +clean-local: + rm -f $(EXTRA_PROGRAMS) + +install-examples: + mkdir -p $(datadir)/edbus/examples + $(install_sh_DATA) -c $(SRCS) $(datadir)/edbus/examples + +uninstall-local: + for f in $(SRCS) ; do \ + rm -f $(datadir)/edbus/examples/$$f ; \ + done diff --git a/edbus/banshee.c b/edbus/banshee.c new file mode 100644 index 00000000..59c6a9a4 --- /dev/null +++ b/edbus/banshee.c @@ -0,0 +1,239 @@ +#include "EDBus.h" +#include + +#define BUS "org.bansheeproject.Banshee" +#define ENGINE_PATH "/org/bansheeproject/Banshee/PlayerEngine" +#define CONTROLLER_PATH "/org/bansheeproject/Banshee/PlaybackController" +#define MPRIS_PATH "/org/mpris/MediaPlayer2" + +#define ENGINE_IFACE "org.bansheeproject.Banshee.PlayerEngine" +#define CONTROLLER_IFACE "org.bansheeproject.Banshee.PlaybackController" +#define MPRIS_IFACE "org.mpris.MediaPlayer2.Playlists" + +static EDBus_Signal_Handler *state_changed2; + +static Eina_Bool +_timeout_application(void *data) +{ + printf("\n## ecore_main_loop_quit()\n"); + ecore_main_loop_quit(); + return EINA_TRUE; +} + +static void +on_get_playlists(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + EDBus_Message_Iter *array, *struct_entry; + const char *path, *name, *image; + int i = 0; + + EINA_SAFETY_ON_TRUE_RETURN(edbus_message_error_get(msg, NULL, NULL)); + + if (!edbus_message_arguments_get(msg, "a(oss)", &array)) + { + fprintf(stderr, "Error: could not get entry contents\n"); + return; + } + printf("on_get_playlists() \n\n"); + while (edbus_message_iter_get_and_next(array, 'r', &struct_entry)) + { + if (!edbus_message_iter_arguments_get(struct_entry, "oss", &path, &name, &image)) + { + printf("error on edbus_massage_iterator_arguments_get()"); + return; + } + i++; + printf("%d - %s | %s | %s\n", i, path, name, image); + } + printf("end of on_get_playlists()\n\n"); +} + +static void +iterate_dict(void *data, const void *key, EDBus_Message_Iter *var) +{ + const char *skey = key; + + if (!strcmp(skey, "PlaylistCount")) + { + unsigned count; + if (!edbus_message_iter_arguments_get(var, "u", &count)) + printf("error2\n"); + printf("PlaylistCount=%d\n", count); + } + else if (!strcmp(skey, "Orderings")) + { + EDBus_Message_Iter *as; + const char *txt; + printf("- Orderings\n"); + if (!edbus_message_iter_arguments_get(var, "as", &as)) + printf("error1\n"); + while (edbus_message_iter_get_and_next(as, 's', &txt)) + printf("\t%s\n", txt); + } +} + +static void +playlist_get_all_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + EDBus_Message_Iter *array; + EINA_SAFETY_ON_TRUE_RETURN(edbus_message_error_get(msg, NULL, NULL)); + + if (edbus_message_arguments_get(msg, "a{sv}", &array)) + edbus_message_iter_dict_iterate(array, "sv", iterate_dict, NULL); +} + +static void +on_introspect(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *string; + + EINA_SAFETY_ON_TRUE_RETURN(edbus_message_error_get(msg, NULL, NULL)); + + if (!edbus_message_arguments_get(msg, "s", &string)) + { + fprintf(stderr, "Error: could not get entry contents\n"); + return; + } + + printf("on_introspect() data=\n%s\n\n", string); +} + +static void +on_next_or_pause(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *status = data; + + EINA_SAFETY_ON_TRUE_RETURN(edbus_message_error_get(msg, NULL, NULL)); + + printf("%s\n", status); +} + +static void +on_state_changed(void *data, const EDBus_Message *msg) +{ + const char *status; + EINA_SAFETY_ON_TRUE_RETURN(edbus_message_error_get(msg, NULL, NULL)); + + if (!edbus_message_arguments_get(msg, "s", &status)) + { + fprintf(stderr, "Error: could not get entry contents\n"); + return; + } + + printf("on_state_changed = %s\n", status); +} + +static void +on_state_changed2(void *data, const EDBus_Message *msg) +{ + const char *status; + EINA_SAFETY_ON_TRUE_RETURN(edbus_message_error_get(msg, NULL, NULL)); + + if (!edbus_message_arguments_get(msg, "s", &status)) + { + fprintf(stderr, "Error: could not get entry contents\n"); + return; + } + + printf("on_state_changed2 = %s\n", status); + edbus_signal_handler_unref(state_changed2); + state_changed2 = NULL; +} + +static void +on_banshee_startup(void *data, const EDBus_Message *msg) +{ + const char *bus, *older_id, *new_id; + + EINA_SAFETY_ON_TRUE_RETURN(edbus_message_error_get(msg, NULL, NULL)); + if (!edbus_message_arguments_get(msg, "sss", &bus, &older_id, &new_id)) + { + printf("Error getting arguments from NameOwnerChanged"); + return; + } + + printf("banshee started on id=%s\n", new_id); +} + +static void +on_name_owner_changed(void *data, const EDBus_Message *msg) +{ + const char *bus, *older_id, *new_id; + + EINA_SAFETY_ON_TRUE_RETURN(edbus_message_error_get(msg, NULL, NULL)); + if (!edbus_message_arguments_get(msg, "sss", &bus, &older_id, &new_id)) + { + printf("Error getting arguments from NameOwnerChanged"); + return; + } + + printf("bus = %s older=%s new=%s\n\n", bus, older_id, new_id); +} + +int +main(void) +{ + EDBus_Connection *conn; + EDBus_Object *engine_obj, *controller_obj, *mpris_obj; + EDBus_Proxy *engine, *controler, *playlists; + EDBus_Signal_Handler *sh; + + ecore_init(); + edbus_init(); + + conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION); + + engine_obj = edbus_object_get(conn, BUS, ENGINE_PATH); + controller_obj = edbus_object_get(conn, BUS, CONTROLLER_PATH); + mpris_obj = edbus_object_get(conn, BUS, MPRIS_PATH); + + engine = edbus_proxy_get(engine_obj, ENGINE_IFACE); + EINA_SAFETY_ON_NULL_GOTO(engine, end); + controler = edbus_proxy_get(controller_obj, CONTROLLER_IFACE); + EINA_SAFETY_ON_NULL_GOTO(controler, end); + playlists = edbus_proxy_get(mpris_obj, MPRIS_IFACE); + EINA_SAFETY_ON_NULL_GOTO(playlists, end); + + edbus_object_introspect(engine_obj, on_introspect, NULL); + + edbus_proxy_signal_handler_add(engine, "StateChanged", on_state_changed, NULL); + edbus_proxy_call(engine, "Pause", on_next_or_pause, "Pause", -1, ""); + + edbus_proxy_call(controler, "Next", on_next_or_pause, "Next", -1, "b", EINA_TRUE); + + edbus_proxy_property_get_all(playlists, playlist_get_all_cb, NULL); + edbus_proxy_call(playlists, "GetPlaylists", on_get_playlists, NULL, -1, + "uusb", (unsigned)0, (unsigned)30, "asc", EINA_FALSE); + + edbus_signal_handler_add(conn, BUS, ENGINE_PATH, ENGINE_IFACE, + "StateChanged", on_state_changed, NULL); + state_changed2 = edbus_signal_handler_add(conn, BUS, ENGINE_PATH, ENGINE_IFACE, + "StateChanged", on_state_changed2, NULL); + + sh = edbus_signal_handler_add(conn, EDBUS_FDO_BUS, EDBUS_FDO_PATH, + EDBUS_FDO_INTERFACE, "NameOwnerChanged", + on_name_owner_changed, NULL); + edbus_signal_handler_match_extra_set(sh, "arg0", BUS, NULL); + + sh = edbus_signal_handler_add(conn, EDBUS_FDO_BUS, EDBUS_FDO_PATH, + EDBUS_FDO_INTERFACE, "NameOwnerChanged", + on_banshee_startup, NULL); + edbus_signal_handler_match_extra_set(sh, "arg0", BUS, "arg1", "", NULL); + + ecore_timer_add(50, _timeout_application, NULL); + + ecore_main_loop_begin(); + +end: + /** + * It's not necessary unref all objecs, proxys and signal handlers + * When a parent have ref = 0, it will unref all your childrens + * before free it self. + **/ + edbus_connection_unref(conn); + + edbus_shutdown(); + ecore_shutdown(); + return 0; +} + diff --git a/edbus/client.c b/edbus/client.c new file mode 100644 index 00000000..02da5a2e --- /dev/null +++ b/edbus/client.c @@ -0,0 +1,331 @@ +#include "EDBus.h" +#include + +#define BUS "org.Enlightenment" +#define PATH "/org/enlightenment" +#define INTERFACE "org.enlightenment.Test" +#define NTESTS 8 + +static int _client_log_dom = -1; +#define ERR(...) EINA_LOG_DOM_ERR(_client_log_dom, __VA_ARGS__) + +static void +_on_alive(void *context, const EDBus_Message *msg) +{ + printf("Alive\n\n"); +} + +static void +_on_hello(void *context, const EDBus_Message *msg) +{ + const char *txt; + if (edbus_message_arguments_get(msg, "s", &txt)) + printf("%s\n", txt); +} + +#include + +static struct expected +{ + Eina_Bool b; + uint8_t y; + uint32_t u; + int32_t i; + int16_t n; + double d; + const char *s; +} expected = { + .b = EINA_TRUE, + .y = 0xAA, + .u = 0xFFFFFFFF, + .i = 0xFFFFFFFF, + .n = 0xFFFF, + .d = 3.1415926, + .s = "test", +}; + +static void +test(void) +{ + static int n = 0; + n++; + if (n >= NTESTS) + printf("Passed in all tests\n"); + else + printf("Passed in %d/%d tests\n", n, NTESTS); +} + +static void +_on_send_bool(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname, *errmsg; + Eina_Bool b; + + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + ERR("%s %s", errname, errmsg); + return; + } + + if (!edbus_message_arguments_get(msg, "b", &b)) + { + ERR("Could not get entry contents"); + return; + } + + if (b != expected.b) + { + ERR("Bool value doesn't match"); + return; + } + + test(); +} + +static void +_on_send_byte(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname, *errmsg; + uint8_t y; + + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + ERR("%s %s", errname, errmsg); + return; + } + + if (!edbus_message_arguments_get(msg, "y", &y)) + { + ERR("Could not get entry contents"); + return; + } + + if (y != expected.y) + { + ERR("Byte value doesn't match expected value"); + return; + } + + test(); +} + +static void +_on_send_uint32(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname, *errmsg; + unsigned int u; + + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + ERR("%s %s", errname, errmsg); + return; + } + + if (!edbus_message_arguments_get(msg, "u", &u)) + { + ERR("Could not get entry contents"); + return; + } + + if (u != expected.u) + { + ERR("Uint32 value doesn't match expected value"); + return; + } + + test(); +} + +static void +_on_send_int32(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname, *errmsg; + int32_t i; + + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + ERR("%s %s", errname, errmsg); + return; + } + + if (!edbus_message_arguments_get(msg, "i", &i)) + { + ERR("Could not get entry contents"); + return; + } + + if (i != expected.i) + { + ERR("Int32 value doesn't match expected value"); + return; + } + + test(); +} + +static void +_on_send_int16(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname, *errmsg; + int16_t n; + + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + ERR("%s %s", errname, errmsg); + return; + } + + if (!edbus_message_arguments_get(msg, "n", &n)) + { + ERR("Could not get entry contents"); + return; + } + + if (n != expected.n) + { + ERR("Int16 value doesn't match expected value"); + return; + } + + test(); +} + +static void +_on_send_double(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname, *errmsg; + double d; + + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + ERR("%s %s", errname, errmsg); + return; + } + + if (!edbus_message_arguments_get(msg, "d", &d)) + { + ERR("Could not get entry contents"); + return; + } + + if (d != expected.d) + { + ERR("Double value doesn't match expected value"); + return; + } + + test(); +} + +static void +_on_send_string(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname, *errmsg; + char *s; + + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + ERR("%s %s", errname, errmsg); + return; + } + + if (!edbus_message_arguments_get(msg, "s", &s)) + { + ERR("Could not get entry contents"); + return; + } + + if (strcmp(s, expected.s) != 0) + { + ERR("Uint32 value doesn't match expected value"); + return; + } + + test(); +} + +static void +_on_async_test(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname, *errmsg; + + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + ERR("%s %s", errname, errmsg); + return; + } + + test(); +} + +static void +on_name_owner_changed(void *data, const char *bus, const char *old_id, const char *new_id) +{ + printf("Bus=%s | old=%s | new=%s\n", bus, old_id, new_id); +} + +static Eina_Bool +finish(void *data) +{ + ecore_main_loop_quit(); + return ECORE_CALLBACK_CANCEL; +} + +int +main(void) +{ + EDBus_Connection *conn; + EDBus_Object *obj; + EDBus_Proxy *proxy; + + eina_init(); + _client_log_dom = eina_log_domain_register("client", EINA_COLOR_CYAN); + if (_client_log_dom < 0) + { + EINA_LOG_ERR("Unable to create 'client' log domain"); + goto exit_eina; + } + + ecore_init(); + edbus_init(); + + conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION); + + obj = edbus_object_get(conn, BUS, PATH); + proxy = edbus_proxy_get(obj, INTERFACE); + edbus_proxy_signal_handler_add(proxy, "Alive", _on_alive, NULL); + edbus_proxy_signal_handler_add(proxy, "Hello", _on_hello, NULL); + + edbus_proxy_call(proxy, "SendBool", _on_send_bool, NULL, -1, "b", + expected.b); + edbus_proxy_call(proxy, "SendByte", _on_send_byte, NULL, -1, "y", + expected.y); + edbus_proxy_call(proxy, "SendUint32", _on_send_uint32, NULL, -1, "u", + expected.u); + edbus_proxy_call(proxy, "SendInt32", _on_send_int32, NULL, -1, "i", + expected.i); + edbus_proxy_call(proxy, "SendInt16", _on_send_int16, NULL, -1, "n", + expected.n); + edbus_proxy_call(proxy, "SendDouble", _on_send_double, NULL, -1, "d", + expected.d); + edbus_proxy_call(proxy, "SendString", _on_send_string, NULL, -1, "s", + expected.s); + edbus_proxy_call(proxy, "AsyncTest", _on_async_test, NULL, -1, ""); + + edbus_name_owner_changed_callback_add(conn, BUS, on_name_owner_changed, + conn, EINA_TRUE); + ecore_timer_add(30, finish, NULL); + + ecore_main_loop_begin(); + + edbus_connection_unref(conn); + + edbus_shutdown(); + ecore_shutdown(); + + eina_log_domain_unregister(_client_log_dom); +exit_eina: + eina_shutdown(); + + return 0; +} diff --git a/edbus/complex-types-client-eina-value.c b/edbus/complex-types-client-eina-value.c new file mode 100644 index 00000000..5f7fa483 --- /dev/null +++ b/edbus/complex-types-client-eina-value.c @@ -0,0 +1,323 @@ +#include "EDBus.h" +#include + +#define BUS "com.profusion" +#define PATH "/com/profusion/Test" +#define IFACE "com.profusion.Test" + +#define size_of_array 5 +static const char *array_string[] = { + "aaaa", "bbbb", "cccc", "dddd", "eeee" +}; + +typedef struct _sub_struct +{ + char *txt; + int num; +} sub_struct; + +typedef struct _main_struct +{ + int size; + sub_struct array[]; +} main_struct; + +static unsigned int +_type_offset(unsigned base, unsigned size) +{ + unsigned padding; + if (!(base % size)) + return base; + padding = abs(base - size); + return base + padding; +} + +static void +_fill_receive_array_of_string_int_with_size(EDBus_Message *msg, int size, const char *array[]) +{ + Eina_Value *value_struct, *value_array; + int i; + unsigned offset; + Eina_Value_Struct_Member main_members[2]; + Eina_Value_Struct_Member sub_members[] = { + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_STRING, sub_struct, txt), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, sub_struct, num) + }; + Eina_Value_Struct_Desc desc_sub_struct = { + EINA_VALUE_STRUCT_DESC_VERSION, + NULL, // no special operations + sub_members, + 2, + sizeof(sub_struct) + }; + Eina_Value_Struct_Desc desc_struct = { + EINA_VALUE_STRUCT_DESC_VERSION, + NULL, // no special operations + main_members, + 2, + 0//will be set below + }; + + offset = _type_offset(sizeof(int), sizeof(Eina_Value_Array)); + main_members[0].name = "size"; + main_members[0].type = EINA_VALUE_TYPE_INT, 0; + main_members[0].offset = 0; + main_members[1].name = "array"; + main_members[1].type = EINA_VALUE_TYPE_ARRAY; + main_members[1].offset = offset; + desc_struct.size = offset + sizeof(Eina_Value_Array); + + value_struct = eina_value_struct_new(&desc_struct); + eina_value_struct_set(value_struct, "size", size); + + value_array = eina_value_array_new(EINA_VALUE_TYPE_STRUCT, size); + for (i = 0; i < size; i++) + { + Eina_Value *value_sub_struct = eina_value_struct_new(&desc_sub_struct); + Eina_Value_Struct st; + eina_value_struct_set(value_sub_struct, "txt", array[i]); + eina_value_struct_set(value_sub_struct, "num", i); + eina_value_get(value_sub_struct, &st); + eina_value_array_append(value_array, st); + eina_value_free(value_sub_struct); + } + eina_value_struct_value_set(value_struct, "array", value_array); + + edbus_message_from_eina_value("ia(si)", msg, value_struct); + + eina_value_free(value_struct); + eina_value_free(value_array); +} + +static void +on_send_array(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + Eina_Value *v, array; + const char *txt; + unsigned i; + printf("2 - on_send_array()\n"); + + if (edbus_message_error_get(msg, NULL, NULL)) + { + printf("Message error\n\n"); + return; + } + + v = edbus_message_to_eina_value(msg); + eina_value_struct_value_get(v, "arg0", &array); + for (i = 0; i < eina_value_array_count(&array); i++) + { + eina_value_array_get(&array, i, &txt); + printf("\t%s\n", txt); + } + + eina_value_free(v); + eina_value_flush(&array); +} + +static void +on_receive_array_with_size(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname; + const char *errmsg; + + printf("1 - on_receive_array_with_size()\n"); + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + fprintf(stderr, "Error: %s %s\n", errname, errmsg); + } +} + +static void +on_plus_one(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + Eina_Value *v; + int num2; + + if (edbus_message_error_get(msg, NULL, NULL)) + { + printf("Message error\n\n"); + return; + } + + v = edbus_message_to_eina_value(msg); + eina_value_struct_get(v, "arg0", &num2); + + printf("3 - on_plus_one() %d\n", num2); + eina_value_free(v); +} + +static void +receive_variant_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + Eina_Value *v, variant, array; + unsigned i; + + printf("4 - receive a variant with an array of strings\n"); + if (edbus_message_error_get(msg, NULL, NULL)) + { + printf("Message error\n\n"); + return; + } + + v = edbus_message_to_eina_value(msg); + + eina_value_struct_value_get(v, "arg0", &variant); + eina_value_struct_value_get(&variant, "arg0", &array); + for (i = 0; i < eina_value_array_count(&array); i++) + { + const char *txt; + eina_value_array_get(&array, i, &txt); + printf("\t%s\n", txt); + } + + eina_value_flush(&array); + eina_value_flush(&variant); + eina_value_free(v); +} + +static void +_property_removed(void *data, EDBus_Proxy *proxy, void *event_info) +{ + EDBus_Proxy_Event_Property_Removed *event = event_info; + + printf("\nproperty removed: %s", event->name); +} + +static void +_property_changed(void *data, EDBus_Proxy *proxy, void *event_info) +{ + EDBus_Proxy_Event_Property_Changed *event = event_info; + const char *name; + const Eina_Value *value; + printf("\nproperty changed\n"); + + name = event->name; + value = event->value; + + if (!strcmp(name, "text") || !strcmp(name, "Resp2")) + { + const char *txt; + eina_value_get(value, &txt); + printf("[%s] = %s\n", name, txt); + } + else if (!strcmp(name, "int32")) + { + int num; + eina_value_get(value, &num); + printf("[%s] = %d\n", name, num); + } + else if (!strcmp(name, "st")) + { + const char *txt; + eina_value_struct_get(value, "arg0", &txt); + printf("[%s] %s | ", name, txt); + eina_value_struct_get(value, "arg1", &txt); + printf("%s\n", txt); + } +} + +static Eina_Bool +_read_cache(void *data) +{ + EDBus_Proxy *proxy = data; + const char *txt; + int num; + Eina_Value *v; + + v = edbus_proxy_property_local_get(proxy, "text"); + if (v) + { + eina_value_get(v, &txt); + printf("Read cache: [txt] = %s\n", txt); + } + + v = edbus_proxy_property_local_get(proxy, "int32"); + if (v) + { + eina_value_get(v, &num); + printf("Read cache: [int32] = %d\n", num); + } + + v = edbus_proxy_property_local_get(proxy, "st"); + if (v) + { + eina_value_struct_get(v, "arg0", &txt); + printf("Read cache: [st] %s | ", txt); + eina_value_struct_get(v, "arg1", &txt); + printf("%s\n", txt); + } + + return EINA_FALSE; +} + +static void +_fill_plus_one(EDBus_Message *msg, int num) +{ + Eina_Value *v; + Eina_Value_Struct_Member main_members[] = { + {"num", EINA_VALUE_TYPE_INT, 0} + }; + Eina_Value_Struct_Desc desc_struct = { + EINA_VALUE_STRUCT_DESC_VERSION, + NULL, // no special operations + main_members, + 1, + sizeof(int) + }; + v = eina_value_struct_new(&desc_struct); + eina_value_struct_set(v, "num", num); + + edbus_message_from_eina_value("i", msg, v); + + eina_value_free(v); +} + +int +main(void) +{ + EDBus_Connection *conn; + EDBus_Object *obj; + EDBus_Proxy *proxy; + EDBus_Message *msg; + + ecore_init(); + edbus_init(); + + conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION); + obj = edbus_object_get(conn, BUS, PATH); + proxy = edbus_proxy_get(obj, IFACE); + + msg = edbus_proxy_method_call_new(proxy, "ReceiveArrayOfStringIntWithSize"); + _fill_receive_array_of_string_int_with_size(msg, size_of_array, array_string); + edbus_proxy_send(proxy, msg, on_receive_array_with_size, NULL, -1); + edbus_message_unref(msg); + + edbus_proxy_call(proxy, "SendArray", on_send_array, NULL, -1 , ""); + + msg = edbus_proxy_method_call_new(proxy, "PlusOne"); + _fill_plus_one(msg, 14); + edbus_proxy_send(proxy, msg, on_plus_one, NULL, -1); + edbus_message_unref(msg); + + edbus_proxy_event_callback_add(proxy, + EDBUS_PROXY_EVENT_PROPERTY_CHANGED, + _property_changed, NULL); + edbus_proxy_event_callback_add(proxy, EDBUS_PROXY_EVENT_PROPERTY_REMOVED, + _property_removed, NULL); + + edbus_proxy_properties_monitor(proxy, EINA_TRUE); + ecore_timer_add(10, _read_cache, proxy); + + edbus_proxy_call(proxy, "ReceiveVariantData", receive_variant_cb, NULL, -1, ""); + + ecore_main_loop_begin(); + + edbus_proxy_event_callback_del(proxy, EDBUS_PROXY_EVENT_PROPERTY_CHANGED, + _property_changed, NULL); + edbus_connection_unref(conn); + + edbus_shutdown(); + ecore_shutdown(); + return 0; +} diff --git a/edbus/complex-types-server.c b/edbus/complex-types-server.c new file mode 100644 index 00000000..5e874223 --- /dev/null +++ b/edbus/complex-types-server.c @@ -0,0 +1,390 @@ +#include "EDBus.h" +#include + +#define BUS "com.profusion" +#define PATH "/com/profusion/Test" +#define IFACE "com.profusion.Test" + +static char *resp2; +/* dummy, incremented each time DBus.Properties.Get() is called */ +static int int32 = 35; +static Ecore_Timer *timer; + +static EDBus_Message * +_receive_array(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + EDBus_Message_Iter *array; + const char *txt; + + printf("- receiveArray\n"); + if (!edbus_message_arguments_get(msg, "as", &array)) + { + printf("Error on edbus_message_arguments_get()\n"); + return reply; + } + + while (edbus_message_iter_get_and_next(array, 's', &txt)) + printf("%s\n", txt); + printf("}\n\n"); + + return reply; +} + +static EDBus_Message * +_receive_array_of_string_int_with_size(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + EDBus_Message_Iter *array, *struct_si; + int size, i = 0; + + printf("- receiveArrayOfStringIntWithSize\n{\n"); + if (!edbus_message_arguments_get(msg, "ia(si)", &size, &array)) + { + printf("Error on edbus_message_arguments_get()\n"); + return reply; + } + + while (edbus_message_iter_get_and_next(array, 'r', &struct_si)) + { + const char *txt; + int num; + if (!edbus_message_iter_arguments_get(struct_si, "si", &txt, &num)) + { + printf("Error on edbus_message_arguments_get()\n"); + return reply; + } + printf("%s | %d\n", txt, num); + i++; + } + printf("size in msg %d | size read %d\n", size, i); + printf("}\n\n"); + + return reply; +} + +static EDBus_Message * +_receive_variant(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + EDBus_Message_Iter *var, *array, *main_iter; + + main_iter = edbus_message_iter_get(reply); + var = edbus_message_iter_container_new(main_iter, 'v', "as"); + edbus_message_iter_arguments_append(var, "as", &array); + + edbus_message_iter_arguments_append(array, "s", "item1"); + edbus_message_iter_arguments_append(array, "s", "item2"); + edbus_message_iter_arguments_append(array, "s", "item3"); + + edbus_message_iter_container_close(var, array); + edbus_message_iter_container_close(main_iter, var); + + return reply; +} + +static EDBus_Message * +_send_variant(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + EDBus_Message_Iter *variant; + char *type; + + printf("- sendVariantData\n{\n"); + if (!edbus_message_arguments_get(msg, "v", &variant)) + { + printf("Error on edbus_message_arguments_get()\n"); + return reply; + } + + type = edbus_message_iter_signature_get(variant); + if (type[1]) + { + printf("It is a complex type, not handle yet.\n"); + free(type); + return reply; + } + + switch (type[0]) + { + case 's': + case 'o': + { + char *txt; + edbus_message_iter_arguments_get(variant, type, &txt); + printf("type = %c value = %s\n", type[0], txt); + break; + } + case 'i': + { + int num; + edbus_message_iter_arguments_get(variant, type, &num); + printf("type = %c value = %d\n", type[0], num); + break; + } + default: + { + printf("Unhandled type\n"); + } + } + + printf("}\n\n"); + + free(type); + return reply; +} + +static EDBus_Message * +_send_array_int(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + EDBus_Message_Iter *iter, *array; + int i; + + printf("- sendArrayInt\n\n"); + + iter = edbus_message_iter_get(reply); + array = edbus_message_iter_container_new(iter, 'a', "i"); + for (i = 0; i < 5; i++) + edbus_message_iter_arguments_append(array, "i", i); + edbus_message_iter_container_close(iter, array); + + return reply; +} + +static EDBus_Message * +_send_array(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + EDBus_Message_Iter *iter, *array; + const char *array_string[5] = {"qqqq", "wwwww", "eeeeee", "rrrrr", "ttttt"}; + int i; + + printf("sendArray\n\n"); + + iter = edbus_message_iter_get(reply); + array = edbus_message_iter_container_new(iter, 'a', "s"); + for (i = 0; i < 5; i++) + edbus_message_iter_arguments_append(array, "s", array_string[i]); + edbus_message_iter_container_close(iter, array); + + return reply; +} + +static EDBus_Message * +_plus_one(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + int num; + + printf("- plusOne\n\n"); + if (!edbus_message_arguments_get(msg, "i", &num)) + { + printf("Error on edbus_message_arguments_get()\n"); + return reply; + } + num++; + edbus_message_arguments_append(reply, "i", num); + + return reply; +} + +static EDBus_Message * +_double_container(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message_Iter *array1, *array2, *structure; + int num1, num2; + EDBus_Message *reply = edbus_message_method_return_new(msg); + + if (!edbus_message_arguments_get(msg, "a(ii)a(ii)", &array1, &array2)) + { + printf("Error on edbus_message_arguments_get()\n"); + return NULL; + } + + printf("DoubleCountainer\n{\nArray1:\n"); + while (edbus_message_iter_get_and_next(array1, 'r', &structure)) + { + edbus_message_iter_arguments_get(structure, "ii", &num1, &num2); + printf("1 %d - 2 %d\n", num1, num2); + } + + printf("Array2:\n"); + while (edbus_message_iter_get_and_next(array2, 'r', &structure)) + { + edbus_message_iter_arguments_get(structure, "ii", &num1, &num2); + printf("1 %d - 2 %d\n", num1, num2); + } + printf("}\n\n"); + return reply; +} + +static Eina_Bool +_properties_get(const EDBus_Service_Interface *iface, const char *propname, EDBus_Message_Iter *iter, const EDBus_Message *request_msg, EDBus_Message **error) +{ + printf("Properties_get - %s\n", propname); + if (!strcmp(propname, "Resp2")) + edbus_message_iter_basic_append(iter, 's', resp2); + else if (!strcmp(propname, "text")) + edbus_message_iter_basic_append(iter, 's', "lalalala"); + else if (!strcmp(propname, "int32")) + { + edbus_message_iter_arguments_append(iter, "i", int32); + int32++; + } + else if (!strcmp(propname, "st")) + { + EDBus_Message_Iter *st; + edbus_message_iter_arguments_append(iter, "(ss)", &st); + edbus_message_iter_arguments_append(st, "ss", "string1", "string2"); + edbus_message_iter_container_close(iter, st); + } + return EINA_TRUE; +} + +static EDBus_Message * +_properties_set(const EDBus_Service_Interface *iface, const char *propname, EDBus_Message_Iter *iter, const EDBus_Message *msg) +{ + char *type; + + type = edbus_message_iter_signature_get(iter); + + if (!strcmp(propname, "int32")) + { + int num; + if (type[0] != 'i') + goto invalid_signature; + edbus_message_iter_arguments_get(iter, "i", &num); + printf("int32 was set to: %d, previously was: %d\n", num, int32); + int32 = num; + } + else if (!strcmp(propname, "Resp2")) + { + const char *txt; + if (type[0] != 's') + goto invalid_signature; + edbus_message_iter_arguments_get(iter, "s", &txt); + printf("Resp2 was set to: %s, previously was: %s\n", txt, resp2); + free(resp2); + resp2 = strdup(txt); + } + free(type); + return edbus_message_method_return_new(msg); + +invalid_signature: + free(type); + return edbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidSignature", + "Invalid type."); +} + +static const EDBus_Method methods[] = { + { + "ReceiveArray", EDBUS_ARGS({"as", "array_of_strings"}), + NULL, _receive_array + }, + { + "ReceiveArrayOfStringIntWithSize", + EDBUS_ARGS({"i", "size_of_array"}, {"a(si)", "array"}), + NULL, _receive_array_of_string_int_with_size, 0 + }, + { + "SendVariantData", EDBUS_ARGS({"v", "variant_data"}), + NULL, _send_variant + }, + { + "ReceiveVariantData", NULL, EDBUS_ARGS({"v", "variant_data"}), + _receive_variant + }, + { + "SendArrayInt", NULL, + EDBUS_ARGS({"ai", "array_of_int"}), _send_array_int, 0 + }, + { + "SendArray", NULL, EDBUS_ARGS({"as", "array_string"}), + _send_array + }, + { + "PlusOne", EDBUS_ARGS({"i", "integer"}), + EDBUS_ARGS({"i", "integer_plus_one"}), _plus_one + }, + { + "DoubleContainner", EDBUS_ARGS({"a(ii)", "array1"}, {"a(ii)", "array2"}), + NULL, _double_container + }, + { } +}; + +static const EDBus_Property properties[] = { + { "Resp2", "s", NULL, _properties_set }, + { "text", "s" }, + { "int32", "i", NULL, _properties_set }, + { "st", "(ss)" }, + { } +}; + +static const EDBus_Service_Interface_Desc iface_desc = { + IFACE, methods, NULL, properties, _properties_get +}; + +static Eina_Bool _emit_changed(void *data) +{ + EDBus_Service_Interface *iface = data; + edbus_service_property_changed(iface, "int32"); + edbus_service_property_invalidate_set(iface, "Resp2", EINA_TRUE); + return ECORE_CALLBACK_RENEW; +} + +static void +on_name_request(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + unsigned int reply; + EDBus_Service_Interface *iface = data; + + if (edbus_message_error_get(msg, NULL, NULL)) + { + printf("error on on_name_request\n"); + return; + } + + if (!edbus_message_arguments_get(msg, "u", &reply)) + { + printf("error geting arguments on on_name_request\n"); + return; + } + + if (reply != EDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER) + { + printf("error name already in use\n"); + return; + } + + timer = ecore_timer_add(3, _emit_changed, iface); +} + +int +main(void) +{ + EDBus_Connection *conn; + EDBus_Service_Interface *iface; + + ecore_init(); + edbus_init(); + + conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION); + + resp2 = malloc(sizeof(char) * 5); + strcpy(resp2, "test"); + iface = edbus_service_interface_register(conn, PATH, &iface_desc); + edbus_name_request(conn, BUS, EDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, + on_name_request, iface); + + ecore_main_loop_begin(); + + free(resp2); + ecore_timer_del(timer); + edbus_connection_unref(conn); + + edbus_shutdown(); + ecore_shutdown(); + return 0; +} diff --git a/edbus/complex-types.c b/edbus/complex-types.c new file mode 100644 index 00000000..a0af846f --- /dev/null +++ b/edbus/complex-types.c @@ -0,0 +1,285 @@ +#include "EDBus.h" +#include + +#define BUS "com.profusion" +#define PATH "/com/profusion/Test" +#define IFACE "com.profusion.Test" + +EDBus_Connection *conn; + +static Eina_Bool +_timer1_cb(void *data) +{ + printf("\nFishing...\n"); + ecore_main_loop_quit(); + return ECORE_CALLBACK_CANCEL; +} + +static void +on_plus_one(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + int num2 = 0; + + if (edbus_message_error_get(msg, NULL, NULL)) + { + printf("Message error\n\n"); + return; + } + if (!edbus_message_arguments_get(msg, "i", &num2)) + { + printf("Error getting arguments."); + return; + } + + printf("on_plus_one() %d\n", num2); +} + +static void +set_property_resp2(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname; + const char *errmsg; + + printf("set_property_resp2()\n"); + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + printf("Message error %s - %s\n\n", errname, errmsg); + return; + } +} + +static void +get_property_resp2(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + EDBus_Proxy *proxy = data; + EDBus_Message_Iter *variant = NULL; + char *type; + char *resp2; + const char *errname; + const char *errmsg; + + printf("get_property_resp2()\n"); + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + printf("Message error %s - %s\n\n", errname, errmsg); + return; + } + if (!edbus_message_arguments_get(msg, "v", &variant)) + { + printf("Error getting arguments."); + return; + } + + type = edbus_message_iter_signature_get(variant); + if (type[1]) + { + printf("It is a complex type, not handle yet.\n\n"); + return; + } + if (type[0] != 's') + { + printf("Expected type is string.\n\n"); + return; + } + if (!edbus_message_iter_arguments_get(variant, "s", &resp2)) + { + printf("error in edbus_message_iter_arguments_get()\n\n"); + return; + } + printf("resp2=%s\n", resp2); + free(type); + + edbus_proxy_property_set(proxy, "Resp2", "s", &"lalala", set_property_resp2, NULL); + edbus_proxy_property_set(proxy, "int32", "i", (void*)(intptr_t)99, set_property_resp2, NULL); +} + +static void +on_send_array_int(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + EDBus_Message_Iter *array = NULL; + int num; + + printf("on_send_array_int()\n"); + if (edbus_message_error_get(msg, NULL, NULL)) + { + printf("Message error\n\n"); + return; + } + if (!edbus_message_arguments_get(msg, "ai", &array)) + { + printf("Error getting arguments."); + return; + } + + while (edbus_message_iter_get_and_next(array, 'i', &num)) + { + printf("%d\n", num); + } +} + +static void +on_send_array(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + EDBus_Message_Iter *array = NULL; + char *txt = NULL; + char *string[10]; + int i = 0; + int z; + + printf("on_send_array()\n"); + if (edbus_message_error_get(msg, NULL, NULL)) + { + printf("Message error\n\n"); + return; + } + if (!edbus_message_arguments_get(msg, "as", &array)) + { + printf("Error getting arguments."); + return; + } + + while (edbus_message_iter_get_and_next(array, 's', &txt)) + { + string[i] = txt; + i++; + } + + for (z = 0; z < i; z++) + printf("string = %s\n", string[z]); +} + +static void +on_receive_array_with_size(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname; + const char *errmsg; + + printf("on_receive_array_with_size()\n"); + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + fprintf(stderr, "Error: %s %s\n", errname, errmsg); + } +} + +static void +on_send_variant(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + printf("on_send_variant()\n\n"); +} + +static void +on_receive_array(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname; + const char *errmsg; + + printf("on_receive_array()\n"); + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + fprintf(stderr, "Error: %s %s\n", errname, errmsg); + } +} + +int +main(void) +{ + EDBus_Object *test2_obj; + EDBus_Proxy *test2_proxy; + EDBus_Pending *pending; + EDBus_Message_Iter *iter, *array_of_string, *variant; + EDBus_Message_Iter *array_itr, *structure; + EDBus_Message *msg; + int size_of_array = 5; + const char *array[5] = { "aaaa", "bbbb", "cccc", "dddd", "eeee" }; + int i; + int plus_one = 24; + + ecore_init(); + edbus_init(); + + conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION); + + test2_obj = edbus_object_get(conn, BUS, PATH); + test2_proxy = edbus_proxy_get(test2_obj, IFACE); + + msg = edbus_proxy_method_call_new(test2_proxy, "ReceiveArray"); + iter = edbus_message_iter_get(msg); + array_of_string = edbus_message_iter_container_new(iter, 'a',"s"); + if (!array_of_string) printf("array_of_string == NULL\n\n"); + for (i = 0; i < 5; i++) + edbus_message_iter_basic_append(array_of_string, 's', array[i]); + edbus_message_iter_container_close(iter, array_of_string); + pending = edbus_proxy_send(test2_proxy, msg, on_receive_array, NULL, -1); + if (!pending) printf("Error in edbus_proxy_send()\n\n"); + edbus_message_unref(msg); + + msg = edbus_proxy_method_call_new(test2_proxy, "ReceiveArrayOfStringIntWithSize"); + iter = edbus_message_iter_get(msg); + if (!edbus_message_iter_arguments_append(iter, "ia(si)", size_of_array, &array_of_string)) + printf("error on edbus_massage_iterator_arguments_set()\n\n"); + for (i = 0; i < size_of_array; i++) + { + EDBus_Message_Iter *struct_of_si; + edbus_message_iter_arguments_append(array_of_string, "(si)", &struct_of_si); + edbus_message_iter_arguments_append(struct_of_si, "si", array[i], i); + edbus_message_iter_container_close(array_of_string, struct_of_si); + } + edbus_message_iter_container_close(iter, array_of_string); + pending = edbus_proxy_send(test2_proxy, msg, on_receive_array_with_size, NULL, -1); + edbus_message_unref(msg); + + msg = edbus_proxy_method_call_new(test2_proxy, "SendVariantData"); + iter = edbus_message_iter_get(msg); + variant = edbus_message_iter_container_new(iter, 'v', "s"); + edbus_message_iter_basic_append(variant, 's', "test"); + edbus_message_iter_container_close(iter, variant); + pending = edbus_proxy_send(test2_proxy, msg, on_send_variant, NULL, -1); + edbus_message_unref(msg); + + msg = edbus_proxy_method_call_new(test2_proxy, "DoubleContainner"); + iter = edbus_message_iter_get(msg); + /** + * edbus_message_iterator_arguments_set(itr, "a(ii)a(ii)", &array_itr, &array_itr2); + * this will cause a error, we could not open another container until + * we close the first one + */ + edbus_message_iter_arguments_append(iter, "a(ii)", &array_itr); + for (i = 0; i < 5; i++) + { + edbus_message_iter_arguments_append(array_itr, "(ii)", &structure); + edbus_message_iter_arguments_append(structure, "ii", i, i*i); + edbus_message_iter_container_close(array_itr, structure); + } + edbus_message_iter_container_close(iter, array_itr); + edbus_message_iter_arguments_append(iter, "a(ii)", &array_itr); + for (i = 0; i < 7; i++) + { + edbus_message_iter_arguments_append(array_itr, "(ii)", &structure); + edbus_message_iter_arguments_append(structure, "ii", i, i*i*i); + edbus_message_iter_container_close(array_itr, structure); + } + edbus_message_iter_container_close(iter, array_itr); + edbus_proxy_send(test2_proxy, msg, NULL, NULL, -1); + edbus_message_unref(msg); + + pending = edbus_proxy_call(test2_proxy, "SendArrayInt", on_send_array_int, NULL, + -1 , ""); + + pending = edbus_proxy_call(test2_proxy, "SendArray", on_send_array, NULL, + -1 , ""); + + pending = edbus_proxy_call(test2_proxy, "PlusOne", on_plus_one, NULL, + -1 , "i", plus_one); + + pending = edbus_proxy_property_get(test2_proxy, "Resp2", get_property_resp2, test2_proxy); + + ecore_timer_add(10, _timer1_cb, NULL); + + ecore_main_loop_begin(); + + edbus_connection_unref(conn); + + edbus_shutdown(); + ecore_shutdown(); + return 0; +} diff --git a/edbus/connman-list-services.c b/edbus/connman-list-services.c new file mode 100644 index 00000000..a192d8b5 --- /dev/null +++ b/edbus/connman-list-services.c @@ -0,0 +1,107 @@ +#include "EDBus.h" +#include + +static void +on_services_get(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + EDBus_Message_Iter *array, *entry; + const char *errname, *errmsg; + + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + fprintf(stderr, "Error: %s %s\n", errname, errmsg); + return; + } + + if (!edbus_message_arguments_get(msg, "a(oa{sv})", &array)) + { + fprintf(stderr, "Error: could not get array\n"); + return; + } + + while (edbus_message_iter_get_and_next(array, 'r', &entry)) + { + EDBus_Message_Iter *properties, *dict_entry; + const char *path; + + if (!edbus_message_iter_arguments_get(entry, "oa{sv}", &path, &properties)) + { + fprintf(stderr, "Error: could not get entry contents\n"); + return; + } + + printf("service: %s\n", path); + + while (edbus_message_iter_get_and_next(properties, 'e', &dict_entry)) + { + EDBus_Message_Iter *variant; + const char *key; + + if (!edbus_message_iter_arguments_get(dict_entry, "sv", &key, + &variant)) + { + fprintf(stderr, + "Error: could not get property contents\n"); + return; + } + + printf("\t%s: type %s\n", key, + edbus_message_iter_signature_get(variant)); + + /* TODO: get the value from variant */ + } + } +} + +int +main(void) +{ + EDBus_Connection *conn; + EDBus_Object *obj; + EDBus_Proxy *manager; + EDBus_Pending *pending; + + ecore_init(); + edbus_init(); + + conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SYSTEM); + if (!conn) + { + fprintf(stderr, "Error: could not get system bus\n"); + return EXIT_FAILURE; + } + + obj = edbus_object_get(conn, "net.connman", "/"); + if (!obj) + { + fprintf(stderr, "Error: could not get object\n"); + return EXIT_FAILURE; + } + + manager = edbus_proxy_get(obj, "net.connman.Manager"); + if (!manager) + { + fprintf(stderr, "Error: could not get proxy\n"); + return EXIT_FAILURE; + } + + pending = edbus_proxy_call(manager, "GetServices", on_services_get, NULL, + -1, ""); + + if (!pending) + { + fprintf(stderr, "Error: could not call\n"); + return EXIT_FAILURE; + } + + ecore_main_loop_begin(); + + edbus_proxy_unref(manager); + edbus_object_unref(obj); + edbus_connection_unref(conn); + + edbus_shutdown(); + ecore_shutdown(); + return 0; +} + diff --git a/edbus/ofono-dial.c b/edbus/ofono-dial.c new file mode 100644 index 00000000..5e833ddc --- /dev/null +++ b/edbus/ofono-dial.c @@ -0,0 +1,85 @@ +#include "EDBus.h" +#include + +static void +on_dial(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + const char *errname, *errmsg; + const char *call_path; + + if (edbus_message_error_get(msg, &errname, &errmsg)) + { + fprintf(stderr, "Error: %s %s\n", errname, errmsg); + return; + } + + if (!edbus_message_arguments_get(msg, "o", &call_path)) + { + fprintf(stderr, "Error: could not get call path\n"); + return; + } + + printf("dialed! call path: %s\n", call_path); +} + +int +main(int argc, char *argv[]) +{ + EDBus_Connection *conn; + EDBus_Object *obj; + EDBus_Proxy *manager; + EDBus_Pending *pending; + const char *number, *hide_callerid; + + if (argc < 2) + { + fprintf(stderr, "Usage:\n\t%s [hide_callerid]\n", argv[0]); + return EXIT_FAILURE; + } + + number = argv[1]; + hide_callerid = (argc > 2) ? argv[2] : ""; + + ecore_init(); + edbus_init(); + + conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SYSTEM); + if (!conn) + { + fprintf(stderr, "Error: could not get system bus\n"); + return EXIT_FAILURE; + } + + obj = edbus_object_get(conn, "org.ofono", "/"); + if (!obj) + { + fprintf(stderr, "Error: could not get object\n"); + return EXIT_FAILURE; + } + + manager = edbus_proxy_get(obj, "org.ofono.Manager"); + if (!manager) + { + fprintf(stderr, "Error: could not get proxy\n"); + return EXIT_FAILURE; + } + + pending = edbus_proxy_call(manager, "Dial", on_dial, NULL, + -1, "ss", number, hide_callerid); + if (!pending) + { + fprintf(stderr, "Error: could not call\n"); + return EXIT_FAILURE; + } + + ecore_main_loop_begin(); + + edbus_proxy_unref(manager); + edbus_object_unref(obj); + edbus_connection_unref(conn); + + edbus_shutdown(); + ecore_shutdown(); + return 0; +} + diff --git a/edbus/server.c b/edbus/server.c new file mode 100644 index 00000000..4953dde9 --- /dev/null +++ b/edbus/server.c @@ -0,0 +1,245 @@ +#include "EDBus.h" +#include + +#define BUS "org.Enlightenment" +#define PATH "/org/enlightenment" +#define PATH_TEST_SON "/org/enlightenment/son" +#define INTERFACE "org.enlightenment.Test" + +static EDBus_Connection *conn; + +static EDBus_Message * +_hello(const EDBus_Service_Interface *iface, const EDBus_Message *message) +{ + EDBus_Message *reply = edbus_message_method_return_new(message); + edbus_message_arguments_append(reply, "s", "Hello World"); + printf("Hello\n"); + return reply; +} + +static EDBus_Message * +_quit(const EDBus_Service_Interface *iface, const EDBus_Message *message) +{ + printf("Quit\n"); + ecore_main_loop_quit(); + return edbus_message_method_return_new(message); +} + +enum +{ + TEST_SIGNAL_ALIVE = 0, + TEST_SIGNAL_HELLO +}; + +static Eina_Bool +send_signal_alive(void *data) +{ + EDBus_Service_Interface *iface = data; + edbus_service_signal_emit(iface, TEST_SIGNAL_ALIVE); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +send_signal_hello(void *data) +{ + EDBus_Service_Interface *iface = data; + edbus_service_signal_emit(iface, TEST_SIGNAL_HELLO, "Hello World"); + return ECORE_CALLBACK_RENEW; +} + +static EDBus_Message * +_send_bool(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + Eina_Bool bool; + if (!edbus_message_arguments_get(msg, "b", &bool)) + printf("edbus_message_arguments_get() error\n"); + edbus_message_arguments_append(reply, "b", bool); + return reply; +} + +static EDBus_Message * +_send_byte(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + unsigned char byte; + if (!edbus_message_arguments_get(msg, "y", &byte)) + printf("edbus_message_arguments_get() error\n"); + edbus_message_arguments_append(reply, "y", byte); + return reply; +} + +static EDBus_Message * +_send_uint32(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + unsigned int uint32; + if (!edbus_message_arguments_get(msg, "u", &uint32)) + printf("edbus_message_arguments_get() error\n"); + edbus_message_arguments_append(reply, "u", uint32); + return reply; +} + +static EDBus_Message * +_send_int32(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + int int32; + if (!edbus_message_arguments_get(msg, "i", &int32)) + printf("edbus_message_arguments_get() error\n"); + edbus_message_arguments_append(reply, "i", int32); + return reply; +} + +static EDBus_Message * +_send_int16(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + short int int16; + if (!edbus_message_arguments_get(msg, "n", &int16)) + printf("edbus_message_arguments_get() error\n"); + edbus_message_arguments_append(reply, "n", int16); + return reply; +} + +static EDBus_Message * +_send_double(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + double d; + if (!edbus_message_arguments_get(msg, "d", &d)) + printf("edbus_message_arguments_get() error\n"); + edbus_message_arguments_append(reply, "d", d); + return reply; +} + +static EDBus_Message * +_send_string(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + const char *txt; + if (!edbus_message_arguments_get(msg, "s", &txt)) + printf("edbus_message_arguments_get() error\n"); + edbus_message_arguments_append(reply, "s", txt); + return reply; +} + +static Eina_Bool +_resp_async(void *data) +{ + EDBus_Message *msg = data; + edbus_message_arguments_append(msg, "s", "Async test ok"); + edbus_connection_send(conn, msg, NULL, NULL, -1); + edbus_message_unref(msg); + return ECORE_CALLBACK_CANCEL; +} + +static EDBus_Message * +_async_test(const EDBus_Service_Interface *iface, const EDBus_Message *msg) +{ + EDBus_Message *reply = edbus_message_method_return_new(msg); + printf("Received a call to AsyncTest.\n"); + printf("Response will be send in 5 seconds.\n"); + ecore_timer_add(5, _resp_async, reply); + return NULL; +} + +static const EDBus_Signal signals[] = { + [TEST_SIGNAL_ALIVE] = {"Alive", NULL, 0}, + [TEST_SIGNAL_HELLO] = {"Hello", EDBUS_ARGS({ "s", "message" }), 0}, + { } +}; + +static const EDBus_Method methods[] = { + { + "Hello", NULL, EDBUS_ARGS({"s", "message"}), + _hello + }, + { + "Quit", NULL, NULL, + _quit, EDBUS_METHOD_FLAG_DEPRECATED + }, + { "SendBool", EDBUS_ARGS({"b", "bool"}), EDBUS_ARGS({"b", "bool"}), + _send_bool + }, + { "SendByte", EDBUS_ARGS({"y", "byte"}), EDBUS_ARGS({"y", "byte"}), + _send_byte + }, + { "SendUint32", EDBUS_ARGS({"u", "uint32"}), EDBUS_ARGS({"u", "uint32"}), + _send_uint32 + }, + { "SendInt32", EDBUS_ARGS({"i", "int32"}), EDBUS_ARGS({"i", "int32"}), + _send_int32 + }, + { "SendInt16", EDBUS_ARGS({"n", "int16"}), EDBUS_ARGS({"n", "int16"}), + _send_int16 + }, + { "SendDouble", EDBUS_ARGS({"d", "double"}), EDBUS_ARGS({"d", "double"}), + _send_double + }, + { "SendString", EDBUS_ARGS({"s", "string"}), EDBUS_ARGS({"s", "string"}), + _send_string + }, + { "AsyncTest", NULL, EDBUS_ARGS({"s", "text"}), + _async_test + }, + { } +}; + +static const EDBus_Service_Interface_Desc iface_desc = { + INTERFACE, methods, signals +}; + +static void +on_name_request(void *data, const EDBus_Message *msg, EDBus_Pending *pending) +{ + EDBus_Service_Interface *iface; + unsigned int reply; + + iface = data; + if (edbus_message_error_get(msg, NULL, NULL)) + { + printf("error on on_name_request\n"); + return; + } + + if (!edbus_message_arguments_get(msg, "u", &reply)) + { + printf("error geting arguments on on_name_request\n"); + return; + } + + if (reply != EDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER) + { + printf("error name already in use\n"); + return; + } + + ecore_timer_add(5, send_signal_alive, iface); + ecore_timer_add(6, send_signal_hello, iface); +} + +int +main(void) +{ + EDBus_Service_Interface *iface; + + ecore_init(); + edbus_init(); + + conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION); + + iface = edbus_service_interface_register(conn, PATH, &iface_desc); + edbus_name_request(conn, BUS, EDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, + on_name_request, iface); + + edbus_service_interface_register(conn, PATH_TEST_SON, &iface_desc); + + ecore_main_loop_begin(); + + edbus_connection_unref(conn); + + edbus_shutdown(); + ecore_shutdown(); + return 0; +} diff --git a/edbus/simple-signal-emit.c b/edbus/simple-signal-emit.c new file mode 100644 index 00000000..960bfe63 --- /dev/null +++ b/edbus/simple-signal-emit.c @@ -0,0 +1,83 @@ +#include + +enum { + TEST_SIGNAL_ALIVE, + TEST_SIGNAL_PROP, + TEST_SIGNAL_NAME, +}; + +static const EDBus_Signal test_signals[] = { + [TEST_SIGNAL_ALIVE] = { "Alive" }, + [TEST_SIGNAL_PROP] = { "Properties", EDBUS_ARGS({ "a{ss}", "properties"}) }, + [TEST_SIGNAL_NAME] = { "Name", EDBUS_ARGS({ "s", "name"}) }, + { } +}; + +/* signal with complex arguments (a dict) */ +static void emit_properties(EDBus_Service_Interface *iface) +{ + EDBus_Message *alive2; + EDBus_Message_Iter *iter, *dict; + struct keyval { + const char *key; + const char *val; + } keyval[] = { + { "key1", "val1" }, + { "key2", "val2" }, + { } + }; + struct keyval *k; + + alive2 = edbus_service_signal_new(iface, TEST_SIGNAL_PROP); + iter = edbus_message_iter_get(alive2); + dict = edbus_message_iter_container_new(iter, 'a', "{ss}"); + + for (k = keyval; k && k->key; k++) + { + EDBus_Message_Iter *entry = edbus_message_iter_container_new(dict, 'e', + NULL); + edbus_message_iter_arguments_append(entry, "ss", k->key, k->val); + edbus_message_iter_container_close(dict, entry); + } + + edbus_message_iter_container_close(iter, dict); + edbus_service_signal_send(iface, alive2); +} + +/* signal with basic args */ +static void emit_name(EDBus_Service_Interface *iface) +{ + edbus_service_signal_emit(iface, TEST_SIGNAL_NAME, "TEST"); +} + +/* simple signal example */ +static void emit_alive(EDBus_Service_Interface *iface) +{ + edbus_service_signal_emit(iface, TEST_SIGNAL_ALIVE); +} + +static const EDBus_Service_Interface_Desc iface_desc = { + "org.enlightenment.Test", NULL, test_signals +}; + +int main(void) +{ + EDBus_Connection *conn; + EDBus_Service_Interface *iface; + + edbus_init(); + + conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION); + iface = edbus_service_interface_register(conn, "/org/enlightenment", + &iface_desc); + + emit_alive(iface); + emit_name(iface); + emit_properties(iface); + + edbus_connection_unref(conn); + + edbus_shutdown(); + + return 0; +}