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