• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <fcntl.h>
17 #include <unistd.h>
18 #include <iostream>
19 #include <fstream>
20 #include <streambuf>
21 #include "scan_log.h"
22 #include "scan_usb_manager.h"
23 #include "scan_util.h"
24 #include "scan_system_data.h"
25 #include "scan_service_ability.h"
26 
27 namespace {
28 const std::string SCANNER_LIST_FILE = "/data/service/el1/public/print_service/scanner_list.json";
29 const std::string SCANNER_LIST_VERSION = "v1";
30 }  // namespace
31 
32 namespace OHOS {
33 namespace Scan {
CheckJsonObjectValue(const Json::Value & object)34 bool ScanSystemData::CheckJsonObjectValue(const Json::Value& object)
35 {
36     const std::vector<std::string> keyList = {"deviceId", "manufacturer", "model", "deviceType",
37         "discoverMode", "serialNumber", "deviceName", "uniqueId"};
38     for (auto key : keyList) {
39         if (!Print::PrintJsonUtil::IsMember(object, key) || !object[key].isString()) {
40             SCAN_HILOGW("can not find %{public}s", key.c_str());
41             return false;
42         }
43     }
44     return true;
45 }
46 
ParseScannerJsonV1(ScanDeviceInfo & scanDeviceInfo,Json::Value & object)47 void ScanSystemData::ParseScannerJsonV1(ScanDeviceInfo &scanDeviceInfo, Json::Value &object)
48 {
49     if (OHOS::Print::PrintJsonUtil::IsMember(object, "deviceId") && object["deviceId"].isString()) {
50         scanDeviceInfo.deviceId = object["deviceId"].asString();
51     }
52     if (OHOS::Print::PrintJsonUtil::IsMember(object, "manufacturer") && object["manufacturer"].isString()) {
53         scanDeviceInfo.manufacturer = object["manufacturer"].asString();
54     }
55     if (OHOS::Print::PrintJsonUtil::IsMember(object, "model") && object["model"].isString()) {
56         scanDeviceInfo.model = object["model"].asString();
57     }
58     if (OHOS::Print::PrintJsonUtil::IsMember(object, "deviceType") && object["deviceType"].isString()) {
59         scanDeviceInfo.deviceType = object["deviceType"].asString();
60     }
61     if (OHOS::Print::PrintJsonUtil::IsMember(object, "discoverMode") && object["discoverMode"].isString()) {
62         scanDeviceInfo.discoverMode = object["discoverMode"].asString();
63     }
64     if (OHOS::Print::PrintJsonUtil::IsMember(object, "serialNumber") && object["serialNumber"].isString()) {
65         scanDeviceInfo.serialNumber = object["serialNumber"].asString();
66     }
67     if (OHOS::Print::PrintJsonUtil::IsMember(object, "deviceName") && object["deviceName"].isString()) {
68         scanDeviceInfo.deviceName = object["deviceName"].asString();
69     }
70     if (OHOS::Print::PrintJsonUtil::IsMember(object, "uniqueId") && object["uniqueId"].isString()) {
71         scanDeviceInfo.uniqueId = object["uniqueId"].asString();
72     }
73     if (OHOS::Print::PrintJsonUtil::IsMember(object, "uuid") && object["uuid"].isString()) {
74         scanDeviceInfo.uuid = object["uuid"].asString();
75     }
76 }
77 
ParseScannerListJsonV1(Json::Value & jsonObject)78 bool ScanSystemData::ParseScannerListJsonV1(Json::Value& jsonObject)
79 {
80     if (!Print::PrintJsonUtil::IsMember(jsonObject, "scaner_list") || !jsonObject["scaner_list"].isArray()) {
81         SCAN_HILOGW("can not find scaner_list");
82         return false;
83     }
84     uint32_t jsonSize = jsonObject["scaner_list"].size();
85     if (jsonObject > MAX_SCANNER_SIZE) {
86         PRINT_HILOGE("scanner list size is illegal.");
87         return false;
88     }
89     for (uint32_t i = 0; i < jsonSize; i++) {
90         Json::Value object = jsonObject["scaner_list"][i];
91         if (!CheckJsonObjectValue(object)) {
92             continue;
93         }
94         ScanDeviceInfo scanDeviceInfo;
95         ParseScannerJsonV1(scanDeviceInfo, object);
96         std::string uniqueId = scanDeviceInfo.discoverMode + scanDeviceInfo.uniqueId;
97         InsertScannerInfo(uniqueId, scanDeviceInfo);
98     }
99     return true;
100 }
101 
Init()102 bool ScanSystemData::Init()
103 {
104     {
105         std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
106         addedScannerMap_.clear();
107     }
108     std::ifstream ifs(SCANNER_LIST_FILE.c_str(), std::ios::in | std::ios::binary);
109     if (!ifs.is_open()) {
110         SCAN_HILOGW("open scanner list file fail");
111         return false;
112     }
113     Json::Value jsonObject;
114     if (!Print::PrintJsonUtil::ParseFromStream(ifs, jsonObject)) {
115         SCAN_HILOGW("json accept fail");
116         return false;
117     }
118     ifs.close();
119     if (!Print::PrintJsonUtil::IsMember(jsonObject, "version") || !jsonObject["version"].isString()) {
120         SCAN_HILOGW("can not find version");
121         return false;
122     }
123     std::string version = jsonObject["version"].asString();
124     SCAN_HILOGI("json version: %{public}s", version.c_str());
125     if (version == SCANNER_LIST_VERSION && ParseScannerListJsonV1(jsonObject)) {
126         RefreshUsbDeviceId();
127         SaveScannerMap();
128         return true;
129     }
130     return false;
131 }
132 
RefreshUsbDeviceId()133 void ScanSystemData::RefreshUsbDeviceId()
134 {
135     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
136     auto usbIt = ScanUsbManager::GetInstance();
137     if (usbIt == nullptr) {
138         SCAN_HILOGE("usbIt is a nullptr.");
139         return;
140     }
141     usbIt->RefreshUsbDevicePort(usbSnToPortMap_);
142     if (usbSnToPortMap_.empty()) {
143         SCAN_HILOGW("usbSnToPortMap_ is empty");
144         return;
145     }
146     for (auto &scanDevIt : addedScannerMap_) {
147         std::string discoverMode = scanDevIt.second->discoverMode;
148         if (discoverMode != "USB") {
149             continue;
150         }
151         std::string serialNumber = scanDevIt.second->serialNumber;
152         auto it = usbSnToPortMap_.find(serialNumber);
153         if (it == usbSnToPortMap_.end()) {
154             continue;
155         }
156         std::string oldDeviceId = scanDevIt.second->deviceId;
157         std::string usbPort = it->second;
158         std::string newDeviceId = ReplaceDeviceIdUsbPort(oldDeviceId, usbPort);
159         if (newDeviceId == "" || newDeviceId == oldDeviceId) {
160             SCAN_HILOGD("cannot update usb deviceId.");
161             continue;
162         }
163         scanDevIt.second->deviceId = newDeviceId;
164         ScanDeviceInfoSync syncInfo;
165         syncInfo.deviceId = newDeviceId;
166         syncInfo.serialNumber = serialNumber;
167         syncInfo.oldDeviceId = oldDeviceId;
168         syncInfo.discoverMode = "USB";
169         auto saPtr = ScanServiceAbility::GetInstance();
170         if (saPtr == nullptr) {
171             SCAN_HILOGE("saPtr is a nullptr");
172             return;
173         }
174         saPtr->UpdateScannerId(syncInfo);
175     }
176 }
177 
ReplaceDeviceIdUsbPort(const std::string & deviceId,const std::string & usbPort)178 std::string ScanSystemData::ReplaceDeviceIdUsbPort(const std::string& deviceId, const std::string& usbPort)
179 {
180     constexpr int32_t invalidPort = -1;
181     int32_t start = invalidPort;
182     int32_t end = invalidPort;
183     char dash;
184     std::istringstream(usbPort) >> start >> dash >> end;
185     if (start < 0 || end < 0 || dash != '-') {
186         SCAN_HILOGE("usbPort format is error");
187         return "";
188     }
189     std::ostringstream oss;
190     char zero = '0';
191     constexpr int32_t portWidth = 3;
192     oss << std::setw(portWidth) << std::setfill(zero) << start;
193     std::string formattedStart = oss.str();
194     oss.str("");
195     oss << std::setw(portWidth) << std::setfill(zero) << end;
196     std::string formattedEnd = oss.str();
197     size_t pos1 = deviceId.rfind(':');
198     if (pos1 == std::string::npos) {
199         SCAN_HILOGE("deviceId format is error");
200         return "";
201     }
202     size_t pos2 = deviceId.rfind(':', pos1 - 1);
203     if (pos2 == std::string::npos) {
204         SCAN_HILOGE("deviceId format is error");
205         return "";
206     }
207     std::string newDeviceId = deviceId.substr(0, pos2 + 1).append(formattedStart).append(":").append(formattedEnd);
208     SCAN_HILOGD("new deviceId = %{private}s", newDeviceId.c_str());
209     return newDeviceId;
210 }
211 
UpdateScannerIdByUsbDevicePort(const std::string & uniqueId,const std::string & usbDevicePort)212 bool ScanSystemData::UpdateScannerIdByUsbDevicePort(const std::string &uniqueId, const std::string &usbDevicePort)
213 {
214     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
215     auto iter = addedScannerMap_.find(uniqueId);
216     if (iter != addedScannerMap_.end() && iter->second != nullptr) {
217         std::string oldDeviceId = iter->second->deviceId;
218         std::string newDeviceId = ReplaceDeviceIdUsbPort(oldDeviceId, usbDevicePort);
219         SCAN_HILOGD("newDeviceId : %{private}s", newDeviceId.c_str());
220         if (newDeviceId == "" || newDeviceId == oldDeviceId) {
221             SCAN_HILOGD("cannot update usb deviceId.");
222             return false;
223         }
224         iter->second->deviceId = newDeviceId;
225     } else {
226         SCAN_HILOGE("ScanSystemData UpdateScannerIdByUsbDevicePort fail");
227         return false;
228     }
229     return true;
230 }
231 
InsertScannerInfo(const std::string & uniqueId,const ScanDeviceInfo & scannerInfo)232 void ScanSystemData::InsertScannerInfo(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo)
233 {
234     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
235     auto iter = addedScannerMap_.find(uniqueId);
236     if (iter == addedScannerMap_.end() || iter->second == nullptr) {
237         SCAN_HILOGI("insert new scanner");
238         addedScannerMap_[uniqueId] = std::make_shared<ScanDeviceInfo>(scannerInfo);
239     } else {
240         SCAN_HILOGI("update exist scanner");
241         *iter->second = scannerInfo;
242     }
243 }
244 
DeleteScannerInfo(const std::string & uniqueId)245 bool ScanSystemData::DeleteScannerInfo(const std::string &uniqueId)
246 {
247     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
248     auto iter = addedScannerMap_.find(uniqueId);
249     if (iter != addedScannerMap_.end()) {
250         addedScannerMap_.erase(uniqueId);
251     } else {
252         SCAN_HILOGE("ScanSystemData delete connected scanner fail");
253         return false;
254     }
255     return true;
256 }
257 
UpdateScannerNameByUniqueId(const std::string & uniqueId,const std::string & deviceName)258 bool ScanSystemData::UpdateScannerNameByUniqueId(const std::string &uniqueId, const std::string &deviceName)
259 {
260     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
261     auto iter = addedScannerMap_.find(uniqueId);
262     if (iter != addedScannerMap_.end() && iter->second != nullptr) {
263         iter->second->deviceName = deviceName;
264     } else {
265         SCAN_HILOGW("ScanSystemData UpdateScannerNameByUniqueId fail");
266         return false;
267     }
268     return true;
269 }
270 
UpdateScannerInfoByUniqueId(const std::string & uniqueId,const ScanDeviceInfo & scannerInfo)271 bool ScanSystemData::UpdateScannerInfoByUniqueId(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo)
272 {
273     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
274     auto iter = addedScannerMap_.find(uniqueId);
275     if (iter != addedScannerMap_.end()) {
276         *iter->second = scannerInfo;
277         return true;
278     }
279     SCAN_HILOGE("ScanSystemData UpdateScannerInfoByUniqueId not found scannerInfo");
280     return false;
281 }
282 
QueryScannerNameByUniqueId(const std::string & uniqueId,std::string & deviceName)283 bool ScanSystemData::QueryScannerNameByUniqueId(const std::string &uniqueId, std::string &deviceName)
284 {
285     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
286     auto iter = addedScannerMap_.find(uniqueId);
287     if (iter != addedScannerMap_.end()) {
288         deviceName = iter->second->deviceName;
289         return true;
290     }
291     SCAN_HILOGW("QueryScannerNameByUniqueId fail");
292     return false;
293 }
294 
QueryScannerInfoByUniqueId(const std::string & uniqueId,ScanDeviceInfo & scannerInfo)295 bool ScanSystemData::QueryScannerInfoByUniqueId(const std::string &uniqueId, ScanDeviceInfo &scannerInfo)
296 {
297     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
298     for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) {
299         auto info = iter->second;
300         if (info == nullptr) {
301             continue;
302         }
303         std::string iterSn = info->discoverMode + info->serialNumber;
304         std::string iterUniqueId = info->discoverMode + info->uniqueId;
305         if (uniqueId == iterSn || uniqueId == iterUniqueId) {
306             *iter->second = scannerInfo;
307             return true;
308         }
309     }
310     return false;
311 }
312 
GetAddedScannerInfoList(std::vector<ScanDeviceInfo> & infoList)313 void ScanSystemData::GetAddedScannerInfoList(std::vector<ScanDeviceInfo> &infoList)
314 {
315     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
316     for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) {
317         if (iter->second != nullptr) {
318             infoList.push_back(*(iter->second));
319         }
320     }
321 }
322 
SaveScannerMap()323 bool ScanSystemData::SaveScannerMap()
324 {
325     FILE *file = fopen(SCANNER_LIST_FILE.c_str(), "w+");
326     if (file == nullptr) {
327         SCAN_HILOGW("Failed to open file errno: %{public}u", errno);
328         return false;
329     }
330     Json::Value scannerMapJson;
331     {
332         std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
333         for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) {
334             auto info = iter->second;
335             if (info == nullptr) {
336                 continue;
337             }
338             Json::Value scannerJson;
339             scannerJson["deviceId"] = info->deviceId;
340             scannerJson["manufacturer"] = info->manufacturer;
341             scannerJson["model"] = info->model;
342             scannerJson["deviceType"] = info->deviceType;
343             scannerJson["discoverMode"] = info->discoverMode;
344             scannerJson["serialNumber"] = info->serialNumber;
345             scannerJson["deviceName"] = info->deviceName;
346             scannerJson["uniqueId"] = info->uniqueId;
347             scannerJson["uuid"] = info->uuid;
348             scannerMapJson.append(scannerJson);
349         }
350     }
351     Json::Value jsonObject;
352     jsonObject["version"] = SCANNER_LIST_VERSION;
353     jsonObject["scaner_list"] = scannerMapJson;
354     std::string jsonString = Print::PrintJsonUtil::WriteString(jsonObject);
355     size_t jsonLength = jsonString.length();
356     size_t writeLength = fwrite(jsonString.c_str(), 1, jsonLength, file);
357     int fcloseResult = fclose(file);
358     if (fcloseResult != 0) {
359         SCAN_HILOGE("File Operation Failure.");
360         return false;
361     }
362     SCAN_HILOGI("SaveScannerMap finished");
363     if (writeLength < 0) {
364         SCAN_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
365         return false;
366     }
367 
368     return writeLength == jsonLength;
369 }
370 
IsContainScanner(const std::string & uniqueId)371 bool ScanSystemData::IsContainScanner(const std::string &uniqueId)
372 {
373     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
374     if (addedScannerMap_.find(uniqueId) != addedScannerMap_.end()) {
375         SCAN_HILOGI("The map contains the scanner.");
376         return true;
377     } else {
378         SCAN_HILOGW("The scanner is not included in the map.");
379         return false;
380     }
381 }
382 
UpdateNetScannerByUuid(const std::string & uuid,const std::string & ip)383 std::pair<std::string, std::string> ScanSystemData::UpdateNetScannerByUuid(const std::string &uuid,
384     const std::string& ip)
385 {
386     std::string oldKey;
387     std::shared_ptr<ScanDeviceInfo> scannerInfo;
388     std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
389     for (const auto& [key, info] : addedScannerMap_) {
390         if (info != nullptr && !info->uuid.empty() && info->uuid == uuid) {
391             oldKey = key;
392             scannerInfo = info;
393             break;
394         }
395     }
396     if (oldKey == "" || scannerInfo == nullptr) {
397         SCAN_HILOGE("Cannot find scanner by uuid");
398         return std::make_pair("", "");
399     }
400     std::string oldDeviceId = scannerInfo->deviceId;
401     std::string newDeviceId = ScanUtil::ReplaceIpAddress(oldDeviceId, ip);
402     if (newDeviceId == scannerInfo->deviceId) {
403         SCAN_HILOGE("Get new device Id fail.");
404         return std::make_pair("", "");
405     }
406     SCAN_HILOGD("newdeviceId = %{private}s", newDeviceId.c_str());
407     addedScannerMap_.erase(oldKey);
408     std::string newKey = "TCP" + ip;
409     scannerInfo->deviceId = newDeviceId;
410     scannerInfo->uniqueId = ip;
411     auto it = addedScannerMap_.find(newKey);
412     if (it == addedScannerMap_.end()) {
413         addedScannerMap_.insert(std::make_pair(newKey, scannerInfo));
414     } else {
415         it->second = scannerInfo;
416     }
417     return std::make_pair(oldDeviceId, newDeviceId);
418 }
419 
420 }  // namespace Scan
421 }  // namespace OHOS