1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "NfceeManager.h"
18
19 #include <android-base/logging.h>
20 #include <android-base/stringprintf.h>
21 #include <errno.h>
22 #include <nativehelper/ScopedLocalRef.h>
23
24 #include "nfc_config.h"
25
26 using android::base::StringPrintf;
27
28 NfceeManager NfceeManager::sNfceeManager;
29
30 /*******************************************************************************
31 **
32 ** Function: NfceeManager
33 **
34 ** Description: Initialize member variables.
35 **
36 ** Returns: None
37 **
38 *******************************************************************************/
NfceeManager()39 NfceeManager::NfceeManager() : mNumEePresent(0) {
40 mActualNumEe = MAX_NUM_NFCEE;
41 eseName = "eSE";
42 uiccName = "SIM";
43 memset(&mNfceeData_t, 0, sizeof(mNfceeData));
44 }
45
46 /*******************************************************************************
47 **
48 ** Function: ~NfceeManager
49 **
50 ** Description: Release all resources.
51 **
52 ** Returns: None
53 **
54 *******************************************************************************/
~NfceeManager()55 NfceeManager::~NfceeManager() {}
56
57 /*******************************************************************************
58 **
59 ** Function: getInstance
60 **
61 ** Description: Get the singleton of this object.
62 **
63 ** Returns: Reference to this object.
64 **
65 *******************************************************************************/
getInstance()66 NfceeManager& NfceeManager::getInstance() { return sNfceeManager; }
67
68 /*******************************************************************************
69 **
70 ** Function: getActiveNfceeList
71 **
72 ** Description: Get the list of Activated NFCEE.
73 ** e: Java Virtual Machine.
74 **
75 ** Returns: List of Activated NFCEE.
76 **
77 *******************************************************************************/
getActiveNfceeList(JNIEnv * e)78 jobject NfceeManager::getActiveNfceeList(JNIEnv* e) {
79 ScopedLocalRef<jclass> hashMapClass(e, e->FindClass(mHashMapClassName));
80 jmethodID hashMapConstructor =
81 e->GetMethodID(hashMapClass.get(), "<init>", "()V");
82 jmethodID hashMapPut = e->GetMethodID(
83 hashMapClass.get(), "put",
84 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
85 jobject nfceeHashMaptObj =
86 e->NewObject(hashMapClass.get(), hashMapConstructor);
87 ScopedLocalRef<jclass> integerClass(e, e->FindClass("java/lang/Integer"));
88 jmethodID integerConstructor =
89 e->GetMethodID(integerClass.get(), "<init>", "(I)V");
90 if (!getNFCEeInfo()) return (nfceeHashMaptObj);
91
92 vector<uint8_t> eSERoute;
93 vector<uint8_t> uiccRoute;
94 map<uint8_t, std::string> nfceeMap;
95
96 if (NfcConfig::hasKey(NAME_OFFHOST_ROUTE_ESE)) {
97 eSERoute = NfcConfig::getBytes(NAME_OFFHOST_ROUTE_ESE);
98 }
99
100 if (NfcConfig::hasKey(NAME_OFFHOST_ROUTE_UICC)) {
101 uiccRoute = NfcConfig::getBytes(NAME_OFFHOST_ROUTE_UICC);
102 }
103
104 for (uint8_t i = 0; i < eSERoute.size(); ++i) {
105 nfceeMap[eSERoute[i]] = eseName + std::to_string(i + 1);
106 }
107
108 for (uint8_t i = 0; i < uiccRoute.size(); ++i) {
109 nfceeMap[uiccRoute[i]] = uiccName + std::to_string(i + 1);
110 }
111
112 for (int i = 0; i < mNfceeData_t.mNfceePresent; i++) {
113 uint8_t id = (mNfceeData_t.mNfceeID[i] & ~NFA_HANDLE_GROUP_EE);
114 uint8_t status = mNfceeData_t.mNfceeStatus[i];
115 if ((nfceeMap.find(id) != nfceeMap.end()) &&
116 (status == NFC_NFCEE_STATUS_ACTIVE)) {
117 jstring element = e->NewStringUTF(nfceeMap[id].c_str());
118 jobject jtechmask = e->NewObject(integerClass.get(), integerConstructor,
119 mNfceeData_t.mNfceeTechMask[i]);
120 e->CallObjectMethod(nfceeHashMaptObj, hashMapPut, element, jtechmask);
121 e->DeleteLocalRef(element);
122 }
123 }
124 return nfceeHashMaptObj;
125 }
126
127 /*******************************************************************************
128 **
129 ** Function: getNFCEeInfo
130 **
131 ** Description: Get latest information about execution
132 ** environments from stack.
133 ** Returns: True if at least 1 EE is available.
134 **
135 *******************************************************************************/
getNFCEeInfo()136 bool NfceeManager::getNFCEeInfo() {
137 static const char fn[] = "getNFCEeInfo";
138 LOG(INFO) << StringPrintf("%s: enter", fn);
139 tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
140 mNumEePresent = 0x00;
141 memset(&mNfceeData_t, 0, sizeof(mNfceeData_t));
142
143 /* Reading latest NFCEE info in case it is updated */
144 if ((nfaStat = NFA_EeGetInfo(&mActualNumEe, mEeInfo)) != NFA_STATUS_OK) {
145 LOG(ERROR) << StringPrintf("%s: fail get info; error=0x%X", fn, nfaStat);
146 mActualNumEe = 0;
147 } else {
148 LOG(INFO) << StringPrintf("%s: num NFCEE discovered: %u", fn, mActualNumEe);
149 if (mActualNumEe != 0) {
150 for (uint8_t xx = 0; xx < mActualNumEe; xx++) {
151 tNFA_TECHNOLOGY_MASK eeTechnology = 0x00;
152 if (mEeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS)
153 mNumEePresent++;
154
155 mNfceeData_t.mNfceeID[xx] = mEeInfo[xx].ee_handle;
156 mNfceeData_t.mNfceeStatus[xx] = mEeInfo[xx].ee_status;
157 if (mEeInfo[xx].la_protocol) eeTechnology |= NFA_TECHNOLOGY_MASK_A;
158 if (mEeInfo[xx].lb_protocol) eeTechnology |= NFA_TECHNOLOGY_MASK_B;
159 if (mEeInfo[xx].lf_protocol) eeTechnology |= NFA_TECHNOLOGY_MASK_F;
160 mNfceeData_t.mNfceeTechMask[xx] = eeTechnology;
161 }
162 }
163 }
164 LOG(INFO) << StringPrintf("%s: exit; mActualNumEe=%d, mNumEePresent=%d", fn,
165 mActualNumEe, mNumEePresent);
166 mNfceeData_t.mNfceePresent = mNumEePresent;
167 return (mActualNumEe != 0);
168 }
169