2 * Copyright (c) 2013-2015 TRUSTONIC LIMITED
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
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.
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.
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.
34 #include <sys/types.h>
37 #include <sys/ioctl.h>
42 #define LOG_TAG "TeeCommonClient"
44 #include "mcVersionHelper.h"
45 #include "driver_client.h"
47 #include "proxy_client.h"
49 #include "common_client.h"
52 // Set default log destination (needs to be somewhere)
53 FILE* mc_log_file_
= stdout
;
56 struct CommonClient::Impl
{
57 pthread_mutex_t mutex
;
65 Impl(): open_count(0), client(NULL
), open_mode(AUTO
) {
66 pthread_mutex_init(&mutex
, NULL
);
70 CommonClient::CommonClient(): pimpl_(new Impl
) {
73 CommonClient::~CommonClient() {
77 int CommonClient::open() {
79 pthread_mutex_lock(&pimpl_
->mutex
);
80 if (pimpl_
->client
&& !pimpl_
->client
->isOpen()) {
81 pimpl_
->open_count
= 0;
83 if (pimpl_
->open_count
== 0) {
84 if ((pimpl_
->open_mode
!= PROXY
) && (pimpl_
->driver
.open() >= 0)) {
85 pimpl_
->client
= &pimpl_
->driver
;
87 } else if ((pimpl_
->open_mode
!= DRIVER
) &&
88 (pimpl_
->proxy
.open() >= 0)) {
89 pimpl_
->client
= &pimpl_
->proxy
;
92 LOG_E("Failed to open lower layers: %s", strerror(errno
));
99 pthread_mutex_unlock(&pimpl_
->mutex
);
100 LOG_D("%s ret=%d open_count=%d", __FUNCTION__
, ret
, pimpl_
->open_count
);
104 int CommonClient::closeCheck() {
106 pthread_mutex_lock(&pimpl_
->mutex
);
107 if (pimpl_
->open_count
> 1) {
108 pimpl_
->open_count
--;
114 pthread_mutex_unlock(&pimpl_
->mutex
);
115 LOG_D("%s ret=%d open_count=%d", __FUNCTION__
, ret
, pimpl_
->open_count
);
119 int CommonClient::close() {
121 pthread_mutex_lock(&pimpl_
->mutex
);
123 if (!pimpl_
->client
) {
127 if (pimpl_
->open_count
== 1) {
128 ret
= pimpl_
->client
->close();
129 pimpl_
->client
= NULL
;
133 pimpl_
->open_count
--;
135 pthread_mutex_unlock(&pimpl_
->mutex
);
136 LOG_D("%s ret=%d open_count=%d", __FUNCTION__
, ret
, pimpl_
->open_count
);
140 bool CommonClient::isOpen() const {
141 return pimpl_
->open_count
> 0;
144 int CommonClient::hasOpenSessions() const {
145 if (!pimpl_
->client
) {
149 return pimpl_
->client
->hasOpenSessions();
152 int CommonClient::openSession(struct mc_ioctl_open_session
& session
) {
153 if (!pimpl_
->client
) {
157 return pimpl_
->client
->openSession(session
);
160 int CommonClient::openTrustlet(struct mc_ioctl_open_trustlet
& trustlet
) {
161 if (!pimpl_
->client
) {
165 return pimpl_
->client
->openTrustlet(trustlet
);
168 int CommonClient::closeSession(uint32_t session_id
) {
169 if (!pimpl_
->client
) {
173 return pimpl_
->client
->closeSession(session_id
);
176 int CommonClient::notify(uint32_t session_id
) {
177 if (!pimpl_
->client
) {
181 return pimpl_
->client
->notify(session_id
);
184 int CommonClient::waitNotification(const struct mc_ioctl_wait
& wait
) {
185 if (!pimpl_
->client
) {
189 return pimpl_
->client
->waitNotification(wait
);
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
)) {
198 if (!pimpl_
->client
) {
202 return pimpl_
->client
->malloc(buffer
, length
);
205 int CommonClient::free(uint8_t* buffer
, uint32_t length
) {
206 if (!pimpl_
->client
) {
210 return pimpl_
->client
->free(buffer
, length
);
213 int CommonClient::map(struct mc_ioctl_map
& map
) {
214 if (!pimpl_
->client
) {
218 return pimpl_
->client
->map(map
);
221 int CommonClient::unmap(const struct mc_ioctl_map
& map
) {
222 if (!pimpl_
->client
) {
226 return pimpl_
->client
->unmap(map
);
229 int CommonClient::getError(struct mc_ioctl_geterr
& err
) {
230 if (!pimpl_
->client
) {
234 return pimpl_
->client
->getError(err
);
237 int CommonClient::getVersion(struct mc_version_info
& version_info
) {
238 if (!pimpl_
->client
) {
242 return pimpl_
->client
->getVersion(version_info
);
245 int CommonClient::gpRequestCancellation(uint32_t session_id
) {
246 if (!pimpl_
->client
) {
250 return pimpl_
->client
->gpRequestCancellation(session_id
);
253 void CommonClient::setOpenMode(OpenMode open_mode
) {
257 pimpl_
->open_mode
= open_mode
;