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