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
00032
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <string.h>
00041
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
00133 p->message->retry = 0;
00134 reply_msg = dbus_pending_call_steal_reply(pcall);
00135 if (reply_msg) {
00136
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
00147
00148 p->p_cb ((EasyDbus_conn *) p->core, p->message,
00149 p->closure);
00150
00151 if (p->message->retry) {
00152
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
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