2821202b0923c23d7f8b29e9f2a99ccd15cb7b2b
[platform/core/security/vasum.git] / server / host-connection.cpp
1 /*
2  *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Piotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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
17  */
18
19 /**
20  * @file
21  * @author  Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
22  * @brief   Implementation of a class for communication with server
23  */
24
25 #include "config.hpp"
26
27 #include "host-connection.hpp"
28 #include "host-dbus-definitions.hpp"
29 #include "exception.hpp"
30
31 #include "log/logger.hpp"
32
33
34 namespace security_containers {
35
36 namespace {
37
38 // Timeout in ms for waiting for dbus name.
39 // Can happen if glib loop is busy or not present.
40 // TODO: this should be in host's configuration file
41 const unsigned int NAME_ACQUIRED_TIMEOUT = 5 * 1000;
42
43 } // namespace
44
45
46 HostConnection::HostConnection()
47     : mNameAcquired(false)
48     , mNameLost(false)
49 {
50     LOGT("Connecting to host system DBUS");
51     mDbusConnection = dbus::DbusConnection::createSystem();
52
53     LOGT("Setting DBUS name");
54     mDbusConnection->setName(hostapi::BUS_NAME,
55                              std::bind(&HostConnection::onNameAcquired, this),
56                              std::bind(&HostConnection::onNameLost, this));
57
58     if (!waitForName(NAME_ACQUIRED_TIMEOUT)) {
59         LOGE("Could not acquire dbus name: " << hostapi::BUS_NAME);
60         throw HostConnectionException("Could not acquire dbus name: " + hostapi::BUS_NAME);
61     }
62
63     LOGT("Registering DBUS interface");
64     using namespace std::placeholders;
65     mDbusConnection->registerObject(hostapi::OBJECT_PATH,
66                                     hostapi::DEFINITION,
67                                     std::bind(&HostConnection::onMessageCall,
68                                               this,
69                                               _1,
70                                               _2,
71                                               _3,
72                                               _4,
73                                               _5));
74
75     LOGD("Connected");
76 }
77
78 HostConnection::~HostConnection()
79 {
80 }
81
82 bool HostConnection::waitForName(const unsigned int timeoutMs)
83 {
84     std::unique_lock<std::mutex> lock(mNameMutex);
85     mNameCondition.wait_for(lock,
86                             std::chrono::milliseconds(timeoutMs),
87                             [this] {
88                                 return mNameAcquired || mNameLost;
89                             });
90
91     return mNameAcquired;
92 }
93
94 void HostConnection::onNameAcquired()
95 {
96     std::unique_lock<std::mutex> lock(mNameMutex);
97     mNameAcquired = true;
98     mNameCondition.notify_one();
99 }
100
101 void HostConnection::onNameLost()
102 {
103     std::unique_lock<std::mutex> lock(mNameMutex);
104     mNameLost = true;
105     mNameCondition.notify_one();
106
107     if (mNameAcquired) {
108         // TODO implement reconnecting
109         LOGE("TODO Reconnect !!!");
110     }
111 }
112
113 void HostConnection::setProxyCallCallback(const ProxyCallCallback& callback)
114 {
115     mProxyCallCallback = callback;
116 }
117
118 void HostConnection::onMessageCall(const std::string& objectPath,
119                                         const std::string& interface,
120                                         const std::string& methodName,
121                                         GVariant* parameters,
122                                         dbus::MethodResultBuilder::Pointer result)
123 {
124     if (objectPath != hostapi::OBJECT_PATH || interface != hostapi::INTERFACE) {
125         return;
126     }
127
128     if (methodName == hostapi::METHOD_PROXY_CALL) {
129         const gchar* target = NULL;
130         const gchar* targetBusName = NULL;
131         const gchar* targetObjectPath = NULL;
132         const gchar* targetInterface = NULL;
133         const gchar* targetMethod = NULL;
134         GVariant* rawArgs = NULL;
135         g_variant_get(parameters,
136                       "(&s&s&s&s&sv)",
137                       &target,
138                       &targetBusName,
139                       &targetObjectPath,
140                       &targetInterface,
141                       &targetMethod,
142                       &rawArgs);
143         dbus::GVariantPtr args(rawArgs, g_variant_unref);
144
145         if (mProxyCallCallback) {
146             mProxyCallCallback(target,
147                                targetBusName,
148                                targetObjectPath,
149                                targetInterface,
150                                targetMethod,
151                                args.get(),
152                                result);
153         }
154     }
155 }
156
157 void HostConnection::proxyCallAsync(const std::string& busName,
158                                     const std::string& objectPath,
159                                     const std::string& interface,
160                                     const std::string& method,
161                                     GVariant* parameters,
162                                     const dbus::DbusConnection::AsyncMethodCallCallback& callback)
163 {
164     mDbusConnection->callMethodAsync(busName,
165                                      objectPath,
166                                      interface,
167                                      method,
168                                      parameters,
169                                      std::string(),
170                                      callback);
171 }
172
173
174 } // namespace security_containers