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