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