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 <semaphore.h>
18
19 #include "com_android_nfc.h"
20
21 static phNfc_sData_t *com_android_nfc_jni_transceive_buffer;
22 static phNfc_sData_t *com_android_nfc_jni_ioctl_buffer;
23 static phNfc_sRemoteDevInformation_t* SecureElementInfo;
24 static int secureElementHandle;
25 extern void *gHWRef;
26 static int SecureElementTech;
27 extern uint8_t device_connected_flag;
28
29 namespace android {
30
com_android_nfc_jni_ioctl_callback(void * pContext,phNfc_sData_t * Outparam_Cb,NFCSTATUS status)31 static void com_android_nfc_jni_ioctl_callback ( void* pContext,
32 phNfc_sData_t* Outparam_Cb,
33 NFCSTATUS status)
34 {
35 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
36
37 if (status == NFCSTATUS_SUCCESS )
38 {
39 LOG_CALLBACK("> IOCTL successful",status);
40 }
41 else
42 {
43 LOG_CALLBACK("> IOCTL error",status);
44 }
45
46 com_android_nfc_jni_ioctl_buffer = Outparam_Cb;
47 pContextData->status = status;
48 sem_post(&pContextData->sem);
49 }
50
com_android_nfc_jni_transceive_callback(void * pContext,phLibNfc_Handle handle,phNfc_sData_t * pResBuffer,NFCSTATUS status)51 static void com_android_nfc_jni_transceive_callback(void *pContext,
52 phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status)
53 {
54 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
55
56 LOG_CALLBACK("com_android_nfc_jni_transceive_callback", status);
57
58 com_android_nfc_jni_transceive_buffer = pResBuffer;
59 pContextData->status = status;
60 sem_post(&pContextData->sem);
61 }
62
63
com_android_nfc_jni_connect_callback(void * pContext,phLibNfc_Handle hRemoteDev,phLibNfc_sRemoteDevInformation_t * psRemoteDevInfo,NFCSTATUS status)64 static void com_android_nfc_jni_connect_callback(void *pContext,
65 phLibNfc_Handle hRemoteDev,
66 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status)
67 {
68 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
69
70 LOG_CALLBACK("com_android_nfc_jni_connect_callback", status);
71
72 pContextData->status = status;
73 sem_post(&pContextData->sem);
74 }
75
com_android_nfc_jni_disconnect_callback(void * pContext,phLibNfc_Handle hRemoteDev,NFCSTATUS status)76 static void com_android_nfc_jni_disconnect_callback(void *pContext,
77 phLibNfc_Handle hRemoteDev,
78 NFCSTATUS status)
79 {
80 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
81
82 LOG_CALLBACK("com_android_nfc_jni_disconnect_callback", status);
83
84 pContextData->status = status;
85 sem_post(&pContextData->sem);
86 }
87
88 /* Set Secure Element mode callback*/
com_android_nfc_jni_smartMX_setModeCb(void * pContext,phLibNfc_Handle hSecureElement,NFCSTATUS status)89 static void com_android_nfc_jni_smartMX_setModeCb (void* pContext,
90 phLibNfc_Handle hSecureElement,
91 NFCSTATUS status)
92 {
93 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
94
95 if(status==NFCSTATUS_SUCCESS)
96 {
97 LOG_CALLBACK("SE Set Mode is Successful",status);
98 TRACE("SE Handle: %lu", hSecureElement);
99 }
100 else
101 {
102 LOG_CALLBACK("SE Set Mode is failed\n ",status);
103 }
104
105 pContextData->status = status;
106 sem_post(&pContextData->sem);
107 }
108
com_android_nfc_jni_open_secure_element_notification_callback(void * pContext,phLibNfc_RemoteDevList_t * psRemoteDevList,uint8_t uNofRemoteDev,NFCSTATUS status)109 static void com_android_nfc_jni_open_secure_element_notification_callback(void *pContext,
110 phLibNfc_RemoteDevList_t *psRemoteDevList,
111 uint8_t uNofRemoteDev,
112 NFCSTATUS status)
113 {
114 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext;
115 NFCSTATUS ret;
116 int i;
117 JNIEnv *e = nfc_get_env();
118
119 if(status == NFCSTATUS_DESELECTED)
120 {
121 LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback: Target deselected", status);
122 }
123 else
124 {
125 LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback", status);
126 TRACE("Discovered %d secure elements", uNofRemoteDev);
127
128 if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
129 {
130 bool foundHandle = false;
131 TRACE("Multiple Protocol supported\n");
132 for (i=0; i<uNofRemoteDev; i++) {
133 // Always open the phNfc_eISO14443_A_PICC protocol
134 TRACE("Protocol %d handle=%x type=%d", i, psRemoteDevList[i].hTargetDev,
135 psRemoteDevList[i].psRemoteDevInfo->RemDevType);
136 if (psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eISO14443_A_PICC) {
137 secureElementHandle = psRemoteDevList[i].hTargetDev;
138 foundHandle = true;
139 }
140 }
141 if (!foundHandle) {
142 LOGE("Could not find ISO-DEP secure element");
143 status = NFCSTATUS_FAILED;
144 goto clean_and_return;
145 }
146 }
147 else
148 {
149 secureElementHandle = psRemoteDevList->hTargetDev;
150 }
151
152 TRACE("Secure Element Handle: 0x%08x", secureElementHandle);
153
154 /* Set type name */
155 jintArray techList;
156 nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList, NULL, NULL);
157
158 // TODO: Should use the "connected" technology, for now use the first
159 if ((techList != NULL) && e->GetArrayLength(techList) > 0) {
160 e->GetIntArrayRegion(techList, 0, 1, &SecureElementTech);
161 TRACE("Store Secure Element Info\n");
162 SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
163
164 TRACE("Discovered secure element: tech=%d", SecureElementTech);
165 }
166 else {
167 LOGE("Discovered secure element, but could not resolve tech");
168 status = NFCSTATUS_FAILED;
169 }
170
171 // This thread may not return to the virtual machine for a long time
172 // so make sure to delete the local refernce to the tech list.
173 e->DeleteLocalRef(techList);
174 }
175
176 clean_and_return:
177 pContextData->status = status;
178 sem_post(&pContextData->sem);
179 }
180
181
com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv * e,jobject o)182 static jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv *e, jobject o)
183 {
184 NFCSTATUS ret;
185 int semResult;
186
187 phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
188 uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
189 phLibNfc_sADD_Cfg_t discovery_cfg;
190 phLibNfc_Registry_Info_t registry_info;
191 phNfc_sData_t InParam;
192 phNfc_sData_t OutParam;
193 uint8_t ExternalRFDetected[3] = {0x00, 0xFC, 0x01};
194 uint8_t GpioGetValue[3] = {0x00, 0xF8, 0x2B};
195 uint8_t GpioSetValue[4];
196 uint8_t gpioValue;
197 uint8_t Output_Buff[10];
198 uint8_t reg_value;
199 uint8_t mask_value;
200 struct nfc_jni_callback_data cb_data;
201
202 /* Create the local semaphore */
203 if (!nfc_cb_data_init(&cb_data, NULL))
204 {
205 goto clean_and_return;
206 }
207
208 /* Registery */
209 registry_info.MifareUL = TRUE;
210 registry_info.MifareStd = TRUE;
211 registry_info.ISO14443_4A = TRUE;
212 registry_info.ISO14443_4B = TRUE;
213 registry_info.Jewel = TRUE;
214 registry_info.Felica = TRUE;
215 registry_info.NFC = FALSE;
216
217 CONCURRENCY_LOCK();
218
219 TRACE("Open Secure Element");
220
221 /* Check if NFC device is already connected to a tag or P2P peer */
222 if (device_connected_flag == 1)
223 {
224 LOGD("Unable to open SE connection, device already connected to a P2P peer or a Tag");
225 goto clean_and_return;
226 }
227
228 /* Test if External RF field is detected */
229 InParam.buffer = ExternalRFDetected;
230 InParam.length = 3;
231 OutParam.buffer = Output_Buff;
232 TRACE("phLibNfc_Mgt_IoCtl()");
233 REENTRANCE_LOCK();
234 ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
235 REENTRANCE_UNLOCK();
236 if(ret!=NFCSTATUS_PENDING)
237 {
238 LOGE("IOCTL status error");
239 goto clean_and_return;
240 }
241
242 /* Wait for callback response */
243 if(sem_wait(&cb_data.sem))
244 {
245 LOGE("IOCTL semaphore error");
246 goto clean_and_return;
247 }
248
249 if(cb_data.status != NFCSTATUS_SUCCESS)
250 {
251 LOGE("READ MEM ERROR");
252 goto clean_and_return;
253 }
254
255 /* Check the value */
256 reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0];
257 mask_value = reg_value & 0x40;
258
259 if(mask_value == 0x40)
260 {
261 // There is an external RF field present, fail the open request
262 LOGD("Unable to open SE connection, external RF Field detected");
263 goto clean_and_return;
264 }
265
266 /* Get Secure Element List */
267 TRACE("phLibNfc_SE_GetSecureElementList()");
268 ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE);
269 if (ret == NFCSTATUS_SUCCESS)
270 {
271 TRACE("\n> Number of Secure Element(s) : %d\n", No_SE);
272 /* Display Secure Element information */
273 for (i = 0; i<No_SE; i++)
274 {
275 if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX)
276 {
277 TRACE("> SMX detected");
278 TRACE("> Secure Element Handle : %d\n", SE_List[i].hSecureElement);
279 /* save SMARTMX index */
280 SmartMX_detected = 1;
281 SmartMX_index = i;
282 }
283 }
284
285 if(SmartMX_detected)
286 {
287 REENTRANCE_LOCK();
288 TRACE("phLibNfc_RemoteDev_NtfRegister()");
289 ret = phLibNfc_RemoteDev_NtfRegister(®istry_info, com_android_nfc_jni_open_secure_element_notification_callback, (void *)&cb_data);
290 REENTRANCE_UNLOCK();
291 if(ret != NFCSTATUS_SUCCESS)
292 {
293 LOGE("Register Notification error");
294 goto clean_and_return;
295 }
296
297 /* Set wired mode */
298 REENTRANCE_LOCK();
299 TRACE("phLibNfc_SE_SetMode: Wired mode");
300 ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement,
301 phLibNfc_SE_ActModeWired,
302 com_android_nfc_jni_smartMX_setModeCb,
303 (void *)&cb_data);
304 REENTRANCE_UNLOCK();
305 if (ret != NFCSTATUS_PENDING )
306 {
307 LOGE("\n> SE Set SmartMX mode ERROR \n" );
308 goto clean_and_return;
309 }
310
311 /* Wait for callback response */
312 if(sem_wait(&cb_data.sem))
313 {
314 LOGE("Secure Element opening error");
315 goto clean_and_return;
316 }
317
318 if(cb_data.status != NFCSTATUS_SUCCESS)
319 {
320 LOGE("SE set mode failed");
321 goto clean_and_return;
322 }
323
324 TRACE("Waiting for notification");
325 /* Wait for callback response */
326 if(sem_wait(&cb_data.sem))
327 {
328 LOGE("Secure Element opening error");
329 goto clean_and_return;
330 }
331
332 if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_MULTIPLE_PROTOCOLS)
333 {
334 LOGE("SE detection failed");
335 goto clean_and_return;
336 }
337 CONCURRENCY_UNLOCK();
338
339 /* Connect Tag */
340 CONCURRENCY_LOCK();
341 TRACE("phLibNfc_RemoteDev_Connect(SMX)");
342 REENTRANCE_LOCK();
343 ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)&cb_data);
344 REENTRANCE_UNLOCK();
345 if(ret != NFCSTATUS_PENDING)
346 {
347 LOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
348 goto clean_and_return;
349 }
350 TRACE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
351
352 /* Wait for callback response */
353 if(sem_wait(&cb_data.sem))
354 {
355 LOGE("CONNECT semaphore error");
356 goto clean_and_return;
357 }
358
359 /* Connect Status */
360 if(cb_data.status != NFCSTATUS_SUCCESS)
361 {
362 LOGE("Secure Element connect error");
363 goto clean_and_return;
364 }
365
366 CONCURRENCY_UNLOCK();
367
368 /* Get GPIO information */
369 CONCURRENCY_LOCK();
370 InParam.buffer = GpioGetValue;
371 InParam.length = 3;
372 OutParam.buffer = Output_Buff;
373 TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
374 REENTRANCE_LOCK();
375 ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
376 REENTRANCE_UNLOCK();
377 if(ret!=NFCSTATUS_PENDING)
378 {
379 LOGE("IOCTL status error");
380 }
381
382 /* Wait for callback response */
383 if(sem_wait(&cb_data.sem))
384 {
385 LOGE("IOCTL semaphore error");
386 goto clean_and_return;
387 }
388
389 if(cb_data.status != NFCSTATUS_SUCCESS)
390 {
391 LOGE("READ MEM ERROR");
392 goto clean_and_return;
393 }
394
395 gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
396 TRACE("GpioValue = Ox%02x",gpioValue);
397
398 /* Set GPIO information */
399 GpioSetValue[0] = 0x00;
400 GpioSetValue[1] = 0xF8;
401 GpioSetValue[2] = 0x2B;
402 GpioSetValue[3] = (gpioValue | 0x40);
403
404 TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
405
406 for(i=0;i<4;i++)
407 {
408 TRACE("0x%02x",GpioSetValue[i]);
409 }
410
411 InParam.buffer = GpioSetValue;
412 InParam.length = 4;
413 OutParam.buffer = Output_Buff;
414 TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
415 REENTRANCE_LOCK();
416 ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
417 REENTRANCE_UNLOCK();
418 if(ret!=NFCSTATUS_PENDING)
419 {
420 LOGE("IOCTL status error");
421 goto clean_and_return;
422 }
423
424 /* Wait for callback response */
425 if(sem_wait(&cb_data.sem))
426 {
427 LOGE("IOCTL semaphore error");
428 goto clean_and_return;
429 }
430
431 if(cb_data.status != NFCSTATUS_SUCCESS)
432 {
433 LOGE("READ MEM ERROR");
434 goto clean_and_return;
435 }
436 CONCURRENCY_UNLOCK();
437 /* Return the Handle of the SecureElement */
438 return secureElementHandle;
439 }
440 else
441 {
442 LOGE("phLibNfc_SE_GetSecureElementList(): No SMX detected");
443 goto clean_and_return;
444 }
445 }
446 else
447 {
448 LOGE("phLibNfc_SE_GetSecureElementList(): Error");
449 goto clean_and_return;
450 }
451
452 clean_and_return:
453 CONCURRENCY_UNLOCK();
454 return 0;
455 }
456
457
com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv * e,jobject o,jint handle)458 static jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle)
459 {
460 jclass cls;
461 jfieldID f;
462 NFCSTATUS status;
463 jboolean result = JNI_FALSE;
464 phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
465 uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
466 uint32_t SmartMX_Handle;
467 struct nfc_jni_callback_data cb_data;
468 phNfc_sData_t InParam;
469 phNfc_sData_t OutParam;
470 uint8_t Output_Buff[10];
471 uint8_t GpioGetValue[3] = {0x00, 0xF8, 0x2B};
472 uint8_t GpioSetValue[4];
473 uint8_t gpioValue;
474
475 /* Create the local semaphore */
476 if (!nfc_cb_data_init(&cb_data, NULL))
477 {
478 goto clean_and_return;
479 }
480
481 TRACE("Close Secure element function ");
482
483 CONCURRENCY_LOCK();
484 /* Disconnect */
485 TRACE("Disconnecting from SMX (handle = 0x%x)", handle);
486 REENTRANCE_LOCK();
487 status = phLibNfc_RemoteDev_Disconnect(handle,
488 NFC_SMARTMX_RELEASE,
489 com_android_nfc_jni_disconnect_callback,
490 (void *)&cb_data);
491 REENTRANCE_UNLOCK();
492 if(status != NFCSTATUS_PENDING)
493 {
494 LOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
495 goto clean_and_return;
496 }
497 TRACE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
498
499 /* Wait for callback response */
500 if(sem_wait(&cb_data.sem))
501 {
502 goto clean_and_return;
503 }
504
505 /* Disconnect Status */
506 if(cb_data.status != NFCSTATUS_SUCCESS)
507 {
508 LOGE("\n> Disconnect SE ERROR \n" );
509 goto clean_and_return;
510 }
511 CONCURRENCY_UNLOCK();
512
513 /* Get GPIO information */
514 CONCURRENCY_LOCK();
515 InParam.buffer = GpioGetValue;
516 InParam.length = 3;
517 OutParam.buffer = Output_Buff;
518 TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
519 REENTRANCE_LOCK();
520 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
521 REENTRANCE_UNLOCK();
522 if(status!=NFCSTATUS_PENDING)
523 {
524 LOGE("IOCTL status error");
525 goto clean_and_return;
526 }
527
528 /* Wait for callback response */
529 if(sem_wait(&cb_data.sem))
530 {
531 LOGE("IOCTL semaphore error");
532 goto clean_and_return;
533 }
534
535 if(cb_data.status != NFCSTATUS_SUCCESS)
536 {
537 LOGE("READ MEM ERROR");
538 goto clean_and_return;
539 }
540
541 gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
542 TRACE("GpioValue = Ox%02x",gpioValue);
543
544 /* Set GPIO information */
545 GpioSetValue[0] = 0x00;
546 GpioSetValue[1] = 0xF8;
547 GpioSetValue[2] = 0x2B;
548 GpioSetValue[3] = (gpioValue & 0xBF);
549
550 TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
551
552 for(i=0;i<4;i++)
553 {
554 TRACE("0x%02x",GpioSetValue[i]);
555 }
556
557 InParam.buffer = GpioSetValue;
558 InParam.length = 4;
559 OutParam.buffer = Output_Buff;
560 TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
561 REENTRANCE_LOCK();
562 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
563 REENTRANCE_UNLOCK();
564 if(status!=NFCSTATUS_PENDING)
565 {
566 LOGE("IOCTL status error");
567 goto clean_and_return;
568 }
569
570 /* Wait for callback response */
571 if(sem_wait(&cb_data.sem))
572 {
573 LOGE("IOCTL semaphore error");
574 goto clean_and_return;
575 }
576
577 if(cb_data.status != NFCSTATUS_SUCCESS)
578 {
579 LOGE("READ MEM ERROR");
580 goto clean_and_return;
581 }
582
583 result = JNI_TRUE;
584
585 clean_and_return:
586 CONCURRENCY_UNLOCK();
587 return result;
588 }
589
com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv * e,jobject o,jint handle,jbyteArray data)590 static jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e,
591 jobject o,jint handle, jbyteArray data)
592 {
593 uint8_t offset = 0;
594 uint8_t *buf;
595 uint32_t buflen;
596 phLibNfc_sTransceiveInfo_t transceive_info;
597 jbyteArray result = NULL;
598 int res;
599
600 int tech = SecureElementTech;
601 NFCSTATUS status;
602 struct nfc_jni_callback_data cb_data;
603
604 /* Create the local semaphore */
605 if (!nfc_cb_data_init(&cb_data, NULL))
606 {
607 goto clean_and_return;
608 }
609
610 TRACE("Exchange APDU function ");
611
612 CONCURRENCY_LOCK();
613
614 TRACE("Secure Element tech: %d\n", tech);
615
616 buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
617 buflen = (uint32_t)e->GetArrayLength(data);
618
619 /* Prepare transceive info structure */
620 if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL)
621 {
622 offset = 2;
623 transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
624 transceive_info.addr = (uint8_t)buf[1];
625 }
626 else if(tech == TARGET_TYPE_ISO14443_4)
627 {
628 transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
629 transceive_info.addr = 0;
630 }
631
632 transceive_info.sSendData.buffer = buf + offset;
633 transceive_info.sSendData.length = buflen - offset;
634 transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024);
635 transceive_info.sRecvData.length = 1024;
636
637 if(transceive_info.sRecvData.buffer == NULL)
638 {
639 goto clean_and_return;
640 }
641
642 TRACE("phLibNfc_RemoteDev_Transceive(SMX)");
643 REENTRANCE_LOCK();
644 status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info,
645 com_android_nfc_jni_transceive_callback, (void *)&cb_data);
646 REENTRANCE_UNLOCK();
647 if(status != NFCSTATUS_PENDING)
648 {
649 LOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
650 goto clean_and_return;
651 }
652 TRACE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
653
654 /* Wait for callback response */
655 if(sem_wait(&cb_data.sem))
656 {
657 LOGE("TRANSCEIVE semaphore error");
658 goto clean_and_return;
659 }
660
661 if(cb_data.status != NFCSTATUS_SUCCESS)
662 {
663 LOGE("TRANSCEIVE error");
664 goto clean_and_return;
665 }
666
667 /* Copy results back to Java */
668 result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length);
669 if(result != NULL)
670 {
671 e->SetByteArrayRegion(result, 0,
672 com_android_nfc_jni_transceive_buffer->length,
673 (jbyte *)com_android_nfc_jni_transceive_buffer->buffer);
674 }
675
676 clean_and_return:
677 if(transceive_info.sRecvData.buffer != NULL)
678 {
679 free(transceive_info.sRecvData.buffer);
680 }
681
682 e->ReleaseByteArrayElements(data,
683 (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);
684
685 CONCURRENCY_UNLOCK();
686
687 return result;
688 }
689
com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv * e,jobject o,jint handle)690 static jbyteArray com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv *e, jobject o, jint handle)
691 {
692 TRACE("Get Secure element UID function ");
693 jbyteArray SecureElementUid;
694
695 if(handle == secureElementHandle)
696 {
697 SecureElementUid = e->NewByteArray(SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength);
698 e->SetByteArrayRegion(SecureElementUid, 0, SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength,(jbyte *)SecureElementInfo->RemoteDevInfo.Iso14443A_Info.Uid);
699 return SecureElementUid;
700 }
701 else
702 {
703 return NULL;
704 }
705 }
706
com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv * e,jobject o,jint handle)707 static jintArray com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv *e, jobject o, jint handle)
708 {
709 jintArray techList;
710 TRACE("Get Secure element Type function ");
711
712 if(handle == secureElementHandle)
713 {
714 techList = e->NewIntArray(1);
715 e->SetIntArrayRegion(techList, 0, 1, &SecureElementTech);
716 return techList;
717 }
718 else
719 {
720 return NULL;
721 }
722 }
723
724
725 /*
726 * JNI registration.
727 */
728 static JNINativeMethod gMethods[] =
729 {
730 {"doOpenSecureElementConnection", "()I",
731 (void *)com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection},
732 {"doDisconnect", "(I)Z",
733 (void *)com_android_nfc_NativeNfcSecureElement_doDisconnect},
734 {"doTransceive", "(I[B)[B",
735 (void *)com_android_nfc_NativeNfcSecureElement_doTransceive},
736 {"doGetUid", "(I)[B",
737 (void *)com_android_nfc_NativeNfcSecureElement_doGetUid},
738 {"doGetTechList", "(I)[I",
739 (void *)com_android_nfc_NativeNfcSecureElement_doGetTechList},
740 };
741
register_com_android_nfc_NativeNfcSecureElement(JNIEnv * e)742 int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
743 {
744 return jniRegisterNativeMethods(e,
745 "com/android/nfc/nxp/NativeNfcSecureElement",
746 gMethods, NELEM(gMethods));
747 }
748
749 } // namespace android
750