1 /*
2 * Copyright (C) 2023 - 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 #include "routing_manager.h"
16
17 #include <unistd.h>
18 #include "nfa_api.h"
19 #include "nfc_config.h"
20 #include "loghelper.h"
21
22 namespace OHOS {
23 namespace NFC {
24 namespace NCI {
25 // default initialize values
26 static const uint16_t DEFAULT_SYS_CODE = 0xFEFE;
27 static const uint8_t AID_ROUTE_QUAL_PREFIX = 0x10;
28 static const int DEFAULT_OFF_HOST_ROUTE_DEST = 0x01;
29 static const int DEFAULT_FELICA_ROUTE_DEST = 0x02;
30 static const int DEFAULT_HOST_ROUTE_DEST = 0x00;
31 static const int DEFAULT_EE_ROUTE_DEST = 0x01; // ese
32 static const std::vector<uint8_t> DEFAULT_UICC_ROUTE_DEST = {0x02, 0x03};
33 static const tNFA_EE_PWR_STATE DEFAULT_SYS_CODE_PWR_STA = 0x00;
34 static const tNFA_HANDLE DEFAULT_SYS_CODE_ROUTE_DEST = 0xC0;
35 static const int MAX_NUM_OF_EE = 5;
36 static const int EE_INFO_WAITE_INTERVAL = 100 * 1000; // ms for usleep
37
38 // power state masks
39 static const int PWR_STA_SWTCH_ON_SCRN_UNLCK = 0x01;
40 static const int PWR_STA_SWTCH_OFF = 0x02;
41 static const int PWR_STA_BATT_OFF = 0x04;
42 static const int PWR_STA_SWTCH_ON_SCRN_LOCK = 0x10;
43 static const int PWR_STA_SWTCH_ON_SCRN_OFF = 0x08;
44 static const int PWR_STA_SWTCH_ON_SCRN_OFF_LOCK = 0x20;
45 static const int DEFAULT_PWR_STA_HOST = PWR_STA_SWTCH_ON_SCRN_UNLCK | PWR_STA_SWTCH_ON_SCRN_LOCK;
46 static const int DEFAULT_PWR_STA_FOR_TECH_A_B = PWR_STA_SWTCH_ON_SCRN_UNLCK | PWR_STA_SWTCH_OFF |
47 PWR_STA_SWTCH_ON_SCRN_OFF | PWR_STA_SWTCH_ON_SCRN_LOCK | PWR_STA_SWTCH_ON_SCRN_OFF_LOCK;
48
49 // routing entries
50 static const int NFA_SET_TECH_ROUTING = 0x01;
51 static const int NFA_SET_PROTO_ROUTING = 0x02;
52 static const int ROUTE_LOC_HOST_ID = 0x400;
53 static const int ROUTE_LOC_ESE_ID = 0x4C0;
54 static const int DEFAULT_PROTO_ROUTE_AND_POWER = 0x013B;
55 static const int ROUTE_LOC_MASK = 8;
56 static const int PWR_STA_MASK = 0x3F;
57 static const int DEFAULT_LISTEN_TECH_MASK = 0x07;
58
GetInstance()59 RoutingManager& RoutingManager::GetInstance()
60 {
61 static RoutingManager manager;
62 return manager;
63 }
64
Initialize()65 bool RoutingManager::Initialize()
66 {
67 tNFA_STATUS status;
68 {
69 SynchronizeEvent guard(eeRegisterEvent_);
70 InfoLog("Initialize: try ee register");
71 status = NFA_EeRegister(NfaEeCallback);
72 if (status != NFA_STATUS_OK) {
73 ErrorLog("Initialize: fail ee register; error=0x%{public}X", status);
74 return false;
75 }
76 eeRegisterEvent_.Wait(); // wait for NFA_EE_REGISTER_EVT
77 }
78
79 // NFA_EE_REGISTER_EVT and NFA_EE_DISCOVER_REQ_EVT may come at the same time
80 // wait 100ms here to avoid timing issue in executing eeInfoEvent_
81 usleep(EE_INFO_WAITE_INTERVAL);
82 if ((defaultOffHostRoute_ != 0) || (defaultFelicaRoute_ != 0)) {
83 SynchronizeEvent guard(eeInfoEvent_);
84 if (!isEeInfoReceived_) {
85 InfoLog("Initialize: Waiting for EE info");
86 eeInfoEvent_.Wait(); // wait for NFA_EE_DISCOVER_REQ_EVT if eeinfo not received
87 }
88 }
89 seTechMask_ = UpdateEeTechRouteSetting();
90
91 // Set the host-routing Tech
92 status = NFA_CeSetIsoDepListenTech(hostListenTechMask_ & (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B));
93 if (status != NFA_STATUS_OK) {
94 ErrorLog("Initialize: Failed to configure CE IsoDep technologies");
95 }
96
97 // Regrister AID routed to the host with an AID length of 0
98 status = NFA_CeRegisterAidOnDH(NULL, 0, NfaCeStackCallback);
99 if (status != NFA_STATUS_OK) {
100 ErrorLog("Initialize: failed to register null AID to DH");
101 }
102
103 UpdateDefaultRoute();
104 UpdateDefaultProtoRoute();
105 SetOffHostNfceeTechMask();
106 return true;
107 }
108
UpdateDefaultProtoRoute()109 void RoutingManager::UpdateDefaultProtoRoute()
110 {
111 // update default proto route for iso-dep
112 tNFA_PROTOCOL_MASK protoMask = NFA_PROTOCOL_MASK_ISO_DEP;
113 tNFA_STATUS status = NFA_STATUS_FAILED;
114 if (defaultIsoDepRoute_ != NFC_DH_ID &&
115 IsTypeABSupportedInEe(defaultIsoDepRoute_ | NFA_HANDLE_GROUP_EE)) {
116 status = NFA_EeClearDefaultProtoRouting(defaultIsoDepRoute_, protoMask);
117 status = NFA_EeSetDefaultProtoRouting(
118 defaultIsoDepRoute_, protoMask, isSecureNfcEnabled_ ? 0 : protoMask, 0,
119 isSecureNfcEnabled_ ? 0 : protoMask, isSecureNfcEnabled_ ? 0 : protoMask,
120 isSecureNfcEnabled_ ? 0 : protoMask);
121 } else {
122 status = NFA_EeClearDefaultProtoRouting(NFC_DH_ID, protoMask);
123 status = NFA_EeSetDefaultProtoRouting(
124 NFC_DH_ID, protoMask, 0, 0, isSecureNfcEnabled_ ? 0 : protoMask, 0, 0);
125 }
126 if (status != NFA_STATUS_OK) {
127 ErrorLog("UpdateDefaultProtoRoute: failed to register default ISO-DEP route");
128 }
129 }
130
SetOffHostNfceeTechMask()131 void RoutingManager::SetOffHostNfceeTechMask()
132 {
133 tNFA_STATUS status = NFA_STATUS_FAILED;
134 tNFA_HANDLE handle = ROUTE_LOC_ESE_ID;
135 int uiccListenTechMask = 0x07;
136 {
137 status = NFA_CeConfigureUiccListenTech(handle, uiccListenTechMask);
138 if (status != NFA_STATUS_OK) {
139 ErrorLog("SetOffHostNfceeTechMask: failed to start uicc listen");
140 }
141 }
142 }
143
ComputeRoutingParams()144 bool RoutingManager::ComputeRoutingParams()
145 {
146 InfoLog("ComputeRoutingParams");
147 int valueProtoIsoDep = 0x01;
148
149 // route for protocol
150 ClearRoutingEntry(NFA_SET_PROTO_ROUTING);
151 SetRoutingEntry(NFA_SET_PROTO_ROUTING, valueProtoIsoDep,
152 ((DEFAULT_PROTO_ROUTE_AND_POWER >> ROUTE_LOC_MASK) & DEFAULT_LISTEN_TECH_MASK),
153 DEFAULT_PROTO_ROUTE_AND_POWER & PWR_STA_MASK);
154
155 // route for technology
156 // currently set tech F default to ese with power 0x3B
157 int techSeId = DEFAULT_EE_ROUTE_DEST;
158 int techFSeId = DEFAULT_EE_ROUTE_DEST;
159 int techRouteForTypeAB = 0x03;
160 int techRouteForTypeF = 0x04;
161 ClearRoutingEntry(NFA_SET_TECH_ROUTING);
162 SetRoutingEntry(NFA_SET_TECH_ROUTING, techRouteForTypeAB, techSeId, DEFAULT_PWR_STA_FOR_TECH_A_B);
163 SetRoutingEntry(NFA_SET_TECH_ROUTING, techRouteForTypeF, techFSeId, DEFAULT_PWR_STA_FOR_TECH_A_B);
164 return true;
165 }
166
SetRoutingEntry(int type,int value,int route,int power)167 bool RoutingManager::SetRoutingEntry(int type, int value, int route, int power)
168 {
169 InfoLog("SetRoutingEntry: type:0x%{public}X, value:0x%{public}X, route:0x%{public}X, power:0x%{public}X",
170 type, value, route, power);
171 int maxTechMask = 0x03; // 0x01 for type A, 0x02 for type B, 0x03 for both
172 int last4BitsMask = 0xF0;
173 tNFA_STATUS status = NFA_STATUS_FAILED;
174 tNFA_HANDLE handle = ((route == DEFAULT_HOST_ROUTE_DEST) ? ROUTE_LOC_HOST_ID : ROUTE_LOC_ESE_ID);
175 uint8_t swtchOnMask = 0;
176 uint8_t swtchOffMask = 0;
177 uint8_t battOffMask = 0;
178 uint8_t scrnLockMask = 0;
179 uint8_t scrnOffMask = 0;
180 uint8_t scrnOffLockMask = 0;
181 uint8_t protoMask = 0;
182
183 // validate power state value
184 power &= PWR_STA_MASK;
185 if ((handle == ROUTE_LOC_HOST_ID) && (type == NFA_SET_PROTO_ROUTING)) {
186 power &= ~(PWR_STA_SWTCH_OFF | PWR_STA_BATT_OFF);
187 }
188 if (type == NFA_SET_TECH_ROUTING) {
189 InfoLog("SetRoutingEntry: NFA_SET_TECH_ROUTING maxTechMask ");
190 value &= maxTechMask;
191 swtchOnMask = (power & PWR_STA_SWTCH_ON_SCRN_UNLCK) ? value : 0;
192 swtchOffMask = (power & PWR_STA_SWTCH_OFF) ? value : 0;
193 battOffMask = (power & PWR_STA_BATT_OFF) ? value : 0;
194 scrnLockMask = (power & PWR_STA_SWTCH_ON_SCRN_LOCK) ? value : 0;
195 scrnOffMask = (power & PWR_STA_SWTCH_ON_SCRN_OFF) ? value : 0;
196 scrnOffLockMask = (power & PWR_STA_SWTCH_ON_SCRN_OFF_LOCK) ? value : 0;
197 if (hostListenTechMask_) {
198 RegisterTechRoutingEntry(handle, swtchOnMask, swtchOffMask, battOffMask, scrnLockMask, scrnOffMask,
199 scrnOffLockMask);
200 }
201 } else if (type == NFA_SET_PROTO_ROUTING) {
202 value &= ~last4BitsMask;
203 while (value) {
204 protoMask = GetProtoMaskFromTechMask(value);
205 if ((protoMask & (NFA_PROTOCOL_MASK_ISO_DEP | NFC_PROTOCOL_MASK_ISO7816)) &&
206 (handle != NFA_EE_HANDLE_DH) &&
207 (maxTechMask & (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B)) == 0) {
208 InfoLog("SetRoutingEntry: proto entry rejected, handle 0x%{public}x does not support"
209 "proto mask 0x%{public}x", handle, protoMask);
210 return status;
211 }
212 swtchOnMask = (power & PWR_STA_SWTCH_ON_SCRN_UNLCK) ? protoMask : 0;
213 swtchOffMask = (power & PWR_STA_SWTCH_OFF) ? protoMask : 0;
214 battOffMask = (power & PWR_STA_BATT_OFF) ? protoMask : 0;
215 scrnLockMask = (power & PWR_STA_SWTCH_ON_SCRN_LOCK) ? protoMask : 0;
216 scrnOffMask = (power & PWR_STA_SWTCH_ON_SCRN_OFF) ? protoMask : 0;
217 scrnOffLockMask = (power & PWR_STA_SWTCH_ON_SCRN_OFF_LOCK) ? protoMask : 0;
218 RegisterProtoRoutingEntry(handle, swtchOnMask, swtchOffMask, battOffMask, scrnLockMask, scrnOffMask,
219 scrnOffLockMask);
220 protoMask = 0;
221 }
222 }
223 return status;
224 }
225
GetProtoMaskFromTechMask(int & value)226 uint8_t RoutingManager::GetProtoMaskFromTechMask(int& value)
227 {
228 if (value & NFA_TECHNOLOGY_MASK_A) {
229 value &= ~NFA_TECHNOLOGY_MASK_A;
230 return NFA_PROTOCOL_MASK_ISO_DEP;
231 } else if (value & NFA_TECHNOLOGY_MASK_B) {
232 value &= ~NFA_TECHNOLOGY_MASK_B;
233 return NFA_PROTOCOL_MASK_NFC_DEP;
234 } else if (value & NFA_TECHNOLOGY_MASK_F) {
235 value &= ~NFA_TECHNOLOGY_MASK_F;
236 return NFA_PROTOCOL_MASK_T3T;
237 } else if (value & NFA_TECHNOLOGY_MASK_V) {
238 value &= ~NFA_TECHNOLOGY_MASK_V;
239 return NFC_PROTOCOL_MASK_ISO7816;
240 }
241 return 0;
242 }
243
RegisterProtoRoutingEntry(tNFA_HANDLE eeHandle,tNFA_PROTOCOL_MASK protoSwitchOn,tNFA_PROTOCOL_MASK protoSwitchOff,tNFA_PROTOCOL_MASK protoBatteryOn,tNFA_PROTOCOL_MASK protoScreenLock,tNFA_PROTOCOL_MASK protoScreenOff,tNFA_PROTOCOL_MASK protoSwitchOffLock)244 void RoutingManager::RegisterProtoRoutingEntry(tNFA_HANDLE eeHandle,
245 tNFA_PROTOCOL_MASK protoSwitchOn, tNFA_PROTOCOL_MASK protoSwitchOff,
246 tNFA_PROTOCOL_MASK protoBatteryOn, tNFA_PROTOCOL_MASK protoScreenLock,
247 tNFA_PROTOCOL_MASK protoScreenOff, tNFA_PROTOCOL_MASK protoSwitchOffLock)
248 {
249 tNFA_STATUS status = NFA_STATUS_FAILED;
250 {
251 SynchronizeEvent guard(routingEvent_);
252 status = NFA_EeSetDefaultProtoRouting(eeHandle, protoSwitchOn,
253 isSecureNfcEnabled_ ? 0 : protoSwitchOff,
254 isSecureNfcEnabled_ ? 0 : protoBatteryOn,
255 isSecureNfcEnabled_ ? 0 : protoScreenLock,
256 isSecureNfcEnabled_ ? 0 : protoSwitchOff,
257 isSecureNfcEnabled_ ? 0 : protoSwitchOffLock);
258 if (status == NFA_STATUS_OK) {
259 routingEvent_.Wait();
260 InfoLog("RegisterProtoRoutingEntry: Register Proto Routing Entry SUCCESS");
261 } else {
262 ErrorLog("RegisterProtoRoutingEntry: Register Proto Routing Entry Failed");
263 }
264 }
265 }
266
RegisterTechRoutingEntry(tNFA_HANDLE eeHandle,tNFA_PROTOCOL_MASK protoSwitchOn,tNFA_PROTOCOL_MASK protoSwitchOff,tNFA_PROTOCOL_MASK protoBatteryOn,tNFA_PROTOCOL_MASK protoScreenLock,tNFA_PROTOCOL_MASK protoScreenOff,tNFA_PROTOCOL_MASK protoSwitchOffLock)267 void RoutingManager::RegisterTechRoutingEntry(tNFA_HANDLE eeHandle,
268 tNFA_PROTOCOL_MASK protoSwitchOn, tNFA_PROTOCOL_MASK protoSwitchOff,
269 tNFA_PROTOCOL_MASK protoBatteryOn, tNFA_PROTOCOL_MASK protoScreenLock,
270 tNFA_PROTOCOL_MASK protoScreenOff, tNFA_PROTOCOL_MASK protoSwitchOffLock)
271 {
272 tNFA_STATUS status = NFA_STATUS_FAILED;
273 {
274 SynchronizeEvent guard(routingEvent_);
275 status = NFA_EeSetDefaultTechRouting(eeHandle, protoSwitchOn,
276 isSecureNfcEnabled_ ? 0 : protoSwitchOff,
277 isSecureNfcEnabled_ ? 0 : protoBatteryOn,
278 isSecureNfcEnabled_ ? 0 : protoScreenLock,
279 isSecureNfcEnabled_ ? 0 : protoSwitchOff,
280 isSecureNfcEnabled_ ? 0 : protoSwitchOffLock);
281 if (status == NFA_STATUS_OK) {
282 routingEvent_.Wait();
283 InfoLog("RegisterTechRoutingEntry: Register Tech Routing Entry SUCCESS");
284 } else {
285 ErrorLog("RegisterTechRoutingEntry: Register Tech Routing Entry Failed");
286 }
287 }
288 }
289
ClearRoutingEntry(int type)290 bool RoutingManager::ClearRoutingEntry(int type)
291 {
292 InfoLog("ClearRoutingEntry: type = %{public}d", type);
293 tNFA_STATUS status = NFA_STATUS_FAILED;
294 SynchronizeEvent guard(routingEvent_);
295 if (type & NFA_SET_TECH_ROUTING) {
296 status = NFA_EeClearDefaultTechRouting(NFA_EE_HANDLE_DH,
297 (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | NFA_TECHNOLOGY_MASK_F));
298 if (status == NFA_STATUS_OK) {
299 routingEvent_.Wait();
300 }
301 }
302 if (type & NFA_SET_PROTO_ROUTING) {
303 {
304 status = NFA_EeClearDefaultProtoRouting(ROUTE_LOC_ESE_ID,
305 (NFA_PROTOCOL_MASK_ISO_DEP | NFC_PROTOCOL_MASK_ISO7816));
306 if (status == NFA_STATUS_OK) {
307 routingEvent_.Wait();
308 }
309 }
310 {
311 status = NFA_EeClearDefaultProtoRouting(NFA_EE_HANDLE_DH,
312 (NFA_PROTOCOL_MASK_ISO_DEP | NFC_PROTOCOL_MASK_ISO7816));
313 if (status == NFA_STATUS_OK) {
314 routingEvent_.Wait();
315 }
316 }
317 }
318 return (status == NFA_STATUS_OK);
319 }
320
IsTypeABSupportedInEe(tNFA_HANDLE eeHandle)321 bool RoutingManager::IsTypeABSupportedInEe(tNFA_HANDLE eeHandle)
322 {
323 bool rst = false;
324 uint8_t numEe = MAX_NUM_OF_EE;
325 tNFA_EE_INFO eeInfo[numEe];
326 if (!memset_s(&eeInfo, numEe * sizeof(tNFA_EE_INFO), 0, numEe * sizeof(tNFA_EE_INFO))) {
327 ErrorLog("IsTypeABSupportedInEe, memset_s error");
328 return rst;
329 }
330 tNFA_STATUS status = NFA_EeGetInfo(&numEe, eeInfo);
331 InfoLog("IsTypeABSupportedInEe, NFA_EeGetInfo status = %{public}d", status);
332 if (status != NFA_STATUS_OK) {
333 return rst;
334 }
335 for (auto i = 0; i < numEe; i++) {
336 if (eeHandle == eeInfo[i].ee_handle) {
337 if (eeInfo[i].la_protocol || eeInfo[i].lb_protocol) {
338 rst = true;
339 break;
340 }
341 }
342 }
343 return rst;
344 }
345
UpdateDefaultRoute()346 void RoutingManager::UpdateDefaultRoute()
347 {
348 if (NFC_GetNCIVersion() != NCI_VERSION_2_0) {
349 return;
350 }
351 tNFA_STATUS status;
352
353 // Register System Code for routing
354 SynchronizeEvent guard(routingEvent_);
355 status = NFA_EeAddSystemCodeRouting(
356 defaultSysCode_, defaultSysCodeRoute_,
357 isSecureNfcEnabled_ ? PWR_STA_SWTCH_ON_SCRN_UNLCK : defaultSysCodePowerstate_);
358 if (status == NFA_STATUS_NOT_SUPPORTED) {
359 ErrorLog("UpdateDefaultRoute: SCBR not supported");
360 } else if (status == NFA_STATUS_OK) {
361 routingEvent_.Wait();
362 DebugLog("UpdateDefaultRoute: Succeed to register system code");
363 } else {
364 ErrorLog("UpdateDefaultRoute: Fail to register system code");
365 }
366
367 // Register zero lengthy Aid for default Aid Routing
368 if (defaultEe_ != defaultIsoDepRoute_) {
369 if (defaultEe_ != NFC_DH_ID) {
370 InfoLog("UpdateDefaultRoute: defaultEe_is not NFC_DH_ID Returning...");
371 return;
372 }
373 uint8_t powerState = PWR_STA_SWTCH_ON_SCRN_UNLCK;
374 if (!isSecureNfcEnabled_) {
375 powerState = (defaultEe_ != 0x00) ? offHostAidRoutingPowerState_ : DEFAULT_PWR_STA_HOST;
376 }
377 status = NFA_EeAddAidRouting(defaultEe_, 0, NULL, powerState, AID_ROUTE_QUAL_PREFIX);
378 if (status == NFA_STATUS_OK) {
379 InfoLog("UpdateDefaultRoute: Succeed to register zero length AID");
380 } else {
381 ErrorLog("UpdateDefaultRoute: failed to register zero length AID");
382 }
383 }
384 }
385
OnNfcDeinit()386 void RoutingManager::OnNfcDeinit()
387 {
388 if (defaultOffHostRoute_ == DEFAULT_HOST_ROUTE_DEST &&
389 defaultFelicaRoute_ == DEFAULT_HOST_ROUTE_DEST) {
390 return;
391 }
392 tNFA_STATUS status = NFA_STATUS_FAILED;
393 isDeinitializing_ = true;
394 uint8_t numEe = MAX_NUM_OF_EE;
395 tNFA_EE_INFO eeInfo[numEe];
396 if (memset_s(&eeInfo, numEe * sizeof(tNFA_EE_INFO), 0, numEe * sizeof(tNFA_EE_INFO))) {
397 ErrorLog("OnNfcDeinit, memset_s error");
398 return;
399 }
400 status = NFA_EeGetInfo(&numEe, eeInfo);
401 if (status != NFA_STATUS_OK) {
402 ErrorLog("OnNfcDeinit: fail get info; error=0x%{public}X", status);
403 return;
404 }
405 if (numEe != 0) {
406 for (uint8_t i = 0; i < numEe; i++) {
407 // only do set ee mode to deactive when ee is active
408 // on NCI VER ower than 2.0, the active state is NCI_NFCEE_INTERFACE_HCI_ACCESS
409 bool isOffHostEEPresent = (NFC_GetNCIVersion() < NCI_VERSION_2_0)
410 ? (eeInfo[i].num_interface != 0) : (eeInfo[i].ee_interface[0] !=
411 NCI_NFCEE_INTERFACE_HCI_ACCESS) && (eeInfo[i].ee_status == NFA_EE_STATUS_ACTIVE);
412 if (isOffHostEEPresent) {
413 InfoLog("OnNfcDeinit: Handle: 0x%{public}04x Change Status Active to Inactive",
414 eeInfo[i].ee_handle);
415 SynchronizeEvent guard(eeSetModeEvent_);
416 status = NFA_EeModeSet(eeInfo[i].ee_handle, NFA_EE_MD_DEACTIVATE);
417 if (status == NFA_STATUS_OK) {
418 eeSetModeEvent_.Wait();
419 } else {
420 ErrorLog("OnNfcDeinit: Failed to set EE inactive");
421 }
422 }
423 }
424 } else {
425 InfoLog("OnNfcDeinit: No active EEs found");
426 }
427 }
428
ClearAllEvents()429 void RoutingManager::ClearAllEvents()
430 {
431 InfoLog("ClearAllEvents");
432 {
433 SynchronizeEvent guard(eeUpdateEvent_);
434 eeUpdateEvent_.NotifyOne();
435 }
436 {
437 SynchronizeEvent guard(eeRegisterEvent_);
438 eeRegisterEvent_.NotifyOne();
439 }
440 {
441 SynchronizeEvent guard(eeInfoEvent_);
442 eeInfoEvent_.NotifyOne();
443 }
444 {
445 SynchronizeEvent guard(routingEvent_);
446 routingEvent_.NotifyOne();
447 }
448 {
449 SynchronizeEvent guard(eeSetModeEvent_);
450 eeSetModeEvent_.NotifyOne();
451 }
452 }
453
Deinitialize()454 void RoutingManager::Deinitialize()
455 {
456 InfoLog("Deinitialize");
457 ClearAllEvents();
458 OnNfcDeinit();
459 }
460
UpdateEeTechRouteSetting()461 tNFA_TECHNOLOGY_MASK RoutingManager::UpdateEeTechRouteSetting()
462 {
463 const tNFA_TECHNOLOGY_MASK noSeTechMask = 0x00;
464 tNFA_TECHNOLOGY_MASK allSeTechMask = noSeTechMask;
465 InfoLog("UpdateEeTechRouteSetting: eeInfo_.num_ee = 0x%{public}02x", (int)eeInfo_.num_ee);
466 tNFA_STATUS status;
467 for (uint8_t i = 0; i < eeInfo_.num_ee; i++) {
468 tNFA_HANDLE eeHandle = eeInfo_.ee_disc_info[i].ee_handle;
469 tNFA_TECHNOLOGY_MASK seTechMask = 0;
470 InfoLog("UpdateEeTechRouteSetting: EE[%{public}u] Handle: 0x%{public}04x techA: 0x%{public}02x techB: "
471 "0x%{public}02x techF: 0x%{public}02x techBprime: 0x%{public}02x",
472 i, eeHandle, eeInfo_.ee_disc_info[i].la_protocol, eeInfo_.ee_disc_info[i].lb_protocol,
473 eeInfo_.ee_disc_info[i].lf_protocol, eeInfo_.ee_disc_info[i].lbp_protocol);
474
475 if ((defaultOffHostRoute_ != 0) && (eeHandle == (defaultOffHostRoute_ | NFA_HANDLE_GROUP_EE))) {
476 if (eeInfo_.ee_disc_info[i].la_protocol != 0) {
477 seTechMask |= NFA_TECHNOLOGY_MASK_A;
478 }
479 if (eeInfo_.ee_disc_info[i].lb_protocol != 0) {
480 seTechMask |= NFA_TECHNOLOGY_MASK_B;
481 }
482 }
483 if ((defaultFelicaRoute_ != 0) && (eeHandle == (defaultFelicaRoute_ | NFA_HANDLE_GROUP_EE))) {
484 if (eeInfo_.ee_disc_info[i].lf_protocol != 0) {
485 seTechMask |= NFA_TECHNOLOGY_MASK_F;
486 }
487 }
488
489 InfoLog("UpdateEeTechRouteSetting: seTechMask[%{public}u]=0x%{public}02x", i, seTechMask);
490 if (seTechMask != noSeTechMask) {
491 InfoLog("UpdateEeTechRouteSetting: Configuring tech mask 0x%{public}02x on EE 0x%{public}04x",
492 seTechMask, eeHandle);
493
494 status = NFA_CeConfigureUiccListenTech(eeHandle, seTechMask);
495 if (status != NFA_STATUS_OK) {
496 ErrorLog("UpdateEeTechRouteSetting: NFA_CeConfigureUiccListenTech failed.");
497 }
498
499 // clear default tech routing before setting new power state
500 status = NFA_EeClearDefaultTechRouting(eeHandle, seTechMask);
501 if (status != NFA_STATUS_OK) {
502 ErrorLog("UpdateEeTechRouteSetting: NFA_EeClearDefaultTechRouting failed.");
503 }
504
505 status = NFA_EeSetDefaultTechRouting(eeHandle, seTechMask, isSecureNfcEnabled_ ? 0 : seTechMask, 0,
506 isSecureNfcEnabled_ ? 0 : seTechMask, isSecureNfcEnabled_ ? 0 : seTechMask,
507 isSecureNfcEnabled_ ? 0 : seTechMask);
508 if (status != NFA_STATUS_OK) {
509 ErrorLog("UpdateEeTechRouteSetting: NFA_EeSetDefaultTechRouting failed.");
510 }
511 allSeTechMask |= seTechMask;
512 }
513 }
514 return allSeTechMask;
515 }
516
CommitRouting()517 bool RoutingManager::CommitRouting()
518 {
519 tNFA_STATUS status = 0;
520 if (isEeInfoChanged_) {
521 seTechMask_ = UpdateEeTechRouteSetting();
522 isEeInfoChanged_ = false;
523 }
524 {
525 SynchronizeEvent guard(eeUpdateEvent_);
526 status = NFA_EeUpdateNow();
527 if (status == NFA_STATUS_OK) {
528 eeUpdateEvent_.Wait(); // wait for NFA_EE_UPDATED_EVT
529 }
530 }
531 return (status == NFA_STATUS_OK);
532 }
533
NfaCeStackCallback(uint8_t event,tNFA_CONN_EVT_DATA * eventData)534 void RoutingManager::NfaCeStackCallback(uint8_t event, tNFA_CONN_EVT_DATA* eventData)
535 {
536 if (!eventData) {
537 ErrorLog("NfaCeStackCallback: eventData is null");
538 return;
539 }
540 InfoLog("NfaCeStackCallback: event = %{public}d", event);
541 RoutingManager& rm = RoutingManager::GetInstance();
542 switch (event) {
543 case NFA_EE_REGISTER_EVT: {
544 InfoLog("NfaCeStackCallback: NFA_EE_REGISTER_EVT notified");
545 SynchronizeEvent guard(rm.routingEvent_);
546 rm.routingEvent_.NotifyOne();
547 break;
548 }
549 default:
550 break;
551 }
552 }
553
NfaEeCallback(tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * eventData)554 void RoutingManager::NfaEeCallback(tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* eventData)
555 {
556 if (!eventData) {
557 ErrorLog("NfaEeCallback: eventData is null");
558 return;
559 }
560 InfoLog("NfaEeCallback: event = %{public}d, status=0x%{public}X", event, eventData->status);
561 switch (event) {
562 case NFA_EE_REGISTER_EVT: {
563 DoNfaEeRegisterEvent();
564 break;
565 }
566 case NFA_EE_DEREGISTER_EVT: {
567 DoNfaEeDeregisterEvent(eventData);
568 break;
569 }
570 case NFA_EE_MODE_SET_EVT: {
571 DoNfaEeModeSetEvent(eventData);
572 break;
573 }
574 case NFA_EE_SET_TECH_CFG_EVT: {
575 NotifyRoutingEvent();
576 break;
577 }
578 case NFA_EE_CLEAR_TECH_CFG_EVT: {
579 NotifyRoutingEvent();
580 break;
581 }
582 case NFA_EE_SET_PROTO_CFG_EVT: {
583 NotifyRoutingEvent();
584 break;
585 }
586 case NFA_EE_CLEAR_PROTO_CFG_EVT: {
587 NotifyRoutingEvent();
588 break;
589 }
590 case NFA_EE_ACTION_EVT:
591 break;
592 case NFA_EE_DISCOVER_REQ_EVT: {
593 DoNfaEeDiscoverReqEvent(eventData);
594 break;
595 }
596 case NFA_EE_NO_CB_ERR_EVT:
597 break;
598 case NFA_EE_ADD_AID_EVT: {
599 DoNfaEeAddOrRemoveAidEvent(eventData);
600 break;
601 }
602 case NFA_EE_ADD_SYSCODE_EVT: {
603 NotifyRoutingEvent();
604 break;
605 }
606 case NFA_EE_REMOVE_SYSCODE_EVT: {
607 NotifyRoutingEvent();
608 break;
609 }
610 case NFA_EE_REMOVE_AID_EVT: {
611 DoNfaEeAddOrRemoveAidEvent(eventData);
612 break;
613 }
614 case NFA_EE_NEW_EE_EVT: {
615 InfoLog("NfaEeCallback: NFA_EE_NEW_EE_EVT h=0x%{public}X; status=%{public}u",
616 eventData->new_ee.ee_handle, eventData->new_ee.ee_status);
617 break;
618 }
619 case NFA_EE_UPDATED_EVT: {
620 DoNfaEeUpdateEvent();
621 break;
622 }
623 case NFA_EE_PWR_AND_LINK_CTRL_EVT: {
624 break;
625 }
626 default:
627 InfoLog("NfaEeCallback: unknown event=%{public}u ????", event);
628 }
629 }
630
DoNfaEeRegisterEvent()631 void RoutingManager::DoNfaEeRegisterEvent()
632 {
633 RoutingManager& rm = RoutingManager::GetInstance();
634 SynchronizeEvent guard(rm.eeRegisterEvent_);
635 InfoLog("NfaEeCallback: NFA_EE_REGISTER_EVT");
636 rm.eeRegisterEvent_.NotifyOne();
637 }
638
DoNfaEeModeSetEvent(tNFA_EE_CBACK_DATA * eventData)639 void RoutingManager::DoNfaEeModeSetEvent(tNFA_EE_CBACK_DATA* eventData)
640 {
641 RoutingManager& rm = RoutingManager::GetInstance();
642 SynchronizeEvent guard(rm.eeSetModeEvent_);
643 InfoLog("NfaEeCallback: NFA_EE_MODE_SET_EVT, status = 0x%{public}04X, handle = 0x%{public}04X",
644 eventData->mode_set.status, eventData->mode_set.ee_handle);
645 rm.eeSetModeEvent_.NotifyOne();
646 }
647
DoNfaEeDeregisterEvent(tNFA_EE_CBACK_DATA * eventData)648 void RoutingManager::DoNfaEeDeregisterEvent(tNFA_EE_CBACK_DATA* eventData)
649 {
650 RoutingManager& rm = RoutingManager::GetInstance();
651 InfoLog("NfaEeCallback: NFA_EE_DEREGISTER_EVT status=0x%{public}X", eventData->status);
652 rm.isEeInfoReceived_ = false;
653 rm.isDeinitializing_ = false;
654 }
655
NotifyRoutingEvent()656 void RoutingManager::NotifyRoutingEvent()
657 {
658 RoutingManager& rm = RoutingManager::GetInstance();
659 SynchronizeEvent guard(rm.routingEvent_);
660 rm.routingEvent_.NotifyOne();
661 }
662
DoNfaEeAddOrRemoveAidEvent(tNFA_EE_CBACK_DATA * eventData)663 void RoutingManager::DoNfaEeAddOrRemoveAidEvent(tNFA_EE_CBACK_DATA* eventData)
664 {
665 InfoLog("NfaEeCallback: NFA_EE_ADD_AID_EVT status=%{public}u", eventData->status);
666 RoutingManager& rm = RoutingManager::GetInstance();
667 SynchronizeEvent guard(rm.routingEvent_);
668 rm.isAidRoutingConfigured_ = (eventData->status == NFA_STATUS_OK);
669 rm.routingEvent_.NotifyOne();
670 }
671
DoNfaEeDiscoverReqEvent(tNFA_EE_CBACK_DATA * eventData)672 void RoutingManager::DoNfaEeDiscoverReqEvent(tNFA_EE_CBACK_DATA* eventData)
673 {
674 InfoLog("NfaEeCallback: NFA_EE_DISCOVER_REQ_EVT; status=0x%{public}X; num ee=%{public}u",
675 eventData->discover_req.status, eventData->discover_req.num_ee);
676 RoutingManager& rm = RoutingManager::GetInstance();
677 SynchronizeEvent guard(rm.eeInfoEvent_);
678 int status = memcpy_s(&rm.eeInfo_, sizeof(rm.eeInfo_), &eventData->discover_req, sizeof(rm.eeInfo_));
679 if (status != 0) {
680 return;
681 }
682 if (rm.isEeInfoReceived_ && !rm.isDeinitializing_) {
683 rm.isEeInfoChanged_ = true;
684 }
685 rm.isEeInfoReceived_ = true;
686 rm.eeInfoEvent_.NotifyOne();
687 }
688
DoNfaEeUpdateEvent()689 void RoutingManager::DoNfaEeUpdateEvent()
690 {
691 InfoLog("NfaEeCallback: NFA_EE_UPDATED_EVT");
692 RoutingManager& rm = RoutingManager::GetInstance();
693 SynchronizeEvent guard(rm.eeUpdateEvent_);
694 rm.eeUpdateEvent_.NotifyOne();
695 }
696
RoutingManager()697 RoutingManager::RoutingManager() : isSecureNfcEnabled_(false),
698 isAidRoutingConfigured_(false) {
699 // read default route params
700 defaultOffHostRoute_ = NfcConfig::getUnsigned(NAME_DEFAULT_OFFHOST_ROUTE, DEFAULT_OFF_HOST_ROUTE_DEST);
701 defaultFelicaRoute_ = NfcConfig::getUnsigned(NAME_DEFAULT_NFCF_ROUTE, DEFAULT_FELICA_ROUTE_DEST);
702 defaultEe_ = NfcConfig::getUnsigned(NAME_DEFAULT_ROUTE, DEFAULT_EE_ROUTE_DEST);
703 if (NfcConfig::hasKey(NAME_OFFHOST_ROUTE_UICC)) {
704 offHostRouteUicc_ = NfcConfig::getBytes(NAME_OFFHOST_ROUTE_UICC);
705 } else {
706 offHostRouteUicc_ = DEFAULT_UICC_ROUTE_DEST;
707 }
708 if (NfcConfig::hasKey(NAME_OFFHOST_ROUTE_ESE)) {
709 offHostRouteEse_ = NfcConfig::getBytes(NAME_OFFHOST_ROUTE_ESE);
710 } else {
711 offHostRouteEse_ = {DEFAULT_EE_ROUTE_DEST};
712 }
713 InfoLog("RoutingManager: defaultEe_ is 0x%{public}02x, defaultFelicaRoute_ is 0x%{public}02x",
714 defaultEe_, defaultFelicaRoute_);
715
716 // read syscode params from config
717 defaultSysCodeRoute_ = NfcConfig::getUnsigned(NAME_DEFAULT_SYS_CODE_ROUTE, DEFAULT_SYS_CODE_ROUTE_DEST);
718 defaultSysCodePowerstate_ = NfcConfig::getUnsigned(NAME_DEFAULT_SYS_CODE_PWR_STATE, DEFAULT_SYS_CODE_PWR_STA);
719 defaultSysCode_ = DEFAULT_SYS_CODE;
720
721 isDeinitializing_ = false;
722 isEeInfoChanged_ = false;
723
724 hostListenTechMask_ = NfcConfig::getUnsigned(NAME_HOST_LISTEN_TECH_MASK,
725 NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B);
726 }
727
~RoutingManager()728 RoutingManager::~RoutingManager() {}
729 } // NCI
730 } // NFC
731 } // OHOS