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"
29 #include "ClientGDBus.h"
32 #define EXTERN_API __attribute__((visibility("default")))
35 #define SHUTDOWN_DELAY 500000 /* us */
37 namespace smartcard_service_api
39 SEService::SEService() : SEServiceHelper(),
40 handle(-1), context(NULL), handler(NULL), listener(NULL)
45 SEService::SEService(void *user_data, serviceConnected handler)
46 throw(ErrorIO &, ErrorIllegalParameter &) :
47 SEServiceHelper(), handle(-1),
50 initialize(user_data, handler);
53 SEService::SEService(void *user_data, SEServiceListener *listener)
54 throw(ErrorIO &, ErrorIllegalParameter &) :
55 SEServiceHelper(), handle(-1),
58 initialize(user_data, listener);
61 SEService::~SEService()
69 catch(ExceptionBase &e)
71 _ERR("EXCEPTION : %s", e.what());
78 for (i = 0; i < readers.size(); i++)
80 delete (Reader *)readers[i];
85 SEService *SEService::createInstance(void *user_data,
86 SEServiceListener *listener)
87 throw(ErrorIO &, ErrorIllegalParameter &)
89 return new SEService(user_data, listener);
92 SEService *SEService::createInstance(void *user_data,
93 serviceConnected handler)
94 throw(ErrorIO &, ErrorIllegalParameter &)
96 return new SEService(user_data, handler);
99 void SEService::reader_inserted(GObject *source_object,
100 guint reader_id, gchar *reader_name, gpointer user_data)
102 Reader *reader = NULL;
103 SEService *service = (SEService *)user_data;
105 _INFO("[MSG_NOTIFY_SE_INSERTED]");
108 reader = new Reader(service->context,
109 reader_name, GUINT_TO_POINTER(reader_id));
112 service->readers.push_back(reader);
116 _ERR("alloc failed");
119 if (service->listener != NULL)
121 service->listener->eventHandler(service,
122 reader_name, 1, service->context);
126 _DBG("listener is null");
130 void SEService::reader_removed(GObject *source_object,
131 guint reader_id, gchar *reader_name, gpointer user_data)
133 SEService *service = (SEService *)user_data;
136 _INFO("[MSG_NOTIFY_SE_REMOVED]");
138 for (i = 0; i < service->readers.size(); i++)
140 if (((Reader *)service->readers[i])->handle ==
141 GUINT_TO_POINTER(reader_id))
143 ((Reader *)service->readers[i])->unavailable();
148 if (service->listener != NULL)
150 service->listener->eventHandler(service,
151 reader_name, 2, service->context);
155 _DBG("listener is null");
159 void SEService::se_service_shutdown_cb(GObject *source_object,
160 GAsyncResult *res, gpointer user_data)
162 SEService *service = (SEService *)user_data;
164 GError *error = NULL;
166 if (smartcard_service_se_service_call_shutdown_finish(
167 SMARTCARD_SERVICE_SE_SERVICE(source_object),
168 &result, res, &error) == true) {
169 if (result == SCARD_ERROR_OK) {
170 service->connected = false;
172 _ERR("smartcard_service_se_service_call_shutdown failed, [%d]", result);
175 _ERR("smartcard_service_se_service_call_shutdown failed, [%s]", error->message);
180 void SEService::se_service_cb(GObject *source_object,
181 GAsyncResult *res, gpointer user_data)
183 SEService *service = (SEService *)user_data;
186 GVariant *readers = NULL;
187 GError *error = NULL;
189 if (service == NULL) {
190 _ERR("null parameter!!!");
194 if (smartcard_service_se_service_call_se_service_finish(
195 SMARTCARD_SERVICE_SE_SERVICE(source_object),
196 &result, &handle, &readers, res, &error) == true) {
197 if (result == SCARD_ERROR_OK) {
198 service->connected = true;
199 service->handle = handle;
200 service->parseReaderInformation(readers);
203 _ERR("smartcard_service_se_service_call_se_service failed, [%s]", error->message);
206 result = SCARD_ERROR_IPC_FAILED;
209 if (service->handler != NULL) {
210 service->handler(service, service->context);
211 } else if (service->listener != NULL) {
212 if (result == SCARD_ERROR_OK) {
213 service->listener->serviceConnected(service, service->context);
215 service->listener->errorHandler(service, result, service->context);
220 void SEService::shutdown()
225 void SEService::shutdownSync()
227 if (connected == true)
231 for (i = 0; i < readers.size(); i++)
233 readers[i]->closeSessions();
237 GError *error = NULL;
239 if (smartcard_service_se_service_call_shutdown_sync(
240 (SmartcardServiceSeService *)proxy,
245 _ERR("smartcard_service_se_service_call_shutdown_sync failed, [%s]", error->message);
250 /* wait at least 500ms */
251 usleep(SHUTDOWN_DELAY);
257 bool SEService::_initialize() throw(ErrorIO &)
263 /* init default context */
264 GError *error = NULL;
266 proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
267 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
268 "org.tizen.SmartcardService",
269 "/org/tizen/SmartcardService/SeService",
273 _ERR("Can not create proxy : %s", error->message);
278 g_signal_connect(proxy, "reader-inserted",
279 G_CALLBACK(&SEService::reader_inserted), this);
281 g_signal_connect(proxy, "reader-removed",
282 G_CALLBACK(&SEService::reader_removed), this);
285 smartcard_service_se_service_call_se_service(
286 (SmartcardServiceSeService *)proxy,
288 &SEService::se_service_cb,
296 bool SEService::initialize(void *context, serviceConnected handler)
297 throw(ErrorIO &, ErrorIllegalParameter &)
301 throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
304 this->context = context;
305 this->handler = handler;
307 return _initialize();
310 bool SEService::initialize(void *context, SEServiceListener *listener)
311 throw(ErrorIO &, ErrorIllegalParameter &)
315 throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
318 this->context = context;
319 this->listener = listener;
321 return _initialize();
324 bool SEService::parseReaderInformation(GVariant *variant)
326 Reader *reader = NULL;
333 g_variant_get(variant, "a(us)", &iter);
335 count = g_variant_iter_n_children(iter);
336 while (g_variant_iter_loop(iter, "(us)", &handle, &name) == true)
339 reader = new Reader((void *)this->handle, name, GUINT_TO_POINTER(handle));
342 _ERR("alloc failed");
346 readers.push_back(reader);
349 g_variant_iter_free(iter);
354 bool SEService::parseReaderInformation(unsigned int count,
355 const ByteArray &data)
358 unsigned int offset = 0;
359 unsigned int len = 0;
361 Reader *reader = NULL;
364 for (i = 0; i < count && offset < data.size(); i++)
366 memset(name, 0, sizeof(name));
368 memcpy(&len, data.getBuffer(offset), sizeof(len));
369 offset += sizeof(len);
371 memcpy(name, data.getBuffer(offset), len);
374 memcpy(&handle, data.getBuffer(offset), sizeof(handle));
375 offset += sizeof(handle);
378 reader = new Reader(context, name, handle);
381 _ERR("alloc failed");
385 readers.push_back(reader);
390 } /* namespace smartcard_service_api */
393 #define SE_SERVICE_EXTERN_BEGIN \
394 if (handle != NULL) \
396 SEService *service = (SEService *)handle;
398 #define SE_SERVICE_EXTERN_END \
402 _ERR("Invalid param"); \
405 using namespace smartcard_service_api;
407 EXTERN_API se_service_h se_service_create_instance(void *user_data, se_service_connected_cb callback)
413 service = new SEService(user_data, (serviceConnected)callback);
420 return (se_service_h)service;
423 EXTERN_API se_service_h se_service_create_instance_with_event_callback(void *user_data,
424 se_service_connected_cb connected, se_service_event_cb event, se_sesrvice_error_cb error)
430 service = new SEService(user_data, (serviceConnected)connected);
437 return (se_service_h)service;
440 EXTERN_API int se_service_get_readers_count(se_service_h handle)
444 SE_SERVICE_EXTERN_BEGIN;
446 vector<ReaderHelper *> temp_readers;
448 temp_readers = service->getReaders();
449 count = temp_readers.size();
451 SE_SERVICE_EXTERN_END;
456 EXTERN_API bool se_service_get_readers(se_service_h handle, reader_h *readers, int *count)
460 SE_SERVICE_EXTERN_BEGIN;
462 vector<ReaderHelper *> temp_readers;
466 temp_readers = service->getReaders();
468 for (i = 0; i < temp_readers.size() && i < (size_t)*count; i++)
470 if (temp_readers[i]->isSecureElementPresent())
472 readers[i] = (reader_h)temp_readers[i];
478 SE_SERVICE_EXTERN_END;
483 EXTERN_API bool se_service_is_connected(se_service_h handle)
487 SE_SERVICE_EXTERN_BEGIN;
489 result = service->isConnected();
491 SE_SERVICE_EXTERN_END;
496 EXTERN_API void se_service_shutdown(se_service_h handle)
498 SE_SERVICE_EXTERN_BEGIN;
500 service->shutdownSync();
502 SE_SERVICE_EXTERN_END;
505 EXTERN_API void se_service_destroy_instance(se_service_h handle)
507 SE_SERVICE_EXTERN_BEGIN;
511 SE_SERVICE_EXTERN_END;