4382de92171c68a78f5c09778114963e933aea51
[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 "Message.h"
27 #include "ClientIPC.h"
28 #include "Reader.h"
29 #include "Session.h"
30
31 #ifndef EXTERN_API
32 #define EXTERN_API __attribute__((visibility("default")))
33 #endif
34
35 namespace smartcard_service_api
36 {
37         Reader::Reader(void *context, const char *name, void *handle) : ReaderHelper()
38         {
39                 unsigned int length = 0;
40
41                 SCARD_BEGIN();
42
43                 this->context = NULL;
44                 this->handle = NULL;
45
46                 if (context == NULL || name == NULL || strlen(name) == 0 || handle == NULL)
47                 {
48                         SCARD_DEBUG_ERR("invalid param");
49
50                         return;
51                 }
52
53                 this->handle = handle;
54                 this->context = context;
55
56                 length = strlen(name);
57                 length = (length < sizeof(this->name)) ? length : sizeof(this->name);
58                 memcpy(this->name, name, length);
59
60                 present = true;
61
62                 SCARD_END();
63         }
64
65         Reader::~Reader()
66         {
67                 size_t i;
68
69                 closeSessions();
70
71                 for (i = 0; i < sessions.size(); i++)
72                 {
73                         delete (Session *)sessions[i];
74                 }
75
76                 sessions.clear();
77         }
78
79         void Reader::closeSessions()
80                 throw(ErrorIO &, ErrorIllegalState &)
81         {
82                 size_t i;
83
84                 for (i = 0; i < sessions.size(); i++)
85                 {
86                         sessions[i]->closeSync();
87                 }
88         }
89
90         SessionHelper *Reader::openSessionSync()
91                 throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
92         {
93                 openedSession = NULL;
94
95                 if (isSecureElementPresent() == true)
96                 {
97                         Message msg;
98                         int rv;
99
100 #ifdef CLIENT_IPC_THREAD
101                         /* request channel handle from server */
102                         msg.message = Message::MSG_REQUEST_OPEN_SESSION;
103                         msg.param1 = (unsigned int)handle;
104                         msg.error = (unsigned int)context; /* using error to context */
105                         msg.caller = (void *)this;
106                         msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
107
108                         syncLock();
109                         if (ClientIPC::getInstance().sendMessage(&msg) == true)
110                         {
111                                 rv = waitTimedCondition(0);
112                                 if (rv != 0)
113                                 {
114                                         SCARD_DEBUG_ERR("time over");
115                                 }
116                         }
117                         else
118                         {
119                                 SCARD_DEBUG_ERR("sendMessage failed");
120                         }
121                         syncUnlock();
122 #endif
123                 }
124                 else
125                 {
126                         SCARD_DEBUG_ERR("unavailable reader");
127                 }
128
129                 return (Session *)openedSession;
130         }
131
132         int Reader::openSession(openSessionCallback callback, void *userData)
133         {
134                 int result = -1;
135
136                 SCARD_BEGIN();
137
138                 if (isSecureElementPresent() == true)
139                 {
140                         Message msg;
141
142                         /* request channel handle from server */
143                         msg.message = Message::MSG_REQUEST_OPEN_SESSION;
144                         msg.param1 = (unsigned int)handle;
145                         msg.error = (unsigned int)context; /* using error to context */
146                         msg.caller = (void *)this;
147                         msg.callback = (void *)callback;
148                         msg.userParam = userData;
149
150                         if (ClientIPC::getInstance().sendMessage(&msg) == true)
151                         {
152                                 result = 0;
153                         }
154                         else
155                         {
156                                 SCARD_DEBUG_ERR("sendMessage failed");
157                         }
158                 }
159                 else
160                 {
161                         SCARD_DEBUG_ERR("unavailable reader");
162                 }
163
164                 SCARD_END();
165
166                 return result;
167         }
168
169         bool Reader::dispatcherCallback(void *message)
170         {
171                 Message *msg = (Message *)message;
172                 Reader *reader = NULL;
173                 bool result = false;
174
175                 SCARD_BEGIN();
176
177                 if (msg == NULL)
178                 {
179                         SCARD_DEBUG_ERR("message is null");
180                         return result;
181                 }
182
183                 reader = (Reader *)msg->caller;
184
185                 switch (msg->message)
186                 {
187                 case Message::MSG_REQUEST_OPEN_SESSION :
188                         {
189                                 Session *session = NULL;
190
191                                 SCARD_DEBUG("MSG_REQUEST_OPEN_SESSION");
192
193                                 if (msg->param1 != 0)
194                                 {
195                                         /* create new instance of channel */
196                                         session = new Session(reader->context, reader, (void *)msg->param1);
197                                         if (session == NULL)
198                                         {
199                                                 SCARD_DEBUG_ERR("Session creating instance failed");
200
201                                                 return session;
202                                         }
203
204                                         reader->sessions.push_back(session);
205                                 }
206
207                                 if (msg->isSynchronousCall() == true) /* synchronized call */
208                                 {
209                                         /* sync call */
210                                         reader->syncLock();
211
212                                         /* copy result */
213                                         reader->error = msg->error;
214                                         reader->openedSession = session;
215                                         reader->signalCondition();
216
217                                         reader->syncUnlock();
218                                 }
219                                 else if (msg->callback != NULL)
220                                 {
221                                         openSessionCallback cb = (openSessionCallback)msg->callback;
222
223                                         /* async call */
224                                         cb(session, msg->error, msg->userParam);
225                                 }
226                         }
227                         break;
228
229                 default:
230                         SCARD_DEBUG("unknown [%s]", msg->toString());
231                         break;
232                 }
233
234                 SCARD_END();
235
236                 return result;
237         }
238
239 } /* namespace smartcard_service_api */
240
241 /* export C API */
242 #define READER_EXTERN_BEGIN \
243         if (handle != NULL) \
244         { \
245                 Reader *reader = (Reader *)handle;
246
247 #define READER_EXTERN_END \
248         } \
249         else \
250         { \
251                 SCARD_DEBUG_ERR("Invalid param"); \
252         }
253
254 using namespace smartcard_service_api;
255
256 EXTERN_API const char *reader_get_name(reader_h handle)
257 {
258         const char *name = NULL;
259
260         READER_EXTERN_BEGIN;
261         name = reader->getName();
262         READER_EXTERN_END;
263
264         return name;
265 }
266
267 EXTERN_API se_service_h reader_get_se_service(reader_h handle)
268 {
269         se_service_h service = NULL;
270
271         READER_EXTERN_BEGIN;
272         service = (se_service_h)reader->getSEService();
273         READER_EXTERN_END;
274
275         return service;
276 }
277
278 EXTERN_API bool reader_is_secure_element_present(reader_h handle)
279 {
280         bool result = false;
281
282         READER_EXTERN_BEGIN;
283         result = reader->isSecureElementPresent();
284         READER_EXTERN_END;
285
286         return result;
287 }
288
289 EXTERN_API int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData)
290 {
291         int result = -1;
292
293         READER_EXTERN_BEGIN;
294         result = reader->openSession((openSessionCallback)callback, userData);
295         READER_EXTERN_END;
296
297         return result;
298 }
299
300 EXTERN_API session_h reader_open_session_sync(reader_h handle)
301 {
302         session_h result = NULL;
303
304 #ifdef CLIENT_IPC_THREAD
305         READER_EXTERN_BEGIN;
306         result = (session_h)reader->openSessionSync();
307         READER_EXTERN_END;
308 #endif
309
310         return result;
311 }
312
313 EXTERN_API void reader_close_sessions(reader_h handle)
314 {
315         READER_EXTERN_BEGIN;
316         reader->closeSessions();
317         READER_EXTERN_END;
318 }
319
320 EXTERN_API void reader_destroy_instance(reader_h handle)
321 {
322 }