connection.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-or-later OR BSD-3-Clause
2 /***************************************************************************
3  * Copyright (C) 2009,2010 by Rick L. Vinyard, Jr. *
4  * rvinyard@cs.nmsu.edu *
5  * Copyright (C) 2019 by Robert Middleton *
6  * robert.middleton@rm5248.com *
7  * *
8  * This file is part of the dbus-cxx library. *
9  ***************************************************************************/
10 #include <stdint.h>
11 #include <dbus-cxx/signal.h>
12 #include <dbus-cxx/signalproxy.h>
14 #include <dbus-cxx/errormessage.h>
16 #include <deque>
17 #include <map>
18 #include <memory>
19 #include <string>
20 #include <vector>
21 #include "enums.h"
22 #include <sigc++/sigc++.h>
23 #include <future>
24 #include <queue>
25 
26 #ifndef DBUSCXX_CONNECTION_H
27 #define DBUSCXX_CONNECTION_H
28 
30 #define DBUSCXX_NAME_FLAG_ALLOW_REPLACEMENT 0x01
32 #define DBUSCXX_NAME_FLAG_REPLACE_EXISTING 0x02
34 #define DBUSCXX_NAME_FLAG_DO_NOT_QUEUE 0x04
35 
36 #define DBUSCXX_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable"
38 #define DBUSCXX_INTROSPECT_1_0_XML_NAMESPACE "http://www.freedesktop.org/standards/dbus"
40 #define DBUSCXX_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
42 #define DBUSCXX_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"
44 #define DBUSCXX_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<!DOCTYPE node PUBLIC \""\
45  DBUSCXX_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "\"\n\"" DBUSCXX_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "\">\n"
46 
47 
48 namespace DBus {
49 class Message;
50 class Object;
51 class ObjectPathHandler;
52 class ObjectProxy;
53 class PendingCall;
54 class ReturnMessage;
55 class SignalMessage;
56 class Timeout;
57 class Watch;
58 class ThreadDispatcher;
59 class ErrorMessage;
60 class DBusDaemonProxy;
61 
62 namespace priv {
63 class Transport;
64 }
65 
73 class Connection : public std::enable_shared_from_this<Connection> {
74 
75 private:
77 
78  Connection( std::string address );
79 
80 public:
88  static std::shared_ptr<Connection> create( BusType type );
89 
100  static std::shared_ptr<Connection> create( std::string address );
101 
102  ~Connection();
103 
105  operator bool() const;
106 
108  bool is_valid() const;
109 
111  bool is_registered() const;
112 
117  bool bus_register();
118 
120  std::string unique_name() const;
121 
129  RequestNameResponse request_name( const std::string& name, unsigned int flags = 0 );
130 
137  ReleaseNameResponse release_name( const std::string& name );
138 
154  bool name_has_owner( const std::string& name ) const;
155 
162  StartReply start_service( const std::string& name, uint32_t flags = 0 ) const;
163 
164  bool add_match( const std::string& rule );
165 
166  void add_match_nonblocking( const std::string& rule );
167 
168  bool remove_match( const std::string& rule );
169 
170  bool is_connected() const;
171 
172  bool is_authenticated() const;
173 
174  bool is_anonymous() const;
175 
176  const char* server_id() const;
177 
184  uint32_t send( const std::shared_ptr<const Message> message );
185 
190  Connection& operator<<( std::shared_ptr<const Message> msg );
191 
201  std::shared_ptr<ReturnMessage> send_with_reply_blocking( std::shared_ptr<const CallMessage> msg, int timeout_milliseconds = -1 );
202 
208  void flush();
209 
211 
227 
228  int unix_fd() const;
229 
230  int socket() const;
231 
232  bool has_messages_to_send();
233 
242  sigc::signal<void()>& signal_needs_dispatch();
243 
252  std::shared_ptr<Object> create_object( const std::string& path,
254 
264  RegistrationStatus register_object( std::shared_ptr<Object> object,
266 
275  bool change_object_calling_thread( std::shared_ptr<Object> object,
276  ThreadForCalling calling );
277 
286  bool change_object_proxy_calling_thread( std::shared_ptr<ObjectProxy> object,
287  ThreadForCalling calling );
288 
289  std::shared_ptr<ObjectProxy> create_object_proxy( const std::string& path,
291 
292  std::shared_ptr<ObjectProxy> create_object_proxy( const std::string& destination, const std::string& path,
294 
302  bool register_object_proxy( std::shared_ptr<ObjectProxy> obj,
304 
305  bool unregister_object( const std::string& path );
306 
318  template<typename... T_arg>
319  std::shared_ptr<SignalProxy<T_arg...> > create_free_signal_proxy( const SignalMatchRule& rule,
321  std::shared_ptr<SignalProxy<T_arg...> > sig;
322  sig = SignalProxy<T_arg...>::create( rule );
323  this->add_free_signal_proxy( sig, calling );
324  return sig;
325  }
326 
330  std::shared_ptr<SignalProxyBase> add_free_signal_proxy( std::shared_ptr<SignalProxyBase> Signal,
332 
339  bool remove_free_signal_proxy( std::shared_ptr<SignalProxyBase> proxy );
340 
342  const std::vector<std::shared_ptr<SignalProxyBase>> get_free_signal_proxies();
343 
345  std::vector<std::shared_ptr<SignalProxyBase>> get_free_signal_proxies( const std::string& interface_name );
346 
348  std::vector<std::shared_ptr<SignalProxyBase>> get_free_signal_proxies( const std::string& interface_name, const std::string& member );
349 
354  template <class T_arg>
355  std::shared_ptr<Signal<T_arg> > create_free_signal( const std::string& path, const std::string& interface_name, const std::string& member ) {
356  std::shared_ptr<Signal<T_arg> > sig;
357  sig = Signal<T_arg>::create( path, interface_name, member );
358  sig->set_connection( shared_from_this() );
359  return sig;
360  }
361 
362  std::string introspect( const std::string& destination, const std::string& path );
363 
374  void set_dispatching_thread( std::thread::id tid );
375 
389  void add_thread_dispatcher( std::weak_ptr<ThreadDispatcher> disp );
390 
391 private:
398 
406  uint32_t write_single_message( std::shared_ptr<const Message> msg );
407 
408  void process_single_message();
409 
411 
417  void send_error_on_handler_result( std::shared_ptr<const CallMessage> msg, HandlerResult result );
418 
419  void process_call_message( std::shared_ptr<const CallMessage> msg );
420  void process_signal_message( std::shared_ptr<const SignalMessage> msg );
421 
422  std::thread::id thread_id_from_calling( ThreadForCalling calling );
423 
424 private:
425  class priv_data;
426 
427  DBUS_CXX_PROPAGATE_CONST( std::unique_ptr<priv_data> ) m_priv;
428 };
429 
430 inline
431 std::shared_ptr<DBus::Connection> operator<<( std::shared_ptr<DBus::Connection> ptr, std::shared_ptr<DBus::Message> msg ) {
432  if( !ptr ) { return ptr; }
433 
434  *ptr << msg;
435  return ptr;
436 }
437 
438 inline
439 std::shared_ptr<DBus::Connection> operator<<( std::shared_ptr<DBus::Connection> ptr, std::shared_ptr<const DBus::Message> msg ) {
440  if( !ptr ) { return ptr; }
441 
442  *ptr << msg;
443  return ptr;
444 }
445 
446 inline
447 std::shared_ptr<DBus::Connection> operator<<( std::shared_ptr<DBus::Connection> ptr, std::shared_ptr<DBus::ReturnMessage> msg ) {
448  if( !ptr ) { return ptr; }
449 
450  *ptr << msg;
451  return ptr;
452 }
453 
454 inline
455 std::shared_ptr<DBus::Connection> operator<<( std::shared_ptr<DBus::Connection> ptr, std::shared_ptr<const DBus::ReturnMessage> msg ) {
456  if( !ptr ) { return ptr; }
457 
458  *ptr << msg;
459  return ptr;
460 }
461 
462 inline
463 std::shared_ptr<DBus::Connection> operator<<( std::shared_ptr<DBus::Connection> ptr, std::shared_ptr<DBus::SignalMessage> msg ) {
464  if( !ptr ) { return ptr; }
465 
466  *ptr << msg;
467  return ptr;
468 }
469 
470 inline
471 std::shared_ptr<DBus::Connection> operator<<( std::shared_ptr<DBus::Connection> ptr, std::shared_ptr<const DBus::SignalMessage> msg ) {
472  if( !ptr ) { return ptr; }
473 
474  *ptr << msg;
475  return ptr;
476 }
477 
478 inline
479 std::shared_ptr<DBus::Connection> operator<<( std::shared_ptr<DBus::Connection> ptr, std::shared_ptr<DBus::ErrorMessage> msg ) {
480  if( !ptr ) { return ptr; }
481 
482  *ptr << msg;
483  return ptr;
484 }
485 
486 inline
487 std::shared_ptr<DBus::Connection> operator<<( std::shared_ptr<DBus::Connection> ptr, std::shared_ptr<const DBus::ErrorMessage> msg ) {
488  if( !ptr ) { return ptr; }
489 
490  *ptr << msg;
491  return ptr;
492 }
493 
494 } /* namespace DBus */
495 
496 #endif
Connection point to the DBus.
Definition: connection.h:73
int unix_fd() const
Definition: connection.cpp:797
uint32_t send(const std::shared_ptr< const Message > message)
Queues up the message to be sent on the bus.
Definition: connection.cpp:371
bool unregister_object(const std::string &path)
Definition: connection.cpp:890
RequestNameResponse request_name(const std::string &name, unsigned int flags=0)
Request the given name on the bus.
Definition: connection.cpp:233
static std::shared_ptr< Connection > create(BusType type)
Connects to a bus daemon.
Definition: connection.cpp:183
bool is_authenticated() const
Definition: connection.cpp:353
~Connection()
Definition: connection.cpp:196
bool is_connected() const
Definition: connection.cpp:347
bool remove_match(const std::string &rule)
Definition: connection.cpp:329
bool is_anonymous() const
Definition: connection.cpp:359
void process_call_message(std::shared_ptr< const CallMessage > msg)
Definition: connection.cpp:659
std::shared_ptr< Object > create_object(const std::string &path, ThreadForCalling calling=ThreadForCalling::DispatcherThread)
Create and return a new object, registering the object automatically.
Definition: connection.cpp:819
void send_error_on_handler_result(std::shared_ptr< const CallMessage > msg, HandlerResult result)
Send an error back to the calling application based on HandlerResult.
Definition: connection.cpp:758
bool add_match(const std::string &rule)
Definition: connection.cpp:302
DBUS_CXX_PROPAGATE_CONST(std::unique_ptr< priv_data >) m_priv
void set_dispatching_thread(std::thread::id tid)
Set the ID of the thread that all of the dispatching hapens from.
Definition: connection.cpp:1047
bool name_has_owner(const std::string &name) const
Check to see if the given name currently has an owner.
Definition: connection.cpp:281
sigc::signal< void()> & signal_needs_dispatch()
This signal is emitted whenever we need to be dispatched.
Definition: connection.cpp:815
void add_thread_dispatcher(std::weak_ptr< ThreadDispatcher > disp)
Add a thread dispatcher that will handle messages for a given thread.
Definition: connection.cpp:1061
std::shared_ptr< ReturnMessage > send_with_reply_blocking(std::shared_ptr< const CallMessage > msg, int timeout_milliseconds=-1)
Send a CallMessage, and wait for the reply.
Definition: connection.cpp:397
void flush()
Flushes all data out to the bus.
Definition: connection.cpp:552
std::shared_ptr< ObjectProxy > create_object_proxy(const std::string &path, ThreadForCalling calling=ThreadForCalling::DispatcherThread)
Definition: connection.cpp:878
Connection & operator<<(std::shared_ptr< const Message > msg)
Blindly sends the message on the connection.
Definition: connection.cpp:391
std::shared_ptr< Signal< T_arg > > create_free_signal(const std::string &path, const std::string &interface_name, const std::string &member)
Create a free signal, that when it is emitted will send that signal over the DBus.
Definition: connection.h:355
bool has_messages_to_send()
Definition: connection.cpp:809
std::string unique_name() const
Gets the unique name of the connection as assigned by the message bus.
Definition: connection.cpp:227
void process_single_message()
Definition: connection.cpp:615
std::thread::id thread_id_from_calling(ThreadForCalling calling)
Definition: connection.cpp:1129
Connection(BusType type)
Definition: connection.cpp:124
void notify_dispatcher_or_dispatch()
Depending on what thread this is called from, will either notify the dispatcher that we need to be di...
Definition: connection.cpp:1051
void remove_invalid_threaddispatchers_and_associated_objects()
Definition: connection.cpp:1066
int socket() const
Definition: connection.cpp:803
RegistrationStatus register_object(std::shared_ptr< Object > object, ThreadForCalling calling=ThreadForCalling::DispatcherThread)
Register an object with this connection.
Definition: connection.cpp:831
bool change_object_proxy_calling_thread(std::shared_ptr< ObjectProxy > object, ThreadForCalling calling)
Change the thread that the signals on this ObjectProxy will be called from.
Definition: connection.cpp:1098
std::shared_ptr< SignalProxyBase > add_free_signal_proxy(std::shared_ptr< SignalProxyBase > Signal, ThreadForCalling calling=ThreadForCalling::DispatcherThread)
Adds the given signal proxy to the connection.
Definition: connection.cpp:903
void process_signal_message(std::shared_ptr< const SignalMessage > msg)
Definition: connection.cpp:707
bool remove_free_signal_proxy(std::shared_ptr< SignalProxyBase > proxy)
Remove a free signal proxy, so that it will not be called anymore.
Definition: connection.cpp:947
DispatchStatus dispatch_status() const
Definition: connection.cpp:573
const char * server_id() const
Definition: connection.cpp:365
std::shared_ptr< SignalProxy< T_arg... > > create_free_signal_proxy(const SignalMatchRule &rule, ThreadForCalling calling=ThreadForCalling::DispatcherThread)
Create and return a signal proxy that lets you listen to signals sent on the DBus as a free proxy.
Definition: connection.h:319
bool is_valid() const
True if this is a valid connection; false otherwise.
Definition: connection.cpp:203
std::string introspect(const std::string &destination, const std::string &path)
Definition: connection.cpp:1025
bool is_registered() const
True if this connection is already registered.
Definition: connection.cpp:223
bool change_object_calling_thread(std::shared_ptr< Object > object, ThreadForCalling calling)
Change the thread that the methods on this object will be called from.
Definition: connection.cpp:858
void add_match_nonblocking(const std::string &rule)
Definition: connection.cpp:324
StartReply start_service(const std::string &name, uint32_t flags=0) const
start_service
Definition: connection.cpp:285
ReleaseNameResponse release_name(const std::string &name)
Release the specified name, after requesting it via request_name.
Definition: connection.cpp:261
uint32_t write_single_message(std::shared_ptr< const Message > msg)
Write a single message, return the serial of this message.
Definition: connection.cpp:567
DispatchStatus dispatch()
Dispatch the connection.
Definition: connection.cpp:579
const std::vector< std::shared_ptr< SignalProxyBase > > get_free_signal_proxies()
Gets all the free signal handlers.
Definition: connection.cpp:989
bool register_object_proxy(std::shared_ptr< ObjectProxy > obj, ThreadForCalling calling=ThreadForCalling::DispatcherThread)
Add an ObjectProxy to this Connection.
Definition: connection.cpp:1117
bool bus_register()
Registers this connection with the bus.
Definition: connection.cpp:207
A special MatchRule for signals.
Definition: matchrule.h:45
Definition: signalproxy.h:26
Definition: signal.h:20
Definition: transport.h:22
Global DBus namespace, where everything happens.
Definition: callmessage.cpp:18
DispatchStatus
Definition: enums.h:89
std::shared_ptr< DBus::Connection > operator<<(std::shared_ptr< DBus::Connection > ptr, std::shared_ptr< DBus::Message > msg)
Definition: connection.h:431
StartReply
Definition: enums.h:108
BusType
Definition: enums.h:16
ReleaseNameResponse
Definition: enums.h:167
DataType type(const uint8_t &)
Definition: types.h:137
HandlerResult
Definition: enums.h:95
RequestNameResponse
Response status to attempting to register a name on the bus.
Definition: enums.h:156
RegistrationStatus
Definition: enums.h:119
ThreadForCalling
Gives hints to the connection as to which thread should be the one to call the methods on the given o...
Definition: enums.h:133
@ DispatcherThread
Always call methods for this object from the dispatcher thread.