1 /*
2 * Copyright (C) 2023 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
16 #include "hce_session.h"
17
18 #include "accesstoken_kit.h"
19 #include "external_deps_proxy.h"
20 #include "hce_cmd_death_recipient.h"
21 #include "ipc_skeleton.h"
22 #include "loghelper.h"
23
24 namespace OHOS {
25 namespace NFC {
26 namespace HCE {
27 using OHOS::AppExecFwk::ElementName;
28
HceSession(std::shared_ptr<INfcService> service)29 HceSession::HceSession(std::shared_ptr<INfcService> service) : nfcService_(service)
30 {
31 if (service == nullptr) {
32 ErrorLog("HceSession create fail, service is nullptr");
33 return;
34 }
35 ceService_ = service->GetCeService();
36 }
37
~HceSession()38 HceSession::~HceSession()
39 {
40 }
41
CallbackEnter(uint32_t code)42 int32_t HceSession::CallbackEnter(uint32_t code)
43 {
44 InfoLog("HceSession code[%{public}u]", code);
45 return ERR_NONE;
46 }
47
CallbackExit(uint32_t code,int32_t result)48 int32_t HceSession::CallbackExit(uint32_t code, int32_t result)
49 {
50 InfoLog("HceSession code[%{public}u], result[%{public}d]", code, result);
51 return ERR_NONE;
52 }
53
RemoveHceDeathRecipient(const wptr<IRemoteObject> & remote)54 void HceSession::RemoveHceDeathRecipient(const wptr<IRemoteObject> &remote)
55 {
56 InfoLog("enter.");
57 std::lock_guard<std::mutex> guard(mutex_);
58 if (hceCmdCallback_ == nullptr) {
59 ErrorLog("hce OnRemoteDied callback_ is nullptr");
60 return;
61 }
62 auto serviceRemote = hceCmdCallback_->AsObject();
63 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
64 serviceRemote->RemoveDeathRecipient(deathRecipient_);
65 hceCmdCallback_ = nullptr;
66 ErrorLog("hce on remote died");
67 }
68 }
69
RegHceCmdCallback(const sptr<IHceCmdCallback> & cb,const std::string & type)70 ErrCode HceSession::RegHceCmdCallback(const sptr<IHceCmdCallback>& cb, const std::string& type)
71 {
72 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
73 ErrorLog("RegHceCmdCallback, ERR_NO_PERMISSION");
74 return KITS::ERR_NO_PERMISSION;
75 }
76 if (cb == nullptr || cb->AsObject() == nullptr) {
77 ErrorLog("input callback nullptr.");
78 return KITS::ERR_HCE_PARAMETERS;
79 }
80 if (ceService_.expired()) {
81 ErrorLog("ceService_ is nullptr");
82 return KITS::ERR_HCE_PARAMETERS;
83 }
84
85 std::unique_ptr<HceCmdDeathRecipient> recipient =
86 std::make_unique<HceCmdDeathRecipient>(this, IPCSkeleton::GetCallingTokenID());
87 sptr<IRemoteObject::DeathRecipient> dr(recipient.release());
88 if (!cb->AsObject()->AddDeathRecipient(dr)) {
89 ErrorLog("Failed to add death recipient");
90 return KITS::ERR_HCE_PARAMETERS;
91 }
92
93 std::lock_guard<std::mutex> guard(mutex_);
94 deathRecipient_ = dr;
95 hceCmdCallback_ = cb;
96 if (ceService_.lock()->RegHceCmdCallback(cb, type, IPCSkeleton::GetCallingTokenID())) {
97 return KITS::ERR_NONE;
98 }
99 return KITS::ERR_NFC_PARAMETERS;
100 }
101
UnregHceCmdCallback(const sptr<IHceCmdCallback> & cb,const std::string & type)102 ErrCode HceSession::UnregHceCmdCallback(const sptr<IHceCmdCallback>& cb, const std::string& type)
103 {
104 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
105 ErrorLog("UnregHceCmdCallback, ERR_NO_PERMISSION");
106 return KITS::ERR_NO_PERMISSION;
107 }
108 if (cb == nullptr || cb->AsObject() == nullptr) {
109 ErrorLog("input callback nullptr.");
110 return KITS::ERR_HCE_PARAMETERS;
111 }
112 if (ceService_.expired()) {
113 ErrorLog("ceService_ is nullptr");
114 return KITS::ERR_HCE_PARAMETERS;
115 }
116
117 std::lock_guard<std::mutex> guard(mutex_);
118 if (!cb->AsObject()->RemoveDeathRecipient(deathRecipient_)) {
119 ErrorLog("Failed to remove death recipient");
120 return KITS::ERR_NONE;
121 }
122 if (ceService_.lock()->UnRegHceCmdCallback(type, IPCSkeleton::GetCallingTokenID())) {
123 return KITS::ERR_NONE;
124 }
125 return KITS::ERR_HCE_PARAMETERS;
126 }
127
UnRegAllCallback(Security::AccessToken::AccessTokenID callerToken)128 KITS::ErrorCode HceSession::UnRegAllCallback(Security::AccessToken::AccessTokenID callerToken)
129 {
130 if (ceService_.expired()) {
131 ErrorLog("UnRegAllCallback ceService_ is nullptr");
132 return KITS::ERR_HCE_PARAMETERS;
133 }
134 if (ceService_.lock()->UnRegAllCallback(callerToken)) {
135 return KITS::ERR_NONE;
136 }
137 return KITS::ERR_HCE_PARAMETERS;
138 }
139
HandleWhenRemoteDie(Security::AccessToken::AccessTokenID callerToken)140 KITS::ErrorCode HceSession::HandleWhenRemoteDie(Security::AccessToken::AccessTokenID callerToken)
141 {
142 if (ceService_.expired()) {
143 ErrorLog("HandleWhenRemoteDie ceService_ is nullptr");
144 return KITS::ERR_HCE_PARAMETERS;
145 }
146 if (ceService_.lock()->HandleWhenRemoteDie(callerToken)) {
147 return KITS::ERR_NONE;
148 }
149 return KITS::ERR_HCE_PARAMETERS;
150 }
151
SendRawFrame(const std::string & hexCmdData,bool raw,std::string & hexRespData)152 ErrCode HceSession::SendRawFrame(const std::string& hexCmdData, bool raw, std::string& hexRespData)
153 {
154 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
155 ErrorLog("SendRawFrame, ERR_NO_PERMISSION");
156 return KITS::ERR_NO_PERMISSION;
157 }
158
159 if (hexCmdData.size() > KITS::MAX_APDU_DATA_HEX_STR) {
160 ErrorLog("raw frame too long");
161 return KITS::ERR_HCE_PARAMETERS;
162 }
163
164 if (ceService_.expired()) {
165 ErrorLog("SendRawFrame ceService_ is nullptr");
166 return KITS::ERR_HCE_PARAMETERS;
167 }
168
169 if (ceService_.lock()->SendHostApduData(hexCmdData, raw, hexRespData, IPCSkeleton::GetCallingTokenID())) {
170 return KITS::ERR_NONE;
171 } else {
172 return KITS::ERR_HCE_STATE_IO_FAILED;
173 }
174 }
175
IsDefaultService(const ElementName & element,const std::string & type,bool & isDefaultService)176 ErrCode HceSession::IsDefaultService(const ElementName& element, const std::string& type, bool& isDefaultService)
177 {
178 if (ceService_.expired()) {
179 ErrorLog("IsDefaultService ceService_ is nullptr");
180 return KITS::ERR_HCE_PARAMETERS;
181 }
182 isDefaultService = ceService_.lock()->IsDefaultService(element, type);
183 return KITS::ERR_NONE;
184 }
185
StartHce(const ElementName & element,const std::vector<std::string> & aids)186 ErrCode HceSession::StartHce(const ElementName& element, const std::vector<std::string>& aids)
187 {
188 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
189 ErrorLog("StartHce, ERR_NO_PERMISSION");
190 return KITS::ERR_NO_PERMISSION;
191 }
192
193 Security::AccessToken::HapTokenInfo hapTokenInfo;
194 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
195 int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callerToken, hapTokenInfo);
196 InfoLog("get hap token info, result = %{public}d", result);
197 if (result) {
198 return KITS::ERR_HCE_PARAMETERS;
199 }
200 if (hapTokenInfo.bundleName.empty()) {
201 ErrorLog("StartHce: not got bundle name");
202 return KITS::ERR_HCE_PARAMETERS;
203 }
204 if (hapTokenInfo.bundleName != element.GetBundleName()) {
205 ErrorLog("StartHce: wrong bundle name");
206 return KITS::ERR_HCE_PARAMETERS;
207 }
208
209 if (ceService_.expired()) {
210 ErrorLog("StartHce ceService_ is nullptr");
211 return KITS::ERR_HCE_PARAMETERS;
212 }
213 if (ceService_.lock()->StartHce(element, aids)) {
214 return KITS::ERR_NONE;
215 }
216 return KITS::ERR_HCE_PARAMETERS;
217 }
218
StopHce(const ElementName & element)219 ErrCode HceSession::StopHce(const ElementName& element)
220 {
221 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
222 ErrorLog("StopHce, ERR_NO_PERMISSION");
223 return KITS::ERR_NO_PERMISSION;
224 }
225
226 Security::AccessToken::HapTokenInfo hapTokenInfo;
227 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
228 int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callerToken, hapTokenInfo);
229 InfoLog("get hap token info, result = %{public}d", result);
230 if (result) {
231 return KITS::ERR_HCE_PARAMETERS;
232 }
233 if (hapTokenInfo.bundleName.empty()) {
234 ErrorLog("StopHce: not got bundle name");
235 return KITS::ERR_HCE_PARAMETERS;
236 }
237 if (hapTokenInfo.bundleName != element.GetBundleName()) {
238 ErrorLog("StopHce: wrong bundle name");
239 return KITS::ERR_HCE_PARAMETERS;
240 }
241
242 if (ceService_.expired()) {
243 ErrorLog("StopHce ceService_ is nullptr");
244 return KITS::ERR_HCE_PARAMETERS;
245 }
246 if (ceService_.lock()->StopHce(element, IPCSkeleton::GetCallingTokenID())) {
247 return KITS::ERR_NONE;
248 }
249 return KITS::ERR_HCE_PARAMETERS;
250 }
251
GetPaymentServices(CePaymentServicesParcelable & parcelable)252 ErrCode HceSession::GetPaymentServices(CePaymentServicesParcelable& parcelable)
253 {
254 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
255 ErrorLog("GetPaymentServices, ERR_NO_PERMISSION");
256 return KITS::ERR_NO_PERMISSION;
257 }
258
259 if (!ExternalDepsProxy::GetInstance().IsSystemApp(IPCSkeleton::GetCallingUid())) {
260 ErrorLog("HandleGetPaymentServices, ERR_NOT_SYSTEM_APP");
261 return KITS::ERR_NOT_SYSTEM_APP;
262 }
263
264 ExternalDepsProxy::GetInstance().GetPaymentAbilityInfos(parcelable.paymentAbilityInfos);
265 #ifdef NFC_SIM_FEATURE
266 AppendSimBundle(parcelable.paymentAbilityInfos);
267 #endif
268 return KITS::ERR_NONE;
269 }
270
271 #ifdef NFC_SIM_FEATURE
AppendSimBundle(std::vector<AbilityInfo> & paymentAbilityInfos)272 void HceSession::AppendSimBundle(std::vector<AbilityInfo> &paymentAbilityInfos)
273 {
274 if (nfcService_.expired()) {
275 ErrorLog("nfcService_ nullptr");
276 return;
277 }
278 std::string simBundleName = nfcService_.lock()->GetSimVendorBundleName();
279 AppExecFwk::BundleInfo bundleInfo;
280 bool result = ExternalDepsProxy::GetInstance().GetBundleInfo(bundleInfo, simBundleName);
281 if (!result) {
282 ErrorLog("get sim bundle info failed.");
283 return;
284 }
285 AbilityInfo simAbility;
286 simAbility.bundleName = simBundleName;
287 simAbility.labelId = bundleInfo.applicationInfo.labelId;
288 simAbility.iconId = bundleInfo.applicationInfo.iconId;
289 paymentAbilityInfos.push_back(simAbility);
290 }
291 #endif // NFC_SIM_FEATURE
292 } // namespace HCE
293 } // namespace NFC
294 } // namespace OHOS
295