• 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 #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 }