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