1cc290419Sopenharmony_ci/*
2cc290419Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd.
3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License.
5cc290419Sopenharmony_ci * You may obtain a copy of the License at
6cc290419Sopenharmony_ci *
7cc290419Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cc290419Sopenharmony_ci *
9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and
13cc290419Sopenharmony_ci * limitations under the License.
14cc290419Sopenharmony_ci */
15cc290419Sopenharmony_ci#include "server.h"
16cc290419Sopenharmony_ci#include "host_updater.h"
17cc290419Sopenharmony_ci
18cc290419Sopenharmony_ci
19cc290419Sopenharmony_cinamespace Hdc {
20cc290419Sopenharmony_ciHdcServer::HdcServer(bool serverOrDaemonIn)
21cc290419Sopenharmony_ci    : HdcSessionBase(serverOrDaemonIn)
22cc290419Sopenharmony_ci{
23cc290419Sopenharmony_ci    clsTCPClt = nullptr;
24cc290419Sopenharmony_ci    clsUSBClt = nullptr;
25cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
26cc290419Sopenharmony_ci    clsUARTClt = nullptr;
27cc290419Sopenharmony_ci#endif
28cc290419Sopenharmony_ci    clsServerForClient = nullptr;
29cc290419Sopenharmony_ci    uv_rwlock_init(&daemonAdmin);
30cc290419Sopenharmony_ci    uv_rwlock_init(&forwardAdmin);
31cc290419Sopenharmony_ci}
32cc290419Sopenharmony_ci
33cc290419Sopenharmony_ciHdcServer::~HdcServer()
34cc290419Sopenharmony_ci{
35cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "~HdcServer");
36cc290419Sopenharmony_ci    uv_rwlock_destroy(&daemonAdmin);
37cc290419Sopenharmony_ci    uv_rwlock_destroy(&forwardAdmin);
38cc290419Sopenharmony_ci}
39cc290419Sopenharmony_ci
40cc290419Sopenharmony_civoid HdcServer::ClearInstanceResource()
41cc290419Sopenharmony_ci{
42cc290419Sopenharmony_ci    TryStopInstance();
43cc290419Sopenharmony_ci    Base::TryCloseLoop(&loopMain, "HdcServer::~HdcServer");
44cc290419Sopenharmony_ci    if (clsTCPClt) {
45cc290419Sopenharmony_ci        delete clsTCPClt;
46cc290419Sopenharmony_ci    }
47cc290419Sopenharmony_ci    if (clsUSBClt) {
48cc290419Sopenharmony_ci        delete clsUSBClt;
49cc290419Sopenharmony_ci    }
50cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
51cc290419Sopenharmony_ci    if (clsUARTClt) {
52cc290419Sopenharmony_ci        delete clsUARTClt;
53cc290419Sopenharmony_ci    }
54cc290419Sopenharmony_ci#endif
55cc290419Sopenharmony_ci    if (clsServerForClient) {
56cc290419Sopenharmony_ci        delete (static_cast<HdcServerForClient *>(clsServerForClient));
57cc290419Sopenharmony_ci    }
58cc290419Sopenharmony_ci}
59cc290419Sopenharmony_ci
60cc290419Sopenharmony_civoid HdcServer::TryStopInstance()
61cc290419Sopenharmony_ci{
62cc290419Sopenharmony_ci    ClearSessions();
63cc290419Sopenharmony_ci    if (clsTCPClt) {
64cc290419Sopenharmony_ci        clsTCPClt->Stop();
65cc290419Sopenharmony_ci    }
66cc290419Sopenharmony_ci    if (clsUSBClt) {
67cc290419Sopenharmony_ci        clsUSBClt->Stop();
68cc290419Sopenharmony_ci    }
69cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
70cc290419Sopenharmony_ci    if (clsUARTClt) {
71cc290419Sopenharmony_ci        clsUARTClt->Stop();
72cc290419Sopenharmony_ci    }
73cc290419Sopenharmony_ci#endif
74cc290419Sopenharmony_ci    if (clsServerForClient) {
75cc290419Sopenharmony_ci        ((HdcServerForClient *)clsServerForClient)->Stop();
76cc290419Sopenharmony_ci    }
77cc290419Sopenharmony_ci    ReMainLoopForInstanceClear();
78cc290419Sopenharmony_ci    ClearMapDaemonInfo();
79cc290419Sopenharmony_ci}
80cc290419Sopenharmony_ci
81cc290419Sopenharmony_cibool HdcServer::Initial(const char *listenString)
82cc290419Sopenharmony_ci{
83cc290419Sopenharmony_ci    if (Base::ProgramMutex(SERVER_NAME.c_str(), false) != 0) {
84cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Other instance already running, program mutex failed");
85cc290419Sopenharmony_ci        return false;
86cc290419Sopenharmony_ci    }
87cc290419Sopenharmony_ci    Base::RemoveLogFile();
88cc290419Sopenharmony_ci    clsServerForClient = new HdcServerForClient(true, listenString, this, &loopMain);
89cc290419Sopenharmony_ci    int rc = (static_cast<HdcServerForClient *>(clsServerForClient))->Initial();
90cc290419Sopenharmony_ci    if (rc != RET_SUCCESS) {
91cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "clsServerForClient Initial failed");
92cc290419Sopenharmony_ci        return false;
93cc290419Sopenharmony_ci    }
94cc290419Sopenharmony_ci    clsUSBClt->InitLogging(ctxUSB);
95cc290419Sopenharmony_ci    clsTCPClt = new HdcHostTCP(true, this);
96cc290419Sopenharmony_ci    clsUSBClt = new HdcHostUSB(true, this, ctxUSB);
97cc290419Sopenharmony_ci    if (clsUSBClt->Initial() != RET_SUCCESS) {
98cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "clsUSBClt Initial failed");
99cc290419Sopenharmony_ci        return false;
100cc290419Sopenharmony_ci    }
101cc290419Sopenharmony_ci    if (!clsServerForClient || !clsTCPClt || !clsUSBClt) {
102cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Class init failed");
103cc290419Sopenharmony_ci        return false;
104cc290419Sopenharmony_ci    }
105cc290419Sopenharmony_ci
106cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
107cc290419Sopenharmony_ci    clsUARTClt = new HdcHostUART(*this);
108cc290419Sopenharmony_ci    if (!clsUARTClt) {
109cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Class init failed");
110cc290419Sopenharmony_ci        return false;
111cc290419Sopenharmony_ci    }
112cc290419Sopenharmony_ci    if (clsUARTClt->Initial() != RET_SUCCESS) {
113cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "clsUARTClt Class init failed.");
114cc290419Sopenharmony_ci        return false;
115cc290419Sopenharmony_ci    }
116cc290419Sopenharmony_ci#endif
117cc290419Sopenharmony_ci    return true;
118cc290419Sopenharmony_ci}
119cc290419Sopenharmony_ci
120cc290419Sopenharmony_cibool HdcServer::PullupServerWin32(const char *path, const char *listenString)
121cc290419Sopenharmony_ci{
122cc290419Sopenharmony_ci    bool retVal = false;
123cc290419Sopenharmony_ci#ifdef _WIN32
124cc290419Sopenharmony_ci    char buf[BUF_SIZE_SMALL] = "";
125cc290419Sopenharmony_ci    char shortPath[MAX_PATH] = "";
126cc290419Sopenharmony_ci    std::string strPath = Base::UnicodeToUtf8(path, true);
127cc290419Sopenharmony_ci    int ret = GetShortPathName(strPath.c_str(), shortPath, MAX_PATH);
128cc290419Sopenharmony_ci    std::string runPath = shortPath;
129cc290419Sopenharmony_ci    if (ret == 0) {
130cc290419Sopenharmony_ci        int err = GetLastError();
131cc290419Sopenharmony_ci        constexpr int bufSize = 1024;
132cc290419Sopenharmony_ci        char buffer[bufSize] = { 0 };
133cc290419Sopenharmony_ci        strerror_s(buffer, bufSize, err);
134cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "GetShortPath path:[%s] errmsg:%s", path, buffer);
135cc290419Sopenharmony_ci        string uvPath = path;
136cc290419Sopenharmony_ci        runPath = uvPath.substr(uvPath.find_last_of("/\\") + 1);
137cc290419Sopenharmony_ci    }
138cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "server shortpath:[%s] runPath:[%s]", shortPath, runPath.c_str());
139cc290419Sopenharmony_ci    // here we give a dummy option first, because getopt will assume the first option is command. it
140cc290419Sopenharmony_ci    // begin from 2nd args.
141cc290419Sopenharmony_ci    if (sprintf_s(buf, sizeof(buf), "dummy -l %d -s %s -m", Base::GetLogLevelByEnv(), listenString) < 0) {
142cc290419Sopenharmony_ci        return retVal;
143cc290419Sopenharmony_ci    }
144cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "Run server in debug-forground, cmd:%s, args:%s", runPath.c_str(), buf);
145cc290419Sopenharmony_ci    STARTUPINFO si = {};
146cc290419Sopenharmony_ci    si.cb = sizeof(STARTUPINFO);
147cc290419Sopenharmony_ci    PROCESS_INFORMATION pi = {};
148cc290419Sopenharmony_ci#ifndef HDC_DEBUG
149cc290419Sopenharmony_ci    si.dwFlags = STARTF_USESHOWWINDOW;
150cc290419Sopenharmony_ci    si.wShowWindow = SW_HIDE;
151cc290419Sopenharmony_ci#endif
152cc290419Sopenharmony_ci    if (!CreateProcess(runPath.c_str(), buf, nullptr, nullptr, false, CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi)) {
153cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "CreateProcess failed with cmd:%s, args:%s, Error Code %d", runPath.c_str(), buf,
154cc290419Sopenharmony_ci                  GetLastError());
155cc290419Sopenharmony_ci        retVal = false;
156cc290419Sopenharmony_ci    } else {
157cc290419Sopenharmony_ci        retVal = true;
158cc290419Sopenharmony_ci    }
159cc290419Sopenharmony_ci    CloseHandle(pi.hThread);
160cc290419Sopenharmony_ci    CloseHandle(pi.hProcess);
161cc290419Sopenharmony_ci#endif
162cc290419Sopenharmony_ci    return retVal;
163cc290419Sopenharmony_ci}
164cc290419Sopenharmony_ci
165cc290419Sopenharmony_ci// Only detects that the default call is in the loop address, the other tubes are not
166cc290419Sopenharmony_cibool HdcServer::PullupServer(const char *listenString)
167cc290419Sopenharmony_ci{
168cc290419Sopenharmony_ci    char path[BUF_SIZE_SMALL] = "";
169cc290419Sopenharmony_ci    size_t nPathSize = sizeof(path);
170cc290419Sopenharmony_ci    int ret = uv_exepath(path, &nPathSize);
171cc290419Sopenharmony_ci    if (ret < 0) {
172cc290419Sopenharmony_ci        constexpr int bufSize = 1024;
173cc290419Sopenharmony_ci        char buf[bufSize] = { 0 };
174cc290419Sopenharmony_ci        uv_err_name_r(ret, buf, bufSize);
175cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "uvexepath ret:%d error:%s", ret, buf);
176cc290419Sopenharmony_ci        return false;
177cc290419Sopenharmony_ci    }
178cc290419Sopenharmony_ci    Base::CreateLogDir();
179cc290419Sopenharmony_ci
180cc290419Sopenharmony_ci#ifdef _WIN32
181cc290419Sopenharmony_ci    if (!PullupServerWin32(path, listenString)) {
182cc290419Sopenharmony_ci        return false;
183cc290419Sopenharmony_ci    }
184cc290419Sopenharmony_ci#else
185cc290419Sopenharmony_ci    pid_t pc = fork();  // create process as daemon process
186cc290419Sopenharmony_ci    if (pc < 0) {
187cc290419Sopenharmony_ci        return false;
188cc290419Sopenharmony_ci    } else if (!pc) {
189cc290419Sopenharmony_ci        int i;
190cc290419Sopenharmony_ci        const int maxFD = 1024;
191cc290419Sopenharmony_ci        for (i = 0; i < maxFD; ++i) {
192cc290419Sopenharmony_ci            // close file pipe
193cc290419Sopenharmony_ci            int fd = i;
194cc290419Sopenharmony_ci            Base::CloseFd(fd);
195cc290419Sopenharmony_ci        }
196cc290419Sopenharmony_ci        execl(path, "hdc", "-m", "-s", listenString, nullptr);
197cc290419Sopenharmony_ci        exit(0);
198cc290419Sopenharmony_ci        return true;
199cc290419Sopenharmony_ci    }
200cc290419Sopenharmony_ci    // orig process
201cc290419Sopenharmony_ci#endif
202cc290419Sopenharmony_ci    // wait little time, util backend-server work ready
203cc290419Sopenharmony_ci    uv_sleep(TIME_BASE);
204cc290419Sopenharmony_ci    return true;
205cc290419Sopenharmony_ci}
206cc290419Sopenharmony_ci
207cc290419Sopenharmony_civoid HdcServer::ClearMapDaemonInfo()
208cc290419Sopenharmony_ci{
209cc290419Sopenharmony_ci    map<string, HDaemonInfo>::iterator iter;
210cc290419Sopenharmony_ci    uv_rwlock_rdlock(&daemonAdmin);
211cc290419Sopenharmony_ci    for (iter = mapDaemon.begin(); iter != mapDaemon.end();) {
212cc290419Sopenharmony_ci        string sKey = iter->first;
213cc290419Sopenharmony_ci        HDaemonInfo hDi = iter->second;
214cc290419Sopenharmony_ci        delete hDi;
215cc290419Sopenharmony_ci        ++iter;
216cc290419Sopenharmony_ci    }
217cc290419Sopenharmony_ci    uv_rwlock_rdunlock(&daemonAdmin);
218cc290419Sopenharmony_ci    uv_rwlock_wrlock(&daemonAdmin);
219cc290419Sopenharmony_ci    mapDaemon.clear();
220cc290419Sopenharmony_ci    uv_rwlock_wrunlock(&daemonAdmin);
221cc290419Sopenharmony_ci}
222cc290419Sopenharmony_ci
223cc290419Sopenharmony_civoid HdcServer::BuildDaemonVisableLine(HDaemonInfo hdi, bool fullDisplay, string &out)
224cc290419Sopenharmony_ci{
225cc290419Sopenharmony_ci    if (fullDisplay) {
226cc290419Sopenharmony_ci        string sConn = conTypeDetail[CONN_UNKNOWN];
227cc290419Sopenharmony_ci        if (hdi->connType < CONN_UNKNOWN) {
228cc290419Sopenharmony_ci            sConn = conTypeDetail[hdi->connType];
229cc290419Sopenharmony_ci        }
230cc290419Sopenharmony_ci
231cc290419Sopenharmony_ci        string sStatus = conStatusDetail[STATUS_UNKNOW];
232cc290419Sopenharmony_ci        if (hdi->connStatus < STATUS_UNAUTH) {
233cc290419Sopenharmony_ci            if (hdi->connStatus == STATUS_CONNECTED && hdi->daemonAuthStatus == DAEOMN_UNAUTHORIZED) {
234cc290419Sopenharmony_ci                sStatus = conStatusDetail[STATUS_UNAUTH];
235cc290419Sopenharmony_ci            } else {
236cc290419Sopenharmony_ci                sStatus = conStatusDetail[hdi->connStatus];
237cc290419Sopenharmony_ci            }
238cc290419Sopenharmony_ci        }
239cc290419Sopenharmony_ci
240cc290419Sopenharmony_ci        string devname = hdi->devName;
241cc290419Sopenharmony_ci        if (devname.empty()) {
242cc290419Sopenharmony_ci            devname = "unknown...";
243cc290419Sopenharmony_ci        }
244cc290419Sopenharmony_ci        out = Base::StringFormat("%s\t\t%s\t%s\t%s\n", hdi->connectKey.c_str(), sConn.c_str(), sStatus.c_str(),
245cc290419Sopenharmony_ci                                 devname.c_str());
246cc290419Sopenharmony_ci    } else {
247cc290419Sopenharmony_ci        if (hdi->connStatus == STATUS_CONNECTED) {
248cc290419Sopenharmony_ci            out = Base::StringFormat("%s", hdi->connectKey.c_str());
249cc290419Sopenharmony_ci            if (hdi->daemonAuthStatus == DAEOMN_UNAUTHORIZED) {
250cc290419Sopenharmony_ci                out.append("\tUnauthorized");
251cc290419Sopenharmony_ci            }
252cc290419Sopenharmony_ci            out.append("\n");
253cc290419Sopenharmony_ci        }
254cc290419Sopenharmony_ci    }
255cc290419Sopenharmony_ci}
256cc290419Sopenharmony_ci
257cc290419Sopenharmony_cistring HdcServer::GetDaemonMapList(uint8_t opType)
258cc290419Sopenharmony_ci{
259cc290419Sopenharmony_ci    string ret;
260cc290419Sopenharmony_ci    bool fullDisplay = false;
261cc290419Sopenharmony_ci    if (opType == OP_GET_STRLIST_FULL) {
262cc290419Sopenharmony_ci        fullDisplay = true;
263cc290419Sopenharmony_ci    }
264cc290419Sopenharmony_ci    uv_rwlock_rdlock(&daemonAdmin);
265cc290419Sopenharmony_ci    map<string, HDaemonInfo>::iterator iter;
266cc290419Sopenharmony_ci    string echoLine;
267cc290419Sopenharmony_ci    for (iter = mapDaemon.begin(); iter != mapDaemon.end(); ++iter) {
268cc290419Sopenharmony_ci        HDaemonInfo di = iter->second;
269cc290419Sopenharmony_ci        if (!di) {
270cc290419Sopenharmony_ci            continue;
271cc290419Sopenharmony_ci        }
272cc290419Sopenharmony_ci        echoLine = "";
273cc290419Sopenharmony_ci        BuildDaemonVisableLine(di, fullDisplay, echoLine);
274cc290419Sopenharmony_ci        ret += echoLine;
275cc290419Sopenharmony_ci    }
276cc290419Sopenharmony_ci    uv_rwlock_rdunlock(&daemonAdmin);
277cc290419Sopenharmony_ci    return ret;
278cc290419Sopenharmony_ci}
279cc290419Sopenharmony_ci
280cc290419Sopenharmony_civoid HdcServer::GetDaemonMapOnlyOne(HDaemonInfo &hDaemonInfoInOut)
281cc290419Sopenharmony_ci{
282cc290419Sopenharmony_ci    uv_rwlock_rdlock(&daemonAdmin);
283cc290419Sopenharmony_ci    string key;
284cc290419Sopenharmony_ci    for (auto &i : mapDaemon) {
285cc290419Sopenharmony_ci        if (i.second->connStatus == STATUS_CONNECTED) {
286cc290419Sopenharmony_ci            if (key == STRING_EMPTY) {
287cc290419Sopenharmony_ci                key = i.first;
288cc290419Sopenharmony_ci            } else {
289cc290419Sopenharmony_ci                key = STRING_EMPTY;
290cc290419Sopenharmony_ci                break;
291cc290419Sopenharmony_ci            }
292cc290419Sopenharmony_ci        }
293cc290419Sopenharmony_ci    }
294cc290419Sopenharmony_ci    if (key.size() > 0) {
295cc290419Sopenharmony_ci        hDaemonInfoInOut = mapDaemon[key];
296cc290419Sopenharmony_ci    }
297cc290419Sopenharmony_ci    uv_rwlock_rdunlock(&daemonAdmin);
298cc290419Sopenharmony_ci}
299cc290419Sopenharmony_ci
300cc290419Sopenharmony_civoid HdcServer::AdminDaemonMapForWait(const string &connectKey, HDaemonInfo &hDaemonInfoInOut)
301cc290419Sopenharmony_ci{
302cc290419Sopenharmony_ci    map<string, HDaemonInfo>::iterator iter;
303cc290419Sopenharmony_ci    for (iter = mapDaemon.begin(); iter != mapDaemon.end(); ++iter) {
304cc290419Sopenharmony_ci        HDaemonInfo di = iter->second;
305cc290419Sopenharmony_ci        if (di->connStatus == STATUS_CONNECTED) {
306cc290419Sopenharmony_ci            if (!connectKey.empty() && connectKey != di->connectKey) {
307cc290419Sopenharmony_ci                continue;
308cc290419Sopenharmony_ci            }
309cc290419Sopenharmony_ci            hDaemonInfoInOut = di;
310cc290419Sopenharmony_ci            return;
311cc290419Sopenharmony_ci        }
312cc290419Sopenharmony_ci    }
313cc290419Sopenharmony_ci    return;
314cc290419Sopenharmony_ci}
315cc290419Sopenharmony_ci
316cc290419Sopenharmony_cistring HdcServer::AdminDaemonMap(uint8_t opType, const string &connectKey, HDaemonInfo &hDaemonInfoInOut)
317cc290419Sopenharmony_ci{
318cc290419Sopenharmony_ci    string sRet;
319cc290419Sopenharmony_ci    switch (opType) {
320cc290419Sopenharmony_ci        case OP_ADD: {
321cc290419Sopenharmony_ci            HDaemonInfo pdiNew = new(std::nothrow) HdcDaemonInformation();
322cc290419Sopenharmony_ci            if (pdiNew == nullptr) {
323cc290419Sopenharmony_ci                WRITE_LOG(LOG_FATAL, "AdminDaemonMap new pdiNew failed");
324cc290419Sopenharmony_ci                break;
325cc290419Sopenharmony_ci            }
326cc290419Sopenharmony_ci            *pdiNew = *hDaemonInfoInOut;
327cc290419Sopenharmony_ci            uv_rwlock_wrlock(&daemonAdmin);
328cc290419Sopenharmony_ci            if (!mapDaemon[hDaemonInfoInOut->connectKey]) {
329cc290419Sopenharmony_ci                mapDaemon[hDaemonInfoInOut->connectKey] = pdiNew;
330cc290419Sopenharmony_ci            }
331cc290419Sopenharmony_ci            uv_rwlock_wrunlock(&daemonAdmin);
332cc290419Sopenharmony_ci            break;
333cc290419Sopenharmony_ci        }
334cc290419Sopenharmony_ci        case OP_GET_STRLIST:
335cc290419Sopenharmony_ci        case OP_GET_STRLIST_FULL: {
336cc290419Sopenharmony_ci            sRet = GetDaemonMapList(opType);
337cc290419Sopenharmony_ci            break;
338cc290419Sopenharmony_ci        }
339cc290419Sopenharmony_ci        case OP_QUERY: {
340cc290419Sopenharmony_ci            uv_rwlock_rdlock(&daemonAdmin);
341cc290419Sopenharmony_ci            if (mapDaemon.count(connectKey)) {
342cc290419Sopenharmony_ci                hDaemonInfoInOut = mapDaemon[connectKey];
343cc290419Sopenharmony_ci            }
344cc290419Sopenharmony_ci            uv_rwlock_rdunlock(&daemonAdmin);
345cc290419Sopenharmony_ci            break;
346cc290419Sopenharmony_ci        }
347cc290419Sopenharmony_ci        case OP_REMOVE: {
348cc290419Sopenharmony_ci            uv_rwlock_wrlock(&daemonAdmin);
349cc290419Sopenharmony_ci            if (mapDaemon.count(connectKey)) {
350cc290419Sopenharmony_ci                mapDaemon.erase(connectKey);
351cc290419Sopenharmony_ci            }
352cc290419Sopenharmony_ci            uv_rwlock_wrunlock(&daemonAdmin);
353cc290419Sopenharmony_ci            break;
354cc290419Sopenharmony_ci        }
355cc290419Sopenharmony_ci        case OP_GET_ANY: {
356cc290419Sopenharmony_ci            uv_rwlock_rdlock(&daemonAdmin);
357cc290419Sopenharmony_ci            map<string, HDaemonInfo>::iterator iter;
358cc290419Sopenharmony_ci            for (iter = mapDaemon.begin(); iter != mapDaemon.end(); ++iter) {
359cc290419Sopenharmony_ci                HDaemonInfo di = iter->second;
360cc290419Sopenharmony_ci                // usb will be auto connected
361cc290419Sopenharmony_ci                if (di->connStatus == STATUS_READY || di->connStatus == STATUS_CONNECTED) {
362cc290419Sopenharmony_ci                    hDaemonInfoInOut = di;
363cc290419Sopenharmony_ci                    break;
364cc290419Sopenharmony_ci                }
365cc290419Sopenharmony_ci            }
366cc290419Sopenharmony_ci            uv_rwlock_rdunlock(&daemonAdmin);
367cc290419Sopenharmony_ci            break;
368cc290419Sopenharmony_ci        }
369cc290419Sopenharmony_ci        case OP_WAIT_FOR_ANY: {
370cc290419Sopenharmony_ci            uv_rwlock_rdlock(&daemonAdmin);
371cc290419Sopenharmony_ci            AdminDaemonMapForWait(connectKey, hDaemonInfoInOut);
372cc290419Sopenharmony_ci            uv_rwlock_rdunlock(&daemonAdmin);
373cc290419Sopenharmony_ci            break;
374cc290419Sopenharmony_ci        }
375cc290419Sopenharmony_ci        case OP_GET_ONLY: {
376cc290419Sopenharmony_ci            GetDaemonMapOnlyOne(hDaemonInfoInOut);
377cc290419Sopenharmony_ci            break;
378cc290419Sopenharmony_ci        }
379cc290419Sopenharmony_ci        case OP_UPDATE: {  // Cannot update the Object HDi lower key value by direct value
380cc290419Sopenharmony_ci            uv_rwlock_wrlock(&daemonAdmin);
381cc290419Sopenharmony_ci            HDaemonInfo hdi = mapDaemon[hDaemonInfoInOut->connectKey];
382cc290419Sopenharmony_ci            if (hdi) {
383cc290419Sopenharmony_ci                *mapDaemon[hDaemonInfoInOut->connectKey] = *hDaemonInfoInOut;
384cc290419Sopenharmony_ci            }
385cc290419Sopenharmony_ci            uv_rwlock_wrunlock(&daemonAdmin);
386cc290419Sopenharmony_ci            break;
387cc290419Sopenharmony_ci        }
388cc290419Sopenharmony_ci        default:
389cc290419Sopenharmony_ci            break;
390cc290419Sopenharmony_ci    }
391cc290419Sopenharmony_ci    return sRet;
392cc290419Sopenharmony_ci}
393cc290419Sopenharmony_ci
394cc290419Sopenharmony_civoid HdcServer::NotifyInstanceSessionFree(HSession hSession, bool freeOrClear)
395cc290419Sopenharmony_ci{
396cc290419Sopenharmony_ci    HDaemonInfo hdiOld = nullptr;
397cc290419Sopenharmony_ci    AdminDaemonMap(OP_QUERY, hSession->connectKey, hdiOld);
398cc290419Sopenharmony_ci    if (hdiOld == nullptr) {
399cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "NotifyInstanceSessionFree hdiOld nullptr");
400cc290419Sopenharmony_ci        return;
401cc290419Sopenharmony_ci    }
402cc290419Sopenharmony_ci    if (!freeOrClear) {  // step1
403cc290419Sopenharmony_ci        // update
404cc290419Sopenharmony_ci        HdcDaemonInformation diNew = *hdiOld;
405cc290419Sopenharmony_ci        diNew.connStatus = STATUS_OFFLINE;
406cc290419Sopenharmony_ci        HDaemonInfo hdiNew = &diNew;
407cc290419Sopenharmony_ci        AdminDaemonMap(OP_UPDATE, hSession->connectKey, hdiNew);
408cc290419Sopenharmony_ci        CleanForwardMap(hSession->sessionId);
409cc290419Sopenharmony_ci    } else {  // step2
410cc290419Sopenharmony_ci        string usbMountPoint = hdiOld->usbMountPoint;
411cc290419Sopenharmony_ci        // The waiting time must be longer than DEVICE_CHECK_INTERVAL. Wait the method WatchUsbNodeChange
412cc290419Sopenharmony_ci        // to finish execution. Otherwise, the main thread and the session worker thread will conflict
413cc290419Sopenharmony_ci        constexpr int waitDaemonReconnect = DEVICE_CHECK_INTERVAL + DEVICE_CHECK_INTERVAL;
414cc290419Sopenharmony_ci        auto funcDelayUsbNotify = [this, usbMountPoint](const uint8_t flag, string &msg, const void *) -> void {
415cc290419Sopenharmony_ci            string s = usbMountPoint;
416cc290419Sopenharmony_ci            clsUSBClt->RemoveIgnoreDevice(s);
417cc290419Sopenharmony_ci        };
418cc290419Sopenharmony_ci        if (usbMountPoint.size() > 0) {
419cc290419Sopenharmony_ci            // wait time for daemon reconnect
420cc290419Sopenharmony_ci            // If removed from maplist, the USB module will be reconnected, so it needs to wait for a while
421cc290419Sopenharmony_ci            Base::DelayDoSimple(&loopMain, waitDaemonReconnect, funcDelayUsbNotify);
422cc290419Sopenharmony_ci        }
423cc290419Sopenharmony_ci    }
424cc290419Sopenharmony_ci}
425cc290419Sopenharmony_ci
426cc290419Sopenharmony_civoid HdcServer::GetDaemonAuthType(HSession hSession, SessionHandShake &handshake)
427cc290419Sopenharmony_ci{
428cc290419Sopenharmony_ci    /*
429cc290419Sopenharmony_ci     * check if daemon support RSA_3072_SHA512 for auth
430cc290419Sopenharmony_ci     * it the value is not RSA_3072_SHA512, we use old auth algorithm
431cc290419Sopenharmony_ci     * Notice, If deamon is old version 'handshake.buf' will be 'hSession->tokenRSA',
432cc290419Sopenharmony_ci     * the length of hSession->tokenRSA less than min len(TLV_MIN_LEN), so there no
433cc290419Sopenharmony_ci     * problem
434cc290419Sopenharmony_ci    */
435cc290419Sopenharmony_ci    std::map<string, string> tlvmap;
436cc290419Sopenharmony_ci    hSession->verifyType = AuthVerifyType::RSA_ENCRYPT;
437cc290419Sopenharmony_ci    if (!Base::TlvToStringMap(handshake.buf, tlvmap)) {
438cc290419Sopenharmony_ci        WRITE_LOG(LOG_INFO, "the deamon maybe old version for %u session, so use rsa encrypt", hSession->sessionId);
439cc290419Sopenharmony_ci        return;
440cc290419Sopenharmony_ci    }
441cc290419Sopenharmony_ci    if (tlvmap.find(TAG_AUTH_TYPE) == tlvmap.end() ||
442cc290419Sopenharmony_ci        tlvmap[TAG_AUTH_TYPE] != std::to_string(AuthVerifyType::RSA_3072_SHA512)) {
443cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "the buf is invalid for %u session, so use rsa encrypt", hSession->sessionId);
444cc290419Sopenharmony_ci        return;
445cc290419Sopenharmony_ci    }
446cc290419Sopenharmony_ci    hSession->verifyType = AuthVerifyType::RSA_3072_SHA512;
447cc290419Sopenharmony_ci    WRITE_LOG(LOG_INFO, "daemon auth type is rsa_3072_sha512 for %u session", hSession->sessionId);
448cc290419Sopenharmony_ci}
449cc290419Sopenharmony_ci
450cc290419Sopenharmony_cibool HdcServer::HandServerAuth(HSession hSession, SessionHandShake &handshake)
451cc290419Sopenharmony_ci{
452cc290419Sopenharmony_ci    string bufString;
453cc290419Sopenharmony_ci    switch (handshake.authType) {
454cc290419Sopenharmony_ci        case AUTH_PUBLICKEY: {
455cc290419Sopenharmony_ci            WRITE_LOG(LOG_INFO, "recive get publickey cmd");
456cc290419Sopenharmony_ci            GetDaemonAuthType(hSession, handshake);
457cc290419Sopenharmony_ci            if (!HdcAuth::GetPublicKeyinfo(handshake.buf)) {
458cc290419Sopenharmony_ci                WRITE_LOG(LOG_FATAL, "load public key failed");
459cc290419Sopenharmony_ci                return false;
460cc290419Sopenharmony_ci            }
461cc290419Sopenharmony_ci            handshake.authType = AUTH_PUBLICKEY;
462cc290419Sopenharmony_ci            bufString = SerialStruct::SerializeToString(handshake);
463cc290419Sopenharmony_ci            Send(hSession->sessionId, 0, CMD_KERNEL_HANDSHAKE,
464cc290419Sopenharmony_ci                 reinterpret_cast<uint8_t *>(const_cast<char *>(bufString.c_str())), bufString.size());
465cc290419Sopenharmony_ci
466cc290419Sopenharmony_ci            WRITE_LOG(LOG_INFO, "send pubkey over");
467cc290419Sopenharmony_ci            return true;
468cc290419Sopenharmony_ci        }
469cc290419Sopenharmony_ci        case AUTH_SIGNATURE: {
470cc290419Sopenharmony_ci            WRITE_LOG(LOG_INFO, "recive auth signture cmd");
471cc290419Sopenharmony_ci            if (!HdcAuth::RsaSignAndBase64(handshake.buf, hSession->verifyType)) {
472cc290419Sopenharmony_ci                WRITE_LOG(LOG_FATAL, "sign failed");
473cc290419Sopenharmony_ci                return false;
474cc290419Sopenharmony_ci            }
475cc290419Sopenharmony_ci            handshake.authType = AUTH_SIGNATURE;
476cc290419Sopenharmony_ci            bufString = SerialStruct::SerializeToString(handshake);
477cc290419Sopenharmony_ci            Send(hSession->sessionId, 0, CMD_KERNEL_HANDSHAKE,
478cc290419Sopenharmony_ci                 reinterpret_cast<uint8_t *>(const_cast<char *>(bufString.c_str())), bufString.size());
479cc290419Sopenharmony_ci            WRITE_LOG(LOG_INFO, "response auth signture success");
480cc290419Sopenharmony_ci            return true;
481cc290419Sopenharmony_ci        }
482cc290419Sopenharmony_ci        default:
483cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "invalid auth type %d", handshake.authType);
484cc290419Sopenharmony_ci            return false;
485cc290419Sopenharmony_ci    }
486cc290419Sopenharmony_ci}
487cc290419Sopenharmony_ci
488cc290419Sopenharmony_civoid HdcServer::UpdateHdiInfo(Hdc::HdcSessionBase::SessionHandShake &handshake, const string &connectKey)
489cc290419Sopenharmony_ci{
490cc290419Sopenharmony_ci    HDaemonInfo hdiOld = nullptr;
491cc290419Sopenharmony_ci    AdminDaemonMap(OP_QUERY, connectKey, hdiOld);
492cc290419Sopenharmony_ci    if (!hdiOld) {
493cc290419Sopenharmony_ci        return;
494cc290419Sopenharmony_ci    }
495cc290419Sopenharmony_ci    HdcDaemonInformation diNew = *hdiOld;
496cc290419Sopenharmony_ci    HDaemonInfo hdiNew = &diNew;
497cc290419Sopenharmony_ci    // update
498cc290419Sopenharmony_ci    hdiNew->connStatus = STATUS_CONNECTED;
499cc290419Sopenharmony_ci    WRITE_LOG(LOG_INFO, "handshake info is : %s", handshake.ToDebugString().c_str());
500cc290419Sopenharmony_ci    WRITE_LOG(LOG_INFO, "handshake.buf = %s", handshake.buf.c_str());
501cc290419Sopenharmony_ci    if (handshake.version < "Ver: 3.0.0b") {
502cc290419Sopenharmony_ci        if (!handshake.buf.empty()) {
503cc290419Sopenharmony_ci            hdiNew->devName = handshake.buf;
504cc290419Sopenharmony_ci        }
505cc290419Sopenharmony_ci    } else {
506cc290419Sopenharmony_ci        std::map<string, string> tlvmap;
507cc290419Sopenharmony_ci        if (Base::TlvToStringMap(handshake.buf, tlvmap)) {
508cc290419Sopenharmony_ci            if (tlvmap.find(TAG_DEVNAME) != tlvmap.end()) {
509cc290419Sopenharmony_ci                hdiNew->devName = tlvmap[TAG_DEVNAME];
510cc290419Sopenharmony_ci                WRITE_LOG(LOG_INFO, "devname = %s", hdiNew->devName.c_str());
511cc290419Sopenharmony_ci            }
512cc290419Sopenharmony_ci            if (tlvmap.find(TAG_EMGMSG) != tlvmap.end()) {
513cc290419Sopenharmony_ci                hdiNew->emgmsg = tlvmap[TAG_EMGMSG];
514cc290419Sopenharmony_ci                WRITE_LOG(LOG_INFO, "emgmsg = %s", hdiNew->emgmsg.c_str());
515cc290419Sopenharmony_ci            }
516cc290419Sopenharmony_ci            if (tlvmap.find(TAG_DAEOMN_AUTHSTATUS) != tlvmap.end()) {
517cc290419Sopenharmony_ci                hdiNew->daemonAuthStatus = tlvmap[TAG_DAEOMN_AUTHSTATUS];
518cc290419Sopenharmony_ci                WRITE_LOG(LOG_INFO, "daemonauthstatus = %s", hdiNew->daemonAuthStatus.c_str());
519cc290419Sopenharmony_ci            }
520cc290419Sopenharmony_ci        } else {
521cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "TlvToStringMap failed");
522cc290419Sopenharmony_ci        }
523cc290419Sopenharmony_ci    }
524cc290419Sopenharmony_ci    hdiNew->version = handshake.version;
525cc290419Sopenharmony_ci    AdminDaemonMap(OP_UPDATE, connectKey, hdiNew);
526cc290419Sopenharmony_ci}
527cc290419Sopenharmony_ci
528cc290419Sopenharmony_cibool HdcServer::ServerSessionHandshake(HSession hSession, uint8_t *payload, int payloadSize)
529cc290419Sopenharmony_ci{
530cc290419Sopenharmony_ci    // session handshake step3
531cc290419Sopenharmony_ci    string s = string(reinterpret_cast<char *>(payload), payloadSize);
532cc290419Sopenharmony_ci    Hdc::HdcSessionBase::SessionHandShake handshake;
533cc290419Sopenharmony_ci    SerialStruct::ParseFromString(handshake, s);
534cc290419Sopenharmony_ci#ifdef HDC_DEBUG
535cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "handshake.banner:%s, payload:%s(%d)", handshake.banner.c_str(), s.c_str(), payloadSize);
536cc290419Sopenharmony_ci#endif
537cc290419Sopenharmony_ci
538cc290419Sopenharmony_ci    if (handshake.banner == HANDSHAKE_FAILED.c_str()) {
539cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Handshake failed");
540cc290419Sopenharmony_ci        return false;
541cc290419Sopenharmony_ci    }
542cc290419Sopenharmony_ci
543cc290419Sopenharmony_ci    if (handshake.banner != HANDSHAKE_MESSAGE.c_str()) {
544cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Hello failed");
545cc290419Sopenharmony_ci        return false;
546cc290419Sopenharmony_ci    }
547cc290419Sopenharmony_ci    if (handshake.authType != AUTH_OK) {
548cc290419Sopenharmony_ci        if (!HandServerAuth(hSession, handshake)) {
549cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "Auth failed");
550cc290419Sopenharmony_ci            return false;
551cc290419Sopenharmony_ci        }
552cc290419Sopenharmony_ci        return true;
553cc290419Sopenharmony_ci    }
554cc290419Sopenharmony_ci    // handshake auth OK
555cc290419Sopenharmony_ci    UpdateHdiInfo(handshake, hSession->connectKey);
556cc290419Sopenharmony_ci    hSession->handshakeOK = true;
557cc290419Sopenharmony_ci    return true;
558cc290419Sopenharmony_ci}
559cc290419Sopenharmony_ci
560cc290419Sopenharmony_ci// call in child thread
561cc290419Sopenharmony_cibool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload,
562cc290419Sopenharmony_ci                             const int payloadSize)
563cc290419Sopenharmony_ci{
564cc290419Sopenharmony_ci    bool ret = true;
565cc290419Sopenharmony_ci    HdcServerForClient *sfc = static_cast<HdcServerForClient *>(clsServerForClient);
566cc290419Sopenharmony_ci    if (command == CMD_KERNEL_HANDSHAKE) {
567cc290419Sopenharmony_ci        ret = ServerSessionHandshake(hSession, payload, payloadSize);
568cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Session handshake %s connType:%d", ret ? "successful" : "failed",
569cc290419Sopenharmony_ci                  hSession->connType);
570cc290419Sopenharmony_ci        return ret;
571cc290419Sopenharmony_ci    }
572cc290419Sopenharmony_ci    // When you first initialize, ChannelID may be 0
573cc290419Sopenharmony_ci    HChannel hChannel = sfc->AdminChannel(OP_QUERY_REF, channelId, nullptr);
574cc290419Sopenharmony_ci    if (!hChannel) {
575cc290419Sopenharmony_ci        if (command == CMD_KERNEL_CHANNEL_CLOSE) {
576cc290419Sopenharmony_ci            // Daemon close channel and want to notify server close channel also, but it may has been
577cc290419Sopenharmony_ci            // closed by herself
578cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "Die channelId :%lu recv CMD_KERNEL_CHANNEL_CLOSE", channelId);
579cc290419Sopenharmony_ci        } else {
580cc290419Sopenharmony_ci            // Client may be ctrl+c and Server remove channel. notify server async
581cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "channelId :%lu die", channelId);
582cc290419Sopenharmony_ci        }
583cc290419Sopenharmony_ci        uint8_t flag = 0;
584cc290419Sopenharmony_ci        Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &flag, 1);
585cc290419Sopenharmony_ci        return ret;
586cc290419Sopenharmony_ci    }
587cc290419Sopenharmony_ci    if (hChannel->isDead) {
588cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "FetchCommand channelId:%u isDead", channelId);
589cc290419Sopenharmony_ci        --hChannel->ref;
590cc290419Sopenharmony_ci        return ret;
591cc290419Sopenharmony_ci    }
592cc290419Sopenharmony_ci    switch (command) {
593cc290419Sopenharmony_ci        case CMD_KERNEL_ECHO_RAW: {  // Native shell data output
594cc290419Sopenharmony_ci            sfc->EchoClientRaw(hChannel, payload, payloadSize);
595cc290419Sopenharmony_ci            break;
596cc290419Sopenharmony_ci        }
597cc290419Sopenharmony_ci        case CMD_KERNEL_ECHO: {
598cc290419Sopenharmony_ci            MessageLevel level = static_cast<MessageLevel>(*payload);
599cc290419Sopenharmony_ci            string s(reinterpret_cast<char *>(payload + 1), payloadSize - 1);
600cc290419Sopenharmony_ci            sfc->EchoClient(hChannel, level, s.c_str());
601cc290419Sopenharmony_ci            WRITE_LOG(LOG_INFO, "CMD_KERNEL_ECHO size:%d channelId:%u", payloadSize - 1, channelId);
602cc290419Sopenharmony_ci            break;
603cc290419Sopenharmony_ci        }
604cc290419Sopenharmony_ci        case CMD_KERNEL_CHANNEL_CLOSE: {
605cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "CMD_KERNEL_CHANNEL_CLOSE channelid:%u", channelId);
606cc290419Sopenharmony_ci            // Forcibly closing the tcp handle here may result in incomplete data reception on the client side
607cc290419Sopenharmony_ci            ClearOwnTasks(hSession, channelId);
608cc290419Sopenharmony_ci            // crossthread free
609cc290419Sopenharmony_ci            sfc->PushAsyncMessage(channelId, ASYNC_FREE_CHANNEL, nullptr, 0);
610cc290419Sopenharmony_ci            if (*payload != 0) {
611cc290419Sopenharmony_ci                --(*payload);
612cc290419Sopenharmony_ci                Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1);
613cc290419Sopenharmony_ci            }
614cc290419Sopenharmony_ci            break;
615cc290419Sopenharmony_ci        }
616cc290419Sopenharmony_ci        case CMD_FORWARD_SUCCESS: {
617cc290419Sopenharmony_ci            // add to local
618cc290419Sopenharmony_ci            HdcForwardInformation di;
619cc290419Sopenharmony_ci            HForwardInfo pdiNew = &di;
620cc290419Sopenharmony_ci            pdiNew->channelId = channelId;
621cc290419Sopenharmony_ci            pdiNew->sessionId = hSession->sessionId;
622cc290419Sopenharmony_ci            pdiNew->connectKey = hSession->connectKey;
623cc290419Sopenharmony_ci            pdiNew->forwardDirection = (reinterpret_cast<char *>(payload))[0] == '1';
624cc290419Sopenharmony_ci            pdiNew->taskString = reinterpret_cast<char *>(payload);
625cc290419Sopenharmony_ci            AdminForwardMap(OP_ADD, STRING_EMPTY, pdiNew);
626cc290419Sopenharmony_ci            Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP);  // detch client channel
627cc290419Sopenharmony_ci            break;
628cc290419Sopenharmony_ci        }
629cc290419Sopenharmony_ci        case CMD_FILE_INIT:
630cc290419Sopenharmony_ci        case CMD_FILE_CHECK:
631cc290419Sopenharmony_ci        case CMD_FILE_BEGIN:
632cc290419Sopenharmony_ci        case CMD_FILE_DATA:
633cc290419Sopenharmony_ci        case CMD_FILE_FINISH:
634cc290419Sopenharmony_ci        case CMD_FILE_MODE:
635cc290419Sopenharmony_ci        case CMD_DIR_MODE:
636cc290419Sopenharmony_ci        case CMD_APP_INIT:
637cc290419Sopenharmony_ci        case CMD_APP_CHECK:
638cc290419Sopenharmony_ci        case CMD_APP_BEGIN:
639cc290419Sopenharmony_ci        case CMD_APP_DATA:
640cc290419Sopenharmony_ci        case CMD_APP_FINISH:
641cc290419Sopenharmony_ci            if (hChannel->fromClient) {
642cc290419Sopenharmony_ci                // server directly passthrough app command to client if remote file mode, else go default
643cc290419Sopenharmony_ci                sfc->SendCommandToClient(hChannel, command, payload, payloadSize);
644cc290419Sopenharmony_ci                break;
645cc290419Sopenharmony_ci            }
646cc290419Sopenharmony_ci        default: {
647cc290419Sopenharmony_ci            HSession hSessionByQuery = AdminSession(OP_QUERY, hChannel->targetSessionId, nullptr);
648cc290419Sopenharmony_ci            if (!hSessionByQuery) {
649cc290419Sopenharmony_ci                ret = false;
650cc290419Sopenharmony_ci                break;
651cc290419Sopenharmony_ci            }
652cc290419Sopenharmony_ci            ret = DispatchTaskData(hSessionByQuery, channelId, command, payload, payloadSize);
653cc290419Sopenharmony_ci            break;
654cc290419Sopenharmony_ci        }
655cc290419Sopenharmony_ci    }
656cc290419Sopenharmony_ci    --hChannel->ref;
657cc290419Sopenharmony_ci    return ret;
658cc290419Sopenharmony_ci}
659cc290419Sopenharmony_ci
660cc290419Sopenharmony_civoid HdcServer::BuildForwardVisableLine(bool fullOrSimble, HForwardInfo hfi, string &echo)
661cc290419Sopenharmony_ci{
662cc290419Sopenharmony_ci    string buf;
663cc290419Sopenharmony_ci    if (fullOrSimble) {
664cc290419Sopenharmony_ci        buf = Base::StringFormat("%s    %s    %s\n", hfi->connectKey.c_str(), hfi->taskString.substr(OFFSET).c_str(),
665cc290419Sopenharmony_ci                                 hfi->forwardDirection ? "[Forward]" : "[Reverse]");
666cc290419Sopenharmony_ci    } else {
667cc290419Sopenharmony_ci        buf = Base::StringFormat("%s\n", hfi->taskString.c_str());
668cc290419Sopenharmony_ci    }
669cc290419Sopenharmony_ci    echo += buf;
670cc290419Sopenharmony_ci}
671cc290419Sopenharmony_ci
672cc290419Sopenharmony_cistring HdcServer::AdminForwardMap(uint8_t opType, const string &taskString, HForwardInfo &hForwardInfoInOut)
673cc290419Sopenharmony_ci{
674cc290419Sopenharmony_ci    string sRet;
675cc290419Sopenharmony_ci    switch (opType) {
676cc290419Sopenharmony_ci        case OP_ADD: {
677cc290419Sopenharmony_ci            HForwardInfo pfiNew = new(std::nothrow) HdcForwardInformation();
678cc290419Sopenharmony_ci            if (pfiNew == nullptr) {
679cc290419Sopenharmony_ci                WRITE_LOG(LOG_FATAL, "AdminForwardMap new pfiNew failed");
680cc290419Sopenharmony_ci                break;
681cc290419Sopenharmony_ci            }
682cc290419Sopenharmony_ci            *pfiNew = *hForwardInfoInOut;
683cc290419Sopenharmony_ci            uv_rwlock_wrlock(&forwardAdmin);
684cc290419Sopenharmony_ci            if (!mapForward[hForwardInfoInOut->taskString]) {
685cc290419Sopenharmony_ci                mapForward[hForwardInfoInOut->taskString] = pfiNew;
686cc290419Sopenharmony_ci            }
687cc290419Sopenharmony_ci            uv_rwlock_wrunlock(&forwardAdmin);
688cc290419Sopenharmony_ci            break;
689cc290419Sopenharmony_ci        }
690cc290419Sopenharmony_ci        case OP_GET_STRLIST:
691cc290419Sopenharmony_ci        case OP_GET_STRLIST_FULL: {
692cc290419Sopenharmony_ci            uv_rwlock_rdlock(&forwardAdmin);
693cc290419Sopenharmony_ci            map<string, HForwardInfo>::iterator iter;
694cc290419Sopenharmony_ci            for (iter = mapForward.begin(); iter != mapForward.end(); ++iter) {
695cc290419Sopenharmony_ci                HForwardInfo di = iter->second;
696cc290419Sopenharmony_ci                if (!di) {
697cc290419Sopenharmony_ci                    continue;
698cc290419Sopenharmony_ci                }
699cc290419Sopenharmony_ci                BuildForwardVisableLine(opType == OP_GET_STRLIST_FULL, di, sRet);
700cc290419Sopenharmony_ci            }
701cc290419Sopenharmony_ci            uv_rwlock_rdunlock(&forwardAdmin);
702cc290419Sopenharmony_ci            break;
703cc290419Sopenharmony_ci        }
704cc290419Sopenharmony_ci        case OP_QUERY: {
705cc290419Sopenharmony_ci            uv_rwlock_rdlock(&forwardAdmin);
706cc290419Sopenharmony_ci            if (mapForward.count(taskString)) {
707cc290419Sopenharmony_ci                hForwardInfoInOut = mapForward[taskString];
708cc290419Sopenharmony_ci            }
709cc290419Sopenharmony_ci            uv_rwlock_rdunlock(&forwardAdmin);
710cc290419Sopenharmony_ci            break;
711cc290419Sopenharmony_ci        }
712cc290419Sopenharmony_ci        case OP_REMOVE: {
713cc290419Sopenharmony_ci            uv_rwlock_wrlock(&forwardAdmin);
714cc290419Sopenharmony_ci            if (mapForward.count(taskString)) {
715cc290419Sopenharmony_ci                mapForward.erase(taskString);
716cc290419Sopenharmony_ci            }
717cc290419Sopenharmony_ci            uv_rwlock_wrunlock(&forwardAdmin);
718cc290419Sopenharmony_ci            break;
719cc290419Sopenharmony_ci        }
720cc290419Sopenharmony_ci        default:
721cc290419Sopenharmony_ci            break;
722cc290419Sopenharmony_ci    }
723cc290419Sopenharmony_ci    return sRet;
724cc290419Sopenharmony_ci}
725cc290419Sopenharmony_ci
726cc290419Sopenharmony_civoid HdcServer::CleanForwardMap(uint32_t sessionId)
727cc290419Sopenharmony_ci{
728cc290419Sopenharmony_ci    uv_rwlock_rdlock(&forwardAdmin);
729cc290419Sopenharmony_ci    map<string, HForwardInfo>::iterator iter;
730cc290419Sopenharmony_ci    for (iter = mapForward.begin(); iter != mapForward.end();) {
731cc290419Sopenharmony_ci        HForwardInfo di = iter->second;
732cc290419Sopenharmony_ci        if (!di) {
733cc290419Sopenharmony_ci            continue;
734cc290419Sopenharmony_ci        }
735cc290419Sopenharmony_ci        if (sessionId == 0 || sessionId == di->sessionId) {
736cc290419Sopenharmony_ci            iter = mapForward.erase(iter);
737cc290419Sopenharmony_ci        } else {
738cc290419Sopenharmony_ci            iter++;
739cc290419Sopenharmony_ci        }
740cc290419Sopenharmony_ci    }
741cc290419Sopenharmony_ci    uv_rwlock_rdunlock(&forwardAdmin);
742cc290419Sopenharmony_ci}
743cc290419Sopenharmony_ci
744cc290419Sopenharmony_civoid HdcServer::UsbPreConnect(uv_timer_t *handle)
745cc290419Sopenharmony_ci{
746cc290419Sopenharmony_ci    HSession hSession = (HSession)handle->data;
747cc290419Sopenharmony_ci    bool stopLoop = false;
748cc290419Sopenharmony_ci    HdcServer *hdcServer = (HdcServer *)hSession->classInstance;
749cc290419Sopenharmony_ci    while (true) {
750cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "HdcServer::UsbPreConnect");
751cc290419Sopenharmony_ci        HDaemonInfo pDi = nullptr;
752cc290419Sopenharmony_ci        if (hSession->connectKey == "any") {
753cc290419Sopenharmony_ci            hdcServer->AdminDaemonMap(OP_GET_ANY, hSession->connectKey, pDi);
754cc290419Sopenharmony_ci        } else {
755cc290419Sopenharmony_ci            hdcServer->AdminDaemonMap(OP_QUERY, hSession->connectKey, pDi);
756cc290419Sopenharmony_ci        }
757cc290419Sopenharmony_ci        if (!pDi || !pDi->usbMountPoint.size()) {
758cc290419Sopenharmony_ci            break;
759cc290419Sopenharmony_ci        }
760cc290419Sopenharmony_ci        HdcHostUSB *hdcHostUSB = (HdcHostUSB *)hSession->classModule;
761cc290419Sopenharmony_ci        hdcHostUSB->ConnectDetectDaemon(hSession, pDi);
762cc290419Sopenharmony_ci        stopLoop = true;
763cc290419Sopenharmony_ci        break;
764cc290419Sopenharmony_ci    }
765cc290419Sopenharmony_ci    if (stopLoop && !uv_is_closing((const uv_handle_t *)handle)) {
766cc290419Sopenharmony_ci        uv_close((uv_handle_t *)handle, Base::CloseTimerCallback);
767cc290419Sopenharmony_ci    }
768cc290419Sopenharmony_ci}
769cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
770cc290419Sopenharmony_civoid HdcServer::UartPreConnect(uv_timer_t *handle)
771cc290419Sopenharmony_ci{
772cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "%s", __FUNCTION__);
773cc290419Sopenharmony_ci    HSession hSession = (HSession)handle->data;
774cc290419Sopenharmony_ci    bool stopLoop = false;
775cc290419Sopenharmony_ci    HdcServer *hdcServer = (HdcServer *)hSession->classInstance;
776cc290419Sopenharmony_ci    const int uartConnectRetryMax = 100; // max 6s
777cc290419Sopenharmony_ci    while (true) {
778cc290419Sopenharmony_ci        if (hSession->hUART->retryCount > uartConnectRetryMax) {
779cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "%s failed because max retry limit %d", __FUNCTION__,
780cc290419Sopenharmony_ci                      hSession->hUART->retryCount);
781cc290419Sopenharmony_ci            hdcServer->FreeSession(hSession->sessionId);
782cc290419Sopenharmony_ci            stopLoop = true;
783cc290419Sopenharmony_ci            break;
784cc290419Sopenharmony_ci        }
785cc290419Sopenharmony_ci        hSession->hUART->retryCount++;
786cc290419Sopenharmony_ci        HDaemonInfo pDi = nullptr;
787cc290419Sopenharmony_ci
788cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "%s query %s", __FUNCTION__, hSession->ToDebugString().c_str());
789cc290419Sopenharmony_ci        hdcServer->AdminDaemonMap(OP_QUERY, hSession->connectKey, pDi);
790cc290419Sopenharmony_ci        if (!pDi) {
791cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "%s not found", __FUNCTION__);
792cc290419Sopenharmony_ci            break;
793cc290419Sopenharmony_ci        }
794cc290419Sopenharmony_ci        HdcHostUART *hdcHostUART = (HdcHostUART *)hSession->classModule;
795cc290419Sopenharmony_ci        hdcHostUART->ConnectDaemonByUart(hSession, pDi);
796cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "%s ConnectDaemonByUart done", __FUNCTION__);
797cc290419Sopenharmony_ci
798cc290419Sopenharmony_ci        stopLoop = true;
799cc290419Sopenharmony_ci        break;
800cc290419Sopenharmony_ci    }
801cc290419Sopenharmony_ci    if (stopLoop) {
802cc290419Sopenharmony_ci        uv_close((uv_handle_t *)handle, Base::CloseTimerCallback);
803cc290419Sopenharmony_ci    }
804cc290419Sopenharmony_ci}
805cc290419Sopenharmony_ci
806cc290419Sopenharmony_civoid HdcServer::CreatConnectUart(HSession hSession)
807cc290419Sopenharmony_ci{
808cc290419Sopenharmony_ci    uv_timer_t *waitTimeDoCmd = new(std::nothrow) uv_timer_t;
809cc290419Sopenharmony_ci    if (waitTimeDoCmd == nullptr) {
810cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "CreatConnectUart new waitTimeDoCmd failed");
811cc290419Sopenharmony_ci        return;
812cc290419Sopenharmony_ci    }
813cc290419Sopenharmony_ci    uv_timer_init(&loopMain, waitTimeDoCmd);
814cc290419Sopenharmony_ci    waitTimeDoCmd->data = hSession;
815cc290419Sopenharmony_ci    uv_timer_start(waitTimeDoCmd, UartPreConnect, UV_TIMEOUT, UV_REPEAT);
816cc290419Sopenharmony_ci}
817cc290419Sopenharmony_ci#endif
818cc290419Sopenharmony_ci// -1,has old,-2 error
819cc290419Sopenharmony_ciint HdcServer::CreateConnect(const string &connectKey, bool isCheck)
820cc290419Sopenharmony_ci{
821cc290419Sopenharmony_ci    uint8_t connType = 0;
822cc290419Sopenharmony_ci    if (connectKey.find(":") != std::string::npos) { // TCP
823cc290419Sopenharmony_ci        connType = CONN_TCP;
824cc290419Sopenharmony_ci    }
825cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
826cc290419Sopenharmony_ci    else if (connectKey.find("COM") == 0 ||
827cc290419Sopenharmony_ci             connectKey.find("/dev/ttyUSB") == 0 ||
828cc290419Sopenharmony_ci             connectKey.find("/dev/cu.") == 0) { // UART
829cc290419Sopenharmony_ci        connType = CONN_SERIAL;
830cc290419Sopenharmony_ci    }
831cc290419Sopenharmony_ci#endif
832cc290419Sopenharmony_ci    else { // Not support
833cc290419Sopenharmony_ci        return ERR_NO_SUPPORT;
834cc290419Sopenharmony_ci    }
835cc290419Sopenharmony_ci    HDaemonInfo hdi = nullptr;
836cc290419Sopenharmony_ci    if (connectKey == "any") {
837cc290419Sopenharmony_ci        return RET_SUCCESS;
838cc290419Sopenharmony_ci    }
839cc290419Sopenharmony_ci    AdminDaemonMap(OP_QUERY, connectKey, hdi);
840cc290419Sopenharmony_ci    if (hdi == nullptr) {
841cc290419Sopenharmony_ci        HdcDaemonInformation di = {};
842cc290419Sopenharmony_ci        di.connectKey = connectKey;
843cc290419Sopenharmony_ci        di.connType = connType;
844cc290419Sopenharmony_ci        di.connStatus = STATUS_UNKNOW;
845cc290419Sopenharmony_ci        HDaemonInfo pDi = reinterpret_cast<HDaemonInfo>(&di);
846cc290419Sopenharmony_ci        AdminDaemonMap(OP_ADD, "", pDi);
847cc290419Sopenharmony_ci        AdminDaemonMap(OP_QUERY, connectKey, hdi);
848cc290419Sopenharmony_ci    }
849cc290419Sopenharmony_ci    if (!hdi || hdi->connStatus == STATUS_CONNECTED) {
850cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Connected return");
851cc290419Sopenharmony_ci        return ERR_GENERIC;
852cc290419Sopenharmony_ci    }
853cc290419Sopenharmony_ci    HSession hSession = nullptr;
854cc290419Sopenharmony_ci    if (connType == CONN_TCP) {
855cc290419Sopenharmony_ci        hSession = clsTCPClt->ConnectDaemon(connectKey, isCheck);
856cc290419Sopenharmony_ci    } else if (connType == CONN_SERIAL) {
857cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
858cc290419Sopenharmony_ci        clsUARTClt->SetCheckFlag(isCheck);
859cc290419Sopenharmony_ci        hSession = clsUARTClt->ConnectDaemon(connectKey);
860cc290419Sopenharmony_ci#endif
861cc290419Sopenharmony_ci    } else {
862cc290419Sopenharmony_ci        hSession = MallocSession(true, CONN_USB, clsUSBClt);
863cc290419Sopenharmony_ci        if (!hSession) {
864cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "CreateConnect malloc usb session failed %s", Hdc::MaskString(connectKey).c_str());
865cc290419Sopenharmony_ci            return ERR_BUF_ALLOC;
866cc290419Sopenharmony_ci        }
867cc290419Sopenharmony_ci        hSession->connectKey = connectKey;
868cc290419Sopenharmony_ci        uv_timer_t *waitTimeDoCmd = new(std::nothrow) uv_timer_t;
869cc290419Sopenharmony_ci        if (waitTimeDoCmd == nullptr) {
870cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "CreateConnect new waitTimeDoCmd failed");
871cc290419Sopenharmony_ci            FreeSession(hSession->sessionId);
872cc290419Sopenharmony_ci            return ERR_GENERIC;
873cc290419Sopenharmony_ci        }
874cc290419Sopenharmony_ci        uv_timer_init(&loopMain, waitTimeDoCmd);
875cc290419Sopenharmony_ci        waitTimeDoCmd->data = hSession;
876cc290419Sopenharmony_ci        uv_timer_start(waitTimeDoCmd, UsbPreConnect, UV_TIMEOUT, UV_REPEAT);
877cc290419Sopenharmony_ci    }
878cc290419Sopenharmony_ci    if (!hSession) {
879cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "CreateConnect hSession nullptr");
880cc290419Sopenharmony_ci        return ERR_BUF_ALLOC;
881cc290419Sopenharmony_ci    }
882cc290419Sopenharmony_ci    HDaemonInfo hdiQuery = nullptr;
883cc290419Sopenharmony_ci    AdminDaemonMap(OP_QUERY, connectKey, hdiQuery);
884cc290419Sopenharmony_ci    if (hdiQuery) {
885cc290419Sopenharmony_ci        HdcDaemonInformation diNew = *hdiQuery;
886cc290419Sopenharmony_ci        diNew.hSession = hSession;
887cc290419Sopenharmony_ci        HDaemonInfo hdiNew = &diNew;
888cc290419Sopenharmony_ci        AdminDaemonMap(OP_UPDATE, hdiQuery->connectKey, hdiNew);
889cc290419Sopenharmony_ci    }
890cc290419Sopenharmony_ci    return RET_SUCCESS;
891cc290419Sopenharmony_ci}
892cc290419Sopenharmony_ci
893cc290419Sopenharmony_civoid HdcServer::AttachChannel(HSession hSession, const uint32_t channelId)
894cc290419Sopenharmony_ci{
895cc290419Sopenharmony_ci    int ret = 0;
896cc290419Sopenharmony_ci    HdcServerForClient *hSfc = static_cast<HdcServerForClient *>(clsServerForClient);
897cc290419Sopenharmony_ci    HChannel hChannel = hSfc->AdminChannel(OP_QUERY_REF, channelId, nullptr);
898cc290419Sopenharmony_ci    if (!hChannel) {
899cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "AttachChannel hChannel null channelId:%u", channelId);
900cc290419Sopenharmony_ci        return;
901cc290419Sopenharmony_ci    }
902cc290419Sopenharmony_ci    uv_tcp_init(&hSession->childLoop, &hChannel->hChildWorkTCP);
903cc290419Sopenharmony_ci    hChannel->hChildWorkTCP.data = hChannel;
904cc290419Sopenharmony_ci    hChannel->targetSessionId = hSession->sessionId;
905cc290419Sopenharmony_ci    if ((ret = uv_tcp_open((uv_tcp_t *)&hChannel->hChildWorkTCP, hChannel->fdChildWorkTCP)) < 0) {
906cc290419Sopenharmony_ci        constexpr int bufSize = 1024;
907cc290419Sopenharmony_ci        char buf[bufSize] = { 0 };
908cc290419Sopenharmony_ci        uv_err_name_r(ret, buf, bufSize);
909cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "Hdcserver AttachChannel uv_tcp_open failed %s, channelid:%d fdChildWorkTCP:%d",
910cc290419Sopenharmony_ci                  buf, hChannel->channelId, hChannel->fdChildWorkTCP);
911cc290419Sopenharmony_ci        Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP);
912cc290419Sopenharmony_ci        --hChannel->ref;
913cc290419Sopenharmony_ci        return;
914cc290419Sopenharmony_ci    }
915cc290419Sopenharmony_ci    Base::SetTcpOptions((uv_tcp_t *)&hChannel->hChildWorkTCP);
916cc290419Sopenharmony_ci    uv_read_start((uv_stream_t *)&hChannel->hChildWorkTCP, hSfc->AllocCallback, hSfc->ReadStream);
917cc290419Sopenharmony_ci    --hChannel->ref;
918cc290419Sopenharmony_ci};
919cc290419Sopenharmony_ci
920cc290419Sopenharmony_civoid HdcServer::DeatchChannel(HSession hSession, const uint32_t channelId)
921cc290419Sopenharmony_ci{
922cc290419Sopenharmony_ci    HdcServerForClient *hSfc = static_cast<HdcServerForClient *>(clsServerForClient);
923cc290419Sopenharmony_ci    // childCleared has not set, no need OP_QUERY_REF
924cc290419Sopenharmony_ci    HChannel hChannel = hSfc->AdminChannel(OP_QUERY, channelId, nullptr);
925cc290419Sopenharmony_ci    if (!hChannel) {
926cc290419Sopenharmony_ci        ClearOwnTasks(hSession, channelId);
927cc290419Sopenharmony_ci        uint8_t count = 0;
928cc290419Sopenharmony_ci        Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1);
929cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "DeatchChannel hChannel null channelId:%u", channelId);
930cc290419Sopenharmony_ci        return;
931cc290419Sopenharmony_ci    }
932cc290419Sopenharmony_ci    if (hChannel->childCleared) {
933cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Childchannel has already freed, cid:%u", channelId);
934cc290419Sopenharmony_ci        return;
935cc290419Sopenharmony_ci    }
936cc290419Sopenharmony_ci    // The own task for this channel must be clear before free channel
937cc290419Sopenharmony_ci    ClearOwnTasks(hSession, channelId);
938cc290419Sopenharmony_ci    uint8_t count = 0;
939cc290419Sopenharmony_ci    Send(hSession->sessionId, hChannel->channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1);
940cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "Childchannel begin close, cid:%u, sid:%u", hChannel->channelId, hSession->sessionId);
941cc290419Sopenharmony_ci    if (uv_is_closing((const uv_handle_t *)&hChannel->hChildWorkTCP)) {
942cc290419Sopenharmony_ci        Base::DoNextLoop(&hSession->childLoop, hChannel, [](const uint8_t flag, string &msg, const void *data) {
943cc290419Sopenharmony_ci            HChannel hChannel = (HChannel)data;
944cc290419Sopenharmony_ci            hChannel->childCleared = true;
945cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "Childchannel free direct, cid:%u", hChannel->channelId);
946cc290419Sopenharmony_ci        });
947cc290419Sopenharmony_ci    } else {
948cc290419Sopenharmony_ci        if (hChannel->hChildWorkTCP.loop == NULL) {
949cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "Childchannel loop is null, cid:%u", hChannel->channelId);
950cc290419Sopenharmony_ci        }
951cc290419Sopenharmony_ci        Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP, [](uv_handle_t *handle) -> void {
952cc290419Sopenharmony_ci            HChannel hChannel = (HChannel)handle->data;
953cc290419Sopenharmony_ci            hChannel->childCleared = true;
954cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "Childchannel free callback, cid:%u", hChannel->channelId);
955cc290419Sopenharmony_ci        });
956cc290419Sopenharmony_ci    }
957cc290419Sopenharmony_ci};
958cc290419Sopenharmony_ci
959cc290419Sopenharmony_cibool HdcServer::ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command,
960cc290419Sopenharmony_ci                              uint8_t *bufPtr, const int size)
961cc290419Sopenharmony_ci{
962cc290419Sopenharmony_ci    HdcServerForClient *hSfc = static_cast<HdcServerForClient *>(clsServerForClient);
963cc290419Sopenharmony_ci    HChannel hChannel = hSfc->AdminChannel(OP_QUERY, channelId, nullptr);
964cc290419Sopenharmony_ci    HSession hSession = AdminSession(OP_QUERY, sessionId, nullptr);
965cc290419Sopenharmony_ci    if (!hChannel || !hSession) {
966cc290419Sopenharmony_ci        return false;
967cc290419Sopenharmony_ci    }
968cc290419Sopenharmony_ci    return FetchCommand(hSession, channelId, command, bufPtr, size);
969cc290419Sopenharmony_ci}
970cc290419Sopenharmony_ci
971cc290419Sopenharmony_ci// clang-format off
972cc290419Sopenharmony_cibool HdcServer::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId,
973cc290419Sopenharmony_ci                               const uint16_t command, uint8_t *payload, const int payloadSize)
974cc290419Sopenharmony_ci// clang-format on
975cc290419Sopenharmony_ci{
976cc290419Sopenharmony_ci    bool ret = true;
977cc290419Sopenharmony_ci    hTaskInfo->ownerSessionClass = this;
978cc290419Sopenharmony_ci    switch (command) {
979cc290419Sopenharmony_ci        case CMD_UNITY_BUGREPORT_INIT:
980cc290419Sopenharmony_ci        case CMD_UNITY_BUGREPORT_DATA:
981cc290419Sopenharmony_ci            ret = TaskCommandDispatch<HdcHostUnity>(hTaskInfo, TYPE_UNITY, command, payload, payloadSize);
982cc290419Sopenharmony_ci            break;
983cc290419Sopenharmony_ci        case CMD_FILE_INIT:
984cc290419Sopenharmony_ci        case CMD_FILE_BEGIN:
985cc290419Sopenharmony_ci        case CMD_FILE_CHECK:
986cc290419Sopenharmony_ci        case CMD_FILE_DATA:
987cc290419Sopenharmony_ci        case CMD_FILE_FINISH:
988cc290419Sopenharmony_ci        case CMD_FILE_MODE:
989cc290419Sopenharmony_ci        case CMD_DIR_MODE:
990cc290419Sopenharmony_ci            ret = TaskCommandDispatch<HdcFile>(hTaskInfo, TASK_FILE, command, payload, payloadSize);
991cc290419Sopenharmony_ci            break;
992cc290419Sopenharmony_ci        case CMD_FORWARD_INIT:
993cc290419Sopenharmony_ci        case CMD_FORWARD_CHECK:
994cc290419Sopenharmony_ci        case CMD_FORWARD_CHECK_RESULT:
995cc290419Sopenharmony_ci        case CMD_FORWARD_ACTIVE_MASTER:
996cc290419Sopenharmony_ci        case CMD_FORWARD_ACTIVE_SLAVE:
997cc290419Sopenharmony_ci        case CMD_FORWARD_DATA:
998cc290419Sopenharmony_ci        case CMD_FORWARD_FREE_CONTEXT:
999cc290419Sopenharmony_ci            ret = TaskCommandDispatch<HdcHostForward>(hTaskInfo, TASK_FORWARD, command, payload, payloadSize);
1000cc290419Sopenharmony_ci            break;
1001cc290419Sopenharmony_ci        case CMD_APP_INIT:
1002cc290419Sopenharmony_ci        case CMD_APP_SIDELOAD:
1003cc290419Sopenharmony_ci        case CMD_APP_BEGIN:
1004cc290419Sopenharmony_ci        case CMD_APP_FINISH:
1005cc290419Sopenharmony_ci        case CMD_APP_UNINSTALL:
1006cc290419Sopenharmony_ci            ret = TaskCommandDispatch<HdcHostApp>(hTaskInfo, TASK_APP, command, payload, payloadSize);
1007cc290419Sopenharmony_ci            break;
1008cc290419Sopenharmony_ci        case CMD_FLASHD_UPDATE_INIT:
1009cc290419Sopenharmony_ci        case CMD_FLASHD_FLASH_INIT:
1010cc290419Sopenharmony_ci        case CMD_FLASHD_CHECK:
1011cc290419Sopenharmony_ci        case CMD_FLASHD_BEGIN:
1012cc290419Sopenharmony_ci        case CMD_FLASHD_DATA:
1013cc290419Sopenharmony_ci        case CMD_FLASHD_FINISH:
1014cc290419Sopenharmony_ci        case CMD_FLASHD_ERASE:
1015cc290419Sopenharmony_ci        case CMD_FLASHD_FORMAT:
1016cc290419Sopenharmony_ci        case CMD_FLASHD_PROGRESS:
1017cc290419Sopenharmony_ci            ret = TaskCommandDispatch<HostUpdater>(hTaskInfo, TASK_FLASHD, command, payload, payloadSize);
1018cc290419Sopenharmony_ci            break;
1019cc290419Sopenharmony_ci        default:
1020cc290419Sopenharmony_ci            // ignore unknown command
1021cc290419Sopenharmony_ci            break;
1022cc290419Sopenharmony_ci    }
1023cc290419Sopenharmony_ci    return ret;
1024cc290419Sopenharmony_ci}
1025cc290419Sopenharmony_ci
1026cc290419Sopenharmony_cibool HdcServer::RemoveInstanceTask(const uint8_t op, HTaskInfo hTask)
1027cc290419Sopenharmony_ci{
1028cc290419Sopenharmony_ci    bool ret = true;
1029cc290419Sopenharmony_ci    switch (hTask->taskType) {
1030cc290419Sopenharmony_ci        case TYPE_SHELL:
1031cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "Server not enable unity/shell");
1032cc290419Sopenharmony_ci            break;
1033cc290419Sopenharmony_ci        case TYPE_UNITY:
1034cc290419Sopenharmony_ci            ret = DoTaskRemove<HdcHostUnity>(hTask, op);
1035cc290419Sopenharmony_ci            break;
1036cc290419Sopenharmony_ci        case TASK_FILE:
1037cc290419Sopenharmony_ci            ret = DoTaskRemove<HdcFile>(hTask, op);
1038cc290419Sopenharmony_ci            break;
1039cc290419Sopenharmony_ci        case TASK_FORWARD:
1040cc290419Sopenharmony_ci            ret = DoTaskRemove<HdcHostForward>(hTask, op);
1041cc290419Sopenharmony_ci            break;
1042cc290419Sopenharmony_ci        case TASK_APP:
1043cc290419Sopenharmony_ci            ret = DoTaskRemove<HdcHostApp>(hTask, op);
1044cc290419Sopenharmony_ci            break;
1045cc290419Sopenharmony_ci        case TASK_FLASHD:
1046cc290419Sopenharmony_ci            ret = DoTaskRemove<HostUpdater>(hTask, op);
1047cc290419Sopenharmony_ci            break;
1048cc290419Sopenharmony_ci        default:
1049cc290419Sopenharmony_ci            ret = false;
1050cc290419Sopenharmony_ci            break;
1051cc290419Sopenharmony_ci    }
1052cc290419Sopenharmony_ci    return ret;
1053cc290419Sopenharmony_ci}
1054cc290419Sopenharmony_ci
1055cc290419Sopenharmony_civoid HdcServer::EchoToClientsForSession(uint32_t targetSessionId, const string &echo)
1056cc290419Sopenharmony_ci{
1057cc290419Sopenharmony_ci    HdcServerForClient *hSfc = static_cast<HdcServerForClient *>(clsServerForClient);
1058cc290419Sopenharmony_ci    WRITE_LOG(LOG_INFO, "%s:%u %s", __FUNCTION__, targetSessionId, echo.c_str());
1059cc290419Sopenharmony_ci    hSfc->EchoToAllChannelsViaSessionId(targetSessionId, echo);
1060cc290419Sopenharmony_ci}
1061cc290419Sopenharmony_ci}  // namespace Hdc
1062