summaryrefslogtreecommitdiffstats
path: root/jni
diff options
context:
space:
mode:
authorJeff Hamilton <jham@android.com>2011-09-13 16:37:35 -0500
committerJeff Hamilton <jham@android.com>2011-09-14 14:40:17 -0500
commit0fe7049a3224aa7b29cc980be07387e17607b0de (patch)
treebcef757afe6f8eac0b3a56d39439a4764cc12092 /jni
parentf40897302add5c03e7e5569bd73d03724335ba15 (diff)
downloadpackages_apps_nfc-0fe7049a3224aa7b29cc980be07387e17607b0de.tar.gz
packages_apps_nfc-0fe7049a3224aa7b29cc980be07387e17607b0de.tar.bz2
packages_apps_nfc-0fe7049a3224aa7b29cc980be07387e17607b0de.zip
Manually port d77e05f7 from gingerbread:
Patch to perform a download at NfcService boot time This patch permit, when NFC is off, to perform a download if the PN544 is not up to date Change-Id: Iaa01e218ccd1e4cb18ef77d58c18348823135b1e
Diffstat (limited to 'jni')
-rw-r--r--jni/com_android_nfc_NativeNfcManager.cpp251
1 files changed, 202 insertions, 49 deletions
diff --git a/jni/com_android_nfc_NativeNfcManager.cpp b/jni/com_android_nfc_NativeNfcManager.cpp
index f244f7c..20f7149 100644
--- a/jni/com_android_nfc_NativeNfcManager.cpp
+++ b/jni/com_android_nfc_NativeNfcManager.cpp
@@ -34,6 +34,7 @@ static phNfc_sData_t gInputParam;
static phNfc_sData_t gOutputParam;
uint8_t device_connected_flag;
+static bool driverConfigured = FALSE;
static phLibNfc_Handle hLlcpHandle;
static NFCSTATUS lastErrorStatus = NFCSTATUS_FAILED;
@@ -288,13 +289,21 @@ static int nfc_jni_download(struct nfc_jni_native_data *nat, uint8_t update)
goto clean_and_return;
}
- /* Download Status */
- if(cb_data.status != NFCSTATUS_SUCCESS)
+ /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
+ try to download an old-style firmware on top of a new-style
+ firmware. Hence, this is expected behavior, and not an
+ error condition. */
+ if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
{
status = cb_data.status;
goto clean_and_return;
}
+ if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
+ {
+ LOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
+ }
+
reinit:
TRACE("phLibNfc_HW_Reset()");
phLibNfc_HW_Reset();
@@ -334,13 +343,14 @@ reinit:
}
else
{
- LOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, FW Update Info = %d",
+ LOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d",
caps.psDevCapabilities.hal_version,
caps.psDevCapabilities.fw_version,
caps.psDevCapabilities.hw_version,
caps.psDevCapabilities.model_id,
caps.psDevCapabilities.hci_version,
caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1],
+ caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2],
caps.psDevCapabilities.firmware_update_info);
}
@@ -352,20 +362,83 @@ clean_and_return:
return status;
}
+static int nfc_jni_configure_driver(struct nfc_jni_native_data *nat)
+{
+ char value[PROPERTY_VALUE_MAX];
+ int result = FALSE;
+ NFCSTATUS status;
+
+ /* ====== CONFIGURE DRIVER ======= */
+ /* Configure hardware link */
+ gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
+
+ property_get("ro.nfc.port", value, "unknown");
+ gDrvCfg.nLinkType = parseLinkType(value);
+
+ TRACE("phLibNfc_Mgt_ConfigureDriver(0x%08x, 0x%08x)", gDrvCfg.nClientId, gDrvCfg.nLinkType);
+ REENTRANCE_LOCK();
+ status = phLibNfc_Mgt_ConfigureDriver(&gDrvCfg, &gHWRef);
+ REENTRANCE_UNLOCK();
+ if(status == NFCSTATUS_ALREADY_INITIALISED) {
+ LOGW("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+ }
+ else if(status != NFCSTATUS_SUCCESS)
+ {
+ LOGE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+ goto clean_and_return;
+ }
+ TRACE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+
+ if(pthread_create(&(nat->thread), NULL, nfc_jni_client_thread, nat) != 0)
+ {
+ LOGE("pthread_create failed");
+ goto clean_and_return;
+ }
+
+ driverConfigured = TRUE;
+
+clean_and_return:
+ return result;
+}
+
+static int nfc_jni_unconfigure_driver(struct nfc_jni_native_data *nat)
+{
+ int result = FALSE;
+ NFCSTATUS status;
+
+ /* Unconfigure driver */
+ TRACE("phLibNfc_Mgt_UnConfigureDriver()");
+ REENTRANCE_LOCK();
+ status = phLibNfc_Mgt_UnConfigureDriver(gHWRef);
+ REENTRANCE_UNLOCK();
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ LOGE("phLibNfc_Mgt_UnConfigureDriver() returned error 0x%04x[%s] -- this should never happen", status, nfc_jni_get_status_name( status));
+ }
+ else
+ {
+ LOGD("phLibNfc_Mgt_UnConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+ result = TRUE;
+ }
+
+ driverConfigured = FALSE;
+
+ return result;
+}
+
/* Initialization function */
static int nfc_jni_initialize(struct nfc_jni_native_data *nat) {
struct timespec ts;
uint8_t resp[16];
NFCSTATUS status;
phLibNfc_StackCapabilities_t caps;
- char value[PROPERTY_VALUE_MAX];
- int result = FALSE;
phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index = 0, SmartMX_detected = 0;
phLibNfc_Llcp_sLinkParameters_t LlcpConfigInfo;
struct nfc_jni_callback_data cb_data;
uint8_t firmware_status;
uint8_t update = TRUE;
+ int result = JNI_FALSE;
LOGD("Start Initialization\n");
@@ -381,33 +454,10 @@ static int nfc_jni_initialize(struct nfc_jni_native_data *nat) {
/* Reset stored handle */
storedHandle = 0;
- /* Configure hardware link */
- gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
-
- property_get("ro.nfc.port", value, "unknown");
- gDrvCfg.nLinkType = parseLinkType(value);
-
- /* ====== CONFIGURE DRIVER ======= */
-
- TRACE("phLibNfc_Mgt_ConfigureDriver(0x%08x, 0x%08x)", gDrvCfg.nClientId, gDrvCfg.nLinkType);
- REENTRANCE_LOCK();
- status = phLibNfc_Mgt_ConfigureDriver(&gDrvCfg, &gHWRef);
- REENTRANCE_UNLOCK();
- if(status == NFCSTATUS_ALREADY_INITIALISED) {
- LOGW("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
- }
- else if(status != NFCSTATUS_SUCCESS)
- {
- LOGE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
- goto clean_and_return;
- }
- TRACE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
-
- if(pthread_create(&(nat->thread), NULL, nfc_jni_client_thread,
- nat) != 0)
+ /* Initialize Driver */
+ if(!driverConfigured)
{
- LOGE("pthread_create failed");
- goto clean_and_return;
+ nfc_jni_configure_driver(nat);
}
/* ====== INITIALIZE ======= */
@@ -474,6 +524,7 @@ force_download:
break;
}
LOGW("Firmware update FAILED");
+ update = FALSE;
}
if(i>=3)
{
@@ -1779,11 +1830,11 @@ static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject
LOGD("Native Structure initialization failed");
return FALSE;
}
-
- TRACE("****** Init Native Structure OK ******");
+ TRACE("****** Init Native Structure OK ******");
return TRUE;
+
}
-
+
/* Init/Deinit method */
static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o)
{
@@ -1846,17 +1897,20 @@ static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o)
{
struct timespec ts;
NFCSTATUS status;
+ int result = JNI_FALSE;
struct nfc_jni_native_data *nat;
int bStackReset = FALSE;
struct nfc_jni_callback_data cb_data;
+ CONCURRENCY_LOCK();
+
/* Retrieve native structure address */
nat = nfc_jni_get_nat(e, o);
/* Clear previous configuration */
memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t));
memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t));
-
+
/* Create the local semaphore */
if (nfc_cb_data_init(&cb_data, NULL))
{
@@ -1906,22 +1960,12 @@ static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o)
emergency_recovery(nat);
}
- /* Unconfigure driver */
- TRACE("phLibNfc_Mgt_UnConfigureDriver()");
- REENTRANCE_LOCK();
- status = phLibNfc_Mgt_UnConfigureDriver(gHWRef);
- REENTRANCE_UNLOCK();
- if(status != NFCSTATUS_SUCCESS)
- {
- LOGE("phLibNfc_Mgt_UnConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
- }
- else
- {
- LOGD("phLibNfc_Mgt_UnConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
- }
+ result = nfc_jni_unconfigure_driver(nat);
TRACE("NFC Deinitialized");
+ CONCURRENCY_UNLOCK();
+
return TRUE;
}
@@ -2465,14 +2509,123 @@ static void com_android_nfc_NfcManager_doAbort(JNIEnv *e, jobject o)
emergency_recovery(NULL);
}
+static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o)
+{
+ char* firmware_version;
+ jboolean result = FALSE;
+ int load_result;
+ int unconfigure_status;
+ bool drive_state = FALSE;
+ uint8_t OutputBuffer[1];
+ uint8_t InputBuffer[1];
+ struct timespec ts;
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ struct nfc_jni_callback_data cb_data;
+ struct nfc_jni_native_data *nat = NULL;
+ char value[PROPERTY_VALUE_MAX];
+
+ /* Create the local semaphore */
+ if (!nfc_cb_data_init(&cb_data, NULL))
+ {
+ result = FALSE;
+ goto clean_and_return;
+ }
+
+ /* Retrieve native structure address */
+ nat = nfc_jni_get_nat(e, o);
+
+ CONCURRENCY_LOCK();
+
+ /* Initialize Driver */
+ if(!driverConfigured)
+ {
+ result = nfc_jni_configure_driver(nat);
+ drive_state = TRUE;
+ }
+
+ TRACE("com_android_nfc_NfcManager_doDownload()");
+
+ TRACE("Go in Download Mode");
+ phLibNfc_Download_Mode();
+
+ TRACE("Load new Firmware Image");
+ load_result = phLibNfc_Load_Firmware_Image();
+ if(load_result != 0)
+ {
+ TRACE("Load new Firmware Image - status = %d",load_result);
+ result = FALSE;
+ goto clean_and_return;
+ }
+
+ // Download
+ gInputParam.buffer = InputBuffer;
+ gInputParam.length = 0x01;
+ gOutputParam.buffer = OutputBuffer;
+ gOutputParam.length = 0x01;
+
+ LOGD("Download new Firmware");
+ REENTRANCE_LOCK();
+ status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
+ REENTRANCE_UNLOCK();
+ if(status != NFCSTATUS_PENDING)
+ {
+ LOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+ result = FALSE;
+ goto clean_and_return;
+ }
+ TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+
+ /* Wait for callback response */
+ if(sem_wait(&cb_data.sem))
+ {
+ LOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
+ result = FALSE;
+ goto clean_and_return;
+ }
+
+ /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
+ try to download an old-style firmware on top of a new-style
+ firmware. Hence, this is expected behavior, and not an
+ error condition. */
+ if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
+ {
+ TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+ result = FALSE;
+ goto clean_and_return;
+ }
+
+ if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
+ {
+ LOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
+ }
+
+ /*Download is successful*/
+ result = TRUE;
+
+clean_and_return:
+ TRACE("phLibNfc_HW_Reset()");
+ phLibNfc_HW_Reset();
+ /* Deinitialize Driver */
+ if(drive_state)
+ {
+ result = nfc_jni_unconfigure_driver(nat);
+ }
+ CONCURRENCY_UNLOCK();
+ nfc_cb_data_deinit(&cb_data);
+ return result;
+}
+
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] =
{
+ {"doDownload", "()Z",
+ (void *)com_android_nfc_NfcManager_doDownload},
+
{"initializeNativeStructure", "()Z",
(void *)com_android_nfc_NfcManager_init_native_struc},
-
+
{"initialize", "()Z",
(void *)com_android_nfc_NfcManager_initialize},