1 /*
2 * Copyright (C) 2010 The Android Open Source Project
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 #include <errno.h>
18 #include <pthread.h>
19 #include <semaphore.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <sys/queue.h>
24 #include <hardware/hardware.h>
25 #include <hardware/nfc.h>
26 #include <cutils/properties.h>
27
28 #include "com_android_nfc.h"
29
30 #define ERROR_BUFFER_TOO_SMALL -12
31 #define ERROR_INSUFFICIENT_RESOURCES -9
32
33 extern uint32_t libnfc_llc_error_count;
34
35 static phLibNfc_sConfig_t gDrvCfg;
36 void *gHWRef;
37 static phNfc_sData_t gInputParam;
38 static phNfc_sData_t gOutputParam;
39
40 uint8_t device_connected_flag;
41 static bool driverConfigured = FALSE;
42
43 static phLibNfc_Handle hLlcpHandle;
44 static NFCSTATUS lastErrorStatus = NFCSTATUS_FAILED;
45 static phLibNfc_Llcp_eLinkStatus_t g_eLinkStatus = phFriNfc_LlcpMac_eLinkDefault;
46
47 static jmethodID cached_NfcManager_notifyNdefMessageListeners;
48 static jmethodID cached_NfcManager_notifyTransactionListeners;
49 static jmethodID cached_NfcManager_notifyLlcpLinkActivation;
50 static jmethodID cached_NfcManager_notifyLlcpLinkDeactivated;
51 static jmethodID cached_NfcManager_notifyTargetDeselected;
52
53 static jmethodID cached_NfcManager_notifySeFieldActivated;
54 static jmethodID cached_NfcManager_notifySeFieldDeactivated;
55
56 static jmethodID cached_NfcManager_notifySeApduReceived;
57 static jmethodID cached_NfcManager_notifySeMifareAccess;
58 static jmethodID cached_NfcManager_notifySeEmvCardRemoval;
59
60 namespace android {
61
62 phLibNfc_Handle storedHandle = 0;
63
64 struct nfc_jni_native_data *exported_nat = NULL;
65
66 /* Internal functions declaration */
67 static void *nfc_jni_client_thread(void *arg);
68 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status);
69 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status);
70 static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status);
71 static void nfc_jni_se_set_mode_callback(void *context,
72 phLibNfc_Handle handle, NFCSTATUS status);
73 static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status);
74 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume);
75 static void nfc_jni_Discovery_notification_callback(void *pContext,
76 phLibNfc_RemoteDevList_t *psRemoteDevList,
77 uint8_t uNofRemoteDev, NFCSTATUS status);
78 static void nfc_jni_transaction_callback(void *context,
79 phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle,
80 phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status);
81 static bool performDownload(struct nfc_jni_native_data *nat, bool takeLock);
82
83 /*
84 * Deferred callback called when client thread must be exited
85 */
client_kill_deferred_call(void * arg)86 static void client_kill_deferred_call(void* arg)
87 {
88 struct nfc_jni_native_data *nat = (struct nfc_jni_native_data *)arg;
89
90 nat->running = FALSE;
91 }
92
kill_client(nfc_jni_native_data * nat)93 static void kill_client(nfc_jni_native_data *nat)
94 {
95 phDal4Nfc_Message_Wrapper_t wrapper;
96 phLibNfc_DeferredCall_t *pMsg;
97
98 usleep(50000);
99
100 ALOGD("Terminating client thread...");
101
102 pMsg = (phLibNfc_DeferredCall_t*)malloc(sizeof(phLibNfc_DeferredCall_t));
103 pMsg->pCallback = client_kill_deferred_call;
104 pMsg->pParameter = (void*)nat;
105
106 wrapper.msg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
107 wrapper.msg.pMsgData = pMsg;
108 wrapper.msg.Size = sizeof(phLibNfc_DeferredCall_t);
109
110 phDal4Nfc_msgsnd(gDrvCfg.nClientId, (struct msgbuf *)&wrapper, sizeof(phLibNfc_Message_t), 0);
111 }
112
nfc_jni_ioctl_callback(void * pContext,phNfc_sData_t * pOutput,NFCSTATUS status)113 static void nfc_jni_ioctl_callback(void *pContext, phNfc_sData_t *pOutput, NFCSTATUS status) {
114 struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext;
115 LOG_CALLBACK("nfc_jni_ioctl_callback", status);
116
117 /* Report the callback status and wake up the caller */
118 pCallbackData->status = status;
119 sem_post(&pCallbackData->sem);
120 }
121
nfc_jni_deinit_download_callback(void * pContext,NFCSTATUS status)122 static void nfc_jni_deinit_download_callback(void *pContext, NFCSTATUS status)
123 {
124 struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext;
125 LOG_CALLBACK("nfc_jni_deinit_download_callback", status);
126
127 /* Report the callback status and wake up the caller */
128 pCallbackData->status = status;
129 sem_post(&pCallbackData->sem);
130 }
131
nfc_jni_download_locked(struct nfc_jni_native_data * nat,uint8_t update)132 static int nfc_jni_download_locked(struct nfc_jni_native_data *nat, uint8_t update)
133 {
134 uint8_t OutputBuffer[1];
135 uint8_t InputBuffer[1];
136 struct timespec ts;
137 NFCSTATUS status = NFCSTATUS_FAILED;
138 phLibNfc_StackCapabilities_t caps;
139 struct nfc_jni_callback_data cb_data;
140 bool result;
141
142 /* Create the local semaphore */
143 if (!nfc_cb_data_init(&cb_data, NULL))
144 {
145 goto clean_and_return;
146 }
147
148 if(update)
149 {
150 //deinit
151 TRACE("phLibNfc_Mgt_DeInitialize() (download)");
152 REENTRANCE_LOCK();
153 status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_download_callback, (void *)&cb_data);
154 REENTRANCE_UNLOCK();
155 if (status != NFCSTATUS_PENDING)
156 {
157 ALOGE("phLibNfc_Mgt_DeInitialize() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
158 }
159
160 clock_gettime(CLOCK_REALTIME, &ts);
161 ts.tv_sec += 5;
162
163 /* Wait for callback response */
164 if(sem_timedwait(&cb_data.sem, &ts))
165 {
166 ALOGW("Deinitialization timed out (download)");
167 }
168
169 if(cb_data.status != NFCSTATUS_SUCCESS)
170 {
171 ALOGW("Deinitialization FAILED (download)");
172 }
173 TRACE("Deinitialization SUCCESS (download)");
174 }
175
176 result = performDownload(nat, false);
177
178 if (!result) {
179 status = NFCSTATUS_FAILED;
180 goto clean_and_return;
181 }
182
183 TRACE("phLibNfc_Mgt_Initialize()");
184 REENTRANCE_LOCK();
185 status = phLibNfc_Mgt_Initialize(gHWRef, nfc_jni_init_callback, (void *)&cb_data);
186 REENTRANCE_UNLOCK();
187 if(status != NFCSTATUS_PENDING)
188 {
189 ALOGE("phLibNfc_Mgt_Initialize() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
190 goto clean_and_return;
191 }
192 TRACE("phLibNfc_Mgt_Initialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
193
194 if(sem_wait(&cb_data.sem))
195 {
196 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
197 status = NFCSTATUS_FAILED;
198 goto clean_and_return;
199 }
200
201 /* Initialization Status */
202 if(cb_data.status != NFCSTATUS_SUCCESS)
203 {
204 status = cb_data.status;
205 goto clean_and_return;
206 }
207
208 /* ====== CAPABILITIES ======= */
209 REENTRANCE_LOCK();
210 status = phLibNfc_Mgt_GetstackCapabilities(&caps, (void*)nat);
211 REENTRANCE_UNLOCK();
212 if (status != NFCSTATUS_SUCCESS)
213 {
214 ALOGW("phLibNfc_Mgt_GetstackCapabilities returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
215 }
216 else
217 {
218 ALOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d",
219 caps.psDevCapabilities.hal_version,
220 caps.psDevCapabilities.fw_version,
221 caps.psDevCapabilities.hw_version,
222 caps.psDevCapabilities.model_id,
223 caps.psDevCapabilities.hci_version,
224 caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1],
225 caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2],
226 caps.psDevCapabilities.firmware_update_info);
227 }
228
229 /*Download is successful*/
230 status = NFCSTATUS_SUCCESS;
231
232 clean_and_return:
233 nfc_cb_data_deinit(&cb_data);
234 return status;
235 }
236
nfc_jni_configure_driver(struct nfc_jni_native_data * nat)237 static int nfc_jni_configure_driver(struct nfc_jni_native_data *nat)
238 {
239 char value[PROPERTY_VALUE_MAX];
240 int result = FALSE;
241 NFCSTATUS status;
242
243 /* ====== CONFIGURE DRIVER ======= */
244 /* Configure hardware link */
245 gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
246
247 TRACE("phLibNfc_Mgt_ConfigureDriver(0x%08x)", gDrvCfg.nClientId);
248 REENTRANCE_LOCK();
249 status = phLibNfc_Mgt_ConfigureDriver(&gDrvCfg, &gHWRef);
250 REENTRANCE_UNLOCK();
251 if(status == NFCSTATUS_ALREADY_INITIALISED) {
252 ALOGW("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
253 }
254 else if(status != NFCSTATUS_SUCCESS)
255 {
256 ALOGE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
257 goto clean_and_return;
258 }
259 TRACE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
260
261 if(pthread_create(&(nat->thread), NULL, nfc_jni_client_thread, nat) != 0)
262 {
263 ALOGE("pthread_create failed");
264 goto clean_and_return;
265 }
266
267 driverConfigured = TRUE;
268
269 clean_and_return:
270 return result;
271 }
272
nfc_jni_unconfigure_driver(struct nfc_jni_native_data * nat)273 static int nfc_jni_unconfigure_driver(struct nfc_jni_native_data *nat)
274 {
275 int result = FALSE;
276 NFCSTATUS status;
277
278 /* Unconfigure driver */
279 TRACE("phLibNfc_Mgt_UnConfigureDriver()");
280 REENTRANCE_LOCK();
281 status = phLibNfc_Mgt_UnConfigureDriver(gHWRef);
282 REENTRANCE_UNLOCK();
283 if(status != NFCSTATUS_SUCCESS)
284 {
285 ALOGE("phLibNfc_Mgt_UnConfigureDriver() returned error 0x%04x[%s] -- this should never happen", status, nfc_jni_get_status_name( status));
286 }
287 else
288 {
289 ALOGD("phLibNfc_Mgt_UnConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
290 result = TRUE;
291 }
292
293 driverConfigured = FALSE;
294
295 return result;
296 }
297
298 /* Initialization function */
nfc_jni_initialize(struct nfc_jni_native_data * nat)299 static int nfc_jni_initialize(struct nfc_jni_native_data *nat) {
300 struct timespec ts;
301 uint8_t resp[16];
302 NFCSTATUS status;
303 phLibNfc_StackCapabilities_t caps;
304 phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
305 uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index = 0, SmartMX_detected = 0;
306 phLibNfc_Llcp_sLinkParameters_t LlcpConfigInfo;
307 struct nfc_jni_callback_data cb_data;
308 uint8_t firmware_status;
309 uint8_t update = TRUE;
310 int result = JNI_FALSE;
311 const hw_module_t* hw_module;
312 nfc_pn544_device_t* pn544_dev = NULL;
313 int ret = 0;
314 ALOGD("Start Initialization\n");
315
316 /* Create the local semaphore */
317 if (!nfc_cb_data_init(&cb_data, NULL))
318 {
319 goto clean_and_return;
320 }
321 /* Get EEPROM values and device port from product-specific settings */
322 ret = hw_get_module(NFC_HARDWARE_MODULE_ID, &hw_module);
323 if (ret) {
324 ALOGE("hw_get_module() failed.");
325 goto clean_and_return;
326 }
327 ret = nfc_pn544_open(hw_module, &pn544_dev);
328 if (ret) {
329 ALOGE("Could not open pn544 hw_module.");
330 goto clean_and_return;
331 }
332 if (pn544_dev->num_eeprom_settings == 0 || pn544_dev->eeprom_settings == NULL) {
333 ALOGE("Could not load EEPROM settings");
334 goto clean_and_return;
335 }
336
337 /* Reset device connected handle */
338 device_connected_flag = 0;
339
340 /* Reset stored handle */
341 storedHandle = 0;
342
343 /* Initialize Driver */
344 if(!driverConfigured)
345 {
346 nfc_jni_configure_driver(nat);
347 }
348
349 /* ====== INITIALIZE ======= */
350
351 TRACE("phLibNfc_Mgt_Initialize()");
352 REENTRANCE_LOCK();
353 status = phLibNfc_Mgt_Initialize(gHWRef, nfc_jni_init_callback, (void *)&cb_data);
354 REENTRANCE_UNLOCK();
355 if(status != NFCSTATUS_PENDING)
356 {
357 ALOGE("phLibNfc_Mgt_Initialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
358 update = FALSE;
359 goto force_download;
360 }
361 TRACE("phLibNfc_Mgt_Initialize returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
362
363 /* Wait for callback response */
364 if(sem_wait(&cb_data.sem))
365 {
366 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
367 goto clean_and_return;
368 }
369
370 /* Initialization Status */
371 if(cb_data.status != NFCSTATUS_SUCCESS)
372 {
373 update = FALSE;
374 goto force_download;
375 }
376
377 /* ====== CAPABILITIES ======= */
378
379 REENTRANCE_LOCK();
380 status = phLibNfc_Mgt_GetstackCapabilities(&caps, (void*)nat);
381 REENTRANCE_UNLOCK();
382 if (status != NFCSTATUS_SUCCESS)
383 {
384 ALOGW("phLibNfc_Mgt_GetstackCapabilities returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
385 }
386 else
387 {
388 ALOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d",
389 caps.psDevCapabilities.hal_version,
390 caps.psDevCapabilities.fw_version,
391 caps.psDevCapabilities.hw_version,
392 caps.psDevCapabilities.model_id,
393 caps.psDevCapabilities.hci_version,
394 caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1],
395 caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2],
396 caps.psDevCapabilities.firmware_update_info);
397 }
398
399 /* ====== FIRMWARE VERSION ======= */
400 if(caps.psDevCapabilities.firmware_update_info)
401 {
402 force_download:
403 for (i=0; i<3; i++)
404 {
405 TRACE("Firmware version not UpToDate");
406 status = nfc_jni_download_locked(nat, update);
407 if(status == NFCSTATUS_SUCCESS)
408 {
409 ALOGI("Firmware update SUCCESS");
410 break;
411 }
412 ALOGW("Firmware update FAILED");
413 update = FALSE;
414 }
415 if(i>=3)
416 {
417 ALOGE("Unable to update firmware, giving up");
418 goto clean_and_return;
419 }
420 }
421 else
422 {
423 TRACE("Firmware version UpToDate");
424 }
425 /* ====== EEPROM SETTINGS ======= */
426
427 // Update EEPROM settings
428 TRACE("****** START EEPROM SETTINGS UPDATE ******");
429 for (i = 0; i < pn544_dev->num_eeprom_settings; i++)
430 {
431 char eeprom_property[PROPERTY_KEY_MAX];
432 char eeprom_value[PROPERTY_VALUE_MAX];
433 uint8_t* eeprom_base = &(pn544_dev->eeprom_settings[i*4]);
434 TRACE("> EEPROM SETTING: %d", i);
435
436 // Check for override of this EEPROM value in properties
437 snprintf(eeprom_property, sizeof(eeprom_property), "debug.nfc.eeprom.%02X%02X",
438 eeprom_base[1], eeprom_base[2]);
439 TRACE(">> Checking property: %s", eeprom_property);
440 if (property_get(eeprom_property, eeprom_value, "") == 2) {
441 int eeprom_value_num = (int)strtol(eeprom_value, (char**)NULL, 16);
442 ALOGD(">> Override EEPROM addr 0x%02X%02X with value %02X",
443 eeprom_base[1], eeprom_base[2], eeprom_value_num);
444 eeprom_base[3] = eeprom_value_num;
445 }
446
447 TRACE(">> Addr: 0x%02X%02X set to: 0x%02X", eeprom_base[1], eeprom_base[2],
448 eeprom_base[3]);
449 gInputParam.buffer = eeprom_base;
450 gInputParam.length = 0x04;
451 gOutputParam.buffer = resp;
452
453 REENTRANCE_LOCK();
454 status = phLibNfc_Mgt_IoCtl(gHWRef, NFC_MEM_WRITE, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
455 REENTRANCE_UNLOCK();
456 if (status != NFCSTATUS_PENDING) {
457 ALOGE("phLibNfc_Mgt_IoCtl() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
458 goto clean_and_return;
459 }
460 /* Wait for callback response */
461 if(sem_wait(&cb_data.sem))
462 {
463 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
464 goto clean_and_return;
465 }
466
467 /* Initialization Status */
468 if (cb_data.status != NFCSTATUS_SUCCESS)
469 {
470 goto clean_and_return;
471 }
472 }
473 TRACE("****** ALL EEPROM SETTINGS UPDATED ******");
474
475 /* ====== SECURE ELEMENTS ======= */
476
477 REENTRANCE_LOCK();
478 ALOGD("phLibNfc_SE_GetSecureElementList()");
479 status = phLibNfc_SE_GetSecureElementList(SE_List, &No_SE);
480 REENTRANCE_UNLOCK();
481 if (status != NFCSTATUS_SUCCESS)
482 {
483 ALOGD("phLibNfc_SE_GetSecureElementList(): Error");
484 goto clean_and_return;
485 }
486
487 ALOGD("\n> Number of Secure Element(s) : %d\n", No_SE);
488 /* Display Secure Element information */
489 for (i = 0; i < No_SE; i++)
490 {
491 if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX) {
492 ALOGD("phLibNfc_SE_GetSecureElementList(): SMX detected, handle=%p", (void*)SE_List[i].hSecureElement);
493 } else if (SE_List[i].eSE_Type == phLibNfc_SE_Type_UICC) {
494 ALOGD("phLibNfc_SE_GetSecureElementList(): UICC detected, handle=%p", (void*)SE_List[i].hSecureElement);
495 }
496
497 /* Set SE mode - Off */
498 REENTRANCE_LOCK();
499 status = phLibNfc_SE_SetMode(SE_List[i].hSecureElement,
500 phLibNfc_SE_ActModeOff, nfc_jni_se_set_mode_callback,
501 (void *)&cb_data);
502 REENTRANCE_UNLOCK();
503 if (status != NFCSTATUS_PENDING)
504 {
505 ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status,
506 nfc_jni_get_status_name(status));
507 goto clean_and_return;
508 }
509 ALOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status,
510 nfc_jni_get_status_name(status));
511
512 /* Wait for callback response */
513 if(sem_wait(&cb_data.sem))
514 {
515 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
516 goto clean_and_return;
517 }
518 }
519
520 /* ====== LLCP ======= */
521
522 /* LLCP Params */
523 TRACE("****** NFC Config Mode NFCIP1 - LLCP ******");
524 LlcpConfigInfo.miu = nat->miu;
525 LlcpConfigInfo.lto = nat->lto;
526 LlcpConfigInfo.wks = nat->wks;
527 LlcpConfigInfo.option = nat->opt;
528
529 REENTRANCE_LOCK();
530 status = phLibNfc_Mgt_SetLlcp_ConfigParams(&LlcpConfigInfo,
531 nfc_jni_llcpcfg_callback,
532 (void *)&cb_data);
533 REENTRANCE_UNLOCK();
534 if(status != NFCSTATUS_PENDING)
535 {
536 ALOGE("phLibNfc_Mgt_SetLlcp_ConfigParams returned 0x%04x[%s]", status,
537 nfc_jni_get_status_name(status));
538 goto clean_and_return;
539 }
540 TRACE("phLibNfc_Mgt_SetLlcp_ConfigParams returned 0x%04x[%s]", status,
541 nfc_jni_get_status_name(status));
542
543 /* Wait for callback response */
544 if(sem_wait(&cb_data.sem))
545 {
546 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
547 goto clean_and_return;
548 }
549
550 /* ===== DISCOVERY ==== */
551 nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes; //initiator
552 nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes; //target
553 nat->discovery_cfg.Duration = 300000; /* in ms */
554 nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE;
555
556 /* Register for the card emulation mode */
557 REENTRANCE_LOCK();
558 ret = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat);
559 REENTRANCE_UNLOCK();
560 if(ret != NFCSTATUS_SUCCESS)
561 {
562 ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",ret);
563 goto clean_and_return;
564 }
565 TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", ret);
566
567
568 /* ====== END ======= */
569
570 ALOGI("NFC Initialized");
571
572 result = TRUE;
573
574 clean_and_return:
575 if (result != TRUE)
576 {
577 if(nat)
578 {
579 kill_client(nat);
580 }
581 }
582 if (pn544_dev != NULL) {
583 nfc_pn544_close(pn544_dev);
584 }
585 nfc_cb_data_deinit(&cb_data);
586
587 return result;
588 }
589
is_user_build()590 static int is_user_build() {
591 char value[PROPERTY_VALUE_MAX];
592 property_get("ro.build.type", value, "");
593 return !strncmp("user", value, PROPERTY_VALUE_MAX);
594 }
595
596 /*
597 * Last-chance fallback when there is no clean way to recover
598 * Performs a software reset
599 */
emergency_recovery(struct nfc_jni_native_data * nat)600 void emergency_recovery(struct nfc_jni_native_data *nat) {
601 if (!is_user_build()) {
602 ALOGE("emergency_recovery: force restart of NFC service");
603 } else {
604 // dont recover immediately, so we can debug
605 unsigned int t;
606 for (t=1; t < 1000000; t <<= 1) {
607 ALOGE("emergency_recovery: NFC stack dead-locked");
608 sleep(t);
609 }
610 }
611 phLibNfc_Mgt_Recovery();
612 abort(); // force a noisy crash
613 }
614
nfc_jni_reset_timeout_values()615 void nfc_jni_reset_timeout_values()
616 {
617 REENTRANCE_LOCK();
618 phLibNfc_SetIsoXchgTimeout(NXP_ISO_XCHG_TIMEOUT);
619 phLibNfc_SetHciTimeout(NXP_NFC_HCI_TIMEOUT);
620 phLibNfc_SetFelicaTimeout(NXP_FELICA_XCHG_TIMEOUT);
621 phLibNfc_SetMifareRawTimeout(NXP_MIFARE_XCHG_TIMEOUT);
622 REENTRANCE_UNLOCK();
623 }
624
625 /*
626 * Restart the polling loop when unable to perform disconnect
627 */
nfc_jni_restart_discovery_locked(struct nfc_jni_native_data * nat)628 void nfc_jni_restart_discovery_locked(struct nfc_jni_native_data *nat)
629 {
630 nfc_jni_start_discovery_locked(nat, true);
631 }
632
633 /*
634 * Utility to recover UID from target infos
635 */
get_target_uid(phLibNfc_sRemoteDevInformation_t * psRemoteDevInfo)636 static phNfc_sData_t get_target_uid(phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo)
637 {
638 phNfc_sData_t uid;
639
640 switch(psRemoteDevInfo->RemDevType)
641 {
642 case phNfc_eISO14443_A_PICC:
643 case phNfc_eISO14443_4A_PICC:
644 case phNfc_eISO14443_3A_PICC:
645 case phNfc_eMifare_PICC:
646 uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid;
647 uid.length = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength;
648 break;
649 case phNfc_eISO14443_B_PICC:
650 case phNfc_eISO14443_4B_PICC:
651 uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.Pupi;
652 uid.length = sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.Pupi);
653 break;
654 case phNfc_eFelica_PICC:
655 uid.buffer = psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm;
656 uid.length = psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDmLength;
657 break;
658 case phNfc_eJewel_PICC:
659 uid.buffer = psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid;
660 uid.length = psRemoteDevInfo->RemoteDevInfo.Jewel_Info.UidLength;
661 break;
662 case phNfc_eISO15693_PICC:
663 uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid;
664 uid.length = psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength;
665 break;
666 case phNfc_eNfcIP1_Target:
667 case phNfc_eNfcIP1_Initiator:
668 uid.buffer = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.NFCID;
669 uid.length = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.NFCID_Length;
670 break;
671 default:
672 uid.buffer = NULL;
673 uid.length = 0;
674 break;
675 }
676
677 return uid;
678 }
679
680 /*
681 * NFC stack message processing
682 */
nfc_jni_client_thread(void * arg)683 static void *nfc_jni_client_thread(void *arg)
684 {
685 struct nfc_jni_native_data *nat;
686 JNIEnv *e;
687 JavaVMAttachArgs thread_args;
688 phDal4Nfc_Message_Wrapper_t wrapper;
689
690 nat = (struct nfc_jni_native_data *)arg;
691
692 thread_args.name = "NFC Message Loop";
693 thread_args.version = nat->env_version;
694 thread_args.group = NULL;
695
696 nat->vm->AttachCurrentThread(&e, &thread_args);
697 pthread_setname_np(pthread_self(), "message");
698
699 TRACE("NFC client started");
700 nat->running = TRUE;
701 while(nat->running == TRUE)
702 {
703 /* Fetch next message from the NFC stack message queue */
704 if(phDal4Nfc_msgrcv(gDrvCfg.nClientId, (void *)&wrapper,
705 sizeof(phLibNfc_Message_t), 0, 0) == -1)
706 {
707 ALOGE("NFC client received bad message");
708 continue;
709 }
710
711 switch(wrapper.msg.eMsgType)
712 {
713 case PH_LIBNFC_DEFERREDCALL_MSG:
714 {
715 phLibNfc_DeferredCall_t *msg =
716 (phLibNfc_DeferredCall_t *)(wrapper.msg.pMsgData);
717
718 REENTRANCE_LOCK();
719 msg->pCallback(msg->pParameter);
720 REENTRANCE_UNLOCK();
721
722 break;
723 }
724 }
725 }
726 TRACE("NFC client stopped");
727
728 nat->vm->DetachCurrentThread();
729
730 return NULL;
731 }
732
733 extern uint8_t nfc_jni_is_ndef;
734 extern uint8_t *nfc_jni_ndef_buf;
735 extern uint32_t nfc_jni_ndef_buf_len;
736
737 static phLibNfc_sNfcIPCfg_t nfc_jni_nfcip1_cfg =
738 {
739 3,
740 { 0x46, 0x66, 0x6D }
741 };
742
743 /*
744 * Callbacks
745 */
746
747 /* P2P - LLCP callbacks */
nfc_jni_llcp_linkStatus_callback(void * pContext,phFriNfc_LlcpMac_eLinkStatus_t eLinkStatus)748 static void nfc_jni_llcp_linkStatus_callback(void *pContext,
749 phFriNfc_LlcpMac_eLinkStatus_t eLinkStatus)
750 {
751 phFriNfc_Llcp_sLinkParameters_t sLinkParams;
752 JNIEnv *e;
753 NFCSTATUS status;
754
755 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
756
757 struct nfc_jni_native_data *nat = (nfc_jni_native_data *)pContextData->pContext;
758
759 nfc_jni_listen_data_t * pListenData = NULL;
760 nfc_jni_native_monitor * pMonitor = nfc_jni_get_monitor();
761
762 TRACE("Callback: nfc_jni_llcp_linkStatus_callback()");
763
764 nat->vm->GetEnv( (void **)&e, nat->env_version);
765
766 /* Update link status */
767 g_eLinkStatus = eLinkStatus;
768
769 if(eLinkStatus == phFriNfc_LlcpMac_eLinkActivated)
770 {
771 REENTRANCE_LOCK();
772 status = phLibNfc_Llcp_GetRemoteInfo(hLlcpHandle, &sLinkParams);
773 REENTRANCE_UNLOCK();
774 if(status != NFCSTATUS_SUCCESS)
775 {
776 ALOGW("GetRemote Info failded - Status = %02x",status);
777 }
778 else
779 {
780 ALOGI("LLCP Link activated (LTO=%d, MIU=%d, OPTION=0x%02x, WKS=0x%02x)",sLinkParams.lto,
781 sLinkParams.miu,
782 sLinkParams.option,
783 sLinkParams.wks);
784 device_connected_flag = 1;
785 }
786 }
787 else if(eLinkStatus == phFriNfc_LlcpMac_eLinkDeactivated)
788 {
789 ALOGI("LLCP Link deactivated");
790 free(pContextData);
791 /* Reset device connected flag */
792 device_connected_flag = 0;
793
794 /* Reset incoming socket list */
795 while (!LIST_EMPTY(&pMonitor->incoming_socket_head))
796 {
797 pListenData = LIST_FIRST(&pMonitor->incoming_socket_head);
798 LIST_REMOVE(pListenData, entries);
799 free(pListenData);
800 }
801
802 /* Notify manager that the LLCP is lost or deactivated */
803 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkDeactivated, nat->tag);
804 if(e->ExceptionCheck())
805 {
806 ALOGE("Exception occured");
807 kill_client(nat);
808 }
809 }
810 }
811
nfc_jni_checkLlcp_callback(void * context,NFCSTATUS status)812 static void nfc_jni_checkLlcp_callback(void *context,
813 NFCSTATUS status)
814 {
815 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)context;
816
817 LOG_CALLBACK("nfc_jni_checkLlcp_callback", status);
818
819 pContextData->status = status;
820 sem_post(&pContextData->sem);
821 }
822
nfc_jni_llcpcfg_callback(void * pContext,NFCSTATUS status)823 static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status)
824 {
825 struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext;
826 LOG_CALLBACK("nfc_jni_llcpcfg_callback", status);
827
828 /* Report the callback status and wake up the caller */
829 pCallbackData->status = status;
830 sem_post(&pCallbackData->sem);
831 }
832
nfc_jni_llcp_transport_listen_socket_callback(void * pContext,phLibNfc_Handle hIncomingSocket)833 static void nfc_jni_llcp_transport_listen_socket_callback(void *pContext,
834 phLibNfc_Handle hIncomingSocket)
835 {
836 phLibNfc_Handle hServiceSocket = (phLibNfc_Handle)pContext;
837 nfc_jni_listen_data_t * pListenData = NULL;
838 nfc_jni_native_monitor * pMonitor = nfc_jni_get_monitor();
839
840 TRACE("nfc_jni_llcp_transport_listen_socket_callback socket handle = %p", (void*)hIncomingSocket);
841
842 pthread_mutex_lock(&pMonitor->incoming_socket_mutex);
843
844 /* Store the connection request */
845 pListenData = (nfc_jni_listen_data_t*)malloc(sizeof(nfc_jni_listen_data_t));
846 if (pListenData == NULL)
847 {
848 ALOGE("Failed to create structure to handle incoming LLCP connection request");
849 goto clean_and_return;
850 }
851 pListenData->pServerSocket = hServiceSocket;
852 pListenData->pIncomingSocket = hIncomingSocket;
853 LIST_INSERT_HEAD(&pMonitor->incoming_socket_head, pListenData, entries);
854
855 /* Signal pending accept operations that the list is updated */
856 pthread_cond_broadcast(&pMonitor->incoming_socket_cond);
857
858 clean_and_return:
859 pthread_mutex_unlock(&pMonitor->incoming_socket_mutex);
860 }
861
nfc_jni_llcp_transport_socket_err_callback(void * pContext,uint8_t nErrCode)862 void nfc_jni_llcp_transport_socket_err_callback(void* pContext,
863 uint8_t nErrCode)
864 {
865 PHNFC_UNUSED_VARIABLE(pContext);
866
867 TRACE("Callback: nfc_jni_llcp_transport_socket_err_callback()");
868
869 if(nErrCode == PHFRINFC_LLCP_ERR_FRAME_REJECTED)
870 {
871 ALOGW("Frame Rejected - Disconnected");
872 }
873 else if(nErrCode == PHFRINFC_LLCP_ERR_DISCONNECTED)
874 {
875 ALOGD("Socket Disconnected");
876 }
877 }
878
879
nfc_jni_discover_callback(void * pContext,NFCSTATUS status)880 static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status)
881 {
882 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
883
884 LOG_CALLBACK("nfc_jni_discover_callback", status);
885
886 pContextData->status = status;
887 sem_post(&pContextData->sem);
888 }
889
find_preferred_target(phLibNfc_RemoteDevList_t * psRemoteDevList,uint8_t uNoOfRemoteDev)890 static uint8_t find_preferred_target(phLibNfc_RemoteDevList_t *psRemoteDevList,
891 uint8_t uNoOfRemoteDev)
892 {
893 // Always prefer p2p targets over other targets. Otherwise, select the first target
894 // reported.
895 uint8_t preferred_index = 0;
896 for (uint8_t i = 0; i < uNoOfRemoteDev; i++) {
897 if((psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
898 || (psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eNfcIP1_Target)) {
899 preferred_index = i;
900 }
901 }
902 return preferred_index;
903 }
904
nfc_jni_Discovery_notification_callback(void * pContext,phLibNfc_RemoteDevList_t * psRemoteDevList,uint8_t uNofRemoteDev,NFCSTATUS status)905 static void nfc_jni_Discovery_notification_callback(void *pContext,
906 phLibNfc_RemoteDevList_t *psRemoteDevList,
907 uint8_t uNofRemoteDev, NFCSTATUS status)
908 {
909 JNIEnv *e;
910 NFCSTATUS ret;
911 jclass tag_cls = NULL;
912 jobject target_array;
913 jobject tag;
914 jmethodID ctor;
915 jfieldID f;
916 const char * typeName;
917 jbyteArray tagUid;
918 jbyteArray generalBytes = NULL;
919 struct nfc_jni_native_data *nat;
920 struct timespec ts;
921 phNfc_sData_t data;
922 int i;
923 int target_index = 0; // Target that will be reported (if multiple can be >0)
924
925 nat = (struct nfc_jni_native_data *)pContext;
926
927 nat->vm->GetEnv( (void **)&e, nat->env_version);
928
929 if(status == NFCSTATUS_DESELECTED)
930 {
931 LOG_CALLBACK("nfc_jni_Discovery_notification_callback: Target deselected", status);
932
933 /* Notify manager that a target was deselected */
934 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTargetDeselected);
935 if(e->ExceptionCheck())
936 {
937 ALOGE("Exception occured");
938 kill_client(nat);
939 }
940 }
941 else
942 {
943 LOG_CALLBACK("nfc_jni_Discovery_notification_callback", status);
944 TRACE("Discovered %d tags", uNofRemoteDev);
945
946 target_index = find_preferred_target(psRemoteDevList, uNofRemoteDev);
947
948 /* Reset device connected flag */
949 device_connected_flag = 1;
950 phLibNfc_sRemoteDevInformation_t *remDevInfo = psRemoteDevList[target_index].psRemoteDevInfo;
951 phLibNfc_Handle remDevHandle = psRemoteDevList[target_index].hTargetDev;
952 if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
953 || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target))
954 {
955
956 tag_cls = e->GetObjectClass(nat->cached_P2pDevice);
957 if(e->ExceptionCheck())
958 {
959 ALOGE("Get Object Class Error");
960 kill_client(nat);
961 return;
962 }
963
964 /* New target instance */
965 ctor = e->GetMethodID(tag_cls, "<init>", "()V");
966 tag = e->NewObject(tag_cls, ctor);
967
968 /* Set P2P Target mode */
969 f = e->GetFieldID(tag_cls, "mMode", "I");
970
971 if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
972 {
973 ALOGD("Discovered P2P Initiator");
974 e->SetIntField(tag, f, (jint)MODE_P2P_INITIATOR);
975 }
976 else
977 {
978 ALOGD("Discovered P2P Target");
979 e->SetIntField(tag, f, (jint)MODE_P2P_TARGET);
980 }
981
982 if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
983 {
984 /* Set General Bytes */
985 f = e->GetFieldID(tag_cls, "mGeneralBytes", "[B");
986
987 TRACE("General Bytes length =");
988 for(i=0;i<remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length;i++)
989 {
990 ALOGD("%02x ", remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[i]);
991 }
992
993 generalBytes = e->NewByteArray(remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length);
994
995 e->SetByteArrayRegion(generalBytes, 0,
996 remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length,
997 (jbyte *)remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo);
998
999 e->SetObjectField(tag, f, generalBytes);
1000 }
1001
1002 /* Set tag handle */
1003 f = e->GetFieldID(tag_cls, "mHandle", "I");
1004 e->SetIntField(tag, f,(jint)remDevHandle);
1005 TRACE("Target handle = 0x%08x",remDevHandle);
1006 }
1007 else
1008 {
1009 tag_cls = e->GetObjectClass(nat->cached_NfcTag);
1010 if(e->ExceptionCheck())
1011 {
1012 kill_client(nat);
1013 return;
1014 }
1015
1016 /* New tag instance */
1017 ctor = e->GetMethodID(tag_cls, "<init>", "()V");
1018 tag = e->NewObject(tag_cls, ctor);
1019
1020 bool multi_protocol = false;
1021
1022 if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
1023 {
1024 TRACE("Multiple Protocol TAG detected\n");
1025 multi_protocol = true;
1026 }
1027
1028 /* Set tag UID */
1029 f = e->GetFieldID(tag_cls, "mUid", "[B");
1030 data = get_target_uid(remDevInfo);
1031 tagUid = e->NewByteArray(data.length);
1032 if(data.length > 0)
1033 {
1034 e->SetByteArrayRegion(tagUid, 0, data.length, (jbyte *)data.buffer);
1035 }
1036 e->SetObjectField(tag, f, tagUid);
1037
1038 /* Generate technology list */
1039 jintArray techList;
1040 jintArray handleList;
1041 jintArray typeList;
1042 nfc_jni_get_technology_tree(e, psRemoteDevList,
1043 multi_protocol ? uNofRemoteDev : 1,
1044 &techList, &handleList, &typeList);
1045
1046 /* Push the technology list into the java object */
1047 f = e->GetFieldID(tag_cls, "mTechList", "[I");
1048 e->SetObjectField(tag, f, techList);
1049
1050 f = e->GetFieldID(tag_cls, "mTechHandles", "[I");
1051 e->SetObjectField(tag, f, handleList);
1052
1053 f = e->GetFieldID(tag_cls, "mTechLibNfcTypes", "[I");
1054 e->SetObjectField(tag, f, typeList);
1055
1056 f = e->GetFieldID(tag_cls, "mConnectedTechIndex", "I");
1057 e->SetIntField(tag, f,(jint)-1);
1058
1059 f = e->GetFieldID(tag_cls, "mConnectedHandle", "I");
1060 e->SetIntField(tag, f,(jint)-1);
1061 }
1062
1063 storedHandle = remDevHandle;
1064 if (nat->tag != NULL) {
1065 e->DeleteGlobalRef(nat->tag);
1066 }
1067 nat->tag = e->NewGlobalRef(tag);
1068
1069 /* Notify the service */
1070 TRACE("Notify Nfc Service");
1071 if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
1072 || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target))
1073 {
1074 /* Store the hanlde of the P2P device */
1075 hLlcpHandle = remDevHandle;
1076
1077 /* Notify manager that new a P2P device was found */
1078 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkActivation, tag);
1079 if(e->ExceptionCheck())
1080 {
1081 ALOGE("Exception occured");
1082 kill_client(nat);
1083 }
1084 }
1085 else
1086 {
1087 /* Notify manager that new a tag was found */
1088 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyNdefMessageListeners, tag);
1089 if(e->ExceptionCheck())
1090 {
1091 ALOGE("Exception occured");
1092 kill_client(nat);
1093 }
1094 }
1095 e->DeleteLocalRef(tag);
1096 }
1097 }
1098
nfc_jni_init_callback(void * pContext,NFCSTATUS status)1099 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status)
1100 {
1101 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
1102
1103 LOG_CALLBACK("nfc_jni_init_callback", status);
1104
1105 pContextData->status = status;
1106 sem_post(&pContextData->sem);
1107 }
1108
nfc_jni_deinit_callback(void * pContext,NFCSTATUS status)1109 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status)
1110 {
1111 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
1112
1113 LOG_CALLBACK("nfc_jni_deinit_callback", status);
1114
1115 pContextData->status = status;
1116 sem_post(&pContextData->sem);
1117 }
1118
1119 /* Set Secure Element mode callback*/
nfc_jni_smartMX_setModeCb(void * pContext,phLibNfc_Handle hSecureElement,NFCSTATUS status)1120 static void nfc_jni_smartMX_setModeCb (void* pContext,
1121 phLibNfc_Handle hSecureElement,
1122 NFCSTATUS status)
1123 {
1124 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
1125
1126 LOG_CALLBACK("nfc_jni_smartMX_setModeCb", status);
1127
1128 pContextData->status = status;
1129 sem_post(&pContextData->sem);
1130 }
1131
1132 /* Card Emulation callback */
nfc_jni_transaction_callback(void * context,phLibNfc_eSE_EvtType_t evt_type,phLibNfc_Handle handle,phLibNfc_uSeEvtInfo_t * evt_info,NFCSTATUS status)1133 static void nfc_jni_transaction_callback(void *context,
1134 phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle,
1135 phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status)
1136 {
1137 JNIEnv *e;
1138 jobject tmp_array = NULL;
1139 jobject mifare_block = NULL;
1140 struct nfc_jni_native_data *nat;
1141 phNfc_sData_t *aid;
1142 phNfc_sData_t *mifare_command;
1143 struct nfc_jni_callback_data *pCallbackData;
1144 int i=0;
1145
1146 LOG_CALLBACK("nfc_jni_transaction_callback", status);
1147
1148 nat = (struct nfc_jni_native_data *)context;
1149
1150 nat->vm->GetEnv( (void **)&e, nat->env_version);
1151
1152 if(status == NFCSTATUS_SUCCESS)
1153 {
1154 switch(evt_type)
1155 {
1156 case phLibNfc_eSE_EvtStartTransaction:
1157 {
1158 TRACE("> SE EVT_START_TRANSACTION");
1159 if(evt_info->UiccEvtInfo.aid.length <= AID_MAXLEN)
1160 {
1161 aid = &(evt_info->UiccEvtInfo.aid);
1162
1163 ALOGD("> AID DETECTED");
1164
1165 if(aid != NULL)
1166 {
1167 if (TRACE_ENABLED == 1) {
1168 char aid_str[AID_MAXLEN * 2 + 1];
1169 aid_str[0] = '\0';
1170 for (i = 0; i < (int) (aid->length) && i < AID_MAXLEN; i++) {
1171 snprintf(&aid_str[i*2], 3, "%02x", aid->buffer[i]);
1172 }
1173 ALOGD("> AID: %s", aid_str);
1174 }
1175 tmp_array = e->NewByteArray(aid->length);
1176 if (tmp_array == NULL)
1177 {
1178 goto error;
1179 }
1180
1181 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, aid->length, (jbyte *)aid->buffer);
1182 if(e->ExceptionCheck())
1183 {
1184 goto error;
1185 }
1186 }
1187 else
1188 {
1189 goto error;
1190 }
1191
1192 TRACE("Notify Nfc Service");
1193 /* Notify manager that a new event occurred on a SE */
1194 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTransactionListeners, tmp_array);
1195 if(e->ExceptionCheck())
1196 {
1197 goto error;
1198 }
1199 }
1200 else
1201 {
1202 ALOGD("> NO AID DETECTED");
1203 }
1204 }break;
1205
1206 case phLibNfc_eSE_EvtApduReceived:
1207 {
1208 phNfc_sData_t *apdu = &(evt_info->UiccEvtInfo.aid);
1209 TRACE("> SE EVT_APDU_RECEIVED");
1210
1211 if (apdu != NULL) {
1212 TRACE(" APDU length=%d", apdu->length);
1213 tmp_array = e->NewByteArray(apdu->length);
1214 if (tmp_array == NULL) {
1215 goto error;
1216 }
1217 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, apdu->length, (jbyte *)apdu->buffer);
1218 if (e->ExceptionCheck()) {
1219 goto error;
1220 }
1221 } else {
1222 TRACE(" APDU EMPTY");
1223 }
1224
1225 TRACE("Notify Nfc Service");
1226 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeApduReceived, tmp_array);
1227 }break;
1228
1229 case phLibNfc_eSE_EvtCardRemoval:
1230 {
1231 TRACE("> SE EVT_EMV_CARD_REMOVAL");
1232 TRACE("Notify Nfc Service");
1233 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeEmvCardRemoval);
1234 }break;
1235
1236 case phLibNfc_eSE_EvtMifareAccess:
1237 {
1238 TRACE("> SE EVT_MIFARE_ACCESS");
1239 mifare_command = &(evt_info->UiccEvtInfo.aid);
1240 TRACE("> MIFARE Block: %d",mifare_command->buffer[1]);
1241 tmp_array = e->NewByteArray(2);
1242 if (tmp_array == NULL)
1243 {
1244 goto error;
1245 }
1246
1247 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, 2, (jbyte *)mifare_command->buffer);
1248 if(e->ExceptionCheck())
1249 {
1250 goto error;
1251 }
1252 TRACE("Notify Nfc Service");
1253 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeMifareAccess, mifare_block);
1254 }break;
1255
1256 case phLibNfc_eSE_EvtFieldOn:
1257 {
1258 TRACE("> SE EVT_FIELD_ON");
1259 TRACE("Notify Nfc Service");
1260 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldActivated);
1261 }break;
1262
1263 case phLibNfc_eSE_EvtFieldOff:
1264 {
1265 TRACE("> SE EVT_FIELD_OFF");
1266 TRACE("Notify Nfc Service");
1267 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldDeactivated);
1268 }break;
1269
1270 default:
1271 {
1272 TRACE("Unknown SE event");
1273 }break;
1274 }
1275 }
1276 else
1277 {
1278 ALOGE("SE transaction notification error");
1279 goto error;
1280 }
1281
1282 /* Function finished, now clean and return */
1283 goto clean_and_return;
1284
1285 error:
1286 /* In case of error, just discard the notification */
1287 ALOGE("Failed to send SE transaction notification");
1288 e->ExceptionClear();
1289
1290 clean_and_return:
1291 if(tmp_array != NULL)
1292 {
1293 e->DeleteLocalRef(tmp_array);
1294 }
1295 }
1296
nfc_jni_se_set_mode_callback(void * pContext,phLibNfc_Handle handle,NFCSTATUS status)1297 static void nfc_jni_se_set_mode_callback(void *pContext,
1298 phLibNfc_Handle handle, NFCSTATUS status)
1299 {
1300 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
1301
1302 LOG_CALLBACK("nfc_jni_se_set_mode_callback", status);
1303
1304 pContextData->status = status;
1305 sem_post(&pContextData->sem);
1306 }
1307
1308 /*
1309 * NFCManager methods
1310 */
1311
nfc_jni_start_discovery_locked(struct nfc_jni_native_data * nat,bool resume)1312 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume)
1313 {
1314 NFCSTATUS ret;
1315 struct nfc_jni_callback_data cb_data;
1316
1317 /* Create the local semaphore */
1318 if (!nfc_cb_data_init(&cb_data, NULL))
1319 {
1320 goto clean_and_return;
1321 }
1322 /* Reset the PN544 ISO XCHG / sw watchdog timeouts */
1323 nfc_jni_reset_timeout_values();
1324
1325 /* Reload the p2p modes */
1326 nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes; //initiator
1327 nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes; //target
1328 nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE;
1329
1330 /* Reset device connected flag */
1331 device_connected_flag = 0;
1332
1333 /* Start Polling loop */
1334 TRACE("****** Start NFC Discovery ******");
1335 REENTRANCE_LOCK();
1336 ret = phLibNfc_Mgt_ConfigureDiscovery(resume ? NFC_DISCOVERY_RESUME : NFC_DISCOVERY_CONFIG,
1337 nat->discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
1338 REENTRANCE_UNLOCK();
1339 TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n",
1340 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"",
1341 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"",
1342 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"",
1343 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"",
1344 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"",
1345 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"",
1346 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"",
1347 nat->discovery_cfg.NfcIP_Mode, nat->discovery_cfg.Duration, ret);
1348
1349 if(ret != NFCSTATUS_PENDING)
1350 {
1351 emergency_recovery(nat);
1352 goto clean_and_return;
1353 }
1354
1355 /* Wait for callback response */
1356 if(sem_wait(&cb_data.sem))
1357 {
1358 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1359 goto clean_and_return;
1360 }
1361
1362 clean_and_return:
1363 nfc_cb_data_deinit(&cb_data);
1364 }
1365
nfc_jni_stop_discovery_locked(struct nfc_jni_native_data * nat)1366 static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat)
1367 {
1368 phLibNfc_sADD_Cfg_t discovery_cfg;
1369 NFCSTATUS ret;
1370 struct nfc_jni_callback_data cb_data;
1371
1372 /* Create the local semaphore */
1373 if (!nfc_cb_data_init(&cb_data, NULL))
1374 {
1375 goto clean_and_return;
1376 }
1377
1378 discovery_cfg.PollDevInfo.PollEnabled = 0;
1379 discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode;
1380 discovery_cfg.NfcIP_Target_Mode = 0;
1381 discovery_cfg.NfcIP_Tgt_Disable = TRUE;
1382
1383 /* Start Polling loop */
1384 TRACE("****** Stop NFC Discovery ******");
1385 REENTRANCE_LOCK();
1386 ret = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_CONFIG,discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
1387 REENTRANCE_UNLOCK();
1388 TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n",
1389 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"",
1390 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"",
1391 discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"",
1392 discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"",
1393 discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"",
1394 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"",
1395 discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"",
1396 discovery_cfg.NfcIP_Mode, discovery_cfg.Duration, ret);
1397
1398 if(ret != NFCSTATUS_PENDING)
1399 {
1400 emergency_recovery(nat);
1401 }
1402
1403 /* Wait for callback response */
1404 if(sem_wait(&cb_data.sem))
1405 {
1406 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1407 goto clean_and_return;
1408 }
1409
1410 clean_and_return:
1411 nfc_cb_data_deinit(&cb_data);
1412 }
1413
1414
com_android_nfc_NfcManager_disableDiscovery(JNIEnv * e,jobject o)1415 static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o)
1416 {
1417 struct nfc_jni_native_data *nat;
1418
1419 CONCURRENCY_LOCK();
1420
1421 /* Retrieve native structure address */
1422 nat = nfc_jni_get_nat(e, o);
1423
1424 nfc_jni_stop_discovery_locked(nat);
1425
1426 CONCURRENCY_UNLOCK();
1427
1428 }
1429
com_android_nfc_NfcManager_enableDiscovery(JNIEnv * e,jobject o)1430 static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o) {
1431 NFCSTATUS ret;
1432 struct nfc_jni_native_data *nat;
1433
1434 CONCURRENCY_LOCK();
1435
1436 nat = nfc_jni_get_nat(e, o);
1437
1438 /* Register callback for remote device notifications.
1439 * Must re-register every time we turn on discovery, since other operations
1440 * (such as opening the Secure Element) can change the remote device
1441 * notification callback*/
1442 REENTRANCE_LOCK();
1443 ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat);
1444 REENTRANCE_UNLOCK();
1445 if(ret != NFCSTATUS_SUCCESS)
1446 {
1447 ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret);
1448 goto clean_and_return;
1449 }
1450 TRACE("phLibNfc_RemoteDev_NtfRegister(%s-%s-%s-%s-%s-%s-%s-%s) returned 0x%x\n",
1451 nat->registry_info.Jewel==TRUE?"J":"",
1452 nat->registry_info.MifareUL==TRUE?"UL":"",
1453 nat->registry_info.MifareStd==TRUE?"Mi":"",
1454 nat->registry_info.Felica==TRUE?"F":"",
1455 nat->registry_info.ISO14443_4A==TRUE?"4A":"",
1456 nat->registry_info.ISO14443_4B==TRUE?"4B":"",
1457 nat->registry_info.NFC==TRUE?"P2P":"",
1458 nat->registry_info.ISO15693==TRUE?"R":"", ret);
1459
1460 nfc_jni_start_discovery_locked(nat, false);
1461 clean_and_return:
1462 CONCURRENCY_UNLOCK();
1463 }
1464
com_android_nfc_NfcManager_doResetTimeouts(JNIEnv * e,jobject o)1465 static void com_android_nfc_NfcManager_doResetTimeouts( JNIEnv *e, jobject o) {
1466 CONCURRENCY_LOCK();
1467 nfc_jni_reset_timeout_values();
1468 CONCURRENCY_UNLOCK();
1469 }
1470
setFelicaTimeout(jint timeout)1471 static void setFelicaTimeout(jint timeout) {
1472 // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms.
1473 // It can be set to 0 to disable the timeout altogether, in which case we
1474 // use the sw watchdog as a fallback.
1475 if (timeout <= 255) {
1476 phLibNfc_SetFelicaTimeout(timeout);
1477 } else {
1478 // Disable hw timeout, use sw watchdog for timeout
1479 phLibNfc_SetFelicaTimeout(0);
1480 phLibNfc_SetHciTimeout(timeout);
1481 }
1482
1483 }
1484 // Calculates ceiling log2 of value
log2(int value)1485 static unsigned int log2(int value) {
1486 unsigned int ret = 0;
1487 bool isPowerOf2 = ((value & (value - 1)) == 0);
1488 while ( (value >> ret) > 1 ) ret++;
1489 if (!isPowerOf2) ret++;
1490 return ret;
1491 }
1492
1493 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X
1494 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X
1495 //
1496 // We keep the constant part of the formula in a static; note the factor
1497 // 1000 off, which is due to the fact that the formula calculates seconds,
1498 // but this method gets milliseconds as an argument.
1499 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0;
1500
calcTimeout(int timeout_in_ms)1501 static int calcTimeout(int timeout_in_ms) {
1502 // timeout = (256 * 16 / 13560000) * 2 ^ X
1503 // First find the first X for which timeout > requested timeout
1504 return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor)));
1505 }
1506
setIsoDepTimeout(jint timeout)1507 static void setIsoDepTimeout(jint timeout) {
1508 if (timeout <= 4900) {
1509 int value = calcTimeout(timeout);
1510 // Then re-compute the actual timeout based on X
1511 double actual_timeout = nxp_nfc_timeout_factor * (1 << value);
1512 // Set the sw watchdog a bit longer (The PN544 timeout is very accurate,
1513 // but it will take some time to get back through the sw layers.
1514 // 500 ms should be enough).
1515 phLibNfc_SetHciTimeout(ceil(actual_timeout + 500));
1516 value |= 0x10; // bit 4 to enable timeout
1517 phLibNfc_SetIsoXchgTimeout(value);
1518 }
1519 else {
1520 // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout
1521 // must be disabled completely, to prevent the PN544 from aborting
1522 // the transaction. We reuse the HCI sw watchdog to catch the timeout
1523 // in that case.
1524 phLibNfc_SetIsoXchgTimeout(0x00);
1525 phLibNfc_SetHciTimeout(timeout);
1526 }
1527 }
1528
setNfcATimeout(jint timeout)1529 static void setNfcATimeout(jint timeout) {
1530 if (timeout <= 4900) {
1531 int value = calcTimeout(timeout);
1532 phLibNfc_SetMifareRawTimeout(value);
1533 }
1534 else {
1535 // Disable mifare raw timeout, use HCI sw watchdog instead
1536 phLibNfc_SetMifareRawTimeout(0x00);
1537 phLibNfc_SetHciTimeout(timeout);
1538 }
1539 }
1540
com_android_nfc_NfcManager_doSetTimeout(JNIEnv * e,jobject o,jint tech,jint timeout)1541 static bool com_android_nfc_NfcManager_doSetTimeout( JNIEnv *e, jobject o,
1542 jint tech, jint timeout) {
1543 bool success = false;
1544 CONCURRENCY_LOCK();
1545 if (timeout <= 0) {
1546 ALOGE("Timeout must be positive.");
1547 return false;
1548 } else {
1549 switch (tech) {
1550 case TARGET_TYPE_MIFARE_CLASSIC:
1551 case TARGET_TYPE_MIFARE_UL:
1552 // Intentional fall-through, Mifare UL, Classic
1553 // transceive just uses raw 3A frames
1554 case TARGET_TYPE_ISO14443_3A:
1555 setNfcATimeout(timeout);
1556 success = true;
1557 break;
1558 case TARGET_TYPE_ISO14443_4:
1559 setIsoDepTimeout(timeout);
1560 success = true;
1561 break;
1562 case TARGET_TYPE_FELICA:
1563 setFelicaTimeout(timeout);
1564 success = true;
1565 break;
1566 default:
1567 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech);
1568 success = false;
1569 }
1570 }
1571 CONCURRENCY_UNLOCK();
1572 return success;
1573 }
1574
com_android_nfc_NfcManager_doGetTimeout(JNIEnv * e,jobject o,jint tech)1575 static jint com_android_nfc_NfcManager_doGetTimeout( JNIEnv *e, jobject o,
1576 jint tech) {
1577 int timeout = -1;
1578 CONCURRENCY_LOCK();
1579 switch (tech) {
1580 case TARGET_TYPE_MIFARE_CLASSIC:
1581 case TARGET_TYPE_MIFARE_UL:
1582 // Intentional fall-through, Mifare UL, Classic
1583 // transceive just uses raw 3A frames
1584 case TARGET_TYPE_ISO14443_3A:
1585 timeout = phLibNfc_GetMifareRawTimeout();
1586 if (timeout == 0) {
1587 timeout = phLibNfc_GetHciTimeout();
1588 } else {
1589 // Timeout returned from libnfc needs conversion to ms
1590 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
1591 }
1592 break;
1593 case TARGET_TYPE_ISO14443_4:
1594 timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only
1595 if (timeout == 0) {
1596 timeout = phLibNfc_GetHciTimeout();
1597 } else {
1598 // Timeout returned from libnfc needs conversion to ms
1599 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
1600 }
1601 break;
1602 case TARGET_TYPE_FELICA:
1603 timeout = phLibNfc_GetFelicaTimeout();
1604 if (timeout == 0) {
1605 timeout = phLibNfc_GetHciTimeout();
1606 } else {
1607 // Felica timeout already in ms
1608 }
1609 break;
1610 default:
1611 ALOGW("doGetTimeout: Timeout not supported for tech %d", tech);
1612 break;
1613 }
1614 CONCURRENCY_UNLOCK();
1615 return timeout;
1616 }
1617
1618
com_android_nfc_NfcManager_init_native_struc(JNIEnv * e,jobject o)1619 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o)
1620 {
1621 NFCSTATUS status;
1622 struct nfc_jni_native_data *nat = NULL;
1623 jclass cls;
1624 jobject obj;
1625 jfieldID f;
1626
1627 TRACE("****** Init Native Structure ******");
1628
1629 /* Initialize native structure */
1630 nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
1631 if(nat == NULL)
1632 {
1633 ALOGD("malloc of nfc_jni_native_data failed");
1634 return FALSE;
1635 }
1636 memset(nat, 0, sizeof(*nat));
1637 e->GetJavaVM(&(nat->vm));
1638 nat->env_version = e->GetVersion();
1639 nat->manager = e->NewGlobalRef(o);
1640
1641 cls = e->GetObjectClass(o);
1642 f = e->GetFieldID(cls, "mNative", "I");
1643 e->SetIntField(o, f, (jint)nat);
1644
1645 /* Initialize native cached references */
1646 cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls,
1647 "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
1648
1649 cached_NfcManager_notifyTransactionListeners = e->GetMethodID(cls,
1650 "notifyTransactionListeners", "([B)V");
1651
1652 cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls,
1653 "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
1654
1655 cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls,
1656 "notifyLlcpLinkDeactivated","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
1657
1658 cached_NfcManager_notifyTargetDeselected = e->GetMethodID(cls,
1659 "notifyTargetDeselected","()V");
1660
1661 cached_NfcManager_notifySeFieldActivated = e->GetMethodID(cls,
1662 "notifySeFieldActivated", "()V");
1663
1664 cached_NfcManager_notifySeFieldDeactivated = e->GetMethodID(cls,
1665 "notifySeFieldDeactivated", "()V");
1666
1667 cached_NfcManager_notifySeApduReceived= e->GetMethodID(cls,
1668 "notifySeApduReceived", "([B)V");
1669
1670 cached_NfcManager_notifySeMifareAccess = e->GetMethodID(cls,
1671 "notifySeMifareAccess", "([B)V");
1672
1673 cached_NfcManager_notifySeEmvCardRemoval = e->GetMethodID(cls,
1674 "notifySeEmvCardRemoval", "()V");
1675
1676 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeNfcTag",&(nat->cached_NfcTag)) == -1)
1677 {
1678 ALOGD("Native Structure initialization failed");
1679 return FALSE;
1680 }
1681
1682 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1)
1683 {
1684 ALOGD("Native Structure initialization failed");
1685 return FALSE;
1686 }
1687 TRACE("****** Init Native Structure OK ******");
1688 return TRUE;
1689
1690 }
1691
1692 /* Init/Deinit method */
com_android_nfc_NfcManager_initialize(JNIEnv * e,jobject o)1693 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o)
1694 {
1695 struct nfc_jni_native_data *nat = NULL;
1696 int init_result = JNI_FALSE;
1697 #ifdef TNFC_EMULATOR_ONLY
1698 char value[PROPERTY_VALUE_MAX];
1699 #endif
1700 jboolean result;
1701
1702 CONCURRENCY_LOCK();
1703
1704 #ifdef TNFC_EMULATOR_ONLY
1705 if (!property_get("ro.kernel.qemu", value, 0))
1706 {
1707 ALOGE("NFC Initialization failed: not running in an emulator\n");
1708 goto clean_and_return;
1709 }
1710 #endif
1711
1712 /* Retrieve native structure address */
1713 nat = nfc_jni_get_nat(e, o);
1714
1715 nat->seId = SMX_SECURE_ELEMENT_ID;
1716
1717 nat->lto = 150; // LLCP_LTO
1718 nat->miu = 128; // LLCP_MIU
1719 // WKS indicates well-known services; 1 << sap for each supported SAP.
1720 // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4)
1721 nat->wks = 0x13; // LLCP_WKS
1722 nat->opt = 0; // LLCP_OPT
1723 nat->p2p_initiator_modes = phNfc_eP2P_ALL;
1724 nat->p2p_target_modes = 0x0E; // All passive except 106, active
1725 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
1726 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
1727 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE;
1728 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE;
1729 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE;
1730 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE;
1731 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
1732
1733 nat->registry_info.MifareUL = TRUE;
1734 nat->registry_info.MifareStd = TRUE;
1735 nat->registry_info.ISO14443_4A = TRUE;
1736 nat->registry_info.ISO14443_4B = TRUE;
1737 nat->registry_info.Jewel = TRUE;
1738 nat->registry_info.Felica = TRUE;
1739 nat->registry_info.NFC = TRUE;
1740 nat->registry_info.ISO15693 = TRUE;
1741
1742 exported_nat = nat;
1743
1744 /* Perform the initialization */
1745 init_result = nfc_jni_initialize(nat);
1746
1747 clean_and_return:
1748 CONCURRENCY_UNLOCK();
1749
1750 /* Convert the result and return */
1751 return (init_result==TRUE)?JNI_TRUE:JNI_FALSE;
1752 }
1753
com_android_nfc_NfcManager_deinitialize(JNIEnv * e,jobject o)1754 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o)
1755 {
1756 struct timespec ts;
1757 NFCSTATUS status;
1758 int result = JNI_FALSE;
1759 struct nfc_jni_native_data *nat;
1760 int bStackReset = FALSE;
1761 struct nfc_jni_callback_data cb_data;
1762
1763 CONCURRENCY_LOCK();
1764
1765 /* Retrieve native structure address */
1766 nat = nfc_jni_get_nat(e, o);
1767
1768 /* Clear previous configuration */
1769 memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t));
1770 memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t));
1771
1772 /* Create the local semaphore */
1773 if (nfc_cb_data_init(&cb_data, NULL))
1774 {
1775 TRACE("phLibNfc_Mgt_DeInitialize()");
1776 REENTRANCE_LOCK();
1777 status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data);
1778 REENTRANCE_UNLOCK();
1779 if (status == NFCSTATUS_PENDING)
1780 {
1781 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
1782
1783 clock_gettime(CLOCK_REALTIME, &ts);
1784 ts.tv_sec += 5;
1785
1786 /* Wait for callback response */
1787 if(sem_timedwait(&cb_data.sem, &ts) == -1)
1788 {
1789 ALOGW("Operation timed out");
1790 bStackReset = TRUE;
1791 }
1792
1793 if(cb_data.status != NFCSTATUS_SUCCESS)
1794 {
1795 ALOGE("Failed to deinit the stack");
1796 bStackReset = TRUE;
1797 }
1798 }
1799 else
1800 {
1801 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
1802 bStackReset = TRUE;
1803 }
1804 nfc_cb_data_deinit(&cb_data);
1805 }
1806 else
1807 {
1808 ALOGE("Failed to create semaphore (errno=0x%08x)", errno);
1809 bStackReset = TRUE;
1810 }
1811
1812 kill_client(nat);
1813
1814 if(bStackReset == TRUE)
1815 {
1816 /* Complete deinit. failed, try hard restart of NFC */
1817 ALOGW("Reseting stack...");
1818 emergency_recovery(nat);
1819 }
1820
1821 result = nfc_jni_unconfigure_driver(nat);
1822
1823 TRACE("NFC Deinitialized");
1824
1825 CONCURRENCY_UNLOCK();
1826
1827 return TRUE;
1828 }
1829
1830 /* Secure Element methods */
com_android_nfc_NfcManager_doGetSecureElementList(JNIEnv * e,jobject o)1831 static jintArray com_android_nfc_NfcManager_doGetSecureElementList(JNIEnv *e, jobject o) {
1832 NFCSTATUS ret;
1833 jintArray list= NULL;
1834 phLibNfc_SE_List_t se_list[PHLIBNFC_MAXNO_OF_SE];
1835 uint8_t i, se_count = PHLIBNFC_MAXNO_OF_SE;
1836
1837 TRACE("****** Get Secure Element List ******");
1838
1839 TRACE("phLibNfc_SE_GetSecureElementList()");
1840 REENTRANCE_LOCK();
1841 ret = phLibNfc_SE_GetSecureElementList(se_list, &se_count);
1842 REENTRANCE_UNLOCK();
1843 if (ret != NFCSTATUS_SUCCESS) {
1844 ALOGE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret,
1845 nfc_jni_get_status_name(ret));
1846 return list;
1847 }
1848 TRACE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret,
1849 nfc_jni_get_status_name(ret));
1850
1851 TRACE("Nb SE: %d", se_count);
1852 list =e->NewIntArray(se_count);
1853 for (i = 0; i < se_count; i++) {
1854 if (se_list[i].eSE_Type == phLibNfc_SE_Type_SmartMX) {
1855 ALOGD("phLibNfc_SE_GetSecureElementList(): SMX detected");
1856 ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement);
1857 } else if(se_list[i].eSE_Type == phLibNfc_SE_Type_UICC) {
1858 ALOGD("phLibNfc_SE_GetSecureElementList(): UICC detected");
1859 ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement);
1860 }
1861 e->SetIntArrayRegion(list, i, 1, (jint*)&se_list[i].hSecureElement);
1862 }
1863
1864 e->DeleteLocalRef(list);
1865
1866 return list;
1867 }
1868
com_android_nfc_NfcManager_doSelectSecureElement(JNIEnv * e,jobject o)1869 static void com_android_nfc_NfcManager_doSelectSecureElement(JNIEnv *e, jobject o) {
1870 NFCSTATUS ret;
1871 struct nfc_jni_native_data *nat;
1872 struct nfc_jni_callback_data cb_data;
1873
1874 CONCURRENCY_LOCK();
1875
1876 /* Retrieve native structure address */
1877 nat = nfc_jni_get_nat(e, o);
1878
1879 /* Create the local semaphore */
1880 if (!nfc_cb_data_init(&cb_data, NULL)) {
1881 goto clean_and_return;
1882 }
1883
1884 TRACE("****** Select Secure Element ******");
1885
1886 TRACE("phLibNfc_SE_SetMode()");
1887 /* Set SE mode - Virtual */
1888 REENTRANCE_LOCK();
1889 ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeVirtualVolatile, nfc_jni_se_set_mode_callback,
1890 (void *)&cb_data);
1891 REENTRANCE_UNLOCK();
1892 if (ret != NFCSTATUS_PENDING) {
1893 ALOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1894 goto clean_and_return;
1895 }
1896 TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1897
1898 /* Wait for callback response */
1899 if (sem_wait(&cb_data.sem)) {
1900 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1901 goto clean_and_return;
1902 }
1903
1904 clean_and_return:
1905 nfc_cb_data_deinit(&cb_data);
1906 CONCURRENCY_UNLOCK();
1907 }
1908
com_android_nfc_NfcManager_doDeselectSecureElement(JNIEnv * e,jobject o)1909 static void com_android_nfc_NfcManager_doDeselectSecureElement(JNIEnv *e, jobject o) {
1910 NFCSTATUS ret;
1911 struct nfc_jni_native_data *nat;
1912 struct nfc_jni_callback_data cb_data;
1913
1914 CONCURRENCY_LOCK();
1915
1916 /* Retrieve native structure address */
1917 nat = nfc_jni_get_nat(e, o);
1918
1919 /* Create the local semaphore */
1920 if (!nfc_cb_data_init(&cb_data, NULL)) {
1921 goto clean_and_return;
1922 }
1923
1924 TRACE("****** Deselect Secure Element ******");
1925
1926 TRACE("phLibNfc_SE_SetMode()");
1927 /* Set SE mode - Default */
1928 REENTRANCE_LOCK();
1929 ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeDefault,
1930 nfc_jni_se_set_mode_callback, (void *)&cb_data);
1931 REENTRANCE_UNLOCK();
1932
1933 TRACE("phLibNfc_SE_SetMode returned 0x%02x", ret);
1934 if (ret != NFCSTATUS_PENDING) {
1935 ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1936 goto clean_and_return;
1937 }
1938 TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1939
1940 /* Wait for callback response */
1941 if (sem_wait(&cb_data.sem)) {
1942 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1943 goto clean_and_return;
1944 }
1945
1946 clean_and_return:
1947 nfc_cb_data_deinit(&cb_data);
1948 CONCURRENCY_UNLOCK();
1949 }
1950
1951 /* Llcp methods */
1952
com_android_nfc_NfcManager_doCheckLlcp(JNIEnv * e,jobject o)1953 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o)
1954 {
1955 NFCSTATUS ret;
1956 bool freeData = false;
1957 jboolean result = JNI_FALSE;
1958 struct nfc_jni_native_data *nat;
1959 struct nfc_jni_callback_data *cb_data;
1960
1961
1962 CONCURRENCY_LOCK();
1963
1964 /* Memory allocation for cb_data
1965 * This is on the heap because it is used by libnfc
1966 * even after this call has succesfully finished. It is only freed
1967 * upon link closure in nfc_jni_llcp_linkStatus_callback.
1968 */
1969 cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data));
1970
1971 /* Retrieve native structure address */
1972 nat = nfc_jni_get_nat(e, o);
1973
1974 /* Create the local semaphore */
1975 if (!nfc_cb_data_init(cb_data, (void*)nat))
1976 {
1977 goto clean_and_return;
1978 }
1979
1980 /* Check LLCP compliancy */
1981 TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle);
1982 REENTRANCE_LOCK();
1983 ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle,
1984 nfc_jni_checkLlcp_callback,
1985 nfc_jni_llcp_linkStatus_callback,
1986 (void*)cb_data);
1987 REENTRANCE_UNLOCK();
1988 /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol
1989 * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */
1990 if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS)
1991 {
1992 ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1993 freeData = true;
1994 goto clean_and_return;
1995 }
1996 TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1997
1998 /* Wait for callback response */
1999 if(sem_wait(&cb_data->sem))
2000 {
2001 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
2002 goto clean_and_return;
2003 }
2004
2005 if(cb_data->status == NFCSTATUS_SUCCESS)
2006 {
2007 result = JNI_TRUE;
2008 }
2009
2010 clean_and_return:
2011 nfc_cb_data_deinit(cb_data);
2012 if (freeData) {
2013 free(cb_data);
2014 }
2015 CONCURRENCY_UNLOCK();
2016 return result;
2017 }
2018
com_android_nfc_NfcManager_doActivateLlcp(JNIEnv * e,jobject o)2019 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv *e, jobject o)
2020 {
2021 NFCSTATUS ret;
2022 TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle);
2023 REENTRANCE_LOCK();
2024 ret = phLibNfc_Llcp_Activate(hLlcpHandle);
2025 REENTRANCE_UNLOCK();
2026 if(ret == NFCSTATUS_SUCCESS)
2027 {
2028 TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2029 return JNI_TRUE;
2030 }
2031 else
2032 {
2033 ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2034 return JNI_FALSE;
2035 }
2036 }
2037
2038
2039
com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv * e,jobject o,jint nSap,jstring sn)2040 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o,
2041 jint nSap, jstring sn)
2042 {
2043 NFCSTATUS ret;
2044 jobject connectionlessSocket = NULL;
2045 phLibNfc_Handle hLlcpSocket;
2046 struct nfc_jni_native_data *nat;
2047 phNfc_sData_t sWorkingBuffer = {NULL, 0};
2048 phNfc_sData_t serviceName = {NULL, 0};
2049 phLibNfc_Llcp_sLinkParameters_t sParams;
2050 jclass clsNativeConnectionlessSocket;
2051 jfieldID f;
2052
2053 /* Retrieve native structure address */
2054 nat = nfc_jni_get_nat(e, o);
2055
2056 /* Allocate Working buffer length */
2057 phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams);
2058 sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP
2059 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2060
2061 /* Create socket */
2062 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)");
2063 REENTRANCE_LOCK();
2064 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess,
2065 NULL,
2066 &sWorkingBuffer,
2067 &hLlcpSocket,
2068 nfc_jni_llcp_transport_socket_err_callback,
2069 (void*)nat);
2070 REENTRANCE_UNLOCK();
2071
2072 if(ret != NFCSTATUS_SUCCESS)
2073 {
2074 lastErrorStatus = ret;
2075 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2076 goto error;
2077 }
2078 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2079
2080 /* Service socket */
2081 if (sn == NULL) {
2082 serviceName.buffer = NULL;
2083 serviceName.length = 0;
2084 } else {
2085 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
2086 serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
2087 }
2088
2089 /* Bind socket */
2090 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2091 REENTRANCE_LOCK();
2092 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
2093 REENTRANCE_UNLOCK();
2094 if(ret != NFCSTATUS_SUCCESS)
2095 {
2096 lastErrorStatus = ret;
2097 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2098 /* Close socket created */
2099 REENTRANCE_LOCK();
2100 ret = phLibNfc_Llcp_Close(hLlcpSocket);
2101 REENTRANCE_UNLOCK();
2102 goto error;
2103 }
2104 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2105
2106
2107 /* Create new NativeLlcpConnectionlessSocket object */
2108 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1)
2109 {
2110 goto error;
2111 }
2112
2113 /* Get NativeConnectionless class object */
2114 clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket);
2115 if(e->ExceptionCheck())
2116 {
2117 goto error;
2118 }
2119
2120 /* Set socket handle */
2121 f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I");
2122 e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket);
2123 TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket);
2124
2125 /* Set the miu link of the connectionless socket */
2126 f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I");
2127 e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT);
2128 TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT);
2129
2130 /* Set socket SAP */
2131 f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I");
2132 e->SetIntField(connectionlessSocket, f,(jint)nSap);
2133 TRACE("Connectionless socket SAP = %d\n",nSap);
2134
2135 return connectionlessSocket;
2136 error:
2137 if (serviceName.buffer != NULL) {
2138 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
2139 }
2140
2141 if (sWorkingBuffer.buffer != NULL) {
2142 free(sWorkingBuffer.buffer);
2143 }
2144
2145 return NULL;
2146 }
2147
com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv * e,jobject o,jint nSap,jstring sn,jint miu,jint rw,jint linearBufferLength)2148 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength)
2149 {
2150 NFCSTATUS ret;
2151 phLibNfc_Handle hLlcpSocket;
2152 phLibNfc_Llcp_sSocketOptions_t sOptions;
2153 phNfc_sData_t sWorkingBuffer;
2154 phNfc_sData_t serviceName;
2155 struct nfc_jni_native_data *nat;
2156 jobject serviceSocket = NULL;
2157 jclass clsNativeLlcpServiceSocket;
2158 jfieldID f;
2159
2160 /* Retrieve native structure address */
2161 nat = nfc_jni_get_nat(e, o);
2162
2163 /* Set Connection Oriented socket options */
2164 sOptions.miu = miu;
2165 sOptions.rw = rw;
2166
2167 /* Allocate Working buffer length */
2168 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
2169 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2170
2171
2172 /* Create socket */
2173 TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle);
2174 REENTRANCE_LOCK();
2175 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
2176 &sOptions,
2177 &sWorkingBuffer,
2178 &hLlcpSocket,
2179 nfc_jni_llcp_transport_socket_err_callback,
2180 (void*)nat);
2181 REENTRANCE_UNLOCK();
2182
2183 if(ret != NFCSTATUS_SUCCESS)
2184 {
2185 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2186 lastErrorStatus = ret;
2187 goto error;
2188 }
2189 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2190
2191 /* Service socket */
2192 if (sn == NULL) {
2193 serviceName.buffer = NULL;
2194 serviceName.length = 0;
2195 } else {
2196 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
2197 serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
2198 }
2199
2200 /* Bind socket */
2201 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2202 REENTRANCE_LOCK();
2203 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
2204 REENTRANCE_UNLOCK();
2205 if(ret != NFCSTATUS_SUCCESS)
2206 {
2207 lastErrorStatus = ret;
2208 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2209 /* Close socket created */
2210 ret = phLibNfc_Llcp_Close(hLlcpSocket);
2211 goto error;
2212 }
2213 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2214
2215 TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket);
2216 REENTRANCE_LOCK();
2217 ret = phLibNfc_Llcp_Listen( hLlcpSocket,
2218 nfc_jni_llcp_transport_listen_socket_callback,
2219 (void*)hLlcpSocket);
2220 REENTRANCE_UNLOCK();
2221
2222 if(ret != NFCSTATUS_SUCCESS)
2223 {
2224 ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2225 lastErrorStatus = ret;
2226 /* Close created socket */
2227 REENTRANCE_LOCK();
2228 ret = phLibNfc_Llcp_Close(hLlcpSocket);
2229 REENTRANCE_UNLOCK();
2230 goto error;
2231 }
2232 TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2233
2234 /* Create new NativeLlcpServiceSocket object */
2235 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1)
2236 {
2237 ALOGE("Llcp Socket object creation error");
2238 goto error;
2239 }
2240
2241 /* Get NativeLlcpServiceSocket class object */
2242 clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket);
2243 if(e->ExceptionCheck())
2244 {
2245 ALOGE("Llcp Socket get object class error");
2246 goto error;
2247 }
2248
2249 /* Set socket handle */
2250 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I");
2251 e->SetIntField(serviceSocket, f,(jint)hLlcpSocket);
2252 TRACE("Service socket Handle = %02x\n",hLlcpSocket);
2253
2254 /* Set socket linear buffer length */
2255 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I");
2256 e->SetIntField(serviceSocket, f,(jint)linearBufferLength);
2257 TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength);
2258
2259 /* Set socket MIU */
2260 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I");
2261 e->SetIntField(serviceSocket, f,(jint)miu);
2262 TRACE("Service socket MIU = %d\n",miu);
2263
2264 /* Set socket RW */
2265 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I");
2266 e->SetIntField(serviceSocket, f,(jint)rw);
2267 TRACE("Service socket RW = %d\n",rw);
2268
2269 return serviceSocket;
2270 error:
2271 if (serviceName.buffer != NULL) {
2272 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
2273 }
2274 return NULL;
2275 }
2276
com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv * e,jobject o,jint nSap,jint miu,jint rw,jint linearBufferLength)2277 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength)
2278 {
2279 jobject clientSocket = NULL;
2280 NFCSTATUS ret;
2281 phLibNfc_Handle hLlcpSocket;
2282 phLibNfc_Llcp_sSocketOptions_t sOptions;
2283 phNfc_sData_t sWorkingBuffer;
2284 struct nfc_jni_native_data *nat;
2285 jclass clsNativeLlcpSocket;
2286 jfieldID f;
2287
2288 /* Retrieve native structure address */
2289 nat = nfc_jni_get_nat(e, o);
2290
2291 /* Set Connection Oriented socket options */
2292 sOptions.miu = miu;
2293 sOptions.rw = rw;
2294
2295 /* Allocate Working buffer length */
2296 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
2297 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2298
2299 /* Create socket */
2300 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)");
2301 REENTRANCE_LOCK();
2302 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
2303 &sOptions,
2304 &sWorkingBuffer,
2305 &hLlcpSocket,
2306 nfc_jni_llcp_transport_socket_err_callback,
2307 (void*)nat);
2308 REENTRANCE_UNLOCK();
2309
2310 if(ret != NFCSTATUS_SUCCESS)
2311 {
2312 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2313 lastErrorStatus = ret;
2314 return NULL;
2315 }
2316 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2317
2318 /* Create new NativeLlcpSocket object */
2319 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1)
2320 {
2321 ALOGE("Llcp socket object creation error");
2322 return NULL;
2323 }
2324
2325 /* Get NativeConnectionless class object */
2326 clsNativeLlcpSocket = e->GetObjectClass(clientSocket);
2327 if(e->ExceptionCheck())
2328 {
2329 ALOGE("Get class object error");
2330 return NULL;
2331 }
2332
2333 /* Test if an SAP number is present */
2334 if(nSap != 0)
2335 {
2336 /* Bind socket */
2337 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2338 REENTRANCE_LOCK();
2339 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL);
2340 REENTRANCE_UNLOCK();
2341 if(ret != NFCSTATUS_SUCCESS)
2342 {
2343 lastErrorStatus = ret;
2344 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2345 /* Close socket created */
2346 REENTRANCE_LOCK();
2347 ret = phLibNfc_Llcp_Close(hLlcpSocket);
2348 REENTRANCE_UNLOCK();
2349 return NULL;
2350 }
2351 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2352
2353 /* Set socket SAP */
2354 f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I");
2355 e->SetIntField(clientSocket, f,(jint)nSap);
2356 TRACE("socket SAP = %d\n",nSap);
2357 }
2358
2359 /* Set socket handle */
2360 f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I");
2361 e->SetIntField(clientSocket, f,(jint)hLlcpSocket);
2362 TRACE("socket Handle = %02x\n",hLlcpSocket);
2363
2364 /* Set socket MIU */
2365 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I");
2366 e->SetIntField(clientSocket, f,(jint)miu);
2367 TRACE("socket MIU = %d\n",miu);
2368
2369 /* Set socket RW */
2370 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I");
2371 e->SetIntField(clientSocket, f,(jint)rw);
2372 TRACE("socket RW = %d\n",rw);
2373
2374
2375 return clientSocket;
2376 }
2377
com_android_nfc_NfcManager_doGetLastError(JNIEnv * e,jobject o)2378 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv *e, jobject o)
2379 {
2380 TRACE("Last Error Status = 0x%02x",lastErrorStatus);
2381
2382 if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL)
2383 {
2384 return ERROR_BUFFER_TOO_SMALL;
2385 }
2386 else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES)
2387 {
2388 return ERROR_INSUFFICIENT_RESOURCES;
2389 }
2390 else
2391 {
2392 return lastErrorStatus;
2393 }
2394 }
2395
com_android_nfc_NfcManager_doAbort(JNIEnv * e,jobject o)2396 static void com_android_nfc_NfcManager_doAbort(JNIEnv *e, jobject o)
2397 {
2398 emergency_recovery(NULL);
2399 }
2400
com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv * e,jobject o,jint modes)2401 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o,
2402 jint modes)
2403 {
2404 ALOGE("Setting init modes to %x", modes);
2405 struct nfc_jni_native_data *nat = NULL;
2406 nat = nfc_jni_get_nat(e, o);
2407 nat->p2p_initiator_modes = modes;
2408 }
2409
com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv * e,jobject o,jint modes)2410 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o,
2411 jint modes)
2412 {
2413 ALOGE("Setting target modes to %x", modes);
2414 struct nfc_jni_native_data *nat = NULL;
2415 nat = nfc_jni_get_nat(e, o);
2416 nat->p2p_target_modes = modes;
2417 }
2418
performDownload(struct nfc_jni_native_data * nat,bool takeLock)2419 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) {
2420 bool result = FALSE;
2421 int load_result;
2422 bool wasDisabled = FALSE;
2423 uint8_t OutputBuffer[1];
2424 uint8_t InputBuffer[1];
2425 NFCSTATUS status = NFCSTATUS_FAILED;
2426 struct nfc_jni_callback_data cb_data;
2427
2428 /* Create the local semaphore */
2429 if (!nfc_cb_data_init(&cb_data, NULL))
2430 {
2431 result = FALSE;
2432 goto clean_and_return;
2433 }
2434
2435 if (takeLock)
2436 {
2437 CONCURRENCY_LOCK();
2438 }
2439
2440 /* Initialize Driver */
2441 if(!driverConfigured)
2442 {
2443 result = nfc_jni_configure_driver(nat);
2444 wasDisabled = TRUE;
2445 }
2446 TRACE("com_android_nfc_NfcManager_doDownload()");
2447
2448 TRACE("Go in Download Mode");
2449 phLibNfc_Download_Mode();
2450
2451 TRACE("Load new Firmware Image");
2452 load_result = phLibNfc_Load_Firmware_Image();
2453 if(load_result != 0)
2454 {
2455 TRACE("Load new Firmware Image - status = %d",load_result);
2456 result = FALSE;
2457 goto clean_and_return;
2458 }
2459
2460 // Download
2461 gInputParam.buffer = InputBuffer;
2462 gInputParam.length = 0x01;
2463 gOutputParam.buffer = OutputBuffer;
2464 gOutputParam.length = 0x01;
2465
2466 ALOGD("Download new Firmware");
2467 REENTRANCE_LOCK();
2468 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
2469 REENTRANCE_UNLOCK();
2470 if(status != NFCSTATUS_PENDING)
2471 {
2472 ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2473 result = FALSE;
2474 goto clean_and_return;
2475 }
2476 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2477
2478 /* Wait for callback response */
2479 if(sem_wait(&cb_data.sem))
2480 {
2481 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
2482 result = FALSE;
2483 goto clean_and_return;
2484 }
2485
2486 /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
2487 try to download an old-style firmware on top of a new-style
2488 firmware. Hence, this is expected behavior, and not an
2489 error condition. */
2490 if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
2491 {
2492 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2493 result = FALSE;
2494 goto clean_and_return;
2495 }
2496
2497 if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
2498 {
2499 ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
2500 }
2501
2502 /*Download is successful*/
2503 result = TRUE;
2504 clean_and_return:
2505 TRACE("phLibNfc_HW_Reset()");
2506 phLibNfc_HW_Reset();
2507 /* Deinitialize Driver */
2508 if(wasDisabled)
2509 {
2510 result = nfc_jni_unconfigure_driver(nat);
2511 }
2512 if (takeLock)
2513 {
2514 CONCURRENCY_UNLOCK();
2515 }
2516 nfc_cb_data_deinit(&cb_data);
2517 return result;
2518 }
2519
com_android_nfc_NfcManager_doDownload(JNIEnv * e,jobject o)2520 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o)
2521 {
2522 struct nfc_jni_native_data *nat = NULL;
2523 nat = nfc_jni_get_nat(e, o);
2524 return performDownload(nat, true);
2525 }
2526
com_android_nfc_NfcManager_doDump(JNIEnv * e,jobject o)2527 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject o)
2528 {
2529 char buffer[100];
2530 snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count);
2531 return e->NewStringUTF(buffer);
2532 }
2533
2534 /*
2535 * JNI registration.
2536 */
2537 static JNINativeMethod gMethods[] =
2538 {
2539 {"doDownload", "()Z",
2540 (void *)com_android_nfc_NfcManager_doDownload},
2541
2542 {"initializeNativeStructure", "()Z",
2543 (void *)com_android_nfc_NfcManager_init_native_struc},
2544
2545 {"doInitialize", "()Z",
2546 (void *)com_android_nfc_NfcManager_initialize},
2547
2548 {"doDeinitialize", "()Z",
2549 (void *)com_android_nfc_NfcManager_deinitialize},
2550
2551 {"enableDiscovery", "()V",
2552 (void *)com_android_nfc_NfcManager_enableDiscovery},
2553
2554 {"doGetSecureElementList", "()[I",
2555 (void *)com_android_nfc_NfcManager_doGetSecureElementList},
2556
2557 {"doSelectSecureElement", "()V",
2558 (void *)com_android_nfc_NfcManager_doSelectSecureElement},
2559
2560 {"doDeselectSecureElement", "()V",
2561 (void *)com_android_nfc_NfcManager_doDeselectSecureElement},
2562
2563 {"doCheckLlcp", "()Z",
2564 (void *)com_android_nfc_NfcManager_doCheckLlcp},
2565
2566 {"doActivateLlcp", "()Z",
2567 (void *)com_android_nfc_NfcManager_doActivateLlcp},
2568
2569 {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;",
2570 (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket},
2571
2572 {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;",
2573 (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket},
2574
2575 {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;",
2576 (void *)com_android_nfc_NfcManager_doCreateLlcpSocket},
2577
2578 {"doGetLastError", "()I",
2579 (void *)com_android_nfc_NfcManager_doGetLastError},
2580
2581 {"disableDiscovery", "()V",
2582 (void *)com_android_nfc_NfcManager_disableDiscovery},
2583
2584 {"doSetTimeout", "(II)Z",
2585 (void *)com_android_nfc_NfcManager_doSetTimeout},
2586
2587 {"doGetTimeout", "(I)I",
2588 (void *)com_android_nfc_NfcManager_doGetTimeout},
2589
2590 {"doResetTimeouts", "()V",
2591 (void *)com_android_nfc_NfcManager_doResetTimeouts},
2592
2593 {"doAbort", "()V",
2594 (void *)com_android_nfc_NfcManager_doAbort},
2595
2596 {"doSetP2pInitiatorModes","(I)V",
2597 (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes},
2598
2599 {"doSetP2pTargetModes","(I)V",
2600 (void *)com_android_nfc_NfcManager_doSetP2pTargetModes},
2601
2602 {"doDump", "()Ljava/lang/String;",
2603 (void *)com_android_nfc_NfcManager_doDump},
2604 };
2605
2606
register_com_android_nfc_NativeNfcManager(JNIEnv * e)2607 int register_com_android_nfc_NativeNfcManager(JNIEnv *e)
2608 {
2609 nfc_jni_native_monitor_t *nfc_jni_native_monitor;
2610
2611 nfc_jni_native_monitor = nfc_jni_init_monitor();
2612 if(nfc_jni_native_monitor == NULL)
2613 {
2614 ALOGE("NFC Manager cannot recover native monitor %x\n", errno);
2615 return -1;
2616 }
2617
2618 return jniRegisterNativeMethods(e,
2619 "com/android/nfc/dhimpl/NativeNfcManager",
2620 gMethods, NELEM(gMethods));
2621 }
2622
2623 } /* namespace android */
2624