From 138276027837f5376052760eabb78a0deb1fd26c Mon Sep 17 00:00:00 2001 From: zako Date: Fri, 5 Nov 2021 13:13:45 +0800 Subject: [PATCH 01/15] Try fix the client connection was closed abnormally Signed-off-by: zako Signed-off-by: zako --- README_zh.md | 4 ++-- src/common/base.cpp | 3 ++- src/common/file.cpp | 7 ++++--- src/daemon/daemon_app.cpp | 2 +- src/host/client.cpp | 2 +- src/host/server.cpp | 9 +++------ src/host/server_for_client.cpp | 9 +++------ 7 files changed, 16 insertions(+), 20 deletions(-) diff --git a/README_zh.md b/README_zh.md index 32ec8c95..03fae843 100644 --- a/README_zh.md +++ b/README_zh.md @@ -69,7 +69,7 @@ linux版本建议ubuntu 16.04以上 64位,其他相近版本也可;libc++.so 在Linux下在非root权限下使用hdc会出现无法找到设备的情况,此问题原因为用户USB操作权限问题,解决方法如下: 1. 开启非root用户USB设备操作权限 - 该操作方法简单易行但是可能存在潜在安全问题,请根据使用场景自行评估 + 该操作方法简单易行,但是可能存在潜在安全问题,请根据使用场景自行评估 ``` sudo chmod -R 777 /dev/bus/usb/ ``` @@ -131,7 +131,7 @@ hdc当前常用命令如下,未尽命令使用hdc -h或者hdc --help查看:

target mount

-

以读写模式挂载/system等分区

+

以读写模式挂载/vendor、/data等分区,因为安全性问题,需要挂在根目录或者/system分区
请单独使用'hdc_std shell mount -o rw,remount /'等命令

举例: hdc target mount

diff --git a/src/common/base.cpp b/src/common/base.cpp index a8c772a3..c81fcc75 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -689,7 +689,8 @@ namespace Base { WRITE_LOG(LOG_FATAL, "Tmppath failed"); return ERR_API_FAIL; } - if (snprintf_s(bufPath, sizeof(bufPath), sizeof(bufPath) - 1, "%s/.%s.pid", buf, procname) < 0) { + if (snprintf_s(bufPath, sizeof(bufPath), sizeof(bufPath) - 1, "%s%c.%s.pid", buf, Base::GetPathSep(), procname) + < 0) { return ERR_BUF_OVERFLOW; } int pid = static_cast(getpid()); diff --git a/src/common/file.cpp b/src/common/file.cpp index 022a09d9..4e3cd905 100644 --- a/src/common/file.cpp +++ b/src/common/file.cpp @@ -34,9 +34,6 @@ void HdcFile::StopTask() singalStop = true; }; -// Send supported below styles -// send|recv path/filename path/filename -// send|recv filename path bool HdcFile::BeginTransfer(CtxFile *context, const string &command) { int argc = 0; @@ -82,6 +79,10 @@ bool HdcFile::SetMasterParameters(CtxFile *context, const char *command, int arg context->transferConfig.updateIfNew = true; ++srcArgvIndex; } else if (argv[i] == CMD_OPTION_TSTMP) { + // The time zone difference may cause the display time on the PC and the + // device to differ by several hours + // + // ls -al --full-time context->transferConfig.holdTimestamp = true; ++srcArgvIndex; } else if (argv[i] == CMD_OPTION_CLIENTCWD) { diff --git a/src/daemon/daemon_app.cpp b/src/daemon/daemon_app.cpp index 2f8edf24..4f04dc93 100644 --- a/src/daemon/daemon_app.cpp +++ b/src/daemon/daemon_app.cpp @@ -65,7 +65,7 @@ bool HdcDaemonApp::CommandDispatch(const uint16_t command, uint8_t *payload, con size_t size = 256; uv_os_tmpdir(tmpPath, &size); dstPath = tmpPath; - dstPath += PREF_SEPARATOR; + dstPath += Base::GetPathSep(); #endif dstPath += ctxNow.transferConfig.optionalName; ctxNow.localPath = dstPath; diff --git a/src/host/client.cpp b/src/host/client.cpp index 2532e34f..5c899409 100644 --- a/src/host/client.cpp +++ b/src/host/client.cpp @@ -46,7 +46,7 @@ uint32_t HdcClient::GetLastPID() WRITE_LOG(LOG_FATAL, "Tmppath failed"); return 0; } - string path = Base::StringFormat("%s/.%s.pid", bufPath, SERVER_NAME.c_str()); + string path = Base::StringFormat("%s%c.%s.pid", bufPath, Base::GetPathSep(), SERVER_NAME.c_str()); Base::ReadBinFile(path.c_str(), (void **)&pidBuf, BUF_SIZE_TINY); int pid = atoi(pidBuf); // pid maybe 0 return pid; diff --git a/src/host/server.cpp b/src/host/server.cpp index fef638b7..a278c6a1 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -471,12 +471,9 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const case CMD_KERNEL_CHANNEL_CLOSE: { WRITE_LOG(LOG_DEBUG, "CMD_KERNEL_CHANNEL_CLOSE channelid:%d", channelId); ClearOwnTasks(hSession, channelId); - auto funcChannleClose = [](uv_handle_t *handle) -> void { - HChannel hChannel = (HChannel)handle->data; - HdcServerForClient *sfc = static_cast(hChannel->clsChannel); - sfc->FreeChannel(hChannel->channelId); - }; - Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP, funcChannleClose); + // Forcibly closing the tcp handle here may result in incomplete data reception on the client side + HdcServerForClient *sfc = static_cast(hChannel->clsChannel); + sfc->FreeChannel(hChannel->channelId); if (*payload) { --(*payload); Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); diff --git a/src/host/server_for_client.cpp b/src/host/server_for_client.cpp index ff913b6f..18abf088 100644 --- a/src/host/server_for_client.cpp +++ b/src/host/server_for_client.cpp @@ -426,19 +426,16 @@ bool HdcServerForClient::TaskCommand(HChannel hChannel, void *formatCommandInput cmdFlag = "sideload "; sizeCmdFlag = 9; } + uint8_t *payload = reinterpret_cast(const_cast(formatCommand->parameters.c_str())) + sizeCmdFlag; if (!strncmp(formatCommand->parameters.c_str(), cmdFlag.c_str(), sizeCmdFlag)) { // local do HSession hSession = FindAliveSession(hChannel->targetSessionId); if (!hSession) { return false; } - ptrServer->DispatchTaskData(hSession, hChannel->channelId, formatCommand->cmdFlag, - reinterpret_cast(const_cast(formatCommand->parameters.c_str())) - + sizeCmdFlag, + ptrServer->DispatchTaskData(hSession, hChannel->channelId, formatCommand->cmdFlag, payload, sizeSend - sizeCmdFlag); } else { // Send to Daemon-side to do - SendToDaemon(hChannel, formatCommand->cmdFlag, - reinterpret_cast(const_cast(formatCommand->parameters.c_str())) + sizeCmdFlag, - sizeSend - sizeCmdFlag); + SendToDaemon(hChannel, formatCommand->cmdFlag, payload, sizeSend - sizeCmdFlag); } return true; } -- Gitee From da7ef90419378d1424abb2237628655b21de92ff Mon Sep 17 00:00:00 2001 From: zhaifenghw Date: Fri, 5 Nov 2021 16:10:44 +0800 Subject: [PATCH 02/15] sync try fix the client connection was closed abnormally. Signed-off-by: zhaifenghw Signed-off-by: zako --- README_zh.md | 4 ++-- src/common/base.cpp | 3 ++- src/common/file.cpp | 9 +++++---- src/daemon/daemon_app.cpp | 2 +- src/host/client.cpp | 2 +- src/host/server.cpp | 9 +++------ src/host/server_for_client.cpp | 8 +++----- 7 files changed, 17 insertions(+), 20 deletions(-) diff --git a/README_zh.md b/README_zh.md index 3df3bd0f..ecbfc53c 100644 --- a/README_zh.md +++ b/README_zh.md @@ -69,7 +69,7 @@ linux版本建议ubuntu 16.04以上 64位,其他相近版本也可;libc++.so 在Linux下在非root权限下使用hdc会出现无法找到设备的情况,此问题原因为用户USB操作权限问题,解决方法如下: 1. 开启非root用户USB设备操作权限 - 该操作方法简单易行但是可能存在潜在安全问题,请根据使用场景自行评估 + 该操作方法简单易行,但是可能存在潜在安全问题,请根据使用场景自行评估 ``` sudo chmod -R 777 /dev/bus/usb/ ``` @@ -131,7 +131,7 @@ hdc当前常用命令如下,未尽命令使用hdc -h或者hdc --help查看:

target mount

-

以读写模式挂载/system等分区

+

以读写模式挂载/vendor、/data等分区,因为安全性问题,需要挂在根目录或者/system分区
请单独使用'hdc_std shell mount -o rw,remount /'等命令

举例: hdc target mount

diff --git a/src/common/base.cpp b/src/common/base.cpp index a8c772a3..c81fcc75 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -689,7 +689,8 @@ namespace Base { WRITE_LOG(LOG_FATAL, "Tmppath failed"); return ERR_API_FAIL; } - if (snprintf_s(bufPath, sizeof(bufPath), sizeof(bufPath) - 1, "%s/.%s.pid", buf, procname) < 0) { + if (snprintf_s(bufPath, sizeof(bufPath), sizeof(bufPath) - 1, "%s%c.%s.pid", buf, Base::GetPathSep(), procname) + < 0) { return ERR_BUF_OVERFLOW; } int pid = static_cast(getpid()); diff --git a/src/common/file.cpp b/src/common/file.cpp index 8bb9ead1..4e3cd905 100644 --- a/src/common/file.cpp +++ b/src/common/file.cpp @@ -34,9 +34,6 @@ void HdcFile::StopTask() singalStop = true; }; -// Send supported below styles -// send|recv path/filename path/filename -// send|recv filename path bool HdcFile::BeginTransfer(CtxFile *context, const string &command) { int argc = 0; @@ -82,11 +79,15 @@ bool HdcFile::SetMasterParameters(CtxFile *context, const char *command, int arg context->transferConfig.updateIfNew = true; ++srcArgvIndex; } else if (argv[i] == CMD_OPTION_TSTMP) { + // The time zone difference may cause the display time on the PC and the + // device to differ by several hours + // + // ls -al --full-time context->transferConfig.holdTimestamp = true; ++srcArgvIndex; } else if (argv[i] == CMD_OPTION_CLIENTCWD) { context->transferConfig.clientCwd = argv[i + 1]; - srcArgvIndex += CMD_ARG1_COUNT; // skip 2args + srcArgvIndex += CMD_ARG1_COUNT; // skip 2args } else if (argv[i][0] == '-') { LogMsg(MSG_FAIL, "Unknow file option: %s", argv[i]); return false; diff --git a/src/daemon/daemon_app.cpp b/src/daemon/daemon_app.cpp index 2f8edf24..4f04dc93 100644 --- a/src/daemon/daemon_app.cpp +++ b/src/daemon/daemon_app.cpp @@ -65,7 +65,7 @@ bool HdcDaemonApp::CommandDispatch(const uint16_t command, uint8_t *payload, con size_t size = 256; uv_os_tmpdir(tmpPath, &size); dstPath = tmpPath; - dstPath += PREF_SEPARATOR; + dstPath += Base::GetPathSep(); #endif dstPath += ctxNow.transferConfig.optionalName; ctxNow.localPath = dstPath; diff --git a/src/host/client.cpp b/src/host/client.cpp index e1f79449..e7a6d359 100644 --- a/src/host/client.cpp +++ b/src/host/client.cpp @@ -46,7 +46,7 @@ uint32_t HdcClient::GetLastPID() WRITE_LOG(LOG_FATAL, "Tmppath failed"); return 0; } - string path = Base::StringFormat("%s/.%s.pid", bufPath, SERVER_NAME.c_str()); + string path = Base::StringFormat("%s%c.%s.pid", bufPath, Base::GetPathSep(), SERVER_NAME.c_str()); Base::ReadBinFile(path.c_str(), (void **)&pidBuf, BUF_SIZE_TINY); int pid = atoi(pidBuf); // pid maybe 0 return pid; diff --git a/src/host/server.cpp b/src/host/server.cpp index fef638b7..a278c6a1 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -471,12 +471,9 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const case CMD_KERNEL_CHANNEL_CLOSE: { WRITE_LOG(LOG_DEBUG, "CMD_KERNEL_CHANNEL_CLOSE channelid:%d", channelId); ClearOwnTasks(hSession, channelId); - auto funcChannleClose = [](uv_handle_t *handle) -> void { - HChannel hChannel = (HChannel)handle->data; - HdcServerForClient *sfc = static_cast(hChannel->clsChannel); - sfc->FreeChannel(hChannel->channelId); - }; - Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP, funcChannleClose); + // Forcibly closing the tcp handle here may result in incomplete data reception on the client side + HdcServerForClient *sfc = static_cast(hChannel->clsChannel); + sfc->FreeChannel(hChannel->channelId); if (*payload) { --(*payload); Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); diff --git a/src/host/server_for_client.cpp b/src/host/server_for_client.cpp index 1d1b09ed..0ac6c43d 100644 --- a/src/host/server_for_client.cpp +++ b/src/host/server_for_client.cpp @@ -426,18 +426,16 @@ bool HdcServerForClient::TaskCommand(HChannel hChannel, void *formatCommandInput cmdFlag = "sideload "; sizeCmdFlag = 9; } + uint8_t *payload = reinterpret_cast(const_cast(formatCommand->parameters.c_str())) + sizeCmdFlag; if (!strncmp(formatCommand->parameters.c_str(), cmdFlag.c_str(), sizeCmdFlag)) { // local do HSession hSession = FindAliveSession(hChannel->targetSessionId); if (!hSession) { return false; } ptrServer->DispatchTaskData(hSession, hChannel->channelId, formatCommand->cmdFlag, - reinterpret_cast(const_cast(formatCommand->parameters.c_str())) + sizeCmdFlag, - sizeSend - sizeCmdFlag); + payload, sizeSend - sizeCmdFlag); } else { // Send to Daemon-side to do - SendToDaemon(hChannel, formatCommand->cmdFlag, - reinterpret_cast(const_cast(formatCommand->parameters.c_str())) + sizeCmdFlag, - sizeSend - sizeCmdFlag); + SendToDaemon(hChannel, formatCommand->cmdFlag, payload, sizeSend - sizeCmdFlag); } return true; } -- Gitee From 0c0efa3c63bd98441617b8af8f20bc92e39cfc8e Mon Sep 17 00:00:00 2001 From: zhaifenghw Date: Fri, 5 Nov 2021 16:55:02 +0800 Subject: [PATCH 03/15] sync jdwp fix Signed-off-by: zhaifenghw Signed-off-by: zako --- src/daemon/jdwp.cpp | 54 ++++++++++++++++++--------------------------- src/daemon/jdwp.h | 4 +--- 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/src/daemon/jdwp.cpp b/src/daemon/jdwp.cpp index 525db5a0..7a3b1526 100644 --- a/src/daemon/jdwp.cpp +++ b/src/daemon/jdwp.cpp @@ -80,43 +80,31 @@ void HdcJdwp::FreeContext(HCtxJdwp ctx) void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) { - bool ret = false; + bool ret = true; HCtxJdwp ctxJdwp = (HCtxJdwp)pipe->data; HdcJdwp *thisClass = (HdcJdwp *)ctxJdwp->thisClass; - char temp[5]; + char *p = ctxJdwp->buf; uint32_t pid = 0; - int offset = 0; - if (nread > 0) { - ctxJdwp->bufIndex += nread; + + if (nread == UV_ENOBUFS) { // It is definite enough, usually only 4 bytes + ret = false; + WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream IOBuf max"); + } else if (nread == 0) { + return; + } else if (nread < 0 || nread != 4) { // 4 : 4 bytes + ret = false; + WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream program exit pid:%d", ctxJdwp->pid); } - // read the PID as a 4-hexchar string - while (offset < ctxJdwp->bufIndex) { - if (nread == UV_ENOBUFS) { // It is definite enough, usually only 4 bytes - WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream IOBuf max"); - break; - } else if (nread == 0) { - ret = 0; - break; - } else if (nread < 0 || nread != 4) { // 4 : 4 bytes - WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream program exit pid:%d", ctxJdwp->pid); - break; + if (ret) { + pid = atoi(p); + if (pid > 0) { + WRITE_LOG(LOG_DEBUG, "JDWP accept pid:%d", pid); + ctxJdwp->pid = pid; + thisClass->AdminContext(OP_ADD, pid, ctxJdwp); + ret = true; } - int errCode = memcpy_s(temp, sizeof(temp), ctxJdwp->buf + offset, 4); // 4 : 4 bytes - if (errCode != EOK) { - break; - } - temp[4] = 0; // 4 : pid length - if (sscanf_s(temp, "%04x", &pid) != 1) { - WRITE_LOG(LOG_WARN, "could not decode PID number: '%s'", temp); - break; - } - WRITE_LOG(LOG_DEBUG, "JDWP accept pid:%d", pid); - ctxJdwp->pid = pid; - thisClass->AdminContext(OP_ADD, pid, ctxJdwp); - offset += 4; // 4 : 4 bytes - ret = true; - break; // just 4bytes, now finish } + Base::ZeroArray(ctxJdwp->buf); if (!ret) { thisClass->FreeContext(ctxJdwp); } @@ -138,8 +126,8 @@ void HdcJdwp::AcceptClient(uv_stream_t *server, int status) } auto funAlloc = [](uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf) -> void { HCtxJdwp ctxJdwp = (HCtxJdwp)handle->data; - buf->base = (char *)ctxJdwp->buf + ctxJdwp->bufIndex; - buf->len = sizeof(ctxJdwp->buf) - ctxJdwp->bufIndex; + buf->base = (char *)ctxJdwp->buf ; + buf->len = sizeof(ctxJdwp->buf); }; uv_read_start((uv_stream_t *)&ctxJdwp->pipe, funAlloc, ReadStream); } diff --git a/src/daemon/jdwp.h b/src/daemon/jdwp.h index d885f6bc..93b3b902 100644 --- a/src/daemon/jdwp.h +++ b/src/daemon/jdwp.h @@ -35,9 +35,7 @@ private: uv_pipe_t pipe; HdcJdwp *thisClass; bool finish; - uint8_t buf[16]; // read read 4 bytes ascii - uint8_t bufIndex; - + char buf[sizeof(uint32_t)]; uint8_t dummy; uv_tcp_t jvmTCP; }; -- Gitee From 04ec74f4fca7f82cf4b841fe4971c2eae5c89ab6 Mon Sep 17 00:00:00 2001 From: zako Date: Sat, 6 Nov 2021 01:13:46 +0800 Subject: [PATCH 04/15] remove blank link Signed-off-by: zako Signed-off-by: zako --- README_zh.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_zh.md b/README_zh.md index 03fae843..bd233dc8 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,6 +1,6 @@ # HDC-OpenHarmony设备连接器 -- [HDC-OpenHarmony设备连接器](#hdc-openharmony设备连接器) +- [HDC-OpenHarmony设备连接器](#) - [简介](#简介) - [架构](#架构) - [目录](#目录) -- Gitee From 9fb75802b6683e72cd299f205202707cda74f613 Mon Sep 17 00:00:00 2001 From: zako Date: Wed, 10 Nov 2021 11:43:35 +0800 Subject: [PATCH 05/15] fix nlp Signed-off-by: zako Signed-off-by: zako --- src/common/define.h | 2 +- src/daemon/daemon.cpp | 4 ++-- src/daemon/daemon_usb.cpp | 2 +- src/host/host_usb.cpp | 8 -------- src/host/server.cpp | 2 +- 5 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/common/define.h b/src/common/define.h index abbd2b88..20ba5181 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -22,7 +22,7 @@ constexpr uint8_t MINOR_TIMEOUT = 5; constexpr uint8_t SIZE_THREAD_POOL = 16; constexpr uint8_t GLOBAL_TIMEOUT = 30; constexpr uint16_t DEFAULT_PORT = 8710; -constexpr uint16_t MAX_SIZE_IOBUF = 5120; // USB EP block max size about 10k +constexpr uint16_t MAX_SIZE_IOBUF = 5120; // USB EP block max size about 10k, USBFFS_BULKSIZE 16384 constexpr bool ENABLE_IO_CHECKSUM = false; const string DEFAULT_SERVER_ADDR = "127.0.0.1:8710"; diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index eb8ba1a8..b3a28a44 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -244,7 +244,7 @@ bool HdcDaemon::FetchCommand(HSession hSession, const uint32_t channelId, const } case CMD_KERNEL_CHANNEL_CLOSE: { // Daemon is only cleaning up the Channel task ClearOwnTasks(hSession, channelId); - if (*payload) { + if (*payload == 1) { --(*payload); Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); } @@ -293,7 +293,7 @@ bool HdcDaemon::ServerCommand(const uint32_t sessionId, const uint32_t channelId void HdcDaemon::JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO) { uint32_t pid = *(uint32_t *)(buf + 1); - uint32_t fd = *(uint32_t *)(buf + 5); // 5 : fd offset + uint32_t fd = *(uint32_t *)(buf + 5); // 5 : fd offset ((HdcJdwp *)clsJdwp)->SendJdwpNewFD(pid, fd); }; } // namespace Hdc diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 0bf6316a..6f5a33b6 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -249,7 +249,7 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t WRITE_LOG(LOG_DEBUG, "BulkinWrite write EINTR, try again"); continue; } else { - WRITE_LOG(LOG_DEBUG, "BulkinWrite write fatal errno %d", err); + WRITE_LOG(LOG_FATAL, "BulkinWrite write fatal errno %d", err); isAlive = false; } break; diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 40e01d92..2b9a9f6d 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -423,14 +423,6 @@ void LIBUSB_CALL HdcHostUSB::WriteUSBBulkCallback(struct libusb_transfer *transf USBHead *usbHead = reinterpret_cast(transfer->buffer); HSession hSession = reinterpret_cast(transfer->user_data); HdcSessionBase *server = reinterpret_cast(hSession->classInstance); - uint16_t zeroMask = hSession->hUSB->wMaxPacketSize - 1; - if (transfer->length != 0 && zeroMask != 0 && (transfer->length & zeroMask) == 0) { - // Zero packet - transfer->length = 0; - if (libusb_submit_transfer(transfer) == 0) { - return; - } - } if (usbHead->option & USB_OPTION_TAIL) { --hSession->sendRef; } diff --git a/src/host/server.cpp b/src/host/server.cpp index a278c6a1..e50f7f53 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -474,7 +474,7 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const // Forcibly closing the tcp handle here may result in incomplete data reception on the client side HdcServerForClient *sfc = static_cast(hChannel->clsChannel); sfc->FreeChannel(hChannel->channelId); - if (*payload) { + if (*payload == 1) { --(*payload); Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); } -- Gitee From 1955c0d1bd931139e0e2fa8670ad8f50c024334e Mon Sep 17 00:00:00 2001 From: zako Date: Fri, 12 Nov 2021 11:51:43 +0800 Subject: [PATCH 06/15] io size, session ref, USBHead htons Signed-off-by: zako Signed-off-by: zako --- src/common/base.cpp | 13 ++++--------- src/common/base.h | 8 ++++++++ src/common/define.h | 3 ++- src/common/file_descriptor.cpp | 2 +- src/common/session.cpp | 10 +++++++--- src/common/transfer.cpp | 7 ++++--- src/common/usb.cpp | 29 +++++++++++++++++++---------- src/daemon/daemon_usb.cpp | 15 ++++++--------- src/host/host_usb.cpp | 12 +++++------- 9 files changed, 56 insertions(+), 43 deletions(-) diff --git a/src/common/base.cpp b/src/common/base.cpp index c81fcc75..9719a8f3 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -183,14 +183,9 @@ namespace Base { return tmpString; } - int GetMaxBufSize() - { - return MAX_SIZE_IOBUF; - } - void SetTcpOptions(uv_tcp_t *tcpHandle) { - constexpr int maxBufFactor = 10; + constexpr int maxBufFactor = 8; if (!tcpHandle) { WRITE_LOG(LOG_WARN, "SetTcpOptions nullptr Ptr"); return; @@ -205,7 +200,7 @@ namespace Base { void ReallocBuf(uint8_t **origBuf, int *nOrigSize, const int indexUsedBuf, int sizeWanted) { - sizeWanted = GetMaxBufSize(); + sizeWanted = GetMaxBufSize() * 8; // socket-option buf size int remainLen = *nOrigSize - indexUsedBuf; // init:0, left less than expected if (!*nOrigSize || (remainLen < sizeWanted && (*nOrigSize + sizeWanted < sizeWanted * 2))) { @@ -1022,8 +1017,8 @@ namespace Base { const string StringFormat(const char * const formater, va_list &vaArgs) { - std::vector args(MAX_SIZE_IOBUF); - const int retSize = vsnprintf_s(args.data(), MAX_SIZE_IOBUF, args.size() - 1, formater, vaArgs); + std::vector args(GetMaxBufSize()); + const int retSize = vsnprintf_s(args.data(), GetMaxBufSize(), args.size() - 1, formater, vaArgs); if (retSize < 0) { return std::string(""); } else { diff --git a/src/common/base.h b/src/common/base.h index 74a1b336..29b55210 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -138,6 +138,14 @@ namespace Base { bool IsRoot(); char GetPathSep(); bool IsAbsolutePath(string &path); + inline int GetMaxBufSize() + { + return MAX_SIZE_IOBUF; + } + inline int GetUsbffsMaxBulkSize() + { + return USBFFS_BULKSIZE_MAX; + } } // namespace base } // namespace Hdc diff --git a/src/common/define.h b/src/common/define.h index 20ba5181..b7e924ec 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -22,7 +22,8 @@ constexpr uint8_t MINOR_TIMEOUT = 5; constexpr uint8_t SIZE_THREAD_POOL = 16; constexpr uint8_t GLOBAL_TIMEOUT = 30; constexpr uint16_t DEFAULT_PORT = 8710; -constexpr uint16_t MAX_SIZE_IOBUF = 5120; // USB EP block max size about 10k, USBFFS_BULKSIZE 16384 +constexpr uint16_t MAX_SIZE_IOBUF = 10240; // USB EP block max size. Should be less than USBFFS_BULKSIZE +constexpr uint16_t USBFFS_BULKSIZE_MAX = 16384; constexpr bool ENABLE_IO_CHECKSUM = false; const string DEFAULT_SERVER_ADDR = "127.0.0.1:8710"; diff --git a/src/common/file_descriptor.cpp b/src/common/file_descriptor.cpp index 61886062..2792c138 100644 --- a/src/common/file_descriptor.cpp +++ b/src/common/file_descriptor.cpp @@ -98,7 +98,7 @@ void HdcFileDescriptor::OnFileIO(uv_fs_t *req) int HdcFileDescriptor::LoopRead() { uv_buf_t iov; - int readMax = Base::GetMaxBufSize() * 1.2; + int readMax = Base::GetMaxBufSize() * 5; auto contextIO = new CtxFileIO(); auto buf = new uint8_t[readMax](); if (!contextIO || !buf) { diff --git a/src/common/session.cpp b/src/common/session.cpp index bef648a2..73bdc739 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -313,13 +313,14 @@ int HdcSessionBase::MallocSessionByConnectType(HSession hSession) } hSession->hUSB = hUSB; #ifdef HDC_HOST - constexpr auto maxBufFactor = 1.5; - int max = Base::GetMaxBufSize() * maxBufFactor + sizeof(USBHead); + int max = Base::GetUsbffsMaxBulkSize(); hUSB->sizeEpBuf = max; hUSB->bufDevice = new uint8_t[max](); hUSB->bufHost = new uint8_t[max](); hUSB->transferRecv = libusb_alloc_transfer(0); hUSB->transferSend = libusb_alloc_transfer(0); + hUSB->recvIOComplete = true; + hUSB->sendIOComplete = true; #else #endif break; @@ -589,7 +590,6 @@ int HdcSessionBase::SendByProtocol(HSession hSession, uint8_t *bufPtr, const int return ERR_SESSION_NOFOUND; } int ret = 0; - ++hSession->sendRef; switch (hSession->connType) { case CONN_TCP: { if (hSession->hWorkThread == uv_thread_self()) { @@ -602,6 +602,9 @@ int HdcSessionBase::SendByProtocol(HSession hSession, uint8_t *bufPtr, const int WRITE_LOG(LOG_FATAL, "SendByProtocol uncontrol send"); ret = ERR_API_FAIL; } + if (ret > 0) { + ++hSession->sendRef; + } break; } case CONN_USB: { @@ -720,6 +723,7 @@ int HdcSessionBase::FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read) int indexBuf = 0; int childRet = 0; if (read < 0) { + WRITE_LOG(LOG_FATAL, "HdcSessionBase read io failed,%s", uv_strerror(read)); return ERR_IO_FAIL; } hSession->availTailIndex += read; diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index fc983cfd..fca1fda0 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -200,8 +200,9 @@ void HdcTransferBase::OnFileIO(uv_fs_t *req) } if (context->indexIO < context->fileSize) { // read continue until result >0, let single file packet +packet header less than GetMaxBufSize() - constexpr auto maxBufFactor = 0.8; - thisClass->SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize() * maxBufFactor); + constexpr auto maxBufFactor = 0.9; + thisClass->SimpleFileIO(context, context->indexIO, nullptr, + Base::GetUsbffsMaxBulkSize() * maxBufFactor); } } else if (req->fs_type == UV_FS_WRITE) { // write if (context->indexIO >= context->fileSize) { @@ -389,7 +390,7 @@ bool HdcTransferBase::CommandDispatch(const uint16_t command, uint8_t *payload, } else if (command == commandData) { // The size of the actual HOST end may be larger than maxbuf constexpr auto doubleSize = 2; - if (payloadSize > MAX_SIZE_IOBUF * doubleSize || payloadSize < 0) { + if (payloadSize > Base::GetMaxBufSize() * doubleSize || payloadSize < 0) { ret = false; break; } diff --git a/src/common/usb.cpp b/src/common/usb.cpp index db39a445..3131b2ac 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -61,12 +61,16 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) { // Format:USBPacket1 payload1...USBPacketn payloadn; // [USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] - int maxIOSize = Base::GetMaxBufSize(); + // + // I hope the size is GetUsbffsMaxBulkSize, but after exceeding 12k, if the split-package is too large, libusb will + // report an error when send callback. I don't know why... + constexpr int maxIOSize = 12000; int sizeUSBPacketHead = sizeof(USBHead); int singleSize = maxIOSize - sizeUSBPacketHead; int iMod = length % singleSize; int iCount = (length - iMod) / singleSize + 1; int offset = 0; + int dataSize = 0; int i = 0; // It doesn't matter of 0 or 1, start from 1 to send it according to the serial number. uint8_t *ioBuf = new uint8_t[maxIOSize](); if (!ioBuf) { @@ -79,20 +83,22 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) offset = ERR_BUF_COPY; break; } - pUSBHead->sessionId = hSession->sessionId; + pUSBHead->sessionId = htonl(hSession->sessionId); if (i != iCount - 1) { - pUSBHead->dataSize = static_cast(singleSize); + dataSize = singleSize; } else { - pUSBHead->dataSize = static_cast(iMod); + dataSize = iMod; pUSBHead->option = pUSBHead->option | USB_OPTION_TAIL; } + pUSBHead->dataSize = htons(static_cast(dataSize)); uint8_t *payload = ioBuf + sizeUSBPacketHead; - if (EOK != memcpy_s(payload, maxIOSize - sizeUSBPacketHead, (uint8_t *)data + offset, pUSBHead->dataSize)) { + if (EOK != memcpy_s(payload, maxIOSize - sizeUSBPacketHead, (uint8_t *)data + offset, dataSize)) { offset = ERR_BUF_COPY; break; } - offset += pUSBHead->dataSize; - if (SendUSBRaw(hSession, ioBuf, sizeUSBPacketHead + pUSBHead->dataSize) <= 0) { + offset += dataSize; + ++hSession->sendRef; + if (SendUSBRaw(hSession, ioBuf, sizeUSBPacketHead + dataSize) <= 0) { offset = ERR_IO_FAIL; break; } @@ -110,12 +116,14 @@ int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t while (bufRecv.size() > sizeof(USBHead)) { USBHead *usbHeader = (USBHead *)bufRecv.data(); if (memcmp(usbHeader->flag, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { - WRITE_LOG(LOG_FATAL, "Error usb packet"); ret = ERR_BUF_CHECK; break; } + usbHeader->sessionId = ntohl(usbHeader->sessionId); + usbHeader->dataSize = ntohs(usbHeader->dataSize); if (bufRecv.size() < sizeof(USBHead) + usbHeader->dataSize) { - WRITE_LOG(LOG_DEBUG, "SendToHdcStream not enough"); + WRITE_LOG(LOG_DEBUG, "SendToHdcStream not enough dataSize:%d bufRecvSize:%d", usbHeader->dataSize, + bufRecv.size()); break; // successful , but not enough } if (usbHeader->sessionId != hSession->sessionId) { @@ -133,7 +141,8 @@ int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t // usb data to logic if (Base::SendToStream(stream, bufRecv.data() + sizeof(USBHead), usbHeader->dataSize) < 0) { ret = ERR_IO_FAIL; - WRITE_LOG(LOG_FATAL, "Error usb send to stream"); + WRITE_LOG(LOG_FATAL, "Error usb send to stream dataSize:%d bufRecvSize:%d", usbHeader->dataSize, + bufRecv.size()); break; } } diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 6f5a33b6..869d4541 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -186,16 +186,16 @@ int HdcDaemonUSB::AvailablePacket(uint8_t *ioBuf, uint32_t *sessionId) ret = ERR_BUF_CHECK; break; } - if (usbPayloadHeader->dataSize > MAX_SIZE_IOBUF * maxBufFactor + sizeof(USBHead)) { + if (ntohs(usbPayloadHeader->dataSize) > Base::GetMaxBufSize() * maxBufFactor + sizeof(USBHead)) { ret = ERR_BUF_SIZE; break; } if ((usbPayloadHeader->option & USB_OPTION_RESET)) { - ResetOldSession(usbPayloadHeader->sessionId); + ResetOldSession(ntohl(usbPayloadHeader->sessionId)); ret = ERR_IO_SOFT_RESET; break; } - *sessionId = usbPayloadHeader->sessionId; + *sessionId = ntohl(usbPayloadHeader->sessionId); break; } return ret; @@ -242,6 +242,7 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t int ret = ERR_IO_FAIL; int offset = 0; while (modRunning && isAlive && !hSession->isDead && !hSession->hUSB->resetIO) { + // WRITE_LOG(LOG_DEBUG, "BulkinWrite write.length:%d", length); childRet = write(bulkIn, (uint8_t *)data + offset, length - offset); if (childRet <= 0) { int err = errno; @@ -266,11 +267,7 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t "BulkinWrite write failed, nsize:%d really:%d modRunning:%d isAlive:%d SessionDead:%d usbReset:%d", length, offset, modRunning, isAlive, hSession->isDead, hSession->hUSB->resetIO); } - USBHead *pUSBHead = (USBHead *)data; - if ((pUSBHead->option & USB_OPTION_TAIL) || ret < 0) { - // tail or failed, dec Ref - hSession->sendRef--; - } + hSession->sendRef--; return ret; } @@ -427,7 +424,7 @@ int HdcDaemonUSB::LoopUSBRead(HUSB hUSB) int ret = -1; HdcDaemon *daemon = reinterpret_cast(clsMainBase); // must > available size, or it will be incorrect - int readMax = Base::GetMaxBufSize() + sizeof(USBHead) + EXTRA_ALLOC_SIZE; + int readMax = Base::GetUsbffsMaxBulkSize(); auto ctxIo = new CtxUvFileCommonIo(); auto buf = new uint8_t[readMax](); uv_fs_t *req = nullptr; diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 2b9a9f6d..a740a7ff 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -73,7 +73,7 @@ void HdcHostUSB::SendUsbSoftReset(HUSB hUSB, uint32_t sessionId) USBHead &usbPayloadHeader = ctxReset->usbPayloadHeader; usbPayloadHeader.option = USB_OPTION_RESET; - usbPayloadHeader.sessionId = sessionId; + usbPayloadHeader.sessionId = htonl(sessionId); if (memcpy_s(usbPayloadHeader.flag, sizeof(usbPayloadHeader.flag), PACKET_FLAG.c_str(), sizeof(usbPayloadHeader.flag)) != EOK) { @@ -420,12 +420,9 @@ int HdcHostUSB::OpenDeviceMyNeed(HUSB hUSB) // at main thread void LIBUSB_CALL HdcHostUSB::WriteUSBBulkCallback(struct libusb_transfer *transfer) { - USBHead *usbHead = reinterpret_cast(transfer->buffer); HSession hSession = reinterpret_cast(transfer->user_data); HdcSessionBase *server = reinterpret_cast(hSession->classInstance); - if (usbHead->option & USB_OPTION_TAIL) { - --hSession->sendRef; - } + --hSession->sendRef; if (LIBUSB_TRANSFER_COMPLETED != transfer->status || (hSession->isDead && 0 == hSession->sendRef)) { WRITE_LOG(LOG_FATAL, "SendUSBRaw status:%d", transfer->status); if (hSession->hUSB->transferRecv != nullptr) { @@ -444,14 +441,14 @@ int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) int ret = ERR_GENERIC; int childRet = -1; HUSB hUSB = hSession->hUSB; + hUSB->sendIOComplete = false; while (true) { - if (memcpy_s(hUSB->bufHost, length, data, length) != EOK) { + if (memcpy_s(hUSB->bufHost, hUSB->sizeEpBuf, data, length) != EOK) { ret = ERR_BUF_COPY; break; } hUSB->lockDeviceHandle.lock(); std::unique_lock lock(hUSB->lockSend); - hUSB->sendIOComplete = false; libusb_fill_bulk_transfer(hUSB->transferSend, hUSB->devHandle, hUSB->epHost, hUSB->bufHost, length, WriteUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); childRet = libusb_submit_transfer(hUSB->transferSend); @@ -466,6 +463,7 @@ int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) } if (ret < 0) { --hSession->sendRef; + hSession->hUSB->sendIOComplete = true; if (hUSB->transferRecv != nullptr) { libusb_cancel_transfer(hUSB->transferRecv); } -- Gitee From 104382381e6a54d6c84a566811a337f3f26e999c Mon Sep 17 00:00:00 2001 From: zako Date: Fri, 12 Nov 2021 11:54:47 +0800 Subject: [PATCH 07/15] Error usb packet tips Signed-off-by: zako Signed-off-by: zako --- src/common/usb.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/usb.cpp b/src/common/usb.cpp index 3131b2ac..2244e2bd 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -116,6 +116,7 @@ int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t while (bufRecv.size() > sizeof(USBHead)) { USBHead *usbHeader = (USBHead *)bufRecv.data(); if (memcmp(usbHeader->flag, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { + WRITE_LOG(LOG_FATAL, "Error usb packet"); ret = ERR_BUF_CHECK; break; } -- Gitee From 6c2f124afc9203571326b47f16b2b79733d06538 Mon Sep 17 00:00:00 2001 From: zhaifenghw Date: Fri, 12 Nov 2021 15:49:08 +0800 Subject: [PATCH 08/15] enable log printing Signed-off-by: zhaifenghw Signed-off-by: zako --- README_zh.md | 2 +- src/common/base.cpp | 45 +++++++++++++++++++++++++++--- src/common/base.h | 2 ++ src/common/define.h | 5 ++-- src/common/define_plus.h | 1 + src/common/forward.cpp | 51 ++++++++++++++++++++++++++++++++-- src/common/forward.h | 1 + src/daemon/daemon.cpp | 4 +-- src/daemon/daemon_usb.cpp | 2 +- src/daemon/main.cpp | 1 + src/host/client.cpp | 2 +- src/host/host_usb.cpp | 8 ------ src/host/main.cpp | 3 ++ src/host/server.cpp | 2 +- src/host/server_for_client.cpp | 7 +++-- src/host/translate.cpp | 6 ++-- 16 files changed, 113 insertions(+), 29 deletions(-) diff --git a/README_zh.md b/README_zh.md index ecbfc53c..bd233dc8 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,6 +1,6 @@ # HDC-OpenHarmony设备连接器 -- [HDC-OpenHarmony设备连接器](#hdc-OpenHarmony设备连接器) +- [HDC-OpenHarmony设备连接器](#) - [简介](#简介) - [架构](#架构) - [目录](#目录) diff --git a/src/common/base.cpp b/src/common/base.cpp index c81fcc75..b31c8a42 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -117,15 +117,16 @@ namespace Base { void PrintLogEx(const char *functionName, int line, uint8_t logLevel, const char *msg, ...) { + if (logLevel > g_logLevel) { + return; + } string debugInfo; string logBuf; string logLevelString; string threadIdString; string sep = "\n"; string timeString; - if (logLevel > g_logLevel) { - return; - } + va_list vaArgs; va_start(vaArgs, msg); string logDetail = Base::StringFormat(msg, vaArgs); @@ -142,7 +143,8 @@ namespace Base { printf("%s", logBuf.c_str()); fflush(stdout); // logfile, not thread-safe - FILE *fp = fopen("/data/local/tmp/hdc.log", "a"); + string path = GetTmpDir() + LOG_FILE_NAME; + FILE *fp = fopen(path.c_str(), "a"); if (fp == nullptr) { return; } @@ -1179,6 +1181,41 @@ namespace Base { return ret; } + string GetCwd() + { + char path[PATH_MAX] = ""; + size_t size = sizeof(path); + string res; + if (uv_cwd(path, &size) < 0) { + return res; + } + if (path[strlen(path) - 1] != Base::GetPathSep()) { + path[strlen(path)] = Base::GetPathSep(); + } + res = path; + return res; + } + + string GetTmpDir() + { + string res; +#ifdef HDC_HOST + char path[PATH_MAX] = ""; + size_t size = sizeof(path); + if (uv_os_tmpdir(path, &size) < 0) { + WRITE_LOG(LOG_FATAL, "get tmppath failed!"); + return res; + } + if (path[strlen(path) - 1] != Base::GetPathSep()) { + path[strlen(path)] = Base::GetPathSep(); + } + res = path; +#else + res = "/data/local/tmp/"; +#endif + return res; + } + bool IsRoot() { #ifdef _WIN32 diff --git a/src/common/base.h b/src/common/base.h index 74a1b336..9a6b12be 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -133,6 +133,8 @@ namespace Base { string ReplaceAll(string str, const string from, const string to); uint8_t CalcCheckSum(const uint8_t *data, int len); string GetFileNameAny(string &path); + string GetCwd(); + string GetTmpDir(); uv_os_sock_t DuplicateUvSocket(uv_tcp_t *tcp); vector Md5Sum(uint8_t *buf, int size); bool IsRoot(); diff --git a/src/common/define.h b/src/common/define.h index abbd2b88..46b5ca3d 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -22,7 +22,7 @@ constexpr uint8_t MINOR_TIMEOUT = 5; constexpr uint8_t SIZE_THREAD_POOL = 16; constexpr uint8_t GLOBAL_TIMEOUT = 30; constexpr uint16_t DEFAULT_PORT = 8710; -constexpr uint16_t MAX_SIZE_IOBUF = 5120; // USB EP block max size about 10k +constexpr uint16_t MAX_SIZE_IOBUF = 5120; // USB EP block max size about 10k, USBFFS_BULKSIZE 16384 constexpr bool ENABLE_IO_CHECKSUM = false; const string DEFAULT_SERVER_ADDR = "127.0.0.1:8710"; @@ -46,11 +46,12 @@ constexpr uint16_t UV_DEFAULT_INTERVAL = 250; // ms constexpr uint16_t VER_PROTOCOL = 0x01; constexpr uint16_t EXTRA_ALLOC_SIZE = 2048; // double-word(hex)=[0]major[1][2]minor[3][4]version[5]fix(a-p)[6][7]reserve -constexpr uint32_t HDC_VERSION_NUMBER = 0x10101700; // 1.1.1b=0x10101100 +constexpr uint32_t HDC_VERSION_NUMBER = 0x10101800; // 1.1.1b=0x10101100 constexpr uint32_t HDC_BUF_MAX_BYTES = 1024000000; const string WHITE_SPACES = " \t\n\r"; const string UT_TMP_PATH = "/tmp/hdc-ut"; +const string LOG_FILE_NAME = "hdc.log"; const string SERVER_NAME = "HDCServer"; const string STRING_EMPTY = ""; const string HANDSHAKE_MESSAGE = "OHOS HDC"; // sep not char '-', not more than 11 bytes diff --git a/src/common/define_plus.h b/src/common/define_plus.h index 2327346f..d2bc938d 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -16,6 +16,7 @@ #define DEFINE_PLUS_H namespace Hdc { +constexpr uint8_t LOG_LEVEL_FULL = 5; // ############################# enum define ################################### enum LogLevel { LOG_OFF, diff --git a/src/common/forward.cpp b/src/common/forward.cpp index 54c99108..b096cbb9 100644 --- a/src/common/forward.cpp +++ b/src/common/forward.cpp @@ -309,8 +309,9 @@ bool HdcForwardBase::DetechForwardType(HCtxForward ctxPoint) } else if (sFType == "dev") { ctxPoint->type = FORWARD_DEVICE; } else if (sFType == "localabstract") { - // daemon shell: /system/bin/socat unix-listen:/tmp/unix.socket - - // host: hdc_std fport tcp:8080 localabstract:/tmp/unix.socket + // daemon shell: /system/bin/socat abstract-listen:linux-abstract - + // daemon shell: /system/bin/socat - abstract-connect:linux-abstract + // host: hdc_std fport tcp:8080 localabstract:linux-abstract ctxPoint->type = FORWARD_ABSTRACT; } else if (sFType == "localreserved") { sNodeCfg = HARMONY_RESERVED_SOCKET_PREFIX + sNodeCfg; @@ -373,6 +374,41 @@ bool HdcForwardBase::SetupDevicePoint(HCtxForward ctxPoint) return true; } +bool HdcForwardBase::LocalAbstractConnect(uv_pipe_t *pipe, string &sNodeCfg) +{ + bool abstractRet = false; +#ifndef _WIN32 + int s = 0; + do { + if ((s = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) { + break; + } + fcntl(s, F_SETFD, FD_CLOEXEC); + struct sockaddr_un addr; + Base::ZeroStruct(addr); + int addrLen = sNodeCfg.size() + offsetof(struct sockaddr_un, sun_path) + 1; + addr.sun_family = AF_LOCAL; + addr.sun_path[0] = 0; + + if (memcpy_s(addr.sun_path + 1, sizeof(addr.sun_path) - 1, sNodeCfg.c_str(), sNodeCfg.size()) != EOK) { + break; + }; + // local connect, ignore timeout + if (connect(s, (struct sockaddr *)&addr, addrLen) < 0) { + break; + } + if (uv_pipe_open(pipe, s)) { + break; + } + abstractRet = true; + } while (false); + if (!abstractRet && s > 0) { + close(s); + } +#endif + return abstractRet; +} + bool HdcForwardBase::SetupFilePoint(HCtxForward ctxPoint) { string &sNodeCfg = ctxPoint->localArgs[1]; @@ -393,7 +429,16 @@ bool HdcForwardBase::SetupFilePoint(HCtxForward ctxPoint) } else { uv_connect_t *connect = new uv_connect_t(); connect->data = ctxPoint; - uv_pipe_connect(connect, &ctxPoint->pipe, sNodeCfg.c_str(), ConnectTarget); + if (ctxPoint->type == FORWARD_ABSTRACT) { + bool abstractRet = LocalAbstractConnect(&ctxPoint->pipe, sNodeCfg); + SetupPointContinue(ctxPoint, abstractRet ? 0 : -1); + if (!abstractRet) { + ctxPoint->lastError = "LocalAbstractConnect failed"; + return false; + } + } else { + uv_pipe_connect(connect, &ctxPoint->pipe, sNodeCfg.c_str(), ConnectTarget); + } } return true; } diff --git a/src/common/forward.h b/src/common/forward.h index 5bc1cfb6..9baf4702 100644 --- a/src/common/forward.h +++ b/src/common/forward.h @@ -93,6 +93,7 @@ private: bool SetupFilePoint(HCtxForward ctxPoint); bool ForwardCommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); bool CommandForwardCheckResult(HCtxForward ctx, uint8_t *payload); + bool LocalAbstractConnect(uv_pipe_t *pipe, string &sNodeCfg); map mapCtxPoint; string taskCommand; diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index eb8ba1a8..b3a28a44 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -244,7 +244,7 @@ bool HdcDaemon::FetchCommand(HSession hSession, const uint32_t channelId, const } case CMD_KERNEL_CHANNEL_CLOSE: { // Daemon is only cleaning up the Channel task ClearOwnTasks(hSession, channelId); - if (*payload) { + if (*payload == 1) { --(*payload); Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); } @@ -293,7 +293,7 @@ bool HdcDaemon::ServerCommand(const uint32_t sessionId, const uint32_t channelId void HdcDaemon::JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO) { uint32_t pid = *(uint32_t *)(buf + 1); - uint32_t fd = *(uint32_t *)(buf + 5); // 5 : fd offset + uint32_t fd = *(uint32_t *)(buf + 5); // 5 : fd offset ((HdcJdwp *)clsJdwp)->SendJdwpNewFD(pid, fd); }; } // namespace Hdc diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 0bf6316a..6f5a33b6 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -249,7 +249,7 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t WRITE_LOG(LOG_DEBUG, "BulkinWrite write EINTR, try again"); continue; } else { - WRITE_LOG(LOG_DEBUG, "BulkinWrite write fatal errno %d", err); + WRITE_LOG(LOG_FATAL, "BulkinWrite write fatal errno %d", err); isAlive = false; } break; diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 883c4af4..fcd82e87 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -164,6 +164,7 @@ int main(int argc, const char *argv[]) return 0; } if (argc == 1 || (argc == CMD_ARG1_COUNT && (!strcmp(argv[1], "-forkchild") || !strcmp(argv[1], "-b")))) { + Base::SetLogLevel(LOG_LEVEL_FULL); ForkChildCheck(argc, argv); } else { GetDaemonCommandlineOptions(argc, argv); diff --git a/src/host/client.cpp b/src/host/client.cpp index e7a6d359..5c899409 100644 --- a/src/host/client.cpp +++ b/src/host/client.cpp @@ -322,7 +322,7 @@ int HdcClient::PreHandshake(HChannel hChannel, const uint8_t *buf) #ifdef HDC_CHANNEL_KEEP_ALIVE // Evaluation method, non long-term support Send(hChannel->channelId, reinterpret_cast(CMDSTR_INNER_ENABLE_KEEPALIVE.c_str()), - CMDSTR_INNER_ENABLE_KEEPALIVE.size()); + CMDSTR_INNER_ENABLE_KEEPALIVE.size()); #endif return RET_SUCCESS; } diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 40e01d92..2b9a9f6d 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -423,14 +423,6 @@ void LIBUSB_CALL HdcHostUSB::WriteUSBBulkCallback(struct libusb_transfer *transf USBHead *usbHead = reinterpret_cast(transfer->buffer); HSession hSession = reinterpret_cast(transfer->user_data); HdcSessionBase *server = reinterpret_cast(hSession->classInstance); - uint16_t zeroMask = hSession->hUSB->wMaxPacketSize - 1; - if (transfer->length != 0 && zeroMask != 0 && (transfer->length & zeroMask) == 0) { - // Zero packet - transfer->length = 0; - if (libusb_submit_transfer(transfer) == 0) { - return; - } - } if (usbHead->option & USB_OPTION_TAIL) { --hSession->sendRef; } diff --git a/src/host/main.cpp b/src/host/main.cpp index 14c39c39..ce10d565 100644 --- a/src/host/main.cpp +++ b/src/host/main.cpp @@ -28,6 +28,7 @@ static bool g_isServerMode = false; static bool g_isPullServer = true; static bool g_isPcDebugRun = false; static bool g_isTCPorUSB = false; +static auto g_logLevel = LOG_LEVEL_FULL; static int g_isTestMethod = 0; static string g_connectKey = ""; static string g_serverListenString = DEFAULT_SERVER_ADDR; @@ -249,6 +250,7 @@ bool GetCommandlineOptions(int optArgc, const char *optArgv[]) needExit = true; return needExit; } + g_logLevel = logLevel; Base::SetLogLevel(logLevel); break; } @@ -319,6 +321,7 @@ int main(int argc, const char *argv[]) } if (g_isServerMode) { // -m server.Run alone in the background, no -s will be listen loopback address, + Base::SetLogLevel(g_logLevel); // default level LOG_LEVEL_FULL Hdc::RunServerMode(g_serverListenString); } else if (g_isPcDebugRun) { Hdc::RunPcDebugMode(g_isPullServer, g_isTCPorUSB, g_isTestMethod); diff --git a/src/host/server.cpp b/src/host/server.cpp index a278c6a1..e50f7f53 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -474,7 +474,7 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const // Forcibly closing the tcp handle here may result in incomplete data reception on the client side HdcServerForClient *sfc = static_cast(hChannel->clsChannel); sfc->FreeChannel(hChannel->channelId); - if (*payload) { + if (*payload == 1) { --(*payload); Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); } diff --git a/src/host/server_for_client.cpp b/src/host/server_for_client.cpp index 0ac6c43d..18abf088 100644 --- a/src/host/server_for_client.cpp +++ b/src/host/server_for_client.cpp @@ -432,8 +432,8 @@ bool HdcServerForClient::TaskCommand(HChannel hChannel, void *formatCommandInput if (!hSession) { return false; } - ptrServer->DispatchTaskData(hSession, hChannel->channelId, formatCommand->cmdFlag, - payload, sizeSend - sizeCmdFlag); + ptrServer->DispatchTaskData(hSession, hChannel->channelId, formatCommand->cmdFlag, payload, + sizeSend - sizeCmdFlag); } else { // Send to Daemon-side to do SendToDaemon(hChannel, formatCommand->cmdFlag, payload, sizeSend - sizeCmdFlag); } @@ -459,7 +459,8 @@ bool HdcServerForClient::DoCommandRemote(HChannel hChannel, void *formatCommandI case CMD_UNITY_ROOTRUN: case CMD_UNITY_JPID: { if (!SendToDaemon(hChannel, formatCommand->cmdFlag, - reinterpret_cast(const_cast(formatCommand->parameters.c_str())), sizeSend)) { + reinterpret_cast(const_cast(formatCommand->parameters.c_str())), + sizeSend)) { break; } ret = true; diff --git a/src/host/translate.cpp b/src/host/translate.cpp index 6a24b873..b335f74a 100644 --- a/src/host/translate.cpp +++ b/src/host/translate.cpp @@ -212,12 +212,12 @@ namespace TranslateCommand { } else if (!strcmp(input.c_str(), CMDSTR_SHELL.c_str())) { outCmd->cmdFlag = CMD_SHELL_INIT; } else if (!strncmp(input.c_str(), CMDSTR_FILE_SEND.c_str(), CMDSTR_FILE_SEND.size()) - || !strncmp(input.c_str(), CMDSTR_FILE_RECV.c_str(), CMDSTR_FILE_RECV.size())) { + || !strncmp(input.c_str(), CMDSTR_FILE_RECV.c_str(), CMDSTR_FILE_RECV.size())) { outCmd->cmdFlag = CMD_FILE_INIT; outCmd->parameters = input.c_str() + 5; // 5: CMDSTR_FORWARD_FPORT CMDSTR_FORWARD_RPORT size } else if (!strncmp(input.c_str(), string(CMDSTR_FORWARD_FPORT + " ").c_str(), CMDSTR_FORWARD_FPORT.size() + 1) - || !strncmp(input.c_str(), string(CMDSTR_FORWARD_RPORT + " ").c_str(), - CMDSTR_FORWARD_RPORT.size() + 1)) { + || !strncmp(input.c_str(), string(CMDSTR_FORWARD_RPORT + " ").c_str(), + CMDSTR_FORWARD_RPORT.size() + 1)) { stringError = ForwardPort(input.c_str(), outCmd); } else if (!strcmp(input.c_str(), CMDSTR_KILL_SERVER.c_str())) { outCmd->cmdFlag = CMD_KERNEL_SERVER_KILL; -- Gitee From d395ee8abb93b0d3c435ddbd133bdda7b4fe69ae Mon Sep 17 00:00:00 2001 From: zako Date: Sat, 13 Nov 2021 00:33:45 +0800 Subject: [PATCH 09/15] Fallback buffer size modification Signed-off-by: zako Signed-off-by: zako --- src/common/base.cpp | 4 ++-- src/common/define.h | 4 ++-- src/common/file_descriptor.cpp | 2 +- src/common/session.cpp | 3 ++- src/common/transfer.cpp | 5 ++--- src/common/usb.cpp | 5 +---- src/daemon/daemon_usb.cpp | 2 +- 7 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/common/base.cpp b/src/common/base.cpp index 9719a8f3..59a63b44 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -185,7 +185,7 @@ namespace Base { void SetTcpOptions(uv_tcp_t *tcpHandle) { - constexpr int maxBufFactor = 8; + constexpr int maxBufFactor = 10; if (!tcpHandle) { WRITE_LOG(LOG_WARN, "SetTcpOptions nullptr Ptr"); return; @@ -200,7 +200,7 @@ namespace Base { void ReallocBuf(uint8_t **origBuf, int *nOrigSize, const int indexUsedBuf, int sizeWanted) { - sizeWanted = GetMaxBufSize() * 8; // socket-option buf size + sizeWanted = GetMaxBufSize(); int remainLen = *nOrigSize - indexUsedBuf; // init:0, left less than expected if (!*nOrigSize || (remainLen < sizeWanted && (*nOrigSize + sizeWanted < sizeWanted * 2))) { diff --git a/src/common/define.h b/src/common/define.h index b7e924ec..18743178 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -22,7 +22,7 @@ constexpr uint8_t MINOR_TIMEOUT = 5; constexpr uint8_t SIZE_THREAD_POOL = 16; constexpr uint8_t GLOBAL_TIMEOUT = 30; constexpr uint16_t DEFAULT_PORT = 8710; -constexpr uint16_t MAX_SIZE_IOBUF = 10240; // USB EP block max size. Should be less than USBFFS_BULKSIZE +constexpr uint16_t MAX_SIZE_IOBUF = 5120; // USB EP block max size about 10k, USBFFS_BULKSIZE 16384 constexpr uint16_t USBFFS_BULKSIZE_MAX = 16384; constexpr bool ENABLE_IO_CHECKSUM = false; const string DEFAULT_SERVER_ADDR = "127.0.0.1:8710"; @@ -47,7 +47,7 @@ constexpr uint16_t UV_DEFAULT_INTERVAL = 250; // ms constexpr uint16_t VER_PROTOCOL = 0x01; constexpr uint16_t EXTRA_ALLOC_SIZE = 2048; // double-word(hex)=[0]major[1][2]minor[3][4]version[5]fix(a-p)[6][7]reserve -constexpr uint32_t HDC_VERSION_NUMBER = 0x10101700; // 1.1.1b=0x10101100 +constexpr uint32_t HDC_VERSION_NUMBER = 0x10101800; // 1.1.1b=0x10101100 constexpr uint32_t HDC_BUF_MAX_BYTES = 1024000000; const string WHITE_SPACES = " \t\n\r"; diff --git a/src/common/file_descriptor.cpp b/src/common/file_descriptor.cpp index 2792c138..61886062 100644 --- a/src/common/file_descriptor.cpp +++ b/src/common/file_descriptor.cpp @@ -98,7 +98,7 @@ void HdcFileDescriptor::OnFileIO(uv_fs_t *req) int HdcFileDescriptor::LoopRead() { uv_buf_t iov; - int readMax = Base::GetMaxBufSize() * 5; + int readMax = Base::GetMaxBufSize() * 1.2; auto contextIO = new CtxFileIO(); auto buf = new uint8_t[readMax](); if (!contextIO || !buf) { diff --git a/src/common/session.cpp b/src/common/session.cpp index 73bdc739..63c1f22b 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -313,7 +313,8 @@ int HdcSessionBase::MallocSessionByConnectType(HSession hSession) } hSession->hUSB = hUSB; #ifdef HDC_HOST - int max = Base::GetUsbffsMaxBulkSize(); + constexpr auto maxBufFactor = 1.5; + int max = Base::GetMaxBufSize() * maxBufFactor + sizeof(USBHead); hUSB->sizeEpBuf = max; hUSB->bufDevice = new uint8_t[max](); hUSB->bufHost = new uint8_t[max](); diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index fca1fda0..a10711e0 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -200,9 +200,8 @@ void HdcTransferBase::OnFileIO(uv_fs_t *req) } if (context->indexIO < context->fileSize) { // read continue until result >0, let single file packet +packet header less than GetMaxBufSize() - constexpr auto maxBufFactor = 0.9; - thisClass->SimpleFileIO(context, context->indexIO, nullptr, - Base::GetUsbffsMaxBulkSize() * maxBufFactor); + constexpr auto maxBufFactor = 0.8; + thisClass->SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize() * maxBufFactor); } } else if (req->fs_type == UV_FS_WRITE) { // write if (context->indexIO >= context->fileSize) { diff --git a/src/common/usb.cpp b/src/common/usb.cpp index 2244e2bd..e76b5053 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -61,10 +61,7 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) { // Format:USBPacket1 payload1...USBPacketn payloadn; // [USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] - // - // I hope the size is GetUsbffsMaxBulkSize, but after exceeding 12k, if the split-package is too large, libusb will - // report an error when send callback. I don't know why... - constexpr int maxIOSize = 12000; + int maxIOSize = Base::GetMaxBufSize(); int sizeUSBPacketHead = sizeof(USBHead); int singleSize = maxIOSize - sizeUSBPacketHead; int iMod = length % singleSize; diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 869d4541..61530344 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -424,7 +424,7 @@ int HdcDaemonUSB::LoopUSBRead(HUSB hUSB) int ret = -1; HdcDaemon *daemon = reinterpret_cast(clsMainBase); // must > available size, or it will be incorrect - int readMax = Base::GetUsbffsMaxBulkSize(); + int readMax = Base::GetMaxBufSize() + sizeof(USBHead) + EXTRA_ALLOC_SIZE; auto ctxIo = new CtxUvFileCommonIo(); auto buf = new uint8_t[readMax](); uv_fs_t *req = nullptr; -- Gitee From f74531912dcc489508025938e288a9294e403b10 Mon Sep 17 00:00:00 2001 From: zako Date: Sat, 13 Nov 2021 00:43:01 +0800 Subject: [PATCH 10/15] little change Signed-off-by: zako Signed-off-by: zako --- src/common/define.h | 2 +- src/daemon/daemon_usb.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/define.h b/src/common/define.h index 18743178..4706fcfe 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -47,7 +47,7 @@ constexpr uint16_t UV_DEFAULT_INTERVAL = 250; // ms constexpr uint16_t VER_PROTOCOL = 0x01; constexpr uint16_t EXTRA_ALLOC_SIZE = 2048; // double-word(hex)=[0]major[1][2]minor[3][4]version[5]fix(a-p)[6][7]reserve -constexpr uint32_t HDC_VERSION_NUMBER = 0x10101800; // 1.1.1b=0x10101100 +constexpr uint32_t HDC_VERSION_NUMBER = 0x10101900; // 1.1.1b=0x10101100 constexpr uint32_t HDC_BUF_MAX_BYTES = 1024000000; const string WHITE_SPACES = " \t\n\r"; diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 61530344..0c598f26 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -242,7 +242,6 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t int ret = ERR_IO_FAIL; int offset = 0; while (modRunning && isAlive && !hSession->isDead && !hSession->hUSB->resetIO) { - // WRITE_LOG(LOG_DEBUG, "BulkinWrite write.length:%d", length); childRet = write(bulkIn, (uint8_t *)data + offset, length - offset); if (childRet <= 0) { int err = errno; -- Gitee From 49a4879133a89f40a73a4ea9a0bf281592891c4c Mon Sep 17 00:00:00 2001 From: zako Date: Sat, 13 Nov 2021 00:58:54 +0800 Subject: [PATCH 11/15] little Signed-off-by: zako --- src/host/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/host/main.cpp b/src/host/main.cpp index ce10d565..2b203063 100644 --- a/src/host/main.cpp +++ b/src/host/main.cpp @@ -321,7 +321,7 @@ int main(int argc, const char *argv[]) } if (g_isServerMode) { // -m server.Run alone in the background, no -s will be listen loopback address, - Base::SetLogLevel(g_logLevel); // default level LOG_LEVEL_FULL + Base::SetLogLevel(g_logLevel); // default level LOG_LEVEL_FULL Hdc::RunServerMode(g_serverListenString); } else if (g_isPcDebugRun) { Hdc::RunPcDebugMode(g_isPullServer, g_isTCPorUSB, g_isTestMethod); -- Gitee From 9d96749f2042d231ada07b69e1f4a891ffa02240 Mon Sep 17 00:00:00 2001 From: zako Date: Sat, 13 Nov 2021 10:32:54 +0800 Subject: [PATCH 12/15] io max Signed-off-by: zako --- src/common/base.cpp | 5 +---- src/common/channel.cpp | 3 --- src/common/define.h | 3 ++- src/common/session.cpp | 5 +++-- src/common/transfer.cpp | 3 +-- src/common/usb.cpp | 5 ++++- src/daemon/daemon_usb.cpp | 2 +- 7 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/common/base.cpp b/src/common/base.cpp index c4a8c5b2..d803dd15 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -187,22 +187,19 @@ namespace Base { void SetTcpOptions(uv_tcp_t *tcpHandle) { - constexpr int maxBufFactor = 10; if (!tcpHandle) { - WRITE_LOG(LOG_WARN, "SetTcpOptions nullptr Ptr"); return; } uv_tcp_keepalive(tcpHandle, 1, GLOBAL_TIMEOUT); // if MAX_SIZE_IOBUF==5k,bufMaxSize at least 40k. It must be set to io 8 times is more appropriate, // otherwise asynchronous IO is too fast, a lot of IO is wasted on IOloop, transmission speed will decrease - int bufMaxSize = GetMaxBufSize() * maxBufFactor; + int bufMaxSize = GetMaxBufSize(); uv_recv_buffer_size((uv_handle_t *)tcpHandle, &bufMaxSize); uv_send_buffer_size((uv_handle_t *)tcpHandle, &bufMaxSize); } void ReallocBuf(uint8_t **origBuf, int *nOrigSize, const int indexUsedBuf, int sizeWanted) { - sizeWanted = GetMaxBufSize(); int remainLen = *nOrigSize - indexUsedBuf; // init:0, left less than expected if (!*nOrigSize || (remainLen < sizeWanted && (*nOrigSize + sizeWanted < sizeWanted * 2))) { diff --git a/src/common/channel.cpp b/src/common/channel.cpp index 8d944ac5..0dfe9a39 100644 --- a/src/common/channel.cpp +++ b/src/common/channel.cpp @@ -277,9 +277,6 @@ void HdcChannelBase::Send(const uint32_t channelId, uint8_t *bufPtr, const int s void HdcChannelBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) { - if (sizeWanted <= 0) { - return; - } HChannel context = (HChannel)handle->data; Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); buf->base = (char *)context->ioBuf + context->availTailIndex; diff --git a/src/common/define.h b/src/common/define.h index abddfe31..810ea9bb 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -22,7 +22,8 @@ constexpr uint8_t MINOR_TIMEOUT = 5; constexpr uint8_t SIZE_THREAD_POOL = 16; constexpr uint8_t GLOBAL_TIMEOUT = 30; constexpr uint16_t DEFAULT_PORT = 8710; -constexpr uint16_t MAX_SIZE_IOBUF = 5120; // USB EP block max size about 10k, USBFFS_BULKSIZE 16384 +// USB EP block max size. Should be less than USBFFS_BULKSIZE, limit < 12k now +constexpr uint16_t MAX_SIZE_IOBUF = 10240; constexpr uint16_t USBFFS_BULKSIZE_MAX = 16384; constexpr bool ENABLE_IO_CHECKSUM = false; const string DEFAULT_SERVER_ADDR = "127.0.0.1:8710"; diff --git a/src/common/session.cpp b/src/common/session.cpp index 63c1f22b..ddfe24b8 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -313,8 +313,7 @@ int HdcSessionBase::MallocSessionByConnectType(HSession hSession) } hSession->hUSB = hUSB; #ifdef HDC_HOST - constexpr auto maxBufFactor = 1.5; - int max = Base::GetMaxBufSize() * maxBufFactor + sizeof(USBHead); + int max = Base::GetUsbffsMaxBulkSize(); hUSB->sizeEpBuf = max; hUSB->bufDevice = new uint8_t[max](); hUSB->bufHost = new uint8_t[max](); @@ -754,6 +753,8 @@ int HdcSessionBase::FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read) void HdcSessionBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) { + // sizeWanted == libuv staic value 65535 + sizeWanted = Base::GetMaxBufSize(); HSession context = (HSession)handle->data; Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); buf->base = (char *)context->ioBuf + context->availTailIndex; diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index a10711e0..285de56b 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -200,8 +200,7 @@ void HdcTransferBase::OnFileIO(uv_fs_t *req) } if (context->indexIO < context->fileSize) { // read continue until result >0, let single file packet +packet header less than GetMaxBufSize() - constexpr auto maxBufFactor = 0.8; - thisClass->SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize() * maxBufFactor); + thisClass->SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize()); } } else if (req->fs_type == UV_FS_WRITE) { // write if (context->indexIO >= context->fileSize) { diff --git a/src/common/usb.cpp b/src/common/usb.cpp index e76b5053..98ae2cbf 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -61,7 +61,10 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) { // Format:USBPacket1 payload1...USBPacketn payloadn; // [USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] - int maxIOSize = Base::GetMaxBufSize(); + // + // I hope the size is GetUsbffsMaxBulkSize, but after exceeding 12k, if the split-package is too large, libusb will + // report an error when send callback. I don't know why... + constexpr int maxIOSize = 12000; // must < 12k now int sizeUSBPacketHead = sizeof(USBHead); int singleSize = maxIOSize - sizeUSBPacketHead; int iMod = length % singleSize; diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 0c598f26..f0de87e4 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -423,7 +423,7 @@ int HdcDaemonUSB::LoopUSBRead(HUSB hUSB) int ret = -1; HdcDaemon *daemon = reinterpret_cast(clsMainBase); // must > available size, or it will be incorrect - int readMax = Base::GetMaxBufSize() + sizeof(USBHead) + EXTRA_ALLOC_SIZE; + int readMax = Base::GetUsbffsMaxBulkSize(); auto ctxIo = new CtxUvFileCommonIo(); auto buf = new uint8_t[readMax](); uv_fs_t *req = nullptr; -- Gitee From 1ff755597d14f5d1899b6234c45dbebc07d15509 Mon Sep 17 00:00:00 2001 From: zako Date: Sun, 14 Nov 2021 22:22:50 +0800 Subject: [PATCH 13/15] try fix 'error packet' Signed-off-by: zako --- src/common/base.cpp | 2 +- src/common/channel.cpp | 53 ++++++++++++++++----------- src/common/define.h | 5 +-- src/common/define_plus.h | 14 ++++---- src/common/session.cpp | 66 +++++++++++++++++++++------------- src/common/transfer.cpp | 4 ++- src/common/usb.cpp | 31 +++++++++++----- src/common/usb.h | 1 + src/daemon/daemon_usb.cpp | 42 ++++++++++++++-------- src/daemon/daemon_usb.h | 3 +- src/host/client.cpp | 4 +-- src/host/host_usb.cpp | 39 ++++++++++++-------- src/host/host_usb.h | 1 + src/host/server.cpp | 25 +++++++------ src/host/server_for_client.cpp | 4 +-- 15 files changed, 186 insertions(+), 108 deletions(-) diff --git a/src/common/base.cpp b/src/common/base.cpp index d803dd15..a0e4bab4 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -193,7 +193,7 @@ namespace Base { uv_tcp_keepalive(tcpHandle, 1, GLOBAL_TIMEOUT); // if MAX_SIZE_IOBUF==5k,bufMaxSize at least 40k. It must be set to io 8 times is more appropriate, // otherwise asynchronous IO is too fast, a lot of IO is wasted on IOloop, transmission speed will decrease - int bufMaxSize = GetMaxBufSize(); + int bufMaxSize = MAX_SIZE_SOCKETPAIR; uv_recv_buffer_size((uv_handle_t *)tcpHandle, &bufMaxSize); uv_send_buffer_size((uv_handle_t *)tcpHandle, &bufMaxSize); } diff --git a/src/common/channel.cpp b/src/common/channel.cpp index 0dfe9a39..91352b97 100644 --- a/src/common/channel.cpp +++ b/src/common/channel.cpp @@ -158,11 +158,11 @@ Finish: void HdcChannelBase::WriteCallback(uv_write_t *req, int status) { HChannel hChannel = (HChannel)req->handle->data; - --hChannel->sendRef; + --hChannel->ref; HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; if (status < 0) { Base::TryCloseHandle((uv_handle_t *)req->handle); - if (!hChannel->isDead && !hChannel->sendRef) { + if (!hChannel->isDead && !hChannel->ref) { thisClass->FreeChannel(hChannel->channelId); WRITE_LOG(LOG_DEBUG, "WriteCallback TryCloseHandle"); } @@ -177,7 +177,7 @@ void HdcChannelBase::AsyncMainLoopTask(uv_idle_t *handle) HdcChannelBase *thisClass = (HdcChannelBase *)param->thisClass; switch (param->method) { - case ASYNC_FREE_SESSION: { + case ASYNC_FREE_CHANNEL: { // alloc/release should pair in main thread. thisClass->FreeChannel(param->sid); break; @@ -255,6 +255,7 @@ void HdcChannelBase::Send(const uint32_t channelId, uint8_t *bufPtr, const int s if (!hChannel || hChannel->isDead) { return; } + auto data = new uint8_t[sizeNewBuf](); if (!data) { return; @@ -270,7 +271,7 @@ void HdcChannelBase::Send(const uint32_t channelId, uint8_t *bufPtr, const int s sendStream = (uv_stream_t *)&hChannel->hChildWorkTCP; } if (!uv_is_closing((const uv_handle_t *)sendStream) && uv_is_writable(sendStream)) { - ++hChannel->sendRef; + ++hChannel->ref; Base::SendToStreamEx(sendStream, data, sizeNewBuf, nullptr, (void *)WriteCallback, data); } } @@ -298,7 +299,7 @@ uint32_t HdcChannelBase::MallocChannel(HChannel *hOutChannel) ++channelId; // Use different value for serverForClient&client in per process } uv_tcp_init(loopMain, &hChannel->hWorkTCP); - ++hChannel->uvRef; + ++hChannel->uvHandleRef; hChannel->hWorkThread = uv_thread_self(); hChannel->hWorkTCP.data = hChannel; hChannel->clsChannel = this; @@ -314,7 +315,7 @@ void HdcChannelBase::FreeChannelFinally(uv_idle_t *handle) { HChannel hChannel = (HChannel)handle->data; HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; - if (hChannel->uvRef > 0) { + if (hChannel->uvHandleRef > 0) { return; } thisClass->NotifyInstanceChannelFree(hChannel); @@ -331,7 +332,7 @@ void HdcChannelBase::FreeChannelContinue(HChannel hChannel) { auto closeChannelHandle = [](uv_handle_t *handle) -> void { HChannel hChannel = (HChannel)handle->data; - --hChannel->uvRef; + --hChannel->uvHandleRef; Base::TryCloseHandle((uv_handle_t *)handle); }; hChannel->availTailIndex = 0; @@ -344,7 +345,7 @@ void HdcChannelBase::FreeChannelContinue(HChannel hChannel) Base::TryCloseHandle((uv_handle_t *)&hChannel->stdoutTty, closeChannelHandle); } if (uv_is_closing((const uv_handle_t *)&hChannel->hWorkTCP)) { - --hChannel->uvRef; + --hChannel->uvHandleRef; } else { Base::TryCloseHandle((uv_handle_t *)&hChannel->hWorkTCP, closeChannelHandle); } @@ -355,7 +356,7 @@ void HdcChannelBase::FreeChannelOpeate(uv_timer_t *handle) { HChannel hChannel = (HChannel)handle->data; HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; - if (hChannel->sendRef > 0) { + if (hChannel->ref > 0) { return; } if (hChannel->hChildWorkTCP.loop) { @@ -379,20 +380,24 @@ void HdcChannelBase::FreeChannelOpeate(uv_timer_t *handle) void HdcChannelBase::FreeChannel(const uint32_t channelId) { - HChannel hChannel = AdminChannel(OP_QUERY, channelId, nullptr); + HChannel hChannel = AdminChannel(OP_QUERY_REF, channelId, nullptr); if (!hChannel) { return; } - // Two cases: alloc in main thread, or work thread - if (hChannel->hWorkThread != uv_thread_self()) { - PushAsyncMessage(hChannel->channelId, ASYNC_FREE_SESSION, nullptr, 0); - return; - } - if (hChannel->isDead) { - return; - } - Base::TimerUvTask(loopMain, hChannel, FreeChannelOpeate, MINOR_TIMEOUT); // do immediately - hChannel->isDead = true; + WRITE_LOG(LOG_DEBUG, "Begin to free channel, channelid:%u", channelId); + do { + // Two cases: alloc in main thread, or work thread + if (hChannel->hWorkThread != uv_thread_self()) { + PushAsyncMessage(hChannel->channelId, ASYNC_FREE_CHANNEL, nullptr, 0); + break; + } + if (hChannel->isDead) { + break; + } + Base::TimerUvTask(loopMain, hChannel, FreeChannelOpeate, MINOR_TIMEOUT); // do immediately + hChannel->isDead = true; + } while (false); + --hChannel->ref; } HChannel HdcChannelBase::AdminChannel(const uint8_t op, const uint32_t channelId, HChannel hInput) @@ -416,6 +421,14 @@ HChannel HdcChannelBase::AdminChannel(const uint8_t op, const uint32_t channelId } uv_rwlock_rdunlock(&lockMapChannel); break; + case OP_QUERY_REF: + uv_rwlock_wrlock(&lockMapChannel); + if (mapChannel.count(channelId)) { + hRet = mapChannel[channelId]; + ++hRet->ref; + } + uv_rwlock_wrunlock(&lockMapChannel); + break; case OP_UPDATE: uv_rwlock_wrlock(&lockMapChannel); // remove old diff --git a/src/common/define.h b/src/common/define.h index 810ea9bb..97415433 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -22,8 +22,8 @@ constexpr uint8_t MINOR_TIMEOUT = 5; constexpr uint8_t SIZE_THREAD_POOL = 16; constexpr uint8_t GLOBAL_TIMEOUT = 30; constexpr uint16_t DEFAULT_PORT = 8710; -// USB EP block max size. Should be less than USBFFS_BULKSIZE, limit < 12k now -constexpr uint16_t MAX_SIZE_IOBUF = 10240; +constexpr uint16_t MAX_SIZE_IOBUF = 15360; // 15360 +constexpr uint16_t MAX_SIZE_SOCKETPAIR = MAX_SIZE_IOBUF * 4; constexpr uint16_t USBFFS_BULKSIZE_MAX = 16384; constexpr bool ENABLE_IO_CHECKSUM = false; const string DEFAULT_SERVER_ADDR = "127.0.0.1:8710"; @@ -47,6 +47,7 @@ constexpr uint16_t AID_SHELL = 2000; constexpr uint16_t UV_DEFAULT_INTERVAL = 250; // ms constexpr uint16_t VER_PROTOCOL = 0x01; constexpr uint16_t EXTRA_ALLOC_SIZE = 2048; +constexpr uint16_t MAX_PACKET_SIZE_HISPEED = 512; // double-word(hex)=[0]major[1][2]minor[3][4]version[5]fix(a-p)[6][7]reserve constexpr uint32_t HDC_VERSION_NUMBER = 0x10101a00; // 1.1.1b=0x10101100 constexpr uint32_t HDC_BUF_MAX_BYTES = 1024000000; diff --git a/src/common/define_plus.h b/src/common/define_plus.h index d2bc938d..e5c4f418 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -42,6 +42,7 @@ enum OperateID { OP_ADD, OP_REMOVE, OP_QUERY, + OP_QUERY_REF, // crossthread query, manually reduce ref OP_GET_STRLIST, OP_GET_STRLIST_FULL, OP_GET_ANY, @@ -92,6 +93,7 @@ enum RetErrCode { enum AsyncEvent { ASYNC_STOP_MAINLOOP = 0, ASYNC_FREE_SESSION, + ASYNC_FREE_CHANNEL, }; enum InnerCtrlCommand { SP_START_SESSION = 0, @@ -213,7 +215,6 @@ struct HdcUSB { uint8_t devId; uint8_t busId; int32_t sizeEpBuf; - uint16_t wMaxPacketSize; string serialNumber; string usbMountPoint; uint8_t *bufDevice; @@ -233,6 +234,7 @@ struct HdcUSB { int bulkOut; // EP1 device recv int bulkIn; // EP2 device send #endif + uint16_t wMaxPacketSizeSend; vector bufRecv; bool resetIO; // if true, must break write and read,default false }; @@ -245,9 +247,9 @@ struct HdcSession { string connectKey; uint8_t connType; // ConnType uint32_t sessionId; - std::atomic sendRef; - uint8_t uvRef; // libuv handle ref -- just main thread now - uint8_t uvChildRef; // libuv handle ref -- just main thread now + std::atomic ref; + uint8_t uvHandleRef; // libuv handle ref -- just main thread now + uint8_t uvChildRef; // libuv handle ref -- just main thread now bool childCleared; map *mapTask; // class ptr @@ -286,14 +288,14 @@ struct HdcChannel { string connectKey; uv_tcp_t hWorkTCP; // work channel for client, forward channel for server uv_thread_t hWorkThread; - uint8_t uvRef = 0; // libuv handle ref -- just main thread now + uint8_t uvHandleRef = 0; // libuv handle ref -- just main thread now bool handshakeOK; bool isDead; bool serverOrClient; // client's channel/ server's channel bool childCleared; bool interactiveShellMode; // Is shell interactive mode bool keepAlive; // channel will not auto-close by server - std::atomic sendRef; + std::atomic ref; uint32_t targetSessionId; // child work uv_tcp_t hChildWorkTCP; // work channel for server, no use in client diff --git a/src/common/session.cpp b/src/common/session.cpp index ddfe24b8..69954bd1 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -118,7 +118,7 @@ void HdcSessionBase::ClearOwnTasks(HSession hSession, const uint32_t channelIDIn continue; } BeginRemoveTask(hTask); - WRITE_LOG(LOG_DEBUG, "ClearOwnTasks OP_CLEAR finish,session:%p channelIDInput:%d", hSession, + WRITE_LOG(LOG_DEBUG, "ClearOwnTasks OP_CLEAR finish, session:%p channelIDInput:%d", hSession, channelIDInput); break; } @@ -300,7 +300,7 @@ int HdcSessionBase::MallocSessionByConnectType(HSession hSession) switch (hSession->connType) { case CONN_TCP: { uv_tcp_init(&loopMain, &hSession->hWorkTCP); - ++hSession->uvRef; + ++hSession->uvHandleRef; hSession->hWorkTCP.data = hSession; break; } @@ -312,6 +312,7 @@ int HdcSessionBase::MallocSessionByConnectType(HSession hSession) break; } hSession->hUSB = hUSB; + hSession->hUSB->wMaxPacketSizeSend = MAX_PACKET_SIZE_HISPEED; #ifdef HDC_HOST int max = Base::GetUsbffsMaxBulkSize(); hUSB->sizeEpBuf = max; @@ -363,12 +364,12 @@ HSession HdcSessionBase::MallocSession(bool serverOrDaemon, const ConnType connT hSession->hWorkThread = uv_thread_self(); hSession->mapTask = new map(); hSession->listKey = new list; - hSession->uvRef = 0; + hSession->uvHandleRef = 0; // pullup child WRITE_LOG(LOG_DEBUG, "HdcSessionBase NewSession, sessionId:%u", hSession->sessionId); uv_tcp_init(&loopMain, &hSession->ctrlPipe[STREAM_MAIN]); - ++hSession->uvRef; + ++hSession->uvHandleRef; Base::CreateSocketPair(hSession->ctrlFd); uv_tcp_open(&hSession->ctrlPipe[STREAM_MAIN], hSession->ctrlFd[STREAM_MAIN]); uv_read_start((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], Base::AllocBufferCallback, ReadCtrlFromSession); @@ -376,7 +377,7 @@ HSession HdcSessionBase::MallocSession(bool serverOrDaemon, const ConnType connT hSession->ctrlPipe[STREAM_WORK].data = hSession; // Activate USB DAEMON's data channel, may not for use uv_tcp_init(&loopMain, &hSession->dataPipe[STREAM_MAIN]); - ++hSession->uvRef; + ++hSession->uvHandleRef; Base::CreateSocketPair(hSession->dataFd); uv_tcp_open(&hSession->dataPipe[STREAM_MAIN], hSession->dataFd[STREAM_MAIN]); hSession->dataPipe[STREAM_MAIN].data = hSession; @@ -434,7 +435,7 @@ void HdcSessionBase::FreeSessionFinally(uv_idle_t *handle) { HSession hSession = (HSession)handle->data; HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; - if (hSession->uvRef > 0) { + if (hSession->uvHandleRef > 0) { return; } // Notify Server or Daemon, just UI or display commandline @@ -453,7 +454,7 @@ void HdcSessionBase::FreeSessionContinue(HSession hSession) { auto closeSessionTCPHandle = [](uv_handle_t *handle) -> void { HSession hSession = (HSession)handle->data; - --hSession->uvRef; + --hSession->uvHandleRef; Base::TryCloseHandle((uv_handle_t *)handle); }; if (CONN_TCP == hSession->connType) { @@ -479,11 +480,16 @@ void HdcSessionBase::FreeSessionOpeate(uv_timer_t *handle) { HSession hSession = (HSession)handle->data; HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; - if (hSession->sendRef > 0) { + if (hSession->ref > 0) { return; } #ifdef HDC_HOST if (hSession->hUSB != nullptr && (!hSession->hUSB->recvIOComplete || !hSession->hUSB->sendIOComplete)) { + if (!hSession->hUSB->recvIOComplete) { + HdcUSBBase *pUSB = ((HdcUSBBase *)hSession->classModule); + pUSB->CancelUsbLoopRead(hSession->hUSB); + } + // send will be end with timeout return; } #endif @@ -510,21 +516,25 @@ void HdcSessionBase::FreeSessionOpeate(uv_timer_t *handle) void HdcSessionBase::FreeSession(const uint32_t sessionId) { - HSession hSession = AdminSession(OP_QUERY, sessionId, nullptr); + HSession hSession = AdminSession(OP_QUERY_REF, sessionId, nullptr); if (!hSession) { return; } - if (hSession->hWorkThread != uv_thread_self()) { - PushAsyncMessage(hSession->sessionId, ASYNC_FREE_SESSION, nullptr, 0); - return; - } - if (hSession->isDead) { - return; - } - hSession->isDead = true; - Base::TimerUvTask(&loopMain, hSession, FreeSessionOpeate); - NotifyInstanceSessionFree(hSession, false); - WRITE_LOG(LOG_DEBUG, "FreeSession sessionId:%u sendref:%u", hSession->sessionId, uint16_t(hSession->sendRef)); + WRITE_LOG(LOG_DEBUG, "Begin to free session, sessionid:%u", sessionId); + do { + if (hSession->hWorkThread != uv_thread_self()) { + PushAsyncMessage(hSession->sessionId, ASYNC_FREE_SESSION, nullptr, 0); + return; + } + if (hSession->isDead) { + return; + } + hSession->isDead = true; + Base::TimerUvTask(&loopMain, hSession, FreeSessionOpeate); + NotifyInstanceSessionFree(hSession, false); + WRITE_LOG(LOG_DEBUG, "FreeSession sessionId:%u ref:%u", hSession->sessionId, uint16_t(hSession->ref)); + } while (false); + --hSession->ref; } HSession HdcSessionBase::AdminSession(const uint8_t op, const uint32_t sessionId, HSession hInput) @@ -548,6 +558,14 @@ HSession HdcSessionBase::AdminSession(const uint8_t op, const uint32_t sessionId } uv_rwlock_rdunlock(&lockMapSession); break; + case OP_QUERY_REF: + uv_rwlock_wrlock(&lockMapSession); + if (mapSession.count(sessionId)) { + hRet = mapSession[sessionId]; + ++hRet->ref; + } + uv_rwlock_wrunlock(&lockMapSession); + break; case OP_UPDATE: uv_rwlock_wrlock(&lockMapSession); // remove old @@ -603,7 +621,7 @@ int HdcSessionBase::SendByProtocol(HSession hSession, uint8_t *bufPtr, const int ret = ERR_API_FAIL; } if (ret > 0) { - ++hSession->sendRef; + ++hSession->ref; } break; } @@ -754,7 +772,7 @@ int HdcSessionBase::FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read) void HdcSessionBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) { // sizeWanted == libuv staic value 65535 - sizeWanted = Base::GetMaxBufSize(); + sizeWanted = MAX_SIZE_SOCKETPAIR; // anti highload IO from socketpair HSession context = (HSession)handle->data; Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); buf->base = (char *)context->ioBuf + context->availTailIndex; @@ -765,11 +783,11 @@ void HdcSessionBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_bu void HdcSessionBase::FinishWriteSessionTCP(uv_write_t *req, int status) { HSession hSession = (HSession)req->handle->data; - --hSession->sendRef; + --hSession->ref; HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; if (status < 0) { Base::TryCloseHandle((uv_handle_t *)req->handle); - if (!hSession->isDead && !hSession->sendRef) { + if (!hSession->isDead && !hSession->ref) { WRITE_LOG(LOG_DEBUG, "FinishWriteSessionTCP freesession :%p", hSession); thisClass->FreeSession(hSession->sessionId); } diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index 285de56b..5b8349d3 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -200,7 +200,9 @@ void HdcTransferBase::OnFileIO(uv_fs_t *req) } if (context->indexIO < context->fileSize) { // read continue until result >0, let single file packet +packet header less than GetMaxBufSize() - thisClass->SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize()); + // Each file packet shall be completed in one IO as far as possible, which is more efficient + constexpr auto maxBufFactor = 0.9; + thisClass->SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize() * maxBufFactor); } } else if (req->fs_type == UV_FS_WRITE) { // write if (context->indexIO >= context->fileSize) { diff --git a/src/common/usb.cpp b/src/common/usb.cpp index 98ae2cbf..89b75940 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -62,16 +62,18 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) // Format:USBPacket1 payload1...USBPacketn payloadn; // [USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] // - // I hope the size is GetUsbffsMaxBulkSize, but after exceeding 12k, if the split-package is too large, libusb will - // report an error when send callback. I don't know why... - constexpr int maxIOSize = 12000; // must < 12k now + int ioStaticValue = std::min(Base::GetMaxBufSize(), Base::GetUsbffsMaxBulkSize()); + // Get integer division maximum and the data size is aligned + int maxIOSize = ioStaticValue - (ioStaticValue % hSession->hUSB->wMaxPacketSizeSend); int sizeUSBPacketHead = sizeof(USBHead); int singleSize = maxIOSize - sizeUSBPacketHead; int iMod = length % singleSize; int iCount = (length - iMod) / singleSize + 1; int offset = 0; int dataSize = 0; + int childRet = 0; int i = 0; // It doesn't matter of 0 or 1, start from 1 to send it according to the serial number. + uint8_t *ioBuf = new uint8_t[maxIOSize](); if (!ioBuf) { return ERR_BUF_ALLOC; @@ -97,23 +99,30 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) break; } offset += dataSize; - ++hSession->sendRef; - if (SendUSBRaw(hSession, ioBuf, sizeUSBPacketHead + dataSize) <= 0) { + ++hSession->ref; + if ((childRet = SendUSBRaw(hSession, ioBuf, sizeUSBPacketHead + dataSize)) <= 0) { offset = ERR_IO_FAIL; break; } + if (!hSession->serverOrDaemon && (childRet % hSession->hUSB->wMaxPacketSizeSend == 0)) { + // Just daemon enable zero length packet. + // win32 send ZLP will block winusb driver and LIBUSB_TRANSFER_ADD_ZERO_PACKET not effect + uint8_t dummy = 0; + SendUSBRaw(hSession, &dummy, 0); + } } delete[] ioBuf; return offset; } +// return value: <0 error; = 0 all finish; >0 need size int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t *appendData, int dataSize) { HUSB hUSB = hSession->hUSB; vector &bufRecv = hUSB->bufRecv; bufRecv.insert(bufRecv.end(), appendData, appendData + dataSize); int ret = RET_SUCCESS; - while (bufRecv.size() > sizeof(USBHead)) { + while (bufRecv.size() >= sizeof(USBHead)) { USBHead *usbHeader = (USBHead *)bufRecv.data(); if (memcmp(usbHeader->flag, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { WRITE_LOG(LOG_FATAL, "Error usb packet"); @@ -122,9 +131,15 @@ int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t } usbHeader->sessionId = ntohl(usbHeader->sessionId); usbHeader->dataSize = ntohs(usbHeader->dataSize); - if (bufRecv.size() < sizeof(USBHead) + usbHeader->dataSize) { + if (usbHeader->dataSize > USBFFS_BULKSIZE_MAX) { + ret = ERR_BUF_SIZE; + break; + } + uint32_t fullPacketSize = sizeof(USBHead) + usbHeader->dataSize; + if (bufRecv.size() < fullPacketSize) { WRITE_LOG(LOG_DEBUG, "SendToHdcStream not enough dataSize:%d bufRecvSize:%d", usbHeader->dataSize, bufRecv.size()); + ret = fullPacketSize - bufRecv.size(); break; // successful , but not enough } if (usbHeader->sessionId != hSession->sessionId) { @@ -147,7 +162,7 @@ int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t break; } } - bufRecv.erase(bufRecv.begin(), bufRecv.begin() + sizeof(USBHead) + usbHeader->dataSize); + bufRecv.erase(bufRecv.begin(), bufRecv.begin() + fullPacketSize); } return ret; } diff --git a/src/common/usb.h b/src/common/usb.h index 8b49c54c..0fc2c8da 100644 --- a/src/common/usb.h +++ b/src/common/usb.h @@ -27,6 +27,7 @@ public: } virtual bool ReadyForWorkThread(HSession hSession); virtual void SendUsbSoftReset(HUSB hUSB, uint32_t sessionId) {}; + virtual void CancelUsbLoopRead(HUSB hUSB) {}; int SendUSBBlock(HSession hSession, uint8_t *data, const int length); static void ReadUSB(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); int SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t *appendData, int dataSize); diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index f0de87e4..91fc90d2 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -73,6 +73,16 @@ string HdcDaemonUSB::GetDevPath(const std::string &path) return res; } +int HdcDaemonUSB::GetMaxPacketSize(int ffs_fd) +{ + usb_endpoint_descriptor desc; + if (ioctl(ffs_fd, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast(&desc))) { + return MAX_PACKET_SIZE_HISPEED; + } else { + return desc.wMaxPacketSize; + } +} + int HdcDaemonUSB::Initial() { // after Linux-3.8,kernel switch to the USB Function FS @@ -132,6 +142,7 @@ int HdcDaemonUSB::ConnectEPPoint(HUSB hUSB) fcntl(controlEp, F_SETFD, FD_CLOEXEC); fcntl(hUSB->bulkOut, F_SETFD, FD_CLOEXEC); fcntl(hUSB->bulkIn, F_SETFD, FD_CLOEXEC); + hUSB->wMaxPacketSizeSend = GetMaxPacketSize(hUSB->bulkIn); WRITE_LOG(LOG_DEBUG, "New bulk in\\out open bulkout:%d bulkin:%d", hUSB->bulkOut, hUSB->bulkIn); hUSB->bufRecv.clear(); @@ -240,13 +251,13 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t int bulkIn = hMainUSB->bulkIn; int childRet = 0; int ret = ERR_IO_FAIL; - int offset = 0; + uint32_t offset = 0; while (modRunning && isAlive && !hSession->isDead && !hSession->hUSB->resetIO) { childRet = write(bulkIn, (uint8_t *)data + offset, length - offset); - if (childRet <= 0) { + if (childRet < 0) { int err = errno; if (err == EINTR) { - WRITE_LOG(LOG_DEBUG, "BulkinWrite write EINTR, try again"); + WRITE_LOG(LOG_DEBUG, "BulkinWrite write EINTR, try again, offset:%u", offset); continue; } else { WRITE_LOG(LOG_FATAL, "BulkinWrite write fatal errno %d", err); @@ -266,7 +277,9 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t "BulkinWrite write failed, nsize:%d really:%d modRunning:%d isAlive:%d SessionDead:%d usbReset:%d", length, offset, modRunning, isAlive, hSession->isDead, hSession->hUSB->resetIO); } - hSession->sendRef--; + if (length != 0) { + hSession->ref--; + } return ret; } @@ -332,6 +345,7 @@ int HdcDaemonUSB::DispatchToWorkThread(const uint32_t sessionId, uint8_t *readBu // payloadn-[USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] HSession hChildSession = nullptr; HdcDaemon *daemon = reinterpret_cast(clsMainBase); + int childRet = RET_SUCCESS; hChildSession = daemon->AdminSession(OP_QUERY, sessionId, nullptr); if (!hChildSession) { hChildSession = PrepareNewSession(sessionId, readBuf, readBytes); @@ -342,12 +356,11 @@ int HdcDaemonUSB::DispatchToWorkThread(const uint32_t sessionId, uint8_t *readBu if (hChildSession->childCleared) { return ERR_SESSION_DEAD; } - if (SendToHdcStream(hChildSession, reinterpret_cast(&hChildSession->dataPipe[STREAM_MAIN]), readBuf, - readBytes) - != RET_SUCCESS) { + uv_stream_t *stream = reinterpret_cast(&hChildSession->dataPipe[STREAM_MAIN]); + if ((childRet = SendToHdcStream(hChildSession, stream, readBuf, readBytes)) < 0) { return ERR_IO_FAIL; } - return readBytes; + return childRet; } bool HdcDaemonUSB::JumpAntiquePacket(const uint8_t &buf, ssize_t bytes) const @@ -396,14 +409,15 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) break; } // reset packet + childRet = 0; // need max size } else { // AvailablePacket case - if (thisClass->DispatchToWorkThread(sessionId, bufPtr, bytesIOBytes) < 0) { + if ((childRet = thisClass->DispatchToWorkThread(sessionId, bufPtr, bytesIOBytes)) < 0) { WRITE_LOG(LOG_FATAL, "DispatchToWorkThread failed"); break; } } - if (thisClass->LoopUSBRead(hUSB) < 0) { + if (thisClass->LoopUSBRead(hUSB, childRet == 0 ? Base::GetUsbffsMaxBulkSize() : childRet) < 0) { WRITE_LOG(LOG_FATAL, "LoopUSBRead failed"); break; } @@ -418,21 +432,19 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) delete ctxIo; } -int HdcDaemonUSB::LoopUSBRead(HUSB hUSB) +int HdcDaemonUSB::LoopUSBRead(HUSB hUSB, int readMaxWanted) { int ret = -1; HdcDaemon *daemon = reinterpret_cast(clsMainBase); - // must > available size, or it will be incorrect - int readMax = Base::GetUsbffsMaxBulkSize(); auto ctxIo = new CtxUvFileCommonIo(); - auto buf = new uint8_t[readMax](); + auto buf = new uint8_t[readMaxWanted](); uv_fs_t *req = nullptr; uv_buf_t iov; if (ctxIo == nullptr || buf == nullptr) { goto FAILED; } ctxIo->buf = buf; - ctxIo->bufSize = readMax; + ctxIo->bufSize = readMaxWanted; ctxIo->data = hUSB; ctxIo->thisClass = this; req = &ctxIo->req; diff --git a/src/daemon/daemon_usb.h b/src/daemon/daemon_usb.h index 38dc5244..8365fb3d 100644 --- a/src/daemon/daemon_usb.h +++ b/src/daemon/daemon_usb.h @@ -42,12 +42,13 @@ private: void CloseEndpoint(HUSB hUSB, bool closeCtrlEp = false); string GetDevPath(const std::string &path); bool ReadyForWorkThread(HSession hSession); - int LoopUSBRead(HUSB hUSB); + int LoopUSBRead(HUSB hUSB, int readMaxWanted = Base::GetUsbffsMaxBulkSize()); HSession PrepareNewSession(uint32_t sessionId, uint8_t *pRecvBuf, int recvBytesIO); bool JumpAntiquePacket(const uint8_t &buf, ssize_t bytes) const; int SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t *data, const int length); int CloseBulkEp(bool bulkInOut, int bulkFd, uv_loop_t *loop); void ResetOldSession(const uint32_t sessionId); + int GetMaxPacketSize(int ffs_fd); HdcUSB usbHandle; string basePath; // usb device's base path diff --git a/src/host/client.cpp b/src/host/client.cpp index 5c899409..6d2ef7fa 100644 --- a/src/host/client.cpp +++ b/src/host/client.cpp @@ -271,9 +271,9 @@ void HdcClient::BindLocalStd(HChannel hChannel) return; } hChannel->stdoutTty.data = hChannel; - ++hChannel->uvRef; + ++hChannel->uvHandleRef; hChannel->stdinTty.data = hChannel; - ++hChannel->uvRef; + ++hChannel->uvHandleRef; if (bShellInteractive) { WRITE_LOG(LOG_DEBUG, "uv_tty_init uv_tty_set_mode"); ModifyTty(true, &hChannel->stdinTty); diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index a740a7ff..9219bc95 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -313,8 +313,8 @@ int HdcHostUSB::CheckActiveConfig(libusb_device *device, HUSB hUSB) hUSB->epDevice = ep_desc->bEndpointAddress; } else { hUSB->epHost = ep_desc->bEndpointAddress; + hUSB->wMaxPacketSizeSend = ep_desc->wMaxPacketSize; } - hUSB->wMaxPacketSize = ep_desc->wMaxPacketSize; } } if (hUSB->epDevice == 0 || hUSB->epHost == 0) { @@ -327,6 +327,14 @@ int HdcHostUSB::CheckActiveConfig(libusb_device *device, HUSB hUSB) return ret; } +void HdcHostUSB::CancelUsbLoopRead(HUSB hUSB) +{ + if (hUSB->transferRecv != nullptr && !hUSB->recvIOComplete) { + libusb_cancel_transfer(hUSB->transferRecv); + hUSB->recvIOComplete = true; + } +} + void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfer) { HSession hSession = (HSession)transfer->user_data; @@ -336,7 +344,7 @@ void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfe int childRet = 0; constexpr int infinity = 0; // ignore timeout while (true) { - if (!thisClass->modRunning || (hSession->isDead && 0 == hSession->sendRef)) + if (!thisClass->modRunning || (hSession->isDead && 0 == hSession->ref)) break; if (LIBUSB_TRANSFER_COMPLETED != transfer->status) { WRITE_LOG(LOG_FATAL, "Host usb not LIBUSB_TRANSFER_COMPLETED, status:%d", transfer->status); @@ -345,13 +353,15 @@ void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfe childRet = thisClass->SendToHdcStream(hSession, reinterpret_cast(&hSession->dataPipe[STREAM_MAIN]), hUSB->bufDevice, transfer->actual_length); - if (childRet != RET_SUCCESS && childRet != ERR_SESSION_NOFOUND) { + if (childRet < 0) { break; } hUSB->lockDeviceHandle.lock(); // loop self - libusb_fill_bulk_transfer(transfer, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, hUSB->sizeEpBuf, - ReadUSBBulkCallback, hSession, infinity); + // get usbffsmax or remaining size + libusb_fill_bulk_transfer(transfer, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, + childRet == 0 ? Base::GetUsbffsMaxBulkSize() : childRet, ReadUSBBulkCallback, + hSession, infinity); childRet = libusb_submit_transfer(transfer); hUSB->lockDeviceHandle.unlock(); if (childRet < 0) { @@ -379,7 +389,7 @@ void HdcHostUSB::RegisterReadCallback(HSession hSession) hUSB->lockDeviceHandle.lock(); // first bulk-read must be Okay and no timeout, otherwise failed. libusb_fill_bulk_transfer(hSession->hUSB->transferRecv, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, - hUSB->sizeEpBuf, ReadUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); + Base::GetUsbffsMaxBulkSize(), ReadUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); int childRet = libusb_submit_transfer(hSession->hUSB->transferRecv); hUSB->lockDeviceHandle.unlock(); if (childRet == 0) { @@ -422,12 +432,9 @@ void LIBUSB_CALL HdcHostUSB::WriteUSBBulkCallback(struct libusb_transfer *transf { HSession hSession = reinterpret_cast(transfer->user_data); HdcSessionBase *server = reinterpret_cast(hSession->classInstance); - --hSession->sendRef; - if (LIBUSB_TRANSFER_COMPLETED != transfer->status || (hSession->isDead && 0 == hSession->sendRef)) { + + if (LIBUSB_TRANSFER_COMPLETED != transfer->status || (hSession->isDead && 0 == hSession->ref)) { WRITE_LOG(LOG_FATAL, "SendUSBRaw status:%d", transfer->status); - if (hSession->hUSB->transferRecv != nullptr) { - libusb_cancel_transfer(hSession->hUSB->transferRecv); - } server->FreeSession(hSession->sessionId); } hSession->hUSB->sendIOComplete = true; @@ -442,6 +449,8 @@ int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) int childRet = -1; HUSB hUSB = hSession->hUSB; hUSB->sendIOComplete = false; + HdcSessionBase *server = reinterpret_cast(hSession->classInstance); + while (true) { if (memcpy_s(hUSB->bufHost, hUSB->sizeEpBuf, data, length) != EOK) { ret = ERR_BUF_COPY; @@ -452,6 +461,9 @@ int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) libusb_fill_bulk_transfer(hUSB->transferSend, hUSB->devHandle, hUSB->epHost, hUSB->bufHost, length, WriteUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); childRet = libusb_submit_transfer(hUSB->transferSend); + if (length != 0) { + --hSession->ref; + } hUSB->lockDeviceHandle.unlock(); if (childRet < 0) { ret = ERR_IO_FAIL; @@ -462,11 +474,8 @@ int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) break; } if (ret < 0) { - --hSession->sendRef; hSession->hUSB->sendIOComplete = true; - if (hUSB->transferRecv != nullptr) { - libusb_cancel_transfer(hUSB->transferRecv); - } + server->FreeSession(hSession->sessionId); } return ret; } diff --git a/src/host/host_usb.h b/src/host/host_usb.h index edafd789..7b93892e 100644 --- a/src/host/host_usb.h +++ b/src/host/host_usb.h @@ -53,6 +53,7 @@ private: void UpdateUSBDaemonInfo(HUSB hUSB, HSession hSession, uint8_t connStatus); void RegisterReadCallback(HSession hSession); void ReviewUsbNodeLater(string &nodeKey); + void CancelUsbLoopRead(HUSB hUSB); uv_idle_t usbWork; libusb_context *ctxUSB; diff --git a/src/host/server.cpp b/src/host/server.cpp index e50f7f53..470fc1e2 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -438,14 +438,14 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const const int payloadSize) { bool ret = true; - HdcServerForClient *pSfc = static_cast(clsServerForClient); - // When you first initialize, ChannelID may be 0 - HChannel hChannel = pSfc->AdminChannel(OP_QUERY, channelId, nullptr); + HdcServerForClient *sfc = static_cast(clsServerForClient); if (CMD_KERNEL_HANDSHAKE == command) { ret = ServerSessionHandshake(hSession, payload, payloadSize); WRITE_LOG(LOG_DEBUG, "Session handshake %s", ret ? "successful" : "failed"); return ret; } + // When you first initialize, ChannelID may be 0 + HChannel hChannel = sfc->AdminChannel(OP_QUERY_REF, channelId, nullptr); if (!hChannel) { if (command == CMD_KERNEL_CHANNEL_CLOSE) { // Daemon close channel and want to notify server close channel also, but it may has been @@ -458,22 +458,22 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const } switch (command) { case CMD_KERNEL_ECHO_RAW: { // Native shell data output - pSfc->EchoClientRaw(channelId, payload, payloadSize); + sfc->EchoClientRaw(channelId, payload, payloadSize); break; } case CMD_KERNEL_ECHO: { MessageLevel level = (MessageLevel)*payload; string s(reinterpret_cast(payload + 1), payloadSize - 1); - pSfc->EchoClient(hChannel, level, s.c_str()); + sfc->EchoClient(hChannel, level, s.c_str()); WRITE_LOG(LOG_DEBUG, "CMD_KERNEL_ECHO size:%d", payloadSize - 1); break; } case CMD_KERNEL_CHANNEL_CLOSE: { WRITE_LOG(LOG_DEBUG, "CMD_KERNEL_CHANNEL_CLOSE channelid:%d", channelId); - ClearOwnTasks(hSession, channelId); // Forcibly closing the tcp handle here may result in incomplete data reception on the client side - HdcServerForClient *sfc = static_cast(hChannel->clsChannel); - sfc->FreeChannel(hChannel->channelId); + ClearOwnTasks(hSession, channelId); + // crossthread free + sfc->PushAsyncMessage(channelId, ASYNC_FREE_CHANNEL, nullptr, 0); if (*payload == 1) { --(*payload); Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); @@ -495,12 +495,14 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const default: { HSession hSession = AdminSession(OP_QUERY, hChannel->targetSessionId, nullptr); if (!hSession) { - return false; + ret = false; + break; } - ret = DispatchTaskData(hSession, hChannel->channelId, command, payload, payloadSize); + ret = DispatchTaskData(hSession, channelId, command, payload, payloadSize); break; } } + --hChannel->ref; return ret; } @@ -652,9 +654,9 @@ int HdcServer::CreateConnect(const string &connectKey) void HdcServer::AttachChannel(HSession hSession, const uint32_t channelId) { + int ret = 0; HdcServerForClient *hSfc = static_cast(clsServerForClient); HChannel hChannel = hSfc->AdminChannel(OP_QUERY, channelId, nullptr); - int ret = 0; if (!hChannel) { return; } @@ -674,6 +676,7 @@ void HdcServer::AttachChannel(HSession hSession, const uint32_t channelId) void HdcServer::DeatchChannel(HSession hSession, const uint32_t channelId) { HdcServerForClient *hSfc = static_cast(clsServerForClient); + // childCleared has not set, no need OP_QUERY_REF HChannel hChannel = hSfc->AdminChannel(OP_QUERY, channelId, nullptr); if (!hChannel) { return; diff --git a/src/host/server_for_client.cpp b/src/host/server_for_client.cpp index 18abf088..b806cdb6 100644 --- a/src/host/server_for_client.cpp +++ b/src/host/server_for_client.cpp @@ -536,9 +536,9 @@ int HdcServerForClient::BindChannelToSession(HChannel hChannel, uint8_t *bufPtr, } uv_close_cb funcWorkTcpClose = [](uv_handle_t *handle) -> void { HChannel hChannel = (HChannel)handle->data; - --hChannel->sendRef; + --hChannel->ref; }; - ++hChannel->sendRef; + ++hChannel->ref; if (!isClosing) { uv_close((uv_handle_t *)&hChannel->hWorkTCP, funcWorkTcpClose); } -- Gitee From e5a2a4ae2ec89e3fa0c2c7fdc056e700c326ccbf Mon Sep 17 00:00:00 2001 From: zako Date: Sun, 14 Nov 2021 23:47:54 +0800 Subject: [PATCH 14/15] build error Signed-off-by: zako --- src/daemon/daemon_usb.cpp | 12 ++++-------- src/daemon/daemon_usb.h | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 91fc90d2..f8a893b9 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -73,14 +73,10 @@ string HdcDaemonUSB::GetDevPath(const std::string &path) return res; } -int HdcDaemonUSB::GetMaxPacketSize(int ffs_fd) +int HdcDaemonUSB::GetMaxPacketSize(int fdFfs) { - usb_endpoint_descriptor desc; - if (ioctl(ffs_fd, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast(&desc))) { - return MAX_PACKET_SIZE_HISPEED; - } else { - return desc.wMaxPacketSize; - } + // no ioctl support, todo dynamic get + return MAX_PACKET_SIZE_HISPEED; } int HdcDaemonUSB::Initial() @@ -251,7 +247,7 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t int bulkIn = hMainUSB->bulkIn; int childRet = 0; int ret = ERR_IO_FAIL; - uint32_t offset = 0; + int offset = 0; while (modRunning && isAlive && !hSession->isDead && !hSession->hUSB->resetIO) { childRet = write(bulkIn, (uint8_t *)data + offset, length - offset); if (childRet < 0) { diff --git a/src/daemon/daemon_usb.h b/src/daemon/daemon_usb.h index 8365fb3d..30c1aed8 100644 --- a/src/daemon/daemon_usb.h +++ b/src/daemon/daemon_usb.h @@ -48,7 +48,7 @@ private: int SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t *data, const int length); int CloseBulkEp(bool bulkInOut, int bulkFd, uv_loop_t *loop); void ResetOldSession(const uint32_t sessionId); - int GetMaxPacketSize(int ffs_fd); + int GetMaxPacketSize(int fdFfs); HdcUSB usbHandle; string basePath; // usb device's base path -- Gitee From 77d496b170e184f650756f118edff3073463fa7e Mon Sep 17 00:00:00 2001 From: zako Date: Mon, 15 Nov 2021 15:55:08 +0800 Subject: [PATCH 15/15] soft dummy ZLP Signed-off-by: zako --- src/common/define_plus.h | 2 +- src/common/usb.cpp | 26 ++++++++++++++++++++++---- src/common/usb.h | 1 + 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/common/define_plus.h b/src/common/define_plus.h index e5c4f418..1840498c 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -161,7 +161,7 @@ enum HdcCommand { enum UsbProtocolOption { USB_OPTION_TAIL = 1, USB_OPTION_RESET = 2, - USB_OPTION_RESERVE4 = 4, + USB_OPTION_DUMMY = 4, USB_OPTION_RESERVE8 = 8, USB_OPTION_RESERVE16 = 16, }; diff --git a/src/common/usb.cpp b/src/common/usb.cpp index 89b75940..ed83c04f 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -55,6 +55,19 @@ bool HdcUSBBase::ReadyForWorkThread(HSession hSession) return true; }; +vector HdcUSBBase::DummyPacket(uint32_t sessionId) +{ + vector dummy; + USBHead head; + head.sessionId = htonl(sessionId); + head.flag[0] = 'H'; + head.flag[1] = 'W'; + head.option = USB_OPTION_DUMMY; + head.dataSize = 0; + dummy.insert(dummy.end(), (uint8_t *)&head, (uint8_t *)&head + sizeof(USBHead)); + return dummy; +} + // USB big data stream, block transmission, mainly to prevent accidental data packets from writing through EP port, // inserting the send queue causes the program to crash int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) @@ -104,11 +117,11 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) offset = ERR_IO_FAIL; break; } - if (!hSession->serverOrDaemon && (childRet % hSession->hUSB->wMaxPacketSizeSend == 0)) { + if (childRet % hSession->hUSB->wMaxPacketSizeSend == 0) { // Just daemon enable zero length packet. // win32 send ZLP will block winusb driver and LIBUSB_TRANSFER_ADD_ZERO_PACKET not effect - uint8_t dummy = 0; - SendUSBRaw(hSession, &dummy, 0); + auto dummy = DummyPacket(hSession->sessionId); + SendUSBRaw(hSession, dummy.data(), dummy.size()); } } delete[] ioBuf; @@ -154,8 +167,13 @@ int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t hUSB->resetIO = true; } } else { + bool isZlp = false; + if (usbHeader->option & USB_OPTION_DUMMY) { + // soft ZLP + isZlp = true; + } // usb data to logic - if (Base::SendToStream(stream, bufRecv.data() + sizeof(USBHead), usbHeader->dataSize) < 0) { + if (!isZlp && Base::SendToStream(stream, bufRecv.data() + sizeof(USBHead), usbHeader->dataSize) < 0) { ret = ERR_IO_FAIL; WRITE_LOG(LOG_FATAL, "Error usb send to stream dataSize:%d bufRecvSize:%d", usbHeader->dataSize, bufRecv.size()); diff --git a/src/common/usb.h b/src/common/usb.h index 0fc2c8da..32d45b32 100644 --- a/src/common/usb.h +++ b/src/common/usb.h @@ -31,6 +31,7 @@ public: int SendUSBBlock(HSession hSession, uint8_t *data, const int length); static void ReadUSB(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); int SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t *appendData, int dataSize); + vector DummyPacket(uint32_t sessionId); protected: void *clsMainBase; -- Gitee