diff options
author | Jeff Hamilton <jham@android.com> | 2011-09-13 16:37:35 -0500 |
---|---|---|
committer | Jeff Hamilton <jham@android.com> | 2011-09-14 14:40:17 -0500 |
commit | 0fe7049a3224aa7b29cc980be07387e17607b0de (patch) | |
tree | bcef757afe6f8eac0b3a56d39439a4764cc12092 /jni/com_android_nfc_NativeNfcManager.cpp | |
parent | f40897302add5c03e7e5569bd73d03724335ba15 (diff) | |
download | packages_apps_nfc-0fe7049a3224aa7b29cc980be07387e17607b0de.zip packages_apps_nfc-0fe7049a3224aa7b29cc980be07387e17607b0de.tar.gz packages_apps_nfc-0fe7049a3224aa7b29cc980be07387e17607b0de.tar.bz2 |
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/com_android_nfc_NativeNfcManager.cpp')
-rw-r--r-- | jni/com_android_nfc_NativeNfcManager.cpp | 251 |
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}, |