This file implements rpc calls from one application to another. More...
#include "internal.h"
#include <assert.h>
#include <stdlib.h>
Go to the source code of this file.
Defines | |
#define | UNUSED(x) (void)(x) |
Functions | |
void | _parse_id (const char *id, eripc_bus_t *bus, char *sender, int *serial) |
void | _make_id (eripc_bus_t bus, const char *sender, int serial, char *id) |
static eripc_error_t | _append_args (DBusMessage *msg, int type, va_list var_args) |
eripc_error_t | eripc_get_timeout (eripc_context_t *context, int *timeout) |
void * | eripc_get_system_connection (eripc_context_t *context) |
void * | eripc_get_session_connection (eripc_context_t *context) |
eripc_error_t | eripc_set_timeout (eripc_context_t *context, int timeout) |
static void | eripc_reply_handler (osso_context_t *osso, DBusMessage *msg, _osso_callback_data_t *cb_data, eripc_bus_t dbus_type) |
static eripc_error_t | _send_signal_helper (eripc_context_t *context, eripc_bus_t bus_type, const char *signal_path, const char *signal_interface, const char *signal_name, eripc_data_t arg_type, va_list va_args) |
eripc_error_t | eripc_send_signal_varargs (eripc_context_t *context, eripc_bus_t bus_type, const char *signal_path, const char *signal_interface, const char *signal_name, eripc_data_t arg_type,...) |
eripc_error_t | eripc_send_signal (eripc_context_t *context, eripc_bus_t bus_type, const char *signal_name, const char *argument) |
static eripc_error_t | _send_helper (eripc_context_t *context, eripc_handler_t *reply_handler, const void *user_data, eripc_bus_t bus_type, const char *destination, const char *message_name, eripc_data_t arg_type, va_list va_args) |
static eripc_error_t | _send_sync_helper (eripc_context_t *context, eripc_event_info_t **reply, eripc_bus_t bus_type, const char *destination, const char *message_name, eripc_data_t arg_type, va_list va_args) |
eripc_error_t | eripc_send_varargs (eripc_context_t *context, eripc_handler_t *reply_handler, const void *user_data, eripc_bus_t bus_type, const char *destination, const char *message_name, eripc_data_t arg_type,...) |
eripc_error_t | eripc_send_varargs_and_wait (eripc_context_t *context, eripc_event_info_t **reply, eripc_bus_t bus_type, const char *destination, const char *message_name, eripc_data_t arg_type,...) |
eripc_error_t | eripc_send_string_and_wait (eripc_context_t *context, eripc_event_info_t **reply, eripc_bus_t bus_type, const char *destination, const char *message_name, const char *string_to_send) |
eripc_error_t | eripc_send_int_and_wait (eripc_context_t *context, eripc_event_info_t **reply, eripc_bus_t bus_type, const char *destination, const char *message_name, int value_to_send) |
eripc_error_t | eripc_send_bool_and_wait (eripc_context_t *context, eripc_event_info_t **reply, eripc_bus_t bus_type, const char *destination, const char *message_name, gboolean value_to_send) |
eripc_error_t | eripc_send_string (eripc_context_t *context, eripc_handler_t *reply_handler, const void *user_data, eripc_bus_t bus_type, const char *destination, const char *message_name, const char *string_to_send) |
eripc_error_t | eripc_send_int (eripc_context_t *context, eripc_handler_t *reply_handler, const void *user_data, eripc_bus_t bus_type, const char *destination, const char *message_name, int value_to_send) |
eripc_error_t | eripc_send_bool (eripc_context_t *context, eripc_handler_t *reply_handler, const void *user_data, eripc_bus_t bus_type, const char *destination, const char *message_name, gboolean value_to_send) |
eripc_error_t | eripc_event_info_free (eripc_context_t *context, eripc_event_info_t *info) |
static eripc_error_t | _reply_helper (eripc_context_t *context, const char *message_id, eripc_data_t arg_type, va_list va_args) |
eripc_error_t | eripc_reply_varargs (eripc_context_t *context, const char *message_id, eripc_data_t arg_type,...) |
eripc_error_t | eripc_reply_string (eripc_context_t *context, const char *message_id, const char *string) |
eripc_error_t | eripc_reply_int (eripc_context_t *context, const char *message_id, int value) |
eripc_error_t | eripc_reply_bool (eripc_context_t *context, const char *message_id, gboolean value) |
eripc_error_t | eripc_reply_error (eripc_context_t *context, const char *message_id, const char *name, const char *message) |
This file implements rpc calls from one application to another.
Definition in file rpc.c.
#define UNUSED | ( | x | ) | (void)(x) |
Copyright (C) 2008 iRex Technologies B.V. All rights reserved.
Based on code found in libosso library by Kimmo Hämäläinen <kimmo.hamalainen@nokia.com>
static eripc_error_t _append_args | ( | DBusMessage * | msg, | |
int | type, | |||
va_list | var_args | |||
) | [static] |
Definition at line 75 of file rpc.c.
References ERIPC_ERROR, ERIPC_ERROR_INVALID, ERIPC_ERROR_SUCCESS, ERIPC_TYPE_BOOL, ERIPC_TYPE_BYTE, ERIPC_TYPE_DATA, ERIPC_TYPE_DOUBLE, ERIPC_TYPE_INT, ERIPC_TYPE_INVALID, ERIPC_TYPE_STRING, ERIPC_TYPE_UINT, and ULOG_ERR_F.
Referenced by _reply_helper(), _send_helper(), _send_signal_helper(), and _send_sync_helper().
00077 { 00078 eripc_error_t rc = ERIPC_ERROR_SUCCESS; 00079 00080 while (type != ERIPC_TYPE_INVALID && rc == ERIPC_ERROR_SUCCESS) { 00081 dbus_bool_t ret; 00082 char *s; 00083 const char *empty_str = ""; 00084 int i; 00085 unsigned int u; 00086 double d; 00087 00088 switch (type) { 00089 case ERIPC_TYPE_BOOL: 00090 i = va_arg(var_args, int); 00091 ret = dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, 00092 &i, DBUS_TYPE_INVALID); 00093 if (!ret) rc = ERIPC_ERROR; 00094 break; 00095 case ERIPC_TYPE_BYTE: 00096 i = va_arg(var_args, int); 00097 ret = dbus_message_append_args(msg, DBUS_TYPE_BYTE, 00098 &i, DBUS_TYPE_INVALID); 00099 if (!ret) rc = ERIPC_ERROR; 00100 break; 00101 case ERIPC_TYPE_INT: 00102 i = va_arg(var_args, int); 00103 ret = dbus_message_append_args(msg, DBUS_TYPE_INT32, 00104 &i, DBUS_TYPE_INVALID); 00105 if (!ret) rc = ERIPC_ERROR; 00106 break; 00107 case ERIPC_TYPE_UINT: 00108 u = va_arg(var_args, unsigned int); 00109 ret = dbus_message_append_args(msg, DBUS_TYPE_UINT32, 00110 &u, DBUS_TYPE_INVALID); 00111 if (!ret) rc = ERIPC_ERROR; 00112 break; 00113 case ERIPC_TYPE_DOUBLE: 00114 d = va_arg(var_args, double); 00115 ret = dbus_message_append_args(msg, DBUS_TYPE_DOUBLE, 00116 &d, DBUS_TYPE_INVALID); 00117 if (!ret) rc = ERIPC_ERROR; 00118 break; 00119 case ERIPC_TYPE_STRING: 00120 s = va_arg(var_args, char *); 00121 if (s == NULL) { 00122 ret = dbus_message_append_args(msg, 00123 DBUS_TYPE_STRING, &empty_str, 00124 DBUS_TYPE_INVALID); 00125 } else { 00126 ret = dbus_message_append_args(msg, 00127 DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID); 00128 } 00129 if (!ret) rc = ERIPC_ERROR; 00130 break; 00131 case ERIPC_TYPE_DATA: 00132 i = va_arg(var_args, int); /* length of the data */ 00133 s = va_arg(var_args, char *); 00134 ret = dbus_message_append_args(msg, 00135 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, 00136 &s, i, DBUS_TYPE_INVALID); 00137 if (!ret) rc = ERIPC_ERROR; 00138 break; 00139 default: 00140 ULOG_ERR_F("unknown type %d", type); 00141 rc = ERIPC_ERROR_INVALID; 00142 break; 00143 } 00144 type = va_arg(var_args, int); 00145 } 00146 return rc; 00147 }
void _make_id | ( | eripc_bus_t | bus, | |
const char * | sender, | |||
int | serial, | |||
char * | id | |||
) |
Definition at line 70 of file rpc.c.
References MAX_MSGID_LEN.
Referenced by _send_sync_helper(), eripc_reply_handler(), and generic_signal_handler().
00071 { 00072 snprintf(id, MAX_MSGID_LEN, "%d,%s,%d", bus, sender, serial); 00073 }
void _parse_id | ( | const char * | id, | |
eripc_bus_t * | bus, | |||
char * | sender, | |||
int * | serial | |||
) |
Definition at line 37 of file rpc.c.
References MAX_SVC_LEN.
Referenced by _reply_helper(), and eripc_reply_error().
00039 { 00040 int i; 00041 char buf[20], *p; 00042 00043 /* get bus type */ 00044 for (i = 0, p = (char*) id; *p != ','; ++p, ++i) { 00045 assert(*p != '\0'); 00046 assert(i < 20); 00047 buf[i] = *p; 00048 } 00049 buf[i] = '\0'; 00050 *bus = atoi(buf); 00051 /* get sender */ 00052 ++p; 00053 for (i = 0; *p != ','; ++p, ++i) { 00054 assert(*p != '\0'); 00055 assert(i <= MAX_SVC_LEN); 00056 sender[i] = *p; 00057 } 00058 sender[i] = '\0'; 00059 /* get serial */ 00060 ++p; 00061 for (i = 0; *p != '\0'; ++p, ++i) { 00062 assert(i < 20); 00063 buf[i] = *p; 00064 } 00065 buf[i] = '\0'; 00066 *serial = atoi(buf); 00067 }
static eripc_error_t _reply_helper | ( | eripc_context_t * | context, | |
const char * | message_id, | |||
eripc_data_t | arg_type, | |||
va_list | va_args | |||
) | [static] |
Definition at line 763 of file rpc.c.
References _append_args(), _parse_id(), _eripc_context_t::conn, ERIPC_BUS_SESSION, ERIPC_BUS_SYSTEM, ERIPC_ERROR, ERIPC_ERROR_INVALID, ERIPC_ERROR_OOM, ERIPC_ERROR_SUCCESS, ERIPC_TYPE_INVALID, MAX_SVC_LEN, _eripc_context_t::reply_dummy, sender, serial, _eripc_context_t::sys_conn, and ULOG_ERR_F.
Referenced by eripc_reply_varargs().
00766 { 00767 DBusConnection *conn; 00768 DBusMessage *reply; 00769 char sender[MAX_SVC_LEN + 1]; 00770 int serial; 00771 eripc_bus_t bus_type; 00772 00773 if (context == NULL || message_id == NULL) { 00774 return ERIPC_ERROR_INVALID; 00775 } 00776 if (context->reply_dummy == NULL) { 00777 /* OOM has happened earlier in the handler, or 00778 * the context is invalid */ 00779 ULOG_ERR_F("reply_dummy has not been created"); 00780 return ERIPC_ERROR; 00781 } 00782 00783 _parse_id(message_id, &bus_type, sender, &serial); 00784 assert(bus_type == ERIPC_BUS_SYSTEM || bus_type == ERIPC_BUS_SESSION); 00785 00786 if (bus_type == ERIPC_BUS_SYSTEM) { 00787 conn = context->sys_conn; 00788 } else { 00789 conn = context->conn; 00790 } 00791 if (!dbus_connection_get_is_connected(conn)) { 00792 ULOG_ERR_F("connection %p is not open", conn); 00793 return ERIPC_ERROR_INVALID; 00794 } 00795 00796 /* make a copy of the reply_dummy and modify the copy */ 00797 reply = dbus_message_copy(context->reply_dummy); 00798 if (reply == NULL) { 00799 ULOG_ERR_F("dbus_message_copy failed"); 00800 return ERIPC_ERROR_OOM; 00801 } 00802 if (!dbus_message_set_destination(reply, sender)) { 00803 ULOG_ERR_F("dbus_message_set_destination failed"); 00804 goto unref_and_exit; 00805 } 00806 if (!dbus_message_set_reply_serial(reply, serial)) { 00807 ULOG_ERR_F("dbus_message_set_reply_serial failed"); 00808 goto unref_and_exit; 00809 } 00810 00811 if (arg_type != ERIPC_TYPE_INVALID) { 00812 eripc_error_t rc; 00813 rc = _append_args(reply, arg_type, va_args); 00814 if (rc != ERIPC_ERROR_SUCCESS) { 00815 ULOG_ERR_F("dbus_message_append_args failed"); 00816 goto unref_and_exit; 00817 } 00818 } 00819 00820 if (!dbus_connection_send(conn, reply, NULL)) { 00821 ULOG_ERR_F("dbus_connection_send failed"); 00822 goto unref_and_exit; 00823 } 00824 dbus_message_unref(reply); 00825 return ERIPC_ERROR_SUCCESS; 00826 00827 unref_and_exit: 00828 dbus_message_unref(reply); 00829 return ERIPC_ERROR_OOM; 00830 }
static eripc_error_t _send_helper | ( | eripc_context_t * | context, | |
eripc_handler_t * | reply_handler, | |||
const void * | user_data, | |||
eripc_bus_t | bus_type, | |||
const char * | destination, | |||
const char * | message_name, | |||
eripc_data_t | arg_type, | |||
va_list | va_args | |||
) | [static] |
Definition at line 352 of file rpc.c.
References _append_args(), _osso_callback_data_t::bus_type, _eripc_context_t::conn, _osso_callback_data_t::data, ERIPC_BUS_SESSION, ERIPC_BUS_SYSTEM, ERIPC_ERROR, ERIPC_ERROR_INVALID, ERIPC_ERROR_OOM, ERIPC_ERROR_SUCCESS, ERIPC_MEMBER_MATCH_ALL, ERIPC_PATH_MATCH_ALL, eripc_reply_handler(), ERIPC_TYPE_INVALID, _osso_callback_data_t::event_type, handler_id, _osso_callback_data_t::interface, interface, _osso_callback_data_t::match_rule, MAX_IF_LEN, MAX_OP_LEN, MAX_SVC_LEN, _osso_callback_data_t::message_id, msg, _osso_callback_data_t::name, _eripc_context_t::next_handler_id, _osso_callback_data_t::path, path, _osso_callback_data_t::service, service, _eripc_context_t::sys_conn, ULOG_ERR_F, _osso_callback_data_t::user_cb, and _osso_callback_data_t::user_data.
Referenced by eripc_send_varargs().
00359 { 00360 char service[MAX_SVC_LEN + 1], path[MAX_OP_LEN + 1], 00361 interface[MAX_IF_LEN + 1]; 00362 _osso_callback_data_t *cb_data; 00363 DBusMessage *msg; 00364 DBusConnection *conn; 00365 unsigned int msg_serial = 0; 00366 int handler_id; 00367 00368 if (context == NULL) { 00369 ULOG_ERR_F("context error"); 00370 return ERIPC_ERROR_INVALID; 00371 } 00372 00373 if (destination == NULL || message_name == NULL || destination[0] == '\0') { 00374 ULOG_ERR_F("destination and message_name must be provided"); 00375 return ERIPC_ERROR_INVALID; 00376 } 00377 00378 if (bus_type != ERIPC_BUS_SESSION && bus_type != ERIPC_BUS_SYSTEM) { 00379 ULOG_ERR_F("bus_type must be either ERIPC_BUS_SESSION " 00380 "or ERIPC_BUS_SYSTEM"); 00381 return ERIPC_ERROR_INVALID; 00382 } 00383 00384 if (reply_handler == NULL && user_data != NULL) { 00385 ULOG_ERR_F("reply_handler == NULL: ignoring user_data " 00386 "argument"); 00387 fprintf(stderr, "Warning: reply_handler is NULL: ignoring" 00388 " user_data argument"); 00389 } 00390 00391 if (bus_type == ERIPC_BUS_SESSION) { 00392 conn = context->conn; 00393 } else { 00394 conn = context->sys_conn; 00395 } 00396 00397 if (!dbus_connection_get_is_connected(conn)) { 00398 ULOG_ERR_F("connection %p is not open", conn); 00399 return ERIPC_ERROR_INVALID; 00400 } 00401 00402 make_default_service(destination, service); 00403 make_default_object_path(destination, path); 00404 make_default_interface(destination, interface); 00405 00406 msg = dbus_message_new_method_call(service, path, interface, 00407 message_name); 00408 if (msg == NULL) { 00409 ULOG_ERR_F("dbus_message_new_method_call failed"); 00410 goto _send_oom; 00411 } 00412 00413 if (arg_type != ERIPC_TYPE_INVALID) { 00414 eripc_error_t rc; 00415 rc = _append_args(msg, arg_type, va_args); 00416 if (rc != ERIPC_ERROR_SUCCESS) { 00417 ULOG_ERR_F("invalid type"); 00418 dbus_message_unref(msg); 00419 return rc; 00420 } 00421 } 00422 00423 if (reply_handler == NULL) { 00424 dbus_message_set_no_reply(msg, TRUE); 00425 } 00426 00427 if (!dbus_connection_send(conn, msg, &msg_serial)) { 00428 ULOG_ERR_F("dbus_connection_send failed"); 00429 dbus_message_unref(msg); 00430 goto _send_oom; 00431 } 00432 dbus_message_unref(msg); 00433 00434 if (reply_handler == NULL) { 00435 /* the caller does not want to handle the reply, so 00436 * let's not put any handler for it */ 00437 return ERIPC_ERROR_SUCCESS; 00438 } 00439 00440 cb_data = calloc(1, sizeof(_osso_callback_data_t)); 00441 if (cb_data == NULL) { 00442 ULOG_ERR_F("calloc failed"); 00443 goto _send_oom; 00444 } 00445 /* this is used to recognise the reply for this message */ 00446 cb_data->message_id = (long)msg_serial; 00447 00448 cb_data->user_cb = reply_handler; 00449 cb_data->user_data = (void*) user_data; 00450 cb_data->match_rule = NULL; 00451 cb_data->event_type = 0; 00452 cb_data->bus_type = bus_type; 00453 cb_data->data = context; 00454 00455 cb_data->service = NULL; 00456 cb_data->path = ERIPC_PATH_MATCH_ALL; 00457 cb_data->interface = NULL; 00458 cb_data->name = ERIPC_MEMBER_MATCH_ALL; 00459 00460 /* (eripc_filter removes the handler, otherwise this would need 00461 * to be saved somewhere) */ 00462 handler_id = context->next_handler_id++; 00463 00464 if (_eripc_set_handler((_eripc_context_t*)context, 00465 eripc_reply_handler, cb_data, handler_id, 00466 FALSE)) { 00467 return ERIPC_ERROR_SUCCESS; 00468 } else { 00469 ULOG_ERR_F("_set_handler failed"); 00470 free(cb_data); 00471 return ERIPC_ERROR; 00472 } 00473 00474 _send_oom: 00475 00476 return ERIPC_ERROR_OOM; 00477 }
static eripc_error_t _send_signal_helper | ( | eripc_context_t * | context, | |
eripc_bus_t | bus_type, | |||
const char * | signal_path, | |||
const char * | signal_interface, | |||
const char * | signal_name, | |||
eripc_data_t | arg_type, | |||
va_list | va_args | |||
) | [static] |
Definition at line 252 of file rpc.c.
References _append_args(), _eripc_context_t::conn, ERIPC_BUS_SESSION, ERIPC_BUS_SYSTEM, ERIPC_ERROR, ERIPC_ERROR_INVALID, ERIPC_ERROR_OOM, ERIPC_ERROR_SUCCESS, ERIPC_TYPE_INVALID, msg, _eripc_context_t::sys_conn, and ULOG_ERR_F.
Referenced by eripc_send_signal_varargs().
00258 { 00259 DBusConnection *conn; 00260 DBusMessage *msg; 00261 00262 if (context == NULL || signal_name == NULL) { 00263 return ERIPC_ERROR_INVALID; 00264 } 00265 00266 if (bus_type != ERIPC_BUS_SESSION && bus_type != ERIPC_BUS_SYSTEM) { 00267 ULOG_ERR_F("bus_type must be either ERIPC_BUS_SESSION " 00268 "or ERIPC_BUS_SYSTEM"); 00269 return ERIPC_ERROR_INVALID; 00270 } 00271 00272 if (bus_type == ERIPC_BUS_SESSION) { 00273 conn = context->conn; 00274 } else { 00275 conn = context->sys_conn; 00276 } 00277 00278 if (!dbus_connection_get_is_connected(conn)) { 00279 ULOG_ERR_F("connection %p is not open", conn); 00280 return ERIPC_ERROR_INVALID; 00281 } 00282 00283 msg = dbus_message_new_signal(signal_path, signal_interface, signal_name); 00284 if (msg == NULL) { 00285 ULOG_ERR_F("dbus_message_new_signal failed"); 00286 return ERIPC_ERROR_OOM; 00287 } 00288 00289 if (arg_type != ERIPC_TYPE_INVALID) { 00290 eripc_error_t rc; 00291 rc = _append_args(msg, arg_type, va_args); 00292 if (rc != ERIPC_ERROR_SUCCESS) { 00293 ULOG_ERR_F("dbus_message_append_args failed"); 00294 dbus_message_unref(msg); 00295 return ERIPC_ERROR; 00296 } 00297 } 00298 00299 if (!dbus_connection_send(conn, msg, NULL)) { 00300 ULOG_ERR_F("dbus_connection_send failed"); 00301 dbus_message_unref(msg); 00302 return ERIPC_ERROR_OOM; 00303 } 00304 dbus_message_unref(msg); 00305 00306 return ERIPC_ERROR_SUCCESS; 00307 }
static eripc_error_t _send_sync_helper | ( | eripc_context_t * | context, | |
eripc_event_info_t ** | reply, | |||
eripc_bus_t | bus_type, | |||
const char * | destination, | |||
const char * | message_name, | |||
eripc_data_t | arg_type, | |||
va_list | va_args | |||
) | [static] |
Definition at line 481 of file rpc.c.
References _append_args(), _get_args(), _make_id(), eripc_event_info_t::args, eripc_event_info_t::bus_type, _eripc_context_t::conn, eripc_event_info_t::dbus_message, ERIPC_BUS_SESSION, ERIPC_BUS_SYSTEM, ERIPC_ERROR_INVALID, ERIPC_ERROR_OOM, ERIPC_ERROR_SUCCESS, ERIPC_ERROR_TIMEOUT, ERIPC_TYPE_INVALID, eripc_event_info_t::error, eripc_event_info_t::event_type, eripc_event_info_t::interface, interface, MAX_IF_LEN, MAX_MSGID_LEN, MAX_OP_LEN, MAX_SVC_LEN, eripc_event_info_t::message_id, msg, eripc_event_info_t::name, eripc_event_info_t::path, path, eripc_event_info_t::service, service, _eripc_context_t::sys_conn, _eripc_context_t::timeout_ms, and ULOG_ERR_F.
Referenced by eripc_send_varargs_and_wait().
00487 { 00488 char service[MAX_SVC_LEN + 1], path[MAX_OP_LEN + 1], 00489 interface[MAX_IF_LEN + 1]; 00490 DBusMessage *msg; 00491 DBusMessage *reply_msg; 00492 DBusConnection *conn; 00493 DBusMessageIter iter; 00494 DBusError error; 00495 00496 char id_buf[MAX_MSGID_LEN + 1]; 00497 00498 if (reply != NULL && *reply != NULL) { 00499 *reply = NULL; 00500 } 00501 00502 if (context == NULL) { 00503 ULOG_ERR_F("context error"); 00504 return ERIPC_ERROR_INVALID; 00505 } 00506 00507 if (destination == NULL || message_name == NULL || destination[0] == '\0') { 00508 ULOG_ERR_F("destination and message_name must be provided"); 00509 return ERIPC_ERROR_INVALID; 00510 } 00511 00512 if (bus_type != ERIPC_BUS_SESSION && bus_type != ERIPC_BUS_SYSTEM) { 00513 ULOG_ERR_F("bus_type must be either ERIPC_BUS_SESSION " 00514 "or ERIPC_BUS_SYSTEM"); 00515 return ERIPC_ERROR_INVALID; 00516 } 00517 00518 if (bus_type == ERIPC_BUS_SESSION) { 00519 conn = context->conn; 00520 } else { 00521 conn = context->sys_conn; 00522 } 00523 00524 if (!dbus_connection_get_is_connected(conn)) { 00525 ULOG_ERR_F("connection %p is not open", conn); 00526 return ERIPC_ERROR_INVALID; 00527 } 00528 00529 make_default_service(destination, service); 00530 make_default_object_path(destination, path); 00531 make_default_interface(destination, interface); 00532 00533 msg = dbus_message_new_method_call(service, path, interface, 00534 message_name); 00535 if (msg == NULL) { 00536 ULOG_ERR_F("dbus_message_new_method_call failed"); 00537 return ERIPC_ERROR_OOM; 00538 } 00539 00540 if (arg_type != ERIPC_TYPE_INVALID) { 00541 eripc_error_t rc; 00542 rc = _append_args(msg, arg_type, va_args); 00543 if (rc != ERIPC_ERROR_SUCCESS) { 00544 ULOG_ERR_F("invalid type"); 00545 dbus_message_unref(msg); 00546 return rc; 00547 } 00548 } 00549 00550 dbus_error_init(&error); 00551 00552 reply_msg = dbus_connection_send_with_reply_and_block(conn, msg, context->timeout_ms, &error); 00553 dbus_message_unref(msg); 00554 00555 if (!reply_msg) { 00556 ULOG_ERR_F("dbus_connection_send_with_reply_and_block failed: %s", error.message); 00557 dbus_error_free(&error); 00558 return ERIPC_ERROR_TIMEOUT; 00559 } 00560 00561 if (reply != NULL) 00562 { 00563 /* Allocate reply info structure */ 00564 eripc_event_info_t *reply_info; 00565 reply_info = calloc(1, sizeof(eripc_event_info_t)); 00566 if (reply_info == NULL) { 00567 ULOG_ERR_F("calloc failed"); 00568 dbus_message_unref(reply_msg); 00569 return ERIPC_ERROR_OOM; 00570 } 00571 00572 reply_info->service = dbus_message_get_sender(reply_msg); 00573 reply_info->path = path; 00574 reply_info->interface = interface; 00575 reply_info->name = dbus_message_get_member(reply_msg); 00576 reply_info->bus_type = bus_type; 00577 reply_info->event_type = 0; 00578 00579 if (dbus_message_get_type(reply_msg) == DBUS_MESSAGE_TYPE_METHOD_RETURN) { 00580 _make_id(bus_type, dbus_message_get_sender(reply_msg), 00581 dbus_message_get_serial(reply_msg), id_buf); 00582 reply_info->message_id = id_buf; 00583 } 00584 00585 if (dbus_message_get_type(reply_msg) == DBUS_MESSAGE_TYPE_ERROR) { 00586 reply_info->error = dbus_message_get_error_name(reply_msg); 00587 } 00588 00589 if (dbus_message_iter_init(reply_msg, &iter)) { 00590 reply_info->args = _get_args(&iter); 00591 } 00592 00593 reply_info->dbus_message = (char*) reply_msg; 00594 00595 /* Return the pointer to the reply info structure */ 00596 *reply = reply_info; 00597 } 00598 else { 00599 /* No reply requested by caller so unref immediately */ 00600 dbus_message_unref(reply_msg); 00601 } 00602 00603 return ERIPC_ERROR_SUCCESS; 00604 }
static void eripc_reply_handler | ( | osso_context_t * | osso, | |
DBusMessage * | msg, | |||
_osso_callback_data_t * | cb_data, | |||
eripc_bus_t | dbus_type | |||
) | [static] |
Definition at line 178 of file rpc.c.
References _get_args(), _make_id(), eripc_event_info_t::args, eripc_event_info_t::bus_type, _osso_callback_data_t::bus_type, _osso_callback_data_t::data, eripc_convert_msgtype(), ERIPC_TYPE_STRING, eripc_event_info_t::error, osso_af_context_t::error_dummy, eripc_event_info_t::event_type, eripc_event_info_t::interface, MAX_MSGID_LEN, eripc_event_info_t::message_id, _osso_callback_data_t::message_id, eripc_event_info_t::name, eripc_event_info_t::path, osso_af_context_t::reply_dummy, eripc_arg_t::s, eripc_event_info_t::service, eripc_arg_t::type, ULOG_WARN_F, _osso_callback_data_t::user_cb, _osso_callback_data_t::user_data, and eripc_arg_t::value.
Referenced by _send_helper().
00182 { 00183 eripc_event_info_t info; 00184 DBusMessageIter iter; 00185 eripc_handler_t *cb; 00186 int msgtype; 00187 char id_buf[MAX_MSGID_LEN + 1]; 00188 00189 assert(cb_data->message_id == dbus_message_get_reply_serial(msg)); 00190 assert(cb_data->bus_type == dbus_type); 00191 assert(cb_data->data == osso); 00192 00193 /* create a dummy reply message for later use (workaround for 00194 * D-Bus library API) */ 00195 if (osso->reply_dummy == NULL) { 00196 DBusMessage *reply; 00197 reply = dbus_message_new_method_return(msg); 00198 if (reply == NULL) { 00199 ULOG_WARN_F("could not create reply_dummy"); 00200 } else { 00201 osso->reply_dummy = reply; 00202 } 00203 } 00204 if (osso->error_dummy == NULL) { 00205 DBusMessage *reply; 00206 reply = dbus_message_new_error(msg, "org.foo.dummy", NULL); 00207 if (reply == NULL) { 00208 ULOG_WARN_F("could not create error_dummy"); 00209 } else { 00210 osso->error_dummy = reply; 00211 } 00212 } 00213 00214 memset(&info, 0, sizeof(info)); 00215 00216 msgtype = dbus_message_get_type(msg); 00217 info.service = dbus_message_get_sender(msg); 00218 info.path = dbus_message_get_path(msg); 00219 info.interface = dbus_message_get_interface(msg); 00220 if (msgtype == DBUS_MESSAGE_TYPE_ERROR) { 00221 info.name = dbus_message_get_error_name(msg); 00222 } else { 00223 info.name = dbus_message_get_member(msg); 00224 } 00225 info.bus_type = dbus_type; 00226 _make_id(dbus_type, dbus_message_get_sender(msg), 00227 dbus_message_get_serial(msg), id_buf); 00228 info.message_id = id_buf; 00229 00230 info.event_type = eripc_convert_msgtype(msgtype); 00231 00232 if (dbus_message_iter_init(msg, &iter)) { 00233 info.args = _get_args(&iter); 00234 if (info.args != NULL && msgtype == DBUS_MESSAGE_TYPE_ERROR 00235 && info.args[0].type == ERIPC_TYPE_STRING) { 00236 info.error = info.args[0].value.s; 00237 } 00238 } 00239 00240 cb = cb_data->user_cb; 00241 assert(cb != NULL); 00242 00243 (*cb)((eripc_context_t*)osso, &info, cb_data->user_data); 00244 00245 if (info.args != NULL) { 00246 free((char*)info.args); 00247 info.args = NULL; 00248 } 00249 }