xref: /openbmc/boost-dbus/include/dbus/connection.hpp (revision dae7063c7b10dc64dc2978c9fe8fbc73824759df)
1 #include <string>
2 #include <boost/asio.hpp>
3 #include "connection_service.hpp"
4 
5 namespace dbus {
6 
7 using std::string;
8 using namespace boost::asio;
9 
10 /// Root D-Bus IO object
11 /**
12  * A connection to a bus, through which messages may be sent or received.
13  */
14 class connection
15   : public basic_io_object<connection_service>
16 {
17 public:
18 
19   /// Constructor.
20   /**
21    * @param io_service The io_service object that the connection will use to
22    * wire D-Bus for asynchronous operation.
23    */
24   explicit connection(io_service& io)
25     : basic_io_object<connection_service>(io)
26   {
27   }
28 
29   //TODO: should these be constructors...?
30 
31   /// Open a connection to a specified address.
32   /**
33    * @note This function or open(unsigned) should be called only once to initialize
34    * a connection.
35    *
36    * @param address The address of the bus to connect to.
37    *
38    * @param shared Set false to open a private connection.
39    *
40    * @throws boost::system::system_error When opening the connection failed.
41    */
42   void open(const string& address, bool shared=true)
43   {
44     this->get_service().open(
45       this->get_implementation(),
46       address,
47       shared);
48   }
49 
50   /// Open a connection to a well-known bus.
51   /**
52    * D-Bus connections are usually opened to well-known buses like the
53    * system or session bus.
54    *
55    * @note This function or open(string) should be called only once to initialize
56    * a connection.
57    *
58    * @param bus_type The well-known bus to connect to.
59    *
60    * @param shared Set false to open a private connection.
61    *
62    * @throws boost::system::system_error When opening the connection failed.
63    */
64   // TODO: change this unsigned to an enumeration
65   void open(const unsigned bus_type, bool shared=true)
66   {
67     this->get_service().open(
68       this->get_implementation(),
69       bus_type,
70       shared);
71   }
72 
73   //TODO add error_code catchers to all these...
74 
75   /// Send a message.
76   /**
77    * @param m The message to send.
78    *
79    * @param timeout Time to wait for a reply. Passing 0 as the timeout means
80    * that you wish to ignore the reply. (Or catch it later somehow...)
81    *
82    * @return The reply received.
83    *
84    * @throws boost::system::system_error When the response timed out, if
85    * timeout was not 0.
86    */
87   template <typename Duration>
88   message send(message& m,
89 	  const Duration& timeout = timeout_default())
90   {
91     return this->get_service().send(
92       this->get_implementation(),
93       m,
94       timeout);
95   }
96 
97   /// Send a message asynchronously.
98   /**
99    * @param m The message to send.
100    *
101    * @param handler Handler for the reply.
102    *
103    * @return Asynchronous result
104    */
105   template<typename MessageHandler>
106   inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler,
107       void(boost::system::error_code, message))
108   async_send(message& m,
109       BOOST_ASIO_MOVE_ARG(MessageHandler) handler)
110   {
111     return this->get_service().async_send(
112       this->get_implementation(),
113       m,
114       BOOST_ASIO_MOVE_CAST(MessageHandler)(handler));
115   }
116 
117   //TODO figure out incomplete type knot without inlining class declaration.
118   //TODO use noncopyable
119 
120   /// Simple placeholder object for a match rule.
121   /**
122    * A match rule determines what messages will be received by this application.
123    *
124    * Each rule will be represented by an instance of match. To remove that rule,
125    * dispose of the object.
126    */
127   class match
128   {
129     connection& connection_;
130     std::string expression_;
131 
132 	match(connection& c,
133 	    BOOST_ASIO_MOVE_ARG(std::string) e)
134       : connection_(c),
135 	    expression_(BOOST_ASIO_MOVE_CAST(e))
136     {
137 	  // dbus_bus_add_match
138     }
139 
140 	match() {}
141 
142   public:
143 	friend class connection;
144 
145     ~match()
146 	{
147       // dbus_bus_remove_match
148 	}
149 
150   };
151 
152   /// Create a new match.
153   match new_match(
154 	  BOOST_ASIO_MOVE_ARG(string) expression)
155   {
156     return this->get_service().new_match(
157       this->get_implementation(),
158       BOOST_ASIO_MOVE_CAST(string)(expression));
159   }
160 
161   /// Represents a filter of incoming messages.
162   /**
163    * Filters examine incoming messages, demuxing them to multiple queues.
164    */
165   class filter
166   {
167 	connection& connection_;
168 	function<bool(message)> predicate_;
169 	detail::queue<message> queue_;
170 
171     template<typename MessagePredicate>
172     filter(connection& c,
173         BOOST_ASIO_MOVE_ARG(MessagePredicate) p)
174       : connection_(c),
175 		predicate_(BOOST_ASIO_MOVE_CAST(MessagePredicate)(p))
176     {
177 	  // dbus_connection_add_filter
178     }
179 
180 	filter() {}
181 
182   public:
183 	friend class connection;
184 
185 	~filter()
186 	{
187 	  // dbus_connection_remove_filter
188 	}
189 
190     template<typename MessageHandler>
191     inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler,
192         void(boost::system::error_code, message))
193     async_dispatch(
194         BOOST_ASIO_MOVE_ARG(MessageHandler) handler)
195     {
196 	  return queue_.async_pop(
197 		BOOST_ASIO_MOVE_CAST(MessageHandler)(handler));
198 	}
199 
200   };
201 
202   /// Create a new filter.
203   template<typename MessagePredicate>
204   filter new_filter(
205 	  BOOST_ASIO_MOVE_ARG(MessagePredicate) p)
206   {
207     return this->get_service().new_match(
208       this->get_implementation(),
209       BOOST_ASIO_MOVE_CAST(MessagePredicate)(p));
210   }
211 
212 };
213 
214 } // namespace dbus
215