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 ErrorIllegalParameter e(0);
239 this->context = context;
240 this->handler = handler;
242 return _initialize();
245 bool SEService::initialize(void *context, SEServiceListener *listener)
246 throw(ErrorIO &, ErrorIllegalParameter &)
250 ErrorIllegalParameter e(0);
255 this->context = context;
256 this->listener = listener;
258 return _initialize();
261 bool SEService::parseReaderInformation(unsigned int count, ByteArray data)
264 unsigned int offset = 0;
265 unsigned int len = 0;
267 Reader *reader = NULL;
270 for (i = 0; i < count && offset < data.getLength(); i++)
272 memset(name, 0, sizeof(name));
274 memcpy(&len, data.getBuffer(offset), sizeof(len));
275 offset += sizeof(len);
277 memcpy(name, data.getBuffer(offset), len);
280 memcpy(&handle, data.getBuffer(offset), sizeof(handle));
281 offset += sizeof(handle);
283 SCARD_DEBUG("Reader [%d] : name [%s], handle [%p]", i, name, handle);
286 reader = new Reader(context, name, handle);
289 SCARD_DEBUG_ERR("alloc failed");
293 readers.push_back(reader);
299 bool SEService::dispatcherCallback(void *message)
301 Message *msg = (Message *)message;
302 SEService *service = NULL;
309 SCARD_DEBUG_ERR("message is null");
313 service = (SEService *)msg->caller;
315 switch (msg->message)
317 case Message::MSG_REQUEST_READERS :
318 SCARD_DEBUG("[MSG_REQUEST_READERS]");
320 service->connected = true;
322 /* parse message data */
323 service->parseReaderInformation(msg->param1, msg->data);
325 /* call callback function */
326 if (service->listener != NULL)
328 service->listener->serviceConnected(service, service->context);
330 else if (service->handler != NULL)
332 service->handler(service, service->context);
336 case Message::MSG_REQUEST_SHUTDOWN :
337 SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
339 if (msg->isSynchronousCall() == true) /* synchronized call */
345 // service->error = msg->error;
346 service->signalCondition();
347 service->syncUnlock();
355 case Message::MSG_NOTIFY_SE_INSERTED :
357 Reader *reader = NULL;
359 SCARD_DEBUG("[MSG_NOTIFY_SE_INSERTED]");
362 reader = new Reader(service->context,
363 (char *)msg->data.getBuffer(), (void *)msg->param1);
366 service->readers.push_back(reader);
370 SCARD_DEBUG_ERR("alloc failed");
373 if (service->listener != NULL)
375 service->listener->eventHandler(service,
376 (char *)msg->data.getBuffer(), 1, service->context);
380 SCARD_DEBUG("listener is null");
385 case Message::MSG_NOTIFY_SE_REMOVED :
389 SCARD_DEBUG("[MSG_NOTIFY_SE_REMOVED]");
391 for (i = 0; i < service->readers.size(); i++)
393 if (((Reader *)service->readers[i])->handle == (void *)msg->param1)
395 ((Reader *)service->readers[i])->present = false;
400 if (service->listener != NULL)
402 service->listener->eventHandler(service,
403 (char *)msg->data.getBuffer(), 2, service->context);
407 SCARD_DEBUG("listener is null");
412 case Message::MSG_OPERATION_RELEASE_CLIENT :
413 SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
415 if (service->listener != NULL)
417 service->listener->errorHandler(service, msg->error, service->context);
419 ClientDispatcher::getInstance().removeSEService(service->context);
420 service->connected = false;
424 SCARD_DEBUG_ERR("service->listener is null");
429 SCARD_DEBUG("unknown message [%s]", msg->toString());
438 } /* namespace smartcard_service_api */
441 #define SE_SERVICE_EXTERN_BEGIN \
442 if (handle != NULL) \
444 SEService *service = (SEService *)handle;
446 #define SE_SERVICE_EXTERN_END \
450 SCARD_DEBUG_ERR("Invalid param"); \
453 using namespace smartcard_service_api;
455 EXTERN_API se_service_h se_service_create_instance(void *user_data, se_service_connected_cb callback)
461 service = new SEService(user_data, (serviceConnected)callback);
468 return (se_service_h)service;
471 EXTERN_API se_service_h se_service_create_instance_with_event_callback(void *user_data,
472 se_service_connected_cb connected, se_service_event_cb event, se_sesrvice_error_cb error)
478 service = new SEService(user_data, (serviceConnected)connected);
485 return (se_service_h)service;
488 EXTERN_API int se_service_get_readers_count(se_service_h handle)
492 SE_SERVICE_EXTERN_BEGIN;
494 vector<ReaderHelper *> temp_readers;
496 temp_readers = service->getReaders();
497 count = temp_readers.size();
499 SE_SERVICE_EXTERN_END;
504 EXTERN_API bool se_service_get_readers(se_service_h handle, reader_h *readers, int *count)
508 SE_SERVICE_EXTERN_BEGIN;
510 vector<ReaderHelper *> temp_readers;
514 temp_readers = service->getReaders();
516 for (i = 0; i < temp_readers.size() && i < (size_t)*count; i++)
518 if (temp_readers[i]->isSecureElementPresent())
520 readers[i] = (reader_h)temp_readers[i];
526 SE_SERVICE_EXTERN_END;
531 EXTERN_API bool se_service_is_connected(se_service_h handle)
535 SE_SERVICE_EXTERN_BEGIN;
537 result = service->isConnected();
539 SE_SERVICE_EXTERN_END;
544 EXTERN_API void se_service_shutdown(se_service_h handle)
546 SE_SERVICE_EXTERN_BEGIN;
550 SE_SERVICE_EXTERN_END;
553 EXTERN_API void se_service_destroy_instance(se_service_h handle)
555 SE_SERVICE_EXTERN_BEGIN;
559 SE_SERVICE_EXTERN_END;