• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(std::map<std::string,std::string> & usbSnToPortMap)88 void ScanUsbManager::RefreshUsbDevicePort(std::map<std::string, std::string> &usbSnToPortMap)
89 {
90     SCAN_HILOGI("RefreshUsbDevicePort start");
91     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         size_t newSize = serialNumber.find_last_not_of('\0') + 1;
104         serialNumber.resize(newSize);
105         if (serialNumber == "") {
106             SCAN_HILOGW("Seria number is empty.");
107             continue;
108         }
109         SCAN_HILOGI("RefreshUsbDevicePort serialNumber = %{private}s.", serialNumber.c_str());
110         std::string devicePort = dev.GetName();
111         std::regex pattern("\\d+-\\d+");
112         if (std::regex_match(devicePort, pattern)) {
113             usbSnToPortMap[serialNumber] = devicePort;
114         } else {
115             SCAN_HILOGW("Incorrect port number format.");
116         }
117     }
118 }
119 
GetSerialNumber(UsbDevice & usbDevice)120 std::string ScanUsbManager::GetSerialNumber(UsbDevice &usbDevice)
121 {
122     auto &UsbSrvClient = UsbSrvClient::GetInstance();
123     SCAN_HILOGI("getSerialNumber dev.GetName() = %{public}s.", usbDevice.GetName().c_str());
124     USBDevicePipe usbDevicePipe;
125     int32_t openDeviceRet = UsbSrvClient.OpenDevice(usbDevice, usbDevicePipe);
126     if (openDeviceRet != UEC_OK) {
127         SCAN_HILOGE("openDevice fail with ret = %{public}d", openDeviceRet);
128         return "";
129     }
130     SCAN_HILOGI("openDevice ret = %{public}d", openDeviceRet);
131     std::string serialNumber = GetDeviceSerialNumber(usbDevicePipe);
132     bool closeDeviceRet = UsbSrvClient.Close(usbDevicePipe);
133     SCAN_HILOGI("openDevice ret = %{public}d", closeDeviceRet);
134     return serialNumber;
135 }
136 
GetDeviceSerialNumber(USBDevicePipe & usbDevicePipe)137 std::string ScanUsbManager::GetDeviceSerialNumber(USBDevicePipe &usbDevicePipe)
138 {
139     auto &UsbSrvClient = UsbSrvClient::GetInstance();
140     SCAN_HILOGI("Enter GetDeviceSerialNumber");
141     uint16_t indexInStringDescriptor = USB_VALUE_DESCRIPTOR_INDEX_SERIAL_NUMBER;
142     uint8_t requestType = USB_REQUESTTYPE_DEVICE_TO_HOST;
143     uint8_t request = USB_REQUEST_GET_DESCRIPTOR;
144     uint16_t value = (USB_VALUE_DESCRIPTOR_TYPE_STRING << HTTP_COMMON_CONST_VALUE_8) | indexInStringDescriptor;
145     uint16_t index = USB_INDEX_LANGUAGE_ID_ENGLISH;
146     int32_t timeOut = HTTP_COMMON_CONST_VALUE_500;
147     const HDI::Usb::V1_0::UsbCtrlTransfer tctrl = {requestType, request, value, index, timeOut};
148     std::vector<uint8_t> bufferData(HTTP_COMMON_CONST_VALUE_100, 0);
149     int32_t ret = UsbSrvClient.ControlTransfer(usbDevicePipe, tctrl, bufferData);
150     if (ret != 0 || bufferData[0] == 0) {
151         SCAN_HILOGE("ControlTransfer failed ret = %{public}d, buffer length = %{public}d", ret, bufferData[0]);
152         return "";
153     }
154 
155     std::vector<uint8_t> arr((bufferData[0] - HTTP_COMMON_CONST_VALUE_2) / HTTP_COMMON_CONST_VALUE_2);
156     int arrIndex = 0;
157     for (int i = 2; i < bufferData[0];) {
158         arr[arrIndex++] = bufferData[i];
159         i += HTTP_COMMON_CONST_VALUE_2;
160     }
161     std::string scannerInfo(arr.begin(), arr.end());
162     SCAN_HILOGI("bufferData scanerInfo: %{public}s\n", scannerInfo.c_str());
163     return scannerInfo;
164 }
165 
FormatUsbPort(std::string & port)166 void ScanUsbManager::FormatUsbPort(std::string &port)
167 {
168     for (auto size = port.size(); size < USB_DEVICEID_FIRSTID_LEN_3; size++) {
169         std::string newString = "0";
170         newString.append(port);
171         port = newString;
172     }
173 }
174 
getNewDeviceId(std::string oldDeviceId,std::string usbDevicePort)175 std::string ScanUsbManager::getNewDeviceId(std::string oldDeviceId, std::string usbDevicePort)
176 {
177     std::string deviceIdHead = oldDeviceId.substr(0, oldDeviceId.find_last_of(":")
178                                                     - USB_DEVICEID_FIRSTID_LEN_3);
179     std::string firstPort = usbDevicePort.substr(0, usbDevicePort.find("-"));
180     std::string secondPort = usbDevicePort.substr(usbDevicePort.find("-") + 1, usbDevicePort.size() - 1);
181     SCAN_HILOGI("firstPort = %{public}s, secondPort = %{public}s.",
182                 firstPort.c_str(), secondPort.c_str());
183     FormatUsbPort(firstPort);
184     FormatUsbPort(secondPort);
185     return deviceIdHead + firstPort + ":" + secondPort;
186 }
187 
UpdateUsbScannerId(std::string serialNumber,std::string usbDevicePort)188 void ScanUsbManager::UpdateUsbScannerId(std::string serialNumber, std::string usbDevicePort)
189 {
190     if (serialNumber.empty() || usbDevicePort.empty()) {
191         SCAN_HILOGE("UpdateUsbScannerId serialNumber or usbDevicePort is null.");
192         return;
193     }
194     std::string uniqueId = "USB" + serialNumber;
195     if (ScanSystemData::GetInstance().UpdateScannerIdByUsbDevicePort(uniqueId, usbDevicePort)) {
196         if (!ScanSystemData::GetInstance().SaveScannerMap()) {
197             SCAN_HILOGW("Failed to update the Json file.");
198         }
199     }
200     auto it = ScanServiceAbility::saneGetUsbDeviceInfoMap.find(serialNumber);
201     if (it != ScanServiceAbility::saneGetUsbDeviceInfoMap.end()) {
202         SCAN_HILOGD("DealUsbDevStatusChange attached find out usbDevicePort = %{private}s, deviceId = %{private}s.",
203                     usbDevicePort.c_str(), it->second.deviceId.c_str());
204         std::string newDeviceId = getNewDeviceId(it->second.deviceId, usbDevicePort);
205         ScanDeviceInfoSync syncInfo;
206         syncInfo.deviceId = newDeviceId;
207         syncInfo.serialNumber = serialNumber;
208         syncInfo.oldDeviceId = it->second.deviceId;
209         syncInfo.discoverMode = "USB";
210         syncInfo.syncMode = "update";
211         ScanServiceAbility::GetInstance()->UpdateScannerId(syncInfo);
212         for (auto &t : ScanServiceAbility::usbSnMap) {
213             if (t.second == serialNumber) {
214                 SCAN_HILOGD("UpdateUsbScannerId usbSnMap erase %{private}s.", t.first.c_str());
215                 ScanServiceAbility::usbSnMap.erase(t.first);
216                 break;
217             }
218         }
219         ScanServiceAbility::usbSnMap[usbDevicePort] = serialNumber;
220     } else {
221         SCAN_HILOGD("DealUsbDevStatusChange attached find out usbDevicePort = %{private}s. "
222                     "No matched device in saneGetUsbDeviceInfoMap.", usbDevicePort.c_str());
223         ScanServiceAbility::GetInstance()->GetScannerList();
224     }
225 }
226 
DisConnectUsbScanner(std::string usbDevicePort)227 void ScanUsbManager::DisConnectUsbScanner(std::string usbDevicePort)
228 {
229     if (usbDevicePort.empty()) {
230         SCAN_HILOGE("DisConnectUsbScanner usbDevicePort is null.");
231         return;
232     }
233     auto usbSnMapit = ScanServiceAbility::usbSnMap.find(usbDevicePort);
234     if (usbSnMapit != ScanServiceAbility::usbSnMap.end()) {
235         std::string serialNumber = usbSnMapit->second;
236         if (!serialNumber.empty()) {
237             auto it = ScanServiceAbility::saneGetUsbDeviceInfoMap.find(serialNumber);
238             if (it != ScanServiceAbility::saneGetUsbDeviceInfoMap.end()) {
239                 ScanServiceAbility::GetInstance()->DisConnectUsbScanner(serialNumber, it->second.deviceId);
240                 ScanServiceAbility::usbSnMap.erase(usbDevicePort);
241             }
242         }
243 #ifdef DEBUG_ENABLE
244         SCAN_HILOGD("DealUsbDevStatusChange detached usbDevicePort = %{public}s, serialNumber = %{public}s. end",
245                     usbDevicePort.c_str(), serialNumber.c_str());
246 #endif
247     }
248 }
249 
DealUsbDevStatusChange(const std::string & devStr,bool isAttach)250 void ScanUsbManager::DealUsbDevStatusChange(const std::string &devStr, bool isAttach)
251 {
252     SCAN_HILOGD("DealUsbDevStatusChange isAttach = %{public}d, devStr = %{public}s.",
253                 isAttach, devStr.c_str());
254     cJSON *devJson = cJSON_Parse(devStr.c_str());
255     if (!devJson) {
256         SCAN_HILOGE("Create devJson error");
257         return;
258     }
259     UsbDevice *dev = new UsbDevice(devJson);
260     std::string usbDevicePort = dev->GetName();
261     if (!isAttach) {
262         DisConnectUsbScanner(usbDevicePort);
263     } else {
264         std::string serialNumber = GetSerialNumber(*dev);
265         size_t newSize = serialNumber.find_last_not_of('\0') + 1;
266         serialNumber.resize(newSize);
267         if (!serialNumber.empty()) {
268             UpdateUsbScannerId(serialNumber, usbDevicePort);
269         }
270     }
271     cJSON_Delete(devJson);
272     delete dev;
273     dev = nullptr;
274 }
275 
276 }