1 /******************************************************************************
2  *
3  *  Copyright 2022-2024 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 #include "Nfc.h"
20 
21 #include <android-base/logging.h>
22 
23 #include "NfcExtns.h"
24 #include "phNfcStatus.h"
25 #include "phNxpConfig.h"
26 #include "phNxpNciHal_Adaptation.h"
27 #include "phNxpNciHal_ext.h"
28 
29 #define CHK_STATUS(x) \
30   ((x) == NFCSTATUS_SUCCESS) ? (NfcStatus::OK) : (NfcStatus::FAILED)
31 
32 namespace aidl {
33 namespace android {
34 namespace hardware {
35 namespace nfc {
36 
37 std::shared_ptr<INfcClientCallback> Nfc::mCallback = nullptr;
38 AIBinder_DeathRecipient* clientDeathRecipient = nullptr;
39 std::mutex syncNfcOpenClose;
40 
OnDeath(void * cookie)41 void OnDeath(void* cookie) {
42   if (Nfc::mCallback != nullptr &&
43       !AIBinder_isAlive(Nfc::mCallback->asBinder().get())) {
44     std::lock_guard<std::mutex> lk(syncNfcOpenClose);
45     LOG(INFO) << __func__ << " Nfc service has died";
46     Nfc* nfc = static_cast<Nfc*>(cookie);
47     nfc->close(NfcCloseType::DISABLE);
48     LOG(INFO) << __func__ << " death NTF completed";
49   }
50 }
51 
open(const std::shared_ptr<INfcClientCallback> & clientCallback)52 ::ndk::ScopedAStatus Nfc::open(
53     const std::shared_ptr<INfcClientCallback>& clientCallback) {
54   LOG(INFO) << "Nfc::open";
55   if (clientCallback == nullptr) {
56     LOG(INFO) << "Nfc::open null callback";
57     return ndk::ScopedAStatus::fromServiceSpecificError(
58         static_cast<int32_t>(NfcStatus::FAILED));
59   }
60   std::lock_guard<std::mutex> lk(syncNfcOpenClose);
61   Nfc::mCallback = clientCallback;
62 
63   clientDeathRecipient = AIBinder_DeathRecipient_new(OnDeath);
64   auto linkRet = AIBinder_linkToDeath(clientCallback->asBinder().get(),
65                                       clientDeathRecipient, this /* cookie */);
66   if (linkRet != STATUS_OK) {
67     LOG(ERROR) << __func__ << ": linkToDeath failed: " << linkRet;
68     // Just ignore the error.
69   }
70 
71   printNfcMwVersion();
72   int ret = phNxpNciHal_open(eventCallback, dataCallback);
73   LOG(INFO) << "Nfc::open Exit";
74   return ret == NFCSTATUS_SUCCESS
75              ? ndk::ScopedAStatus::ok()
76              : ndk::ScopedAStatus::fromServiceSpecificError(
77                    static_cast<int32_t>(NfcStatus::FAILED));
78 }
79 
close(NfcCloseType type)80 ::ndk::ScopedAStatus Nfc::close(NfcCloseType type) {
81   LOG(INFO) << "Nfc::close";
82   if (Nfc::mCallback == nullptr) {
83     LOG(ERROR) << __func__ << "mCallback null";
84     return ndk::ScopedAStatus::fromServiceSpecificError(
85         static_cast<int32_t>(NfcStatus::FAILED));
86   }
87   int ret = 0;
88   if (type == NfcCloseType::HOST_SWITCHED_OFF) {
89     ret = phNxpNciHal_configDiscShutdown();
90   } else {
91     ret = phNxpNciHal_close(false);
92   }
93   AIBinder_DeathRecipient_delete(clientDeathRecipient);
94   clientDeathRecipient = nullptr;
95   return ret == NFCSTATUS_SUCCESS
96              ? ndk::ScopedAStatus::ok()
97              : ndk::ScopedAStatus::fromServiceSpecificError(
98                    static_cast<int32_t>(NfcStatus::FAILED));
99 }
100 
coreInitialized()101 ::ndk::ScopedAStatus Nfc::coreInitialized() {
102   LOG(INFO) << "Nfc::coreInitialized";
103   if (Nfc::mCallback == nullptr) {
104     LOG(ERROR) << __func__ << "mCallback null";
105     return ndk::ScopedAStatus::fromServiceSpecificError(
106         static_cast<int32_t>(NfcStatus::FAILED));
107   }
108   int ret = phNxpNciHal_core_initialized();
109 
110   return ret == NFCSTATUS_SUCCESS
111              ? ndk::ScopedAStatus::ok()
112              : ndk::ScopedAStatus::fromServiceSpecificError(
113                    static_cast<int32_t>(NfcStatus::FAILED));
114 }
115 
factoryReset()116 ::ndk::ScopedAStatus Nfc::factoryReset() {
117   LOG(INFO) << "Nfc::factoryReset";
118   phNxpNciHal_do_factory_reset();
119   return ndk::ScopedAStatus::ok();
120 }
121 
getConfig(NfcConfig * _aidl_return)122 ::ndk::ScopedAStatus Nfc::getConfig(NfcConfig* _aidl_return) {
123   LOG(INFO) << "Nfc::getConfig";
124   NfcConfig config;
125   NfcExtns nfcExtns;
126   nfcExtns.getConfig(config);
127   *_aidl_return = std::move(config);
128   return ndk::ScopedAStatus::ok();
129 }
130 
powerCycle()131 ::ndk::ScopedAStatus Nfc::powerCycle() {
132   LOG(INFO) << "powerCycle";
133   if (Nfc::mCallback == nullptr) {
134     LOG(ERROR) << __func__ << "mCallback null";
135     return ndk::ScopedAStatus::fromServiceSpecificError(
136         static_cast<int32_t>(NfcStatus::FAILED));
137   }
138   int ret = phNxpNciHal_power_cycle();
139   return ret == NFCSTATUS_SUCCESS
140              ? ndk::ScopedAStatus::ok()
141              : ndk::ScopedAStatus::fromServiceSpecificError(
142                    static_cast<int32_t>(NfcStatus::FAILED));
143 }
144 
preDiscover()145 ::ndk::ScopedAStatus Nfc::preDiscover() {
146   LOG(INFO) << "preDiscover";
147   if (Nfc::mCallback == nullptr) {
148     LOG(ERROR) << __func__ << "mCallback null";
149     return ndk::ScopedAStatus::fromServiceSpecificError(
150         static_cast<int32_t>(NfcStatus::FAILED));
151   }
152   int ret = phNxpNciHal_pre_discover();
153   return ret == NFCSTATUS_SUCCESS
154              ? ndk::ScopedAStatus::ok()
155              : ndk::ScopedAStatus::fromServiceSpecificError(
156                    static_cast<int32_t>(NfcStatus::FAILED));
157 }
158 
write(const std::vector<uint8_t> & data,int32_t * _aidl_return)159 ::ndk::ScopedAStatus Nfc::write(const std::vector<uint8_t>& data,
160                                 int32_t* _aidl_return) {
161   LOG(INFO) << "write";
162   if (Nfc::mCallback == nullptr) {
163     LOG(ERROR) << __func__ << "mCallback null";
164     return ndk::ScopedAStatus::fromServiceSpecificError(
165         static_cast<int32_t>(NfcStatus::FAILED));
166   }
167   *_aidl_return = phNxpNciHal_write(data.size(), &data[0]);
168   return ndk::ScopedAStatus::ok();
169 }
setEnableVerboseLogging(bool enable)170 ::ndk::ScopedAStatus Nfc::setEnableVerboseLogging(bool enable) {
171   LOG(INFO) << "setVerboseLogging";
172   phNxpNciHal_setVerboseLogging(enable);
173   return ndk::ScopedAStatus::ok();
174 }
175 
isVerboseLoggingEnabled(bool * _aidl_return)176 ::ndk::ScopedAStatus Nfc::isVerboseLoggingEnabled(bool* _aidl_return) {
177   *_aidl_return = phNxpNciHal_getVerboseLogging();
178   return ndk::ScopedAStatus::ok();
179 }
180 
controlGranted(NfcStatus * _aidl_return)181 ::ndk::ScopedAStatus Nfc::controlGranted(NfcStatus* _aidl_return) {
182   LOG(INFO) << "controlGranted";
183   int status = phNxpNciHal_control_granted();
184   *_aidl_return = CHK_STATUS(status);
185   return ndk::ScopedAStatus::ok();
186 }
187 
188 }  // namespace nfc
189 }  // namespace hardware
190 }  // namespace android
191 }  // namespace aidl
192