diff --git a/BUILD.gn b/BUILD.gn index 5d9aee6754a1acff5075903aee0b767fc492d1a9..d7f5c6c34c31bde2fe892486f494b0b433c83344 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -61,7 +61,8 @@ ohos_executable("hdcd") { ] if (use_musl) { deps += [ - "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", + "//base/startup/init_lite/interfaces/innerkits/reboot:libreboot", + "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", ] } include_dirs = [ @@ -73,7 +74,8 @@ ohos_executable("hdcd") { ] if (use_musl) { include_dirs += [ - "//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include", + "//base/startup/init_lite/interfaces/innerkits/include", + "//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include", ] } install_enable = true diff --git a/prebuilt/linux/hdc_std b/prebuilt/linux/hdc_std index 3f170d86adebd72324b404682ed3dad89b34cea4..b3267cc862b7aea660ff3b3a031b2586b573629d 100755 Binary files a/prebuilt/linux/hdc_std and b/prebuilt/linux/hdc_std differ diff --git a/prebuilt/windows/hdc_std.exe b/prebuilt/windows/hdc_std.exe index 4174db891ebcf5cb7f805be1a945631b18caecd6..335f233173f4e6a12e44e72c4d65baa495852050 100644 --- a/prebuilt/windows/hdc_std.exe +++ b/prebuilt/windows/hdc_std.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7d95e291cc173be53b2542f593f65cbeb726c8d6d6f5bf2edc5cfdfc2c4db607 -size 3301888 +oid sha256:5920b35edb50cc1e6118b0e3c08f8158d6539ffdad7b2668133ca140f6e8f0bf +size 3305984 diff --git a/src/common/async_cmd.cpp b/src/common/async_cmd.cpp index ee541af1575be177beed3ed625c960cb12c8eb08..2a9e9bc217b56cda331cea8ab2062f2593f5cceb 100644 --- a/src/common/async_cmd.cpp +++ b/src/common/async_cmd.cpp @@ -46,7 +46,7 @@ void AsyncCmd::DoRelease() return; } hasStop = true; // must set here to deny repeate release - ExitCallback(&proc, 0, 0); + uv_process_kill(&proc, SIGKILL); WRITE_LOG(LOG_DEBUG, "AsyncCmd::DoRelease finish"); } @@ -58,7 +58,10 @@ void AsyncCmd::ChildReadCallback(uv_stream_t *stream, ssize_t nread, const uv_bu } else { if (thisClass->options & OPTION_READBACK_OUT) { thisClass->cmdResult = buf->base; - thisClass->resultCallback(false, 0, thisClass->cmdResult); + 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; @@ -85,7 +88,6 @@ void AsyncCmd::ExitCallback(uv_process_t *req, int64_t exitStatus, int tersignal 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); - uv_process_kill(req, SIGKILL); thisClass->cmdResult = STRING_EMPTY; } diff --git a/src/common/async_cmd.h b/src/common/async_cmd.h index ca063f5d704c622433983bdc6e6895e3daeac66d..b319adf387f5d10c3eb23f153a0f26c877d8689f 100644 --- a/src/common/async_cmd.h +++ b/src/common/async_cmd.h @@ -28,7 +28,7 @@ public: USB_OPTION_RESERVE8 = 8, }; // 1)is finish 2)exitStatus 3)resultString(maybe empty) - using CmdResultCallback = std::function; + using CmdResultCallback = std::function; static uint32_t GetDefaultOption() { return OPTION_APPEND_NEWLINE | OPTION_COMMAND_ONETIME; diff --git a/src/common/base.cpp b/src/common/base.cpp index 47767e469a5995309ea2ece1106b4197f878c3dd..24df97297398f0547d8e5d8fc62ef6b9e6efccaf 100644 --- a/src/common/base.cpp +++ b/src/common/base.cpp @@ -145,7 +145,7 @@ namespace Base { printf("%s", logBuf.c_str()); fflush(stdout); - // logfile + // logfile, not thread-safe FILE *fp = fopen("/data/local/tmp/hdc.log", "a"); if (fp == nullptr) { return; @@ -559,12 +559,18 @@ namespace Base { 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 = "getparam " + sKey; + RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); #endif value[sizeOutBuf - 1] = '\0'; return true; @@ -686,9 +692,9 @@ namespace Base { return ERR_BUF_OVERFLOW; } // no need to CanonicalizeSpecPath, else not work - int fd = open(bufPath, O_RDWR | O_CREAT, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); + int fd = open(bufPath, O_RDWR | O_CREAT, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)); if (fd < 0) { - WRITE_LOG(LOG_FATAL, "Open mutex file \"%s\" failed!!!\n", buf); + WRITE_LOG(LOG_FATAL, "Open mutex file \"%s\" failed!!!Errno:%d\n", buf, errno); return ERR_FILE_OPEN; } #ifdef _WIN32 @@ -1001,7 +1007,13 @@ namespace Base { string GetVersion() { - return "Ver: " + VERSION_NUMBER; + const uint8_t a = 'a'; + uint8_t major = (HDC_VERSION_NUMBER >> 28) & 0xff; + uint8_t minor = (HDC_VERSION_NUMBER << 4 >> 24) & 0xff; + uint8_t version = (HDC_VERSION_NUMBER << 12 >> 24) & 0xff; + uint8_t fix = (HDC_VERSION_NUMBER << 20 >> 28) & 0xff; // max 16, tail is p + string ver = StringFormat("%x.%x.%x%c", major, minor, version, a + fix); + return "Ver: " + ver; } bool IdleUvTask(uv_loop_t *loop, void *data, uv_idle_cb cb) @@ -1141,5 +1153,17 @@ namespace Base { return ret; } + bool IsRoot() + { +#ifdef _WIN32 + // reserve + return true; +#else + if (getuid() == 0) { + return true; + } +#endif + return false; + } } } // namespace Hdc diff --git a/src/common/base.h b/src/common/base.h index 2014bd2d10c6288610d1a284b9d6d898ed032495..ecef2009555d96b130e2c9db145560a95472db7d 100644 --- a/src/common/base.h +++ b/src/common/base.h @@ -110,11 +110,32 @@ namespace Base { { return DelayDo(loop, 0, 0, "", data, cb); } + + // Trim from right side + inline string &RightTrim(string &s, const string &w = WHITE_SPACES) + { + s.erase(s.find_last_not_of(w) + 1); + return s; + } + + // Trim from left side + inline string &LeftTrim(string &s, const string &w = WHITE_SPACES) + { + s.erase(0, s.find_first_not_of(w)); + return s; + } + + // Trim from both sides + inline string &Trim(string &s, const string &w = WHITE_SPACES) + { + return LeftTrim(RightTrim(s, w), w); + } string ReplaceAll(string str, const string from, const string to); uint8_t CalcCheckSum(const uint8_t *data, int len); string GetFileNameAny(string &path); uv_os_sock_t DuplicateUvSocket(uv_tcp_t *tcp); vector Md5Sum(uint8_t *buf, int size); + bool IsRoot(); } // namespace base } // namespace Hdc diff --git a/src/common/channel.cpp b/src/common/channel.cpp index 6cd141dfe14b6b5cd30bf7bd365c43906c90bcb3..1171078b7ce9c4783929d2f9d11f52c1b3b688cd 100644 --- a/src/common/channel.cpp +++ b/src/common/channel.cpp @@ -252,13 +252,13 @@ void HdcChannelBase::Send(const uint32_t channelId, uint8_t *bufPtr, const int s delete[] data; return; } - ++hChannel->sendRef; if (hChannel->hWorkThread == uv_thread_self()) { sendStream = (uv_stream_t *)&hChannel->hWorkTCP; } else { sendStream = (uv_stream_t *)&hChannel->hChildWorkTCP; } if (uv_is_writable(sendStream)) { + ++hChannel->sendRef; Base::SendToStreamEx(sendStream, data, sizeNewBuf, nullptr, (void *)WriteCallback, data); } } diff --git a/src/common/define.h b/src/common/define.h index 270ecc0f5d18d3b97193407e65012e5472592b4e..5850f85fa85df492c7f15e33ef93bfc46565f2a7 100644 --- a/src/common/define.h +++ b/src/common/define.h @@ -22,13 +22,13 @@ namespace Hdc { // USB EP block max size about 10k, error if too big constexpr uint16_t MAX_SIZE_IOBUF = 5120; constexpr uint16_t VER_PROTOCOL = 0x01; -constexpr uint8_t SIZE_THREAD_POOL = 8; +constexpr uint8_t SIZE_THREAD_POOL = 16; constexpr uint8_t GLOBAL_TIMEOUT = 60; constexpr uint16_t DEFAULT_PORT = 8710; constexpr uint16_t EXTRA_ALLOC_SIZE = 2048; constexpr uint8_t MINOR_TIMEOUT = 5; constexpr bool ENABLE_IO_CHECKSUM = false; - +const string WHITE_SPACES = " \t\n\r"; const string UT_TMP_PATH = "/tmp/hdc-ut"; const string SERVER_NAME = "HDCServer"; const string STRING_EMPTY = ""; @@ -51,13 +51,11 @@ constexpr uint16_t MAX_CONNECTKEY_SIZE = 32; // usb sn/tcp ipport constexpr uint8_t MAX_IO_OVERLAP = 32; // test on windows 32 is OK constexpr auto TIME_BASE = 1000; // time unit conversion base value constexpr uint16_t AID_SHELL = 2000; -// double-word(hex)=[0]major[1][2]monor[3][4]version[5]fix(a-p)[6][7]reserve -constexpr uint32_t HDC_VERSION_NUMBER = 0x10100f00; +// double-word(hex)=[0]major[1][2]minor[3][4]version[5]fix(a-p)[6][7]reserve +constexpr uint32_t HDC_VERSION_NUMBER = 0x10101200; // 1.1.1b=0x10101100 // general one argument command argc constexpr int CMD_ARG1_COUNT = 2; -// The first child versions must match, otherwise server and daemon must be upgraded -const string VERSION_NUMBER = "1.1.0q"; // same with openssl version, 1.1.2==VERNUMBER 0x10102000 const string HANDSHAKE_MESSAGE = "OHOS HDC"; // sep not char '-', not more than 11 bytes const string PACKET_FLAG = "HW"; // must 2bytes const string EMPTY_ECHO = "[Empty]"; diff --git a/src/common/define_plus.h b/src/common/define_plus.h index ba34687dfd1ab8d4cffc97e8f397eb5113d396e0..b63c8d90081216150241acb1fbdb8698bf8962a7 100644 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -81,6 +81,8 @@ enum RetErrCode { ERR_UT_MODULE_NOTREADY = -19000, ERR_UT_MODULE_WAITMAX, ERR_THREAD_MUTEX_FAIL = -20000, + ERR_PROCESS_SUB_FAIL = -21000, + ERR_PRIVELEGE_NEED = -22000, }; // Flags shared by multiple modules diff --git a/src/common/file_descriptor.cpp b/src/common/file_descriptor.cpp index cfc7e4d5037864d4a6694728e4220f464b25f4a1..61886062b23fa7bee3e67845f2504bc1af402287 100644 --- a/src/common/file_descriptor.cpp +++ b/src/common/file_descriptor.cpp @@ -39,10 +39,23 @@ bool HdcFileDescriptor::ReadyForRelease() return refIO == 0; } -// force stop -void HdcFileDescriptor::StopWork() +// just tryCloseFdIo = true, callback will be effect +void HdcFileDescriptor::StopWork(bool tryCloseFdIo, std::function closeFdCallback) { workContinue = false; + callbackCloseFd = closeFdCallback; + if (tryCloseFdIo && refIO > 0) { + ++refIO; + reqClose.data = this; + uv_fs_close(loop, &reqClose, fdIO, [](uv_fs_t *req) { + auto thisClass = (HdcFileDescriptor *)req->data; + uv_fs_req_cleanup(req); + if (thisClass->callbackCloseFd != nullptr) { + thisClass->callbackCloseFd(); + } + --thisClass->refIO; + }); + } }; void HdcFileDescriptor::OnFileIO(uv_fs_t *req) @@ -53,7 +66,7 @@ void HdcFileDescriptor::OnFileIO(uv_fs_t *req) bool bFinish = false; bool fetalFinish = false; - while (thisClass->workContinue) { + do { if (req->result > 0) { if (req->fs_type == UV_FS_READ) { if (!thisClass->callbackRead(thisClass->callerContext, buf, req->result)) { @@ -65,12 +78,12 @@ 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)); bFinish = true; fetalFinish = true; break; } - break; - } + } while (false); uv_fs_req_cleanup(req); delete[] buf; delete ctxIO; @@ -95,7 +108,6 @@ int HdcFileDescriptor::LoopRead() if (buf) { delete[] buf; } - WRITE_LOG(LOG_FATAL, "Memory alloc failed"); callbackFinish(callerContext, true, "Memory alloc failed"); return -1; @@ -105,7 +117,6 @@ int HdcFileDescriptor::LoopRead() contextIO->thisClass = this; req->data = contextIO; ++refIO; - iov = uv_buf_init((char *)buf, readMax); uv_fs_read(loop, req, fdIO, &iov, 1, -1, OnFileIO); return 0; @@ -113,7 +124,9 @@ int HdcFileDescriptor::LoopRead() bool HdcFileDescriptor::StartWork() { - LoopRead(); + if (LoopRead() < 0) { + return false; + } return true; } diff --git a/src/common/file_descriptor.h b/src/common/file_descriptor.h index 4486fb2501dc045cbcf9f43e7ddc79524a2c87bc..40311e7121ca17a4ff6e5cb637639a39be08c8c7 100644 --- a/src/common/file_descriptor.h +++ b/src/common/file_descriptor.h @@ -24,14 +24,14 @@ public: // callerContext, readBuf, readIOByes using CallBackWhenRead = std::function; HdcFileDescriptor(uv_loop_t *loopIn, int fdToRead, void *callerContextIn, CallBackWhenRead callbackReadIn, - CmdResultCallback callbackFinishIn); + CmdResultCallback callbackFinishIn); virtual ~HdcFileDescriptor(); int Write(uint8_t *data, int size); int WriteWithMem(uint8_t *data, int size); bool ReadyForRelease(); bool StartWork(); - void StopWork(); + void StopWork(bool tryCloseFdIo, std::function closeFdCallback); protected: private: @@ -40,16 +40,18 @@ private: uint8_t *bufIO; HdcFileDescriptor *thisClass; }; + static void OnFileIO(uv_fs_t *req); + int LoopRead(); + + std::function callbackCloseFd; + CmdResultCallback callbackFinish; + CallBackWhenRead callbackRead; uv_loop_t *loop; + uv_fs_t reqClose; void *callerContext; bool workContinue; int fdIO; int refIO; - - static void OnFileIO(uv_fs_t *req); - int LoopRead(); - CmdResultCallback callbackFinish; - CallBackWhenRead callbackRead; }; } // namespace Hdc diff --git a/src/common/forward.cpp b/src/common/forward.cpp index 91c15c54ddf36b2a1b681b3e10469e90e8f8e3d3..0d5faf6b123c2c903c45346ce9d88dc14e60a0e4 100644 --- a/src/common/forward.cpp +++ b/src/common/forward.cpp @@ -133,7 +133,7 @@ void HdcForwardBase::FreeJDWP(HCtxForward ctx) close(ctx->fd); } if (ctx->fdClass) { - ctx->fdClass->StopWork(); + ctx->fdClass->StopWork(false, nullptr); auto funcReqClose = [](uv_idle_t *handle) -> void { uv_close_cb funcIdleHandleClose = [](uv_handle_t *handle) -> void { diff --git a/src/common/session.cpp b/src/common/session.cpp index 5ae19c9a3f93e5787c13a7d90006200d25982b15..724c8fe6130e829164806f7ee45de204dbef75da 100644 --- a/src/common/session.cpp +++ b/src/common/session.cpp @@ -18,8 +18,7 @@ namespace Hdc { HdcSessionBase::HdcSessionBase(bool serverOrDaemonIn) { - string threadNum = std::to_string(SIZE_THREAD_POOL); - uv_os_setenv("UV_THREADPOOL_SIZE", threadNum.c_str()); + // server/daemon common initialize uv_loop_init(&loopMain); WRITE_LOG(LOG_DEBUG, "loopMain init"); uv_rwlock_init(&mainAsync); @@ -28,6 +27,17 @@ HdcSessionBase::HdcSessionBase(bool serverOrDaemonIn) serverOrDaemon = serverOrDaemonIn; ctxUSB = nullptr; wantRestart = false; + + // server/daemon common set + string threadNum = std::to_string(SIZE_THREAD_POOL); + uv_os_setenv("UV_THREADPOOL_SIZE", threadNum.c_str()); +#ifndef _WIN32 + // global signal detect + umask(0); + signal(SIGPIPE, SIG_IGN); // SIG_DFL + // prevent zoombie process, let 'init' process do process's clear + signal(SIGCHLD, SIG_IGN); +#endif #ifdef HDC_HOST if (serverOrDaemon) { libusb_init((libusb_context **)&ctxUSB); @@ -88,7 +98,7 @@ bool HdcSessionBase::BeginRemoveTask(HTaskInfo hTask) thisClass->AdminTask(OP_REMOVE, hSession, hTask->channelId, nullptr); WRITE_LOG(LOG_DEBUG, "TaskDelay task remove finish, channelId:%d", hTask->channelId); delete hTask; - uv_close((uv_handle_t *)handle, Base::CloseIdleCallback); + Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseIdleCallback); }; Base::IdleUvTask(hTask->runLoop, hTask, taskClassDeleteRetry); @@ -238,7 +248,7 @@ void HdcSessionBase::AsyncMainLoopTask(uv_idle_t *handle) } delete param; param = nullptr; - uv_close((uv_handle_t *)handle, Base::CloseIdleCallback); + Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseIdleCallback); } void HdcSessionBase::MainAsyncCallback(uv_async_t *handle) @@ -378,7 +388,6 @@ HSession HdcSessionBase::MallocSession(bool serverOrDaemon, const ConnType connT hSession->dataPipe[STREAM_MAIN].data = hSession; hSession->dataPipe[STREAM_WORK].data = hSession; Base::SetTcpOptions(&hSession->dataPipe[STREAM_MAIN]); - ret = MallocSessionByConnectType(hSession); if (ret) { delete hSession; @@ -463,10 +472,8 @@ void HdcSessionBase::FreeSessionContinue(HSession hSession) delete[] hSession->ioBuf; hSession->ioBuf = nullptr; } - Base::TryCloseHandle((uv_handle_t *)&hSession->ctrlPipe[STREAM_MAIN], closeSessionTCPHandle); - Base::CloseSocketPair(hSession->ctrlFd); - Base::TryCloseHandle((uv_handle_t *)&hSession->dataPipe[STREAM_MAIN], closeSessionTCPHandle); - Base::CloseSocketPair(hSession->dataFd); + Base::TryCloseHandle((uv_handle_t *)&hSession->ctrlPipe[STREAM_MAIN], true, closeSessionTCPHandle); + Base::TryCloseHandle((uv_handle_t *)&hSession->dataPipe[STREAM_MAIN], true, closeSessionTCPHandle); delete hSession->mapTask; HdcAuth::FreeKey(!hSession->serverOrDaemon, hSession->listKey); delete hSession->listKey; // to clear @@ -932,18 +939,27 @@ void HdcSessionBase::ReadCtrlFromMain(uv_stream_t *uvpipe, ssize_t nread, const HdcSessionBase *hSessionBase = (HdcSessionBase *)hSession->classInstance; int formatCommandSize = sizeof(CtrlStruct); int index = 0; - while (index < nread) { + bool ret = true; + while (true) { + if (nread < 0) { + WRITE_LOG(LOG_DEBUG, "SessionCtrl failed,%s", uv_strerror(nread)); + ret = false; + break; + } if (nread % formatCommandSize != 0) { WRITE_LOG(LOG_FATAL, "ReadCtrlFromMain size failed, nread == %d", nread); + ret = false; break; } - if (nread < 0) { - WRITE_LOG(LOG_DEBUG, "SessionCtrl failed,%s", uv_strerror(nread)); + CtrlStruct *ctrl = reinterpret_cast(buf->base + index); + if (!(ret = hSessionBase->DispatchMainThreadCommand(hSession, ctrl))) { + ret = false; break; } - CtrlStruct *ctrl = reinterpret_cast(buf->base + index); index += sizeof(CtrlStruct); - hSessionBase->DispatchMainThreadCommand(hSession, ctrl); + if (index >= nread) { + break; + } } delete[] buf->base; } diff --git a/src/common/task.cpp b/src/common/task.cpp index aca68023ffeb2ab8bb8e511650a78dd450a2a8f2..20590edd0de91c9837a12464c3ac33da7e3b7340 100644 --- a/src/common/task.cpp +++ b/src/common/task.cpp @@ -23,7 +23,6 @@ HdcTaskBase::HdcTaskBase(HTaskInfo hTaskInfo) taskInfo = hTaskInfo; loopTask = hTaskInfo->runLoop; clsSession = hTaskInfo->ownerSessionClass; - runningProtect = false; childReady = false; singalStop = false; refCount = 0; @@ -36,7 +35,7 @@ HdcTaskBase::~HdcTaskBase() bool HdcTaskBase::ReadyForRelease() { - return !runningProtect && refCount == 0; + return refCount == 0; } // Only the Task work thread call is allowed to use only when Workfortask returns FALSE. @@ -49,6 +48,9 @@ void HdcTaskBase::TaskFinish() bool HdcTaskBase::SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size) { + if (singalStop) { + return false; + } HdcSessionBase *sessionBase = reinterpret_cast(taskInfo->ownerSessionClass); return sessionBase->Send(taskInfo->sessionId, taskInfo->channelId, command, bufPtr, size) > 0; } diff --git a/src/common/task.h b/src/common/task.h index 23b61497ed8647ea0801af0403a8f5f9c47e0b2f..1af6126ae93216e1f0d151b5b60498424ad92a18 100644 --- a/src/common/task.h +++ b/src/common/task.h @@ -30,7 +30,7 @@ public: // directly instantified of these two virtual functions. virtual void StopTask() { - singalStop = false; + singalStop = true; // default opeartion } bool ReadyForRelease(); void TaskFinish(); @@ -45,9 +45,8 @@ protected: void *clsSession; // Task has stopped running. When Task is officially running, set True as soon as possible, set FALSE after the last // step, when the value is false, the Task class will be destructured as soon as possible - bool runningProtect; // [deprecated]will be remove, please use refCount - bool childReady; // Subcompulents have been prepared - bool singalStop; // Request stop signal + bool childReady; // Subcompulents have been prepared + bool singalStop; // Request stop signal HTaskInfo taskInfo; uint32_t refCount; diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index c96e738709e12e679479f6e013beb5bfdf678fa9..d9c524a3857aa69eb31295635f597694d9f528f8 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -87,9 +87,8 @@ void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB) // enable security char value[4] = "0"; Base::GetHdcProperty("ro.hdc.secure", value, 4); - if (!strcmp("1", value)) { - enableSecure = true; - } + string secure = value; + enableSecure = (Base::Trim(secure) == "1"); } // clang-format off @@ -188,23 +187,6 @@ bool HdcDaemon::HandDaemonAuth(HSession hSession, const uint32_t channelId, Sess return ret; } -bool HdcDaemon::CheckVersionMatch(string version) -{ - uint32_t nowMajor; - uint32_t nowMinor; - uint32_t inMajor; - uint32_t inMinor; - uint32_t ignore; - if (sscanf_s(VERSION_NUMBER.c_str(), "%d.%d.%d", &nowMajor, &nowMinor, &ignore) < 3 - || sscanf_s(VERSION_NUMBER.c_str(), "%d.%d.%d", &inMajor, &inMinor, &ignore) < 3) { - return false; - } - if (nowMajor != inMajor || nowMinor != inMinor) { - return false; - } - return true; -} - bool HdcDaemon::DaemonSessionHandshake(HSession hSession, const uint32_t channelId, uint8_t *payload, int payloadSize) { // session handshake step2 @@ -219,7 +201,6 @@ bool HdcDaemon::DaemonSessionHandshake(HSession hSession, const uint32_t channel return false; } if (handshake.authType == AUTH_NONE) { - // checkVersionMatch // daemon handshake 1st packet uint32_t unOld = hSession->sessionId; hSession->sessionId = handshake.sessionId; diff --git a/src/daemon/daemon.h b/src/daemon/daemon.h index 3e7e6f353f3b8385689d694913022e4e9db4716b..b25929f4747a8f1517715a82ab183d5d0b3df743 100644 --- a/src/daemon/daemon.h +++ b/src/daemon/daemon.h @@ -38,7 +38,6 @@ private: bool HandDaemonAuth(HSession hSession, const uint32_t channelId, SessionHandShake &handshake); void ClearInstanceResource(); bool DaemonSessionHandshake(HSession hSession, const uint32_t channelId, uint8_t *payload, int payloadSize); - bool CheckVersionMatch(string version); void TryStopInstance(); bool enableSecure; diff --git a/src/daemon/daemon_app.cpp b/src/daemon/daemon_app.cpp index 41f3a3fbd45db13d583bd2fe2182a5b2419341cd..a4bbfdc13a7c203e1d6586f77bf6f98a82baccc6 100644 --- a/src/daemon/daemon_app.cpp +++ b/src/daemon/daemon_app.cpp @@ -87,7 +87,7 @@ bool HdcDaemonApp::CommandDispatch(const uint16_t command, uint8_t *payload, con return ret; }; -void HdcDaemonApp::AsyncInstallFinish(bool finish, int64_t exitStatus, const string result) +bool HdcDaemonApp::AsyncInstallFinish(bool finish, int64_t exitStatus, const string result) { if (mode == APPMOD_INSTALL) { unlink(ctxNow.localPath.c_str()); @@ -105,6 +105,7 @@ void HdcDaemonApp::AsyncInstallFinish(bool finish, int64_t exitStatus, const str Base::WriteBinFile((UT_TMP_PATH + "/appinstall.result").c_str(), (uint8_t *)MESSAGE_SUCCESS.c_str(), MESSAGE_SUCCESS.size(), true); #endif + return true; } void HdcDaemonApp::PackageShell(bool installOrUninstall, const char *options, const char *package) diff --git a/src/daemon/daemon_app.h b/src/daemon/daemon_app.h index a2df188cdbdd8d90d1f9941e667af3cac286c404..5b1ec81d4f8d23ad40f0fcf95a05d0ef2c3ed514 100644 --- a/src/daemon/daemon_app.h +++ b/src/daemon/daemon_app.h @@ -27,7 +27,7 @@ public: private: void WhenTransferFinish(CtxFile *context); void PackageShell(bool installOrUninstall, const char *options, const char *package); - void AsyncInstallFinish(bool finish, int64_t exitStatus, const string result); + bool AsyncInstallFinish(bool finish, int64_t exitStatus, const string result); void Sideload(const char *pathOTA); AsyncCmd asyncCommand; diff --git a/src/daemon/daemon_unity.cpp b/src/daemon/daemon_unity.cpp index 9b4ba1e7f228b1f781e2060153dd2a19fd455643..712265773f3cc51d9831dd11730a6ea64b31338d 100644 --- a/src/daemon/daemon_unity.cpp +++ b/src/daemon/daemon_unity.cpp @@ -14,6 +14,11 @@ */ #include "daemon_unity.h" #include +#ifdef __MUSL__ +extern "C" { +#include "init_reboot.h" +} +#endif namespace Hdc { HdcDaemonUnity::HdcDaemonUnity(HTaskInfo hTaskInfo) @@ -40,27 +45,30 @@ bool HdcDaemonUnity::ReadyForRelease() return true; } -void HdcDaemonUnity::AsyncCmdOut(bool finish, int64_t exitStatus, const string result) +bool HdcDaemonUnity::AsyncCmdOut(bool finish, int64_t exitStatus, const string result) { #ifdef UNIT_TEST Base::WriteBinFile((UT_TMP_PATH + "/execute.result").c_str(), (uint8_t *)result.c_str(), result.size(), countUt++ == 0); #endif + bool ret = false; bool wantFinish = false; do { if (finish) { wantFinish = true; + ret = true; --refCount; break; } if (!SendToAnother(currentDataCommand, (uint8_t *)result.c_str(), result.size())) { - asyncCommand.DoRelease(); // will callback self, set wantFinish =true break; } + ret = true; } while (false); if (wantFinish) { TaskFinish(); } + return ret; } int HdcDaemonUnity::ExecuteShell(const char *shellCommand) @@ -169,6 +177,7 @@ bool HdcDaemonUnity::RemountDevice() bool HdcDaemonUnity::RebootDevice(const string &cmd) { sync(); +#ifndef __MUSL__ string propertyVal; if (!cmd.size()) { propertyVal = "reboot"; @@ -176,6 +185,15 @@ bool HdcDaemonUnity::RebootDevice(const string &cmd) 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 = "NoArgument"; + } + return DoReboot(reason.c_str()); +#endif } bool HdcDaemonUnity::SetDeviceRunMode(void *daemonIn, const char *cmd) diff --git a/src/daemon/daemon_unity.h b/src/daemon/daemon_unity.h index 6b82378118ac6032a497be2401b18242edc18bc0..c816487fda7f531b91e3c9ed739e1020596839cd 100644 --- a/src/daemon/daemon_unity.h +++ b/src/daemon/daemon_unity.h @@ -35,7 +35,7 @@ private: bool SetDeviceRunMode(void *daemonIn, const char *cmd); bool GetHiLog(const char *cmd); bool ListJdwpProcess(void *daemonIn); - void AsyncCmdOut(bool finish, int64_t exitStatus, const string result); + bool AsyncCmdOut(bool finish, int64_t exitStatus, const string result); const string rebootProperty = "sys.powerctl"; AsyncCmd asyncCommand; diff --git a/src/daemon/daemon_usb.cpp b/src/daemon/daemon_usb.cpp index 6c51b46e86e2a36edcaacada3aa5b7f20f8feda5..2cde3f624fcfbbd373ae0c886ef24ecb008a7da5 100644 --- a/src/daemon/daemon_usb.cpp +++ b/src/daemon/daemon_usb.cpp @@ -44,7 +44,8 @@ void HdcDaemonUSB::Stop() WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB Stop free main session finish"); } -string HdcDaemonUSB::GetDevPath(const std::string& path) { +string HdcDaemonUSB::GetDevPath(const std::string &path) +{ DIR *dir = ::opendir(path.c_str()); if (dir == nullptr) { WRITE_LOG(LOG_WARN, "%s: cannot open devpath: errno: %d", path.c_str(), errno); @@ -256,7 +257,8 @@ int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, uint8_t *data, } Finish: USBHead *pUSBHead = (USBHead *)data; - if (pUSBHead->option & USB_OPTION_TAIL) { + if ((pUSBHead->option & USB_OPTION_TAIL) || ret < 0) { + // tail or failed, dec Ref hSession->sendRef--; } if (ret < 0) { @@ -335,6 +337,9 @@ int HdcDaemonUSB::DispatchToWorkThread(const uint32_t sessionId, uint8_t *readBu return ERR_SESSION_NOFOUND; } } + if (hChildSession->childCleared) { + return ERR_SESSION_DEAD; + } if (!SendToHdcStream(hChildSession, reinterpret_cast(&hChildSession->dataPipe[STREAM_MAIN]), readBuf, readBytes)) { return ERR_IO_FAIL; diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 2e0b5faf9711f10b6ea86b27f59b9c16ac2dc442..542908e90d813fe0cdfd649d922d4661761534be 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -36,14 +36,16 @@ bool ForkChildCheck(int argc, const char *argv[]) // hdcd -fork #fork char modeSet[BUF_SIZE_TINY] = ""; Base::GetHdcProperty("persist.hdc.mode", modeSet, BUF_SIZE_TINY); - Base::PrintMessage("Background mode, persist.hdc.mode:%s", modeSet); - if (!strcmp(modeSet, "tcp")) { + Base::PrintMessage("Background mode, persist.hdc.mode:[%s]", modeSet); + string workMode = modeSet; + workMode = Base::Trim(workMode); + if (workMode == CMDSTR_TMODE_TCP) { WRITE_LOG(LOG_DEBUG, "Property enable TCP"); g_enableTcp = true; - } else if (!strcmp(modeSet, CMDSTR_TMODE_USB.c_str())) { + } else if (workMode == CMDSTR_TMODE_USB) { WRITE_LOG(LOG_DEBUG, "Property enable USB"); g_enableUsb = true; - } else if (!strcmp(modeSet, "all")) { + } else if (workMode == "all") { WRITE_LOG(LOG_DEBUG, "Property enable USB and TCP"); g_enableUsb = true; g_enableTcp = true; @@ -81,17 +83,16 @@ int BackgroundRun() string DaemonUsage() { string ret; - ret = "\n Harmony device connector(HDC) daemon side...\n\n" + ret = "\n Harmony device connector daemon(HDCD) Usage: hdcd [options]...\n\n" "\n" - "service mode commands:\n" - " hdcd - Daemon server mode\n" - " -b - Daemon server backgroundRun/fork mode\n" - "\n" - "paramenter mode commands:\n" + "general options:\n" " -h - Print help\n" " -l 0-5 - Print runtime log\n" - " -u - Enable USB mod\n" - " -t - Enable TCP mod\n"; + "\n" + "daemon mode options:\n" + " -b - Daemon run in background/fork mode\n" + " -u - Enable USB mode\n" + " -t - Enable TCP mode\n"; return ret; } @@ -99,7 +100,7 @@ bool GetDaemonCommandlineOptions(int argc, const char *argv[]) { int ch; // hdcd -l4 ... - WRITE_LOG(LOG_DEBUG, "Paraments mode"); + WRITE_LOG(LOG_DEBUG, "Fgcli mode"); // Both settings are running with parameters while ((ch = getopt(argc, (char *const *)argv, "utl:")) != -1) { switch (ch) { @@ -112,18 +113,18 @@ bool GetDaemonCommandlineOptions(int argc, const char *argv[]) Base::SetLogLevel(logLevel); break; } - case 'u': { // enable usb - Base::PrintMessage("Parament Enable USB"); + case 'u': { + Base::PrintMessage("Option USB enabled"); g_enableUsb = true; break; } - case 't': { // enable tcp - Base::PrintMessage("Parament Enable TCP"); + case 't': { + Base::PrintMessage("Option TCP enabled"); g_enableTcp = true; break; } default: - Base::PrintMessage("other option:%c\n", ch); + Base::PrintMessage("Option:%c non-supported!", ch); exit(0); break; } @@ -136,13 +137,13 @@ void NeedDropPriv() char droprootSet[BUF_SIZE_TINY] = ""; Base::GetHdcProperty("persist.hdc.root", droprootSet, BUF_SIZE_TINY); droprootSet[sizeof(droprootSet) - 1] = '\0'; - if (!strcmp(droprootSet, "1")) { + string rootMode = droprootSet; + if (Base::Trim(rootMode) == "1") { setuid(0); g_rootRun = true; WRITE_LOG(LOG_DEBUG, "Root run"); - } else if (!strcmp(droprootSet, "0")) { + } else if (Base::Trim(rootMode) == "0") { setuid(AID_SHELL); - // if need, will be more priv. operate } } } // namespace Hdc @@ -189,4 +190,4 @@ int main(int argc, const char *argv[]) } return 0; } -#endif \ No newline at end of file +#endif diff --git a/src/daemon/shell.cpp b/src/daemon/shell.cpp index 5e77e6f404118097fe0b00b29e476a065c160670..0d56b435526432297062026eadec906e43146203 100644 --- a/src/daemon/shell.cpp +++ b/src/daemon/shell.cpp @@ -13,8 +13,11 @@ * limitations under the License. */ #include "shell.h" +#include namespace Hdc { +std::mutex HdcShell::mutexPty; + HdcShell::HdcShell(HTaskInfo hTaskInfo) : HdcTaskBase(hTaskInfo) { @@ -40,21 +43,26 @@ bool HdcShell::ReadyForRelease() } delete childShell; childShell = nullptr; + if (fdPTY > 0) { + close(fdPTY); + } return true; } void HdcShell::StopTask() { + singalStop = true; WRITE_LOG(LOG_DEBUG, "HdcShell::StopTask"); if (!childReady) { return; } if (childShell) { - childShell->StopWork(); + childShell->StopWork(false, nullptr); } - close(fdPTY); kill(pidShell, SIGKILL); - runningProtect = false; + int status; + waitpid(pidShell, &status, 0); + WRITE_LOG(LOG_DEBUG, "StopTask, kill pidshell:%d", pidShell); }; bool HdcShell::SpecialSignal(uint8_t ch) @@ -79,8 +87,7 @@ bool HdcShell::CommandDispatch(const uint16_t command, uint8_t *payload, const i switch (command) { case CMD_SHELL_INIT: { // initial if (StartShell()) { - const string echo = "Shell not running"; - SendToAnother(CMD_KERNEL_ECHO_RAW, (uint8_t *)echo.c_str(), echo.size()); + LogMsg(MSG_FAIL, "Shell initialize failed"); } break; } @@ -100,20 +107,13 @@ bool HdcShell::CommandDispatch(const uint16_t command, uint8_t *payload, const i return true; } -int HdcShell::ChildForkDo(const char *devname, int ptm, const char *cmd, const char *arg0, const char *arg1) +int HdcShell::ChildForkDo(int pts, const char *cmd, const char *arg0, const char *arg1) { - setsid(); - int pts = open(devname, O_RDWR | O_CLOEXEC); - if (pts < 0) { - return -1; - } dup2(pts, STDIN_FILENO); dup2(pts, STDOUT_FILENO); dup2(pts, STDERR_FILENO); close(pts); - close(ptm); - - string text = Base::StringFormat("/proc/%d/oom_score_adj", getpid()); + string text = "/proc/self/oom_score_adj"; int fd = 0; if ((fd = open(text.c_str(), O_WRONLY)) >= 0) { write(fd, "0", 1); @@ -123,67 +123,95 @@ int HdcShell::ChildForkDo(const char *devname, int ptm, const char *cmd, const c if ((env = getenv("HOME")) && chdir(env) < 0) { } execl(cmd, cmd, arg0, arg1, nullptr); + _Exit(1); + return 0; +} + +int HdcShell::ShellFork(const char *cmd, const char *arg0, const char *arg1) +{ + pid_t pid; + pid = fork(); + if (pid < 0) { + WRITE_LOG(LOG_DEBUG, "Fork shell failed:%s", strerror(errno)); + return -4; + } + if (pid == 0) { + HdcShell::mutexPty.unlock(); + setsid(); + close(ptm); + int pts = 0; + if ((pts = open(devname, O_RDWR | O_CLOEXEC)) < 0) { + return -1; + } + ChildForkDo(pts, cmd, arg0, arg1); + // proc finish + } else { + return pid; + } return 0; } int HdcShell::CreateSubProcessPTY(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) { - char devname[BUF_SIZE_TINY]; - int ptm = open(devPTMX.c_str(), O_RDWR | O_CLOEXEC); + ptm = open(devPTMX.c_str(), O_RDWR | O_CLOEXEC); if (ptm < 0) { WRITE_LOG(LOG_DEBUG, "Cannot open ptmx, error:%s", strerror(errno)); - return -1; + return ERR_FILE_OPEN; } if (grantpt(ptm) || unlockpt(ptm)) { WRITE_LOG(LOG_DEBUG, "Cannot open2 ptmx, error:%s", strerror(errno)); close(ptm); - return -2; + return ERR_API_FAIL; } - fcntl(ptm, F_SETFD, FD_CLOEXEC); if (ptsname_r(ptm, devname, sizeof(devname)) != 0) { WRITE_LOG(LOG_DEBUG, "Trouble with ptmx, error:%s", strerror(errno)); close(ptm); - return -3; - } - *pid = fork(); - if (*pid < 0) { - WRITE_LOG(LOG_DEBUG, "Fork shell failed:%s", strerror(errno)); - close(ptm); - return -4; - } - if (*pid == 0) { - int childRet = ChildForkDo(devname, ptm, cmd, arg0, arg1); - exit(childRet); - } else { - return ptm; + return ERR_API_FAIL; } + *pid = ShellFork(cmd, arg0, arg1); + return ptm; } bool HdcShell::FinishShellProc(const void *context, const bool result, const string exitMsg) { + WRITE_LOG(LOG_DEBUG, "FinishShellProc finish"); HdcShell *thisClass = (HdcShell *)context; thisClass->TaskFinish(); - WRITE_LOG(LOG_DEBUG, "FinishShellProc finish"); + --thisClass->refCount; return true; }; bool HdcShell::ChildReadCallback(const void *context, uint8_t *buf, const int size) { HdcShell *thisClass = (HdcShell *)context; - if (!thisClass->SendToAnother(CMD_KERNEL_ECHO_RAW, (uint8_t *)buf, size)) { - thisClass->TaskFinish(); - } - return true; + return thisClass->SendToAnother(CMD_KERNEL_ECHO_RAW, (uint8_t *)buf, size); }; int HdcShell::StartShell() { WRITE_LOG(LOG_DEBUG, "StartShell..."); - fdPTY = CreateSubProcessPTY(Base::GetShellPath().c_str(), "-", 0, &pidShell); - childShell = new HdcFileDescriptor(loopTask, fdPTY, this, ChildReadCallback, FinishShellProc); - childShell->StartWork(); - childReady = true; - runningProtect = true; - return 0; + int ret = 0; + HdcShell::mutexPty.lock(); + do { + if ((fdPTY = CreateSubProcessPTY(Base::GetShellPath().c_str(), "-", 0, &pidShell)) < 0) { + ret = ERR_PROCESS_SUB_FAIL; + break; + } + childShell = new HdcFileDescriptor(loopTask, fdPTY, this, ChildReadCallback, FinishShellProc); + if (!childShell->StartWork()) { + ret = ERR_API_FAIL; + break; + } + childReady = true; + ++refCount; + } while (false); + if (ret != ERR_SUCCESS) { + if (pidShell > 0) { + kill(pidShell, SIGKILL); + } + // fdPTY close by ~clase + } + HdcShell::mutexPty.unlock(); + return ret; } } // namespace Hdc \ No newline at end of file diff --git a/src/daemon/shell.h b/src/daemon/shell.h index 51a80379a9b96fd37177f1d770f2dd5c9b5ef8e5..1c2cda8328987fc9028fa0b624ff6c159a7806f8 100644 --- a/src/daemon/shell.h +++ b/src/daemon/shell.h @@ -15,6 +15,7 @@ #ifndef HDC_SHELL_H #define HDC_SHELL_H #include "daemon_common.h" +#include namespace Hdc { class HdcShell : public HdcTaskBase { @@ -26,17 +27,21 @@ public: bool ReadyForRelease(); private: - int StartShell(); - HdcFileDescriptor *childShell; - int CreateSubProcessPTY(const char *cmd, const char *arg0, const char *arg1, pid_t *pid); 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 ChildForkDo(const char *devname, int ptm, const char *cmd, const char *arg0, const char *arg1); + int StartShell(); + int CreateSubProcessPTY(const char *cmd, const char *arg0, const char *arg1, pid_t *pid); + int ChildForkDo(int pts, const char *cmd, const char *arg0, const char *arg1); bool SpecialSignal(uint8_t ch); + int ShellFork(const char *cmd, const char *arg0, const char *arg1); + HdcFileDescriptor *childShell; pid_t pidShell = 0; int fdPTY; + int ptm = 0; const string devPTMX = "/dev/ptmx"; + static std::mutex mutexPty; + char devname[BUF_SIZE_SMALL] = ""; }; } // namespace Hdc #endif \ No newline at end of file diff --git a/src/host/host_unity.cpp b/src/host/host_unity.cpp index ed5d0532d4c33632cde03b5355b8a3bdee3ae5cd..276682ebf90697f6f5068974add29470bc1b9d15 100644 --- a/src/host/host_unity.cpp +++ b/src/host/host_unity.cpp @@ -45,7 +45,7 @@ void HdcHostUnity::StopTask() return; } if (opContext.enableLog) { - runningProtect = true; + ++refCount; opContext.fsClose.data = &opContext; uv_fs_close(loopTask, &opContext.fsClose, opContext.fileLog, OnFileClose); } @@ -57,7 +57,7 @@ void HdcHostUnity::OnFileClose(uv_fs_t *req) ContextUnity *context = (ContextUnity *)req->data; HdcHostUnity *thisClass = (HdcHostUnity *)context->thisClass; context->hasFilelogClosed = true; - thisClass->runningProtect = false; + --thisClass->refCount; return; } @@ -80,10 +80,7 @@ void HdcHostUnity::OnFileIO(uv_fs_t *req) HdcHostUnity *thisClass = (HdcHostUnity *)context->thisClass; uint8_t *bufIO = contextIO->bufIO; uv_fs_req_cleanup(req); - --context->ref; - if (!context->ref) { - thisClass->runningProtect = false; - } + --thisClass->refCount; while (true) { if (req->result <= 0) { if (req->result < 0) { @@ -115,8 +112,7 @@ bool HdcHostUnity::AppendLocalLog(const char *bufLog, const int sizeLog) contextIO->bufIO = buf; contextIO->context = &opContext; req->data = contextIO; - ++opContext.ref; - runningProtect = true; + ++refCount; if (memcpy_s(buf, sizeLog, bufLog, sizeLog)) { } diff --git a/src/host/host_unity.h b/src/host/host_unity.h index 1c0115d52cdcb81a9e2f94e19a43223fa27c69a8..e4cb08f8628e5b36c1c46753e515ef097076f223 100644 --- a/src/host/host_unity.h +++ b/src/host/host_unity.h @@ -31,7 +31,6 @@ private: uv_file fileLog; uint64_t fileIOIndex; uint64_t fileBufIndex; - int ref; bool hasFilelogClosed; uv_fs_t fsClose; HdcHostUnity *thisClass; diff --git a/src/host/host_usb.cpp b/src/host/host_usb.cpp index 7420a3dd60c5fbf5c022f8f276009073cd8295c1..b681656391d8c411f9b059c8a1e3706c1ed6d28c 100644 --- a/src/host/host_usb.cpp +++ b/src/host/host_usb.cpp @@ -115,7 +115,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; - uv_timer_start(waitTimeDoCmd, hdcServer->UsbPreConnect, 10, 100); + uv_timer_start(waitTimeDoCmd, hdcServer->UsbPreConnect, 0, 3000); mapIgnoreDevice[sn] = HOST_USB_REGISTER; ret = true; libusb_release_interface(hUSB->devHandle, hUSB->interfaceNumber); diff --git a/src/host/main.cpp b/src/host/main.cpp index 729ad3814916ba90e9d1a4492df54d8cd2eb9573..80d8c2caef06c6684fc4e26681cb4c2181861ac5 100644 --- a/src/host/main.cpp +++ b/src/host/main.cpp @@ -142,7 +142,7 @@ int RunClientMode(string &commands, string &serverListenString, string &connectK { uv_loop_t loopMain; uv_loop_init(&loopMain); - HdcClient client(false, DEFAULT_SERVER_ADDR, &loopMain); + HdcClient client(false, serverListenString, &loopMain); if (!commands.size()) { Base::PrintMessage("Unknow operation command..."); TranslateCommand::Usage(); @@ -154,8 +154,10 @@ int RunClientMode(string &commands, string &serverListenString, string &connectK client.CtrlServiceWork(commands.c_str()); return 0; } - if (isPullServer && Base::ProgramMutex(SERVER_NAME.c_str(), true) == 0) { - HdcServer::CheckToPullUptrServer(serverListenString.c_str()); + if (isPullServer && serverListenString == DEFAULT_SERVER_ADDR + && Base::ProgramMutex(SERVER_NAME.c_str(), true) == 0) { + // default pullup, just default listenstr.If want to customer listen-string, please use 'hdc -m -s lanip:port' + HdcServer::CheckToPullUptrServer(DEFAULT_SERVER_ADDR.c_str()); uv_sleep(300); // give time to start serverForClient,at least 200ms } client.Initial(connectKey); @@ -175,6 +177,10 @@ bool ParseServerListenString(string &serverListenString, char *optarg) } char *p = strchr(buf, ':'); if (!p) { // Only port + if (strlen(buf) > 5) { + Base::PrintMessage("The port-string's length must < 5"); + return false; + } int port = atoi(buf); if (port <= 0 || port > MAX_IP_PORT) { Base::PrintMessage("Port range incorrect"); @@ -279,9 +285,8 @@ bool GetCommandlineOptions(int optArgc, const char *optArgv[]) } #ifndef UNIT_TEST -// hdc -l4 -m -// hdc -l4 discover / hdc -l4 connect 127.0.0.1:10178 -// hdc -l4 -t 127.0.0.1:10178 shell id +// hdc -l4 -m -s ip:port|hdc -l4 -m +// hdc -l4 - s ip:port list targets int main(int argc, const char *argv[]) { string options; @@ -295,7 +300,7 @@ int main(int argc, const char *argv[]) return 0; } if (g_isServerMode) { - // -m server.Run alone in the background + // -m server.Run alone in the background, no -s will be listen loopback address, 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 4795c3aaf662fa586a6dfd550d64bb92142df338..83173b2a26811489fe9967ea4fb7136f35ebca90 100644 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -76,7 +76,6 @@ bool HdcServer::Initial(const char *listenString) WRITE_LOG(LOG_FATAL, "Class init failed"); return false; } - (static_cast(clsServerForClient))->Initial(); clsUSBClt->Initial(); return true; @@ -427,11 +426,13 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const } if (!hChannel) { if (command == CMD_KERNEL_CHANNEL_CLOSE) { - // Saturated release. Daemon close channel and want to notify server close channel also, but it may has been + // Daemon close channel and want to notify server close channel also, but it may has been // closed by herself - return true; + } else { + // Client may be ctrl+c and Server remove channel. notify server async } - return false; + Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); + return true; } switch (command) { case CMD_KERNEL_ECHO_RAW: { // Native shell data output @@ -551,10 +552,10 @@ void HdcServer::UsbPreConnect(uv_timer_t *handle) HSession hSession = (HSession)handle->data; bool stopLoop = false; HdcServer *hdcServer = (HdcServer *)hSession->classInstance; - const int usbConnectRetryMax = 100; + const int usbConnectRetryMax = 5; while (true) { WRITE_LOG(LOG_DEBUG, "HdcServer::UsbPreConnect"); - if (++hSession->hUSB->retryCount > usbConnectRetryMax) { // max 10s + if (++hSession->hUSB->retryCount > usbConnectRetryMax) { // max 15s hdcServer->FreeSession(hSession->sessionId); stopLoop = true; break; diff --git a/src/host/server_for_client.cpp b/src/host/server_for_client.cpp index cee7dd3f784e23a1eff53a404fc1b527a02b49be..f8b4db6e860afab43240b4549686015c945bd572 100644 --- a/src/host/server_for_client.cpp +++ b/src/host/server_for_client.cpp @@ -114,7 +114,7 @@ void HdcServerForClient::EchoClient(HChannel hChannel, MessageLevel level, const string log = logInfo + Base::StringFormat(msg, vaArgs); va_end(vaArgs); if (log.back() != '\n') { - log += "\n"; + log += "\r\n"; } Send(hChannel->channelId, (uint8_t *)log.c_str(), log.size()); }