Merge "Implementation of NFC HAL 1.2"
diff --git a/1.2/Nfc.cpp b/1.2/Nfc.cpp
new file mode 100644
index 0000000..c197255
--- /dev/null
+++ b/1.2/Nfc.cpp
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ *  Copyright 2018 NXP
+ *  Copyright 2019 ST Microelectronics S.A.
+ *
+ *  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 "StNfc_hal_api.h"
+
+
+
+#define CHK_STATUS(x) ((x) == NFCSTATUS_SUCCESS) \
+      ? (V1_0::NfcStatus::OK) : (V1_0::NfcStatus::FAILED)
+
+bool nfc_debug_enabled = true;
+
+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*/);
+  }
+
+  int ret = StNfc_hal_open(eventCallback, dataCallback);
+  ALOGD_IF(nfc_debug_enabled, "Nfc::open Exit");
+  return ret == 0 ? V1_0::NfcStatus::OK : V1_0::NfcStatus::FAILED;
+}
+
+Return<uint32_t> Nfc::write(const hidl_vec<uint8_t>& data) {
+  hidl_vec<uint8_t> copy = data;
+
+  return StNfc_hal_write(data.size(), &data[0]);
+}
+
+Return<V1_0::NfcStatus> Nfc::coreInitialized(const hidl_vec<uint8_t>& data) {
+  hidl_vec<uint8_t> copy = data;
+
+  int ret = StNfc_hal_core_initialized(&copy[0]);
+  return ret == 0 ? V1_0::NfcStatus::OK : V1_0::NfcStatus::FAILED;
+}
+
+Return<V1_0::NfcStatus> Nfc::prediscover() {
+  return StNfc_hal_pre_discover() ? V1_0::NfcStatus::FAILED
+                                  : V1_0::NfcStatus::OK;
+}
+
+Return<V1_0::NfcStatus> Nfc::close() {
+  if (mCallbackV1_1 == nullptr && mCallbackV1_0 == nullptr) {
+    return V1_0::NfcStatus::FAILED;
+  }
+  int ret = StNfc_hal_close(NFC_MODE_OFF);
+
+  if (mCallbackV1_1 != nullptr) {
+    mCallbackV1_1->unlinkToDeath(this);
+    mCallbackV1_1 = nullptr;
+  }
+  if (mCallbackV1_0 != nullptr) {
+    mCallbackV1_0->unlinkToDeath(this);
+    mCallbackV1_0 = nullptr;
+  }
+  return ret == 0 ? V1_0::NfcStatus::OK : V1_0::NfcStatus::FAILED;
+}
+
+Return<V1_0::NfcStatus> Nfc::controlGranted() {
+  return StNfc_hal_control_granted() ? V1_0::NfcStatus::FAILED
+                                     : V1_0::NfcStatus::OK;
+}
+
+Return<V1_0::NfcStatus> Nfc::powerCycle() {
+  return StNfc_hal_power_cycle() ? V1_0::NfcStatus::FAILED
+                                 : V1_0::NfcStatus::OK;
+}
+
+// Methods from ::android::hardware::nfc::V1_1::INfc follow.
+Return<void> Nfc::factoryReset() {
+  StNfc_hal_factoryReset();
+  return Void();
+}
+
+Return<V1_0::NfcStatus> Nfc::closeForPowerOffCase() {
+  if (mCallbackV1_1 == nullptr && mCallbackV1_0 == nullptr) {
+    return V1_0::NfcStatus::FAILED;
+  }
+
+  int ret = StNfc_hal_closeForPowerOffCase();
+
+  if (mCallbackV1_1 != nullptr) {
+    mCallbackV1_1->unlinkToDeath(this);
+    mCallbackV1_1 = nullptr;
+  }
+  if (mCallbackV1_0 != nullptr) {
+    mCallbackV1_0->unlinkToDeath(this);
+    mCallbackV1_0 = nullptr;
+  }
+  return ret == 0 ? V1_0::NfcStatus::OK : V1_0::NfcStatus::FAILED;
+}
+
+Return<void> Nfc::getConfig(getConfig_cb hidl_cb) {
+  android::hardware::nfc::V1_1::NfcConfig nfcVendorConfig;
+  StNfc_hal_getConfig(nfcVendorConfig);
+  hidl_cb(nfcVendorConfig);
+  return Void();
+}
+
+Return<void> Nfc::getConfig_1_2(getConfig_1_2_cb hidl_cb) {
+  NfcConfig nfcVendorConfig;
+  StNfc_hal_getConfig_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 100644
index 0000000..77657d8
--- /dev/null
+++ b/1.2/Nfc.h
@@ -0,0 +1,114 @@
+/******************************************************************************
+ *
+ *  Copyright 2018 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);
+
+  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/StNfcService.cpp b/1.2/StNfcService.cpp
new file mode 100644
index 0000000..abc675f
--- /dev/null
+++ b/1.2/StNfcService.cpp
@@ -0,0 +1,51 @@
+/******************************************************************************
+ *
+ *  Copyright 2018 NXP
+ *  Copyright 2018 ST Microelectronics
+ *
+ *  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 "stnfc@1.0-service.st"
+#include <android/hardware/nfc/1.1/INfc.h>
+
+
+#include <hidl/LegacySupport.h>
+#include "Nfc.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;
+
+
+int main() {
+    ALOGD(" ST 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;
+    }
+    ALOGD(" ST NFC service is ready");
+    joinRpcThreadpool();
+    return 1;
+}
diff --git a/1.2/android.hardware.nfc@1.2-service.st.rc b/1.2/android.hardware.nfc@1.2-service.st.rc
new file mode 100644
index 0000000..cf31b3e
--- /dev/null
+++ b/1.2/android.hardware.nfc@1.2-service.st.rc
@@ -0,0 +1,4 @@
+service nfc_hal_service /vendor/bin/hw/android.hardware.nfc@1.2-service.st
+    class hal
+    user nfc
+    group nfc
diff --git a/Android.bp b/Android.bp
index 82e47bc..7cd2c80 100644
--- a/Android.bp
+++ b/Android.bp
@@ -47,6 +47,7 @@
     shared_libs: [
         "android.hardware.nfc@1.0",
         "android.hardware.nfc@1.1",
+        "android.hardware.nfc@1.2",
         "libbase",
         "libcutils",
         "libhardware",
@@ -59,14 +60,14 @@
 }
 
 cc_binary {
-    name: "android.hardware.nfc@1.1-service.st",
+    name: "android.hardware.nfc@1.2-service.st",
     defaults: ["hidl_defaults"],
     proprietary: true,
-    init_rc: ["1.1/android.hardware.nfc@1.1-service.st.rc"],
+    init_rc: ["1.2/android.hardware.nfc@1.2-service.st.rc"],
     relative_install_path: "hw",
     srcs: [
-        "1.1/StNfcService.cpp",
-        "1.1/Nfc.cpp",
+        "1.2/StNfcService.cpp",
+        "1.2/Nfc.cpp",
     ],
 
     shared_libs: [
@@ -78,6 +79,7 @@
         "libutils",
         "android.hardware.nfc@1.0",
         "android.hardware.nfc@1.1",
+        "android.hardware.nfc@1.2",
         "libhidlbase",
         "libhidltransport",
         "libhwbinder",
diff --git a/st21nfc/hal_st21nfc.cc b/st21nfc/hal_st21nfc.cc
index 3bd7bc6..b6fd45a 100644
--- a/st21nfc/hal_st21nfc.cc
+++ b/st21nfc/hal_st21nfc.cc
@@ -53,6 +53,7 @@
 int nfc_mode = 0;
 
 using namespace android::hardware::nfc::V1_1;
+using namespace android::hardware::nfc::V1_2;
 using android::hardware::nfc::V1_1::NfcEvent;
 
 /*
@@ -416,7 +417,7 @@
   return StNfc_hal_close(nfc_mode);
 }
 
-void StNfc_hal_getConfig(NfcConfig& config) {
+void StNfc_hal_getConfig(android::hardware::nfc::V1_1::NfcConfig& config) {
   STLOG_HAL_D("HAL st21nfc: %s", __func__);
   unsigned long num = 0;
   std::array<uint8_t, 10> buffer;
@@ -424,7 +425,7 @@
   buffer.fill(0);
   long retlen = 0;
 
-  memset(&config, 0x00, sizeof(NfcConfig));
+  memset(&config, 0x00, sizeof(android::hardware::nfc::V1_1::NfcConfig));
 
   if (GetNumValue(NAME_CE_ON_SWITCH_OFF_STATE, &num, sizeof(num))) {
     if (num == 0x1) {
@@ -487,3 +488,37 @@
     config.presenceCheckAlgorithm = (PresenceCheckAlgorithm)num;
   }
 }
+
+void StNfc_hal_getConfig_1_2(android::hardware::nfc::V1_2::NfcConfig& config) {
+  STLOG_HAL_D("HAL st21nfc: %s", __func__);
+  unsigned long num = 0;
+  std::array<uint8_t, 10> buffer;
+
+  buffer.fill(0);
+  long retlen = 0;
+
+  memset(&config, 0x00, sizeof(android::hardware::nfc::V1_2::NfcConfig));
+
+  StNfc_hal_getConfig(config.v1_1);
+
+  if (GetByteArrayValue(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 (GetByteArrayValue(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 (GetNumValue(NAME_DEFAULT_ISODEP_ROUTE, &num, sizeof(num))) {
+    config.defaultIsoDepRoute = num;
+
+  }
+}
diff --git a/st21nfc/include/StNfc_hal_api.h b/st21nfc/include/StNfc_hal_api.h
index 8881401..4ac52d8 100644
--- a/st21nfc/include/StNfc_hal_api.h
+++ b/st21nfc/include/StNfc_hal_api.h
@@ -20,11 +20,12 @@
 #ifndef _STNFC_HAL_API_H_
 #define _STNFC_HAL_API_H_
 
-#include <android/hardware/nfc/1.1/INfc.h>
-#include <android/hardware/nfc/1.1/types.h>
 #include <hardware/nfc.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_1::NfcConfig;
+using ::android::hardware::nfc::V1_2::NfcConfig;
 
 #define NFC_MODE_OFF 0
 #define NFC_MODE_QuickBoot 2
@@ -47,6 +48,7 @@
 
 int StNfc_hal_closeForPowerOffCase();
 
-void StNfc_hal_getConfig(NfcConfig& config);
+void StNfc_hal_getConfig(android::hardware::nfc::V1_1::NfcConfig& config);
+void StNfc_hal_getConfig_1_2(NfcConfig& config);
 
 #endif /* _STNFC_HAL_API_H_ */
diff --git a/st21nfc/include/hal_config.h b/st21nfc/include/hal_config.h
index fbddb08..190a9d9 100644
--- a/st21nfc/include/hal_config.h
+++ b/st21nfc/include/hal_config.h
@@ -37,5 +37,8 @@
 #define NAME_NFA_PROPRIETARY_CFG "NFA_PROPRIETARY_CFG"
 #define NAME_PRESENCE_CHECK_ALGORITHM "PRESENCE_CHECK_ALGORITHM"
 #define NAME_CE_ON_SWITCH_OFF_STATE "CE_ON_SWITCH_OFF_STATE"
+#define NAME_OFFHOST_ROUTE_ESE "OFFHOST_ROUTE_ESE"
+#define NAME_OFFHOST_ROUTE_UICC "OFFHOST_ROUTE_UICC"
+#define NAME_DEFAULT_ISODEP_ROUTE "DEFAULT_ISODEP_ROUTE"
 
 #endif