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