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_HPP
7 #define DBUS_CONNECTION_HPP
8 
9 #include <dbus/connection_service.hpp>
10 #include <dbus/element.hpp>
11 #include <dbus/message.hpp>
12 #include <chrono>
13 #include <string>
14 #include <boost/asio.hpp>
15 
16 namespace dbus {
17 
18 class filter;
19 class match;
20 
21 /// Root D-Bus IO object
22 /**
23  * A connection to a bus, through which messages may be sent or received.
24  */
25 class connection : public boost::asio::basic_io_object<connection_service> {
26  public:
27   /// Open a connection to a specified address.
28   /**
29  * @param io_service The io_service object that the connection will use to
30  * wire D-Bus for asynchronous operation.
31  *
32  * @param address The address of the bus to connect to.
33  *
34  * @throws boost::system::system_error When opening the connection failed.
35  */
36   connection(boost::asio::io_service& io, const string& address)
37       : basic_io_object<connection_service>(io) {
38     this->get_service().open(this->get_implementation(), address);
39   }
40 
41   /// Open a connection to a well-known bus.
42   /**
43  * D-Bus connections are usually opened to well-known buses like the
44  * system or session bus.
45  *
46  * @param bus The well-known bus to connect to.
47  *
48  * @throws boost::system::system_error When opening the connection failed.
49  */
50   // TODO: change this unsigned to an enumeration
51   connection(boost::asio::io_service& io, const int bus)
52       : basic_io_object<connection_service>(io) {
53     this->get_service().open(this->get_implementation(), bus);
54   }
55 
56   /// Send a message.
57   /**
58  * @param m The message to send.
59  *
60  * @return The reply received.
61  *
62  * @throws boost::system::system_error When the response timed out or
63  * there was some other error.
64  */
65   message send(message& m) {
66     return this->get_service().send(this->get_implementation(), m);
67   }
68 
69   /// Send a message.
70   /**
71  * @param m The message to send.
72  *
73  * @param t Time to wait for a reply. Passing 0 as the timeout means
74  * that you wish to ignore the reply. (Or catch it later somehow...)
75  *
76  * @return The reply received.
77  *
78  * @throws boost::system::system_error When the response timed out (if
79  * timeout was not 0), or there was some other error.
80  */
81   template <typename Duration>
82   message send(message& m, const Duration& t) {
83     return this->get_service().send(this->get_implementation(), m, t);
84   }
85 
86   /// Send a message asynchronously.
87   /**
88  * @param m The message to send.
89  *
90  * @param handler Handler for the reply.
91  *
92  * @return Asynchronous result
93  */
94   template <typename MessageHandler>
95   inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler,
96                                        void(boost::system::error_code, message))
97       async_send(message& m, BOOST_ASIO_MOVE_ARG(MessageHandler) handler) {
98     return this->get_service().async_send(
99         this->get_implementation(), m,
100         BOOST_ASIO_MOVE_CAST(MessageHandler)(handler));
101   }
102 
103   /// Create a new match.
104   void new_match(match& m) {
105     this->get_service().new_match(this->get_implementation(), m);
106   }
107 
108   /// Destroy a match.
109   void delete_match(match& m) {
110     this->get_service().delete_match(this->get_implementation(), m);
111   }
112 
113   /// Create a new filter.
114   void new_filter(filter& f) {
115     this->get_service().new_filter(this->get_implementation(), f);
116   }
117 
118   /// Destroy a filter.
119   void delete_filter(filter& f) {
120     this->get_service().delete_filter(this->get_implementation(), f);
121   }
122 
123   // FIXME the only way around this I see is to expose start() here, which seems
124   // ugly
125   friend class filter;
126 };
127 
128 }  // namespace dbus
129 
130 #endif  // DBUS_CONNECTION_HPP
131