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>
26 #include "SEService.h"
27 #include "ClientChannel.h"
29 #include "ClientGDBus.h"
34 #define EXTERN_API __attribute__((visibility("default")))
37 #define SHUTDOWN_DELAY 500000 /* us */
40 namespace smartcard_service_api
42 SEService::SEService() : SEServiceHelper(),
43 handle(-1), context(NULL), handler(NULL), listener(NULL),
49 SEService::SEService(void *user_data, serviceConnected handler)
50 throw(ErrorIO &, ErrorIllegalParameter &) :
51 SEServiceHelper(), handle(-1), context(NULL), listener(NULL),
52 event_handler(NULL), event_handler_context(NULL),
53 proxy(NULL), version(VERSION)
55 initialize(user_data, handler);
58 SEService::SEService(void *user_data, SEServiceListener *listener)
59 throw(ErrorIO &, ErrorIllegalParameter &) :
60 SEServiceHelper(), handle(-1), handler(NULL),
61 event_handler(NULL), event_handler_context(NULL),
62 proxy(NULL), version(VERSION)
64 initialize(user_data, listener);
67 SEService::SEService(void *user_data)
68 throw(ErrorIO &, ErrorIllegalParameter &, ExceptionBase &) :
69 SEServiceHelper(), handle(-1), handler(NULL), listener(NULL),
70 event_handler(NULL), event_handler_context(NULL),
71 proxy(NULL), version(VERSION)
73 initializeSync(user_data);
76 SEService::~SEService()
84 for (i = 0; i < readers.size(); i++)
86 delete (Reader *)readers[i];
91 catch (ExceptionBase &e)
93 _ERR("EXCEPTION : %s", e.what());
101 void SEService::reader_inserted(GObject *source_object,
102 guint reader_id, gchar *reader_name, gpointer user_data)
104 Reader *reader = NULL;
105 SEService *service = (SEService *)user_data;
107 _INFO("[MSG_NOTIFY_SE_INSERTED]");
110 reader = new (std::nothrow)Reader(service->context,
111 reader_name, GUINT_TO_POINTER(reader_id));
113 if (reader != NULL) {
114 service->readers.push_back(reader);
116 _ERR("alloc failed");
119 if (service->listener != NULL) {
120 service->listener->eventHandler(service,
121 reader_name, 1, service->context);
122 } else if (service->event_handler != NULL) {
123 service->event_handler(reader_id, 1, service->context);
125 _DBG("listener is null");
129 void SEService::reader_removed(GObject *source_object,
130 guint reader_id, gchar *reader_name, gpointer user_data)
132 SEService *service = (SEService *)user_data;
135 _INFO("[MSG_NOTIFY_SE_REMOVED]");
137 for (i = 0; i < service->readers.size(); i++)
139 if (((Reader *)service->readers[i])->handle ==
140 GUINT_TO_POINTER(reader_id))
142 ((Reader *)service->readers[i])->unavailable();
147 if (service->listener != NULL) {
148 service->listener->eventHandler(service,
149 reader_name, 2, service->context);
150 } else if (service->event_handler != NULL) {
151 service->event_handler(reader_id, 2, service->context);
153 _DBG("listener is null");
157 void SEService::se_service_shutdown_cb(GObject *source_object,
158 GAsyncResult *res, gpointer user_data)
160 SEService *service = (SEService *)user_data;
162 GError *error = NULL;
164 if (smartcard_service_se_service_call_shutdown_finish(
165 SMARTCARD_SERVICE_SE_SERVICE(source_object),
166 &result, res, &error) == true) {
167 if (result == SCARD_ERROR_OK) {
168 service->connected = false;
170 _ERR("smartcard_service_se_service_call_shutdown failed, [%d]", result);
173 _ERR("smartcard_service_se_service_call_shutdown failed, [%s]", error->message);
178 void SEService::se_service_cb(GObject *source_object,
179 GAsyncResult *res, gpointer user_data)
181 SEService *service = (SEService *)user_data;
184 GVariant *readers = NULL;
185 GError *error = NULL;
187 if (service == NULL) {
188 _ERR("null parameter!!!");
192 if (smartcard_service_se_service_call_se_service_finish(
193 SMARTCARD_SERVICE_SE_SERVICE(source_object),
194 &result, &handle, &readers, res, &error) == true) {
195 if (result == SCARD_ERROR_OK) {
196 service->connected = true;
197 service->handle = handle;
198 service->parseReaderInformation(readers);
201 _ERR("smartcard_service_se_service_call_se_service failed, [%s]", error->message);
204 result = SCARD_ERROR_IPC_FAILED;
207 if (service->handler != NULL) {
208 service->handler(service, service->context);
209 } else if (service->listener != NULL) {
210 if (result == SCARD_ERROR_OK) {
211 service->listener->serviceConnected(service, service->context);
213 service->listener->errorHandler(service, result, service->context);
218 void SEService::shutdown()
223 void SEService::shutdownSync()
225 if (connected == true)
229 for (i = 0; i < readers.size(); i++)
231 readers[i]->closeSessions();
235 GError *error = NULL;
237 if (smartcard_service_se_service_call_shutdown_sync(
238 (SmartcardServiceSeService *)proxy,
243 _ERR("smartcard_service_se_service_call_shutdown_sync failed, [%s]", error->message);
248 /* wait at least 500ms */
249 usleep(SHUTDOWN_DELAY);
255 bool SEService::_initialize() throw(ErrorIO &)
261 /* init default context */
262 GError *error = NULL;
264 proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
265 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
266 "org.tizen.SmartcardService",
267 "/org/tizen/SmartcardService/SeService",
271 _ERR("Can not create proxy : %s", error->message);
276 g_signal_connect(proxy, "reader-inserted",
277 G_CALLBACK(&SEService::reader_inserted), this);
279 g_signal_connect(proxy, "reader-removed",
280 G_CALLBACK(&SEService::reader_removed), this);
283 smartcard_service_se_service_call_se_service(
284 (SmartcardServiceSeService *)proxy,
286 &SEService::se_service_cb,
294 int SEService::_initialize_sync_do_not_throw_exception()
298 GError *error = NULL;
299 GVariant *readers = NULL;
300 SEService *service = (SEService *)this;
304 /* init default context */
306 proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
307 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
308 "org.tizen.SmartcardService",
309 "/org/tizen/SmartcardService/SeService",
313 _ERR("Can not create proxy : %s", error->message);
318 g_signal_connect(proxy, "reader-inserted",
319 G_CALLBACK(&SEService::reader_inserted), this);
321 g_signal_connect(proxy, "reader-removed",
322 G_CALLBACK(&SEService::reader_removed), this);
325 if(smartcard_service_se_service_call_se_service_sync(
326 (SmartcardServiceSeService *)proxy, &result, &handle, &readers, NULL, &error) == true)
328 if (result == SCARD_ERROR_OK) {
329 service->connected = true;
330 service->handle = handle;
331 service->parseReaderInformation(readers);
333 _ERR("Initialize error : %d", result);
337 if (service->handler != NULL) {
338 service->handler(service, service->context);
339 } else if (service->listener != NULL) {
340 if (result == SCARD_ERROR_OK) {
341 service->listener->serviceConnected(service, service->context);
343 service->listener->errorHandler(service, result, service->context);
352 int SEService::_initialize_sync() throw(ErrorIO &, ExceptionBase &)
356 GError *error = NULL;
357 GVariant *readers = NULL;
358 SEService *service = (SEService *)this;
362 /* init default context */
364 proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
365 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
366 "org.tizen.SmartcardService",
367 "/org/tizen/SmartcardService/SeService",
371 _ERR("Can not create proxy : %s", error->message);
376 g_signal_connect(proxy, "reader-inserted",
377 G_CALLBACK(&SEService::reader_inserted), this);
379 g_signal_connect(proxy, "reader-removed",
380 G_CALLBACK(&SEService::reader_removed), this);
383 if(smartcard_service_se_service_call_se_service_sync(
384 (SmartcardServiceSeService *)proxy, &result, &handle, &readers, NULL, &error) == true) {
385 if (result == SCARD_ERROR_OK) {
386 service->connected = true;
387 service->handle = handle;
388 service->parseReaderInformation(readers);
390 throw ExceptionBase(result);
393 _ERR("smartcard_service_se_service_call_se_service failed, [%s]", error->message);
396 result = SCARD_ERROR_IPC_FAILED;
404 bool SEService::initialize(void *context, serviceConnected handler)
405 throw(ErrorIO &, ErrorIllegalParameter &)
409 throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
412 this->context = context;
413 this->handler = handler;
415 return _initialize();
418 bool SEService::initialize(void *context, SEServiceListener *listener)
419 throw(ErrorIO &, ErrorIllegalParameter &)
423 throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
426 this->context = context;
427 this->listener = listener;
429 return _initialize_sync_do_not_throw_exception();
432 bool SEService::initializeSync(void *context)
433 throw(ErrorIO &, ErrorIllegalParameter &, ExceptionBase &)
435 this->context = context;
441 void SEService::setEventHandler(se_service_event_cb cb, void *context)
443 this->event_handler = cb;
444 this->event_handler_context = context;
447 bool SEService::parseReaderInformation(GVariant *variant)
449 Reader *reader = NULL;
455 g_variant_get(variant, "a(us)", &iter);
457 while (g_variant_iter_loop(iter, "(us)", &handle, &name) == true)
459 SECURE_LOGD("Reader : name [%s], handle [%08x]", name, handle);
462 reader = new (std::nothrow)Reader(GUINT_TO_POINTER(this->handle), name, GUINT_TO_POINTER(handle));
465 _ERR("alloc failed");
469 readers.push_back(reader);
472 g_variant_iter_free(iter);
477 bool SEService::parseReaderInformation(unsigned int count,
478 const ByteArray &data)
481 unsigned int offset = 0;
482 unsigned int len = 0;
484 Reader *reader = NULL;
486 const uint8_t *buffer = NULL;
489 for (i = 0; i < count && offset < data.size(); i++)
491 memset(name, 0, sizeof(name));
493 buffer = data.getBuffer(offset);
497 memcpy(&len, buffer, sizeof(len));
498 offset += sizeof(len);
500 buffer = data.getBuffer(offset);
504 memcpy(name, buffer, len);
507 buffer = data.getBuffer(offset);
511 memcpy(&handle, buffer, sizeof(handle));
512 offset += sizeof(handle);
514 SECURE_LOGD("Reader [%zu] : name [%s], handle [%p]", i, name, (void *)handle);
517 reader = new (std::nothrow)Reader(context, name, handle);
520 _ERR("alloc failed");
524 readers.push_back(reader);
529 } /* namespace smartcard_service_api */
532 #define SE_SERVICE_EXTERN_BEGIN \
533 if (handle != NULL) \
535 SEService *service = (SEService *)handle;
537 #define SE_SERVICE_EXTERN_END \
541 _ERR("Invalid param"); \
544 using namespace smartcard_service_api;
546 EXTERN_API se_service_h se_service_create_instance(void *user_data,
547 se_service_connected_cb callback)
553 service = new (std::nothrow)SEService(user_data, (serviceConnected)callback);
560 return (se_service_h)service;
563 EXTERN_API se_service_h se_service_create_instance_with_event_callback(
564 void *user_data, se_service_connected_cb connected,
565 se_service_event_cb event, se_sesrvice_error_cb error)
571 service = new (std::nothrow)SEService(user_data, (serviceConnected)connected);
578 return (se_service_h)service;
581 EXTERN_API se_service_h se_service_create_instance_sync(void *user_data,
588 service = new (std::nothrow)SEService(user_data);
590 catch (ExceptionBase &e)
592 *result = e.getErrorCode();
597 *result = SCARD_ERROR_UNKNOWN;
601 return (se_service_h)service;
604 EXTERN_API int se_service_get_version(se_service_h handle, char **version_str)
608 SE_SERVICE_EXTERN_BEGIN;
610 *version_str = g_strdup(service->getVersion());
612 SE_SERVICE_EXTERN_END;
617 EXTERN_API int se_service_get_readers_count(se_service_h handle)
621 SE_SERVICE_EXTERN_BEGIN;
623 vector<ReaderHelper *> temp_readers;
625 temp_readers = service->getReaders();
626 count = temp_readers.size();
628 SE_SERVICE_EXTERN_END;
633 EXTERN_API int se_service_get_readers(se_service_h handle, int **readers, int *count)
637 SE_SERVICE_EXTERN_BEGIN;
639 vector<ReaderHelper *> temp_readers;
643 temp_readers = service->getReaders();
644 if (temp_readers.size() > 0) {
645 *readers = (int *)calloc(temp_readers.size(), sizeof(int));
650 return SCARD_ERROR_NOT_ENOUGH_RESOURCE;
653 for (i = 0; i < temp_readers.size(); i++)
655 if (temp_readers[i]->isSecureElementPresent()) {
656 (*readers)[i] = (long)temp_readers[i];
665 SE_SERVICE_EXTERN_END;
670 EXTERN_API bool se_service_is_connected(se_service_h handle)
674 SE_SERVICE_EXTERN_BEGIN;
676 result = service->isConnected();
678 SE_SERVICE_EXTERN_END;
683 EXTERN_API void se_service_shutdown(se_service_h handle)
685 SE_SERVICE_EXTERN_BEGIN;
687 service->shutdownSync();
689 SE_SERVICE_EXTERN_END;
692 EXTERN_API void se_service_set_event_handler(se_service_h handle,
693 se_service_event_cb event_handler, void *user_data)
695 SE_SERVICE_EXTERN_BEGIN;
697 service->setEventHandler(event_handler, user_data);
699 SE_SERVICE_EXTERN_END;
702 EXTERN_API void se_service_unset_event_handler(se_service_h handle)
704 SE_SERVICE_EXTERN_BEGIN;
706 service->setEventHandler(NULL, NULL);
708 SE_SERVICE_EXTERN_END;
711 EXTERN_API int se_service_destroy_instance(se_service_h handle)
715 SE_SERVICE_EXTERN_BEGIN;
719 SE_SERVICE_EXTERN_END;