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