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 */
26 #include "smartcard-types.h"
28 #include "TerminalInterface.h"
29 #include "UICCTerminal.h"
32 #define EXPORT_API __attribute__((visibility("default")))
35 typedef struct _callback_param_t
42 using namespace smartcard_service_api;
44 static const char *se_name = "SIM1";
46 /* below functions will be called when dlopen or dlclose is called */
48 typedef struct _context_s
55 void __attribute__ ((constructor)) lib_init()
59 void __attribute__ ((destructor)) lib_fini()
63 /* below three functions must be implemented */
64 extern "C" EXPORT_API const char *get_name()
69 extern "C" EXPORT_API void *create_instance()
71 return (void *)UICCTerminal::getInstance();
74 extern "C" EXPORT_API void destroy_instance(void *instance)
76 UICCTerminal *inst = (UICCTerminal *)instance;
77 if (inst == UICCTerminal::getInstance())
83 _ERR("instance is invalid : getInstance [%p], instance [%p]",
84 UICCTerminal::getInstance(), instance);
89 static void _uiccTransmitCallback(TapiHandle *handle, int result,
90 void *data, void *user_data)
92 TelSimAccessResult_t access_rt = (TelSimAccessResult_t)result;
93 TelSimApduResp_t *apdu = (TelSimApduResp_t *)data;
94 callback_param_t *param = (callback_param_t *)user_data;
98 if (param->callback != NULL)
100 terminalTransmitCallback callback =
101 (terminalTransmitCallback)param->callback;
103 if (apdu != NULL && apdu->apdu_resp_len > 0)
105 callback(apdu->apdu_resp, apdu->apdu_resp_len,
106 access_rt, param->param);
110 callback(NULL, 0, access_rt, param->param);
118 _ERR("invalid param");
122 static void _uiccGetATRCallback(TapiHandle *handle, int result,
123 void *data, void *user_data)
125 TelSimAccessResult_t access_rt = (TelSimAccessResult_t)result;
126 TelSimAtrResp_t *atr = (TelSimAtrResp_t *)data;
127 callback_param_t *param = (callback_param_t *)user_data;
131 if (param->callback != NULL)
133 terminalGetATRCallback callback =
134 (terminalGetATRCallback)param->callback;
136 if (atr != NULL && atr->atr_resp_len > 0)
138 callback(atr->atr_resp, atr->atr_resp_len,
139 access_rt, param->param);
143 callback(NULL, 0, access_rt, param->param);
151 _ERR("invalid param");
155 static void _uiccCallback_sync(TapiHandle *handle, int result,
156 void *data, void *user_data)
158 context_s* context = (context_s*)user_data;
160 if(result == TAPI_SIM_ACCESS_SUCCESS)
161 context->resp = data;
163 g_main_loop_quit(context->loop);
164 g_main_loop_unref(context->loop);
168 namespace smartcard_service_api
170 UICCTerminal::UICCTerminal() : Terminal()
172 name = (char *)se_name;
177 UICCTerminal::~UICCTerminal()
182 UICCTerminal *UICCTerminal::getInstance()
184 static UICCTerminal instance;
189 bool UICCTerminal::initialize()
193 if (initialized == false)
195 // char **cpList = NULL;
197 // cpList = tel_get_cp_name_list();
199 handle = tel_init(NULL);
204 error = tel_register_noti_event(handle,
205 TAPI_NOTI_SIM_STATUS,
206 &UICCTerminal::uiccStatusNotiCallback,
209 _ERR("tel_register_noti_event failed, [%d]", error);
216 _ERR("tel_init failed");
225 void UICCTerminal::finalize()
231 if (tel_deregister_noti_event(handle,
232 TAPI_NOTI_SIM_STATUS) < 0) {
233 _ERR("tel_deregister_noti_event failed");
244 bool UICCTerminal::open()
246 /* no need to open */
250 void UICCTerminal::close()
252 /* no need to close */
255 int UICCTerminal::transmitSync(const ByteArray &command,
258 int result = SCARD_ERROR_OK;
264 if (command.size() > 0)
266 TelSimApduResp_t *resp = NULL;
267 TelSimApdu_t apdu_data = { 0, };
268 context_s context = { NULL, resp };
270 context.loop = g_main_loop_new(NULL, false);
272 apdu_data.apdu = (uint8_t *)command.getBuffer();
273 apdu_data.apdu_len = command.size();
275 result = tel_req_sim_apdu(handle, &apdu_data,
276 _uiccCallback_sync, &context);
279 _ERR("tel_req_sim_apdu failed [%d]", result);
281 result = SCARD_ERROR_IO_FAILED;
285 g_main_loop_run(context.loop);
286 response.assign(((TelSimApduResp_t *)context.resp)->apdu_resp,
287 ((TelSimApduResp_t *)context.resp)->apdu_resp_len);
292 _ERR("apdu is empty");
294 result = SCARD_ERROR_ILLEGAL_PARAM;
303 int UICCTerminal::getATRSync(ByteArray &atr)
305 int result = SCARD_ERROR_OK;
311 TelSimAtrResp_t *resp = NULL;
312 context_s context = { NULL, resp };
314 context.loop = g_main_loop_new(NULL, false);
316 result = tel_req_sim_atr(handle,
317 _uiccCallback_sync, &context);
320 _ERR("tel_req_sim_atr failed [%d]", result);
322 result = SCARD_ERROR_IO_FAILED;
326 g_main_loop_run(context.loop);
328 if((TelSimAtrResp_t *)context.resp != NULL &&
329 ((TelSimAtrResp_t *)context.resp)->atr_resp != NULL )
331 atr.assign(((TelSimAtrResp_t *)context.resp)->atr_resp,
332 ((TelSimAtrResp_t *)context.resp)->atr_resp_len);
342 /* LCOV_EXCL_START */
343 int UICCTerminal::transmit(const ByteArray &command,
344 terminalTransmitCallback callback, void *userParam)
346 int result = SCARD_ERROR_OK;
352 if (command.size() > 0)
354 TelSimApdu_t apdu_data = { 0, };
355 callback_param_t *param = NULL;
357 apdu_data.apdu = (uint8_t *)command.getBuffer();
358 apdu_data.apdu_len = command.size();
360 param = new callback_param_t();
361 param->callback = (void *)callback;
362 param->param = userParam;
364 result = tel_req_sim_apdu(handle, &apdu_data,
365 _uiccTransmitCallback, param);
368 _DBG("tel_req_sim_apdu request is success");
372 _ERR("tel_req_sim_apdu failed [%d]", result);
373 result = SCARD_ERROR_IO_FAILED;
378 _ERR("apdu is empty");
379 result = SCARD_ERROR_ILLEGAL_PARAM;
388 int UICCTerminal::getATR(terminalGetATRCallback callback,
391 int result = SCARD_ERROR_OK;
397 callback_param_t *param = NULL;
399 param = new callback_param_t();
400 param->callback = (void *)callback;
401 param->param = userParam;
403 result = tel_req_sim_atr(handle,
404 _uiccGetATRCallback, param);
407 _DBG("tel_req_sim_atr request is success");
411 _ERR("tel_req_sim_atr failed [%d]", result);
412 result = SCARD_ERROR_IO_FAILED;
422 bool UICCTerminal::isSecureElementPresence() const
426 TelSimCardStatus_t state = (TelSimCardStatus_t)0;
431 error = tel_get_sim_init_info(handle, &state, &cardChanged);
434 if (state == TAPI_SIM_STATUS_SIM_INIT_COMPLETED)
440 _ERR("sim is not initialized, state [%d]", state);
445 _ERR("tel_get_sim_init_info failed, [%d]", error);
453 /* LCOV_EXCL_START */
454 void UICCTerminal::uiccStatusNotiCallback(TapiHandle *handle,
455 const char *noti_id, void *data, void *user_data)
457 UICCTerminal *instance = (UICCTerminal *)user_data;
458 TelSimCardStatus_t *status = (TelSimCardStatus_t *)data;
462 case TAPI_SIM_STATUS_SIM_INIT_COMPLETED :
463 _DBG("TAPI_SIM_STATUS_SIM_INIT_COMPLETED");
465 if (instance->statusCallback != NULL)
467 instance->statusCallback((void *)se_name,
468 NOTIFY_SE_AVAILABLE, 0, NULL);
472 case TAPI_SIM_STATUS_CARD_REMOVED :
473 _DBG("TAPI_SIM_STATUS_CARD_REMOVED");
475 if (instance->statusCallback != NULL)
477 instance->statusCallback((void *)se_name,
478 NOTIFY_SE_NOT_AVAILABLE, 0, NULL);
483 /* ignore notification */
488 } /* namespace smartcard_service_api */