message.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:  message.c
00020  
00021   Description: Functions used for manage messages.
00022  
00023   Version:  1.0
00024   Created:  11/03/07 19:25:58 CEST
00025   Revision:  
00026         0 - created (Ge@@ru)
00027  
00028   Author:   Daniele Rondina aka ge@@ru, (geaaru@gmail.com) 
00029   Company:  
00030   License:  GPL 2.0
00031 */
00032 
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <string.h>
00041 // easydbus includes 
00042 #include "easydbus-core.h"
00043 #include "message_internal.h"
00044 #include "debug.h"
00045 
00058 inline int
00059 easydbus_message_send (struct EasyDbus_core *core, DBusMessage * msg, 
00060                        unsigned int flush, dbus_uint32_t *mserial)
00061 {
00062    EasyDbusDebug ("Message serial %d", 
00063                    mserial ? *mserial : 0);
00064    
00065    if (!dbus_connection_send (core->conn, msg, mserial)) {
00066       fprintf (stderr, "Could not send message on D-BUS.");
00067       return -1;
00068    }
00069 
00070    EasyDbusDebug ("Message serial %d", 
00071                    mserial ? *mserial : 0);
00072 
00073    if (flush)
00074       dbus_connection_flush (core->conn);
00075 
00076    return 0;
00077 }
00078 
00079 
00086 int 
00087 easydbus_message_send_async (struct EasyDbus_core *core, 
00088                              struct EasyDbus_Pending *p,
00089                              DBusMessage * msg)
00090 {
00091    if (!core || !p || !msg)
00092       return -1;
00093 
00094    if (!dbus_connection_send_with_reply (core->conn, msg, 
00095                                          &(p->pcall), p->timeout))
00096       return -1;
00097 
00098    EasyDbusDebug ("Created Pending Object (%p)", p->pcall);
00099 
00100    if (!dbus_pending_call_set_notify (p->pcall, 
00101                                       easydbus_pending_msg_handler, 
00102                                       (void *) p, NULL))
00103       return -1;
00104 
00105    EasyDbusDebug ("Message insert on queue");
00106    return 0;
00107 }
00108 
00116 void 
00117 easydbus_pending_msg_handler (DBusPendingCall *pcall, 
00118                               void *data)
00119 {
00120    DBusMessage *reply_msg = NULL;
00121    EasyDbus_reply *reply = NULL;
00122    struct EasyDbus_Pending *p, **temp;
00123    
00124    p = (struct EasyDbus_Pending *) data;
00125    EasyDbusDebug ("Use Pending Object (%p)", pcall);
00126 
00127    if (!p || p->pcall != pcall) {
00128       EasyDbusDebug ("Error data mismatch");
00129       return;
00130    }
00131 
00132    // initialize retry field of method
00133    p->message->retry = 0;
00134    reply_msg = dbus_pending_call_steal_reply(pcall);
00135    if (reply_msg) {
00136       // there is a reply
00137       reply = easydbus_reply_create_skeleton ();
00138       if (!reply) 
00139          goto error;
00140 
00141       if (easydbus_build_skeleton_data (reply_msg, EASYDBUS_ET_REPLY,
00142                                         reply))
00143          goto error;
00144       p->message->reply = reply;
00145    } 
00146    // else a timeout is handled.
00147 
00148    p->p_cb ((EasyDbus_conn *) p->core, p->message,
00149             p->closure);
00150 
00151    if (p->message->retry) {
00152       // retry method call
00153       if (p->message->reply) {
00154          easydbus_reply_free_skeleton (p->message->reply);
00155          p->message->reply = NULL;
00156       }
00158       dbus_pending_call_unref (p->pcall);
00159    }
00160    else {
00161       // remove pending object from list
00162       for (temp = &(p->core->pending_msgs); *temp;
00163            temp = &(*temp)->next)
00164          if (*temp == p) {
00165             *temp = (*temp)->next;
00166             break;
00167          }
00168       if (reply_msg)
00169          dbus_message_unref (reply_msg);
00170       easydbus_pending_destroy (p);
00171    }
00172 
00173    return;
00174 error:
00175    EasyDbusDebug ("Error not managed");
00176    if (reply) 
00177       easydbus_reply_free_skeleton (reply);
00178 }
00179 
00191 struct EasyDbus_Pending * 
00192 easydbus_pending_create_skeleton (struct EasyDbus_core *core,
00193                                   EasyDbus_method *method,
00194                                   easydbus_method_async_reply_cb_f p_cb,
00195                                   void *closure, int timeout)
00196 {
00197    struct EasyDbus_Pending *p;
00198 
00199    if (!core || !method)
00200       return NULL;
00201 
00202    p = (struct EasyDbus_Pending *) 
00203        malloc (sizeof (struct EasyDbus_Pending));
00204    
00205    if (!p) 
00206       return NULL;
00207    
00208    memset (p, 0, sizeof (struct EasyDbus_Pending));
00209 
00210    p->core = core;
00211    p->message = method;
00212    p->message_serial = 0;
00213    p->p_cb = p_cb;
00214    p->closure = closure;
00215    p->next = NULL;
00216    p->timeout = timeout;
00217    p->pcall = NULL;
00218   
00219    return p;
00220 }
00221 
00229 void
00230 easydbus_pending_destroy (struct EasyDbus_Pending *p) 
00231 {
00232    if (!p) return;
00233 
00234    if (p->message)
00235       easydbus_method_free_skeleton(p->message);
00236 
00237    if (p->pcall) {
00238       EasyDbusDebug ("Free EasyDbus_Pending object (%p)", p->pcall);
00239       dbus_pending_call_unref (p->pcall);
00240       p->pcall = NULL;
00241    }
00242 
00243    p->message = NULL;
00244    p->message_serial = 0;
00245    p->core = NULL;
00246    p->p_cb = NULL;
00247    p->next = NULL;
00248    p->closure = NULL;
00249 
00250    free(p);
00251    
00252 }
00253 
00254 // vim: ts=3 shiftwidth=3 expandtab

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