method.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:  method.c
00020  
00021   Description:  
00022  
00023   Version:  1.0
00024   Created:  06/07/07 23:23:26 CEST
00025   Revision: 
00026     - 0 created (Ge@@ru)
00027     - 1 add doxygen documentation and added support
00028         for opaque structs (Ge@@ru) - 11/02/07 19:12:00 CEST
00029  
00030   Author:   Daniele Rondina aka Ge@@ru (geaaru@gmail.com) 
00031   License:  GPL 2.0
00032 */
00033 
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 // easydbus includes
00044 #include "easydbus-core.h"
00045 #include "elem_internal.h"
00046 #include "message_internal.h"
00047 #include "debug.h"
00048 #include "monitor_internal.h"
00049 
00056 inline void
00057 easydbus_method_free_skeleton (EasyDbus_method * method) 
00058 {
00059    struct EasyDbus_elem *el = NULL;
00060 
00061    if (method == NULL)
00062       return;
00063 
00064    if (method->name != NULL)
00065       free (method->name);
00066    if (method->path != NULL)
00067       free (method->path);
00068    if (method->destination != NULL)
00069       free (method->destination);
00070    if (method->interface != NULL)
00071       free (method->interface);
00072 
00073    method->name = method->path = method->interface = NULL;
00074 
00075    while (method->args) {
00076       if (method->first != NULL) {
00077          el = method->first;
00078          method->first = method->first->next;
00079          easydbus_elem_free (el);
00080       }
00081       method->args--;
00082    }
00083 
00084    if (method->reply != NULL)
00085       easydbus_reply_free_skeleton (method->reply);
00086 
00087    free (method);
00088 }
00089 
00097 inline int
00098 easydbus_method_set_reply (EasyDbus_method * method,
00099                            EasyDbus_reply * reply)
00100 {
00101    if (reply == NULL || method == NULL)
00102       return -1;
00103 
00104    method->reply = reply;
00105 
00106    return 0;
00107 }
00108 
00115 inline const EasyDbus_reply *
00116 easydbus_method_get_reply (EasyDbus_method * method)
00117 {
00118    if (method == NULL)
00119       return NULL;
00120 
00121    return method->reply;
00122 }
00123 
00133 EasyDbus_method *
00134 easydbus_method_create_skeleton (char *destination,
00135                                  char *path, char *interface,
00136                                  char *method)
00137 {
00138    int len = 0;
00139    struct EasyDbus_method *m = NULL;
00140 
00141    m = (struct EasyDbus_method *)
00142       malloc (sizeof (struct EasyDbus_method));
00143 
00144    if (m == NULL || path == NULL)
00145       return NULL;
00146 
00147    memset (m, 0, sizeof (struct EasyDbus_method));
00148 
00149    m->name = m->path = m->destination = m->interface = NULL;
00150    m->first = NULL;
00151    m->reply = NULL;
00152    m->retry = 0;
00153 
00154    len = strlen (method) + 1;
00155    m->name = (char *) malloc (len);
00156    if (!m->name)
00157       goto out_of_memory_error;
00158    EASYDBUS_MEMCOPY (m->name, method, len)
00159 
00160    if (interface) {
00161       len = strlen (interface) + 1;
00162       m->interface = (char *) malloc (len);
00163       if (!m->interface)
00164          goto out_of_memory_error;
00165       EASYDBUS_MEMCOPY (m->interface, interface, len);
00166    }
00167 
00168    len = strlen (path) + 1;
00169    m->path = (char *) malloc (len);
00170    if (!m->path)
00171       goto out_of_memory_error;
00172    EASYDBUS_MEMCOPY (m->path, path, len);
00173 
00174    if (destination) {
00175       len = strlen (destination) + 1;
00176       m->destination = (char *) malloc (len);
00177       if (!m->destination)
00178          goto out_of_memory_error;
00179       EASYDBUS_MEMCOPY (m->destination, destination, len);
00180    }
00181 
00182    return m;
00183 
00184  out_of_memory_error:
00185    if (m->path)
00186       free (m->path);
00187    if (m->interface)
00188       free (m->interface);
00189    if (m->name)
00190       free (m->name);
00191    if (m)
00192       free (m);
00193    return NULL;
00194 }
00195 
00204 EasyDbus_method *
00205 easydbus_method_build_skeleton (DBusMessage * msg)
00206 {
00207    struct EasyDbus_method *method = NULL;
00208 
00209    EasyDbusDebug ("Build Method Struct");
00210 
00211    method =
00212      easydbus_method_create_skeleton (
00213                                       // destination
00214                                       (char *) dbus_message_get_destination (msg),
00215                                       // path
00216                                       (char *) dbus_message_get_path (msg),
00217                                       // interface
00218                                       (char *) dbus_message_get_interface (msg),
00219                                       // method
00220                                       (char *) dbus_message_get_member (msg));
00221 
00222    if (method == NULL)
00223       return NULL;
00224 
00225    if (easydbus_build_skeleton_data (msg, EASYDBUS_ET_METHOD, method))
00226       goto out_of_memory_error;
00227 
00228    EasyDbusDebug ("Created method object");
00229 
00230    return method;
00231 
00232  out_of_memory_error:
00233    if (method != NULL)
00234       easydbus_method_free_skeleton (method);
00235    return NULL;
00236 }
00237 
00246 const char *
00247 easydbus_method_get_interface (EasyDbus_method * method)
00248 {
00249    return (method ? (const char *) method->interface : NULL);
00250 }
00251 
00260 const char *
00261 easydbus_method_get_name (EasyDbus_method * method)
00262 {
00263    return (method ? (const char *) method->name : NULL);
00264 }
00265 
00274 const char *
00275 easydbus_method_get_path (EasyDbus_method * method)
00276 {
00277    return (method ? (const char *) method->path : NULL);
00278 }
00279 
00288 const char *
00289 easydbus_method_get_destination (EasyDbus_method * method)
00290 {
00291    return (method ? (const char *) method->destination : NULL);
00292 }
00293 
00302 int
00303 easydbus_method_get_args (EasyDbus_method * method)
00304 {
00305    return (method ? method->args : -1);
00306 }
00307 
00318 const EasyDbus_elem *
00319 easydbus_method_get_element (EasyDbus_method * method, unsigned int n)
00320 {
00321    return ((!method || n > method->args) ? NULL :
00322            easydbus_elem_get_element (method->first, n));
00323 }
00324 
00333 inline DBusMessage *
00334 create_method_msg (struct EasyDbus_core * core,
00335                    struct EasyDbus_method * method)
00336 {
00337 
00338    /* create msg */
00339    DBusMessage *msg =
00340       dbus_message_new_method_call (method->destination,
00341                                     method->path,
00342                                     method->interface,
00343                                     method->name);
00344 
00345    if (msg == NULL)
00346       return msg;
00347 
00348    /* add method data if there are */
00349    if (method->args)
00350       add_elems_to_msg (msg, method->first);
00351 
00352    return msg;
00353 }
00354 
00369 int
00370 easydbus_method_send_async_with_notify (EasyDbus_conn *conn,
00371                                         EasyDbus_method *method,
00372                                         easydbus_method_async_reply_cb_f r_cb,
00373                                         void *closure,
00374                                         int timeout)
00375 {
00376    DBusMessage *msg = NULL;
00377    struct EasyDbus_core *core = 
00378       (struct EasyDbus_core *) conn;
00379    struct EasyDbus_Pending *p = NULL;
00380 
00381    if (!conn || !method || !r_cb)
00382       return -1;
00383 
00384    p = easydbus_pending_create_skeleton (core, method, r_cb,
00385                                          closure, timeout);
00386    if (!p) goto error;
00387 
00388    msg = create_method_msg (core, method);
00389    if (!msg) goto error;
00390 
00391    if (easydbus_message_send_async(core, p, msg))
00392       goto error;
00393 
00394    // add EasyDbus_Pending object to list
00395    if (core->pending_msgs)
00396       p->next = core->pending_msgs;
00397    core->pending_msgs = p;
00398 
00399    dbus_message_unref (msg);
00400    return 0;
00401 
00402 error:
00403    if (p) {
00405       p->message = NULL;
00406       easydbus_pending_destroy (p);
00407    }
00408    if (msg)
00409       dbus_message_unref(msg);
00410    return -1;
00411 }
00412 
00422 int
00423 easydbus_method_send_async (EasyDbus_conn * conn, 
00424                             EasyDbus_method * method,
00425                             void *closure)
00426 {
00427    struct EasyDbus_core *core =
00428       (struct EasyDbus_core *) conn;
00429    struct EasyDbus_Pending *p = NULL;
00430    DBusMessage *msg = NULL;
00431 
00432    if (!conn || !method)
00433       return -1;
00434 
00435    p = easydbus_pending_create_skeleton (core, method, NULL,
00436                                          closure, 0);
00437    if (!p) goto error;
00438 
00439    msg = create_method_msg (core, method);
00440 
00441    if (!msg) {
00442       EasyDbusDebug ("Error on create method message");
00443       goto error;
00444    }
00445 
00446    if (easydbus_message_send(core, msg, 0, &p->message_serial)) {
00447       EasyDbusDebug ("Error on send message");
00448       goto error;
00449    }
00450 
00451    // add EasyDbus_Pending object to list
00452    if (core->pending_msgs)
00453       p->next = core->pending_msgs;
00454    core->pending_msgs = p;
00455 
00456    dbus_message_unref (msg);
00457 
00458    return 0;
00459 error:
00460    if (p) {
00462       p->message = NULL;
00463       easydbus_pending_destroy (p);
00464    }
00465    if (msg)
00466       dbus_message_unref(msg);
00467 
00468    return -1;
00469 }
00470 
00481 enum easydbus_ret_values
00482 easydbus_method_send_blocking (EasyDbus_conn * conn, 
00483                                EasyDbus_method * method,
00484                                int timeout) 
00485 {
00486    struct EasyDbus_core *core =
00487       (struct EasyDbus_core *) conn;
00488    int ret_val = EASYDBUS_METHOD_NOT_SENT;
00489 
00490    if (!conn || !method)
00491       return EASYDBUS_ERROR;
00492 
00493    DBusMessage *msg = create_method_msg (core, method);
00494 
00495    if (!msg) {
00496       EasyDbusDebug ("Error on create method message");
00497       return EASYDBUS_ERROR;
00498    }
00499 
00500    if (!easydbus_send_method_withReply_Blocking
00501        (core, msg, method, timeout))
00502       ret_val = EASYDBUS_METHOD_SENT;
00503 
00504    dbus_message_unref (msg);
00505 
00506    return ret_val;
00507 }
00508 
00518 int
00519 easydbus_method_set_retry_flags (EasyDbus_method *method) 
00520 {
00521    if (!method)
00522       return -1;
00523 
00524    method->retry = 1;
00525    return 0;
00526 }
00527 
00528 // vim: ts=3 shiftwidth=3 expandtab

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