import exynos 7570 bsp
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos7580.git] / mobicore / ClientLib / src / common_client.cpp
1 /*
2 * Copyright (c) 2013-2015 TRUSTONIC LIMITED
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <pthread.h>
33 #include <unistd.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <sys/ioctl.h>
38 #include <errno.h>
39 #include <string.h>
40
41 #undef LOG_TAG
42 #define LOG_TAG "TeeCommonClient"
43 #include "log.h"
44 #include "mcVersionHelper.h"
45 #include "driver_client.h"
46 #ifndef WITHOUT_PROXY
47 #include "proxy_client.h"
48 #endif
49 #include "common_client.h"
50
51 #ifdef LOG_FPRINTF
52 // Set default log destination (needs to be somewhere)
53 FILE* mc_log_file_ = stdout;
54 #endif
55
56 struct CommonClient::Impl {
57 pthread_mutex_t mutex;
58 int open_count;
59 DriverClient driver;
60 #ifndef WITHOUT_PROXY
61 ProxyClient proxy;
62 #endif
63 IClient* client;
64 OpenMode open_mode;
65 Impl(): open_count(0), client(NULL), open_mode(AUTO) {
66 pthread_mutex_init(&mutex, NULL);
67 }
68 };
69
70 CommonClient::CommonClient(): pimpl_(new Impl) {
71 }
72
73 CommonClient::~CommonClient() {
74 delete pimpl_;
75 }
76
77 int CommonClient::open() {
78 int ret = 0;
79 pthread_mutex_lock(&pimpl_->mutex);
80 if (pimpl_->client && !pimpl_->client->isOpen()) {
81 pimpl_->open_count = 0;
82 }
83 if (pimpl_->open_count == 0) {
84 if ((pimpl_->open_mode != PROXY) && (pimpl_->driver.open() >= 0)) {
85 pimpl_->client = &pimpl_->driver;
86 #ifndef WITHOUT_PROXY
87 } else if ((pimpl_->open_mode != DRIVER) &&
88 (pimpl_->proxy.open() >= 0)) {
89 pimpl_->client = &pimpl_->proxy;
90 #endif
91 } else {
92 LOG_E("Failed to open lower layers: %s", strerror(errno));
93 ret = -1;
94 }
95 }
96 if (pimpl_->client) {
97 pimpl_->open_count++;
98 }
99 pthread_mutex_unlock(&pimpl_->mutex);
100 LOG_D("%s ret=%d open_count=%d", __FUNCTION__, ret, pimpl_->open_count);
101 return ret;
102 }
103
104 int CommonClient::closeCheck() {
105 int ret;
106 pthread_mutex_lock(&pimpl_->mutex);
107 if (pimpl_->open_count > 1) {
108 pimpl_->open_count--;
109 ret = 0;
110 } else {
111 errno = EPERM;
112 ret = -1;
113 }
114 pthread_mutex_unlock(&pimpl_->mutex);
115 LOG_D("%s ret=%d open_count=%d", __FUNCTION__, ret, pimpl_->open_count);
116 return ret;
117 }
118
119 int CommonClient::close() {
120 int ret = -1;
121 pthread_mutex_lock(&pimpl_->mutex);
122 /* Not open */
123 if (!pimpl_->client) {
124 errno = EBADF;
125 } else {
126 /* Last token */
127 if (pimpl_->open_count == 1) {
128 ret = pimpl_->client->close();
129 pimpl_->client = NULL;
130 } else {
131 ret = 0;
132 }
133 pimpl_->open_count--;
134 }
135 pthread_mutex_unlock(&pimpl_->mutex);
136 LOG_D("%s ret=%d open_count=%d", __FUNCTION__, ret, pimpl_->open_count);
137 return ret;
138 }
139
140 bool CommonClient::isOpen() const {
141 return pimpl_->open_count > 0;
142 }
143
144 int CommonClient::hasOpenSessions() const {
145 if (!pimpl_->client) {
146 errno = EBADF;
147 return -1;
148 }
149 return pimpl_->client->hasOpenSessions();
150 }
151
152 int CommonClient::openSession(struct mc_ioctl_open_session& session) {
153 if (!pimpl_->client) {
154 errno = EBADF;
155 return -1;
156 }
157 return pimpl_->client->openSession(session);
158 }
159
160 int CommonClient::openTrustlet(struct mc_ioctl_open_trustlet& trustlet) {
161 if (!pimpl_->client) {
162 errno = EBADF;
163 return -1;
164 }
165 return pimpl_->client->openTrustlet(trustlet);
166 }
167
168 int CommonClient::closeSession(uint32_t session_id) {
169 if (!pimpl_->client) {
170 errno = EBADF;
171 return -1;
172 }
173 return pimpl_->client->closeSession(session_id);
174 }
175
176 int CommonClient::notify(uint32_t session_id) {
177 if (!pimpl_->client) {
178 errno = EBADF;
179 return -1;
180 }
181 return pimpl_->client->notify(session_id);
182 }
183
184 int CommonClient::waitNotification(const struct mc_ioctl_wait& wait) {
185 if (!pimpl_->client) {
186 errno = EBADF;
187 return -1;
188 }
189 return pimpl_->client->waitNotification(wait);
190 }
191
192 int CommonClient::malloc(uint8_t** buffer, uint32_t length) {
193 // Check length here to make sure we are consistent, with or without proxy
194 if ((length == 0) || (length > BUFFER_LENGTH_MAX)) {
195 errno = EINVAL;
196 return -1;
197 }
198 if (!pimpl_->client) {
199 errno = EBADF;
200 return -1;
201 }
202 return pimpl_->client->malloc(buffer, length);
203 }
204
205 int CommonClient::free(uint8_t* buffer, uint32_t length) {
206 if (!pimpl_->client) {
207 errno = EBADF;
208 return -1;
209 }
210 return pimpl_->client->free(buffer, length);
211 }
212
213 int CommonClient::map(struct mc_ioctl_map& map) {
214 if (!pimpl_->client) {
215 errno = EBADF;
216 return -1;
217 }
218 return pimpl_->client->map(map);
219 }
220
221 int CommonClient::unmap(const struct mc_ioctl_map& map) {
222 if (!pimpl_->client) {
223 errno = EBADF;
224 return -1;
225 }
226 return pimpl_->client->unmap(map);
227 }
228
229 int CommonClient::getError(struct mc_ioctl_geterr& err) {
230 if (!pimpl_->client) {
231 errno = EBADF;
232 return -1;
233 }
234 return pimpl_->client->getError(err);
235 }
236
237 int CommonClient::getVersion(struct mc_version_info& version_info) {
238 if (!pimpl_->client) {
239 errno = EBADF;
240 return -1;
241 }
242 return pimpl_->client->getVersion(version_info);
243 }
244
245 int CommonClient::gpRequestCancellation(uint32_t session_id) {
246 if (!pimpl_->client) {
247 errno = EBADF;
248 return -1;
249 }
250 return pimpl_->client->gpRequestCancellation(session_id);
251 }
252
253 void CommonClient::setOpenMode(OpenMode open_mode) {
254 #ifdef WITHOUT_PROXY
255 (void) open_mode;
256 #else
257 pimpl_->open_mode = open_mode;
258 #endif
259 }