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_notifyLlcpLinkActivation;
50 static jmethodID cached_NfcManager_notifyLlcpLinkDeactivated;
51 static jmethodID cached_NfcManager_notifyTargetDeselected;
52
53 static jmethodID cached_NfcManager_notifyRfFieldActivated;
54 static jmethodID cached_NfcManager_notifyRfFieldDeactivated;
55 namespace android {
56
57 phLibNfc_Handle storedHandle = 0;
58
59 struct nfc_jni_native_data *exported_nat = NULL;
60
61 /* Internal functions declaration */
62 static void *nfc_jni_client_thread(void *arg);
63 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status);
64 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status);
65 static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status);
66 static void nfc_jni_se_set_mode_callback(void *context,
67 phLibNfc_Handle handle, NFCSTATUS status);
68 static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status);
69 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume);
70 static void nfc_jni_Discovery_notification_callback(void *pContext,
71 phLibNfc_RemoteDevList_t *psRemoteDevList,
72 uint8_t uNofRemoteDev, NFCSTATUS status);
73 static void nfc_jni_transaction_callback(void *context,
74 phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle,
75 phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status);
76 static bool performDownload(struct nfc_jni_native_data *nat, bool takeLock);
77
78 extern void set_target_activationBytes(JNIEnv *e, jobject tag,
79 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo);
80 extern void set_target_pollBytes(JNIEnv *e, jobject tag,
81 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo);
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 *,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 *)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 *)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 NFCSTATUS ret;
910 const char * typeName;
911 struct timespec ts;
912 phNfc_sData_t data;
913 int i;
914 int target_index = 0; // Target that will be reported (if multiple can be >0)
915
916 struct nfc_jni_native_data* nat = (struct nfc_jni_native_data *)pContext;
917
918 JNIEnv *e;
919 nat->vm->GetEnv( (void **)&e, nat->env_version);
920
921 if(status == NFCSTATUS_DESELECTED)
922 {
923 LOG_CALLBACK("nfc_jni_Discovery_notification_callback: Target deselected", status);
924
925 /* Notify manager that a target was deselected */
926 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTargetDeselected);
927 if(e->ExceptionCheck())
928 {
929 ALOGE("Exception occurred");
930 kill_client(nat);
931 }
932 }
933 else
934 {
935 LOG_CALLBACK("nfc_jni_Discovery_notification_callback", status);
936 TRACE("Discovered %d tags", uNofRemoteDev);
937
938 target_index = find_preferred_target(psRemoteDevList, uNofRemoteDev);
939
940 ScopedLocalRef<jobject> tag(e, NULL);
941
942 /* Reset device connected flag */
943 device_connected_flag = 1;
944 phLibNfc_sRemoteDevInformation_t *remDevInfo = psRemoteDevList[target_index].psRemoteDevInfo;
945 phLibNfc_Handle remDevHandle = psRemoteDevList[target_index].hTargetDev;
946 if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
947 || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target))
948 {
949 ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(nat->cached_P2pDevice));
950 if(e->ExceptionCheck())
951 {
952 ALOGE("Get Object Class Error");
953 kill_client(nat);
954 return;
955 }
956
957 /* New target instance */
958 jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V");
959 tag.reset(e->NewObject(tag_cls.get(), ctor));
960
961 /* Set P2P Target mode */
962 jfieldID f = e->GetFieldID(tag_cls.get(), "mMode", "I");
963
964 if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
965 {
966 ALOGD("Discovered P2P Initiator");
967 e->SetIntField(tag.get(), f, (jint)MODE_P2P_INITIATOR);
968 }
969 else
970 {
971 ALOGD("Discovered P2P Target");
972 e->SetIntField(tag.get(), f, (jint)MODE_P2P_TARGET);
973 }
974
975 if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
976 {
977 /* Set General Bytes */
978 f = e->GetFieldID(tag_cls.get(), "mGeneralBytes", "[B");
979
980 TRACE("General Bytes length =");
981 for(i=0;i<remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length;i++)
982 {
983 ALOGD("%02x ", remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[i]);
984 }
985
986 ScopedLocalRef<jbyteArray> generalBytes(e, e->NewByteArray(remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length));
987
988 e->SetByteArrayRegion(generalBytes.get(), 0,
989 remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length,
990 (jbyte *)remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo);
991 e->SetObjectField(tag.get(), f, generalBytes.get());
992 }
993
994 /* Set tag handle */
995 f = e->GetFieldID(tag_cls.get(), "mHandle", "I");
996 e->SetIntField(tag.get(), f,(jint)remDevHandle);
997 TRACE("Target handle = 0x%08x",remDevHandle);
998 }
999 else
1000 {
1001 ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(nat->cached_NfcTag));
1002 if(e->ExceptionCheck())
1003 {
1004 kill_client(nat);
1005 return;
1006 }
1007
1008 /* New tag instance */
1009 jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V");
1010 tag.reset(e->NewObject(tag_cls.get(), ctor));
1011
1012 bool multi_protocol = false;
1013
1014 if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
1015 {
1016 TRACE("Multiple Protocol TAG detected\n");
1017 multi_protocol = true;
1018 }
1019
1020 /* Set tag UID */
1021 jfieldID f = e->GetFieldID(tag_cls.get(), "mUid", "[B");
1022 data = get_target_uid(remDevInfo);
1023 ScopedLocalRef<jbyteArray> tagUid(e, e->NewByteArray(data.length));
1024 if(data.length > 0)
1025 {
1026 e->SetByteArrayRegion(tagUid.get(), 0, data.length, (jbyte *)data.buffer);
1027 }
1028 e->SetObjectField(tag.get(), f, tagUid.get());
1029
1030 /* Generate technology list */
1031 ScopedLocalRef<jintArray> techList(e, NULL);
1032 ScopedLocalRef<jintArray> handleList(e, NULL);
1033 ScopedLocalRef<jintArray> typeList(e, NULL);
1034 nfc_jni_get_technology_tree(e, psRemoteDevList,
1035 multi_protocol ? uNofRemoteDev : 1,
1036 &techList, &handleList, &typeList);
1037
1038 /* Push the technology list into the java object */
1039 f = e->GetFieldID(tag_cls.get(), "mTechList", "[I");
1040 e->SetObjectField(tag.get(), f, techList.get());
1041
1042 f = e->GetFieldID(tag_cls.get(), "mTechHandles", "[I");
1043 e->SetObjectField(tag.get(), f, handleList.get());
1044
1045 f = e->GetFieldID(tag_cls.get(), "mTechLibNfcTypes", "[I");
1046 e->SetObjectField(tag.get(), f, typeList.get());
1047
1048 f = e->GetFieldID(tag_cls.get(), "mConnectedTechIndex", "I");
1049 e->SetIntField(tag.get(), f,(jint)-1);
1050
1051 f = e->GetFieldID(tag_cls.get(), "mConnectedHandle", "I");
1052 e->SetIntField(tag.get(), f,(jint)-1);
1053
1054 set_target_pollBytes(e, tag.get(), psRemoteDevList->psRemoteDevInfo);
1055
1056 set_target_activationBytes(e, tag.get(), psRemoteDevList->psRemoteDevInfo);
1057 }
1058
1059 storedHandle = remDevHandle;
1060 if (nat->tag != NULL) {
1061 e->DeleteGlobalRef(nat->tag);
1062 }
1063 nat->tag = e->NewGlobalRef(tag.get());
1064
1065 /* Notify the service */
1066 TRACE("Notify Nfc Service");
1067 if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
1068 || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target))
1069 {
1070 /* Store the handle of the P2P device */
1071 hLlcpHandle = remDevHandle;
1072
1073 /* Notify manager that new a P2P device was found */
1074 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkActivation, tag.get());
1075 if(e->ExceptionCheck())
1076 {
1077 ALOGE("Exception occurred");
1078 kill_client(nat);
1079 }
1080 }
1081 else
1082 {
1083 /* Notify manager that new a tag was found */
1084 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyNdefMessageListeners, tag.get());
1085 if(e->ExceptionCheck())
1086 {
1087 ALOGE("Exception occurred");
1088 kill_client(nat);
1089 }
1090 }
1091 }
1092 }
1093
nfc_jni_init_callback(void * pContext,NFCSTATUS status)1094 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status)
1095 {
1096 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
1097
1098 LOG_CALLBACK("nfc_jni_init_callback", status);
1099
1100 pContextData->status = status;
1101 sem_post(&pContextData->sem);
1102 }
1103
nfc_jni_deinit_callback(void * pContext,NFCSTATUS status)1104 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status)
1105 {
1106 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
1107
1108 LOG_CALLBACK("nfc_jni_deinit_callback", status);
1109
1110 pContextData->status = status;
1111 sem_post(&pContextData->sem);
1112 }
1113
1114 /* Set Secure Element mode callback*/
nfc_jni_smartMX_setModeCb(void * pContext,phLibNfc_Handle,NFCSTATUS status)1115 static void nfc_jni_smartMX_setModeCb (void* pContext,
1116 phLibNfc_Handle /*hSecureElement*/,
1117 NFCSTATUS status)
1118 {
1119 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
1120
1121 LOG_CALLBACK("nfc_jni_smartMX_setModeCb", status);
1122
1123 pContextData->status = status;
1124 sem_post(&pContextData->sem);
1125 }
1126
1127 /* Card Emulation callback */
nfc_jni_transaction_callback(void * context,phLibNfc_eSE_EvtType_t evt_type,phLibNfc_Handle,phLibNfc_uSeEvtInfo_t * evt_info,NFCSTATUS status)1128 static void nfc_jni_transaction_callback(void *context,
1129 phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle /*handle*/,
1130 phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status)
1131 {
1132 JNIEnv *e;
1133 jobject tmp_array = NULL;
1134 jobject mifare_block = NULL;
1135 struct nfc_jni_native_data *nat;
1136 phNfc_sData_t *aid;
1137 phNfc_sData_t *mifare_command;
1138 struct nfc_jni_callback_data *pCallbackData;
1139 int i=0;
1140
1141 LOG_CALLBACK("nfc_jni_transaction_callback", status);
1142
1143 nat = (struct nfc_jni_native_data *)context;
1144
1145 nat->vm->GetEnv( (void **)&e, nat->env_version);
1146
1147 if(status == NFCSTATUS_SUCCESS)
1148 {
1149 switch(evt_type)
1150 {
1151 case phLibNfc_eSE_EvtStartTransaction:
1152 {
1153 TRACE("> SE EVT_START_TRANSACTION");
1154 }break;
1155
1156 case phLibNfc_eSE_EvtApduReceived:
1157 {
1158 TRACE("> SE EVT_APDU_RECEIVED");
1159 }break;
1160
1161 case phLibNfc_eSE_EvtCardRemoval:
1162 {
1163 TRACE("> SE EVT_EMV_CARD_REMOVAL");
1164 }break;
1165
1166 case phLibNfc_eSE_EvtMifareAccess:
1167 {
1168 TRACE("> SE EVT_MIFARE_ACCESS");
1169 }break;
1170
1171 case phLibNfc_eSE_EvtFieldOn:
1172 {
1173 TRACE("> SE EVT_FIELD_ON");
1174 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyRfFieldActivated);
1175 }break;
1176
1177 case phLibNfc_eSE_EvtFieldOff:
1178 {
1179 TRACE("> SE EVT_FIELD_OFF");
1180 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyRfFieldDeactivated);
1181 }break;
1182
1183 default:
1184 {
1185 TRACE("Unknown SE event");
1186 }break;
1187 }
1188 }
1189 else
1190 {
1191 ALOGE("SE transaction notification error");
1192 goto error;
1193 }
1194
1195 /* Function finished, now clean and return */
1196 goto clean_and_return;
1197
1198 error:
1199 /* In case of error, just discard the notification */
1200 ALOGE("Failed to send SE transaction notification");
1201 e->ExceptionClear();
1202
1203 clean_and_return:
1204 if(tmp_array != NULL)
1205 {
1206 e->DeleteLocalRef(tmp_array);
1207 }
1208 }
1209
nfc_jni_se_set_mode_callback(void * pContext,phLibNfc_Handle,NFCSTATUS status)1210 static void nfc_jni_se_set_mode_callback(void *pContext,
1211 phLibNfc_Handle /*handle*/, NFCSTATUS status)
1212 {
1213 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
1214
1215 LOG_CALLBACK("nfc_jni_se_set_mode_callback", status);
1216
1217 pContextData->status = status;
1218 sem_post(&pContextData->sem);
1219 }
1220
1221 /*
1222 * NFCManager methods
1223 */
1224
nfc_jni_start_discovery_locked(struct nfc_jni_native_data * nat,bool resume)1225 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume)
1226 {
1227 NFCSTATUS ret;
1228 struct nfc_jni_callback_data cb_data;
1229 int numRetries = 3;
1230
1231 /* Create the local semaphore */
1232 if (!nfc_cb_data_init(&cb_data, NULL))
1233 {
1234 goto clean_and_return;
1235 }
1236 /* Reset the PN544 ISO XCHG / sw watchdog timeouts */
1237 nfc_jni_reset_timeout_values();
1238
1239 /* Reload the p2p modes */
1240 nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes; //initiator
1241 nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes; //target
1242 nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE;
1243
1244 /* Reset device connected flag */
1245 device_connected_flag = 0;
1246 configure:
1247 /* Start Polling loop */
1248 TRACE("****** Start NFC Discovery ******");
1249 REENTRANCE_LOCK();
1250 ret = phLibNfc_Mgt_ConfigureDiscovery(resume ? NFC_DISCOVERY_RESUME : NFC_DISCOVERY_CONFIG,
1251 nat->discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
1252 REENTRANCE_UNLOCK();
1253 TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n",
1254 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"",
1255 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"",
1256 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"",
1257 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"",
1258 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"",
1259 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"",
1260 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"",
1261 nat->discovery_cfg.NfcIP_Mode, nat->discovery_cfg.Duration, ret);
1262
1263 if (ret == NFCSTATUS_BUSY && numRetries-- > 0)
1264 {
1265 TRACE("ConfigDiscovery BUSY, retrying");
1266 usleep(1000000);
1267 goto configure;
1268 }
1269
1270 if(ret != NFCSTATUS_PENDING)
1271 {
1272 emergency_recovery(nat);
1273 goto clean_and_return;
1274 }
1275
1276 /* Wait for callback response */
1277 if(sem_wait(&cb_data.sem))
1278 {
1279 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1280 goto clean_and_return;
1281 }
1282
1283 clean_and_return:
1284 nfc_cb_data_deinit(&cb_data);
1285 }
1286
nfc_jni_stop_discovery_locked(struct nfc_jni_native_data * nat)1287 static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat)
1288 {
1289 phLibNfc_sADD_Cfg_t discovery_cfg;
1290 NFCSTATUS ret;
1291 struct nfc_jni_callback_data cb_data;
1292 int numRetries = 3;
1293
1294 /* Create the local semaphore */
1295 if (!nfc_cb_data_init(&cb_data, NULL))
1296 {
1297 goto clean_and_return;
1298 }
1299
1300 discovery_cfg.PollDevInfo.PollEnabled = 0;
1301 discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode;
1302 discovery_cfg.NfcIP_Target_Mode = 0;
1303 discovery_cfg.NfcIP_Tgt_Disable = TRUE;
1304
1305 configure:
1306 /* Start Polling loop */
1307 TRACE("****** Stop NFC Discovery ******");
1308 REENTRANCE_LOCK();
1309 ret = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_CONFIG,discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
1310 REENTRANCE_UNLOCK();
1311 TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n",
1312 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"",
1313 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"",
1314 discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"",
1315 discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"",
1316 discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"",
1317 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"",
1318 discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"",
1319 discovery_cfg.NfcIP_Mode, discovery_cfg.Duration, ret);
1320
1321 if (ret == NFCSTATUS_BUSY && numRetries-- > 0)
1322 {
1323 TRACE("ConfigDiscovery BUSY, retrying");
1324 usleep(1000000);
1325 goto configure;
1326 }
1327
1328 if(ret != NFCSTATUS_PENDING)
1329 {
1330 ALOGE("[STOP] ConfigDiscovery returned %x", ret);
1331 emergency_recovery(nat);
1332 }
1333
1334 /* Wait for callback response */
1335 if(sem_wait(&cb_data.sem))
1336 {
1337 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1338 goto clean_and_return;
1339 }
1340
1341 clean_and_return:
1342 nfc_cb_data_deinit(&cb_data);
1343 }
1344
1345
com_android_nfc_NfcManager_disableDiscovery(JNIEnv * e,jobject o)1346 static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o)
1347 {
1348 struct nfc_jni_native_data *nat;
1349
1350 CONCURRENCY_LOCK();
1351
1352 /* Retrieve native structure address */
1353 nat = nfc_jni_get_nat(e, o);
1354
1355 nfc_jni_stop_discovery_locked(nat);
1356
1357 CONCURRENCY_UNLOCK();
1358
1359 }
1360
1361 // TODO: use enable_lptd
com_android_nfc_NfcManager_enableDiscovery(JNIEnv * e,jobject o,jint modes,jboolean,jboolean reader_mode,jboolean restart)1362 static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o, jint modes,
1363 jboolean, jboolean reader_mode, jboolean restart)
1364 {
1365 NFCSTATUS ret;
1366 struct nfc_jni_native_data *nat;
1367
1368 CONCURRENCY_LOCK();
1369
1370 nat = nfc_jni_get_nat(e, o);
1371
1372 /* Register callback for remote device notifications.
1373 * Must re-register every time we turn on discovery, since other operations
1374 * (such as opening the Secure Element) can change the remote device
1375 * notification callback*/
1376 REENTRANCE_LOCK();
1377 ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat);
1378 REENTRANCE_UNLOCK();
1379 if(ret != NFCSTATUS_SUCCESS)
1380 {
1381 ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret);
1382 goto clean_and_return;
1383 }
1384 TRACE("phLibNfc_RemoteDev_NtfRegister(%s-%s-%s-%s-%s-%s-%s-%s) returned 0x%x\n",
1385 nat->registry_info.Jewel==TRUE?"J":"",
1386 nat->registry_info.MifareUL==TRUE?"UL":"",
1387 nat->registry_info.MifareStd==TRUE?"Mi":"",
1388 nat->registry_info.Felica==TRUE?"F":"",
1389 nat->registry_info.ISO14443_4A==TRUE?"4A":"",
1390 nat->registry_info.ISO14443_4B==TRUE?"4B":"",
1391 nat->registry_info.NFC==TRUE?"P2P":"",
1392 nat->registry_info.ISO15693==TRUE?"R":"", ret);
1393
1394 if (modes != 0)
1395 {
1396 if (reader_mode)
1397 {
1398 nat->p2p_initiator_modes = 0;
1399 nat->p2p_target_modes = 0;
1400 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE;
1401 nat->discovery_cfg.Duration = 200000; /* in ms */
1402 }
1403 else
1404 {
1405 nat->p2p_initiator_modes = phNfc_eP2P_ALL;
1406 nat->p2p_target_modes = 0x0E; // All passive except 106, active
1407 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
1408 nat->discovery_cfg.Duration = 300000; /* in ms */
1409 }
1410 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = (modes & 0x01) != 0;
1411 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = (modes & 0x02) != 0;
1412 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = (modes & 0x04) != 0;
1413 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = (modes & 0x04) != 0;
1414 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = (modes & 0x08) != 0;
1415 }
1416
1417 nfc_jni_start_discovery_locked(nat, restart);
1418 clean_and_return:
1419 CONCURRENCY_UNLOCK();
1420 }
1421
com_android_nfc_NfcManager_doResetTimeouts(JNIEnv *,jobject)1422 static void com_android_nfc_NfcManager_doResetTimeouts(JNIEnv*, jobject) {
1423 CONCURRENCY_LOCK();
1424 nfc_jni_reset_timeout_values();
1425 CONCURRENCY_UNLOCK();
1426 }
1427
setFelicaTimeout(jint timeout)1428 static void setFelicaTimeout(jint timeout) {
1429 // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms.
1430 // It can be set to 0 to disable the timeout altogether, in which case we
1431 // use the sw watchdog as a fallback.
1432 if (timeout <= 255) {
1433 phLibNfc_SetFelicaTimeout(timeout);
1434 } else {
1435 // Disable hw timeout, use sw watchdog for timeout
1436 phLibNfc_SetFelicaTimeout(0);
1437 phLibNfc_SetHciTimeout(timeout);
1438 }
1439
1440 }
1441 // Calculates ceiling log2 of value
log2(int value)1442 static unsigned int log2(int value) {
1443 unsigned int ret = 0;
1444 bool isPowerOf2 = ((value & (value - 1)) == 0);
1445 while ( (value >> ret) > 1 ) ret++;
1446 if (!isPowerOf2) ret++;
1447 return ret;
1448 }
1449
1450 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X
1451 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X
1452 //
1453 // We keep the constant part of the formula in a static; note the factor
1454 // 1000 off, which is due to the fact that the formula calculates seconds,
1455 // but this method gets milliseconds as an argument.
1456 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0;
1457
calcTimeout(int timeout_in_ms)1458 static int calcTimeout(int timeout_in_ms) {
1459 // timeout = (256 * 16 / 13560000) * 2 ^ X
1460 // First find the first X for which timeout > requested timeout
1461 return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor)));
1462 }
1463
setIsoDepTimeout(jint timeout)1464 static void setIsoDepTimeout(jint timeout) {
1465 if (timeout <= 4900) {
1466 int value = calcTimeout(timeout);
1467 // Then re-compute the actual timeout based on X
1468 double actual_timeout = nxp_nfc_timeout_factor * (1 << value);
1469 // Set the sw watchdog a bit longer (The PN544 timeout is very accurate,
1470 // but it will take some time to get back through the sw layers.
1471 // 500 ms should be enough).
1472 phLibNfc_SetHciTimeout(ceil(actual_timeout + 500));
1473 value |= 0x10; // bit 4 to enable timeout
1474 phLibNfc_SetIsoXchgTimeout(value);
1475 }
1476 else {
1477 // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout
1478 // must be disabled completely, to prevent the PN544 from aborting
1479 // the transaction. We reuse the HCI sw watchdog to catch the timeout
1480 // in that case.
1481 phLibNfc_SetIsoXchgTimeout(0x00);
1482 phLibNfc_SetHciTimeout(timeout);
1483 }
1484 }
1485
setNfcATimeout(jint timeout)1486 static void setNfcATimeout(jint timeout) {
1487 if (timeout <= 4900) {
1488 int value = calcTimeout(timeout);
1489 phLibNfc_SetMifareRawTimeout(value);
1490 }
1491 else {
1492 // Disable mifare raw timeout, use HCI sw watchdog instead
1493 phLibNfc_SetMifareRawTimeout(0x00);
1494 phLibNfc_SetHciTimeout(timeout);
1495 }
1496 }
1497
com_android_nfc_NfcManager_doSetTimeout(JNIEnv *,jobject,jint tech,jint timeout)1498 static bool com_android_nfc_NfcManager_doSetTimeout(JNIEnv*, jobject,
1499 jint tech, jint timeout) {
1500 bool success = false;
1501 CONCURRENCY_LOCK();
1502 if (timeout <= 0) {
1503 ALOGE("Timeout must be positive.");
1504 success = false;
1505 } else {
1506 switch (tech) {
1507 case TARGET_TYPE_MIFARE_CLASSIC:
1508 case TARGET_TYPE_MIFARE_UL:
1509 // Intentional fall-through, Mifare UL, Classic
1510 // transceive just uses raw 3A frames
1511 case TARGET_TYPE_ISO14443_3A:
1512 setNfcATimeout(timeout);
1513 success = true;
1514 break;
1515 case TARGET_TYPE_ISO14443_4:
1516 setIsoDepTimeout(timeout);
1517 success = true;
1518 break;
1519 case TARGET_TYPE_FELICA:
1520 setFelicaTimeout(timeout);
1521 success = true;
1522 break;
1523 default:
1524 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech);
1525 success = false;
1526 }
1527 }
1528 CONCURRENCY_UNLOCK();
1529 return success;
1530 }
1531
com_android_nfc_NfcManager_doGetTimeout(JNIEnv *,jobject,jint tech)1532 static jint com_android_nfc_NfcManager_doGetTimeout(JNIEnv*, jobject,
1533 jint tech) {
1534 int timeout = -1;
1535 CONCURRENCY_LOCK();
1536 switch (tech) {
1537 case TARGET_TYPE_MIFARE_CLASSIC:
1538 case TARGET_TYPE_MIFARE_UL:
1539 // Intentional fall-through, Mifare UL, Classic
1540 // transceive just uses raw 3A frames
1541 case TARGET_TYPE_ISO14443_3A:
1542 timeout = phLibNfc_GetMifareRawTimeout();
1543 if (timeout == 0) {
1544 timeout = phLibNfc_GetHciTimeout();
1545 } else {
1546 // Timeout returned from libnfc needs conversion to ms
1547 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
1548 }
1549 break;
1550 case TARGET_TYPE_ISO14443_4:
1551 timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only
1552 if (timeout == 0) {
1553 timeout = phLibNfc_GetHciTimeout();
1554 } else {
1555 // Timeout returned from libnfc needs conversion to ms
1556 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
1557 }
1558 break;
1559 case TARGET_TYPE_FELICA:
1560 timeout = phLibNfc_GetFelicaTimeout();
1561 if (timeout == 0) {
1562 timeout = phLibNfc_GetHciTimeout();
1563 } else {
1564 // Felica timeout already in ms
1565 }
1566 break;
1567 default:
1568 ALOGW("doGetTimeout: Timeout not supported for tech %d", tech);
1569 break;
1570 }
1571 CONCURRENCY_UNLOCK();
1572 return timeout;
1573 }
1574
1575
com_android_nfc_NfcManager_init_native_struc(JNIEnv * e,jobject o)1576 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o)
1577 {
1578 NFCSTATUS status;
1579 struct nfc_jni_native_data *nat = NULL;
1580 jclass cls;
1581 jobject obj;
1582 jfieldID f;
1583
1584 TRACE("****** Init Native Structure ******");
1585
1586 /* Initialize native structure */
1587 nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
1588 if(nat == NULL)
1589 {
1590 ALOGD("malloc of nfc_jni_native_data failed");
1591 return FALSE;
1592 }
1593 memset(nat, 0, sizeof(*nat));
1594 e->GetJavaVM(&(nat->vm));
1595 nat->env_version = e->GetVersion();
1596 nat->manager = e->NewGlobalRef(o);
1597
1598 cls = e->GetObjectClass(o);
1599 f = e->GetFieldID(cls, "mNative", "J");
1600 e->SetLongField(o, f, (jlong)nat);
1601
1602 /* Initialize native cached references */
1603 cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls,
1604 "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
1605
1606 cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls,
1607 "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
1608
1609 cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls,
1610 "notifyLlcpLinkDeactivated","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
1611
1612 cached_NfcManager_notifyRfFieldActivated = e->GetMethodID(cls,
1613 "notifyRfFieldActivated", "()V");
1614
1615 cached_NfcManager_notifyRfFieldDeactivated = e->GetMethodID(cls,
1616 "notifyRfFieldDeactivated", "()V");
1617
1618 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeNfcTag",&(nat->cached_NfcTag)) == -1)
1619 {
1620 ALOGD("Native Structure initialization failed");
1621 return FALSE;
1622 }
1623
1624 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1)
1625 {
1626 ALOGD("Native Structure initialization failed");
1627 return FALSE;
1628 }
1629 TRACE("****** Init Native Structure OK ******");
1630 return TRUE;
1631
1632 }
1633
1634 /* Init/Deinit method */
com_android_nfc_NfcManager_initialize(JNIEnv * e,jobject o)1635 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o)
1636 {
1637 struct nfc_jni_native_data *nat = NULL;
1638 int init_result = JNI_FALSE;
1639 #ifdef TNFC_EMULATOR_ONLY
1640 char value[PROPERTY_VALUE_MAX];
1641 #endif
1642 jboolean result;
1643
1644 CONCURRENCY_LOCK();
1645
1646 #ifdef TNFC_EMULATOR_ONLY
1647 if (!property_get("ro.kernel.qemu", value, 0))
1648 {
1649 ALOGE("NFC Initialization failed: not running in an emulator\n");
1650 goto clean_and_return;
1651 }
1652 #endif
1653
1654 /* Retrieve native structure address */
1655 nat = nfc_jni_get_nat(e, o);
1656
1657 nat->seId = SMX_SECURE_ELEMENT_ID;
1658
1659 nat->lto = 150; // LLCP_LTO
1660 nat->miu = 128; // LLCP_MIU
1661 // WKS indicates well-known services; 1 << sap for each supported SAP.
1662 // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4)
1663 nat->wks = 0x13; // LLCP_WKS
1664 nat->opt = 0; // LLCP_OPT
1665 nat->p2p_initiator_modes = phNfc_eP2P_ALL;
1666 nat->p2p_target_modes = 0x0E; // All passive except 106, active
1667 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
1668 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
1669 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE;
1670 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE;
1671 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE;
1672 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE;
1673 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
1674
1675 nat->registry_info.MifareUL = TRUE;
1676 nat->registry_info.MifareStd = TRUE;
1677 nat->registry_info.ISO14443_4A = TRUE;
1678 nat->registry_info.ISO14443_4B = TRUE;
1679 nat->registry_info.Jewel = TRUE;
1680 nat->registry_info.Felica = TRUE;
1681 nat->registry_info.NFC = TRUE;
1682 nat->registry_info.ISO15693 = TRUE;
1683
1684 exported_nat = nat;
1685
1686 /* Perform the initialization */
1687 init_result = nfc_jni_initialize(nat);
1688
1689 clean_and_return:
1690 CONCURRENCY_UNLOCK();
1691
1692 /* Convert the result and return */
1693 return (init_result==TRUE)?JNI_TRUE:JNI_FALSE;
1694 }
1695
com_android_nfc_NfcManager_deinitialize(JNIEnv * e,jobject o)1696 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o)
1697 {
1698 struct timespec ts;
1699 NFCSTATUS status;
1700 int result = JNI_FALSE;
1701 struct nfc_jni_native_data *nat;
1702 int bStackReset = FALSE;
1703 struct nfc_jni_callback_data cb_data;
1704
1705 CONCURRENCY_LOCK();
1706
1707 /* Retrieve native structure address */
1708 nat = nfc_jni_get_nat(e, o);
1709
1710 /* Clear previous configuration */
1711 memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t));
1712 memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t));
1713
1714 /* Create the local semaphore */
1715 if (nfc_cb_data_init(&cb_data, NULL))
1716 {
1717 TRACE("phLibNfc_Mgt_DeInitialize()");
1718 REENTRANCE_LOCK();
1719 status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data);
1720 REENTRANCE_UNLOCK();
1721 if (status == NFCSTATUS_PENDING)
1722 {
1723 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
1724
1725 clock_gettime(CLOCK_REALTIME, &ts);
1726 ts.tv_sec += 5;
1727
1728 /* Wait for callback response */
1729 if(sem_timedwait(&cb_data.sem, &ts) == -1)
1730 {
1731 ALOGW("Operation timed out");
1732 bStackReset = TRUE;
1733 }
1734
1735 if(cb_data.status != NFCSTATUS_SUCCESS)
1736 {
1737 ALOGE("Failed to deinit the stack");
1738 bStackReset = TRUE;
1739 }
1740 }
1741 else
1742 {
1743 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
1744 bStackReset = TRUE;
1745 }
1746 nfc_cb_data_deinit(&cb_data);
1747 }
1748 else
1749 {
1750 ALOGE("Failed to create semaphore (errno=0x%08x)", errno);
1751 bStackReset = TRUE;
1752 }
1753
1754 kill_client(nat);
1755
1756 if(bStackReset == TRUE)
1757 {
1758 /* Complete deinit. failed, try hard restart of NFC */
1759 ALOGW("Reseting stack...");
1760 emergency_recovery(nat);
1761 }
1762
1763 result = nfc_jni_unconfigure_driver(nat);
1764
1765 TRACE("NFC Deinitialized");
1766
1767 CONCURRENCY_UNLOCK();
1768
1769 return TRUE;
1770 }
1771
1772 /* Llcp methods */
1773
com_android_nfc_NfcManager_doCheckLlcp(JNIEnv * e,jobject o)1774 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o)
1775 {
1776 NFCSTATUS ret;
1777 bool freeData = false;
1778 jboolean result = JNI_FALSE;
1779 struct nfc_jni_native_data *nat;
1780 struct nfc_jni_callback_data *cb_data;
1781
1782
1783 CONCURRENCY_LOCK();
1784
1785 /* Memory allocation for cb_data
1786 * This is on the heap because it is used by libnfc
1787 * even after this call has succesfully finished. It is only freed
1788 * upon link closure in nfc_jni_llcp_linkStatus_callback.
1789 */
1790 cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data));
1791
1792 /* Retrieve native structure address */
1793 nat = nfc_jni_get_nat(e, o);
1794
1795 /* Create the local semaphore */
1796 if (!nfc_cb_data_init(cb_data, (void*)nat))
1797 {
1798 goto clean_and_return;
1799 }
1800
1801 /* Check LLCP compliancy */
1802 TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle);
1803 REENTRANCE_LOCK();
1804 ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle,
1805 nfc_jni_checkLlcp_callback,
1806 nfc_jni_llcp_linkStatus_callback,
1807 (void*)cb_data);
1808 REENTRANCE_UNLOCK();
1809 /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol
1810 * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */
1811 if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS)
1812 {
1813 ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1814 freeData = true;
1815 goto clean_and_return;
1816 }
1817 TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1818
1819 /* Wait for callback response */
1820 if(sem_wait(&cb_data->sem))
1821 {
1822 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1823 goto clean_and_return;
1824 }
1825
1826 if(cb_data->status == NFCSTATUS_SUCCESS)
1827 {
1828 result = JNI_TRUE;
1829 }
1830
1831 clean_and_return:
1832 nfc_cb_data_deinit(cb_data);
1833 if (freeData) {
1834 free(cb_data);
1835 }
1836 CONCURRENCY_UNLOCK();
1837 return result;
1838 }
1839
com_android_nfc_NfcManager_doActivateLlcp(JNIEnv *,jobject)1840 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv*, jobject)
1841 {
1842 NFCSTATUS ret;
1843 TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle);
1844 REENTRANCE_LOCK();
1845 ret = phLibNfc_Llcp_Activate(hLlcpHandle);
1846 REENTRANCE_UNLOCK();
1847 if(ret == NFCSTATUS_SUCCESS)
1848 {
1849 TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1850 return JNI_TRUE;
1851 }
1852 else
1853 {
1854 ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1855 return JNI_FALSE;
1856 }
1857 }
1858
1859
1860
com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv * e,jobject o,jint nSap,jstring sn)1861 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o,
1862 jint nSap, jstring sn)
1863 {
1864 NFCSTATUS ret;
1865 jobject connectionlessSocket = NULL;
1866 phLibNfc_Handle hLlcpSocket;
1867 struct nfc_jni_native_data *nat;
1868 phNfc_sData_t sWorkingBuffer = {NULL, 0};
1869 phNfc_sData_t serviceName = {NULL, 0};
1870 phLibNfc_Llcp_sLinkParameters_t sParams;
1871 jclass clsNativeConnectionlessSocket;
1872 jfieldID f;
1873
1874 /* Retrieve native structure address */
1875 nat = nfc_jni_get_nat(e, o);
1876
1877 /* Allocate Working buffer length */
1878 phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams);
1879 sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP
1880 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
1881
1882 /* Create socket */
1883 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)");
1884 REENTRANCE_LOCK();
1885 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess,
1886 NULL,
1887 &sWorkingBuffer,
1888 &hLlcpSocket,
1889 nfc_jni_llcp_transport_socket_err_callback,
1890 (void*)nat);
1891 REENTRANCE_UNLOCK();
1892
1893 if(ret != NFCSTATUS_SUCCESS)
1894 {
1895 lastErrorStatus = ret;
1896 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1897 goto error;
1898 }
1899 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1900
1901 /* Service socket */
1902 if (sn == NULL) {
1903 serviceName.buffer = NULL;
1904 serviceName.length = 0;
1905 } else {
1906 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
1907 serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
1908 }
1909
1910 /* Bind socket */
1911 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
1912 REENTRANCE_LOCK();
1913 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
1914 REENTRANCE_UNLOCK();
1915 if(ret != NFCSTATUS_SUCCESS)
1916 {
1917 lastErrorStatus = ret;
1918 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1919 /* Close socket created */
1920 REENTRANCE_LOCK();
1921 ret = phLibNfc_Llcp_Close(hLlcpSocket);
1922 REENTRANCE_UNLOCK();
1923 goto error;
1924 }
1925 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1926
1927
1928 /* Create new NativeLlcpConnectionlessSocket object */
1929 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1)
1930 {
1931 goto error;
1932 }
1933
1934 /* Get NativeConnectionless class object */
1935 clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket);
1936 if(e->ExceptionCheck())
1937 {
1938 goto error;
1939 }
1940
1941 /* Set socket handle */
1942 f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I");
1943 e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket);
1944 TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket);
1945
1946 /* Set the miu link of the connectionless socket */
1947 f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I");
1948 e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT);
1949 TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT);
1950
1951 /* Set socket SAP */
1952 f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I");
1953 e->SetIntField(connectionlessSocket, f,(jint)nSap);
1954 TRACE("Connectionless socket SAP = %d\n",nSap);
1955
1956 return connectionlessSocket;
1957 error:
1958 if (serviceName.buffer != NULL) {
1959 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
1960 }
1961
1962 if (sWorkingBuffer.buffer != NULL) {
1963 free(sWorkingBuffer.buffer);
1964 }
1965
1966 return NULL;
1967 }
1968
com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv * e,jobject o,jint nSap,jstring sn,jint miu,jint rw,jint linearBufferLength)1969 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength)
1970 {
1971 NFCSTATUS ret;
1972 phLibNfc_Handle hLlcpSocket;
1973 phLibNfc_Llcp_sSocketOptions_t sOptions;
1974 phNfc_sData_t sWorkingBuffer;
1975 phNfc_sData_t serviceName;
1976 struct nfc_jni_native_data *nat;
1977 jobject serviceSocket = NULL;
1978 jclass clsNativeLlcpServiceSocket;
1979 jfieldID f;
1980
1981 /* Retrieve native structure address */
1982 nat = nfc_jni_get_nat(e, o);
1983
1984 /* Set Connection Oriented socket options */
1985 sOptions.miu = miu;
1986 sOptions.rw = rw;
1987
1988 /* Allocate Working buffer length */
1989 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
1990 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
1991
1992
1993 /* Create socket */
1994 TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle);
1995 REENTRANCE_LOCK();
1996 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
1997 &sOptions,
1998 &sWorkingBuffer,
1999 &hLlcpSocket,
2000 nfc_jni_llcp_transport_socket_err_callback,
2001 (void*)nat);
2002 REENTRANCE_UNLOCK();
2003
2004 if(ret != NFCSTATUS_SUCCESS)
2005 {
2006 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2007 lastErrorStatus = ret;
2008 goto error;
2009 }
2010 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2011
2012 /* Service socket */
2013 if (sn == NULL) {
2014 serviceName.buffer = NULL;
2015 serviceName.length = 0;
2016 } else {
2017 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
2018 serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
2019 }
2020
2021 /* Bind socket */
2022 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2023 REENTRANCE_LOCK();
2024 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
2025 REENTRANCE_UNLOCK();
2026 if(ret != NFCSTATUS_SUCCESS)
2027 {
2028 lastErrorStatus = ret;
2029 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2030 /* Close socket created */
2031 ret = phLibNfc_Llcp_Close(hLlcpSocket);
2032 goto error;
2033 }
2034 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2035
2036 TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket);
2037 REENTRANCE_LOCK();
2038 ret = phLibNfc_Llcp_Listen( hLlcpSocket,
2039 nfc_jni_llcp_transport_listen_socket_callback,
2040 (void*)hLlcpSocket);
2041 REENTRANCE_UNLOCK();
2042
2043 if(ret != NFCSTATUS_SUCCESS)
2044 {
2045 ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2046 lastErrorStatus = ret;
2047 /* Close created socket */
2048 REENTRANCE_LOCK();
2049 ret = phLibNfc_Llcp_Close(hLlcpSocket);
2050 REENTRANCE_UNLOCK();
2051 goto error;
2052 }
2053 TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2054
2055 /* Create new NativeLlcpServiceSocket object */
2056 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1)
2057 {
2058 ALOGE("Llcp Socket object creation error");
2059 goto error;
2060 }
2061
2062 /* Get NativeLlcpServiceSocket class object */
2063 clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket);
2064 if(e->ExceptionCheck())
2065 {
2066 ALOGE("Llcp Socket get object class error");
2067 goto error;
2068 }
2069
2070 /* Set socket handle */
2071 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I");
2072 e->SetIntField(serviceSocket, f,(jint)hLlcpSocket);
2073 TRACE("Service socket Handle = %02x\n",hLlcpSocket);
2074
2075 /* Set socket linear buffer length */
2076 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I");
2077 e->SetIntField(serviceSocket, f,(jint)linearBufferLength);
2078 TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength);
2079
2080 /* Set socket MIU */
2081 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I");
2082 e->SetIntField(serviceSocket, f,(jint)miu);
2083 TRACE("Service socket MIU = %d\n",miu);
2084
2085 /* Set socket RW */
2086 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I");
2087 e->SetIntField(serviceSocket, f,(jint)rw);
2088 TRACE("Service socket RW = %d\n",rw);
2089
2090 return serviceSocket;
2091 error:
2092 if (serviceName.buffer != NULL) {
2093 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
2094 }
2095 return NULL;
2096 }
2097
com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv * e,jobject o,jint nSap,jint miu,jint rw,jint linearBufferLength)2098 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength)
2099 {
2100 jobject clientSocket = NULL;
2101 NFCSTATUS ret;
2102 phLibNfc_Handle hLlcpSocket;
2103 phLibNfc_Llcp_sSocketOptions_t sOptions;
2104 phNfc_sData_t sWorkingBuffer;
2105 struct nfc_jni_native_data *nat;
2106 jclass clsNativeLlcpSocket;
2107 jfieldID f;
2108
2109 /* Retrieve native structure address */
2110 nat = nfc_jni_get_nat(e, o);
2111
2112 /* Set Connection Oriented socket options */
2113 sOptions.miu = miu;
2114 sOptions.rw = rw;
2115
2116 /* Allocate Working buffer length */
2117 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
2118 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2119
2120 /* Create socket */
2121 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)");
2122 REENTRANCE_LOCK();
2123 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
2124 &sOptions,
2125 &sWorkingBuffer,
2126 &hLlcpSocket,
2127 nfc_jni_llcp_transport_socket_err_callback,
2128 (void*)nat);
2129 REENTRANCE_UNLOCK();
2130
2131 if(ret != NFCSTATUS_SUCCESS)
2132 {
2133 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2134 lastErrorStatus = ret;
2135 return NULL;
2136 }
2137 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2138
2139 /* Create new NativeLlcpSocket object */
2140 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1)
2141 {
2142 ALOGE("Llcp socket object creation error");
2143 return NULL;
2144 }
2145
2146 /* Get NativeConnectionless class object */
2147 clsNativeLlcpSocket = e->GetObjectClass(clientSocket);
2148 if(e->ExceptionCheck())
2149 {
2150 ALOGE("Get class object error");
2151 return NULL;
2152 }
2153
2154 /* Test if an SAP number is present */
2155 if(nSap != 0)
2156 {
2157 /* Bind socket */
2158 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2159 REENTRANCE_LOCK();
2160 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL);
2161 REENTRANCE_UNLOCK();
2162 if(ret != NFCSTATUS_SUCCESS)
2163 {
2164 lastErrorStatus = ret;
2165 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2166 /* Close socket created */
2167 REENTRANCE_LOCK();
2168 ret = phLibNfc_Llcp_Close(hLlcpSocket);
2169 REENTRANCE_UNLOCK();
2170 return NULL;
2171 }
2172 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2173
2174 /* Set socket SAP */
2175 f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I");
2176 e->SetIntField(clientSocket, f,(jint)nSap);
2177 TRACE("socket SAP = %d\n",nSap);
2178 }
2179
2180 /* Set socket handle */
2181 f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I");
2182 e->SetIntField(clientSocket, f,(jint)hLlcpSocket);
2183 TRACE("socket Handle = %02x\n",hLlcpSocket);
2184
2185 /* Set socket MIU */
2186 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I");
2187 e->SetIntField(clientSocket, f,(jint)miu);
2188 TRACE("socket MIU = %d\n",miu);
2189
2190 /* Set socket RW */
2191 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I");
2192 e->SetIntField(clientSocket, f,(jint)rw);
2193 TRACE("socket RW = %d\n",rw);
2194
2195
2196 return clientSocket;
2197 }
2198
com_android_nfc_NfcManager_doGetLastError(JNIEnv *,jobject)2199 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv*, jobject)
2200 {
2201 TRACE("Last Error Status = 0x%02x",lastErrorStatus);
2202
2203 if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL)
2204 {
2205 return ERROR_BUFFER_TOO_SMALL;
2206 }
2207 else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES)
2208 {
2209 return ERROR_INSUFFICIENT_RESOURCES;
2210 }
2211 else
2212 {
2213 return lastErrorStatus;
2214 }
2215 }
2216
com_android_nfc_NfcManager_doAbort(JNIEnv *,jobject)2217 static void com_android_nfc_NfcManager_doAbort(JNIEnv*, jobject)
2218 {
2219 emergency_recovery(NULL);
2220 }
2221
com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv * e,jobject o,jint modes)2222 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o,
2223 jint modes)
2224 {
2225 ALOGE("Setting init modes to %x", modes);
2226 struct nfc_jni_native_data *nat = NULL;
2227 nat = nfc_jni_get_nat(e, o);
2228 nat->p2p_initiator_modes = modes;
2229 }
2230
com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv * e,jobject o,jint modes)2231 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o,
2232 jint modes)
2233 {
2234 ALOGE("Setting target modes to %x", modes);
2235 struct nfc_jni_native_data *nat = NULL;
2236 nat = nfc_jni_get_nat(e, o);
2237 nat->p2p_target_modes = modes;
2238 }
2239
performDownload(struct nfc_jni_native_data * nat,bool takeLock)2240 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) {
2241 bool result = FALSE;
2242 int load_result;
2243 bool wasDisabled = FALSE;
2244 uint8_t OutputBuffer[1];
2245 uint8_t InputBuffer[1];
2246 NFCSTATUS status = NFCSTATUS_FAILED;
2247 struct nfc_jni_callback_data cb_data;
2248
2249 /* Create the local semaphore */
2250 if (!nfc_cb_data_init(&cb_data, NULL))
2251 {
2252 result = FALSE;
2253 goto clean_and_return;
2254 }
2255
2256 if (takeLock)
2257 {
2258 CONCURRENCY_LOCK();
2259 }
2260
2261 /* Initialize Driver */
2262 if(!driverConfigured)
2263 {
2264 result = nfc_jni_configure_driver(nat);
2265 wasDisabled = TRUE;
2266 }
2267 TRACE("com_android_nfc_NfcManager_doDownload()");
2268
2269 TRACE("Go in Download Mode");
2270 phLibNfc_Download_Mode();
2271
2272 TRACE("Load new Firmware Image");
2273 load_result = phLibNfc_Load_Firmware_Image();
2274 if(load_result != 0)
2275 {
2276 TRACE("Load new Firmware Image - status = %d",load_result);
2277 result = FALSE;
2278 goto clean_and_return;
2279 }
2280
2281 // Download
2282 gInputParam.buffer = InputBuffer;
2283 gInputParam.length = 0x01;
2284 gOutputParam.buffer = OutputBuffer;
2285 gOutputParam.length = 0x01;
2286
2287 ALOGD("Download new Firmware");
2288 REENTRANCE_LOCK();
2289 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
2290 REENTRANCE_UNLOCK();
2291 if(status != NFCSTATUS_PENDING)
2292 {
2293 ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2294 result = FALSE;
2295 goto clean_and_return;
2296 }
2297 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2298
2299 /* Wait for callback response */
2300 if(sem_wait(&cb_data.sem))
2301 {
2302 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
2303 result = FALSE;
2304 goto clean_and_return;
2305 }
2306
2307 /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
2308 try to download an old-style firmware on top of a new-style
2309 firmware. Hence, this is expected behavior, and not an
2310 error condition. */
2311 if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
2312 {
2313 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2314 result = FALSE;
2315 goto clean_and_return;
2316 }
2317
2318 if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
2319 {
2320 ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
2321 }
2322
2323 /*Download is successful*/
2324 result = TRUE;
2325 clean_and_return:
2326 TRACE("phLibNfc_HW_Reset()");
2327 phLibNfc_HW_Reset();
2328 /* Deinitialize Driver */
2329 if(wasDisabled)
2330 {
2331 result = nfc_jni_unconfigure_driver(nat);
2332 }
2333 if (takeLock)
2334 {
2335 CONCURRENCY_UNLOCK();
2336 }
2337 nfc_cb_data_deinit(&cb_data);
2338 return result;
2339 }
2340
com_android_nfc_NfcManager_doDownload(JNIEnv * e,jobject o)2341 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o)
2342 {
2343 struct nfc_jni_native_data *nat = NULL;
2344 nat = nfc_jni_get_nat(e, o);
2345 return performDownload(nat, true);
2346 }
2347
com_android_nfc_NfcManager_doDump(JNIEnv * e,jobject)2348 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject)
2349 {
2350 char buffer[100];
2351 snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count);
2352 return e->NewStringUTF(buffer);
2353 }
2354
2355 /*
2356 * JNI registration.
2357 */
2358 static JNINativeMethod gMethods[] =
2359 {
2360 {"doDownload", "()Z",
2361 (void *)com_android_nfc_NfcManager_doDownload},
2362
2363 {"initializeNativeStructure", "()Z",
2364 (void *)com_android_nfc_NfcManager_init_native_struc},
2365
2366 {"doInitialize", "()Z",
2367 (void *)com_android_nfc_NfcManager_initialize},
2368
2369 {"doDeinitialize", "()Z",
2370 (void *)com_android_nfc_NfcManager_deinitialize},
2371
2372 {"doEnableDiscovery", "(IZZZ)V",
2373 (void *)com_android_nfc_NfcManager_enableDiscovery},
2374
2375 {"doCheckLlcp", "()Z",
2376 (void *)com_android_nfc_NfcManager_doCheckLlcp},
2377
2378 {"doActivateLlcp", "()Z",
2379 (void *)com_android_nfc_NfcManager_doActivateLlcp},
2380
2381 {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;",
2382 (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket},
2383
2384 {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;",
2385 (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket},
2386
2387 {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;",
2388 (void *)com_android_nfc_NfcManager_doCreateLlcpSocket},
2389
2390 {"doGetLastError", "()I",
2391 (void *)com_android_nfc_NfcManager_doGetLastError},
2392
2393 {"disableDiscovery", "()V",
2394 (void *)com_android_nfc_NfcManager_disableDiscovery},
2395
2396 {"doSetTimeout", "(II)Z",
2397 (void *)com_android_nfc_NfcManager_doSetTimeout},
2398
2399 {"doGetTimeout", "(I)I",
2400 (void *)com_android_nfc_NfcManager_doGetTimeout},
2401
2402 {"doResetTimeouts", "()V",
2403 (void *)com_android_nfc_NfcManager_doResetTimeouts},
2404
2405 {"doAbort", "()V",
2406 (void *)com_android_nfc_NfcManager_doAbort},
2407
2408 {"doSetP2pInitiatorModes","(I)V",
2409 (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes},
2410
2411 {"doSetP2pTargetModes","(I)V",
2412 (void *)com_android_nfc_NfcManager_doSetP2pTargetModes},
2413
2414 {"doDump", "()Ljava/lang/String;",
2415 (void *)com_android_nfc_NfcManager_doDump},
2416 };
2417
2418
register_com_android_nfc_NativeNfcManager(JNIEnv * e)2419 int register_com_android_nfc_NativeNfcManager(JNIEnv *e)
2420 {
2421 nfc_jni_native_monitor_t *nfc_jni_native_monitor;
2422
2423 nfc_jni_native_monitor = nfc_jni_init_monitor();
2424 if(nfc_jni_native_monitor == NULL)
2425 {
2426 ALOGE("NFC Manager cannot recover native monitor %x\n", errno);
2427 return -1;
2428 }
2429
2430 return jniRegisterNativeMethods(e,
2431 "com/android/nfc/dhimpl/NativeNfcManager",
2432 gMethods, NELEM(gMethods));
2433 }
2434
2435 } /* namespace android */
2436