2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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 */
29 #include "ClientGDBus.h"
30 #include "smartcard-service-gdbus.h"
33 #include "ClientIPC.h"
37 #define EXTERN_API __attribute__((visibility("default")))
40 namespace smartcard_service_api
42 Reader::Reader(void *context, const char *name, void *handle) :
43 ReaderHelper(name), context(context), handle(handle)
47 if (context == NULL || name == NULL ||
48 strlen(name) == 0 || handle == NULL)
50 _ERR("invalid param");
55 /* initialize client */
56 if (!g_thread_supported())
63 /* init default context */
66 proxy = smartcard_service_reader_proxy_new_for_bus_sync(
67 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
68 "org.tizen.SmartcardService",
69 "/org/tizen/SmartcardService/Reader",
73 _ERR("Can not create proxy : %s", error->message);
89 for (i = 0; i < sessions.size(); i++)
91 delete (Session *)sessions[i];
97 void Reader::closeSessions()
98 throw(ErrorIO &, ErrorIllegalState &)
102 for (i = 0; i < sessions.size(); i++)
104 sessions[i]->closeSync();
108 SessionHelper *Reader::openSessionSync()
109 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
110 ErrorIllegalParameter &, ErrorSecurity &)
112 Session *session = NULL;
114 if (isSecureElementPresent() == true)
118 GError *error = NULL;
121 if (smartcard_service_reader_call_open_session_sync(
122 (SmartcardServiceReader *)proxy,
123 ClientGDBus::getCookie(),
124 GPOINTER_TO_UINT(context),
125 GPOINTER_TO_UINT(handle),
126 &result, &session_id, NULL, &error) == true) {
127 if (result == SCARD_ERROR_OK) {
128 /* create new instance of channel */
129 session = new Session(context, this,
130 GUINT_TO_POINTER(session_id));
131 if (session != NULL) {
132 sessions.push_back(session);
134 _ERR("Session creating instance failed");
136 THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
139 _ERR("smartcard_service_reader_call_open_session_sync failed, [%d]", result);
144 _ERR("smartcard_service_reader_call_open_session_sync failed, [%s]", error->message);
147 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
153 openedSession = NULL;
154 #ifdef CLIENT_IPC_THREAD
155 /* request channel handle from server */
156 msg.message = Message::MSG_REQUEST_OPEN_SESSION;
157 msg.param1 = (unsigned long)handle;
158 msg.error = (unsigned long)context; /* using error to context */
159 msg.caller = (void *)this;
160 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
163 if (ClientIPC::getInstance().sendMessage(msg) == true)
165 rv = waitTimedCondition(0);
169 this->error = SCARD_ERROR_OPERATION_TIMEOUT;
172 session = openedSession;
176 _ERR("sendMessage failed");
177 this->error = SCARD_ERROR_IPC_FAILED;
181 if (this->error != SCARD_ERROR_OK)
183 ThrowError::throwError(this->error);
190 _ERR("unavailable reader");
191 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
198 void Reader::reader_open_session_cb(GObject *source_object,
199 GAsyncResult *res, gpointer user_data)
201 CallbackParam *param = (CallbackParam *)user_data;
203 openSessionCallback callback;
204 Session *session = NULL;
207 GError *error = NULL;
209 _INFO("MSG_REQUEST_OPEN_SESSION");
212 _ERR("null parameter!!!");
216 reader = (Reader *)param->instance;
217 callback = (openSessionCallback)param->callback;
219 if (smartcard_service_reader_call_open_session_finish(
220 SMARTCARD_SERVICE_READER(source_object),
221 &result, &handle, res, &error) == true) {
222 if (result == SCARD_ERROR_OK) {
223 /* create new instance of channel */
224 session = new Session(reader->context, reader,
225 GUINT_TO_POINTER(handle));
226 if (session != NULL) {
227 reader->sessions.push_back(session);
229 _ERR("Session creating instance failed");
231 result = SCARD_ERROR_OUT_OF_MEMORY;
234 _ERR("smartcard_service_reader_call_open_session failed, [%d]", result);
237 _ERR("smartcard_service_reader_call_open_session failed, [%s]", error->message);
240 result = SCARD_ERROR_IPC_FAILED;
243 if (callback != NULL) {
244 callback(session, result, param->user_param);
250 int Reader::openSession(openSessionCallback callback, void *userData)
256 if (isSecureElementPresent() == true)
259 CallbackParam *param = new CallbackParam();
261 param->instance = this;
262 param->callback = (void *)callback;
263 param->user_param = userData;
265 smartcard_service_reader_call_open_session(
266 (SmartcardServiceReader *)proxy,
267 ClientGDBus::getCookie(),
268 GPOINTER_TO_UINT(context),
269 GPOINTER_TO_UINT(handle),
270 NULL, &Reader::reader_open_session_cb, param);
272 result = SCARD_ERROR_OK;
276 /* request channel handle from server */
277 msg.message = Message::MSG_REQUEST_OPEN_SESSION;
278 msg.param1 = (unsigned long)handle;
279 msg.error = (unsigned long)context; /* using error to context */
280 msg.caller = (void *)this;
281 msg.callback = (void *)callback;
282 msg.userParam = userData;
284 if (ClientIPC::getInstance().sendMessage(msg) == true)
286 result = SCARD_ERROR_OK;
290 _ERR("sendMessage failed");
291 result = SCARD_ERROR_IPC_FAILED;
297 _ERR("unavailable reader");
298 result = SCARD_ERROR_ILLEGAL_STATE;
307 bool Reader::dispatcherCallback(void *message)
309 Message *msg = (Message *)message;
317 _ERR("message is null");
321 reader = (Reader *)msg->caller;
323 switch (msg->message)
325 case Message::MSG_REQUEST_OPEN_SESSION :
327 Session *session = NULL;
329 _INFO("MSG_REQUEST_OPEN_SESSION");
331 if (msg->param1 != 0)
333 /* create new instance of channel */
334 session = new Session(reader->context, reader, (void *)msg->param1);
337 _ERR("Session creating instance failed");
342 reader->sessions.push_back(session);
345 if (msg->isSynchronousCall() == true) /* synchronized call */
351 reader->error = msg->error;
352 reader->openedSession = session;
353 reader->signalCondition();
355 reader->syncUnlock();
357 else if (msg->callback != NULL)
359 openSessionCallback cb = (openSessionCallback)msg->callback;
362 cb(session, msg->error, msg->userParam);
368 _DBG("unknown [%s]", msg->toString().c_str());
379 } /* namespace smartcard_service_api */
382 #define READER_EXTERN_BEGIN \
383 if (handle != NULL) \
385 Reader *reader = (Reader *)handle;
387 #define READER_EXTERN_END \
391 _ERR("Invalid param"); \
394 using namespace smartcard_service_api;
396 EXTERN_API const char *reader_get_name(reader_h handle)
398 const char *name = NULL;
401 name = reader->getName();
407 EXTERN_API se_service_h reader_get_se_service(reader_h handle)
409 se_service_h service = NULL;
412 service = (se_service_h)reader->getSEService();
418 EXTERN_API bool reader_is_secure_element_present(reader_h handle)
423 result = reader->isSecureElementPresent();
429 EXTERN_API int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData)
434 result = reader->openSession((openSessionCallback)callback, userData);
440 EXTERN_API session_h reader_open_session_sync(reader_h handle)
442 session_h result = NULL;
444 #ifdef CLIENT_IPC_THREAD
446 result = (session_h)reader->openSessionSync();
453 EXTERN_API void reader_close_sessions(reader_h handle)
456 reader->closeSessions();
460 EXTERN_API void reader_destroy_instance(reader_h handle)