2 * Worldvisions Weaver Software:
3 * Copyright (C) 2004-2006 Net Integration Technologies, Inc.
6 * Copyright (C) 2007, Carillon Information Security Inc.
8 * This library is licensed under the LGPL, please read LICENSE for details.
10 * A WvDBusConn represents a connection to another application. Messages
11 * can be sent and received via this connection. In most cases, the
12 * other application is a message bus.
14 #ifndef __WVDBUSCONN_H
15 #define __WVDBUSCONN_H
17 #include "wvstreamclone.h"
19 #include "wvdbusmsg.h"
20 #include "wvhashtable.h"
23 #define WVDBUS_DEFAULT_TIMEOUT (300*1000)
28 * The data type of callbacks used by WvDBusConn::add_callback(). The
29 * return value should be true if the callback processes the message, false
32 typedef wv::function
<bool(WvDBusMsg
&)> WvDBusCallback
;
37 virtual ~IWvDBusAuth() { };
40 * Main action callback. Called whenever d seems to have data available.
41 * Return false if you're not yet authorized and need to be called again
42 * when data is available; return true if you're done.
44 * If authorization fails, call seterr on d with an appropriate error
47 virtual bool authorize(WvDBusConn
&c
) = 0;
49 // Returns the unix UID negotiated during authentication. Boring on the
50 // client side (generally just getuid()), more useful for the server.
51 virtual wvuid_t
get_uid() = 0;
55 class WvDBusClientAuth
: public IWvDBusAuth
60 virtual bool authorize(WvDBusConn
&c
);
61 virtual wvuid_t
get_uid();
65 class WvDBusConn
: public WvStreamClone
67 bool client
, authorized
, in_post_select
;
75 * Creates a new dbus connection using the given WvStreams moniker.
77 * WvDBus uses special monikers for the "standard" DBus buses:
78 * dbus:system, dbus:session, and dbus:starter. These correspond to
79 * DBUS_BUS_SYSTEM, DBUS_BUS_SESSION, and DBUS_BUS_STARTER, respectively.
81 * If a non-NULL _auth parameter is passed, the WvDBusConn object takes
82 * ownership of it and will delete it at some point (possibly before
83 * the WvDBusConn itself is destroyed).
85 WvDBusConn(WvStringParm moniker
, IWvDBusAuth
*_auth
= NULL
,
89 * Creates a new dbus connection from the given stream. Takes ownership
90 * of the stream and will WVRELEASE() it when done.
92 WvDBusConn(IWvStream
*_cloned
, IWvDBusAuth
*_auth
= NULL
,
95 void init(IWvDBusAuth
*_auth
, bool _client
);
98 * Release this connection. If this is the last owner of the associated
99 * DBusConnection object, the connection itself closes.
101 virtual ~WvDBusConn();
103 void set_uniquename(WvStringParm s
);
106 wvuid_t
get_uid() { return auth
? auth
->get_uid() : WVUID_INVALID
; }
108 void out(WvStringParm s
);
109 void out(WVSTRING_FORMAT_DECL
)
110 { return out(WvString(WVSTRING_FORMAT_CALL
)); }
114 * Request the given service name on DBus. There's no guarantee the
115 * server will let us have the requested name, though.
117 * The name will be released when this connection object is destroyed.
119 void request_name(WvStringParm name
, const WvDBusCallback
&onreply
= 0,
120 time_t msec_timeout
= WVDBUS_DEFAULT_TIMEOUT
);
123 * Return this connection's unique name on the bus, assigned by the server
126 WvString
uniquename() const;
129 * Close the underlying stream. The object becomes unusable. This is
130 * also called whenever an error is set.
132 virtual void close();
135 * Send a message on the bus, not expecting any reply. Returns the
136 * assigned serial number in case you want to track it some other way.
138 uint32_t send(WvDBusMsg msg
);
141 * Send a message on the bus, calling onreply() when the reply comes in
142 * or the messages times out.
144 void send(WvDBusMsg msg
, const WvDBusCallback
&onreply
,
145 time_t msec_timeout
= WVDBUS_DEFAULT_TIMEOUT
);
148 * Send a message on the bus and wait for a reply to come in, returning
149 * the message when it does. There is always a reply, even if it's
150 * "message expired" or some other error message.
152 * The serial_cb parameter allows you to create a callback which is called
153 * after 'send' but before the runonce() loop is initiated, allowing you
154 * to perform some kind of setup based on the serial number of the message.
156 * It waits by doing this->runonce(). Streams on the globallist may run.
158 * WARNING: this function does a synchronous wait operation, and thus
159 * does not play nicely in single-threaded WvStreams applications. Use
162 WvDBusMsg
send_and_wait(WvDBusMsg msg
,
163 time_t msec_timeout
= WVDBUS_DEFAULT_TIMEOUT
,
164 wv::function
<void(uint32_t)> serial_cb
= 0);
167 * The priority level of a callback registration. This defines the order
168 * in which callbacks are processed, from lowest to highest integer.
171 PriSystem
= 0, // implemented by DBus or WvDBus. Don't use.
172 PriSpecific
= 5000, // strictly limited by interface/method
173 PriNormal
= 6000, // a reasonably selective callback
174 PriBridge
= 7000, // proxy selectively to other listeners
175 PriBroadcast
= 8000, // last-resort proxy to all listeners
176 PriGaveUp
= 9900, // run this if nothing else works
180 * Adds a callback to the connection: all received messages will be
181 * sent to all callbacks to look at and possibly process. This method
182 * is simple and flexible, but it can be slow if you have too many
185 * Your application is very unlikely to have "too many" callbacks. If
186 * for some reason you need to register lots of separate callbacks,
187 * make your own data structure for them and register just a single
188 * callback here that looks things up in your own structure.
190 * 'pri' defines the callback sort order. When calling callbacks, we
191 * call them in priority order until the first callback returns 'true'.
192 * If you just want to log certain messages and let other people handle
193 * them, use a high priority but return 'false'.
195 * 'cookie' is used to identify this callback for del_callback(). Your
196 * 'this' pointer is a useful value here.
198 void add_callback(CallbackPri pri
, WvDBusCallback cb
, void *cookie
= NULL
);
201 * Delete all callbacks that have the given cookie.
203 void del_callback(void *cookie
);
206 * Called by for each received message. Returns true if we handled
207 * this message, false if not. You should not need to call or override
208 * this; see add_callback() instead.
210 virtual bool filter_func(WvDBusMsg
&msg
);
213 * Returns true if there are no outstanding messages that have not
214 * received (or timed out) their reply. Mostly useful in unit tests
215 * that want to terminate once all messages have been processed.
220 time_t mintimeout_msec();
221 virtual bool post_select(SelectInfo
&si
);
225 WvDBusMsg msg
; // needed in case we need to generate timeout replies
230 Pending(WvDBusMsg
&_msg
, const WvDBusCallback
&_cb
,
234 serial
= msg
.get_serial();
235 if (msec_timeout
< 0)
236 msec_timeout
= 5*3600*1000; // "forever" is a few hours
237 valid_until
= msecadd(wvstime(), msec_timeout
);
240 DeclareWvDict(Pending
, uint32_t, serial
);
243 WvDynBuf in_queue
, out_queue
;
245 void expire_pending(Pending
*p
);
246 void cancel_pending(uint32_t serial
);
247 void add_pending(WvDBusMsg
&msg
, WvDBusCallback cb
,
248 time_t msec_timeout
);
249 bool _registered(WvDBusMsg
&msg
);
257 CallbackInfo(CallbackPri _pri
,
258 const WvDBusCallback
&_cb
, void *_cookie
)
260 { pri
= _pri
; cookie
= _cookie
; }
262 static int priority_order(const CallbackInfo
*a
, const CallbackInfo
*b
);
264 DeclareWvList(CallbackInfo
);
265 CallbackInfoList callbacks
;
269 #endif // __WVDBUSCONN_H