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
29 namespace OHOS::Scan {
30 using namespace OHOS;
31 using namespace OHOS::USB;
32
ScanUsbManager()33 ScanUsbManager::ScanUsbManager()
34 {}
35
~ScanUsbManager()36 ScanUsbManager::~ScanUsbManager()
37 {}
38
Init()39 void ScanUsbManager::Init()
40 {
41 if (isInit) {
42 return;
43 }
44 SCAN_HILOGI("listen usb device attach detach");
45 EventFwk::MatchingSkills matchingSkills;
46 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USB_DEVICE_ATTACHED);
47 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USB_DEVICE_DETACHED);
48 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
49 subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
50
51 usbDevStatusListener = std::make_shared<ScanEventSubscriber>(subscribeInfo);
52 if (!EventFwk::CommonEventManager::SubscribeCommonEvent(usbDevStatusListener)) {
53 SCAN_HILOGE("subscribe common event failed");
54 return;
55 }
56 isInit = true;
57 }
58
RefreshUsbDevice()59 void ScanUsbManager::RefreshUsbDevice()
60 {
61 SCAN_HILOGI("RefreshDeviceList start");
62 std::vector<UsbDevice> devlist;
63 auto &UsbSrvClient = UsbSrvClient::GetInstance();
64 auto ret = UsbSrvClient.GetDevices(devlist);
65 if (ret != ERR_OK) {
66 SCAN_HILOGE("RefreshDeviceList GetDevices failed with ret = %{public}d.", ret);
67 return;
68 }
69 SCAN_HILOGI("RefreshDeviceList DeviceList size = %{public}zu.", devlist.size());
70 for (auto dev : devlist) {
71 std::string serialNumber = GetSerialNumber(dev);
72 if (serialNumber == "") {
73 SCAN_HILOGW("Seria number is empty.");
74 continue;
75 }
76 SCAN_HILOGI("RefreshDeviceList serialNumber = %{private}s.", serialNumber.c_str());
77 std::string devicePort = dev.GetName();
78 std::regex pattern("\\d+-\\d+");
79 if (std::regex_match(devicePort, pattern)) {
80 SCAN_HILOGI("RefreshDeviceList dev.GetName() %{private}s ", devicePort.c_str());
81 ScanServiceAbility::usbSnMap[devicePort] = serialNumber;
82 } else {
83 SCAN_HILOGW("Incorrect port number format.");
84 }
85 }
86 }
87
RefreshUsbDevicePort()88 void ScanUsbManager::RefreshUsbDevicePort()
89 {
90 SCAN_HILOGI("RefreshUsbDevicePort start");
91 ScanSystemData::usbSnToPortMap_.clear();
92 std::vector<UsbDevice> devlist;
93 auto &UsbSrvClient = UsbSrvClient::GetInstance();
94 auto ret = UsbSrvClient.GetDevices(devlist);
95 if (ret != ERR_OK) {
96 SCAN_HILOGE("RefreshUsbDevicePort GetDevices failed with ret = %{public}d.", ret);
97 return;
98 }
99 SCAN_HILOGI("RefreshUsbDevicePort DeviceList size = %{public}zu.", devlist.size());
100 for (auto dev : devlist) {
101 SCAN_HILOGI("RefreshUsbDevicePort dev.GetName() %{private}s ", dev.GetName().c_str());
102 std::string serialNumber = GetSerialNumber(dev);
103 if (serialNumber == "") {
104 SCAN_HILOGW("Seria number is empty.");
105 continue;
106 }
107 SCAN_HILOGI("RefreshUsbDevicePort serialNumber = %{private}s.", serialNumber.c_str());
108 std::string devicePort = dev.GetName();
109 std::regex pattern("\\d+-\\d+");
110 if (std::regex_match(devicePort, pattern)) {
111 ScanSystemData::usbSnToPortMap_[serialNumber] = devicePort;
112 } else {
113 SCAN_HILOGW("Incorrect port number format.");
114 }
115 }
116 }
117
GetSerialNumber(UsbDevice & usbDevice)118 std::string ScanUsbManager::GetSerialNumber(UsbDevice &usbDevice)
119 {
120 auto &UsbSrvClient = UsbSrvClient::GetInstance();
121 SCAN_HILOGI("getSerialNumber dev.GetName() = %{public}s.", usbDevice.GetName().c_str());
122 USBDevicePipe usbDevicePipe;
123 int32_t openDeviceRet = UsbSrvClient.OpenDevice(usbDevice, usbDevicePipe);
124 if (openDeviceRet != UEC_OK) {
125 SCAN_HILOGE("openDevice fail with ret = %{public}d", openDeviceRet);
126 return "";
127 }
128 SCAN_HILOGI("openDevice ret = %{public}d", openDeviceRet);
129 std::string serialNumber = GetDeviceSerialNumber(usbDevicePipe);
130 return serialNumber;
131 }
132
GetDeviceSerialNumber(USBDevicePipe & usbDevicePipe)133 std::string ScanUsbManager::GetDeviceSerialNumber(USBDevicePipe &usbDevicePipe)
134 {
135 auto &UsbSrvClient = UsbSrvClient::GetInstance();
136 SCAN_HILOGI("Enter GetDeviceSerialNumber");
137 uint16_t indexInStringDescriptor = USB_VALUE_DESCRIPTOR_INDEX_SERIAL_NUMBER;
138 uint8_t requestType = USB_REQUESTTYPE_DEVICE_TO_HOST;
139 uint8_t request = USB_REQUEST_GET_DESCRIPTOR;
140 uint16_t value = (USB_VALUE_DESCRIPTOR_TYPE_STRING << HTTP_COMMON_CONST_VALUE_8) | indexInStringDescriptor;
141 uint16_t index = USB_INDEX_LANGUAGE_ID_ENGLISH;
142 int32_t timeOut = HTTP_COMMON_CONST_VALUE_500;
143 const HDI::Usb::V1_0::UsbCtrlTransfer tctrl = {requestType, request, value, index, timeOut};
144 std::vector<uint8_t> bufferData(HTTP_COMMON_CONST_VALUE_100, 0);
145 int32_t ret = UsbSrvClient.ControlTransfer(usbDevicePipe, tctrl, bufferData);
146 if (ret != 0 || bufferData[0] == 0) {
147 SCAN_HILOGE("ControlTransfer failed ret = %{public}d, buffer length = %{public}d", ret, bufferData[0]);
148 return "";
149 }
150
151 std::vector<uint8_t> arr((bufferData[0] - HTTP_COMMON_CONST_VALUE_2) / HTTP_COMMON_CONST_VALUE_2);
152 int arrIndex = 0;
153 for (int i = 2; i < bufferData[0];) {
154 arr[arrIndex++] = bufferData[i];
155 i += HTTP_COMMON_CONST_VALUE_2;
156 }
157 std::string scannerInfo(arr.begin(), arr.end());
158 SCAN_HILOGI("bufferData scanerInfo: %{public}s\n", scannerInfo.c_str());
159 return scannerInfo;
160 }
161
FormatUsbPort(std::string & port)162 void ScanUsbManager::FormatUsbPort(std::string &port)
163 {
164 for (auto size = port.size(); size < USB_DEVICEID_FIRSTID_LEN_3; size++) {
165 std::string newString = "0";
166 newString.append(port);
167 port = newString;
168 }
169 }
170
getNewDeviceId(std::string oldDeviceId,std::string usbDevicePort)171 std::string ScanUsbManager::getNewDeviceId(std::string oldDeviceId, std::string usbDevicePort)
172 {
173 std::string deviceIdHead = oldDeviceId.substr(0, oldDeviceId.find_last_of(":")
174 - USB_DEVICEID_FIRSTID_LEN_3);
175 std::string firstPort = usbDevicePort.substr(0, usbDevicePort.find("-"));
176 std::string secondPort = usbDevicePort.substr(usbDevicePort.find("-") + 1, usbDevicePort.size() - 1);
177 SCAN_HILOGI("firstPort = %{public}s, secondPort = %{public}s.",
178 firstPort.c_str(), secondPort.c_str());
179 FormatUsbPort(firstPort);
180 FormatUsbPort(secondPort);
181 return deviceIdHead + firstPort + ":" + secondPort;
182 }
183
UpdateUsbScannerId(std::string serialNumber,std::string usbDevicePort)184 void ScanUsbManager::UpdateUsbScannerId(std::string serialNumber, std::string usbDevicePort)
185 {
186 if (serialNumber.empty() || usbDevicePort.empty()) {
187 SCAN_HILOGE("UpdateUsbScannerId serialNumber or usbDevicePort is null.");
188 return;
189 }
190 std::string uniqueId = "USB" + serialNumber;
191 if (ScanSystemData::GetInstance().UpdateScannerIdByUsbDevicePort(uniqueId, usbDevicePort)) {
192 if (!ScanSystemData::GetInstance().SaveScannerMap()) {
193 SCAN_HILOGW("Failed to update the Json file.");
194 }
195 }
196 auto it = ScanServiceAbility::saneGetUsbDeviceInfoMap.find(serialNumber);
197 if (it != ScanServiceAbility::saneGetUsbDeviceInfoMap.end()) {
198 SCAN_HILOGD("DealUsbDevStatusChange attached find out usbDevicePort = %{private}s, deviceId = %{private}s.",
199 usbDevicePort.c_str(), it->second.deviceId.c_str());
200 std::string newDeviceId = getNewDeviceId(it->second.deviceId, usbDevicePort);
201 ScanDeviceInfoSync syncInfo;
202 syncInfo.deviceId = newDeviceId;
203 syncInfo.serialNumber = serialNumber;
204 syncInfo.oldDeviceId = it->second.deviceId;
205 syncInfo.discoverMode = "USB";
206 syncInfo.syncMode = "update";
207 ScanServiceAbility::GetInstance()->UpdateScannerId(syncInfo);
208 for (auto &t : ScanServiceAbility::usbSnMap) {
209 if (t.second == serialNumber) {
210 SCAN_HILOGD("UpdateUsbScannerId usbSnMap erase %{private}s.", t.first.c_str());
211 ScanServiceAbility::usbSnMap.erase(t.first);
212 break;
213 }
214 }
215 ScanServiceAbility::usbSnMap[usbDevicePort] = serialNumber;
216 } else {
217 SCAN_HILOGD("DealUsbDevStatusChange attached find out usbDevicePort = %{private}s. "
218 "No matched device in saneGetUsbDeviceInfoMap.", usbDevicePort.c_str());
219 ScanServiceAbility::GetInstance()->GetScannerList();
220 }
221 }
222
DisConnectUsbScanner(std::string usbDevicePort)223 void ScanUsbManager::DisConnectUsbScanner(std::string usbDevicePort)
224 {
225 if (usbDevicePort.empty()) {
226 SCAN_HILOGE("DisConnectUsbScanner usbDevicePort is null.");
227 return;
228 }
229 auto usbSnMapit = ScanServiceAbility::usbSnMap.find(usbDevicePort);
230 if (usbSnMapit != ScanServiceAbility::usbSnMap.end()) {
231 std::string serialNumber = usbSnMapit->second;
232 if (!serialNumber.empty()) {
233 auto it = ScanServiceAbility::saneGetUsbDeviceInfoMap.find(serialNumber);
234 if (it != ScanServiceAbility::saneGetUsbDeviceInfoMap.end()) {
235 ScanServiceAbility::GetInstance()->DisConnectUsbScanner(serialNumber, it->second.deviceId);
236 ScanServiceAbility::usbSnMap.erase(usbDevicePort);
237 }
238 }
239 #ifdef DEBUG_ENABLE
240 SCAN_HILOGD("DealUsbDevStatusChange detached usbDevicePort = %{public}s, serialNumber = %{public}s. end",
241 usbDevicePort.c_str(), serialNumber.c_str());
242 #endif
243 }
244 }
245
DealUsbDevStatusChange(const std::string & devStr,bool isAttach)246 void ScanUsbManager::DealUsbDevStatusChange(const std::string &devStr, bool isAttach)
247 {
248 SCAN_HILOGD("DealUsbDevStatusChange isAttach = %{public}d, devStr = %{public}s.",
249 isAttach, devStr.c_str());
250 cJSON *devJson = cJSON_Parse(devStr.c_str());
251 if (!devJson) {
252 SCAN_HILOGE("Create devJson error");
253 return;
254 }
255 UsbDevice *dev = new UsbDevice(devJson);
256 std::string usbDevicePort = dev->GetName();
257 if (!isAttach) {
258 DisConnectUsbScanner(usbDevicePort);
259 } else {
260 std::string serialNumber = GetSerialNumber(*dev);
261 if (!serialNumber.empty()) {
262 UpdateUsbScannerId(serialNumber, usbDevicePort);
263 }
264 }
265 cJSON_Delete(devJson);
266 delete dev;
267 dev = nullptr;
268 }
269
270 }