887d8968bd53af35c934d8a78203f725d1ff47df
[platform/core/connectivity/smartcard-service.git] / client / Reader.cpp
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /* standard library header */
18 #include <stdio.h>
19 #include <string.h>
20 #include <unistd.h>
21
22 /* SLP library header */
23
24 /* local header */
25 #include "Debug.h"
26 #include "Reader.h"
27 #include "Session.h"
28 #include "ClientGDBus.h"
29
30 #ifndef EXTERN_API
31 #define EXTERN_API __attribute__((visibility("default")))
32 #endif
33
34 namespace smartcard_service_api
35 {
36         Reader::Reader(void *context, const char *name, void *handle) :
37                 ReaderHelper(name), context(context), handle(handle)
38         {
39                 _BEGIN();
40
41                 if (context == NULL || handle == NULL)
42                 {
43                         _ERR("invalid param");
44
45                         return;
46                 }
47
48                 /* init default context */
49                 GError *error = NULL;
50
51                 proxy = smartcard_service_reader_proxy_new_for_bus_sync(
52                         G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
53                         "org.tizen.SmartcardService",
54                         "/org/tizen/SmartcardService/Reader",
55                         NULL, &error);
56                 if (proxy == NULL)
57                 {
58                         _ERR("Can not create proxy : %s", error->message);
59                         g_error_free(error);
60                         return;
61                 }
62
63                 present = true;
64
65                 _END();
66         }
67
68         Reader::~Reader()
69         {
70                 size_t i;
71
72                 closeSessions();
73
74                 for (i = 0; i < sessions.size(); i++)
75                 {
76                         delete (Session *)sessions[i];
77                 }
78
79                 sessions.clear();
80         }
81
82         void Reader::closeSessions()
83                 throw(ErrorIO &, ErrorIllegalState &)
84         {
85                 size_t i;
86
87                 for (i = 0; i < sessions.size(); i++)
88                 {
89                         sessions[i]->closeSync();
90                 }
91         }
92
93         SessionHelper *Reader::openSessionSync()
94                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
95                         ErrorIllegalParameter &, ErrorSecurity &)
96         {
97                 Session *session = NULL;
98
99                 if (isSecureElementPresent() == true)
100                 {
101                         gint result;
102                         GError *error = NULL;
103                         guint session_id;
104
105                         if (smartcard_service_reader_call_open_session_sync(
106                                 (SmartcardServiceReader *)proxy,
107                                 GPOINTER_TO_UINT(context),
108                                 GPOINTER_TO_UINT(handle),
109                                 &result, &session_id, NULL, &error) == true) {
110                                 if (result == SCARD_ERROR_OK) {
111                                         /* create new instance of channel */
112                                         session = new Session(context, this,
113                                                 GUINT_TO_POINTER(session_id));
114                                         if (session != NULL) {
115                                                 sessions.push_back(session);
116                                         } else {
117                                                 _ERR("Session creating instance failed");
118
119                                                 THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
120                                         }
121                                 } else {
122                                         _ERR("smartcard_service_reader_call_open_session_sync failed, [%d]", result);
123
124                                         THROW_ERROR(result);
125                                 }
126                         } else {
127                                 _ERR("smartcard_service_reader_call_open_session_sync failed, [%s]", error->message);
128                                 g_error_free(error);
129
130                                 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
131                         }
132                 }
133                 else
134                 {
135                         _ERR("unavailable reader");
136                         throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
137                 }
138
139                 return session;
140         }
141
142         void Reader::reader_open_session_cb(GObject *source_object,
143                 GAsyncResult *res, gpointer user_data)
144         {
145                 CallbackParam *param = (CallbackParam *)user_data;
146                 Reader *reader;
147                 openSessionCallback callback;
148                 Session *session = NULL;
149                 gint result;
150                 guint handle;
151                 GError *error = NULL;
152
153                 _INFO("MSG_REQUEST_OPEN_SESSION");
154
155                 if (param == NULL) {
156                         _ERR("null parameter!!!");
157                         return;
158                 }
159
160                 reader = (Reader *)param->instance;
161                 callback = (openSessionCallback)param->callback;
162
163                 if (smartcard_service_reader_call_open_session_finish(
164                         SMARTCARD_SERVICE_READER(source_object),
165                         &result, &handle, res, &error) == true) {
166                         if (result == SCARD_ERROR_OK) {
167                                 /* create new instance of channel */
168                                 session = new Session(reader->context, reader,
169                                         GUINT_TO_POINTER(handle));
170                                 if (session != NULL) {
171                                         reader->sessions.push_back(session);
172                                 } else {
173                                         _ERR("Session creating instance failed");
174
175                                         result = SCARD_ERROR_OUT_OF_MEMORY;
176                                 }
177                         } else {
178                                 _ERR("smartcard_service_reader_call_open_session failed, [%d]", result);
179                         }
180                 } else {
181                         _ERR("smartcard_service_reader_call_open_session failed, [%s]", error->message);
182                         g_error_free(error);
183
184                         result = SCARD_ERROR_IPC_FAILED;
185                 }
186
187                 if (callback != NULL) {
188                         callback(session, result, param->user_param);
189                 }
190
191                 delete param;
192         }
193         int Reader::openSession(openSessionCallback callback, void *userData)
194         {
195                 int result;
196
197                 _BEGIN();
198
199                 if (isSecureElementPresent() == true)
200                 {
201                         CallbackParam *param = new CallbackParam();
202
203                         param->instance = this;
204                         param->callback = (void *)callback;
205                         param->user_param = userData;
206
207                         smartcard_service_reader_call_open_session(
208                                 (SmartcardServiceReader *)proxy,
209                                 GPOINTER_TO_UINT(context),
210                                 GPOINTER_TO_UINT(handle),
211                                 NULL, &Reader::reader_open_session_cb, param);
212
213                         result = SCARD_ERROR_OK;
214                 }
215                 else
216                 {
217                         _ERR("unavailable reader");
218                         result = SCARD_ERROR_ILLEGAL_STATE;
219                 }
220
221                 _END();
222
223                 return result;
224         }
225 } /* namespace smartcard_service_api */
226
227 /* export C API */
228 #define READER_EXTERN_BEGIN \
229         if (handle != NULL) \
230         { \
231                 Reader *reader = (Reader *)handle;
232
233 #define READER_EXTERN_END \
234         } \
235         else \
236         { \
237                 _ERR("Invalid param"); \
238         }
239
240 using namespace smartcard_service_api;
241
242 EXTERN_API int reader_get_name(reader_h handle, char** reader_name)
243 {
244         int result = SCARD_ERROR_OK;
245
246         READER_EXTERN_BEGIN;
247
248         try
249         {
250                 *reader_name = g_strdup(reader->getName());
251         }
252         catch (ExceptionBase &e)
253         {
254                 _ERR("Error occur : %s\n", e.what());
255                 result = e.getErrorCode();
256         }
257         catch (...)
258         {
259                 _ERR("Error occur : unknown error\n");
260                 result = SCARD_ERROR_UNKNOWN;
261         }
262
263         READER_EXTERN_END;
264
265         return result;
266 }
267
268 EXTERN_API  int reader_is_secure_element_present(reader_h handle, bool* is_present)
269 {
270         int result = SCARD_ERROR_OK;
271
272         READER_EXTERN_BEGIN;
273
274         try
275         {
276                 *is_present = reader->isSecureElementPresent();
277         }
278         catch (...)
279         {
280                 _ERR("Error occur : unknown error\n");
281                 result = SCARD_ERROR_UNKNOWN;
282         }
283
284         READER_EXTERN_END;
285
286         return result;
287 }
288
289 EXTERN_API int reader_open_session_sync(reader_h handle, int *session_handle)
290 {
291         session_h session;
292         int result = SCARD_ERROR_OK;
293
294         READER_EXTERN_BEGIN;
295
296         try
297         {
298                 session = (session_h)reader->openSessionSync();
299                 *session_handle = (long)session;
300         }
301         catch (ExceptionBase &e)
302         {
303                 _ERR("Error occur : %s\n", e.what());
304                 result = e.getErrorCode();
305                 *session_handle = 0;
306         }
307         catch (...)
308         {
309                 _ERR("Error occur : unknown error\n");
310                 result = SCARD_ERROR_UNKNOWN;
311                 *session_handle = 0;
312         }
313
314         READER_EXTERN_END;
315
316         return result;
317 }
318
319 EXTERN_API int reader_close_sessions(reader_h handle)
320 {
321         int result = SCARD_ERROR_OK;
322
323         READER_EXTERN_BEGIN;
324
325         try
326         {
327                 reader->closeSessions();
328         }
329         catch (ExceptionBase &e)
330         {
331                 _ERR("Error occur : %s\n", e.what());
332                 result = e.getErrorCode();
333         }
334         catch (...)
335         {
336                 _ERR("Error occur : unknown error\n");
337                 result = SCARD_ERROR_UNKNOWN;
338         }
339
340         READER_EXTERN_END;
341
342         return result;
343 }
344
345
346 EXTERN_API se_service_h reader_get_se_service(reader_h handle)
347 {
348         se_service_h service = NULL;
349
350         READER_EXTERN_BEGIN;
351         service = (se_service_h)reader->getSEService();
352         READER_EXTERN_END;
353
354         return service;
355 }
356
357 EXTERN_API int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData)
358 {
359         int result = -1;
360
361         READER_EXTERN_BEGIN;
362         result = reader->openSession((openSessionCallback)callback, userData);
363         READER_EXTERN_END;
364
365         return result;
366 }
367
368 EXTERN_API void reader_destroy_instance(reader_h handle)
369 {
370 }