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 boost::asio::detail::service_base<connection_service>
33 {
34 public:
35   typedef impl::connection implementation_type;
36 
37   explicit connection_service(io_service& io)
38     : boost::asio::detail::service_base<connection_service>(io)
39   {
40   }
41 
42   void construct(implementation_type& impl)
43   {
44   }
45 
46   void destroy(implementation_type& impl)
47   {
48   }
49 
50   void shutdown_service()
51   {
52     //TODO is there anything that needs shutting down?
53   }
54 
55   void open(implementation_type& impl,
56       const string& address)
57   {
58     io_service& io = this->get_io_service();
59 
60     impl.open(io, address);
61   }
62 
63   void open(implementation_type& impl,
64       const int bus = bus::system)
65   {
66     io_service& io = this->get_io_service();
67 
68     impl.open(io, bus);
69   }
70 
71   message send(implementation_type& impl,
72       message& m)
73   {
74     return impl.send_with_reply_and_block(m);
75   }
76 
77   template <typename Duration>
78   message send(implementation_type& impl,
79       message& m,
80       const Duration& timeout)
81   {
82     if(timeout == Duration::zero()) {
83       //TODO this can return false if it failed
84       impl.send(m);
85       return message();
86     } else {
87       return impl.send_with_reply_and_block(m,
88         chrono::milliseconds(timeout).count());
89     }
90   }
91 
92   template<typename MessageHandler>
93   inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler,
94       void(boost::system::error_code, message))
95   async_send(implementation_type& impl,
96       message& m,
97       BOOST_ASIO_MOVE_ARG(MessageHandler) handler)
98   {
99     // begin asynchronous operation
100     impl.start(this->get_io_service());
101 
102     boost::asio::detail::async_result_init<
103       MessageHandler, void(boost::system::error_code, message)> init(
104         BOOST_ASIO_MOVE_CAST(MessageHandler)(handler));
105 
106     detail::async_send_op<
107       BOOST_ASIO_HANDLER_TYPE(MessageHandler,
108         void(boost::system::error_code, message))>(
109           this->get_io_service(),
110             BOOST_ASIO_MOVE_CAST(MessageHandler)(init.handler)) (impl, m);
111 
112     return init.result.get();
113   }
114 
115   void new_match(implementation_type& impl,
116       match& m);
117 
118   void delete_match(implementation_type& impl,
119       match& m);
120 
121   void new_filter(implementation_type& impl,
122       filter& f);
123 
124   void delete_filter(implementation_type& impl,
125       filter& f);
126 };
127 
128 } // namespace dbus
129 
130 #endif // DBUS_CONNECTION_SERVICE_HPP
131