DBusConnectionStatusEvent: AVAILABLE on subscribe if isConnected
[profile/ivi/common-api-dbus-runtime.git] / src / CommonAPI / DBus / DBusConnection.h
1 /* Copyright (C) 2013 BMW Group
2  * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
3  * Author: Juergen Gehring (juergen.gehring@bmw.de)
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef COMMONAPI_DBUS_DBUS_CONNECTION_H_
8 #define COMMONAPI_DBUS_DBUS_CONNECTION_H_
9
10 #include "DBusProxyConnection.h"
11 #include "DBusDaemonProxy.h"
12 #include "DBusServiceRegistry.h"
13 #include "DBusObjectManager.h"
14
15 #include <dbus/dbus.h>
16
17
18 namespace CommonAPI {
19 namespace DBus {
20
21 class DBusObjectManager;
22
23 class DBusConnectionStatusEvent: public DBusProxyConnection::ConnectionStatusEvent {
24     friend class DBusConnection;
25
26  public:
27     DBusConnectionStatusEvent(DBusConnection* dbusConnection);
28
29  protected:
30     virtual void onListenerAdded(const CancellableListener& listener);
31
32     DBusConnection* dbusConnection_;
33 };
34
35
36 class DBusConnection: public DBusProxyConnection, public std::enable_shared_from_this<DBusConnection> {
37  public:
38         enum BusType {
39                 SESSION = DBUS_BUS_SESSION,
40                 SYSTEM = DBUS_BUS_SYSTEM,
41                 STARTER = DBUS_BUS_STARTER,
42                 WRAPPED
43         };
44
45         inline static std::shared_ptr<DBusConnection> getBus(const BusType& busType);
46         inline static std::shared_ptr<DBusConnection> wrapLibDBus(::DBusConnection* libDbusConnection);
47         inline static std::shared_ptr<DBusConnection> getSessionBus();
48         inline static std::shared_ptr<DBusConnection> getSystemBus();
49         inline static std::shared_ptr<DBusConnection> getStarterBus();
50
51         DBusConnection(const DBusConnection&) = delete;
52         DBusConnection(::DBusConnection* libDbusConnection);
53
54         DBusConnection& operator=(const DBusConnection&) = delete;
55         virtual ~DBusConnection();
56
57         BusType getBusType() const;
58
59         bool connect();
60         bool connect(DBusError& dbusError);
61         void disconnect();
62
63         virtual bool isConnected() const;
64
65         virtual ConnectionStatusEvent& getConnectionStatusEvent();
66
67         virtual bool requestServiceNameAndBlock(const std::string& serviceName) const;
68         virtual bool releaseServiceName(const std::string& serviceName) const;
69
70         bool sendDBusMessage(const DBusMessage& dbusMessage, uint32_t* allocatedSerial = NULL) const;
71
72         static const int kDefaultSendTimeoutMs = 100 * 1000;
73
74         std::future<CallStatus> sendDBusMessageWithReplyAsync(
75                         const DBusMessage& dbusMessage,
76                         std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler,
77                         int timeoutMilliseconds = kDefaultSendTimeoutMs) const;
78
79         DBusMessage sendDBusMessageWithReplyAndBlock(const DBusMessage& dbusMessage,
80                                                      DBusError& dbusError,
81                                                      int timeoutMilliseconds = kDefaultSendTimeoutMs) const;
82
83         DBusSignalHandlerToken addSignalMemberHandler(const std::string& objectPath,
84                                                       const std::string& interfaceName,
85                                                       const std::string& interfaceMemberName,
86                                                       const std::string& interfaceMemberSignature,
87                                                       DBusSignalHandler* dbusSignalHandler);
88
89         void registerObjectPath(const std::string& objectPath);
90         void unregisterObjectPath(const std::string& objectPath);
91
92         void removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken);
93
94         bool readWriteDispatch(int timeoutMilliseconds = -1);
95
96         virtual const std::shared_ptr<DBusDaemonProxy>& getDBusDaemonProxy();
97     virtual const std::shared_ptr<DBusServiceRegistry>& getDBusServiceRegistry();
98     virtual const std::shared_ptr<DBusObjectManager>& getDBusObjectManager();
99
100  private:
101     void dispatch();
102
103     std::thread dispatchThread_;
104     bool stopDispatching_;
105
106         DBusConnection(BusType busType);
107
108         void addLibdbusSignalMatchRule(const std::string& objectPath,
109                                        const std::string& interfaceName,
110                                        const std::string& interfaceMemberName);
111
112         void removeLibdbusSignalMatchRule(const std::string& objectPath,
113                                           const std::string& interfaceName,
114                                           const std::string& interfaceMemberName);
115
116         void initLibdbusObjectPathHandlerAfterConnect();
117
118         void initLibdbusSignalFilterAfterConnect();
119
120         ::DBusHandlerResult onLibdbusObjectPathMessage(::DBusMessage* libdbusMessage) const;
121
122         ::DBusHandlerResult onLibdbusSignalFilter(::DBusMessage* libdbusMessage);
123
124         static void onLibdbusPendingCallNotifyThunk(::DBusPendingCall* libdbusPendingCall, void *userData);
125         static void onLibdbusDataCleanup(void* userData);
126
127         static ::DBusHandlerResult onLibdbusObjectPathMessageThunk(::DBusConnection* libdbusConnection,
128                                                                    ::DBusMessage* libdbusMessage,
129                                                                     void* userData);
130
131         static ::DBusHandlerResult onLibdbusSignalFilterThunk(::DBusConnection* libdbusConnection,
132                                                               ::DBusMessage* libdbusMessage,
133                                                                void* userData);
134
135         BusType busType_;
136
137         ::DBusConnection* libdbusConnection_;
138
139         std::shared_ptr<DBusDaemonProxy> dbusDaemonProxy_;
140         std::shared_ptr<DBusServiceRegistry> dbusServiceRegistry_;
141     std::shared_ptr<DBusObjectManager> dbusObjectManager_;
142
143         DBusConnectionStatusEvent dbusConnectionStatusEvent_;
144
145         typedef std::tuple<std::string, std::string, std::string> DBusSignalMatchRuleTuple;
146         typedef std::pair<uint32_t, std::string> DBusSignalMatchRuleMapping;
147         typedef std::unordered_map<DBusSignalMatchRuleTuple, DBusSignalMatchRuleMapping> DBusSignalMatchRulesMap;
148         DBusSignalMatchRulesMap dbusSignalMatchRulesMap_;
149
150     bool isLibdbusSignalFilterAdded_;
151
152     DBusSignalHandlerTable dbusSignalHandlerTable_;
153
154     // referenceCount, objectPath
155     typedef std::unordered_map<std::string, uint32_t> LibdbusRegisteredObjectPathHandlersTable;
156     LibdbusRegisteredObjectPathHandlersTable libdbusRegisteredObjectPaths_;
157
158     static DBusObjectPathVTable libdbusObjectPathVTable_;
159 };
160
161 std::shared_ptr<DBusConnection> DBusConnection::getBus(const BusType& busType) {
162         return std::shared_ptr<DBusConnection>(new DBusConnection(busType));
163 }
164
165 std::shared_ptr<DBusConnection> DBusConnection::wrapLibDBus(::DBusConnection* libDbusConnection) {
166     return std::shared_ptr<DBusConnection>(new DBusConnection(libDbusConnection));
167 }
168
169 std::shared_ptr<DBusConnection> DBusConnection::getSessionBus() {
170         return getBus(BusType::SESSION);
171 }
172
173 std::shared_ptr<DBusConnection> DBusConnection::getSystemBus() {
174         return getBus(BusType::SYSTEM);
175 }
176
177 std::shared_ptr<DBusConnection> DBusConnection::getStarterBus() {
178         return getBus(BusType::STARTER);
179 }
180
181
182 } // namespace DBus
183 } // namespace CommonAPI
184
185 #endif // COMMONAPI_DBUS_DBUS_CONNECTION_H_