complex-types-server.c

Server to test complex types (arrays, structs, dicts).

//Compile with:
// gcc -o complex-types-server complex-types-server.c `pkg-config --cflags --libs eldbus ecore`
#include "Eldbus.h"
#include <Ecore.h>
#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 Eldbus_Message *
_receive_array(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
Eldbus_Message_Iter *array;
const char *txt;
printf("- receiveArray\n");
if (!eldbus_message_arguments_get(msg, "as", &array))
{
printf("Error on eldbus_message_arguments_get()\n");
return reply;
}
while (eldbus_message_iter_get_and_next(array, 's', &txt))
printf("%s\n", txt);
printf("}\n\n");
return reply;
}
static Eldbus_Message *
_receive_array_of_string_int_with_size(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
Eldbus_Message_Iter *array, *struct_si;
int size, i = 0;
printf("- receiveArrayOfStringIntWithSize\n{\n");
if (!eldbus_message_arguments_get(msg, "ia(si)", &size, &array))
{
printf("Error on eldbus_message_arguments_get()\n");
return reply;
}
while (eldbus_message_iter_get_and_next(array, 'r', &struct_si))
{
const char *txt;
int num;
if (!eldbus_message_iter_arguments_get(struct_si, "si", &txt, &num))
{
printf("Error on eldbus_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 Eldbus_Message *
_receive_variant(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
Eldbus_Message_Iter *var, *array, *main_iter;
main_iter = eldbus_message_iter_get(reply);
var = eldbus_message_iter_container_new(main_iter, 'v', "as");
eldbus_message_iter_arguments_append(var, "as", &array);
eldbus_message_iter_arguments_append(array, "s", "item1");
eldbus_message_iter_arguments_append(array, "s", "item2");
eldbus_message_iter_arguments_append(array, "s", "item3");
eldbus_message_iter_container_close(var, array);
eldbus_message_iter_container_close(main_iter, var);
return reply;
}
static Eldbus_Message *
_send_variant(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
Eldbus_Message_Iter *variant;
char *type;
printf("- sendVariantData\n{\n");
if (!eldbus_message_arguments_get(msg, "v", &variant))
{
printf("Error on eldbus_message_arguments_get()\n");
return reply;
}
type = eldbus_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;
eldbus_message_iter_arguments_get(variant, type, &txt);
printf("type = %c value = %s\n", type[0], txt);
break;
}
case 'i':
{
int num;
eldbus_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 Eldbus_Message *
_send_array_int(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
Eldbus_Message_Iter *iter, *array;
int numbers[] = { 10, 9, 8, 7, 6, 5 };
printf("- sendArrayInt\n\n");
iter = eldbus_message_iter_get(reply);
array = eldbus_message_iter_container_new(iter, 'a', "i");
eldbus_message_iter_fixed_array_append(array, 'i', numbers, EINA_C_ARRAY_LENGTH(numbers));
eldbus_message_iter_container_close(iter, array);
return reply;
}
static Eldbus_Message *
_send_array(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
Eldbus_Message_Iter *iter, *array;
const char *array_string[5] = {"qqqq", "wwwww", "eeeeee", "rrrrr", "ttttt"};
int i;
printf("sendArray\n\n");
iter = eldbus_message_iter_get(reply);
array = eldbus_message_iter_container_new(iter, 'a', "s");
for (i = 0; i < 5; i++)
eldbus_message_iter_arguments_append(array, "s", array_string[i]);
eldbus_message_iter_container_close(iter, array);
return reply;
}
static Eldbus_Message *
_plus_one(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
int num;
printf("- plusOne\n\n");
if (!eldbus_message_arguments_get(msg, "i", &num))
{
printf("Error on eldbus_message_arguments_get()\n");
return reply;
}
num++;
eldbus_message_arguments_append(reply, "i", num);
return reply;
}
static Eldbus_Message *
_double_container(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
Eldbus_Message_Iter *array1, *array2, *structure;
int num1, num2;
Eldbus_Message *reply;
if (!eldbus_message_arguments_get(msg, "a(ii)a(ii)", &array1, &array2))
{
printf("Error on eldbus_message_arguments_get()\n");
return NULL;
}
reply = eldbus_message_method_return_new(msg);
printf("DoubleCountainer\n{\nArray1:\n");
while (eldbus_message_iter_get_and_next(array1, 'r', &structure))
{
eldbus_message_iter_arguments_get(structure, "ii", &num1, &num2);
printf("1 %d - 2 %d\n", num1, num2);
}
printf("Array2:\n");
while (eldbus_message_iter_get_and_next(array2, 'r', &structure))
{
eldbus_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 Eldbus_Service_Interface *iface EINA_UNUSED, const char *propname, Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg EINA_UNUSED, Eldbus_Message **error EINA_UNUSED)
{
printf("Properties_get - %s\n", propname);
if (!strcmp(propname, "Resp2"))
eldbus_message_iter_basic_append(iter, 's', resp2);
else if (!strcmp(propname, "text"))
eldbus_message_iter_basic_append(iter, 's', "lalalala");
else if (!strcmp(propname, "int32"))
{
eldbus_message_iter_arguments_append(iter, "i", int32);
int32++;
}
else if (!strcmp(propname, "st"))
{
Eldbus_Message_Iter *st;
eldbus_message_iter_arguments_append(iter, "(ss)", &st);
eldbus_message_iter_arguments_append(st, "ss", "string1", "string2");
eldbus_message_iter_container_close(iter, st);
}
return EINA_TRUE;
}
static Eldbus_Message *
_properties_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const char *propname, Eldbus_Message_Iter *iter, const Eldbus_Message *msg)
{
char *type;
type = eldbus_message_iter_signature_get(iter);
if (!strcmp(propname, "int32"))
{
int num;
if (type[0] != 'i')
goto invalid_signature;
eldbus_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;
eldbus_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 eldbus_message_method_return_new(msg);
invalid_signature:
free(type);
return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidSignature",
"Invalid type.");
}
static const Eldbus_Method methods[] = {
{
"ReceiveArray", ELDBUS_ARGS({"as", "array_of_strings"}),
NULL, _receive_array, 0
},
{
"ReceiveArrayOfStringIntWithSize",
ELDBUS_ARGS({"i", "size_of_array"}, {"a(si)", "array"}),
NULL, _receive_array_of_string_int_with_size, 0
},
{
"SendVariantData", ELDBUS_ARGS({"v", "variant_data"}),
NULL, _send_variant, 0
},
{
"ReceiveVariantData", NULL, ELDBUS_ARGS({"v", "variant_data"}),
_receive_variant, 0
},
{
"SendArrayInt", NULL,
ELDBUS_ARGS({"ai", "array_of_int"}), _send_array_int, 0
},
{
"SendArray", NULL, ELDBUS_ARGS({"as", "array_string"}),
_send_array, 0
},
{
"PlusOne", ELDBUS_ARGS({"i", "integer"}),
ELDBUS_ARGS({"i", "integer_plus_one"}), _plus_one, 0
},
{
"DoubleContainner", ELDBUS_ARGS({"a(ii)", "array1"}, {"a(ii)", "array2"}),
NULL, _double_container, 0
},
{ }
};
static const Eldbus_Property properties[] = {
{ "Resp2", "s", NULL, _properties_set, 0 },
{ "text", "s", NULL, NULL, 0 },
{ "int32", "i", NULL, _properties_set, 0 },
{ "st", "(ss)", NULL, NULL, 0 },
{ }
};
static const Eldbus_Service_Interface_Desc iface_desc = {
IFACE, methods, NULL, properties, _properties_get, NULL
};
static Eina_Bool _emit_changed(void *data)
{
Eldbus_Service_Interface *iface = data;
eldbus_service_property_changed(iface, "int32");
eldbus_service_property_invalidate_set(iface, "Resp2", EINA_TRUE);
return ECORE_CALLBACK_RENEW;
}
static void
on_name_request(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
{
unsigned int reply;
Eldbus_Service_Interface *iface = data;
if (eldbus_message_error_get(msg, NULL, NULL))
{
printf("error on on_name_request\n");
return;
}
if (!eldbus_message_arguments_get(msg, "u", &reply))
{
printf("error geting arguments on on_name_request\n");
return;
}
if (reply != ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER)
{
printf("error name already in use\n");
return;
}
timer = ecore_timer_add(3, _emit_changed, iface);
}
int
main(void)
{
Eldbus_Connection *conn;
Eldbus_Service_Interface *iface;
ecore_init();
eldbus_init();
conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
resp2 = malloc(sizeof(char) * 5);
strcpy(resp2, "test");
iface = eldbus_service_interface_register(conn, PATH, &iface_desc);
eldbus_name_request(conn, BUS, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
on_name_request, iface);
ecore_main_loop_begin();
free(resp2);
ecore_timer_del(timer);
eldbus_service_interface_unregister(iface);
eldbus_connection_unref(conn);
eldbus_shutdown();
ecore_shutdown();
return 0;
}
ecore_shutdown
EAPI int ecore_shutdown(void)
Shuts down connections, signal handlers sockets etc.
Definition: ecore.c:371
ecore_init
EAPI int ecore_init(void)
Sets up connections, signal handlers, sockets etc.
Definition: ecore.c:230
ECORE_CALLBACK_RENEW
#define ECORE_CALLBACK_RENEW
Return value to keep a callback.
Definition: Ecore_Common.h:153
ecore_main_loop_begin
void ecore_main_loop_begin(void)
Runs the application main loop.
Definition: ecore_main.c:1311
ecore_timer_add
Ecore_Timer * ecore_timer_add(double in, Ecore_Task_Cb func, const void *data)
Creates a timer to call the given function in the given period of time.
Definition: ecore_timer.c:189
ecore_timer_del
void * ecore_timer_del(Ecore_Timer *timer)
Deletes the specified timer from the timer list.
Definition: ecore_timer.c:238
Ecore_Timer
Eo Ecore_Timer
A handle for timers.
Definition: Ecore_Common.h:3065
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:539
Eina_Bool
unsigned char Eina_Bool
Type to mimic a boolean.
Definition: eina_types.h:527
EINA_C_ARRAY_LENGTH
#define EINA_C_ARRAY_LENGTH(arr)
Macro to return the array length of a standard c array.
Definition: eina_types.h:621
EINA_UNUSED
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition: eina_types.h:339
ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE
#define ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE
If we can not become the primary owner do not place us in the queue.
Definition: eldbus_freedesktop.h:12
eldbus_name_request
Eldbus_Pending * eldbus_name_request(Eldbus_Connection *conn, const char *name, unsigned int flags, Eldbus_Message_Cb cb, const void *cb_data)
Send a "RequestName" method call in proxy.
Definition: eldbus_freedesktop.c:6
ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER
#define ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER
Service has become the primary owner of the requested name.
Definition: eldbus_freedesktop.h:15
eldbus_connection_unref
void eldbus_connection_unref(Eldbus_Connection *conn)
Decrement connection reference count.
Definition: eldbus_core.c:1306
eldbus_connection_get
Eldbus_Connection * eldbus_connection_get(Eldbus_Connection_Type type)
Establish a connection to bus and integrate it with the ecore main loop.
Definition: eldbus_core.c:1102
Eldbus_Message_Iter
struct _Eldbus_Message_Iter Eldbus_Message_Iter
Represents an iterator over a complex message type (array, dict, struct, or variant).
Definition: Eldbus.h:181
Eldbus_Message
struct _Eldbus_Message Eldbus_Message
Represents the way data is sent and received in DBus.
Definition: Eldbus.h:173
eldbus_shutdown
EAPI int eldbus_shutdown(void)
Shutdown eldbus.
Definition: eldbus_core.c:246
Eldbus_Pending
struct _Eldbus_Pending Eldbus_Pending
Represents a message that has been sent but has not yet reached its destination.
Definition: Eldbus.h:188
eldbus_init
EAPI int eldbus_init(void)
Initialize eldbus.
Definition: eldbus_core.c:128
eldbus_message_iter_container_close
Eina_Bool eldbus_message_iter_container_close(Eldbus_Message_Iter *iter, Eldbus_Message_Iter *sub)
Closes a container-typed value appended to the message.
Definition: eldbus_message.c:548
eldbus_message_iter_get_and_next
Eina_Bool eldbus_message_iter_get_and_next(Eldbus_Message_Iter *iter, char signature,...)
Useful when iterating over arrays.
Definition: eldbus_message.c:736
eldbus_message_iter_fixed_array_append
Eina_Bool eldbus_message_iter_fixed_array_append(Eldbus_Message_Iter *iter, int type, const void *array, unsigned int size)
Append a array of basic type with fixed size to Eldbus_Message_Iter.
Definition: eldbus_message.c:573
eldbus_message_iter_get
Eldbus_Message_Iter * eldbus_message_iter_get(const Eldbus_Message *msg)
Get the main Eldbus_Message_Iter from the Eldbus_Message.
Definition: eldbus_message.c:264
eldbus_message_iter_signature_get
char * eldbus_message_iter_signature_get(Eldbus_Message_Iter *iter)
Returns the current signature of a message iterator.
Definition: eldbus_message.c:605
eldbus_message_iter_container_new
Eldbus_Message_Iter * eldbus_message_iter_container_new(Eldbus_Message_Iter *iter, int type, const char *contained_signature)
Create and append a typed iterator to another iterator.
Definition: eldbus_message.c:526
eldbus_message_iter_arguments_append
Eina_Bool eldbus_message_iter_arguments_append(Eldbus_Message_Iter *iter, const char *signature,...)
Append an argument into an Eldbus_Message_Iter.
Definition: eldbus_message.c:379
eldbus_message_iter_arguments_get
Eina_Bool eldbus_message_iter_arguments_get(Eldbus_Message_Iter *iter, const char *signature,...)
Get data from Eldbus_Message_Iter, for each complete type must have a pointer to store his value,...
Definition: eldbus_message.c:842
eldbus_message_iter_basic_append
Eina_Bool eldbus_message_iter_basic_append(Eldbus_Message_Iter *iter, int type,...)
Append a basic type into an Eldbus_Iterator.
Definition: eldbus_message.c:558
eldbus_message_method_return_new
Eldbus_Message * eldbus_message_method_return_new(const Eldbus_Message *msg)
Create a message that is a reply to a method call.
Definition: eldbus_message.c:895
eldbus_message_error_get
Eina_Bool eldbus_message_error_get(const Eldbus_Message *msg, const char **name, const char **text)
Get the error text and name from a Eldbus_Message.
Definition: eldbus_message.c:233
eldbus_message_error_new
Eldbus_Message * eldbus_message_error_new(const Eldbus_Message *msg, const char *error_name, const char *error_msg)
Create a new message that is an error reply to another message.
Definition: eldbus_message.c:875
eldbus_message_arguments_get
Eina_Bool eldbus_message_arguments_get(const Eldbus_Message *msg, const char *signature,...)
Get the arguments from an Eldbus_Message.
Definition: eldbus_message.c:274
eldbus_message_arguments_append
Eina_Bool eldbus_message_arguments_append(Eldbus_Message *msg, const char *signature,...)
Append arguments into an Eldbus_Message.
Definition: eldbus_message.c:495
eldbus_service_interface_unregister
void eldbus_service_interface_unregister(Eldbus_Service_Interface *iface)
Unregister a interface.
Definition: eldbus_service.c:1277
eldbus_service_property_changed
Eina_Bool eldbus_service_property_changed(const Eldbus_Service_Interface *interface, const char *name)
Add property to list of changed properties A DBus.PropertiesChanged signal will be sent in an idler w...
Definition: eldbus_service.c:1478
eldbus_service_interface_register
Eldbus_Service_Interface * eldbus_service_interface_register(Eldbus_Connection *conn, const char *path, const Eldbus_Service_Interface_Desc *desc)
Register an interface in the given path and connection.
Definition: eldbus_service.c:998
ELDBUS_ARGS
#define ELDBUS_ARGS(args...)
Used to insert complete types to signature of methods or signals.
Definition: eldbus_service.h:33
Eldbus_Connection
struct _Eldbus_Connection Eldbus_Connection
Represents a connection of one the type of connection with the DBus daemon.
Definition: Eldbus.h:227
_Eldbus_Method
Definition: eldbus_service.h:71
_Eldbus_Property
Definition: eldbus_service.h:94
_Eldbus_Service_Interface_Desc
Definition: eldbus_service.h:103