1 /******************************************************************************
2  *
3  *  Copyright 2019-2023 NXP
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #define LOG_TAG "android.hardware.nfc@1.2-impl"
20 #include "Nfc.h"
21 
22 #include <log/log.h>
23 #include <memunreachable/memunreachable.h>
24 
25 #include "NfcExtns.h"
26 #include "halimpl/inc/phNxpNciHal_Adaptation.h"
27 #include "phNfcStatus.h"
28 #include "phNxpNciHal_ext.h"
29 
30 #define CHK_STATUS(x) \
31   ((x) == NFCSTATUS_SUCCESS) ? (V1_0::NfcStatus::OK) : (V1_0::NfcStatus::FAILED)
32 
33 extern bool nfc_debug_enabled;
34 
35 namespace android {
36 namespace hardware {
37 namespace nfc {
38 namespace V1_2 {
39 namespace implementation {
40 
41 sp<V1_1::INfcClientCallback> Nfc::mCallbackV1_1 = nullptr;
42 sp<V1_0::INfcClientCallback> Nfc::mCallbackV1_0 = nullptr;
43 
open_1_1(const sp<V1_1::INfcClientCallback> & clientCallback)44 Return<V1_0::NfcStatus> Nfc::open_1_1(
45     const sp<V1_1::INfcClientCallback>& clientCallback) {
46   if (clientCallback == nullptr) {
47     ALOGD_IF(nfc_debug_enabled, "Nfc::open null callback");
48     return V1_0::NfcStatus::FAILED;
49   } else {
50     mCallbackV1_1 = clientCallback;
51     mCallbackV1_1->linkToDeath(this, 0 /*cookie*/);
52   }
53   return open(clientCallback);
54 }
55 
56 // Methods from ::android::hardware::nfc::V1_0::INfc follow.
open(const sp<V1_0::INfcClientCallback> & clientCallback)57 Return<V1_0::NfcStatus> Nfc::open(
58     const sp<V1_0::INfcClientCallback>& clientCallback) {
59   if (mIsServiceStarted) {
60     ALOGD_IF(nfc_debug_enabled, "Nfc::open service is already started");
61     return V1_0::NfcStatus::OK;
62   }
63   ALOGD_IF(nfc_debug_enabled, "Nfc::open Enter");
64   if (clientCallback == nullptr) {
65     ALOGD_IF(nfc_debug_enabled, "Nfc::open null callback");
66     return V1_0::NfcStatus::FAILED;
67   } else {
68     mCallbackV1_0 = clientCallback;
69     mCallbackV1_0->linkToDeath(this, 0 /*cookie*/);
70   }
71   printNfcMwVersion();
72   NFCSTATUS status = phNxpNciHal_open(eventCallback, dataCallback);
73   mIsServiceStarted = true;
74   ALOGD_IF(nfc_debug_enabled, "Nfc::open Exit");
75   return CHK_STATUS(status);
76 }
77 
write(const hidl_vec<uint8_t> & data)78 Return<uint32_t> Nfc::write(const hidl_vec<uint8_t>& data) {
79   hidl_vec<uint8_t> copy = data;
80   return phNxpNciHal_write(copy.size(), &copy[0]);
81 }
82 
coreInitialized(const hidl_vec<uint8_t> & data)83 Return<V1_0::NfcStatus> Nfc::coreInitialized(const hidl_vec<uint8_t>& data) {
84   hidl_vec<uint8_t> copy = data;
85   NFCSTATUS status = phNxpNciHal_core_initialized(copy.size(), &copy[0]);
86   return CHK_STATUS(status);
87 }
88 
prediscover()89 Return<V1_0::NfcStatus> Nfc::prediscover() { return V1_0::NfcStatus::OK; }
90 
close()91 Return<V1_0::NfcStatus> Nfc::close() {
92   if (mCallbackV1_1 == nullptr && mCallbackV1_0 == nullptr) {
93     return V1_0::NfcStatus::FAILED;
94   }
95   NFCSTATUS status = phNxpNciHal_close(false);
96   mIsServiceStarted = false;
97 
98   if (mCallbackV1_1 != nullptr) {
99     mCallbackV1_1->unlinkToDeath(this);
100     mCallbackV1_1 = nullptr;
101   }
102   if (mCallbackV1_0 != nullptr) {
103     mCallbackV1_0->unlinkToDeath(this);
104     mCallbackV1_0 = nullptr;
105   }
106   return CHK_STATUS(status);
107 }
108 
controlGranted()109 Return<V1_0::NfcStatus> Nfc::controlGranted() {
110   NFCSTATUS status = phNxpNciHal_control_granted();
111   return CHK_STATUS(status);
112 }
113 
powerCycle()114 Return<V1_0::NfcStatus> Nfc::powerCycle() {
115   NFCSTATUS status = phNxpNciHal_power_cycle();
116   return CHK_STATUS(status);
117 }
118 
119 // Methods from ::android::hardware::nfc::V1_1::INfc follow.
factoryReset()120 Return<void> Nfc::factoryReset() {
121   phNxpNciHal_do_factory_reset();
122   return Void();
123 }
124 
closeForPowerOffCase()125 Return<V1_0::NfcStatus> Nfc::closeForPowerOffCase() {
126   if (mCallbackV1_1 == nullptr && mCallbackV1_0 == nullptr) {
127     return V1_0::NfcStatus::FAILED;
128   }
129   NFCSTATUS status = phNxpNciHal_configDiscShutdown();
130   mIsServiceStarted = false;
131   if (mCallbackV1_1 != nullptr) {
132     mCallbackV1_1->unlinkToDeath(this);
133     mCallbackV1_1 = nullptr;
134   }
135   if (mCallbackV1_0 != nullptr) {
136     mCallbackV1_0->unlinkToDeath(this);
137     mCallbackV1_0 = nullptr;
138   }
139   return CHK_STATUS(status);
140 }
141 
getConfig(getConfig_cb hidl_cb)142 Return<void> Nfc::getConfig(getConfig_cb hidl_cb) {
143   android::hardware::nfc::V1_1::NfcConfig nfcVendorConfig;
144   NfcExtns nfcExtns;
145   nfcExtns.getConfig(nfcVendorConfig);
146   hidl_cb(nfcVendorConfig);
147   return Void();
148 }
149 
getConfig_1_2(getConfig_1_2_cb hidl_cb)150 Return<void> Nfc::getConfig_1_2(getConfig_1_2_cb hidl_cb) {
151   NfcConfig nfcVendorConfig;
152   NfcExtns nfcExtns;
153   nfcExtns.getConfig(nfcVendorConfig);
154   hidl_cb(nfcVendorConfig);
155   return Void();
156 }
157 
serviceDied(uint64_t,const wp<IBase> &)158 void Nfc::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
159   if (mCallbackV1_1 == nullptr && mCallbackV1_0 == nullptr) {
160     return;
161   }
162   phNxpNciHal_close(true);
163   mIsServiceStarted = false;
164 
165   if (mCallbackV1_1 != nullptr) {
166     mCallbackV1_1->unlinkToDeath(this);
167     mCallbackV1_1 = nullptr;
168   }
169   if (mCallbackV1_0 != nullptr) {
170     mCallbackV1_0->unlinkToDeath(this);
171     mCallbackV1_0 = nullptr;
172   }
173 }
174 
debug(const hidl_handle &,const hidl_vec<hidl_string> &)175 Return<void> Nfc::debug(const hidl_handle& /* fd */,
176                         const hidl_vec<hidl_string>& /* options */) {
177   ALOGD_IF(nfc_debug_enabled, "\n Nfc HAL MemoryLeak Info =  %s \n",
178            android::GetUnreachableMemoryString(true, 10000).c_str());
179   return Void();
180 }
181 
182 }  // namespace implementation
183 }  // namespace V1_2
184 }  // namespace nfc
185 }  // namespace hardware
186 }  // namespace android
187