• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 "NfcVendorExtn.h"
18 
19 #include <android-base/file.h>
20 #include <android-base/logging.h>
21 #include <android-base/properties.h>
22 #include <android-base/stringprintf.h>
23 #include <android/log.h>
24 #include <dlfcn.h>
25 #include <error.h>
26 #include <log/log.h>
27 #include <string>
28 
29 using android::base::StringPrintf;
30 #define UNUSED_PROP(X) (void)(X);
31 
32 const std::string vendor_nfc_init_name = "vendor_nfc_init";
33 const std::string vendor_nfc_de_init_name = "vendor_nfc_de_init";
34 const std::string vendor_nfc_handle_event_name = "vendor_nfc_handle_event";
35 const std::string vendor_nfc_on_config_update_name =
36     "vendor_nfc_on_config_update";
37 
38 static NfcVendorExtn* sNfcVendorExtn;
39 
40 typedef bool (*fp_extn_init_t)(VendorExtnCb*);
41 typedef bool (*fp_extn_deinit_t)();
42 typedef tNFC_STATUS (*fp_extn_handle_nfc_event_t)(NfcExtEvent_t,
43                                                   NfcExtEventData_t);
44 typedef void (*fp_extn_on_config_update_t)(std::map<std::string, ConfigValue>*);
45 
46 fp_extn_init_t fp_extn_init = NULL;
47 fp_extn_deinit_t fp_extn_deinit = NULL;
48 fp_extn_handle_nfc_event_t fp_extn_handle_nfc_event = NULL;
49 fp_extn_on_config_update_t fp_extn_on_config_update = NULL;
50 
51 NfcExtEventData_t mNfcExtEventData;
52 std::string mLibPathName = "";
53 
54 void* p_oem_extn_handle = NULL;
55 
56 namespace {
searchLibPath(std::string file_name)57   std::string searchLibPath(std::string file_name) {
58 #if (defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64))
59     const std::vector<std::string> search_path = {
60         "/system/lib64/"
61     };
62 #else
63     const std::vector<std::string> search_path = {
64         "/system/lib/"
65     };
66 #endif
67     for (std::string path : search_path) {
68       path.append(file_name);
69       struct stat file_stat;
70       if (stat(path.c_str(), &file_stat) != 0) continue;
71       if (S_ISREG(file_stat.st_mode)) return path;
72     }
73     return "";
74   }
75   // Extension library file Search sequence
76   // 1. If prop_lib_file_name is defined.(where prop_config_file_name is the
77   //   value of the property persist.nfc_vendor_extn.lib_file_name)
78   //   Search a file matches prop_lib_file_name.
79   // 2. If SKU is defined (where SKU is the value of the property
80   //   ro.boot.product.hardware.sku)
81   //   Search a file matches libnfc_vendor_extn-SKU.so
82   // 3. If none of 1,2 is defined, search a default file name "libnfc_vendor_extn.so".
findLibPath()83   std::string findLibPath() {
84     std::string f_path = searchLibPath(
85         android::base::GetProperty("persist.nfc_vendor_extn.lib_file_name", ""));
86     if (!f_path.empty()) return f_path;
87 
88     // Search for libnfc_vendor_extn-SKU.so
89     f_path = searchLibPath(
90         "libnfc_vendor_extn-" +
91         android::base::GetProperty("ro.boot.product.hardware.sku", "") + ".so");
92     if (!f_path.empty()) return f_path;
93 
94     // load default file if the desired file not found.
95     return searchLibPath("libnfc_vendor_extn.so");
96   }
97 }  // namespace
98 
NfcVendorExtn()99 NfcVendorExtn::NfcVendorExtn() {}
100 
~NfcVendorExtn()101 NfcVendorExtn::~NfcVendorExtn() { sNfcVendorExtn = nullptr; }
102 
getInstance()103 NfcVendorExtn* NfcVendorExtn::getInstance() {
104   if (sNfcVendorExtn == nullptr) {
105     sNfcVendorExtn = new NfcVendorExtn();
106   }
107   return sNfcVendorExtn;
108 }
109 
NfcExtn_LibInit()110 void NfcExtn_LibInit() {
111   LOG(VERBOSE) << __func__;
112   if (fp_extn_init != NULL) {
113     if (!fp_extn_init(NfcVendorExtn::getInstance()->getVendorExtnCb())) {
114       LOG(ERROR) << StringPrintf("%s: %s failed!", __func__,
115                                  vendor_nfc_init_name.c_str());
116     }
117   }
118 }
119 
NfcExtn_LibSetup()120 bool NfcExtn_LibSetup() {
121   LOG(VERBOSE) << __func__;
122   mLibPathName = findLibPath();
123   if (mLibPathName.empty()) {
124     LOG(ERROR) << StringPrintf("%s: Failed to find %s !!", __func__,
125                                mLibPathName.c_str());
126     return false;
127   }
128   p_oem_extn_handle = dlopen(mLibPathName.c_str(), RTLD_NOW);
129   if (p_oem_extn_handle == NULL) {
130     LOG(DEBUG) << StringPrintf(
131         "%s: Error : opening (%s) !! dlerror: "
132         "%s",
133         __func__, mLibPathName.c_str(), dlerror());
134     return false;
135   }
136   if ((fp_extn_init = (fp_extn_init_t)dlsym(
137            p_oem_extn_handle, vendor_nfc_init_name.c_str())) == NULL) {
138     LOG(ERROR) << StringPrintf("%s: Failed to find %s !!", __func__,
139                                vendor_nfc_init_name.c_str());
140   }
141 
142   if ((fp_extn_deinit = (fp_extn_deinit_t)dlsym(
143            p_oem_extn_handle, vendor_nfc_de_init_name.c_str())) == NULL) {
144     LOG(ERROR) << StringPrintf("%s: Failed to find %s !!", __func__,
145                                vendor_nfc_de_init_name.c_str());
146   }
147 
148   if ((fp_extn_handle_nfc_event = (fp_extn_handle_nfc_event_t)dlsym(
149            p_oem_extn_handle, vendor_nfc_handle_event_name.c_str())) == NULL) {
150     LOG(ERROR) << StringPrintf("%s: Failed to find %s !!", __func__,
151                                vendor_nfc_handle_event_name.c_str());
152   }
153 
154   if ((fp_extn_on_config_update = (fp_extn_on_config_update_t)dlsym(
155            p_oem_extn_handle, vendor_nfc_on_config_update_name.c_str())) ==
156       NULL) {
157     LOG(ERROR) << StringPrintf("%s: Failed to find %s !!", __func__,
158                                vendor_nfc_on_config_update_name.c_str());
159   }
160 
161   NfcExtn_LibInit();
162   return true;
163 }
164 
Initialize(sp<INfc> hidlHal,std::shared_ptr<INfcAidl> aidlHal)165 bool NfcVendorExtn::Initialize(sp<INfc> hidlHal,
166                                std::shared_ptr<INfcAidl> aidlHal) {
167   LOG(VERBOSE) << StringPrintf("%s:", __func__);
168   mVendorExtnCb.hidlHal = hidlHal;
169   mVendorExtnCb.aidlHal = aidlHal;
170   if (!NfcExtn_LibSetup()) {
171     mVendorExtnCb.hidlHal = nullptr;
172     mVendorExtnCb.aidlHal = nullptr;
173     return false;
174   }
175   return true;
176 }
177 
setNciCallback(tHAL_NFC_CBACK * pHalCback,tHAL_NFC_DATA_CBACK * pDataCback)178 void NfcVendorExtn::setNciCallback(tHAL_NFC_CBACK* pHalCback,
179                                    tHAL_NFC_DATA_CBACK* pDataCback) {
180   LOG(VERBOSE) << __func__;
181   mVendorExtnCb.pHalCback = pHalCback;
182   mVendorExtnCb.pDataCback = pDataCback;
183 }
184 
processCmd(uint16_t dataLen,uint8_t * pData)185 bool NfcVendorExtn::processCmd(uint16_t dataLen, uint8_t* pData) {
186   LOG(VERBOSE) << StringPrintf("%s: Enter dataLen=%d", __func__, dataLen);
187   NciData_t nci_data;
188   nci_data.data_len = dataLen;
189   nci_data.p_data = (uint8_t*)pData;
190   mNfcExtEventData.nci_msg = nci_data;
191 
192   if (fp_extn_handle_nfc_event != NULL) {
193     tNFC_STATUS stat =
194         fp_extn_handle_nfc_event(HANDLE_VENDOR_NCI_MSG, mNfcExtEventData);
195     LOG(VERBOSE) << StringPrintf("%s: Exit status(%d)", __func__, stat);
196     return stat == NFCSTATUS_EXTN_FEATURE_SUCCESS;
197   } else {
198     LOG(ERROR) << StringPrintf("%s: not found", __func__);
199     return false;
200   }
201 }
202 
processRspNtf(uint16_t dataLen,uint8_t * pData)203 bool NfcVendorExtn::processRspNtf(uint16_t dataLen, uint8_t* pData) {
204   LOG(VERBOSE) << StringPrintf("%s: dataLen=%d", __func__, dataLen);
205   NciData_t nciData;
206   nciData.data_len = dataLen;
207   nciData.p_data = (uint8_t*)pData;
208   mNfcExtEventData.nci_rsp_ntf = nciData;
209 
210   if (fp_extn_handle_nfc_event != NULL) {
211     tNFC_STATUS stat =
212         fp_extn_handle_nfc_event(HANDLE_VENDOR_NCI_RSP_NTF, mNfcExtEventData);
213     LOG(VERBOSE) << StringPrintf("%s: Exit status(%d)", __func__, stat);
214     return stat == NFCSTATUS_EXTN_FEATURE_SUCCESS;
215   } else {
216     LOG(ERROR) << StringPrintf("%s: not found", __func__);
217     return false;
218   }
219 }
220 
processEvent(uint8_t event,uint8_t status)221 bool NfcVendorExtn::processEvent(uint8_t event, uint8_t status) {
222   LOG(VERBOSE) << StringPrintf("%s: event=%d, status=%d", __func__, event,
223                                status);
224   if (fp_extn_handle_nfc_event != NULL) {
225     mNfcExtEventData.hal_event = event;
226     mNfcExtEventData.hal_event_status = status;
227     tNFC_STATUS stat =
228         fp_extn_handle_nfc_event(HANDLE_HAL_EVENT, mNfcExtEventData);
229     LOG(DEBUG) << StringPrintf("%s: Exit status(%d)", __func__, stat);
230     return stat == NFCSTATUS_EXTN_FEATURE_SUCCESS;
231   } else {
232     LOG(ERROR) << StringPrintf("%s: not found", __func__);
233     return false;
234   }
235 }
236 
getVendorConfigs(std::map<std::string,ConfigValue> * pConfigMap)237 void NfcVendorExtn::getVendorConfigs(
238     std::map<std::string, ConfigValue>* pConfigMap) {
239   LOG(VERBOSE) << __func__;
240   mVendorExtnCb.configMap = *pConfigMap;
241   if (fp_extn_on_config_update != NULL) {
242     fp_extn_on_config_update(pConfigMap);
243   } else {
244     LOG(ERROR) << StringPrintf("%s: not found", __func__);
245   }
246 }
247 
getVendorExtnCb()248 VendorExtnCb* NfcVendorExtn::getVendorExtnCb() { return &mVendorExtnCb; }
249 
phNfcExtn_LibClose()250 void phNfcExtn_LibClose() {
251   LOG(VERBOSE) << __func__;
252   if (fp_extn_deinit != NULL) {
253     if (!fp_extn_deinit()) {
254       LOG(ERROR) << StringPrintf("%s: %s failed", __func__,
255                                  vendor_nfc_de_init_name.c_str());
256     }
257   }
258   if (p_oem_extn_handle != NULL) {
259     LOG(DEBUG) << StringPrintf("%s: Closing %s!!", __func__, mLibPathName.c_str());
260     dlclose(p_oem_extn_handle);
261     p_oem_extn_handle = NULL;
262   }
263 }
264 
finalize(void)265 bool NfcVendorExtn::finalize(void) {
266   LOG(VERBOSE) << __func__;
267   phNfcExtn_LibClose();
268   mVendorExtnCb.hidlHal = nullptr;
269   mVendorExtnCb.aidlHal = nullptr;
270   return true;
271 }
272