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
00031 #include <string.h>
00032 #include <stdlib.h>
00033
00034 #include "easydbus-core.h"
00035 #include "debug.h"
00036 #include "utils.h"
00037 #include "reply_internal.h"
00038 #include "introspect_internal.h"
00039 #include "register_obj_internal.h"
00040 #include "message_internal.h"
00041
00042
00043 static DBusHandlerResult
00044 easydbus_signal_handler (struct EasyDbus_core *,
00045 DBusMessage *);
00046
00047 static DBusHandlerResult
00048 easydbus_error_handler (struct EasyDbus_core *,
00049 DBusMessage *);
00050
00051 static DBusHandlerResult
00052 easydbus_reply_handler (struct EasyDbus_core *,
00053 DBusMessage *);
00054
00077 DBusHandlerResult
00078 easydbus_obj_path_msg_function (DBusConnection * conn,
00079 DBusMessage * msg,
00080 void *user_data)
00081 {
00082 struct EasyDbus_core *core = (struct EasyDbus_core *) user_data;
00083 struct EasyDbus_object_box *obj = NULL;
00084 struct EasyDbus_obj_interface *interface = NULL;
00085 EasyDbus_reply *reply = NULL;
00086 const char *msg_member = NULL;
00087 const char *msg_interface = NULL;
00088 const char *msg_path = NULL;
00089 int ret_val = -1;
00090
00091
00092 if (!msg || !conn || !user_data ||
00093 (dbus_message_get_type (msg) !=
00094 DBUS_MESSAGE_TYPE_METHOD_CALL)) {
00095 EasyDbusDebug ("Error");
00096
00097 return DBUS_HANDLER_RESULT_HANDLED;
00098 }
00099
00100 msg_path = dbus_message_get_path (msg);
00101 msg_member = dbus_message_get_member (msg);
00102 msg_interface = dbus_message_get_interface (msg);
00103
00104 EasyDbusDebug ("Message %s for \n"
00105 "path = %s\n"
00106 "interface = %s\n"
00107 "member = %s\n",
00108 dbus_message_type_to_string (
00109 dbus_message_get_type (msg)),
00110 msg_path, msg_interface, msg_member);
00111
00112
00113
00114 obj = easydbus_get_obj (core->objects, msg_path);
00115 if (!obj)
00116 goto obj_not_found;
00117
00118
00119
00120 for (interface = obj->core.handled_interfaces;
00121 interface; interface = interface->next) {
00122 reply = easydbus_verify_match_and_prepare_reply (interface,
00123 msg, msg_interface,
00124 msg_member, &ret_val);
00125 if (ret_val == EASYDBUS_METHOD_HANDLED ||
00126 ret_val == EASYDBUS_FAILURE_HANDLED) {
00127 easydbus_reply_send (core, msg, reply);
00128 easydbus_reply_free_skeleton (reply);
00129 return DBUS_HANDLER_RESULT_HANDLED;
00130
00131 }
00132 else if (ret_val == EASYDBUS_SIGNAL_HANDLED ||
00133 ret_val == EASYDBUS_METHOD_RETURN_HANDLED) {
00134 easydbus_reply_send_error (core, msg,
00135 "Error",
00136 "Error: unpredictable error");
00137 return DBUS_HANDLER_RESULT_HANDLED;
00138 }
00139 }
00140
00141 obj_not_found:
00142
00143
00144 easydbus_reply_send_error (core, msg, "NotFound",
00145 "Error: method not found");
00146 return DBUS_HANDLER_RESULT_HANDLED;
00147 }
00148
00157 void
00158 easydbus_obj_path_unregister_function (DBusConnection * conn,
00159 void *user_data)
00160 {
00161 }
00162
00177 EasyDbus_reply *
00178 easydbus_verify_match_and_prepare_reply
00179 (struct EasyDbus_obj_interface *interface,
00180 DBusMessage * msg, const char *msg_interface,
00181 const char *member_name, int *return_value)
00182 {
00183 int callback_retvalue;
00184 struct EasyDbus_obj_method *method = NULL;
00185 EasyDbus_method *method_skeleton = NULL;
00186 EasyDbus_reply *reply = NULL;
00187
00188
00189 method = easydbus_obj_interface_get_method (member_name,
00190 msg_interface,
00191 interface);
00192 if (!method) {
00193 *return_value = EASYDBUS_METHOD_NOT_FOUND;
00194 goto not_found;
00195 }
00196
00197 method_skeleton = easydbus_method_build_skeleton (msg);
00198 if (!method_skeleton) {
00199 *return_value = EASYDBUS_ERROR;
00200 goto not_found;
00201 }
00202 callback_retvalue = (int)
00203 method->method_callback (method_skeleton);
00204
00205 if (callback_retvalue == EASYDBUS_METHOD_HANDLED) {
00206 reply = method_skeleton->reply;
00207 *return_value = callback_retvalue;
00208 }
00209 else if (callback_retvalue == EASYDBUS_FAILURE_HANDLED)
00210 if (method_skeleton->reply) {
00211 reply = method_skeleton->reply;
00212 *return_value = callback_retvalue;
00213 }
00214 method_skeleton->reply = NULL;
00215 easydbus_method_free_skeleton (method_skeleton);
00216
00217 return reply;
00218
00219 not_found:
00220
00221 return NULL;
00222 }
00223
00224
00234 static DBusHandlerResult
00235 easydbus_signal_handler (struct EasyDbus_core *core,
00236 DBusMessage *msg)
00237 {
00238 struct EasyDbus_ext_signal *el = NULL;
00239 struct EasyDbus_signal *handled_signal = NULL;
00240 const char *msg_member = NULL;
00241 const char *msg_interface = NULL;
00242 const char *msg_path = NULL;
00243 const char *msg_sender = NULL;
00244 const char *msg_destination = NULL;
00245
00246
00247 msg_member = dbus_message_get_member (msg);
00248
00249 msg_interface = dbus_message_get_interface (msg);
00250
00251 msg_path = dbus_message_get_path (msg);
00252
00253 msg_sender = dbus_message_get_sender (msg);
00254
00255 msg_destination = dbus_message_get_destination (msg);
00256
00257 if (core->handled_signal)
00258 for (el = core->handled_ext_signals; el; el = el->next)
00259 if (!easydbus_verify_signal_match
00260 (msg_member, msg_interface, msg_path, msg_sender,
00261 msg_destination, el)) {
00262 EasyDbusDebug ("Extern Signal Handled");
00263 handled_signal = easydbus_signal_build_skeleton (msg);
00264 if (handled_signal) {
00266 if (msg_sender)
00267 easydbus_signal_set_sender (handled_signal, msg_sender);
00268 el->signal_callback ((struct EasyDbus_conn *) core,
00269 handled_signal);
00270 easydbus_signal_free_skeleton (handled_signal);
00271 }
00272 goto out;
00273 }
00274
00275 EasyDbusDebug ("\n"
00276 "- Drop signal -------------------\n"
00277 "path = %s\n"
00278 "interface = %s\n"
00279 "member = %s\n"
00280 "sender = %s\n"
00281 "destination = %s\n"
00282 "---------------------------------\n",
00283 msg_path, msg_interface, msg_member,
00284 msg_sender, msg_destination);
00285
00286 out:
00287 return DBUS_HANDLER_RESULT_HANDLED;
00288 }
00289
00300 static DBusHandlerResult
00301 easydbus_error_handler (struct EasyDbus_core *core,
00302 DBusMessage *msg)
00303 {
00304 EasyDbus_reply *error_message = NULL;
00305 struct EasyDbus_Pending *p = NULL, **pp = NULL;
00306 const char *msg_interface = NULL;
00307 const char *msg_path = NULL;
00308 const char *msg_sender = NULL;
00309 dbus_uint32_t serial = 0;
00310
00311
00312 msg_interface = dbus_message_get_interface (msg);
00313
00314 msg_path = dbus_message_get_path (msg);
00315
00316 msg_sender = dbus_message_get_sender (msg);
00317
00318 EasyDbusDebug ("\n"
00319 "- Handle error message ----------\n"
00320 "path = %s\n"
00321 "interface = %s\n"
00322 "member = %s\n"
00323 "sender = %s\n"
00324 "---------------------------------\n",
00325 msg_path, msg_interface,
00326 dbus_message_get_member (msg), msg_sender);
00327
00328 error_message = easydbus_reply_create_skeleton ();
00329 if (!error_message)
00330 goto need_memory;
00331
00332 easydbus_reply_set_type (error_message, EASYDBUS_ET_FAILURE);
00333
00334 if (msg_interface)
00335 if (easydbus_reply_set_interface (error_message, msg_interface))
00336 goto need_memory;
00337 if (msg_path)
00338 if (easydbus_reply_set_path (error_message, msg_path))
00339 goto need_memory;
00340 if (msg_sender)
00341 if (easydbus_reply_set_sender (error_message, msg_sender))
00342 goto need_memory;
00343
00344 easydbus_build_skeleton_data (msg, EASYDBUS_ET_FAILURE,
00345 error_message);
00346
00347 serial = dbus_message_get_reply_serial (msg);
00348 EasyDbusDebug ("Message serial = %d", serial);
00349
00350 for (p = core->pending_msgs; p; p = p->next)
00351
00352
00353 if (!p->pcall && p->message_serial == serial) {
00354 p->message->reply = error_message;
00355
00356 for (pp = &(p->core->pending_msgs); *pp; pp = &(*pp)->next)
00357 if (*pp == p) {
00358 *pp = (*pp)->next;
00359 break;
00360 }
00361 if (core->user_data.reply_message_cb)
00362 core->user_data.reply_message_cb ((EasyDbus_conn *) core,
00363 (const EasyDbus_method *) p->message,
00364 p->closure);
00365 break;
00366 }
00367
00368 if (p)
00369
00370
00371 easydbus_pending_destroy (p);
00372 else {
00373 if (core->user_data.error_message_cb)
00374 core->user_data.error_message_cb ((EasyDbus_conn *) core,
00375 (const EasyDbus_reply *) error_message,
00376 core->user_data.error_message_closure);
00377 easydbus_reply_free_skeleton (error_message);
00378 }
00379
00380 return DBUS_HANDLER_RESULT_HANDLED;
00381
00382 need_memory:
00383 if (error_message)
00384 easydbus_reply_free_skeleton (error_message);
00385
00386 return DBUS_HANDLER_RESULT_NEED_MEMORY;
00387 }
00388
00401 static DBusHandlerResult
00402 easydbus_reply_handler (struct EasyDbus_core *core,
00403 DBusMessage *msg)
00404 {
00405 EasyDbus_reply *reply = NULL;
00406 struct EasyDbus_Pending *p = NULL, **pp = NULL;
00407 const char *msg_member = NULL;
00408 const char *msg_interface = NULL;
00409 const char *msg_path = NULL;
00410 const char *msg_sender = NULL;
00411 dbus_uint32_t serial = 0;
00412
00413
00414 msg_member = dbus_message_get_member (msg);
00415
00416 msg_interface = dbus_message_get_interface (msg);
00417
00418 msg_path = dbus_message_get_path (msg);
00419
00420 msg_sender = dbus_message_get_sender (msg);
00421
00422 EasyDbusDebug ("\n"
00423 "- Message reply -----------------\n"
00424 "path = %s\n"
00425 "interface = %s\n"
00426 "member = %s\n"
00427 "sender = %s\n"
00428 "---------------------------------\n",
00429 msg_path, msg_interface, msg_member, msg_sender);
00430
00431 reply = easydbus_reply_create_skeleton ();
00432 if (!reply)
00433 goto need_memory;
00434
00435 easydbus_reply_set_type (reply, EASYDBUS_ET_REPLY);
00436
00437 if (msg_interface)
00438 if (easydbus_reply_set_interface (reply, msg_interface))
00439 goto need_memory;
00440 if (msg_path)
00441 if (easydbus_reply_set_path (reply, msg_path))
00442 goto need_memory;
00443 if (msg_sender)
00444 if (easydbus_reply_set_sender (reply, msg_sender))
00445 goto need_memory;
00446
00447 easydbus_build_skeleton_data (msg, EASYDBUS_ET_REPLY,
00448 reply);
00449
00450 serial = dbus_message_get_reply_serial (msg);
00451 EasyDbusDebug ("Message serial = %d", serial);
00452
00453 for (p = core->pending_msgs; p; p = p->next)
00454
00455
00456 if (!p->pcall && p->message_serial == serial) {
00457 p->message->reply = reply;
00458
00459 for (pp = &(p->core->pending_msgs); *pp; pp = &(*pp)->next)
00460 if (*pp == p) {
00461 *pp = (*pp)->next;
00462 break;
00463 }
00464 if (core->user_data.reply_message_cb)
00465 core->user_data.reply_message_cb ((EasyDbus_conn *) core,
00466 (const EasyDbus_method *) p->message,
00467 p->closure);
00468 break;
00469 }
00470
00471 if (p)
00472 easydbus_pending_destroy (p);
00473 else
00474 easydbus_reply_free_skeleton (reply);
00475
00476 return DBUS_HANDLER_RESULT_HANDLED;
00477
00478 need_memory:
00479
00480 if (reply)
00481 easydbus_reply_free_skeleton (reply);
00482
00483 return DBUS_HANDLER_RESULT_NEED_MEMORY;
00484 }
00485
00508 DBusHandlerResult
00509 easydbus_core_filter_func (DBusConnection * conn,
00510 DBusMessage * msg, void *user_data)
00511 {
00512 struct EasyDbus_core *core =
00513 (struct EasyDbus_core *) user_data;
00514
00515 if (dbus_message_is_signal (msg,
00516 DBUS_INTERFACE_LOCAL,
00517 "Disconnected")) {
00518 EasyDbusDebug ("Error DBUS disconnected!!!");
00519
00520 if (core->user_data.error_cb)
00521 core->user_data.error_cb ((EasyDbus_conn *) user_data,
00522 core->user_data.error_closure);
00523 return DBUS_HANDLER_RESULT_HANDLED;
00524 }
00525
00526 EasyDbusDebug ("Core filter analysis");
00527 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00528 }
00529
00539 DBusHandlerResult
00540 easydbus_filter_func (DBusConnection * conn,
00541 DBusMessage * msg, void *user_data)
00542 {
00543 struct EasyDbus_core *core = (struct EasyDbus_core *) user_data;
00544 int msg_type;
00545
00546 if (!conn || !msg || !user_data) {
00547 EasyDbusDebug ("Error");
00548 return DBUS_HANDLER_RESULT_HANDLED;
00549 }
00550
00551 EasyDbusDebug ("Message under filter analysis");
00552
00553
00554 msg_type = dbus_message_get_type (msg);
00555
00556 if (msg_type == DBUS_MESSAGE_TYPE_SIGNAL)
00557 return easydbus_signal_handler (core, msg);
00558 else if (msg_type == DBUS_MESSAGE_TYPE_ERROR)
00559 return easydbus_error_handler (core, msg);
00560 else if (msg_type == DBUS_MESSAGE_TYPE_METHOD_RETURN)
00561 return easydbus_reply_handler (core, msg);
00562
00563 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00564 }
00565
00577 int
00578 easydbus_verify_signal_match (const char *member,
00579 const char *interface,
00580 const char *path,
00581 const char *sender,
00582 const char *destination,
00583 struct EasyDbus_ext_signal *el)
00584 {
00585 if (!el || !member )
00586 return -1;
00587
00588 if (strcmp (el->signal, member))
00589 return -1;
00590
00591 if (interface && el->interface)
00592 if (strcmp (el->interface, interface))
00593 return -1;
00594
00595 if (path && el->path)
00596 if (strcmp (el->path, path))
00597 return -1;
00598
00599 if (sender && el->sender)
00600 if (strcmp (el->sender, sender))
00601 return -1;
00602
00603 if (destination && el->destination)
00604 if (strcmp (el->destination, destination))
00605 return -1;
00606
00607 return 0;
00608 }
00609
00610