1 /*
2 * Copyright (c) 2023 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 <regex>
17 #include "scan_log.h"
18 #include "usb_errors.h"
19 #include "scan_constant.h"
20 #include "scan_service_ability.h"
21 #include "cJSON.h"
22 #include "common_event_data.h"
23 #include "common_event_manager.h"
24 #include "common_event_support.h"
25 #include "scan_system_data.h"
26 #include "scan_usb_manager.h"
27 #include "scanner_info.h"
28 #include "scan_service_utils.h"
29 #include "scan_util.h"
30
31 namespace OHOS::Scan {
32 using namespace OHOS;
33 using namespace OHOS::USB;
34
ScanUsbManager()35 ScanUsbManager::ScanUsbManager()
36 {}
37
~ScanUsbManager()38 ScanUsbManager::~ScanUsbManager()
39 {}
40
Init()41 void ScanUsbManager::Init()
42 {
43 if (isInit) {
44 return;
45 }
46 SCAN_HILOGI("listen usb device attach detach");
47 EventFwk::MatchingSkills matchingSkills;
48 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USB_DEVICE_ATTACHED);
49 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USB_DEVICE_DETACHED);
50 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
51 subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
52
53 usbDevStatusListener = std::make_shared<ScanEventSubscriber>(subscribeInfo);
54 if (!EventFwk::CommonEventManager::SubscribeCommonEvent(usbDevStatusListener)) {
55 SCAN_HILOGE("subscribe common event failed");
56 return;
57 }
58 RefreshUsbDevice();
59 isInit = true;
60 }
61
RefreshUsbDevice()62 void ScanUsbManager::RefreshUsbDevice()
63 {
64 SCAN_HILOGI("RefreshDeviceList start");
65 std::vector<UsbDevice> devlist;
66 auto &UsbSrvClient = UsbSrvClient::GetInstance();
67 auto ret = UsbSrvClient.GetDevices(devlist);
68 if (ret != ERR_OK) {
69 SCAN_HILOGE("RefreshDeviceList GetDevices failed with ret = %{public}d.", ret);
70 return;
71 }
72 std::lock_guard<std::mutex> autoLock(usbSnMapLock_);
73 usbSnMap_.clear();
74 SCAN_HILOGI("RefreshDeviceList DeviceList size = %{public}zu.", devlist.size());
75 for (auto& dev : devlist) {
76 std::string serialNumber = GetSerialNumber(dev);
77 if (serialNumber.empty()) {
78 SCAN_HILOGW("Seria number is empty, port = %{private}s", dev.GetName().c_str());
79 continue;
80 }
81 SCAN_HILOGD("RefreshDeviceList serialNumber = %{private}s.", serialNumber.c_str());
82 std::string devicePort = dev.GetName();
83 dev.SetmSerial(serialNumber);
84 usbSnMap_[devicePort] = dev;
85 }
86 }
87
GetScannerNameBySn(const std::string & serialNumber)88 std::string ScanUsbManager::GetScannerNameBySn(const std::string& serialNumber)
89 {
90 std::lock_guard<std::mutex> autoLock(usbSnMapLock_);
91 for (const auto& [port, device] : usbSnMap_) {
92 std::string sn = device.GetmSerial();
93 if (serialNumber == sn) {
94 std::ostringstream oss;
95 oss << "USB-" << device.GetManufacturerName() << " " << device.GetProductName() << "-";
96 constexpr int32_t INDEX_SIX = 6;
97 if (serialNumber.size() <= INDEX_SIX) {
98 oss << serialNumber;
99 } else {
100 oss << serialNumber.substr(serialNumber.size() - INDEX_SIX);
101 }
102 return oss.str();
103 }
104 }
105 return "";
106 }
107
GetSerialNumber(UsbDevice & usbDevice)108 std::string ScanUsbManager::GetSerialNumber(UsbDevice &usbDevice)
109 {
110 auto &UsbSrvClient = UsbSrvClient::GetInstance();
111 SCAN_HILOGI("getSerialNumber dev.GetName() = %{public}s.", usbDevice.GetName().c_str());
112 USBDevicePipe usbDevicePipe;
113 int32_t openDeviceRet = UsbSrvClient.OpenDevice(usbDevice, usbDevicePipe);
114 if (openDeviceRet != UEC_OK) {
115 SCAN_HILOGE("openDevice fail with ret = %{public}d", openDeviceRet);
116 return "";
117 }
118 std::string serialNumber = GetDeviceSerialNumber(usbDevicePipe);
119 bool closeDeviceRet = UsbSrvClient.Close(usbDevicePipe);
120 SCAN_HILOGD("openDevice ret = %{public}d", closeDeviceRet);
121 size_t pos = serialNumber.find_last_not_of('\0');
122 size_t newSize = (pos == std::string::npos) ? 0 : pos + 1;
123 serialNumber.resize(newSize);
124 return serialNumber;
125 }
126
GetDeviceSerialNumber(USBDevicePipe & usbDevicePipe)127 std::string ScanUsbManager::GetDeviceSerialNumber(USBDevicePipe &usbDevicePipe)
128 {
129 auto &UsbSrvClient = UsbSrvClient::GetInstance();
130 uint16_t indexInStringDescriptor = USB_VALUE_DESCRIPTOR_INDEX_SERIAL_NUMBER;
131 uint8_t requestType = USB_REQUESTTYPE_DEVICE_TO_HOST;
132 uint8_t request = USB_REQUEST_GET_DESCRIPTOR;
133 uint16_t value = (USB_VALUE_DESCRIPTOR_TYPE_STRING << HTTP_COMMON_CONST_VALUE_8) | indexInStringDescriptor;
134 uint16_t index = USB_INDEX_LANGUAGE_ID_ENGLISH;
135 int32_t timeOut = HTTP_COMMON_CONST_VALUE_500;
136 const HDI::Usb::V1_0::UsbCtrlTransfer tctrl = {requestType, request, value, index, timeOut};
137 std::vector<uint8_t> bufferData(HTTP_COMMON_CONST_VALUE_100, 0);
138 int32_t ret = UsbSrvClient.ControlTransfer(usbDevicePipe, tctrl, bufferData);
139 if (ret != 0 || bufferData[0] == 0) {
140 SCAN_HILOGE("ControlTransfer failed ret = %{public}d, buffer length = %{public}d", ret, bufferData[0]);
141 return "";
142 }
143
144 std::vector<uint8_t> arr((bufferData[0] - HTTP_COMMON_CONST_VALUE_2) / HTTP_COMMON_CONST_VALUE_2);
145 int arrIndex = 0;
146 for (int i = 2; i < bufferData[0];) {
147 arr[arrIndex++] = bufferData[i];
148 i += HTTP_COMMON_CONST_VALUE_2;
149 }
150 std::string serialNumber(arr.begin(), arr.end());
151 return serialNumber;
152 }
153
GetSerialNumberByPort(const std::string & port)154 std::string ScanUsbManager::GetSerialNumberByPort(const std::string& port)
155 {
156 std::lock_guard<std::mutex> autoLock(usbSnMapLock_);
157 auto it = usbSnMap_.find(port);
158 if (it == usbSnMap_.end()) {
159 SCAN_HILOGW("Cannot find sn by %{public}s", port.c_str());
160 return "";
161 }
162 return it->second.GetmSerial();
163 }
164
GetPortBySerialNumber(const std::string & serialNumber)165 std::string ScanUsbManager::GetPortBySerialNumber(const std::string& serialNumber)
166 {
167 std::lock_guard<std::mutex> autoLock(usbSnMapLock_);
168 for (const auto& [port, device] : usbSnMap_) {
169 if (serialNumber == device.GetmSerial()) {
170 return port;
171 }
172 }
173 return "";
174 }
175
IsDeviceAvailable(const std::string & firstId,const std::string & secondId)176 bool ScanUsbManager::IsDeviceAvailable(const std::string& firstId, const std::string& secondId)
177 {
178 int32_t busNum = 0;
179 int32_t devAddr = 0;
180 if (!ScanUtil::ConvertToInt(firstId, busNum) || !ScanUtil::ConvertToInt(secondId, devAddr)) {
181 SCAN_HILOGE("[%{public}s][%{public}s] format error", firstId.c_str(), secondId.c_str());
182 return false;
183 }
184 UsbDevice usbDevice;
185 usbDevice.SetBusNum(static_cast<uint8_t>(busNum));
186 usbDevice.SetDevAddr(static_cast<uint8_t>(devAddr));
187 USBDevicePipe usbDevicePipe;
188 auto &UsbSrvClient = UsbSrvClient::GetInstance();
189 int32_t openDeviceRet = UsbSrvClient.OpenDevice(usbDevice, usbDevicePipe);
190 if (openDeviceRet != UEC_OK) {
191 SCAN_HILOGE("openDevice fail with ret = %{public}d", openDeviceRet);
192 return false;
193 }
194 bool closeDeviceRet = UsbSrvClient.Close(usbDevicePipe);
195 SCAN_HILOGD("openDevice ret = %{public}d", closeDeviceRet);
196 return true;
197 }
198
UpdateUsbScannerId(std::string serialNumber,std::string usbDevicePort)199 void ScanUsbManager::UpdateUsbScannerId(std::string serialNumber, std::string usbDevicePort)
200 {
201 if (serialNumber.empty() || usbDevicePort.empty()) {
202 SCAN_HILOGE("UpdateUsbScannerId serialNumber or usbDevicePort is null.");
203 return;
204 }
205 std::string uniqueId = "USB" + serialNumber;
206 if (ScanSystemData::GetInstance().UpdateScannerIdByUsbDevicePort(uniqueId, usbDevicePort)) {
207 if (!ScanSystemData::GetInstance().SaveScannerMap()) {
208 SCAN_HILOGW("Failed to update the Json file.");
209 }
210 }
211 auto it = ScanServiceAbility::saneGetUsbDeviceInfoMap.find(serialNumber);
212 if (it != ScanServiceAbility::saneGetUsbDeviceInfoMap.end()) {
213 SCAN_HILOGD("DealUsbDevStatusChange attached find out usbDevicePort = %{private}s, deviceId = %{private}s.",
214 usbDevicePort.c_str(), it->second.deviceId.c_str());
215 std::string newDeviceId = ScanServiceUtils::ReplaceDeviceIdUsbPort(it->second.deviceId, usbDevicePort);
216 ScanDeviceInfoSync syncInfo;
217 syncInfo.deviceId = newDeviceId;
218 syncInfo.serialNumber = serialNumber;
219 syncInfo.oldDeviceId = it->second.deviceId;
220 syncInfo.discoverMode = "USB";
221 syncInfo.syncMode = "update";
222 ScanServiceAbility::GetInstance()->UpdateScannerId(syncInfo);
223 } else {
224 SCAN_HILOGD("DealUsbDevStatusChange attached find out usbDevicePort = %{private}s. "
225 "No matched device in saneGetUsbDeviceInfoMap.", usbDevicePort.c_str());
226 ScanServiceAbility::GetInstance()->GetScannerList();
227 }
228 }
229
DisConnectUsbScanner(std::string usbDevicePort)230 void ScanUsbManager::DisConnectUsbScanner(std::string usbDevicePort)
231 {
232 if (usbDevicePort.empty()) {
233 SCAN_HILOGD("DisConnectUsbScanner usbDevicePort is null.");
234 return;
235 }
236 std::lock_guard<std::mutex> autoLock(usbSnMapLock_);
237 auto usbSnMapit = usbSnMap_.find(usbDevicePort);
238 if (usbSnMapit != usbSnMap_.end()) {
239 std::string serialNumber = usbSnMapit->second.GetmSerial();
240 auto it = ScanServiceAbility::saneGetUsbDeviceInfoMap.find(serialNumber);
241 if (it != ScanServiceAbility::saneGetUsbDeviceInfoMap.end()) {
242 ScanServiceAbility::GetInstance()->DisConnectUsbScanner(serialNumber, it->second.deviceId);
243 }
244 usbSnMap_.erase(usbDevicePort);
245 SCAN_HILOGD("DealUsbDevStatusChange detached usbDevicePort = %{private}s, serialNumber = %{private}s",
246 usbDevicePort.c_str(), serialNumber.c_str());
247 }
248 }
249
ConnectUsbScanner(UsbDevice & device)250 void ScanUsbManager::ConnectUsbScanner(UsbDevice& device)
251 {
252 std::string serialNumber = GetSerialNumber(device);
253 if (serialNumber.empty()) {
254 SCAN_HILOGD("ConnectUsbScanner serialNumber is null.");
255 return;
256 }
257 std::string port = device.GetName();
258 UpdateUsbScannerId(serialNumber, port);
259 std::lock_guard<std::mutex> autoLock(usbSnMapLock_);
260 device.SetmSerial(serialNumber);
261 usbSnMap_.insert({port, device});
262 SCAN_HILOGD("ConnectUsbScanner usbDevicePort = %{private}s, serialNumber = %{private}s",
263 port.c_str(), serialNumber.c_str());
264 }
265
DealUsbDevStatusChange(const std::string & devStr,bool isAttach)266 void ScanUsbManager::DealUsbDevStatusChange(const std::string &devStr, bool isAttach)
267 {
268 SCAN_HILOGD("DealUsbDevStatusChange isAttach = %{public}d, devStr = %{public}s.",
269 isAttach, devStr.c_str());
270 cJSON *devJson = cJSON_Parse(devStr.c_str());
271 if (!devJson) {
272 SCAN_HILOGE("Create devJson error");
273 return;
274 }
275 UsbDevice *dev = new UsbDevice(devJson);
276 std::string usbDevicePort = dev->GetName();
277 if (!isAttach) {
278 DisConnectUsbScanner(usbDevicePort);
279 } else {
280 ConnectUsbScanner(*dev);
281 }
282 cJSON_Delete(devJson);
283 delete dev;
284 dev = nullptr;
285 }
286
287 }