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 enable_p2p,jboolean restart)1362 static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o, jint modes,
1363 jboolean, jboolean reader_mode, jboolean enable_p2p, 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
1397 if (enable_p2p)
1398 {
1399 nat->p2p_initiator_modes = phNfc_eP2P_ALL;
1400 nat->p2p_target_modes = 0x0E; // All passive except 106, active
1401 nat->discovery_cfg.Duration = 300000; /* in ms */
1402 }
1403 else
1404 {
1405 nat->p2p_initiator_modes = 0;
1406 nat->p2p_target_modes = 0;
1407 nat->discovery_cfg.Duration = 200000; /* in ms */
1408
1409 }
1410
1411 if (reader_mode)
1412 {
1413 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE;
1414 nat->discovery_cfg.Duration = 200000; /* in ms */
1415 }
1416 else
1417 {
1418 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
1419 nat->discovery_cfg.Duration = 300000; /* in ms */
1420 }
1421 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = (modes & 0x01) != 0;
1422 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = (modes & 0x02) != 0;
1423 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = (modes & 0x04) != 0;
1424 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = (modes & 0x04) != 0;
1425 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = (modes & 0x08) != 0;
1426 }
1427
1428 nfc_jni_start_discovery_locked(nat, false);
1429 clean_and_return:
1430 CONCURRENCY_UNLOCK();
1431 }
1432
com_android_nfc_NfcManager_doResetTimeouts(JNIEnv *,jobject)1433 static void com_android_nfc_NfcManager_doResetTimeouts(JNIEnv*, jobject) {
1434 CONCURRENCY_LOCK();
1435 nfc_jni_reset_timeout_values();
1436 CONCURRENCY_UNLOCK();
1437 }
1438
setFelicaTimeout(jint timeout)1439 static void setFelicaTimeout(jint timeout) {
1440 // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms.
1441 // It can be set to 0 to disable the timeout altogether, in which case we
1442 // use the sw watchdog as a fallback.
1443 if (timeout <= 255) {
1444 phLibNfc_SetFelicaTimeout(timeout);
1445 } else {
1446 // Disable hw timeout, use sw watchdog for timeout
1447 phLibNfc_SetFelicaTimeout(0);
1448 phLibNfc_SetHciTimeout(timeout);
1449 }
1450
1451 }
1452 // Calculates ceiling log2 of value
log2(int value)1453 static unsigned int log2(int value) {
1454 unsigned int ret = 0;
1455 bool isPowerOf2 = ((value & (value - 1)) == 0);
1456 while ( (value >> ret) > 1 ) ret++;
1457 if (!isPowerOf2) ret++;
1458 return ret;
1459 }
1460
1461 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X
1462 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X
1463 //
1464 // We keep the constant part of the formula in a static; note the factor
1465 // 1000 off, which is due to the fact that the formula calculates seconds,
1466 // but this method gets milliseconds as an argument.
1467 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0;
1468
calcTimeout(int timeout_in_ms)1469 static int calcTimeout(int timeout_in_ms) {
1470 // timeout = (256 * 16 / 13560000) * 2 ^ X
1471 // First find the first X for which timeout > requested timeout
1472 return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor)));
1473 }
1474
setIsoDepTimeout(jint timeout)1475 static void setIsoDepTimeout(jint timeout) {
1476 if (timeout <= 4900) {
1477 int value = calcTimeout(timeout);
1478 // Then re-compute the actual timeout based on X
1479 double actual_timeout = nxp_nfc_timeout_factor * (1 << value);
1480 // Set the sw watchdog a bit longer (The PN544 timeout is very accurate,
1481 // but it will take some time to get back through the sw layers.
1482 // 500 ms should be enough).
1483 phLibNfc_SetHciTimeout(ceil(actual_timeout + 500));
1484 value |= 0x10; // bit 4 to enable timeout
1485 phLibNfc_SetIsoXchgTimeout(value);
1486 }
1487 else {
1488 // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout
1489 // must be disabled completely, to prevent the PN544 from aborting
1490 // the transaction. We reuse the HCI sw watchdog to catch the timeout
1491 // in that case.
1492 phLibNfc_SetIsoXchgTimeout(0x00);
1493 phLibNfc_SetHciTimeout(timeout);
1494 }
1495 }
1496
setNfcATimeout(jint timeout)1497 static void setNfcATimeout(jint timeout) {
1498 if (timeout <= 4900) {
1499 int value = calcTimeout(timeout);
1500 phLibNfc_SetMifareRawTimeout(value);
1501 }
1502 else {
1503 // Disable mifare raw timeout, use HCI sw watchdog instead
1504 phLibNfc_SetMifareRawTimeout(0x00);
1505 phLibNfc_SetHciTimeout(timeout);
1506 }
1507 }
1508
com_android_nfc_NfcManager_doSetTimeout(JNIEnv *,jobject,jint tech,jint timeout)1509 static bool com_android_nfc_NfcManager_doSetTimeout(JNIEnv*, jobject,
1510 jint tech, jint timeout) {
1511 bool success = false;
1512 CONCURRENCY_LOCK();
1513 if (timeout <= 0) {
1514 ALOGE("Timeout must be positive.");
1515 success = false;
1516 } else {
1517 switch (tech) {
1518 case TARGET_TYPE_MIFARE_CLASSIC:
1519 case TARGET_TYPE_MIFARE_UL:
1520 // Intentional fall-through, Mifare UL, Classic
1521 // transceive just uses raw 3A frames
1522 case TARGET_TYPE_ISO14443_3A:
1523 setNfcATimeout(timeout);
1524 success = true;
1525 break;
1526 case TARGET_TYPE_ISO14443_4:
1527 setIsoDepTimeout(timeout);
1528 success = true;
1529 break;
1530 case TARGET_TYPE_FELICA:
1531 setFelicaTimeout(timeout);
1532 success = true;
1533 break;
1534 default:
1535 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech);
1536 success = false;
1537 }
1538 }
1539 CONCURRENCY_UNLOCK();
1540 return success;
1541 }
1542
com_android_nfc_NfcManager_doGetTimeout(JNIEnv *,jobject,jint tech)1543 static jint com_android_nfc_NfcManager_doGetTimeout(JNIEnv*, jobject,
1544 jint tech) {
1545 int timeout = -1;
1546 CONCURRENCY_LOCK();
1547 switch (tech) {
1548 case TARGET_TYPE_MIFARE_CLASSIC:
1549 case TARGET_TYPE_MIFARE_UL:
1550 // Intentional fall-through, Mifare UL, Classic
1551 // transceive just uses raw 3A frames
1552 case TARGET_TYPE_ISO14443_3A:
1553 timeout = phLibNfc_GetMifareRawTimeout();
1554 if (timeout == 0) {
1555 timeout = phLibNfc_GetHciTimeout();
1556 } else {
1557 // Timeout returned from libnfc needs conversion to ms
1558 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
1559 }
1560 break;
1561 case TARGET_TYPE_ISO14443_4:
1562 timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only
1563 if (timeout == 0) {
1564 timeout = phLibNfc_GetHciTimeout();
1565 } else {
1566 // Timeout returned from libnfc needs conversion to ms
1567 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
1568 }
1569 break;
1570 case TARGET_TYPE_FELICA:
1571 timeout = phLibNfc_GetFelicaTimeout();
1572 if (timeout == 0) {
1573 timeout = phLibNfc_GetHciTimeout();
1574 } else {
1575 // Felica timeout already in ms
1576 }
1577 break;
1578 default:
1579 ALOGW("doGetTimeout: Timeout not supported for tech %d", tech);
1580 break;
1581 }
1582 CONCURRENCY_UNLOCK();
1583 return timeout;
1584 }
1585
1586
com_android_nfc_NfcManager_init_native_struc(JNIEnv * e,jobject o)1587 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o)
1588 {
1589 NFCSTATUS status;
1590 struct nfc_jni_native_data *nat = NULL;
1591 jclass cls;
1592 jobject obj;
1593 jfieldID f;
1594
1595 TRACE("****** Init Native Structure ******");
1596
1597 /* Initialize native structure */
1598 nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
1599 if(nat == NULL)
1600 {
1601 ALOGD("malloc of nfc_jni_native_data failed");
1602 return FALSE;
1603 }
1604 memset(nat, 0, sizeof(*nat));
1605 e->GetJavaVM(&(nat->vm));
1606 nat->env_version = e->GetVersion();
1607 nat->manager = e->NewGlobalRef(o);
1608
1609 cls = e->GetObjectClass(o);
1610 f = e->GetFieldID(cls, "mNative", "J");
1611 e->SetLongField(o, f, (jlong)nat);
1612
1613 /* Initialize native cached references */
1614 cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls,
1615 "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
1616
1617 cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls,
1618 "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
1619
1620 cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls,
1621 "notifyLlcpLinkDeactivated","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
1622
1623 cached_NfcManager_notifyRfFieldActivated = e->GetMethodID(cls,
1624 "notifyRfFieldActivated", "()V");
1625
1626 cached_NfcManager_notifyRfFieldDeactivated = e->GetMethodID(cls,
1627 "notifyRfFieldDeactivated", "()V");
1628
1629 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeNfcTag",&(nat->cached_NfcTag)) == -1)
1630 {
1631 ALOGD("Native Structure initialization failed");
1632 return FALSE;
1633 }
1634
1635 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1)
1636 {
1637 ALOGD("Native Structure initialization failed");
1638 return FALSE;
1639 }
1640 TRACE("****** Init Native Structure OK ******");
1641 return TRUE;
1642
1643 }
1644
1645 /* Init/Deinit method */
com_android_nfc_NfcManager_initialize(JNIEnv * e,jobject o)1646 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o)
1647 {
1648 struct nfc_jni_native_data *nat = NULL;
1649 int init_result = JNI_FALSE;
1650 #ifdef TNFC_EMULATOR_ONLY
1651 char value[PROPERTY_VALUE_MAX];
1652 #endif
1653 jboolean result;
1654
1655 CONCURRENCY_LOCK();
1656
1657 #ifdef TNFC_EMULATOR_ONLY
1658 if (!property_get("ro.kernel.qemu", value, 0))
1659 {
1660 ALOGE("NFC Initialization failed: not running in an emulator\n");
1661 goto clean_and_return;
1662 }
1663 #endif
1664
1665 /* Retrieve native structure address */
1666 nat = nfc_jni_get_nat(e, o);
1667
1668 nat->seId = SMX_SECURE_ELEMENT_ID;
1669
1670 nat->lto = 150; // LLCP_LTO
1671 nat->miu = 128; // LLCP_MIU
1672 // WKS indicates well-known services; 1 << sap for each supported SAP.
1673 // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4)
1674 nat->wks = 0x13; // LLCP_WKS
1675 nat->opt = 0; // LLCP_OPT
1676 nat->p2p_initiator_modes = phNfc_eP2P_ALL;
1677 nat->p2p_target_modes = 0x0E; // All passive except 106, active
1678 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
1679 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
1680 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE;
1681 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE;
1682 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE;
1683 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE;
1684 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
1685
1686 nat->registry_info.MifareUL = TRUE;
1687 nat->registry_info.MifareStd = TRUE;
1688 nat->registry_info.ISO14443_4A = TRUE;
1689 nat->registry_info.ISO14443_4B = TRUE;
1690 nat->registry_info.Jewel = TRUE;
1691 nat->registry_info.Felica = TRUE;
1692 nat->registry_info.NFC = TRUE;
1693 nat->registry_info.ISO15693 = TRUE;
1694
1695 exported_nat = nat;
1696
1697 /* Perform the initialization */
1698 init_result = nfc_jni_initialize(nat);
1699
1700 clean_and_return:
1701 CONCURRENCY_UNLOCK();
1702
1703 /* Convert the result and return */
1704 return (init_result==TRUE)?JNI_TRUE:JNI_FALSE;
1705 }
1706
com_android_nfc_NfcManager_deinitialize(JNIEnv * e,jobject o)1707 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o)
1708 {
1709 struct timespec ts;
1710 NFCSTATUS status;
1711 int result = JNI_FALSE;
1712 struct nfc_jni_native_data *nat;
1713 int bStackReset = FALSE;
1714 struct nfc_jni_callback_data cb_data;
1715
1716 CONCURRENCY_LOCK();
1717
1718 /* Retrieve native structure address */
1719 nat = nfc_jni_get_nat(e, o);
1720
1721 /* Clear previous configuration */
1722 memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t));
1723 memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t));
1724
1725 /* Create the local semaphore */
1726 if (nfc_cb_data_init(&cb_data, NULL))
1727 {
1728 TRACE("phLibNfc_Mgt_DeInitialize()");
1729 REENTRANCE_LOCK();
1730 status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data);
1731 REENTRANCE_UNLOCK();
1732 if (status == NFCSTATUS_PENDING)
1733 {
1734 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
1735
1736 clock_gettime(CLOCK_REALTIME, &ts);
1737 ts.tv_sec += 5;
1738
1739 /* Wait for callback response */
1740 if(sem_timedwait(&cb_data.sem, &ts) == -1)
1741 {
1742 ALOGW("Operation timed out");
1743 bStackReset = TRUE;
1744 }
1745
1746 if(cb_data.status != NFCSTATUS_SUCCESS)
1747 {
1748 ALOGE("Failed to deinit the stack");
1749 bStackReset = TRUE;
1750 }
1751 }
1752 else
1753 {
1754 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
1755 bStackReset = TRUE;
1756 }
1757 nfc_cb_data_deinit(&cb_data);
1758 }
1759 else
1760 {
1761 ALOGE("Failed to create semaphore (errno=0x%08x)", errno);
1762 bStackReset = TRUE;
1763 }
1764
1765 kill_client(nat);
1766
1767 if(bStackReset == TRUE)
1768 {
1769 /* Complete deinit. failed, try hard restart of NFC */
1770 ALOGW("Reseting stack...");
1771 emergency_recovery(nat);
1772 }
1773
1774 result = nfc_jni_unconfigure_driver(nat);
1775
1776 TRACE("NFC Deinitialized");
1777
1778 CONCURRENCY_UNLOCK();
1779
1780 return TRUE;
1781 }
1782
1783 /* Llcp methods */
1784
com_android_nfc_NfcManager_doCheckLlcp(JNIEnv * e,jobject o)1785 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o)
1786 {
1787 NFCSTATUS ret;
1788 bool freeData = false;
1789 jboolean result = JNI_FALSE;
1790 struct nfc_jni_native_data *nat;
1791 struct nfc_jni_callback_data *cb_data;
1792
1793
1794 CONCURRENCY_LOCK();
1795
1796 /* Memory allocation for cb_data
1797 * This is on the heap because it is used by libnfc
1798 * even after this call has succesfully finished. It is only freed
1799 * upon link closure in nfc_jni_llcp_linkStatus_callback.
1800 */
1801 cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data));
1802
1803 /* Retrieve native structure address */
1804 nat = nfc_jni_get_nat(e, o);
1805
1806 /* Create the local semaphore */
1807 if (!nfc_cb_data_init(cb_data, (void*)nat))
1808 {
1809 goto clean_and_return;
1810 }
1811
1812 /* Check LLCP compliancy */
1813 TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle);
1814 REENTRANCE_LOCK();
1815 ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle,
1816 nfc_jni_checkLlcp_callback,
1817 nfc_jni_llcp_linkStatus_callback,
1818 (void*)cb_data);
1819 REENTRANCE_UNLOCK();
1820 /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol
1821 * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */
1822 if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS)
1823 {
1824 ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1825 freeData = true;
1826 goto clean_and_return;
1827 }
1828 TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1829
1830 /* Wait for callback response */
1831 if(sem_wait(&cb_data->sem))
1832 {
1833 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1834 goto clean_and_return;
1835 }
1836
1837 if(cb_data->status == NFCSTATUS_SUCCESS)
1838 {
1839 result = JNI_TRUE;
1840 }
1841
1842 clean_and_return:
1843 nfc_cb_data_deinit(cb_data);
1844 if (freeData) {
1845 free(cb_data);
1846 }
1847 CONCURRENCY_UNLOCK();
1848 return result;
1849 }
1850
com_android_nfc_NfcManager_doActivateLlcp(JNIEnv *,jobject)1851 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv*, jobject)
1852 {
1853 NFCSTATUS ret;
1854 TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle);
1855 REENTRANCE_LOCK();
1856 ret = phLibNfc_Llcp_Activate(hLlcpHandle);
1857 REENTRANCE_UNLOCK();
1858 if(ret == NFCSTATUS_SUCCESS)
1859 {
1860 TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1861 return JNI_TRUE;
1862 }
1863 else
1864 {
1865 ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1866 return JNI_FALSE;
1867 }
1868 }
1869
1870
1871
com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv * e,jobject o,jint nSap,jstring sn)1872 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o,
1873 jint nSap, jstring sn)
1874 {
1875 NFCSTATUS ret;
1876 jobject connectionlessSocket = NULL;
1877 phLibNfc_Handle hLlcpSocket;
1878 struct nfc_jni_native_data *nat;
1879 phNfc_sData_t sWorkingBuffer = {NULL, 0};
1880 phNfc_sData_t serviceName = {NULL, 0};
1881 phLibNfc_Llcp_sLinkParameters_t sParams;
1882 jclass clsNativeConnectionlessSocket;
1883 jfieldID f;
1884
1885 /* Retrieve native structure address */
1886 nat = nfc_jni_get_nat(e, o);
1887
1888 /* Allocate Working buffer length */
1889 phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams);
1890 sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP
1891 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
1892
1893 /* Create socket */
1894 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)");
1895 REENTRANCE_LOCK();
1896 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess,
1897 NULL,
1898 &sWorkingBuffer,
1899 &hLlcpSocket,
1900 nfc_jni_llcp_transport_socket_err_callback,
1901 (void*)nat);
1902 REENTRANCE_UNLOCK();
1903
1904 if(ret != NFCSTATUS_SUCCESS)
1905 {
1906 lastErrorStatus = ret;
1907 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1908 goto error;
1909 }
1910 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1911
1912 /* Service socket */
1913 if (sn == NULL) {
1914 serviceName.buffer = NULL;
1915 serviceName.length = 0;
1916 } else {
1917 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
1918 serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
1919 }
1920
1921 /* Bind socket */
1922 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
1923 REENTRANCE_LOCK();
1924 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
1925 REENTRANCE_UNLOCK();
1926 if(ret != NFCSTATUS_SUCCESS)
1927 {
1928 lastErrorStatus = ret;
1929 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1930 /* Close socket created */
1931 REENTRANCE_LOCK();
1932 ret = phLibNfc_Llcp_Close(hLlcpSocket);
1933 REENTRANCE_UNLOCK();
1934 goto error;
1935 }
1936 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1937
1938
1939 /* Create new NativeLlcpConnectionlessSocket object */
1940 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1)
1941 {
1942 goto error;
1943 }
1944
1945 /* Get NativeConnectionless class object */
1946 clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket);
1947 if(e->ExceptionCheck())
1948 {
1949 goto error;
1950 }
1951
1952 /* Set socket handle */
1953 f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I");
1954 e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket);
1955 TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket);
1956
1957 /* Set the miu link of the connectionless socket */
1958 f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I");
1959 e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT);
1960 TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT);
1961
1962 /* Set socket SAP */
1963 f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I");
1964 e->SetIntField(connectionlessSocket, f,(jint)nSap);
1965 TRACE("Connectionless socket SAP = %d\n",nSap);
1966
1967 return connectionlessSocket;
1968 error:
1969 if (serviceName.buffer != NULL) {
1970 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
1971 }
1972
1973 if (sWorkingBuffer.buffer != NULL) {
1974 free(sWorkingBuffer.buffer);
1975 }
1976
1977 return NULL;
1978 }
1979
com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv * e,jobject o,jint nSap,jstring sn,jint miu,jint rw,jint linearBufferLength)1980 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength)
1981 {
1982 NFCSTATUS ret;
1983 phLibNfc_Handle hLlcpSocket;
1984 phLibNfc_Llcp_sSocketOptions_t sOptions;
1985 phNfc_sData_t sWorkingBuffer;
1986 phNfc_sData_t serviceName;
1987 struct nfc_jni_native_data *nat;
1988 jobject serviceSocket = NULL;
1989 jclass clsNativeLlcpServiceSocket;
1990 jfieldID f;
1991
1992 /* Retrieve native structure address */
1993 nat = nfc_jni_get_nat(e, o);
1994
1995 /* Set Connection Oriented socket options */
1996 sOptions.miu = miu;
1997 sOptions.rw = rw;
1998
1999 /* Allocate Working buffer length */
2000 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
2001 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2002
2003
2004 /* Create socket */
2005 TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle);
2006 REENTRANCE_LOCK();
2007 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
2008 &sOptions,
2009 &sWorkingBuffer,
2010 &hLlcpSocket,
2011 nfc_jni_llcp_transport_socket_err_callback,
2012 (void*)nat);
2013 REENTRANCE_UNLOCK();
2014
2015 if(ret != NFCSTATUS_SUCCESS)
2016 {
2017 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2018 lastErrorStatus = ret;
2019 goto error;
2020 }
2021 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2022
2023 /* Service socket */
2024 if (sn == NULL) {
2025 serviceName.buffer = NULL;
2026 serviceName.length = 0;
2027 } else {
2028 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
2029 serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
2030 }
2031
2032 /* Bind socket */
2033 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2034 REENTRANCE_LOCK();
2035 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
2036 REENTRANCE_UNLOCK();
2037 if(ret != NFCSTATUS_SUCCESS)
2038 {
2039 lastErrorStatus = ret;
2040 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2041 /* Close socket created */
2042 ret = phLibNfc_Llcp_Close(hLlcpSocket);
2043 goto error;
2044 }
2045 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2046
2047 TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket);
2048 REENTRANCE_LOCK();
2049 ret = phLibNfc_Llcp_Listen( hLlcpSocket,
2050 nfc_jni_llcp_transport_listen_socket_callback,
2051 (void*)hLlcpSocket);
2052 REENTRANCE_UNLOCK();
2053
2054 if(ret != NFCSTATUS_SUCCESS)
2055 {
2056 ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2057 lastErrorStatus = ret;
2058 /* Close created socket */
2059 REENTRANCE_LOCK();
2060 ret = phLibNfc_Llcp_Close(hLlcpSocket);
2061 REENTRANCE_UNLOCK();
2062 goto error;
2063 }
2064 TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2065
2066 /* Create new NativeLlcpServiceSocket object */
2067 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1)
2068 {
2069 ALOGE("Llcp Socket object creation error");
2070 goto error;
2071 }
2072
2073 /* Get NativeLlcpServiceSocket class object */
2074 clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket);
2075 if(e->ExceptionCheck())
2076 {
2077 ALOGE("Llcp Socket get object class error");
2078 goto error;
2079 }
2080
2081 /* Set socket handle */
2082 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I");
2083 e->SetIntField(serviceSocket, f,(jint)hLlcpSocket);
2084 TRACE("Service socket Handle = %02x\n",hLlcpSocket);
2085
2086 /* Set socket linear buffer length */
2087 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I");
2088 e->SetIntField(serviceSocket, f,(jint)linearBufferLength);
2089 TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength);
2090
2091 /* Set socket MIU */
2092 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I");
2093 e->SetIntField(serviceSocket, f,(jint)miu);
2094 TRACE("Service socket MIU = %d\n",miu);
2095
2096 /* Set socket RW */
2097 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I");
2098 e->SetIntField(serviceSocket, f,(jint)rw);
2099 TRACE("Service socket RW = %d\n",rw);
2100
2101 return serviceSocket;
2102 error:
2103 if (serviceName.buffer != NULL) {
2104 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
2105 }
2106 return NULL;
2107 }
2108
com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv * e,jobject o,jint nSap,jint miu,jint rw,jint linearBufferLength)2109 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength)
2110 {
2111 jobject clientSocket = NULL;
2112 NFCSTATUS ret;
2113 phLibNfc_Handle hLlcpSocket;
2114 phLibNfc_Llcp_sSocketOptions_t sOptions;
2115 phNfc_sData_t sWorkingBuffer;
2116 struct nfc_jni_native_data *nat;
2117 jclass clsNativeLlcpSocket;
2118 jfieldID f;
2119
2120 /* Retrieve native structure address */
2121 nat = nfc_jni_get_nat(e, o);
2122
2123 /* Set Connection Oriented socket options */
2124 sOptions.miu = miu;
2125 sOptions.rw = rw;
2126
2127 /* Allocate Working buffer length */
2128 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
2129 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2130
2131 /* Create socket */
2132 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)");
2133 REENTRANCE_LOCK();
2134 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
2135 &sOptions,
2136 &sWorkingBuffer,
2137 &hLlcpSocket,
2138 nfc_jni_llcp_transport_socket_err_callback,
2139 (void*)nat);
2140 REENTRANCE_UNLOCK();
2141
2142 if(ret != NFCSTATUS_SUCCESS)
2143 {
2144 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2145 lastErrorStatus = ret;
2146 return NULL;
2147 }
2148 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2149
2150 /* Create new NativeLlcpSocket object */
2151 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1)
2152 {
2153 ALOGE("Llcp socket object creation error");
2154 return NULL;
2155 }
2156
2157 /* Get NativeConnectionless class object */
2158 clsNativeLlcpSocket = e->GetObjectClass(clientSocket);
2159 if(e->ExceptionCheck())
2160 {
2161 ALOGE("Get class object error");
2162 return NULL;
2163 }
2164
2165 /* Test if an SAP number is present */
2166 if(nSap != 0)
2167 {
2168 /* Bind socket */
2169 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2170 REENTRANCE_LOCK();
2171 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL);
2172 REENTRANCE_UNLOCK();
2173 if(ret != NFCSTATUS_SUCCESS)
2174 {
2175 lastErrorStatus = ret;
2176 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2177 /* Close socket created */
2178 REENTRANCE_LOCK();
2179 ret = phLibNfc_Llcp_Close(hLlcpSocket);
2180 REENTRANCE_UNLOCK();
2181 return NULL;
2182 }
2183 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2184
2185 /* Set socket SAP */
2186 f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I");
2187 e->SetIntField(clientSocket, f,(jint)nSap);
2188 TRACE("socket SAP = %d\n",nSap);
2189 }
2190
2191 /* Set socket handle */
2192 f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I");
2193 e->SetIntField(clientSocket, f,(jint)hLlcpSocket);
2194 TRACE("socket Handle = %02x\n",hLlcpSocket);
2195
2196 /* Set socket MIU */
2197 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I");
2198 e->SetIntField(clientSocket, f,(jint)miu);
2199 TRACE("socket MIU = %d\n",miu);
2200
2201 /* Set socket RW */
2202 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I");
2203 e->SetIntField(clientSocket, f,(jint)rw);
2204 TRACE("socket RW = %d\n",rw);
2205
2206
2207 return clientSocket;
2208 }
2209
com_android_nfc_NfcManager_doGetLastError(JNIEnv *,jobject)2210 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv*, jobject)
2211 {
2212 TRACE("Last Error Status = 0x%02x",lastErrorStatus);
2213
2214 if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL)
2215 {
2216 return ERROR_BUFFER_TOO_SMALL;
2217 }
2218 else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES)
2219 {
2220 return ERROR_INSUFFICIENT_RESOURCES;
2221 }
2222 else
2223 {
2224 return lastErrorStatus;
2225 }
2226 }
2227
com_android_nfc_NfcManager_doAbort(JNIEnv *,jobject)2228 static void com_android_nfc_NfcManager_doAbort(JNIEnv*, jobject)
2229 {
2230 emergency_recovery(NULL);
2231 }
2232
com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv * e,jobject o,jint modes)2233 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o,
2234 jint modes)
2235 {
2236 ALOGE("Setting init modes to %x", modes);
2237 struct nfc_jni_native_data *nat = NULL;
2238 nat = nfc_jni_get_nat(e, o);
2239 nat->p2p_initiator_modes = modes;
2240 }
2241
com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv * e,jobject o,jint modes)2242 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o,
2243 jint modes)
2244 {
2245 ALOGE("Setting target modes to %x", modes);
2246 struct nfc_jni_native_data *nat = NULL;
2247 nat = nfc_jni_get_nat(e, o);
2248 nat->p2p_target_modes = modes;
2249 }
2250
performDownload(struct nfc_jni_native_data * nat,bool takeLock)2251 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) {
2252 bool result = FALSE;
2253 int load_result;
2254 bool wasDisabled = FALSE;
2255 uint8_t OutputBuffer[1];
2256 uint8_t InputBuffer[1];
2257 NFCSTATUS status = NFCSTATUS_FAILED;
2258 struct nfc_jni_callback_data cb_data;
2259
2260 /* Create the local semaphore */
2261 if (!nfc_cb_data_init(&cb_data, NULL))
2262 {
2263 result = FALSE;
2264 goto clean_and_return;
2265 }
2266
2267 if (takeLock)
2268 {
2269 CONCURRENCY_LOCK();
2270 }
2271
2272 /* Initialize Driver */
2273 if(!driverConfigured)
2274 {
2275 result = nfc_jni_configure_driver(nat);
2276 wasDisabled = TRUE;
2277 }
2278 TRACE("com_android_nfc_NfcManager_doDownload()");
2279
2280 TRACE("Go in Download Mode");
2281 phLibNfc_Download_Mode();
2282
2283 TRACE("Load new Firmware Image");
2284 load_result = phLibNfc_Load_Firmware_Image();
2285 if(load_result != 0)
2286 {
2287 TRACE("Load new Firmware Image - status = %d",load_result);
2288 result = FALSE;
2289 goto clean_and_return;
2290 }
2291
2292 // Download
2293 gInputParam.buffer = InputBuffer;
2294 gInputParam.length = 0x01;
2295 gOutputParam.buffer = OutputBuffer;
2296 gOutputParam.length = 0x01;
2297
2298 ALOGD("Download new Firmware");
2299 REENTRANCE_LOCK();
2300 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
2301 REENTRANCE_UNLOCK();
2302 if(status != NFCSTATUS_PENDING)
2303 {
2304 ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2305 result = FALSE;
2306 goto clean_and_return;
2307 }
2308 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2309
2310 /* Wait for callback response */
2311 if(sem_wait(&cb_data.sem))
2312 {
2313 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
2314 result = FALSE;
2315 goto clean_and_return;
2316 }
2317
2318 /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
2319 try to download an old-style firmware on top of a new-style
2320 firmware. Hence, this is expected behavior, and not an
2321 error condition. */
2322 if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
2323 {
2324 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2325 result = FALSE;
2326 goto clean_and_return;
2327 }
2328
2329 if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
2330 {
2331 ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
2332 }
2333
2334 /*Download is successful*/
2335 result = TRUE;
2336 clean_and_return:
2337 TRACE("phLibNfc_HW_Reset()");
2338 phLibNfc_HW_Reset();
2339 /* Deinitialize Driver */
2340 if(wasDisabled)
2341 {
2342 result = nfc_jni_unconfigure_driver(nat);
2343 }
2344 if (takeLock)
2345 {
2346 CONCURRENCY_UNLOCK();
2347 }
2348 nfc_cb_data_deinit(&cb_data);
2349 return result;
2350 }
2351
com_android_nfc_NfcManager_doDownload(JNIEnv * e,jobject o)2352 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o)
2353 {
2354 struct nfc_jni_native_data *nat = NULL;
2355 nat = nfc_jni_get_nat(e, o);
2356 return performDownload(nat, true);
2357 }
2358
com_android_nfc_NfcManager_doDump(JNIEnv * e,jobject)2359 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject)
2360 {
2361 char buffer[100];
2362 snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count);
2363 return e->NewStringUTF(buffer);
2364 }
2365
2366 /*
2367 * JNI registration.
2368 */
2369 static JNINativeMethod gMethods[] =
2370 {
2371 {"doDownload", "()Z",
2372 (void *)com_android_nfc_NfcManager_doDownload},
2373
2374 {"initializeNativeStructure", "()Z",
2375 (void *)com_android_nfc_NfcManager_init_native_struc},
2376
2377 {"doInitialize", "()Z",
2378 (void *)com_android_nfc_NfcManager_initialize},
2379
2380 {"doDeinitialize", "()Z",
2381 (void *)com_android_nfc_NfcManager_deinitialize},
2382
2383 {"doEnableDiscovery", "(IZZZZ)V",
2384 (void *)com_android_nfc_NfcManager_enableDiscovery},
2385
2386 {"doCheckLlcp", "()Z",
2387 (void *)com_android_nfc_NfcManager_doCheckLlcp},
2388
2389 {"doActivateLlcp", "()Z",
2390 (void *)com_android_nfc_NfcManager_doActivateLlcp},
2391
2392 {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;",
2393 (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket},
2394
2395 {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;",
2396 (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket},
2397
2398 {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;",
2399 (void *)com_android_nfc_NfcManager_doCreateLlcpSocket},
2400
2401 {"doGetLastError", "()I",
2402 (void *)com_android_nfc_NfcManager_doGetLastError},
2403
2404 {"disableDiscovery", "()V",
2405 (void *)com_android_nfc_NfcManager_disableDiscovery},
2406
2407 {"doSetTimeout", "(II)Z",
2408 (void *)com_android_nfc_NfcManager_doSetTimeout},
2409
2410 {"doGetTimeout", "(I)I",
2411 (void *)com_android_nfc_NfcManager_doGetTimeout},
2412
2413 {"doResetTimeouts", "()V",
2414 (void *)com_android_nfc_NfcManager_doResetTimeouts},
2415
2416 {"doAbort", "()V",
2417 (void *)com_android_nfc_NfcManager_doAbort},
2418
2419 {"doSetP2pInitiatorModes","(I)V",
2420 (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes},
2421
2422 {"doSetP2pTargetModes","(I)V",
2423 (void *)com_android_nfc_NfcManager_doSetP2pTargetModes},
2424
2425 {"doDump", "()Ljava/lang/String;",
2426 (void *)com_android_nfc_NfcManager_doDump},
2427 };
2428
2429
register_com_android_nfc_NativeNfcManager(JNIEnv * e)2430 int register_com_android_nfc_NativeNfcManager(JNIEnv *e)
2431 {
2432 nfc_jni_native_monitor_t *nfc_jni_native_monitor;
2433
2434 nfc_jni_native_monitor = nfc_jni_init_monitor();
2435 if(nfc_jni_native_monitor == NULL)
2436 {
2437 ALOGE("NFC Manager cannot recover native monitor %x\n", errno);
2438 return -1;
2439 }
2440
2441 return jniRegisterNativeMethods(e,
2442 "com/android/nfc/dhimpl/NativeNfcManager",
2443 gMethods, NELEM(gMethods));
2444 }
2445
2446 } /* namespace android */
2447