00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "internal.h"
00031 #include <assert.h>
00032 #include <stdlib.h>
00033
00034 #define UNUSED(x) (void)(x)
00035
00036 void
00037 _parse_id(const char *id, eripc_bus_t *bus, char *sender,
00038 int *serial)
00039 {
00040 int i;
00041 char buf[20], *p;
00042
00043
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
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
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 }
00068
00069 void
00070 _make_id(eripc_bus_t bus, const char *sender, int serial, char *id)
00071 {
00072 snprintf(id, MAX_MSGID_LEN, "%d,%s,%d", bus, sender, serial);
00073 }
00074
00075 static eripc_error_t _append_args(DBusMessage *msg, int type,
00076 va_list var_args)
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);
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 }
00148
00149
00150 eripc_error_t eripc_get_timeout (eripc_context_t *context, int *timeout)
00151 {
00152 if(context == NULL) return ERIPC_ERROR_INVALID;
00153 *timeout = context->timeout_ms;
00154 return ERIPC_ERROR_SUCCESS;
00155 }
00156
00157
00158 void *eripc_get_system_connection (eripc_context_t *context)
00159 {
00160 return (void *) context->sys_conn;
00161 }
00162
00163 void *eripc_get_session_connection (eripc_context_t *context)
00164 {
00165 return (void *) context->conn;
00166 }
00167
00168
00169 eripc_error_t eripc_set_timeout(eripc_context_t *context, int timeout)
00170 {
00171 if(context == NULL) return ERIPC_ERROR_INVALID;
00172 context->timeout_ms = timeout;
00173 return ERIPC_ERROR_SUCCESS;
00174 }
00175
00176
00177
00178 static void eripc_reply_handler(osso_context_t *osso,
00179 DBusMessage *msg,
00180 _osso_callback_data_t *cb_data,
00181 eripc_bus_t dbus_type)
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
00194
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 }
00250
00251
00252 static eripc_error_t _send_signal_helper(eripc_context_t *context,
00253 eripc_bus_t bus_type,
00254 const char *signal_path,
00255 const char *signal_interface,
00256 const char *signal_name,
00257 eripc_data_t arg_type, va_list va_args)
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 }
00308
00309
00310 eripc_error_t eripc_send_signal_varargs(eripc_context_t *context,
00311 eripc_bus_t bus_type,
00312 const char *signal_path,
00313 const char *signal_interface,
00314 const char *signal_name,
00315 eripc_data_t arg_type, ...)
00316 {
00317 va_list va_args;
00318 eripc_error_t rc;
00319
00320 va_start(va_args, arg_type);
00321 rc = _send_signal_helper(context, bus_type,
00322 signal_path, signal_interface, signal_name,
00323 arg_type, va_args);
00324 va_end(va_args);
00325 return rc;
00326 }
00327
00328
00329 eripc_error_t eripc_send_signal(eripc_context_t *context,
00330 eripc_bus_t bus_type,
00331 const char *signal_name,
00332 const char *argument)
00333 {
00334 eripc_error_t rc;
00335
00336 if (argument == NULL)
00337 {
00338 rc = eripc_send_signal_varargs(context, bus_type,
00339 context->object_path, context->interface, signal_name,
00340 ERIPC_TYPE_INVALID);
00341 }
00342 else
00343 {
00344 rc = eripc_send_signal_varargs(context, bus_type,
00345 context->object_path, context->interface, signal_name,
00346 ERIPC_TYPE_STRING, argument,
00347 ERIPC_TYPE_INVALID);
00348 }
00349 return rc;
00350 }
00351
00352 static eripc_error_t _send_helper(eripc_context_t *context,
00353 eripc_handler_t *reply_handler,
00354 const void *user_data,
00355 eripc_bus_t bus_type,
00356 const char *destination,
00357 const char *message_name,
00358 eripc_data_t arg_type, va_list va_args)
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
00436
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
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
00461
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 }
00478
00479
00480 static
00481 eripc_error_t _send_sync_helper(eripc_context_t *context,
00482 eripc_event_info_t **reply,
00483 eripc_bus_t bus_type,
00484 const char *destination,
00485 const char *message_name,
00486 eripc_data_t arg_type, va_list va_args)
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
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
00596 *reply = reply_info;
00597 }
00598 else {
00599
00600 dbus_message_unref(reply_msg);
00601 }
00602
00603 return ERIPC_ERROR_SUCCESS;
00604 }
00605
00606
00607 eripc_error_t eripc_send_varargs(eripc_context_t *context,
00608 eripc_handler_t *reply_handler,
00609 const void *user_data,
00610 eripc_bus_t bus_type,
00611 const char *destination,
00612 const char *message_name,
00613 eripc_data_t arg_type, ...)
00614 {
00615 va_list va_args;
00616 eripc_error_t rc;
00617
00618 va_start(va_args, arg_type);
00619 rc = _send_helper(context, reply_handler, user_data,
00620 bus_type, destination, message_name,
00621 arg_type, va_args);
00622 va_end(va_args);
00623 return rc;
00624 }
00625
00626
00627 eripc_error_t eripc_send_varargs_and_wait(eripc_context_t *context,
00628 eripc_event_info_t **reply,
00629 eripc_bus_t bus_type,
00630 const char *destination,
00631 const char *message_name,
00632 eripc_data_t arg_type, ...)
00633 {
00634 va_list va_args;
00635 eripc_error_t rc;
00636
00637 va_start(va_args, arg_type);
00638 rc = _send_sync_helper(context, reply, bus_type, destination,
00639 message_name, arg_type, va_args);
00640 va_end(va_args);
00641 return rc;
00642 }
00643
00644 eripc_error_t eripc_send_string_and_wait(eripc_context_t *context,
00645 eripc_event_info_t **reply,
00646 eripc_bus_t bus_type,
00647 const char *destination,
00648 const char *message_name,
00649 const char *string_to_send)
00650
00651
00652 {
00653 eripc_error_t rc;
00654 rc = eripc_send_varargs_and_wait(context, reply,
00655 bus_type, destination, message_name,
00656 ERIPC_TYPE_STRING, string_to_send,
00657 ERIPC_TYPE_INVALID);
00658 return rc;
00659 }
00660
00661 eripc_error_t eripc_send_int_and_wait(eripc_context_t *context,
00662 eripc_event_info_t **reply,
00663 eripc_bus_t bus_type,
00664 const char *destination,
00665 const char *message_name,
00666 int value_to_send)
00667
00668
00669 {
00670 eripc_error_t rc;
00671 rc = eripc_send_varargs_and_wait(context, reply,
00672 bus_type, destination, message_name,
00673 ERIPC_TYPE_INT, value_to_send,
00674 ERIPC_TYPE_INVALID);
00675 return rc;
00676 }
00677
00678 eripc_error_t eripc_send_bool_and_wait(eripc_context_t *context,
00679 eripc_event_info_t **reply,
00680 eripc_bus_t bus_type,
00681 const char *destination,
00682 const char *message_name,
00683 gboolean value_to_send)
00684
00685
00686 {
00687 eripc_error_t rc;
00688 rc = eripc_send_varargs_and_wait(context, reply,
00689 bus_type, destination, message_name,
00690 ERIPC_TYPE_BOOL, value_to_send,
00691 ERIPC_TYPE_INVALID);
00692 return rc;
00693 }
00694
00695 eripc_error_t eripc_send_string(eripc_context_t *context,
00696 eripc_handler_t *reply_handler,
00697 const void *user_data,
00698 eripc_bus_t bus_type,
00699 const char *destination,
00700 const char *message_name,
00701 const char *string_to_send)
00702 {
00703 eripc_error_t rc;
00704 rc = eripc_send_varargs(context, reply_handler, user_data,
00705 bus_type, destination, message_name,
00706 ERIPC_TYPE_STRING, string_to_send,
00707 ERIPC_TYPE_INVALID);
00708 return rc;
00709 }
00710
00711 eripc_error_t eripc_send_int(eripc_context_t *context,
00712 eripc_handler_t *reply_handler,
00713 const void *user_data,
00714 eripc_bus_t bus_type,
00715 const char *destination,
00716 const char *message_name,
00717 int value_to_send)
00718 {
00719 eripc_error_t rc;
00720 rc = eripc_send_varargs(context, reply_handler, user_data,
00721 bus_type, destination, message_name,
00722 ERIPC_TYPE_INT, value_to_send,
00723 ERIPC_TYPE_INVALID);
00724 return rc;
00725 }
00726
00727 eripc_error_t eripc_send_bool(eripc_context_t *context,
00728 eripc_handler_t *reply_handler,
00729 const void *user_data,
00730 eripc_bus_t bus_type,
00731 const char *destination,
00732 const char *message_name,
00733 gboolean value_to_send)
00734 {
00735 eripc_error_t rc;
00736 rc = eripc_send_varargs(context, reply_handler, user_data,
00737 bus_type, destination, message_name,
00738 ERIPC_TYPE_BOOL, value_to_send,
00739 ERIPC_TYPE_INVALID);
00740 return rc;
00741 }
00742
00743 eripc_error_t eripc_event_info_free(eripc_context_t *context,
00744 eripc_event_info_t *info)
00745 {
00746 UNUSED(context);
00747 if (info != NULL) {
00748 if (info->args != NULL) {
00749 free((char*)info->args);
00750 }
00751
00752 if (info->dbus_message != NULL) {
00753 dbus_message_unref((DBusMessage *)info->dbus_message);
00754 }
00755
00756 free(info);
00757 }
00758
00759 return ERIPC_ERROR_SUCCESS;
00760 }
00761
00762 static
00763 eripc_error_t _reply_helper(eripc_context_t *context,
00764 const char *message_id,
00765 eripc_data_t arg_type, va_list va_args)
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
00778
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
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 }
00831
00832 eripc_error_t eripc_reply_varargs(eripc_context_t *context,
00833 const char *message_id,
00834 eripc_data_t arg_type, ...)
00835 {
00836 va_list va_args;
00837 eripc_error_t rc;
00838
00839 va_start(va_args, arg_type);
00840 rc = _reply_helper(context, message_id,
00841 arg_type, va_args);
00842 va_end(va_args);
00843 return rc;
00844 }
00845
00846 eripc_error_t eripc_reply_string(eripc_context_t *context,
00847 const char *message_id,
00848 const char *string)
00849 {
00850 eripc_error_t rc;
00851 rc = eripc_reply_varargs(context, message_id,
00852 ERIPC_TYPE_STRING, string,
00853 ERIPC_TYPE_INVALID);
00854 return rc;
00855 }
00856
00857 eripc_error_t eripc_reply_int(eripc_context_t *context,
00858 const char *message_id,
00859 int value)
00860 {
00861 eripc_error_t rc;
00862 rc = eripc_reply_varargs(context, message_id,
00863 ERIPC_TYPE_INT, value,
00864 ERIPC_TYPE_INVALID);
00865 return rc;
00866 }
00867
00868 eripc_error_t eripc_reply_bool(eripc_context_t *context,
00869 const char *message_id,
00870 gboolean value)
00871 {
00872 eripc_error_t rc;
00873 rc = eripc_reply_varargs(context, message_id,
00874 ERIPC_TYPE_BOOL, value,
00875 ERIPC_TYPE_INVALID);
00876 return rc;
00877 }
00878
00879 eripc_error_t eripc_reply_error(eripc_context_t *context,
00880 const char *message_id,
00881 const char *name,
00882 const char *message)
00883 {
00884 DBusConnection *conn;
00885 DBusMessage *reply;
00886 dbus_bool_t ret;
00887 char sender[MAX_SVC_LEN + 1], error_name[MAX_ERROR_LEN + 1];
00888 int serial;
00889 eripc_bus_t bus_type;
00890
00891 if (context == NULL || name == NULL || message_id == NULL) {
00892 return ERIPC_ERROR_INVALID;
00893 }
00894 if (context->error_dummy == NULL) {
00895
00896
00897 ULOG_ERR_F("error_dummy has not been created");
00898 return ERIPC_ERROR;
00899 }
00900
00901 _parse_id(message_id, &bus_type, sender, &serial);
00902 assert(bus_type == ERIPC_BUS_SYSTEM || bus_type == ERIPC_BUS_SESSION);
00903
00904 if (bus_type == ERIPC_BUS_SYSTEM) {
00905 conn = context->sys_conn;
00906 } else {
00907 conn = context->conn;
00908 }
00909 if (!dbus_connection_get_is_connected(conn)) {
00910 ULOG_ERR_F("connection %p is not open", conn);
00911 return ERIPC_ERROR_INVALID;
00912 }
00913
00914 make_default_error_name(context->service, name, error_name);
00915
00916
00917 reply = dbus_message_copy(context->error_dummy);
00918 if (reply == NULL) {
00919 ULOG_ERR_F("dbus_message_copy failed");
00920 return ERIPC_ERROR_OOM;
00921 }
00922 if (!dbus_message_set_destination(reply, sender)) {
00923 ULOG_ERR_F("dbus_message_set_destination failed");
00924 goto unref_and_exit;
00925 }
00926 if (!dbus_message_set_reply_serial(reply, serial)) {
00927 ULOG_ERR_F("dbus_message_set_reply_serial failed");
00928 goto unref_and_exit;
00929 }
00930 if (!dbus_message_set_error_name(reply, error_name)) {
00931 ULOG_ERR_F("dbus_message_set_error_name failed");
00932 goto unref_and_exit;
00933 }
00934
00935 if (message != NULL) {
00936 ret = dbus_message_append_args(reply, DBUS_TYPE_STRING,
00937 &message,
00938 DBUS_TYPE_INVALID);
00939 if (!ret) {
00940 ULOG_ERR_F("dbus_message_append_args failed");
00941 goto unref_and_exit;
00942 }
00943 }
00944
00945 if (!dbus_connection_send(conn, reply, NULL)) {
00946 ULOG_ERR_F("dbus_connection_send failed");
00947 goto unref_and_exit;
00948 }
00949 dbus_message_unref(reply);
00950 return ERIPC_ERROR_SUCCESS;
00951
00952 unref_and_exit:
00953 dbus_message_unref(reply);
00954 return ERIPC_ERROR_OOM;
00955 }