2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 /* standard library header */
22 /* SLP library header */
27 #include "ClientIPC.h"
28 #include "ClientChannel.h"
29 #include "ReaderHelper.h"
32 #define EXTERN_API __attribute__((visibility("default")))
35 namespace smartcard_service_api
37 ClientChannel::ClientChannel(void *context, Session *session, int channelNum, ByteArray selectResponse, void *handle):Channel(session)
39 this->channelNum = -1;
45 SCARD_DEBUG_ERR("ClientIPC::getInstance() failed");
50 this->channelNum = channelNum;
51 this->handle = handle;
52 this->selectResponse = selectResponse;
53 this->context = context;
56 ClientChannel::~ClientChannel()
61 void ClientChannel::closeSync()
63 #ifdef CLIENT_IPC_THREAD
64 if (isClosed() == false)
66 if (getSession()->getReader()->isSecureElementPresent() == true)
71 /* send message to server */
72 msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
73 msg.param1 = (int)handle;
74 msg.error = (unsigned int)context; /* using error to context */
75 msg.caller = (void *)this;
76 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
79 if (ClientIPC::getInstance().sendMessage(&msg) == true)
81 rv = waitTimedCondition(0);
84 SCARD_DEBUG_ERR("closeSync failed [%d]", rv);
89 SCARD_DEBUG_ERR("sendMessage failed");
97 SCARD_DEBUG_ERR("unavailable channel");
103 int ClientChannel::close(closeCallback callback, void *userParam)
107 if (isClosed() == false)
109 if (getSession()->getReader()->isSecureElementPresent() == true)
115 /* send message to server */
116 msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
117 msg.param1 = (int)handle;
118 msg.error = (unsigned int)context; /* using error to context */
119 msg.caller = (void *)this;
120 msg.callback = (void *)callback;
121 msg.userParam = userParam;
123 if (ClientIPC::getInstance().sendMessage(&msg) == true)
134 SCARD_DEBUG_ERR("unavailable channel");
142 int ClientChannel::transmitSync(ByteArray command, ByteArray &result)
146 if (getSession()->getReader()->isSecureElementPresent() == true)
150 #ifdef CLIENT_IPC_THREAD
151 /* send message to server */
152 msg.message = Message::MSG_REQUEST_TRANSMIT;
153 msg.param1 = (int)handle;
156 msg.error = (unsigned int)context; /* using error to context */
157 msg.caller = (void *)this;
158 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
161 if (ClientIPC::getInstance().sendMessage(&msg) == true)
163 rv = waitTimedCondition(0);
172 SCARD_DEBUG_ERR("clientIPC is null");
179 SCARD_DEBUG_ERR("sendMessage failed");
186 SCARD_DEBUG_ERR("unavailable channel");
192 int ClientChannel::transmit(ByteArray command, transmitCallback callback, void *userParam)
196 if (getSession()->getReader()->isSecureElementPresent() == true)
200 /* send message to server */
201 msg.message = Message::MSG_REQUEST_TRANSMIT;
202 msg.param1 = (int)handle;
205 msg.error = (unsigned int)context; /* using error to context */
206 msg.caller = (void *)this;
207 msg.callback = (void *)callback;
208 msg.userParam = userParam;
210 if (ClientIPC::getInstance().sendMessage(&msg) == true)
221 SCARD_DEBUG_ERR("unavailable channel");
227 bool ClientChannel::dispatcherCallback(void *message)
229 Message *msg = (Message *)message;
230 ClientChannel *channel = NULL;
235 SCARD_DEBUG_ERR("message is null");
239 channel = (ClientChannel *)msg->caller;
241 switch (msg->message)
243 case Message::MSG_REQUEST_TRANSMIT :
245 /* transmit result */
246 SCARD_DEBUG("MSG_REQUEST_TRANSMIT");
248 if (msg->isSynchronousCall() == true) /* synchronized call */
254 channel->error = msg->error;
255 channel->response = msg->data;
257 channel->signalCondition();
258 channel->syncUnlock();
260 else if (msg->callback != NULL)
262 transmitCallback cb = (transmitCallback)msg->callback;
265 cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
270 case Message::MSG_REQUEST_CLOSE_CHANNEL :
272 SCARD_DEBUG("MSG_REQUEST_CLOSE_CHANNEL");
274 if (msg->isSynchronousCall() == true) /* synchronized call */
279 channel->error = msg->error;
281 channel->signalCondition();
282 channel->syncUnlock();
284 else if (msg->callback != NULL)
286 closeCallback cb = (closeCallback)msg->callback;
289 cb(msg->error, msg->userParam);
295 SCARD_DEBUG("unknwon message : %s", msg->toString());
301 } /* namespace smartcard_service_api */
304 #define CHANNEL_EXTERN_BEGIN \
305 if (handle != NULL) \
307 ClientChannel *channel = (ClientChannel *)handle;
309 #define CHANNEL_EXTERN_END \
313 SCARD_DEBUG_ERR("Invalid param"); \
316 using namespace smartcard_service_api;
318 EXTERN_API int channel_close(channel_h handle, channel_close_cb callback, void *userParam)
322 CHANNEL_EXTERN_BEGIN;
323 result = channel->close((closeCallback)callback, userParam);
329 EXTERN_API int channel_transmit(channel_h handle, unsigned char *command, unsigned int length, channel_transmit_cb callback, void *userParam)
333 CHANNEL_EXTERN_BEGIN;
336 temp.setBuffer(command, length);
337 result = channel->transmit(temp, (transmitCallback)callback, userParam);
343 EXTERN_API void channel_close_sync(channel_h handle)
345 #ifdef CLIENT_IPC_THREAD
346 CHANNEL_EXTERN_BEGIN;
347 channel->closeSync();
352 EXTERN_API int channel_transmit_sync(channel_h handle, unsigned char *command, unsigned int cmd_len, unsigned char **response, unsigned int *resp_len)
356 #ifdef CLIENT_IPC_THREAD
357 if (command == NULL || cmd_len == 0 || response == NULL || resp_len == NULL)
360 CHANNEL_EXTERN_BEGIN;
361 ByteArray temp, resp;
363 temp.setBuffer(command, cmd_len);
364 result = channel->transmitSync(temp, resp);
365 if (resp.getLength() > 0)
367 *resp_len = resp.getLength();
368 *response = (unsigned char *)calloc(1, *resp_len);
369 memcpy(*response, resp.getBuffer(), *resp_len);
377 EXTERN_API bool channel_is_basic_channel(channel_h handle)
381 CHANNEL_EXTERN_BEGIN;
382 result = channel->isBasicChannel();
388 EXTERN_API bool channel_is_closed(channel_h handle)
392 CHANNEL_EXTERN_BEGIN;
393 result = channel->isClosed();
399 EXTERN_API unsigned int channel_get_select_response_length(channel_h handle)
401 unsigned int result = 0;
403 CHANNEL_EXTERN_BEGIN;
404 result = channel->getSelectResponse().getLength();
410 EXTERN_API bool channel_get_select_response(channel_h handle, unsigned char *buffer, unsigned int length)
414 if (buffer == NULL || length == 0)
419 CHANNEL_EXTERN_BEGIN;
422 response = channel->getSelectResponse();
423 if (response.getLength() > 0)
425 memcpy(buffer, response.getBuffer(), MIN(length, response.getLength()));
433 EXTERN_API session_h channel_get_session(channel_h handle)
435 session_h session = NULL;
437 CHANNEL_EXTERN_BEGIN;
438 session = channel->getSession();
444 EXTERN_API void channel_destroy_instance(channel_h handle)
446 CHANNEL_EXTERN_BEGIN;