1 // Copyright (c) Benjamin Kietzman (github.com/bkietz)
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef DBUS_CONNECTION_SERVICE_HPP
7 #define DBUS_CONNECTION_SERVICE_HPP
8 
9 #include <boost/asio.hpp>
10 
11 #include <dbus/error.hpp>
12 #include <dbus/element.hpp>
13 #include <dbus/message.hpp>
14 #include <dbus/detail/async_send_op.hpp>
15 
16 #include <dbus/impl/connection.ipp>
17 
18 namespace dbus {
19 
20 namespace bus {
21   static const int session = DBUS_BUS_SESSION;
22   static const int system  = DBUS_BUS_SYSTEM;
23   static const int starter = DBUS_BUS_STARTER;
24 } // namespace bus
25 
26 using namespace boost::asio;
27 
28 class filter;
29 class match;
30 
31 class connection_service
32   : public io_service::service
33 {
34 public:
35   static io_service::id id;
36 
37   typedef impl::connection implementation_type;
38 
39   explicit connection_service(io_service& io)
40     : service(io)
41   {
42   }
43 
44   void construct(implementation_type& impl)
45   {
46   }
47 
48   void destroy(implementation_type& impl)
49   {
50   }
51 
52   void shutdown_service()
53   {
54     //TODO is there anything that needs shutting down?
55   }
56 
57   void open(implementation_type& impl,
58       const string& address)
59   {
60     io_service& io = this->get_io_service();
61 
62     impl.open(io, address);
63   }
64 
65   void open(implementation_type& impl,
66       const int bus = bus::system)
67   {
68     io_service& io = this->get_io_service();
69 
70     impl.open(io, bus);
71   }
72 
73   message send(implementation_type& impl,
74       message& m)
75   {
76     return impl.send_with_reply_and_block(m);
77   }
78 
79   template <typename Duration>
80   message send(implementation_type& impl,
81       message& m,
82       const Duration& timeout)
83   {
84     if(timeout == Duration::zero()) {
85       //TODO this can return false if it failed
86       impl.send(m);
87       return message();
88     } else {
89       return impl.send_with_reply_and_block(m,
90         chrono::milliseconds(timeout).count());
91     }
92   }
93 
94   template<typename MessageHandler>
95   inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler,
96       void(boost::system::error_code, message))
97   async_send(implementation_type& impl,
98       message& m,
99       BOOST_ASIO_MOVE_ARG(MessageHandler) handler)
100   {
101     // begin asynchronous operation
102     impl.start(this->get_io_service());
103 
104     boost::asio::detail::async_result_init<
105       MessageHandler, void(boost::system::error_code, message)> init(
106         BOOST_ASIO_MOVE_CAST(MessageHandler)(handler));
107 
108     detail::async_send_op<
109       BOOST_ASIO_HANDLER_TYPE(MessageHandler,
110         void(boost::system::error_code, message))>(
111           this->get_io_service(),
112             BOOST_ASIO_MOVE_CAST(MessageHandler)(init.handler)) (impl, m);
113 
114     return init.result.get();
115   }
116 
117   void new_match(implementation_type& impl,
118       match& m);
119 
120   void delete_match(implementation_type& impl,
121       match& m);
122 
123   void new_filter(implementation_type& impl,
124       filter& f);
125 
126   void delete_filter(implementation_type& impl,
127       filter& f);
128 
129 };
130 
131 io_service::id connection_service::id;
132 
133 
134 
135 
136 } // namespace dbus
137 
138 #endif // DBUS_CONNECTION_SERVICE_HPP
139