191cdbe46SBenjamin Kietzman // Copyright (c) Benjamin Kietzman (github.com/bkietz) 291cdbe46SBenjamin Kietzman // 391cdbe46SBenjamin Kietzman // Distributed under the Boost Software License, Version 1.0. (See accompanying 491cdbe46SBenjamin Kietzman // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 591cdbe46SBenjamin Kietzman 6fc79e461SBenjamin Kietzman #ifndef DBUS_CONNECTION_SERVICE_HPP 7fc79e461SBenjamin Kietzman #define DBUS_CONNECTION_SERVICE_HPP 8fc79e461SBenjamin Kietzman 9fc79e461SBenjamin Kietzman #include <string> 10d620effbSBenjamin Kietzman #include <boost/asio.hpp> 11d620effbSBenjamin Kietzman 1285860989SBenjamin Kietzman #include <dbus/error.hpp> 13fc79e461SBenjamin Kietzman #include <dbus/message.hpp> 14fc79e461SBenjamin Kietzman #include <dbus/detail/watch_timeout.hpp> 15fc79e461SBenjamin Kietzman #include <dbus/detail/queue.hpp> 16a1051121SBenjamin Kietzman #include <dbus/detail/async_send_op.hpp> 17fc79e461SBenjamin Kietzman 18d620effbSBenjamin Kietzman namespace dbus { 19d620effbSBenjamin Kietzman 20cd8b76a3SBenjamin Kietzman namespace bus { 21cd8b76a3SBenjamin Kietzman static const int session = DBUS_BUS_SESSION; 22cd8b76a3SBenjamin Kietzman static const int system = DBUS_BUS_SYSTEM; 23cd8b76a3SBenjamin Kietzman static const int starter = DBUS_BUS_STARTER; 24cd8b76a3SBenjamin Kietzman } // namespace bus 25cd8b76a3SBenjamin Kietzman 26fc79e461SBenjamin Kietzman using std::string; 27fc79e461SBenjamin Kietzman using namespace boost::asio; 28fc79e461SBenjamin Kietzman 2917826fe7SBenjamin Kietzman class filter; 3017826fe7SBenjamin Kietzman class match; 3117826fe7SBenjamin Kietzman 32d620effbSBenjamin Kietzman class connection_service 33d620effbSBenjamin Kietzman : public io_service::service 34d620effbSBenjamin Kietzman { 35d620effbSBenjamin Kietzman public: 36d620effbSBenjamin Kietzman static io_service::id id; 37d620effbSBenjamin Kietzman 38d620effbSBenjamin Kietzman typedef DBusConnection *implementation_type; 39d620effbSBenjamin Kietzman 40d620effbSBenjamin Kietzman explicit connection_service(io_service& io) 41d620effbSBenjamin Kietzman : service(io) 42d620effbSBenjamin Kietzman { 43d620effbSBenjamin Kietzman } 44d620effbSBenjamin Kietzman 45d620effbSBenjamin Kietzman void construct(implementation_type& impl) 46d620effbSBenjamin Kietzman { 47d620effbSBenjamin Kietzman } 48d620effbSBenjamin Kietzman 49d620effbSBenjamin Kietzman void destroy(implementation_type& impl) 50d620effbSBenjamin Kietzman { 51d620effbSBenjamin Kietzman dbus_connection_unref(impl); 52d620effbSBenjamin Kietzman } 53d620effbSBenjamin Kietzman 54d620effbSBenjamin Kietzman void shutdown_service() 55d620effbSBenjamin Kietzman { 56cd8b76a3SBenjamin Kietzman //TODO is there anything that needs shutting down? 57d620effbSBenjamin Kietzman } 58d620effbSBenjamin Kietzman 59d620effbSBenjamin Kietzman void open(implementation_type& impl, 60d620effbSBenjamin Kietzman const string& address, bool shared=true) 61d620effbSBenjamin Kietzman { 62d620effbSBenjamin Kietzman io_service& io = this->get_io_service(); 63d620effbSBenjamin Kietzman 6485860989SBenjamin Kietzman error e; 6585860989SBenjamin Kietzman impl = dbus_connection_open(address.c_str(), e); 66d620effbSBenjamin Kietzman 6785860989SBenjamin Kietzman e.throw_if_set(); 68cd8b76a3SBenjamin Kietzman detail::set_watch_timeout_dispatch_functions(impl, io); 69d620effbSBenjamin Kietzman } 70d620effbSBenjamin Kietzman 71d620effbSBenjamin Kietzman void open(implementation_type& impl, 72cd8b76a3SBenjamin Kietzman const int bus = (int) DBUS_BUS_SYSTEM, 73d620effbSBenjamin Kietzman bool shared=true) 74d620effbSBenjamin Kietzman { 75d620effbSBenjamin Kietzman io_service& io = this->get_io_service(); 76d620effbSBenjamin Kietzman 7785860989SBenjamin Kietzman error e; 7885860989SBenjamin Kietzman impl = dbus_bus_get((DBusBusType)bus, e); 79d620effbSBenjamin Kietzman 8085860989SBenjamin Kietzman e.throw_if_set(); 81cd8b76a3SBenjamin Kietzman detail::set_watch_timeout_dispatch_functions(impl, io); 82cd8b76a3SBenjamin Kietzman } 83d620effbSBenjamin Kietzman 84cd8b76a3SBenjamin Kietzman message send(implementation_type& impl, 85cd8b76a3SBenjamin Kietzman message& m) 86cd8b76a3SBenjamin Kietzman { 8785860989SBenjamin Kietzman error e; 8885860989SBenjamin Kietzman message reply(dbus_connection_send_with_reply_and_block(impl, 8985860989SBenjamin Kietzman m, -1, e)); 9085860989SBenjamin Kietzman 9185860989SBenjamin Kietzman e.throw_if_set(); 9285860989SBenjamin Kietzman return reply; 93d620effbSBenjamin Kietzman } 94d620effbSBenjamin Kietzman 95d620effbSBenjamin Kietzman template <typename Duration> 96d620effbSBenjamin Kietzman message send(implementation_type& impl, 97d620effbSBenjamin Kietzman message& m, 98d620effbSBenjamin Kietzman const Duration& timeout) 99d620effbSBenjamin Kietzman { 100d620effbSBenjamin Kietzman //TODO generically convert timeout to milliseconds 101cd8b76a3SBenjamin Kietzman if(timeout == Duration::zero()) { 102d620effbSBenjamin Kietzman //TODO this can return false if it failed 103*4317e4d9SBenjamin Kietzman dbus_connection_send(impl, m, NULL); 104d620effbSBenjamin Kietzman return message(); 105d620effbSBenjamin Kietzman } else { 10685860989SBenjamin Kietzman error e; 10785860989SBenjamin Kietzman message reply(dbus_connection_send_with_reply_and_block(impl, 10885860989SBenjamin Kietzman m, chrono::milliseconds(timeout).count(), e)); 10985860989SBenjamin Kietzman 11085860989SBenjamin Kietzman e.throw_if_set(); 11185860989SBenjamin Kietzman return reply; 112d620effbSBenjamin Kietzman } 113d620effbSBenjamin Kietzman } 114d620effbSBenjamin Kietzman 115d620effbSBenjamin Kietzman template<typename MessageHandler> 116d620effbSBenjamin Kietzman inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler, 117d620effbSBenjamin Kietzman void(boost::system::error_code, message)) 118d620effbSBenjamin Kietzman async_send(implementation_type& impl, 119d620effbSBenjamin Kietzman message& m, 120d620effbSBenjamin Kietzman BOOST_ASIO_MOVE_ARG(MessageHandler) handler) 121d620effbSBenjamin Kietzman { 122a1051121SBenjamin Kietzman boost::asio::detail::async_result_init< 123a1051121SBenjamin Kietzman MessageHandler, void(boost::system::error_code, message)> init( 124a1051121SBenjamin Kietzman BOOST_ASIO_MOVE_CAST(MessageHandler)(handler)); 125cd8b76a3SBenjamin Kietzman 126a1051121SBenjamin Kietzman detail::async_send_op< 127a1051121SBenjamin Kietzman BOOST_ASIO_HANDLER_TYPE(MessageHandler, 128a1051121SBenjamin Kietzman void(boost::system::error_code, message))>( 129a1051121SBenjamin Kietzman this->get_io_service(), 130a1051121SBenjamin Kietzman BOOST_ASIO_MOVE_CAST(MessageHandler)(init.handler)) (impl, m); 131a1051121SBenjamin Kietzman 132a1051121SBenjamin Kietzman return init.result.get(); 133d620effbSBenjamin Kietzman } 134d620effbSBenjamin Kietzman 135cd8b76a3SBenjamin Kietzman void new_match(implementation_type& impl, 13617826fe7SBenjamin Kietzman match& m); 137cd8b76a3SBenjamin Kietzman 138cd8b76a3SBenjamin Kietzman void delete_match(implementation_type& impl, 13917826fe7SBenjamin Kietzman match& m); 140cd8b76a3SBenjamin Kietzman 14117826fe7SBenjamin Kietzman static DBusHandlerResult filter_callback( 142cd8b76a3SBenjamin Kietzman DBusConnection *c, 143cd8b76a3SBenjamin Kietzman DBusMessage *m, 14417826fe7SBenjamin Kietzman void *userdata); 145cd8b76a3SBenjamin Kietzman 146cd8b76a3SBenjamin Kietzman void new_filter(implementation_type& impl, 14717826fe7SBenjamin Kietzman filter& f); 148cd8b76a3SBenjamin Kietzman 149cd8b76a3SBenjamin Kietzman void delete_filter(implementation_type& impl, 15017826fe7SBenjamin Kietzman filter& f); 15117826fe7SBenjamin Kietzman 152d620effbSBenjamin Kietzman }; 153d620effbSBenjamin Kietzman 154d620effbSBenjamin Kietzman io_service::id connection_service::id; 155d620effbSBenjamin Kietzman 156cd8b76a3SBenjamin Kietzman 157cd8b76a3SBenjamin Kietzman 158cd8b76a3SBenjamin Kietzman 159d620effbSBenjamin Kietzman } // namespace dbus 160fc79e461SBenjamin Kietzman 161fc79e461SBenjamin Kietzman #endif // DBUS_CONNECTION_SERVICE_HPP 162