• 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 #ifdef IPPOVERUSB_ENABLE
17 #include "print_usb_manager.h"
18 #include "print_log.h"
19 #include "usb_errors.h"
20 #include "print_ipp_over_usb_util.h"
21 #include "cJSON.h"
22 
23 namespace OHOS::Print {
24 using namespace std;
25 using namespace OHOS;
26 using namespace OHOS::USB;
27 
PrintUsbManager()28 PrintUsbManager::PrintUsbManager()
29 {}
30 
~PrintUsbManager()31 PrintUsbManager::~PrintUsbManager()
32 {}
33 
Init()34 void PrintUsbManager::Init()
35 {
36     if (isInit) {
37         PRINT_HILOGD("has init");
38     }
39     isInit = true;
40     RefreshUsbPrinterDevice();
41 }
42 
isExistIppOverUsbPrinter(std::string printerName)43 bool PrintUsbManager::isExistIppOverUsbPrinter(std::string printerName)
44 {
45     PRINT_HILOGD("isExistIppOverUsbPrinter printerName = %{public}s", printerName.c_str());
46     if (!printerName.empty() && printDeviceMap.find(printerName) != printDeviceMap.end()) {
47         return true;
48     }
49     return false;
50 }
51 
52 
isPrintDevice(USB::UsbDevice & usbdevice,std::string & printerName)53 bool PrintUsbManager::isPrintDevice(USB::UsbDevice &usbdevice, std::string &printerName)
54 {
55     int32_t configCount = usbdevice.GetConfigCount();
56     std::vector<std::pair<int32_t, int32_t>> indexVec;
57     int32_t ippusbInterfaceCount = 0;
58     PRINT_HILOGD("name = %{public}s.", usbdevice.GetName().c_str());
59     for (int32_t configIndex = 0; configIndex < configCount; configIndex++) {
60         int32_t interfaceCount = static_cast<int32_t>(usbdevice.GetConfigs()[configIndex].GetInterfaceCount());
61         PRINT_HILOGD("configIndex = %{public}d.", configIndex);
62         for (int32_t interfaceIndex = 0; interfaceIndex < interfaceCount; interfaceIndex++) {
63             PRINT_HILOGD("interfaceIndex = %{public}d.", interfaceIndex);
64             UsbInterface usbInterface = usbdevice.GetConfigs()[configIndex].GetInterfaces()[interfaceIndex];
65             PRINT_HILOGD("isPrintDevice class = %{public}d, subclass = %{public}d, protocol = %{public}d",
66                 usbInterface.GetClass(), usbInterface.GetSubClass(), usbInterface.GetProtocol());
67             bool isSupportIpp = (usbInterface.GetClass() == USB_DEVICE_CLASS_PRINT &&
68                 usbInterface.GetSubClass() == USB_DEVICE_SUBCLASS_PRINT &&
69                 usbInterface.GetProtocol() == USB_DEVICE_PROTOCOL_PRINT);
70             if (isSupportIpp) {
71                 auto indexPair = std::make_pair(configIndex, interfaceIndex);
72                 indexVec.push_back(indexPair);
73                 ippusbInterfaceCount++;
74             }
75         }
76     }
77     // Two or more interfaces are required
78     if (ippusbInterfaceCount >= USB_INTERFACE_MIN_COUNT) {
79         printerName = GetProductName(usbdevice);
80         PRINT_HILOGI("support IppPrint printerName = %{public}s.", printerName.c_str());
81         if (printerName.empty()) {
82             return false;
83         }
84         printerIndexMap[printerName] = indexVec;
85         return true;
86     }
87     return false;
88 }
89 
RefreshUsbPrinterDevice()90 void PrintUsbManager::RefreshUsbPrinterDevice()
91 {
92     vector<UsbDevice> devlist;
93     auto &UsbSrvClient = UsbSrvClient::GetInstance();
94     auto ret = UsbSrvClient.GetDevices(devlist);
95     if (ERR_OK != ret) {
96         PRINT_HILOGE("RefreshDeviceList GetDevices failed with ret = %{public}d.", ret);
97         return;
98     } else if (devlist.empty()) {
99         PRINT_HILOGE("RefreshDeviceList GetDevices empty with ret = %{public}d.", ret);
100         return;
101     }
102     for (auto dev : devlist) {
103         std::string printerName;
104         if (isPrintDevice(dev, printerName)) {
105             printDeviceMap[printerName] = dev;
106         }
107     }
108 }
109 
GetProductName(UsbDevice & usbDevice)110 std::string PrintUsbManager::GetProductName(UsbDevice &usbDevice)
111 {
112     auto &UsbSrvClient = UsbSrvClient::GetInstance();
113     PRINT_HILOGI("getProductName dev.GetName() = %{public}s.", usbDevice.GetName().c_str());
114     USBDevicePipe usbDevicePipe;
115     int32_t openDeviceRet = UsbSrvClient.OpenDevice(usbDevice, usbDevicePipe);
116     PRINT_HILOGI("openDevice ret = %{public}d", openDeviceRet);
117     if (openDeviceRet != UEC_OK) {
118         PRINT_HILOGE("openDevice fail with ret = %{public}d", openDeviceRet);
119         return "";
120     }
121     std::string productName =
122         QueryPrinterInfoFromStringDescriptor(usbDevicePipe, USB_VALUE_DESCRIPTOR_INDEX_PRODUCT_NAME);
123     std::string serialNumber =
124         QueryPrinterInfoFromStringDescriptor(usbDevicePipe, USB_VALUE_DESCRIPTOR_INDEX_SERIAL_NUMBER);
125     std::string printerName =
126         productName + "-" + serialNumber.substr(serialNumber.length() - HTTP_COMMON_CONST_VALUE_4);
127     PRINT_HILOGI("getProductName printerName = %{public}s.", printerName.c_str());
128     return printerName;
129 }
130 
QueryPrinterInfoFromStringDescriptor(USBDevicePipe & usbDevicePipe,uint16_t indexInStringDescriptor)131 std::string PrintUsbManager::QueryPrinterInfoFromStringDescriptor(
132     USBDevicePipe &usbDevicePipe, uint16_t indexInStringDescriptor)
133 {
134     auto &UsbSrvClient = UsbSrvClient::GetInstance();
135     PRINT_HILOGI("enter QueryPrinterInfoFromStringDescriptor");
136     uint8_t requestType = USB_REQUESTTYPE_DEVICE_TO_HOST;
137     uint8_t request = USB_REQUEST_GET_DESCRIPTOR;
138     uint16_t value = (USB_VALUE_DESCRIPTOR_TYPE_STRING << HTTP_COMMON_CONST_VALUE_8) | indexInStringDescriptor;
139     uint16_t index = USB_INDEX_LANGUAGE_ID_ENGLISH;
140     int32_t timeOut = HTTP_COMMON_CONST_VALUE_500;
141     const HDI::Usb::V1_0::UsbCtrlTransfer tctrl = {requestType, request, value, index, timeOut};
142     std::vector<uint8_t> bufferData(HTTP_COMMON_CONST_VALUE_100, 0);
143     int32_t ret = UsbSrvClient.ControlTransfer(usbDevicePipe, tctrl, bufferData);
144     if (ret != 0 || bufferData[INDEX_0] == 0) {
145         PRINT_HILOGE("ControlTransfer failed ret = %{public}d, buffer length = %{public}d", ret, bufferData[0]);
146         return "";
147     }
148 
149     std::vector<uint8_t> arr((bufferData[INDEX_0] - HTTP_COMMON_CONST_VALUE_2) / HTTP_COMMON_CONST_VALUE_2);
150     int arrIndex = 0;
151     for (int i = INDEX_2; i < bufferData[INDEX_0];) {
152         arr[arrIndex++] = bufferData[i];
153         i += HTTP_COMMON_CONST_VALUE_2;
154     }
155     std::string printerInfo(arr.begin(), arr.end());
156     PRINT_HILOGI("bufferData printerInfo: %{public}s\n", printerInfo.c_str());
157     return printerInfo;
158 }
159 
AllocateInterface(const std::string & printerName,UsbDevice & usbdevice,USBDevicePipe & usbDevicePipe)160 bool PrintUsbManager::AllocateInterface(const std::string &printerName, UsbDevice &usbdevice,
161     USBDevicePipe &usbDevicePipe)
162 {
163     auto &UsbSrvClient = UsbSrvClient::GetInstance();
164     PrinterTranIndex tranIndex;
165     for (auto index : printerIndexMap[printerName]) {
166         int32_t configIndex = index.first;
167         int32_t interfaceIndex = index.second;
168         UsbInterface ippInterface =
169             usbdevice.GetConfigs()[configIndex].GetInterfaces()[interfaceIndex];
170         int32_t ret = UsbSrvClient.ClaimInterface(usbDevicePipe, ippInterface, true);
171         if (ret != UEC_OK) {
172             PRINT_HILOGE("ClaimInterface fail, ret = %{public}d", ret);
173             continue;
174         }
175         if (tranIndex.commonConfigIndex == INVAILD_VALUE) {
176             tranIndex.commonConfigIndex = configIndex;
177             tranIndex.commonInterfaceIndex = interfaceIndex;
178         } else if (tranIndex.sendDocConfigIndex == INVAILD_VALUE) {
179             tranIndex.sendDocConfigIndex = configIndex;
180             tranIndex.sendDocInterfaceIndex = interfaceIndex;
181             break;
182         }
183     }
184     if (tranIndex.commonConfigIndex == INVAILD_VALUE || tranIndex.sendDocConfigIndex == INVAILD_VALUE) {
185         PRINT_HILOGE("connect usb printerName = %{public}s fail!", printerName.c_str());
186         if (tranIndex.commonConfigIndex != INVAILD_VALUE) {
187             int32_t configIndex = tranIndex.commonConfigIndex;
188             UsbInterface commonInterface =
189                 usbdevice.GetConfigs()[configIndex].GetInterfaces()[tranIndex.commonInterfaceIndex];
190             UsbSrvClient.ReleaseInterface(usbDevicePipe, commonInterface);
191         }
192         UsbSrvClient.Close(usbDevicePipe);
193         return false;
194     }
195 
196     printPipeMap[printerName] = usbDevicePipe;
197     printTranIndexMap[printerName] = tranIndex;
198     return true;
199 }
200 
ConnectUsbPinter(const std::string & printerName)201 bool PrintUsbManager::ConnectUsbPinter(const std::string &printerName)
202 {
203     auto &UsbSrvClient = UsbSrvClient::GetInstance();
204     PRINT_HILOGD("connect usb printerName = %{public}s", printerName.c_str());
205     if (!printerName.empty() && printPipeMap.find(printerName) != printPipeMap.end()) {
206         PRINT_HILOGD("printerName = %{public}s is opened", printerName.c_str());
207         return true;
208     }
209     if (!printerName.empty() && printDeviceMap.find(printerName) != printDeviceMap.end()) {
210         UsbDevice usbdevice = printDeviceMap[printerName];
211         USBDevicePipe usbDevicePipe;
212         int32_t openDeviceRet = UsbSrvClient.OpenDevice(usbdevice, usbDevicePipe);
213         PRINT_HILOGD("openDevice ret = %{public}d", openDeviceRet);
214         if (openDeviceRet == UEC_OK) {
215             return AllocateInterface(printerName, usbdevice, usbDevicePipe);
216         } else {
217             PRINT_HILOGE("ipp usb openDevice fail with ret = %{public}d", openDeviceRet);
218             return false;
219         }
220     }
221     return false;
222 }
223 
DisConnectUsbPinter(const std::string & printerName)224 void PrintUsbManager::DisConnectUsbPinter(const std::string &printerName)
225 {
226     if (!printerName.empty() && printDeviceMap.find(printerName) != printDeviceMap.end() &&
227         printPipeMap.find(printerName) != printPipeMap.end()) {
228         auto &UsbSrvClient = UsbSrvClient::GetInstance();
229 
230         UsbDevice usbdevice = printDeviceMap[printerName];
231         USBDevicePipe usbDevicePipe = printPipeMap[printerName];
232 
233         PrinterTranIndex tranIndex = printTranIndexMap[printerName];
234         UsbInterface commonInterface =
235             usbdevice.GetConfigs()[tranIndex.commonConfigIndex].GetInterfaces()[tranIndex.commonInterfaceIndex];
236         UsbSrvClient.ReleaseInterface(usbDevicePipe, commonInterface);
237 
238         UsbInterface sendDocIterface =
239             usbdevice.GetConfigs()[tranIndex.sendDocConfigIndex].GetInterfaces()[tranIndex.sendDocInterfaceIndex];
240         UsbSrvClient.ReleaseInterface(usbDevicePipe, sendDocIterface);
241 
242         UsbSrvClient.Close(usbDevicePipe);
243 
244         printPipeMap.erase(printerName);
245         printTranIndexMap.erase(printerName);
246     }
247 }
248 
BulkTransferWrite(std::string printerName,const Operation operation,std::vector<uint8_t> & vectorRequestBuffer)249 int32_t PrintUsbManager::BulkTransferWrite(std::string printerName, const Operation operation,
250     std::vector<uint8_t> &vectorRequestBuffer)
251 {
252     if (printDeviceMap.find(printerName) == printDeviceMap.end()) {
253         return INVAILD_VALUE;
254     }
255     auto &UsbSrvClient = UsbSrvClient::GetInstance();
256     UsbDevice usbdevice = printDeviceMap[printerName];
257     int32_t currentConfigIndex = INVAILD_VALUE;
258     int32_t currentInterfaceIndex = INVAILD_VALUE;
259     PrinterTranIndex tranIndex = printTranIndexMap[printerName];
260     if (operation == Operation::Send_Document) {
261         currentConfigIndex = tranIndex.sendDocConfigIndex;
262         currentInterfaceIndex = tranIndex.sendDocInterfaceIndex;
263     } else {
264         currentConfigIndex = tranIndex.commonConfigIndex;
265         currentInterfaceIndex = tranIndex.commonInterfaceIndex;
266     }
267     UsbInterface useInterface = usbdevice.GetConfigs()[currentConfigIndex].GetInterfaces()[currentInterfaceIndex];
268     USBEndpoint point1 = useInterface.GetEndpoints().at(INDEX_0);
269     USBEndpoint point2 = useInterface.GetEndpoints().at(INDEX_1);
270     USBEndpoint pointWrite;
271     if (point1.GetDirection() == 0) {
272         pointWrite = point1;
273     } else {
274         pointWrite = point2;
275     }
276     USBDevicePipe usbDevicePipe = printPipeMap[printerName];
277     int32_t writeRet = UsbSrvClient.BulkTransfer(usbDevicePipe, pointWrite, vectorRequestBuffer,
278         USB_BULKTRANSFER_WRITE_TIMEOUT);
279     return writeRet;
280 }
281 
BulkTransferRead(std::string printerName,const Operation operation,std::vector<uint8_t> & readTempBUffer)282 int32_t PrintUsbManager::BulkTransferRead(std::string printerName, const Operation operation,
283     std::vector<uint8_t> &readTempBUffer)
284 {
285     if (printDeviceMap.find(printerName) == printDeviceMap.end()) {
286         return INVAILD_VALUE;
287     }
288     auto &UsbSrvClient = UsbSrvClient::GetInstance();
289     UsbDevice usbdevice = printDeviceMap[printerName];
290     int32_t currentConfigIndex = INVAILD_VALUE;
291     int32_t currentInterfaceIndex = INVAILD_VALUE;
292     PrinterTranIndex tranIndex = printTranIndexMap[printerName];
293     if (operation == Operation::Send_Document) {
294         currentConfigIndex = tranIndex.sendDocConfigIndex;
295         currentInterfaceIndex = tranIndex.sendDocInterfaceIndex;
296     } else {
297         currentConfigIndex = tranIndex.commonConfigIndex;
298         currentInterfaceIndex = tranIndex.commonInterfaceIndex;
299     }
300     UsbInterface useInterface = usbdevice.GetConfigs()[currentConfigIndex].GetInterfaces()[currentInterfaceIndex];
301     USBEndpoint point1 = useInterface.GetEndpoints().at(INDEX_0);
302     USBEndpoint point2 = useInterface.GetEndpoints().at(INDEX_1);
303     USBEndpoint pointRead;
304     if (point1.GetDirection() == 0) {
305         pointRead = point2;
306     } else {
307         pointRead = point1;
308     }
309     USBDevicePipe usbDevicePipe = printPipeMap[printerName];
310     int32_t readFromUsbRes = UsbSrvClient.BulkTransfer(usbDevicePipe, pointRead, readTempBUffer,
311         USB_BULKTRANSFER_READ_TIMEOUT);
312     return readFromUsbRes;
313 }
314 
DealUsbDevStatusChange(const std::string & devStr,bool isAttach)315 void PrintUsbManager::DealUsbDevStatusChange(const std::string &devStr, bool isAttach)
316 {
317     PRINT_HILOGD("DealUsbDevStatusChange isAttach = %{public}d, devStr = %{public}s.",
318         isAttach, devStr.c_str());
319     cJSON *devJson = cJSON_Parse(devStr.c_str());
320     if (!devJson) {
321         PRINT_HILOGE("Create devJson error");
322     }
323     UsbDevice *dev = new UsbDevice(devJson);
324     if (!isAttach) {
325         std::string printerName = GetPrinterName(dev->GetName());
326         PRINT_HILOGI("DealUsbDevStatusChange detached dev->GetName() = %{public}s, printerName = %{public}s.",
327             dev->GetName().c_str(), printerName.c_str());
328         if (!printerName.empty()) {
329             DisConnectUsbPinter(printerName);
330             printDeviceMap.erase(printerName);
331             printerIndexMap.erase(printerName);
332         }
333     } else {
334         std::string printerName;
335         if (isPrintDevice(*dev, printerName)) {
336             printDeviceMap[printerName] = *dev;
337             PRINT_HILOGI("DealUsbDevStatusChange attached dev->GetName() = %{public}s , printerName = %{public}s.",
338                 dev->GetName().c_str(), printerName.c_str());
339         }
340     }
341     cJSON_Delete(devJson);
342     delete dev;
343     dev = nullptr;
344 }
345 
GetPrinterName(const std::string & name)346 std::string PrintUsbManager::GetPrinterName(const std::string &name)
347 {
348     for (const auto& pair : printDeviceMap) {
349         if (pair.second.GetName() == name) {
350             return pair.first;
351         }
352     }
353     return "";
354 }
355 }
356 
357 #endif // IPPOVERUSB_ENABLE