Merge "NfCC power state tracker implementation" into qt-dev
diff --git a/1.2/Nfc.cpp b/1.2/Nfc.cpp
new file mode 100755
index 0000000..540f982
--- /dev/null
+++ b/1.2/Nfc.cpp
@@ -0,0 +1,152 @@
+/******************************************************************************
+ *
+ *  Copyright 2018-2019 NXP
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#define LOG_TAG "android.hardware.nfc@1.2-impl"
+#include <log/log.h>
+#include "Nfc.h"
+#include "halimpl/inc/phNxpNciHal_Adaptation.h"
+#include "phNfcStatus.h"
+
+#define CHK_STATUS(x) ((x) == NFCSTATUS_SUCCESS) \
+      ? (V1_0::NfcStatus::OK) : (V1_0::NfcStatus::FAILED)
+
+extern bool nfc_debug_enabled;
+
+namespace android {
+namespace hardware {
+namespace nfc {
+namespace V1_2 {
+namespace implementation {
+
+sp<V1_1::INfcClientCallback> Nfc::mCallbackV1_1 = nullptr;
+sp<V1_0::INfcClientCallback> Nfc::mCallbackV1_0 = nullptr;
+
+Return<V1_0::NfcStatus> Nfc::open_1_1(
+    const sp<V1_1::INfcClientCallback>& clientCallback) {
+  if (clientCallback == nullptr) {
+    ALOGD_IF(nfc_debug_enabled, "Nfc::open null callback");
+    return V1_0::NfcStatus::FAILED;
+  } else {
+    mCallbackV1_1 = clientCallback;
+    mCallbackV1_1->linkToDeath(this, 0 /*cookie*/);
+  }
+  return open(clientCallback);
+}
+
+// Methods from ::android::hardware::nfc::V1_0::INfc follow.
+Return<V1_0::NfcStatus> Nfc::open(
+    const sp<V1_0::INfcClientCallback>& clientCallback) {
+  ALOGD_IF(nfc_debug_enabled, "Nfc::open Enter");
+  if (clientCallback == nullptr) {
+    ALOGD_IF(nfc_debug_enabled, "Nfc::open null callback");
+    return V1_0::NfcStatus::FAILED;
+  } else {
+    mCallbackV1_0 = clientCallback;
+    mCallbackV1_0->linkToDeath(this, 0 /*cookie*/);
+  }
+
+  NFCSTATUS status = phNxpNciHal_open(eventCallback, dataCallback);
+  ALOGD_IF(nfc_debug_enabled, "Nfc::open Exit");
+  return CHK_STATUS(status);
+}
+
+Return<uint32_t> Nfc::write(const hidl_vec<uint8_t>& data) {
+  hidl_vec<uint8_t> copy = data;
+  return phNxpNciHal_write(copy.size(), &copy[0]);
+}
+
+Return<V1_0::NfcStatus> Nfc::coreInitialized(const hidl_vec<uint8_t>& data) {
+  hidl_vec<uint8_t> copy = data;
+  NFCSTATUS status = phNxpNciHal_core_initialized(&copy[0]);
+  return CHK_STATUS(status);
+}
+
+Return<V1_0::NfcStatus> Nfc::prediscover() {
+  NFCSTATUS status = phNxpNciHal_pre_discover();
+  return CHK_STATUS(status);
+}
+
+Return<V1_0::NfcStatus> Nfc::close() {
+  if (mCallbackV1_1 == nullptr && mCallbackV1_0 == nullptr) {
+    return V1_0::NfcStatus::FAILED;
+  }
+  NFCSTATUS status = phNxpNciHal_close(false);
+
+  if (mCallbackV1_1 != nullptr) {
+    mCallbackV1_1->unlinkToDeath(this);
+    mCallbackV1_1 = nullptr;
+  }
+  if (mCallbackV1_0 != nullptr) {
+    mCallbackV1_0->unlinkToDeath(this);
+    mCallbackV1_0 = nullptr;
+  }
+  return CHK_STATUS(status);
+}
+
+Return<V1_0::NfcStatus> Nfc::controlGranted() {
+  NFCSTATUS status = phNxpNciHal_control_granted();
+  return CHK_STATUS(status);
+}
+
+Return<V1_0::NfcStatus> Nfc::powerCycle() {
+  NFCSTATUS status = phNxpNciHal_power_cycle();
+  return CHK_STATUS(status);
+}
+
+// Methods from ::android::hardware::nfc::V1_1::INfc follow.
+Return<void> Nfc::factoryReset() {
+  phNxpNciHal_do_factory_reset();
+  return Void();
+}
+
+Return<V1_0::NfcStatus> Nfc::closeForPowerOffCase() {
+  if (mCallbackV1_1 == nullptr && mCallbackV1_0 == nullptr) {
+    return V1_0::NfcStatus::FAILED;
+  }
+  NFCSTATUS status = phNxpNciHal_configDiscShutdown();
+
+  if (mCallbackV1_1 != nullptr) {
+    mCallbackV1_1->unlinkToDeath(this);
+    mCallbackV1_1 = nullptr;
+  }
+  if (mCallbackV1_0 != nullptr) {
+    mCallbackV1_0->unlinkToDeath(this);
+    mCallbackV1_0 = nullptr;
+  }
+  return CHK_STATUS(status);
+}
+
+Return<void> Nfc::getConfig(getConfig_cb hidl_cb) {
+  android::hardware::nfc::V1_1::NfcConfig nfcVendorConfig;
+  phNxpNciHal_getVendorConfig(nfcVendorConfig);
+  hidl_cb(nfcVendorConfig);
+  return Void();
+}
+
+// Methods from ::android::hardware::nfc::V1_2::INfc follow.
+Return<void> Nfc::getConfig_1_2(getConfig_1_2_cb hidl_cb) {
+  NfcConfig nfcVendorConfig;
+  phNxpNciHal_getVendorConfig_1_2(nfcVendorConfig);
+  hidl_cb(nfcVendorConfig);
+  return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace nfc
+}  // namespace hardware
+}  // namespace android
diff --git a/1.2/Nfc.h b/1.2/Nfc.h
new file mode 100755
index 0000000..3a5d76a
--- /dev/null
+++ b/1.2/Nfc.h
@@ -0,0 +1,114 @@
+/******************************************************************************
+ *
+ *  Copyright 2018-2019 NXP
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef ANDROID_HARDWARE_NFC_V1_2_NFC_H
+#define ANDROID_HARDWARE_NFC_V1_2_NFC_H
+
+#include <android/hardware/nfc/1.2/INfc.h>
+#include <android/hardware/nfc/1.2/types.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace nfc {
+namespace V1_2 {
+namespace implementation {
+
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::nfc::V1_2::INfc;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+struct Nfc : public V1_2::INfc, public hidl_death_recipient {
+ public:
+  // Methods from ::android::hardware::nfc::V1_0::INfc follow.
+  Return<V1_0::NfcStatus> open(
+      const sp<V1_0::INfcClientCallback>& clientCallback) override;
+  Return<V1_0::NfcStatus> open_1_1(
+      const sp<V1_1::INfcClientCallback>& clientCallback) override;
+  Return<uint32_t> write(const hidl_vec<uint8_t>& data) override;
+  Return<V1_0::NfcStatus> coreInitialized(
+      const hidl_vec<uint8_t>& data) override;
+  Return<V1_0::NfcStatus> prediscover() override;
+  Return<V1_0::NfcStatus> close() override;
+  Return<V1_0::NfcStatus> controlGranted() override;
+  Return<V1_0::NfcStatus> powerCycle() override;
+
+  // Methods from ::android::hardware::nfc::V1_1::INfc follow.
+  Return<void> factoryReset();
+  Return<V1_0::NfcStatus> closeForPowerOffCase();
+  Return<void> getConfig(getConfig_cb config);
+
+  // Methods from ::android::hardware::nfc::V1_2::INfc follow.
+  Return<void> getConfig_1_2(getConfig_1_2_cb config);
+
+  // Methods from ::android::hidl::base::V1_0::IBase follow.
+  static void eventCallback(uint8_t event, uint8_t status) {
+    if (mCallbackV1_1 != nullptr) {
+      auto ret = mCallbackV1_1->sendEvent_1_1((V1_1::NfcEvent)event,
+                                              (V1_0::NfcStatus)status);
+      if (!ret.isOk()) {
+        ALOGW("failed to send event!!!");
+      }
+    } else if (mCallbackV1_0 != nullptr) {
+      auto ret = mCallbackV1_0->sendEvent((V1_0::NfcEvent)event,
+                                          (V1_0::NfcStatus)status);
+      if (!ret.isOk()) {
+        ALOGE("failed to send event!!!");
+      }
+    }
+  }
+
+  static void dataCallback(uint16_t data_len, uint8_t* p_data) {
+    hidl_vec<uint8_t> data;
+    data.setToExternal(p_data, data_len);
+    if (mCallbackV1_1 != nullptr) {
+      auto ret = mCallbackV1_1->sendData(data);
+      if (!ret.isOk()) {
+        ALOGW("failed to send data!!!");
+      }
+    } else if (mCallbackV1_0 != nullptr) {
+      auto ret = mCallbackV1_0->sendData(data);
+      if (!ret.isOk()) {
+        ALOGE("failed to send data!!!");
+      }
+    }
+  }
+
+  virtual void serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
+    close();
+  }
+
+ private:
+  static sp<V1_1::INfcClientCallback> mCallbackV1_1;
+  static sp<V1_0::INfcClientCallback> mCallbackV1_0;
+};
+
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace nfc
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_NFC_V1_2_NFC_H
diff --git a/1.2/NxpNfcService.cpp b/1.2/NxpNfcService.cpp
new file mode 100755
index 0000000..7d9e76a
--- /dev/null
+++ b/1.2/NxpNfcService.cpp
@@ -0,0 +1,56 @@
+/******************************************************************************
+ *
+ *  Copyright 2018-2019 NXP
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#define LOG_TAG "nxpnfc@1.2-service"
+#include <android/hardware/nfc/1.2/INfc.h>
+#include <vendor/nxp/nxpnfc/1.0/INxpNfc.h>
+
+#include <hidl/LegacySupport.h>
+#include "Nfc.h"
+#include "NxpNfc.h"
+
+// Generated HIDL files
+using android::hardware::nfc::V1_2::INfc;
+using android::hardware::nfc::V1_2::implementation::Nfc;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::sp;
+using android::status_t;
+using android::OK;
+using vendor::nxp::nxpnfc::V1_0::INxpNfc;
+using vendor::nxp::nxpnfc::V1_0::implementation::NxpNfc;
+
+int main() {
+    ALOGD("NFC HAL Service 1.2 is starting.");
+    sp<INfc> nfc_service = new Nfc();
+
+    configureRpcThreadpool(1, true /*callerWillJoin*/);
+    status_t status = nfc_service->registerAsService();
+    if (status != OK) {
+        LOG_ALWAYS_FATAL("Could not register service for NFC HAL Iface (%d).", status);
+        return -1;
+    }
+    sp<INxpNfc> nxp_nfc_service = new NxpNfc();
+    status = nxp_nfc_service->registerAsService();
+    if (status != OK) {
+        ALOGD("Could not register service for NXP NFC Extn Iface (%d).", status);
+    }
+    ALOGD("NFC service is ready");
+    joinRpcThreadpool();
+    return 1;
+}
diff --git a/1.2/android.hardware.nfc@1.2-service.rc b/1.2/android.hardware.nfc@1.2-service.rc
new file mode 100755
index 0000000..7017c0e
--- /dev/null
+++ b/1.2/android.hardware.nfc@1.2-service.rc
@@ -0,0 +1,4 @@
+service vendor.nfc_hal_service /vendor/bin/hw/android.hardware.nfc@1.2-service
+    class hal
+    user nfc
+    group nfc
diff --git a/Android.bp b/Android.bp
index 6f12e84..7d5d199 100755
--- a/Android.bp
+++ b/Android.bp
@@ -68,6 +68,7 @@
     shared_libs: [
         "android.hardware.nfc@1.0",
         "android.hardware.nfc@1.1",
+        "android.hardware.nfc@1.2",
         "android.hardware.secure_element@1.0",
         "libbase",
         "libcutils",
@@ -82,15 +83,12 @@
     ],
 }
 
-cc_binary {
-    name: "android.hardware.nfc@1.1-service",
-    defaults: ["hidl_defaults"],
-    proprietary: true,
-    init_rc: ["1.1/android.hardware.nfc@1.1-service.rc"],
+cc_defaults {
+    name: "nxp_nfc_defaults",
     relative_install_path: "hw",
+    proprietary: true,
+    defaults: ["hidl_defaults"],
     srcs: [
-        "1.1/NxpNfcService.cpp",
-        "1.1/Nfc.cpp",
         "extns/impl/NxpNfc.cpp",
     ],
 
@@ -103,6 +101,7 @@
         "libutils",
         "android.hardware.nfc@1.0",
         "android.hardware.nfc@1.1",
+        "android.hardware.nfc@1.2",
         "libhidlbase",
         "libhidltransport",
         "libhwbinder",
@@ -111,3 +110,23 @@
         "vendor.nxp.nxpnfc@1.0",
     ],
 }
+
+cc_binary {
+    name: "android.hardware.nfc@1.1-service",
+    init_rc: ["1.1/android.hardware.nfc@1.1-service.rc"],
+    defaults: ["nxp_nfc_defaults"],
+    srcs: [
+        "1.1/NxpNfcService.cpp",
+        "1.1/Nfc.cpp",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.nfc@1.2-service",
+    init_rc: ["1.2/android.hardware.nfc@1.2-service.rc"],
+    defaults: ["nxp_nfc_defaults"],
+    srcs: [
+        "1.2/NxpNfcService.cpp",
+        "1.2/Nfc.cpp",
+    ],
+}
diff --git a/halimpl/hal/phNxpNciHal.cc b/halimpl/hal/phNxpNciHal.cc
index f579f0c..7d3264d 100755
--- a/halimpl/hal/phNxpNciHal.cc
+++ b/halimpl/hal/phNxpNciHal.cc
@@ -33,6 +33,7 @@
 #include <sys/stat.h>
 
 using namespace android::hardware::nfc::V1_1;
+using namespace android::hardware::nfc::V1_2;
 using android::hardware::nfc::V1_1::NfcEvent;
 
 /*********************** Global Variables *************************************/
@@ -2225,12 +2226,12 @@
  *
  ******************************************************************************/
 
-void phNxpNciHal_getVendorConfig(NfcConfig& config) {
+void phNxpNciHal_getVendorConfig(android::hardware::nfc::V1_1::NfcConfig& config) {
   unsigned long num = 0;
   std::array<uint8_t, NXP_MAX_CONFIG_STRING_LEN> buffer;
   buffer.fill(0);
   long retlen = 0;
-  memset(&config, 0x00, sizeof(NfcConfig));
+  memset(&config, 0x00, sizeof(android::hardware::nfc::V1_1::NfcConfig));
 
   phNxpNciHal_getPersistUiccSetting();
 
@@ -2288,6 +2289,42 @@
 }
 
 /******************************************************************************
+ * Function         phNxpNciHal_getVendorConfig_1_2
+ *
+ * Description      This function can be used by HAL to inform
+ *                 to update vendor configuration parametres
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+
+void phNxpNciHal_getVendorConfig_1_2(android::hardware::nfc::V1_2::NfcConfig& config) {
+  unsigned long num = 0;
+  std::array<uint8_t, NXP_MAX_CONFIG_STRING_LEN> buffer;
+  buffer.fill(0);
+  long retlen = 0;
+  memset(&config, 0x00, sizeof(android::hardware::nfc::V1_2::NfcConfig));
+  phNxpNciHal_getVendorConfig(config.v1_1);
+
+  if (GetNxpByteArrayValue(NAME_OFFHOST_ROUTE_UICC, (char*)buffer.data(), buffer.size(), &retlen)) {
+    config.offHostRouteUicc.resize(retlen);
+    for(int i=0; i<retlen; i++)
+      config.offHostRouteUicc[i] = buffer[i];
+  }
+
+  if (GetNxpByteArrayValue(NAME_OFFHOST_ROUTE_ESE, (char*)buffer.data(), buffer.size(), &retlen)) {
+    config.offHostRouteEse.resize(retlen);
+    for(int i=0; i<retlen; i++)
+      config.offHostRouteEse[i] = buffer[i];
+  }
+
+  if (GetNxpNumValue(NAME_DEFAULT_ISODEP_ROUTE, &num, sizeof(num))) {
+      config.defaultIsoDepRoute = num;
+  }
+
+}
+
+/******************************************************************************
  * Function         phNxpNciHal_notify_i2c_fragmentation
  *
  * Description      This function can be used by HAL to inform
diff --git a/halimpl/inc/phNxpNciHal_Adaptation.h b/halimpl/inc/phNxpNciHal_Adaptation.h
index c2a02cc..7da4fd5 100755
--- a/halimpl/inc/phNxpNciHal_Adaptation.h
+++ b/halimpl/inc/phNxpNciHal_Adaptation.h
@@ -18,10 +18,10 @@
 #define _PHNXPNCIHAL_ADAPTATION_H_
 
 #include <hardware/nfc.h>
-#include <android/hardware/nfc/1.1/INfc.h>
-#include <android/hardware/nfc/1.1/types.h>
+#include <android/hardware/nfc/1.2/INfc.h>
+#include <android/hardware/nfc/1.2/types.h>
 
-using ::android::hardware::nfc::V1_1::NfcConfig;
+using ::android::hardware::nfc::V1_2::NfcConfig;
 
 typedef struct {
   struct nfc_nci_device nci_device;
@@ -42,5 +42,6 @@
 int phNxpNciHal_power_cycle(void);
 int phNxpNciHal_ioctl(long arg, void* p_data);
 void phNxpNciHal_do_factory_reset(void);
-void phNxpNciHal_getVendorConfig(NfcConfig& config);
+void phNxpNciHal_getVendorConfig(android::hardware::nfc::V1_1::NfcConfig& config);
+void phNxpNciHal_getVendorConfig_1_2(NfcConfig& config);
 #endif /* _PHNXPNCIHAL_ADAPTATION_H_ */
diff --git a/halimpl/utils/phNxpConfig.h b/halimpl/utils/phNxpConfig.h
index e6931e2..3901c1d 100755
--- a/halimpl/utils/phNxpConfig.h
+++ b/halimpl/utils/phNxpConfig.h
@@ -104,6 +104,9 @@
 #define NAME_NFA_PROPRIETARY_CFG "NFA_PROPRIETARY_CFG"
 #define NAME_PRESENCE_CHECK_ALGORITHM "PRESENCE_CHECK_ALGORITHM"
 #define NAME_NXP_PHASE_TIRM_OFFSET_SIGN_UPDATE "NXP_PHASE_TIRM_OFFSET_SIGN_UPDATE"
+#define NAME_OFFHOST_ROUTE_ESE "OFFHOST_ROUTE_ESE"
+#define NAME_OFFHOST_ROUTE_UICC "OFFHOST_ROUTE_UICC"
+#define NAME_DEFAULT_ISODEP_ROUTE "DEFAULT_ISODEP_ROUTE"
 
 /* default configuration */
 #define default_storage_location "/data/vendor/nfc"