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