From 138276027837f5376052760eabb78a0deb1fd26c Mon Sep 17 00:00:00 2001 From: zako Date: Fri, 5 Nov 2021 13:13:45 +0800 Subject: [PATCH 01/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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 From 2175c35c45c140057e82f83a678820566f00f2da Mon Sep 17 00:00:00 2001 From: zako Date: Sun, 21 Nov 2021 01:07:55 +0800 Subject: [PATCH 16/50] 202111update- try fix all know issue Signed-off-by: zako --- src/common/async_cmd.cpp | 214 +++++++++++++-------------------- src/common/async_cmd.h | 26 ++-- src/common/base.h | 4 +- src/common/channel.cpp | 28 +++-- src/common/channel.h | 2 + src/common/define.h | 6 +- src/common/define_plus.h | 18 +-- src/common/file_descriptor.cpp | 4 +- src/common/session.cpp | 22 ++-- src/common/session.h | 1 + src/common/transfer.cpp | 12 +- src/common/transfer.h | 2 + src/common/usb.cpp | 200 +++++++++++++++--------------- src/common/usb.h | 24 ++-- src/daemon/daemon_unity.cpp | 4 +- src/daemon/daemon_usb.cpp | 68 ++++++----- src/daemon/daemon_usb.h | 8 +- src/host/host_usb.cpp | 49 +++----- src/host/host_usb.h | 2 +- src/host/server.cpp | 4 +- 20 files changed, 324 insertions(+), 374 deletions(-) diff --git a/src/common/async_cmd.cpp b/src/common/async_cmd.cpp index 43d5f1a9..c87a4572 100644 --- a/src/common/async_cmd.cpp +++ b/src/common/async_cmd.cpp @@ -13,20 +13,11 @@ * limitations under the License. */ #include "async_cmd.h" -#define PIPE_READ 0 -#define PIPE_WRITE 1 namespace Hdc { // Do not add thread-specific init op in the following methods as it's running in child thread. AsyncCmd::AsyncCmd() { - Base::ZeroStruct(stdinPipe); - Base::ZeroStruct(stdoutPipe); - Base::ZeroStruct(stderrPipe); - Base::ZeroStruct(proc); - Base::ZeroStruct(procOptions); - running = false; - loop = nullptr; } AsyncCmd::~AsyncCmd() @@ -36,154 +27,115 @@ AsyncCmd::~AsyncCmd() bool AsyncCmd::ReadyForRelease() const { - return !running; + if (childShell != nullptr && !childShell->ReadyForRelease()) { + return false; + } + if (refCount != 0) { + return false; + } + if (childShell != nullptr) { + delete childShell; + } + if (fd > 0) { + close(fd); + } + return true; } -// manual stop will not trigger ExitCallback, we call it void AsyncCmd::DoRelease() { - if (hasStop || !running) { - return; - } - hasStop = true; // must set here to deny repeate release - uv_process_kill(&proc, SIGKILL); WRITE_LOG(LOG_DEBUG, "AsyncCmd::DoRelease finish"); -} - -void AsyncCmd::ChildReadCallback(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) -{ - AsyncCmd *thisClass = (AsyncCmd *)stream->data; - if (nread <= 0) { // stdout and stderr - WRITE_LOG(LOG_DEBUG, "Read ShellChildProcess failed %s", uv_err_name(nread)); - } else { - if (thisClass->options & OPTION_READBACK_OUT) { - thisClass->cmdResult = buf->base; - if (!thisClass->resultCallback(false, 0, thisClass->cmdResult)) { - uv_process_kill(&thisClass->proc, SIGKILL); - uv_read_stop(stream); - } - thisClass->cmdResult = STRING_EMPTY; - } else { // output all when finish - thisClass->cmdResult += buf->base; - } + if (childShell != nullptr) { + childShell->StopWork(false, nullptr); + } + if (pid > 0) { + uv_kill(pid, SIGTERM); } - delete[] buf->base; -} - -void AsyncCmd::ExitCallback(uv_process_t *req, int64_t exitStatus, int tersignal) -{ - auto funcReqClose = [](uv_handle_t *handle) -> void { - AsyncCmd *thisClass = (AsyncCmd *)handle->data; - if (--thisClass->uvRef == 0) { - thisClass->running = false; - } - }; - AsyncCmd *thisClass = (AsyncCmd *)req->data; - thisClass->hasStop = true; // callback maybe call dorelease, so deny repeate ExitCallback - - thisClass->resultCallback(true, exitStatus, thisClass->cmdResult); - WRITE_LOG(LOG_DEBUG, "AsyncCmd::ExitCallback"); - thisClass->uvRef = 4; - Base::TryCloseHandle((uv_handle_t *)&thisClass->stdinPipe, true, funcReqClose); - Base::TryCloseHandle((uv_handle_t *)&thisClass->stdoutPipe, true, funcReqClose); - Base::TryCloseHandle((uv_handle_t *)&thisClass->stderrPipe, true, funcReqClose); - Base::TryCloseHandle((uv_handle_t *)req, true, funcReqClose); - thisClass->cmdResult = STRING_EMPTY; } bool AsyncCmd::Initial(uv_loop_t *loopIn, const CmdResultCallback callback, uint32_t optionsIn) { - if (running) { - return false; - } +#if defined _WIN32 || defined HDC_HOST + WRITE_LOG(LOG_FATAL, "Not support for win32-host"); + return false; +#endif loop = loopIn; resultCallback = callback; options = optionsIn; return true; } -bool AsyncCmd::ExecuteCommand(const string &command) +bool AsyncCmd::FinishShellProc(const void *context, const bool result, const string exitMsg) { - string cmd = command; - Base::Trim(cmd, "\""); - if (!(options & OPTION_COMMAND_ONETIME)) { - if (StartProcess() < 0) { - return false; - } - if (options & OPTION_APPEND_NEWLINE) { - cmd += "\n"; - } - Base::SendToStream((uv_stream_t *)&stdinPipe, (uint8_t *)cmd.c_str(), cmd.size() + 1); - } else { - if (StartProcess(cmd) < 0) { - return false; - } - } + WRITE_LOG(LOG_DEBUG, "FinishShellProc finish"); + AsyncCmd *thisClass = (AsyncCmd *)context; + thisClass->resultCallback(true, result, exitMsg); + --thisClass->refCount; return true; -} +}; -int AsyncCmd::StartProcess(string command) +bool AsyncCmd::ChildReadCallback(const void *context, uint8_t *buf, const int size) { - constexpr auto countStdIOCount = 3; - char **ppShellArgs = nullptr; - string shellPath = Base::GetShellPath(); - uv_stdio_container_t stdioShellProc[countStdIOCount]; - while (true) { - uv_pipe_init(loop, &stdinPipe, 1); - uv_pipe_init(loop, &stdoutPipe, 1); - uv_pipe_init(loop, &stderrPipe, 1); - stdinPipe.data = this; - stdoutPipe.data = this; - stderrPipe.data = this; - procOptions.stdio = stdioShellProc; - procOptions.stdio[STDIN_FILENO].flags = (uv_stdio_flags)(UV_CREATE_PIPE | UV_READABLE_PIPE); - procOptions.stdio[STDIN_FILENO].data.stream = (uv_stream_t *)&stdinPipe; - procOptions.stdio[STDOUT_FILENO].flags = (uv_stdio_flags)(UV_CREATE_PIPE | UV_WRITABLE_PIPE); - procOptions.stdio[STDOUT_FILENO].data.stream = (uv_stream_t *)&stdoutPipe; - procOptions.stdio[STDERR_FILENO].flags = (uv_stdio_flags)(UV_CREATE_PIPE | UV_WRITABLE_PIPE); - procOptions.stdio[STDERR_FILENO].data.stream = (uv_stream_t *)&stderrPipe; - procOptions.stdio_count = countStdIOCount; - procOptions.file = shellPath.c_str(); - procOptions.exit_cb = ExitCallback; + AsyncCmd *thisClass = (AsyncCmd *)context; + string s((char *)buf, size); + return thisClass->resultCallback(false, 0, s); +}; - if (command.size() > 0) { - constexpr auto args = 4; - ppShellArgs = new char *[args]; - const string shellCommandFlag = "-c"; - ppShellArgs[0] = (char *)shellPath.c_str(); - ppShellArgs[1] = (char *)shellCommandFlag.c_str(); - ppShellArgs[args - CMD_ARG1_COUNT] = (char *)command.c_str(); - ppShellArgs[args - 1] = nullptr; - } else { - ppShellArgs = new char *[CMD_ARG1_COUNT]; - ppShellArgs[0] = (char *)shellPath.c_str(); - ppShellArgs[1] = nullptr; - } - procOptions.args = ppShellArgs; - proc.data = this; +int AsyncCmd::Popen(string command, bool readWrite, int &pid) +{ +#ifdef _WIN32 + return ERR_NO_SUPPORT; +#else + constexpr uint8_t PIPE_READ = 0; + constexpr uint8_t PIPE_WRITE = 1; + pid_t childPid; + int fd[2]; + pipe(fd); - if (uv_spawn(loop, &proc, &procOptions)) { - WRITE_LOG(LOG_FATAL, "Spawn shell process failed"); - break; - } - if (uv_read_start((uv_stream_t *)&stdoutPipe, Base::AllocBufferCallback, ChildReadCallback)) { - break; + if ((childPid = fork()) == -1) { + return ERR_GENERIC; + } + if (childPid == 0) { + if (readWrite) { + close(fd[PIPE_READ]); + dup2(fd[PIPE_WRITE], STDOUT_FILENO); + dup2(fd[PIPE_WRITE], STDERR_FILENO); + } else { + close(fd[PIPE_WRITE]); + dup2(fd[PIPE_READ], STDIN_FILENO); } - if (uv_read_start((uv_stream_t *)&stderrPipe, Base::AllocBufferCallback, ChildReadCallback)) { - break; + setpgid(childPid, childPid); + string shellPath = Base::GetShellPath(); + execl(shellPath.c_str(), shellPath.c_str(), "-c", command.c_str(), NULL); + exit(0); + } else { + if (readWrite) { + close(fd[PIPE_WRITE]); + } else { + close(fd[PIPE_READ]); } - running = true; - break; - } - if (ppShellArgs) { - delete[] ppShellArgs; } - if (!running) { - // failed - resultCallback(true, -1, "Start process failed"); - return -1; + pid = childPid; + if (readWrite) { + return fd[PIPE_READ]; } else { - return 0; + return fd[PIPE_WRITE]; } +#endif +} + +bool AsyncCmd::ExecuteCommand(const string &command) +{ + string cmd = command; + Base::Trim(cmd, "\""); + if ((fd = Popen(cmd, true, pid)) < 0) { + return false; + } + childShell = new HdcFileDescriptor(loop, fd, this, ChildReadCallback, FinishShellProc); + if (!childShell->StartWork()) { + return false; + } + ++refCount; + return true; } } // namespace Hdc \ No newline at end of file diff --git a/src/common/async_cmd.h b/src/common/async_cmd.h index f7772282..f14eaaff 100644 --- a/src/common/async_cmd.h +++ b/src/common/async_cmd.h @@ -40,25 +40,17 @@ public: bool ReadyForRelease() const; private: - int StartProcess(string command = STRING_EMPTY); - // uv_read_cb callback 1st parameter can't be changed, const can't be added - static void ChildReadCallback(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); - // uv_exit_cb callback 1st parameter can't be changed, const can't be added - static void ExitCallback(uv_process_t *req, int64_t exitStatus, int tersignal); + static bool FinishShellProc(const void *context, const bool result, const string exitMsg); + static bool ChildReadCallback(const void *context, uint8_t *buf, const int size); + int Popen(string command, bool readWrite, int &pid); - uv_loop_t *loop; - // loop is given to uv_spawn, which can't be const - uv_pipe_t stdinPipe; - uv_pipe_t stdoutPipe; - uv_pipe_t stderrPipe; - uv_process_t proc; - uv_process_options_t procOptions; - CmdResultCallback resultCallback; - string cmdResult; - bool running; - bool hasStop = false; uint32_t options = 0; - uint8_t uvRef = 0; + int fd = 0; + int pid; + HdcFileDescriptor *childShell = nullptr; + uint32_t refCount = 0; + CmdResultCallback resultCallback; + uv_loop_t *loop; }; } // namespace Hdc #endif \ No newline at end of file diff --git a/src/common/base.h b/src/common/base.h index ec40a99e..4faf228f 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -144,9 +144,9 @@ namespace Base { { return MAX_SIZE_IOBUF; } - inline int GetUsbffsMaxBulkSize() + inline int GetUsbffsBulkSize() { - return USBFFS_BULKSIZE_MAX; + return MAX_USBFFS_BULK; } } // namespace base } // namespace Hdc diff --git a/src/common/channel.cpp b/src/common/channel.cpp index 91352b97..3fa84c56 100644 --- a/src/common/channel.cpp +++ b/src/common/channel.cpp @@ -19,6 +19,7 @@ HdcChannelBase::HdcChannelBase(const bool serverOrClient, const string &addrStri SetChannelTCPString(addrString); isServerOrClient = serverOrClient; loopMain = loopMainIn; + hChannelBasenMainThread = uv_thread_self(); uv_rwlock_init(&mainAsync); uv_async_init(loopMain, &asyncMainLoop, MainAsyncCallback); uv_rwlock_init(&lockMapChannel); @@ -287,13 +288,23 @@ void HdcChannelBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_bu } } +uint32_t HdcChannelBase::GetChannelPseudoUid() +{ + uint32_t uid = 0; + HChannel hInput = nullptr; + do { + uid = static_cast(Base::GetRandom()); + } while ((hInput = AdminChannel(OP_QUERY, uid, nullptr)) != nullptr); + return uid; +} + uint32_t HdcChannelBase::MallocChannel(HChannel *hOutChannel) { auto hChannel = new HdcChannel(); if (!hChannel) { return 0; } - uint32_t channelId = Base::GetRuntimeMSec(); + uint32_t channelId = GetChannelPseudoUid(); if (isServerOrClient) { hChannel->serverOrClient = isServerOrClient; ++channelId; // Use different value for serverForClient&client in per process @@ -380,24 +391,19 @@ void HdcChannelBase::FreeChannelOpeate(uv_timer_t *handle) void HdcChannelBase::FreeChannel(const uint32_t channelId) { - HChannel hChannel = AdminChannel(OP_QUERY_REF, channelId, nullptr); - if (!hChannel) { + if (hChannelBasenMainThread != uv_thread_self()) { + PushAsyncMessage(channelId, ASYNC_FREE_CHANNEL, nullptr, 0); return; } - WRITE_LOG(LOG_DEBUG, "Begin to free channel, channelid:%u", channelId); + HChannel hChannel = AdminChannel(OP_QUERY, channelId, nullptr); 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) { + if (!hChannel || hChannel->isDead) { break; } + WRITE_LOG(LOG_DEBUG, "Begin to free channel, channelid:%u", channelId); 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) diff --git a/src/common/channel.h b/src/common/channel.h index 72b81813..8171ffab 100644 --- a/src/common/channel.h +++ b/src/common/channel.h @@ -67,9 +67,11 @@ private: void ClearChannels(); void FreeChannelContinue(HChannel hChannel); bool SetChannelTCPString(const string &addrString); + uint32_t GetChannelPseudoUid(); uv_rwlock_t lockMapChannel; // protect mapChannel map mapChannel; + uv_thread_t hChannelBasenMainThread; }; } // namespace Hdc diff --git a/src/common/define.h b/src/common/define.h index 97415433..28f22d44 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -23,8 +23,8 @@ 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 = 15360; // 15360 +constexpr uint16_t MAX_USBFFS_BULK = 16384; 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"; @@ -49,8 +49,8 @@ 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; +constexpr uint32_t HDC_VERSION_NUMBER = 0x10101b00; // 1.1.1b=0x10101100 +constexpr uint32_t HDC_BUF_MAX_BYTES = INT_MAX; const string WHITE_SPACES = " \t\n\r"; const string UT_TMP_PATH = "/tmp/hdc-ut"; diff --git a/src/common/define_plus.h b/src/common/define_plus.h index 1840498c..0251b1a3 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -55,6 +55,7 @@ enum OperateID { enum RetErrCode { RET_SUCCESS = 0, ERR_GENERIC = -1, + ERR_NO_SUPPORT, ERR_BUF_SIZE = -10000, ERR_BUF_ALLOC, ERR_BUF_OVERFLOW, @@ -159,9 +160,9 @@ enum HdcCommand { }; enum UsbProtocolOption { - USB_OPTION_TAIL = 1, + USB_OPTION_HEADER = 1, USB_OPTION_RESET = 2, - USB_OPTION_DUMMY = 4, + USB_OPTION_RESERVE4 = 4, USB_OPTION_RESERVE8 = 8, USB_OPTION_RESERVE16 = 16, }; @@ -173,7 +174,7 @@ struct USBHead { uint8_t flag[2]; uint8_t option; uint32_t sessionId; - uint16_t dataSize; + uint32_t dataSize; }; struct AsyncParam { @@ -214,13 +215,11 @@ struct HdcUSB { uint8_t epHost; uint8_t devId; uint8_t busId; - int32_t sizeEpBuf; + uint16_t sizeEpBuf; string serialNumber; string usbMountPoint; uint8_t *bufDevice; uint8_t *bufHost; - - mutex lockDeviceHandle; libusb_transfer *transferRecv; bool recvIOComplete; @@ -234,8 +233,9 @@ struct HdcUSB { int bulkOut; // EP1 device recv int bulkIn; // EP2 device send #endif + mutex lockDeviceHandle; uint16_t wMaxPacketSizeSend; - vector bufRecv; + uint32_t bulkinDataSize; bool resetIO; // if true, must break write and read,default false }; using HUSB = struct HdcUSB *; @@ -247,7 +247,7 @@ struct HdcSession { string connectKey; uint8_t connType; // ConnType uint32_t sessionId; - std::atomic ref; + 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; @@ -295,7 +295,7 @@ struct HdcChannel { bool childCleared; bool interactiveShellMode; // Is shell interactive mode bool keepAlive; // channel will not auto-close by server - std::atomic ref; + 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/file_descriptor.cpp b/src/common/file_descriptor.cpp index 61886062..83fd4d82 100644 --- a/src/common/file_descriptor.cpp +++ b/src/common/file_descriptor.cpp @@ -78,7 +78,9 @@ void HdcFileDescriptor::OnFileIO(uv_fs_t *req) // fs_write } } else { - WRITE_LOG(LOG_DEBUG, "OnFileIO fd:%d failed:%s", thisClass->fdIO, uv_strerror(req->result)); + if (req->result != 0) { + WRITE_LOG(LOG_DEBUG, "OnFileIO fd:%d failed:%s", thisClass->fdIO, uv_strerror(req->result)); + } bFinish = true; fetalFinish = true; break; diff --git a/src/common/session.cpp b/src/common/session.cpp index 69954bd1..6f4855bb 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -29,6 +29,7 @@ HdcSessionBase::HdcSessionBase(bool serverOrDaemonIn) serverOrDaemon = serverOrDaemonIn; ctxUSB = nullptr; wantRestart = false; + hSessioBasenMainThread = uv_thread_self(); #ifdef HDC_HOST if (serverOrDaemon) { @@ -314,7 +315,7 @@ int HdcSessionBase::MallocSessionByConnectType(HSession hSession) hSession->hUSB = hUSB; hSession->hUSB->wMaxPacketSizeSend = MAX_PACKET_SIZE_HISPEED; #ifdef HDC_HOST - int max = Base::GetUsbffsMaxBulkSize(); + int max = Base::GetUsbffsBulkSize(); hUSB->sizeEpBuf = max; hUSB->bufDevice = new uint8_t[max](); hUSB->bufHost = new uint8_t[max](); @@ -337,7 +338,7 @@ int HdcSessionBase::MallocSessionByConnectType(HSession hSession) uint32_t HdcSessionBase::GetSessionPseudoUid() { uint32_t uid = 0; - Hdc::HSession hInput = nullptr; + HSession hInput = nullptr; do { uid = static_cast(Base::GetRandom()); } while ((hInput = AdminSession(OP_QUERY, uid, nullptr)) != nullptr); @@ -481,6 +482,7 @@ void HdcSessionBase::FreeSessionOpeate(uv_timer_t *handle) HSession hSession = (HSession)handle->data; HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; if (hSession->ref > 0) { + WRITE_LOG(LOG_DEBUG, "ref:%u", uint32_t(hSession->ref)); return; } #ifdef HDC_HOST @@ -516,25 +518,21 @@ void HdcSessionBase::FreeSessionOpeate(uv_timer_t *handle) void HdcSessionBase::FreeSession(const uint32_t sessionId) { - HSession hSession = AdminSession(OP_QUERY_REF, sessionId, nullptr); - if (!hSession) { + if (hSessioBasenMainThread != uv_thread_self()) { + PushAsyncMessage(sessionId, ASYNC_FREE_SESSION, nullptr, 0); return; } + HSession hSession = AdminSession(OP_QUERY, sessionId, nullptr); 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; + if (!hSession || hSession->isDead) { + break; } 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)); + WRITE_LOG(LOG_DEBUG, "FreeSession sessionId:%u ref:%u", hSession->sessionId, uint32_t(hSession->ref)); } while (false); - --hSession->ref; } HSession HdcSessionBase::AdminSession(const uint8_t op, const uint32_t sessionId, HSession hInput) diff --git a/src/common/session.h b/src/common/session.h index ce0b760c..6f5bde31 100644 --- a/src/common/session.h +++ b/src/common/session.h @@ -178,6 +178,7 @@ private: uv_rwlock_t lockMapSession; std::atomic sessionRef = 0; const uint8_t payloadProtectStaticVcode = 0x09; + uv_thread_t hSessioBasenMainThread; }; } // namespace Hdc #endif \ No newline at end of file diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index 5b8349d3..4a15b795 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -199,10 +199,8 @@ void HdcTransferBase::OnFileIO(uv_fs_t *req) break; } if (context->indexIO < context->fileSize) { - // read continue until result >0, let single file packet +packet header less than 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); + thisClass->SimpleFileIO(context, context->indexIO, nullptr, + Base::GetMaxBufSize() * thisClass->maxTransferBufFactor); } } else if (req->fs_type == UV_FS_WRITE) { // write if (context->indexIO >= context->fileSize) { @@ -385,12 +383,10 @@ bool HdcTransferBase::CommandDispatch(const uint16_t command, uint8_t *payload, while (true) { if (command == commandBegin) { CtxFile *context = &ctxNow; - SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize()); + SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize() * maxTransferBufFactor); context->transferBegin = Base::GetRuntimeMSec(); } else if (command == commandData) { - // The size of the actual HOST end may be larger than maxbuf - constexpr auto doubleSize = 2; - if (payloadSize > Base::GetMaxBufSize() * doubleSize || payloadSize < 0) { + if ((uint32_t)payloadSize > HDC_BUF_MAX_BYTES || payloadSize < 0) { ret = false; break; } diff --git a/src/common/transfer.h b/src/common/transfer.h index 3b660cf7..3b9ccaab 100644 --- a/src/common/transfer.h +++ b/src/common/transfer.h @@ -109,6 +109,8 @@ private: int SimpleFileIO(CtxFile *context, uint64_t index, uint8_t *sendBuf, int bytesIO); bool SendIOPayload(CtxFile *context, int index, uint8_t *data, int dataSize); bool RecvIOPayload(CtxFile *context, uint8_t *data, int dataSize); + + double maxTransferBufFactor = 0.8; // Make the data sent by each IO in one hdc packet }; } // namespace Hdc diff --git a/src/common/usb.cpp b/src/common/usb.cpp index ed83c04f..51148aa4 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -55,133 +55,131 @@ bool HdcUSBBase::ReadyForWorkThread(HSession hSession) return true; }; -vector HdcUSBBase::DummyPacket(uint32_t sessionId) +vector HdcUSBBase::BuildPacketHeader(uint32_t sessionId, uint8_t option, uint32_t dataSize) { - vector dummy; + vector vecData; 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; + for (size_t i = 0; i < sizeof(head.flag); i++) { + head.flag[i] = USB_PACKET_FLAG.data()[i]; + } + head.option = option; + head.dataSize = htonl(dataSize); + vecData.insert(vecData.end(), (uint8_t *)&head, (uint8_t *)&head + sizeof(USBHead)); + return vecData; } // 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) { - // Format:USBPacket1 payload1...USBPacketn payloadn; - // [USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] - // - 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; - } - for (i = 0; i < iCount; ++i) { - USBHead *pUSBHead = (USBHead *)ioBuf; - int errCode = memcpy_s(pUSBHead->flag, sizeof(pUSBHead->flag), PACKET_FLAG.c_str(), PACKET_FLAG.size()); - if (errCode != EOK) { - offset = ERR_BUF_COPY; - break; - } - pUSBHead->sessionId = htonl(hSession->sessionId); - if (i != iCount - 1) { - dataSize = singleSize; - } else { - 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, dataSize)) { - offset = ERR_BUF_COPY; + auto header = BuildPacketHeader(hSession->sessionId, USB_OPTION_HEADER, length); + hSession->hUSB->lockDeviceHandle.lock(); + do { + if ((childRet = SendUSBRaw(hSession, header.data(), header.size())) <= 0) { break; } - offset += dataSize; - ++hSession->ref; - if ((childRet = SendUSBRaw(hSession, ioBuf, sizeUSBPacketHead + dataSize)) <= 0) { - offset = ERR_IO_FAIL; + if ((childRet = SendUSBRaw(hSession, data, length)) <= 0) { break; } - if (childRet % hSession->hUSB->wMaxPacketSizeSend == 0) { - // Just daemon enable zero length packet. + if (childRet > 0 && (childRet % hSession->hUSB->wMaxPacketSizeSend == 0)) { // win32 send ZLP will block winusb driver and LIBUSB_TRANSFER_ADD_ZERO_PACKET not effect - auto dummy = DummyPacket(hSession->sessionId); - SendUSBRaw(hSession, dummy.data(), dummy.size()); + // so, we send dummy packet to prevent zero packet generate + auto dummy = BuildPacketHeader(hSession->sessionId, 0, 0); + if ((childRet = SendUSBRaw(hSession, dummy.data(), dummy.size())) < 0) { + break; + } } - } - delete[] ioBuf; - return offset; + childRet = length; + } while (false); + hSession->hUSB->lockDeviceHandle.unlock(); + return childRet; } -// return value: <0 error; = 0 all finish; >0 need size -int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t *appendData, int dataSize) +bool HdcUSBBase::IsUsbPacketHeader(uint8_t *ioBuf, int ioBytes) { - HUSB hUSB = hSession->hUSB; - vector &bufRecv = hUSB->bufRecv; - bufRecv.insert(bufRecv.end(), appendData, appendData + dataSize); - int ret = RET_SUCCESS; - 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; + USBHead *usbPayloadHeader = (struct USBHead *)ioBuf; + uint32_t maybeSize = ntohl(usbPayloadHeader->dataSize); + bool isHeader = false; + do { + if (memcmp(usbPayloadHeader->flag, USB_PACKET_FLAG.c_str(), USB_PACKET_FLAG.size())) { break; } - usbHeader->sessionId = ntohl(usbHeader->sessionId); - usbHeader->dataSize = ntohs(usbHeader->dataSize); - if (usbHeader->dataSize > USBFFS_BULKSIZE_MAX) { - ret = ERR_BUF_SIZE; + if (ioBytes != sizeof(USBHead)) { 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) { - // Only server do it here, daemon 'SendUsbSoftReset' no use - // hilog + ctrl^C to reproduction scene - // - // Because the USB-reset API does not work on all platforms, the last session IO data may be - // recveived, we need to ignore it. - if (hSession->serverOrDaemon && !hUSB->resetIO) { - WRITE_LOG(LOG_WARN, "SendToHdcStream sessionId not matched"); - SendUsbSoftReset(hUSB, usbHeader->sessionId); - hUSB->resetIO = true; - } - } else { - bool isZlp = false; - if (usbHeader->option & USB_OPTION_DUMMY) { - // soft ZLP - isZlp = true; - } - // usb data to logic - 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()); + if (maybeSize == 0) { + isHeader = true; // nop packet + break; + } else { // maybeSize != 0 + if (usbPayloadHeader->option & USB_OPTION_HEADER) { + isHeader = true; break; } } - bufRecv.erase(bufRecv.begin(), bufRecv.begin() + fullPacketSize); + } while (false); + return isHeader; +} + +void HdcUSBBase::PreSendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) +{ + HUSB hUSB = hSession->hUSB; + if (hSession->serverOrDaemon && !hUSB->resetIO) { + uint32_t sid = sessionIdOld; + if (hUSB->lockDeviceHandle.try_lock()) { + ++hSession->ref; + WRITE_LOG(LOG_WARN, "SendToHdcStream check, sessionId not matched"); + SendUsbSoftReset(hSession, sid); + --hSession->ref; + hUSB->lockDeviceHandle.unlock(); + } + } +} + +int HdcUSBBase::SpecialPacket(HSession hSession, uint8_t *appendData, int dataSize) +{ + HUSB hUSB = hSession->hUSB; + // special short packet + USBHead *header = (USBHead *)appendData; + header->sessionId = ntohl(header->sessionId); + header->dataSize = ntohl(header->dataSize); + if (header->sessionId != hSession->sessionId) { + // Only server do it here, daemon 'SendUsbSoftReset' no use + // hilog + ctrl^C to reproduction scene + // + // Because the USB-reset API does not work on all platforms, the last session IO data may be + // recveived, we need to ignore it. + PreSendUsbSoftReset(hSession, header->sessionId); + return 0; + } + if (header->option & USB_OPTION_HEADER) { + // header packet + hUSB->bulkinDataSize = header->dataSize; } - return ret; + // soft ZLP + return hUSB->bulkinDataSize; } + +// return value: <0 error; = 0 all finish; >0 need size +int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t *appendData, int dataSize) +{ + int childRet = 0; + HUSB hUSB = hSession->hUSB; + if (IsUsbPacketHeader(appendData, dataSize)) { + return SpecialPacket(hSession, appendData, dataSize); + } + if (hUSB->bulkinDataSize <= (uint32_t)childRet) { + // last session data + PreSendUsbSoftReset(hSession, 0); // 0 == reset current + return 0; + } + if ((childRet = Base::SendToStream(stream, appendData, dataSize)) < 0) { + WRITE_LOG(LOG_FATAL, "Error usb send to stream dataSize:%d", dataSize); + return ERR_IO_FAIL; + } + hUSB->bulkinDataSize -= childRet; + return hUSB->bulkinDataSize; +} + } \ No newline at end of file diff --git a/src/common/usb.h b/src/common/usb.h index 32d45b32..d0fd6dae 100644 --- a/src/common/usb.h +++ b/src/common/usb.h @@ -21,22 +21,30 @@ class HdcUSBBase { public: HdcUSBBase(const bool serverOrDaemonIn, void *ptrMainBase); virtual ~HdcUSBBase(); + virtual bool ReadyForWorkThread(HSession hSession); + virtual void CancelUsbLoopRead(HUSB hUSB) {}; + int SendUSBBlock(HSession hSession, uint8_t *data, const int length); + +protected: virtual int SendUSBRaw(HSession hSession, uint8_t *data, const int length) { return 0; } - 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); - vector DummyPacket(uint32_t sessionId); + int GetSafeUsbBlockSize(uint16_t wMaxPacketSizeSend); + bool IsUsbPacketHeader(uint8_t *ioBuf, int ioBytes); -protected: void *clsMainBase; - bool serverOrDaemon; bool modRunning; + bool serverOrDaemon; + const string USB_PACKET_FLAG = "UB"; // must 2bytes + +private: + virtual void SendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) {}; + static void ReadUSB(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); + vector BuildPacketHeader(uint32_t sessionId, uint8_t option, uint32_t dataSize); + int SpecialPacket(HSession hSession, uint8_t *appendData, int dataSize); + void PreSendUsbSoftReset(HSession hSession, uint32_t sessionIdOld); }; } // namespace Hdc diff --git a/src/daemon/daemon_unity.cpp b/src/daemon/daemon_unity.cpp index c4dc63af..062cabd3 100644 --- a/src/daemon/daemon_unity.cpp +++ b/src/daemon/daemon_unity.cpp @@ -118,7 +118,7 @@ bool HdcDaemonUnity::FindMountDeviceByPath(const char *toQuery, char *dev) // clang-format on dev[BUF_SIZE_SMALL - 1] = '\0'; dir[BUF_SIZE_SMALL - 1] = '\0'; - if (res == 4 && (strcmp(toQuery, dir) == 0)) { // 4 : The correct number of parameters + if (res == 4 && (strcmp(toQuery, dir) == 0)) { // 4 : The correct number of parameters return true; } token = strtok(nullptr, delims); @@ -132,7 +132,7 @@ bool HdcDaemonUnity::RemountPartition(const char *dir) int off = 0; char dev[BUF_SIZE_SMALL] = ""; - if (!FindMountDeviceByPath(dir, dev) || strlen(dev) < 4) { // 4 : file count + if (!FindMountDeviceByPath(dir, dev) || strlen(dev) < 4) { // 4 : file count WRITE_LOG(LOG_DEBUG, "FindMountDeviceByPath failed"); return false; } diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index f8a893b9..51a5131e 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -141,7 +141,6 @@ int HdcDaemonUSB::ConnectEPPoint(HUSB hUSB) 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(); ret = RET_SUCCESS; break; } @@ -169,9 +168,12 @@ void HdcDaemonUSB::CloseEndpoint(HUSB hUSB, bool closeCtrlEp) WRITE_LOG(LOG_FATAL, "DaemonUSB close endpoint"); } -void HdcDaemonUSB::ResetOldSession(const uint32_t sessionId) +void HdcDaemonUSB::ResetOldSession(uint32_t sessionId) { HdcDaemon *daemon = reinterpret_cast(clsMainBase); + if (sessionId == 0) { + sessionId = currentSessionId; + } HSession hSession = daemon->AdminSession(OP_QUERY, sessionId, nullptr); if (hSession == nullptr) { return; @@ -179,30 +181,26 @@ void HdcDaemonUSB::ResetOldSession(const uint32_t sessionId) hSession->hUSB->resetIO = true; // The Host side is restarted, but the USB cable is still connected WRITE_LOG(LOG_WARN, "Hostside softreset to restart daemon, old sessionId:%u", sessionId); - daemon->PushAsyncMessage(sessionId, ASYNC_FREE_SESSION, nullptr, 0); + daemon->FreeSession(sessionId); } // Prevent other USB data misfortunes to send the program crash -int HdcDaemonUSB::AvailablePacket(uint8_t *ioBuf, uint32_t *sessionId) +int HdcDaemonUSB::AvailablePacket(uint8_t *ioBuf, int ioBytes, uint32_t *sessionId) { int ret = RET_SUCCESS; - constexpr auto maxBufFactor = 1.2; while (true) { - struct USBHead *usbPayloadHeader = (struct USBHead *)ioBuf; - if (memcmp(usbPayloadHeader->flag, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { - ret = ERR_BUF_CHECK; - break; - } - if (ntohs(usbPayloadHeader->dataSize) > Base::GetMaxBufSize() * maxBufFactor + sizeof(USBHead)) { - ret = ERR_BUF_SIZE; + if (!IsUsbPacketHeader(ioBuf, ioBytes)) { break; } + // usb header + USBHead *usbPayloadHeader = (struct USBHead *)ioBuf; + uint32_t inSessionId = ntohl(usbPayloadHeader->sessionId); if ((usbPayloadHeader->option & USB_OPTION_RESET)) { - ResetOldSession(ntohl(usbPayloadHeader->sessionId)); + ResetOldSession(inSessionId); ret = ERR_IO_SOFT_RESET; break; } - *sessionId = ntohl(usbPayloadHeader->sessionId); + *sessionId = inSessionId; break; } return ret; @@ -273,9 +271,6 @@ 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); } - if (length != 0) { - hSession->ref--; - } return ret; } @@ -283,13 +278,14 @@ int HdcDaemonUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) { HdcDaemon *daemon = (HdcDaemon *)hSession->classInstance; // Prevent memory stacking, send temporary way to use asynchronous - // Generally sent in the same thread, but when new session is created, there is a possibility that the old session - // is not retired. - // At present, the radical transmission method is currently opened directly in various threads, and - // it can be used exclusive File-DESC transmission mode in each thread. The late stage can be used as asynchronous + - // SendPipe to the main thread transmission. + // Generally sent in the same thread, but when new session is created, there is a possibility that the old + // session is not retired. At present, the radical transmission method is currently opened directly in various + // threads, and it can be used exclusive File-DESC transmission mode in each thread. The late stage can be used + // as asynchronous + SendPipe to the main thread transmission. uv_mutex_lock(&sendEP); + ++hSession->ref; int ret = SendUSBIOSync(hSession, &usbHandle, data, length); + --hSession->ref; if (ret < 0) { daemon->FreeSession(hSession->sessionId); WRITE_LOG(LOG_DEBUG, "SendUSBRaw try to freesession"); @@ -301,7 +297,7 @@ int HdcDaemonUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) // cross thread call void HdcDaemonUSB::OnNewHandshakeOK(const uint32_t sessionId) { - currentSessionId = sessionId; // real Id + currentSessionId = sessionId; // sync with server, and set server's real Id } HSession HdcDaemonUSB::PrepareNewSession(uint32_t sessionId, uint8_t *pRecvBuf, int recvBytesIO) @@ -311,12 +307,7 @@ HSession HdcDaemonUSB::PrepareNewSession(uint32_t sessionId, uint8_t *pRecvBuf, if (!hChildSession) { return nullptr; } - if (currentSessionId != 0) { - // reset old session - // The Host side is restarted, but the USB cable is still connected - WRITE_LOG(LOG_WARN, "New session coming, restart old sessionId:%u", currentSessionId); - daemon->PushAsyncMessage(currentSessionId, ASYNC_FREE_SESSION, nullptr, 0); - } + currentSessionId = sessionId; Base::StartWorkThread(&daemon->loopMain, daemon->SessionWorkThread, Base::FinishWorkThread, hChildSession); auto funcNewSessionUp = [](uv_timer_t *handle) -> void { HSession hChildSession = reinterpret_cast(handle->data); @@ -335,13 +326,22 @@ HSession HdcDaemonUSB::PrepareNewSession(uint32_t sessionId, uint8_t *pRecvBuf, return hChildSession; } -int HdcDaemonUSB::DispatchToWorkThread(const uint32_t sessionId, uint8_t *readBuf, int readBytes) +int HdcDaemonUSB::DispatchToWorkThread(uint32_t sessionId, uint8_t *readBuf, int readBytes) { // Format:USBPacket1 payload1...USBPacketn // payloadn-[USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] HSession hChildSession = nullptr; HdcDaemon *daemon = reinterpret_cast(clsMainBase); int childRet = RET_SUCCESS; + if (sessionId == 0) { + // hdc packet data + sessionId = currentSessionId; + } + if (currentSessionId != 0 && sessionId != currentSessionId) { + WRITE_LOG(LOG_WARN, "New session coming, restart old sessionId:%u", currentSessionId); + ResetOldSession(currentSessionId); + currentSessionId = 0; + } hChildSession = daemon->AdminSession(OP_QUERY, sessionId, nullptr); if (!hChildSession) { hChildSession = PrepareNewSession(sessionId, readBuf, readBytes); @@ -349,6 +349,7 @@ int HdcDaemonUSB::DispatchToWorkThread(const uint32_t sessionId, uint8_t *readBu return ERR_SESSION_NOFOUND; } } + if (hChildSession->childCleared) { return ERR_SESSION_DEAD; } @@ -399,7 +400,7 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) break; } // guess is head of packet - if ((childRet = thisClass->AvailablePacket((uint8_t *)bufPtr, &sessionId)) != RET_SUCCESS) { + if ((childRet = thisClass->AvailablePacket((uint8_t *)bufPtr, bytesIOBytes, &sessionId)) != RET_SUCCESS) { if (childRet != ERR_IO_SOFT_RESET) { WRITE_LOG(LOG_WARN, "AvailablePacket check failed, ret:%d buf:%-50s", bytesIOBytes, bufPtr); break; @@ -413,7 +414,8 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) break; } } - if (thisClass->LoopUSBRead(hUSB, childRet == 0 ? Base::GetUsbffsMaxBulkSize() : childRet) < 0) { + int nextReadSize = childRet == 0 ? hUSB->wMaxPacketSizeSend : std::min(childRet, Base::GetUsbffsBulkSize()); + if (thisClass->LoopUSBRead(hUSB, nextReadSize) < 0) { WRITE_LOG(LOG_FATAL, "LoopUSBRead failed"); break; } @@ -497,6 +499,6 @@ void HdcDaemonUSB::WatchEPTimer(uv_timer_t *handle) } // connect OK thisClass->isAlive = true; - thisClass->LoopUSBRead(hUSB); + thisClass->LoopUSBRead(hUSB, hUSB->wMaxPacketSizeSend); } } // namespace Hdc \ No newline at end of file diff --git a/src/daemon/daemon_usb.h b/src/daemon/daemon_usb.h index 30c1aed8..6a93eadc 100644 --- a/src/daemon/daemon_usb.h +++ b/src/daemon/daemon_usb.h @@ -37,17 +37,17 @@ private: static void OnUSBRead(uv_fs_t *req); static void WatchEPTimer(uv_timer_t *handle); int ConnectEPPoint(HUSB hUSB); - int DispatchToWorkThread(const uint32_t sessionId, uint8_t *readBuf, int readBytes); - int AvailablePacket(uint8_t *ioBuf, uint32_t *sessionId); + int DispatchToWorkThread(uint32_t sessionId, uint8_t *readBuf, int readBytes); + int AvailablePacket(uint8_t *ioBuf, int ioBytes, uint32_t *sessionId); void CloseEndpoint(HUSB hUSB, bool closeCtrlEp = false); string GetDevPath(const std::string &path); bool ReadyForWorkThread(HSession hSession); - int LoopUSBRead(HUSB hUSB, int readMaxWanted = Base::GetUsbffsMaxBulkSize()); + int LoopUSBRead(HUSB hUSB, int readMaxWanted); 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); + void ResetOldSession(uint32_t sessionId); int GetMaxPacketSize(int fdFfs); HdcUSB usbHandle; diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 9219bc95..29650b20 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -62,19 +62,21 @@ int HdcHostUSB::Initial() // windows/mac's control port reset seems invalid? So we try to use soft interrupt // if all platform 'libusb_reset_device()' work ok, commit this function and use it replace // main thread call -void HdcHostUSB::SendUsbSoftReset(HUSB hUSB, uint32_t sessionId) +void HdcHostUSB::SendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) { struct ResetCtx { USBHead usbPayloadHeader; - HUSB hUSB; + HSession hSession; }; ResetCtx *ctxReset = new ResetCtx(); - ctxReset->hUSB = hUSB; + ctxReset->hSession = hSession; + HUSB hUSB = hSession->hUSB; USBHead &usbPayloadHeader = ctxReset->usbPayloadHeader; usbPayloadHeader.option = USB_OPTION_RESET; - usbPayloadHeader.sessionId = htonl(sessionId); - if (memcpy_s(usbPayloadHeader.flag, sizeof(usbPayloadHeader.flag), PACKET_FLAG.c_str(), + usbPayloadHeader.dataSize = 0; + usbPayloadHeader.sessionId = htonl(sessionIdOld); + if (memcpy_s(usbPayloadHeader.flag, sizeof(usbPayloadHeader.flag), USB_PACKET_FLAG.c_str(), sizeof(usbPayloadHeader.flag)) != EOK) { delete ctxReset; @@ -85,24 +87,25 @@ void HdcHostUSB::SendUsbSoftReset(HUSB hUSB, uint32_t sessionId) if (LIBUSB_TRANSFER_COMPLETED != transfer->status) { WRITE_LOG(LOG_FATAL, "SendUSBRaw status:%d", transfer->status); } - ctxReset->hUSB->sendIOComplete = true; + --ctxReset->hSession->ref; + ctxReset->hSession->hUSB->sendIOComplete = true; delete ctxReset; libusb_free_transfer(transfer); // has send soft reset, next reset daemon's send WRITE_LOG(LOG_DEBUG, "Device reset singal send"); }; - hUSB->lockDeviceHandle.lock(); libusb_transfer *transferUsb = libusb_alloc_transfer(0); libusb_fill_bulk_transfer(transferUsb, hUSB->devHandle, hUSB->epHost, (uint8_t *)&usbPayloadHeader, sizeof(USBHead), resetUsbCallback, ctxReset, GLOBAL_TIMEOUT * TIME_BASE); int err = libusb_submit_transfer(transferUsb); + --hSession->ref; if (err < 0) { WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", err); delete ctxReset; } else { hUSB->sendIOComplete = false; } - hUSB->lockDeviceHandle.unlock(); + hUSB->resetIO = true; } bool HdcHostUSB::DetectMyNeed(libusb_device *device, string &sn) @@ -356,14 +359,11 @@ void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfe if (childRet < 0) { break; } - hUSB->lockDeviceHandle.lock(); // loop self - // get usbffsmax or remaining size - libusb_fill_bulk_transfer(transfer, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, - childRet == 0 ? Base::GetUsbffsMaxBulkSize() : childRet, ReadUSBBulkCallback, - hSession, infinity); + int nextReadSize = childRet == 0 ? hUSB->wMaxPacketSizeSend : std::min(childRet, Base::GetUsbffsBulkSize()); + libusb_fill_bulk_transfer(transfer, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, nextReadSize, + ReadUSBBulkCallback, hSession, infinity); childRet = libusb_submit_transfer(transfer); - hUSB->lockDeviceHandle.unlock(); if (childRet < 0) { WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", childRet); break; @@ -386,12 +386,9 @@ void HdcHostUSB::RegisterReadCallback(HSession hSession) return; } hSession->hUSB->transferRecv->user_data = 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, - Base::GetUsbffsMaxBulkSize(), ReadUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); + hUSB->wMaxPacketSizeSend, ReadUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); int childRet = libusb_submit_transfer(hSession->hUSB->transferRecv); - hUSB->lockDeviceHandle.unlock(); if (childRet == 0) { hSession->hUSB->recvIOComplete = false; } @@ -450,21 +447,12 @@ int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) HUSB hUSB = hSession->hUSB; hUSB->sendIOComplete = false; HdcSessionBase *server = reinterpret_cast(hSession->classInstance); - + ++hSession->ref; while (true) { - if (memcpy_s(hUSB->bufHost, hUSB->sizeEpBuf, data, length) != EOK) { - ret = ERR_BUF_COPY; - break; - } - hUSB->lockDeviceHandle.lock(); std::unique_lock lock(hUSB->lockSend); - libusb_fill_bulk_transfer(hUSB->transferSend, hUSB->devHandle, hUSB->epHost, hUSB->bufHost, length, - WriteUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); + libusb_fill_bulk_transfer(hUSB->transferSend, hUSB->devHandle, hUSB->epHost, data, 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; break; @@ -473,6 +461,7 @@ int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) hUSB->cvTransferSend.wait(lock, [hUSB]() { return hUSB->sendIOComplete; }); break; } + --hSession->ref; if (ret < 0) { hSession->hUSB->sendIOComplete = true; server->FreeSession(hSession->sessionId); diff --git a/src/host/host_usb.h b/src/host/host_usb.h index 7b93892e..58f1ad22 100644 --- a/src/host/host_usb.h +++ b/src/host/host_usb.h @@ -48,7 +48,7 @@ private: bool ReadyForWorkThread(HSession hSession); bool FindDeviceByID(HUSB hUSB, const char *usbMountPoint, libusb_context *ctxUSB); bool DetectMyNeed(libusb_device *device, string &sn); - void SendUsbSoftReset(HUSB hUSB, uint32_t sessionId); + void SendUsbSoftReset(HSession hSession, uint32_t sessionIdOld); void RestoreHdcProtocol(HUSB hUsb, const uint8_t *buf, int bufSize); void UpdateUSBDaemonInfo(HUSB hUSB, HSession hSession, uint8_t connStatus); void RegisterReadCallback(HSession hSession); diff --git a/src/host/server.cpp b/src/host/server.cpp index 470fc1e2..3f2386fd 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -656,7 +656,7 @@ 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); + HChannel hChannel = hSfc->AdminChannel(OP_QUERY_REF, channelId, nullptr); if (!hChannel) { return; } @@ -667,10 +667,12 @@ void HdcServer::AttachChannel(HSession hSession, const uint32_t channelId) WRITE_LOG(LOG_DEBUG, "Hdcserver AttachChannel uv_tcp_open failed %s, channelid:%d fdChildWorkTCP:%d", uv_err_name(ret), hChannel->channelId, hChannel->fdChildWorkTCP); Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP); + --hChannel->ref; return; } Base::SetTcpOptions((uv_tcp_t *)&hChannel->hChildWorkTCP); uv_read_start((uv_stream_t *)&hChannel->hChildWorkTCP, hSfc->AllocCallback, hSfc->ReadStream); + --hChannel->ref; }; void HdcServer::DeatchChannel(HSession hSession, const uint32_t channelId) -- Gitee From fba4e20b8b1f85cc9f6def88ab70125c1f820f66 Mon Sep 17 00:00:00 2001 From: zako Date: Tue, 23 Nov 2021 21:15:36 +0800 Subject: [PATCH 17/50] maybe mutithread issue fix Signed-off-by: zako --- src/common/channel.cpp | 33 +++++++++++++++++++++------------ src/common/channel.h | 3 ++- src/common/define.h | 2 +- src/common/define_plus.h | 2 +- src/common/session.cpp | 7 ++++--- src/common/session.h | 2 +- src/common/transfer.h | 1 - src/common/usb.cpp | 12 ++++++++---- src/common/usb.h | 2 +- src/daemon/daemon.cpp | 2 +- src/daemon/daemon_usb.cpp | 9 +++++---- src/host/host_usb.cpp | 1 + src/host/server.cpp | 24 +++++++++++++++--------- src/host/server_for_client.cpp | 6 +++--- src/host/server_for_client.h | 2 +- 15 files changed, 65 insertions(+), 43 deletions(-) diff --git a/src/common/channel.cpp b/src/common/channel.cpp index 3fa84c56..e9fcbf38 100644 --- a/src/common/channel.cpp +++ b/src/common/channel.cpp @@ -19,7 +19,7 @@ HdcChannelBase::HdcChannelBase(const bool serverOrClient, const string &addrStri SetChannelTCPString(addrString); isServerOrClient = serverOrClient; loopMain = loopMainIn; - hChannelBasenMainThread = uv_thread_self(); + threadChanneMain = uv_thread_self(); uv_rwlock_init(&mainAsync); uv_async_init(loopMain, &asyncMainLoop, MainAsyncCallback); uv_rwlock_init(&lockMapChannel); @@ -246,17 +246,10 @@ void HdcChannelBase::PushAsyncMessage(const uint32_t channelId, const uint8_t me uv_async_send(&asyncMainLoop); } -// client to server, or vice versa -// works only in current working thread -void HdcChannelBase::Send(const uint32_t channelId, uint8_t *bufPtr, const int size) +void HdcChannelBase::SendChannel(HChannel hChannel, uint8_t *bufPtr, const int size) { uv_stream_t *sendStream = nullptr; int sizeNewBuf = size + DWORD_SERIALIZE_SIZE; - HChannel hChannel = (HChannel)AdminChannel(OP_QUERY, channelId, nullptr); - if (!hChannel || hChannel->isDead) { - return; - } - auto data = new uint8_t[sizeNewBuf](); if (!data) { return; @@ -277,6 +270,22 @@ void HdcChannelBase::Send(const uint32_t channelId, uint8_t *bufPtr, const int s } } +// works only in current working thread +void HdcChannelBase::Send(const uint32_t channelId, uint8_t *bufPtr, const int size) +{ + HChannel hChannel = (HChannel)AdminChannel(OP_QUERY_REF, channelId, nullptr); + if (!hChannel) { + return; + } + do { + if (hChannel->isDead) { + break; + } + SendChannel(hChannel, bufPtr, size); + } while (false); + --hChannel->ref; +} + void HdcChannelBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) { HChannel context = (HChannel)handle->data; @@ -317,7 +326,7 @@ uint32_t HdcChannelBase::MallocChannel(HChannel *hOutChannel) hChannel->channelId = channelId; AdminChannel(OP_ADD, channelId, hChannel); *hOutChannel = hChannel; - WRITE_LOG(LOG_DEBUG, "Mallocchannel:%d", channelId); + WRITE_LOG(LOG_DEBUG, "Mallocchannel:%u", channelId); return channelId; } @@ -331,7 +340,7 @@ void HdcChannelBase::FreeChannelFinally(uv_idle_t *handle) } thisClass->NotifyInstanceChannelFree(hChannel); thisClass->AdminChannel(OP_REMOVE, hChannel->channelId, nullptr); - WRITE_LOG(LOG_DEBUG, "!!!FreeChannelFinally channelId:%d finish", hChannel->channelId); + WRITE_LOG(LOG_DEBUG, "!!!FreeChannelFinally channelId:%u finish", hChannel->channelId); if (!hChannel->serverOrClient) { uv_stop(thisClass->loopMain); } @@ -391,7 +400,7 @@ void HdcChannelBase::FreeChannelOpeate(uv_timer_t *handle) void HdcChannelBase::FreeChannel(const uint32_t channelId) { - if (hChannelBasenMainThread != uv_thread_self()) { + if (threadChanneMain != uv_thread_self()) { PushAsyncMessage(channelId, ASYNC_FREE_CHANNEL, nullptr, 0); return; } diff --git a/src/common/channel.h b/src/common/channel.h index 8171ffab..689b2f4e 100644 --- a/src/common/channel.h +++ b/src/common/channel.h @@ -44,6 +44,7 @@ protected: } virtual void NotifyInstanceChannelFree(HChannel hChannel) {}; void Send(const uint32_t channelId, uint8_t *bufPtr, const int size); + void SendChannel(HChannel hChannel, uint8_t *bufPtr, const int size); virtual bool ChannelSendSessionCtrlMsg(vector &ctrlMsg, uint32_t sessionId) { return true; // just server use @@ -71,7 +72,7 @@ private: uv_rwlock_t lockMapChannel; // protect mapChannel map mapChannel; - uv_thread_t hChannelBasenMainThread; + uv_thread_t threadChanneMain; }; } // namespace Hdc diff --git a/src/common/define.h b/src/common/define.h index 28f22d44..2bb12cf1 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -49,7 +49,7 @@ 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 = 0x10101b00; // 1.1.1b=0x10101100 +constexpr uint32_t HDC_VERSION_NUMBER = 0x10101900; // 1.1.1b=0x10101100 constexpr uint32_t HDC_BUF_MAX_BYTES = INT_MAX; const string WHITE_SPACES = " \t\n\r"; diff --git a/src/common/define_plus.h b/src/common/define_plus.h index 0251b1a3..cd351356 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -55,7 +55,7 @@ enum OperateID { enum RetErrCode { RET_SUCCESS = 0, ERR_GENERIC = -1, - ERR_NO_SUPPORT, + ERR_NO_SUPPORT = -2, ERR_BUF_SIZE = -10000, ERR_BUF_ALLOC, ERR_BUF_OVERFLOW, diff --git a/src/common/session.cpp b/src/common/session.cpp index 6f4855bb..5d44e426 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -29,7 +29,7 @@ HdcSessionBase::HdcSessionBase(bool serverOrDaemonIn) serverOrDaemon = serverOrDaemonIn; ctxUSB = nullptr; wantRestart = false; - hSessioBasenMainThread = uv_thread_self(); + threadSessionMain = uv_thread_self(); #ifdef HDC_HOST if (serverOrDaemon) { @@ -518,7 +518,7 @@ void HdcSessionBase::FreeSessionOpeate(uv_timer_t *handle) void HdcSessionBase::FreeSession(const uint32_t sessionId) { - if (hSessioBasenMainThread != uv_thread_self()) { + if (threadSessionMain != uv_thread_self()) { PushAsyncMessage(sessionId, ASYNC_FREE_SESSION, nullptr, 0); return; } @@ -713,13 +713,14 @@ int HdcSessionBase::OnRead(HSession hSession, uint8_t *bufPtr, const int bufLen) { int ret = ERR_GENERIC; if (memcmp(bufPtr, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { + WRITE_LOG(LOG_FATAL, "PACKET_FLAG incorrect"); return ERR_BUF_CHECK; } struct PayloadHead *payloadHead = (struct PayloadHead *)bufPtr; int tobeReadLen = ntohl(payloadHead->dataSize) + ntohs(payloadHead->headSize); int packetHeadSize = sizeof(struct PayloadHead); if (tobeReadLen <= 0 || (uint32_t)tobeReadLen > HDC_BUF_MAX_BYTES) { - // max 1G + WRITE_LOG(LOG_FATAL, "Packet size incorrect"); return ERR_BUF_CHECK; } if (bufLen - packetHeadSize < tobeReadLen) { diff --git a/src/common/session.h b/src/common/session.h index 6f5bde31..440cb84f 100644 --- a/src/common/session.h +++ b/src/common/session.h @@ -178,7 +178,7 @@ private: uv_rwlock_t lockMapSession; std::atomic sessionRef = 0; const uint8_t payloadProtectStaticVcode = 0x09; - uv_thread_t hSessioBasenMainThread; + uv_thread_t threadSessionMain; }; } // namespace Hdc #endif \ No newline at end of file diff --git a/src/common/transfer.h b/src/common/transfer.h index 3b9ccaab..f9579976 100644 --- a/src/common/transfer.h +++ b/src/common/transfer.h @@ -109,7 +109,6 @@ private: int SimpleFileIO(CtxFile *context, uint64_t index, uint8_t *sendBuf, int bytesIO); bool SendIOPayload(CtxFile *context, int index, uint8_t *data, int dataSize); bool RecvIOPayload(CtxFile *context, uint8_t *data, int dataSize); - double maxTransferBufFactor = 0.8; // Make the data sent by each IO in one hdc packet }; } // namespace Hdc diff --git a/src/common/usb.cpp b/src/common/usb.cpp index 51148aa4..a6733ad6 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -74,13 +74,16 @@ vector HdcUSBBase::BuildPacketHeader(uint32_t sessionId, uint8_t option int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) { int childRet = 0; + int ret = ERR_IO_FAIL; auto header = BuildPacketHeader(hSession->sessionId, USB_OPTION_HEADER, length); hSession->hUSB->lockDeviceHandle.lock(); do { if ((childRet = SendUSBRaw(hSession, header.data(), header.size())) <= 0) { + WRITE_LOG(LOG_FATAL, "SendUSBRaw index failed"); break; } if ((childRet = SendUSBRaw(hSession, data, length)) <= 0) { + WRITE_LOG(LOG_FATAL, "SendUSBRaw body failed"); break; } if (childRet > 0 && (childRet % hSession->hUSB->wMaxPacketSizeSend == 0)) { @@ -88,13 +91,14 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) // so, we send dummy packet to prevent zero packet generate auto dummy = BuildPacketHeader(hSession->sessionId, 0, 0); if ((childRet = SendUSBRaw(hSession, dummy.data(), dummy.size())) < 0) { + WRITE_LOG(LOG_FATAL, "SendUSBRaw dummy failed"); break; } } - childRet = length; + ret = length; } while (false); hSession->hUSB->lockDeviceHandle.unlock(); - return childRet; + return ret; } bool HdcUSBBase::IsUsbPacketHeader(uint8_t *ioBuf, int ioBytes) @@ -137,7 +141,7 @@ void HdcUSBBase::PreSendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) } } -int HdcUSBBase::SpecialPacket(HSession hSession, uint8_t *appendData, int dataSize) +int HdcUSBBase::CheckPacketOption(HSession hSession, uint8_t *appendData, int dataSize) { HUSB hUSB = hSession->hUSB; // special short packet @@ -167,7 +171,7 @@ int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t int childRet = 0; HUSB hUSB = hSession->hUSB; if (IsUsbPacketHeader(appendData, dataSize)) { - return SpecialPacket(hSession, appendData, dataSize); + return CheckPacketOption(hSession, appendData, dataSize); } if (hUSB->bulkinDataSize <= (uint32_t)childRet) { // last session data diff --git a/src/common/usb.h b/src/common/usb.h index d0fd6dae..ac30a308 100644 --- a/src/common/usb.h +++ b/src/common/usb.h @@ -43,7 +43,7 @@ private: virtual void SendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) {}; static void ReadUSB(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); vector BuildPacketHeader(uint32_t sessionId, uint8_t option, uint32_t dataSize); - int SpecialPacket(HSession hSession, uint8_t *appendData, int dataSize); + int CheckPacketOption(HSession hSession, uint8_t *appendData, int dataSize); void PreSendUsbSoftReset(HSession hSession, uint32_t sessionIdOld); }; } // namespace Hdc diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index b3a28a44..b37f473a 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 == 1) { + if (*payload != 0) { --(*payload); Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); } diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 51a5131e..8066cd26 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -248,7 +248,7 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t int 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, offset:%u", offset); @@ -350,7 +350,7 @@ int HdcDaemonUSB::DispatchToWorkThread(uint32_t sessionId, uint8_t *readBuf, int } } - if (hChildSession->childCleared) { + if (hChildSession->childCleared || hChildSession->isDead) { return ERR_SESSION_DEAD; } uv_stream_t *stream = reinterpret_cast(&hChildSession->dataPipe[STREAM_MAIN]); @@ -391,6 +391,7 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) break; } else if (bytesIOBytes == 0) { // zero packet + WRITE_LOG(LOG_WARN, "Zero packet received"); ret = true; break; } @@ -432,7 +433,7 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) int HdcDaemonUSB::LoopUSBRead(HUSB hUSB, int readMaxWanted) { - int ret = -1; + int ret = ERR_GENERIC; HdcDaemon *daemon = reinterpret_cast(clsMainBase); auto ctxIo = new CtxUvFileCommonIo(); auto buf = new uint8_t[readMaxWanted](); @@ -462,7 +463,7 @@ FAILED: if (buf != nullptr) { delete[] buf; } - return -1; + return ERR_GENERIC; } // Because USB can connect to only one host,daemonUSB is only one Session by default diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 29650b20..91363707 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -342,6 +342,7 @@ void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfe { HSession hSession = (HSession)transfer->user_data; HdcHostUSB *thisClass = (HdcHostUSB *)hSession->classModule; + HdcServer *pServer = (HdcServer *)thisClass->clsMainBase; HUSB hUSB = hSession->hUSB; bool bOK = false; int childRet = 0; diff --git a/src/host/server.cpp b/src/host/server.cpp index 3f2386fd..ac2495d6 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -434,6 +434,7 @@ bool HdcServer::ServerSessionHandshake(HSession hSession, uint8_t *payload, int return true; } +// call in child thread bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, const int payloadSize) { @@ -453,12 +454,17 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const } else { // Client may be ctrl+c and Server remove channel. notify server async } - Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); - return true; + uint8_t flag = 0; + Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &flag, 1); + return ret; + } + if (hChannel->isDead) { + --hChannel->ref; + return ret; } switch (command) { case CMD_KERNEL_ECHO_RAW: { // Native shell data output - sfc->EchoClientRaw(channelId, payload, payloadSize); + sfc->EchoClientRaw(hChannel, payload, payloadSize); break; } case CMD_KERNEL_ECHO: { @@ -469,12 +475,12 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const break; } case CMD_KERNEL_CHANNEL_CLOSE: { - WRITE_LOG(LOG_DEBUG, "CMD_KERNEL_CHANNEL_CLOSE channelid:%d", channelId); + WRITE_LOG(LOG_DEBUG, "CMD_KERNEL_CHANNEL_CLOSE channelid:%u", channelId); // Forcibly closing the tcp handle here may result in incomplete data reception on the client side ClearOwnTasks(hSession, channelId); // crossthread free sfc->PushAsyncMessage(channelId, ASYNC_FREE_CHANNEL, nullptr, 0); - if (*payload == 1) { + if (*payload != 0) { --(*payload); Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); } @@ -684,22 +690,22 @@ void HdcServer::DeatchChannel(HSession hSession, const uint32_t channelId) return; } if (hChannel->childCleared) { - WRITE_LOG(LOG_DEBUG, "Childchannel has already freed, cid:%d", channelId); + WRITE_LOG(LOG_DEBUG, "Childchannel has already freed, cid:%u", channelId); return; } - uint8_t count = 1; + uint8_t count = 0; Send(hSession->sessionId, hChannel->channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1); if (uv_is_closing((const uv_handle_t *)&hChannel->hChildWorkTCP)) { Base::DoNextLoop(&hSession->childLoop, hChannel, [](const uint8_t flag, string &msg, const void *data) { HChannel hChannel = (HChannel)data; hChannel->childCleared = true; - WRITE_LOG(LOG_DEBUG, "Childchannel free direct, cid:%d", hChannel->channelId); + WRITE_LOG(LOG_DEBUG, "Childchannel free direct, cid:%u", hChannel->channelId); }); } else { Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP, [](uv_handle_t *handle) -> void { HChannel hChannel = (HChannel)handle->data; hChannel->childCleared = true; - WRITE_LOG(LOG_DEBUG, "Childchannel free callback, cid:%d", hChannel->channelId); + WRITE_LOG(LOG_DEBUG, "Childchannel free callback, cid:%u", hChannel->channelId); }); } }; diff --git a/src/host/server_for_client.cpp b/src/host/server_for_client.cpp index b806cdb6..d1917811 100644 --- a/src/host/server_for_client.cpp +++ b/src/host/server_for_client.cpp @@ -116,12 +116,12 @@ void HdcServerForClient::EchoClient(HChannel hChannel, MessageLevel level, const if (log.back() != '\n') { log += "\r\n"; } - Send(hChannel->channelId, (uint8_t *)log.c_str(), log.size()); + SendChannel(hChannel, (uint8_t *)log.c_str(), log.size()); } -void HdcServerForClient::EchoClientRaw(const uint32_t channelId, uint8_t *payload, const int payloadSize) +void HdcServerForClient::EchoClientRaw(const HChannel hChannel, uint8_t *payload, const int payloadSize) { - Send(channelId, payload, payloadSize); + SendChannel(hChannel, payload, payloadSize); } bool HdcServerForClient::SendToDaemon(HChannel hChannel, const uint16_t commandFlag, uint8_t *bufPtr, const int bufSize) diff --git a/src/host/server_for_client.h b/src/host/server_for_client.h index 22ca06e2..45e013b8 100644 --- a/src/host/server_for_client.h +++ b/src/host/server_for_client.h @@ -24,7 +24,7 @@ public: virtual ~HdcServerForClient(); int Initial(); void EchoClient(HChannel hChannel, MessageLevel level, const char *msg, ...); - void EchoClientRaw(const uint32_t channelId, uint8_t *payload, const int payloadSize); + void EchoClientRaw(const HChannel hChannel, uint8_t *payload, const int payloadSize); uint16_t GetTCPListenPort(); void Stop(); -- Gitee From 6ac35a4c3c66f33f72f8b68e407aa9f294c3b5e6 Mon Sep 17 00:00:00 2001 From: zako Date: Wed, 24 Nov 2021 15:10:00 +0800 Subject: [PATCH 18/50] Host usb send recv, split thread Signed-off-by: zako --- src/common/define_plus.h | 1 - src/common/usb.cpp | 4 +- src/common/usb.h | 4 ++ src/daemon/daemon_usb.cpp | 5 ++ src/daemon/daemon_usb.h | 1 + src/host/host_usb.cpp | 123 ++++++++++++++++++++++---------------- src/host/host_usb.h | 7 ++- 7 files changed, 86 insertions(+), 59 deletions(-) diff --git a/src/common/define_plus.h b/src/common/define_plus.h index cd351356..7918741a 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -224,7 +224,6 @@ struct HdcUSB { bool recvIOComplete; mutex lockSend; - condition_variable cvTransferSend; libusb_transfer *transferSend; bool sendIOComplete; #else diff --git a/src/common/usb.cpp b/src/common/usb.cpp index a6733ad6..1020f166 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -90,7 +90,7 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) // win32 send ZLP will block winusb driver and LIBUSB_TRANSFER_ADD_ZERO_PACKET not effect // so, we send dummy packet to prevent zero packet generate auto dummy = BuildPacketHeader(hSession->sessionId, 0, 0); - if ((childRet = SendUSBRaw(hSession, dummy.data(), dummy.size())) < 0) { + if ((childRet = SendUSBRaw(hSession, dummy.data(), dummy.size())) <= 0) { WRITE_LOG(LOG_FATAL, "SendUSBRaw dummy failed"); break; } @@ -178,7 +178,7 @@ int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t PreSendUsbSoftReset(hSession, 0); // 0 == reset current return 0; } - if ((childRet = Base::SendToStream(stream, appendData, dataSize)) < 0) { + if ((childRet = UsbToHdcProtocol(stream, appendData, dataSize)) < 0) { WRITE_LOG(LOG_FATAL, "Error usb send to stream dataSize:%d", dataSize); return ERR_IO_FAIL; } diff --git a/src/common/usb.h b/src/common/usb.h index ac30a308..0c9361ec 100644 --- a/src/common/usb.h +++ b/src/common/usb.h @@ -30,6 +30,10 @@ protected: { return 0; } + virtual int UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int dataSize) + { + return 0; + }; int SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t *appendData, int dataSize); int GetSafeUsbBlockSize(uint16_t wMaxPacketSizeSend); bool IsUsbPacketHeader(uint8_t *ioBuf, int ioBytes); diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 8066cd26..93b8924a 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -326,6 +326,11 @@ HSession HdcDaemonUSB::PrepareNewSession(uint32_t sessionId, uint8_t *pRecvBuf, return hChildSession; } +int HdcDaemonUSB::UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int dataSize) +{ + return Base::SendToStream(stream, appendData, dataSize); +} + int HdcDaemonUSB::DispatchToWorkThread(uint32_t sessionId, uint8_t *readBuf, int readBytes) { // Format:USBPacket1 payload1...USBPacketn diff --git a/src/daemon/daemon_usb.h b/src/daemon/daemon_usb.h index 6a93eadc..1d2a8845 100644 --- a/src/daemon/daemon_usb.h +++ b/src/daemon/daemon_usb.h @@ -49,6 +49,7 @@ private: int CloseBulkEp(bool bulkInOut, int bulkFd, uv_loop_t *loop); void ResetOldSession(uint32_t sessionId); int GetMaxPacketSize(int fdFfs); + int UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int dataSize); HdcUSB usbHandle; string basePath; // usb device's base path diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 91363707..5301f845 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -24,7 +24,6 @@ HdcHostUSB::HdcHostUSB(const bool serverOrDaemonIn, void *ptrMainBase, void *ctx return; } HdcServer *pServer = (HdcServer *)ptrMainBase; - uv_idle_init(&pServer->loopMain, &usbWork); ctxUSB = (libusb_context *)ctxUSBin; uv_timer_init(&pServer->loopMain, &devListWatcher); } @@ -42,7 +41,6 @@ void HdcHostUSB::Stop() if (!ctxUSB) { return; } - Base::TryCloseHandle((uv_handle_t *)&usbWork); Base::TryCloseHandle((uv_handle_t *)&devListWatcher); modRunning = false; } @@ -141,18 +139,6 @@ bool HdcHostUSB::DetectMyNeed(libusb_device *device, string &sn) return ret; } -// sub-thread all called -void HdcHostUSB::PenddingUSBIO(uv_idle_t *handle) -{ - libusb_context *ctxUSB = (libusb_context *)handle->data; - // every plug,handle,libusb_handle_events - struct timeval zerotime; - int nComplete = 0; - zerotime.tv_sec = 0; - zerotime.tv_usec = 1; // if == 0,windows will be high CPU load - libusb_handle_events_timeout_completed(ctxUSB, &zerotime, &nComplete); -} - void HdcHostUSB::KickoutZombie(HSession hSession) { HdcServer *ptrConnect = (HdcServer *)hSession->classInstance; @@ -214,6 +200,18 @@ void HdcHostUSB::WatchDevPlugin(uv_timer_t *handle) libusb_free_device_list(devs, 1); } +void HdcHostUSB::UsbWorkThread(void *arg) +{ + HdcHostUSB *thisClass = (HdcHostUSB *)arg; + constexpr uint8_t USB_HANDLE_TIMEOUT = 30; // second + while (thisClass->modRunning) { + struct timeval zerotime; + zerotime.tv_sec = USB_HANDLE_TIMEOUT; + zerotime.tv_usec = 0; // if == 0,windows will be high CPU load + libusb_handle_events_timeout(thisClass->ctxUSB, &zerotime); + } +} + int HdcHostUSB::StartupUSBWork() { // Because libusb(winusb backend) does not support hotplug under win32, we use list mode for all platforms @@ -221,8 +219,7 @@ int HdcHostUSB::StartupUSBWork() devListWatcher.data = this; uv_timer_start(&devListWatcher, WatchDevPlugin, 0, intervalDevCheck); // Running pendding in independent threads does not significantly improve the efficiency - usbWork.data = ctxUSB; - uv_idle_start(&usbWork, PenddingUSBIO); + uv_thread_create(&threadUsbWork, UsbWorkThread, this); return 0; } @@ -338,15 +335,61 @@ void HdcHostUSB::CancelUsbLoopRead(HUSB hUSB) } } +// 3rd write child-hdc-workthread +// no use uvwrite, raw write to socketpair's fd +int HdcHostUSB::UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int dataSize) +{ + HSession hSession = (HSession)stream->data; + int fd = hSession->dataFd[STREAM_MAIN]; + fd_set fdSet; + struct timeval timeout = { 3, 0 }; + FD_ZERO(&fdSet); + FD_SET(fd, &fdSet); + int index = 0; + int childRet = 0; + + while (index < dataSize) { + if (select(fd + 1, NULL, &fdSet, NULL, &timeout) <= 0) { + break; + } + childRet = send(fd, (const char *)appendData + index, dataSize - index, 0); + if (childRet < 0) { + break; + } + index += childRet; + } + if (index != dataSize) { + return ERR_IO_FAIL; + } + return index; +} + +bool HdcHostUSB::SubmitUsbWorkthread(HSession hSession, libusb_transfer *transfer, const int nextReadSize, + const int timeout) +{ + HUSB hUSB = hSession->hUSB; + ++hSession->ref; + libusb_fill_bulk_transfer(transfer, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, nextReadSize, + ReadUSBBulkCallback, hSession, timeout); + int childRet = libusb_submit_transfer(transfer); + if (childRet < 0) { + --hSession->ref; + WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", childRet); + return false; + } + return true; +} + +// at usb 3rd thread void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfer) { HSession hSession = (HSession)transfer->user_data; HdcHostUSB *thisClass = (HdcHostUSB *)hSession->classModule; - HdcServer *pServer = (HdcServer *)thisClass->clsMainBase; HUSB hUSB = hSession->hUSB; bool bOK = false; int childRet = 0; constexpr int infinity = 0; // ignore timeout + --hSession->ref; while (true) { if (!thisClass->modRunning || (hSession->isDead && 0 == hSession->ref)) break; @@ -362,11 +405,7 @@ void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfe } // loop self int nextReadSize = childRet == 0 ? hUSB->wMaxPacketSizeSend : std::min(childRet, Base::GetUsbffsBulkSize()); - libusb_fill_bulk_transfer(transfer, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, nextReadSize, - ReadUSBBulkCallback, hSession, infinity); - childRet = libusb_submit_transfer(transfer); - if (childRet < 0) { - WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", childRet); + if (!thisClass->SubmitUsbWorkthread(hSession, transfer, nextReadSize, infinity)) { break; } bOK = true; @@ -387,10 +426,8 @@ void HdcHostUSB::RegisterReadCallback(HSession hSession) return; } hSession->hUSB->transferRecv->user_data = hSession; - libusb_fill_bulk_transfer(hSession->hUSB->transferRecv, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, - hUSB->wMaxPacketSizeSend, ReadUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); - int childRet = libusb_submit_transfer(hSession->hUSB->transferRecv); - if (childRet == 0) { + if (SubmitUsbWorkthread(hSession, hUSB->transferRecv, hUSB->wMaxPacketSizeSend, GLOBAL_TIMEOUT * TIME_BASE)) { + // success hSession->hUSB->recvIOComplete = false; } } @@ -425,48 +462,28 @@ int HdcHostUSB::OpenDeviceMyNeed(HUSB hUSB) return ret; } -// at main thread -void LIBUSB_CALL HdcHostUSB::WriteUSBBulkCallback(struct libusb_transfer *transfer) -{ - HSession hSession = reinterpret_cast(transfer->user_data); - HdcSessionBase *server = reinterpret_cast(hSession->classInstance); - - if (LIBUSB_TRANSFER_COMPLETED != transfer->status || (hSession->isDead && 0 == hSession->ref)) { - WRITE_LOG(LOG_FATAL, "SendUSBRaw status:%d", transfer->status); - server->FreeSession(hSession->sessionId); - } - hSession->hUSB->sendIOComplete = true; - hSession->hUSB->cvTransferSend.notify_one(); -} - // libusb can send directly across threads?!!! -// Just call from child work thread, it will be block when overlap full int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) { int ret = ERR_GENERIC; int childRet = -1; + int reallySize = 0; HUSB hUSB = hSession->hUSB; - hUSB->sendIOComplete = false; HdcSessionBase *server = reinterpret_cast(hSession->classInstance); ++hSession->ref; - while (true) { - std::unique_lock lock(hUSB->lockSend); - libusb_fill_bulk_transfer(hUSB->transferSend, hUSB->devHandle, hUSB->epHost, data, length, WriteUSBBulkCallback, - hSession, GLOBAL_TIMEOUT * TIME_BASE); - childRet = libusb_submit_transfer(hUSB->transferSend); - if (childRet < 0) { - ret = ERR_IO_FAIL; + do { + childRet = libusb_bulk_transfer(hUSB->devHandle, hUSB->epHost, data, length, &reallySize, + GLOBAL_TIMEOUT * TIME_BASE); + if (childRet < 0 || reallySize != length) { break; } ret = length; - hUSB->cvTransferSend.wait(lock, [hUSB]() { return hUSB->sendIOComplete; }); - break; - } - --hSession->ref; + } while (false); if (ret < 0) { hSession->hUSB->sendIOComplete = true; server->FreeSession(hSession->sessionId); } + --hSession->ref; return ret; } diff --git a/src/host/host_usb.h b/src/host/host_usb.h index 58f1ad22..5d49a9b5 100644 --- a/src/host/host_usb.h +++ b/src/host/host_usb.h @@ -35,10 +35,9 @@ private: }; static int LIBUSB_CALL HotplugHostUSBCallback(libusb_context *ctx, libusb_device *device, libusb_hotplug_event event, void *userData); - static void PenddingUSBIO(uv_idle_t *handle); + static void UsbWorkThread(void *arg); // 3rd thread static void WatchDevPlugin(uv_timer_t *handle); static void KickoutZombie(HSession hSession); - static void LIBUSB_CALL WriteUSBBulkCallback(struct libusb_transfer *transfer); static void LIBUSB_CALL ReadUSBBulkCallback(struct libusb_transfer *transfer); int StartupUSBWork(); int CheckActiveConfig(libusb_device *device, HUSB hUSB); @@ -54,14 +53,16 @@ private: void RegisterReadCallback(HSession hSession); void ReviewUsbNodeLater(string &nodeKey); void CancelUsbLoopRead(HUSB hUSB); + int UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int dataSize); - uv_idle_t usbWork; libusb_context *ctxUSB; uv_timer_t devListWatcher; map mapIgnoreDevice; const int intervalDevCheck = 3000; private: + bool SubmitUsbWorkthread(HSession hSession, libusb_transfer *transfer, const int nextReadSize, const int timeout); + uv_thread_t threadUsbWork; }; } // namespace Hdc #endif \ No newline at end of file -- Gitee From b5dc2385af8184ef4c108d5ae2b2d4d66438e998 Mon Sep 17 00:00:00 2001 From: zako Date: Wed, 24 Nov 2021 20:48:56 +0800 Subject: [PATCH 19/50] fix asynccmd issue Signed-off-by: zako --- src/common/async_cmd.cpp | 7 ++++++- src/common/async_cmd.h | 13 +++++-------- src/common/file_descriptor.cpp | 2 +- src/common/transfer.cpp | 1 - src/daemon/daemon_app.cpp | 2 +- src/daemon/daemon_unity.cpp | 3 +-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/common/async_cmd.cpp b/src/common/async_cmd.cpp index c87a4572..95734594 100644 --- a/src/common/async_cmd.cpp +++ b/src/common/async_cmd.cpp @@ -69,7 +69,7 @@ bool AsyncCmd::FinishShellProc(const void *context, const bool result, const str { WRITE_LOG(LOG_DEBUG, "FinishShellProc finish"); AsyncCmd *thisClass = (AsyncCmd *)context; - thisClass->resultCallback(true, result, exitMsg); + thisClass->resultCallback(true, result, thisClass->cmdResult + exitMsg); --thisClass->refCount; return true; }; @@ -77,6 +77,11 @@ bool AsyncCmd::FinishShellProc(const void *context, const bool result, const str bool AsyncCmd::ChildReadCallback(const void *context, uint8_t *buf, const int size) { AsyncCmd *thisClass = (AsyncCmd *)context; + if (thisClass->options & OPTION_COMMAND_ONETIME) { + string s((char *)buf, size); + thisClass->cmdResult += s; + return true; + } string s((char *)buf, size); return thisClass->resultCallback(false, 0, s); }; diff --git a/src/common/async_cmd.h b/src/common/async_cmd.h index f14eaaff..f7aecccb 100644 --- a/src/common/async_cmd.h +++ b/src/common/async_cmd.h @@ -22,19 +22,15 @@ public: AsyncCmd(); virtual ~AsyncCmd(); enum AsyncCmdOption { - OPTION_APPEND_NEWLINE = 1, - OPTION_COMMAND_ONETIME = 2, - OPTION_READBACK_OUT = 4, + OPTION_COMMAND_ONETIME = 1, + USB_OPTION_RESERVE2 = 2, + USB_OPTION_RESERVE4 = 4, USB_OPTION_RESERVE8 = 8, }; // 1)is finish 2)exitStatus 3)resultString(maybe empty) using CmdResultCallback = std::function; - static uint32_t GetDefaultOption() - { - return OPTION_APPEND_NEWLINE | OPTION_COMMAND_ONETIME; - } // uv_loop_t loop is given to uv_spawn, which can't be const - bool Initial(uv_loop_t *loopIn, const CmdResultCallback callback, uint32_t optionsIn = GetDefaultOption()); + bool Initial(uv_loop_t *loopIn, const CmdResultCallback callback, uint32_t optionsIn = 0); void DoRelease(); // Release process resources bool ExecuteCommand(const string &command); bool ReadyForRelease() const; @@ -51,6 +47,7 @@ private: uint32_t refCount = 0; CmdResultCallback resultCallback; uv_loop_t *loop; + string cmdResult; }; } // namespace Hdc #endif \ No newline at end of file diff --git a/src/common/file_descriptor.cpp b/src/common/file_descriptor.cpp index 83fd4d82..ae9d419f 100644 --- a/src/common/file_descriptor.cpp +++ b/src/common/file_descriptor.cpp @@ -92,7 +92,7 @@ void HdcFileDescriptor::OnFileIO(uv_fs_t *req) --thisClass->refIO; if (bFinish) { - thisClass->callbackFinish(thisClass->callerContext, fetalFinish, "OnRead finish"); + thisClass->callbackFinish(thisClass->callerContext, fetalFinish, STRING_EMPTY); thisClass->workContinue = false; } } diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index 4a15b795..eb7adaf3 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -49,7 +49,6 @@ bool HdcTransferBase::ResetCtx(CtxFile *context, bool full) context->remotePath = ""; context->transferBegin = 0; context->taskQueue.clear(); - Base::ZeroStruct(ctxNow.transferConfig); } return true; } diff --git a/src/daemon/daemon_app.cpp b/src/daemon/daemon_app.cpp index 4f04dc93..3e4e07e3 100644 --- a/src/daemon/daemon_app.cpp +++ b/src/daemon/daemon_app.cpp @@ -127,7 +127,7 @@ void HdcDaemonApp::PackageShell(bool installOrUninstall, const char *options, co } else { mode = APPMOD_UNINSTALL; } - asyncCommand.Initial(loopTask, funcAppModFinish); + asyncCommand.Initial(loopTask, funcAppModFinish, AsyncCmd::OPTION_COMMAND_ONETIME); asyncCommand.ExecuteCommand(doBuf); } diff --git a/src/daemon/daemon_unity.cpp b/src/daemon/daemon_unity.cpp index 83c3769d..f6b1114f 100644 --- a/src/daemon/daemon_unity.cpp +++ b/src/daemon/daemon_unity.cpp @@ -77,8 +77,7 @@ int HdcDaemonUnity::ExecuteShell(const char *shellCommand) AsyncCmd::CmdResultCallback funcResultOutput; funcResultOutput = std::bind(&HdcDaemonUnity::AsyncCmdOut, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); - if (!asyncCommand.Initial(loopTask, funcResultOutput, - asyncCommand.GetDefaultOption() | asyncCommand.OPTION_READBACK_OUT)) { + if (!asyncCommand.Initial(loopTask, funcResultOutput)) { break; } asyncCommand.ExecuteCommand(shellCommand); -- Gitee From 0a5fbf66321ec1b597d6a7ff6c7d07544b7d6260 Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 25 Nov 2021 13:27:15 +0800 Subject: [PATCH 20/50] reboot modifu Signed-off-by: zako --- src/daemon/daemon_unity.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/daemon/daemon_unity.cpp b/src/daemon/daemon_unity.cpp index f6b1114f..4eae6501 100644 --- a/src/daemon/daemon_unity.cpp +++ b/src/daemon/daemon_unity.cpp @@ -185,10 +185,14 @@ bool HdcDaemonUnity::RebootDevice(const string &cmd) } return Base::SetHdcProperty(rebootProperty.c_str(), propertyVal.c_str()); #else - if ((cmd == "recovery") || (cmd == "bootloader")) { - return DoReboot("updater"); + string reason; + if (cmd == "recovery") { + reason = "updater"; + } else if (cmd == "bootloader") { + reason = "updater"; } - return DoReboot(""); + WRITE_LOG(LOG_DEBUG, "DoReboot with args:[%s] for cmd:[%s]", reason.c_str(), cmd.c_str()); + return DoReboot(reason.c_str()); #endif } -- Gitee From 6de384fcc44f8b4ab714ff22f84071fbcf1aed6a Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 25 Nov 2021 13:31:02 +0800 Subject: [PATCH 21/50] unsigned cid sid Signed-off-by: zako --- src/common/session.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/session.cpp b/src/common/session.cpp index 5d44e426..f9565da1 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -50,7 +50,7 @@ HdcSessionBase::~HdcSessionBase() libusb_exit((libusb_context *)ctxUSB); } #endif - WRITE_LOG(LOG_DEBUG, "~HdcSessionBase free sessionRef:%d instance:%s", uint32_t(sessionRef), + WRITE_LOG(LOG_DEBUG, "~HdcSessionBase free sessionRef:%u instance:%s", uint32_t(sessionRef), serverOrDaemon ? "server" : "daemon"); } @@ -89,7 +89,7 @@ bool HdcSessionBase::BeginRemoveTask(HTaskInfo hTask) } HSession hSession = thisClass->AdminSession(OP_QUERY, hTask->sessionId, nullptr); thisClass->AdminTask(OP_REMOVE, hSession, hTask->channelId, nullptr); - WRITE_LOG(LOG_DEBUG, "TaskDelay task remove finish, channelId:%d", hTask->channelId); + WRITE_LOG(LOG_DEBUG, "TaskDelay task remove finish, channelId:%u", hTask->channelId); delete hTask; Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseIdleCallback); }; @@ -119,7 +119,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:%u", hSession, channelIDInput); break; } @@ -1056,7 +1056,7 @@ bool HdcSessionBase::DispatchTaskData(HSession hSession, const uint32_t channelI hTaskInfo->serverOrDaemon = serverOrDaemon; } if (hTaskInfo->taskStop) { - WRITE_LOG(LOG_DEBUG, "RedirectToTask jump stopped task:%d", channelId); + WRITE_LOG(LOG_DEBUG, "RedirectToTask jump stopped task:%u", channelId); break; } if (hTaskInfo->taskFree) { -- Gitee From d8fcb88684261aa3e08b75807a4a6db0bd927314 Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 25 Nov 2021 13:31:32 +0800 Subject: [PATCH 22/50] select Signed-off-by: zako --- src/host/host_usb.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 5301f845..0dfd7b4b 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -349,7 +349,7 @@ int HdcHostUSB::UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int d int childRet = 0; while (index < dataSize) { - if (select(fd + 1, NULL, &fdSet, NULL, &timeout) <= 0) { + if ((childRet = select(fd + 1, NULL, &fdSet, NULL, &timeout)) <= 0) { break; } childRet = send(fd, (const char *)appendData + index, dataSize - index, 0); @@ -475,6 +475,7 @@ int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) childRet = libusb_bulk_transfer(hUSB->devHandle, hUSB->epHost, data, length, &reallySize, GLOBAL_TIMEOUT * TIME_BASE); if (childRet < 0 || reallySize != length) { + WRITE_LOG(LOG_FATAL, "SendUSBRaw failed, ret:%d reallySize:%d", childRet, reallySize); break; } ret = length; -- Gitee From da24763ba518a5a2a0f8843f597b519a74766e91 Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 25 Nov 2021 23:43:57 +0800 Subject: [PATCH 23/50] spilt thread finish Signed-off-by: zako --- src/common/base.cpp | 31 ++++++++----------------------- src/common/base.h | 8 +++----- src/common/channel.cpp | 7 ++----- src/common/define.h | 1 - src/common/define_plus.h | 1 + src/common/session.cpp | 8 +++----- src/common/usb.cpp | 14 +++++++------- src/host/host_usb.cpp | 30 +++++++++++++++++++++++++----- src/host/host_usb.h | 3 ++- src/host/server_for_client.cpp | 2 +- 10 files changed, 52 insertions(+), 53 deletions(-) diff --git a/src/common/base.cpp b/src/common/base.cpp index 59d35a59..84cef087 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -193,34 +193,19 @@ 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 = MAX_SIZE_SOCKETPAIR; + int bufMaxSize = GetMaxBufSize() * 10; 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) + void ReallocBuf(uint8_t **origBuf, int *nOrigSize, int sizeWanted) { - int remainLen = *nOrigSize - indexUsedBuf; - // init:0, left less than expected - if (!*nOrigSize || (remainLen < sizeWanted && (*nOrigSize + sizeWanted < sizeWanted * 2))) { - // Memory allocation size is slightly larger than the maximum - int nNewLen = *nOrigSize + sizeWanted + EXTRA_ALLOC_SIZE; - uint8_t *bufPtrOrig = *origBuf; - *origBuf = new uint8_t[nNewLen](); - if (!*origBuf) { - *origBuf = bufPtrOrig; - } else { - *nOrigSize = nNewLen; - if (bufPtrOrig) { - if (memcpy_s(*origBuf, nNewLen, bufPtrOrig, *nOrigSize)) { - WRITE_LOG(LOG_FATAL, "ReallocBuf failed"); - } - delete[] bufPtrOrig; - } - } - uint8_t *buf = static_cast(*origBuf + indexUsedBuf); - Base::ZeroBuf(buf, nNewLen - indexUsedBuf); - } + if (*nOrigSize > 0) + return; + *origBuf = new uint8_t[sizeWanted]; + if (!*origBuf) + return; + *nOrigSize = sizeWanted; } // As an uv_alloc_cb it must keep the same as prototype diff --git a/src/common/base.h b/src/common/base.h index f463ff35..38acddc3 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -24,7 +24,7 @@ namespace Base { // tcpHandle can't be const as it's passed into uv_tcp_keepalive void SetTcpOptions(uv_tcp_t *tcpHandle); // Realloc need to update origBuf&origSize which can't be const - void ReallocBuf(uint8_t **origBuf, int *nOrigSize, const int indexUsedBuf, int sizeWanted); + void ReallocBuf(uint8_t **origBuf, int *nOrigSize, int sizeWanted); // handle&sendHandle must keep sync with uv_write int SendToStreamEx(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen, uv_stream_t *handleSend, const void *finishCallback, const void *pWriteReqData); @@ -39,10 +39,8 @@ namespace Base { uint64_t GetRandom(const uint64_t min = 0, const uint64_t max = UINT64_MAX); int ConnectKey2IPPort(const char *connectKey, char *outIP, uint16_t *outPort); // As an uv_work_cb it must keep the same as prototype - // clang-format off - int StartWorkThread(uv_loop_t *loop, uv_work_cb pFuncWorkThread, - uv_after_work_cb pFuncAfterThread, void *pThreadData); - // clang-format on + int StartWorkThread(uv_loop_t *loop, uv_work_cb pFuncWorkThread, uv_after_work_cb pFuncAfterThread, + void *pThreadData); // As an uv_work_cb it must keep the same as prototype void FinishWorkThread(uv_work_t *req, int status); int GetMaxBufSize(); diff --git a/src/common/channel.cpp b/src/common/channel.cpp index e9fcbf38..b527857e 100644 --- a/src/common/channel.cpp +++ b/src/common/channel.cpp @@ -289,12 +289,9 @@ 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) { HChannel context = (HChannel)handle->data; - Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); + Base::ReallocBuf(&context->ioBuf, &context->bufSize, Base::GetMaxBufSize() * 4); buf->base = (char *)context->ioBuf + context->availTailIndex; - buf->len = context->bufSize - context->availTailIndex - 1; - if (buf->len < 0) { - buf->len = 0; - } + buf->len = context->bufSize - context->availTailIndex; } uint32_t HdcChannelBase::GetChannelPseudoUid() diff --git a/src/common/define.h b/src/common/define.h index 2bb12cf1..16756893 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -24,7 +24,6 @@ constexpr uint8_t GLOBAL_TIMEOUT = 30; constexpr uint16_t DEFAULT_PORT = 8710; constexpr uint16_t MAX_SIZE_IOBUF = 15360; // 15360 constexpr uint16_t MAX_USBFFS_BULK = 16384; -constexpr uint16_t MAX_SIZE_SOCKETPAIR = MAX_SIZE_IOBUF * 4; constexpr bool ENABLE_IO_CHECKSUM = false; const string DEFAULT_SERVER_ADDR = "127.0.0.1:8710"; diff --git a/src/common/define_plus.h b/src/common/define_plus.h index 7918741a..0008089c 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -226,6 +226,7 @@ struct HdcUSB { mutex lockSend; libusb_transfer *transferSend; bool sendIOComplete; + uv_thread_t threadUsbChildWork; #else // usb accessory FunctionFS // USB main thread use, sub-thread disable, sub-thread uses the main thread USB handle diff --git a/src/common/session.cpp b/src/common/session.cpp index f9565da1..9d537b97 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -770,13 +770,10 @@ 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 = MAX_SIZE_SOCKETPAIR; // anti highload IO from socketpair HSession context = (HSession)handle->data; - Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); + Base::ReallocBuf(&context->ioBuf, &context->bufSize, Base::GetMaxBufSize() * 4); buf->base = (char *)context->ioBuf + context->availTailIndex; - buf->len = context->bufSize - context->availTailIndex - 1; // 16Bytes are retained to prevent memory sticking - assert(buf->len >= 0); + buf->len = context->bufSize - context->availTailIndex; } void HdcSessionBase::FinishWriteSessionTCP(uv_write_t *req, int status) @@ -820,6 +817,7 @@ void HdcSessionBase::ReadCtrlFromSession(uv_stream_t *uvpipe, ssize_t nread, con while (true) { if (nread < 0) { WRITE_LOG(LOG_DEBUG, "SessionCtrl failed,%s", uv_strerror(nread)); + uv_read_stop(uvpipe); break; } if (nread > 64) { // 64 : max length diff --git a/src/common/usb.cpp b/src/common/usb.cpp index 1020f166..c971bd02 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -131,13 +131,13 @@ void HdcUSBBase::PreSendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) HUSB hUSB = hSession->hUSB; if (hSession->serverOrDaemon && !hUSB->resetIO) { uint32_t sid = sessionIdOld; - if (hUSB->lockDeviceHandle.try_lock()) { - ++hSession->ref; - WRITE_LOG(LOG_WARN, "SendToHdcStream check, sessionId not matched"); - SendUsbSoftReset(hSession, sid); - --hSession->ref; - hUSB->lockDeviceHandle.unlock(); - } + // or we can sendmsg to childthread send? + hUSB->lockDeviceHandle.lock(); + ++hSession->ref; + WRITE_LOG(LOG_WARN, "SendToHdcStream check, sessionId not matched"); + SendUsbSoftReset(hSession, sid); + --hSession->ref; + hUSB->lockDeviceHandle.unlock(); } } diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 0dfd7b4b..c332b578 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -200,6 +200,7 @@ void HdcHostUSB::WatchDevPlugin(uv_timer_t *handle) libusb_free_device_list(devs, 1); } +// Main thread USB operates in this thread void HdcHostUSB::UsbWorkThread(void *arg) { HdcHostUSB *thisClass = (HdcHostUSB *)arg; @@ -210,6 +211,7 @@ void HdcHostUSB::UsbWorkThread(void *arg) zerotime.tv_usec = 0; // if == 0,windows will be high CPU load libusb_handle_events_timeout(thisClass->ctxUSB, &zerotime); } + WRITE_LOG(LOG_DEBUG, "Host Sessionbase usb workthread finish"); } int HdcHostUSB::StartupUSBWork() @@ -389,7 +391,7 @@ void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfe bool bOK = false; int childRet = 0; constexpr int infinity = 0; // ignore timeout - --hSession->ref; + while (true) { if (!thisClass->modRunning || (hSession->isDead && 0 == hSession->ref)) break; @@ -417,6 +419,7 @@ void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfe hUSB->recvIOComplete = true; WRITE_LOG(LOG_WARN, "ReadUSBBulkCallback failed"); } + --hSession->ref; // until function finsh, dec ref } void HdcHostUSB::RegisterReadCallback(HSession hSession) @@ -448,8 +451,7 @@ int HdcHostUSB::OpenDeviceMyNeed(HUSB hUSB) if (CheckActiveConfig(device, hUSB)) { break; } - // USB filter rules are set according to specific device - // pedding device + // USB filter rules are set according to specific device pedding device libusb_claim_interface(handle, hUSB->interfaceNumber); ret = 0; break; @@ -462,7 +464,6 @@ int HdcHostUSB::OpenDeviceMyNeed(HUSB hUSB) return ret; } -// libusb can send directly across threads?!!! int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) { int ret = ERR_GENERIC; @@ -537,13 +538,32 @@ bool HdcHostUSB::ReadyForWorkThread(HSession hSession) return true; }; +// Target session USB operates in this thread +void HdcHostUSB::SessionUsbWorkThread(void *arg) +{ + HSession hSession = (HSession)arg; + constexpr uint8_t USB_HANDLE_TIMEOUT = 3; // second + WRITE_LOG(LOG_DEBUG, "SessionUsbWorkThread work thread:%p", uv_thread_self()); + while (!hSession->isDead) { + struct timeval zerotime; + zerotime.tv_sec = USB_HANDLE_TIMEOUT; + zerotime.tv_usec = 0; // if == 0,windows will be high CPU load + libusb_handle_events_timeout(hSession->hUSB->ctxUSB, &zerotime); + } + --hSession->ref; + WRITE_LOG(LOG_DEBUG, "Session usb workthread finish"); +} + // Determines that daemonInfo must have the device HSession HdcHostUSB::ConnectDetectDaemon(const HSession hSession, const HDaemonInfo pdi) { HdcServer *pServer = (HdcServer *)clsMainBase; HUSB hUSB = hSession->hUSB; hUSB->usbMountPoint = pdi->usbMountPoint; - hUSB->ctxUSB = ctxUSB; + + libusb_init((libusb_context **)&hUSB->ctxUSB); + ++hSession->ref; + uv_thread_create(&hUSB->threadUsbChildWork, SessionUsbWorkThread, hSession); if (!FindDeviceByID(hUSB, hUSB->usbMountPoint.c_str(), hUSB->ctxUSB)) { pServer->FreeSession(hSession->sessionId); return nullptr; diff --git a/src/host/host_usb.h b/src/host/host_usb.h index 5d49a9b5..aa885348 100644 --- a/src/host/host_usb.h +++ b/src/host/host_usb.h @@ -35,7 +35,8 @@ private: }; static int LIBUSB_CALL HotplugHostUSBCallback(libusb_context *ctx, libusb_device *device, libusb_hotplug_event event, void *userData); - static void UsbWorkThread(void *arg); // 3rd thread + static void UsbWorkThread(void *arg); // 3rd thread + static void SessionUsbWorkThread(void *arg); // 3rd thread static void WatchDevPlugin(uv_timer_t *handle); static void KickoutZombie(HSession hSession); static void LIBUSB_CALL ReadUSBBulkCallback(struct libusb_transfer *transfer); diff --git a/src/host/server_for_client.cpp b/src/host/server_for_client.cpp index d1917811..30b0dd08 100644 --- a/src/host/server_for_client.cpp +++ b/src/host/server_for_client.cpp @@ -57,7 +57,7 @@ void HdcServerForClient::AcceptClient(uv_stream_t *server, int status) uv_recv_buffer_size((uv_handle_t *)&hChannel->hWorkTCP, &bufMaxSize); auto funcChannelHeaderAlloc = [](uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) -> void { HChannel context = (HChannel)handle->data; - Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); + Base::ReallocBuf(&context->ioBuf, &context->bufSize, sizeWanted); // sizeWanted default 6k buf->base = (char *)context->ioBuf + context->availTailIndex; buf->len = sizeof(struct ChannelHandShake) + DWORD_SERIALIZE_SIZE; // only recv static size }; -- Gitee From eb6d75e57a508ced3d53e5da71474135100cb287 Mon Sep 17 00:00:00 2001 From: zako Date: Sat, 27 Nov 2021 22:13:07 +0800 Subject: [PATCH 24/50] try fix thread conflic after USB io freession Signed-off-by: zako --- src/common/define.h | 8 ++++---- src/common/session.cpp | 1 + src/host/host_usb.cpp | 11 +++++------ src/host/host_usb.h | 3 +-- src/host/server.cpp | 4 +++- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/common/define.h b/src/common/define.h index 16756893..c7446368 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -18,16 +18,14 @@ namespace Hdc { // ############################## config ####################################### -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 = 15360; // 15360 -constexpr uint16_t MAX_USBFFS_BULK = 16384; constexpr bool ENABLE_IO_CHECKSUM = false; const string DEFAULT_SERVER_ADDR = "127.0.0.1:8710"; // ################################ macro define ################################### +constexpr uint8_t MINOR_TIMEOUT = 5; constexpr uint8_t DWORD_SERIALIZE_SIZE = 4; constexpr uint8_t CMD_ARG1_COUNT = 2; constexpr uint8_t STREAM_MAIN = 0; // work at main thread @@ -45,8 +43,10 @@ constexpr uint16_t TIME_BASE = 1000; // time unit conversion base value 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; +constexpr uint16_t DEVICE_CHECK_INTERVAL = 3000; // ms +constexpr uint16_t MAX_SIZE_IOBUF = 15360; +constexpr uint16_t MAX_USBFFS_BULK = 16384; // double-word(hex)=[0]major[1][2]minor[3][4]version[5]fix(a-p)[6][7]reserve constexpr uint32_t HDC_VERSION_NUMBER = 0x10101900; // 1.1.1b=0x10101100 constexpr uint32_t HDC_BUF_MAX_BYTES = INT_MAX; diff --git a/src/common/session.cpp b/src/common/session.cpp index 9d537b97..dbe86033 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -416,6 +416,7 @@ void HdcSessionBase::FreeSessionByConnectType(HSession hSession) delete[] hUSB->bufHost; libusb_free_transfer(hUSB->transferRecv); libusb_free_transfer(hUSB->transferSend); + libusb_exit(hUSB->ctxUSB); #else if (hUSB->bulkIn > 0) { close(hUSB->bulkIn); diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index c332b578..83b7a261 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -131,8 +131,7 @@ bool HdcHostUSB::DetectMyNeed(libusb_device *device, string &sn) uv_timer_t *waitTimeDoCmd = new uv_timer_t; uv_timer_init(&hdcServer->loopMain, waitTimeDoCmd); waitTimeDoCmd->data = hSession; - constexpr uint16_t PRECONNECT_INTERVAL = 3000; - uv_timer_start(waitTimeDoCmd, hdcServer->UsbPreConnect, 0, PRECONNECT_INTERVAL); + uv_timer_start(waitTimeDoCmd, hdcServer->UsbPreConnect, 0, DEVICE_CHECK_INTERVAL); mapIgnoreDevice[sn] = HOST_USB_REGISTER; ret = true; delete hUSB; @@ -164,12 +163,12 @@ void HdcHostUSB::ReviewUsbNodeLater(string &nodeKey) HdcServer *hdcServer = (HdcServer *)clsMainBase; // add to ignore list mapIgnoreDevice[nodeKey] = HOST_USB_IGNORE; - int delayRemoveFromList = intervalDevCheck * MINOR_TIMEOUT; // wait little time for daemon reinit + int delayRemoveFromList = DEVICE_CHECK_INTERVAL * 5; // wait little time for daemon reinit Base::DelayDo(&hdcServer->loopMain, delayRemoveFromList, 0, nodeKey, nullptr, [this](const uint8_t flag, string &msg, const void *) -> void { RemoveIgnoreDevice(msg); }); } -void HdcHostUSB::WatchDevPlugin(uv_timer_t *handle) +void HdcHostUSB::WatchUsbNodeChange(uv_timer_t *handle) { HdcHostUSB *thisClass = (HdcHostUSB *)handle->data; HdcServer *ptrConnect = (HdcServer *)thisClass->clsMainBase; @@ -219,7 +218,7 @@ int HdcHostUSB::StartupUSBWork() // Because libusb(winusb backend) does not support hotplug under win32, we use list mode for all platforms WRITE_LOG(LOG_DEBUG, "USBHost loopfind mode"); devListWatcher.data = this; - uv_timer_start(&devListWatcher, WatchDevPlugin, 0, intervalDevCheck); + uv_timer_start(&devListWatcher, WatchUsbNodeChange, 0, DEVICE_CHECK_INTERVAL); // Running pendding in independent threads does not significantly improve the efficiency uv_thread_create(&threadUsbWork, UsbWorkThread, this); return 0; @@ -542,7 +541,7 @@ bool HdcHostUSB::ReadyForWorkThread(HSession hSession) void HdcHostUSB::SessionUsbWorkThread(void *arg) { HSession hSession = (HSession)arg; - constexpr uint8_t USB_HANDLE_TIMEOUT = 3; // second + constexpr uint8_t USB_HANDLE_TIMEOUT = DEVICE_CHECK_INTERVAL / TIME_BASE; WRITE_LOG(LOG_DEBUG, "SessionUsbWorkThread work thread:%p", uv_thread_self()); while (!hSession->isDead) { struct timeval zerotime; diff --git a/src/host/host_usb.h b/src/host/host_usb.h index aa885348..e32c6191 100644 --- a/src/host/host_usb.h +++ b/src/host/host_usb.h @@ -37,7 +37,7 @@ private: libusb_hotplug_event event, void *userData); static void UsbWorkThread(void *arg); // 3rd thread static void SessionUsbWorkThread(void *arg); // 3rd thread - static void WatchDevPlugin(uv_timer_t *handle); + static void WatchUsbNodeChange(uv_timer_t *handle); static void KickoutZombie(HSession hSession); static void LIBUSB_CALL ReadUSBBulkCallback(struct libusb_transfer *transfer); int StartupUSBWork(); @@ -59,7 +59,6 @@ private: libusb_context *ctxUSB; uv_timer_t devListWatcher; map mapIgnoreDevice; - const int intervalDevCheck = 3000; private: bool SubmitUsbWorkthread(HSession hSession, libusb_transfer *transfer, const int nextReadSize, const int timeout); diff --git a/src/host/server.cpp b/src/host/server.cpp index ac2495d6..81664899 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -337,7 +337,9 @@ void HdcServer::NotifyInstanceSessionFree(HSession hSession, bool freeOrClear) AdminDaemonMap(OP_UPDATE, hSession->connectKey, hdiNew); } else { // step2 string usbMountPoint = hdiOld->usbMountPoint; - constexpr int waitDaemonReconnect = UV_DEFAULT_INTERVAL; // wait little time for daemon reinit + // The time must be longer than DEVICE_CHECK_INTERVAL. Wait this time and the WatchUsbNodeChange-Method + // execution finish. Otherwise, the main thread and the session worker thread will conflict + constexpr int waitDaemonReconnect = DEVICE_CHECK_INTERVAL * 2; // longer than DEVICE_CHECK_INTERVAL auto funcDelayUsbNotify = [this, usbMountPoint](const uint8_t flag, string &msg, const void *) -> void { string s = usbMountPoint; clsUSBClt->RemoveIgnoreDevice(s); -- Gitee From 15f63cab7b4d85c3655299e701f87453d3c7581d Mon Sep 17 00:00:00 2001 From: zako Date: Sat, 27 Nov 2021 22:32:06 +0800 Subject: [PATCH 25/50] remove unused var Signed-off-by: zako --- src/common/define_plus.h | 3 --- src/common/session.cpp | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/common/define_plus.h b/src/common/define_plus.h index 0008089c..07760d6b 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -222,9 +222,6 @@ struct HdcUSB { uint8_t *bufHost; libusb_transfer *transferRecv; bool recvIOComplete; - - mutex lockSend; - libusb_transfer *transferSend; bool sendIOComplete; uv_thread_t threadUsbChildWork; #else diff --git a/src/common/session.cpp b/src/common/session.cpp index dbe86033..3e0fc2f9 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -320,7 +320,6 @@ int HdcSessionBase::MallocSessionByConnectType(HSession hSession) 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 @@ -415,7 +414,6 @@ void HdcSessionBase::FreeSessionByConnectType(HSession hSession) delete[] hUSB->bufDevice; delete[] hUSB->bufHost; libusb_free_transfer(hUSB->transferRecv); - libusb_free_transfer(hUSB->transferSend); libusb_exit(hUSB->ctxUSB); #else if (hUSB->bulkIn > 0) { @@ -483,9 +481,9 @@ void HdcSessionBase::FreeSessionOpeate(uv_timer_t *handle) HSession hSession = (HSession)handle->data; HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; if (hSession->ref > 0) { - WRITE_LOG(LOG_DEBUG, "ref:%u", uint32_t(hSession->ref)); return; } + WRITE_LOG(LOG_DEBUG, "FreeSessionOpeate ref:%u", uint32_t(hSession->ref)); #ifdef HDC_HOST if (hSession->hUSB != nullptr && (!hSession->hUSB->recvIOComplete || !hSession->hUSB->sendIOComplete)) { if (!hSession->hUSB->recvIOComplete) { -- Gitee From b4bb1963b3c2d3195aec879ee153caa35e427aa7 Mon Sep 17 00:00:00 2001 From: stesen Date: Sat, 4 Dec 2021 15:29:31 +0800 Subject: [PATCH 26/50] Description:[feature] add data sync after file transfer Test: 1. hdc file send filename 2. reset immediately 3. check file context after reboot Change-Id: I9149b3508d3e3d7d7269e7b710365679777569ca Signed-off-by: stesen Signed-off-by: zako --- src/common/transfer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index eb7adaf3..c5474bed 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -219,6 +219,7 @@ void HdcTransferBase::OnFileIO(uv_fs_t *req) if (tryFinishIO) { // close-step1 ++thisClass->refCount; + uv_fs_sync(thisClass->loopTask, &context->fsCloseReq, context->fsOpenReq.result, nullptr); uv_fs_close(thisClass->loopTask, &context->fsCloseReq, context->fsOpenReq.result, OnFileClose); } } -- Gitee From 099b062c3238ab556a5f64c6ddc3cdd68e102d8d Mon Sep 17 00:00:00 2001 From: stesen Date: Sun, 5 Dec 2021 08:53:30 +0000 Subject: [PATCH 27/50] fix typo Signed-off-by: stesen Signed-off-by: zako --- src/common/transfer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index c5474bed..dcd0985f 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -219,7 +219,7 @@ void HdcTransferBase::OnFileIO(uv_fs_t *req) if (tryFinishIO) { // close-step1 ++thisClass->refCount; - uv_fs_sync(thisClass->loopTask, &context->fsCloseReq, context->fsOpenReq.result, nullptr); + uv_fs_fsync(thisClass->loopTask, &context->fsCloseReq, context->fsOpenReq.result, nullptr); uv_fs_close(thisClass->loopTask, &context->fsCloseReq, context->fsOpenReq.result, OnFileClose); } } -- Gitee From 3bf941f7f126e83763c431dfce1b6f75e46b36dc Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 9 Dec 2021 15:44:32 +0800 Subject: [PATCH 28/50] try fix transfer uninit issue Signed-off-by: zako --- src/common/async_cmd.cpp | 1 + src/common/base.cpp | 29 +++++++++++++++++------- src/common/common.h | 1 + src/common/define_plus.h | 4 ++-- src/common/session.cpp | 23 ++++++++++++------- src/common/transfer.cpp | 19 +++++++--------- src/daemon/daemon_app.cpp | 4 ++-- src/daemon/daemon_common.h | 4 +++- src/daemon/daemon_tcp.cpp | 9 ++++---- src/daemon/daemon_usb.cpp | 4 ++++ src/daemon/daemon_usb.h | 1 + src/daemon/jdwp.cpp | 46 ++++++++++++++------------------------ src/daemon/jdwp.h | 34 ++++++++++++++-------------- src/host/host_usb.cpp | 3 ++- src/test/ut_runtime.cpp | 4 ++-- src/test/ut_runtime.h | 2 +- 16 files changed, 101 insertions(+), 87 deletions(-) diff --git a/src/common/async_cmd.cpp b/src/common/async_cmd.cpp index 95734594..80699f87 100644 --- a/src/common/async_cmd.cpp +++ b/src/common/async_cmd.cpp @@ -109,6 +109,7 @@ int AsyncCmd::Popen(string command, bool readWrite, int &pid) close(fd[PIPE_WRITE]); dup2(fd[PIPE_READ], STDIN_FILENO); } + setsid(); setpgid(childPid, childPid); string shellPath = Base::GetShellPath(); execl(shellPath.c_str(), shellPath.c_str(), "-c", command.c_str(), NULL); diff --git a/src/common/base.cpp b/src/common/base.cpp index 1535f6c0..8e927c89 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -45,7 +45,7 @@ namespace Base { { string tmpString = GetFileNameAny(debugInfo); debugInfo = StringFormat("%s:%d", tmpString.c_str(), line); - if (g_logLevel < LOG_FULL) { + if (g_logLevel < LOG_ALL) { debugInfo = ""; threadIdString = ""; } else { @@ -97,11 +97,11 @@ namespace Base { case LOG_WARN: logLevelString = "\033[1;33mW\033[0m"; break; - case LOG_DEBUG: + case LOG_DEBUG: // will reduce performance logLevelString = "\033[1;36mD\033[0m"; break; - default: - logLevelString = "\033[1;36mD\033[0m"; + default: // all, just more IO/Memory informations + logLevelString = "\033[1;38;5;21mA\033[0m"; break; } } else { @@ -221,6 +221,9 @@ namespace Base { // As an uv_write_cb it must keep the same as prototype void SendCallback(uv_write_t *req, int status) { + if (status < 0) { + WRITE_LOG(LOG_WARN, "SendCallback failed,status:%d", status); + } delete[]((uint8_t *)req->data); delete req; } @@ -294,9 +297,11 @@ namespace Base { } uint8_t *pDynBuf = new uint8_t[bufLen]; if (!pDynBuf) { + WRITE_LOG(LOG_WARN, "SendToStream, alloc failed, size:%d", bufLen); return ERR_BUF_ALLOC; } if (memcpy_s(pDynBuf, bufLen, buf, bufLen)) { + WRITE_LOG(LOG_WARN, "SendToStream, memory copy failed, size:%d", bufLen); delete[] pDynBuf; return ERR_BUF_COPY; } @@ -308,10 +313,11 @@ namespace Base { int SendToStreamEx(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen, uv_stream_t *handleSend, const void *finishCallback, const void *pWriteReqData) { - int ret = -1; + int ret = ERR_GENERIC; uv_write_t *reqWrite = new uv_write_t(); if (!reqWrite) { - return 0; + WRITE_LOG(LOG_WARN, "SendToStreamEx, new write_t failed, size:%d", bufLen); + return ERR_BUF_ALLOC; } uv_buf_t bfr; while (true) { @@ -319,15 +325,22 @@ namespace Base { bfr.base = (char *)buf; bfr.len = bufLen; if (!uv_is_writable(handleStream)) { + WRITE_LOG(LOG_WARN, "SendToStreamEx, uv_is_writable false, size:%d", bufLen); delete reqWrite; break; } // handleSend must be a TCP socket or pipe, which is a server or a connection (listening or // connected state). Bound sockets or pipes will be assumed to be servers. if (handleSend) { - uv_write2(reqWrite, handleStream, &bfr, 1, handleSend, (uv_write_cb)finishCallback); + ret = uv_write2(reqWrite, handleStream, &bfr, 1, handleSend, (uv_write_cb)finishCallback); } else { - uv_write(reqWrite, handleStream, &bfr, 1, (uv_write_cb)finishCallback); + ret = uv_write(reqWrite, handleStream, &bfr, 1, (uv_write_cb)finishCallback); + } + if (ret < 0) { + WRITE_LOG(LOG_WARN, "SendToStreamEx, uv_write false, size:%d", bufLen); + delete reqWrite; + ret = ERR_IO_FAIL; + break; } ret = bufLen; break; diff --git a/src/common/common.h b/src/common/common.h index e90125ba..b2f6a2e6 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -61,6 +61,7 @@ using std::vector; #endif #include +#include #include "define.h" #include "debug.h" diff --git a/src/common/define_plus.h b/src/common/define_plus.h index a563a83a..a36c70ca 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -24,8 +24,8 @@ enum LogLevel { LOG_INFO, // default LOG_WARN, LOG_DEBUG, - LOG_FULL, - LOG_LAST = LOG_FULL, // tail, not use + LOG_ALL, + LOG_LAST = LOG_ALL, // tail, not use }; #define WRITE_LOG(x, y...) Base::PrintLogEx(__FILE__, __LINE__, x, y) diff --git a/src/common/session.cpp b/src/common/session.cpp index 3e0fc2f9..965d3698 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -743,13 +743,17 @@ int HdcSessionBase::FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read) return ERR_IO_FAIL; } hSession->availTailIndex += read; + WRITE_LOG(LOG_ALL, "FetchIOBuf begin, IOSize:%d availTailIndex:%d", read, hSession->availTailIndex); while (!hSession->isDead && hSession->availTailIndex > static_cast(sizeof(PayloadHead))) { childRet = ptrConnect->OnRead(hSession, ioBuf + indexBuf, hSession->availTailIndex); if (childRet > 0) { hSession->availTailIndex -= childRet; indexBuf += childRet; + WRITE_LOG(LOG_ALL, "FetchIOBuf loop read indexBuf:%d availTailIndex:%d", indexBuf, + hSession->availTailIndex); } else if (childRet == 0) { // Not enough a IO + WRITE_LOG(LOG_ALL, "FetchIOBuf loop read not enough, availTailIndex:%d", hSession->availTailIndex); break; } else { // <0 @@ -760,19 +764,25 @@ int HdcSessionBase::FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read) // It may be multi-time IO to merge in a BUF, need to loop processing } if (indexBuf > 0 && hSession->availTailIndex > 0) { - memmove_s(hSession->ioBuf, hSession->bufSize, hSession->ioBuf + indexBuf, hSession->availTailIndex); + if (memmove_s(hSession->ioBuf, hSession->bufSize, hSession->ioBuf + indexBuf, hSession->availTailIndex) + != EOK) { + return ERR_BUF_COPY; + }; uint8_t *bufToZero = (uint8_t *)(hSession->ioBuf + hSession->availTailIndex); Base::ZeroBuf(bufToZero, hSession->bufSize - hSession->availTailIndex); } + WRITE_LOG(LOG_ALL, "FetchIOBuf Finish, IOSize:%d availTailIndex:%d", read, hSession->availTailIndex); return indexBuf; } void HdcSessionBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) { HSession context = (HSession)handle->data; - Base::ReallocBuf(&context->ioBuf, &context->bufSize, Base::GetMaxBufSize() * 4); + Base::ReallocBuf(&context->ioBuf, &context->bufSize, Base::GetMaxBufSize() * 10); buf->base = (char *)context->ioBuf + context->availTailIndex; - buf->len = context->bufSize - context->availTailIndex; + int size = context->bufSize - context->availTailIndex; + buf->len = std::min(size, (int)sizeWanted); + WRITE_LOG(LOG_ALL, "Session/Channel buffer given, size:%d addr:%p", buf->len, buf->base); } void HdcSessionBase::FinishWriteSessionTCP(uv_write_t *req, int status) @@ -1041,7 +1051,7 @@ void HdcSessionBase::LogMsg(const uint32_t sessionId, const uint32_t channelId, bool HdcSessionBase::DispatchTaskData(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, int payloadSize) { - bool ret = false; + bool ret = true; while (true) { HTaskInfo hTaskInfo = AdminTask(OP_QUERY, hSession, channelId, nullptr); if (!hTaskInfo) { @@ -1060,14 +1070,11 @@ bool HdcSessionBase::DispatchTaskData(HSession hSession, const uint32_t channelI WRITE_LOG(LOG_DEBUG, "Jump delete HTaskInfo"); break; } - bool result = RedirectToTask(hTaskInfo, hSession, channelId, command, payload, payloadSize); + ret = RedirectToTask(hTaskInfo, hSession, channelId, command, payload, payloadSize); if (!hTaskInfo->hasInitial) { AdminTask(OP_ADD, hSession, channelId, hTaskInfo); hTaskInfo->hasInitial = true; } - if (result) { - ret = true; - } break; } return ret; diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index eb7adaf3..6607fed0 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -37,19 +37,16 @@ HdcTransferBase::~HdcTransferBase() bool HdcTransferBase::ResetCtx(CtxFile *context, bool full) { - context->fsOpenReq.data = context; - context->fsCloseReq.data = context; - context->thisClass = this; - context->closeNotify = false; - context->indexIO = 0; - context->loop = loopTask; - context->cb = OnFileIO; if (full) { - context->localPath = ""; - context->remotePath = ""; - context->transferBegin = 0; - context->taskQueue.clear(); + *context = {}; + context->fsOpenReq.data = context; + context->fsCloseReq.data = context; + context->thisClass = this; + context->loop = loopTask; + context->cb = OnFileIO; } + context->closeNotify = false; + context->indexIO = 0; return true; } diff --git a/src/daemon/daemon_app.cpp b/src/daemon/daemon_app.cpp index 1162692a..45b74c4e 100644 --- a/src/daemon/daemon_app.cpp +++ b/src/daemon/daemon_app.cpp @@ -73,8 +73,8 @@ bool HdcDaemonApp::CommandDispatch(const uint16_t command, uint8_t *payload, con ctxNow.fileSize = ctxNow.transferConfig.fileSize; ++refCount; uv_fs_open(loopTask, &ctxNow.fsOpenReq, ctxNow.localPath.c_str(), - UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, - S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, OnFileOpen); + UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, + OnFileOpen); break; } case CMD_APP_UNINSTALL: { diff --git a/src/daemon/daemon_common.h b/src/daemon/daemon_common.h index e1563ceb..f001d9fa 100644 --- a/src/daemon/daemon_common.h +++ b/src/daemon/daemon_common.h @@ -22,6 +22,8 @@ #include "../common/forward.h" #include "../common/async_cmd.h" #include "../common/serial_struct.h" + +#ifndef HDC_HOST //daemon used #include "jdwp.h" #include "daemon.h" #include "daemon_unity.h" @@ -30,7 +32,7 @@ #include "daemon_usb.h" #include "daemon_forward.h" #include "shell.h" - +#endif // clang-format on namespace Hdc { diff --git a/src/daemon/daemon_tcp.cpp b/src/daemon/daemon_tcp.cpp index c1a6c6e5..35e90be1 100644 --- a/src/daemon/daemon_tcp.cpp +++ b/src/daemon/daemon_tcp.cpp @@ -99,14 +99,13 @@ void HdcDaemonTCP::RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const void HdcDaemonTCP::SetUDPListen() { struct sockaddr_in addr; - int r; HdcSessionBase *ptrConnect = (HdcSessionBase *)clsMainBase; // udp broadcast servUDP.data = this; - r = uv_udp_init(&ptrConnect->loopMain, &servUDP); - r = uv_ip4_addr("0.0.0.0", DEFAULT_PORT, &addr); - r = uv_udp_bind(&servUDP, (const struct sockaddr *)&addr, UV_UDP_REUSEADDR); - r = uv_udp_recv_start(&servUDP, AllocStreamUDP, RecvUDP); + uv_udp_init(&ptrConnect->loopMain, &servUDP); + uv_ip4_addr("0.0.0.0", DEFAULT_PORT, &addr); + uv_udp_bind(&servUDP, (const struct sockaddr *)&addr, UV_UDP_REUSEADDR); + uv_udp_recv_start(&servUDP, AllocStreamUDP, RecvUDP); } // Set the daemon-side TCP listening diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 93b8924a..c1988bbc 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -389,6 +389,9 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) bool ret = false; int childRet = 0; --thisClass->ref; + if (thisClass->toReadUsbDataSize > hUSB->wMaxPacketSizeSend && bytesIOBytes != thisClass->toReadUsbDataSize) { + WRITE_LOG(LOG_WARN, "Not read all data, indexsay:%d really:%d", thisClass->toReadUsbDataSize, bytesIOBytes); + } while (thisClass->isAlive) { // Don't care is module running, first deal with this if (bytesIOBytes < 0) { @@ -421,6 +424,7 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) } } int nextReadSize = childRet == 0 ? hUSB->wMaxPacketSizeSend : std::min(childRet, Base::GetUsbffsBulkSize()); + thisClass->toReadUsbDataSize = nextReadSize; if (thisClass->LoopUSBRead(hUSB, nextReadSize) < 0) { WRITE_LOG(LOG_FATAL, "LoopUSBRead failed"); break; diff --git a/src/daemon/daemon_usb.h b/src/daemon/daemon_usb.h index 1d2a8845..cecb67e9 100644 --- a/src/daemon/daemon_usb.h +++ b/src/daemon/daemon_usb.h @@ -59,6 +59,7 @@ private: uv_mutex_t sendEP; bool isAlive = false; int controlEp = 0; // EP0 + int toReadUsbDataSize; }; } // namespace Hdc #endif \ No newline at end of file diff --git a/src/daemon/jdwp.cpp b/src/daemon/jdwp.cpp index 8e8d0089..c39d4972 100644 --- a/src/daemon/jdwp.cpp +++ b/src/daemon/jdwp.cpp @@ -13,16 +13,10 @@ * limitations under the License. */ #include "jdwp.h" -#include #include +#include namespace Hdc { -#ifdef JS_JDWP_CONNECT -static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024 * 4; -#else -static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024; -#endif // JS_JDWP_CONNECT - HdcJdwp::HdcJdwp(uv_loop_t *loopIn) { Base::ZeroStruct(listenPipe); @@ -97,7 +91,7 @@ void HdcJdwp::FreeContext(HCtxJdwp ctx) void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) { bool ret = true; - if (nread == UV_ENOBUFS) { // It is definite enough, usually only 4 bytes + 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) { @@ -105,8 +99,8 @@ void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) #ifdef JS_JDWP_CONNECT } else if (nread < 0 || nread < JS_PKG_MIN_SIZE) { #else - } else if (nread < 0 || nread != 4) { // 4 : 4 bytes -#endif // JS_JDWP_CONNECT + } else if (nread < 0 || nread != 4) { // 4 : 4 bytes +#endif // JS_JDWP_CONNECT ret = false; WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream invalid package nread:%d.", nread); } @@ -116,22 +110,20 @@ void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) if (ret) { uint32_t pid = 0; char *p = ctxJdwp->buf; - if (nread == sizeof(uint32_t)) { // Java: pid + if (nread == sizeof(uint32_t)) { // Java: pid pid = atoi(p); - } else { // JS:pid PkgName + } else { // JS:pid PkgName #ifdef JS_JDWP_CONNECT struct JsMsgHeader *jsMsg = (struct JsMsgHeader *)p; if (jsMsg->msgLen == nread) { pid = jsMsg->pid; - string pkgName = - string((char *)p + sizeof(JsMsgHeader), jsMsg->msgLen - sizeof(JsMsgHeader)); + string pkgName = string((char *)p + sizeof(JsMsgHeader), jsMsg->msgLen - sizeof(JsMsgHeader)); ctxJdwp->pkgName = pkgName; } else { ret = false; - WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream invalid js package size %d:%d.", - jsMsg->msgLen, nread); + WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream invalid js package size %d:%d.", jsMsg->msgLen, nread); } -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT } if (pid > 0) { ctxJdwp->pid = pid; @@ -139,7 +131,7 @@ void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) WRITE_LOG(LOG_DEBUG, "JDWP accept pid:%d-pkg:%s", pid, ctxJdwp->pkgName.c_str()); #else WRITE_LOG(LOG_DEBUG, "JDWP accept pid:%d", pid); -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT thisClass->AdminContext(OP_ADD, pid, ctxJdwp); ret = true; int fd = -1; @@ -169,7 +161,7 @@ string HdcJdwp::GetProcessListExtendPkgName() uv_rwlock_rdunlock(&lockMapContext); return ret; } -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT void HdcJdwp::AcceptClient(uv_stream_t *server, int status) { @@ -187,7 +179,7 @@ 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 ; + buf->base = (char *)ctxJdwp->buf; buf->len = sizeof(ctxJdwp->buf); }; uv_read_start((uv_stream_t *)&ctxJdwp->pipe, funAlloc, ReadStream); @@ -345,7 +337,7 @@ size_t HdcJdwp::JdwpProcessListMsg(char *buffer, size_t bufferlen) string result = GetProcessListExtendPkgName(); #else string result = GetProcessList(); -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT size_t len = result.length(); if (bufferlen < (len + headerLen)) { @@ -381,8 +373,7 @@ void HdcJdwp::ProcessListUpdated(void) data.resize(len); for (auto &t : jdwpTrackers) { if (t->taskStop || t->taskFree || !t->taskClass) { - jdwpTrackers.erase(remove(jdwpTrackers.begin(), jdwpTrackers.end(), t), - jdwpTrackers.end()); + jdwpTrackers.erase(remove(jdwpTrackers.begin(), jdwpTrackers.end(), t), jdwpTrackers.end()); } else { void *clsSession = t->ownerSessionClass; HdcSessionBase *sessionBase = reinterpret_cast(clsSession); @@ -406,8 +397,7 @@ void HdcJdwp::DrainAwakenPollThread() const uint64_t value = 0; ssize_t retVal = read(awakenPollFd, &value, sizeof(value)); if (retVal < 0) { - WRITE_LOG(LOG_FATAL, "DrainAwakenPollThread: Failed to read data from awaken pipe %d", - retVal); + WRITE_LOG(LOG_FATAL, "DrainAwakenPollThread: Failed to read data from awaken pipe %d", retVal); } } @@ -447,13 +437,11 @@ void *HdcJdwp::FdEventPollThread(void *args) } poll(&pollfds[0], size, -1); for (const auto &pollfdsing : pollfds) { - if (pollfdsing.revents & - (POLLNVAL | POLLRDHUP | POLLHUP | POLLERR)) { // POLLNVAL:fd not open + if (pollfdsing.revents & (POLLNVAL | POLLRDHUP | POLLHUP | POLLERR)) { // POLLNVAL:fd not open auto it = thisClass->pollNodeMap.find(pollfdsing.fd); if (it != thisClass->pollNodeMap.end()) { uint32_t targetPID = it->second.ppid; - HCtxJdwp ctx = - (HCtxJdwp)(thisClass->AdminContext(OP_QUERY, targetPID, nullptr)); + HCtxJdwp ctx = (HCtxJdwp)(thisClass->AdminContext(OP_QUERY, targetPID, nullptr)); if (ctx != nullptr) { WRITE_LOG(LOG_INFO, "FreeContext for targetPID :%d", targetPID); uv_read_stop((uv_stream_t *)&ctx->pipe); diff --git a/src/daemon/jdwp.h b/src/daemon/jdwp.h index 3b9adea2..f4d56dca 100644 --- a/src/daemon/jdwp.h +++ b/src/daemon/jdwp.h @@ -25,15 +25,12 @@ public: virtual ~HdcJdwp(); int Initial(); void Stop(); - bool CreateJdwpTracker(HTaskInfo hTaskInfo) ; + bool CreateJdwpTracker(HTaskInfo hTaskInfo); bool ReadyForRelease(); string GetProcessList(); bool SendJdwpNewFD(uint32_t targetPID, int fd); bool CheckPIDExist(uint32_t targetPID); -#ifdef JS_JDWP_CONNECT - static constexpr uint8_t JS_PKG_MIN_SIZE = 15; // JsMsgHeader + "pkgName:"uint8_t[7~127] - static constexpr uint8_t JS_PKG_MX_SIZE = 135; -#endif // JS_JDWP_CONNECT + private: struct _PollFd { int fd; @@ -52,12 +49,6 @@ private: ppid = pid; } }; -#ifdef JS_JDWP_CONNECT - struct JsMsgHeader { - uint32_t msgLen; - uint32_t pid; - }; -#endif // JS_JDWP_CONNECT struct ContextJdwp { uint32_t pid; uv_pipe_t pipe; @@ -68,10 +59,22 @@ private: string pkgName; #else char buf[sizeof(uint32_t)]; -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT uint8_t dummy; uv_tcp_t jvmTCP; }; +#ifdef JS_JDWP_CONNECT + struct JsMsgHeader { + uint32_t msgLen; + uint32_t pid; + }; + static constexpr uint8_t JS_PKG_MIN_SIZE = 15; // JsMsgHeader + "pkgName:"uint8_t[7~127] + static constexpr uint8_t JS_PKG_MX_SIZE = 135; + static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024 * 4; + string GetProcessListExtendPkgName(); +#else + static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024; +#endif // JS_JDWP_CONNECT using HCtxJdwp = struct ContextJdwp *; bool JdwpListen(); @@ -80,14 +83,11 @@ private: static void SendCallbackJdwpNewFD(uv_write_t *req, int status); static void *FdEventPollThread(void *args); size_t JdwpProcessListMsg(char *buffer, size_t bufferlen); -#ifdef JS_JDWP_CONNECT - string GetProcessListExtendPkgName(); -#endif // JS_JDWP_CONNECT void *MallocContext(); void FreeContext(HCtxJdwp ctx); void *AdminContext(const uint8_t op, const uint32_t pid, HCtxJdwp ctxJdwp); int CreateFdEventPoll(); - void ProcessListUpdated(void) ; + void ProcessListUpdated(void); void DrainAwakenPollThread() const; void WakePollThread(); @@ -98,7 +98,7 @@ private: map mapCtxJdwp; uv_rwlock_t lockMapContext; uv_rwlock_t lockJdwpTrack; - std::unordered_map pollNodeMap; // fd, PollNode + std::unordered_map pollNodeMap; // fd, PollNode std::vector jdwpTrackers; bool stop; }; diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index f5636504..68e0e271 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -543,7 +543,8 @@ void HdcHostUSB::SessionUsbWorkThread(void *arg) HSession hSession = (HSession)arg; constexpr uint8_t USB_HANDLE_TIMEOUT = DEVICE_CHECK_INTERVAL / TIME_BASE; WRITE_LOG(LOG_DEBUG, "SessionUsbWorkThread work thread:%p", uv_thread_self()); - while (!hSession->isDead) { + // run until all USB callback finish(ref == 1, I'm the only one left) + while (!hSession->isDead || hSession->ref > 1) { struct timeval zerotime; zerotime.tv_sec = USB_HANDLE_TIMEOUT; zerotime.tv_usec = 0; // if == 0,windows will be high CPU load diff --git a/src/test/ut_runtime.cpp b/src/test/ut_runtime.cpp index d8daa103..55c3264f 100644 --- a/src/test/ut_runtime.cpp +++ b/src/test/ut_runtime.cpp @@ -22,8 +22,8 @@ Runtime::Runtime() bCheckResult = false; checkFinish = false; hashInitialize = false; - // UintTest Running log level LOG_INFO/LOG_FULL - // Base::SetLogLevel(Hdc::LOG_FULL); // LOG_INFO + // UintTest Running log level LOG_INFO/LOG_ALL + // Base::SetLogLevel(Hdc::LOG_ALL); // LOG_INFO Base::SetLogLevel(Hdc::LOG_INFO); // three nodes all run host, at least 5+(reserve:2)=7 threads for use // client 1 + (server+daemon)= SIZE_THREAD_POOL*2+1 diff --git a/src/test/ut_runtime.h b/src/test/ut_runtime.h index a8f0daff..744ab3f7 100644 --- a/src/test/ut_runtime.h +++ b/src/test/ut_runtime.h @@ -59,7 +59,7 @@ private: uv_idle_t checkServerStop; uv_idle_t checkDaemonStop; Hdc::HdcServer *server; - Hdc::HdcDaemon *daemon; + void *daemon; // Hdc::HdcDaemon * uint8_t waitServerDaemonReadyCount = 0; bool bConnectToDaemon = false; }; -- Gitee From e3955782a3979911bfc7ced49ce0c20d9e381dda Mon Sep 17 00:00:00 2001 From: zako Date: Mon, 13 Dec 2021 01:27:36 +0800 Subject: [PATCH 29/50] buildroot/gnuc++ support and gdb fix Signed-off-by: zako Signed-off-by: zako --- BUILD.gn | 1 + src/common/base.cpp | 41 ------------- src/common/base.h | 3 - src/common/common.h | 1 + src/common/system_depend.cpp | 112 +++++++++++++++++++++++++++++++++++ src/common/system_depend.h | 27 +++++++++ src/daemon/daemon.cpp | 2 +- src/daemon/daemon_tcp.cpp | 2 +- src/daemon/daemon_unity.cpp | 34 ++--------- src/daemon/daemon_unity.h | 1 - src/daemon/daemon_usb.cpp | 84 ++++++++++++++++++-------- src/daemon/daemon_usb.h | 1 + src/daemon/jdwp.cpp | 8 ++- src/daemon/jdwp.h | 34 +++++------ src/daemon/main.cpp | 4 +- src/daemon/usb_ffs.h | 35 +---------- 16 files changed, 239 insertions(+), 151 deletions(-) create mode 100644 src/common/system_depend.cpp create mode 100644 src/common/system_depend.h diff --git a/BUILD.gn b/BUILD.gn index 5470ce02..3f74addf 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -31,6 +31,7 @@ hdc_common_sources = [ "${HDC_PATH}/src/common/tcp.cpp", "${HDC_PATH}/src/common/transfer.cpp", "${HDC_PATH}/src/common/usb.cpp", + "${HDC_PATH}/src/common/system_depend.cpp", ] config("hdc_config") { diff --git a/src/common/base.cpp b/src/common/base.cpp index 8e927c89..e773dca0 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -23,11 +23,6 @@ #include #include #include -#ifdef __MUSL__ -extern "C" { -#include "parameter.h" -} -#endif using namespace std::chrono; namespace Hdc { @@ -537,42 +532,6 @@ namespace Base { return bytesRead; } - bool SetHdcProperty(const char *key, const char *value) - { -#ifndef __MUSL__ -#ifdef HDC_PCDEBUG - WRITE_LOG(LOG_DEBUG, "Setproperty, key:%s value:%s", key, value); -#else - string sKey = key; - string sValue = value; - string sBuf = "setprop " + sKey + " " + value; - system(sBuf.c_str()); -#endif -#else - SetParameter(key, value); -#endif - return true; - } - - bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf) - { -#ifndef __MUSL__ -#ifdef HDC_PCDEBUG - WRITE_LOG(LOG_DEBUG, "Getproperty, key:%s value:%s", key, value); -#else - string sKey = key; - string sBuf = "getprop " + sKey; - RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); -#endif -#else - string sKey = key; - string sBuf = "param get " + sKey; - RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); -#endif - value[sizeOutBuf - 1] = '\0'; - return true; - } - // bufLen == 0: alloc buffer in heap, need free it later // >0: read max nBuffLen bytes to *buff // ret value: <0 or bytes read diff --git a/src/common/base.h b/src/common/base.h index 38acddc3..dce28df6 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -49,9 +49,6 @@ namespace Base { void TryCloseHandle(const uv_handle_t *handle, uv_close_cb closeCallBack); void TryCloseHandle(const uv_handle_t *handle, bool alwaysCallback, uv_close_cb closeCallBack); char **SplitCommandToArgs(const char *cmdStringLine, int *slotIndex); - bool SetHdcProperty(const char *key, const char *value); - // value needs to save results which can't be const - bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf); bool RunPipeComand(const char *cmdString, char *outBuf, uint16_t sizeOutBuf, bool ignoreTailLF); // results need to save in buf which can't be const int ReadBinFile(const char *pathName, void **buf, const int bufLen); diff --git a/src/common/common.h b/src/common/common.h index b2f6a2e6..81696a78 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -74,6 +74,7 @@ using std::vector; #include "tcp.h" #include "usb.h" #include "file_descriptor.h" +#include "system_depend.h" // clang-format on diff --git a/src/common/system_depend.cpp b/src/common/system_depend.cpp new file mode 100644 index 00000000..6d23c264 --- /dev/null +++ b/src/common/system_depend.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +############ +This file is used to support compatibility between platforms, differences between old and new projects and +compilation platforms + +defined __MUSL__ Has migrated to the latest version of harmony project + +defined HARMONY_PROJECT +With openharmony toolchains suport. If not defined, it should be [device]buildroot or [PC]msys64(...)/ubuntu-apt(...) +envirments +############ +*/ +#include "system_depend.h" +#if defined __MUSL__ && defined HARMONY_PROJECT +extern "C" { +#include "init_reboot.h" +#include "parameter.h" +} +#endif + +namespace Hdc { +namespace SystemDepend { + bool SetHdcProperty(const char *key, const char *value) + { +#if defined __MUSL__ +#ifdef HARMONY_PROJECT + SetParameter(key, value); +#else + char outBuf[256] = ""; + string sBuf = Base::StringFormat("param set %s %s", key, value); + Base::RunPipeComand(sBuf.c_str(), outBuf, sizeof(outBuf), true); +#endif // HARMONY_PROJECT +#else // not __MUSL__ +#ifdef HDC_PCDEBUG + WRITE_LOG(LOG_DEBUG, "Setproperty, key:%s value:%s", key, value); +#else + string sKey = key; + string sValue = value; + string sBuf = "setprop " + sKey + " " + value; + system(sBuf.c_str()); +#endif // HDC_PCDEBUG +#endif // __MUSL__ + return true; + } + + bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf) + { +#if defined __MUSL__ + string sKey = key; + string sBuf = "param get " + sKey; + Base::RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); +#else // not __MUSL__ +#ifdef HDC_PCDEBUG + WRITE_LOG(LOG_DEBUG, "Getproperty, key:%s value:%s", key, value); +#else + string sKey = key; + string sBuf = "getprop " + sKey; + Base::RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); +#endif // HDC_PCDEBUG +#endif //__MUSL__ + value[sizeOutBuf - 1] = '\0'; + return true; + } + + bool CallDoReboot(const char *reason) + { +#ifdef HARMONY_PROJECT + return DoReboot(reason); +#else + // todo + return false; +#endif + } + + bool RebootDevice(const string &cmd) + { +#if defined __MUSL__ + string reason; + if (cmd == "recovery") { + reason = "updater"; + } else if (cmd == "bootloader") { + reason = "updater"; + } + WRITE_LOG(LOG_DEBUG, "DoReboot with args:[%s] for cmd:[%s]", reason.c_str(), cmd.c_str()); + return CallDoReboot(reason.c_str()); +#else + const string rebootProperty = "sys.powerctl"; + string propertyVal; + if (!cmd.size()) { + propertyVal = "reboot"; + } else { + propertyVal = Base::StringFormat("reboot,%s", cmd.c_str()); + } + return SetHdcProperty(rebootProperty.c_str(), propertyVal.c_str()); +#endif + } +} +} // namespace Hdc diff --git a/src/common/system_depend.h b/src/common/system_depend.h new file mode 100644 index 00000000..732fb8c8 --- /dev/null +++ b/src/common/system_depend.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef HDC_SYSTEM_DEPEND_H +#define HDC_SYSTEM_DEPEND_H +#include "common.h" + +namespace Hdc { +namespace SystemDepend { + bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf); + bool SetHdcProperty(const char *key, const char *value); + bool RebootDevice(const string &cmd); +} // namespace SystemDepend +} // namespace Hdc + +#endif // HDC_BASE_H \ No newline at end of file diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index a4924b1f..a7e3c4a0 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -86,7 +86,7 @@ void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB) // enable security char value[4] = "0"; - Base::GetHdcProperty("ro.hdc.secure", value, sizeof(value)); + SystemDepend::GetHdcProperty("ro.hdc.secure", value, sizeof(value)); string secure = value; enableSecure = (Base::Trim(secure) == "1"); } diff --git a/src/daemon/daemon_tcp.cpp b/src/daemon/daemon_tcp.cpp index 35e90be1..acb4caf9 100644 --- a/src/daemon/daemon_tcp.cpp +++ b/src/daemon/daemon_tcp.cpp @@ -21,7 +21,7 @@ HdcDaemonTCP::HdcDaemonTCP(const bool serverOrDaemonIn, void *ptrMainBase) // If the listening value for the property setting is obtained, it will be 0 randomly assigned. char strTCPPort[BUF_SIZE_TINY] = ""; const uint16_t BUFF_SIZE = 8; - Base::GetHdcProperty("persist.hdc.port", strTCPPort, BUFF_SIZE); + SystemDepend::GetHdcProperty("persist.hdc.port", strTCPPort, BUFF_SIZE); tcpListenPort = atoi(strTCPPort); if (tcpListenPort <= 0) { tcpListenPort = 0; diff --git a/src/daemon/daemon_unity.cpp b/src/daemon/daemon_unity.cpp index 268cc090..d2992920 100644 --- a/src/daemon/daemon_unity.cpp +++ b/src/daemon/daemon_unity.cpp @@ -14,11 +14,6 @@ */ #include "daemon_unity.h" #include -#ifdef __MUSL__ -extern "C" { -#include "init_reboot.h" -} -#endif namespace Hdc { HdcDaemonUnity::HdcDaemonUnity(HTaskInfo hTaskInfo) @@ -176,24 +171,7 @@ bool HdcDaemonUnity::RemountDevice() bool HdcDaemonUnity::RebootDevice(const string &cmd) { sync(); -#ifndef __MUSL__ - string propertyVal; - if (!cmd.size()) { - propertyVal = "reboot"; - } else { - propertyVal = Base::StringFormat("reboot,%s", cmd.c_str()); - } - return Base::SetHdcProperty(rebootProperty.c_str(), propertyVal.c_str()); -#else - string reason; - if (cmd == "recovery") { - reason = "updater"; - } else if (cmd == "bootloader") { - reason = "updater"; - } - WRITE_LOG(LOG_DEBUG, "DoReboot with args:[%s] for cmd:[%s]", reason.c_str(), cmd.c_str()); - return DoReboot(reason.c_str()); -#endif + return SystemDepend::RebootDevice(cmd); } bool HdcDaemonUnity::SetDeviceRunMode(void *daemonIn, const char *cmd) @@ -201,12 +179,12 @@ bool HdcDaemonUnity::SetDeviceRunMode(void *daemonIn, const char *cmd) HdcDaemon *daemon = (HdcDaemon *)daemonIn; WRITE_LOG(LOG_DEBUG, "Set run mode:%s", cmd); if (!strcmp(CMDSTR_TMODE_USB.c_str(), cmd)) { - Base::SetHdcProperty("persist.hdc.mode", CMDSTR_TMODE_USB.c_str()); + SystemDepend::SetHdcProperty("persist.hdc.mode", CMDSTR_TMODE_USB.c_str()); } else if (!strncmp("port", cmd, strlen("port"))) { - Base::SetHdcProperty("persist.hdc.mode", CMDSTR_TMODE_TCP.c_str()); + SystemDepend::SetHdcProperty("persist.hdc.mode", CMDSTR_TMODE_TCP.c_str()); if (!strncmp("port ", cmd, strlen("port "))) { const char *port = cmd + 5; - Base::SetHdcProperty("persist.hdc.port", port); + SystemDepend::SetHdcProperty("persist.hdc.port", port); } } else { LogMsg(MSG_FAIL, "Unknow command"); @@ -285,9 +263,9 @@ bool HdcDaemonUnity::CommandDispatch(const uint16_t command, uint8_t *payload, c case CMD_UNITY_ROOTRUN: { ret = false; if (payloadSize != 0 && !strcmp((char *)strPayload.c_str(), "r")) { - Base::SetHdcProperty("persist.hdc.root", "0"); + SystemDepend::SetHdcProperty("persist.hdc.root", "0"); } else { - Base::SetHdcProperty("persist.hdc.root", "1"); + SystemDepend::SetHdcProperty("persist.hdc.root", "1"); } daemon->PostStopInstanceMessage(true); break; diff --git a/src/daemon/daemon_unity.h b/src/daemon/daemon_unity.h index 01b9d48b..3da6de65 100644 --- a/src/daemon/daemon_unity.h +++ b/src/daemon/daemon_unity.h @@ -38,7 +38,6 @@ private: bool AsyncCmdOut(bool finish, int64_t exitStatus, const string result); bool TrackJdwpProcess(void *daemonIn); - const string rebootProperty = "sys.powerctl"; AsyncCmd asyncCommand; uint16_t currentDataCommand; #ifdef UNIT_TEST diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index c1988bbc..d61bb488 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -97,10 +97,45 @@ int HdcDaemonUSB::Initial() return 0; } +// make gnuc++ happy. Clang support direct assignment value to structure, buf g++ weakness +void HdcDaemonUSB::FillUsbV2Head(usb_functionfs_desc_v2 &descUsbFfs) +{ + descUsbFfs.head.magic = LONG_LE(FUNCTIONFS_DESCRIPTORS_MAGIC_V2); + descUsbFfs.head.length = LONG_LE(sizeof(descUsbFfs)); + descUsbFfs.head.flags + = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC | FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC; + descUsbFfs.config1Count = 3; + descUsbFfs.config2Count = 3; + descUsbFfs.config3Count = 5; + descUsbFfs.configWosCount = 1; + descUsbFfs.config1Desc = config1; + descUsbFfs.config2Desc = config2; + descUsbFfs.config3Desc = config3; + descUsbFfs.wosHead.interface = 1; + descUsbFfs.wosHead.dwLength = LONG_LE(sizeof(descUsbFfs.wosHead) + sizeof(descUsbFfs.wosDesc)); + descUsbFfs.wosHead.bcdVersion = SHORT_LE(1); + descUsbFfs.wosHead.wIndex = SHORT_LE(4); + descUsbFfs.wosHead.bCount = 1; + descUsbFfs.wosHead.Reserved = 0; + descUsbFfs.wosDesc.bFirstInterfaceNumber = 0; + descUsbFfs.wosDesc.Reserved1 = 1; + descUsbFfs.wosDesc.CompatibleID[0] = 'W'; + descUsbFfs.wosDesc.CompatibleID[1] = 'I'; + descUsbFfs.wosDesc.CompatibleID[2] = 'N'; + descUsbFfs.wosDesc.CompatibleID[3] = 'U'; + descUsbFfs.wosDesc.CompatibleID[4] = 'S'; + descUsbFfs.wosDesc.CompatibleID[5] = 'B'; + descUsbFfs.wosDesc.CompatibleID[6] = '\0'; + Base::ZeroArray(descUsbFfs.wosDesc.SubCompatibleID); + Base::ZeroArray(descUsbFfs.wosDesc.Reserved2); +} + // DAEMON end USB module USB-FFS EP port connection int HdcDaemonUSB::ConnectEPPoint(HUSB hUSB) { int ret = ERR_GENERIC; + struct usb_functionfs_desc_v2 descUsbFfs = {}; + FillUsbV2Head(descUsbFfs); while (true) { if (controlEp <= 0) { // After the control port sends the instruction, the device is initialized by the device to the HOST host, @@ -112,7 +147,7 @@ int HdcDaemonUSB::ConnectEPPoint(HUSB hUSB) WRITE_LOG(LOG_WARN, "%s: cannot open control endpoint: errno=%d", ep0Path.c_str(), errno); break; } - if (write(controlEp, &USB_FFS_DESC, sizeof(USB_FFS_DESC)) < 0) { + if (write(controlEp, &descUsbFfs, sizeof(descUsbFfs)) < 0) { WRITE_LOG(LOG_WARN, "%s: write ffs configs failed: errno=%d", ep0Path.c_str(), errno); break; } @@ -121,7 +156,7 @@ int HdcDaemonUSB::ConnectEPPoint(HUSB hUSB) break; } // active usbrc,Send USB initialization singal - Base::SetHdcProperty("sys.usb.ffs.ready", "1"); + SystemDepend::SetHdcProperty("sys.usb.ffs.ready", "1"); WRITE_LOG(LOG_DEBUG, "ConnectEPPoint ctrl init finish, set usb-ffs ready"); } string outPath = basePath + "/ep1"; @@ -395,33 +430,34 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) while (thisClass->isAlive) { // Don't care is module running, first deal with this if (bytesIOBytes < 0) { - WRITE_LOG(LOG_WARN, "USBIO failed1 %s", uv_strerror(bytesIOBytes)); - break; - } else if (bytesIOBytes == 0) { - // zero packet - WRITE_LOG(LOG_WARN, "Zero packet received"); - ret = true; - break; - } - if (thisClass->JumpAntiquePacket(*bufPtr, bytesIOBytes)) { - WRITE_LOG(LOG_DEBUG, "JumpAntiquePacket auto jump"); - ret = true; - break; - } - // guess is head of packet - if ((childRet = thisClass->AvailablePacket((uint8_t *)bufPtr, bytesIOBytes, &sessionId)) != RET_SUCCESS) { - if (childRet != ERR_IO_SOFT_RESET) { - WRITE_LOG(LOG_WARN, "AvailablePacket check failed, ret:%d buf:%-50s", bytesIOBytes, bufPtr); + if (bytesIOBytes != -EINTR) { // Epoll will be broken when gdb attach + WRITE_LOG(LOG_WARN, "USBIO failed1 %s", uv_strerror(bytesIOBytes)); + ret = false; break; } - // reset packet - childRet = 0; // need max size + } else if (bytesIOBytes == 0) { // zero packet + WRITE_LOG(LOG_WARN, "Zero packet received"); } else { - // AvailablePacket case - if ((childRet = thisClass->DispatchToWorkThread(sessionId, bufPtr, bytesIOBytes)) < 0) { - WRITE_LOG(LOG_FATAL, "DispatchToWorkThread failed"); + if (thisClass->JumpAntiquePacket(*bufPtr, bytesIOBytes)) { + WRITE_LOG(LOG_DEBUG, "JumpAntiquePacket auto jump"); + ret = true; break; } + // guess is head of packet + if ((childRet = thisClass->AvailablePacket((uint8_t *)bufPtr, bytesIOBytes, &sessionId)) != RET_SUCCESS) { + if (childRet != ERR_IO_SOFT_RESET) { + WRITE_LOG(LOG_WARN, "AvailablePacket check failed, ret:%d buf:%-50s", bytesIOBytes, bufPtr); + break; + } + // reset packet + childRet = 0; // need max size + } else { + // AvailablePacket case + if ((childRet = thisClass->DispatchToWorkThread(sessionId, bufPtr, bytesIOBytes)) < 0) { + WRITE_LOG(LOG_FATAL, "DispatchToWorkThread failed"); + break; + } + } } int nextReadSize = childRet == 0 ? hUSB->wMaxPacketSizeSend : std::min(childRet, Base::GetUsbffsBulkSize()); thisClass->toReadUsbDataSize = nextReadSize; diff --git a/src/daemon/daemon_usb.h b/src/daemon/daemon_usb.h index cecb67e9..a09cfd3d 100644 --- a/src/daemon/daemon_usb.h +++ b/src/daemon/daemon_usb.h @@ -50,6 +50,7 @@ private: void ResetOldSession(uint32_t sessionId); int GetMaxPacketSize(int fdFfs); int UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int dataSize); + void FillUsbV2Head(struct usb_functionfs_desc_v2 &descUsbFfs); HdcUSB usbHandle; string basePath; // usb device's base path diff --git a/src/daemon/jdwp.cpp b/src/daemon/jdwp.cpp index c39d4972..da2da110 100644 --- a/src/daemon/jdwp.cpp +++ b/src/daemon/jdwp.cpp @@ -17,6 +17,12 @@ #include namespace Hdc { +#ifdef JS_JDWP_CONNECT +static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024 * 4; +#else +static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024; +#endif // JS_JDWP_CONNECT + HdcJdwp::HdcJdwp(uv_loop_t *loopIn) { Base::ZeroStruct(listenPipe); @@ -115,7 +121,7 @@ void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) } else { // JS:pid PkgName #ifdef JS_JDWP_CONNECT struct JsMsgHeader *jsMsg = (struct JsMsgHeader *)p; - if (jsMsg->msgLen == nread) { + if (jsMsg->msgLen == (uint32_t)nread) { pid = jsMsg->pid; string pkgName = string((char *)p + sizeof(JsMsgHeader), jsMsg->msgLen - sizeof(JsMsgHeader)); ctxJdwp->pkgName = pkgName; diff --git a/src/daemon/jdwp.h b/src/daemon/jdwp.h index f4d56dca..3b9adea2 100644 --- a/src/daemon/jdwp.h +++ b/src/daemon/jdwp.h @@ -25,12 +25,15 @@ public: virtual ~HdcJdwp(); int Initial(); void Stop(); - bool CreateJdwpTracker(HTaskInfo hTaskInfo); + bool CreateJdwpTracker(HTaskInfo hTaskInfo) ; bool ReadyForRelease(); string GetProcessList(); bool SendJdwpNewFD(uint32_t targetPID, int fd); bool CheckPIDExist(uint32_t targetPID); - +#ifdef JS_JDWP_CONNECT + static constexpr uint8_t JS_PKG_MIN_SIZE = 15; // JsMsgHeader + "pkgName:"uint8_t[7~127] + static constexpr uint8_t JS_PKG_MX_SIZE = 135; +#endif // JS_JDWP_CONNECT private: struct _PollFd { int fd; @@ -49,6 +52,12 @@ private: ppid = pid; } }; +#ifdef JS_JDWP_CONNECT + struct JsMsgHeader { + uint32_t msgLen; + uint32_t pid; + }; +#endif // JS_JDWP_CONNECT struct ContextJdwp { uint32_t pid; uv_pipe_t pipe; @@ -59,22 +68,10 @@ private: string pkgName; #else char buf[sizeof(uint32_t)]; -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT uint8_t dummy; uv_tcp_t jvmTCP; }; -#ifdef JS_JDWP_CONNECT - struct JsMsgHeader { - uint32_t msgLen; - uint32_t pid; - }; - static constexpr uint8_t JS_PKG_MIN_SIZE = 15; // JsMsgHeader + "pkgName:"uint8_t[7~127] - static constexpr uint8_t JS_PKG_MX_SIZE = 135; - static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024 * 4; - string GetProcessListExtendPkgName(); -#else - static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024; -#endif // JS_JDWP_CONNECT using HCtxJdwp = struct ContextJdwp *; bool JdwpListen(); @@ -83,11 +80,14 @@ private: static void SendCallbackJdwpNewFD(uv_write_t *req, int status); static void *FdEventPollThread(void *args); size_t JdwpProcessListMsg(char *buffer, size_t bufferlen); +#ifdef JS_JDWP_CONNECT + string GetProcessListExtendPkgName(); +#endif // JS_JDWP_CONNECT void *MallocContext(); void FreeContext(HCtxJdwp ctx); void *AdminContext(const uint8_t op, const uint32_t pid, HCtxJdwp ctxJdwp); int CreateFdEventPoll(); - void ProcessListUpdated(void); + void ProcessListUpdated(void) ; void DrainAwakenPollThread() const; void WakePollThread(); @@ -98,7 +98,7 @@ private: map mapCtxJdwp; uv_rwlock_t lockMapContext; uv_rwlock_t lockJdwpTrack; - std::unordered_map pollNodeMap; // fd, PollNode + std::unordered_map pollNodeMap; // fd, PollNode std::vector jdwpTrackers; bool stop; }; diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 2cd54680..ce8b9bac 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -35,7 +35,7 @@ bool ForkChildCheck(int argc, const char *argv[]) // hdcd -b #service start backgroundRun // hdcd -fork #fork char modeSet[BUF_SIZE_TINY] = ""; - Base::GetHdcProperty("persist.hdc.mode", modeSet, BUF_SIZE_TINY); + SystemDepend::GetHdcProperty("persist.hdc.mode", modeSet, BUF_SIZE_TINY); Base::PrintMessage("Background mode, persist.hdc.mode"); string workMode = modeSet; workMode = Base::Trim(workMode); @@ -135,7 +135,7 @@ bool GetDaemonCommandlineOptions(int argc, const char *argv[]) void NeedDropPriv() { char droprootSet[BUF_SIZE_TINY] = ""; - Base::GetHdcProperty("persist.hdc.root", droprootSet, BUF_SIZE_TINY); + SystemDepend::GetHdcProperty("persist.hdc.root", droprootSet, BUF_SIZE_TINY); droprootSet[sizeof(droprootSet) - 1] = '\0'; string rootMode = droprootSet; if (Base::Trim(rootMode) == "1") { diff --git a/src/daemon/usb_ffs.h b/src/daemon/usb_ffs.h index 1998daaf..c8bb1ee0 100644 --- a/src/daemon/usb_ffs.h +++ b/src/daemon/usb_ffs.h @@ -173,7 +173,7 @@ static struct UsbFunctionDesc config2 = { }, }; -static const struct { +struct usb_functionfs_desc_v2 { struct usb_functionfs_descs_head_v2 head; __le32 config1Count; __le32 config2Count; @@ -183,36 +183,7 @@ static const struct { struct UsbFuncConfig config3Desc; struct usb_os_desc_header wosHead; struct usb_ext_compat_desc wosDesc; -} __attribute__((packed)) USB_FFS_DESC = { - .head = - { - .magic = LONG_LE(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), - .length = LONG_LE(sizeof(USB_FFS_DESC)), - .flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC | - FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC - }, - .config1Count = 3, - .config2Count = 3, - .config3Count = 5, - .configWosCount = 1, - .config1Desc = config1, - .config2Desc = config2, - .config3Desc = config3, - .wosHead = { - .interface = 1, - .dwLength = LONG_LE(sizeof(USB_FFS_DESC.wosHead) + sizeof(USB_FFS_DESC.wosDesc)), - .bcdVersion = SHORT_LE(1), - .wIndex = SHORT_LE(4), - .bCount = 1, - .Reserved = 0, - }, - .wosDesc = { - .bFirstInterfaceNumber = 0, - .Reserved1 = 1, - .CompatibleID = { 'W', 'I', 'N', 'U', 'S', 'B', '\0', '\0'}, - .SubCompatibleID = {0}, - .Reserved2 = {0}, - } -}; +} __attribute__((packed)); + } // namespace Hdc #endif -- Gitee From 648bb6ce23ba6693de69800b79237d431c6c02b8 Mon Sep 17 00:00:00 2001 From: zako Date: Mon, 13 Dec 2021 09:31:46 +0800 Subject: [PATCH 30/50] jdwp modfiy Signed-off-by: zako --- src/daemon/jdwp.cpp | 8 +------- src/daemon/jdwp.h | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/daemon/jdwp.cpp b/src/daemon/jdwp.cpp index da2da110..c39d4972 100644 --- a/src/daemon/jdwp.cpp +++ b/src/daemon/jdwp.cpp @@ -17,12 +17,6 @@ #include namespace Hdc { -#ifdef JS_JDWP_CONNECT -static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024 * 4; -#else -static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024; -#endif // JS_JDWP_CONNECT - HdcJdwp::HdcJdwp(uv_loop_t *loopIn) { Base::ZeroStruct(listenPipe); @@ -121,7 +115,7 @@ void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) } else { // JS:pid PkgName #ifdef JS_JDWP_CONNECT struct JsMsgHeader *jsMsg = (struct JsMsgHeader *)p; - if (jsMsg->msgLen == (uint32_t)nread) { + if (jsMsg->msgLen == nread) { pid = jsMsg->pid; string pkgName = string((char *)p + sizeof(JsMsgHeader), jsMsg->msgLen - sizeof(JsMsgHeader)); ctxJdwp->pkgName = pkgName; diff --git a/src/daemon/jdwp.h b/src/daemon/jdwp.h index 3b9adea2..f4d56dca 100644 --- a/src/daemon/jdwp.h +++ b/src/daemon/jdwp.h @@ -25,15 +25,12 @@ public: virtual ~HdcJdwp(); int Initial(); void Stop(); - bool CreateJdwpTracker(HTaskInfo hTaskInfo) ; + bool CreateJdwpTracker(HTaskInfo hTaskInfo); bool ReadyForRelease(); string GetProcessList(); bool SendJdwpNewFD(uint32_t targetPID, int fd); bool CheckPIDExist(uint32_t targetPID); -#ifdef JS_JDWP_CONNECT - static constexpr uint8_t JS_PKG_MIN_SIZE = 15; // JsMsgHeader + "pkgName:"uint8_t[7~127] - static constexpr uint8_t JS_PKG_MX_SIZE = 135; -#endif // JS_JDWP_CONNECT + private: struct _PollFd { int fd; @@ -52,12 +49,6 @@ private: ppid = pid; } }; -#ifdef JS_JDWP_CONNECT - struct JsMsgHeader { - uint32_t msgLen; - uint32_t pid; - }; -#endif // JS_JDWP_CONNECT struct ContextJdwp { uint32_t pid; uv_pipe_t pipe; @@ -68,10 +59,22 @@ private: string pkgName; #else char buf[sizeof(uint32_t)]; -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT uint8_t dummy; uv_tcp_t jvmTCP; }; +#ifdef JS_JDWP_CONNECT + struct JsMsgHeader { + uint32_t msgLen; + uint32_t pid; + }; + static constexpr uint8_t JS_PKG_MIN_SIZE = 15; // JsMsgHeader + "pkgName:"uint8_t[7~127] + static constexpr uint8_t JS_PKG_MX_SIZE = 135; + static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024 * 4; + string GetProcessListExtendPkgName(); +#else + static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024; +#endif // JS_JDWP_CONNECT using HCtxJdwp = struct ContextJdwp *; bool JdwpListen(); @@ -80,14 +83,11 @@ private: static void SendCallbackJdwpNewFD(uv_write_t *req, int status); static void *FdEventPollThread(void *args); size_t JdwpProcessListMsg(char *buffer, size_t bufferlen); -#ifdef JS_JDWP_CONNECT - string GetProcessListExtendPkgName(); -#endif // JS_JDWP_CONNECT void *MallocContext(); void FreeContext(HCtxJdwp ctx); void *AdminContext(const uint8_t op, const uint32_t pid, HCtxJdwp ctxJdwp); int CreateFdEventPoll(); - void ProcessListUpdated(void) ; + void ProcessListUpdated(void); void DrainAwakenPollThread() const; void WakePollThread(); @@ -98,7 +98,7 @@ private: map mapCtxJdwp; uv_rwlock_t lockMapContext; uv_rwlock_t lockJdwpTrack; - std::unordered_map pollNodeMap; // fd, PollNode + std::unordered_map pollNodeMap; // fd, PollNode std::vector jdwpTrackers; bool stop; }; -- Gitee From 85e163f7d448aa2bbd480196eb52cd4c9cc4a636 Mon Sep 17 00:00:00 2001 From: zako Date: Tue, 14 Dec 2021 10:54:37 +0800 Subject: [PATCH 31/50] fix forward issue Signed-off-by: zako --- src/common/base.cpp | 4 ++-- src/common/forward.cpp | 13 +++++++------ src/common/forward.h | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/common/base.cpp b/src/common/base.cpp index e773dca0..4cff03f3 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -40,7 +40,7 @@ namespace Base { { string tmpString = GetFileNameAny(debugInfo); debugInfo = StringFormat("%s:%d", tmpString.c_str(), line); - if (g_logLevel < LOG_ALL) { + if (g_logLevel < LOG_DEBUG) { debugInfo = ""; threadIdString = ""; } else { @@ -103,7 +103,7 @@ namespace Base { logLevelString = std::to_string(logLevel); } string msTimeSurplus; - if (g_logLevel > LOG_DEBUG) { + if (g_logLevel >= LOG_DEBUG) { const auto sSinceUnix0Rest = duration_cast(sinceUnix0).count() % (TIME_BASE * TIME_BASE); msTimeSurplus = StringFormat(".%06llu", sSinceUnix0Rest); } diff --git a/src/common/forward.cpp b/src/common/forward.cpp index b096cbb9..9c7f9a4f 100644 --- a/src/common/forward.cpp +++ b/src/common/forward.cpp @@ -119,12 +119,12 @@ void *HdcForwardBase::MallocContext(bool masterSlave) void HdcForwardBase::FreeContextCallBack(HCtxForward ctx) { - AdminContext(OP_REMOVE, ctx->id, nullptr); - Base::DoNextLoop(loopTask, ctx, [](const uint8_t flag, string &msg, const void *data) { + Base::DoNextLoop(loopTask, ctx, [this](const uint8_t flag, string &msg, const void *data) { HCtxForward ctx = (HCtxForward)data; + AdminContext(OP_REMOVE, ctx->id, nullptr); delete ctx; + --refCount; }); - --refCount; } void HdcForwardBase::FreeJDWP(HCtxForward ctx) @@ -491,7 +491,7 @@ bool HdcForwardBase::SetupPoint(HCtxForward ctxPoint) return ret; } -bool HdcForwardBase::BeginForward(const char *command, string &sError) +bool HdcForwardBase::BeginForward(const string &command, string &sError) { bool ret = false; int argc = 0; @@ -501,7 +501,7 @@ bool HdcForwardBase::BeginForward(const char *command, string &sError) WRITE_LOG(LOG_FATAL, "MallocContext failed"); return false; } - char **argv = Base::SplitCommandToArgs(command, &argc); + char **argv = Base::SplitCommandToArgs(command.c_str(), &argc); while (true) { if (argc < CMD_ARG1_COUNT) { break; @@ -751,7 +751,8 @@ bool HdcForwardBase::CommandDispatch(const uint16_t command, uint8_t *payload, c string sError; // prepare if (CMD_FORWARD_INIT == command) { - if (!BeginForward((char *)(payload), sError)) { + string strCommand((char *)payload, payloadSize); + if (!BeginForward(strCommand, sError)) { ret = false; goto Finish; } diff --git a/src/common/forward.h b/src/common/forward.h index 9baf4702..cf3741a2 100644 --- a/src/common/forward.h +++ b/src/common/forward.h @@ -22,7 +22,7 @@ public: HdcForwardBase(HTaskInfo hTaskInfo); virtual ~HdcForwardBase(); bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); - bool BeginForward(const char *command, string &sError); + bool BeginForward(const string &command, string &sError); void StopTask(); bool ReadyForRelease(); -- Gitee From d4623fbf9e15ddbc5bfc82d6f261874cbc8878dc Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 16 Dec 2021 21:51:44 +0800 Subject: [PATCH 32/50] fix UsbIO may issues Signed-off-by: zako --- src/common/define_plus.h | 1 + src/common/forward.cpp | 2 +- src/common/session.cpp | 7 +++- src/common/usb.cpp | 2 - src/common/usb.h | 2 +- src/daemon/daemon.cpp | 11 ++++++ src/daemon/daemon.h | 1 + src/daemon/daemon_usb.cpp | 80 +++++++++++++++++++-------------------- src/daemon/daemon_usb.h | 11 ++++-- src/host/host_usb.cpp | 25 +++++++++--- src/host/host_usb.h | 2 +- src/host/server.cpp | 1 + 12 files changed, 87 insertions(+), 58 deletions(-) diff --git a/src/common/define_plus.h b/src/common/define_plus.h index a36c70ca..27350091 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -222,6 +222,7 @@ struct HdcUSB { uint8_t *bufDevice; uint8_t *bufHost; libusb_transfer *transferRecv; + mutex lockTransferRecv; bool recvIOComplete; bool sendIOComplete; uv_thread_t threadUsbChildWork; diff --git a/src/common/forward.cpp b/src/common/forward.cpp index 9c7f9a4f..eeb6c8c7 100644 --- a/src/common/forward.cpp +++ b/src/common/forward.cpp @@ -751,7 +751,7 @@ bool HdcForwardBase::CommandDispatch(const uint16_t command, uint8_t *payload, c string sError; // prepare if (CMD_FORWARD_INIT == command) { - string strCommand((char *)payload, payloadSize); + string strCommand(reinterpret_cast(payload), payloadSize); if (!BeginForward(strCommand, sError)) { ret = false; goto Finish; diff --git a/src/common/session.cpp b/src/common/session.cpp index 965d3698..8798f0f8 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -488,7 +488,7 @@ void HdcSessionBase::FreeSessionOpeate(uv_timer_t *handle) if (hSession->hUSB != nullptr && (!hSession->hUSB->recvIOComplete || !hSession->hUSB->sendIOComplete)) { if (!hSession->hUSB->recvIOComplete) { HdcUSBBase *pUSB = ((HdcUSBBase *)hSession->classModule); - pUSB->CancelUsbLoopRead(hSession->hUSB); + pUSB->CancelUsbLoopRead(hSession); } // send will be end with timeout return; @@ -701,6 +701,11 @@ int HdcSessionBase::DecryptPayload(HSession hSession, PayloadHead *payloadHeadBe WRITE_LOG(LOG_FATAL, "Session recv CalcCheckSum failed"); return ERR_BUF_CHECK; } + //++debug + if (!memcmp(data, "id", 2)) { + WRITE_LOG(LOG_FATAL, "Test command recv"); + return ERR_GENERIC; + } if (!FetchCommand(hSession, protectBuf.channelId, protectBuf.commandFlag, data, dataSize)) { WRITE_LOG(LOG_WARN, "FetchCommand failed"); return ERR_GENERIC; diff --git a/src/common/usb.cpp b/src/common/usb.cpp index c971bd02..852277ab 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -133,10 +133,8 @@ void HdcUSBBase::PreSendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) uint32_t sid = sessionIdOld; // or we can sendmsg to childthread send? hUSB->lockDeviceHandle.lock(); - ++hSession->ref; WRITE_LOG(LOG_WARN, "SendToHdcStream check, sessionId not matched"); SendUsbSoftReset(hSession, sid); - --hSession->ref; hUSB->lockDeviceHandle.unlock(); } } diff --git a/src/common/usb.h b/src/common/usb.h index 0c9361ec..225375c7 100644 --- a/src/common/usb.h +++ b/src/common/usb.h @@ -22,7 +22,7 @@ public: HdcUSBBase(const bool serverOrDaemonIn, void *ptrMainBase); virtual ~HdcUSBBase(); virtual bool ReadyForWorkThread(HSession hSession); - virtual void CancelUsbLoopRead(HUSB hUSB) {}; + virtual void CancelUsbLoopRead(HSession hSession) {}; int SendUSBBlock(HSession hSession, uint8_t *data, const int length); protected: diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index a7e3c4a0..fd95f3e7 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -129,6 +129,7 @@ bool HdcDaemon::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uin break; case CMD_FORWARD_INIT: case CMD_FORWARD_CHECK: + case CMD_FORWARD_ACTIVE_MASTER: case CMD_FORWARD_ACTIVE_SLAVE: case CMD_FORWARD_DATA: case CMD_FORWARD_FREE_CONTEXT: @@ -297,4 +298,14 @@ void HdcDaemon::JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO) uint32_t fd = *(uint32_t *)(buf + 5); // 5 : fd offset ((HdcJdwp *)clsJdwp)->SendJdwpNewFD(pid, fd); }; + +void HdcDaemon::NotifyInstanceSessionFree(HSession hSession, bool freeOrClear) +{ + if (!freeOrClear) + return; // ignore step 1 + if (clsUSBServ != nullptr) { + auto clsUsbModule = reinterpret_cast(clsUSBServ); + clsUsbModule->OnSessionFreeFinally(hSession); + } +} } // namespace Hdc diff --git a/src/daemon/daemon.h b/src/daemon/daemon.h index b25929f4..c5576d30 100644 --- a/src/daemon/daemon.h +++ b/src/daemon/daemon.h @@ -39,6 +39,7 @@ private: void ClearInstanceResource(); bool DaemonSessionHandshake(HSession hSession, const uint32_t channelId, uint8_t *payload, int payloadSize); void TryStopInstance(); + void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear); bool enableSecure; }; diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index d61bb488..c9580aa5 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -31,6 +31,10 @@ HdcDaemonUSB::~HdcDaemonUSB() if (controlEp > 0) { close(controlEp); } + if (ctxRecv.buf) { + delete[] ctxRecv.buf; + } + uv_fs_req_cleanup(&ctxRecv.req); } void HdcDaemonUSB::Stop() @@ -87,8 +91,16 @@ int HdcDaemonUSB::Initial() basePath = GetDevPath(USB_FFS_BASE); if (access((basePath + "/ep0").c_str(), F_OK) != 0) { WRITE_LOG(LOG_DEBUG, "Only support usb-ffs, make sure kernel3.8+ and usb-ffs enabled, usbmode disabled"); - return -1; + return ERR_API_FAIL; + } + ctxRecv.thisClass = this; + ctxRecv.bufSizeMax = Base::GetUsbffsBulkSize(); + ctxRecv.buf = new uint8_t[ctxRecv.bufSizeMax](); + if (!ctxRecv.buf) { + WRITE_LOG(LOG_FATAL, "Init alloc memory failed"); + return ERR_BUF_ALLOC; } + HdcDaemon *daemon = (HdcDaemon *)clsMainBase; WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB::Initiall"); uv_timer_init(&daemon->loopMain, &checkEP); @@ -263,12 +275,12 @@ int HdcDaemonUSB::CloseBulkEp(bool bulkInOut, int bulkFd, uv_loop_t *loop) isAlive = false; uv_fs_close(loop, req, bulkFd, [](uv_fs_t *req) { auto ctx = (CtxCloseBulkEp *)req->data; + WRITE_LOG(LOG_DEBUG, "Try to abort blukin write callback %s", ctx->bulkInOut ? "bulkin" : "bulkout"); if (ctx->bulkInOut) { ctx->thisClass->usbHandle.bulkIn = 0; } else { ctx->thisClass->usbHandle.bulkOut = 0; } - WRITE_LOG(LOG_DEBUG, "Try to abort blukin write callback %s", ctx->bulkInOut ? "bulkin" : "bulkout"); uv_fs_req_cleanup(req); delete ctx; }); @@ -312,11 +324,6 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t int HdcDaemonUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) { HdcDaemon *daemon = (HdcDaemon *)hSession->classInstance; - // Prevent memory stacking, send temporary way to use asynchronous - // Generally sent in the same thread, but when new session is created, there is a possibility that the old - // session is not retired. At present, the radical transmission method is currently opened directly in various - // threads, and it can be used exclusive File-DESC transmission mode in each thread. The late stage can be used - // as asynchronous + SendPipe to the main thread transmission. uv_mutex_lock(&sendEP); ++hSession->ref; int ret = SendUSBIOSync(hSession, &usbHandle, data, length); @@ -335,6 +342,15 @@ void HdcDaemonUSB::OnNewHandshakeOK(const uint32_t sessionId) currentSessionId = sessionId; // sync with server, and set server's real Id } +// MainThreadCall, when seession was freeed +void HdcDaemonUSB::OnSessionFreeFinally(const HSession hSession) +{ + if (currentSessionId == hSession->sessionId) { + isAlive = false; + // uv_cancel ctxRecv.req == UV_EBUSY, not effect immediately. It must be close by logic + } +} + HSession HdcDaemonUSB::PrepareNewSession(uint32_t sessionId, uint8_t *pRecvBuf, int recvBytesIO) { HdcDaemon *daemon = reinterpret_cast(clsMainBase); @@ -368,8 +384,6 @@ int HdcDaemonUSB::UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int int HdcDaemonUSB::DispatchToWorkThread(uint32_t sessionId, uint8_t *readBuf, int readBytes) { - // Format:USBPacket1 payload1...USBPacketn - // payloadn-[USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] HSession hChildSession = nullptr; HdcDaemon *daemon = reinterpret_cast(clsMainBase); int childRet = RET_SUCCESS; @@ -423,13 +437,11 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) uint32_t sessionId = 0; bool ret = false; int childRet = 0; - --thisClass->ref; - if (thisClass->toReadUsbDataSize > hUSB->wMaxPacketSizeSend && bytesIOBytes != thisClass->toReadUsbDataSize) { - WRITE_LOG(LOG_WARN, "Not read all data, indexsay:%d really:%d", thisClass->toReadUsbDataSize, bytesIOBytes); - } while (thisClass->isAlive) { // Don't care is module running, first deal with this if (bytesIOBytes < 0) { + // logic alive and EINTER is gdb attach + // logic unalive and EINTER maybe close fd if (bytesIOBytes != -EINTR) { // Epoll will be broken when gdb attach WRITE_LOG(LOG_WARN, "USBIO failed1 %s", uv_strerror(bytesIOBytes)); ret = false; @@ -460,7 +472,6 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) } } int nextReadSize = childRet == 0 ? hUSB->wMaxPacketSizeSend : std::min(childRet, Base::GetUsbffsBulkSize()); - thisClass->toReadUsbDataSize = nextReadSize; if (thisClass->LoopUSBRead(hUSB, nextReadSize) < 0) { WRITE_LOG(LOG_FATAL, "LoopUSBRead failed"); break; @@ -470,45 +481,28 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) } if (!ret) { thisClass->isAlive = false; + thisClass->ctxRecv.atPollQueue = false; } - delete[] ctxIo->buf; - uv_fs_req_cleanup(req); - delete ctxIo; } int HdcDaemonUSB::LoopUSBRead(HUSB hUSB, int readMaxWanted) { int ret = ERR_GENERIC; HdcDaemon *daemon = reinterpret_cast(clsMainBase); - auto ctxIo = new CtxUvFileCommonIo(); - 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 = readMaxWanted; - ctxIo->data = hUSB; - ctxIo->thisClass = this; - req = &ctxIo->req; - req->data = ctxIo; - iov = uv_buf_init(reinterpret_cast(ctxIo->buf), ctxIo->bufSize); + ctxRecv.data = hUSB; + ctxRecv.bufSize = readMaxWanted; + ctxRecv.req = {}; + uv_fs_t *req = &ctxRecv.req; + req->data = &ctxRecv; + iov = uv_buf_init(reinterpret_cast(ctxRecv.buf), ctxRecv.bufSize); ret = uv_fs_read(&daemon->loopMain, req, hUSB->bulkOut, &iov, 1, -1, OnUSBRead); if (ret < 0) { WRITE_LOG(LOG_FATAL, "uv_fs_read < 0"); - goto FAILED; - } - ++this->ref; - return 0; -FAILED: - if (ctxIo != nullptr) { - delete ctxIo; - } - if (buf != nullptr) { - delete[] buf; + return ERR_API_FAIL; } - return ERR_GENERIC; + ctxRecv.atPollQueue = true; + return RET_SUCCESS; } // Because USB can connect to only one host,daemonUSB is only one Session by default @@ -517,16 +511,18 @@ void HdcDaemonUSB::WatchEPTimer(uv_timer_t *handle) HdcDaemonUSB *thisClass = (HdcDaemonUSB *)handle->data; HUSB hUSB = &thisClass->usbHandle; HdcDaemon *daemon = reinterpret_cast(thisClass->clsMainBase); - if (thisClass->isAlive || thisClass->ref > 0) { + if (thisClass->isAlive || thisClass->ctxRecv.atPollQueue) { return; } bool resetEp = false; do { if (hUSB->bulkIn > 0) { + WRITE_LOG(LOG_DEBUG, "Watchdog close bulkin"); thisClass->CloseBulkEp(true, thisClass->usbHandle.bulkIn, &daemon->loopMain); resetEp = true; } if (hUSB->bulkOut > 0) { + WRITE_LOG(LOG_DEBUG, "Watchdog close bulkout"); thisClass->CloseBulkEp(false, thisClass->usbHandle.bulkOut, &daemon->loopMain); resetEp = true; } diff --git a/src/daemon/daemon_usb.h b/src/daemon/daemon_usb.h index a09cfd3d..3613c9e7 100644 --- a/src/daemon/daemon_usb.h +++ b/src/daemon/daemon_usb.h @@ -25,13 +25,17 @@ public: void Stop(); int SendUSBRaw(HSession hSession, uint8_t *data, const int length); void OnNewHandshakeOK(const uint32_t sessionId); + void OnSessionFreeFinally(const HSession hSession); private: struct CtxUvFileCommonIo { + void *thisClass; uv_fs_t req; uint8_t *buf; + int bufSizeMax; + // dynamic below + bool atPollQueue; int bufSize; - void *thisClass; void *data; }; static void OnUSBRead(uv_fs_t *req); @@ -55,12 +59,11 @@ private: HdcUSB usbHandle; string basePath; // usb device's base path uint32_t currentSessionId = 0; // USB mode,limit only one session - std::atomic ref = 0; - uv_timer_t checkEP; // server-use + uv_timer_t checkEP; // server-use uv_mutex_t sendEP; bool isAlive = false; int controlEp = 0; // EP0 - int toReadUsbDataSize; + CtxUvFileCommonIo ctxRecv = {}; }; } // namespace Hdc #endif \ No newline at end of file diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 68e0e271..8773b770 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -93,13 +93,14 @@ void HdcHostUSB::SendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) WRITE_LOG(LOG_DEBUG, "Device reset singal send"); }; libusb_transfer *transferUsb = libusb_alloc_transfer(0); + ++hSession->ref; libusb_fill_bulk_transfer(transferUsb, hUSB->devHandle, hUSB->epHost, (uint8_t *)&usbPayloadHeader, sizeof(USBHead), resetUsbCallback, ctxReset, GLOBAL_TIMEOUT * TIME_BASE); int err = libusb_submit_transfer(transferUsb); - --hSession->ref; if (err < 0) { WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", err); delete ctxReset; + --hSession->ref; } else { hUSB->sendIOComplete = false; } @@ -328,12 +329,16 @@ int HdcHostUSB::CheckActiveConfig(libusb_device *device, HUSB hUSB) return ret; } -void HdcHostUSB::CancelUsbLoopRead(HUSB hUSB) +// multi-thread calll +void HdcHostUSB::CancelUsbLoopRead(HSession hSession) { + HUSB hUSB = hSession->hUSB; + hUSB->lockTransferRecv.lock(); if (hUSB->transferRecv != nullptr && !hUSB->recvIOComplete) { + WRITE_LOG(LOG_DEBUG, "HostUSB CancelUsbLoopRead, ref:%u", uint32_t(hSession->ref)); libusb_cancel_transfer(hUSB->transferRecv); - hUSB->recvIOComplete = true; } + hUSB->lockTransferRecv.unlock(); } // 3rd write child-hdc-workthread @@ -390,12 +395,14 @@ void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfe bool bOK = false; int childRet = 0; constexpr int infinity = 0; // ignore timeout - + hUSB->lockTransferRecv.lock(); while (true) { - if (!thisClass->modRunning || (hSession->isDead && 0 == hSession->ref)) + if (!thisClass->modRunning || hUSB->recvIOComplete) { + WRITE_LOG(LOG_WARN, "Hostusb read break"); break; + } if (LIBUSB_TRANSFER_COMPLETED != transfer->status) { - WRITE_LOG(LOG_FATAL, "Host usb not LIBUSB_TRANSFER_COMPLETED, status:%d", transfer->status); + WRITE_LOG(LOG_FATAL, "Hostusb not LIBUSB_TRANSFER_COMPLETED, status:%d", transfer->status); break; } childRet @@ -419,6 +426,7 @@ void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfe WRITE_LOG(LOG_WARN, "ReadUSBBulkCallback failed"); } --hSession->ref; // until function finsh, dec ref + hUSB->lockTransferRecv.unlock(); } void HdcHostUSB::RegisterReadCallback(HSession hSession) @@ -481,6 +489,7 @@ int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) ret = length; } while (false); if (ret < 0) { + CancelUsbLoopRead(hSession); hSession->hUSB->sendIOComplete = true; server->FreeSession(hSession->sessionId); } @@ -542,9 +551,13 @@ void HdcHostUSB::SessionUsbWorkThread(void *arg) { HSession hSession = (HSession)arg; constexpr uint8_t USB_HANDLE_TIMEOUT = DEVICE_CHECK_INTERVAL / TIME_BASE; + constexpr uint8_t USB_SESSION_IDLE_COMMMON_REFERENCE = 2; WRITE_LOG(LOG_DEBUG, "SessionUsbWorkThread work thread:%p", uv_thread_self()); // run until all USB callback finish(ref == 1, I'm the only one left) while (!hSession->isDead || hSession->ref > 1) { + if (hSession->ref != USB_SESSION_IDLE_COMMMON_REFERENCE) { + WRITE_LOG(LOG_DEBUG, "Session usb workthread session-ref:%u", uint32_t(hSession->ref)); + } struct timeval zerotime; zerotime.tv_sec = USB_HANDLE_TIMEOUT; zerotime.tv_usec = 0; // if == 0,windows will be high CPU load diff --git a/src/host/host_usb.h b/src/host/host_usb.h index e32c6191..915ab2e8 100644 --- a/src/host/host_usb.h +++ b/src/host/host_usb.h @@ -53,7 +53,7 @@ private: void UpdateUSBDaemonInfo(HUSB hUSB, HSession hSession, uint8_t connStatus); void RegisterReadCallback(HSession hSession); void ReviewUsbNodeLater(string &nodeKey); - void CancelUsbLoopRead(HUSB hUSB); + void CancelUsbLoopRead(HSession hSession); int UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int dataSize); libusb_context *ctxUSB; diff --git a/src/host/server.cpp b/src/host/server.cpp index bf8b7365..1a8240cf 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -747,6 +747,7 @@ bool HdcServer::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uin case CMD_FORWARD_CHECK: case CMD_FORWARD_CHECK_RESULT: case CMD_FORWARD_ACTIVE_MASTER: + case CMD_FORWARD_ACTIVE_SLAVE: case CMD_FORWARD_DATA: case CMD_FORWARD_FREE_CONTEXT: ret = TaskCommandDispatch(hTaskInfo, TASK_FORWARD, command, payload, payloadSize); -- Gitee From 36308c54ef4183c2433ebbc4e1bd7a845b7ec858 Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 16 Dec 2021 22:14:39 +0800 Subject: [PATCH 33/50] make ci happy Signed-off-by: zako --- src/daemon/daemon.cpp | 3 ++- src/daemon/jdwp.cpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index fd95f3e7..8ae606bf 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -301,8 +301,9 @@ void HdcDaemon::JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO) void HdcDaemon::NotifyInstanceSessionFree(HSession hSession, bool freeOrClear) { - if (!freeOrClear) + if (!freeOrClear) { return; // ignore step 1 + } if (clsUSBServ != nullptr) { auto clsUsbModule = reinterpret_cast(clsUSBServ); clsUsbModule->OnSessionFreeFinally(hSession); diff --git a/src/daemon/jdwp.cpp b/src/daemon/jdwp.cpp index c39d4972..4ad42503 100644 --- a/src/daemon/jdwp.cpp +++ b/src/daemon/jdwp.cpp @@ -23,6 +23,8 @@ HdcJdwp::HdcJdwp(uv_loop_t *loopIn) listenPipe.data = this; loop = loopIn; refCount = 0; + awakenPollFd = 0; + stop = false; uv_rwlock_init(&lockMapContext); uv_rwlock_init(&lockJdwpTrack); } -- Gitee From f3eb5cf83c74e513140c93f388de19b798309980 Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 16 Dec 2021 22:17:05 +0800 Subject: [PATCH 34/50] remove debug Signed-off-by: zako --- src/common/session.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/common/session.cpp b/src/common/session.cpp index 307ff195..aa8eb2ff 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -707,11 +707,6 @@ int HdcSessionBase::DecryptPayload(HSession hSession, PayloadHead *payloadHeadBe WRITE_LOG(LOG_FATAL, "Session recv CalcCheckSum failed"); return ERR_BUF_CHECK; } - //++debug - if (!memcmp(data, "id", 2)) { - WRITE_LOG(LOG_FATAL, "Test command recv"); - return ERR_GENERIC; - } if (!FetchCommand(hSession, protectBuf.channelId, protectBuf.commandFlag, data, dataSize)) { WRITE_LOG(LOG_WARN, "FetchCommand failed"); return ERR_GENERIC; -- Gitee From 4fed3fe8db7eec0b7349fff34b2ea16c09bcf688 Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 16 Dec 2021 23:51:24 +0800 Subject: [PATCH 35/50] depend and jdwp Signed-off-by: zako --- BUILD.gn | 2 +- src/common/common.h | 1 - src/daemon/daemon_common.h | 1 + src/daemon/jdwp.cpp | 2 +- src/daemon/jdwp.h | 31 ++++++++++++------------ src/{common => daemon}/system_depend.cpp | 0 src/{common => daemon}/system_depend.h | 2 +- 7 files changed, 20 insertions(+), 19 deletions(-) rename src/{common => daemon}/system_depend.cpp (100%) rename src/{common => daemon}/system_depend.h (97%) diff --git a/BUILD.gn b/BUILD.gn index 3f74addf..513bc6a3 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -31,7 +31,6 @@ hdc_common_sources = [ "${HDC_PATH}/src/common/tcp.cpp", "${HDC_PATH}/src/common/transfer.cpp", "${HDC_PATH}/src/common/usb.cpp", - "${HDC_PATH}/src/common/system_depend.cpp", ] config("hdc_config") { @@ -50,6 +49,7 @@ ohos_executable("hdcd") { "src/daemon/jdwp.cpp", "src/daemon/main.cpp", "src/daemon/shell.cpp", + "src/daemon/system_depend.cpp", ] sources += hdc_common_sources diff --git a/src/common/common.h b/src/common/common.h index 81696a78..b2f6a2e6 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -74,7 +74,6 @@ using std::vector; #include "tcp.h" #include "usb.h" #include "file_descriptor.h" -#include "system_depend.h" // clang-format on diff --git a/src/daemon/daemon_common.h b/src/daemon/daemon_common.h index f001d9fa..88e32253 100644 --- a/src/daemon/daemon_common.h +++ b/src/daemon/daemon_common.h @@ -32,6 +32,7 @@ #include "daemon_usb.h" #include "daemon_forward.h" #include "shell.h" +#include "system_depend.h" #endif // clang-format on diff --git a/src/daemon/jdwp.cpp b/src/daemon/jdwp.cpp index 4ad42503..c1800910 100644 --- a/src/daemon/jdwp.cpp +++ b/src/daemon/jdwp.cpp @@ -117,7 +117,7 @@ void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) } else { // JS:pid PkgName #ifdef JS_JDWP_CONNECT struct JsMsgHeader *jsMsg = (struct JsMsgHeader *)p; - if (jsMsg->msgLen == nread) { + if (jsMsg->msgLen == static_cast(nread)) { pid = jsMsg->pid; string pkgName = string((char *)p + sizeof(JsMsgHeader), jsMsg->msgLen - sizeof(JsMsgHeader)); ctxJdwp->pkgName = pkgName; diff --git a/src/daemon/jdwp.h b/src/daemon/jdwp.h index f4d56dca..6afeda74 100644 --- a/src/daemon/jdwp.h +++ b/src/daemon/jdwp.h @@ -32,6 +32,19 @@ public: bool CheckPIDExist(uint32_t targetPID); private: + static constexpr uint8_t JS_PKG_MX_SIZE = 135; + static constexpr uint8_t JS_PKG_MIN_SIZE = 15; // JsMsgHeader + "pkgName:"uint8_t[7~127] + +#ifdef JS_JDWP_CONNECT + struct JsMsgHeader { + uint32_t msgLen; + uint32_t pid; + }; + string GetProcessListExtendPkgName(); + static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024 * 4; +#else + static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024; +#endif // JS_JDWP_CONNECT struct _PollFd { int fd; short events; @@ -54,27 +67,15 @@ private: uv_pipe_t pipe; HdcJdwp *thisClass; bool finish; + uint8_t dummy; + uv_tcp_t jvmTCP; + string pkgName; #ifdef JS_JDWP_CONNECT char buf[JS_PKG_MX_SIZE]; - string pkgName; #else char buf[sizeof(uint32_t)]; #endif // JS_JDWP_CONNECT - uint8_t dummy; - uv_tcp_t jvmTCP; - }; -#ifdef JS_JDWP_CONNECT - struct JsMsgHeader { - uint32_t msgLen; - uint32_t pid; }; - static constexpr uint8_t JS_PKG_MIN_SIZE = 15; // JsMsgHeader + "pkgName:"uint8_t[7~127] - static constexpr uint8_t JS_PKG_MX_SIZE = 135; - static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024 * 4; - string GetProcessListExtendPkgName(); -#else - static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024; -#endif // JS_JDWP_CONNECT using HCtxJdwp = struct ContextJdwp *; bool JdwpListen(); diff --git a/src/common/system_depend.cpp b/src/daemon/system_depend.cpp similarity index 100% rename from src/common/system_depend.cpp rename to src/daemon/system_depend.cpp diff --git a/src/common/system_depend.h b/src/daemon/system_depend.h similarity index 97% rename from src/common/system_depend.h rename to src/daemon/system_depend.h index 732fb8c8..7f84a8e1 100644 --- a/src/common/system_depend.h +++ b/src/daemon/system_depend.h @@ -14,7 +14,7 @@ */ #ifndef HDC_SYSTEM_DEPEND_H #define HDC_SYSTEM_DEPEND_H -#include "common.h" +#include "../common/base.h" namespace Hdc { namespace SystemDepend { -- Gitee From e7f7a1128954d93d46100d722cdedacd1cb0d833 Mon Sep 17 00:00:00 2001 From: zako Date: Fri, 17 Dec 2021 12:55:00 +0800 Subject: [PATCH 36/50] ci depend Signed-off-by: zako --- src/common/async_cmd.h | 4 ++-- src/common/base.h | 11 +++++++++++ src/common/define_plus.h | 3 +++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/common/async_cmd.h b/src/common/async_cmd.h index d585c670..9b05dd8c 100644 --- a/src/common/async_cmd.h +++ b/src/common/async_cmd.h @@ -24,12 +24,12 @@ public: enum AsyncCmdOption { OPTION_COMMAND_ONETIME = 1, USB_OPTION_RESERVE2 = 2, - OPTION_READBACK_OUT = 4, // PS: Not used, remove it later + OPTION_READBACK_OUT = 4, // deprecated, remove it later USB_OPTION_RESERVE8 = 8, }; // 1)is finish 2)exitStatus 3)resultString(maybe empty) using CmdResultCallback = std::function; - // PS: Not used, remove it later + // deprecated, remove it later static uint32_t GetDefaultOption() { return OPTION_COMMAND_ONETIME; diff --git a/src/common/base.h b/src/common/base.h index 487fda05..8b30adc2 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -147,6 +147,17 @@ namespace Base { { return MAX_USBFFS_BULK; } + + // deprecated, remove later + inline bool SetHdcProperty(const char *key, const char *value) + { + return false; + } + // deprecated, remove later + inline bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf) + { + return false; + } } // namespace base } // namespace Hdc diff --git a/src/common/define_plus.h b/src/common/define_plus.h index 27350091..dfd9c628 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -158,6 +158,9 @@ enum HdcCommand { CMD_APP_DATA, CMD_APP_FINISH, CMD_APP_UNINSTALL, + + // deprecated, remove later + CMD_UNITY_JPID, }; enum UsbProtocolOption { -- Gitee From aaa2af94b053cd1900a7c02278482e818d12b186 Mon Sep 17 00:00:00 2001 From: zako Date: Fri, 17 Dec 2021 13:32:11 +0800 Subject: [PATCH 37/50] ci depend2 Signed-off-by: zako --- src/common/session.h | 4 +--- src/daemon/system_depend.cpp | 1 + src/daemon/system_depend.h | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/common/session.h b/src/common/session.h index 440cb84f..c8684ded 100644 --- a/src/common/session.h +++ b/src/common/session.h @@ -47,14 +47,12 @@ public: virtual ~HdcSessionBase(); virtual void AttachChannel(HSession hSession, const uint32_t channelId) {}; virtual void DeatchChannel(HSession hSession, const uint32_t channelId) {}; + virtual void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear) {}; virtual bool RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, const int payloadSize) { return true; } - virtual void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear) - { - } // Thread security interface for global stop programs void PostStopInstanceMessage(bool restart = false); void ReMainLoopForInstanceClear(); diff --git a/src/daemon/system_depend.cpp b/src/daemon/system_depend.cpp index 6d23c264..73c6d85c 100644 --- a/src/daemon/system_depend.cpp +++ b/src/daemon/system_depend.cpp @@ -25,6 +25,7 @@ envirments ############ */ #include "system_depend.h" +#include "../common/base.h" #if defined __MUSL__ && defined HARMONY_PROJECT extern "C" { #include "init_reboot.h" diff --git a/src/daemon/system_depend.h b/src/daemon/system_depend.h index 7f84a8e1..15666b18 100644 --- a/src/daemon/system_depend.h +++ b/src/daemon/system_depend.h @@ -14,7 +14,7 @@ */ #ifndef HDC_SYSTEM_DEPEND_H #define HDC_SYSTEM_DEPEND_H -#include "../common/base.h" +#include "daemon_common.h" namespace Hdc { namespace SystemDepend { -- Gitee From 078d5c5f7bc5403a3814441a9e74feda59d41e76 Mon Sep 17 00:00:00 2001 From: zako Date: Fri, 17 Dec 2021 15:30:22 +0800 Subject: [PATCH 38/50] ci depend Signed-off-by: zako --- src/common/base.h | 17 ++++++++++++++++- src/daemon/daemon.h | 5 +++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/common/base.h b/src/common/base.h index 8b30adc2..0c736d44 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -147,7 +147,7 @@ namespace Base { { return MAX_USBFFS_BULK; } - +#ifdef HDC_SUPPORT_FLASHD // deprecated, remove later inline bool SetHdcProperty(const char *key, const char *value) { @@ -158,7 +158,22 @@ namespace Base { { return false; } +#endif } // namespace base + +#ifdef HDC_SUPPORT_FLASHD + // deprecated, remove later +namespace SystemDepend { + inline bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf) + { + return false; + }; + inline bool SetHdcProperty(const char *key, const char *value) + { + return false; + }; +} // namespace SystemDepend +#endif } // namespace Hdc #endif // HDC_BASE_H diff --git a/src/daemon/daemon.h b/src/daemon/daemon.h index c5576d30..73c75995 100644 --- a/src/daemon/daemon.h +++ b/src/daemon/daemon.h @@ -39,7 +39,12 @@ private: void ClearInstanceResource(); bool DaemonSessionHandshake(HSession hSession, const uint32_t channelId, uint8_t *payload, int payloadSize); void TryStopInstance(); +// deprecated, remove later +#ifdef HDC_SUPPORT_FLASHD +// null +#else void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear); +#endif bool enableSecure; }; -- Gitee From b14cded1be018f60e10e645eef6f4e9c708d9bfc Mon Sep 17 00:00:00 2001 From: zako Date: Sat, 18 Dec 2021 02:09:41 +0800 Subject: [PATCH 39/50] PR RFC Signed-off-by: zako --- src/common/base.cpp | 14 ++-------- src/common/base.h | 14 ---------- src/common/define.h | 1 + src/common/define_plus.h | 2 +- src/common/session.cpp | 2 +- src/common/session.h | 12 ++++++-- src/daemon/daemon.cpp | 7 ++--- src/daemon/daemon_common.h | 4 +-- src/daemon/daemon_tcp.cpp | 7 ++--- src/daemon/daemon_unity.cpp | 10 +++---- src/daemon/daemon_usb.cpp | 2 +- src/daemon/jdwp.cpp | 50 ++++++++++++++++++++------------- src/daemon/jdwp.h | 41 +++++++++++++-------------- src/daemon/main.cpp | 11 +++----- src/daemon/system_depend.cpp | 54 +++++++++++++++++++++++------------- src/daemon/system_depend.h | 16 +++++++++-- src/host/host_usb.cpp | 8 +++--- 17 files changed, 133 insertions(+), 122 deletions(-) diff --git a/src/common/base.cpp b/src/common/base.cpp index ce1a1ec0..c8ec9f75 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -191,7 +191,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() * 10; + int bufMaxSize = HDC_SOCKETPAIR_SIZE; uv_recv_buffer_size((uv_handle_t *)tcpHandle, &bufMaxSize); uv_send_buffer_size((uv_handle_t *)tcpHandle, &bufMaxSize); } @@ -1156,16 +1156,6 @@ namespace Base { return ret; } - int open_osfhandle(uv_os_fd_t os_fd) - { - // equal libuv's uv_open_osfhandle, libuv 1.23 added. old libuv not impl... -#ifdef _WIN32 - return _open_osfhandle((intptr_t)os_fd, 0); -#else - return os_fd; -#endif - } - uv_os_sock_t DuplicateUvSocket(uv_tcp_t *tcp) { uv_os_sock_t dupFd = -1; @@ -1181,7 +1171,7 @@ namespace Base { if (uv_fileno((const uv_handle_t *)tcp, &fdOs) < 0) { return ERR_API_FAIL; } - dupFd = dup(open_osfhandle(fdOs)); + dupFd = dup(uv_open_osfhandle(fdOs)); #endif return dupFd; } diff --git a/src/common/base.h b/src/common/base.h index 0c736d44..b1575918 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -160,20 +160,6 @@ namespace Base { } #endif } // namespace base - -#ifdef HDC_SUPPORT_FLASHD - // deprecated, remove later -namespace SystemDepend { - inline bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf) - { - return false; - }; - inline bool SetHdcProperty(const char *key, const char *value) - { - return false; - }; -} // namespace SystemDepend -#endif } // namespace Hdc #endif // HDC_BASE_H diff --git a/src/common/define.h b/src/common/define.h index 4e4dafa5..b58b3fcc 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -50,6 +50,7 @@ constexpr uint16_t MAX_USBFFS_BULK = 16384; // 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 = INT_MAX; +constexpr uint32_t HDC_SOCKETPAIR_SIZE = MAX_SIZE_IOBUF * 10; const string WHITE_SPACES = " \t\n\r"; const string UT_TMP_PATH = "/tmp/hdc-ut"; diff --git a/src/common/define_plus.h b/src/common/define_plus.h index dfd9c628..4f568c88 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -160,7 +160,7 @@ enum HdcCommand { CMD_APP_UNINSTALL, // deprecated, remove later - CMD_UNITY_JPID, + CMD_UNITY_JPID = CMD_JDWP_LIST, }; enum UsbProtocolOption { diff --git a/src/common/session.cpp b/src/common/session.cpp index aa8eb2ff..d4617a19 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -785,7 +785,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) { HSession context = (HSession)handle->data; - Base::ReallocBuf(&context->ioBuf, &context->bufSize, Base::GetMaxBufSize() * 10); + Base::ReallocBuf(&context->ioBuf, &context->bufSize, HDC_SOCKETPAIR_SIZE); buf->base = (char *)context->ioBuf + context->availTailIndex; int size = context->bufSize - context->availTailIndex; buf->len = std::min(size, static_cast(sizeWanted)); diff --git a/src/common/session.h b/src/common/session.h index c8684ded..8fdd2a5e 100644 --- a/src/common/session.h +++ b/src/common/session.h @@ -45,9 +45,15 @@ public: HdcSessionBase(bool serverOrDaemonIn); virtual ~HdcSessionBase(); - virtual void AttachChannel(HSession hSession, const uint32_t channelId) {}; - virtual void DeatchChannel(HSession hSession, const uint32_t channelId) {}; - virtual void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear) {}; + virtual void AttachChannel(HSession hSession, const uint32_t channelId) + { + } + virtual void DeatchChannel(HSession hSession, const uint32_t channelId) + { + } + virtual void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear) + { + } virtual bool RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, const int payloadSize) { diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 8ae606bf..f7132007 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -80,14 +80,11 @@ void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB) clsUSBServ = new HdcDaemonUSB(false, this); ((HdcDaemonUSB *)clsUSBServ)->Initial(); } - clsJdwp = new HdcJdwp(&loopMain); ((HdcJdwp *)clsJdwp)->Initial(); - // enable security - char value[4] = "0"; - SystemDepend::GetHdcProperty("ro.hdc.secure", value, sizeof(value)); - string secure = value; + string secure; + SystemDepend::GetProperty("ro.hdc.secure", secure); enableSecure = (Base::Trim(secure) == "1"); } diff --git a/src/daemon/daemon_common.h b/src/daemon/daemon_common.h index 88e32253..b96e2b38 100644 --- a/src/daemon/daemon_common.h +++ b/src/daemon/daemon_common.h @@ -23,7 +23,8 @@ #include "../common/async_cmd.h" #include "../common/serial_struct.h" -#ifndef HDC_HOST //daemon used +#ifndef HDC_HOST // daemon used +#include "system_depend.h" #include "jdwp.h" #include "daemon.h" #include "daemon_unity.h" @@ -32,7 +33,6 @@ #include "daemon_usb.h" #include "daemon_forward.h" #include "shell.h" -#include "system_depend.h" #endif // clang-format on diff --git a/src/daemon/daemon_tcp.cpp b/src/daemon/daemon_tcp.cpp index acb4caf9..c5569d4d 100644 --- a/src/daemon/daemon_tcp.cpp +++ b/src/daemon/daemon_tcp.cpp @@ -19,10 +19,9 @@ HdcDaemonTCP::HdcDaemonTCP(const bool serverOrDaemonIn, void *ptrMainBase) : HdcTCPBase(serverOrDaemonIn, ptrMainBase) { // If the listening value for the property setting is obtained, it will be 0 randomly assigned. - char strTCPPort[BUF_SIZE_TINY] = ""; - const uint16_t BUFF_SIZE = 8; - SystemDepend::GetHdcProperty("persist.hdc.port", strTCPPort, BUFF_SIZE); - tcpListenPort = atoi(strTCPPort); + string strTCPPort; + SystemDepend::GetProperty("persist.hdc.port", strTCPPort); + tcpListenPort = atoi(strTCPPort.c_str()); if (tcpListenPort <= 0) { tcpListenPort = 0; } diff --git a/src/daemon/daemon_unity.cpp b/src/daemon/daemon_unity.cpp index d2992920..bba9eed8 100644 --- a/src/daemon/daemon_unity.cpp +++ b/src/daemon/daemon_unity.cpp @@ -179,12 +179,12 @@ bool HdcDaemonUnity::SetDeviceRunMode(void *daemonIn, const char *cmd) HdcDaemon *daemon = (HdcDaemon *)daemonIn; WRITE_LOG(LOG_DEBUG, "Set run mode:%s", cmd); if (!strcmp(CMDSTR_TMODE_USB.c_str(), cmd)) { - SystemDepend::SetHdcProperty("persist.hdc.mode", CMDSTR_TMODE_USB.c_str()); + SystemDepend::SetProperty("persist.hdc.mode", CMDSTR_TMODE_USB.c_str()); } else if (!strncmp("port", cmd, strlen("port"))) { - SystemDepend::SetHdcProperty("persist.hdc.mode", CMDSTR_TMODE_TCP.c_str()); + SystemDepend::SetProperty("persist.hdc.mode", CMDSTR_TMODE_TCP.c_str()); if (!strncmp("port ", cmd, strlen("port "))) { const char *port = cmd + 5; - SystemDepend::SetHdcProperty("persist.hdc.port", port); + SystemDepend::SetProperty("persist.hdc.port", port); } } else { LogMsg(MSG_FAIL, "Unknow command"); @@ -263,9 +263,9 @@ bool HdcDaemonUnity::CommandDispatch(const uint16_t command, uint8_t *payload, c case CMD_UNITY_ROOTRUN: { ret = false; if (payloadSize != 0 && !strcmp((char *)strPayload.c_str(), "r")) { - SystemDepend::SetHdcProperty("persist.hdc.root", "0"); + SystemDepend::SetProperty("persist.hdc.root", "0"); } else { - SystemDepend::SetHdcProperty("persist.hdc.root", "1"); + SystemDepend::SetProperty("persist.hdc.root", "1"); } daemon->PostStopInstanceMessage(true); break; diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 290796d1..74d56e57 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -168,7 +168,7 @@ int HdcDaemonUSB::ConnectEPPoint(HUSB hUSB) break; } // active usbrc,Send USB initialization singal - SystemDepend::SetHdcProperty("sys.usb.ffs.ready", "1"); + SystemDepend::SetProperty("sys.usb.ffs.ready", "1"); WRITE_LOG(LOG_DEBUG, "ConnectEPPoint ctrl init finish, set usb-ffs ready"); } string outPath = basePath + "/ep1"; diff --git a/src/daemon/jdwp.cpp b/src/daemon/jdwp.cpp index c1800910..8e8d0089 100644 --- a/src/daemon/jdwp.cpp +++ b/src/daemon/jdwp.cpp @@ -13,18 +13,22 @@ * limitations under the License. */ #include "jdwp.h" -#include #include +#include namespace Hdc { +#ifdef JS_JDWP_CONNECT +static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024 * 4; +#else +static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024; +#endif // JS_JDWP_CONNECT + HdcJdwp::HdcJdwp(uv_loop_t *loopIn) { Base::ZeroStruct(listenPipe); listenPipe.data = this; loop = loopIn; refCount = 0; - awakenPollFd = 0; - stop = false; uv_rwlock_init(&lockMapContext); uv_rwlock_init(&lockJdwpTrack); } @@ -93,7 +97,7 @@ void HdcJdwp::FreeContext(HCtxJdwp ctx) void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) { bool ret = true; - if (nread == UV_ENOBUFS) { // It is definite enough, usually only 4 bytes + 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) { @@ -101,8 +105,8 @@ void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) #ifdef JS_JDWP_CONNECT } else if (nread < 0 || nread < JS_PKG_MIN_SIZE) { #else - } else if (nread < 0 || nread != 4) { // 4 : 4 bytes -#endif // JS_JDWP_CONNECT + } else if (nread < 0 || nread != 4) { // 4 : 4 bytes +#endif // JS_JDWP_CONNECT ret = false; WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream invalid package nread:%d.", nread); } @@ -112,20 +116,22 @@ void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) if (ret) { uint32_t pid = 0; char *p = ctxJdwp->buf; - if (nread == sizeof(uint32_t)) { // Java: pid + if (nread == sizeof(uint32_t)) { // Java: pid pid = atoi(p); - } else { // JS:pid PkgName + } else { // JS:pid PkgName #ifdef JS_JDWP_CONNECT struct JsMsgHeader *jsMsg = (struct JsMsgHeader *)p; - if (jsMsg->msgLen == static_cast(nread)) { + if (jsMsg->msgLen == nread) { pid = jsMsg->pid; - string pkgName = string((char *)p + sizeof(JsMsgHeader), jsMsg->msgLen - sizeof(JsMsgHeader)); + string pkgName = + string((char *)p + sizeof(JsMsgHeader), jsMsg->msgLen - sizeof(JsMsgHeader)); ctxJdwp->pkgName = pkgName; } else { ret = false; - WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream invalid js package size %d:%d.", jsMsg->msgLen, nread); + WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream invalid js package size %d:%d.", + jsMsg->msgLen, nread); } -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT } if (pid > 0) { ctxJdwp->pid = pid; @@ -133,7 +139,7 @@ void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) WRITE_LOG(LOG_DEBUG, "JDWP accept pid:%d-pkg:%s", pid, ctxJdwp->pkgName.c_str()); #else WRITE_LOG(LOG_DEBUG, "JDWP accept pid:%d", pid); -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT thisClass->AdminContext(OP_ADD, pid, ctxJdwp); ret = true; int fd = -1; @@ -163,7 +169,7 @@ string HdcJdwp::GetProcessListExtendPkgName() uv_rwlock_rdunlock(&lockMapContext); return ret; } -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT void HdcJdwp::AcceptClient(uv_stream_t *server, int status) { @@ -181,7 +187,7 @@ 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; + buf->base = (char *)ctxJdwp->buf ; buf->len = sizeof(ctxJdwp->buf); }; uv_read_start((uv_stream_t *)&ctxJdwp->pipe, funAlloc, ReadStream); @@ -339,7 +345,7 @@ size_t HdcJdwp::JdwpProcessListMsg(char *buffer, size_t bufferlen) string result = GetProcessListExtendPkgName(); #else string result = GetProcessList(); -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT size_t len = result.length(); if (bufferlen < (len + headerLen)) { @@ -375,7 +381,8 @@ void HdcJdwp::ProcessListUpdated(void) data.resize(len); for (auto &t : jdwpTrackers) { if (t->taskStop || t->taskFree || !t->taskClass) { - jdwpTrackers.erase(remove(jdwpTrackers.begin(), jdwpTrackers.end(), t), jdwpTrackers.end()); + jdwpTrackers.erase(remove(jdwpTrackers.begin(), jdwpTrackers.end(), t), + jdwpTrackers.end()); } else { void *clsSession = t->ownerSessionClass; HdcSessionBase *sessionBase = reinterpret_cast(clsSession); @@ -399,7 +406,8 @@ void HdcJdwp::DrainAwakenPollThread() const uint64_t value = 0; ssize_t retVal = read(awakenPollFd, &value, sizeof(value)); if (retVal < 0) { - WRITE_LOG(LOG_FATAL, "DrainAwakenPollThread: Failed to read data from awaken pipe %d", retVal); + WRITE_LOG(LOG_FATAL, "DrainAwakenPollThread: Failed to read data from awaken pipe %d", + retVal); } } @@ -439,11 +447,13 @@ void *HdcJdwp::FdEventPollThread(void *args) } poll(&pollfds[0], size, -1); for (const auto &pollfdsing : pollfds) { - if (pollfdsing.revents & (POLLNVAL | POLLRDHUP | POLLHUP | POLLERR)) { // POLLNVAL:fd not open + if (pollfdsing.revents & + (POLLNVAL | POLLRDHUP | POLLHUP | POLLERR)) { // POLLNVAL:fd not open auto it = thisClass->pollNodeMap.find(pollfdsing.fd); if (it != thisClass->pollNodeMap.end()) { uint32_t targetPID = it->second.ppid; - HCtxJdwp ctx = (HCtxJdwp)(thisClass->AdminContext(OP_QUERY, targetPID, nullptr)); + HCtxJdwp ctx = + (HCtxJdwp)(thisClass->AdminContext(OP_QUERY, targetPID, nullptr)); if (ctx != nullptr) { WRITE_LOG(LOG_INFO, "FreeContext for targetPID :%d", targetPID); uv_read_stop((uv_stream_t *)&ctx->pipe); diff --git a/src/daemon/jdwp.h b/src/daemon/jdwp.h index 6afeda74..3b9adea2 100644 --- a/src/daemon/jdwp.h +++ b/src/daemon/jdwp.h @@ -25,26 +25,16 @@ public: virtual ~HdcJdwp(); int Initial(); void Stop(); - bool CreateJdwpTracker(HTaskInfo hTaskInfo); + bool CreateJdwpTracker(HTaskInfo hTaskInfo) ; bool ReadyForRelease(); string GetProcessList(); bool SendJdwpNewFD(uint32_t targetPID, int fd); bool CheckPIDExist(uint32_t targetPID); - -private: - static constexpr uint8_t JS_PKG_MX_SIZE = 135; - static constexpr uint8_t JS_PKG_MIN_SIZE = 15; // JsMsgHeader + "pkgName:"uint8_t[7~127] - #ifdef JS_JDWP_CONNECT - struct JsMsgHeader { - uint32_t msgLen; - uint32_t pid; - }; - string GetProcessListExtendPkgName(); - static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024 * 4; -#else - static constexpr uint32_t JPID_TRACK_LIST_SIZE = 1024; -#endif // JS_JDWP_CONNECT + static constexpr uint8_t JS_PKG_MIN_SIZE = 15; // JsMsgHeader + "pkgName:"uint8_t[7~127] + static constexpr uint8_t JS_PKG_MX_SIZE = 135; +#endif // JS_JDWP_CONNECT +private: struct _PollFd { int fd; short events; @@ -62,19 +52,25 @@ private: ppid = pid; } }; +#ifdef JS_JDWP_CONNECT + struct JsMsgHeader { + uint32_t msgLen; + uint32_t pid; + }; +#endif // JS_JDWP_CONNECT struct ContextJdwp { uint32_t pid; uv_pipe_t pipe; HdcJdwp *thisClass; bool finish; - uint8_t dummy; - uv_tcp_t jvmTCP; - string pkgName; #ifdef JS_JDWP_CONNECT char buf[JS_PKG_MX_SIZE]; + string pkgName; #else char buf[sizeof(uint32_t)]; -#endif // JS_JDWP_CONNECT +#endif // JS_JDWP_CONNECT + uint8_t dummy; + uv_tcp_t jvmTCP; }; using HCtxJdwp = struct ContextJdwp *; @@ -84,11 +80,14 @@ private: static void SendCallbackJdwpNewFD(uv_write_t *req, int status); static void *FdEventPollThread(void *args); size_t JdwpProcessListMsg(char *buffer, size_t bufferlen); +#ifdef JS_JDWP_CONNECT + string GetProcessListExtendPkgName(); +#endif // JS_JDWP_CONNECT void *MallocContext(); void FreeContext(HCtxJdwp ctx); void *AdminContext(const uint8_t op, const uint32_t pid, HCtxJdwp ctxJdwp); int CreateFdEventPoll(); - void ProcessListUpdated(void); + void ProcessListUpdated(void) ; void DrainAwakenPollThread() const; void WakePollThread(); @@ -99,7 +98,7 @@ private: map mapCtxJdwp; uv_rwlock_t lockMapContext; uv_rwlock_t lockJdwpTrack; - std::unordered_map pollNodeMap; // fd, PollNode + std::unordered_map pollNodeMap; // fd, PollNode std::vector jdwpTrackers; bool stop; }; diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index ce8b9bac..76a284ce 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -34,10 +34,9 @@ bool ForkChildCheck(int argc, const char *argv[]) // hdcd #service start forground // hdcd -b #service start backgroundRun // hdcd -fork #fork - char modeSet[BUF_SIZE_TINY] = ""; - SystemDepend::GetHdcProperty("persist.hdc.mode", modeSet, BUF_SIZE_TINY); Base::PrintMessage("Background mode, persist.hdc.mode"); - string workMode = modeSet; + string workMode; + SystemDepend::GetProperty("persist.hdc.mode", workMode); workMode = Base::Trim(workMode); if (workMode == CMDSTR_TMODE_TCP) { WRITE_LOG(LOG_DEBUG, "Property enable TCP"); @@ -134,10 +133,8 @@ bool GetDaemonCommandlineOptions(int argc, const char *argv[]) void NeedDropPriv() { - char droprootSet[BUF_SIZE_TINY] = ""; - SystemDepend::GetHdcProperty("persist.hdc.root", droprootSet, BUF_SIZE_TINY); - droprootSet[sizeof(droprootSet) - 1] = '\0'; - string rootMode = droprootSet; + string rootMode; + SystemDepend::GetProperty("persist.hdc.root", rootMode); if (Base::Trim(rootMode) == "1") { setuid(0); g_rootRun = true; diff --git a/src/daemon/system_depend.cpp b/src/daemon/system_depend.cpp index 73c6d85c..745305ac 100644 --- a/src/daemon/system_depend.cpp +++ b/src/daemon/system_depend.cpp @@ -35,46 +35,60 @@ extern "C" { namespace Hdc { namespace SystemDepend { - bool SetHdcProperty(const char *key, const char *value) + bool SetProperty(const char *key, const char *value) { + bool ret = true; #if defined __MUSL__ #ifdef HARMONY_PROJECT - SetParameter(key, value); + ret = SetParameter(key, value) == 0; #else char outBuf[256] = ""; - string sBuf = Base::StringFormat("param set %s %s", key, value); - Base::RunPipeComand(sBuf.c_str(), outBuf, sizeof(outBuf), true); + string stringBuf = Base::StringFormat("param set %s %s", key, value); + Base::RunPipeComand(stringBuf.c_str(), outBuf, sizeof(outBuf), true); #endif // HARMONY_PROJECT #else // not __MUSL__ #ifdef HDC_PCDEBUG WRITE_LOG(LOG_DEBUG, "Setproperty, key:%s value:%s", key, value); #else - string sKey = key; - string sValue = value; - string sBuf = "setprop " + sKey + " " + value; - system(sBuf.c_str()); + string keyValue = key; + string stringBuf = "setprop " + keyValue + " " + value; + system(stringBuf.c_str()); #endif // HDC_PCDEBUG #endif // __MUSL__ - return true; + return ret; } - bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf) + bool GetProperty(const char *key, string &out, string preDefine) { + bool ret = true; + char tmpStringBuf[BUF_SIZE_MEDIUM] = ""; #if defined __MUSL__ - string sKey = key; - string sBuf = "param get " + sKey; - Base::RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); +#ifdef HARMONY_PROJECT + const string strKey(key); + if (GetParameter(key, preDefine.c_str(), tmpStringBuf, BUF_SIZE_MEDIUM) < 0) { + ret = false; + Base::ZeroStruct(tmpStringBuf); + } +#else + string sFailString = Base::StringFormat("Get parameter \"%s\" fail", key); + string stringBuf = "param get " + string(key); + Base::RunPipeComand(stringBuf.c_str(), tmpStringBuf, BUF_SIZE_MEDIUM - 1, true); + if (!strcmp(sFailString.c_str(), tmpStringBuf)) { + // failed + ret = false; + Base::ZeroStruct(tmpStringBuf); + } +#endif #else // not __MUSL__ #ifdef HDC_PCDEBUG - WRITE_LOG(LOG_DEBUG, "Getproperty, key:%s value:%s", key, value); + WRITE_LOG(LOG_DEBUG, "Getproperty, key:%s", key); #else - string sKey = key; - string sBuf = "getprop " + sKey; - Base::RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); + string stringBuf = "getprop " + string(key); + Base::RunPipeComand(stringBuf.c_str(), tmpStringBuf, BUF_SIZE_MEDIUM - 1, true); #endif // HDC_PCDEBUG #endif //__MUSL__ - value[sizeOutBuf - 1] = '\0'; - return true; + out = tmpStringBuf; + return ret; } bool CallDoReboot(const char *reason) @@ -106,7 +120,7 @@ namespace SystemDepend { } else { propertyVal = Base::StringFormat("reboot,%s", cmd.c_str()); } - return SetHdcProperty(rebootProperty.c_str(), propertyVal.c_str()); + return SetProperty(rebootProperty.c_str(), propertyVal.c_str()); #endif } } diff --git a/src/daemon/system_depend.h b/src/daemon/system_depend.h index 15666b18..090c48bf 100644 --- a/src/daemon/system_depend.h +++ b/src/daemon/system_depend.h @@ -18,8 +18,20 @@ namespace Hdc { namespace SystemDepend { - bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf); - bool SetHdcProperty(const char *key, const char *value); +#ifdef HDC_SUPPORT_FLASHD + // deprecated, remove later + inline bool GetProperty(const char *key, string value) + { + return false; + }; + inline bool SetProperty(const char *key, const char *value) + { + return false; + }; +#else + bool GetProperty(const char *key, string &out, string preDefine = ""); + bool SetProperty(const char *key, const char *value); +#endif bool RebootDevice(const string &cmd); } // namespace SystemDepend } // namespace Hdc diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index be01fdb9..8be47f70 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -554,16 +554,16 @@ bool HdcHostUSB::ReadyForWorkThread(HSession hSession) void HdcHostUSB::SessionUsbWorkThread(void *arg) { HSession hSession = (HSession)arg; - constexpr uint8_t USB_HANDLE_TIMEOUT = DEVICE_CHECK_INTERVAL / TIME_BASE; - constexpr uint8_t USB_SESSION_IDLE_COMMMON_REFERENCE = 2; + constexpr uint8_t usbHandleTimeOut = DEVICE_CHECK_INTERVAL / TIME_BASE; + constexpr uint8_t usbSessionIdleCommonReference = 2; WRITE_LOG(LOG_DEBUG, "SessionUsbWorkThread work thread:%p", uv_thread_self()); // run until all USB callback finish(ref == 1, I'm the only one left) while (!hSession->isDead || hSession->ref > 1) { - if (hSession->ref != USB_SESSION_IDLE_COMMMON_REFERENCE) { + if (hSession->ref != usbSessionIdleCommonReference) { WRITE_LOG(LOG_DEBUG, "Session usb workthread session-ref:%u", uint32_t(hSession->ref)); } struct timeval zerotime; - zerotime.tv_sec = USB_HANDLE_TIMEOUT; + zerotime.tv_sec = usbHandleTimeOut; zerotime.tv_usec = 0; // if == 0,windows will be high CPU load libusb_handle_events_timeout(hSession->hUSB->ctxUSB, &zerotime); } -- Gitee From 9f0c63be7fa5d3d1b5649f62a77a07f2e29fec1e Mon Sep 17 00:00:00 2001 From: zako Date: Mon, 20 Dec 2021 15:05:23 +0800 Subject: [PATCH 40/50] Property modify Signed-off-by: zako --- src/daemon/daemon.cpp | 2 +- src/daemon/daemon_tcp.cpp | 2 +- src/daemon/daemon_unity.cpp | 10 +++++----- src/daemon/daemon_usb.cpp | 2 +- src/daemon/daemon_usb.h | 7 +++---- src/daemon/main.cpp | 4 ++-- src/daemon/system_depend.cpp | 12 ++++++------ src/daemon/system_depend.h | 8 ++++---- 8 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index f7132007..d6b5a493 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -84,7 +84,7 @@ void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB) ((HdcJdwp *)clsJdwp)->Initial(); // enable security string secure; - SystemDepend::GetProperty("ro.hdc.secure", secure); + SystemDepend::GetOhosParameter("ro.hdc.secure", secure); enableSecure = (Base::Trim(secure) == "1"); } diff --git a/src/daemon/daemon_tcp.cpp b/src/daemon/daemon_tcp.cpp index c5569d4d..e0e8063b 100644 --- a/src/daemon/daemon_tcp.cpp +++ b/src/daemon/daemon_tcp.cpp @@ -20,7 +20,7 @@ HdcDaemonTCP::HdcDaemonTCP(const bool serverOrDaemonIn, void *ptrMainBase) { // If the listening value for the property setting is obtained, it will be 0 randomly assigned. string strTCPPort; - SystemDepend::GetProperty("persist.hdc.port", strTCPPort); + SystemDepend::GetOhosParameter("persist.hdc.port", strTCPPort); tcpListenPort = atoi(strTCPPort.c_str()); if (tcpListenPort <= 0) { tcpListenPort = 0; diff --git a/src/daemon/daemon_unity.cpp b/src/daemon/daemon_unity.cpp index bba9eed8..784f8b30 100644 --- a/src/daemon/daemon_unity.cpp +++ b/src/daemon/daemon_unity.cpp @@ -179,12 +179,12 @@ bool HdcDaemonUnity::SetDeviceRunMode(void *daemonIn, const char *cmd) HdcDaemon *daemon = (HdcDaemon *)daemonIn; WRITE_LOG(LOG_DEBUG, "Set run mode:%s", cmd); if (!strcmp(CMDSTR_TMODE_USB.c_str(), cmd)) { - SystemDepend::SetProperty("persist.hdc.mode", CMDSTR_TMODE_USB.c_str()); + SystemDepend::SetOhosParameter("persist.hdc.mode", CMDSTR_TMODE_USB.c_str()); } else if (!strncmp("port", cmd, strlen("port"))) { - SystemDepend::SetProperty("persist.hdc.mode", CMDSTR_TMODE_TCP.c_str()); + SystemDepend::SetOhosParameter("persist.hdc.mode", CMDSTR_TMODE_TCP.c_str()); if (!strncmp("port ", cmd, strlen("port "))) { const char *port = cmd + 5; - SystemDepend::SetProperty("persist.hdc.port", port); + SystemDepend::SetOhosParameter("persist.hdc.port", port); } } else { LogMsg(MSG_FAIL, "Unknow command"); @@ -263,9 +263,9 @@ bool HdcDaemonUnity::CommandDispatch(const uint16_t command, uint8_t *payload, c case CMD_UNITY_ROOTRUN: { ret = false; if (payloadSize != 0 && !strcmp((char *)strPayload.c_str(), "r")) { - SystemDepend::SetProperty("persist.hdc.root", "0"); + SystemDepend::SetOhosParameter("persist.hdc.root", "0"); } else { - SystemDepend::SetProperty("persist.hdc.root", "1"); + SystemDepend::SetOhosParameter("persist.hdc.root", "1"); } daemon->PostStopInstanceMessage(true); break; diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 74d56e57..9a3ca76b 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -168,7 +168,7 @@ int HdcDaemonUSB::ConnectEPPoint(HUSB hUSB) break; } // active usbrc,Send USB initialization singal - SystemDepend::SetProperty("sys.usb.ffs.ready", "1"); + SystemDepend::SetOhosParameter("sys.usb.ffs.ready", "1"); WRITE_LOG(LOG_DEBUG, "ConnectEPPoint ctrl init finish, set usb-ffs ready"); } string outPath = basePath + "/ep1"; diff --git a/src/daemon/daemon_usb.h b/src/daemon/daemon_usb.h index 3613c9e7..b77bcce2 100644 --- a/src/daemon/daemon_usb.h +++ b/src/daemon/daemon_usb.h @@ -30,13 +30,12 @@ public: private: struct CtxUvFileCommonIo { void *thisClass; - uv_fs_t req; + void *data; uint8_t *buf; int bufSizeMax; - // dynamic below - bool atPollQueue; int bufSize; - void *data; + bool atPollQueue; + uv_fs_t req; }; static void OnUSBRead(uv_fs_t *req); static void WatchEPTimer(uv_timer_t *handle); diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 76a284ce..c543cbc4 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -36,7 +36,7 @@ bool ForkChildCheck(int argc, const char *argv[]) // hdcd -fork #fork Base::PrintMessage("Background mode, persist.hdc.mode"); string workMode; - SystemDepend::GetProperty("persist.hdc.mode", workMode); + SystemDepend::GetOhosParameter("persist.hdc.mode", workMode); workMode = Base::Trim(workMode); if (workMode == CMDSTR_TMODE_TCP) { WRITE_LOG(LOG_DEBUG, "Property enable TCP"); @@ -134,7 +134,7 @@ bool GetDaemonCommandlineOptions(int argc, const char *argv[]) void NeedDropPriv() { string rootMode; - SystemDepend::GetProperty("persist.hdc.root", rootMode); + SystemDepend::GetOhosParameter("persist.hdc.root", rootMode); if (Base::Trim(rootMode) == "1") { setuid(0); g_rootRun = true; diff --git a/src/daemon/system_depend.cpp b/src/daemon/system_depend.cpp index 745305ac..f9cf77ca 100644 --- a/src/daemon/system_depend.cpp +++ b/src/daemon/system_depend.cpp @@ -26,7 +26,7 @@ envirments */ #include "system_depend.h" #include "../common/base.h" -#if defined __MUSL__ && defined HARMONY_PROJECT +#if defined(__MUSL__) && defined(HARMONY_PROJECT) extern "C" { #include "init_reboot.h" #include "parameter.h" @@ -35,7 +35,7 @@ extern "C" { namespace Hdc { namespace SystemDepend { - bool SetProperty(const char *key, const char *value) + bool SetOhosParameter(const char *key, const char *value) { bool ret = true; #if defined __MUSL__ @@ -48,7 +48,7 @@ namespace SystemDepend { #endif // HARMONY_PROJECT #else // not __MUSL__ #ifdef HDC_PCDEBUG - WRITE_LOG(LOG_DEBUG, "Setproperty, key:%s value:%s", key, value); + WRITE_LOG(LOG_DEBUG, "SetOhosParameter, key:%s value:%s", key, value); #else string keyValue = key; string stringBuf = "setprop " + keyValue + " " + value; @@ -58,7 +58,7 @@ namespace SystemDepend { return ret; } - bool GetProperty(const char *key, string &out, string preDefine) + bool GetOhosParameter(const char *key, string &out, string preDefine) { bool ret = true; char tmpStringBuf[BUF_SIZE_MEDIUM] = ""; @@ -81,7 +81,7 @@ namespace SystemDepend { #endif #else // not __MUSL__ #ifdef HDC_PCDEBUG - WRITE_LOG(LOG_DEBUG, "Getproperty, key:%s", key); + WRITE_LOG(LOG_DEBUG, "GetOhosParameter, key:%s", key); #else string stringBuf = "getprop " + string(key); Base::RunPipeComand(stringBuf.c_str(), tmpStringBuf, BUF_SIZE_MEDIUM - 1, true); @@ -120,7 +120,7 @@ namespace SystemDepend { } else { propertyVal = Base::StringFormat("reboot,%s", cmd.c_str()); } - return SetProperty(rebootProperty.c_str(), propertyVal.c_str()); + return SetOhosParameter(rebootProperty.c_str(), propertyVal.c_str()); #endif } } diff --git a/src/daemon/system_depend.h b/src/daemon/system_depend.h index 090c48bf..99b2f43d 100644 --- a/src/daemon/system_depend.h +++ b/src/daemon/system_depend.h @@ -20,17 +20,17 @@ namespace Hdc { namespace SystemDepend { #ifdef HDC_SUPPORT_FLASHD // deprecated, remove later - inline bool GetProperty(const char *key, string value) + inline bool GetOhosParameter(const char *key, string value) { return false; }; - inline bool SetProperty(const char *key, const char *value) + inline bool SetOhosParameter(const char *key, const char *value) { return false; }; #else - bool GetProperty(const char *key, string &out, string preDefine = ""); - bool SetProperty(const char *key, const char *value); + bool GetOhosParameter(const char *key, string &out, string preDefine = ""); + bool SetOhosParameter(const char *key, const char *value); #endif bool RebootDevice(const string &cmd); } // namespace SystemDepend -- Gitee From e8470b1c9b62532147357f4b685fb6842e1d415a Mon Sep 17 00:00:00 2001 From: zako Date: Mon, 20 Dec 2021 17:44:04 +0800 Subject: [PATCH 41/50] property modify2 Signed-off-by: zako --- src/daemon/daemon.cpp | 2 +- src/daemon/daemon_tcp.cpp | 2 +- src/daemon/daemon_unity.cpp | 10 +++++----- src/daemon/daemon_usb.cpp | 2 +- src/daemon/main.cpp | 4 ++-- src/daemon/system_depend.cpp | 10 +++++----- src/daemon/system_depend.h | 8 ++++---- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index d6b5a493..18734a82 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -84,7 +84,7 @@ void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB) ((HdcJdwp *)clsJdwp)->Initial(); // enable security string secure; - SystemDepend::GetOhosParameter("ro.hdc.secure", secure); + SystemDepend::GetDevItem("ro.hdc.secure", secure); enableSecure = (Base::Trim(secure) == "1"); } diff --git a/src/daemon/daemon_tcp.cpp b/src/daemon/daemon_tcp.cpp index e0e8063b..3df9c23f 100644 --- a/src/daemon/daemon_tcp.cpp +++ b/src/daemon/daemon_tcp.cpp @@ -20,7 +20,7 @@ HdcDaemonTCP::HdcDaemonTCP(const bool serverOrDaemonIn, void *ptrMainBase) { // If the listening value for the property setting is obtained, it will be 0 randomly assigned. string strTCPPort; - SystemDepend::GetOhosParameter("persist.hdc.port", strTCPPort); + SystemDepend::GetDevItem("persist.hdc.port", strTCPPort); tcpListenPort = atoi(strTCPPort.c_str()); if (tcpListenPort <= 0) { tcpListenPort = 0; diff --git a/src/daemon/daemon_unity.cpp b/src/daemon/daemon_unity.cpp index 784f8b30..1853ee17 100644 --- a/src/daemon/daemon_unity.cpp +++ b/src/daemon/daemon_unity.cpp @@ -179,12 +179,12 @@ bool HdcDaemonUnity::SetDeviceRunMode(void *daemonIn, const char *cmd) HdcDaemon *daemon = (HdcDaemon *)daemonIn; WRITE_LOG(LOG_DEBUG, "Set run mode:%s", cmd); if (!strcmp(CMDSTR_TMODE_USB.c_str(), cmd)) { - SystemDepend::SetOhosParameter("persist.hdc.mode", CMDSTR_TMODE_USB.c_str()); + SystemDepend::SetDevItem("persist.hdc.mode", CMDSTR_TMODE_USB.c_str()); } else if (!strncmp("port", cmd, strlen("port"))) { - SystemDepend::SetOhosParameter("persist.hdc.mode", CMDSTR_TMODE_TCP.c_str()); + SystemDepend::SetDevItem("persist.hdc.mode", CMDSTR_TMODE_TCP.c_str()); if (!strncmp("port ", cmd, strlen("port "))) { const char *port = cmd + 5; - SystemDepend::SetOhosParameter("persist.hdc.port", port); + SystemDepend::SetDevItem("persist.hdc.port", port); } } else { LogMsg(MSG_FAIL, "Unknow command"); @@ -263,9 +263,9 @@ bool HdcDaemonUnity::CommandDispatch(const uint16_t command, uint8_t *payload, c case CMD_UNITY_ROOTRUN: { ret = false; if (payloadSize != 0 && !strcmp((char *)strPayload.c_str(), "r")) { - SystemDepend::SetOhosParameter("persist.hdc.root", "0"); + SystemDepend::SetDevItem("persist.hdc.root", "0"); } else { - SystemDepend::SetOhosParameter("persist.hdc.root", "1"); + SystemDepend::SetDevItem("persist.hdc.root", "1"); } daemon->PostStopInstanceMessage(true); break; diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 9a3ca76b..222b6232 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -168,7 +168,7 @@ int HdcDaemonUSB::ConnectEPPoint(HUSB hUSB) break; } // active usbrc,Send USB initialization singal - SystemDepend::SetOhosParameter("sys.usb.ffs.ready", "1"); + SystemDepend::SetDevItem("sys.usb.ffs.ready", "1"); WRITE_LOG(LOG_DEBUG, "ConnectEPPoint ctrl init finish, set usb-ffs ready"); } string outPath = basePath + "/ep1"; diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index c543cbc4..4b3b954e 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -36,7 +36,7 @@ bool ForkChildCheck(int argc, const char *argv[]) // hdcd -fork #fork Base::PrintMessage("Background mode, persist.hdc.mode"); string workMode; - SystemDepend::GetOhosParameter("persist.hdc.mode", workMode); + SystemDepend::GetDevItem("persist.hdc.mode", workMode); workMode = Base::Trim(workMode); if (workMode == CMDSTR_TMODE_TCP) { WRITE_LOG(LOG_DEBUG, "Property enable TCP"); @@ -134,7 +134,7 @@ bool GetDaemonCommandlineOptions(int argc, const char *argv[]) void NeedDropPriv() { string rootMode; - SystemDepend::GetOhosParameter("persist.hdc.root", rootMode); + SystemDepend::GetDevItem("persist.hdc.root", rootMode); if (Base::Trim(rootMode) == "1") { setuid(0); g_rootRun = true; diff --git a/src/daemon/system_depend.cpp b/src/daemon/system_depend.cpp index f9cf77ca..23b4ccf2 100644 --- a/src/daemon/system_depend.cpp +++ b/src/daemon/system_depend.cpp @@ -35,7 +35,7 @@ extern "C" { namespace Hdc { namespace SystemDepend { - bool SetOhosParameter(const char *key, const char *value) + bool SetDevItem(const char *key, const char *value) { bool ret = true; #if defined __MUSL__ @@ -48,7 +48,7 @@ namespace SystemDepend { #endif // HARMONY_PROJECT #else // not __MUSL__ #ifdef HDC_PCDEBUG - WRITE_LOG(LOG_DEBUG, "SetOhosParameter, key:%s value:%s", key, value); + WRITE_LOG(LOG_DEBUG, "SetDevItem, key:%s value:%s", key, value); #else string keyValue = key; string stringBuf = "setprop " + keyValue + " " + value; @@ -58,7 +58,7 @@ namespace SystemDepend { return ret; } - bool GetOhosParameter(const char *key, string &out, string preDefine) + bool GetDevItem(const char *key, string &out, string preDefine) { bool ret = true; char tmpStringBuf[BUF_SIZE_MEDIUM] = ""; @@ -81,7 +81,7 @@ namespace SystemDepend { #endif #else // not __MUSL__ #ifdef HDC_PCDEBUG - WRITE_LOG(LOG_DEBUG, "GetOhosParameter, key:%s", key); + WRITE_LOG(LOG_DEBUG, "GetDevItem, key:%s", key); #else string stringBuf = "getprop " + string(key); Base::RunPipeComand(stringBuf.c_str(), tmpStringBuf, BUF_SIZE_MEDIUM - 1, true); @@ -120,7 +120,7 @@ namespace SystemDepend { } else { propertyVal = Base::StringFormat("reboot,%s", cmd.c_str()); } - return SetOhosParameter(rebootProperty.c_str(), propertyVal.c_str()); + return SetDevItem(rebootProperty.c_str(), propertyVal.c_str()); #endif } } diff --git a/src/daemon/system_depend.h b/src/daemon/system_depend.h index 99b2f43d..a1fc2d34 100644 --- a/src/daemon/system_depend.h +++ b/src/daemon/system_depend.h @@ -20,17 +20,17 @@ namespace Hdc { namespace SystemDepend { #ifdef HDC_SUPPORT_FLASHD // deprecated, remove later - inline bool GetOhosParameter(const char *key, string value) + inline bool GetDevItem(const char *key, string value) { return false; }; - inline bool SetOhosParameter(const char *key, const char *value) + inline bool SetDevItem(const char *key, const char *value) { return false; }; #else - bool GetOhosParameter(const char *key, string &out, string preDefine = ""); - bool SetOhosParameter(const char *key, const char *value); + bool GetDevItem(const char *key, string &out, string preDefine = ""); + bool SetDevItem(const char *key, const char *value); #endif bool RebootDevice(const string &cmd); } // namespace SystemDepend -- Gitee From c90db88e114e8e09e65c33867f98660d7f58225c Mon Sep 17 00:00:00 2001 From: zako Date: Mon, 20 Dec 2021 17:50:09 +0800 Subject: [PATCH 42/50] log remove Signed-off-by: zako --- src/common/session.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/common/session.cpp b/src/common/session.cpp index d4617a19..9fd51f30 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -750,20 +750,15 @@ int HdcSessionBase::FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read) return ERR_IO_FAIL; } hSession->availTailIndex += read; - WRITE_LOG(LOG_ALL, "FetchIOBuf begin, IOSize:%d availTailIndex:%d", read, hSession->availTailIndex); while (!hSession->isDead && hSession->availTailIndex > static_cast(sizeof(PayloadHead))) { childRet = ptrConnect->OnRead(hSession, ioBuf + indexBuf, hSession->availTailIndex); if (childRet > 0) { hSession->availTailIndex -= childRet; indexBuf += childRet; - WRITE_LOG(LOG_ALL, "FetchIOBuf loop read indexBuf:%d availTailIndex:%d", indexBuf, - hSession->availTailIndex); } else if (childRet == 0) { // Not enough a IO - WRITE_LOG(LOG_ALL, "FetchIOBuf loop read not enough, availTailIndex:%d", hSession->availTailIndex); break; - } else { - // <0 + } else { // <0 hSession->availTailIndex = 0; // Preventing malicious data packages indexBuf = ERR_BUF_SIZE; break; @@ -778,7 +773,6 @@ int HdcSessionBase::FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read) uint8_t *bufToZero = (uint8_t *)(hSession->ioBuf + hSession->availTailIndex); Base::ZeroBuf(bufToZero, hSession->bufSize - hSession->availTailIndex); } - WRITE_LOG(LOG_ALL, "FetchIOBuf Finish, IOSize:%d availTailIndex:%d", read, hSession->availTailIndex); return indexBuf; } -- Gitee From 8ec5e9644f7eee1298b28ed3b8dd851b5428ebc4 Mon Sep 17 00:00:00 2001 From: zako Date: Wed, 22 Dec 2021 09:56:44 +0800 Subject: [PATCH 43/50] [tmp]BIO hostusb Signed-off-by: zako --- src/common/base.cpp | 10 ----- src/common/base.h | 1 - src/daemon/daemon_usb.cpp | 4 ++ src/daemon/daemon_usb.h | 1 + src/host/host_usb.cpp | 93 ++++++++++++--------------------------- src/host/host_usb.h | 2 - src/test/ut_mod.cpp | 16 ++++++- 7 files changed, 47 insertions(+), 80 deletions(-) diff --git a/src/common/base.cpp b/src/common/base.cpp index c8ec9f75..6a92862c 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -1176,16 +1176,6 @@ namespace Base { return dupFd; } - vector Md5Sum(uint8_t *buf, int size) - { - vector ret; - uint8_t md5Hash[MD5_DIGEST_LENGTH] = { 0 }; - if (EVP_Digest(buf, size, md5Hash, NULL, EVP_md5(), NULL)) { - ret.insert(ret.begin(), md5Hash, md5Hash + sizeof(md5Hash)); - } - return ret; - } - string GetCwd() { char path[PATH_MAX] = ""; diff --git a/src/common/base.h b/src/common/base.h index b1575918..15718fc0 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -135,7 +135,6 @@ namespace Base { string GetTmpDir(); void RemoveLogFile(); uv_os_sock_t DuplicateUvSocket(uv_tcp_t *tcp); - vector Md5Sum(uint8_t *buf, int size); bool IsRoot(); char GetPathSep(); bool IsAbsolutePath(string &path); diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 222b6232..41be2e48 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -440,6 +440,9 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) uint32_t sessionId = 0; bool ret = false; int childRet = 0; + if (bytesIOBytes > 512 && bytesIOBytes != thisClass->saveNextReadSize) { + WRITE_LOG(LOG_FATAL, "Issue packet"); + } while (thisClass->isAlive) { // Don't care is module running, first deal with this if (bytesIOBytes < 0) { @@ -475,6 +478,7 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) } } int nextReadSize = childRet == 0 ? hUSB->wMaxPacketSizeSend : std::min(childRet, Base::GetUsbffsBulkSize()); + thisClass->saveNextReadSize = nextReadSize; if (thisClass->LoopUSBRead(hUSB, nextReadSize) < 0) { WRITE_LOG(LOG_FATAL, "LoopUSBRead failed"); break; diff --git a/src/daemon/daemon_usb.h b/src/daemon/daemon_usb.h index b77bcce2..d582058e 100644 --- a/src/daemon/daemon_usb.h +++ b/src/daemon/daemon_usb.h @@ -63,6 +63,7 @@ private: bool isAlive = false; int controlEp = 0; // EP0 CtxUvFileCommonIo ctxRecv = {}; + int saveNextReadSize = 0; }; } // namespace Hdc #endif \ No newline at end of file diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 8be47f70..9eeb819c 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -14,6 +14,7 @@ */ #include "host_usb.h" #include "server.h" +#include namespace Hdc { HdcHostUSB::HdcHostUSB(const bool serverOrDaemonIn, void *ptrMainBase, void *ctxUSBin) @@ -334,12 +335,11 @@ int HdcHostUSB::CheckActiveConfig(libusb_device *device, HUSB hUSB) void HdcHostUSB::CancelUsbLoopRead(HSession hSession) { HUSB hUSB = hSession->hUSB; - hUSB->lockTransferRecv.lock(); + std::unique_lock lock(hUSB->lockTransferRecv); if (hUSB->transferRecv != nullptr && !hUSB->recvIOComplete) { WRITE_LOG(LOG_DEBUG, "HostUSB CancelUsbLoopRead, ref:%u", uint32_t(hSession->ref)); libusb_cancel_transfer(hUSB->transferRecv); } - hUSB->lockTransferRecv.unlock(); } // 3rd write child-hdc-workthread @@ -374,76 +374,39 @@ int HdcHostUSB::UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int d return index; } -bool HdcHostUSB::SubmitUsbWorkthread(HSession hSession, libusb_transfer *transfer, const int nextReadSize, - const int timeout) +void HdcHostUSB::RegisterReadCallback(HSession hSession) { HUSB hUSB = hSession->hUSB; ++hSession->ref; - libusb_fill_bulk_transfer(transfer, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, nextReadSize, - ReadUSBBulkCallback, hSession, timeout); - int childRet = libusb_submit_transfer(transfer); - if (childRet < 0) { - --hSession->ref; - WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", childRet); - return false; - } - return true; -} - -// at usb 3rd thread -void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfer) -{ - HSession hSession = (HSession)transfer->user_data; - HdcHostUSB *thisClass = (HdcHostUSB *)hSession->classModule; - HUSB hUSB = hSession->hUSB; - bool bOK = false; - int childRet = 0; - constexpr int infinity = 0; // ignore timeout - hUSB->lockTransferRecv.lock(); - while (true) { - if (!thisClass->modRunning || hUSB->recvIOComplete) { - WRITE_LOG(LOG_WARN, "Hostusb read break"); - break; - } - if (LIBUSB_TRANSFER_COMPLETED != transfer->status) { - WRITE_LOG(LOG_FATAL, "Hostusb not LIBUSB_TRANSFER_COMPLETED, status:%d", transfer->status); - break; - } - childRet - = thisClass->SendToHdcStream(hSession, reinterpret_cast(&hSession->dataPipe[STREAM_MAIN]), - hUSB->bufDevice, transfer->actual_length); - if (childRet < 0) { - break; - } - // loop self - int nextReadSize = childRet == 0 ? hUSB->wMaxPacketSizeSend : std::min(childRet, Base::GetUsbffsBulkSize()); - if (!thisClass->SubmitUsbWorkthread(hSession, transfer, nextReadSize, infinity)) { - break; + hUSB->transferRecv->user_data = hSession; + hUSB->recvIOComplete = false; + std::thread([this, hSession, hUSB]() { + int childRet = 0; + int nextReadSize = 0; + int reallySize = 0; + while (!hSession->isDead) { + nextReadSize = childRet == 0 ? hUSB->wMaxPacketSizeSend : std::min(childRet, Base::GetUsbffsBulkSize()); + hUSB->lockTransferRecv.lock(); + childRet + = libusb_bulk_transfer(hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, nextReadSize, &reallySize, 0); + hUSB->lockTransferRecv.unlock(); + if (childRet < 0) { + WRITE_LOG(LOG_FATAL, "Recv usb failed, ret:%d reallySize:%d", childRet, reallySize); + break; + } + childRet = SendToHdcStream(hSession, reinterpret_cast(&hSession->dataPipe[STREAM_MAIN]), + hUSB->bufDevice, reallySize); + if (childRet < 0) { + WRITE_LOG(LOG_FATAL, "SendToHdcStream failed, ret:%d", childRet); + break; + } } - bOK = true; - break; - } - if (!bOK) { - auto server = reinterpret_cast(thisClass->clsMainBase); + --hSession->ref; + auto server = reinterpret_cast(clsMainBase); server->FreeSession(hSession->sessionId); hUSB->recvIOComplete = true; WRITE_LOG(LOG_WARN, "ReadUSBBulkCallback failed"); - } - --hSession->ref; // until function finsh, dec ref - hUSB->lockTransferRecv.unlock(); -} - -void HdcHostUSB::RegisterReadCallback(HSession hSession) -{ - HUSB hUSB = hSession->hUSB; - if (hSession->isDead || !modRunning) { - return; - } - hSession->hUSB->transferRecv->user_data = hSession; - if (SubmitUsbWorkthread(hSession, hUSB->transferRecv, hUSB->wMaxPacketSizeSend, GLOBAL_TIMEOUT * TIME_BASE)) { - // success - hSession->hUSB->recvIOComplete = false; - } + }).detach(); } // ==0 Represents new equipment and is what we need,<0 my need diff --git a/src/host/host_usb.h b/src/host/host_usb.h index 915ab2e8..c79d6e5f 100644 --- a/src/host/host_usb.h +++ b/src/host/host_usb.h @@ -39,7 +39,6 @@ private: static void SessionUsbWorkThread(void *arg); // 3rd thread static void WatchUsbNodeChange(uv_timer_t *handle); static void KickoutZombie(HSession hSession); - static void LIBUSB_CALL ReadUSBBulkCallback(struct libusb_transfer *transfer); int StartupUSBWork(); int CheckActiveConfig(libusb_device *device, HUSB hUSB); int OpenDeviceMyNeed(HUSB hUSB); @@ -61,7 +60,6 @@ private: map mapIgnoreDevice; private: - bool SubmitUsbWorkthread(HSession hSession, libusb_transfer *transfer, const int nextReadSize, const int timeout); uv_thread_t threadUsbWork; }; } // namespace Hdc diff --git a/src/test/ut_mod.cpp b/src/test/ut_mod.cpp index d6315e09..64ace3bd 100644 --- a/src/test/ut_mod.cpp +++ b/src/test/ut_mod.cpp @@ -13,6 +13,8 @@ * limitations under the License. */ #include "ut_mod.h" +#include +#include using namespace Hdc; namespace HdcTest { @@ -109,6 +111,16 @@ bool TestShellExecute(void *runtimePtr) return ret; } +vector Md5Sum(uint8_t *buf, int size) +{ + vector ret; + uint8_t md5Hash[MD5_DIGEST_LENGTH] = { 0 }; + if (EVP_Digest(buf, size, md5Hash, NULL, EVP_md5(), NULL)) { + ret.insert(ret.begin(), md5Hash, md5Hash + sizeof(md5Hash)); + } + return ret; +} + // file send like recv in our code, so just test send is enough bool TestFileCommand(void *runtimePtr) { @@ -132,8 +144,8 @@ bool TestFileCommand(void *runtimePtr) if ((sizeRemote = Base::ReadBinFile(remoteFile.c_str(), (void **)&bufRemote, 0)) < 0) { break; }; - auto localHash = Base::Md5Sum(bufLocal, sizeLocal); - auto remoteHash = Base::Md5Sum(bufRemote, sizeRemote); + auto localHash = Md5Sum(bufLocal, sizeLocal); + auto remoteHash = Md5Sum(bufRemote, sizeRemote); if (memcmp(localHash.data(), remoteHash.data(), localHash.size())) { break; } -- Gitee From 2aaadaaeaa1c5d9051689a24a32e33a720ecd567 Mon Sep 17 00:00:00 2001 From: zako Date: Wed, 22 Dec 2021 23:55:12 +0800 Subject: [PATCH 44/50] host usb bio modify2 Signed-off-by: zako --- src/common/async_cmd.cpp | 6 ++++++ src/common/define.h | 2 +- src/common/define_plus.h | 1 - src/daemon/daemon_usb.cpp | 16 ++++++++++++++-- src/daemon/main.cpp | 2 +- src/host/host_usb.cpp | 2 +- src/host/main.cpp | 5 ++--- src/host/server.cpp | 2 +- 8 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/common/async_cmd.cpp b/src/common/async_cmd.cpp index 54d3a473..8adf1d43 100644 --- a/src/common/async_cmd.cpp +++ b/src/common/async_cmd.cpp @@ -101,6 +101,12 @@ int AsyncCmd::Popen(string command, bool readWrite, int &pid) return ERR_GENERIC; } if (childPid == 0) { + // // ignre signal alarm to avoid usb async-read EINTR? + struct sigaction action; + action.sa_handler = SIG_IGN; + sigemptyset(&action.sa_mask); + sigaction(SIGALRM, &action, NULL); + if (readWrite) { close(fd[PIPE_READ]); dup2(fd[PIPE_WRITE], STDOUT_FILENO); diff --git a/src/common/define.h b/src/common/define.h index b58b3fcc..0d63052c 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -48,7 +48,7 @@ constexpr uint16_t DEVICE_CHECK_INTERVAL = 3000; // ms constexpr uint16_t MAX_SIZE_IOBUF = 15360; constexpr uint16_t MAX_USBFFS_BULK = 16384; // 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_VERSION_NUMBER = 0x10101b00; // 1.1.1b=0x10101100 constexpr uint32_t HDC_BUF_MAX_BYTES = INT_MAX; constexpr uint32_t HDC_SOCKETPAIR_SIZE = MAX_SIZE_IOBUF * 10; diff --git a/src/common/define_plus.h b/src/common/define_plus.h index 4f568c88..43b4f36d 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -16,7 +16,6 @@ #define DEFINE_PLUS_H namespace Hdc { -constexpr uint8_t LOG_LEVEL_FULL = 5; // ############################# enum define ################################### enum LogLevel { LOG_OFF, diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 41be2e48..695a325d 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -22,6 +22,12 @@ HdcDaemonUSB::HdcDaemonUSB(const bool serverOrDaemonIn, void *ptrMainBase) Base::ZeroStruct(sendEP); Base::ZeroStruct(usbHandle); uv_mutex_init(&sendEP); + + // ignre signal alarm to avoid usb async-read EINTR? + struct sigaction action; + action.sa_handler = SIG_IGN; + sigemptyset(&action.sa_mask); + sigaction(SIGALRM, &action, NULL); } HdcDaemonUSB::~HdcDaemonUSB() @@ -447,14 +453,20 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) // Don't care is module running, first deal with this if (bytesIOBytes < 0) { // logic alive and EINTER is gdb attach - // logic unalive and EINTER maybe close fd + // + // [about gdb attach known issue] + // When GDB debugging is loaded, the number of USB read interrupts of libuv will increase. Multiple + // interrupts will increase the correctness of USB data reading. Setting GDB to asynchronous mode or using + // log debugging can avoid this problem if (bytesIOBytes != -EINTR) { // Epoll will be broken when gdb attach WRITE_LOG(LOG_WARN, "USBIO failed1 %s", uv_strerror(bytesIOBytes)); ret = false; break; + } else { + WRITE_LOG(LOG_ALL, "OnUSBRead singal EINTR"); } } else if (bytesIOBytes == 0) { // zero packet - WRITE_LOG(LOG_WARN, "Zero packet received"); + WRITE_LOG(LOG_ALL, "Zero packet received"); } else { if (thisClass->JumpAntiquePacket(*bufPtr, bytesIOBytes)) { WRITE_LOG(LOG_DEBUG, "JumpAntiquePacket auto jump"); diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 4b3b954e..9234ca8c 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -162,7 +162,7 @@ int main(int argc, const char *argv[]) } if (argc == 1 || (argc == CMD_ARG1_COUNT && (!strcmp(argv[1], "-forkchild") || !strcmp(argv[1], "-b")))) { Hdc::Base::RemoveLogFile(); - Base::SetLogLevel(LOG_LEVEL_FULL); + Base::SetLogLevel(LOG_DEBUG); // tmp set ForkChildCheck(argc, argv); } else { GetDaemonCommandlineOptions(argc, argv); diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 9eeb819c..16c5486e 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -523,7 +523,7 @@ void HdcHostUSB::SessionUsbWorkThread(void *arg) // run until all USB callback finish(ref == 1, I'm the only one left) while (!hSession->isDead || hSession->ref > 1) { if (hSession->ref != usbSessionIdleCommonReference) { - WRITE_LOG(LOG_DEBUG, "Session usb workthread session-ref:%u", uint32_t(hSession->ref)); + WRITE_LOG(LOG_ALL, "Session usb workthread session-ref:%u", uint32_t(hSession->ref)); } struct timeval zerotime; zerotime.tv_sec = usbHandleTimeOut; diff --git a/src/host/main.cpp b/src/host/main.cpp index 7e6fbb41..ed62195b 100644 --- a/src/host/main.cpp +++ b/src/host/main.cpp @@ -28,7 +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 auto g_logLevel = 0; static int g_isTestMethod = 0; static string g_connectKey = ""; static string g_serverListenString = DEFAULT_SERVER_ADDR; @@ -251,7 +251,6 @@ bool GetCommandlineOptions(int optArgc, const char *optArgv[]) needExit = true; return needExit; } - g_logLevel = logLevel; Base::SetLogLevel(logLevel); break; } @@ -323,7 +322,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 Hdc::Base::RemoveLogFile(); - Base::SetLogLevel(g_logLevel); // default level LOG_LEVEL_FULL + Base::SetLogLevel(LOG_DEBUG); // tmp set 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 36e88aaf..9a312302 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -95,7 +95,7 @@ bool HdcServer::PullupServerWin32(const char *path, const char *listenString) runPath = uvPath.substr(uvPath.find_last_of("/\\") + 1); } WRITE_LOG(LOG_DEBUG, "server shortpath:[%s] runPath:[%s]", shortPath, runPath.c_str()); - if (sprintf_s(buf, sizeof(buf), "%s -l5 -s %s -m", runPath.c_str(), listenString) < 0) { + if (sprintf_s(buf, sizeof(buf), "%s -s %s -m", runPath.c_str(), listenString) < 0) { return false; } WRITE_LOG(LOG_DEBUG, "Run server in debug-forground, cmd:%s", buf); -- Gitee From dfd385b2a95193671a884221f7e9fb4da51c3f89 Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 23 Dec 2021 00:21:09 +0800 Subject: [PATCH 45/50] code style Signed-off-by: zako --- src/common/async_cmd.cpp | 2 +- src/daemon/daemon_usb.cpp | 2 +- src/host/host_usb.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common/async_cmd.cpp b/src/common/async_cmd.cpp index 8adf1d43..a75b3b3f 100644 --- a/src/common/async_cmd.cpp +++ b/src/common/async_cmd.cpp @@ -101,7 +101,7 @@ int AsyncCmd::Popen(string command, bool readWrite, int &pid) return ERR_GENERIC; } if (childPid == 0) { - // // ignre signal alarm to avoid usb async-read EINTR? + // ignre signal alarm to avoid usb async-read EINTR? struct sigaction action; action.sa_handler = SIG_IGN; sigemptyset(&action.sa_mask); diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 695a325d..637a51a8 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -446,7 +446,7 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) uint32_t sessionId = 0; bool ret = false; int childRet = 0; - if (bytesIOBytes > 512 && bytesIOBytes != thisClass->saveNextReadSize) { + if (bytesIOBytes > hUSB->wMaxPacketSizeSend && bytesIOBytes != thisClass->saveNextReadSize) { WRITE_LOG(LOG_FATAL, "Issue packet"); } while (thisClass->isAlive) { diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 16c5486e..9f7e4b10 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -75,9 +75,9 @@ void HdcHostUSB::SendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) usbPayloadHeader.option = USB_OPTION_RESET; usbPayloadHeader.dataSize = 0; usbPayloadHeader.sessionId = htonl(sessionIdOld); - if (memcpy_s(usbPayloadHeader.flag, sizeof(usbPayloadHeader.flag), USB_PACKET_FLAG.c_str(), - sizeof(usbPayloadHeader.flag)) - != EOK) { + bool resultCopy = memcpy_s(usbPayloadHeader.flag, sizeof(usbPayloadHeader.flag), USB_PACKET_FLAG.c_str(), + sizeof(usbPayloadHeader.flag)); + if (resultCopy != EOK) { WRITE_LOG(LOG_FATAL, "SendUsbSoftReset memcpy failed"); delete ctxReset; return; -- Gitee From ce02c4d19257e21b8a7d43eadb9bb65405cdc232 Mon Sep 17 00:00:00 2001 From: zako Date: Thu, 23 Dec 2021 22:55:13 +0800 Subject: [PATCH 46/50] modfiy3 Signed-off-by: zako --- src/common/async_cmd.cpp | 6 ------ src/common/base.cpp | 2 +- src/common/base.h | 1 + src/common/session.cpp | 2 ++ src/daemon/daemon_usb.cpp | 8 +------- src/daemon/main.cpp | 4 ++-- src/host/main.cpp | 2 -- src/host/server.cpp | 8 ++++---- 8 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/common/async_cmd.cpp b/src/common/async_cmd.cpp index a75b3b3f..54d3a473 100644 --- a/src/common/async_cmd.cpp +++ b/src/common/async_cmd.cpp @@ -101,12 +101,6 @@ int AsyncCmd::Popen(string command, bool readWrite, int &pid) return ERR_GENERIC; } if (childPid == 0) { - // ignre signal alarm to avoid usb async-read EINTR? - struct sigaction action; - action.sa_handler = SIG_IGN; - sigemptyset(&action.sa_mask); - sigaction(SIGALRM, &action, NULL); - if (readWrite) { close(fd[PIPE_READ]); dup2(fd[PIPE_WRITE], STDOUT_FILENO); diff --git a/src/common/base.cpp b/src/common/base.cpp index 6a92862c..85fa0f41 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -27,7 +27,7 @@ using namespace std::chrono; namespace Hdc { namespace Base { - uint8_t g_logLevel = 0; + uint8_t g_logLevel = LOG_DEBUG; // tmp set,now debugmode.LOG_OFF when release;; void SetLogLevel(const uint8_t logLevel) { g_logLevel = logLevel; diff --git a/src/common/base.h b/src/common/base.h index 15718fc0..d0e80d05 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -18,6 +18,7 @@ namespace Hdc { namespace Base { + extern uint8_t g_logLevel; void SetLogLevel(const uint8_t logLevel); void PrintLogEx(const char *functionName, int line, uint8_t logLevel, const char *msg, ...); void PrintMessage(const char *fmt, ...); diff --git a/src/common/session.cpp b/src/common/session.cpp index 9fd51f30..91dcbc88 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -18,6 +18,8 @@ namespace Hdc { HdcSessionBase::HdcSessionBase(bool serverOrDaemonIn) { + // print version pid + WRITE_LOG(LOG_INFO, "Program running. %s Pid:%u", Base::GetVersion().c_str(), getpid()); // server/daemon common initialization code string threadNum = std::to_string(SIZE_THREAD_POOL); uv_os_setenv("UV_THREADPOOL_SIZE", threadNum.c_str()); diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 637a51a8..afa46fd4 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -22,12 +22,6 @@ HdcDaemonUSB::HdcDaemonUSB(const bool serverOrDaemonIn, void *ptrMainBase) Base::ZeroStruct(sendEP); Base::ZeroStruct(usbHandle); uv_mutex_init(&sendEP); - - // ignre signal alarm to avoid usb async-read EINTR? - struct sigaction action; - action.sa_handler = SIG_IGN; - sigemptyset(&action.sa_mask); - sigaction(SIGALRM, &action, NULL); } HdcDaemonUSB::~HdcDaemonUSB() @@ -463,7 +457,7 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) ret = false; break; } else { - WRITE_LOG(LOG_ALL, "OnUSBRead singal EINTR"); + WRITE_LOG(LOG_ALL, "OnUSBRead signal EINTR"); } } else if (bytesIOBytes == 0) { // zero packet WRITE_LOG(LOG_ALL, "Zero packet received"); diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 9234ca8c..c9e6580b 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -99,7 +99,7 @@ bool GetDaemonCommandlineOptions(int argc, const char *argv[]) { int ch; // hdcd -l4 ... - WRITE_LOG(LOG_DEBUG, "Fgcli mode"); + WRITE_LOG(LOG_DEBUG, "Forground cli-mode"); // Both settings are running with parameters while ((ch = getopt(argc, (char *const *)argv, "utl:")) != -1) { switch (ch) { @@ -162,7 +162,6 @@ int main(int argc, const char *argv[]) } if (argc == 1 || (argc == CMD_ARG1_COUNT && (!strcmp(argv[1], "-forkchild") || !strcmp(argv[1], "-b")))) { Hdc::Base::RemoveLogFile(); - Base::SetLogLevel(LOG_DEBUG); // tmp set ForkChildCheck(argc, argv); } else { GetDaemonCommandlineOptions(argc, argv); @@ -178,6 +177,7 @@ int main(int argc, const char *argv[]) umask(0); signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, SIG_IGN); + signal(SIGALRM, SIG_IGN); WRITE_LOG(LOG_DEBUG, "HdcDaemon main run"); HdcDaemon daemon(false); daemon.InitMod(g_enableTcp, g_enableUsb); diff --git a/src/host/main.cpp b/src/host/main.cpp index ed62195b..4ebfc976 100644 --- a/src/host/main.cpp +++ b/src/host/main.cpp @@ -28,7 +28,6 @@ static bool g_isServerMode = false; static bool g_isPullServer = true; static bool g_isPcDebugRun = false; static bool g_isTCPorUSB = false; -static auto g_logLevel = 0; static int g_isTestMethod = 0; static string g_connectKey = ""; static string g_serverListenString = DEFAULT_SERVER_ADDR; @@ -322,7 +321,6 @@ int main(int argc, const char *argv[]) if (g_isServerMode) { // -m server.Run alone in the background, no -s will be listen loopback address Hdc::Base::RemoveLogFile(); - Base::SetLogLevel(LOG_DEBUG); // tmp set 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 7df88b22..94b735c3 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -96,8 +96,8 @@ bool HdcServer::PullupServerWin32(const char *path, const char *listenString) runPath = uvPath.substr(uvPath.find_last_of("/\\") + 1); } WRITE_LOG(LOG_DEBUG, "server shortpath:[%s] runPath:[%s]", shortPath, runPath.c_str()); - if (sprintf_s(buf, sizeof(buf), "%s -s %s -m", runPath.c_str(), listenString) < 0) { - return false; + if (sprintf_s(buf, sizeof(buf), "-s %s -m", listenString) < 0) { + return retVal; } WRITE_LOG(LOG_DEBUG, "Run server in debug-forground, cmd:%s, args:%s", runPath.c_str(), buf); STARTUPINFO si; @@ -110,8 +110,8 @@ bool HdcServer::PullupServerWin32(const char *path, const char *listenString) si.wShowWindow = SW_HIDE; #endif if (!CreateProcess(runPath.c_str(), buf, nullptr, nullptr, true, CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi)) { - WRITE_LOG(LOG_WARN, "CreateProcess failed with cmd:%s, args:%s, Error Code %d", runPath.c_str(), buf, - GetLastError()); + WRITE_LOG(LOG_WARN, "CreateProcess failed with cmd:%s, args:%s, Error Code %d", + runPath.c_str(), buf, GetLastError()); retVal = false; } else { retVal = true; -- Gitee From c125ed3f5e64e55888f6e3554b9fa3e05af9d9f2 Mon Sep 17 00:00:00 2001 From: zako Date: Fri, 24 Dec 2021 19:53:33 +0800 Subject: [PATCH 47/50] fix issue2 Signed-off-by: zako --- src/host/main.cpp | 19 ++++++++++++------- src/host/server.cpp | 6 +++--- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/host/main.cpp b/src/host/main.cpp index 4ebfc976..0481b957 100644 --- a/src/host/main.cpp +++ b/src/host/main.cpp @@ -24,13 +24,14 @@ using namespace HdcTest; #include "server_for_client.h" using namespace Hdc; -static bool g_isServerMode = false; -static bool g_isPullServer = true; -static bool g_isPcDebugRun = false; -static bool g_isTCPorUSB = false; -static int g_isTestMethod = 0; -static string g_connectKey = ""; -static string g_serverListenString = DEFAULT_SERVER_ADDR; +bool g_isServerMode = false; +bool g_isPullServer = true; +bool g_isPcDebugRun = false; +bool g_isTCPorUSB = false; +bool g_isCustomLoglevel = false; +int g_isTestMethod = 0; +string g_connectKey = ""; +string g_serverListenString = DEFAULT_SERVER_ADDR; namespace Hdc { // return value: 0 == not command, 1 == one command, 2 == double command @@ -250,6 +251,7 @@ bool GetCommandlineOptions(int optArgc, const char *optArgv[]) needExit = true; return needExit; } + g_isCustomLoglevel = true; Base::SetLogLevel(logLevel); break; } @@ -325,6 +327,9 @@ int main(int argc, const char *argv[]) } else if (g_isPcDebugRun) { Hdc::RunPcDebugMode(g_isPullServer, g_isTCPorUSB, g_isTestMethod); } else { + if (!g_isCustomLoglevel) { + Base::SetLogLevel(LOG_INFO); + } Hdc::RunClientMode(commands, g_serverListenString, g_connectKey, g_isPullServer); } WRITE_LOG(LOG_DEBUG, "!!!!!!!!!Main finish main"); diff --git a/src/host/server.cpp b/src/host/server.cpp index 94b735c3..07cff530 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -96,7 +96,7 @@ bool HdcServer::PullupServerWin32(const char *path, const char *listenString) runPath = uvPath.substr(uvPath.find_last_of("/\\") + 1); } WRITE_LOG(LOG_DEBUG, "server shortpath:[%s] runPath:[%s]", shortPath, runPath.c_str()); - if (sprintf_s(buf, sizeof(buf), "-s %s -m", listenString) < 0) { + if (sprintf_s(buf, sizeof(buf), "-l0 -s %s -m", listenString) < 0) { return retVal; } WRITE_LOG(LOG_DEBUG, "Run server in debug-forground, cmd:%s, args:%s", runPath.c_str(), buf); @@ -110,8 +110,8 @@ bool HdcServer::PullupServerWin32(const char *path, const char *listenString) si.wShowWindow = SW_HIDE; #endif if (!CreateProcess(runPath.c_str(), buf, nullptr, nullptr, true, CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi)) { - WRITE_LOG(LOG_WARN, "CreateProcess failed with cmd:%s, args:%s, Error Code %d", - runPath.c_str(), buf, GetLastError()); + WRITE_LOG(LOG_WARN, "CreateProcess failed with cmd:%s, args:%s, Error Code %d", runPath.c_str(), buf, + GetLastError()); retVal = false; } else { retVal = true; -- Gitee From 6ab302ff05572c6f9248868ca4ba4ec8a09d885c Mon Sep 17 00:00:00 2001 From: zako Date: Tue, 28 Dec 2021 15:43:17 +0800 Subject: [PATCH 48/50] modify all hostusb to aio-wait Signed-off-by: zako --- src/common/define_plus.h | 49 ++++++--- src/common/session.cpp | 25 +---- src/common/usb.cpp | 27 ++--- src/common/usb.h | 3 +- src/host/host_usb.cpp | 213 +++++++++++++++++++-------------------- src/host/host_usb.h | 10 +- 6 files changed, 160 insertions(+), 167 deletions(-) diff --git a/src/common/define_plus.h b/src/common/define_plus.h index 43b4f36d..853e8efa 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -205,39 +205,58 @@ using HTaskInfo = TaskInformation *; #pragma pack(pop) +#ifdef HDC_HOST +struct HostUSBEndpoint { + HostUSBEndpoint() + { + endpoint = 0; + sizeEpBuf = 16384; // MAX_USBFFS_BULK + transfer = libusb_alloc_transfer(0); + isShutdown = false; + isComplete = false; + } + ~HostUSBEndpoint() + { + libusb_free_transfer(transfer); + } + uint8_t endpoint; + uint8_t buf[16384]; // MAX_USBFFS_BULK + bool isComplete; + bool isShutdown; + bool bulkInOut; // true is bulkIn + uint16_t sizeEpBuf; + mutex mutexIo; + mutex mutexCb; + condition_variable cv; + libusb_transfer *transfer; +}; +#endif + struct HdcUSB { #ifdef HDC_HOST libusb_context *ctxUSB = nullptr; // child-use, main null libusb_device *device; libusb_device_handle *devHandle; - uint8_t interfaceNumber; uint16_t retryCount; - // D2H device to host endpoint's address - uint8_t epDevice; - // H2D host to device endpoint's address - uint8_t epHost; uint8_t devId; uint8_t busId; - uint16_t sizeEpBuf; + uint8_t interfaceNumber; string serialNumber; string usbMountPoint; - uint8_t *bufDevice; - uint8_t *bufHost; - libusb_transfer *transferRecv; - mutex lockTransferRecv; - bool recvIOComplete; - bool sendIOComplete; - uv_thread_t threadUsbChildWork; + HostUSBEndpoint hostBulkIn; + HostUSBEndpoint hostBulkOut; + #else // usb accessory FunctionFS // USB main thread use, sub-thread disable, sub-thread uses the main thread USB handle int bulkOut; // EP1 device recv int bulkIn; // EP2 device send #endif - mutex lockDeviceHandle; + uint32_t payloadSize; uint16_t wMaxPacketSizeSend; - uint32_t bulkinDataSize; bool resetIO; // if true, must break write and read,default false + mutex lockDeviceHandle; + mutex lockSendUsbBlock; }; using HUSB = struct HdcUSB *; diff --git a/src/common/session.cpp b/src/common/session.cpp index 91dcbc88..6ac17f85 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -316,16 +316,6 @@ int HdcSessionBase::MallocSessionByConnectType(HSession hSession) } hSession->hUSB = hUSB; hSession->hUSB->wMaxPacketSizeSend = MAX_PACKET_SIZE_HISPEED; -#ifdef HDC_HOST - int max = Base::GetUsbffsBulkSize(); - hUSB->sizeEpBuf = max; - hUSB->bufDevice = new uint8_t[max](); - hUSB->bufHost = new uint8_t[max](); - hUSB->transferRecv = libusb_alloc_transfer(0); - hUSB->recvIOComplete = true; - hUSB->sendIOComplete = true; -#else -#endif break; } default: @@ -412,11 +402,6 @@ void HdcSessionBase::FreeSessionByConnectType(HSession hSession) libusb_close(hUSB->devHandle); hUSB->devHandle = nullptr; } - - delete[] hUSB->bufDevice; - delete[] hUSB->bufHost; - libusb_free_transfer(hUSB->transferRecv); - libusb_exit(hUSB->ctxUSB); #else if (hUSB->bulkIn > 0) { close(hUSB->bulkIn); @@ -487,12 +472,10 @@ void HdcSessionBase::FreeSessionOpeate(uv_timer_t *handle) } WRITE_LOG(LOG_DEBUG, "FreeSessionOpeate ref:%u", uint32_t(hSession->ref)); #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); - } - // send will be end with timeout + if (hSession->hUSB != nullptr + && (!hSession->hUSB->hostBulkIn.isShutdown || !hSession->hUSB->hostBulkOut.isShutdown)) { + HdcUSBBase *pUSB = ((HdcUSBBase *)hSession->classModule); + pUSB->CancelUsbIo(hSession); return; } #endif diff --git a/src/common/usb.cpp b/src/common/usb.cpp index 852277ab..b61996a3 100644 --- a/src/common/usb.cpp +++ b/src/common/usb.cpp @@ -76,7 +76,7 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) int childRet = 0; int ret = ERR_IO_FAIL; auto header = BuildPacketHeader(hSession->sessionId, USB_OPTION_HEADER, length); - hSession->hUSB->lockDeviceHandle.lock(); + hSession->hUSB->lockSendUsbBlock.lock(); do { if ((childRet = SendUSBRaw(hSession, header.data(), header.size())) <= 0) { WRITE_LOG(LOG_FATAL, "SendUSBRaw index failed"); @@ -97,7 +97,7 @@ int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) } ret = length; } while (false); - hSession->hUSB->lockDeviceHandle.unlock(); + hSession->hUSB->lockSendUsbBlock.unlock(); return ret; } @@ -129,13 +129,16 @@ bool HdcUSBBase::IsUsbPacketHeader(uint8_t *ioBuf, int ioBytes) void HdcUSBBase::PreSendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) { HUSB hUSB = hSession->hUSB; + int childRet = 0; if (hSession->serverOrDaemon && !hUSB->resetIO) { - uint32_t sid = sessionIdOld; - // or we can sendmsg to childthread send? - hUSB->lockDeviceHandle.lock(); + hUSB->lockSendUsbBlock.lock(); WRITE_LOG(LOG_WARN, "SendToHdcStream check, sessionId not matched"); - SendUsbSoftReset(hSession, sid); - hUSB->lockDeviceHandle.unlock(); + auto header = BuildPacketHeader(sessionIdOld, USB_OPTION_RESET, 0); + if ((childRet = SendUSBRaw(hSession, header.data(), header.size())) <= 0) { + WRITE_LOG(LOG_FATAL, "PreSendUsbSoftReset send failed"); + } + hUSB->lockSendUsbBlock.unlock(); + hUSB->resetIO = true; } } @@ -157,10 +160,10 @@ int HdcUSBBase::CheckPacketOption(HSession hSession, uint8_t *appendData, int da } if (header->option & USB_OPTION_HEADER) { // header packet - hUSB->bulkinDataSize = header->dataSize; + hUSB->payloadSize = header->dataSize; } // soft ZLP - return hUSB->bulkinDataSize; + return hUSB->payloadSize; } // return value: <0 error; = 0 all finish; >0 need size @@ -171,7 +174,7 @@ int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t if (IsUsbPacketHeader(appendData, dataSize)) { return CheckPacketOption(hSession, appendData, dataSize); } - if (hUSB->bulkinDataSize <= (uint32_t)childRet) { + if (hUSB->payloadSize <= (uint32_t)childRet) { // last session data PreSendUsbSoftReset(hSession, 0); // 0 == reset current return 0; @@ -180,8 +183,8 @@ int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t WRITE_LOG(LOG_FATAL, "Error usb send to stream dataSize:%d", dataSize); return ERR_IO_FAIL; } - hUSB->bulkinDataSize -= childRet; - return hUSB->bulkinDataSize; + hUSB->payloadSize -= childRet; + return hUSB->payloadSize; } } \ No newline at end of file diff --git a/src/common/usb.h b/src/common/usb.h index 225375c7..046890f2 100644 --- a/src/common/usb.h +++ b/src/common/usb.h @@ -22,7 +22,7 @@ public: HdcUSBBase(const bool serverOrDaemonIn, void *ptrMainBase); virtual ~HdcUSBBase(); virtual bool ReadyForWorkThread(HSession hSession); - virtual void CancelUsbLoopRead(HSession hSession) {}; + virtual void CancelUsbIo(HSession hSession) {}; int SendUSBBlock(HSession hSession, uint8_t *data, const int length); protected: @@ -44,7 +44,6 @@ protected: const string USB_PACKET_FLAG = "UB"; // must 2bytes private: - virtual void SendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) {}; static void ReadUSB(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); vector BuildPacketHeader(uint32_t sessionId, uint8_t option, uint32_t dataSize); int CheckPacketOption(HSession hSession, uint8_t *appendData, int dataSize); diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 9f7e4b10..4af65987 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -58,57 +58,6 @@ int HdcHostUSB::Initial() return 0; } -// windows/mac's control port reset seems invalid? So we try to use soft interrupt -// if all platform 'libusb_reset_device()' work ok, commit this function and use it replace -// main thread call -void HdcHostUSB::SendUsbSoftReset(HSession hSession, uint32_t sessionIdOld) -{ - struct ResetCtx { - USBHead usbPayloadHeader; - HSession hSession; - }; - ResetCtx *ctxReset = new ResetCtx(); - ctxReset->hSession = hSession; - HUSB hUSB = hSession->hUSB; - - USBHead &usbPayloadHeader = ctxReset->usbPayloadHeader; - usbPayloadHeader.option = USB_OPTION_RESET; - usbPayloadHeader.dataSize = 0; - usbPayloadHeader.sessionId = htonl(sessionIdOld); - bool resultCopy = memcpy_s(usbPayloadHeader.flag, sizeof(usbPayloadHeader.flag), USB_PACKET_FLAG.c_str(), - sizeof(usbPayloadHeader.flag)); - if (resultCopy != EOK) { - WRITE_LOG(LOG_FATAL, "SendUsbSoftReset memcpy failed"); - delete ctxReset; - return; - } - auto resetUsbCallback = [](struct libusb_transfer *transfer) -> void LIBUSB_CALL { - ResetCtx *ctxReset = (ResetCtx *)transfer->user_data; - if (LIBUSB_TRANSFER_COMPLETED != transfer->status) { - WRITE_LOG(LOG_FATAL, "SendUSBRaw status:%d", transfer->status); - } - --ctxReset->hSession->ref; - ctxReset->hSession->hUSB->sendIOComplete = true; - delete ctxReset; - libusb_free_transfer(transfer); - // has send soft reset, next reset daemon's send - WRITE_LOG(LOG_DEBUG, "Device reset singal send"); - }; - libusb_transfer *transferUsb = libusb_alloc_transfer(0); - ++hSession->ref; - libusb_fill_bulk_transfer(transferUsb, hUSB->devHandle, hUSB->epHost, (uint8_t *)&usbPayloadHeader, sizeof(USBHead), - resetUsbCallback, ctxReset, GLOBAL_TIMEOUT * TIME_BASE); - int err = libusb_submit_transfer(transferUsb); - if (err < 0) { - WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", err); - delete ctxReset; - --hSession->ref; - } else { - hUSB->sendIOComplete = false; - } - hUSB->resetIO = true; -} - bool HdcHostUSB::DetectMyNeed(libusb_device *device, string &sn) { bool ret = false; @@ -314,14 +263,16 @@ int HdcHostUSB::CheckActiveConfig(libusb_device *device, HUSB hUSB) const struct libusb_endpoint_descriptor *ep_desc = &ifDescriptor->endpoint[k]; if ((ep_desc->bmAttributes & 0x03) == LIBUSB_TRANSFER_TYPE_BULK) { if (ep_desc->bEndpointAddress & LIBUSB_ENDPOINT_IN) { - hUSB->epDevice = ep_desc->bEndpointAddress; + hUSB->hostBulkIn.endpoint = ep_desc->bEndpointAddress; + hUSB->hostBulkIn.bulkInOut = true; } else { - hUSB->epHost = ep_desc->bEndpointAddress; + hUSB->hostBulkOut.endpoint = ep_desc->bEndpointAddress; hUSB->wMaxPacketSizeSend = ep_desc->wMaxPacketSize; + hUSB->hostBulkOut.bulkInOut = false; } } } - if (hUSB->epDevice == 0 || hUSB->epHost == 0) { + if (hUSB->hostBulkIn.endpoint == 0 || hUSB->hostBulkOut.endpoint == 0) { break; } ret = 0; @@ -332,13 +283,26 @@ int HdcHostUSB::CheckActiveConfig(libusb_device *device, HUSB hUSB) } // multi-thread calll -void HdcHostUSB::CancelUsbLoopRead(HSession hSession) +void HdcHostUSB::CancelUsbIo(HSession hSession) { + WRITE_LOG(LOG_DEBUG, "HostUSB CancelUsbIo, ref:%u", uint32_t(hSession->ref)); HUSB hUSB = hSession->hUSB; - std::unique_lock lock(hUSB->lockTransferRecv); - if (hUSB->transferRecv != nullptr && !hUSB->recvIOComplete) { - WRITE_LOG(LOG_DEBUG, "HostUSB CancelUsbLoopRead, ref:%u", uint32_t(hSession->ref)); - libusb_cancel_transfer(hUSB->transferRecv); + std::unique_lock lock(hUSB->lockDeviceHandle); + if (!hUSB->hostBulkIn.isShutdown) { + if (!hUSB->hostBulkIn.isComplete) { + libusb_cancel_transfer(hUSB->hostBulkIn.transfer); + hUSB->hostBulkIn.cv.notify_one(); + } else { + hUSB->hostBulkIn.isShutdown = true; + } + } + if (!hUSB->hostBulkOut.isShutdown) { + if (!hUSB->hostBulkOut.isComplete) { + libusb_cancel_transfer(hUSB->hostBulkOut.transfer); + hUSB->hostBulkOut.cv.notify_one(); + } else { + hUSB->hostBulkOut.isShutdown = true; + } } } @@ -374,28 +338,87 @@ int HdcHostUSB::UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int d return index; } -void HdcHostUSB::RegisterReadCallback(HSession hSession) +void LIBUSB_CALL HdcHostUSB::USBBulkCallback(struct libusb_transfer *transfer) +{ + auto *ep = static_cast(transfer->user_data); + std::unique_lock lock(ep->mutexIo); + do { + if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { + WRITE_LOG(LOG_FATAL, "USBBulkCallback1 failed, ret:%d", transfer->status); + break; + } + if (!ep->bulkInOut && transfer->actual_length != transfer->length) { + transfer->length -= transfer->actual_length; + transfer->buffer += transfer->actual_length; + int rc = libusb_submit_transfer(transfer); + if (rc != 0) { + WRITE_LOG(LOG_FATAL, "USBBulkCallback2 failed, ret:%d", rc); + transfer->status = LIBUSB_TRANSFER_ERROR; + break; + } + return; + } + } while (false); + ep->isComplete = true; + ep->cv.notify_one(); +} + +int HdcHostUSB::SubmitUsbBio(HSession hSession, bool sendOrRecv, uint8_t *buf, int bufSize) +{ + HUSB hUSB = hSession->hUSB; + int timeout = 0; + int childRet = 0; + int ret = ERR_IO_FAIL; + HostUSBEndpoint *ep = nullptr; + + if (sendOrRecv) { + timeout = GLOBAL_TIMEOUT * TIME_BASE; + ep = &hUSB->hostBulkOut; + } else { + timeout = 0; // infinity + ep = &hUSB->hostBulkIn; + } + hUSB->lockDeviceHandle.lock(); + ep->isComplete = false; + do { + std::unique_lock lock(ep->mutexIo); + libusb_fill_bulk_transfer(ep->transfer, hUSB->devHandle, ep->endpoint, buf, bufSize, USBBulkCallback, ep, + timeout); + childRet = libusb_submit_transfer(ep->transfer); + hUSB->lockDeviceHandle.unlock(); + if (childRet < 0) { + WRITE_LOG(LOG_FATAL, "SubmitUsbBio libusb_submit_transfer failed, ret:%d", childRet); + break; + } + ep->cv.wait(lock, [ep]() { return ep->isComplete; }); + if (ep->transfer->status != 0) { + WRITE_LOG(LOG_FATAL, "SubmitUsbBio transfer failed, status:%d", ep->transfer->status); + break; + } + ret = ep->transfer->actual_length; + } while (false); + return ret; +} + +void HdcHostUSB::BeginUsbRead(HSession hSession) { HUSB hUSB = hSession->hUSB; ++hSession->ref; - hUSB->transferRecv->user_data = hSession; - hUSB->recvIOComplete = false; + // loop read std::thread([this, hSession, hUSB]() { int childRet = 0; int nextReadSize = 0; - int reallySize = 0; while (!hSession->isDead) { - nextReadSize = childRet == 0 ? hUSB->wMaxPacketSizeSend : std::min(childRet, Base::GetUsbffsBulkSize()); - hUSB->lockTransferRecv.lock(); - childRet - = libusb_bulk_transfer(hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, nextReadSize, &reallySize, 0); - hUSB->lockTransferRecv.unlock(); + // if readIO < wMaxPacketSizeSend, libusb report overflow + nextReadSize = (childRet < hUSB->wMaxPacketSizeSend ? hUSB->wMaxPacketSizeSend + : std::min(childRet, Base::GetUsbffsBulkSize())); + childRet = SubmitUsbBio(hSession, false, hUSB->hostBulkIn.buf, nextReadSize); if (childRet < 0) { - WRITE_LOG(LOG_FATAL, "Recv usb failed, ret:%d reallySize:%d", childRet, reallySize); + WRITE_LOG(LOG_FATAL, "Read usb failed, ret:%d", childRet); break; } childRet = SendToHdcStream(hSession, reinterpret_cast(&hSession->dataPipe[STREAM_MAIN]), - hUSB->bufDevice, reallySize); + hUSB->hostBulkIn.buf, childRet); if (childRet < 0) { WRITE_LOG(LOG_FATAL, "SendToHdcStream failed, ret:%d", childRet); break; @@ -403,9 +426,9 @@ void HdcHostUSB::RegisterReadCallback(HSession hSession) } --hSession->ref; auto server = reinterpret_cast(clsMainBase); + hUSB->hostBulkIn.isShutdown = true; server->FreeSession(hSession->sessionId); - hUSB->recvIOComplete = true; - WRITE_LOG(LOG_WARN, "ReadUSBBulkCallback failed"); + WRITE_LOG(LOG_DEBUG, "Usb loop read finish"); }).detach(); } @@ -441,23 +464,13 @@ int HdcHostUSB::OpenDeviceMyNeed(HUSB hUSB) int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) { int ret = ERR_GENERIC; - int childRet = -1; - int reallySize = 0; - HUSB hUSB = hSession->hUSB; HdcSessionBase *server = reinterpret_cast(hSession->classInstance); ++hSession->ref; - do { - childRet = libusb_bulk_transfer(hUSB->devHandle, hUSB->epHost, data, length, &reallySize, - GLOBAL_TIMEOUT * TIME_BASE); - if (childRet < 0 || reallySize != length) { - WRITE_LOG(LOG_FATAL, "SendUSBRaw failed, ret:%d reallySize:%d", childRet, reallySize); - break; - } - ret = length; - } while (false); + ret = SubmitUsbBio(hSession, true, data, length); if (ret < 0) { - CancelUsbLoopRead(hSession); - hSession->hUSB->sendIOComplete = true; + WRITE_LOG(LOG_FATAL, "Send usb failed, ret:%d", ret); + CancelUsbIo(hSession); + hSession->hUSB->hostBulkOut.isShutdown = true; server->FreeSession(hSession->sessionId); } --hSession->ref; @@ -513,43 +526,19 @@ bool HdcHostUSB::ReadyForWorkThread(HSession hSession) return true; }; -// Target session USB operates in this thread -void HdcHostUSB::SessionUsbWorkThread(void *arg) -{ - HSession hSession = (HSession)arg; - constexpr uint8_t usbHandleTimeOut = DEVICE_CHECK_INTERVAL / TIME_BASE; - constexpr uint8_t usbSessionIdleCommonReference = 2; - WRITE_LOG(LOG_DEBUG, "SessionUsbWorkThread work thread:%p", uv_thread_self()); - // run until all USB callback finish(ref == 1, I'm the only one left) - while (!hSession->isDead || hSession->ref > 1) { - if (hSession->ref != usbSessionIdleCommonReference) { - WRITE_LOG(LOG_ALL, "Session usb workthread session-ref:%u", uint32_t(hSession->ref)); - } - struct timeval zerotime; - zerotime.tv_sec = usbHandleTimeOut; - zerotime.tv_usec = 0; // if == 0,windows will be high CPU load - libusb_handle_events_timeout(hSession->hUSB->ctxUSB, &zerotime); - } - --hSession->ref; - WRITE_LOG(LOG_DEBUG, "Session usb workthread finish"); -} - // Determines that daemonInfo must have the device HSession HdcHostUSB::ConnectDetectDaemon(const HSession hSession, const HDaemonInfo pdi) { HdcServer *pServer = (HdcServer *)clsMainBase; HUSB hUSB = hSession->hUSB; hUSB->usbMountPoint = pdi->usbMountPoint; - - libusb_init((libusb_context **)&hUSB->ctxUSB); - ++hSession->ref; - uv_thread_create(&hUSB->threadUsbChildWork, SessionUsbWorkThread, hSession); + hUSB->ctxUSB = ctxUSB; if (!FindDeviceByID(hUSB, hUSB->usbMountPoint.c_str(), hUSB->ctxUSB)) { pServer->FreeSession(hSession->sessionId); return nullptr; } UpdateUSBDaemonInfo(hUSB, hSession, STATUS_CONNECTED); - RegisterReadCallback(hSession); + BeginUsbRead(hSession); hUSB->usbMountPoint = pdi->usbMountPoint; WRITE_LOG(LOG_DEBUG, "HSession HdcHostUSB::ConnectDaemon"); diff --git a/src/host/host_usb.h b/src/host/host_usb.h index c79d6e5f..d6c65564 100644 --- a/src/host/host_usb.h +++ b/src/host/host_usb.h @@ -35,10 +35,10 @@ private: }; static int LIBUSB_CALL HotplugHostUSBCallback(libusb_context *ctx, libusb_device *device, libusb_hotplug_event event, void *userData); - static void UsbWorkThread(void *arg); // 3rd thread - static void SessionUsbWorkThread(void *arg); // 3rd thread + static void UsbWorkThread(void *arg); // 3rd thread static void WatchUsbNodeChange(uv_timer_t *handle); static void KickoutZombie(HSession hSession); + static void LIBUSB_CALL USBBulkCallback(struct libusb_transfer *transfer); int StartupUSBWork(); int CheckActiveConfig(libusb_device *device, HUSB hUSB); int OpenDeviceMyNeed(HUSB hUSB); @@ -47,13 +47,13 @@ private: bool ReadyForWorkThread(HSession hSession); bool FindDeviceByID(HUSB hUSB, const char *usbMountPoint, libusb_context *ctxUSB); bool DetectMyNeed(libusb_device *device, string &sn); - void SendUsbSoftReset(HSession hSession, uint32_t sessionIdOld); void RestoreHdcProtocol(HUSB hUsb, const uint8_t *buf, int bufSize); void UpdateUSBDaemonInfo(HUSB hUSB, HSession hSession, uint8_t connStatus); - void RegisterReadCallback(HSession hSession); + void BeginUsbRead(HSession hSession); void ReviewUsbNodeLater(string &nodeKey); - void CancelUsbLoopRead(HSession hSession); + void CancelUsbIo(HSession hSession); int UsbToHdcProtocol(uv_stream_t *stream, uint8_t *appendData, int dataSize); + int SubmitUsbBio(HSession hSession, bool sendOrRecv, uint8_t *buf, int bufSize); libusb_context *ctxUSB; uv_timer_t devListWatcher; -- Gitee From 079c8d1f46c595a1dc65cf99634b269d73dc27b4 Mon Sep 17 00:00:00 2001 From: zako Date: Sun, 2 Jan 2022 22:54:23 +0800 Subject: [PATCH 49/50] app install ctrlC+host usb init issue Signed-off-by: zako --- src/common/async_cmd.cpp | 2 +- src/common/define_plus.h | 15 +++++++---- src/common/session.cpp | 54 ++++++++++++++++++++++++++++--------- src/common/session.h | 4 ++- src/common/task.cpp | 2 ++ src/common/transfer.cpp | 28 ++++++++++++------- src/common/transfer.h | 17 +++++++----- src/daemon/daemon.cpp | 2 +- src/daemon/daemon_app.cpp | 8 +++--- src/daemon/daemon_unity.cpp | 1 - src/daemon/daemon_usb.cpp | 18 +++++-------- src/daemon/daemon_usb.h | 2 +- src/host/host_usb.cpp | 22 ++++++++++----- src/host/server.cpp | 2 +- 14 files changed, 115 insertions(+), 62 deletions(-) diff --git a/src/common/async_cmd.cpp b/src/common/async_cmd.cpp index 54d3a473..6aca1239 100644 --- a/src/common/async_cmd.cpp +++ b/src/common/async_cmd.cpp @@ -56,7 +56,7 @@ void AsyncCmd::DoRelease() bool AsyncCmd::Initial(uv_loop_t *loopIn, const CmdResultCallback callback, uint32_t optionsIn) { #if defined _WIN32 || defined HDC_HOST - WRITE_LOG(LOG_FATAL, "Not support for win32-host"); + WRITE_LOG(LOG_FATAL, "Not support for win32 or host side"); return false; #endif loop = loopIn; diff --git a/src/common/define_plus.h b/src/common/define_plus.h index 853e8efa..486ebcb6 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -117,18 +117,22 @@ enum HdcCommand { CMD_KERNEL_ECHO, CMD_KERNEL_ECHO_RAW, CMD_KERNEL_ENABLE_KEEPALIVE, + CMD_KERNEL_WAKEUP_SLAVETASK, // One-pass simple commands - CMD_UNITY_EXECUTE = 1000, + CMD_UNITY_COMMAND_HEAD = 1000, // not use + CMD_UNITY_EXECUTE, CMD_UNITY_REMOUNT, CMD_UNITY_REBOOT, CMD_UNITY_RUNMODE, CMD_UNITY_HILOG, CMD_UNITY_TERMINATE, CMD_UNITY_ROOTRUN, - CMD_UNITY_BUGREPORT_INIT, - CMD_UNITY_BUGREPORT_DATA, CMD_JDWP_LIST, CMD_JDWP_TRACK, + CMD_UNITY_COMMAND_TAIL, // not use + // It will be separated from unity in the near future + CMD_UNITY_BUGREPORT_INIT, + CMD_UNITY_BUGREPORT_DATA, // Shell commands types CMD_SHELL_INIT = 2000, CMD_SHELL_DATA, @@ -197,6 +201,7 @@ struct TaskInformation { bool taskStop; bool taskFree; bool serverOrDaemon; + bool masterSlave; uv_loop_t *runLoop; void *taskClass; void *ownerSessionClass; @@ -212,8 +217,8 @@ struct HostUSBEndpoint { endpoint = 0; sizeEpBuf = 16384; // MAX_USBFFS_BULK transfer = libusb_alloc_transfer(0); - isShutdown = false; - isComplete = false; + isShutdown = true; + isComplete = true; } ~HostUSBEndpoint() { diff --git a/src/common/session.cpp b/src/common/session.cpp index 6ac17f85..5f6ab035 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -1031,35 +1031,65 @@ void HdcSessionBase::LogMsg(const uint32_t sessionId, const uint32_t channelId, ServerCommand(sessionId, channelId, CMD_KERNEL_ECHO, buf.data(), buf.size()); } +bool HdcSessionBase::NeedNewTaskInfo(const uint16_t command, bool &masterTask) +{ + // referer from HdcServerForClient::DoCommandRemote + bool ret = false; + bool taskMasterInit = false; + masterTask = false; + switch (command) { + case CMD_FILE_INIT: + case CMD_FORWARD_INIT: + case CMD_APP_INIT: + case CMD_APP_UNINSTALL: + case CMD_UNITY_BUGREPORT_INIT: + case CMD_APP_SIDELOAD: + taskMasterInit = true; + break; + default: + break; + } + if (!serverOrDaemon + && (command == CMD_SHELL_INIT || (command > CMD_UNITY_COMMAND_HEAD && command < CMD_UNITY_COMMAND_TAIL))) { + // daemon's single side command + ret = true; + } else if (command == CMD_KERNEL_WAKEUP_SLAVETASK) { + // slave tasks + ret = true; + } else if (taskMasterInit) { + // task init command + masterTask = true; + ret = true; + } + return ret; +} // Heavy and time-consuming work was putted in the new thread to do, and does // not occupy the main thread bool HdcSessionBase::DispatchTaskData(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, int payloadSize) { bool ret = true; + HTaskInfo hTaskInfo = nullptr; + bool masterTask = false; while (true) { - HTaskInfo hTaskInfo = AdminTask(OP_QUERY, hSession, channelId, nullptr); - if (!hTaskInfo) { + // Some basic commands do not have a local task constructor. example: Interactive shell, some uinty commands + if (NeedNewTaskInfo(command, masterTask)) { WRITE_LOG(LOG_DEBUG, "New HTaskInfo"); hTaskInfo = new TaskInformation(); hTaskInfo->channelId = channelId; hTaskInfo->sessionId = hSession->sessionId; hTaskInfo->runLoop = &hSession->childLoop; hTaskInfo->serverOrDaemon = serverOrDaemon; + hTaskInfo->masterSlave = masterTask; + AdminTask(OP_ADD, hSession, channelId, hTaskInfo); + } else { + hTaskInfo = AdminTask(OP_QUERY, hSession, channelId, nullptr); } - if (hTaskInfo->taskStop) { - WRITE_LOG(LOG_DEBUG, "RedirectToTask jump stopped task:%u", channelId); - break; - } - if (hTaskInfo->taskFree) { - WRITE_LOG(LOG_DEBUG, "Jump delete HTaskInfo"); + if (!hTaskInfo || hTaskInfo->taskStop || hTaskInfo->taskFree) { + WRITE_LOG(LOG_ALL, "Dead HTaskInfo, ignore, channelId:%u command:%u", channelId, command); break; } ret = RedirectToTask(hTaskInfo, hSession, channelId, command, payload, payloadSize); - if (!hTaskInfo->hasInitial) { - AdminTask(OP_ADD, hSession, channelId, hTaskInfo); - hTaskInfo->hasInitial = true; - } break; } return ret; diff --git a/src/common/session.h b/src/common/session.h index 8fdd2a5e..9e7422f7 100644 --- a/src/common/session.h +++ b/src/common/session.h @@ -132,9 +132,10 @@ protected: bool ret = true; T *ptrTask = nullptr; if (!hTaskInfo->hasInitial) { + hTaskInfo->taskType = taskType; ptrTask = new T(hTaskInfo); + hTaskInfo->hasInitial = true; hTaskInfo->taskClass = ptrTask; - hTaskInfo->taskType = taskType; } else { ptrTask = (T *)hTaskInfo->taskClass; } @@ -177,6 +178,7 @@ private: void FreeSessionByConnectType(HSession hSession); bool WorkThreadStartSession(HSession hSession); uint32_t GetSessionPseudoUid(); + bool NeedNewTaskInfo(const uint16_t command, bool &masterTask); map mapSession; uv_rwlock_t lockMapSession; diff --git a/src/common/task.cpp b/src/common/task.cpp index 13383b31..add408ad 100644 --- a/src/common/task.cpp +++ b/src/common/task.cpp @@ -26,6 +26,8 @@ HdcTaskBase::HdcTaskBase(HTaskInfo hTaskInfo) childReady = false; singalStop = false; refCount = 0; + if (taskInfo->masterSlave) + SendToAnother(CMD_KERNEL_WAKEUP_SLAVETASK, nullptr, 0); } HdcTaskBase::~HdcTaskBase() diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index 4e2a1ba9..1fa96d15 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -47,6 +47,8 @@ bool HdcTransferBase::ResetCtx(CtxFile *context, bool full) } context->closeNotify = false; context->indexIO = 0; + context->lastErrno = 0; + context->ioFinish = false; return true; } @@ -58,6 +60,11 @@ int HdcTransferBase::SimpleFileIO(CtxFile *context, uint64_t index, uint8_t *sen bool ret = false; while (true) { if (!buf || !ioContext || bytes < 0) { + WRITE_LOG(LOG_DEBUG, "SimpleFileIO param check failed"); + break; + } + if (context->ioFinish) { + WRITE_LOG(LOG_DEBUG, "SimpleFileIO to closed IOStream"); break; } uv_fs_t *req = &ioContext->fs; @@ -102,6 +109,7 @@ void HdcTransferBase::OnFileClose(uv_fs_t *req) HdcTransferBase *thisClass = (HdcTransferBase *)context->thisClass; if (context->closeNotify) { // close-step2 + // maybe successful finish or failed finish thisClass->WhenTransferFinish(context); } --thisClass->refCount; @@ -174,24 +182,23 @@ bool HdcTransferBase::SendIOPayload(CtxFile *context, int index, uint8_t *data, void HdcTransferBase::OnFileIO(uv_fs_t *req) { - bool tryFinishIO = false; CtxFileIO *contextIO = (CtxFileIO *)req->data; CtxFile *context = (CtxFile *)contextIO->context; HdcTransferBase *thisClass = (HdcTransferBase *)context->thisClass; uint8_t *bufIO = contextIO->bufIO; uv_fs_req_cleanup(req); - --thisClass->refCount; while (true) { if (req->result < 0) { WRITE_LOG(LOG_DEBUG, "OnFileIO error: %s", uv_strerror((int)req->result)); context->closeNotify = true; - tryFinishIO = true; + context->lastErrno = abs(req->result); + context->ioFinish = true; break; } context->indexIO += req->result; if (req->fs_type == UV_FS_READ) { if (!thisClass->SendIOPayload(context, context->indexIO - req->result, bufIO, req->result)) { - tryFinishIO = true; + context->ioFinish = true; break; } if (context->indexIO < context->fileSize) { @@ -203,22 +210,23 @@ void HdcTransferBase::OnFileIO(uv_fs_t *req) // The active end must first read it first, but you can't make Finish first, because Slave may not // end.Only slave receives complete talents Finish context->closeNotify = true; - tryFinishIO = true; + context->ioFinish = true; thisClass->SetFileTime(context); } } else { - tryFinishIO = true; + context->ioFinish = true; } break; } - delete[] bufIO; - delete contextIO; // Req is part of the Contextio structure, no free release - if (tryFinishIO) { + if (context->ioFinish) { // close-step1 ++thisClass->refCount; - uv_fs_fsync(thisClass->loopTask, &context->fsCloseReq, context->fsOpenReq.result, nullptr); + uv_fs_fsync(nullptr, &context->fsCloseReq, context->fsOpenReq.result, nullptr); uv_fs_close(thisClass->loopTask, &context->fsCloseReq, context->fsOpenReq.result, OnFileClose); } + --thisClass->refCount; + delete[] bufIO; + delete contextIO; // Req is part of the Contextio structure, no free release } void HdcTransferBase::OnFileOpen(uv_fs_t *req) diff --git a/src/common/transfer.h b/src/common/transfer.h index 135f81f2..61e2c580 100644 --- a/src/common/transfer.h +++ b/src/common/transfer.h @@ -52,20 +52,23 @@ public: protected: // Static file context - struct CtxFile { // The structure cannot be initialized by MEMSET - bool master; // Document transmission initiative - bool closeNotify; - void *thisClass; + struct CtxFile { // The structure cannot be initialized by MEMSET, will rename to CtxTransfer uint64_t fileSize; uint64_t indexIO; // Id or written IO bytes - uv_loop_t *loop; - uv_fs_cb cb; + uint64_t transferBegin; string localName; string localPath; string remotePath; + bool master; // Document transmission initiative + bool closeNotify; + bool ioFinish; + void *thisClass; + uint32_t lastErrno; + + uv_loop_t *loop; uv_fs_t fsOpenReq; uv_fs_t fsCloseReq; - uint64_t transferBegin; + uv_fs_cb cb; vector taskQueue; TransferConfig transferConfig; // Used for network IO configuration initialization }; diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 18734a82..db9516dd 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -134,7 +134,7 @@ bool HdcDaemon::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uin ret = TaskCommandDispatch(hTaskInfo, TASK_FORWARD, command, payload, payloadSize); break; default: - ret = false; + //ignore unknow command break; } return ret; diff --git a/src/daemon/daemon_app.cpp b/src/daemon/daemon_app.cpp index b472039f..1d2f70bc 100644 --- a/src/daemon/daemon_app.cpp +++ b/src/daemon/daemon_app.cpp @@ -36,6 +36,7 @@ bool HdcDaemonApp::ReadyForRelease() if (!asyncCommand.ReadyForRelease()) { return false; } + WRITE_LOG(LOG_DEBUG, "HdcDaemonApp ready for release"); return true; } @@ -142,14 +143,15 @@ void HdcDaemonApp::Sideload(const char *pathOTA) void HdcDaemonApp::WhenTransferFinish(CtxFile *context) { + if (context->lastErrno > 0) { + WRITE_LOG(LOG_DEBUG, "HdcDaemonApp WhenTransferFinish with errno:%d", context->lastErrno); + return; + } if (ctxNow.transferConfig.functionName == CMDSTR_APP_SIDELOAD) { Sideload(context->localPath.c_str()); } else if (ctxNow.transferConfig.functionName == CMDSTR_APP_INSTALL) { PackageShell(true, context->transferConfig.options.c_str(), context->localPath.c_str()); } else { - WRITE_LOG(LOG_WARN, "WhenTransferFinish error funcnm:[%s] lpath:[%s]", - ctxNow.transferConfig.functionName.c_str(), context->localPath.c_str()); - PackageShell(true, context->transferConfig.options.c_str(), context->localPath.c_str()); } }; } \ No newline at end of file diff --git a/src/daemon/daemon_unity.cpp b/src/daemon/daemon_unity.cpp index 958935c1..ebabd9c8 100644 --- a/src/daemon/daemon_unity.cpp +++ b/src/daemon/daemon_unity.cpp @@ -31,7 +31,6 @@ void HdcDaemonUnity::StopTask() { // Remove jpid tracker when stopping task RemoveJdwpTracker(); - asyncCommand.DoRelease(); } diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index afa46fd4..9833aa28 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -19,15 +19,12 @@ namespace Hdc { HdcDaemonUSB::HdcDaemonUSB(const bool serverOrDaemonIn, void *ptrMainBase) : HdcUSBBase(serverOrDaemonIn, ptrMainBase) { - Base::ZeroStruct(sendEP); Base::ZeroStruct(usbHandle); - uv_mutex_init(&sendEP); } HdcDaemonUSB::~HdcDaemonUSB() { // Closed in the IO loop, no longer closing CLOSE ENDPOINT - uv_mutex_destroy(&sendEP); if (controlEp > 0) { close(controlEp); } @@ -225,7 +222,6 @@ void HdcDaemonUSB::ResetOldSession(uint32_t sessionId) if (hSession == nullptr) { return; } - hSession->hUSB->resetIO = true; // The Host side is restarted, but the USB cable is still connected WRITE_LOG(LOG_WARN, "Hostside softreset to restart daemon, old sessionId:%u", sessionId); daemon->FreeSession(sessionId); @@ -293,7 +289,7 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t int childRet = 0; int ret = ERR_IO_FAIL; int offset = 0; - while (modRunning && isAlive && !hSession->isDead && !hSession->hUSB->resetIO) { + while (modRunning && isAlive && !hSession->isDead) { childRet = write(bulkIn, (uint8_t *)data + offset, length - offset); if (childRet <= 0) { int err = errno; @@ -314,9 +310,8 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t if (offset == length) { ret = length; } else { - WRITE_LOG(LOG_FATAL, - "BulkinWrite write failed, nsize:%d really:%d modRunning:%d isAlive:%d SessionDead:%d usbReset:%d", - length, offset, modRunning, isAlive, hSession->isDead, hSession->hUSB->resetIO); + WRITE_LOG(LOG_FATAL, "BulkinWrite write failed, nsize:%d really:%d modRunning:%d isAlive:%d SessionDead:%d", + length, offset, modRunning, isAlive, hSession->isDead); } return ret; } @@ -324,7 +319,7 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t int HdcDaemonUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) { HdcDaemon *daemon = (HdcDaemon *)hSession->classInstance; - uv_mutex_lock(&sendEP); + std::unique_lock lock(mutexUsbFfs); ++hSession->ref; int ret = SendUSBIOSync(hSession, &usbHandle, data, length); --hSession->ref; @@ -332,7 +327,6 @@ int HdcDaemonUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) daemon->FreeSession(hSession->sessionId); WRITE_LOG(LOG_DEBUG, "SendUSBRaw try to freesession"); } - uv_mutex_unlock(&sendEP); return ret; } @@ -441,7 +435,7 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) bool ret = false; int childRet = 0; if (bytesIOBytes > hUSB->wMaxPacketSizeSend && bytesIOBytes != thisClass->saveNextReadSize) { - WRITE_LOG(LOG_FATAL, "Issue packet"); + WRITE_LOG(LOG_WARN, "Not full packet, wanted:%d really:%d", thisClass->saveNextReadSize, bytesIOBytes); } while (thisClass->isAlive) { // Don't care is module running, first deal with this @@ -453,7 +447,7 @@ void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) // interrupts will increase the correctness of USB data reading. Setting GDB to asynchronous mode or using // log debugging can avoid this problem if (bytesIOBytes != -EINTR) { // Epoll will be broken when gdb attach - WRITE_LOG(LOG_WARN, "USBIO failed1 %s", uv_strerror(bytesIOBytes)); + WRITE_LOG(LOG_WARN, "USBIO ret:%d failed:%s", bytesIOBytes, uv_strerror(bytesIOBytes)); ret = false; break; } else { diff --git a/src/daemon/daemon_usb.h b/src/daemon/daemon_usb.h index d582058e..fdb97091 100644 --- a/src/daemon/daemon_usb.h +++ b/src/daemon/daemon_usb.h @@ -59,7 +59,7 @@ private: string basePath; // usb device's base path uint32_t currentSessionId = 0; // USB mode,limit only one session uv_timer_t checkEP; // server-use - uv_mutex_t sendEP; + mutex mutexUsbFfs; bool isAlive = false; int controlEp = 0; // EP0 CtxUvFileCommonIo ctxRecv = {}; diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 4af65987..f2b50ec1 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -342,6 +342,8 @@ void LIBUSB_CALL HdcHostUSB::USBBulkCallback(struct libusb_transfer *transfer) { auto *ep = static_cast(transfer->user_data); std::unique_lock lock(ep->mutexIo); + bool retrySumit = false; + int childRet = 0; do { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { WRITE_LOG(LOG_FATAL, "USBBulkCallback1 failed, ret:%d", transfer->status); @@ -350,15 +352,19 @@ void LIBUSB_CALL HdcHostUSB::USBBulkCallback(struct libusb_transfer *transfer) if (!ep->bulkInOut && transfer->actual_length != transfer->length) { transfer->length -= transfer->actual_length; transfer->buffer += transfer->actual_length; - int rc = libusb_submit_transfer(transfer); - if (rc != 0) { - WRITE_LOG(LOG_FATAL, "USBBulkCallback2 failed, ret:%d", rc); - transfer->status = LIBUSB_TRANSFER_ERROR; - break; - } - return; + retrySumit = true; + break; } } while (false); + while (retrySumit) { + childRet = libusb_submit_transfer(transfer); + if (childRet != 0) { + WRITE_LOG(LOG_FATAL, "USBBulkCallback2 failed, ret:%d", childRet); + transfer->status = LIBUSB_TRANSFER_ERROR; + break; + } + return; + } ep->isComplete = true; ep->cv.notify_one(); } @@ -403,6 +409,8 @@ int HdcHostUSB::SubmitUsbBio(HSession hSession, bool sendOrRecv, uint8_t *buf, i void HdcHostUSB::BeginUsbRead(HSession hSession) { HUSB hUSB = hSession->hUSB; + hUSB->hostBulkIn.isShutdown = false; + hUSB->hostBulkOut.isShutdown = false; ++hSession->ref; // loop read std::thread([this, hSession, hUSB]() { diff --git a/src/host/server.cpp b/src/host/server.cpp index 07cff530..b3ee2c85 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -767,7 +767,7 @@ bool HdcServer::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uin ret = TaskCommandDispatch(hTaskInfo, TASK_APP, command, payload, payloadSize); break; default: - ret = false; + // ignore unknow command break; } return ret; -- Gitee From 9a0841afc613f78a8e5d54909d158eeb63789945 Mon Sep 17 00:00:00 2001 From: zako Date: Sun, 2 Jan 2022 23:13:39 +0800 Subject: [PATCH 50/50] ~ Signed-off-by: zako --- src/common/transfer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/transfer.cpp b/src/common/transfer.cpp index e5257203..68c7edb5 100644 --- a/src/common/transfer.cpp +++ b/src/common/transfer.cpp @@ -205,7 +205,7 @@ void HdcTransferBase::OnFileIO(uv_fs_t *req) thisClass->SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize() * thisClass->maxTransferBufFactor); } else { - tryFinishIO = true; + context->ioFinish = true; } } else if (req->fs_type == UV_FS_WRITE) { // write if (context->indexIO >= context->fileSize) { -- Gitee