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