xref: /openbmc/boost-dbus/include/dbus/connection_service.hpp (revision 17826fe7116ca8f7cdd2c987041450c0c5da1740)
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 
7fc79e461SBenjamin Kietzman #include <dbus/message.hpp>
8fc79e461SBenjamin Kietzman #include <dbus/detail/watch_timeout.hpp>
9fc79e461SBenjamin Kietzman #include <dbus/detail/queue.hpp>
10fc79e461SBenjamin Kietzman 
11d620effbSBenjamin Kietzman namespace dbus {
12d620effbSBenjamin Kietzman 
13cd8b76a3SBenjamin Kietzman namespace bus {
14cd8b76a3SBenjamin Kietzman   static const int session = DBUS_BUS_SESSION;
15cd8b76a3SBenjamin Kietzman   static const int system  = DBUS_BUS_SYSTEM;
16cd8b76a3SBenjamin Kietzman   static const int starter = DBUS_BUS_STARTER;
17cd8b76a3SBenjamin Kietzman } // namespace bus
18cd8b76a3SBenjamin Kietzman 
19fc79e461SBenjamin Kietzman using std::string;
20fc79e461SBenjamin Kietzman using namespace boost::asio;
21fc79e461SBenjamin Kietzman 
22*17826fe7SBenjamin Kietzman class filter;
23*17826fe7SBenjamin Kietzman class match;
24*17826fe7SBenjamin Kietzman 
25d620effbSBenjamin Kietzman class connection_service
26d620effbSBenjamin Kietzman   : public io_service::service
27d620effbSBenjamin Kietzman {
28d620effbSBenjamin Kietzman public:
29d620effbSBenjamin Kietzman   static io_service::id id;
30d620effbSBenjamin Kietzman 
31d620effbSBenjamin Kietzman   typedef DBusConnection *implementation_type;
32d620effbSBenjamin Kietzman 
33d620effbSBenjamin Kietzman   explicit connection_service(io_service& io)
34d620effbSBenjamin Kietzman     :  service(io)
35d620effbSBenjamin Kietzman   {
36d620effbSBenjamin Kietzman   }
37d620effbSBenjamin Kietzman 
38d620effbSBenjamin Kietzman   void construct(implementation_type& impl)
39d620effbSBenjamin Kietzman   {
40d620effbSBenjamin Kietzman   }
41d620effbSBenjamin Kietzman 
42d620effbSBenjamin Kietzman   void destroy(implementation_type& impl)
43d620effbSBenjamin Kietzman   {
44d620effbSBenjamin Kietzman     dbus_connection_unref(impl);
45d620effbSBenjamin Kietzman   }
46d620effbSBenjamin Kietzman 
47d620effbSBenjamin Kietzman   void shutdown_service()
48d620effbSBenjamin Kietzman   {
49cd8b76a3SBenjamin Kietzman     //TODO is there anything that needs shutting down?
50d620effbSBenjamin Kietzman   }
51d620effbSBenjamin Kietzman 
52d620effbSBenjamin Kietzman   void open(implementation_type& impl,
53d620effbSBenjamin Kietzman       const string& address, bool shared=true)
54d620effbSBenjamin Kietzman   {
55d620effbSBenjamin Kietzman     io_service& io = this->get_io_service();
56d620effbSBenjamin Kietzman 
57d620effbSBenjamin Kietzman     DBusError error;
58d620effbSBenjamin Kietzman     dbus_error_init(&error);
59d620effbSBenjamin Kietzman     impl = dbus_connection_open(address.c_str(), &error);
60d620effbSBenjamin Kietzman     //TODO actually deal with that error
61d620effbSBenjamin Kietzman 
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 
71d620effbSBenjamin Kietzman     DBusError error;
72d620effbSBenjamin Kietzman     dbus_error_init(&error);
73cd8b76a3SBenjamin Kietzman     impl = dbus_bus_get((DBusBusType)bus, &error);
74d620effbSBenjamin Kietzman     //TODO actually deal with that error
75d620effbSBenjamin Kietzman 
76cd8b76a3SBenjamin Kietzman     detail::set_watch_timeout_dispatch_functions(impl, io);
77cd8b76a3SBenjamin Kietzman   }
78d620effbSBenjamin Kietzman 
79cd8b76a3SBenjamin Kietzman   message send(implementation_type& impl,
80cd8b76a3SBenjamin Kietzman       message& m)
81cd8b76a3SBenjamin Kietzman   {
82cd8b76a3SBenjamin Kietzman     DBusError error;
83cd8b76a3SBenjamin Kietzman     dbus_error_init(&error);
84cd8b76a3SBenjamin Kietzman     return message(dbus_connection_send_with_reply_and_block(impl,
85cd8b76a3SBenjamin Kietzman         m, -1, &error));
86cd8b76a3SBenjamin Kietzman         //TODO deal with that error
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 {
100d620effbSBenjamin Kietzman       DBusError error;
101d620effbSBenjamin Kietzman       dbus_error_init(&error);
1020de54404SBenjamin Kietzman       return message(dbus_connection_send_with_reply_and_block(impl,
103cd8b76a3SBenjamin Kietzman           m, chrono::milliseconds(timeout).count(), &error));
104d620effbSBenjamin Kietzman           //TODO deal with that error
105d620effbSBenjamin Kietzman     }
106d620effbSBenjamin Kietzman   }
107d620effbSBenjamin Kietzman 
108d620effbSBenjamin Kietzman   template<typename MessageHandler>
109d620effbSBenjamin Kietzman   inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler,
110d620effbSBenjamin Kietzman       void(boost::system::error_code, message))
111d620effbSBenjamin Kietzman   async_send(implementation_type& impl,
112d620effbSBenjamin Kietzman       message& m,
113d620effbSBenjamin Kietzman       BOOST_ASIO_MOVE_ARG(MessageHandler) handler)
114d620effbSBenjamin Kietzman   {
115d620effbSBenjamin Kietzman     DBusPendingCall *p;
116d620effbSBenjamin Kietzman     dbus_connection_send_with_reply(impl,
117d620effbSBenjamin Kietzman         m, &p, -1);
118cd8b76a3SBenjamin Kietzman     /*
119cd8b76a3SBenjamin Kietzman     dbus_pending_call_set_notify(p,
120cd8b76a3SBenjamin Kietzman         &pending_call_notify, &get_io_service(), NULL);
121cd8b76a3SBenjamin Kietzman 
122cd8b76a3SBenjamin Kietzman     //FIXME Race condition: another thread might have
123cd8b76a3SBenjamin Kietzman     // processed the pending call's reply before a notify
124cd8b76a3SBenjamin Kietzman     // function could be set. If so, the notify function
125cd8b76a3SBenjamin Kietzman     // will never trigger, so it must be called manually:
126cd8b76a3SBenjamin Kietzman     if(dbus_pending_call_get_completed(p))
127cd8b76a3SBenjamin Kietzman     {
128cd8b76a3SBenjamin Kietzman       //TODO: does this work, or might it call the notify
129cd8b76a3SBenjamin Kietzman       // function too many times? Might have to use steal_reply
130cd8b76a3SBenjamin Kietzman       pending_call_notify(p, &get_io_service());
131cd8b76a3SBenjamin Kietzman     }
132cd8b76a3SBenjamin Kietzman     */
133d620effbSBenjamin Kietzman   }
134d620effbSBenjamin Kietzman 
135cd8b76a3SBenjamin Kietzman   void new_match(implementation_type& impl,
136*17826fe7SBenjamin Kietzman       match& m);
137cd8b76a3SBenjamin Kietzman 
138cd8b76a3SBenjamin Kietzman   void delete_match(implementation_type& impl,
139*17826fe7SBenjamin Kietzman       match& m);
140cd8b76a3SBenjamin Kietzman 
141*17826fe7SBenjamin Kietzman   static DBusHandlerResult filter_callback(
142cd8b76a3SBenjamin Kietzman       DBusConnection *c,
143cd8b76a3SBenjamin Kietzman       DBusMessage *m,
144*17826fe7SBenjamin Kietzman       void *userdata);
145cd8b76a3SBenjamin Kietzman 
146cd8b76a3SBenjamin Kietzman   void new_filter(implementation_type& impl,
147*17826fe7SBenjamin Kietzman       filter& f);
148cd8b76a3SBenjamin Kietzman 
149cd8b76a3SBenjamin Kietzman   void delete_filter(implementation_type& impl,
150*17826fe7SBenjamin Kietzman       filter& f);
151*17826fe7SBenjamin Kietzman 
152d620effbSBenjamin Kietzman };
153d620effbSBenjamin Kietzman 
154d620effbSBenjamin Kietzman io_service::id connection_service::id;
155d620effbSBenjamin Kietzman 
156cd8b76a3SBenjamin Kietzman 
157cd8b76a3SBenjamin Kietzman 
158cd8b76a3SBenjamin Kietzman 
159d620effbSBenjamin Kietzman } // namespace dbus
160fc79e461SBenjamin Kietzman 
161fc79e461SBenjamin Kietzman #endif // DBUS_CONNECTION_SERVICE_HPP
162