2 * Copyright (c) 2012, 2013 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.
17 /* standard library header */
23 /* SLP library header */
27 #include "TerminalInterface.h"
28 #include "UICCTerminal.h"
31 #define EXPORT_API __attribute__((visibility("default")))
34 typedef struct _callback_param_t
41 using namespace smartcard_service_api;
43 static const char *se_name = "SIM1";
45 /* below functions will be called when dlopen or dlclose is called */
46 void __attribute__ ((constructor)) lib_init()
50 void __attribute__ ((destructor)) lib_fini()
54 /* below trhee functions must be implemented */
55 extern "C" EXPORT_API const char *get_name()
60 extern "C" EXPORT_API void *create_instance()
62 return (void *)UICCTerminal::getInstance();
65 extern "C" EXPORT_API void destroy_instance(void *instance)
67 UICCTerminal *inst = (UICCTerminal *)instance;
68 if (inst == UICCTerminal::getInstance())
74 SCARD_DEBUG_ERR("instance is invalid : getInstance [%p], instance [%p]", UICCTerminal::getInstance(), instance);
78 static void _uiccTransmitCallback(TapiHandle *handle, int result, void *data, void *user_data)
80 TelSimAccessResult_t access_rt = (TelSimAccessResult_t)result;
81 TelSimApduResp_t *apdu = (TelSimApduResp_t *)data;
82 callback_param_t *param = (callback_param_t *)user_data;
84 SCARD_DEBUG("APDU response");
88 if (param->callback != NULL)
90 terminalTransmitCallback callback = (terminalTransmitCallback)param->callback;
92 if (apdu != NULL && apdu->apdu_resp_len > 0)
94 callback(apdu->apdu_resp, apdu->apdu_resp_len, access_rt, param->param);
98 callback(NULL, 0, access_rt, param->param);
103 SCARD_DEBUG("there is no callback");
110 SCARD_DEBUG_ERR("invalid param");
114 static void _uiccGetATRCallback(TapiHandle *handle, int result, void *data, void *user_data)
116 TelSimAccessResult_t access_rt = (TelSimAccessResult_t)result;
117 TelSimAtrResp_t *atr = (TelSimAtrResp_t *)data;
118 callback_param_t *param = (callback_param_t *)user_data;
120 SCARD_DEBUG("APDU response");
124 if (param->callback != NULL)
126 terminalGetATRCallback callback = (terminalGetATRCallback)param->callback;
128 if (atr != NULL && atr->atr_resp_len > 0)
130 callback(atr->atr_resp, atr->atr_resp_len, access_rt, param->param);
134 callback(NULL, 0, access_rt, param->param);
139 SCARD_DEBUG("there is no callback");
146 SCARD_DEBUG_ERR("invalid param");
150 namespace smartcard_service_api
152 UICCTerminal::UICCTerminal()
154 name = (char *)se_name;
158 UICCTerminal::~UICCTerminal()
163 UICCTerminal *UICCTerminal::getInstance()
165 static UICCTerminal instance;
170 bool UICCTerminal::initialize()
174 if (initialized == false)
176 char **cpList = NULL;
178 // cpList = tel_get_cp_name_list();
180 handle = tel_init(NULL);
185 error = tel_register_noti_event(handle, TAPI_NOTI_SIM_STATUS, &UICCTerminal::uiccStatusNotiCallback, this);
191 SCARD_DEBUG_ERR("tel_init failed");
200 void UICCTerminal::finalize()
206 tel_deregister_noti_event(handle, TAPI_NOTI_SIM_STATUS);
216 int UICCTerminal::transmitSync(ByteArray command, ByteArray &response)
224 if (command.getLength() > 0)
226 TelSimApdu_t apdu_data = { 0, };
228 apdu_data.apdu = command.getBuffer();
229 apdu_data.apdu_len = command.getLength();
233 result = tel_req_sim_apdu(handle, &apdu_data, &UICCTerminal::uiccTransmitAPDUCallback, this);
236 SCARD_DEBUG("tel_req_sim_apdu request is success");
239 this->response.releaseBuffer();
241 result = waitTimedCondition(3);
244 if (result == 0 && error == 0)
246 if (this->response.getLength() > 0)
248 response = this->response;
251 SCARD_DEBUG("tel_req_sim_apdu success, length [%d]", response.getLength());
255 SCARD_DEBUG_ERR("tel_req_sim_apdu failed, result [%d], cbResult [%d]", result, error);
260 SCARD_DEBUG_ERR("tel_req_sim_apdu failed [%d]", result);
267 SCARD_DEBUG_ERR("apdu is empty");
276 int UICCTerminal::getATRSync(ByteArray &atr)
286 result = tel_req_sim_atr(handle, &UICCTerminal::uiccGetAtrCallback, this);
289 SCARD_DEBUG("tel_req_sim_atr request is success");
292 this->response.releaseBuffer();
294 result = waitTimedCondition(3);
296 if (result == 0 && error == 0)
298 if (this->response.getLength() > 0)
300 atr = this->response;
303 SCARD_DEBUG("tel_req_sim_atr success, length [%d]", response.getLength());
307 SCARD_DEBUG_ERR("tel_req_sim_atr failed, result [%d], cbResult [%d]", result, error);
312 SCARD_DEBUG_ERR("tel_req_sim_atr failed [%d]", result);
323 int UICCTerminal::transmit(ByteArray command, terminalTransmitCallback callback, void *userParam)
331 if (command.getLength() > 0)
333 TelSimApdu_t apdu_data = { 0, };
334 callback_param_t *param = NULL;
336 apdu_data.apdu = command.getBuffer();
337 apdu_data.apdu_len = command.getLength();
339 param = new callback_param_t();
340 param->callback = (void *)callback;
341 param->param = userParam;
343 result = tel_req_sim_apdu(handle, &apdu_data, _uiccTransmitCallback, param);
346 SCARD_DEBUG("tel_req_sim_apdu request is success");
350 SCARD_DEBUG_ERR("tel_req_sim_apdu failed [%d]", result);
355 SCARD_DEBUG_ERR("apdu is empty");
364 int UICCTerminal::getATR(terminalGetATRCallback callback, void *userParam)
372 callback_param_t *param = NULL;
374 param = new callback_param_t();
375 param->callback = (void *)callback;
376 param->param = userParam;
378 result = tel_req_sim_atr(handle, _uiccGetATRCallback, param);
381 SCARD_DEBUG("tel_req_sim_atr request is success");
385 SCARD_DEBUG_ERR("tel_req_sim_atr failed [%d]", result);
394 bool UICCTerminal::isSecureElementPresence()
398 TelSimCardStatus_t state = (TelSimCardStatus_t)0;
403 error = tel_get_sim_init_info(handle, &state, &cardChanged);
405 SCARD_DEBUG("current sim init state = [%d], error [%d], cardChanged [%d]", state, error, cardChanged);
409 if (state == TAPI_SIM_STATUS_SIM_INIT_COMPLETED || state == TAPI_SIM_STATUS_SIM_INITIALIZING)
411 SCARD_DEBUG("sim is initialized");
417 SCARD_DEBUG_ERR("sim is not initialized");
422 SCARD_DEBUG_ERR("error = [%d]", error);
430 void UICCTerminal::uiccTransmitAPDUCallback(TapiHandle *handle, int result, void *data, void *user_data)
432 UICCTerminal *instance = (UICCTerminal *)user_data;
433 TelSimAccessResult_t access_rt = (TelSimAccessResult_t)result;
434 TelSimApduResp_t *apdu = (TelSimApduResp_t *)data;
436 SCARD_DEBUG("APDU response");
438 instance->syncLock();
440 instance->error = access_rt;
442 if (instance->error == 0)
444 if (apdu != NULL && apdu->apdu_resp_len > 0)
446 instance->response.setBuffer(apdu->apdu_resp, apdu->apdu_resp_len);
449 SCARD_DEBUG("response : %s", instance->response.toString());
453 SCARD_DEBUG_ERR("error : event->Status == [%d]", access_rt);
456 instance->signalCondition();
457 instance->syncUnlock();
460 void UICCTerminal::uiccGetAtrCallback(TapiHandle *handle, int result, void *data, void *user_data)
462 UICCTerminal *instance = (UICCTerminal *)user_data;
463 TelSimAccessResult_t access_rt = (TelSimAccessResult_t)result;
464 TelSimAtrResp_t *atr = (TelSimAtrResp_t *)data;
466 SCARD_DEBUG("Get ATR response");
468 instance->syncLock();
470 instance->error = access_rt;
474 if (atr != NULL && atr->atr_resp_len > 0)
476 instance->response.setBuffer(atr->atr_resp, atr->atr_resp_len);
479 SCARD_DEBUG("response : %s", instance->response.toString());
483 SCARD_DEBUG_ERR("error : event->Status == [%d]", access_rt);
486 instance->signalCondition();
487 instance->syncUnlock();
490 void UICCTerminal::uiccStatusNotiCallback(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
492 UICCTerminal *instance = (UICCTerminal *)user_data;
493 TelSimCardStatus_t *status = (TelSimCardStatus_t *)data;
495 SCARD_DEBUG("TAPI_NOTI_SIM_STATUS");
499 case TAPI_SIM_STATUS_SIM_INIT_COMPLETED :
500 SCARD_DEBUG("TAPI_SIM_STATUS_SIM_INIT_COMPLETED");
502 if (instance->statusCallback != NULL)
504 instance->statusCallback((void *)se_name, NOTIFY_SE_AVAILABLE, 0, NULL);
508 case TAPI_SIM_STATUS_CARD_REMOVED :
509 SCARD_DEBUG("TAPI_SIM_STATUS_CARD_REMOVED");
511 if (instance->statusCallback != NULL)
513 instance->statusCallback((void *)se_name, NOTIFY_SE_NOT_AVAILABLE, 0, NULL);
518 SCARD_DEBUG("unknown status [%d]", *status);
522 } /* namespace smartcard_service_api */