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_http_request_process.h"
18 #include <cmath>
19 #include "print_log.h"
20 #include "print_ipp_over_usb_util.h"
21 #include "usb_errors.h"
22 
23 namespace OHOS::Print {
24 using namespace std;
25 using namespace OHOS;
26 using namespace OHOS::USB;
27 using namespace httplib;
28 
PrintHttpRequestProcess()29 PrintHttpRequestProcess::PrintHttpRequestProcess()
30 {}
31 
~PrintHttpRequestProcess()32 PrintHttpRequestProcess::~PrintHttpRequestProcess()
33 {}
34 
PrintOperation(Operation operation)35 std::string PrintHttpRequestProcess::PrintOperation(Operation operation)
36 {
37     if (operation == Operation::Get_Printer_Attributes) {
38         return HTTP_OPERATION_GET_ATTR;
39     } else if (operation == Operation::Send_Document) {
40         return HTTP_OPERATION_SEND_DOC;
41     } else {
42         return HTTP_OPERATION_COMMON;
43     }
44 }
45 
NeedOffset(const std::vector<uint8_t> &readTempBuffer)46 size_t PrintHttpRequestProcess::NeedOffset(const std::vector<uint8_t> &readTempBuffer)
47 {
48     size_t readSize = readTempBuffer.size();
49     size_t reqindex = 0;
50     bool checkNeedOffset = (readSize > HTTP_COMMON_CONST_VALUE_25 && readTempBuffer[INDEX_0] == HTTP_RESPONSE_H &&
51         readTempBuffer[INDEX_1] == HTTP_RESPONSE_T && readTempBuffer[INDEX_2] == HTTP_RESPONSE_T &&
52         readTempBuffer[INDEX_3] == HTTP_RESPONSE_P &&
53         readTempBuffer[INDEX_4] == HTTP_RESPONSE_VERSION_SPLIT_GANG &&
54         readTempBuffer[INDEX_5] == HTTP_MSG_CHAR_1 &&
55         readTempBuffer[INDEX_6] == HTTP_MSG_CHAR_2E &&
56         readTempBuffer[INDEX_7] == HTTP_MSG_CHAR_1 &&
57         readTempBuffer[INDEX_8] == HTTP_MSG_CHAR_20 &&
58         readTempBuffer[INDEX_9] == HTTP_MSG_CHAR_1 &&
59         readTempBuffer[INDEX_10] == HTTP_MSG_CHAR_0 &&
60         readTempBuffer[INDEX_11] == HTTP_MSG_CHAR_0);
61     if (checkNeedOffset) {
62         PRINT_HILOGD("include HTTP/1.1 100");
63         reqindex = HTTP_COMMON_CONST_VALUE_25;
64     }
65     return reqindex;
66 }
67 
RecordBufByOperation(Operation operation, size_t requestId, const std::vector<uint8_t> &tmVector)68 void PrintHttpRequestProcess::RecordBufByOperation(Operation operation, size_t requestId,
69     const std::vector<uint8_t> &tmVector)
70 {
71     if (operation == Operation::Send_Document) {
72         std::lock_guard<std::mutex> mtx_locker(mutexSendDoc);
73         if (readSendDocBufMap.find(requestId) == readSendDocBufMap.end()) {
74             readSendDocBufMap[requestId] = tmVector;
75         }
76     } else {
77         if (reqIdOperaIdMap[requestId] == HTTP_REQUEST_GET_ATTR)  {
78             std::lock_guard<std::mutex> mtx_locker(mutexGetAttr);
79             if (readGetAttrBufMap.find(requestId) == readGetAttrBufMap.end()) {
80                 readGetAttrBufMap[requestId] = tmVector;
81             }
82         } else {
83             std::lock_guard<std::mutex> mtx_locker(mutexCommon);
84             if (readBufMap.find(requestId) == readBufMap.end()) {
85                 readBufMap[requestId] = tmVector;
86             }
87         }
88     }
89 }
90 
GetContentLength(const std::vector<uint8_t> &readTempBuffer, size_t index, bool &findContentLength, size_t &contentLength)91 void PrintHttpRequestProcess::GetContentLength(const std::vector<uint8_t> &readTempBuffer, size_t index,
92     bool &findContentLength, size_t &contentLength)
93 {
94     size_t readSize = readTempBuffer.size();
95     if ((index + HTTP_COMMON_CONST_VALUE_14) < readSize) {
96         std::string tmpStr = "";
97         for (size_t offset = 0; offset < HTTP_COMMON_CONST_VALUE_14; offset++) {
98             tmpStr += readTempBuffer[index + offset];
99         }
100         if (tmpStr == HTTP_CONTENT_LENGTH) {
101             findContentLength = true;
102             std::string lenStr = "";
103             size_t lenIndex = index + HTTP_COMMON_CONST_VALUE_14 + HTTP_COMMON_CONST_VALUE_2;
104             while (lenIndex < readSize - 1 && (!(readTempBuffer[lenIndex] == HTTP_SPLIT_R_CODE &&
105                                                   readTempBuffer[lenIndex + INDEX_1] == HTTP_SPLIT_N_CODE))) {
106                 lenStr += readTempBuffer[lenIndex];
107                 lenIndex++;
108             }
109             try {
110                 contentLength = static_cast<size_t>(std::stoi(lenStr));
111             } catch (std::invalid_argument &e) {
112                 PRINT_HILOGE("invalid_argument error: %s", e.what());
113             } catch (std::out_of_range &e) {
114                 PRINT_HILOGE("out_of_range error: %s", e.what());
115             }
116             PRINT_HILOGD("contentLength = %{public}s,  %{public}lu", lenStr.c_str(), contentLength);
117         }
118     }
119 }
120 
DumpRespIdCode(const std::vector<uint8_t> &readTempBuffer, Operation operation, size_t begin, size_t maxSize)121 void PrintHttpRequestProcess::DumpRespIdCode(const std::vector<uint8_t> &readTempBuffer,
122     Operation operation, size_t begin, size_t maxSize)
123 {
124     for (size_t i = begin; i < (begin + HTTP_COMMON_CONST_VALUE_8) && i < maxSize; i++) {
125         PRINT_HILOGD("operation:%{public}s, readTempBuffer: %{public}x",
126             PrintOperation(operation).c_str(), readTempBuffer[i]);
127     }
128 }
129 
CheckLineEnd(std::vector<uint8_t> &readTempBuffer, size_t index)130 bool PrintHttpRequestProcess::CheckLineEnd(std::vector<uint8_t> &readTempBuffer, size_t index)
131 {
132     size_t readSize = readTempBuffer.size();
133     if ((index + HTTP_COMMON_CONST_VALUE_3) < readSize && readTempBuffer[index] == HTTP_SPLIT_R_CODE &&
134         readTempBuffer[index + INDEX_1] == HTTP_SPLIT_N_CODE && readTempBuffer[index + INDEX_2] == HTTP_SPLIT_R_CODE &&
135         readTempBuffer[index + INDEX_3] == HTTP_SPLIT_N_CODE) {
136         return true;
137     }
138     return false;
139 }
140 
CalculateRequestId( std::vector<uint8_t> &readTempBuffer, size_t index, Operation operation)141 size_t PrintHttpRequestProcess::CalculateRequestId(
142     std::vector<uint8_t> &readTempBuffer, size_t index, Operation operation)
143 {
144     size_t readSize = readTempBuffer.size();
145     if ((index + HTTP_COMMON_CONST_VALUE_8) < readSize &&
146         (index + HTTP_COMMON_CONST_VALUE_9) < readSize &&
147         (index + HTTP_COMMON_CONST_VALUE_10) < readSize &&
148         (index + HTTP_COMMON_CONST_VALUE_11) < readSize) {
149         DumpRespIdCode(readTempBuffer, operation, index + HTTP_COMMON_CONST_VALUE_4, readSize);
150         return readTempBuffer[index + HTTP_COMMON_CONST_VALUE_8] *
151                 pow(HTTP_COMMON_CONST_VALUE_10, HTTP_COMMON_CONST_VALUE_3) +
152             readTempBuffer[index + HTTP_COMMON_CONST_VALUE_9] *
153                 pow(HTTP_COMMON_CONST_VALUE_10, HTTP_COMMON_CONST_VALUE_2) +
154             readTempBuffer[index + HTTP_COMMON_CONST_VALUE_10] * HTTP_COMMON_CONST_VALUE_10 +
155             readTempBuffer[index + HTTP_COMMON_CONST_VALUE_11];
156     }
157     PRINT_HILOGE("Invalid index");
158     return 0;
159 }
160 
CalculateFileDataBeginIndex(size_t index, Operation operation)161 size_t PrintHttpRequestProcess::CalculateFileDataBeginIndex(size_t index, Operation operation)
162 {
163     size_t fileDataBeginIndex = index + INDEX_4;
164     PRINT_HILOGD("operation:%{public}s, fileDataBeginIndex = %{public}lu",
165         PrintOperation(operation).c_str(), fileDataBeginIndex);
166     return fileDataBeginIndex;
167 }
168 
ProcessDataFromDevice(Operation operation)169 bool PrintHttpRequestProcess::ProcessDataFromDevice(Operation operation)
170 {
171     std::vector<uint8_t> readTempBuffer;
172     int32_t readFromUsbRes =
173         DelayedSingleton<PrintUsbManager>::GetInstance()->BulkTransferRead(devName, operation, readTempBuffer);
174     if (readFromUsbRes == EORROR_HDF_DEV_ERR_NO_DEVICE) {
175         PRINT_HILOGE("HDF_DEV_ERR_NO_DEVICE, The device module has no device");
176         deviceOpen = false;
177         return true;
178     }
179     size_t readSize = readTempBuffer.size();
180     if (readSize > 0 && readFromUsbRes == UEC_OK) {
181         PRINT_HILOGD("operation:%{public}s, readSize = %{public}lu", PrintOperation(operation).c_str(), readSize);
182         size_t reqindex = NeedOffset(readTempBuffer);
183         size_t requestId = 0;
184         std::vector<uint8_t> tmVector;
185         bool findRequestId = false;
186         bool findContentLength = false;
187         size_t contentLength = 0;
188         size_t fileDataBeginIndex = 0;
189         // 解析出报文中的RequestId 和 Content-Length
190         for (size_t index = reqindex; index < readSize; index++) {
191             bool findLineEnd = (!findRequestId && CheckLineEnd(readTempBuffer, index));
192             if (findLineEnd) {
193                 fileDataBeginIndex = CalculateFileDataBeginIndex(index, operation);
194                 findRequestId = true;
195             }
196             if (!findContentLength) {
197                 GetContentLength(readTempBuffer, index, findContentLength, contentLength);
198             }
199             tmVector.push_back(readTempBuffer[index]);
200         }
201         int count = 0;
202         int maxCount = 50;
203         // 一次读取的报文长度小于 Content-Length字段的值则需再读取一次
204         while (tmVector.size() < readSize + contentLength && count < maxCount) {
205             GetAttrAgain(operation, tmVector);
206             count++;
207         }
208         if (fileDataBeginIndex > HTTP_COMMON_CONST_VALUE_4) {
209             requestId = CalculateRequestId(tmVector, fileDataBeginIndex - HTTP_COMMON_CONST_VALUE_4, operation);
210         }
211         PRINT_HILOGD("operation:%{public}s requestId: %{public}lu ", PrintOperation(operation).c_str(), requestId);
212         RecordBufByOperation(operation, requestId, tmVector);
213         return true;
214     }
215     return false;
216 }
217 
GetAttrAgain(Operation operation, std::vector<uint8_t> &tmVector)218 void PrintHttpRequestProcess::GetAttrAgain(Operation operation, std::vector<uint8_t> &tmVector)
219 {
220     PRINT_HILOGD("GetAttr again");
221     std::vector<uint8_t> readBuffer;
222     int32_t readFromUsbRes =
223         DelayedSingleton<PrintUsbManager>::GetInstance()->BulkTransferRead(devName, operation, readBuffer);
224     size_t readSize = readBuffer.size();
225     if (readSize > 0 && readFromUsbRes == UEC_OK) {
226         PRINT_HILOGD("GetAttr again readSize = %{public}lu", readSize);
227         for (size_t index = 0; index < readSize; index++) {
228             tmVector.push_back(readBuffer[index]);
229         }
230     }
231 }
232 
StartReadSendDocDataFromPrinterLooper()233 void PrintHttpRequestProcess::StartReadSendDocDataFromPrinterLooper()
234 {
235     PRINT_HILOGD("StartReadSendDocDataFromPrinterLooper");
236     while (deviceOpen && needReadSendDoc) {
237         if (ProcessDataFromDevice(Operation::Send_Document)) {
238             break;
239         }
240         std::this_thread::sleep_for(std::chrono::milliseconds(USB_READ_INTERVAL));
241     }
242     PRINT_HILOGD("EndReadSendDocDataFromPrinterLooper");
243 }
244 
ProcessHttpResponse(httplib::Response &responseData, size_t requestId)245 void PrintHttpRequestProcess::ProcessHttpResponse(httplib::Response &responseData, size_t requestId)
246 {
247     PRINT_HILOGD("processHttpResponse enter");
248     int retryCount = 0;
249     // cups timeout is 30 seconds
250     while (retryCount < RESPONSE_RETRY_MAX_TIMES && deviceOpen) {
251         std::this_thread::sleep_for(std::chrono::milliseconds(RESPONSE_RETRY_INTERVAL));
252         retryCount++;
253         std::lock_guard<std::mutex> mtx_locker(mutexCommon);
254         if (readBufMap.find(requestId) != readBufMap.end()) {
255             size_t totalSize = readBufMap[requestId].size();
256             PRINT_HILOGD("Response totalSize:%{public}lu, retryCout = %{public}d", totalSize, retryCount);
257             PrintIppOverUsbUtil::ConstructHttpResponse(&readBufMap[requestId][0], totalSize, responseData);
258             readBufMap.erase(requestId);
259             break;
260         } else {
261             continue;
262         }
263     }
264     // 超时错误
265     if (retryCount >= RESPONSE_RETRY_MAX_TIMES) {
266         PRINT_HILOGE("process_http_response time out retryCout: %{public}d", retryCount);
267     }
268     PRINT_HILOGD("process_http_response out");
269 }
270 
ProcessHttpResponseGetAttr(httplib::Response &responseData, size_t requestId)271 void PrintHttpRequestProcess::ProcessHttpResponseGetAttr(httplib::Response &responseData, size_t requestId)
272 {
273     PRINT_HILOGD("processHttpResponseGetAttr enter");
274     int retryCount = 0;
275     while (retryCount < RESPONSE_RETRY_MAX_TIMES && deviceOpen) {
276         std::this_thread::sleep_for(std::chrono::milliseconds(RESPONSE_RETRY_INTERVAL));
277         retryCount++;
278         std::lock_guard<std::mutex> mtx_locker(mutexGetAttr);
279         if (readGetAttrBufMap.find(requestId) != readGetAttrBufMap.end()) {
280             size_t totalSize = readGetAttrBufMap[requestId].size();
281             PRINT_HILOGD("Response GetAttr totalSize:%{public}lu, retryCout = %{public}d", totalSize, retryCount);
282             PrintIppOverUsbUtil::ConstructHttpResponse(&readGetAttrBufMap[requestId][0], totalSize, responseData);
283             readGetAttrBufMap.erase(requestId);
284             break;
285         } else {
286             continue;
287         }
288     }
289     // 超时错误
290     if (retryCount >= RESPONSE_RETRY_MAX_TIMES) {
291         PRINT_HILOGE("process_http_response_get_attr time out retryCout: %{public}d", retryCount);
292     }
293     PRINT_HILOGD("process_http_response_get_attr out");
294 }
295 
ProcessHttpResponseSendDoc(httplib::Response &responseData, size_t requestId)296 void PrintHttpRequestProcess::ProcessHttpResponseSendDoc(httplib::Response &responseData, size_t requestId)
297 {
298     PRINT_HILOGD("ProcessHttpResponseSendDoc enter");
299     int retryCount = 0;
300     while (retryCount < RESPONSE_RETRY_MAX_TIMES && deviceOpen) {
301         std::this_thread::sleep_for(std::chrono::milliseconds(RESPONSE_RETRY_INTERVAL));
302         retryCount++;
303         std::lock_guard<std::mutex> mtx_locker(mutexSendDoc);
304         if (readSendDocBufMap.find(requestId) != readSendDocBufMap.end()) {
305             size_t totalSize = readSendDocBufMap[requestId].size();
306             PRINT_HILOGD("Response SendDoc totalSize:%{public}lu, retryCout = %{public}d", totalSize, retryCount);
307             PrintIppOverUsbUtil::ConstructHttpResponse(&readSendDocBufMap[requestId][0], totalSize, responseData);
308             readSendDocBufMap.erase(requestId);
309             break;
310         } else {
311             continue;
312         }
313     }
314     // 超时错误
315     if (retryCount >= RESPONSE_RETRY_MAX_TIMES) {
316         PRINT_HILOGE("ProcessHttpResponseSendDoc time out retryCout: %{public}d", retryCount);
317         needReadSendDoc = false;
318     }
319     PRINT_HILOGD("ProcessHttpResponseSendDoc out");
320 }
321 
DealRequestHeader(const httplib::Request &requestData, std::string &sHeadersAndBody)322 bool PrintHttpRequestProcess::DealRequestHeader(const httplib::Request &requestData, std::string &sHeadersAndBody)
323 {
324     bool ischunked = false;
325     for (const auto &x : requestData.headers) {
326         PRINT_HILOGD("requestData.headers first: %{public}s, second : %{public}s", x.first.c_str(), x.second.c_str());
327         if (x.first == HTTP_TRANSFER_ENCODING && x.second == HTTP_CHUNKED) {
328             ischunked = true;
329         }
330         if (x.first == HTTP_EXPECT) {
331             continue;
332         }
333         sHeadersAndBody += x.first;
334         sHeadersAndBody += SPLIT_VALUE_COLON;
335         sHeadersAndBody += x.second;
336         sHeadersAndBody += HTTP_MSG_STRING_R_AND_N;
337     }
338     sHeadersAndBody += HTTP_MSG_STRING_R_AND_N;
339     return ischunked;
340 }
341 
CalcReqIdOperaId(const char *data, size_t dataLength, size_t &requestId)342 void PrintHttpRequestProcess::CalcReqIdOperaId(const char *data, size_t dataLength, size_t &requestId)
343 {
344     if (data == nullptr) {
345         return;
346     }
347     if (dataLength < HTTP_COMMON_CONST_VALUE_8) {
348         return;
349     }
350     DumpReqIdOperaId(data, dataLength);
351     size_t operationId = (uint8_t)(*(data + INDEX_2)) * HTTP_COMMON_CONST_VALUE_10 + (uint8_t)(*(data + INDEX_3));
352     requestId = (uint8_t)(*(data + INDEX_4)) * HTTP_COMMON_CONST_VALUE_1000 +
353         (uint8_t)(*(data + INDEX_5)) * HTTP_COMMON_CONST_VALUE_100 +
354          (uint8_t)(*(data + INDEX_6)) * HTTP_COMMON_CONST_VALUE_10 + (uint8_t)(*(data + INDEX_7));
355     reqIdOperaIdMap[requestId] = operationId;
356 }
357 
StartWriteDataToPrinterLooper()358 void PrintHttpRequestProcess::StartWriteDataToPrinterLooper()
359 {
360     PRINT_HILOGD("StartWriteDataToPrinterLooper");
361     std::vector<uint8_t> vectorRequestBuffer;
362     while (deviceOpen && needWriteData) {
363         std::string str = "";
364         if (!ippDataQue.pop(str)) {
365             continue;
366         }
367 
368         vectorRequestBuffer.assign(str.begin(), str.end());
369         int32_t ret = 0;
370         int32_t writeDataRetryCount = 0;
371         do {
372             ret = DelayedSingleton<PrintUsbManager>::GetInstance()->BulkTransferWrite(
373                 devName, Operation::Common, vectorRequestBuffer);
374             PRINT_HILOGD("writeBody ret: %{public}d", ret);
375             if (ret == EORROR_HDF_DEV_ERR_TIME_OUT) {
376                 std::this_thread::sleep_for(std::chrono::milliseconds(USB_WRITE_INTERVAL));
377                 writeDataRetryCount++;
378                 PRINT_HILOGE(
379                     "StartWriteDataToPrinterLooper, retrwriteDataRetryCounty = %{public}d", writeDataRetryCount);
380             }
381         } while (ret == EORROR_HDF_DEV_ERR_TIME_OUT && writeDataRetryCount < WRITE_RETRY_MAX_TIMES);
382 
383         if (ret == EORROR_HDF_DEV_ERR_NO_DEVICE) {
384             PRINT_HILOGE("WriteData HDF_DEV_ERR_NO_DEVICE, The device module has no device");
385             needWriteData = false;
386             break;
387         }
388         vectorRequestBuffer.clear();
389         int retryCount = 0;
390         while (retryCount < READ_RETRY_MAX_TIMES) {
391             retryCount++;
392             if (ProcessDataFromDevice(Operation::Common)) {
393                 break;
394             }
395             std::this_thread::sleep_for(std::chrono::milliseconds(USB_READ_INTERVAL));
396         }
397         // 读超时错误
398         if (retryCount >= READ_RETRY_MAX_TIMES) {
399             PRINT_HILOGE("read data time out retryCout: %{public}d", retryCount);
400         }
401     }
402     PRINT_HILOGD("endtWriteDataToPrinterLooper");
403 }
404 
CreatWriteDataTask()405 void PrintHttpRequestProcess::CreatWriteDataTask()
406 {
407     PRINT_HILOGD("CreatWriteDataTask needWriteData: %{public}d", needWriteData);
408     if (!needWriteData) {
409         needWriteData = true;
410         std::thread writeDataTask([this] {this->StartWriteDataToPrinterLooper();});
411         writeDataTask.detach();
412     }
413 }
414 
ProcessOtherRequest(const char *data, size_t data_length, std::string &sHeadersAndBody, size_t requestId)415 void PrintHttpRequestProcess::ProcessOtherRequest(const char *data, size_t data_length,
416     std::string &sHeadersAndBody, size_t requestId)
417 {
418     CreatWriteDataTask();
419 
420     sHeadersAndBody.append(data, data_length);
421     ippDataQue.push(sHeadersAndBody);
422 }
423 
DumpReqIdOperaId(const char *data, size_t data_length)424 void PrintHttpRequestProcess::DumpReqIdOperaId(const char *data, size_t data_length)
425 {
426     if (data_length < REQID_OPERAID_LEN) {
427         return;
428     }
429     for (size_t i = 0; i < REQID_OPERAID_LEN; i++) {
430         PRINT_HILOGD("ipp: %{public}x", *(data + i));
431     }
432 }
433 
CreatReadSendDocTask()434 void PrintHttpRequestProcess::CreatReadSendDocTask()
435 {
436     PRINT_HILOGD("CreatReadSendDocTask needReadSendDoc: %{public}d", needReadSendDoc);
437     if (!needReadSendDoc) {
438         needReadSendDoc = true;
439         std::thread readSendDocTask([this] {this->StartReadSendDocDataFromPrinterLooper();});
440         readSendDocTask.detach();
441     }
442 }
443 
CreateChunk(const char *data, size_t data_length)444 std::string PrintHttpRequestProcess::CreateChunk(const char *data, size_t data_length)
445 {
446     std::string chunkStr = PrintIppOverUsbUtil::IntToHexString(static_cast<unsigned int>(data_length));
447     chunkStr += HTTP_MSG_STRING_R_AND_N;
448     chunkStr.append(data, data_length);
449     chunkStr += HTTP_MSG_STRING_R_AND_N;
450     return chunkStr;
451 }
452 
WriteDataSync(const std::string &dataStr)453 int32_t PrintHttpRequestProcess::WriteDataSync(const std::string &dataStr)
454 {
455     std::string sHeadersAndBody = dataStr;
456     int32_t ret = 0;
457     while (sHeadersAndBody.length() > USB_ENDPOINT_MAX_LENGTH) {
458         std::string send = sHeadersAndBody.substr(0, USB_ENDPOINT_MAX_LENGTH);
459         ret = BulkTransferWriteData(send);
460         if (ret != 0) {
461             return ret;
462         }
463         sHeadersAndBody = sHeadersAndBody.substr(USB_ENDPOINT_MAX_LENGTH);
464     }
465     if (!sHeadersAndBody.empty()) {
466         ret = BulkTransferWriteData(sHeadersAndBody);
467     }
468     return ret;
469 }
470 
BulkTransferWriteData(const std::string &dataStr)471 int32_t PrintHttpRequestProcess::BulkTransferWriteData(const std::string &dataStr)
472 {
473     std::vector<uint8_t> vectorRequestBuffer;
474     size_t len = dataStr.length();
475     sendDocTotalLen += len;
476     vectorRequestBuffer.assign(dataStr.begin(), dataStr.end());
477     uint32_t retryNum = 0;
478     int32_t ret = 0;
479     do {
480         ret = DelayedSingleton<PrintUsbManager>::GetInstance()->BulkTransferWrite(devName,
481             Operation::Send_Document, vectorRequestBuffer);
482         PRINT_HILOGD("writeBody chunk, ret: %{public}d, len: %{public}lu, sendDocTotalLen: %{public}lu",
483             ret, len, sendDocTotalLen);
484         if (ret == EORROR_HDF_DEV_ERR_NO_DEVICE) {
485             sendDocTotalLen = 0;
486             deviceOpen = false;
487             return ret;
488         }
489         if (ret == EORROR_HDF_DEV_ERR_TIME_OUT) {
490             std::this_thread::sleep_for(std::chrono::milliseconds(USB_BULKTRANSFER_WRITE_SLEEP));
491             retryNum++;
492         }
493     } while (ret == EORROR_HDF_DEV_ERR_TIME_OUT && retryNum < WRITE_RETRY_MAX_TIMES);
494     if (ret != 0) {
495         sendDocTotalLen = 0;
496         PRINT_HILOGD("Write data fail");
497         return ret;
498     }
499     vectorRequestBuffer.clear();
500     return ret;
501 }
502 
ProcessHttpResp(size_t requestId, httplib::Response &responseData, const std::string &sHeadersAndBody)503 void PrintHttpRequestProcess::ProcessHttpResp(size_t requestId, httplib::Response &responseData,
504     const std::string &sHeadersAndBody)
505 {
506     if (reqIdOperaIdMap[requestId] == HTTP_REQUEST_GET_ATTR) {
507         ProcessHttpResponseGetAttr(responseData, requestId);
508     } else if (reqIdOperaIdMap[requestId] == HTTP_REQUEST_SEND_DOC) {
509         if (!deviceOpen) {
510             PRINT_HILOGE("Device disconnect, return");
511             return;
512         }
513         PRINT_HILOGD("writeBody chunk end sHeadersAndBody len: %{public}lu", sHeadersAndBody.length());
514         std::string dataStr = sHeadersAndBody + HTTP_MSG_STRING_CHUNK_END;
515         auto ret = WriteDataSync(dataStr);
516         sendDocTotalLen = 0;
517         if (ret != 0) {
518             PRINT_HILOGE("writeBody chunk end fail");
519             return;
520         }
521         PRINT_HILOGD("writeBody chunk end");
522         ProcessHttpResponseSendDoc(responseData, requestId);
523     } else {
524         ProcessHttpResponse(responseData, requestId);
525     }
526 }
527 
ProcessRequest(const httplib::Request &requestData, httplib::Response &responseData, const httplib::ContentReader &content_reader)528 uint32_t PrintHttpRequestProcess::ProcessRequest(const httplib::Request &requestData, httplib::Response &responseData,
529     const httplib::ContentReader &content_reader)
530 {
531     PRINT_HILOGI("ProcessRequest devName: %{public}s", devName.c_str());
532     std::string sHeadersAndBody = HTTP_POST;
533     bool isChunked = DealRequestHeader(requestData, sHeadersAndBody);
534     size_t requestId = 0;
535     bool isFirstRead = true;
536     content_reader([&](const char *data, size_t data_length) {
537         if (isChunked) {
538             if (isFirstRead) {
539                 isFirstRead = false;
540                 CalcReqIdOperaId(data, data_length, requestId);
541                 CreatReadSendDocTask();
542                 sHeadersAndBody += CreateChunk(data, data_length);
543                 return CPP_HTTP_OK;
544             }
545         } else {
546             CalcReqIdOperaId(data, data_length, requestId);
547         }
548 
549         if (reqIdOperaIdMap[requestId] == HTTP_REQUEST_SEND_DOC) {
550             std::string dataChunk = CreateChunk(data, data_length);
551             if ((sHeadersAndBody.length() + dataChunk.length()) < USB_DATA_MAX_LENGTH) {
552                 sHeadersAndBody += dataChunk;
553                 return CPP_HTTP_OK;
554             }
555             auto ret = WriteDataSync(sHeadersAndBody);
556             if (ret != 0) {
557                 return CPP_HTTP_FAIL;
558             }
559             sHeadersAndBody = dataChunk;
560             return CPP_HTTP_OK;
561         }
562 
563         ProcessOtherRequest(data, data_length, sHeadersAndBody, requestId);
564         return CPP_HTTP_OK;
565     });
566     ProcessHttpResp(requestId, responseData, sHeadersAndBody);
567     PRINT_HILOGD("processRequest path: %{public}s end", requestData.path.c_str());
568     return 0;
569 }
570 
SetDeviceName(std::string name)571 void PrintHttpRequestProcess::SetDeviceName(std::string name)
572 {
573     devName = name;
574 }
575 
GetDeviceName()576 std::string PrintHttpRequestProcess::GetDeviceName()
577 {
578     return devName;
579 }
580 
Stop()581 void PrintHttpRequestProcess::Stop()
582 {
583     PRINT_HILOGD("stop read data looper");
584     needReadSendDoc = false;
585     needWriteSendDoc = false;
586     needWriteData = false;
587 }
588 
589 }
590 
591 #endif // IPPOVERUSB_ENABLE