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