From 5c9f958e209472c1888ffeb5a9cc2868753989e8 Mon Sep 17 00:00:00 2001 From: faithwang Date: Tue, 26 Jul 2022 21:17:21 +0800 Subject: [PATCH] add remote install app Signed-off-by: faithwang --- src/common/define.h | 2 +- src/common/define_plus.h | 10 +++- src/common/file.cpp | 2 +- src/host/client.cpp | 84 +++++++++++++++++++++++----------- src/host/client.h | 8 +++- src/host/host_common.h | 2 +- src/host/main.cpp | 5 +- src/host/server.cpp | 11 +++-- src/host/server_for_client.cpp | 46 ++++++++++++------- src/host/server_for_client.h | 1 + 10 files changed, 117 insertions(+), 54 deletions(-) diff --git a/src/common/define.h b/src/common/define.h index b814f2a8..6e780a24 100755 --- a/src/common/define.h +++ b/src/common/define.h @@ -107,7 +107,7 @@ constexpr uint16_t MAX_UART_SIZE_IOBUF = 4096; // MAX_SIZE_IOBUF; const string CMDSTR_TMODE_TCP = "tcp"; const string CMDSTR_FILE_SEND = "file send"; const string CMDSTR_FILE_RECV = "file recv"; -const string CMDSTR_FILE_REMOTE_PARAMETER = "-r"; +const string CMDSTR_REMOTE_PARAMETER = "remote"; const string CMDSTR_FORWARD_FPORT = "fport"; const string CMDSTR_FORWARD_RPORT = "rport"; const string CMDSTR_APP_INSTALL = "install"; diff --git a/src/common/define_plus.h b/src/common/define_plus.h index 799cf3f9..9785aaf1 100755 --- a/src/common/define_plus.h +++ b/src/common/define_plus.h @@ -445,6 +445,12 @@ struct HdcSession { }; using HSession = struct HdcSession *; +enum class RemoteType { + REMOTE_NONE = 0, + REMOTE_FILE = 1, + REMOTE_APP = 2, +}; + struct HdcChannel { void *clsChannel; // ptr Class of serverForClient or client uint32_t channelId; @@ -473,8 +479,8 @@ struct HdcChannel { char bufStd[128]; bool isCheck = false; string key; - bool bFileSend = false; - bool bFileFromClient = false; + RemoteType remote = RemoteType::REMOTE_NONE; + bool fromClient = false; }; using HChannel = struct HdcChannel *; diff --git a/src/common/file.cpp b/src/common/file.cpp index 258e0514..cd495c55 100644 --- a/src/common/file.cpp +++ b/src/common/file.cpp @@ -93,7 +93,7 @@ bool HdcFile::SetMasterParameters(CtxFile *context, const char *command, int arg } else if (argv[i] == CMD_OPTION_MODE_SYNC) { context->fileModeSync = true; ++srcArgvIndex; - } else if (argv[i] == CMDSTR_FILE_REMOTE_PARAMETER) { + } else if (argv[i] == CMDSTR_REMOTE_PARAMETER) { ++srcArgvIndex; } else if (argv[i][0] == '-') { LogMsg(MSG_FAIL, "Unknown file option: %s", argv[i]); diff --git a/src/host/client.cpp b/src/host/client.cpp index bf5bf143..1f08e4b8 100755 --- a/src/host/client.cpp +++ b/src/host/client.cpp @@ -186,7 +186,10 @@ int HdcClient::ExecuteCommand(const string &commandIn) if (!strncmp(commandIn.c_str(), CMDSTR_FILE_SEND.c_str(), CMDSTR_FILE_SEND.size()) || !strncmp(commandIn.c_str(), CMDSTR_FILE_RECV.c_str(), CMDSTR_FILE_RECV.size())) { WRITE_LOG(LOG_DEBUG, "Set file send mode"); - channel->bFileSend = true; + channel->remote = RemoteType::REMOTE_FILE; + } + if (!strncmp(commandIn.c_str(), CMDSTR_APP_INSTALL.c_str(), CMDSTR_APP_INSTALL.size())) { + channel->remote = RemoteType::REMOTE_APP; } command = commandIn; connectKey = AutoConnectKey(command, connectKey); @@ -423,44 +426,73 @@ int HdcClient::ReadChannel(HChannel hChannel, uint8_t *buf, const int bytesIO) uint16_t command = 0; bool bOffset = false; if (bytesIO >= static_cast(sizeof(uint16_t))) { - command = *reinterpret_cast(buf); - bOffset = (command == CMD_CHECK_SERVER) - || (command == CMD_FILE_INIT) - || (command == CMD_FILE_CHECK) - || (command == CMD_FILE_BEGIN) - || (command == CMD_FILE_DATA) - || (command == CMD_FILE_FINISH) - || (command == CMD_FILE_MODE) - || (command == CMD_DIR_MODE); - } - if ((isCheckVersionCmd || hChannel->bFileSend) && bOffset) { - if (CMD_CHECK_SERVER == command) { - WRITE_LOG(LOG_DEBUG, "recieve CMD_CHECK_VERSION command"); - string version(reinterpret_cast(buf + sizeof(uint16_t)), bytesIO - sizeof(uint16_t)); - fprintf(stdout, "Client version:%s, server version:%s\n", Base::GetVersion().c_str(), version.c_str()); - fflush(stdout); - return 0; - } else { - // file command + command = *reinterpret_cast(buf); + bOffset = IsOffset(command); + } + if (CMD_CHECK_SERVER == command && isCheckVersionCmd) { + WRITE_LOG(LOG_DEBUG, "recieve CMD_CHECK_VERSION command"); + string version(reinterpret_cast(buf + sizeof(uint16_t)), bytesIO - sizeof(uint16_t)); + fprintf(stdout, "Client version:%s, server version:%s\n", Base::GetVersion().c_str(), version.c_str()); + fflush(stdout); + return 0; + } + if (hChannel->remote > RemoteType::REMOTE_NONE && bOffset) { + // file command + if (hChannel->remote == RemoteType::REMOTE_FILE) { if (fileTask == nullptr) { - HTaskInfo hTaskInfo = new TaskInformation(); - hTaskInfo->channelId = hChannel->channelId; - hTaskInfo->runLoop = loopMain; - hTaskInfo->serverOrDaemon = true; + HTaskInfo hTaskInfo = GetRemoteTaskInfo(hChannel); hTaskInfo->masterSlave = (command == CMD_FILE_INIT); - hTaskInfo->channelTask = true; - hTaskInfo->channelClass = this; fileTask = std::make_unique(hTaskInfo); } if (!fileTask->CommandDispatch(command, buf + sizeof(uint16_t), bytesIO - sizeof(uint16_t))) { fileTask->TaskFinish(); } } + // app command + if (hChannel->remote == RemoteType::REMOTE_APP) { + if (appTask == nullptr) { + HTaskInfo hTaskInfo = GetRemoteTaskInfo(hChannel); + hTaskInfo->masterSlave = (command == CMD_APP_INIT); + appTask = std::make_unique(hTaskInfo); + } + if (!appTask->CommandDispatch(command, buf + sizeof(uint16_t), bytesIO - sizeof(uint16_t))) { + appTask->TaskFinish(); + } + } return 0; } + string s(reinterpret_cast(buf), bytesIO); fprintf(stdout, "%s", s.c_str()); fflush(stdout); return 0; +} + +bool HdcClient::IsOffset(uint16_t command) +{ + return (command == CMD_CHECK_SERVER) || + (command == CMD_FILE_INIT) || + (command == CMD_FILE_CHECK) || + (command == CMD_FILE_BEGIN) || + (command == CMD_FILE_DATA) || + (command == CMD_FILE_FINISH) || + (command == CMD_FILE_MODE) || + (command == CMD_DIR_MODE) || + (command == CMD_APP_INIT) || + (command == CMD_APP_CHECK) || + (command == CMD_APP_BEGIN) || + (command == CMD_APP_DATA) || + (command == CMD_APP_FINISH); +} + +HTaskInfo HdcClient::GetRemoteTaskInfo(HChannel hChannel) +{ + HTaskInfo hTaskInfo = new TaskInformation(); + hTaskInfo->channelId = hChannel->channelId; + hTaskInfo->runLoop = loopMain; + hTaskInfo->serverOrDaemon = true; + hTaskInfo->channelTask = true; + hTaskInfo->channelClass = this; + return hTaskInfo; }; } // namespace Hdc diff --git a/src/host/client.h b/src/host/client.h index 530a7c8d..78cfa916 100755 --- a/src/host/client.h +++ b/src/host/client.h @@ -17,6 +17,9 @@ #include "host_common.h" namespace Hdc { +// Avoiding Circular dependency +class HdcHostApp; + class HdcClient : public HdcChannelBase { public: HdcClient(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn, bool checkVersion = false); @@ -42,6 +45,8 @@ private: void BindLocalStd(HChannel hChannel); void ModifyTty(bool setOrRestore, uv_tty_t *tty); void NotifyInstanceChannelFree(HChannel hChannel) override; + bool IsOffset(uint16_t command); + HTaskInfo GetRemoteTaskInfo(HChannel hChannel); #ifndef _WIN32 termios terminalState; @@ -54,7 +59,8 @@ private: uv_check_t ctrlServerWork; HChannel channel; std::unique_ptr fileTask; + std::unique_ptr appTask; bool isCheckVersionCmd = false; }; } // namespace Hdc -#endif \ No newline at end of file +#endif diff --git a/src/host/host_common.h b/src/host/host_common.h index 9064300f..8b9f5c80 100644 --- a/src/host/host_common.h +++ b/src/host/host_common.h @@ -36,4 +36,4 @@ #include "host_unity.h" // clang-format on -#endif \ No newline at end of file +#endif diff --git a/src/host/main.cpp b/src/host/main.cpp index 37c2fd89..7a93c767 100755 --- a/src/host/main.cpp +++ b/src/host/main.cpp @@ -116,12 +116,11 @@ void AppendCwdWhenTransfer(string &outCommand) if (path[strlen(path) - 1] != Base::GetPathSep()) { path[strlen(path)] = Base::GetPathSep(); } + outCommand += outCommand.size() ? " " : ""; + outCommand += CMDSTR_REMOTE_PARAMETER; outCommand += outCommand.size() ? " -cwd " : "-cwd "; string utf8Path = Base::UnicodeToUtf8(path, true); outCommand += Base::StringFormat("\"%s\"", utf8Path.c_str()); - outCommand += " "; - // add default parameter to command - outCommand += CMDSTR_FILE_REMOTE_PARAMETER; } int SplitOptionAndCommand(int argc, const char **argv, string &outOption, string &outCommand) diff --git a/src/host/server.cpp b/src/host/server.cpp index 9966c352..f288f00c 100755 --- a/src/host/server.cpp +++ b/src/host/server.cpp @@ -575,9 +575,14 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const case CMD_FILE_FINISH: case CMD_FILE_MODE: case CMD_DIR_MODE: - if (hChannel->bFileFromClient) { - // server directly passthrough file command to client if remote file mode, else go default - WRITE_LOG(LOG_INFO, "server directly passthrough file command to client command:%u", channelId); + case CMD_APP_INIT: + case CMD_APP_CHECK: + case CMD_APP_BEGIN: + case CMD_APP_DATA: + case CMD_APP_FINISH: + if (hChannel->fromClient) { + // server directly passthrough app command to client if remote file mode, else go default + WRITE_LOG(LOG_DEBUG, "command passthrough to client command:%u channelId:%u", command, channelId); sfc->SendCommandToClient(hChannel, command, payload, payloadSize); break; } diff --git a/src/host/server_for_client.cpp b/src/host/server_for_client.cpp index d2535f52..bd737429 100755 --- a/src/host/server_for_client.cpp +++ b/src/host/server_for_client.cpp @@ -463,28 +463,19 @@ bool HdcServerForClient::TaskCommand(HChannel hChannel, void *formatCommandInput { TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput; HdcServer *ptrServer = (HdcServer *)clsServer; - int sizeSend = formatCommand->parameters.size(); string cmdFlag; uint8_t sizeCmdFlag = 0; if (CMD_FILE_INIT == formatCommand->cmdFlag) { cmdFlag = "send "; sizeCmdFlag = 5; // 5: cmdFlag send size - hChannel->bFileSend = true; - int argc = 0; - char **argv = Base::SplitCommandToArgs(formatCommand->parameters.c_str(), &argc); - for (int i = 0; i < argc - CMD_ARG1_COUNT; i++) { - if (argv[i] == CMDSTR_FILE_REMOTE_PARAMETER) { - hChannel->bFileFromClient = true; - WRITE_LOG(LOG_INFO, "defaul mode file from client"); - break; - } - } + HandleRemote(hChannel, formatCommand->parameters, RemoteType::REMOTE_FILE); } else if (CMD_FORWARD_INIT == formatCommand->cmdFlag) { cmdFlag = "fport "; sizeCmdFlag = 6; // 6: cmdFlag fport size } else if (CMD_APP_INIT == formatCommand->cmdFlag) { cmdFlag = "install "; sizeCmdFlag = 8; // 8: cmdFlag install size + HandleRemote(hChannel, formatCommand->parameters, RemoteType::REMOTE_APP); } else if (CMD_APP_UNINSTALL == formatCommand->cmdFlag) { cmdFlag = "uninstall "; sizeCmdFlag = 10; // 10: cmdFlag uninstall size @@ -501,16 +492,18 @@ bool HdcServerForClient::TaskCommand(HChannel hChannel, void *formatCommandInput cmdFlag = "flash "; sizeCmdFlag = 6; // 6: cmdFlag flash size } + int sizeSend = formatCommand->parameters.size(); 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; } - if ((CMD_FILE_INIT == formatCommand->cmdFlag) && hChannel->bFileFromClient) { - // file send from client mode, CMD_FILE_INIT command send back to client - WRITE_LOG(LOG_INFO, "file send from client mode, CMD_FILE_INIT command send back to client"); - SendChannelWithCmd(hChannel, CMD_FILE_INIT, payload, sizeSend - sizeCmdFlag); + if ((CMD_FILE_INIT == formatCommand->cmdFlag || CMD_APP_INIT == formatCommand->cmdFlag) + && hChannel->fromClient) { + // remote client mode, CMD_FILE_INIT and CMD_APP_INIT command send back to client + WRITE_LOG(LOG_DEBUG, "command send back to remote client channelId:%u", hChannel->channelId); + SendChannelWithCmd(hChannel, formatCommand->cmdFlag, payload, sizeSend - sizeCmdFlag); return false; } ptrServer->DispatchTaskData(hSession, hChannel->channelId, formatCommand->cmdFlag, payload, @@ -522,6 +515,27 @@ bool HdcServerForClient::TaskCommand(HChannel hChannel, void *formatCommandInput return true; } +void HdcServerForClient::HandleRemote(HChannel hChannel, string ¶meters, RemoteType flag) +{ + hChannel->remote = flag; + int argc = 0; + char **argv = Base::SplitCommandToArgs(parameters.c_str(), &argc); + for (int i = 0; i < argc; i++) { + if (argv[i] == CMDSTR_REMOTE_PARAMETER) { + hChannel->fromClient = true; + WRITE_LOG(LOG_DEBUG, "remote client mode channelId:%u", hChannel->channelId); + break; + } + } + if (hChannel->fromClient) { + string remote = CMDSTR_REMOTE_PARAMETER + " "; + if (parameters.find(remote) != std::string::npos) { + parameters.replace(parameters.find(remote), remote.size(), ""); + WRITE_LOG(LOG_DEBUG, "parameters: %s", parameters.c_str()); + } + } +} + bool HdcServerForClient::DoCommandRemote(HChannel hChannel, void *formatCommandInput) { TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput; @@ -710,7 +724,7 @@ int HdcServerForClient::ReadChannel(HChannel hChannel, uint8_t *bufPtr, const in } uint16_t command = *reinterpret_cast(bufPtr); - if (command != 0 && hChannel->bFileSend) { + if (command != 0 && (hChannel->remote > RemoteType::REMOTE_NONE)) { // server directly passthrough file command to daemon if (!SendToDaemon(hChannel, command, bufPtr + sizeof(uint16_t), bytesIO - sizeof(uint16_t))) { WRITE_LOG(LOG_FATAL, "Client ReadChannel : direct send to daemon failed"); diff --git a/src/host/server_for_client.h b/src/host/server_for_client.h index f04e4cf0..daf61463 100755 --- a/src/host/server_for_client.h +++ b/src/host/server_for_client.h @@ -51,6 +51,7 @@ private: bool GetAnyTarget(HChannel hChannel); bool RemoveForward(HChannel hChannel, const char *parameterString); bool TaskCommand(HChannel hChannel, void *formatCommandInput); + void HandleRemote(HChannel hChannel, string ¶meters, RemoteType flag); int ChannelHandShake(HChannel hChannel, uint8_t *bufPtr, const int bytesIO); bool ChannelSendSessionCtrlMsg(vector &ctrlMsg, uint32_t sessionId) override; HSession FindAliveSession(uint32_t sessionId); -- Gitee