1 /*
2  * Copyright (c) 2024 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 
16 #include "vendor_wlan_group.h"
17 #include "print_log.h"
18 #include "print_utils.h"
19 #include "file_ex.h"
20 
21 using namespace OHOS::Print;
22 namespace {
23     const std::string VENDOR_BSUNI_URI_START = "://";
24     const std::string VENDOR_BSUNI_URI_END = ":";
25     const std::string VENDOR_CONVERTED_PRINTERID = "uuid";
26     const std::string VENDOR_BSUNI_GS_PATH = "/system/bin/uni_print_driver/ghostscript/bin/gs";
27 }
28 
VendorWlanGroup(VendorManager * vendorManager)29 VendorWlanGroup::VendorWlanGroup(VendorManager *vendorManager) : parentVendorManager(vendorManager)
30 {
31     hasGs = FileExists(VENDOR_BSUNI_GS_PATH);
32 }
33 
GetVendorName()34 std::string VendorWlanGroup::GetVendorName()
35 {
36     return VENDOR_WLAN_GROUP;
37 }
38 
OnQueryCapability(const std::string & printerId,int timeout)39 bool VendorWlanGroup::OnQueryCapability(const std::string &printerId, int timeout)
40 {
41     PRINT_HILOGI("OnQueryCapability enter.");
42     if (parentVendorManager == nullptr) {
43         PRINT_HILOGE("VendorManager is null.");
44         return false;
45     }
46     auto ppdDriver = parentVendorManager->FindDriverByVendorName(VENDOR_PPD_DRIVER);
47     if (ppdDriver != nullptr) {
48         printerVendorGroupList_[printerId] = VENDOR_PPD_DRIVER;
49         auto printerInfo = parentVendorManager->QueryDiscoveredPrinterInfoById(GetVendorName(), printerId);
50         if (printerInfo != nullptr && ppdDriver->OnQueryProperties(printerId, std::vector<std::string>(1,
51             printerInfo->GetPrinterMake()))) {
52             if (ppdDriver->OnQueryCapability(printerId, timeout)) {
53                 PRINT_HILOGI("on query capability on ppd vendor seccess.");
54                 return true;
55             }
56         }
57         RemovePrinterVendorGroupById(printerId);
58     }
59     if (IsBsunidriverSupport(printerId)) {
60         printerVendorGroupList_[printerId] = VENDOR_BSUNI_DRIVER;
61         auto bsuniDriver = parentVendorManager->FindDriverByVendorName(VENDOR_BSUNI_DRIVER);
62         auto printerInfo = parentVendorManager->QueryDiscoveredPrinterInfoById(GetVendorName(), printerId);
63         if (bsuniDriver != nullptr && printerInfo != nullptr &&
64             bsuniDriver->OnQueryCapability(ExtractBsUniPrinterIdByPrinterInfo(*printerInfo), timeout)) {
65             PRINT_HILOGI("on query capability on bsuni vendor seccess.");
66             return true;
67         }
68         RemovePrinterVendorGroupById(printerId);
69     } else {
70         printerVendorGroupList_[printerId] = VENDOR_IPP_EVERYWHERE;
71         auto ippEverywhereDriver = parentVendorManager->FindDriverByVendorName(VENDOR_IPP_EVERYWHERE);
72         if (ippEverywhereDriver != nullptr && ippEverywhereDriver->OnQueryCapabilityByIp(printerId, "auto")) {
73             PRINT_HILOGI("on query capability on ipp everywhere seccess.");
74             return true;
75         }
76         RemovePrinterVendorGroupById(printerId);
77     }
78     PRINT_HILOGE("no vendor can query capability.");
79     return false;
80 }
81 
OnQueryCapabilityByIp(const std::string & printerIp,const std::string & protocol)82 bool VendorWlanGroup::OnQueryCapabilityByIp(const std::string &printerIp, const std::string &protocol)
83 {
84     PRINT_HILOGI("OnQueryCapabilityByIp enter.");
85     if (parentVendorManager == nullptr) {
86         PRINT_HILOGE("VendorManager is null.");
87         return false;
88     }
89     auto bsuniDriver = parentVendorManager->FindDriverByVendorName(VENDOR_BSUNI_DRIVER);
90     printerVendorGroupList_[printerIp] = VENDOR_BSUNI_DRIVER;
91     if (bsuniDriver != nullptr && bsuniDriver->OnQueryCapabilityByIp(printerIp, protocol)) {
92         PRINT_HILOGI("on query capability by ip on bsuni vendor seccess.");
93         return true;
94     }
95     RemovePrinterVendorGroupById(printerIp);
96     printerVendorGroupList_[printerIp] = VENDOR_IPP_EVERYWHERE;
97     auto ippEverywhereDriver = parentVendorManager->FindDriverByVendorName(VENDOR_IPP_EVERYWHERE);
98     if (ippEverywhereDriver != nullptr && ippEverywhereDriver->OnQueryCapabilityByIp(printerIp, protocol)) {
99         PRINT_HILOGI("on query capability by ip on ipp everywhere seccess.");
100         return true;
101     }
102     RemovePrinterVendorGroupById(printerIp);
103     PRINT_HILOGE("no vendor can query capability by ip.");
104     return false;
105 }
106 
OnPrinterDiscovered(const std::string & vendorName,const PrinterInfo & printerInfo)107 int32_t VendorWlanGroup::OnPrinterDiscovered(const std::string &vendorName, const PrinterInfo &printerInfo)
108 {
109     if (vendorManager == nullptr) {
110         PRINT_HILOGE("VendorManager is null.");
111         return EXTENSION_ERROR_CALLBACK_NULL;
112     }
113     return vendorManager->AddPrinterToDiscovery(GetVendorName(), ConvertPrinterInfoId(printerInfo));
114 }
115 
OnUpdatePrinterToDiscovery(const std::string & vendorName,const PrinterInfo & printerInfo)116 int32_t VendorWlanGroup::OnUpdatePrinterToDiscovery(const std::string &vendorName, const PrinterInfo &printerInfo)
117 {
118     if (vendorManager == nullptr) {
119         PRINT_HILOGE("VendorManager is null.");
120         return EXTENSION_ERROR_CALLBACK_NULL;
121     }
122     return vendorManager->UpdatePrinterToDiscovery(GetVendorName(), ConvertPrinterInfoId(printerInfo));
123 }
124 
OnPrinterRemoved(const std::string & vendorName,const std::string & printerId)125 int32_t VendorWlanGroup::OnPrinterRemoved(const std::string &vendorName, const std::string &printerId)
126 {
127     if (vendorManager == nullptr) {
128         PRINT_HILOGE("VendorManager is null.");
129         return EXTENSION_ERROR_CALLBACK_NULL;
130     }
131     RemovePrinterVendorGroupById(printerId);
132     std::string id(VendorManager::ExtractPrinterId(printerId));
133     QueryBsUniPrinterIdByUuidPrinterId(id);
134     return vendorManager->RemovePrinterFromDiscovery(GetVendorName(), id);
135 }
136 
IsConnectingPrinter(const std::string & globalPrinterIdOrIp,const std::string & uri)137 bool VendorWlanGroup::IsConnectingPrinter(const std::string &globalPrinterIdOrIp, const std::string &uri)
138 {
139     if (vendorManager == nullptr) {
140         PRINT_HILOGE("VendorManager is null.");
141         return false;
142     }
143     std::string printerId(VendorManager::ExtractPrinterId(globalPrinterIdOrIp));
144     QueryBsUniPrinterIdByUuidPrinterId(printerId);
145     printerId = GetGlobalPrinterId(printerId);
146     return vendorManager->IsConnectingPrinter(printerId, uri);
147 }
148 
SetConnectingPrinter(ConnectMethod method,const std::string & globalPrinterIdOrIp)149 void VendorWlanGroup::SetConnectingPrinter(ConnectMethod method, const std::string &globalPrinterIdOrIp)
150 {
151     if (vendorManager == nullptr) {
152         PRINT_HILOGE("VendorManager is null.");
153         return;
154     }
155     std::string printerId(VendorManager::ExtractPrinterId(globalPrinterIdOrIp));
156     QueryBsUniPrinterIdByUuidPrinterId(printerId);
157     printerId = GetGlobalPrinterId(printerId);
158     vendorManager->SetConnectingPrinter(method, printerId);
159 }
160 
OnPrinterPpdQueried(const std::string & vendorName,const std::string & printerId,const std::string & ppdData)161 bool VendorWlanGroup::OnPrinterPpdQueried(const std::string &vendorName, const std::string &printerId,
162                                           const std::string &ppdData)
163 {
164     if (vendorManager == nullptr) {
165         PRINT_HILOGE("VendorManager is null.");
166         return false;
167     }
168     std::string id(printerId);
169     QueryBsUniPrinterIdByUuidPrinterId(id);
170     return vendorManager->OnPrinterPpdQueried(GetVendorName(), id, ppdData);
171 }
172 
173 
IsGroupDriver(const std::string & bothPrinterId)174 bool VendorWlanGroup::IsGroupDriver(const std::string &bothPrinterId)
175 {
176     if (bothPrinterId.find(VENDOR_CONVERTED_PRINTERID) != std::string::npos) {
177         PRINT_HILOGD("printerId has be converted whit uuid, is group driver!.");
178         return true;
179     }
180     std::string printerId(VendorManager::ExtractPrinterId(bothPrinterId));
181     auto iter = printerVendorGroupList_.find(printerId);
182     return (iter != printerVendorGroupList_.end() && !iter->second.empty());
183 }
184 
ConvertGroupDriver(std::string & printerId,std::string & vendorName)185 bool VendorWlanGroup::ConvertGroupDriver(std::string &printerId, std::string &vendorName)
186 {
187     printerId = VendorManager::ExtractPrinterId(printerId);
188     if (vendorName == VENDOR_BSUNI_DRIVER) {
189         QueryBsUniPrinterIdByUuidPrinterId(printerId);
190         return false;
191     }
192     auto iter = printerVendorGroupList_.find(printerId);
193     if (iter != printerVendorGroupList_.end() && !iter->second.empty()) {
194         vendorName = VENDOR_WLAN_GROUP;
195         return true;
196     }
197     return false;
198 }
199 
IsBsunidriverSupport(const std::string & printerId)200 bool VendorWlanGroup::IsBsunidriverSupport(const std::string &printerId)
201 {
202     PRINT_HILOGD("IsBsunidriverSupport enter");
203     auto printerInfo = parentVendorManager->QueryDiscoveredPrinterInfoById(GetVendorName(), printerId);
204     if (printerInfo == nullptr) {
205         return false;
206     }
207     std::string supportValue;
208     if (printerInfo->HasOption() && nlohmann::json::accept(printerInfo->GetOption())) {
209         nlohmann::json option = nlohmann::json::parse(printerInfo->GetOption());
210         if (option.contains("bsunidriverSupport") && option["bsunidriverSupport"].is_string()) {
211             supportValue = option["bsunidriverSupport"].get<std::string>();
212         }
213     }
214     PRINT_HILOGD("IsBsunidriverSupport bsunidriverSupport=%{public}s", supportValue.c_str());
215     if (supportValue == "true") {
216         return true;
217     } else if (supportValue == "need_gs") {
218         return hasGs;
219     } else {
220         return false;
221     }
222 }
223 
RemovePrinterVendorGroupById(const std::string & printerId)224 void VendorWlanGroup::RemovePrinterVendorGroupById(const std::string &printerId)
225 {
226     auto iter = printerVendorGroupList_.find(printerId);
227     if (iter != printerVendorGroupList_.end()) {
228         PRINT_HILOGD("remove printer from vendor group list");
229         printerVendorGroupList_.erase(printerId);
230     }
231 }
232 
ConvertGroupGlobalPrinterId(const std::string & bothPrinterId)233 std::string VendorWlanGroup::ConvertGroupGlobalPrinterId(const std::string &bothPrinterId)
234 {
235     std::string printerId(VendorManager::ExtractPrinterId(bothPrinterId));
236     return PrintUtils::GetGlobalId(VendorManager::GetGlobalVendorName(GetVendorName()), printerId);
237 }
238 
QueryBsUniPrinterIdByUuidPrinterId(std::string & bsUniPrinterId)239 void VendorWlanGroup::QueryBsUniPrinterIdByUuidPrinterId(std::string &bsUniPrinterId)
240 {
241     std::lock_guard<std::mutex> lock(uuidMapMutex);
242     auto item = printerIdToUuidMap_.find(bsUniPrinterId);
243     if (item != printerIdToUuidMap_.end() && !item->second.empty()) {
244         bsUniPrinterId = std::string(item->second);
245     }
246 }
247 
UpdateMappedPrinterId(const std::string & bsUniPrinterId,const std::string printerId)248 void VendorWlanGroup::UpdateMappedPrinterId(const std::string &bsUniPrinterId, const std::string printerId)
249 {
250     std::lock_guard<std::mutex> lock(uuidMapMutex);
251     printerIdToUuidMap_[bsUniPrinterId] = printerId;
252 }
253 
ConvertPrinterInfoId(const PrinterInfo & printerInfo)254 PrinterInfo VendorWlanGroup::ConvertPrinterInfoId(const PrinterInfo &printerInfo)
255 {
256     PrinterInfo info(printerInfo);
257     if (printerInfo.HasOption() && nlohmann::json::accept(std::string(printerInfo.GetOption()))) {
258         nlohmann::json option = nlohmann::json::parse(std::string(printerInfo.GetOption()));
259         if (option != nullptr && option.contains("printer-uuid") && option["printer-uuid"].is_string()) {
260             info.SetPrinterId(std::string(option["printer-uuid"]));
261             UpdateMappedPrinterId(printerInfo.GetPrinterId(), std::string(option["printer-uuid"]));
262             PRINT_HILOGD("Convert PrinterId with uuid");
263             return info;
264         }
265     }
266     return printerInfo;
267 }
268 
ExtractBsUniPrinterIdByPrinterInfo(const PrinterInfo & printerInfo)269 std::string VendorWlanGroup::ExtractBsUniPrinterIdByPrinterInfo(const PrinterInfo &printerInfo)
270 {
271     std::string uri(printerInfo.GetUri());
272     if (uri.empty()) {
273         return "";
274     }
275     auto pos_start = uri.find_first_of(VENDOR_BSUNI_URI_START);
276     auto pos_end = uri.find_last_of(VENDOR_BSUNI_URI_END);
277     if (pos_start == std::string::npos || uri.length() <= pos_start + 1 ||
278         pos_start == std::string::npos || uri.length() <= pos_start + 1) {
279         return "";
280     }
281     return uri.substr(pos_start + VENDOR_BSUNI_URI_START.length(),
282         pos_end - pos_start - VENDOR_BSUNI_URI_START.length());
283 }
284