2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Piotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
21 * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
22 * @brief Implementation of a class for communication with server
25 #ifdef DBUS_CONNECTION
28 #include "host-dbus-connection.hpp"
29 #include "host-dbus-definitions.hpp"
30 #include "exception.hpp"
31 #include "api/dbus-method-result-builder.hpp"
32 #include "api/messages.hpp"
34 #include "logger/logger.hpp"
35 #include "config/manager.hpp"
36 #include "zones-manager.hpp"
42 // Timeout in ms for waiting for dbus name.
43 // Can happen if glib loop is busy or not present.
44 // TODO: this should be in host's configuration file
45 const unsigned int NAME_ACQUIRED_TIMEOUT = 5 * 1000;
46 const std::string EMPTY_CALLER = "";
51 HostDbusConnection::HostDbusConnection(ZonesManager* zonesManagerPtr)
52 : mNameAcquired(false)
54 , mZonesManagerPtr(zonesManagerPtr)
56 LOGT("Connecting to host system DBUS");
57 mDbusConnection = dbus::DbusConnection::createSystem();
59 LOGT("Setting DBUS name");
60 mDbusConnection->setName(api::dbus::BUS_NAME,
61 std::bind(&HostDbusConnection::onNameAcquired, this),
62 std::bind(&HostDbusConnection::onNameLost, this));
64 if (!waitForName(NAME_ACQUIRED_TIMEOUT)) {
65 const std::string msg = "Could not acquire dbus name: " + api::dbus::BUS_NAME;
67 throw HostConnectionException(msg);
70 LOGT("Registering DBUS interface");
71 using namespace std::placeholders;
72 mDbusConnection->registerObject(api::dbus::OBJECT_PATH,
73 api::dbus::DEFINITION,
74 std::bind(&HostDbusConnection::onMessageCall,
75 this, _1, _2, _3, _4, _5),
76 std::bind(&HostDbusConnection::onClientVanished,
79 mSubscriptionId = mDbusConnection->signalSubscribe(std::bind(&HostDbusConnection::onSignalCall,
80 this, _1, _2, _3, _4, _5),
82 api::dbus::INTERFACE);
86 HostDbusConnection::~HostDbusConnection()
88 mDbusConnection->signalUnsubscribe(mSubscriptionId);
91 bool HostDbusConnection::waitForName(const unsigned int timeoutMs)
93 std::unique_lock<std::mutex> lock(mNameMutex);
94 mNameCondition.wait_for(lock,
95 std::chrono::milliseconds(timeoutMs),
97 return mNameAcquired || mNameLost;
100 return mNameAcquired;
103 void HostDbusConnection::onNameAcquired()
105 std::unique_lock<std::mutex> lock(mNameMutex);
106 mNameAcquired = true;
107 mNameCondition.notify_one();
110 void HostDbusConnection::onNameLost()
112 std::unique_lock<std::mutex> lock(mNameMutex);
114 mNameCondition.notify_one();
117 // TODO implement reconnecting
118 LOGE("TODO Reconnect !!!");
122 void HostDbusConnection::setProxyCallCallback(const ProxyCallCallback& callback)
124 mProxyCallCallback = callback;
127 void HostDbusConnection::onMessageCall(const std::string& objectPath,
128 const std::string& interface,
129 const std::string& methodName,
130 GVariant* parameters,
131 dbus::MethodResultBuilder::Pointer result)
133 if (objectPath != api::dbus::OBJECT_PATH || interface != api::dbus::INTERFACE) {
137 if (methodName == api::dbus::METHOD_SET_ACTIVE_ZONE) {
139 config::loadFromGVariant(parameters, zoneId);
141 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
142 mZonesManagerPtr->handleSetActiveZoneCall(zoneId, rb);
146 if (methodName == api::dbus::METHOD_PROXY_CALL) {
147 const gchar* target = NULL;
148 const gchar* targetBusName = NULL;
149 const gchar* targetObjectPath = NULL;
150 const gchar* targetInterface = NULL;
151 const gchar* targetMethod = NULL;
152 GVariant* rawArgs = NULL;
153 g_variant_get(parameters,
161 dbus::GVariantPtr args(rawArgs, g_variant_unref);
163 if (mProxyCallCallback) {
164 mProxyCallCallback(target,
175 if (methodName == api::dbus::METHOD_LOCK_QUEUE) {
176 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
177 mZonesManagerPtr->handleLockQueueCall(rb);
181 if (methodName == api::dbus::METHOD_UNLOCK_QUEUE) {
182 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
183 mZonesManagerPtr->handleUnlockQueueCall(rb);
187 if (methodName == api::dbus::METHOD_GET_ZONE_ID_LIST) {
188 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::ZoneIds>>(result);
189 mZonesManagerPtr->handleGetZoneIdsCall(rb);
193 if (methodName == api::dbus::METHOD_GET_ACTIVE_ZONE_ID) {
194 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::ZoneId>>(result);
195 mZonesManagerPtr->handleGetActiveZoneIdCall(rb);
199 if (methodName == api::dbus::METHOD_GET_ZONE_INFO) {
201 config::loadFromGVariant(parameters, zoneId);
203 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::ZoneInfoOut>>(result);
204 mZonesManagerPtr->handleGetZoneInfoCall(zoneId, rb);
208 if (methodName == api::dbus::METHOD_SET_NETDEV_ATTRS) {
209 api::SetNetDevAttrsIn data;
210 config::loadFromGVariant(parameters, data);
212 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
213 mZonesManagerPtr->handleSetNetdevAttrsCall(data, rb);
217 if (methodName == api::dbus::METHOD_GET_NETDEV_ATTRS) {
218 api::GetNetDevAttrsIn data;
219 config::loadFromGVariant(parameters, data);
221 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::GetNetDevAttrs>>(result);
222 mZonesManagerPtr->handleGetNetdevAttrsCall(data, rb);
226 if (methodName == api::dbus::METHOD_GET_NETDEV_LIST) {
228 config::loadFromGVariant(parameters, data);
230 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::NetDevList>>(result);
231 mZonesManagerPtr->handleGetNetdevListCall(data, rb);
235 if (methodName == api::dbus::METHOD_CREATE_NETDEV_VETH) {
236 api::CreateNetDevVethIn data;
237 config::loadFromGVariant(parameters, data);
239 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
240 mZonesManagerPtr->handleCreateNetdevVethCall(data, rb);
244 if (methodName == api::dbus::METHOD_CREATE_NETDEV_MACVLAN) {
245 api::CreateNetDevMacvlanIn data;
246 config::loadFromGVariant(parameters, data);
248 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
249 mZonesManagerPtr->handleCreateNetdevMacvlanCall(data, rb);
253 if (methodName == api::dbus::METHOD_CREATE_NETDEV_PHYS) {
254 api::CreateNetDevPhysIn data;
255 config::loadFromGVariant(parameters, data);
257 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
258 mZonesManagerPtr->handleCreateNetdevPhysCall(data, rb);
262 if (methodName == api::dbus::METHOD_DESTROY_NETDEV) {
263 api::DestroyNetDevIn data;
264 config::loadFromGVariant(parameters, data);
266 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
267 mZonesManagerPtr->handleDestroyNetdevCall(data, rb);
271 if (methodName == api::dbus::METHOD_DELETE_NETDEV_IP_ADDRESS) {
272 api::DeleteNetdevIpAddressIn data;
273 config::loadFromGVariant(parameters, data);
275 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
276 mZonesManagerPtr->handleDeleteNetdevIpAddressCall(data, rb);
280 if (methodName == api::dbus::METHOD_DECLARE_FILE) {
281 api::DeclareFileIn data;
282 config::loadFromGVariant(parameters, data);
284 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Declaration>>(result);
285 mZonesManagerPtr->handleDeclareFileCall(data, rb);
289 if (methodName == api::dbus::METHOD_DECLARE_MOUNT) {
290 api::DeclareMountIn data;
291 config::loadFromGVariant(parameters, data);
293 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Declaration>>(result);
294 mZonesManagerPtr->handleDeclareMountCall(data, rb);
298 if (methodName == api::dbus::METHOD_DECLARE_LINK) {
299 api::DeclareLinkIn data;
300 config::loadFromGVariant(parameters, data);
302 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Declaration>>(result);
303 mZonesManagerPtr->handleDeclareLinkCall(data, rb);
307 if (methodName == api::dbus::METHOD_GET_DECLARATIONS) {
309 config::loadFromGVariant(parameters, data);
311 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Declarations>>(result);
312 mZonesManagerPtr->handleGetDeclarationsCall(data, rb);
316 if (methodName == api::dbus::METHOD_REMOVE_DECLARATION) {
317 api::RemoveDeclarationIn data;
318 config::loadFromGVariant(parameters, data);
320 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
321 mZonesManagerPtr->handleRemoveDeclarationCall(data, rb);
325 if (methodName == api::dbus::METHOD_CREATE_ZONE) {
326 api::CreateZoneIn data;
327 config::loadFromGVariant(parameters, data);
329 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
330 mZonesManagerPtr->handleCreateZoneCall(data, rb);
334 if (methodName == api::dbus::METHOD_DESTROY_ZONE) {
336 config::loadFromGVariant(parameters, data);
338 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
339 mZonesManagerPtr->handleDestroyZoneCall(data, rb);
343 if (methodName == api::dbus::METHOD_SHUTDOWN_ZONE) {
345 config::loadFromGVariant(parameters, data);
347 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
348 mZonesManagerPtr->handleShutdownZoneCall(data, rb);
352 if (methodName == api::dbus::METHOD_START_ZONE) {
354 config::loadFromGVariant(parameters, data);
356 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
357 mZonesManagerPtr->handleStartZoneCall(data, rb);
360 if (methodName == api::dbus::METHOD_LOCK_ZONE) {
362 config::loadFromGVariant(parameters, data);
364 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
365 mZonesManagerPtr->handleLockZoneCall(data, rb);
369 if (methodName == api::dbus::METHOD_UNLOCK_ZONE) {
371 config::loadFromGVariant(parameters, data);
373 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
374 mZonesManagerPtr->handleUnlockZoneCall(data, rb);
378 if (methodName == api::dbus::METHOD_GRANT_DEVICE) {
379 api::GrantDeviceIn data;
380 config::loadFromGVariant(parameters, data);
382 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
383 mZonesManagerPtr->handleGrantDeviceCall(data, rb);
387 if (methodName == api::dbus::METHOD_REVOKE_DEVICE) {
388 api::RevokeDeviceIn data;
389 config::loadFromGVariant(parameters, data);
391 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
392 mZonesManagerPtr->handleRevokeDeviceCall(data, rb);
396 if (methodName == api::dbus::METHOD_CREATE_FILE) {
397 api::CreateFileIn data;
398 config::loadFromGVariant(parameters, data);
400 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::CreateFileOut>>(result);
401 mZonesManagerPtr->handleCreateFileCall(data, rb);
405 if (methodName == api::dbus::METHOD_SWITCH_TO_DEFAULT) {
406 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
407 mZonesManagerPtr->handleSwitchToDefaultCall(EMPTY_CALLER, rb);
411 if (methodName == api::dbus::METHOD_CLEAN_UP_ZONES_ROOT) {
412 auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
413 mZonesManagerPtr->handleCleanUpZonesRootCall(rb);
418 void HostDbusConnection::onClientVanished(const std::string& name)
420 const std::string id = api::DBUS_CONNECTION_PREFIX + name;
421 mZonesManagerPtr->disconnectedCallback(id);
424 void HostDbusConnection::onSignalCall(const std::string& /* senderBusName */,
425 const std::string& objectPath,
426 const std::string& interface,
427 const std::string& /* signalName */,
428 GVariant* /* parameters */) const
430 (void)this; // satisfy cpp-check
431 if (objectPath != api::dbus::OBJECT_PATH || interface != api::dbus::INTERFACE) {
436 void HostDbusConnection::proxyCallAsync(const std::string& busName,
437 const std::string& objectPath,
438 const std::string& interface,
439 const std::string& method,
440 GVariant* parameters,
441 const dbus::DbusConnection::AsyncMethodCallCallback& callback)
443 mDbusConnection->callMethodAsync(busName,
453 #endif //DBUS_CONNECTION