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>
25 #include "SEService.h"
26 #include "ClientChannel.h"
28 #include "ClientGDBus.h"
31 #define EXTERN_API __attribute__((visibility("default")))
34 #define SHUTDOWN_DELAY 500000 /* us */
37 namespace smartcard_service_api
39 SEService::SEService() : SEServiceHelper(),
40 handle(-1), context(NULL), handler(NULL), listener(NULL),
46 SEService::SEService(void *user_data, serviceConnected handler)
47 throw(ErrorIO &, ErrorIllegalParameter &) :
48 SEServiceHelper(), handle(-1),
49 listener(NULL), version(VERSION)
51 initialize(user_data, handler);
54 SEService::SEService(void *user_data, SEServiceListener *listener)
55 throw(ErrorIO &, ErrorIllegalParameter &) :
56 SEServiceHelper(), handle(-1),
57 handler(NULL), version(VERSION)
59 initialize(user_data, listener);
62 SEService::SEService(void *user_data)
63 throw(ErrorIO &, ErrorIllegalParameter &, ExceptionBase &) :
64 SEServiceHelper(), handle(-1),
65 handler(NULL), version(VERSION)
67 initializeSync(user_data);
70 SEService::~SEService()
78 for (i = 0; i < readers.size(); i++)
80 delete (Reader *)readers[i];
85 catch (ExceptionBase &e)
87 _ERR("EXCEPTION : %s", e.what());
95 SEService *SEService::createInstance(void *user_data,
96 SEServiceListener *listener)
97 throw(ErrorIO &, ErrorIllegalParameter &)
99 return new SEService(user_data, listener);
102 SEService *SEService::createInstance(void *user_data,
103 serviceConnected handler)
104 throw(ErrorIO &, ErrorIllegalParameter &)
106 return new SEService(user_data, handler);
109 void SEService::reader_inserted(GObject *source_object,
110 guint reader_id, gchar *reader_name, gpointer user_data)
112 Reader *reader = NULL;
113 SEService *service = (SEService *)user_data;
115 _INFO("[MSG_NOTIFY_SE_INSERTED]");
118 reader = new Reader(service->context,
119 reader_name, GUINT_TO_POINTER(reader_id));
122 service->readers.push_back(reader);
126 _ERR("alloc failed");
129 if (service->listener != NULL)
131 service->listener->eventHandler(service,
132 reader_name, 1, service->context);
134 else if (service->event_handler != NULL)
136 service->event_handler(reader_id, 1, service->context);
140 _DBG("listener is null");
144 void SEService::reader_removed(GObject *source_object,
145 guint reader_id, gchar *reader_name, gpointer user_data)
147 SEService *service = (SEService *)user_data;
150 _INFO("[MSG_NOTIFY_SE_REMOVED]");
152 for (i = 0; i < service->readers.size(); i++)
154 if (((Reader *)service->readers[i])->handle ==
155 GUINT_TO_POINTER(reader_id))
157 ((Reader *)service->readers[i])->unavailable();
162 if (service->listener != NULL)
164 service->listener->eventHandler(service,
165 reader_name, 2, service->context);
167 else if (service->event_handler != NULL)
169 service->event_handler(reader_id, 2, service->context);
173 _DBG("listener is null");
177 void SEService::se_service_shutdown_cb(GObject *source_object,
178 GAsyncResult *res, gpointer user_data)
180 SEService *service = (SEService *)user_data;
182 GError *error = NULL;
184 if (smartcard_service_se_service_call_shutdown_finish(
185 SMARTCARD_SERVICE_SE_SERVICE(source_object),
186 &result, res, &error) == true) {
187 if (result == SCARD_ERROR_OK) {
188 service->connected = false;
190 _ERR("smartcard_service_se_service_call_shutdown failed, [%d]", result);
193 _ERR("smartcard_service_se_service_call_shutdown failed, [%s]", error->message);
198 void SEService::se_service_cb(GObject *source_object,
199 GAsyncResult *res, gpointer user_data)
201 SEService *service = (SEService *)user_data;
204 GVariant *readers = NULL;
205 GError *error = NULL;
207 if (service == NULL) {
208 _ERR("null parameter!!!");
212 if (smartcard_service_se_service_call_se_service_finish(
213 SMARTCARD_SERVICE_SE_SERVICE(source_object),
214 &result, &handle, &readers, res, &error) == true) {
215 if (result == SCARD_ERROR_OK) {
216 service->connected = true;
217 service->handle = handle;
218 service->parseReaderInformation(readers);
221 _ERR("smartcard_service_se_service_call_se_service failed, [%s]", error->message);
224 result = SCARD_ERROR_IPC_FAILED;
227 if (service->handler != NULL) {
228 service->handler(service, service->context);
229 } else if (service->listener != NULL) {
230 if (result == SCARD_ERROR_OK) {
231 service->listener->serviceConnected(service, service->context);
233 service->listener->errorHandler(service, result, service->context);
238 void SEService::shutdown()
243 void SEService::shutdownSync()
245 if (connected == true)
249 for (i = 0; i < readers.size(); i++)
251 readers[i]->closeSessions();
255 GError *error = NULL;
257 if (smartcard_service_se_service_call_shutdown_sync(
258 (SmartcardServiceSeService *)proxy,
263 _ERR("smartcard_service_se_service_call_shutdown_sync failed, [%s]", error->message);
268 /* wait at least 500ms */
269 usleep(SHUTDOWN_DELAY);
275 bool SEService::_initialize() throw(ErrorIO &)
281 /* init default context */
282 GError *error = NULL;
284 proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
285 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
286 "org.tizen.SmartcardService",
287 "/org/tizen/SmartcardService/SeService",
291 _ERR("Can not create proxy : %s", error->message);
296 g_signal_connect(proxy, "reader-inserted",
297 G_CALLBACK(&SEService::reader_inserted), this);
299 g_signal_connect(proxy, "reader-removed",
300 G_CALLBACK(&SEService::reader_removed), this);
303 smartcard_service_se_service_call_se_service(
304 (SmartcardServiceSeService *)proxy,
306 &SEService::se_service_cb,
314 int SEService::_initialize_sync_do_not_throw_exception()
318 GError *error = NULL;
319 GVariant *readers = NULL;
320 SEService *service = (SEService *)this;
324 /* init default context */
326 proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
327 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
328 "org.tizen.SmartcardService",
329 "/org/tizen/SmartcardService/SeService",
333 _ERR("Can not create proxy : %s", error->message);
338 g_signal_connect(proxy, "reader-inserted",
339 G_CALLBACK(&SEService::reader_inserted), this);
341 g_signal_connect(proxy, "reader-removed",
342 G_CALLBACK(&SEService::reader_removed), this);
345 if(smartcard_service_se_service_call_se_service_sync(
346 (SmartcardServiceSeService *)proxy, &result, &handle, &readers, NULL, &error) == true)
348 if (result == SCARD_ERROR_OK)
350 service->connected = true;
351 service->handle = handle;
352 service->parseReaderInformation(readers);
356 _ERR("Initialize error : %d", result);
360 if (service->handler != NULL) {
361 service->handler(service, service->context);
362 } else if (service->listener != NULL) {
363 if (result == SCARD_ERROR_OK) {
364 service->listener->serviceConnected(service, service->context);
366 service->listener->errorHandler(service, result, service->context);
375 int SEService::_initialize_sync() throw(ErrorIO &, ExceptionBase &)
379 GError *error = NULL;
380 GVariant *readers = NULL;
381 SEService *service = (SEService *)this;
385 /* init default context */
387 proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
388 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
389 "org.tizen.SmartcardService",
390 "/org/tizen/SmartcardService/SeService",
394 _ERR("Can not create proxy : %s", error->message);
399 g_signal_connect(proxy, "reader-inserted",
400 G_CALLBACK(&SEService::reader_inserted), this);
402 g_signal_connect(proxy, "reader-removed",
403 G_CALLBACK(&SEService::reader_removed), this);
406 if(smartcard_service_se_service_call_se_service_sync(
407 (SmartcardServiceSeService *)proxy, &result, &handle, &readers, NULL, &error) == true)
409 if (result == SCARD_ERROR_OK)
411 service->connected = true;
412 service->handle = handle;
413 service->parseReaderInformation(readers);
417 throw ExceptionBase(result);
422 _ERR("smartcard_service_se_service_call_se_service failed, [%s]", error->message);
425 result = SCARD_ERROR_IPC_FAILED;
433 bool SEService::initialize(void *context, serviceConnected handler)
434 throw(ErrorIO &, ErrorIllegalParameter &)
438 throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
441 this->context = context;
442 this->handler = handler;
444 return _initialize();
447 bool SEService::initialize(void *context, SEServiceListener *listener)
448 throw(ErrorIO &, ErrorIllegalParameter &)
452 throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
455 this->context = context;
456 this->listener = listener;
458 return _initialize_sync_do_not_throw_exception();
461 bool SEService::initializeSync(void *context)
462 throw(ErrorIO &, ErrorIllegalParameter &, ExceptionBase &)
464 this->context = context;
470 void SEService::setEventHandler(se_service_event_cb cb, void *context)
472 this->event_handler = cb;
473 this->event_handler_context = context;
476 bool SEService::parseReaderInformation(GVariant *variant)
478 Reader *reader = NULL;
484 g_variant_get(variant, "a(us)", &iter);
486 while (g_variant_iter_loop(iter, "(us)", &handle, &name) == true)
488 SECURE_LOGD("Reader : name [%s], handle [%08x]", name, handle);
491 reader = new Reader((void *)this->handle, name, GUINT_TO_POINTER(handle));
494 _ERR("alloc failed");
498 readers.push_back(reader);
501 g_variant_iter_free(iter);
506 bool SEService::parseReaderInformation(unsigned int count,
507 const ByteArray &data)
510 unsigned int offset = 0;
511 unsigned int len = 0;
513 Reader *reader = NULL;
515 const uint8_t *buffer = NULL;
518 for (i = 0; i < count && offset < data.size(); i++)
520 memset(name, 0, sizeof(name));
522 buffer = data.getBuffer(offset);
526 memcpy(&len, buffer, sizeof(len));
527 offset += sizeof(len);
529 buffer = data.getBuffer(offset);
533 memcpy(name, buffer, len);
536 buffer = data.getBuffer(offset);
540 memcpy(&handle, buffer, sizeof(handle));
541 offset += sizeof(handle);
543 SECURE_LOGD("Reader [%d] : name [%s], handle [%p]", i, name, handle);
546 reader = new Reader(context, name, handle);
549 _ERR("alloc failed");
553 readers.push_back(reader);
558 } /* namespace smartcard_service_api */
561 #define SE_SERVICE_EXTERN_BEGIN \
562 if (handle != NULL) \
564 SEService *service = (SEService *)handle;
566 #define SE_SERVICE_EXTERN_END \
570 _ERR("Invalid param"); \
573 using namespace smartcard_service_api;
575 EXTERN_API se_service_h se_service_create_instance(void *user_data,
576 se_service_connected_cb callback)
582 service = new SEService(user_data, (serviceConnected)callback);
589 return (se_service_h)service;
592 EXTERN_API se_service_h se_service_create_instance_with_event_callback(
593 void *user_data, se_service_connected_cb connected,
594 se_service_event_cb event, se_sesrvice_error_cb error)
600 service = new SEService(user_data, (serviceConnected)connected);
607 return (se_service_h)service;
610 EXTERN_API se_service_h se_service_create_instance_sync(void *user_data,
617 service = new SEService(user_data);
619 catch (ExceptionBase &e)
621 *result = e.getErrorCode();
626 *result = SCARD_ERROR_UNKNOWN;
630 return (se_service_h)service;
633 EXTERN_API int se_service_get_version(se_service_h handle, char **version_str)
637 SE_SERVICE_EXTERN_BEGIN;
639 *version_str = g_strdup(service->getVersion());
641 SE_SERVICE_EXTERN_END;
646 EXTERN_API int se_service_get_readers_count(se_service_h handle)
650 SE_SERVICE_EXTERN_BEGIN;
652 vector<ReaderHelper *> temp_readers;
654 temp_readers = service->getReaders();
655 count = temp_readers.size();
657 SE_SERVICE_EXTERN_END;
662 EXTERN_API int se_service_get_readers(se_service_h handle, int **readers, int *count)
666 SE_SERVICE_EXTERN_BEGIN;
668 vector<ReaderHelper *> temp_readers;
672 temp_readers = service->getReaders();
673 if(temp_readers.size() > 0)
675 *readers = (int *)calloc(temp_readers.size(), sizeof(int));
680 return SCARD_ERROR_NOT_ENOUGH_RESOURCE;
683 for (i = 0; i < temp_readers.size(); i++)
685 if (temp_readers[i]->isSecureElementPresent())
687 (*readers)[i] = (long)temp_readers[i];
698 SE_SERVICE_EXTERN_END;
703 EXTERN_API bool se_service_is_connected(se_service_h handle)
707 SE_SERVICE_EXTERN_BEGIN;
709 result = service->isConnected();
711 SE_SERVICE_EXTERN_END;
716 EXTERN_API void se_service_shutdown(se_service_h handle)
718 SE_SERVICE_EXTERN_BEGIN;
720 service->shutdownSync();
722 SE_SERVICE_EXTERN_END;
725 EXTERN_API void se_service_set_event_handler(se_service_h handle,
726 se_service_event_cb event_handler, void *user_data)
728 SE_SERVICE_EXTERN_BEGIN;
730 service->setEventHandler(event_handler, user_data);
732 SE_SERVICE_EXTERN_END;
735 EXTERN_API void se_service_unset_event_handler(se_service_h handle)
737 SE_SERVICE_EXTERN_BEGIN;
739 service->setEventHandler(NULL, NULL);
741 SE_SERVICE_EXTERN_END;
744 EXTERN_API int se_service_destroy_instance(se_service_h handle)
748 SE_SERVICE_EXTERN_BEGIN;
752 SE_SERVICE_EXTERN_END;