blob: 50e02073346361ef349ceae5f1deb30002b6e348 [file] [log] [blame]
Ed Tanousc9b55212017-06-12 13:25:51 -07001// 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
16namespace dbus {
17
18class filter;
19class match;
20
21/// Root D-Bus IO object
22/**
23 * A connection to a bus, through which messages may be sent or received.
24 */
25class 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
Ed Tanous5fceeb42017-06-28 09:43:09 -070056
57 /// Request a name on the bus.
58 /**
59 * @param name The name requested on the bus
60 *
61 * @return
62 *
63 * @throws boost::system::system_error When the response timed out or
64 * there was some other error.
65 */
66 void request_name(const string& name) {
67 this->get_implementation().request_name(name);
68 }
69
70 /// Reply to a message.
71 /**
72 * @param m The message from which to create the reply
73 *
74 * @return The new reply message
75 *
76 * @throws boost::system::system_error When the response timed out or
77 * there was some other error.
78 */
79 message reply(message& m) {
80 return this->get_implementation().new_method_return(m);
81 }
82
Ed Tanousc9b55212017-06-12 13:25:51 -070083 /// Send a message.
84 /**
85 * @param m The message to send.
86 *
87 * @return The reply received.
88 *
89 * @throws boost::system::system_error When the response timed out or
90 * there was some other error.
91 */
92 message send(message& m) {
93 return this->get_service().send(this->get_implementation(), m);
94 }
95
96 /// Send a message.
97 /**
98 * @param m The message to send.
99 *
100 * @param t Time to wait for a reply. Passing 0 as the timeout means
101 * that you wish to ignore the reply. (Or catch it later somehow...)
102 *
103 * @return The reply received.
104 *
105 * @throws boost::system::system_error When the response timed out (if
106 * timeout was not 0), or there was some other error.
107 */
108 template <typename Duration>
109 message send(message& m, const Duration& t) {
110 return this->get_service().send(this->get_implementation(), m, t);
111 }
112
113 /// Send a message asynchronously.
114 /**
115 * @param m The message to send.
116 *
117 * @param handler Handler for the reply.
118 *
119 * @return Asynchronous result
120 */
121 template <typename MessageHandler>
122 inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler,
123 void(boost::system::error_code, message))
124 async_send(message& m, BOOST_ASIO_MOVE_ARG(MessageHandler) handler) {
125 return this->get_service().async_send(
126 this->get_implementation(), m,
127 BOOST_ASIO_MOVE_CAST(MessageHandler)(handler));
128 }
129
130 /// Create a new match.
131 void new_match(match& m) {
132 this->get_service().new_match(this->get_implementation(), m);
133 }
134
135 /// Destroy a match.
136 void delete_match(match& m) {
137 this->get_service().delete_match(this->get_implementation(), m);
138 }
139
140 /// Create a new filter.
141 void new_filter(filter& f) {
142 this->get_service().new_filter(this->get_implementation(), f);
143 }
144
145 /// Destroy a filter.
146 void delete_filter(filter& f) {
147 this->get_service().delete_filter(this->get_implementation(), f);
148 }
149
150 // FIXME the only way around this I see is to expose start() here, which seems
151 // ugly
152 friend class filter;
153};
154
Ed Tanous5fceeb42017-06-28 09:43:09 -0700155typedef std::shared_ptr<connection> connection_ptr;
156
Ed Tanousc9b55212017-06-12 13:25:51 -0700157} // namespace dbus
158
159#endif // DBUS_CONNECTION_HPP