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_SERVICE_HPP 7 #define DBUS_CONNECTION_SERVICE_HPP 8 9 #include <string> 10 #include <boost/asio.hpp> 11 12 #include <dbus/error.hpp> 13 #include <dbus/message.hpp> 14 #include <dbus/detail/watch_timeout.hpp> 15 #include <dbus/detail/queue.hpp> 16 #include <dbus/detail/async_send_op.hpp> 17 18 namespace dbus { 19 20 namespace bus { 21 static const int session = DBUS_BUS_SESSION; 22 static const int system = DBUS_BUS_SYSTEM; 23 static const int starter = DBUS_BUS_STARTER; 24 } // namespace bus 25 26 using std::string; 27 using namespace boost::asio; 28 29 class filter; 30 class match; 31 32 class connection_service 33 : public io_service::service 34 { 35 public: 36 static io_service::id id; 37 38 typedef DBusConnection *implementation_type; 39 40 explicit connection_service(io_service& io) 41 : service(io) 42 { 43 } 44 45 void construct(implementation_type& impl) 46 { 47 } 48 49 void destroy(implementation_type& impl) 50 { 51 dbus_connection_unref(impl); 52 } 53 54 void shutdown_service() 55 { 56 //TODO is there anything that needs shutting down? 57 } 58 59 void open(implementation_type& impl, 60 const string& address, bool shared=true) 61 { 62 io_service& io = this->get_io_service(); 63 64 error e; 65 impl = dbus_connection_open(address.c_str(), e); 66 67 e.throw_if_set(); 68 detail::set_watch_timeout_dispatch_functions(impl, io); 69 } 70 71 void open(implementation_type& impl, 72 const int bus = bus::system, 73 bool shared=true) 74 { 75 io_service& io = this->get_io_service(); 76 77 error e; 78 impl = dbus_bus_get((DBusBusType)bus, e); 79 80 e.throw_if_set(); 81 detail::set_watch_timeout_dispatch_functions(impl, io); 82 } 83 84 message send(implementation_type& impl, 85 message& m) 86 { 87 error e; 88 message reply(dbus_connection_send_with_reply_and_block(impl, 89 m, -1, e)); 90 91 e.throw_if_set(); 92 return reply; 93 } 94 95 template <typename Duration> 96 message send(implementation_type& impl, 97 message& m, 98 const Duration& timeout) 99 { 100 //TODO generically convert timeout to milliseconds 101 if(timeout == Duration::zero()) { 102 //TODO this can return false if it failed 103 dbus_connection_send(impl, m, NULL); 104 return message(); 105 } else { 106 error e; 107 message reply(dbus_connection_send_with_reply_and_block(impl, 108 m, chrono::milliseconds(timeout).count(), e)); 109 110 e.throw_if_set(); 111 return reply; 112 } 113 } 114 115 template<typename MessageHandler> 116 inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler, 117 void(boost::system::error_code, message)) 118 async_send(implementation_type& impl, 119 message& m, 120 BOOST_ASIO_MOVE_ARG(MessageHandler) handler) 121 { 122 boost::asio::detail::async_result_init< 123 MessageHandler, void(boost::system::error_code, message)> init( 124 BOOST_ASIO_MOVE_CAST(MessageHandler)(handler)); 125 126 detail::async_send_op< 127 BOOST_ASIO_HANDLER_TYPE(MessageHandler, 128 void(boost::system::error_code, message))>( 129 this->get_io_service(), 130 BOOST_ASIO_MOVE_CAST(MessageHandler)(init.handler)) (impl, m); 131 132 return init.result.get(); 133 } 134 135 void new_match(implementation_type& impl, 136 match& m); 137 138 void delete_match(implementation_type& impl, 139 match& m); 140 141 void new_filter(implementation_type& impl, 142 filter& f); 143 144 void delete_filter(implementation_type& impl, 145 filter& f); 146 147 }; 148 149 io_service::id connection_service::id; 150 151 152 153 154 } // namespace dbus 155 156 #endif // DBUS_CONNECTION_SERVICE_HPP 157