1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "client.h"
16 #ifndef TEST_HASH
17 #include "hdc_hash_gen.h"
18 #endif
19 #include "host_updater.h"
20 #include "server.h"
21 #include "file.h"
22
23 std::map<std::string, std::string> g_lists;
24 bool g_show = true;
25
26 namespace Hdc {
27 bool terminalStateChange = false;
HdcClient(const bool serverOrClient,const string & addrString,uv_loop_t * loopMainIn,bool checkVersion)28 HdcClient::HdcClient(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn, bool checkVersion)
29 : HdcChannelBase(serverOrClient, addrString, loopMainIn)
30 {
31 MallocChannel(&channel); // free by logic
32 debugRetryCount = 0;
33 #ifndef _WIN32
34 Base::ZeroStruct(terminalState);
35 #endif
36 isCheckVersionCmd = checkVersion;
37 }
38
~HdcClient()39 HdcClient::~HdcClient()
40 {
41 #ifndef _WIN32
42 if (terminalStateChange) {
43 tcsetattr(STDIN_FILENO, TCSAFLUSH, &terminalState);
44 }
45 #endif
46 Base::TryCloseLoop(loopMain, "ExecuteCommand finish");
47 }
48
NotifyInstanceChannelFree(HChannel hChannel)49 void HdcClient::NotifyInstanceChannelFree(HChannel hChannel)
50 {
51 if (bShellInteractive) {
52 WRITE_LOG(LOG_DEBUG, "Restore tty");
53 ModifyTty(false, &hChannel->stdinTty);
54 }
55 }
56
GetLastPID()57 uint32_t HdcClient::GetLastPID()
58 {
59 char bufPath[BUF_SIZE_MEDIUM] = "";
60 size_t size = BUF_SIZE_MEDIUM;
61 char pidBuf[BUF_SIZE_TINY] = "";
62 // get running pid to kill it
63 if (uv_os_tmpdir(bufPath, &size) < 0) {
64 WRITE_LOG(LOG_FATAL, "Tmppath failed");
65 return 0;
66 }
67 string path = Base::StringFormat("%s%c.%s.pid", bufPath, Base::GetPathSep(), SERVER_NAME.c_str());
68 Base::ReadBinFile(path.c_str(), reinterpret_cast<void **>(&pidBuf), BUF_SIZE_TINY);
69 int pid = atoi(pidBuf); // pid maybe 0
70 return pid;
71 }
72
StartKillServer(const char * cmd,bool startOrKill)73 bool HdcClient::StartKillServer(const char *cmd, bool startOrKill)
74 {
75 bool isNowRunning = Base::ProgramMutex(SERVER_NAME.c_str(), true) != 0;
76 const int signNum = 9;
77 uint32_t pid = GetLastPID();
78 if (!pid) {
79 return false;
80 }
81 if (startOrKill) {
82 if (isNowRunning) {
83 // already running
84 if (!strstr(cmd, " -r")) {
85 return true;
86 }
87 if (pid) {
88 uv_kill(pid, signNum);
89 }
90 }
91 HdcServer::PullupServer(channelHostPort.c_str());
92 } else {
93 if (isNowRunning && pid) {
94 int rc = uv_kill(pid, signNum);
95 if (rc == 0) {
96 Base::PrintMessage("Kill server finish");
97 } else {
98 constexpr int size = 1024;
99 char buf[size] = { 0 };
100 uv_strerror_r(rc, buf, size);
101 Base::PrintMessage("Kill server failed %s", buf);
102 }
103 }
104 // already running
105 if (!strstr(cmd, " -r")) {
106 return true;
107 }
108 HdcServer::PullupServer(channelHostPort.c_str());
109 }
110 return true;
111 }
112
DoCtrlServiceWork(uv_check_t * handle)113 void HdcClient::DoCtrlServiceWork(uv_check_t *handle)
114 {
115 HdcClient *thisClass = (HdcClient *)handle->data;
116 string &strCmd = thisClass->command;
117 if (!strncmp(thisClass->command.c_str(), CMDSTR_SERVICE_START.c_str(), CMDSTR_SERVICE_START.size())) {
118 thisClass->StartKillServer(thisClass->command.c_str(), true);
119 } else if (!strncmp(thisClass->command.c_str(), CMDSTR_SERVICE_KILL.c_str(), CMDSTR_SERVICE_KILL.size())) {
120 thisClass->StartKillServer(thisClass->command.c_str(), false);
121 // clang-format off
122 } else if (!strncmp(thisClass->command.c_str(), CMDSTR_GENERATE_KEY.c_str(), CMDSTR_GENERATE_KEY.size()) &&
123 strCmd.find(" ") != std::string::npos) {
124 // clang-format on
125 string keyPath = strCmd.substr(CMDSTR_GENERATE_KEY.size() + 1, strCmd.size());
126 HdcAuth::GenerateKey(keyPath.c_str());
127 } else {
128 Base::PrintMessage("Unknown command");
129 }
130 Base::TryCloseHandle((const uv_handle_t *)handle);
131 }
132
CtrlServiceWork(const char * commandIn)133 int HdcClient::CtrlServiceWork(const char *commandIn)
134 {
135 command = commandIn;
136 ctrlServerWork.data = this;
137 uv_check_init(loopMain, &ctrlServerWork);
138 uv_check_start(&ctrlServerWork, DoCtrlServiceWork);
139 uv_run(loopMain, UV_RUN_NOWAIT);
140 return 0;
141 }
142
AutoConnectKey(string & doCommand,const string & preConnectKey) const143 string HdcClient::AutoConnectKey(string &doCommand, const string &preConnectKey) const
144 {
145 string key = preConnectKey;
146 bool isNoTargetCommand = false;
147 vector<string> vecNoConnectKeyCommand;
148 vecNoConnectKeyCommand.push_back(CMDSTR_SOFTWARE_VERSION);
149 vecNoConnectKeyCommand.push_back(CMDSTR_SOFTWARE_HELP);
150 vecNoConnectKeyCommand.push_back(CMDSTR_TARGET_DISCOVER);
151 vecNoConnectKeyCommand.push_back(CMDSTR_LIST_TARGETS);
152 vecNoConnectKeyCommand.push_back(CMDSTR_CHECK_SERVER);
153 vecNoConnectKeyCommand.push_back(CMDSTR_CONNECT_TARGET);
154 vecNoConnectKeyCommand.push_back(CMDSTR_CHECK_DEVICE);
155 vecNoConnectKeyCommand.push_back(CMDSTR_WAIT_FOR);
156 vecNoConnectKeyCommand.push_back(CMDSTR_KILL_SERVER);
157 vecNoConnectKeyCommand.push_back(CMDSTR_FORWARD_FPORT + " ls");
158 vecNoConnectKeyCommand.push_back(CMDSTR_FORWARD_FPORT + " rm");
159 for (string v : vecNoConnectKeyCommand) {
160 if (!doCommand.compare(0, v.size(), v)) {
161 isNoTargetCommand = true;
162 break;
163 }
164 }
165 if (isNoTargetCommand) {
166 key = "";
167 } else {
168 if (!preConnectKey.size()) {
169 key = CMDSTR_CONNECT_ANY;
170 }
171 }
172 return key;
173 }
174
ExecuteCommand(const string & commandIn)175 int HdcClient::ExecuteCommand(const string &commandIn)
176 {
177 char ip[BUF_SIZE_TINY] = "";
178 uint16_t port = 0;
179 int ret = Base::ConnectKey2IPPort(channelHostPort.c_str(), ip, &port);
180 if (ret < 0) {
181 WRITE_LOG(LOG_FATAL, "ConnectKey2IPPort %s failed with %d",
182 channelHostPort.c_str(), ret);
183 return -1;
184 }
185
186 if (!strncmp(commandIn.c_str(), CMDSTR_FILE_SEND.c_str(), CMDSTR_FILE_SEND.size()) ||
187 !strncmp(commandIn.c_str(), CMDSTR_FILE_RECV.c_str(), CMDSTR_FILE_RECV.size())) {
188 WRITE_LOG(LOG_DEBUG, "Set file send mode");
189 channel->remote = RemoteType::REMOTE_FILE;
190 }
191 if (!strncmp(commandIn.c_str(), CMDSTR_APP_INSTALL.c_str(), CMDSTR_APP_INSTALL.size())) {
192 channel->remote = RemoteType::REMOTE_APP;
193 }
194 command = commandIn;
195 connectKey = AutoConnectKey(command, connectKey);
196 ConnectServerForClient(ip, port);
197 uv_timer_init(loopMain, &waitTimeDoCmd);
198 waitTimeDoCmd.data = this;
199 uv_timer_start(&waitTimeDoCmd, CommandWorker, 10, 10);
200 WorkerPendding();
201 return 0;
202 }
203
Initial(const string & connectKeyIn)204 int HdcClient::Initial(const string &connectKeyIn)
205 {
206 connectKey = connectKeyIn;
207 if (!channelHostPort.size() || !channelHost.size() || !channelPort) {
208 WRITE_LOG(LOG_FATAL, "Listen string initial failed");
209 return ERR_PARM_FAIL;
210 }
211 return 0;
212 }
213
ConnectServerForClient(const char * ip,uint16_t port)214 int HdcClient::ConnectServerForClient(const char *ip, uint16_t port)
215 {
216 if (uv_is_closing((const uv_handle_t *)&channel->hWorkTCP)) {
217 return ERR_SOCKET_FAIL;
218 }
219 WRITE_LOG(LOG_DEBUG, "Try to connect %s:%d", ip, port);
220 struct sockaddr_in6 dest;
221 uv_ip6_addr(ip, port, &dest);
222 uv_connect_t *conn = new(std::nothrow) uv_connect_t();
223 if (conn == nullptr) {
224 WRITE_LOG(LOG_FATAL, "ConnectServerForClient new conn failed");
225 return ERR_GENERIC;
226 }
227 conn->data = this;
228 uv_tcp_connect(conn, (uv_tcp_t *)&channel->hWorkTCP, (const struct sockaddr *)&dest, Connect);
229 return 0;
230 }
231
CommandWorker(uv_timer_t * handle)232 void HdcClient::CommandWorker(uv_timer_t *handle)
233 {
234 const uint16_t maxWaitRetry = 500;
235 HdcClient *thisClass = (HdcClient *)handle->data;
236 if (++thisClass->debugRetryCount > maxWaitRetry) {
237 uv_timer_stop(handle);
238 uv_stop(thisClass->loopMain);
239 WRITE_LOG(LOG_DEBUG, "Connect server failed");
240 fprintf(stderr, "Connect server failed\n");
241 return;
242 }
243 if (!thisClass->channel->handshakeOK) {
244 return;
245 }
246 uv_timer_stop(handle);
247 WRITE_LOG(LOG_DEBUG, "Connect server successful");
248 bool closeInput = false;
249 if (!HostUpdater::ConfirmCommand(thisClass->command, closeInput)) {
250 uv_timer_stop(handle);
251 uv_stop(thisClass->loopMain);
252 WRITE_LOG(LOG_DEBUG, "Cmd \'%s\' has been canceld", thisClass->command.c_str());
253 return;
254 }
255 while (closeInput) {
256 #ifndef _WIN32
257 if (tcgetattr(STDIN_FILENO, &thisClass->terminalState)) {
258 break;
259 }
260 termios tio;
261 if (tcgetattr(STDIN_FILENO, &tio)) {
262 break;
263 }
264 cfmakeraw(&tio);
265 tio.c_cc[VTIME] = 0;
266 tio.c_cc[VMIN] = 1;
267 tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio);
268 terminalStateChange = true;
269 #endif
270 break;
271 }
272 thisClass->Send(thisClass->channel->channelId,
273 const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(thisClass->command.c_str())),
274 thisClass->command.size() + 1);
275 }
276
AllocStdbuf(uv_handle_t * handle,size_t sizeWanted,uv_buf_t * buf)277 void HdcClient::AllocStdbuf(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf)
278 {
279 if (sizeWanted <= 0) {
280 return;
281 }
282 HChannel context = (HChannel)handle->data;
283 int availSize = strlen(context->bufStd);
284 buf->base = (char *)context->bufStd + availSize;
285 buf->len = sizeof(context->bufStd) - availSize - 2; // reserve 2bytes
286 }
287
ReadStd(uv_stream_t * stream,ssize_t nread,const uv_buf_t * buf)288 void HdcClient::ReadStd(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
289 {
290 HChannel hChannel = (HChannel)stream->data;
291 HdcClient *thisClass = (HdcClient *)hChannel->clsChannel;
292 char *cmd = hChannel->bufStd;
293 if (nread <= 0) {
294 return; // error
295 }
296 thisClass->Send(hChannel->channelId, reinterpret_cast<uint8_t *>(cmd), strlen(cmd));
297 Base::ZeroArray(hChannel->bufStd);
298 }
299
ModifyTty(bool setOrRestore,uv_tty_t * tty)300 void HdcClient::ModifyTty(bool setOrRestore, uv_tty_t *tty)
301 {
302 if (setOrRestore) {
303 #ifdef _WIN32
304 uv_tty_set_mode(tty, UV_TTY_MODE_RAW);
305 #else
306 if (tcgetattr(STDIN_FILENO, &terminalState)) {
307 return;
308 }
309 termios tio;
310 if (tcgetattr(STDIN_FILENO, &tio)) {
311 return;
312 }
313 cfmakeraw(&tio);
314 tio.c_cc[VTIME] = 0;
315 tio.c_cc[VMIN] = 1;
316 tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio);
317 #endif
318 } else {
319 #ifndef _WIN32
320 tcsetattr(STDIN_FILENO, TCSAFLUSH, &terminalState);
321 #endif
322 }
323 }
324
BindLocalStd(HChannel hChannel)325 void HdcClient::BindLocalStd(HChannel hChannel)
326 {
327 if (command == CMDSTR_SHELL) {
328 bShellInteractive = true;
329 }
330 if (bShellInteractive && uv_guess_handle(STDIN_FILENO) != UV_TTY) {
331 WRITE_LOG(LOG_WARN, "Not support stdio TTY mode");
332 return;
333 }
334
335 WRITE_LOG(LOG_DEBUG, "setup stdio TTY mode");
336 if (uv_tty_init(loopMain, &hChannel->stdoutTty, STDOUT_FILENO, 0)
337 || uv_tty_init(loopMain, &hChannel->stdinTty, STDIN_FILENO, 1)) {
338 WRITE_LOG(LOG_DEBUG, "uv_tty_init failed");
339 return;
340 }
341 hChannel->stdoutTty.data = hChannel;
342 ++hChannel->uvHandleRef;
343 hChannel->stdinTty.data = hChannel;
344 ++hChannel->uvHandleRef;
345 if (bShellInteractive) {
346 WRITE_LOG(LOG_DEBUG, "uv_tty_init uv_tty_set_mode");
347 ModifyTty(true, &hChannel->stdinTty);
348 uv_read_start((uv_stream_t *)&hChannel->stdinTty, AllocStdbuf, ReadStd);
349 }
350 }
351
Connect(uv_connect_t * connection,int status)352 void HdcClient::Connect(uv_connect_t *connection, int status)
353 {
354 HdcClient *thisClass = (HdcClient *)connection->data;
355 delete connection;
356 HChannel hChannel = reinterpret_cast<HChannel>(thisClass->channel);
357 if (status < 0 || uv_is_closing((const uv_handle_t *)&hChannel->hWorkTCP)) {
358 WRITE_LOG(LOG_FATAL, "connect failed");
359 thisClass->FreeChannel(hChannel->channelId);
360 return;
361 }
362 thisClass->BindLocalStd(hChannel);
363 Base::SetTcpOptions((uv_tcp_t *)&hChannel->hWorkTCP);
364 uv_read_start((uv_stream_t *)&hChannel->hWorkTCP, AllocCallback, ReadStream);
365 }
366
PreHandshake(HChannel hChannel,const uint8_t * buf)367 int HdcClient::PreHandshake(HChannel hChannel, const uint8_t *buf)
368 {
369 ChannelHandShake *hShake = reinterpret_cast<ChannelHandShake *>(const_cast<uint8_t *>(buf));
370 if (strncmp(hShake->banner, HANDSHAKE_MESSAGE.c_str(), HANDSHAKE_MESSAGE.size())) {
371 hChannel->availTailIndex = 0;
372 WRITE_LOG(LOG_DEBUG, "Channel Hello failed");
373 return ERR_BUF_CHECK;
374 }
375 // sync remote session id to local
376 uint32_t unOld = hChannel->channelId;
377 hChannel->channelId = ntohl(hShake->channelId);
378 AdminChannel(OP_UPDATE, unOld, hChannel);
379 WRITE_LOG(LOG_DEBUG, "Client channel handshake finished, use connectkey:%s", connectKey.c_str());
380 // send config
381 // channel handshake step2
382 if (memset_s(hShake->connectKey, sizeof(hShake->connectKey), 0, sizeof(hShake->connectKey)) != EOK
383 || memcpy_s(hShake->connectKey, sizeof(hShake->connectKey), connectKey.c_str(), connectKey.size()) != EOK) {
384 hChannel->availTailIndex = 0;
385 WRITE_LOG(LOG_DEBUG, "Channel Hello failed");
386 return ERR_BUF_COPY;
387 }
388
389 #ifdef HDC_VERSION_CHECK
390 // add check version
391 if (!isCheckVersionCmd) { // do not check version cause user want to get server version
392 string clientVer = Base::GetVersion() + HDC_MSG_HASH;
393 string serverVer(hShake->version);
394
395 if (clientVer != serverVer) {
396 serverVer = serverVer.substr(0, Base::GetVersion().size());
397 WRITE_LOG(LOG_FATAL, "Client version:%s, server version:%s", clientVer.c_str(), serverVer.c_str());
398 hChannel->availTailIndex = 0;
399 return ERR_CHECK_VERSION;
400 }
401 }
402 Send(hChannel->channelId, reinterpret_cast<uint8_t *>(hShake), sizeof(ChannelHandShake));
403 #else
404 // do not send version message if check feature disable
405 Send(hChannel->channelId, reinterpret_cast<uint8_t *>(hShake), offsetof(struct ChannelHandShake, version));
406 #endif
407 hChannel->handshakeOK = true;
408 #ifdef HDC_CHANNEL_KEEP_ALIVE
409 // Evaluation method, non long-term support
410 Send(hChannel->channelId,
411 reinterpret_cast<uint8_t *>(const_cast<char*>(CMDSTR_INNER_ENABLE_KEEPALIVE.c_str())),
412 CMDSTR_INNER_ENABLE_KEEPALIVE.size());
413 #endif
414 return RET_SUCCESS;
415 }
416
417 // read serverForClient(server)TCP data
ReadChannel(HChannel hChannel,uint8_t * buf,const int bytesIO)418 int HdcClient::ReadChannel(HChannel hChannel, uint8_t *buf, const int bytesIO)
419 {
420 if (!hChannel->handshakeOK) {
421 return PreHandshake(hChannel, buf);
422 }
423 #ifdef UNIT_TEST
424 // Do not output to console when the unit test
425 return 0;
426 #endif
427 WRITE_LOG(LOG_DEBUG, "Client ReadChannel :%d", bytesIO);
428
429 uint16_t cmd = 0;
430 bool bOffset = false;
431 if (bytesIO >= static_cast<int>(sizeof(uint16_t))) {
432 cmd = *reinterpret_cast<uint16_t *>(buf);
433 bOffset = IsOffset(cmd);
434 }
435 if (cmd == CMD_CHECK_SERVER && isCheckVersionCmd) {
436 WRITE_LOG(LOG_DEBUG, "recieve CMD_CHECK_VERSION command");
437 string version(reinterpret_cast<char *>(buf + sizeof(uint16_t)), bytesIO - sizeof(uint16_t));
438 fprintf(stdout, "Client version:%s, server version:%s\n", Base::GetVersion().c_str(), version.c_str());
439 fflush(stdout);
440 return 0;
441 }
442 if (hChannel->remote > RemoteType::REMOTE_NONE && bOffset) {
443 // file command
444 if (hChannel->remote == RemoteType::REMOTE_FILE) {
445 if (fileTask == nullptr) {
446 HTaskInfo hTaskInfo = GetRemoteTaskInfo(hChannel);
447 hTaskInfo->masterSlave = (cmd == CMD_FILE_INIT);
448 fileTask = std::make_unique<HdcFile>(hTaskInfo);
449 }
450 if (!fileTask->CommandDispatch(cmd, buf + sizeof(uint16_t), bytesIO - sizeof(uint16_t))) {
451 fileTask->TaskFinish();
452 }
453 }
454 // app command
455 if (hChannel->remote == RemoteType::REMOTE_APP) {
456 if (appTask == nullptr) {
457 HTaskInfo hTaskInfo = GetRemoteTaskInfo(hChannel);
458 hTaskInfo->masterSlave = (cmd == CMD_APP_INIT);
459 appTask = std::make_unique<HdcHostApp>(hTaskInfo);
460 }
461 if (!appTask->CommandDispatch(cmd, buf + sizeof(uint16_t), bytesIO - sizeof(uint16_t))) {
462 appTask->TaskFinish();
463 }
464 }
465 return 0;
466 }
467
468 string s(reinterpret_cast<char *>(buf), bytesIO);
469 if (WaitFor(s)) {
470 return 0;
471 }
472 s = ListTargetsAll(s);
473 if (g_show) {
474 fprintf(stdout, "%s", s.c_str());
475 fflush(stdout);
476 }
477 return 0;
478 }
479
WaitFor(const string & str)480 bool HdcClient::WaitFor(const string &str)
481 {
482 bool wait = false;
483 if (!strncmp(this->command.c_str(), CMDSTR_WAIT_FOR.c_str(), CMDSTR_WAIT_FOR.size())) {
484 const string waitFor = "[Fail]No any connected target";
485 if (!strncmp(str.c_str(), waitFor.c_str(), waitFor.size())) {
486 Send(this->channel->channelId, (uint8_t *)this->command.c_str(), this->command.size() + 1);
487 constexpr int timeout = 1;
488 std::this_thread::sleep_for(std::chrono::seconds(timeout));
489 wait = true;
490 } else {
491 _exit(0);
492 }
493 }
494 return wait;
495 }
496
ListTargetsAll(const string & str)497 string HdcClient::ListTargetsAll(const string &str)
498 {
499 string all = str;
500 const string lists = "list targets -v";
501 if (!strncmp(this->command.c_str(), lists.c_str(), lists.size())) {
502 UpdateList(str);
503 all = Base::ReplaceAll(all, "\n", "\thdc\n");
504 } else if (!strncmp(this->command.c_str(), CMDSTR_LIST_TARGETS.c_str(), CMDSTR_LIST_TARGETS.size())) {
505 UpdateList(str);
506 }
507 if (!strncmp(this->command.c_str(), CMDSTR_LIST_TARGETS.c_str(), CMDSTR_LIST_TARGETS.size())) {
508 if (g_lists.size() > 0 && !strncmp(str.c_str(), EMPTY_ECHO.c_str(), EMPTY_ECHO.size())) {
509 all = "";
510 }
511 }
512 return all;
513 }
514
UpdateList(const string & str)515 void HdcClient::UpdateList(const string &str)
516 {
517 if (!strncmp(str.c_str(), EMPTY_ECHO.c_str(), EMPTY_ECHO.size())) {
518 return;
519 }
520 vector<string> devs;
521 Base::SplitString(str, "\n", devs);
522 for (size_t i = 0; i < devs.size(); i++) {
523 string::size_type pos = devs[i].find("\t");
524 if (pos != string::npos) {
525 string key = devs[i].substr(0, pos);
526 g_lists[key] = "hdc";
527 } else {
528 string key = devs[i];
529 g_lists[key] = "hdc";
530 }
531 }
532 }
533
IsOffset(uint16_t cmd)534 bool HdcClient::IsOffset(uint16_t cmd)
535 {
536 return (cmd == CMD_CHECK_SERVER) ||
537 (cmd == CMD_FILE_INIT) ||
538 (cmd == CMD_FILE_CHECK) ||
539 (cmd == CMD_FILE_BEGIN) ||
540 (cmd == CMD_FILE_DATA) ||
541 (cmd == CMD_FILE_FINISH) ||
542 (cmd == CMD_FILE_MODE) ||
543 (cmd == CMD_DIR_MODE) ||
544 (cmd == CMD_APP_INIT) ||
545 (cmd == CMD_APP_CHECK) ||
546 (cmd == CMD_APP_BEGIN) ||
547 (cmd == CMD_APP_DATA) ||
548 (cmd == CMD_APP_FINISH);
549 }
550
GetRemoteTaskInfo(HChannel hChannel)551 HTaskInfo HdcClient::GetRemoteTaskInfo(HChannel hChannel)
552 {
553 HTaskInfo hTaskInfo = new TaskInformation();
554 hTaskInfo->channelId = hChannel->channelId;
555 hTaskInfo->runLoop = loopMain;
556 hTaskInfo->serverOrDaemon = true;
557 hTaskInfo->channelTask = true;
558 hTaskInfo->channelClass = this;
559 return hTaskInfo;
560 };
561 } // namespace Hdc
562