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