1f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/* 2f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Copyright (C) 2010 The Android Open Source Project 3f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * 4f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 5f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * you may not use this file except in compliance with the License. 6f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * You may obtain a copy of the License at 7f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * 8f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * http://www.apache.org/licenses/LICENSE-2.0 9f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * 10f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Unless required by applicable law or agreed to in writing, software 11f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 12f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * See the License for the specific language governing permissions and 14f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * limitations under the License. 15f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly */ 16f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly#include <semaphore.h> 18b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau#include <errno.h> 192534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes#include <ScopedLocalRef.h> 202534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes#include <ScopedPrimitiveArray.h> 21f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 22c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly#include "com_android_nfc.h" 2397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen#include "phNfcHalTypes.h" 24f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 25c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic phLibNfc_Data_t nfc_jni_ndef_rw; 26f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellystatic phLibNfc_Handle handle; 27c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyuint8_t *nfc_jni_ndef_buf = NULL; 28c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyuint32_t nfc_jni_ndef_buf_len = 0; 29f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 3004a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomasextern uint8_t device_connected_flag; 31f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 32f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellynamespace android { 33f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 3407c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomasextern phLibNfc_Handle storedHandle; 3507c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas 3621545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pellyextern void nfc_jni_restart_discovery_locked(struct nfc_jni_native_data *nat); 371b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenenextern void nfc_jni_reset_timeout_values(); 38f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 39f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/* 40f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Callbacks 41f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly */ 42c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly static void nfc_jni_tag_rw_callback(void *pContext, NFCSTATUS status) 43f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 44b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 45c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly LOG_CALLBACK("nfc_jni_tag_rw_callback", status); 46f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 47b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Report the callback status and wake up the caller */ 48b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau pCallbackData->status = status; 49b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau sem_post(&pCallbackData->sem); 50f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 51f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 52c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_connect_callback(void *pContext, 53f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly phLibNfc_Handle hRemoteDev, 54f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status) 55f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 56b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 57c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly LOG_CALLBACK("nfc_jni_connect_callback", status); 58f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 59b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Report the callback status and wake up the caller */ 60b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau pCallbackData->status = status; 61319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen if (pCallbackData->pContext != NULL) { 62319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen // Store the remote dev info ptr in the callback context 63319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen // Note that this ptr will remain valid, it is tied to a statically 64319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen // allocated buffer in libnfc. 65319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen phLibNfc_sRemoteDevInformation_t** ppRemoteDevInfo = 66319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (phLibNfc_sRemoteDevInformation_t**)pCallbackData->pContext; 67319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen *ppRemoteDevInfo = psRemoteDevInfo; 68319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen } 69319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen 70b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau sem_post(&pCallbackData->sem); 71f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 72f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 73c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_checkndef_callback(void *pContext, 74f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly phLibNfc_ChkNdef_Info_t info, NFCSTATUS status) 75f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 76b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 77c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly LOG_CALLBACK("nfc_jni_checkndef_callback", status); 783ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen phLibNfc_ChkNdef_Info_t* pNdefInfo = (phLibNfc_ChkNdef_Info_t*) (pCallbackData->pContext); 79f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if(status == NFCSTATUS_OK) 80f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 81c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly if(nfc_jni_ndef_buf) 82f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 83c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly free(nfc_jni_ndef_buf); 84f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 85c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_ndef_buf_len = info.MaxNdefMsgLength; 86c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_ndef_buf = (uint8_t*)malloc(nfc_jni_ndef_buf_len); 873ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen if (pNdefInfo != NULL) *pNdefInfo = info; 8841368d81f3076ac903693951f1d5cdba756f33fcMartijn Coenen } 8941368d81f3076ac903693951f1d5cdba756f33fcMartijn Coenen else { 903ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen if (pNdefInfo != NULL) { 913ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen memset(pNdefInfo, 0, sizeof(*pNdefInfo)); 923ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen } 93f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 94f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 95b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Report the callback status and wake up the caller */ 96b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau pCallbackData->status = status; 97b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau sem_post(&pCallbackData->sem); 98f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 99f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 100c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_disconnect_callback(void *pContext, 101f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly phLibNfc_Handle hRemoteDev, NFCSTATUS status) 102f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 103b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 104c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly LOG_CALLBACK("nfc_jni_disconnect_callback", status); 105f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 106c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly if(nfc_jni_ndef_buf) 107f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 108c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly free(nfc_jni_ndef_buf); 109f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 110c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_ndef_buf = NULL; 111c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_ndef_buf_len = 0; 112f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 113b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Report the callback status and wake up the caller */ 114b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau pCallbackData->status = status; 115b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau sem_post(&pCallbackData->sem); 116f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 117f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 118c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_async_disconnect_callback(void *pContext, 119f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly phLibNfc_Handle hRemoteDev, NFCSTATUS status) 120f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 121c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly LOG_CALLBACK("nfc_jni_async_disconnect_callback", status); 122f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 123c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly if(nfc_jni_ndef_buf) 124f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 125c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly free(nfc_jni_ndef_buf); 126f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 127c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_ndef_buf = NULL; 128c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_ndef_buf_len = 0; 129f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 130f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 131c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic phNfc_sData_t *nfc_jni_transceive_buffer; 132f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 133c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_transceive_callback(void *pContext, 134f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status) 135f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 136b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 137c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly LOG_CALLBACK("nfc_jni_transceive_callback", status); 1382534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes 139c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_transceive_buffer = pResBuffer; 140f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 141b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Report the callback status and wake up the caller */ 142b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau pCallbackData->status = status; 143b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau sem_post(&pCallbackData->sem); 144f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 145f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 146b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneaustatic void nfc_jni_presencecheck_callback(void *pContext, NFCSTATUS status) 147b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau{ 148b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 149b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau LOG_CALLBACK("nfc_jni_presencecheck_callback", status); 150b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 151b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Report the callback status and wake up the caller */ 152b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau pCallbackData->status = status; 153b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau sem_post(&pCallbackData->sem); 154b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau} 155b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1560aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenenstatic void nfc_jni_formatndef_callback(void *pContext, NFCSTATUS status) 1570aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen{ 1580aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 1590aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen LOG_CALLBACK("nfc_jni_formatndef_callback", status); 1600aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 1610aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen /* Report the callback status and wake up the caller */ 1620aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen pCallbackData->status = status; 1630aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen sem_post(&pCallbackData->sem); 1640aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen} 1650aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 16603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenenstatic void nfc_jni_readonly_callback(void *pContext, NFCSTATUS status) 16703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen{ 16803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 16903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen LOG_CALLBACK("nfc_jni_readonly_callback", status); 17003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 17103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen /* Report the callback status and wake up the caller */ 17203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen pCallbackData->status = status; 17303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen sem_post(&pCallbackData->sem); 17403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen} 17503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 176f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/* Functions */ 17713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellystatic jbyteArray com_android_nfc_NativeNfcTag_doRead(JNIEnv *e, 178f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jobject o) 179f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 180f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NFCSTATUS status; 181f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly phLibNfc_Handle handle = 0; 182f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jbyteArray buf = NULL; 183b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data cb_data; 184f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 185f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly CONCURRENCY_LOCK(); 186f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 187b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Create the local semaphore */ 188b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if (!nfc_cb_data_init(&cb_data, NULL)) 189b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 190b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 191b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 192b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 193ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen handle = nfc_jni_get_connected_handle(e, o); 194f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 195c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_ndef_rw.length = nfc_jni_ndef_buf_len; 196c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_ndef_rw.buffer = nfc_jni_ndef_buf; 197f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 198ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_Ndef_Read()"); 199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly REENTRANCE_LOCK(); 200c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly status = phLibNfc_Ndef_Read(handle, &nfc_jni_ndef_rw, 2012534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes phLibNfc_Ndef_EBegin, 2022534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes nfc_jni_tag_rw_callback, 203b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau (void *)&cb_data); 204f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly REENTRANCE_UNLOCK(); 205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if(status != NFCSTATUS_PENDING) 206f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 207afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 208f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly goto clean_and_return; 209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 210ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2112534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes 212f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Wait for callback response */ 213b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(sem_wait(&cb_data.sem)) 214b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 215afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 216b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 217b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 218f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 219b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(cb_data.status != NFCSTATUS_SUCCESS) 220f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 221f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly goto clean_and_return; 222f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 223f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 224c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly buf = e->NewByteArray(nfc_jni_ndef_rw.length); 225c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly e->SetByteArrayRegion(buf, 0, nfc_jni_ndef_rw.length, 226c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly (jbyte *)nfc_jni_ndef_rw.buffer); 227f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 228f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyclean_and_return: 229b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau nfc_cb_data_deinit(&cb_data); 230f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly CONCURRENCY_UNLOCK(); 231f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 232f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return buf; 233f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 2342534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes 235f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 23613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellystatic jboolean com_android_nfc_NativeNfcTag_doWrite(JNIEnv *e, 237f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jobject o, jbyteArray buf) 238f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 239f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NFCSTATUS status; 240f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jboolean result = JNI_FALSE; 241b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data cb_data; 242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 243ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen phLibNfc_Handle handle = nfc_jni_get_connected_handle(e, o); 244f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 245f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly CONCURRENCY_LOCK(); 246f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 247b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Create the local semaphore */ 248b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if (!nfc_cb_data_init(&cb_data, NULL)) 249b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 250b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 251b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 252b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 253c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_ndef_rw.length = (uint32_t)e->GetArrayLength(buf); 254c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_ndef_rw.buffer = (uint8_t *)e->GetByteArrayElements(buf, NULL); 255f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 256ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_Ndef_Write()"); 257ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("Ndef Handle :0x%x\n",handle); 258ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("Ndef buffer length : %d", nfc_jni_ndef_rw.length); 259f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly REENTRANCE_LOCK(); 260b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau status = phLibNfc_Ndef_Write(handle, &nfc_jni_ndef_rw,nfc_jni_tag_rw_callback, (void *)&cb_data); 261f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly REENTRANCE_UNLOCK(); 262f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if(status != NFCSTATUS_PENDING) 263f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 264afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 265f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly goto clean_and_return; 266f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 267ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 268f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 269f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Wait for callback response */ 270b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(sem_wait(&cb_data.sem)) 271b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 272afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 273b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 274b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 275f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 276b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(cb_data.status != NFCSTATUS_SUCCESS) 277f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly goto clean_and_return; 279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 281f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly result = JNI_TRUE; 282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 283f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyclean_and_return: 28414df195961abcd98263f5e03c5b17e96c5889a07Martijn Coenen e->ReleaseByteArrayElements(buf, (jbyte *)nfc_jni_ndef_rw.buffer, JNI_ABORT); 28514df195961abcd98263f5e03c5b17e96c5889a07Martijn Coenen 286b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau nfc_cb_data_deinit(&cb_data); 287f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly CONCURRENCY_UNLOCK(); 288f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return result; 289f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 290f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 291319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen/* 292319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen * Utility to recover poll bytes from target infos 293319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen */ 2943dd24ecefb71ce4f585faa002ba1054a0c6dbd06Martijn Coenenvoid set_target_pollBytes(JNIEnv *e, jobject tag, 295319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo) 296319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen{ 2972534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(tag)); 2982534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes jfieldID f = e->GetFieldID(tag_cls.get(), "mTechPollBytes", "[[B"); 299d6a675eeecb5074c8a822353cb89762f8c6cc4bdMartijn Coenen 3002534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jobjectArray> existingPollBytes(e, (jobjectArray) e->GetObjectField(tag, f)); 3012534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes if (existingPollBytes.get() != NULL) { 302d6a675eeecb5074c8a822353cb89762f8c6cc4bdMartijn Coenen return; 303d6a675eeecb5074c8a822353cb89762f8c6cc4bdMartijn Coenen } 304d6a675eeecb5074c8a822353cb89762f8c6cc4bdMartijn Coenen 3052534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes jfieldID techListField = e->GetFieldID(tag_cls.get(), "mTechList", "[I"); 3062534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jintArray> techList(e, (jintArray) e->GetObjectField(tag, techListField)); 3072534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedIntArrayRO techIds(e, techList.get()); 3082534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes int techListLength = techIds.size(); 309319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen 3102534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jbyteArray> pollBytes(e, e->NewByteArray(0)); 3112534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(pollBytes.get())); 3122534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jobjectArray> techPollBytes(e, e->NewObjectArray(techListLength, byteArrayClass.get(), NULL)); 313319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen 314319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen for (int tech = 0; tech < techListLength; tech++) { 3152534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes switch(techIds[tech]) 316319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen { 317319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen /* ISO14443-3A: ATQA/SENS_RES */ 318319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen case TARGET_TYPE_ISO14443_3A: 31993e639baa0b64f85a66bb2ed944583df815b276dMartijn Coenen if (psRemoteDevInfo->RemDevType == phNfc_eJewel_PICC) { 32093e639baa0b64f85a66bb2ed944583df815b276dMartijn Coenen // Jewel ATQA is not read and stored by the PN544, but it is fixed 32193e639baa0b64f85a66bb2ed944583df815b276dMartijn Coenen // at {0x00, 0x0C} in the spec. So eJewel can safely be 32293e639baa0b64f85a66bb2ed944583df815b276dMartijn Coenen // translated to {0x00, 0x0C}. 32393e639baa0b64f85a66bb2ed944583df815b276dMartijn Coenen const static jbyte JewelAtqA[2] = {0x00, 0x0C}; 3242534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes pollBytes.reset(e->NewByteArray(2)); 3252534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(pollBytes.get(), 0, 2, (jbyte*) JewelAtqA); 3262534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes } else { 3272534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes pollBytes.reset(e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA))); 3282534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(pollBytes.get(), 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA), 32993e639baa0b64f85a66bb2ed944583df815b276dMartijn Coenen (jbyte *)psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA); 33093e639baa0b64f85a66bb2ed944583df815b276dMartijn Coenen } 331319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen break; 332319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen /* ISO14443-3B: Application data (4 bytes) and Protocol Info (3 bytes) from ATQB/SENSB_RES */ 333319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen case TARGET_TYPE_ISO14443_3B: 3342534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes pollBytes.reset(e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.AppData) 3352534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes + sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.ProtInfo))); 3362534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(pollBytes.get(), 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.AppData), 337319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.AppData); 3382534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(pollBytes.get(), sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.AppData), 339319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.ProtInfo), 340319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.ProtInfo); 341319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen break; 342319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen /* JIS_X_6319_4: PAD0 (2 byte), PAD1 (2 byte), MRTI(2 byte), PAD2 (1 byte), RC (2 byte) */ 343319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen case TARGET_TYPE_FELICA: 3442534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes pollBytes.reset(e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm) 3452534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes + sizeof(psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode))); 3462534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(pollBytes.get(), 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm), 347319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm); 3482534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(pollBytes.get(), sizeof(psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm), 349319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen sizeof(psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode), 350319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode); 351319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen break; 352319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen /* ISO15693: response flags (1 byte), DSFID (1 byte) */ 353319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen case TARGET_TYPE_ISO15693: 3542534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes pollBytes.reset(e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags) 3552534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes + sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid))); 3562534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(pollBytes.get(), 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags), 357319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)&psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags); 3582534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(pollBytes.get(), sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags), 359319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid), 360319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)&psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid); 361319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen break; 362319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen default: 3632534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes pollBytes.reset(e->NewByteArray(0)); 364319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen break; 365319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen } 3662534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetObjectArrayElement(techPollBytes.get(), tech, pollBytes.get()); 367319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen } 368319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen 3692534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetObjectField(tag, f, techPollBytes.get()); 370319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen} 371319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen 372319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen/* 373319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen * Utility to recover activation bytes from target infos 374319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen */ 3753dd24ecefb71ce4f585faa002ba1054a0c6dbd06Martijn Coenenvoid set_target_activationBytes(JNIEnv *e, jobject tag, 376319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo) 377319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen{ 3782534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(tag)); 379d6a675eeecb5074c8a822353cb89762f8c6cc4bdMartijn Coenen 3802534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes jfieldID f = e->GetFieldID(tag_cls.get(), "mTechActBytes", "[[B"); 3812534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jobjectArray> existingActBytes(e, (jobjectArray) e->GetObjectField(tag, f)); 3822534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes if (existingActBytes.get() != NULL) { 383d6a675eeecb5074c8a822353cb89762f8c6cc4bdMartijn Coenen return; 384d6a675eeecb5074c8a822353cb89762f8c6cc4bdMartijn Coenen } 385d6a675eeecb5074c8a822353cb89762f8c6cc4bdMartijn Coenen 3862534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes jfieldID techListField = e->GetFieldID(tag_cls.get(), "mTechList", "[I"); 3872534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jintArray> techList(e, (jintArray) e->GetObjectField(tag, techListField)); 3882534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedIntArrayRO techIds(e, techList.get()); 3892534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes int techListLength = techIds.size(); 390319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen 3912534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jbyteArray> actBytes(e, e->NewByteArray(0)); 3922534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(actBytes.get())); 3932534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes ScopedLocalRef<jobjectArray> techActBytes(e, e->NewObjectArray(techListLength, byteArrayClass.get(), 0)); 394319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen 395319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen for (int tech = 0; tech < techListLength; tech++) { 3962534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes switch(techIds[tech]) { 397319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen 398319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen /* ISO14443-3A: SAK/SEL_RES */ 399319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen case TARGET_TYPE_ISO14443_3A: 4002534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes actBytes.reset(e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak))); 4012534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(actBytes.get(), 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak), 402319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)&psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak); 403319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen break; 404319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen /* ISO14443-3A & ISO14443-4: SAK/SEL_RES, historical bytes from ATS */ 405319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen /* ISO14443-3B & ISO14443-4: HiLayerResp */ 406319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen case TARGET_TYPE_ISO14443_4: 407319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen // Determine whether -A or -B 408319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen if (psRemoteDevInfo->RemDevType == phNfc_eISO14443_B_PICC || 4092534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes psRemoteDevInfo->RemDevType == phNfc_eISO14443_4B_PICC) { 4102534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes actBytes.reset(e->NewByteArray(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.HiLayerRespLength)); 4112534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(actBytes.get(), 0, psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.HiLayerRespLength, 412319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.HiLayerResp); 4132534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes } else if (psRemoteDevInfo->RemDevType == phNfc_eISO14443_A_PICC || 4142534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes psRemoteDevInfo->RemDevType == phNfc_eISO14443_4A_PICC) { 4152534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes actBytes.reset(e->NewByteArray(psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AppDataLength)); 4162534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(actBytes.get(), 0, 417319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AppDataLength, 418319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AppData); 419319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen } 420319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen break; 421319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen /* ISO15693: response flags (1 byte), DSFID (1 byte) */ 422319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen case TARGET_TYPE_ISO15693: 4232534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes actBytes.reset(e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags) 4242534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes + sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid))); 4252534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(actBytes.get(), 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags), 426319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)&psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags); 4272534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetByteArrayRegion(actBytes.get(), sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags), 428319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid), 429319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen (jbyte *)&psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid); 430319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen break; 431319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen default: 4322534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes actBytes.reset(e->NewByteArray(0)); 433319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen break; 434319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen } 4352534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetObjectArrayElement(techActBytes.get(), tech, actBytes.get()); 436319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen } 4372534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes e->SetObjectField(tag, f, techActBytes.get()); 438319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen} 439319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen 4402c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomasstatic jint com_android_nfc_NativeNfcTag_doConnect(JNIEnv *e, 441bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jobject o, phLibNfc_Handle handle) 442f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 4432c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas jint status; 444b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data cb_data; 445319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen phLibNfc_sRemoteDevInformation_t* pRemDevInfo = NULL; 446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 447f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly CONCURRENCY_LOCK(); 448f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 449b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Create the local semaphore */ 450319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen if (!nfc_cb_data_init(&cb_data, &pRemDevInfo)) 451b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 4522c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas status = NFCSTATUS_NOT_ENOUGH_MEMORY; 453b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 454b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 455b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 456ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_RemoteDev_Connect(RW)"); 457f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly REENTRANCE_LOCK(); 458ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen storedHandle = handle; 459b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau status = phLibNfc_RemoteDev_Connect(handle, nfc_jni_connect_callback,(void *)&cb_data); 460f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly REENTRANCE_UNLOCK(); 461f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if(status != NFCSTATUS_PENDING) 462f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 463afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_RemoteDev_Connect(RW) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 464f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly goto clean_and_return; 465f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 466ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_RemoteDev_Connect(RW) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 467f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 468f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Wait for callback response */ 469b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(sem_wait(&cb_data.sem)) 470b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 471afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 4722c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas status = NFCSTATUS_ABORTED; 473b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 474b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 4752c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas 4762c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas status = cb_data.status; 4772c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas TRACE("phLibNfc_RemoteDev_Connect() - Status code = %d", status); 4782c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas 479f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Connect Status */ 4802c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas if(status != NFCSTATUS_SUCCESS) 481f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 482f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly goto clean_and_return; 483f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 484f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 485319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen // Success, set poll & act bytes 486319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen set_target_pollBytes(e, o, pRemDevInfo); 487319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen set_target_activationBytes(e, o, pRemDevInfo); 488319fc851b61dd975e2309219ed13e21d3e167bddMartijn Coenen 489f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyclean_and_return: 490b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau nfc_cb_data_deinit(&cb_data); 491f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly CONCURRENCY_UNLOCK(); 4922c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas return status; 493f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 494f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 4952c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomasstatic jint com_android_nfc_NativeNfcTag_doHandleReconnect(JNIEnv *e, 49678d140e347337074b38dea417d10beb58948106bMartijn Coenen jobject o, phLibNfc_Handle handle) 49778d140e347337074b38dea417d10beb58948106bMartijn Coenen{ 4982c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas jint status; 49978d140e347337074b38dea417d10beb58948106bMartijn Coenen struct nfc_jni_callback_data cb_data; 50078d140e347337074b38dea417d10beb58948106bMartijn Coenen phLibNfc_sRemoteDevInformation_t* pRemDevInfo = NULL; 50178d140e347337074b38dea417d10beb58948106bMartijn Coenen CONCURRENCY_LOCK(); 50278d140e347337074b38dea417d10beb58948106bMartijn Coenen 50378d140e347337074b38dea417d10beb58948106bMartijn Coenen /* Create the local semaphore */ 50478d140e347337074b38dea417d10beb58948106bMartijn Coenen if (!nfc_cb_data_init(&cb_data, &pRemDevInfo)) 50578d140e347337074b38dea417d10beb58948106bMartijn Coenen { 5062c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas status = NFCSTATUS_NOT_ENOUGH_MEMORY; 50778d140e347337074b38dea417d10beb58948106bMartijn Coenen goto clean_and_return; 50878d140e347337074b38dea417d10beb58948106bMartijn Coenen } 50978d140e347337074b38dea417d10beb58948106bMartijn Coenen 51078d140e347337074b38dea417d10beb58948106bMartijn Coenen TRACE("phLibNfc_RemoteDev_ReConnect(RW)"); 51178d140e347337074b38dea417d10beb58948106bMartijn Coenen REENTRANCE_LOCK(); 51278d140e347337074b38dea417d10beb58948106bMartijn Coenen storedHandle = handle; 51378d140e347337074b38dea417d10beb58948106bMartijn Coenen status = phLibNfc_RemoteDev_ReConnect(handle, nfc_jni_connect_callback,(void *)&cb_data); 51478d140e347337074b38dea417d10beb58948106bMartijn Coenen REENTRANCE_UNLOCK(); 51578d140e347337074b38dea417d10beb58948106bMartijn Coenen if(status != NFCSTATUS_PENDING) 51678d140e347337074b38dea417d10beb58948106bMartijn Coenen { 517afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_RemoteDev_ReConnect(RW) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 51878d140e347337074b38dea417d10beb58948106bMartijn Coenen goto clean_and_return; 51978d140e347337074b38dea417d10beb58948106bMartijn Coenen } 52078d140e347337074b38dea417d10beb58948106bMartijn Coenen TRACE("phLibNfc_RemoteDev_ReConnect(RW) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 52178d140e347337074b38dea417d10beb58948106bMartijn Coenen 52278d140e347337074b38dea417d10beb58948106bMartijn Coenen /* Wait for callback response */ 52378d140e347337074b38dea417d10beb58948106bMartijn Coenen if(sem_wait(&cb_data.sem)) 52478d140e347337074b38dea417d10beb58948106bMartijn Coenen { 525afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 5262c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas status = NFCSTATUS_ABORTED; 52778d140e347337074b38dea417d10beb58948106bMartijn Coenen goto clean_and_return; 52878d140e347337074b38dea417d10beb58948106bMartijn Coenen } 52978d140e347337074b38dea417d10beb58948106bMartijn Coenen 5302c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas status = cb_data.status; 5312c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas 53278d140e347337074b38dea417d10beb58948106bMartijn Coenen /* Connect Status */ 5332c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas if(status != NFCSTATUS_SUCCESS) 53478d140e347337074b38dea417d10beb58948106bMartijn Coenen { 53578d140e347337074b38dea417d10beb58948106bMartijn Coenen goto clean_and_return; 53678d140e347337074b38dea417d10beb58948106bMartijn Coenen } 53778d140e347337074b38dea417d10beb58948106bMartijn Coenen 53878d140e347337074b38dea417d10beb58948106bMartijn Coenenclean_and_return: 53978d140e347337074b38dea417d10beb58948106bMartijn Coenen nfc_cb_data_deinit(&cb_data); 54078d140e347337074b38dea417d10beb58948106bMartijn Coenen CONCURRENCY_UNLOCK(); 5412c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas return status; 54278d140e347337074b38dea417d10beb58948106bMartijn Coenen} 54378d140e347337074b38dea417d10beb58948106bMartijn Coenen 5442c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomasstatic jint com_android_nfc_NativeNfcTag_doReconnect(JNIEnv *e, 545aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen jobject o) 546aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen{ 547aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen // Reconnect is provided by libnfc by just calling connect again 548aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen // on the same handle. 5490a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen int libNfcType = nfc_jni_get_connected_technology_libnfc_type(e, o); 5500a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen if (libNfcType != -1) { 5510a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen // Note that some tag types are stateless, hence we do not reconnect 5520a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen // those. Currently those are the Jewel and Iso15693 technologies. 5530a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen if ((libNfcType != phNfc_eJewel_PICC) && (libNfcType != phNfc_eISO15693_PICC)) { 554bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen phLibNfc_Handle handle = nfc_jni_get_connected_handle(e,o); 555bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen return com_android_nfc_NativeNfcTag_doConnect(e, o, handle); 556bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen } 557bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen else { 5582c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas return NFCSTATUS_SUCCESS; 559bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen } 560bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen } 561bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen else { 5622c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas return NFCSTATUS_REJECTED; 563bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen } 564aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen} 565aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 566aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 56713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellystatic jboolean com_android_nfc_NativeNfcTag_doDisconnect(JNIEnv *e, jobject o) 568f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 569f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly phLibNfc_Handle handle = 0; 570f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NFCSTATUS status; 571f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jboolean result = JNI_FALSE; 572b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data cb_data; 573f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 574f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly CONCURRENCY_LOCK(); 575f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 576ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen handle = nfc_jni_get_connected_handle(e, o); 57707c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas 578b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Create the local semaphore */ 579b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if (!nfc_cb_data_init(&cb_data, NULL)) 580b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 581b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 582b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 583b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 58407c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas /* Reset the stored handle */ 58507c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas storedHandle = 0; 58607c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas 5871b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen nfc_jni_reset_timeout_values(); 5881b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen 589f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Disconnect */ 590ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("Disconnecting from tag (%x)", handle); 5912534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes 592809fdd1fce70e8ec65601a2910fd11a4dde7268dMartijn Coenen if (handle == -1) { 593809fdd1fce70e8ec65601a2910fd11a4dde7268dMartijn Coenen // Was never connected to any tag, exit 594809fdd1fce70e8ec65601a2910fd11a4dde7268dMartijn Coenen result = JNI_TRUE; 595afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("doDisconnect() - Target already disconnected"); 596809fdd1fce70e8ec65601a2910fd11a4dde7268dMartijn Coenen nfc_jni_restart_discovery_locked(nfc_jni_get_nat_ext(e)); 597809fdd1fce70e8ec65601a2910fd11a4dde7268dMartijn Coenen goto clean_and_return; 598809fdd1fce70e8ec65601a2910fd11a4dde7268dMartijn Coenen } 599809fdd1fce70e8ec65601a2910fd11a4dde7268dMartijn Coenen 600ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_RemoteDev_Disconnect(%x)", handle); 60148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas REENTRANCE_LOCK(); 60248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas status = phLibNfc_RemoteDev_Disconnect(handle, NFC_DISCOVERY_CONTINUE, 603b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau nfc_jni_disconnect_callback, (void *)&cb_data); 60448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas REENTRANCE_UNLOCK(); 60507c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas 60607c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas if(status == NFCSTATUS_TARGET_NOT_CONNECTED) 60707c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas { 60807c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas result = JNI_TRUE; 609ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_RemoteDev_Disconnect() - Target already disconnected"); 61007c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas goto clean_and_return; 61107c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas } 61248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas if(status != NFCSTATUS_PENDING) 61348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas { 614afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_RemoteDev_Disconnect(%x) returned 0x%04x[%s]", handle, status, nfc_jni_get_status_name(status)); 61548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas nfc_jni_restart_discovery_locked(nfc_jni_get_nat_ext(e)); 61648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas goto clean_and_return; 61748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas } 618ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_RemoteDev_Disconnect(%x) returned 0x%04x[%s]", handle, status, nfc_jni_get_status_name(status)); 61948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas 62048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas /* Wait for callback response */ 621b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(sem_wait(&cb_data.sem)) 622b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 623afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 624b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 625b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 6262534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes 62748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas /* Disconnect Status */ 628b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(cb_data.status != NFCSTATUS_SUCCESS) 62948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas { 63048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas goto clean_and_return; 63148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas } 63204a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas 63348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas result = JNI_TRUE; 634f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 635f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyclean_and_return: 63604a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas /* Reset device connected flag */ 63704a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas device_connected_flag = 0; 638b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau nfc_cb_data_deinit(&cb_data); 639f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly CONCURRENCY_UNLOCK(); 640f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return result; 641f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 642f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 64397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenenstatic uint16_t 64497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenencrc_16_ccitt1( uint8_t* msg, size_t len, uint16_t init ) 64597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen{ 64697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen uint16_t b, crc = init; 64797c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 64897c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen do { 64997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen b = *msg++ ^ (crc & 0xFF); 65097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen b ^= (b << 4) & 0xFF; 65197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen crc = (crc >> 8) ^ (b << 8) ^ (b << 3) ^ (b >> 4); 65297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } while( --len ); 65397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 65497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen return crc; 65597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen} 65697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 65797c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenenstatic void 65897c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenennfc_insert_crc_a( uint8_t* msg, size_t len ) 65997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen{ 66097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen uint16_t crc; 66197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 66297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen crc = crc_16_ccitt1( msg, len, 0x6363 ); 66397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen msg[len] = crc & 0xFF; 66497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen msg[len + 1] = (crc >> 8) & 0xFF; 66597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen} 66697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 66797c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenenstatic void 66897c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenennfc_get_crc_a( uint8_t* msg, size_t len, uint8_t* byte1, uint8_t* byte2) 66997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen{ 67097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen uint16_t crc; 67197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 67297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen crc = crc_16_ccitt1( msg, len, 0x6363 ); 67397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen *byte1 = crc & 0xFF; 67497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen *byte2 = (crc >> 8) & 0xFF; 67597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen} 67697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 67797c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenenstatic bool 67897c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenencrc_valid( uint8_t* msg, size_t len) 67997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen{ 68097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen uint8_t crcByte1, crcByte2; 68197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 68297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen nfc_get_crc_a(nfc_jni_transceive_buffer->buffer, 68397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen len - 2, &crcByte1, &crcByte2); 68497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 68597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen if (msg[len - 2] == crcByte1 && 68697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen msg[len - 1] == crcByte2) { 68797c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen return true; 68897c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } 68997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen else { 69097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen return false; 69197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } 69297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 69397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen} 694bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 69513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellystatic jbyteArray com_android_nfc_NativeNfcTag_doTransceive(JNIEnv *e, 6969d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen jobject o, jbyteArray data, jboolean raw, jintArray statusTargetLost) 697f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 69848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas uint8_t offset = 0; 69997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen // buf is the pointer to the JNI array and never overwritten, 70097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen // outbuf is passed into the transceive - it may be pointed to new memory 70197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen // to be extended with CRC. 70297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen uint8_t *buf = NULL; 70348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas uint32_t buflen; 70497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 70597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen uint8_t *outbuf = NULL; 70697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen uint32_t outlen; 70748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas phLibNfc_sTransceiveInfo_t transceive_info; 70848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas jbyteArray result = NULL; 70948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas int res; 710ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen phLibNfc_Handle handle = nfc_jni_get_connected_handle(e, o); 71148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas NFCSTATUS status; 712b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data cb_data; 7136d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen int selectedTech = 0; 7140a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen int selectedLibNfcType = 0; 7156d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen jint* technologies = NULL; 71697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen bool checkResponseCrc = false; 71748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas 7189d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen jint *targetLost; 7199d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen if (statusTargetLost != NULL) { 7209d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen targetLost = e->GetIntArrayElements(statusTargetLost, 0); 7219d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen if (targetLost != NULL) { 7229d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen *targetLost = 0; 7239d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen } 7249d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen } else { 7259d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen targetLost = NULL; 7269d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen } 7279d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen 728bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen memset(&transceive_info, 0, sizeof(transceive_info)); 72948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas CONCURRENCY_LOCK(); 73048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas 731b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Create the local semaphore */ 732b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if (!nfc_cb_data_init(&cb_data, NULL)) 733b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 734b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 735b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 736b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 737bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen selectedTech = nfc_jni_get_connected_technology(e, o); 7380a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen selectedLibNfcType = nfc_jni_get_connected_technology_libnfc_type(e, o); 73948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas 74097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen buf = outbuf = (uint8_t *)e->GetByteArrayElements(data, NULL); 74197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen buflen = outlen = (uint32_t)e->GetArrayLength(data); 74248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas 7436d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen switch (selectedTech) { 7446d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen case TARGET_TYPE_FELICA: 7456d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen transceive_info.cmd.FelCmd = phNfc_eFelica_Raw; 7466d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen transceive_info.addr = 0; 7476d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen break; 7486d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen case TARGET_TYPE_MIFARE_CLASSIC: 7496d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen case TARGET_TYPE_MIFARE_UL: 75097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen if (raw) { 75197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen transceive_info.cmd.MfCmd = phHal_eMifareRaw; 75297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen transceive_info.addr = 0; 75397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen // Need to add in the crc here 75497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen outbuf = (uint8_t*)malloc(buflen + 2); 75597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen outlen += 2; 75697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen memcpy(outbuf, buf, buflen); 75797c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen nfc_insert_crc_a(outbuf, buflen); 75897c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 75997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen checkResponseCrc = true; 76097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } else { 76197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen offset = 2; 76297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0]; 76397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen transceive_info.addr = (uint8_t)buf[1]; 76497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } 7656d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen break; 7666d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen case TARGET_TYPE_ISO14443_3A: 7670a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen // Check which libnfc type 7680a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen if (selectedLibNfcType == phNfc_eJewel_PICC) { 7690a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen // For the Jewel pipe, CRC is automatically computed 7700a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen transceive_info.cmd.JewelCmd = phNfc_eJewel_Raw; 7710a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen transceive_info.addr = 0; 7720a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen } else { 7731cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen if (raw) { 7741cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen // Use Mifare Raw to implement a standard 7751cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen // ISO14443-3A transceive, with CRC added 7761cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen transceive_info.cmd.MfCmd = phHal_eMifareRaw; 7771cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen transceive_info.addr = 0; 7781cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen // Need to add in the crc here 7791cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen outbuf = (uint8_t*)malloc(buflen + 2); 7801cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen outlen += 2; 7811cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen memcpy(outbuf, buf, buflen); 7821cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen nfc_insert_crc_a(outbuf, buflen); 7831cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen 7841cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen checkResponseCrc = true; 7851cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen } else { 7861cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen // Use the mifare pipe 7871cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen offset = 2; 7881cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0]; 7891cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen transceive_info.addr = (uint8_t)buf[1]; 7901cbf328d5e4dd6b06b877d3c5753c150f2c409fbMartijn Coenen } 79197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 79297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } 7936d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen break; 7946d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen case TARGET_TYPE_ISO14443_4: 7956d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw; 7966d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen transceive_info.addr = 0; 7976d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen break; 7986d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen case TARGET_TYPE_ISO15693: 7996d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen transceive_info.cmd.Iso15693Cmd = phNfc_eIso15693_Cmd; 8006d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen transceive_info.addr = 0; 8016d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen break; 8026d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen case TARGET_TYPE_UNKNOWN: 80397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen case TARGET_TYPE_ISO14443_3B: 80497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen // Not supported 80597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen goto clean_and_return; 8066d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen default: 8076d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen break; 80848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas } 809f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 81097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen transceive_info.sSendData.buffer = outbuf + offset; 81197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen transceive_info.sSendData.length = outlen - offset; 81248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024); 81348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas transceive_info.sRecvData.length = 1024; 81448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas if(transceive_info.sRecvData.buffer == NULL) 81548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas { 816f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly goto clean_and_return; 81748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas } 818f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 819ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_RemoteDev_Transceive()"); 82048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas REENTRANCE_LOCK(); 82148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info, 822b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau nfc_jni_transceive_callback, (void *)&cb_data); 82348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas REENTRANCE_UNLOCK(); 82448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas if(status != NFCSTATUS_PENDING) 82548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas { 826afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_RemoteDev_Transceive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 8279d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen if ((targetLost != NULL) && (status == NFCSTATUS_TARGET_LOST)) { 8289d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen *targetLost = 1; 8299d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen } 830f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly goto clean_and_return; 83148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas } 832ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_RemoteDev_Transceive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 83348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas 83448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas /* Wait for callback response */ 835b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(sem_wait(&cb_data.sem)) 836b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 837afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 838b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 839b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 84048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas 841b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(cb_data.status != NFCSTATUS_SUCCESS) 84248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas { 8439d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen if ((targetLost != NULL) && (cb_data.status == NFCSTATUS_TARGET_LOST)) { 8449d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen *targetLost = 1; 8459d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen } 84648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas goto clean_and_return; 84748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas } 84848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas 84997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen /* Copy results back to Java * 85097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen * In case of NfcA and raw, also check the CRC in the response 85197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen * and cut it off in the returned data. 85297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen */ 853ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen if ((nfc_jni_transceive_buffer->length > 2) && checkResponseCrc) { 85497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen if (crc_valid(nfc_jni_transceive_buffer->buffer, nfc_jni_transceive_buffer->length)) { 85597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen result = e->NewByteArray(nfc_jni_transceive_buffer->length - 2); 85697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen if (result != NULL) { 85797c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen e->SetByteArrayRegion(result, 0, 85897c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen nfc_jni_transceive_buffer->length - 2, 85997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen (jbyte *)nfc_jni_transceive_buffer->buffer); 86097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } 86197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } 86297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } else { 86397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen result = e->NewByteArray(nfc_jni_transceive_buffer->length); 86497c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen if (result != NULL) { 86597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen e->SetByteArrayRegion(result, 0, 86697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen nfc_jni_transceive_buffer->length, 86797c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen (jbyte *)nfc_jni_transceive_buffer->buffer); 86897c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } 86948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas } 870b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneauclean_and_return: 87148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas if(transceive_info.sRecvData.buffer != NULL) 87248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas { 873f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly free(transceive_info.sRecvData.buffer); 87448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas } 875f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 87697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen if ((outbuf != buf) && (outbuf != NULL)) { 87797c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen // Buf was extended and re-alloced with crc bytes, free separately 87897c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen free(outbuf); 87997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen } 88097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 88148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas e->ReleaseByteArrayElements(data, 88297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen (jbyte *)buf, JNI_ABORT); 883f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 8849d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen if (targetLost != NULL) { 8859d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen e->ReleaseIntArrayElements(statusTargetLost, targetLost, 0); 8869d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen } 8879d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen 888b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau nfc_cb_data_deinit(&cb_data); 889b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 89048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas CONCURRENCY_UNLOCK(); 891f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 89248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas return result; 893f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 894f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 895f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenenstatic jint com_android_nfc_NativeNfcTag_doGetNdefType(JNIEnv *e, jobject o, 896f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen jint libnfcType, jint javaType) 897f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen{ 898f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen jint ndefType = NDEF_UNKNOWN_TYPE; 899f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen 900f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen switch (libnfcType) { 901f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen case phNfc_eJewel_PICC: 902f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen ndefType = NDEF_TYPE1_TAG; 903f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen break; 904f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen case phNfc_eISO14443_3A_PICC: 905f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen ndefType = NDEF_TYPE2_TAG;; 906f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen break; 907f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen case phNfc_eFelica_PICC: 908f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen ndefType = NDEF_TYPE3_TAG; 909f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen break; 910f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen case phNfc_eISO14443_A_PICC: 911f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen case phNfc_eISO14443_4A_PICC: 912f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen case phNfc_eISO14443_B_PICC: 913f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen case phNfc_eISO14443_4B_PICC: 914f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen ndefType = NDEF_TYPE4_TAG; 915f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen break; 916f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen case phNfc_eMifare_PICC: 917f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen if (javaType == TARGET_TYPE_MIFARE_UL) { 918f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen ndefType = NDEF_TYPE2_TAG; 919f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen } else { 920f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen ndefType = NDEF_MIFARE_CLASSIC_TAG; 921f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen } 922f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen break; 923f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen case phNfc_eISO15693_PICC: 924e8848005e3c79df26d8cdc4228220205eaeffe4fMartijn Coenen ndefType = NDEF_ICODE_SLI_TAG; 925e8848005e3c79df26d8cdc4228220205eaeffe4fMartijn Coenen break; 926f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen default: 927f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen ndefType = NDEF_UNKNOWN_TYPE; 928f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen break; 929f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen } 930f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen return ndefType; 931f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen} 932f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen 9332c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomasstatic jint com_android_nfc_NativeNfcTag_doCheckNdef(JNIEnv *e, jobject o, jintArray ndefinfo) 934f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 935f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly phLibNfc_Handle handle = 0; 9362c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas jint status; 9373ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen phLibNfc_ChkNdef_Info_t sNdefInfo; 938b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data cb_data; 9393ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen jint *ndef = e->GetIntArrayElements(ndefinfo, 0); 9403ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen int apiCardState = NDEF_MODE_UNKNOWN; 941f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 942f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly CONCURRENCY_LOCK(); 943f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 944b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Create the local semaphore */ 945b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if (!nfc_cb_data_init(&cb_data, NULL)) 946b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 9472c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas status = NFCSTATUS_NOT_ENOUGH_MEMORY; 948b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 949b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 9503ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen cb_data.pContext = &sNdefInfo; 951b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 952ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen handle = nfc_jni_get_connected_handle(e, o); 953f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 954ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_Ndef_CheckNdef()"); 955f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly REENTRANCE_LOCK(); 956b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau status = phLibNfc_Ndef_CheckNdef(handle, nfc_jni_checkndef_callback,(void *)&cb_data); 957f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly REENTRANCE_UNLOCK(); 958f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if(status != NFCSTATUS_PENDING) 959f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 960afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_Ndef_CheckNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 961f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly goto clean_and_return; 962f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 963ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_Ndef_CheckNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 964b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 965f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Wait for callback response */ 966b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(sem_wait(&cb_data.sem)) 967b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 968afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 9692c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas status = NFCSTATUS_ABORTED; 970b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 971b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 972f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 9732c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas status = cb_data.status; 9742c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas TRACE("phLibNfc_Ndef_CheckNdef() - Status code = %d", status); 9752c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas 9762c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas if (status != NFCSTATUS_SUCCESS) 977f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 978f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly goto clean_and_return; 979f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 980f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 9813ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen ndef[0] = sNdefInfo.MaxNdefMsgLength; 9823ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen // Translate the card state to know values for the NFC API 9833ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen switch (sNdefInfo.NdefCardState) { 984eb5976d83844fbe1b16d951c781abe35b4305606Martijn Coenen case PHLIBNFC_NDEF_CARD_INITIALISED: 9853ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen apiCardState = NDEF_MODE_READ_WRITE; 9863ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen break; 987eb5976d83844fbe1b16d951c781abe35b4305606Martijn Coenen case PHLIBNFC_NDEF_CARD_READ_ONLY: 9883ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen apiCardState = NDEF_MODE_READ_ONLY; 9893ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen break; 990eb5976d83844fbe1b16d951c781abe35b4305606Martijn Coenen case PHLIBNFC_NDEF_CARD_READ_WRITE: 9913ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen apiCardState = NDEF_MODE_READ_WRITE; 9923ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen break; 993eb5976d83844fbe1b16d951c781abe35b4305606Martijn Coenen case PHLIBNFC_NDEF_CARD_INVALID: 9943ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen apiCardState = NDEF_MODE_UNKNOWN; 9953ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen break; 9963ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen } 9973ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen ndef[1] = apiCardState; 9983ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen 999f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyclean_and_return: 10003ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen e->ReleaseIntArrayElements(ndefinfo, ndef, 0); 1001b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau nfc_cb_data_deinit(&cb_data); 1002f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly CONCURRENCY_UNLOCK(); 10032c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas return status; 1004f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 1005f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1006b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneaustatic jboolean com_android_nfc_NativeNfcTag_doPresenceCheck(JNIEnv *e, jobject o) 1007b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau{ 1008b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau phLibNfc_Handle handle = 0; 1009b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau NFCSTATUS status; 1010b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau jboolean result = JNI_FALSE; 1011b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau struct nfc_jni_callback_data cb_data; 1012b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1013b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau CONCURRENCY_LOCK(); 1014b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1015b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Create the local semaphore */ 1016b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if (!nfc_cb_data_init(&cb_data, NULL)) 1017b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 1018b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 1019b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 1020b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 1021ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen handle = nfc_jni_get_connected_handle(e, o); 1022b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1023ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_RemoteDev_CheckPresence()"); 1024b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau REENTRANCE_LOCK(); 1025b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau status = phLibNfc_RemoteDev_CheckPresence(handle, nfc_jni_presencecheck_callback, (void *)&cb_data); 1026b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau REENTRANCE_UNLOCK(); 102707c19c3098f1d98c1c1a9e9f28aad22bd62a72a9Daniel Tomas 1028b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if(status != NFCSTATUS_PENDING) 1029b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau { 1030afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 1031b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau goto clean_and_return; 1032b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1033ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton TRACE("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 1034b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1035b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau /* Wait for callback response */ 1036b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(sem_wait(&cb_data.sem)) 1037b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 1038afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1039b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau goto clean_and_return; 1040b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 1041b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1042b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if (cb_data.status == NFCSTATUS_SUCCESS) 1043b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau { 1044b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau result = JNI_TRUE; 1045b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1046b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1047b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauclean_and_return: 1048b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau nfc_cb_data_deinit(&cb_data); 104904a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas 1050b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau CONCURRENCY_UNLOCK(); 105197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen 1052b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return result; 1053b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau} 1054f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1055841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenenstatic jboolean com_android_nfc_NativeNfcTag_doIsIsoDepNdefFormatable(JNIEnv *e, 1056841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen jobject o, jbyteArray pollBytes, jbyteArray actBytes) 1057eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen{ 1058841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // Determines whether this is a formatable IsoDep tag - currently only NXP DESFire 1059841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // is supported. 1060eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen jboolean result = JNI_FALSE; 1061eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen 1062841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // DESfire has one sak byte and 2 ATQA bytes 1063841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen if (pollBytes != NULL && (e->GetArrayLength(pollBytes) >= 2) && 1064841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen actBytes != NULL && (e->GetArrayLength(actBytes) >= 1)) { 1065841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen jbyte* poll = e->GetByteArrayElements(pollBytes, NULL); 1066841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen jbyte* act = e->GetByteArrayElements(actBytes, NULL); 1067841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen if (act[0] == 0x20 && poll[1] == 0x03) { 1068841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen uint8_t cmd[] = {0x90, 0x60, 0x00, 0x00, 0x00}; 1069841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // Identifies as DESfire, use get version cmd to be sure 1070841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen jbyteArray versionCmd = e->NewByteArray(5); 1071841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen e->SetByteArrayRegion(versionCmd, 0, 5, (jbyte*)cmd); 1072841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen jbyteArray respBytes = com_android_nfc_NativeNfcTag_doTransceive(e, o, 1073841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen versionCmd, JNI_TRUE, NULL); 1074841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen if (respBytes != NULL) { 1075841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // Check whether the response matches a typical DESfire 1076841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // response. 1077841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // libNFC even does more advanced checking than we do 1078841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // here, and will only format DESfire's with a certain 1079841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // major/minor sw version and NXP as a manufacturer. 1080841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // We don't want to do such checking here, to avoid 1081841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // having to change code in multiple places. 1082841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // A succesful (wrapped) DESFire getVersion command returns 1083841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // 9 bytes, with byte 7 0x91 and byte 8 having status 1084841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen // code 0xAF (these values are fixed and well-known). 1085841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen int respLength = e->GetArrayLength(respBytes); 1086841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen jbyte* resp = e->GetByteArrayElements(respBytes, NULL); 1087841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen if (respLength == 9 && resp[7] == (jbyte)0x91 && 1088841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen resp[8] == (jbyte)0xAF) { 108973cc851dcb7d026015f6f91ab9336e5c042b8ac1Martijn Coenen result = JNI_TRUE; 109073cc851dcb7d026015f6f91ab9336e5c042b8ac1Martijn Coenen } 1091841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen e->ReleaseByteArrayElements(respBytes, (jbyte *)resp, JNI_ABORT); 109273cc851dcb7d026015f6f91ab9336e5c042b8ac1Martijn Coenen } 1093841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen } 1094841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen e->ReleaseByteArrayElements(pollBytes, (jbyte *)poll, JNI_ABORT); 1095841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen e->ReleaseByteArrayElements(actBytes, (jbyte *)act, JNI_ABORT); 1096eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen } 1097eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen 1098841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen return result; 1099eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen} 1100eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen 11010aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenenstatic jboolean com_android_nfc_NativeNfcTag_doNdefFormat(JNIEnv *e, jobject o, jbyteArray key) 11020aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen{ 11030aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen phLibNfc_Handle handle = 0; 11040aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen NFCSTATUS status; 11050aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen phNfc_sData_t keyBuffer; 11060aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen jboolean result = JNI_FALSE; 11070aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen struct nfc_jni_callback_data cb_data; 11080aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 11090aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen CONCURRENCY_LOCK(); 11100aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 11110aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen /* Create the local semaphore */ 11120aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (!nfc_cb_data_init(&cb_data, NULL)) 11130aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen { 11140aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen goto clean_and_return; 11150aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 11160aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 1117ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen handle = nfc_jni_get_connected_handle(e, o); 11180aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 11190aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen keyBuffer.buffer = (uint8_t *)e->GetByteArrayElements(key, NULL); 11200aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen keyBuffer.length = e->GetArrayLength(key); 11210aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen TRACE("phLibNfc_RemoteDev_FormatNdef()"); 11220aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen REENTRANCE_LOCK(); 11230aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen status = phLibNfc_RemoteDev_FormatNdef(handle, &keyBuffer, nfc_jni_formatndef_callback, (void *)&cb_data); 11240aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen REENTRANCE_UNLOCK(); 11250aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 11260aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if(status != NFCSTATUS_PENDING) 11270aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen { 1128afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_RemoteDev_FormatNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 11290aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen goto clean_and_return; 11300aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 11310aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen TRACE("phLibNfc_RemoteDev_FormatNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 11320aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 11330aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen /* Wait for callback response */ 11340aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if(sem_wait(&cb_data.sem)) 11350aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen { 1136afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 11370aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen goto clean_and_return; 11380aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 11390aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 11400aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (cb_data.status == NFCSTATUS_SUCCESS) 11410aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen { 11420aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen result = JNI_TRUE; 11430aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 11440aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 11450aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenenclean_and_return: 11460aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen e->ReleaseByteArrayElements(key, (jbyte *)keyBuffer.buffer, JNI_ABORT); 11470aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen nfc_cb_data_deinit(&cb_data); 11480aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen CONCURRENCY_UNLOCK(); 11490aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return result; 11500aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen} 1151f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1152ff07dc2bb156d62f447bc3613d6df339fa09794cMartijn Coenenstatic jboolean com_android_nfc_NativeNfcTag_doMakeReadonly(JNIEnv *e, jobject o, jbyteArray key) 115303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen{ 115403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen phLibNfc_Handle handle = 0; 115503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen NFCSTATUS status; 115603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen jboolean result = JNI_FALSE; 115703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen struct nfc_jni_callback_data cb_data; 1158ff07dc2bb156d62f447bc3613d6df339fa09794cMartijn Coenen phNfc_sData_t keyBuffer; 115903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 116003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen CONCURRENCY_LOCK(); 116103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 116203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen /* Create the local semaphore */ 116303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (!nfc_cb_data_init(&cb_data, NULL)) 116403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen { 116503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen goto clean_and_return; 116603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 116703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 116803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen handle = nfc_jni_get_connected_handle(e, o); 1169ff07dc2bb156d62f447bc3613d6df339fa09794cMartijn Coenen keyBuffer.buffer = (uint8_t *)e->GetByteArrayElements(key, NULL); 1170ff07dc2bb156d62f447bc3613d6df339fa09794cMartijn Coenen keyBuffer.length = e->GetArrayLength(key); 117103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen TRACE("phLibNfc_ConvertToReadOnlyNdef()"); 117203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen REENTRANCE_LOCK(); 1173ff07dc2bb156d62f447bc3613d6df339fa09794cMartijn Coenen status = phLibNfc_ConvertToReadOnlyNdef(handle, &keyBuffer, nfc_jni_readonly_callback, 1174ff07dc2bb156d62f447bc3613d6df339fa09794cMartijn Coenen (void *)&cb_data); 117503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen REENTRANCE_UNLOCK(); 117603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 117703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if(status != NFCSTATUS_PENDING) 117803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen { 1179afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("pphLibNfc_ConvertToReadOnlyNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 118003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen goto clean_and_return; 118103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 118203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen TRACE("phLibNfc_ConvertToReadOnlyNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 118303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 118403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen /* Wait for callback response */ 118503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if(sem_wait(&cb_data.sem)) 118603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen { 1187afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 118803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen goto clean_and_return; 118903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 119003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 119103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (cb_data.status == NFCSTATUS_SUCCESS) 119203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen { 119303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen result = JNI_TRUE; 119403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 119503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 119603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenenclean_and_return: 1197ff07dc2bb156d62f447bc3613d6df339fa09794cMartijn Coenen e->ReleaseByteArrayElements(key, (jbyte *)keyBuffer.buffer, JNI_ABORT); 119803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen nfc_cb_data_deinit(&cb_data); 119903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen CONCURRENCY_UNLOCK(); 120003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return result; 120103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen} 1202f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/* 1203f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * JNI registration. 1204f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly */ 1205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellystatic JNINativeMethod gMethods[] = 1206f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 12072c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas {"doConnect", "(I)I", 120813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly (void *)com_android_nfc_NativeNfcTag_doConnect}, 1209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly {"doDisconnect", "()Z", 121013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly (void *)com_android_nfc_NativeNfcTag_doDisconnect}, 12112c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas {"doReconnect", "()I", 1212aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen (void *)com_android_nfc_NativeNfcTag_doReconnect}, 12132c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas {"doHandleReconnect", "(I)I", 121478d140e347337074b38dea417d10beb58948106bMartijn Coenen (void *)com_android_nfc_NativeNfcTag_doHandleReconnect}, 12159d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen {"doTransceive", "([BZ[I)[B", 121613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly (void *)com_android_nfc_NativeNfcTag_doTransceive}, 1217f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen {"doGetNdefType", "(II)I", 1218f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen (void *)com_android_nfc_NativeNfcTag_doGetNdefType}, 12192c3f9be8111dd454e430ffb327c051ff9d2bba21Daniel Tomas {"doCheckNdef", "([I)I", 1220b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau (void *)com_android_nfc_NativeNfcTag_doCheckNdef}, 1221f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly {"doRead", "()[B", 122213d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly (void *)com_android_nfc_NativeNfcTag_doRead}, 1223f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly {"doWrite", "([B)Z", 122413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly (void *)com_android_nfc_NativeNfcTag_doWrite}, 1225b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau {"doPresenceCheck", "()Z", 1226b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau (void *)com_android_nfc_NativeNfcTag_doPresenceCheck}, 1227841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen {"doIsIsoDepNdefFormatable", "([B[B)Z", 1228841409b8ad298d34de24e584f3c152f023c3d2f4Martijn Coenen (void *)com_android_nfc_NativeNfcTag_doIsIsoDepNdefFormatable}, 12290aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen {"doNdefFormat", "([B)Z", 12300aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen (void *)com_android_nfc_NativeNfcTag_doNdefFormat}, 1231ff07dc2bb156d62f447bc3613d6df339fa09794cMartijn Coenen {"doMakeReadonly", "([B)Z", 123203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen (void *)com_android_nfc_NativeNfcTag_doMakeReadonly}, 1233f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}; 1234f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 123513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyint register_com_android_nfc_NativeNfcTag(JNIEnv *e) 1236f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 1237f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return jniRegisterNativeMethods(e, 1238642ab20c81425ba93e206d2a30602cd67ae8bd38Martijn Coenen "com/android/nfc/dhimpl/NativeNfcTag", 1239f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly gMethods, NELEM(gMethods)); 1240f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 1241f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} // namespace android 1243