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