4a8b78c5f7300621daf780675d7c046b1fe5ffe2
[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                 /* initialize client */
49                 if (!g_thread_supported())
50                 {
51                         g_thread_init(NULL);
52                 }
53
54                 g_type_init();
55
56                 /* init default context */
57                 GError *error = NULL;
58
59                 proxy = smartcard_service_reader_proxy_new_for_bus_sync(
60                         G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
61                         "org.tizen.SmartcardService",
62                         "/org/tizen/SmartcardService/Reader",
63                         NULL, &error);
64                 if (proxy == NULL)
65                 {
66                         _ERR("Can not create proxy : %s", error->message);
67                         g_error_free(error);
68                         return;
69                 }
70
71                 present = true;
72
73                 _END();
74         }
75
76         Reader::~Reader()
77         {
78                 size_t i;
79
80                 closeSessions();
81
82                 for (i = 0; i < sessions.size(); i++)
83                 {
84                         delete (Session *)sessions[i];
85                 }
86
87                 sessions.clear();
88         }
89
90         void Reader::closeSessions()
91                 throw(ErrorIO &, ErrorIllegalState &)
92         {
93                 size_t i;
94
95                 for (i = 0; i < sessions.size(); i++)
96                 {
97                         sessions[i]->closeSync();
98                 }
99         }
100
101         SessionHelper *Reader::openSessionSync()
102                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
103                         ErrorIllegalParameter &, ErrorSecurity &)
104         {
105                 Session *session = NULL;
106
107                 if (isSecureElementPresent() == true)
108                 {
109                         gint result;
110                         GError *error = NULL;
111                         guint session_id;
112
113                         if (smartcard_service_reader_call_open_session_sync(
114                                 (SmartcardServiceReader *)proxy,
115                                 GPOINTER_TO_UINT(context),
116                                 GPOINTER_TO_UINT(handle),
117                                 &result, &session_id, NULL, &error) == true) {
118                                 if (result == SCARD_ERROR_OK) {
119                                         /* create new instance of channel */
120                                         session = new Session(context, this,
121                                                 GUINT_TO_POINTER(session_id));
122                                         if (session != NULL) {
123                                                 sessions.push_back(session);
124                                         } else {
125                                                 _ERR("Session creating instance failed");
126
127                                                 THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
128                                         }
129                                 } else {
130                                         _ERR("smartcard_service_reader_call_open_session_sync failed, [%d]", result);
131
132                                         THROW_ERROR(result);
133                                 }
134                         } else {
135                                 _ERR("smartcard_service_reader_call_open_session_sync failed, [%s]", error->message);
136                                 g_error_free(error);
137
138                                 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
139                         }
140                 }
141                 else
142                 {
143                         _ERR("unavailable reader");
144                         throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
145                 }
146
147                 return session;
148         }
149
150         void Reader::reader_open_session_cb(GObject *source_object,
151                 GAsyncResult *res, gpointer user_data)
152         {
153                 CallbackParam *param = (CallbackParam *)user_data;
154                 Reader *reader;
155                 openSessionCallback callback;
156                 Session *session = NULL;
157                 gint result;
158                 guint handle;
159                 GError *error = NULL;
160
161                 _INFO("MSG_REQUEST_OPEN_SESSION");
162
163                 if (param == NULL) {
164                         _ERR("null parameter!!!");
165                         return;
166                 }
167
168                 reader = (Reader *)param->instance;
169                 callback = (openSessionCallback)param->callback;
170
171                 if (smartcard_service_reader_call_open_session_finish(
172                         SMARTCARD_SERVICE_READER(source_object),
173                         &result, &handle, res, &error) == true) {
174                         if (result == SCARD_ERROR_OK) {
175                                 /* create new instance of channel */
176                                 session = new Session(reader->context, reader,
177                                         GUINT_TO_POINTER(handle));
178                                 if (session != NULL) {
179                                         reader->sessions.push_back(session);
180                                 } else {
181                                         _ERR("Session creating instance failed");
182
183                                         result = SCARD_ERROR_OUT_OF_MEMORY;
184                                 }
185                         } else {
186                                 _ERR("smartcard_service_reader_call_open_session failed, [%d]", result);
187                         }
188                 } else {
189                         _ERR("smartcard_service_reader_call_open_session failed, [%s]", error->message);
190                         g_error_free(error);
191
192                         result = SCARD_ERROR_IPC_FAILED;
193                 }
194
195                 if (callback != NULL) {
196                         callback(session, result, param->user_param);
197                 }
198
199                 delete param;
200         }
201         int Reader::openSession(openSessionCallback callback, void *userData)
202         {
203                 int result;
204
205                 _BEGIN();
206
207                 if (isSecureElementPresent() == true)
208                 {
209                         CallbackParam *param = new CallbackParam();
210
211                         param->instance = this;
212                         param->callback = (void *)callback;
213                         param->user_param = userData;
214
215                         smartcard_service_reader_call_open_session(
216                                 (SmartcardServiceReader *)proxy,
217                                 GPOINTER_TO_UINT(context),
218                                 GPOINTER_TO_UINT(handle),
219                                 NULL, &Reader::reader_open_session_cb, param);
220
221                         result = SCARD_ERROR_OK;
222                 }
223                 else
224                 {
225                         _ERR("unavailable reader");
226                         result = SCARD_ERROR_ILLEGAL_STATE;
227                 }
228
229                 _END();
230
231                 return result;
232         }
233 } /* namespace smartcard_service_api */
234
235 /* export C API */
236 #define READER_EXTERN_BEGIN \
237         if (handle != NULL) \
238         { \
239                 Reader *reader = (Reader *)handle;
240
241 #define READER_EXTERN_END \
242         } \
243         else \
244         { \
245                 _ERR("Invalid param"); \
246         }
247
248 using namespace smartcard_service_api;
249
250 EXTERN_API const char *reader_get_name(reader_h handle)
251 {
252         const char *name = NULL;
253
254         READER_EXTERN_BEGIN;
255         name = reader->getName();
256         READER_EXTERN_END;
257
258         return name;
259 }
260
261 EXTERN_API se_service_h reader_get_se_service(reader_h handle)
262 {
263         se_service_h service = NULL;
264
265         READER_EXTERN_BEGIN;
266         service = (se_service_h)reader->getSEService();
267         READER_EXTERN_END;
268
269         return service;
270 }
271
272 EXTERN_API bool reader_is_secure_element_present(reader_h handle)
273 {
274         bool result = false;
275
276         READER_EXTERN_BEGIN;
277         result = reader->isSecureElementPresent();
278         READER_EXTERN_END;
279
280         return result;
281 }
282
283 EXTERN_API int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData)
284 {
285         int result = -1;
286
287         READER_EXTERN_BEGIN;
288         result = reader->openSession((openSessionCallback)callback, userData);
289         READER_EXTERN_END;
290
291         return result;
292 }
293
294 EXTERN_API session_h reader_open_session_sync(reader_h handle)
295 {
296         session_h result = NULL;
297
298         READER_EXTERN_BEGIN;
299         result = (session_h)reader->openSessionSync();
300         READER_EXTERN_END;
301
302         return result;
303 }
304
305 EXTERN_API void reader_close_sessions(reader_h handle)
306 {
307         READER_EXTERN_BEGIN;
308         reader->closeSessions();
309         READER_EXTERN_END;
310 }
311
312 EXTERN_API void reader_destroy_instance(reader_h handle)
313 {
314 }