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