watch_events.c

Go to the documentation of this file.
00001 /*
00002  EasyDbus: DBUS Binding Library.
00003  Copyright (C) 2007  Daniele Rondina aka ge@@ru, geaaru@gmail.com 
00004 
00005  This program is free software; you can redistribute it and/or
00006  modify it under the terms of the GNU General Public License
00007  as published by the Free Software Foundation; either version 2
00008  of the License, or (at your option) any later version.
00009 
00010  This program is distributed in the hope that it will be useful,
00011  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  GNU General Public License for more details.
00014 
00015  You should have received a copy of the GNU General Public License
00016  along with this program; if not, write to the Free Software
00017  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018 
00019  Filename:  watch_events.c
00020  
00021  Description:  
00022  
00023  Version:  1.0
00024  Created:  09/18/07 10:57:24 CEST
00025  Revision:  none
00026  
00027  Author:   Daniele Rondina aka Ge@@ru (geaaru@gmail.com) 
00028  License:  GPL 2.0
00029 */
00030 
00036 #include <string.h>
00037 #include <stdlib.h>
00038 // easydbus includes
00039 #include "debug.h"
00040 #include "easydbus-core.h"
00041 #include "reply_internal.h"
00042 #include "monitor_internal.h"
00043 
00044 
00051 int
00052 easydbus_watcher_get_fd (EasyDbus_watcher * watcher)
00053 {
00054    if (watcher)
00055 #if defined(__DBUS_VERSION__) && (__DBUS_VERSION__ <= 102)
00056       return dbus_watch_get_fd (watcher->watch);
00057 #else
00058       return dbus_watch_get_unix_fd (watcher->watch);
00059 #endif
00060    return -1;
00061 }
00062 
00072 int 
00073 easydbus_object_handle_message (EasyDbus_conn * data, 
00074                                 int event_fd) 
00075 {
00076    struct EasyDbus_core *core = (struct EasyDbus_core *) data;
00077    struct EasyDbus_watcher *watch = NULL;
00078    int ret_val;
00079 
00080    if (data == NULL || event_fd < 0)
00081       return -1;
00082 
00083    watch = easydbus_watcher_get_from_fd (core->watcher, event_fd, 
00084                                          EASYDBUS_WATCHER_READABLE);
00085    if (watch == NULL)
00086       return -1;
00087 
00088    do {
00089       if (!dbus_watch_get_enabled (watch->watch)) {
00090          EasyDbusDebug ("Watch not enabled");
00091          return -1;
00092       }
00093       else
00094          dbus_watch_handle (watch->watch, DBUS_WATCH_READABLE);
00095       ret_val = dbus_connection_dispatch (core->conn);
00096       // this permit to call dbus_connection_dispatch
00097       // in the next step. See if it is needed a sleep.
00098       if (ret_val == DBUS_DISPATCH_NEED_MEMORY)
00099          return 0;
00100    } while (ret_val == DBUS_DISPATCH_DATA_REMAINS);
00101 
00102    return 0;
00103 }
00104 
00111 int 
00112 easydbus_object_main_loop (EasyDbus_conn * data) 
00113 {
00114    struct EasyDbus_core *core = (struct EasyDbus_core *) data;
00115    void *user_data;
00116 
00117    if (core == NULL || core->objects == NULL)
00118       return -1;
00119 
00120    if (!dbus_connection_get_object_path_data (core->conn,
00121                                               core->objects->core.
00122                                               path, &user_data)) {
00123       EasyDbusDebug ("Error on recover user data");
00124       return -1;
00125    }
00126 
00127    if (user_data != (void *) core) {
00128       EasyDbusDebug ("User data pointer wrong!");
00129    }
00130    EasyDbusDebug ("User data pointer is correct!");
00131 
00132    while (1) 
00133       dbus_connection_read_write_dispatch (core->conn, -1);
00134 
00135    return 0;
00136 }
00137 
00150 enum easydbus_ret_values
00151 easydbus_watch_method_blocking (EasyDbus_conn * conn,
00152                                 EasyDbus_method *method_container, 
00153                                 int timeout)
00154 {
00155    DBusMessage *msg;
00156    struct EasyDbus_core *core = (struct EasyDbus_core *) conn;
00157    int ret_val = EASYDBUS_METHOD_NOT_HANDLED;
00158 
00159    // blocking read of the next available message
00160    dbus_connection_read_write_dispatch (core->conn, timeout);
00161    msg = dbus_connection_pop_message (core->conn);
00162 
00163    // loop again if we haven't read a message
00164    if (!msg) {
00165       EasyDbusDebug ("Null Message");
00166       return EASYDBUS_METHOD_MSG_NULL;
00167    }
00168 
00169    EasyDbusDebug ("%s Message: member = %s\n"
00170                   "interface = %s\n"
00171                   "path = %s\n",
00172                   dbus_message_type_to_string (dbus_message_get_type
00173                                                (msg)),
00174                   dbus_message_get_member (msg),
00175                   dbus_message_get_interface (msg),
00176                   dbus_message_get_path (msg));
00177 
00178    // check if the message is a signal from the correct 
00179    // interface and with the correct name
00180    if (dbus_message_is_method_call (msg,
00181                                     method_container->interface,
00182                                     method_container->name)) {
00183       conn->received_msg++;
00184       // data->received_methods++;
00185       struct EasyDbus_method *temp =
00186          easydbus_method_build_skeleton (msg);
00187       easydbus_method_free_skeleton (temp);
00188       ret_val = EASYDBUS_METHOD_HANDLED;
00189    }
00190 
00191    if (msg)
00192       dbus_message_unref (msg);
00193 
00194    return ret_val;
00195 }
00196 
00209 enum easydbus_ret_values
00210 easydbus_watch_signal_blocking (EasyDbus_conn * data,
00211                                 EasyDbus_signal *signal_container, 
00212                                 int timeout)
00213 {
00214    DBusMessage *msg;
00215    struct EasyDbus_core *core = (struct EasyDbus_core *) data;
00216    int ret_val = EASYDBUS_SIGNAL_NOT_HANDLED;
00217 
00218    do {
00219       // blocking read of the next available message
00220       dbus_connection_read_write_dispatch (core->conn, timeout);
00221       msg = dbus_connection_pop_message (core->conn);
00222 
00223       // loop again if we haven't read a message
00224       // (a timeout is handled);
00225       if (!msg) {
00226          EasyDbusDebug ("Null Message");
00227          return EASYDBUS_SIGNAL_MSG_NULL;
00228       }
00229 
00230       EasyDbusDebug ("%s Message: member = %s\n"
00231                      "interface = %s\n"
00232                      "path = %s\n",
00233                      dbus_message_type_to_string
00234                      (dbus_message_get_type (msg)),
00235                      dbus_message_get_member (msg),
00236                      dbus_message_get_interface (msg),
00237                      dbus_message_get_path (msg));
00238 
00239       // check if the message is a signal from the correct 
00240       // interface and with the correct name
00241       if (dbus_message_is_signal (msg,
00242                                   signal_container->interface,
00243                                   signal_container->name)) {
00244          //data->received_msg++;
00245          data->received_signal++;
00246          // add arg of signal to signal container passed in input 
00247          easydbus_build_skeleton_data (msg, EASYDBUS_ET_SIGNAL,
00248                                        signal_container);
00249          ret_val = EASYDBUS_SIGNAL_HANDLED;
00250       }
00251 
00252       if (msg)
00253          dbus_message_unref (msg);
00254 
00255    } while (ret_val == EASYDBUS_SIGNAL_NOT_HANDLED);
00256 
00257    return ret_val;
00258 }
00259 
00272 int
00273 easydbus_watcher_enable (EasyDbus_conn * conn,
00274                          easydbus_watcher_add_cb_f watcher_add_cb,
00275                          easydbus_watcher_remove_cb_f watcher_remove_cb, 
00276                          void *closure)
00277 {
00278    struct EasyDbus_core *core = (struct EasyDbus_core *) conn;
00279    int ret_val;
00280 
00281    if (!conn || !watcher_add_cb || !watcher_remove_cb)
00282       return -1;
00283 
00284    conn->watcher_add_cb = watcher_add_cb;
00285    conn->watcher_remove_cb = watcher_remove_cb;
00286    conn->watcher_closure = closure;
00287 //#ifdef EASYDBUS_TESTING
00288 //   dbus_connection_set_dispatch_status_function
00289 //    (core->conn, easydbus_dispatch_status_callback,
00290 //     (void *) core, NULL);
00291 //#endif
00292    dbus_connection_set_watch_functions (core->conn,
00293                                         easydbus_add_watch_callback,
00294                                         easydbus_remove_watch_callback,
00295                                         easydbus_toggle_watch_callback,
00296                                         core, NULL);
00297 // dbus_connection_set_timeout_functions (core->conn,
00298 //    easydbus_add_timeout, 
00299 //    easydbus_remove_timeout, 
00300 //    easydbus_toggle_timeout, core,
00301 //    NULL);
00302 
00303    do {
00304       ret_val = dbus_connection_dispatch (core->conn);
00305    } while (ret_val == DBUS_DISPATCH_DATA_REMAINS);
00306 
00307 // dbus_connection_set_wakeup_main_function 
00308 // (core->conn,
00309 //    easydbus_wakeup_main_callback,
00310 // core, NULL);
00311 
00312    return 0;
00313 }
00314 
00324 int *
00325 easydbus_watcher_get_fd_list (EasyDbus_conn * data, 
00326                               int *num_fd)
00327 {
00328    int *list_fd = NULL, *fd = NULL;
00329    int i = 0;
00330    struct EasyDbus_watcher *watch = NULL;
00331    struct EasyDbus_core *core = (struct EasyDbus_core *) data;
00332 
00333    if (data == NULL || num_fd == NULL)
00334       return NULL;
00335 
00336    if (core->watcher == NULL)
00337       return NULL;
00338 
00339    // count watcher 
00340    watch = core->watcher;
00341    while (watch != NULL) {
00342       i++;
00343       watch = watch->next;
00344    }
00345 
00346    EasyDbusDebug ("Founded %d watcher", i);
00347 
00348    list_fd = (int *) malloc (sizeof (int) * i);
00349    if (list_fd == NULL)
00350       return NULL;
00351 
00352    memset (list_fd, 0, sizeof (int) * i);
00353 
00354    // save fd
00355    watch = core->watcher;
00356    fd = list_fd;
00357    while (watch != NULL) {
00358 #if defined(__DBUS_VERSION__) && (__DBUS_VERSION__ <= 102)
00359       *fd = dbus_watch_get_fd (watch->watch);
00360 #else
00361       *fd = dbus_watch_get_unix_fd(watch->watch);
00362 #endif
00363       fd++;
00364       watch = watch->next;
00365    }
00366    *num_fd = i;
00367    return list_fd;
00368 }
00369 // vim: ts=3 shiftwidth=3 expandtab

Generated on Thu Apr 10 10:00:18 2008 for EasyDbus-0.2 by  doxygen 1.5.4