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 */
21 #include <glib-object.h>
23 /* SLP library header */
27 #include "SEService.h"
30 #include "ClientGDBus.h"
33 #include "ClientIPC.h"
34 #include "ClientDispatcher.h"
38 #define EXTERN_API __attribute__((visibility("default")))
41 namespace smartcard_service_api
43 SEService::SEService() : SEServiceHelper(),
44 handle(-1), context(NULL), handler(NULL), listener(NULL)
51 SEService::SEService(void *user_data, serviceConnected handler)
52 throw(ErrorIO &, ErrorIllegalParameter &) :
53 SEServiceHelper(), handle(-1),
56 initialize(user_data, handler);
59 SEService::SEService(void *user_data, SEServiceListener *listener)
60 throw(ErrorIO &, ErrorIllegalParameter &) :
61 SEServiceHelper(), handle(-1),
64 initialize(user_data, listener);
67 SEService::~SEService()
75 catch(ExceptionBase &e)
77 _ERR("EXCEPTION : %s", e.what());
84 for (i = 0; i < readers.size(); i++)
86 delete (Reader *)readers[i];
91 SEService *SEService::createInstance(void *user_data,
92 SEServiceListener *listener)
93 throw(ErrorIO &, ErrorIllegalParameter &)
95 return new SEService(user_data, listener);
98 SEService *SEService::createInstance(void *user_data,
99 serviceConnected handler)
100 throw(ErrorIO &, ErrorIllegalParameter &)
102 return new SEService(user_data, handler);
106 void SEService::reader_inserted(GObject *source_object,
107 guint reader_id, gchar *reader_name, gpointer user_data)
109 Reader *reader = NULL;
110 SEService *service = (SEService *)user_data;
112 _INFO("[MSG_NOTIFY_SE_INSERTED]");
115 reader = new Reader(service->context,
116 reader_name, GUINT_TO_POINTER(reader_id));
119 service->readers.push_back(reader);
123 _ERR("alloc failed");
126 if (service->listener != NULL)
128 service->listener->eventHandler(service,
129 reader_name, 1, service->context);
133 _DBG("listener is null");
137 void SEService::reader_removed(GObject *source_object,
138 guint reader_id, gchar *reader_name, gpointer user_data)
140 SEService *service = (SEService *)user_data;
143 _INFO("[MSG_NOTIFY_SE_REMOVED]");
145 for (i = 0; i < service->readers.size(); i++)
147 if (((Reader *)service->readers[i])->handle ==
148 GUINT_TO_POINTER(reader_id))
150 ((Reader *)service->readers[i])->unavailable();
155 if (service->listener != NULL)
157 service->listener->eventHandler(service,
158 reader_name, 2, service->context);
162 _DBG("listener is null");
166 void SEService::se_service_shutdown_cb(GObject *source_object,
167 GAsyncResult *res, gpointer user_data)
169 SEService *service = (SEService *)user_data;
171 GError *error = NULL;
173 if (smartcard_service_se_service_call_shutdown_finish(
174 SMARTCARD_SERVICE_SE_SERVICE(source_object),
175 &result, res, &error) == true) {
176 if (result == SCARD_ERROR_OK) {
177 service->connected = false;
179 _ERR("smartcard_service_se_service_call_shutdown failed, [%d]", result);
182 _ERR("smartcard_service_se_service_call_shutdown failed, [%s]", error->message);
187 void SEService::se_service_cb(GObject *source_object,
188 GAsyncResult *res, gpointer user_data)
190 SEService *service = (SEService *)user_data;
193 GVariant *readers = NULL;
194 GError *error = NULL;
196 if (service == NULL) {
197 _ERR("null parameter!!!");
201 if (smartcard_service_se_service_call_se_service_finish(
202 SMARTCARD_SERVICE_SE_SERVICE(source_object),
203 &result, &handle, &readers, res, &error) == true) {
204 if (result == SCARD_ERROR_OK) {
205 service->connected = true;
206 service->handle = handle;
207 service->parseReaderInformation(readers);
210 _ERR("smartcard_service_se_service_call_se_service failed, [%s]", error->message);
213 result = SCARD_ERROR_IPC_FAILED;
216 if (service->handler != NULL) {
217 service->handler(service, service->context);
218 } else if (service->listener != NULL) {
219 if (result == SCARD_ERROR_OK) {
220 service->listener->serviceConnected(service, service->context);
222 service->listener->errorHandler(service, result, service->context);
227 void SEService::shutdown()
229 if (connected == true)
233 for (i = 0; i < readers.size(); i++)
235 readers[i]->closeSessions();
238 smartcard_service_se_service_call_shutdown(
239 (SmartcardServiceSeService *)proxy,
240 ClientGDBus::getCookie(),
243 &SEService::se_service_shutdown_cb,
248 msg.message = Message::MSG_REQUEST_SHUTDOWN;
249 msg.param1 = (unsigned long)handle;
250 msg.error = (unsigned long)this; /* using error to context */
251 msg.caller = (void *)this;
252 msg.callback = (void *)NULL;
254 if (ClientIPC::getInstance().sendMessage(msg) == false)
262 void SEService::shutdownSync()
264 if (connected == true)
268 for (i = 0; i < readers.size(); i++)
270 readers[i]->closeSessions();
274 GError *error = NULL;
276 if (smartcard_service_se_service_call_shutdown_sync(
277 (SmartcardServiceSeService *)proxy,
278 ClientGDBus::getCookie(),
283 _ERR("smartcard_service_se_service_call_shutdown_sync failed, [%s]", error->message);
290 #ifdef CLIENT_IPC_THREAD
291 /* send message to load se */
294 msg.message = Message::MSG_REQUEST_SHUTDOWN;
295 msg.param1 = (unsigned long)handle;
296 msg.error = (unsigned long)this; /* using error to context */
297 msg.caller = (void *)this;
298 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
301 if (ClientIPC::getInstance().sendMessage(msg) == true)
305 rv = waitTimedCondition(0);
308 ClientDispatcher::getInstance().removeSEService(handle);
319 _ERR("sendMessage failed");
327 bool SEService::_initialize() throw(ErrorIO &)
331 ClientIPC *clientIPC;
332 ClientDispatcher *clientDispatcher;
336 /* initialize client */
337 if (!g_thread_supported())
345 /* init default context */
346 GError *error = NULL;
348 proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
349 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
350 "org.tizen.SmartcardService",
351 "/org/tizen/SmartcardService/SeService",
355 _ERR("Can not create proxy : %s", error->message);
360 g_signal_connect(proxy, "reader-inserted",
361 G_CALLBACK(&SEService::reader_inserted), this);
363 g_signal_connect(proxy, "reader-removed",
364 G_CALLBACK(&SEService::reader_removed), this);
367 smartcard_service_se_service_call_se_service(
368 (SmartcardServiceSeService *)proxy,
369 ClientGDBus::getCookie(),
371 &SEService::se_service_cb,
374 clientDispatcher = &ClientDispatcher::getInstance();
375 clientIPC = &ClientIPC::getInstance();
377 clientIPC->setDispatcher(clientDispatcher);
379 #ifndef CLIENT_IPC_THREAD
380 if (clientDispatcher->runDispatcherThread() == false)
382 _ERR("clientDispatcher->runDispatcherThread() failed");
388 if (clientIPC->createConnectSocket() == false)
390 _ERR("clientIPC->createConnectSocket() failed");
396 /* send message to load se */
399 msg.message = Message::MSG_REQUEST_READERS;
400 msg.error = getpid(); /* using error to pid */
401 msg.caller = (void *)this;
402 msg.userParam = context;
404 result = clientIPC->sendMessage(msg);
412 bool SEService::initialize(void *context, serviceConnected handler)
413 throw(ErrorIO &, ErrorIllegalParameter &)
417 throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
420 this->context = context;
421 this->handler = handler;
423 return _initialize();
426 bool SEService::initialize(void *context, SEServiceListener *listener)
427 throw(ErrorIO &, ErrorIllegalParameter &)
431 throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
434 this->context = context;
435 this->listener = listener;
437 return _initialize();
441 bool SEService::parseReaderInformation(GVariant *variant)
443 Reader *reader = NULL;
450 g_variant_get(variant, "a(us)", &iter);
452 count = g_variant_iter_n_children(iter);
453 while (g_variant_iter_loop(iter, "(us)", &handle, &name) == true)
455 SECURE_LOGD("Reader : name [%s], handle [%08x]", name, handle);
458 reader = new Reader((void *)this->handle, name, GUINT_TO_POINTER(handle));
461 _ERR("alloc failed");
465 readers.push_back(reader);
468 g_variant_iter_free(iter);
473 bool SEService::parseReaderInformation(unsigned int count,
474 const ByteArray &data)
477 unsigned int offset = 0;
478 unsigned int len = 0;
480 Reader *reader = NULL;
483 for (i = 0; i < count && offset < data.size(); i++)
485 memset(name, 0, sizeof(name));
487 memcpy(&len, data.getBuffer(offset), sizeof(len));
488 offset += sizeof(len);
490 memcpy(name, data.getBuffer(offset), len);
493 memcpy(&handle, data.getBuffer(offset), sizeof(handle));
494 offset += sizeof(handle);
497 reader = new Reader(context, name, handle);
500 _ERR("alloc failed");
504 readers.push_back(reader);
511 bool SEService::dispatcherCallback(void *message)
513 Message *msg = (Message *)message;
521 _ERR("message is null");
525 service = (SEService *)msg->caller;
527 switch (msg->message)
529 case Message::MSG_REQUEST_READERS :
530 _INFO("[MSG_REQUEST_READERS]");
532 service->connected = true;
533 service->handle = (unsigned int)msg->param2;
535 ClientDispatcher::getInstance().addSEService(service->handle, service);
537 /* parse message data */
538 service->parseReaderInformation(msg->param1, msg->data);
540 /* call callback function */
541 if (service->listener != NULL)
543 service->listener->serviceConnected(service, service->context);
545 else if (service->handler != NULL)
547 service->handler(service, service->context);
551 case Message::MSG_REQUEST_SHUTDOWN :
552 _INFO("[MSG_REQUEST_SHUTDOWN]");
554 if (msg->isSynchronousCall() == true) /* synchronized call */
560 // service->error = msg->error;
561 service->signalCondition();
562 service->syncUnlock();
570 case Message::MSG_NOTIFY_SE_INSERTED :
572 Reader *reader = NULL;
574 _INFO("[MSG_NOTIFY_SE_INSERTED]");
577 reader = new Reader(service->context,
578 (char *)msg->data.getBuffer(), (void *)msg->param1);
581 service->readers.push_back(reader);
585 _ERR("alloc failed");
588 if (service->listener != NULL)
590 service->listener->eventHandler(service,
591 (char *)msg->data.getBuffer(), 1, service->context);
595 _DBG("listener is null");
600 case Message::MSG_NOTIFY_SE_REMOVED :
604 _INFO("[MSG_NOTIFY_SE_REMOVED]");
606 for (i = 0; i < service->readers.size(); i++)
608 if (((Reader *)service->readers[i])->handle == (void *)msg->param1)
610 ((Reader *)service->readers[i])->present = false;
615 if (service->listener != NULL)
617 service->listener->eventHandler(service,
618 (char *)msg->data.getBuffer(), 2, service->context);
622 _DBG("listener is null");
627 case Message::MSG_OPERATION_RELEASE_CLIENT :
628 _INFO("[MSG_OPERATION_RELEASE_CLIENT]");
630 if (service->listener != NULL)
632 service->listener->errorHandler(service, msg->error, service->context);
634 ClientDispatcher::getInstance().removeSEService(service->handle);
635 service->connected = false;
639 _ERR("service->listener is null");
644 _DBG("unknown message [%s]", msg->toString().c_str());
655 } /* namespace smartcard_service_api */
658 #define SE_SERVICE_EXTERN_BEGIN \
659 if (handle != NULL) \
661 SEService *service = (SEService *)handle;
663 #define SE_SERVICE_EXTERN_END \
667 _ERR("Invalid param"); \
670 using namespace smartcard_service_api;
672 EXTERN_API se_service_h se_service_create_instance(void *user_data, se_service_connected_cb callback)
678 service = new SEService(user_data, (serviceConnected)callback);
685 return (se_service_h)service;
688 EXTERN_API se_service_h se_service_create_instance_with_event_callback(void *user_data,
689 se_service_connected_cb connected, se_service_event_cb event, se_sesrvice_error_cb error)
695 service = new SEService(user_data, (serviceConnected)connected);
702 return (se_service_h)service;
705 EXTERN_API int se_service_get_readers_count(se_service_h handle)
709 SE_SERVICE_EXTERN_BEGIN;
711 vector<ReaderHelper *> temp_readers;
713 temp_readers = service->getReaders();
714 count = temp_readers.size();
716 SE_SERVICE_EXTERN_END;
721 EXTERN_API bool se_service_get_readers(se_service_h handle, reader_h *readers, int *count)
725 SE_SERVICE_EXTERN_BEGIN;
727 vector<ReaderHelper *> temp_readers;
731 temp_readers = service->getReaders();
733 for (i = 0; i < temp_readers.size() && i < (size_t)*count; i++)
735 if (temp_readers[i]->isSecureElementPresent())
737 readers[i] = (reader_h)temp_readers[i];
743 SE_SERVICE_EXTERN_END;
748 EXTERN_API bool se_service_is_connected(se_service_h handle)
752 SE_SERVICE_EXTERN_BEGIN;
754 result = service->isConnected();
756 SE_SERVICE_EXTERN_END;
761 EXTERN_API void se_service_shutdown(se_service_h handle)
763 SE_SERVICE_EXTERN_BEGIN;
767 SE_SERVICE_EXTERN_END;
770 EXTERN_API void se_service_destroy_instance(se_service_h handle)
772 SE_SERVICE_EXTERN_BEGIN;
776 SE_SERVICE_EXTERN_END;