tizen 2.3 release
[framework/system/smartcard-plugin-nfc.git] / NFCTerminal.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 <cstdio>
19 #include <cstring>
20 #include <unistd.h>
21 #include <sys/time.h>
22 #include <glib.h>
23
24 /* SLP library header */
25 #include "nfc.h"
26 #include "nfc_internal.h"
27
28 /* local header */
29 #include "smartcard-types.h"
30 #include "Debug.h"
31 #include "TerminalInterface.h"
32 #include "NFCTerminal.h"
33
34 #ifndef EXPORT_API
35 #define EXPORT_API __attribute__((visibility("default")))
36 #endif
37
38 #define ASYNC
39
40 using namespace smartcard_service_api;
41
42 static const char *se_name = "eSE";
43
44 /* below functions will be called when dlopen or dlclose is called */
45 void __attribute__ ((constructor)) lib_init()
46 {
47 }
48
49 void __attribute__ ((destructor)) lib_fini()
50 {
51 }
52
53 /* below three functions must be implemented */
54 extern "C"
55 {
56 EXPORT_API const char *get_name()
57 {
58         return se_name;
59 }
60
61 EXPORT_API void *create_instance()
62 {
63         return (void *)NFCTerminal::getInstance();
64 }
65
66 EXPORT_API void destroy_instance(void *instance)
67 {
68         NFCTerminal *inst = (NFCTerminal *)instance;
69
70         if (inst == NFCTerminal::getInstance())
71         {
72                 inst->finalize();
73         }
74         else
75         {
76                 _ERR("instance is invalid : getInstance [%p], instance [%p]",
77                         NFCTerminal::getInstance(), instance);
78         }
79 }
80 }
81
82 namespace smartcard_service_api
83 {
84         NFCTerminal::NFCTerminal() : Terminal(), seHandle(NULL),
85                 present(false), referred(0)
86         {
87                 name = (char *)se_name;
88
89                 initialize();
90         }
91
92         NFCTerminal *NFCTerminal::getInstance()
93         {
94                 static NFCTerminal instance;
95
96                 return &instance;
97         }
98
99         NFCTerminal::~NFCTerminal()
100         {
101                 finalize();
102         }
103
104         bool NFCTerminal::initialize()
105         {
106                 int ret;
107
108                 if (initialized == true)
109                         return initialized;
110
111                 ret = nfc_manager_initialize();
112                 if (ret == NFC_ERROR_NONE)
113                 {
114                         initialized = true;
115
116                         if (open() == true) {
117                                 present = true;
118                                 close();
119                         }
120                 }
121                 else
122                 {
123                         _ERR("net_nfc_initialize failed [%d]", ret);
124                 }
125
126                 return initialized;
127         }
128
129         void NFCTerminal::finalize()
130         {
131                 int ret;
132
133                 if (isClosed() == false) {
134                         /* close now */
135                         ret = nfc_se_close_secure_element_internal(seHandle);
136                         if (ret == NFC_ERROR_NONE) {
137                                 seHandle = NULL;
138                                 closed = true;
139                                 referred = 0;
140                         } else {
141                                 _ERR("nfc_se_close_secure_element failed [%d]", ret);
142                         }
143                 }
144
145                 ret = nfc_manager_deinitialize();
146                 if (ret == NFC_ERROR_NONE) {
147                         initialized = false;
148                 } else {
149                         _ERR("nfc_manager_deinitialize failed [%d]", ret);
150                 }
151         }
152
153         bool NFCTerminal::open()
154         {
155                 int ret;
156
157                 _BEGIN();
158
159                 if (isInitialized()) {
160                         if (referred == 0) {
161                                 ret = nfc_se_open_secure_element_internal(NFC_SE_TYPE_ESE,
162                                         &seHandle);
163                                 if (ret == NFC_ERROR_NONE) {
164                                         closed = false;
165                                         referred++;
166                                 } else {
167                                         _ERR("nfc_se_open_secure_element failed [%d]", ret);
168                                 }
169                         } else {
170                                 referred++;
171                         }
172
173                         _DBG("reference count [%d]", referred);
174                 }
175
176                 _END();
177
178                 return (isClosed() == false);
179         }
180
181         void NFCTerminal::close()
182         {
183                 int ret;
184
185                 _BEGIN();
186
187                 if (isInitialized())
188                 {
189                         if (referred <= 1) {
190                                 ret = nfc_se_close_secure_element_internal(seHandle);
191                                 if (ret == NFC_ERROR_NONE) {
192                                         seHandle = NULL;
193                                         closed = true;
194                                         referred = 0;
195                                 } else {
196                                         _ERR("nfc_se_close_secure_element failed [%d]", ret);
197                                 }
198                         } else {
199                                 referred--;
200                         }
201
202                         _DBG("reference count [%d]", referred);
203                 }
204
205                 _END();
206         }
207
208         int NFCTerminal::transmitSync(const ByteArray &command, ByteArray &response)
209         {
210                 int rv = SCARD_ERROR_NOT_INITIALIZED;
211
212                 _BEGIN();
213
214                 if (isClosed() == false)
215                 {
216                         if (command.size() > 0)
217                         {
218                                 uint8_t *resp = NULL;
219                                 uint32_t resp_len;
220
221                                 rv = nfc_se_send_apdu_internal(seHandle,
222                                         (uint8_t *)command.getBuffer(),
223                                         command.size(),
224                                         &resp,
225                                         &resp_len);
226                                 if (rv == NFC_ERROR_NONE &&
227                                         resp != NULL)
228                                 {
229                                         response.assign(resp, resp_len);
230
231                                         g_free(resp);
232                                 }
233                                 else
234                                 {
235                                         _ERR("net_nfc_send_apdu_sync failed, [%d]", rv);
236                                 }
237                         }
238                         else
239                         {
240                                 _ERR("invalid command");
241                         }
242                 }
243                 else
244                 {
245                         _ERR("closed...");
246                 }
247
248                 _END();
249
250                 return rv;
251         }
252
253         int NFCTerminal::getATRSync(ByteArray &atr)
254         {
255                 int rv = -1;
256
257                 _BEGIN();
258
259                 if (isClosed() == false)
260                 {
261                         uint8_t *temp = NULL;
262                         uint32_t temp_len;
263
264                         rv = nfc_se_get_atr_internal(seHandle, &temp, &temp_len);
265                         if (rv == NFC_ERROR_NONE &&
266                                 temp != NULL)
267                         {
268                                 atr.assign(temp, temp_len);
269
270                                 g_free(temp);
271                         }
272                         else
273                         {
274                                 _ERR("net_nfc_client_se_get_atr_sync failed");
275                         }
276                 }
277                 else
278                 {
279                         _ERR("closed...");
280                 }
281
282                 _END();
283
284                 return rv;
285         }
286 } /* namespace smartcard_service_api */