• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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