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