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