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 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 71 std::string get_unique_name(){ 72 return this->get_implementation().get_unique_name(); 73 } 74 75 /// Reply to a message. 76 /** 77 * @param m The message from which to create the reply 78 * 79 * @return The new reply message 80 * 81 * @throws boost::system::system_error When the response timed out or 82 * there was some other error. 83 */ 84 message reply(message& m) { 85 return this->get_implementation().new_method_return(m); 86 } 87 88 /// Send a message. 89 /** 90 * @param m The message to send. 91 * 92 * @return The reply received. 93 * 94 * @throws boost::system::system_error When the response timed out or 95 * there was some other error. 96 */ 97 message send(message& m) { 98 return this->get_service().send(this->get_implementation(), m); 99 } 100 101 /// Send a message. 102 /** 103 * @param m The message to send. 104 * 105 * @param t Time to wait for a reply. Passing 0 as the timeout means 106 * that you wish to ignore the reply. (Or catch it later somehow...) 107 * 108 * @return The reply received. 109 * 110 * @throws boost::system::system_error When the response timed out (if 111 * timeout was not 0), or there was some other error. 112 */ 113 template <typename Duration> 114 message send(message& m, const Duration& t = std::chrono::seconds(0)) { 115 return this->get_service().send(this->get_implementation(), m, t); 116 } 117 118 /// Send a message asynchronously. 119 /** 120 * @param m The message to send. 121 * 122 * @param handler Handler for the reply. 123 * 124 * @return Asynchronous result 125 */ 126 template <typename MessageHandler> 127 inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler, 128 void(boost::system::error_code, message)) 129 async_send(message& m, BOOST_ASIO_MOVE_ARG(MessageHandler) handler) { 130 return this->get_service().async_send( 131 this->get_implementation(), m, 132 BOOST_ASIO_MOVE_CAST(MessageHandler)(handler)); 133 } 134 135 /// Create a new match. 136 void new_match(match& m) { 137 this->get_service().new_match(this->get_implementation(), m); 138 } 139 140 /// Destroy a match. 141 void delete_match(match& m) { 142 this->get_service().delete_match(this->get_implementation(), m); 143 } 144 145 /// Create a new filter. 146 void new_filter(filter& f) { 147 this->get_service().new_filter(this->get_implementation(), f); 148 } 149 150 /// Destroy a filter. 151 void delete_filter(filter& f) { 152 this->get_service().delete_filter(this->get_implementation(), f); 153 } 154 155 // FIXME the only way around this I see is to expose start() here, which seems 156 // ugly 157 friend class filter; 158 }; 159 160 typedef std::shared_ptr<connection> connection_ptr; 161 162 } // namespace dbus 163 164 #endif // DBUS_CONNECTION_HPP 165