1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include "nfc_controller_stub.h"
16
17#include "ipc_skeleton.h"
18#include "loghelper.h"
19#include "ndef_msg_callback_proxy.h"
20#include "nfc_sdk_common.h"
21#include "nfc_service_ipc_interface_code.h"
22#include "nfc_controller_death_recipient.h"
23#include "nfc_permission_checker.h"
24#ifdef VENDOR_APPLICATIONS_ENABLED
25#include "on_card_emulation_notify_cb_proxy.h"
26#include "query_app_info_callback_proxy.h"
27#endif
28#include "external_deps_proxy.h"
29
30namespace OHOS {
31namespace NFC {
32int NfcControllerStub::OnRemoteRequest(uint32_t code,         /* [in] */
33                                       MessageParcel& data,   /* [in] */
34                                       MessageParcel& reply,  /* [out] */
35                                       MessageOption& option) /* [in] */
36{
37    InfoLog("NfcControllerStub OnRemoteRequest occur, code is %{public}d", code);
38    if (data.ReadInterfaceToken() != GetDescriptor()) {
39        ErrorLog("NfcControllerStub OnRemoteRequest GetDescriptor failed");
40        return KITS::ERR_NFC_PARAMETERS;
41    }
42    switch (code) {
43        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_GET_STATE):
44            return HandleGetState(data, reply);
45        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_TURN_ON):
46            return HandleTurnOn(data, reply);
47        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_TURN_OFF):
48            return HandleTurnOff(data, reply);
49        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_REGISTER_CALLBACK):
50            return HandleRegisterCallBack(data, reply);
51        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_UNREGISTER_CALLBACK):
52            return HandleUnRegisterCallBack(data, reply);
53        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_IS_NFC_OPEN):
54            return HandleIsNfcOpen(data, reply);
55        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_GET_TAG_INTERFACE):
56            return HandleGetNfcTagInterface(data, reply);
57        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_REG_NDEF_MSG_CALLBACK):
58            return HandleRegNdefMsgCb(data, reply);
59#ifdef VENDOR_APPLICATIONS_ENABLED
60        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_QUERY_APP_INFO_MSG_CALLBACK):
61            return HandleRegQueryApplicationCb(data, reply);
62        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_ON_CARD_EMULATION_NOTIFY):
63            return HandleRegCardEmulationNotifyCb(data, reply);
64        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_VENDOR_NOTIFY):
65            return HandleNotifyEventStatus(data, reply);
66#endif
67        case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_GET_HCE_INTERFACE):
68            return HandleGetNfcHceInterface(data, reply);
69        default:
70            return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
71    }
72}
73
74int NfcControllerStub::HandleGetState(MessageParcel& data, MessageParcel& reply)
75{
76    int state = GetState();
77    reply.WriteInt32(state);
78    return ERR_NONE;
79}
80
81int NfcControllerStub::HandleTurnOn(MessageParcel& data, MessageParcel& reply)
82{
83    if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::SYS_PERM)) {
84        ErrorLog("HandleTurnOn no permission");
85        reply.WriteInt32(KITS::ErrorCode::ERR_NO_PERMISSION);
86        return KITS::ErrorCode::ERR_NO_PERMISSION;
87    }
88    std::string appPackageName = ExternalDepsProxy::GetInstance().GetBundleNameByUid(IPCSkeleton::GetCallingUid());
89    ExternalDepsProxy::GetInstance().WriteAppBehaviorHiSysEvent(SubErrorCode::TURN_ON_NFC, appPackageName);
90    int statusCode = TurnOn();
91    reply.WriteInt32(statusCode);
92    return statusCode;
93}
94
95int NfcControllerStub::HandleTurnOff(MessageParcel& data, MessageParcel& reply)
96{
97    if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::SYS_PERM)) {
98        ErrorLog("HandleTurnOff no permission");
99        reply.WriteInt32(KITS::ErrorCode::ERR_NO_PERMISSION);
100        return KITS::ErrorCode::ERR_NO_PERMISSION;
101    }
102    std::string appPackageName = ExternalDepsProxy::GetInstance().GetBundleNameByUid(IPCSkeleton::GetCallingUid());
103    ExternalDepsProxy::GetInstance().WriteAppBehaviorHiSysEvent(SubErrorCode::TURN_OFF_NFC, appPackageName);
104    int statusCode = TurnOff();
105    reply.WriteInt32(statusCode);
106    return statusCode;
107}
108
109int NfcControllerStub::HandleIsNfcOpen(MessageParcel& data, MessageParcel& reply)
110{
111    bool isOpen = false;
112    int statusCode = IsNfcOpen(isOpen);
113    reply.WriteBool(isOpen);
114    return statusCode;
115}
116
117int NfcControllerStub::HandleRegisterCallBack(MessageParcel &data, MessageParcel &reply)
118{
119    std::string type = data.ReadString();
120    int exception = data.ReadInt32();
121    if (exception) {
122        return KITS::ERR_NFC_PARAMETERS;
123    }
124    KITS::ErrorCode ret = KITS::ERR_NFC_PARAMETERS;
125    do {
126        sptr<IRemoteObject> remote = data.ReadRemoteObject();
127        if (remote == nullptr) {
128            DebugLog("Failed to readRemoteObject!");
129            break;
130        }
131
132        std::unique_ptr<NfcControllerDeathRecipient> recipient
133            = std::make_unique<NfcControllerDeathRecipient>(this, IPCSkeleton::GetCallingTokenID());
134        if (recipient == nullptr) {
135            ErrorLog("recipient is null");
136            return ERR_NONE;
137        }
138        sptr<IRemoteObject::DeathRecipient> dr(recipient.release());
139        if ((remote->IsProxyObject()) && (!remote->AddDeathRecipient(dr))) {
140            ErrorLog("Failed to add death recipient");
141            return ERR_NONE;
142        }
143
144        {
145            std::lock_guard<std::mutex> guard(mutex_);
146            deathRecipient_ = dr;
147            callback_ = iface_cast<INfcControllerCallback>(remote);
148            if (callback_ == nullptr) {
149                callback_ = new (std::nothrow) NfcControllerCallBackProxy(remote);
150                DebugLog("create new `NfcControllerCallBackProxy`!");
151            }
152            ret = RegisterCallBack(callback_, type);
153        }
154    } while (0);
155
156    reply.WriteInt32(ret);
157    return ERR_NONE;
158}
159
160void NfcControllerStub::RemoveNfcDeathRecipient(const wptr<IRemoteObject> &remote)
161{
162    std::lock_guard<std::mutex> guard(mutex_);
163    if (callback_ == nullptr) {
164        ErrorLog("OnRemoteDied callback_ is nullptr");
165        return;
166    }
167    auto serviceRemote = callback_->AsObject();
168    if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
169        serviceRemote->RemoveDeathRecipient(deathRecipient_);
170        callback_ = nullptr;
171        ErrorLog("on remote died");
172    }
173}
174
175int NfcControllerStub::HandleUnRegisterCallBack(MessageParcel &data, MessageParcel &reply)
176{
177    InfoLog("OnUnRegisterCallBack");
178    std::string type = data.ReadString();
179    int exception = data.ReadInt32();
180    if (exception) {
181        return KITS::ERR_NFC_PARAMETERS;
182    }
183    KITS::ErrorCode ret = UnRegisterCallBack(type);
184    DebugLog("OnUnRegisterCallBack::OnUnRegisterCallBack end##ret=%{public}d\n", ret);
185    reply.WriteInt32(ret);
186    return ERR_NONE;
187}
188
189KITS::ErrorCode NfcControllerStub::RegisterCallBack(const sptr<INfcControllerCallback> &callback,
190    const std::string& type)
191{
192    return RegisterCallBack(callback, type, IPCSkeleton::GetCallingTokenID());
193}
194
195KITS::ErrorCode NfcControllerStub::UnRegisterCallBack(const std::string& type)
196{
197    return UnRegisterCallBack(type, IPCSkeleton::GetCallingTokenID());
198}
199
200int NfcControllerStub::HandleGetNfcTagInterface(MessageParcel& data, MessageParcel& reply)
201{
202    if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::TAG_PERM)) {
203        ErrorLog("HandleGetNfcTagInterface no permission");
204        return KITS::ErrorCode::ERR_NO_PERMISSION;
205    }
206    OHOS::sptr<IRemoteObject> remoteOjbect = GetTagServiceIface();
207    if (remoteOjbect == nullptr) {
208        ErrorLog("HandleGetNfcTagInterface remoteOjbect null!");
209        return KITS::ERR_NFC_PARAMETERS;
210    }
211
212    reply.WriteRemoteObject(remoteOjbect);
213    return ERR_NONE;
214}
215
216int NfcControllerStub::HandleGetNfcHceInterface(MessageParcel& data, MessageParcel& reply)
217{
218    if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
219        ErrorLog("HandleGetNfcHceInterface no permission");
220        return KITS::ErrorCode::ERR_NO_PERMISSION;
221    }
222    OHOS::sptr<IRemoteObject> remoteOjbect = GetHceServiceIface();
223    if (remoteOjbect == nullptr) {
224        ErrorLog("HandleGetNfcHceInterface remoteOjbect null!");
225        return KITS::ERR_NFC_PARAMETERS;
226    }
227
228    reply.WriteRemoteObject(remoteOjbect);
229    return ERR_NONE;
230}
231
232int NfcControllerStub::HandleRegNdefMsgCb(MessageParcel& data, MessageParcel& reply)
233{
234    if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::TAG_PERM)) {
235        ErrorLog("HandleRegNdefMsgCb no permission");
236        return KITS::ErrorCode::ERR_NO_PERMISSION;
237    }
238    InfoLog("NfcControllerStub::HandleRegNdefMsgCb");
239    KITS::ErrorCode ret = KITS::ERR_NFC_PARAMETERS;
240    do {
241        sptr<IRemoteObject> remote = data.ReadRemoteObject();
242        if (remote == nullptr) {
243            DebugLog("Failed to readRemoteObject!");
244            break;
245        }
246        {
247            std::lock_guard<std::mutex> guard(mutex_);
248            ndefCallback_ = iface_cast<INdefMsgCallback>(remote);
249            if (ndefCallback_ == nullptr) {
250                ndefCallback_ = new (std::nothrow) NdefMsgCallbackProxy(remote);
251                DebugLog("NfcControllerStub::HandleRegNdefMsgCb, create new `NdefMsgCallbackProxy`!");
252            }
253            ret = RegNdefMsgCallback(ndefCallback_);
254        }
255    } while (0);
256    reply.WriteInt32(ret);
257    return ERR_NONE;
258}
259
260#ifdef VENDOR_APPLICATIONS_ENABLED
261int NfcControllerStub::HandleRegQueryApplicationCb(MessageParcel& data, MessageParcel& reply)
262{
263    if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
264        ErrorLog("HandleRegQueryApplicationCb no permission");
265        return KITS::ErrorCode::ERR_NO_PERMISSION;
266    }
267    InfoLog("NfcControllerStub::HandleRegQueryApplicationCb");
268    sptr<IRemoteObject> remote = data.ReadRemoteObject();
269    if (remote == nullptr) {
270        ErrorLog("Failed to readRemoteObject!");
271        return KITS::ERR_NFC_PARAMETERS;
272    }
273    {
274        std::lock_guard<std::mutex> guard(mutex_);
275        queryAppInfoCallback_ = iface_cast<IQueryAppInfoCallback>(remote);
276        if (queryAppInfoCallback_ == nullptr) {
277            queryAppInfoCallback_ = new (std::nothrow) QueryAppInfoCallbackProxy(remote);
278            DebugLog("NfcControllerStub::HandleRegQueryApplicationCb, create new `QueryAppInfoCallbackProxy`!");
279        }
280        int ret = RegQueryApplicationCb(queryAppInfoCallback_);
281        reply.WriteInt32(ret);
282    }
283    return ERR_NONE;
284}
285
286int NfcControllerStub::HandleRegCardEmulationNotifyCb(MessageParcel& data, MessageParcel& reply)
287{
288    if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
289        ErrorLog("HandleRegCardEmulationNotifyCb no permission");
290        return KITS::ErrorCode::ERR_NO_PERMISSION;
291    }
292    InfoLog("NfcControllerStub::HandleRegCardEmulationNotifyCb");
293    sptr<IRemoteObject> remote = data.ReadRemoteObject();
294    if (remote == nullptr) {
295        ErrorLog("Failed to readRemoteObject!");
296        return KITS::ERR_NFC_PARAMETERS;
297    }
298    {
299        std::lock_guard<std::mutex> guard(mutex_);
300        onCardEmulationNotifyCb_ = iface_cast<IOnCardEmulationNotifyCb>(remote);
301        if (onCardEmulationNotifyCb_ == nullptr) {
302            onCardEmulationNotifyCb_ = new (std::nothrow) OnCardEmulationNotifyCbProxy(remote);
303            DebugLog("NfcControllerStub::HandleRegCardEmulationNotifyCb, create new `OnCardEmulationNotifyCbProxy`!");
304        }
305        int ret = RegCardEmulationNotifyCb(onCardEmulationNotifyCb_);
306        reply.WriteInt32(ret);
307    }
308    return ERR_NONE;
309}
310int NfcControllerStub::HandleNotifyEventStatus(MessageParcel& data, MessageParcel& reply)
311{
312    if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
313        ErrorLog("HandleNotifyEventStatus no permission");
314        return KITS::ErrorCode::ERR_NO_PERMISSION;
315    }
316    int eventType = data.ReadInt32();
317    int arg1 = data.ReadInt32();
318    std::string arg2 = data.ReadString();
319    int exception = data.ReadInt32();
320    if (exception) {
321        ErrorLog("HandleNotifyEventStatus::read param failed.");
322        return KITS::ERR_NFC_PARAMETERS;
323    }
324    KITS::ErrorCode ret = NotifyEventStatus(eventType, arg1, arg2);
325    reply.WriteInt32(ret);
326    return ERR_NONE;
327}
328#endif
329
330KITS::ErrorCode NfcControllerStub::RegNdefMsgCb(const sptr<INdefMsgCallback> &callback)
331{
332    if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::TAG_PERM)) {
333        ErrorLog("RegNdefMsgCb no permission");
334        return KITS::ErrorCode::ERR_NO_PERMISSION;
335    }
336    InfoLog("NfcControllerStub::RegNdefMsgCb");
337    return RegNdefMsgCallback(callback);
338}
339}  // namespace NFC
340}  // namespace OHOS
341