Fetch the repository succeeded.
This action will force synchronization from OpenHarmony/developtools_hdc, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
/*
* 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.
*/
#include "client.h"
#ifndef TEST_HASH
#include "hdc_hash_gen.h"
#endif
#include "host_updater.h"
#include "server.h"
#include "file.h"
std::map<std::string, std::string> g_lists;
bool g_show = true;
namespace Hdc {
bool g_terminalStateChange = false;
HdcClient::HdcClient(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn, bool checkVersion)
: HdcChannelBase(serverOrClient, addrString, loopMainIn)
{
MallocChannel(&channel); // free by logic
debugRetryCount = 0;
#ifndef _WIN32
Base::ZeroStruct(terminalState);
#endif
isCheckVersionCmd = checkVersion;
}
HdcClient::~HdcClient()
{
#ifndef _WIN32
if (g_terminalStateChange) {
tcsetattr(STDIN_FILENO, TCSAFLUSH, &terminalState);
}
#endif
Base::TryCloseLoop(loopMain, "ExecuteCommand finish");
}
void HdcClient::NotifyInstanceChannelFree(HChannel hChannel)
{
if (bShellInteractive) {
WRITE_LOG(LOG_DEBUG, "Restore tty");
ModifyTty(false, &hChannel->stdinTty);
}
}
uint32_t HdcClient::GetLastPID()
{
char bufPath[BUF_SIZE_MEDIUM] = "";
size_t size = BUF_SIZE_MEDIUM;
char pidBuf[BUF_SIZE_TINY] = "";
// get running pid to kill it
if (uv_os_tmpdir(bufPath, &size) < 0) {
WRITE_LOG(LOG_FATAL, "Tmppath failed");
return 0;
}
string path = Base::StringFormat("%s%c.%s.pid", bufPath, Base::GetPathSep(), SERVER_NAME.c_str());
Base::ReadBinFile(path.c_str(), reinterpret_cast<void **>(&pidBuf), BUF_SIZE_TINY);
int pid = atoi(pidBuf); // pid maybe 0
return pid;
}
bool HdcClient::StartKillServer(const char *cmd, bool startOrKill)
{
bool isNowRunning = Base::ProgramMutex(SERVER_NAME.c_str(), true) != 0;
const int signNum = 9;
uint32_t pid = GetLastPID();
if (!pid) {
WRITE_LOG(LOG_FATAL, "StartKillServer pid is 0");
return false;
}
if (startOrKill) {
if (isNowRunning) {
// already running
if (!strstr(cmd, " -r")) {
return true;
}
if (pid) {
int rc = uv_kill(pid, signNum);
WRITE_LOG(LOG_DEBUG, "uv_kill rc:%d", rc);
}
}
HdcServer::PullupServer(channelHostPort.c_str());
} else {
if (isNowRunning && pid) {
int rc = uv_kill(pid, signNum);
if (rc == 0) {
Base::PrintMessage("Kill server finish");
} else {
constexpr int size = 1024;
char buf[size] = { 0 };
uv_strerror_r(rc, buf, size);
Base::PrintMessage("Kill server failed %s", buf);
}
}
// already running
if (!strstr(cmd, " -r")) {
return true;
}
HdcServer::PullupServer(channelHostPort.c_str());
}
return true;
}
void HdcClient::DoCtrlServiceWork(uv_check_t *handle)
{
HdcClient *thisClass = (HdcClient *)handle->data;
string &strCmd = thisClass->command;
if (!strncmp(thisClass->command.c_str(), CMDSTR_SERVICE_START.c_str(), CMDSTR_SERVICE_START.size())) {
thisClass->StartKillServer(thisClass->command.c_str(), true);
} else if (!strncmp(thisClass->command.c_str(), CMDSTR_SERVICE_KILL.c_str(), CMDSTR_SERVICE_KILL.size())) {
thisClass->StartKillServer(thisClass->command.c_str(), false);
// clang-format off
} else if (!strncmp(thisClass->command.c_str(), CMDSTR_GENERATE_KEY.c_str(), CMDSTR_GENERATE_KEY.size()) &&
strCmd.find(" ") != std::string::npos) {
// clang-format on
string keyPath = strCmd.substr(CMDSTR_GENERATE_KEY.size() + 1, strCmd.size());
HdcAuth::GenerateKey(keyPath.c_str());
} else {
Base::PrintMessage("Unknown command");
}
Base::TryCloseHandle((const uv_handle_t *)handle);
}
int HdcClient::CtrlServiceWork(const char *commandIn)
{
command = commandIn;
ctrlServerWork.data = this;
uv_check_init(loopMain, &ctrlServerWork);
uv_check_start(&ctrlServerWork, DoCtrlServiceWork);
uv_run(loopMain, UV_RUN_NOWAIT);
return 0;
}
string HdcClient::AutoConnectKey(string &doCommand, const string &preConnectKey) const
{
string key = preConnectKey;
bool isNoTargetCommand = false;
vector<string> vecNoConnectKeyCommand;
vecNoConnectKeyCommand.push_back(CMDSTR_SOFTWARE_VERSION);
vecNoConnectKeyCommand.push_back(CMDSTR_SOFTWARE_HELP);
vecNoConnectKeyCommand.push_back(CMDSTR_TARGET_DISCOVER);
vecNoConnectKeyCommand.push_back(CMDSTR_LIST_TARGETS);
vecNoConnectKeyCommand.push_back(CMDSTR_CHECK_SERVER);
vecNoConnectKeyCommand.push_back(CMDSTR_CONNECT_TARGET);
vecNoConnectKeyCommand.push_back(CMDSTR_CHECK_DEVICE);
vecNoConnectKeyCommand.push_back(CMDSTR_WAIT_FOR);
vecNoConnectKeyCommand.push_back(CMDSTR_KILL_SERVER);
vecNoConnectKeyCommand.push_back(CMDSTR_FORWARD_FPORT + " ls");
vecNoConnectKeyCommand.push_back(CMDSTR_FORWARD_FPORT + " rm");
for (string v : vecNoConnectKeyCommand) {
if (!doCommand.compare(0, v.size(), v)) {
isNoTargetCommand = true;
break;
}
}
if (isNoTargetCommand) {
key = "";
} else {
if (!preConnectKey.size()) {
key = CMDSTR_CONNECT_ANY;
}
}
return key;
}
#ifdef _WIN32
static void ReadFileThreadFunc(void* arg)
{
char buffer[BUF_SIZE_DEFAULT] = { 0 };
DWORD bytesRead = 0;
HANDLE* read = reinterpret_cast<HANDLE*>(arg);
while (true) {
if (!ReadFile(*read, buffer, BUF_SIZE_DEFAULT - 1, &bytesRead, NULL)) {
break;
}
string str = std::to_string(bytesRead);
const char* zero = "0";
if (!strncmp(zero, str.c_str(), strlen(zero))) {
return;
}
printf("%s", buffer);
if (memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)) != EOK) {
return;
}
}
}
string HdcClient::GetHilogPath()
{
string hdcPath = Base::GetHdcAbsolutePath();
int index = hdcPath.find_last_of(Base::GetPathSep());
string exePath = hdcPath.substr(0, index) + Base::GetPathSep() + HILOG_NAME;
return exePath;
}
void HdcClient::RunCommandWin32(const string& cmd)
{
HANDLE hSubWrite;
HANDLE hParentRead;
HANDLE hParentWrite;
HANDLE hSubRead;
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = true;
if (!CreatePipe(&hParentRead, &hSubWrite, &sa, 0) ||
!CreatePipe(&hSubRead, &hParentWrite, &sa, 0) ||
!SetHandleInformation(hParentRead, HANDLE_FLAG_INHERIT, 0) ||
!SetHandleInformation(hParentWrite, HANDLE_FLAG_INHERIT, 0)) {
return;
}
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hSubWrite;
si.hStdOutput = hSubWrite;
si.hStdInput = hSubRead;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
const char *msg = cmd.c_str();
char buffer[BUF_SIZE_SMALL] = {0};
if (strcpy_s(buffer, sizeof(buffer), msg) != EOK) {
return;
}
const string exePath = GetHilogPath();
if (!CreateProcess(_T(exePath.c_str()), _T(buffer), NULL, NULL, true, NULL, NULL, NULL, &si, &pi)) {
WRITE_LOG(LOG_INFO, "create process failed, error:%d", GetLastError());
return;
}
auto thread = std::thread(ReadFileThreadFunc, &hParentRead);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(hSubWrite);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
thread.join();
CloseHandle(hParentRead);
CloseHandle(hParentWrite);
CloseHandle(hSubRead);
}
#else
void HdcClient::RunCommand(const string& cmd)
{
FILE *procFileInfo = nullptr;
procFileInfo = popen(cmd.c_str(), "r");
if (procFileInfo == nullptr) {
perror("popen execute failed");
return;
}
char resultBufShell[BUF_SIZE_DEFAULT] = {0};
while (fgets(resultBufShell, sizeof(resultBufShell), procFileInfo) != nullptr) {
printf("%s", resultBufShell);
if (memset_s(resultBufShell, sizeof(resultBufShell), 0, sizeof(resultBufShell)) != EOK) {
break;
}
}
pclose(procFileInfo);
}
#endif
void HdcClient::RunExecuteCommand(const string& cmd)
{
#ifdef _WIN32
RunCommandWin32(cmd);
#else
RunCommand(cmd);
#endif
}
bool IsCaptureCommand(const string& cmd)
{
int index = string(CMDSTR_HILOG).length();
int length = cmd.length();
const string captureOption = "parse";
while (index < length) {
if (cmd[index] == ' ') {
index++;
continue;
}
if (!strncmp(cmd.c_str() + index, captureOption.c_str(), captureOption.size())) {
return true;
} else {
return false;
}
}
return false;
}
int HdcClient::ExecuteCommand(const string &commandIn)
{
char ip[BUF_SIZE_TINY] = "";
uint16_t port = 0;
int ret = Base::ConnectKey2IPPort(channelHostPort.c_str(), ip, &port);
if (ret < 0) {
WRITE_LOG(LOG_FATAL, "ConnectKey2IPPort %s failed with %d",
channelHostPort.c_str(), ret);
return -1;
}
if (!strncmp(commandIn.c_str(), CMDSTR_HILOG.c_str(), CMDSTR_HILOG.size()) &&
IsCaptureCommand(commandIn)) {
RunExecuteCommand(commandIn);
return 0;
}
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->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);
ConnectServerForClient(ip, port);
uv_timer_init(loopMain, &waitTimeDoCmd);
waitTimeDoCmd.data = this;
uv_timer_start(&waitTimeDoCmd, CommandWorker, UV_START_TIMEOUT, UV_START_REPEAT);
WorkerPendding();
return 0;
}
int HdcClient::Initial(const string &connectKeyIn)
{
connectKey = connectKeyIn;
if (!channelHostPort.size() || !channelHost.size() || !channelPort) {
WRITE_LOG(LOG_FATAL, "Listen string initial failed");
return ERR_PARM_FAIL;
}
return 0;
}
int HdcClient::ConnectServerForClient(const char *ip, uint16_t port)
{
if (uv_is_closing((const uv_handle_t *)&channel->hWorkTCP)) {
WRITE_LOG(LOG_FATAL, "ConnectServerForClient uv_is_closing");
return ERR_SOCKET_FAIL;
}
WRITE_LOG(LOG_DEBUG, "Try to connect %s:%d", ip, port);
uv_connect_t *conn = new(std::nothrow) uv_connect_t();
if (conn == nullptr) {
WRITE_LOG(LOG_FATAL, "ConnectServerForClient new conn failed");
return ERR_GENERIC;
}
conn->data = this;
if (strchr(ip, '.')) {
std::string s = ip;
size_t index = s.find(IPV4_MAPPING_PREFIX);
size_t size = IPV4_MAPPING_PREFIX.size();
if (index != std::string::npos) {
s = s.substr(index + size);
}
WRITE_LOG(LOG_DEBUG, "ConnectServerForClient ipv4 %s:%d", s.c_str(), port);
struct sockaddr_in destv4;
uv_ip4_addr(s.c_str(), port, &destv4);
uv_tcp_connect(conn, (uv_tcp_t *)&channel->hWorkTCP, (const struct sockaddr *)&destv4, Connect);
} else {
WRITE_LOG(LOG_DEBUG, "ConnectServerForClient ipv6 %s:%d", ip, port);
struct sockaddr_in6 dest;
uv_ip6_addr(ip, port, &dest);
uv_tcp_connect(conn, (uv_tcp_t *)&channel->hWorkTCP, (const struct sockaddr *)&dest, Connect);
}
return 0;
}
void HdcClient::CommandWorker(uv_timer_t *handle)
{
const uint16_t maxWaitRetry = 1200; // client socket try 12s
HdcClient *thisClass = (HdcClient *)handle->data;
if (++thisClass->debugRetryCount > maxWaitRetry) {
uv_timer_stop(handle);
uv_stop(thisClass->loopMain);
WRITE_LOG(LOG_DEBUG, "Connect server failed");
fprintf(stderr, "Connect server failed\n");
return;
}
if (!thisClass->channel->handshakeOK) {
return;
}
uv_timer_stop(handle);
WRITE_LOG(LOG_DEBUG, "Connect server successful");
bool closeInput = false;
if (!HostUpdater::ConfirmCommand(thisClass->command, closeInput)) {
uv_timer_stop(handle);
uv_stop(thisClass->loopMain);
WRITE_LOG(LOG_DEBUG, "Cmd \'%s\' has been canceld", thisClass->command.c_str());
return;
}
while (closeInput) {
#ifndef _WIN32
if (tcgetattr(STDIN_FILENO, &thisClass->terminalState)) {
break;
}
termios tio;
if (tcgetattr(STDIN_FILENO, &tio)) {
break;
}
cfmakeraw(&tio);
tio.c_cc[VTIME] = 0;
tio.c_cc[VMIN] = 1;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio);
g_terminalStateChange = true;
#endif
break;
}
thisClass->Send(thisClass->channel->channelId,
const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(thisClass->command.c_str())),
thisClass->command.size() + 1);
}
void HdcClient::AllocStdbuf(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf)
{
if (sizeWanted <= 0) {
return;
}
HChannel context = (HChannel)handle->data;
int availSize = strlen(context->bufStd);
buf->base = (char *)context->bufStd + availSize;
buf->len = sizeof(context->bufStd) - availSize - 2; // reserve 2bytes
}
void HdcClient::ReadStd(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
{
HChannel hChannel = (HChannel)stream->data;
HdcClient *thisClass = (HdcClient *)hChannel->clsChannel;
char *cmd = hChannel->bufStd;
if (nread <= 0) {
WRITE_LOG(LOG_FATAL, "ReadStd error nread:%zd", nread);
return; // error
}
thisClass->Send(hChannel->channelId, reinterpret_cast<uint8_t *>(cmd), strlen(cmd));
Base::ZeroArray(hChannel->bufStd);
}
void HdcClient::ModifyTty(bool setOrRestore, uv_tty_t *tty)
{
if (setOrRestore) {
#ifdef _WIN32
uv_tty_set_mode(tty, UV_TTY_MODE_RAW);
#else
if (tcgetattr(STDIN_FILENO, &terminalState)) {
return;
}
termios tio;
if (tcgetattr(STDIN_FILENO, &tio)) {
return;
}
cfmakeraw(&tio);
tio.c_cc[VTIME] = 0;
tio.c_cc[VMIN] = 1;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio);
#endif
} else {
#ifndef _WIN32
tcsetattr(STDIN_FILENO, TCSAFLUSH, &terminalState);
#endif
}
}
void HdcClient::BindLocalStd(HChannel hChannel)
{
if (command == CMDSTR_SHELL) {
bShellInteractive = true;
}
if (bShellInteractive && uv_guess_handle(STDIN_FILENO) != UV_TTY) {
WRITE_LOG(LOG_WARN, "Not support stdio TTY mode");
return;
}
WRITE_LOG(LOG_DEBUG, "setup stdio TTY mode");
if (uv_tty_init(loopMain, &hChannel->stdoutTty, STDOUT_FILENO, 0)
|| uv_tty_init(loopMain, &hChannel->stdinTty, STDIN_FILENO, 1)) {
WRITE_LOG(LOG_DEBUG, "uv_tty_init failed");
return;
}
hChannel->stdoutTty.data = hChannel;
++hChannel->uvHandleRef;
hChannel->stdinTty.data = hChannel;
++hChannel->uvHandleRef;
if (bShellInteractive) {
WRITE_LOG(LOG_DEBUG, "uv_tty_init uv_tty_set_mode");
ModifyTty(true, &hChannel->stdinTty);
uv_read_start((uv_stream_t *)&hChannel->stdinTty, AllocStdbuf, ReadStd);
}
}
void HdcClient::Connect(uv_connect_t *connection, int status)
{
HdcClient *thisClass = (HdcClient *)connection->data;
delete connection;
HChannel hChannel = reinterpret_cast<HChannel>(thisClass->channel);
if (status < 0 || uv_is_closing((const uv_handle_t *)&hChannel->hWorkTCP)) {
WRITE_LOG(LOG_FATAL, "connect failed status:%d", status);
thisClass->FreeChannel(hChannel->channelId);
return;
}
thisClass->BindLocalStd(hChannel);
Base::SetTcpOptions((uv_tcp_t *)&hChannel->hWorkTCP);
uv_read_start((uv_stream_t *)&hChannel->hWorkTCP, AllocCallback, ReadStream);
}
int HdcClient::PreHandshake(HChannel hChannel, const uint8_t *buf)
{
ChannelHandShake *hShake = reinterpret_cast<ChannelHandShake *>(const_cast<uint8_t *>(buf));
if (strncmp(hShake->banner, HANDSHAKE_MESSAGE.c_str(), HANDSHAKE_MESSAGE.size())) {
hChannel->availTailIndex = 0;
WRITE_LOG(LOG_DEBUG, "Channel Hello failed");
return ERR_BUF_CHECK;
}
// sync remote session id to local
uint32_t unOld = hChannel->channelId;
hChannel->channelId = ntohl(hShake->channelId);
AdminChannel(OP_UPDATE, unOld, hChannel);
WRITE_LOG(LOG_DEBUG, "Client channel handshake finished, use connectkey:%s", connectKey.c_str());
// send config
// channel handshake step2
if (memset_s(hShake->connectKey, sizeof(hShake->connectKey), 0, sizeof(hShake->connectKey)) != EOK
|| memcpy_s(hShake->connectKey, sizeof(hShake->connectKey), connectKey.c_str(), connectKey.size()) != EOK) {
hChannel->availTailIndex = 0;
WRITE_LOG(LOG_DEBUG, "Channel Hello failed");
return ERR_BUF_COPY;
}
#ifdef HDC_VERSION_CHECK
// add check version
if (!isCheckVersionCmd) { // do not check version cause user want to get server version
string clientVer = Base::GetVersion() + HDC_MSG_HASH;
string serverVer(hShake->version);
if (clientVer != serverVer) {
serverVer = serverVer.substr(0, Base::GetVersion().size());
WRITE_LOG(LOG_FATAL, "Client version:%s, server version:%s", clientVer.c_str(), serverVer.c_str());
hChannel->availTailIndex = 0;
return ERR_CHECK_VERSION;
}
}
Send(hChannel->channelId, reinterpret_cast<uint8_t *>(hShake), sizeof(ChannelHandShake));
#else
// do not send version message if check feature disable
Send(hChannel->channelId, reinterpret_cast<uint8_t *>(hShake), offsetof(struct ChannelHandShake, version));
#endif
hChannel->handshakeOK = true;
#ifdef HDC_CHANNEL_KEEP_ALIVE
// Evaluation method, non long-term support
Send(hChannel->channelId,
reinterpret_cast<uint8_t *>(const_cast<char*>(CMDSTR_INNER_ENABLE_KEEPALIVE.c_str())),
CMDSTR_INNER_ENABLE_KEEPALIVE.size());
#endif
return RET_SUCCESS;
}
// read serverForClient(server)TCP data
int HdcClient::ReadChannel(HChannel hChannel, uint8_t *buf, const int bytesIO)
{
if (!hChannel->handshakeOK) {
return PreHandshake(hChannel, buf);
}
#ifdef UNIT_TEST
// Do not output to console when the unit test
return 0;
#endif
WRITE_LOG(LOG_DEBUG, "Client ReadChannel :%d", bytesIO);
uint16_t cmd = 0;
bool bOffset = false;
if (bytesIO >= static_cast<int>(sizeof(uint16_t))) {
cmd = *reinterpret_cast<uint16_t *>(buf);
bOffset = IsOffset(cmd);
}
if (cmd == CMD_CHECK_SERVER && isCheckVersionCmd) {
WRITE_LOG(LOG_DEBUG, "recieve CMD_CHECK_VERSION command");
string version(reinterpret_cast<char *>(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 = GetRemoteTaskInfo(hChannel);
hTaskInfo->masterSlave = (cmd == CMD_FILE_INIT);
fileTask = std::make_unique<HdcFile>(hTaskInfo);
}
if (!fileTask->CommandDispatch(cmd, 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 = (cmd == CMD_APP_INIT);
appTask = std::make_unique<HdcHostApp>(hTaskInfo);
}
if (!appTask->CommandDispatch(cmd, buf + sizeof(uint16_t), bytesIO - sizeof(uint16_t))) {
appTask->TaskFinish();
}
}
return 0;
}
string s(reinterpret_cast<char *>(buf), bytesIO);
if (WaitFor(s)) {
return 0;
}
s = ListTargetsAll(s);
if (g_show) {
#ifdef _WIN32
fprintf(stdout, "%s", s.c_str());
fflush(stdout);
#else
constexpr int len = 512;
int size = s.size() / len;
int left = s.size() % len;
for (int i = 0; i <= size; i++) {
int cnt = len;
const char *p = reinterpret_cast<char *>(buf) + i * cnt;
if (i == size) {
cnt = left;
}
fprintf(stdout, "%.*s", cnt, p);
fflush(stdout);
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
#endif
}
return 0;
}
bool HdcClient::WaitFor(const string &str)
{
bool wait = false;
if (!strncmp(this->command.c_str(), CMDSTR_WAIT_FOR.c_str(), CMDSTR_WAIT_FOR.size())) {
const string waitFor = "[Fail]No any connected target";
if (!strncmp(str.c_str(), waitFor.c_str(), waitFor.size())) {
Send(this->channel->channelId, reinterpret_cast<uint8_t *>(const_cast<char *>(this->command.c_str())),
this->command.size() + 1);
constexpr int timeout = 1;
std::this_thread::sleep_for(std::chrono::seconds(timeout));
wait = true;
} else {
_exit(0);
}
}
return wait;
}
string HdcClient::ListTargetsAll(const string &str)
{
string all = str;
const string lists = "list targets -v";
if (!strncmp(this->command.c_str(), lists.c_str(), lists.size())) {
UpdateList(str);
all = Base::ReplaceAll(all, "\n", "\thdc\n");
} else if (!strncmp(this->command.c_str(), CMDSTR_LIST_TARGETS.c_str(), CMDSTR_LIST_TARGETS.size())) {
UpdateList(str);
}
if (!strncmp(this->command.c_str(), CMDSTR_LIST_TARGETS.c_str(), CMDSTR_LIST_TARGETS.size())) {
if (g_lists.size() > 0 && !strncmp(str.c_str(), EMPTY_ECHO.c_str(), EMPTY_ECHO.size())) {
all = "";
}
}
return all;
}
void HdcClient::UpdateList(const string &str)
{
if (!strncmp(str.c_str(), EMPTY_ECHO.c_str(), EMPTY_ECHO.size())) {
return;
}
vector<string> devs;
Base::SplitString(str, "\n", devs);
for (size_t i = 0; i < devs.size(); i++) {
string::size_type pos = devs[i].find("\t");
if (pos != string::npos) {
string key = devs[i].substr(0, pos);
g_lists[key] = "hdc";
} else {
string key = devs[i];
g_lists[key] = "hdc";
}
}
}
bool HdcClient::IsOffset(uint16_t cmd)
{
return (cmd == CMD_CHECK_SERVER) ||
(cmd == CMD_FILE_INIT) ||
(cmd == CMD_FILE_CHECK) ||
(cmd == CMD_FILE_BEGIN) ||
(cmd == CMD_FILE_DATA) ||
(cmd == CMD_FILE_FINISH) ||
(cmd == CMD_FILE_MODE) ||
(cmd == CMD_DIR_MODE) ||
(cmd == CMD_APP_INIT) ||
(cmd == CMD_APP_CHECK) ||
(cmd == CMD_APP_BEGIN) ||
(cmd == CMD_APP_DATA) ||
(cmd == 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
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。