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.
18 /* standard library header */
23 /* SLP library header */
27 #include "ClientIPC.h"
28 #include "ClientDispatcher.h"
29 #include "SEService.h"
34 #define EXTERN_API __attribute__((visibility("default")))
37 namespace smartcard_service_api
39 SEService::SEService():SEServiceHelper()
44 this->listener = NULL;
50 SEService::SEService(void *user_data, serviceConnected handler):SEServiceHelper()
55 this->listener = NULL;
60 initialize(user_data, handler);
63 SEService::SEService(void *user_data, SEServiceListener *listener):SEServiceHelper()
68 this->listener = NULL;
73 initialize(user_data, listener);
76 SEService::~SEService()
82 for (i = 0; i < readers.size(); i++)
84 delete (Reader *)readers[i];
89 void SEService::shutdown()
91 if (connected == true)
95 for (i = 0; i < readers.size(); i++)
97 readers[i]->closeSessions();
102 msg.message = Message::MSG_REQUEST_SHUTDOWN;
103 msg.error = (unsigned int)this; /* using error to context */
104 msg.caller = (void *)this;
105 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
107 if (ClientIPC::getInstance().sendMessage(&msg) == false)
109 SCARD_DEBUG_ERR("time over");
114 void SEService::shutdownSync()
116 #ifdef CLIENT_IPC_THREAD
117 if (connected == true)
121 for (i = 0; i < readers.size(); i++)
123 readers[i]->closeSessions();
126 /* send message to load se */
130 msg.message = Message::MSG_REQUEST_SHUTDOWN;
131 msg.error = (unsigned int)this; /* using error to context */
132 msg.caller = (void *)this;
133 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
136 if (ClientIPC::getInstance().sendMessage(&msg) == true)
138 rv = waitTimedCondition(0);
142 ClientDispatcher::getInstance().removeSEService(context);
148 SCARD_DEBUG_ERR("time over");
153 SCARD_DEBUG_ERR("sendMessage failed");
160 bool SEService::_initialize()
163 ClientIPC *clientIPC = NULL;
164 ClientDispatcher *clientDispatcher = NULL;
168 /* initialize client */
169 if (!g_thread_supported())
174 clientDispatcher = &ClientDispatcher::getInstance();
175 clientIPC = &ClientIPC::getInstance();
177 clientIPC->setDispatcher(clientDispatcher);
179 #ifndef CLIENT_IPC_THREAD
180 if (clientDispatcher->runDispatcherThread() == false)
182 SCARD_DEBUG_ERR("clientDispatcher->runDispatcherThread() failed");
188 if (clientIPC->createConnectSocket() == false)
190 SCARD_DEBUG_ERR("clientIPC->createConnectSocket() failed");
195 clientDispatcher->addSEService(context, this);
198 /* send message to load se */
201 msg.message = Message::MSG_REQUEST_READERS;
202 msg.error = pid; /* using error to pid */
203 msg.caller = (void *)this;
204 msg.userParam = context;
206 result = clientIPC->sendMessage(&msg);
214 bool SEService::initialize(void *context, serviceConnected handler)
218 SCARD_DEBUG_ERR("invalid param");
222 this->context = context;
223 this->handler = handler;
225 return _initialize();
228 bool SEService::initialize(void *context, SEServiceListener *listener)
232 SCARD_DEBUG_ERR("invalid param");
236 this->context = context;
237 this->listener = listener;
239 return _initialize();
242 bool SEService::parseReaderInformation(unsigned int count, ByteArray data)
245 unsigned int offset = 0;
246 unsigned int len = 0;
248 Reader *reader = NULL;
251 for (i = 0; i < count && offset < data.getLength(); i++)
253 memset(name, 0, sizeof(name));
255 memcpy(&len, data.getBuffer(offset), sizeof(len));
256 offset += sizeof(len);
258 memcpy(name, data.getBuffer(offset), len);
261 memcpy(&handle, data.getBuffer(offset), sizeof(handle));
262 offset += sizeof(handle);
264 SCARD_DEBUG("Reader [%d] : name [%s], handle [%p]", i, name, handle);
267 reader = new Reader(context, name, handle);
270 SCARD_DEBUG_ERR("alloc failed");
274 readers.push_back(reader);
280 bool SEService::dispatcherCallback(void *message)
282 Message *msg = (Message *)message;
283 SEService *service = NULL;
290 SCARD_DEBUG_ERR("message is null");
294 service = (SEService *)msg->caller;
296 switch (msg->message)
298 case Message::MSG_REQUEST_READERS :
299 SCARD_DEBUG("[MSG_REQUEST_READERS]");
301 service->connected = true;
303 /* parse message data */
304 service->parseReaderInformation(msg->param1, msg->data);
306 /* call callback function */
307 if (service->listener != NULL)
309 service->listener->serviceConnected(service, service->context);
311 else if (service->handler != NULL)
313 service->handler(service, service->context);
317 case Message::MSG_REQUEST_SHUTDOWN :
318 SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
320 if (msg->isSynchronousCall() == true) /* synchronized call */
326 // service->error = msg->error;
328 service->signalCondition();
329 service->syncUnlock();
333 // openSessionCallback cb = (openSessionCallback)msg->callback;
336 // cb(session, msg->error, msg->userParam);
340 case Message::MSG_NOTIFY_SE_INSERTED :
342 Reader *reader = NULL;
344 SCARD_DEBUG("[MSG_NOTIFY_SE_INSERTED]");
347 reader = new Reader(service->context, (char *)msg->data.getBuffer(), (void *)msg->param1);
350 service->readers.push_back(reader);
354 SCARD_DEBUG_ERR("alloc failed");
357 if (service->listener != NULL)
359 service->listener->eventHandler(service, (char *)msg->data.getBuffer(), 1, service->context);
363 SCARD_DEBUG("listener is null");
368 case Message::MSG_NOTIFY_SE_REMOVED :
372 SCARD_DEBUG("[MSG_NOTIFY_SE_REMOVED]");
374 for (i = 0; i < service->readers.size(); i++)
376 if (((Reader *)service->readers[i])->handle == (void *)msg->param1)
378 ((Reader *)service->readers[i])->present = false;
383 if (service->listener != NULL)
385 service->listener->eventHandler(service, (char *)msg->data.getBuffer(), 2, service->context);
389 SCARD_DEBUG("listener is null");
394 case Message::MSG_OPERATION_RELEASE_CLIENT :
395 SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
397 if (service->listener != NULL)
399 service->listener->errorHandler(service, msg->error, service->context);
401 ClientDispatcher::getInstance().removeSEService(service->context);
402 service->connected = false;
406 SCARD_DEBUG_ERR("service->listener is null");
411 SCARD_DEBUG("unknown message [%s]", msg->toString());
420 } /* namespace smartcard_service_api */
423 #define SE_SERVICE_EXTERN_BEGIN \
424 if (handle != NULL) \
426 SEService *service = (SEService *)handle;
428 #define SE_SERVICE_EXTERN_END \
432 SCARD_DEBUG_ERR("Invalid param"); \
435 using namespace smartcard_service_api;
437 EXTERN_API se_service_h se_service_create_instance(void *user_data, se_service_connected_cb callback)
439 SEService *service = new SEService(user_data, (serviceConnected)callback);
441 return (se_service_h)service;
444 EXTERN_API se_service_h se_service_create_instance_with_event_callback(void *user_data, se_service_connected_cb connected, se_service_event_cb event, se_sesrvice_error_cb error)
446 SEService *service = new SEService(user_data, (serviceConnected)connected);
448 return (se_service_h)service;
451 EXTERN_API int se_service_get_readers_count(se_service_h handle)
455 SE_SERVICE_EXTERN_BEGIN;
456 vector<ReaderHelper *> temp_readers;
458 temp_readers = service->getReaders();
459 count = temp_readers.size();
460 SE_SERVICE_EXTERN_END;
465 EXTERN_API bool se_service_get_readers(se_service_h handle, reader_h *readers, int *count)
469 SE_SERVICE_EXTERN_BEGIN;
470 vector<ReaderHelper *> temp_readers;
474 temp_readers = service->getReaders();
476 for (i = 0; i < temp_readers.size() && i < (size_t)*count; i++)
478 if (temp_readers[i]->isSecureElementPresent())
480 readers[i] = (reader_h)temp_readers[i];
485 SE_SERVICE_EXTERN_END;
490 EXTERN_API bool se_service_is_connected(se_service_h handle)
494 SE_SERVICE_EXTERN_BEGIN;
495 result = service->isConnected();
496 SE_SERVICE_EXTERN_END;
501 EXTERN_API void se_service_shutdown(se_service_h handle)
503 SE_SERVICE_EXTERN_BEGIN;
505 SE_SERVICE_EXTERN_END;
508 EXTERN_API void se_service_destroy_instance(se_service_h handle)
510 SE_SERVICE_EXTERN_BEGIN;
512 SE_SERVICE_EXTERN_END;