1fc79e461SBenjamin Kietzman #ifndef DBUS_CONNECTION_SERVICE_HPP 2fc79e461SBenjamin Kietzman #define DBUS_CONNECTION_SERVICE_HPP 3fc79e461SBenjamin Kietzman 4fc79e461SBenjamin Kietzman #include <string> 5d620effbSBenjamin Kietzman #include <boost/asio.hpp> 6d620effbSBenjamin Kietzman 785860989SBenjamin Kietzman #include <dbus/error.hpp> 8fc79e461SBenjamin Kietzman #include <dbus/message.hpp> 9fc79e461SBenjamin Kietzman #include <dbus/detail/watch_timeout.hpp> 10fc79e461SBenjamin Kietzman #include <dbus/detail/queue.hpp> 11*a1051121SBenjamin Kietzman #include <dbus/detail/async_send_op.hpp> 12fc79e461SBenjamin Kietzman 13d620effbSBenjamin Kietzman namespace dbus { 14d620effbSBenjamin Kietzman 15cd8b76a3SBenjamin Kietzman namespace bus { 16cd8b76a3SBenjamin Kietzman static const int session = DBUS_BUS_SESSION; 17cd8b76a3SBenjamin Kietzman static const int system = DBUS_BUS_SYSTEM; 18cd8b76a3SBenjamin Kietzman static const int starter = DBUS_BUS_STARTER; 19cd8b76a3SBenjamin Kietzman } // namespace bus 20cd8b76a3SBenjamin Kietzman 21fc79e461SBenjamin Kietzman using std::string; 22fc79e461SBenjamin Kietzman using namespace boost::asio; 23fc79e461SBenjamin Kietzman 2417826fe7SBenjamin Kietzman class filter; 2517826fe7SBenjamin Kietzman class match; 2617826fe7SBenjamin Kietzman 27d620effbSBenjamin Kietzman class connection_service 28d620effbSBenjamin Kietzman : public io_service::service 29d620effbSBenjamin Kietzman { 30d620effbSBenjamin Kietzman public: 31d620effbSBenjamin Kietzman static io_service::id id; 32d620effbSBenjamin Kietzman 33d620effbSBenjamin Kietzman typedef DBusConnection *implementation_type; 34d620effbSBenjamin Kietzman 35d620effbSBenjamin Kietzman explicit connection_service(io_service& io) 36d620effbSBenjamin Kietzman : service(io) 37d620effbSBenjamin Kietzman { 38d620effbSBenjamin Kietzman } 39d620effbSBenjamin Kietzman 40d620effbSBenjamin Kietzman void construct(implementation_type& impl) 41d620effbSBenjamin Kietzman { 42d620effbSBenjamin Kietzman } 43d620effbSBenjamin Kietzman 44d620effbSBenjamin Kietzman void destroy(implementation_type& impl) 45d620effbSBenjamin Kietzman { 46d620effbSBenjamin Kietzman dbus_connection_unref(impl); 47d620effbSBenjamin Kietzman } 48d620effbSBenjamin Kietzman 49d620effbSBenjamin Kietzman void shutdown_service() 50d620effbSBenjamin Kietzman { 51cd8b76a3SBenjamin Kietzman //TODO is there anything that needs shutting down? 52d620effbSBenjamin Kietzman } 53d620effbSBenjamin Kietzman 54d620effbSBenjamin Kietzman void open(implementation_type& impl, 55d620effbSBenjamin Kietzman const string& address, bool shared=true) 56d620effbSBenjamin Kietzman { 57d620effbSBenjamin Kietzman io_service& io = this->get_io_service(); 58d620effbSBenjamin Kietzman 5985860989SBenjamin Kietzman error e; 6085860989SBenjamin Kietzman impl = dbus_connection_open(address.c_str(), e); 61d620effbSBenjamin Kietzman 6285860989SBenjamin Kietzman e.throw_if_set(); 63cd8b76a3SBenjamin Kietzman detail::set_watch_timeout_dispatch_functions(impl, io); 64d620effbSBenjamin Kietzman } 65d620effbSBenjamin Kietzman 66d620effbSBenjamin Kietzman void open(implementation_type& impl, 67cd8b76a3SBenjamin Kietzman const int bus = (int) DBUS_BUS_SYSTEM, 68d620effbSBenjamin Kietzman bool shared=true) 69d620effbSBenjamin Kietzman { 70d620effbSBenjamin Kietzman io_service& io = this->get_io_service(); 71d620effbSBenjamin Kietzman 7285860989SBenjamin Kietzman error e; 7385860989SBenjamin Kietzman impl = dbus_bus_get((DBusBusType)bus, e); 74d620effbSBenjamin Kietzman 7585860989SBenjamin Kietzman e.throw_if_set(); 76cd8b76a3SBenjamin Kietzman detail::set_watch_timeout_dispatch_functions(impl, io); 77cd8b76a3SBenjamin Kietzman } 78d620effbSBenjamin Kietzman 79cd8b76a3SBenjamin Kietzman message send(implementation_type& impl, 80cd8b76a3SBenjamin Kietzman message& m) 81cd8b76a3SBenjamin Kietzman { 8285860989SBenjamin Kietzman error e; 8385860989SBenjamin Kietzman message reply(dbus_connection_send_with_reply_and_block(impl, 8485860989SBenjamin Kietzman m, -1, e)); 8585860989SBenjamin Kietzman 8685860989SBenjamin Kietzman e.throw_if_set(); 8785860989SBenjamin Kietzman return reply; 88d620effbSBenjamin Kietzman } 89d620effbSBenjamin Kietzman 90d620effbSBenjamin Kietzman template <typename Duration> 91d620effbSBenjamin Kietzman message send(implementation_type& impl, 92d620effbSBenjamin Kietzman message& m, 93d620effbSBenjamin Kietzman const Duration& timeout) 94d620effbSBenjamin Kietzman { 95d620effbSBenjamin Kietzman //TODO generically convert timeout to milliseconds 96cd8b76a3SBenjamin Kietzman if(timeout == Duration::zero()) { 97d620effbSBenjamin Kietzman //TODO this can return false if it failed 98d620effbSBenjamin Kietzman dbus_connection_send(impl, m, &m.serial); 99d620effbSBenjamin Kietzman return message(); 100d620effbSBenjamin Kietzman } else { 10185860989SBenjamin Kietzman error e; 10285860989SBenjamin Kietzman message reply(dbus_connection_send_with_reply_and_block(impl, 10385860989SBenjamin Kietzman m, chrono::milliseconds(timeout).count(), e)); 10485860989SBenjamin Kietzman 10585860989SBenjamin Kietzman e.throw_if_set(); 10685860989SBenjamin Kietzman return reply; 107d620effbSBenjamin Kietzman } 108d620effbSBenjamin Kietzman } 109d620effbSBenjamin Kietzman 110d620effbSBenjamin Kietzman template<typename MessageHandler> 111d620effbSBenjamin Kietzman inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler, 112d620effbSBenjamin Kietzman void(boost::system::error_code, message)) 113d620effbSBenjamin Kietzman async_send(implementation_type& impl, 114d620effbSBenjamin Kietzman message& m, 115d620effbSBenjamin Kietzman BOOST_ASIO_MOVE_ARG(MessageHandler) handler) 116d620effbSBenjamin Kietzman { 117*a1051121SBenjamin Kietzman boost::asio::detail::async_result_init< 118*a1051121SBenjamin Kietzman MessageHandler, void(boost::system::error_code, message)> init( 119*a1051121SBenjamin Kietzman BOOST_ASIO_MOVE_CAST(MessageHandler)(handler)); 120cd8b76a3SBenjamin Kietzman 121*a1051121SBenjamin Kietzman detail::async_send_op< 122*a1051121SBenjamin Kietzman BOOST_ASIO_HANDLER_TYPE(MessageHandler, 123*a1051121SBenjamin Kietzman void(boost::system::error_code, message))>( 124*a1051121SBenjamin Kietzman this->get_io_service(), 125*a1051121SBenjamin Kietzman BOOST_ASIO_MOVE_CAST(MessageHandler)(init.handler)) (impl, m); 126*a1051121SBenjamin Kietzman 127*a1051121SBenjamin Kietzman return init.result.get(); 128d620effbSBenjamin Kietzman } 129d620effbSBenjamin Kietzman 130cd8b76a3SBenjamin Kietzman void new_match(implementation_type& impl, 13117826fe7SBenjamin Kietzman match& m); 132cd8b76a3SBenjamin Kietzman 133cd8b76a3SBenjamin Kietzman void delete_match(implementation_type& impl, 13417826fe7SBenjamin Kietzman match& m); 135cd8b76a3SBenjamin Kietzman 13617826fe7SBenjamin Kietzman static DBusHandlerResult filter_callback( 137cd8b76a3SBenjamin Kietzman DBusConnection *c, 138cd8b76a3SBenjamin Kietzman DBusMessage *m, 13917826fe7SBenjamin Kietzman void *userdata); 140cd8b76a3SBenjamin Kietzman 141cd8b76a3SBenjamin Kietzman void new_filter(implementation_type& impl, 14217826fe7SBenjamin Kietzman filter& f); 143cd8b76a3SBenjamin Kietzman 144cd8b76a3SBenjamin Kietzman void delete_filter(implementation_type& impl, 14517826fe7SBenjamin Kietzman filter& f); 14617826fe7SBenjamin Kietzman 147d620effbSBenjamin Kietzman }; 148d620effbSBenjamin Kietzman 149d620effbSBenjamin Kietzman io_service::id connection_service::id; 150d620effbSBenjamin Kietzman 151cd8b76a3SBenjamin Kietzman 152cd8b76a3SBenjamin Kietzman 153cd8b76a3SBenjamin Kietzman 154d620effbSBenjamin Kietzman } // namespace dbus 155fc79e461SBenjamin Kietzman 156fc79e461SBenjamin Kietzman #endif // DBUS_CONNECTION_SERVICE_HPP 157