2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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 */
26 #include "ClientIPC.h"
27 #include "ClientDispatcher.h"
28 #include "SEService.h"
33 #define EXTERN_API __attribute__((visibility("default")))
36 namespace smartcard_service_api
38 SEService::SEService() :
43 this->listener = NULL;
47 SEService::SEService(void *user_data, serviceConnected handler)
48 throw(ErrorIO &, ErrorIllegalParameter &) :
51 this->listener = NULL;
54 initialize(user_data, handler);
57 SEService::SEService(void *user_data, SEServiceListener *listener)
58 throw(ErrorIO &, ErrorIllegalParameter &) :
64 initialize(user_data, listener);
67 SEService::~SEService()
75 catch(ExceptionBase &e)
77 SCARD_DEBUG_ERR("EXCEPTION : %s", e.what());
81 SCARD_DEBUG_ERR("EXCEPTION!!!");
84 for (i = 0; i < readers.size(); i++)
86 delete (Reader *)readers[i];
91 SEService *SEService::createInstance(void *user_data, SEServiceListener *listener)
92 throw(ErrorIO &, ErrorIllegalParameter &)
94 return new SEService(user_data, listener);
97 SEService *SEService::createInstance(void *user_data, serviceConnected handler)
98 throw(ErrorIO &, ErrorIllegalParameter &)
100 return new SEService(user_data, handler);
103 void SEService::shutdown()
105 if (connected == true)
109 for (i = 0; i < readers.size(); i++)
111 readers[i]->closeSessions();
116 msg.message = Message::MSG_REQUEST_SHUTDOWN;
117 msg.error = (unsigned long)this; /* using error to context */
118 msg.caller = (void *)this;
119 msg.callback = (void *)NULL;
121 if (ClientIPC::getInstance().sendMessage(&msg) == false)
123 SCARD_DEBUG_ERR("time over");
128 void SEService::shutdownSync()
130 #ifdef CLIENT_IPC_THREAD
131 if (connected == true)
135 for (i = 0; i < readers.size(); i++)
137 readers[i]->closeSessions();
140 /* send message to load se */
143 msg.message = Message::MSG_REQUEST_SHUTDOWN;
144 msg.error = (unsigned long)this; /* using error to context */
145 msg.caller = (void *)this;
146 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
149 if (ClientIPC::getInstance().sendMessage(&msg) == true)
153 rv = waitTimedCondition(0);
157 ClientDispatcher::getInstance().removeSEService(context);
163 SCARD_DEBUG_ERR("time over");
168 SCARD_DEBUG_ERR("sendMessage failed");
175 bool SEService::_initialize() throw(ErrorIO &)
178 ClientIPC *clientIPC;
179 ClientDispatcher *clientDispatcher;
183 /* initialize client */
184 if (!g_thread_supported())
189 clientDispatcher = &ClientDispatcher::getInstance();
190 clientIPC = &ClientIPC::getInstance();
192 clientIPC->setDispatcher(clientDispatcher);
194 #ifndef CLIENT_IPC_THREAD
195 if (clientDispatcher->runDispatcherThread() == false)
197 SCARD_DEBUG_ERR("clientDispatcher->runDispatcherThread() failed");
203 if (clientIPC->createConnectSocket() == false)
205 SCARD_DEBUG_ERR("clientIPC->createConnectSocket() failed");
210 clientDispatcher->addSEService(context, this);
213 /* send message to load se */
216 msg.message = Message::MSG_REQUEST_READERS;
217 msg.error = getpid(); /* using error to pid */
218 msg.caller = (void *)this;
219 msg.userParam = context;
221 result = clientIPC->sendMessage(&msg);
229 bool SEService::initialize(void *context, serviceConnected handler)
230 throw(ErrorIO &, ErrorIllegalParameter &)
234 throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
237 this->context = context;
238 this->handler = handler;
240 return _initialize();
243 bool SEService::initialize(void *context, SEServiceListener *listener)
244 throw(ErrorIO &, ErrorIllegalParameter &)
248 throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
251 this->context = context;
252 this->listener = listener;
254 return _initialize();
257 bool SEService::parseReaderInformation(unsigned int count, ByteArray data)
260 unsigned int offset = 0;
261 unsigned int len = 0;
263 Reader *reader = NULL;
266 for (i = 0; i < count && offset < data.getLength(); i++)
268 memset(name, 0, sizeof(name));
270 memcpy(&len, data.getBuffer(offset), sizeof(len));
271 offset += sizeof(len);
273 memcpy(name, data.getBuffer(offset), len);
276 memcpy(&handle, data.getBuffer(offset), sizeof(handle));
277 offset += sizeof(handle);
279 SCARD_DEBUG("Reader [%d] : name [%s], handle [%p]", i, name, handle);
282 reader = new Reader(context, name, handle);
285 SCARD_DEBUG_ERR("alloc failed");
289 readers.push_back(reader);
295 bool SEService::dispatcherCallback(void *message)
297 Message *msg = (Message *)message;
298 SEService *service = NULL;
305 SCARD_DEBUG_ERR("message is null");
309 service = (SEService *)msg->caller;
311 switch (msg->message)
313 case Message::MSG_REQUEST_READERS :
314 SCARD_DEBUG("[MSG_REQUEST_READERS]");
316 service->connected = true;
318 /* parse message data */
319 service->parseReaderInformation(msg->param1, msg->data);
321 /* call callback function */
322 if (service->listener != NULL)
324 service->listener->serviceConnected(service, service->context);
326 else if (service->handler != NULL)
328 service->handler(service, service->context);
332 case Message::MSG_REQUEST_SHUTDOWN :
333 SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
335 if (msg->isSynchronousCall() == true) /* synchronized call */
341 // service->error = msg->error;
342 service->signalCondition();
343 service->syncUnlock();
351 case Message::MSG_NOTIFY_SE_INSERTED :
353 Reader *reader = NULL;
355 SCARD_DEBUG("[MSG_NOTIFY_SE_INSERTED]");
358 reader = new Reader(service->context,
359 (char *)msg->data.getBuffer(), (void *)msg->param1);
362 service->readers.push_back(reader);
366 SCARD_DEBUG_ERR("alloc failed");
369 if (service->listener != NULL)
371 service->listener->eventHandler(service,
372 (char *)msg->data.getBuffer(), 1, service->context);
376 SCARD_DEBUG("listener is null");
381 case Message::MSG_NOTIFY_SE_REMOVED :
385 SCARD_DEBUG("[MSG_NOTIFY_SE_REMOVED]");
387 for (i = 0; i < service->readers.size(); i++)
389 if (((Reader *)service->readers[i])->handle == (void *)msg->param1)
391 ((Reader *)service->readers[i])->present = false;
396 if (service->listener != NULL)
398 service->listener->eventHandler(service,
399 (char *)msg->data.getBuffer(), 2, service->context);
403 SCARD_DEBUG("listener is null");
408 case Message::MSG_OPERATION_RELEASE_CLIENT :
409 SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
411 if (service->listener != NULL)
413 service->listener->errorHandler(service, msg->error, service->context);
415 ClientDispatcher::getInstance().removeSEService(service->context);
416 service->connected = false;
420 SCARD_DEBUG_ERR("service->listener is null");
425 SCARD_DEBUG("unknown message [%s]", msg->toString());
434 } /* namespace smartcard_service_api */
437 #define SE_SERVICE_EXTERN_BEGIN \
438 if (handle != NULL) \
440 SEService *service = (SEService *)handle;
442 #define SE_SERVICE_EXTERN_END \
446 SCARD_DEBUG_ERR("Invalid param"); \
449 using namespace smartcard_service_api;
451 EXTERN_API se_service_h se_service_create_instance(void *user_data, se_service_connected_cb callback)
457 service = new SEService(user_data, (serviceConnected)callback);
464 return (se_service_h)service;
467 EXTERN_API se_service_h se_service_create_instance_with_event_callback(void *user_data,
468 se_service_connected_cb connected, se_service_event_cb event, se_sesrvice_error_cb error)
474 service = new SEService(user_data, (serviceConnected)connected);
481 return (se_service_h)service;
484 EXTERN_API int se_service_get_readers_count(se_service_h handle)
488 SE_SERVICE_EXTERN_BEGIN;
490 vector<ReaderHelper *> temp_readers;
492 temp_readers = service->getReaders();
493 count = temp_readers.size();
495 SE_SERVICE_EXTERN_END;
500 EXTERN_API bool se_service_get_readers(se_service_h handle, reader_h *readers, int *count)
504 SE_SERVICE_EXTERN_BEGIN;
506 vector<ReaderHelper *> temp_readers;
510 temp_readers = service->getReaders();
512 for (i = 0; i < temp_readers.size() && i < (size_t)*count; i++)
514 if (temp_readers[i]->isSecureElementPresent())
516 readers[i] = (reader_h)temp_readers[i];
522 SE_SERVICE_EXTERN_END;
527 EXTERN_API bool se_service_is_connected(se_service_h handle)
531 SE_SERVICE_EXTERN_BEGIN;
533 result = service->isConnected();
535 SE_SERVICE_EXTERN_END;
540 EXTERN_API void se_service_shutdown(se_service_h handle)
542 SE_SERVICE_EXTERN_BEGIN;
546 SE_SERVICE_EXTERN_END;
549 EXTERN_API void se_service_destroy_instance(se_service_h handle)
551 SE_SERVICE_EXTERN_BEGIN;
555 SE_SERVICE_EXTERN_END;