2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <sys/types.h>
23 #include "smartcard-types.h"
25 #include "TerminalInterface.h"
26 #include "USBTerminal.h"
29 #define EXPORT_API __attribute__((visibility("default")))
32 typedef struct _callback_param_t
39 using namespace smartcard_service_api;
41 static const char *se_name = "USB0";
43 void __attribute__ ((constructor)) lib_init()
47 void __attribute__ ((destructor)) lib_fini()
51 /* below three functions must be implemented */
52 extern "C" EXPORT_API const char *get_name()
57 extern "C" EXPORT_API void *create_instance()
59 return (void *)USBTerminal::getInstance();
62 extern "C" EXPORT_API void destroy_instance(void *instance)
64 USBTerminal *inst = (USBTerminal *)instance;
65 if (inst == USBTerminal::getInstance())
71 _ERR("instance is invalid : getInstance [%p], instance [%p]",
72 USBTerminal::getInstance(), instance);
76 namespace smartcard_service_api
78 USBTerminal::USBTerminal() : Terminal()
80 name = (char *)se_name;
81 cardConnected = false;
82 readerConnected = false;
83 readerStates[0].szReader = "\\\\?PnP?\\Notification"; // name of the card reader to monitor
84 readerStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
85 readerStates[0].dwEventState = SCARD_STATE_UNKNOWN;
90 USBTerminal::~USBTerminal()
95 USBTerminal *USBTerminal::getInstance()
97 static USBTerminal instance;
102 bool USBTerminal::initialize()
106 if (initialized == false)
108 LONG rv = SCARD_S_SUCCESS;
109 LPSTR readerName = NULL;
112 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &mainContext);
113 if (rv != SCARD_S_SUCCESS)
115 _ERR("SCardEstablishContext failed : %s", pcsc_stringify_error(rv));
120 readerLen = SCARD_AUTOALLOCATE;
121 rv = SCardListReaders(mainContext, NULL, (LPSTR)&readerName, &readerLen);
122 if (rv == SCARD_S_SUCCESS)
124 _INFO("Reader Connected : %s", readerName);
125 readerStates[1].szReader = readerName;
126 readerStates[1].dwCurrentState = SCARD_STATE_UNAWARE;
127 readerStates[1].dwEventState = SCARD_STATE_UNKNOWN;
129 readerConnected = true;
132 monitorEventsThreadId = pthread_create(&monitorEventsThread, NULL, USBTerminal::monitorEvents, NULL);
134 if (monitorEventsThreadId >= 0)
140 _ERR("initialize failed");
149 void USBTerminal::finalize()
156 SCardCancel(monitorEventsThreadContext);
157 pthread_join(monitorEventsThread, NULL);
159 if (readerStates[1].szReader != NULL)
160 free((void *)readerStates[1].szReader);
166 bool USBTerminal::open()
170 _INFO("Nothing to do for open operation");
177 void USBTerminal::close()
181 _INFO("Nothing to do for close operation");
186 int USBTerminal::transmitSync(const ByteArray &command,
189 int result = SCARD_ERROR_OK;
193 if (cardConnected == true)
195 if (command.size() > 0)
197 LONG rv = SCARD_S_SUCCESS;
198 const uint8_t *send = command.getBuffer();
199 unsigned int send_len = command.size();
200 uint8_t resp[MAX_BUFFER_SIZE] = {0,};
201 uint32_t resp_len = MAX_BUFFER_SIZE;
202 SCARD_IO_REQUEST pioRecvPci;
204 _INFO("Sending: %s", command.toString().c_str());
206 rv = SCardTransmit(cardHandle, activeProtocol, send, send_len,
207 &pioRecvPci, resp, (LPDWORD)&resp_len);
208 if (rv == SCARD_S_SUCCESS)
210 response.assign(resp, resp_len);
211 _INFO("Received: %s", response.toString().c_str());
215 _ERR("SCardTransmit failed, [%s]", pcsc_stringify_error(rv));
217 result = SCARD_ERROR_IO_FAILED;
222 _ERR("apdu is empty");
224 result = SCARD_ERROR_ILLEGAL_PARAM;
229 _ERR("Card is not connected");
231 result = SCARD_ERROR_SE_NOT_INITIALIZED;
239 int USBTerminal::getATRSync(ByteArray &atr)
241 int result = SCARD_ERROR_OK;
245 if (cardConnected == true)
251 _ERR("Card is not connected");
253 result = SCARD_ERROR_SE_NOT_INITIALIZED;
261 int USBTerminal::transmit(const ByteArray &command, terminalTransmitCallback callback, void *userData)
263 _INFO("transmit Async function is not supported");
265 return SCARD_ERROR_NOT_SUPPORTED;
268 int USBTerminal::getATR(terminalGetATRCallback callback, void *userData)
270 _INFO("Get ATR Async function is not supported");
272 return SCARD_ERROR_NOT_SUPPORTED;
275 bool USBTerminal::isSecureElementPresence() const
279 _INFO("isReaderConnected : %d", isReaderConnected());
283 return isReaderConnected();
286 gboolean USBTerminal::cardConnect(gpointer user_data)
291 USBTerminal *mTerminal = USBTerminal::getInstance();
293 char pbReader[MAX_READERNAME] = "";
294 BYTE pbAtr[MAX_ATR_SIZE] = "";
295 DWORD dwActiveProtocol, dwReaderLen, dwState, dwProt, dwAtrLen;
296 pthread_mutex_t *eventMutex = (pthread_mutex_t *)user_data;
297 const char *readerName = mTerminal->readerStates[1].szReader;
299 if (eventMutex == NULL)
301 _INFO("eventMutex is NULL");
305 pthread_mutex_lock(eventMutex);
307 if (mTerminal->isReaderConnected() != true || readerName == NULL)
309 _INFO("Reader is not connected");
310 pthread_mutex_unlock(eventMutex);
315 dwActiveProtocol = -1;
316 rv = SCardConnect(mTerminal->getMainContext(), readerName, SCARD_SHARE_SHARED,
317 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
318 if (rv != SCARD_S_SUCCESS)
320 _INFO("SCardConnect failed : %s", pcsc_stringify_error(rv));
321 pthread_mutex_unlock(eventMutex);
325 _INFO("Card Inserted");
326 mTerminal->setCardConnected(true);
327 mTerminal->setCardHandle(hCard);
329 _INFO(" Protocol: %ld\n", dwActiveProtocol);
330 switch(dwActiveProtocol)
332 case SCARD_PROTOCOL_T0:
333 mTerminal->setActiveProtocol(SCARD_PCI_T0);
335 case SCARD_PROTOCOL_T1:
336 mTerminal->setActiveProtocol(SCARD_PCI_T1);
339 _INFO("Unknown protocol. set default protocol");
340 mTerminal->setActiveProtocol(SCARD_PCI_T1);
343 dwAtrLen = sizeof(pbAtr);
344 dwReaderLen = sizeof(pbReader);
345 rv = SCardStatus(hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
347 if (rv != SCARD_S_SUCCESS)
349 _INFO("SCardStatus failed : %s", pcsc_stringify_error(rv));
350 pthread_mutex_unlock(eventMutex);
354 _INFO(" Reader: %s (length %ld bytes)", pbReader, dwReaderLen);
355 _INFO(" State: 0x%lX", dwState);
356 _INFO(" Prot: %ld", dwProt);
357 _INFO(" ATR (length %ld bytes):", dwAtrLen);
359 ByteArray atrArray(pbAtr, dwAtrLen);
360 _INFO(" %s", atrArray.toString().c_str());
361 mTerminal->setCurrentAtr(atrArray);
363 pthread_mutex_unlock(eventMutex);
365 if (mTerminal->statusCallback != NULL)
366 mTerminal->statusCallback(mTerminal->getName(), NOTIFY_CARD_AVAILABLE, SCARD_ERROR_OK, NULL);
373 gboolean USBTerminal::cardDisconnect(gpointer user_data)
377 USBTerminal *mTerminal = USBTerminal::getInstance();
378 pthread_mutex_t *eventMutex = (pthread_mutex_t *)user_data;
380 _INFO("Card Removed");
382 pthread_mutex_lock(eventMutex);
384 mTerminal->setCardConnected(false);
386 pthread_mutex_unlock(eventMutex);
388 if (mTerminal->statusCallback != NULL)
389 mTerminal->statusCallback(mTerminal->getName(), NOTIFY_CARD_NOT_AVAILABLE, SCARD_ERROR_OK, NULL);
396 int USBTerminal::resetReaderStates(SCARDCONTEXT hContext)
400 LPSTR readerName = NULL;
403 USBTerminal *mTerminal = USBTerminal::getInstance();
407 readerLen = SCARD_AUTOALLOCATE;
408 rv = SCardListReaders(hContext, NULL, (LPSTR)&readerName, &readerLen);
409 if (rv == SCARD_S_SUCCESS)
411 _INFO("[Monitor] Reader Connected : %s", readerName);
413 if (mTerminal->readerStates[1].szReader != NULL)
414 free((void *)mTerminal->readerStates[1].szReader);
416 mTerminal->readerStates[1].szReader = readerName;
417 mTerminal->readerStates[1].dwCurrentState = SCARD_STATE_UNAWARE;
418 mTerminal->readerStates[1].dwEventState = SCARD_STATE_UNKNOWN;
420 mTerminal->setReaderConnected(true);
423 if (mTerminal->statusCallback != NULL)
424 mTerminal->statusCallback(mTerminal->getName(), NOTIFY_SE_AVAILABLE, SCARD_ERROR_OK, NULL);
428 _INFO("[Monitor] Reader Removed");
429 mTerminal->setReaderConnected(false);
432 if (mTerminal->statusCallback != NULL)
433 mTerminal->statusCallback(mTerminal->getName(), NOTIFY_SE_NOT_AVAILABLE, SCARD_ERROR_OK, NULL);
441 void *USBTerminal::monitorEvents(void *data)
444 DWORD readerCounts = 1;
445 pthread_mutex_t eventMutex;
447 SCARDCONTEXT hContext;
448 USBTerminal *mTerminal = USBTerminal::getInstance();
450 pthread_mutex_init(&eventMutex, NULL);
454 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
455 if (rv != SCARD_S_SUCCESS)
457 _ERR("[Monitor] SCardEstablishContext failed : %s", pcsc_stringify_error(rv));
461 mTerminal->setMonitorEventsThreadContext(hContext);
463 if (mTerminal->isReaderConnected())
466 while (mTerminal->isInitialized())
468 rv = SCardGetStatusChange(hContext, INFINITE, mTerminal->readerStates, readerCounts);
469 if (rv != SCARD_S_SUCCESS)
471 _INFO("[Monitor] SCardGetStatusChange error : %s", pcsc_stringify_error(rv));
475 pthread_mutex_lock(&eventMutex);
477 if (mTerminal->readerStates[0].dwEventState & SCARD_STATE_CHANGED)
479 _INFO("[Monitor] reader state changed");
480 readerCounts = USBTerminal::resetReaderStates(hContext);
483 if (mTerminal->isReaderConnected())
485 if ((mTerminal->readerStates[1].dwEventState & SCARD_STATE_EMPTY) == SCARD_STATE_EMPTY)
487 _INFO("[Monitor] Card Removed");
488 g_idle_add(&USBTerminal::cardDisconnect, &eventMutex);
490 else if ((mTerminal->readerStates[1].dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT)
492 _INFO("[Monitor] Card Inserted");
493 g_idle_add(&USBTerminal::cardConnect, &eventMutex);
496 mTerminal->readerStates[1].dwCurrentState = mTerminal->readerStates[1].dwEventState;
499 pthread_mutex_unlock(&eventMutex);
502 rv = SCardReleaseContext(hContext);
503 if (rv != SCARD_S_SUCCESS)
504 _ERR("[Monitor] SCardReleaseContext failed : %s", pcsc_stringify_error(rv));
510 } /* namespace smartcard_service_api */