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_system_data.h"
24
25 namespace {
26 const std::string SCANNER_LIST_FILE = "/data/service/el2/public/print_service/sane/tmp/scanner_list.json";
27 const std::string SCANNER_LIST_VERSION = "v1";
28 } // namespace
29
30 namespace OHOS {
31 namespace Scan {
32 std::map<std::string, std::string> ScanSystemData::usbSnToPortMap_;
CheckJsonObjectValue(const nlohmann::json& object)33 bool ScanSystemData::CheckJsonObjectValue(const nlohmann::json& object)
34 {
35 const std::vector<std::string> keyList = {"deviceId", "manufacturer", "model", "deviceType",
36 "discoverMode", "serialNumber", "deviceName"};
37 for (auto key : keyList) {
38 if (!object.contains(key) || !object[key].is_string()) {
39 SCAN_HILOGW("can not find %{public}s", key.c_str());
40 return false;
41 }
42 }
43 return true;
44 }
45
ParseScannerListJsonV1(nlohmann::json& jsonObject)46 bool ScanSystemData::ParseScannerListJsonV1(nlohmann::json& jsonObject)
47 {
48 if (!jsonObject.contains("scaner_list") || !jsonObject["scaner_list"].is_array()) {
49 SCAN_HILOGW("can not find scaner_list");
50 return false;
51 }
52 for (auto &element : jsonObject["scaner_list"].items()) {
53 nlohmann::json object = element.value();
54 if (!CheckJsonObjectValue(object)) {
55 continue;
56 }
57 ScanDeviceInfo scanDeviceInfo;
58 scanDeviceInfo.deviceId = object["deviceId"];
59 scanDeviceInfo.manufacturer = object["manufacturer"];
60 scanDeviceInfo.model = object["model"];
61 scanDeviceInfo.deviceType = object["deviceType"];
62 scanDeviceInfo.discoverMode = object["discoverMode"];
63 scanDeviceInfo.serialNumber = object["serialNumber"];
64 scanDeviceInfo.deviceName = object["deviceName"];
65 std::string uniqueId = scanDeviceInfo.discoverMode + scanDeviceInfo.serialNumber;
66 InsertScannerInfo(uniqueId, scanDeviceInfo);
67 }
68 RefreshUsbDeviceId();
69 return true;
70 }
71
Init()72 bool ScanSystemData::Init()
73 {
74 addedScannerMap_.clear();
75 std::ifstream ifs(SCANNER_LIST_FILE.c_str(), std::ios::in | std::ios::binary);
76 if (!ifs.is_open()) {
77 SCAN_HILOGW("open scanner list file fail");
78 return false;
79 }
80 std::string fileData((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
81 ifs.close();
82 if (!nlohmann::json::accept(fileData)) {
83 SCAN_HILOGW("json accept fail");
84 return false;
85 }
86 nlohmann::json jsonObject = nlohmann::json::parse(fileData);
87 if (!jsonObject.contains("version") || !jsonObject["version"].is_string()) {
88 SCAN_HILOGW("can not find version");
89 return false;
90 }
91 std::string version = jsonObject["version"].get<std::string>();
92 SCAN_HILOGI("json version: %{public}s", version.c_str());
93 if (version == SCANNER_LIST_VERSION) {
94 return ParseScannerListJsonV1(jsonObject);
95 }
96 return false;
97 }
98
RefreshUsbDeviceId()99 void ScanSystemData::RefreshUsbDeviceId()
100 {
101 ScanUsbManager::GetInstance()->RefreshUsbDevicePort();
102 if (usbSnToPortMap_.empty()) {
103 SCAN_HILOGW("Failed to refresh the USB device.");
104 return;
105 }
106 for (auto &scanDevIt : addedScannerMap_) {
107 std::string discoverMode = scanDevIt.second->discoverMode;
108 if (discoverMode == "TCP") {
109 continue;
110 }
111 std::string serialNumber = scanDevIt.second->serialNumber;
112 auto it = usbSnToPortMap_.find(serialNumber);
113 if (it == usbSnToPortMap_.end()) {
114 continue;
115 }
116 std::string oldDeviceId = scanDevIt.second->deviceId;
117 std::string usbPort = it->second;
118 if (oldDeviceId.find_last_of(":") == std::string::npos ||
119 oldDeviceId.find_last_of(":") < USB_DEVICEID_FIRSTID_LEN_3 ||
120 usbPort.find("_") == std::string::npos) {
121 SCAN_HILOGE("oldDeviceId or usbPort string format fail");
122 return;
123 }
124 std::string newDeviceId = GetNewDeviceId(oldDeviceId, usbPort);
125 scanDevIt.second->deviceId = newDeviceId;
126 }
127 if (!SaveScannerMap()) {
128 SCAN_HILOGW("Failed to save the JSON file.");
129 }
130 }
131
GetNewDeviceId(std::string oldDeviceId, std::string usbDevicePort)132 std::string ScanSystemData::GetNewDeviceId(std::string oldDeviceId, std::string usbDevicePort)
133 {
134 std::string deviceIdHead = oldDeviceId.substr(0, oldDeviceId.find_last_of(":") - USB_DEVICEID_FIRSTID_LEN_3);
135 std::string firstPort = usbDevicePort.substr(0, usbDevicePort.find("-"));
136 std::string secondPort = usbDevicePort.substr(usbDevicePort.find("-") + 1, usbDevicePort.size() - 1);
137 SCAN_HILOGI("firstPort = %{public}s, secondPort = %{public}s.",
138 firstPort.c_str(), secondPort.c_str());
139 FormatUsbPort(firstPort);
140 FormatUsbPort(secondPort);
141 return deviceIdHead + firstPort + ":" + secondPort;
142 }
143
FormatUsbPort(std::string &port)144 void ScanSystemData::FormatUsbPort(std::string &port)
145 {
146 port.insert(0, USB_DEVICEID_FIRSTID_LEN_3 - port.size(), '0');
147 }
148
UpdateScannerIdByUsbDevicePort(const std::string &uniqueId, const std::string &usbDevicePort)149 bool ScanSystemData::UpdateScannerIdByUsbDevicePort(const std::string &uniqueId, const std::string &usbDevicePort)
150 {
151 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
152 auto iter = addedScannerMap_.find(uniqueId);
153 if (iter != addedScannerMap_.end()) {
154 std::string oldDeviceId = iter->second->deviceId;
155 if (oldDeviceId.find_last_of(":") == std::string::npos ||
156 oldDeviceId.find_last_of(":") < USB_DEVICEID_FIRSTID_LEN_3 ||
157 usbDevicePort.find("_") == std::string::npos) {
158 SCAN_HILOGE("oldDeviceId or usbPort string format fail");
159 return false;
160 }
161 std::string newDeviceId = GetNewDeviceId(oldDeviceId, usbDevicePort);
162 iter->second->deviceId = newDeviceId;
163 } else {
164 SCAN_HILOGE("ScanSystemData UpdateScannerIdByUsbDevicePort fail");
165 return false;
166 }
167 return true;
168 }
169
InsertScannerInfo(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo)170 void ScanSystemData::InsertScannerInfo(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo)
171 {
172 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
173 auto iter = addedScannerMap_.find(uniqueId);
174 if (iter == addedScannerMap_.end() || iter->second == nullptr) {
175 SCAN_HILOGI("insert new scanner");
176 addedScannerMap_[uniqueId] = std::make_shared<ScanDeviceInfo>(scannerInfo);
177 } else {
178 SCAN_HILOGI("update exist scanner");
179 iter->second->deviceId = scannerInfo.deviceId;
180 iter->second->manufacturer = scannerInfo.manufacturer;
181 iter->second->model = scannerInfo.model;
182 iter->second->deviceType = scannerInfo.deviceType;
183 iter->second->serialNumber = scannerInfo.serialNumber;
184 iter->second->deviceName = scannerInfo.deviceName;
185 }
186 }
187
DeleteScannerInfo(const std::string &uniqueId)188 bool ScanSystemData::DeleteScannerInfo(const std::string &uniqueId)
189 {
190 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
191 auto iter = addedScannerMap_.find(uniqueId);
192 if (iter != addedScannerMap_.end()) {
193 addedScannerMap_.erase(uniqueId);
194 } else {
195 SCAN_HILOGE("ScanSystemData delete connected scanner fail");
196 return false;
197 }
198 return true;
199 }
200
UpdateScannerNameByUniqueId(const std::string &uniqueId, const std::string &deviceName)201 bool ScanSystemData::UpdateScannerNameByUniqueId(const std::string &uniqueId, const std::string &deviceName)
202 {
203 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
204 auto iter = addedScannerMap_.find(uniqueId);
205 if (iter != addedScannerMap_.end() && iter->second != nullptr) {
206 iter->second->deviceName = deviceName;
207 } else {
208 SCAN_HILOGE("ScanSystemData UpdateScannerNameByUniqueId fail");
209 return false;
210 }
211 return true;
212 }
213
UpdateScannerInfoByUniqueId(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo)214 bool ScanSystemData::UpdateScannerInfoByUniqueId(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo)
215 {
216 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
217 auto iter = addedScannerMap_.find(uniqueId);
218 if (iter != addedScannerMap_.end()) {
219 iter->second->deviceId = scannerInfo.deviceId;
220 iter->second->model = scannerInfo.model;
221 iter->second->deviceType = scannerInfo.deviceType;
222 iter->second->serialNumber = scannerInfo.serialNumber;
223 iter->second->deviceName = scannerInfo.deviceName;
224 return true;
225 }
226 SCAN_HILOGE("ScanSystemData UpdateScannerInfoByUniqueId not found scannerInfo");
227 return false;
228 }
229
QueryScannerNameByUniqueId(const std::string &uniqueId, std::string &deviceName)230 bool ScanSystemData::QueryScannerNameByUniqueId(const std::string &uniqueId, std::string &deviceName)
231 {
232 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
233 auto iter = addedScannerMap_.find(uniqueId);
234 if (iter != addedScannerMap_.end()) {
235 deviceName = iter->second->deviceName;
236 return true;
237 }
238 SCAN_HILOGW("QueryScannerNameByUniqueId fail");
239 return false;
240 }
241
QueryScannerInfoByUniqueId(const std::string &uniqueId, ScanDeviceInfo &scannerInfo)242 bool ScanSystemData::QueryScannerInfoByUniqueId(const std::string &uniqueId, ScanDeviceInfo &scannerInfo)
243 {
244 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
245 for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) {
246 auto info = iter->second;
247 if (info == nullptr) {
248 continue;
249 }
250 std::string iterUniqueId = info->discoverMode + info->serialNumber;
251 if (uniqueId == iterUniqueId) {
252 scannerInfo.deviceId = info->deviceId;
253 scannerInfo.manufacturer = info->manufacturer;
254 scannerInfo.model = info->model;
255 scannerInfo.deviceType = info->deviceType;
256 scannerInfo.discoverMode = info->discoverMode;
257 scannerInfo.serialNumber = info->serialNumber;
258 scannerInfo.deviceName = info->deviceName;
259 return true;
260 }
261 }
262 return false;
263 }
264
GetAddedScannerInfoList(std::vector<ScanDeviceInfo> &infoList)265 void ScanSystemData::GetAddedScannerInfoList(std::vector<ScanDeviceInfo> &infoList)
266 {
267 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
268 for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) {
269 if (iter->second != nullptr) {
270 infoList.push_back(*(iter->second));
271 }
272 }
273 }
274
SaveScannerMap()275 bool ScanSystemData::SaveScannerMap()
276 {
277 int32_t fd = open(SCANNER_LIST_FILE.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0640);
278 SCAN_HILOGD("SaveScannerMap fd: %{public}d", fd);
279 if (fd < 0) {
280 SCAN_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
281 return false;
282 }
283 nlohmann::json scannerMapJson = nlohmann::json::array();
284 {
285 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
286 for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) {
287 auto info = iter->second;
288 if (info == nullptr) {
289 continue;
290 }
291 nlohmann::json scannerJson = nlohmann::json::object();
292 scannerJson["deviceId"] = info->deviceId;
293 scannerJson["manufacturer"] = info->manufacturer;
294 scannerJson["model"] = info->model;
295 scannerJson["deviceType"] = info->deviceType;
296 scannerJson["discoverMode"] = info->discoverMode;
297 scannerJson["serialNumber"] = info->serialNumber;
298 scannerJson["deviceName"] = info->deviceName;
299 scannerMapJson.push_back(scannerJson);
300 }
301 }
302 nlohmann::json jsonObject;
303 jsonObject["version"] = SCANNER_LIST_VERSION;
304 jsonObject["scaner_list"] = scannerMapJson;
305 std::string jsonString = jsonObject.dump();
306 size_t jsonLength = jsonString.length();
307 auto writeLength = write(fd, jsonString.c_str(), jsonLength);
308 close(fd);
309 fd = -1;
310 SCAN_HILOGI("SaveScannerMap finished");
311 if (writeLength < 0) {
312 return false;
313 }
314 return (size_t)writeLength == jsonLength;
315 }
316
IsContainScanner(const std::string &uniqueId)317 bool ScanSystemData::IsContainScanner(const std::string &uniqueId)
318 {
319 if (addedScannerMap_.find(uniqueId) != addedScannerMap_.end()) {
320 SCAN_HILOGI("The map contains the scanner.");
321 return true;
322 } else {
323 SCAN_HILOGW("The scanner is not included in the map.");
324 return false;
325 }
326 }
327 } // namespace Scan
328 } // namespace OHOS