xref: /openbmc/boost-dbus/include/dbus/connection_service.hpp (revision 8586098902e756bffbcf058d030445d755d6b191)
1fc79e461SBenjamin Kietzman #ifndef DBUS_CONNECTION_SERVICE_HPP
2fc79e461SBenjamin Kietzman #define DBUS_CONNECTION_SERVICE_HPP
3fc79e461SBenjamin Kietzman 
4fc79e461SBenjamin Kietzman #include <string>
5d620effbSBenjamin Kietzman #include <boost/asio.hpp>
6d620effbSBenjamin Kietzman 
7*85860989SBenjamin Kietzman #include <dbus/error.hpp>
8fc79e461SBenjamin Kietzman #include <dbus/message.hpp>
9fc79e461SBenjamin Kietzman #include <dbus/detail/watch_timeout.hpp>
10fc79e461SBenjamin Kietzman #include <dbus/detail/queue.hpp>
11fc79e461SBenjamin Kietzman 
12d620effbSBenjamin Kietzman namespace dbus {
13d620effbSBenjamin Kietzman 
14cd8b76a3SBenjamin Kietzman namespace bus {
15cd8b76a3SBenjamin Kietzman   static const int session = DBUS_BUS_SESSION;
16cd8b76a3SBenjamin Kietzman   static const int system  = DBUS_BUS_SYSTEM;
17cd8b76a3SBenjamin Kietzman   static const int starter = DBUS_BUS_STARTER;
18cd8b76a3SBenjamin Kietzman } // namespace bus
19cd8b76a3SBenjamin Kietzman 
20fc79e461SBenjamin Kietzman using std::string;
21fc79e461SBenjamin Kietzman using namespace boost::asio;
22fc79e461SBenjamin Kietzman 
2317826fe7SBenjamin Kietzman class filter;
2417826fe7SBenjamin Kietzman class match;
2517826fe7SBenjamin Kietzman 
26d620effbSBenjamin Kietzman class connection_service
27d620effbSBenjamin Kietzman   : public io_service::service
28d620effbSBenjamin Kietzman {
29d620effbSBenjamin Kietzman public:
30d620effbSBenjamin Kietzman   static io_service::id id;
31d620effbSBenjamin Kietzman 
32d620effbSBenjamin Kietzman   typedef DBusConnection *implementation_type;
33d620effbSBenjamin Kietzman 
34d620effbSBenjamin Kietzman   explicit connection_service(io_service& io)
35d620effbSBenjamin Kietzman     :  service(io)
36d620effbSBenjamin Kietzman   {
37d620effbSBenjamin Kietzman   }
38d620effbSBenjamin Kietzman 
39d620effbSBenjamin Kietzman   void construct(implementation_type& impl)
40d620effbSBenjamin Kietzman   {
41d620effbSBenjamin Kietzman   }
42d620effbSBenjamin Kietzman 
43d620effbSBenjamin Kietzman   void destroy(implementation_type& impl)
44d620effbSBenjamin Kietzman   {
45d620effbSBenjamin Kietzman     dbus_connection_unref(impl);
46d620effbSBenjamin Kietzman   }
47d620effbSBenjamin Kietzman 
48d620effbSBenjamin Kietzman   void shutdown_service()
49d620effbSBenjamin Kietzman   {
50cd8b76a3SBenjamin Kietzman     //TODO is there anything that needs shutting down?
51d620effbSBenjamin Kietzman   }
52d620effbSBenjamin Kietzman 
53d620effbSBenjamin Kietzman   void open(implementation_type& impl,
54d620effbSBenjamin Kietzman       const string& address, bool shared=true)
55d620effbSBenjamin Kietzman   {
56d620effbSBenjamin Kietzman     io_service& io = this->get_io_service();
57d620effbSBenjamin Kietzman 
58*85860989SBenjamin Kietzman     error e;
59*85860989SBenjamin Kietzman     impl = dbus_connection_open(address.c_str(), e);
60d620effbSBenjamin Kietzman 
61*85860989SBenjamin Kietzman     e.throw_if_set();
62cd8b76a3SBenjamin Kietzman     detail::set_watch_timeout_dispatch_functions(impl, io);
63d620effbSBenjamin Kietzman   }
64d620effbSBenjamin Kietzman 
65d620effbSBenjamin Kietzman   void open(implementation_type& impl,
66cd8b76a3SBenjamin Kietzman       const int bus = (int) DBUS_BUS_SYSTEM,
67d620effbSBenjamin Kietzman       bool shared=true)
68d620effbSBenjamin Kietzman   {
69d620effbSBenjamin Kietzman     io_service& io = this->get_io_service();
70d620effbSBenjamin Kietzman 
71*85860989SBenjamin Kietzman     error e;
72*85860989SBenjamin Kietzman     impl = dbus_bus_get((DBusBusType)bus, e);
73d620effbSBenjamin Kietzman 
74*85860989SBenjamin Kietzman     e.throw_if_set();
75cd8b76a3SBenjamin Kietzman     detail::set_watch_timeout_dispatch_functions(impl, io);
76cd8b76a3SBenjamin Kietzman   }
77d620effbSBenjamin Kietzman 
78cd8b76a3SBenjamin Kietzman   message send(implementation_type& impl,
79cd8b76a3SBenjamin Kietzman       message& m)
80cd8b76a3SBenjamin Kietzman   {
81*85860989SBenjamin Kietzman     error e;
82*85860989SBenjamin Kietzman     message reply(dbus_connection_send_with_reply_and_block(impl,
83*85860989SBenjamin Kietzman         m, -1, e));
84*85860989SBenjamin Kietzman 
85*85860989SBenjamin Kietzman     e.throw_if_set();
86*85860989SBenjamin Kietzman     return reply;
87d620effbSBenjamin Kietzman   }
88d620effbSBenjamin Kietzman 
89d620effbSBenjamin Kietzman   template <typename Duration>
90d620effbSBenjamin Kietzman   message send(implementation_type& impl,
91d620effbSBenjamin Kietzman       message& m,
92d620effbSBenjamin Kietzman       const Duration& timeout)
93d620effbSBenjamin Kietzman   {
94d620effbSBenjamin Kietzman     //TODO generically convert timeout to milliseconds
95cd8b76a3SBenjamin Kietzman     if(timeout == Duration::zero()) {
96d620effbSBenjamin Kietzman       //TODO this can return false if it failed
97d620effbSBenjamin Kietzman       dbus_connection_send(impl, m, &m.serial);
98d620effbSBenjamin Kietzman       return message();
99d620effbSBenjamin Kietzman     } else {
100*85860989SBenjamin Kietzman       error e;
101*85860989SBenjamin Kietzman       message reply(dbus_connection_send_with_reply_and_block(impl,
102*85860989SBenjamin Kietzman           m, chrono::milliseconds(timeout).count(), e));
103*85860989SBenjamin Kietzman 
104*85860989SBenjamin Kietzman       e.throw_if_set();
105*85860989SBenjamin Kietzman       return reply;
106d620effbSBenjamin Kietzman     }
107d620effbSBenjamin Kietzman   }
108d620effbSBenjamin Kietzman 
109d620effbSBenjamin Kietzman   template<typename MessageHandler>
110d620effbSBenjamin Kietzman   inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler,
111d620effbSBenjamin Kietzman       void(boost::system::error_code, message))
112d620effbSBenjamin Kietzman   async_send(implementation_type& impl,
113d620effbSBenjamin Kietzman       message& m,
114d620effbSBenjamin Kietzman       BOOST_ASIO_MOVE_ARG(MessageHandler) handler)
115d620effbSBenjamin Kietzman   {
116d620effbSBenjamin Kietzman     DBusPendingCall *p;
117d620effbSBenjamin Kietzman     dbus_connection_send_with_reply(impl,
118d620effbSBenjamin Kietzman         m, &p, -1);
119cd8b76a3SBenjamin Kietzman     /*
120cd8b76a3SBenjamin Kietzman     dbus_pending_call_set_notify(p,
121cd8b76a3SBenjamin Kietzman         &pending_call_notify, &get_io_service(), NULL);
122cd8b76a3SBenjamin Kietzman 
123cd8b76a3SBenjamin Kietzman     //FIXME Race condition: another thread might have
124cd8b76a3SBenjamin Kietzman     // processed the pending call's reply before a notify
125cd8b76a3SBenjamin Kietzman     // function could be set. If so, the notify function
126cd8b76a3SBenjamin Kietzman     // will never trigger, so it must be called manually:
127cd8b76a3SBenjamin Kietzman     if(dbus_pending_call_get_completed(p))
128cd8b76a3SBenjamin Kietzman     {
129cd8b76a3SBenjamin Kietzman       //TODO: does this work, or might it call the notify
130cd8b76a3SBenjamin Kietzman       // function too many times? Might have to use steal_reply
131cd8b76a3SBenjamin Kietzman       pending_call_notify(p, &get_io_service());
132cd8b76a3SBenjamin Kietzman     }
133cd8b76a3SBenjamin Kietzman     */
134d620effbSBenjamin Kietzman   }
135d620effbSBenjamin Kietzman 
136cd8b76a3SBenjamin Kietzman   void new_match(implementation_type& impl,
13717826fe7SBenjamin Kietzman       match& m);
138cd8b76a3SBenjamin Kietzman 
139cd8b76a3SBenjamin Kietzman   void delete_match(implementation_type& impl,
14017826fe7SBenjamin Kietzman       match& m);
141cd8b76a3SBenjamin Kietzman 
14217826fe7SBenjamin Kietzman   static DBusHandlerResult filter_callback(
143cd8b76a3SBenjamin Kietzman       DBusConnection *c,
144cd8b76a3SBenjamin Kietzman       DBusMessage *m,
14517826fe7SBenjamin Kietzman       void *userdata);
146cd8b76a3SBenjamin Kietzman 
147cd8b76a3SBenjamin Kietzman   void new_filter(implementation_type& impl,
14817826fe7SBenjamin Kietzman       filter& f);
149cd8b76a3SBenjamin Kietzman 
150cd8b76a3SBenjamin Kietzman   void delete_filter(implementation_type& impl,
15117826fe7SBenjamin Kietzman       filter& f);
15217826fe7SBenjamin Kietzman 
153d620effbSBenjamin Kietzman };
154d620effbSBenjamin Kietzman 
155d620effbSBenjamin Kietzman io_service::id connection_service::id;
156d620effbSBenjamin Kietzman 
157cd8b76a3SBenjamin Kietzman 
158cd8b76a3SBenjamin Kietzman 
159cd8b76a3SBenjamin Kietzman 
160d620effbSBenjamin Kietzman } // namespace dbus
161fc79e461SBenjamin Kietzman 
162fc79e461SBenjamin Kietzman #endif // DBUS_CONNECTION_SERVICE_HPP
163