Saner handling if config.mk doesn't exist: use a default config.defaults.mk.
[wvstreams.git] / include / wvdbusconn.h
blob95830b0184bee1f2fd6352fe0d2c109a538d61e7
1 /* -*- Mode: C++ -*-
2 * Worldvisions Weaver Software:
3 * Copyright (C) 2004-2006 Net Integration Technologies, Inc.
4 *
5 * Pathfinder Software:
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.
13 */
14 #ifndef __WVDBUSCONN_H
15 #define __WVDBUSCONN_H
17 #include "wvstreamclone.h"
18 #include "wvlog.h"
19 #include "wvdbusmsg.h"
20 #include "wvhashtable.h"
21 #include "wvuid.h"
23 #define WVDBUS_DEFAULT_TIMEOUT (300*1000)
25 class WvDBusConn;
27 /**
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
30 * otherwise.
32 typedef wv::function<bool(WvDBusMsg&)> WvDBusCallback;
34 class IWvDBusAuth
36 public:
37 virtual ~IWvDBusAuth() { };
39 /**
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
45 * message.
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
57 bool sent_request;
58 public:
59 WvDBusClientAuth();
60 virtual bool authorize(WvDBusConn &c);
61 virtual wvuid_t get_uid();
65 class WvDBusConn : public WvStreamClone
67 bool client, authorized, in_post_select;
68 WvString _uniquename;
69 IWvDBusAuth *auth;
71 public:
72 WvLog log;
74 /**
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,
86 bool _client = true);
88 /**
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,
93 bool _client = true);
95 void init(IWvDBusAuth *_auth, bool _client);
97 /**
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);
104 void try_auth();
105 void send_hello();
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)); }
111 const char *in();
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
124 * at connect time.
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 * It waits by doing this->runonce(). Streams on the globallist may run.
154 * WARNING: this function does a synchronous wait operation, and thus
155 * does not play nicely in single-threaded WvStreams applications. Use
156 * with extreme care.
158 WvDBusMsg send_and_wait(WvDBusMsg msg,
159 time_t msec_timeout = WVDBUS_DEFAULT_TIMEOUT);
162 * The priority level of a callback registration. This defines the order
163 * in which callbacks are processed, from lowest to highest integer.
165 enum CallbackPri {
166 PriSystem = 0, // implemented by DBus or WvDBus. Don't use.
167 PriSpecific = 5000, // strictly limited by interface/method
168 PriNormal = 6000, // a reasonably selective callback
169 PriBridge = 7000, // proxy selectively to other listeners
170 PriBroadcast = 8000, // last-resort proxy to all listeners
171 PriGaveUp = 9900, // run this if nothing else works
175 * Adds a callback to the connection: all received messages will be
176 * sent to all callbacks to look at and possibly process. This method
177 * is simpler and more flexible than add_listener()/add_method(),
178 * but it can be slow if you have too many callbacks set.
180 * Your application is very unlikely to have "too many" callbacks. If
181 * for some reason you need to register lots of separate callbacks,
182 * make your own data structure for them and register just a single
183 * callback here that looks things up in your own structure.
185 * 'pri' defines the callback sort order. When calling callbacks, we
186 * call them in priority order until the first callback returns 'true'.
187 * If you just want to log certain messages and let other people handle
188 * them, use a high priority but return 'false'.
190 * 'cookie' is used to identify this callback for del_callback(). Your
191 * 'this' pointer is a useful value here.
193 void add_callback(CallbackPri pri, WvDBusCallback cb, void *cookie = NULL);
196 * Delete all callbacks that have the given cookie.
198 void del_callback(void *cookie);
201 * Called by for each received message. Returns true if we handled
202 * this message, false if not. You should not need to call or override
203 * this; see add_callback() instead.
205 virtual bool filter_func(WvDBusMsg &msg);
208 * Returns true if there are no outstanding messages that have not
209 * received (or timed out) their reply. Mostly useful in unit tests
210 * that want to terminate once all messages have been processed.
212 bool isidle();
214 private:
215 time_t mintimeout_msec();
216 virtual bool post_select(SelectInfo &si);
218 struct Pending
220 WvDBusMsg msg; // needed in case we need to generate timeout replies
221 uint32_t serial;
222 WvDBusCallback cb;
223 WvTime valid_until;
225 Pending(WvDBusMsg &_msg, const WvDBusCallback &_cb,
226 time_t msec_timeout)
227 : msg(_msg), cb(_cb)
229 serial = msg.get_serial();
230 if (msec_timeout < 0)
231 msec_timeout = 5*3600*1000; // "forever" is a few hours
232 valid_until = msecadd(wvstime(), msec_timeout);
235 DeclareWvDict(Pending, uint32_t, serial);
237 PendingDict pending;
238 WvDynBuf in_queue, out_queue;
240 void expire_pending(Pending *p);
241 void cancel_pending(uint32_t serial);
242 void add_pending(WvDBusMsg &msg, WvDBusCallback cb,
243 time_t msec_timeout);
244 bool _registered(WvDBusMsg &msg);
246 struct CallbackInfo
248 CallbackPri pri;
249 WvDBusCallback cb;
250 void *cookie;
252 CallbackInfo(CallbackPri _pri,
253 const WvDBusCallback &_cb, void *_cookie)
254 : cb(_cb)
255 { pri = _pri; cookie = _cookie; }
257 static int priority_order(const CallbackInfo *a, const CallbackInfo *b);
259 DeclareWvList(CallbackInfo);
260 CallbackInfoList callbacks;
264 #endif // __WVDBUSCONN_H