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_for_client.h"
16cc290419Sopenharmony_ci#ifndef TEST_HASH
17cc290419Sopenharmony_ci#include "hdc_hash_gen.h"
18cc290419Sopenharmony_ci#endif
19cc290419Sopenharmony_ci#include "server.h"
20cc290419Sopenharmony_ci
21cc290419Sopenharmony_cinamespace Hdc {
22cc290419Sopenharmony_cistatic const int MAX_RETRY_COUNT = 500;
23cc290419Sopenharmony_cistatic const int MAX_CONNECT_DEVICE_RETRY_COUNT = 100;
24cc290419Sopenharmony_ci
25cc290419Sopenharmony_ciHdcServerForClient::HdcServerForClient(const bool serverOrClient, const string &addrString, void *pClsServer,
26cc290419Sopenharmony_ci                                       uv_loop_t *loopMainIn)
27cc290419Sopenharmony_ci    : HdcChannelBase(serverOrClient, addrString, loopMainIn)
28cc290419Sopenharmony_ci{
29cc290419Sopenharmony_ci    clsServer = pClsServer;
30cc290419Sopenharmony_ci}
31cc290419Sopenharmony_ci
32cc290419Sopenharmony_ciHdcServerForClient::~HdcServerForClient()
33cc290419Sopenharmony_ci{
34cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "~HdcServerForClient");
35cc290419Sopenharmony_ci}
36cc290419Sopenharmony_ci
37cc290419Sopenharmony_civoid HdcServerForClient::Stop()
38cc290419Sopenharmony_ci{
39cc290419Sopenharmony_ci    Base::TryCloseHandle((uv_handle_t *)&tcpListen);
40cc290419Sopenharmony_ci}
41cc290419Sopenharmony_ci
42cc290419Sopenharmony_ciuint16_t HdcServerForClient::GetTCPListenPort()
43cc290419Sopenharmony_ci{
44cc290419Sopenharmony_ci    return channelPort;
45cc290419Sopenharmony_ci}
46cc290419Sopenharmony_ci
47cc290419Sopenharmony_civoid HdcServerForClient::AcceptClient(uv_stream_t *server, int status)
48cc290419Sopenharmony_ci{
49cc290419Sopenharmony_ci    uv_tcp_t *pServTCP = (uv_tcp_t *)server;
50cc290419Sopenharmony_ci    HdcServerForClient *thisClass = (HdcServerForClient *)pServTCP->data;
51cc290419Sopenharmony_ci    HChannel hChannel = nullptr;
52cc290419Sopenharmony_ci    uint32_t uid = thisClass->MallocChannel(&hChannel);
53cc290419Sopenharmony_ci    if (!hChannel) {
54cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "AcceptClient hChannel is nullptr");
55cc290419Sopenharmony_ci        return;
56cc290419Sopenharmony_ci    }
57cc290419Sopenharmony_ci    int rc = uv_accept(server, (uv_stream_t *)&hChannel->hWorkTCP);
58cc290419Sopenharmony_ci    if (rc < 0) {
59cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "AcceptClient uv_accept error rc:%d uid:%u", rc, uid);
60cc290419Sopenharmony_ci        thisClass->FreeChannel(uid);
61cc290419Sopenharmony_ci        return;
62cc290419Sopenharmony_ci    }
63cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "AcceptClient uid:%u", uid);
64cc290419Sopenharmony_ci    // limit first recv
65cc290419Sopenharmony_ci    int bufMaxSize = 0;
66cc290419Sopenharmony_ci    uv_recv_buffer_size((uv_handle_t *)&hChannel->hWorkTCP, &bufMaxSize);
67cc290419Sopenharmony_ci    auto funcChannelHeaderAlloc = [](uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) -> void {
68cc290419Sopenharmony_ci        HChannel context = (HChannel)handle->data;
69cc290419Sopenharmony_ci        Base::ReallocBuf(&context->ioBuf, &context->bufSize, Base::GetMaxBufSize() * BUF_EXTEND_SIZE);
70cc290419Sopenharmony_ci        buf->base = (char *)context->ioBuf + context->availTailIndex;
71cc290419Sopenharmony_ci#ifdef HDC_VERSION_CHECK
72cc290419Sopenharmony_ci        buf->len = sizeof(struct ChannelHandShake) + DWORD_SERIALIZE_SIZE;  // only recv static size
73cc290419Sopenharmony_ci#else
74cc290419Sopenharmony_ci        buf->len = offsetof(struct ChannelHandShake, version) + DWORD_SERIALIZE_SIZE;
75cc290419Sopenharmony_ci#endif
76cc290419Sopenharmony_ci    };
77cc290419Sopenharmony_ci    // first packet static size, after this packet will be dup for normal recv
78cc290419Sopenharmony_ci    uv_read_start((uv_stream_t *)&hChannel->hWorkTCP, funcChannelHeaderAlloc, ReadStream);
79cc290419Sopenharmony_ci    // channel handshake step1
80cc290419Sopenharmony_ci    struct ChannelHandShake handShake = {};
81cc290419Sopenharmony_ci    if (EOK == strcpy_s(handShake.banner, sizeof(handShake.banner), HANDSHAKE_MESSAGE.c_str())) {
82cc290419Sopenharmony_ci        handShake.banner[BANNER_FEATURE_TAG_OFFSET] = HUGE_BUF_TAG; // set feature tag for huge buf size
83cc290419Sopenharmony_ci        handShake.channelId = htonl(hChannel->channelId);
84cc290419Sopenharmony_ci        string ver = Base::GetVersion() + HDC_MSG_HASH;
85cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Server ver:%s", ver.c_str());
86cc290419Sopenharmony_ci        if (EOK != strcpy_s(handShake.version, sizeof(handShake.version), ver.c_str())) {
87cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "strcpy_s failed");
88cc290419Sopenharmony_ci            return;
89cc290419Sopenharmony_ci        }
90cc290419Sopenharmony_ci#ifdef HDC_VERSION_CHECK
91cc290419Sopenharmony_ci    thisClass->Send(hChannel->channelId, (uint8_t *)&handShake, sizeof(struct ChannelHandShake));
92cc290419Sopenharmony_ci#else
93cc290419Sopenharmony_ci    // do not send version message if check feature disable
94cc290419Sopenharmony_ci    thisClass->Send(hChannel->channelId, reinterpret_cast<uint8_t *>(&handShake),
95cc290419Sopenharmony_ci                    offsetof(struct ChannelHandShake, version));
96cc290419Sopenharmony_ci#endif
97cc290419Sopenharmony_ci    }
98cc290419Sopenharmony_ci}
99cc290419Sopenharmony_ci
100cc290419Sopenharmony_cibool HdcServerForClient::SetTCPListen()
101cc290419Sopenharmony_ci{
102cc290419Sopenharmony_ci    char buffer[BUF_SIZE_DEFAULT] = { 0 };
103cc290419Sopenharmony_ci    tcpListen.data = this;
104cc290419Sopenharmony_ci    struct sockaddr_in6 addr;
105cc290419Sopenharmony_ci    uv_tcp_init(loopMain, &tcpListen);
106cc290419Sopenharmony_ci
107cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "channelHost %s, port: %d", channelHost.c_str(), channelPort);
108cc290419Sopenharmony_ci    int rc = uv_ip6_addr(channelHost.c_str(), channelPort, &addr);
109cc290419Sopenharmony_ci    if (rc != 0) {
110cc290419Sopenharmony_ci        uv_strerror_r(rc, buffer, BUF_SIZE_DEFAULT);
111cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "uv_ip6_addr %d %s", rc, buffer);
112cc290419Sopenharmony_ci        return false;
113cc290419Sopenharmony_ci    }
114cc290419Sopenharmony_ci    rc = uv_tcp_bind(&tcpListen, (const struct sockaddr *)&addr, 0);
115cc290419Sopenharmony_ci    if (rc != 0) {
116cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "uv_tcp_bind ipv6 %d", rc);
117cc290419Sopenharmony_ci        if (rc == -EAFNOSUPPORT) {
118cc290419Sopenharmony_ci            size_t index = channelHost.find(IPV4_MAPPING_PREFIX);
119cc290419Sopenharmony_ci            size_t size = IPV4_MAPPING_PREFIX.size();
120cc290419Sopenharmony_ci            if (index != std::string::npos) {
121cc290419Sopenharmony_ci                struct sockaddr_in addr4v;
122cc290419Sopenharmony_ci                std::string ipv4 = channelHost.substr(index + size);
123cc290419Sopenharmony_ci                uv_ip4_addr(ipv4.c_str(), channelPort, &addr4v);
124cc290419Sopenharmony_ci                rc = uv_tcp_bind(&tcpListen, (const struct sockaddr *)&addr4v, 0);
125cc290419Sopenharmony_ci                if (rc != 0) {
126cc290419Sopenharmony_ci                    uv_strerror_r(rc, buffer, BUF_SIZE_DEFAULT);
127cc290419Sopenharmony_ci                    WRITE_LOG(LOG_FATAL, "uv_tcp_bind ipv4 %s failed %d %s",
128cc290419Sopenharmony_ci                        ipv4.c_str(), rc, buffer);
129cc290419Sopenharmony_ci                    return false;
130cc290419Sopenharmony_ci                }
131cc290419Sopenharmony_ci            }
132cc290419Sopenharmony_ci        } else {
133cc290419Sopenharmony_ci            uv_strerror_r(rc, buffer, BUF_SIZE_DEFAULT);
134cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "uv_tcp_bind %d %s", rc, buffer);
135cc290419Sopenharmony_ci            return false;
136cc290419Sopenharmony_ci        }
137cc290419Sopenharmony_ci    }
138cc290419Sopenharmony_ci    int backLog = 128;
139cc290419Sopenharmony_ci    rc = uv_listen((uv_stream_t *)&tcpListen, backLog, (uv_connection_cb)AcceptClient);
140cc290419Sopenharmony_ci    if (rc != 0) {
141cc290419Sopenharmony_ci        uv_strerror_r(rc, buffer, BUF_SIZE_DEFAULT);
142cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "uv_listen %d %s", rc, buffer);
143cc290419Sopenharmony_ci        return false;
144cc290419Sopenharmony_ci    }
145cc290419Sopenharmony_ci    return true;
146cc290419Sopenharmony_ci}
147cc290419Sopenharmony_ci
148cc290419Sopenharmony_ciint HdcServerForClient::Initial()
149cc290419Sopenharmony_ci{
150cc290419Sopenharmony_ci    if (!clsServer) {
151cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Module client initial failed");
152cc290419Sopenharmony_ci        return -1;
153cc290419Sopenharmony_ci    }
154cc290419Sopenharmony_ci    if (!channelHostPort.size() || !channelHost.size() || !channelPort) {
155cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Listen string initial failed");
156cc290419Sopenharmony_ci        return -2;  // -2:err for Listen initial failed
157cc290419Sopenharmony_ci    }
158cc290419Sopenharmony_ci    bool b = SetTCPListen();
159cc290419Sopenharmony_ci    if (!b) {
160cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "SetTCPListen failed");
161cc290419Sopenharmony_ci        int listenError = -3;  // -3:error for SetTCPListen failed
162cc290419Sopenharmony_ci        return listenError;
163cc290419Sopenharmony_ci    }
164cc290419Sopenharmony_ci    return 0;
165cc290419Sopenharmony_ci}
166cc290419Sopenharmony_ci
167cc290419Sopenharmony_civoid HdcServerForClient::EchoClient(HChannel hChannel, MessageLevel level, const char *msg, ...)
168cc290419Sopenharmony_ci{
169cc290419Sopenharmony_ci    string logInfo = "";
170cc290419Sopenharmony_ci    switch (level) {
171cc290419Sopenharmony_ci        case MSG_FAIL:
172cc290419Sopenharmony_ci            logInfo = MESSAGE_FAIL;
173cc290419Sopenharmony_ci            break;
174cc290419Sopenharmony_ci        case MSG_INFO:
175cc290419Sopenharmony_ci            logInfo = MESSAGE_INFO;
176cc290419Sopenharmony_ci            break;
177cc290419Sopenharmony_ci        default:  // successful, not append extra info
178cc290419Sopenharmony_ci            break;
179cc290419Sopenharmony_ci    }
180cc290419Sopenharmony_ci    va_list vaArgs;
181cc290419Sopenharmony_ci    va_start(vaArgs, msg);
182cc290419Sopenharmony_ci    string log = logInfo + Base::StringFormat(msg, vaArgs);
183cc290419Sopenharmony_ci    va_end(vaArgs);
184cc290419Sopenharmony_ci    if (log.back() != '\n') {
185cc290419Sopenharmony_ci        log += "\r\n";
186cc290419Sopenharmony_ci    }
187cc290419Sopenharmony_ci    SendChannel(hChannel, const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(log.c_str())), log.size());
188cc290419Sopenharmony_ci}
189cc290419Sopenharmony_ci
190cc290419Sopenharmony_civoid HdcServerForClient::EchoClientRaw(const HChannel hChannel, uint8_t *payload, const int payloadSize)
191cc290419Sopenharmony_ci{
192cc290419Sopenharmony_ci    SendChannel(hChannel, payload, payloadSize);
193cc290419Sopenharmony_ci}
194cc290419Sopenharmony_ci
195cc290419Sopenharmony_ci// HdcServerForClient passthrough file command to client
196cc290419Sopenharmony_civoid HdcServerForClient::SendCommandToClient(const HChannel hChannel, const uint16_t commandFlag,
197cc290419Sopenharmony_ci                                             uint8_t *payload, const int payloadSize)
198cc290419Sopenharmony_ci{
199cc290419Sopenharmony_ci    SendChannelWithCmd(hChannel, commandFlag, payload, payloadSize);
200cc290419Sopenharmony_ci}
201cc290419Sopenharmony_ci
202cc290419Sopenharmony_cibool HdcServerForClient::SendToDaemon(HChannel hChannel, const uint16_t commandFlag, uint8_t *bufPtr, const int bufSize)
203cc290419Sopenharmony_ci{
204cc290419Sopenharmony_ci    HDaemonInfo hdi = nullptr;
205cc290419Sopenharmony_ci    bool ret = false;
206cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
207cc290419Sopenharmony_ci    while (true) {
208cc290419Sopenharmony_ci        ptrServer->AdminDaemonMap(OP_QUERY, hChannel->connectKey, hdi);
209cc290419Sopenharmony_ci        if (hdi == nullptr) {
210cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "SendToDaemon hdi nullptr");
211cc290419Sopenharmony_ci            break;
212cc290419Sopenharmony_ci        }
213cc290419Sopenharmony_ci        if (hdi->connStatus != STATUS_CONNECTED) {
214cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "SendToDaemon not connected");
215cc290419Sopenharmony_ci            break;
216cc290419Sopenharmony_ci        }
217cc290419Sopenharmony_ci        if (!hdi->hSession) {
218cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "SendToDaemon hdi->hSession nullptr");
219cc290419Sopenharmony_ci            break;
220cc290419Sopenharmony_ci        }
221cc290419Sopenharmony_ci        if (ptrServer->Send(hdi->hSession->sessionId, hChannel->channelId, commandFlag, bufPtr, bufSize) < 0) {
222cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "SendToDaemon Send failed channelId:%u", hChannel->channelId);
223cc290419Sopenharmony_ci            break;
224cc290419Sopenharmony_ci        }
225cc290419Sopenharmony_ci        ret = true;
226cc290419Sopenharmony_ci        break;
227cc290419Sopenharmony_ci    }
228cc290419Sopenharmony_ci    return ret;
229cc290419Sopenharmony_ci}
230cc290419Sopenharmony_ci
231cc290419Sopenharmony_civoid HdcServerForClient::OrderFindTargets(HChannel hChannel)
232cc290419Sopenharmony_ci{
233cc290419Sopenharmony_ci    int count = 0;
234cc290419Sopenharmony_ci    EchoClient(hChannel, MSG_INFO, "Please add HDC server's firewall ruler to allow udp incoming, udpport:%d",
235cc290419Sopenharmony_ci               DEFAULT_PORT);
236cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
237cc290419Sopenharmony_ci    ptrServer->clsTCPClt->FindLanDaemon();
238cc290419Sopenharmony_ci    list<string> &lst = ptrServer->clsTCPClt->lstDaemonResult;
239cc290419Sopenharmony_ci    // refresh main list
240cc290419Sopenharmony_ci    HdcDaemonInformation di;
241cc290419Sopenharmony_ci    while (!lst.empty()) {
242cc290419Sopenharmony_ci        di = {};
243cc290419Sopenharmony_ci        ++count;
244cc290419Sopenharmony_ci        di.connectKey = lst.front();
245cc290419Sopenharmony_ci        di.connType = CONN_TCP;
246cc290419Sopenharmony_ci        di.connStatus = STATUS_READY;
247cc290419Sopenharmony_ci        HDaemonInfo pDi = reinterpret_cast<HDaemonInfo>(&di);
248cc290419Sopenharmony_ci        ptrServer->AdminDaemonMap(OP_ADD, STRING_EMPTY, pDi);
249cc290419Sopenharmony_ci        lst.pop_front();
250cc290419Sopenharmony_ci    }
251cc290419Sopenharmony_ci    EchoClient(hChannel, MSG_INFO, "Broadcast find daemon, total:%d", count);
252cc290419Sopenharmony_ci#ifdef UNIT_TEST
253cc290419Sopenharmony_ci    string bufString = std::to_string(count);
254cc290419Sopenharmony_ci    Base::WriteBinFile((UT_TMP_PATH + "/base-discover.result").c_str(), (uint8_t *)bufString.c_str(), bufString.size(),
255cc290419Sopenharmony_ci                       true);
256cc290419Sopenharmony_ci#endif
257cc290419Sopenharmony_ci}
258cc290419Sopenharmony_ci
259cc290419Sopenharmony_civoid HdcServerForClient::OrderConnecTargetResult(uv_timer_t *req)
260cc290419Sopenharmony_ci{
261cc290419Sopenharmony_ci    HChannel hChannel = (HChannel)req->data;
262cc290419Sopenharmony_ci    HdcServerForClient *thisClass = (HdcServerForClient *)hChannel->clsChannel;
263cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)thisClass->clsServer;
264cc290419Sopenharmony_ci    bool bConnectOK = false;
265cc290419Sopenharmony_ci    bool bExitRepet = false;
266cc290419Sopenharmony_ci    HDaemonInfo hdi = nullptr;
267cc290419Sopenharmony_ci    string sRet;
268cc290419Sopenharmony_ci    string target = std::string(hChannel->bufStd + 2);
269cc290419Sopenharmony_ci    if (target == "any") {
270cc290419Sopenharmony_ci        ptrServer->AdminDaemonMap(OP_GET_ANY, target, hdi);
271cc290419Sopenharmony_ci    } else {
272cc290419Sopenharmony_ci        ptrServer->AdminDaemonMap(OP_QUERY, target, hdi);
273cc290419Sopenharmony_ci    }
274cc290419Sopenharmony_ci    if (hdi && hdi->connStatus == STATUS_CONNECTED) {
275cc290419Sopenharmony_ci        bConnectOK = true;
276cc290419Sopenharmony_ci    }
277cc290419Sopenharmony_ci    while (true) {
278cc290419Sopenharmony_ci        if (bConnectOK) {
279cc290419Sopenharmony_ci            bExitRepet = true;
280cc290419Sopenharmony_ci            if (hChannel->isCheck) {
281cc290419Sopenharmony_ci                WRITE_LOG(LOG_INFO, "%s check device success and remove %s", __FUNCTION__, hChannel->key.c_str());
282cc290419Sopenharmony_ci                thisClass->CommandRemoveSession(hChannel, hChannel->key.c_str());
283cc290419Sopenharmony_ci                thisClass->EchoClient(hChannel, MSG_OK, const_cast<char *>(hdi->version.c_str()));
284cc290419Sopenharmony_ci            } else {
285cc290419Sopenharmony_ci                sRet = "Connect OK";
286cc290419Sopenharmony_ci                thisClass->EchoClient(hChannel, MSG_OK, const_cast<char *>(sRet.c_str()));
287cc290419Sopenharmony_ci            }
288cc290419Sopenharmony_ci            break;
289cc290419Sopenharmony_ci        } else {
290cc290419Sopenharmony_ci            uint16_t *bRetryCount = reinterpret_cast<uint16_t *>(hChannel->bufStd);
291cc290419Sopenharmony_ci            ++(*bRetryCount);
292cc290419Sopenharmony_ci            if (*bRetryCount > MAX_RETRY_COUNT ||
293cc290419Sopenharmony_ci                (hChannel->connectLocalDevice && *bRetryCount > MAX_CONNECT_DEVICE_RETRY_COUNT)) {
294cc290419Sopenharmony_ci                // 5s or localDevice 1s
295cc290419Sopenharmony_ci                bExitRepet = true;
296cc290419Sopenharmony_ci                sRet = "Connect failed";
297cc290419Sopenharmony_ci                thisClass->EchoClient(hChannel, MSG_FAIL, const_cast<char *>(sRet.c_str()));
298cc290419Sopenharmony_ci                break;
299cc290419Sopenharmony_ci            }
300cc290419Sopenharmony_ci        }
301cc290419Sopenharmony_ci        break;
302cc290419Sopenharmony_ci    }
303cc290419Sopenharmony_ci    if (bExitRepet) {
304cc290419Sopenharmony_ci        thisClass->FreeChannel(hChannel->channelId);
305cc290419Sopenharmony_ci        Base::TryCloseHandle((const uv_handle_t *)req, Base::CloseTimerCallback);
306cc290419Sopenharmony_ci    }
307cc290419Sopenharmony_ci}
308cc290419Sopenharmony_ci
309cc290419Sopenharmony_cibool HdcServerForClient::NewConnectTry(void *ptrServer, HChannel hChannel, const string &connectKey, bool isCheck)
310cc290419Sopenharmony_ci{
311cc290419Sopenharmony_ci#ifdef HDC_DEBUG
312cc290419Sopenharmony_ci    WRITE_LOG(LOG_ALL, "%s %s", __FUNCTION__, Hdc::MaskString(connectKey).c_str());
313cc290419Sopenharmony_ci#endif
314cc290419Sopenharmony_ci    int childRet = ((HdcServer *)ptrServer)->CreateConnect(connectKey, isCheck);
315cc290419Sopenharmony_ci    bool ret = false;
316cc290419Sopenharmony_ci    int connectError = -2;
317cc290419Sopenharmony_ci    constexpr uint8_t bufOffsetTwo = 2;
318cc290419Sopenharmony_ci    constexpr uint8_t bufOffsetThree = 3;
319cc290419Sopenharmony_ci    if (childRet == -1) {
320cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_INFO, "Target is connected, repeat operation");
321cc290419Sopenharmony_ci    } else if (childRet == connectError) {
322cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_FAIL, "CreateConnect failed");
323cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "CreateConnect failed");
324cc290419Sopenharmony_ci    } else {
325cc290419Sopenharmony_ci        size_t pos = connectKey.find(":");
326cc290419Sopenharmony_ci        if (pos != std::string::npos) {
327cc290419Sopenharmony_ci            string ip = connectKey.substr(0, pos);
328cc290419Sopenharmony_ci            if (ip == "127.0.0.1") {
329cc290419Sopenharmony_ci                hChannel->connectLocalDevice = true;
330cc290419Sopenharmony_ci            }
331cc290419Sopenharmony_ci        }
332cc290419Sopenharmony_ci        Base::ZeroBuf(hChannel->bufStd, bufOffsetTwo);
333cc290419Sopenharmony_ci        childRet = snprintf_s(hChannel->bufStd + bufOffsetTwo, sizeof(hChannel->bufStd) - bufOffsetTwo,
334cc290419Sopenharmony_ci                              sizeof(hChannel->bufStd) - bufOffsetThree, "%s",
335cc290419Sopenharmony_ci                              const_cast<char *>(connectKey.c_str()));
336cc290419Sopenharmony_ci        if (childRet > 0) {
337cc290419Sopenharmony_ci            Base::TimerUvTask(loopMain, hChannel, OrderConnecTargetResult, UV_START_REPEAT);
338cc290419Sopenharmony_ci            ret = true;
339cc290419Sopenharmony_ci        }
340cc290419Sopenharmony_ci    }
341cc290419Sopenharmony_ci    return ret;
342cc290419Sopenharmony_ci}
343cc290419Sopenharmony_ci
344cc290419Sopenharmony_cibool HdcServerForClient::CommandRemoveSession(HChannel hChannel, const char *connectKey)
345cc290419Sopenharmony_ci{
346cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
347cc290419Sopenharmony_ci    HDaemonInfo hdiOld = nullptr;
348cc290419Sopenharmony_ci    (reinterpret_cast<HdcServer *>(ptrServer))->AdminDaemonMap(OP_QUERY, connectKey, hdiOld);
349cc290419Sopenharmony_ci    if (!hdiOld) {
350cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_FAIL, "No target available");
351cc290419Sopenharmony_ci        return false;
352cc290419Sopenharmony_ci    }
353cc290419Sopenharmony_ci    (reinterpret_cast<HdcServer *>(ptrServer))->FreeSession(hdiOld->hSession->sessionId);
354cc290419Sopenharmony_ci    return true;
355cc290419Sopenharmony_ci}
356cc290419Sopenharmony_ci
357cc290419Sopenharmony_cibool HdcServerForClient::CommandRemoveForward(const string &forwardKey)
358cc290419Sopenharmony_ci{
359cc290419Sopenharmony_ci    bool ret = RemoveFportkey("0|" + forwardKey);
360cc290419Sopenharmony_ci    ret |= RemoveFportkey("1|" + forwardKey);
361cc290419Sopenharmony_ci    return ret;
362cc290419Sopenharmony_ci}
363cc290419Sopenharmony_ci
364cc290419Sopenharmony_cibool HdcServerForClient::RemoveFportkey(const string &forwardKey)
365cc290419Sopenharmony_ci{
366cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
367cc290419Sopenharmony_ci    HForwardInfo hfi = nullptr;
368cc290419Sopenharmony_ci    ptrServer->AdminForwardMap(OP_QUERY, forwardKey, hfi);
369cc290419Sopenharmony_ci    if (!hfi) {
370cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "CommandRemoveForward hfi nullptr forwardKey:%s", forwardKey.c_str());
371cc290419Sopenharmony_ci        return false;
372cc290419Sopenharmony_ci    }
373cc290419Sopenharmony_ci    HSession hSession = ptrServer->AdminSession(OP_QUERY, hfi->sessionId, nullptr);
374cc290419Sopenharmony_ci    if (!hSession) {
375cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "CommandRemoveForward hSession nullptr sessionId:%u", hfi->sessionId);
376cc290419Sopenharmony_ci        ptrServer->AdminForwardMap(OP_REMOVE, forwardKey, hfi);
377cc290419Sopenharmony_ci        return true;
378cc290419Sopenharmony_ci    }
379cc290419Sopenharmony_ci    ptrServer->ClearOwnTasks(hSession, hfi->channelId);
380cc290419Sopenharmony_ci    FreeChannel(hfi->channelId);
381cc290419Sopenharmony_ci    hfi = nullptr;
382cc290419Sopenharmony_ci    ptrServer->AdminForwardMap(OP_REMOVE, forwardKey, hfi);
383cc290419Sopenharmony_ci    return true;
384cc290419Sopenharmony_ci}
385cc290419Sopenharmony_ci
386cc290419Sopenharmony_civoid HdcServerForClient::GetTargetList(HChannel hChannel, void *formatCommandInput)
387cc290419Sopenharmony_ci{
388cc290419Sopenharmony_ci    TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput;
389cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
390cc290419Sopenharmony_ci    uint16_t cmd = OP_GET_STRLIST;
391cc290419Sopenharmony_ci    if (formatCommand->parameters == "v") {
392cc290419Sopenharmony_ci        cmd = OP_GET_STRLIST_FULL;
393cc290419Sopenharmony_ci    }
394cc290419Sopenharmony_ci    HDaemonInfo hdi = nullptr;
395cc290419Sopenharmony_ci    string sRet = ptrServer->AdminDaemonMap(cmd, STRING_EMPTY, hdi);
396cc290419Sopenharmony_ci    if (!sRet.length()) {
397cc290419Sopenharmony_ci        sRet = EMPTY_ECHO;
398cc290419Sopenharmony_ci    }
399cc290419Sopenharmony_ci    EchoClient(hChannel, MSG_OK, const_cast<char *>(sRet.c_str()));
400cc290419Sopenharmony_ci#ifdef UNIT_TEST
401cc290419Sopenharmony_ci    Base::WriteBinFile((UT_TMP_PATH + "/base-list.result").c_str(), (uint8_t *)MESSAGE_SUCCESS.c_str(),
402cc290419Sopenharmony_ci                       MESSAGE_SUCCESS.size(), true);
403cc290419Sopenharmony_ci#endif
404cc290419Sopenharmony_ci}
405cc290419Sopenharmony_ci
406cc290419Sopenharmony_cibool HdcServerForClient::GetAnyTarget(HChannel hChannel)
407cc290419Sopenharmony_ci{
408cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
409cc290419Sopenharmony_ci    HDaemonInfo hdi = nullptr;
410cc290419Sopenharmony_ci    ptrServer->AdminDaemonMap(OP_GET_ANY, STRING_EMPTY, hdi);
411cc290419Sopenharmony_ci    if (!hdi) {
412cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_FAIL, "No target available");
413cc290419Sopenharmony_ci        return false;
414cc290419Sopenharmony_ci    }
415cc290419Sopenharmony_ci    // can not use hdi->connectKey.This memory may be released to re-Malloc
416cc290419Sopenharmony_ci    string connectKey = hdi->connectKey;
417cc290419Sopenharmony_ci    bool ret = NewConnectTry(ptrServer, hChannel, connectKey);
418cc290419Sopenharmony_ci#ifdef UNIT_TEST
419cc290419Sopenharmony_ci    Base::WriteBinFile((UT_TMP_PATH + "/base-any.result").c_str(), (uint8_t *)MESSAGE_SUCCESS.c_str(),
420cc290419Sopenharmony_ci                       MESSAGE_SUCCESS.size(), true);
421cc290419Sopenharmony_ci#endif
422cc290419Sopenharmony_ci    return ret;
423cc290419Sopenharmony_ci}
424cc290419Sopenharmony_ci
425cc290419Sopenharmony_cibool HdcServerForClient::WaitForAny(HChannel hChannel)
426cc290419Sopenharmony_ci{
427cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
428cc290419Sopenharmony_ci    HDaemonInfo hdi = nullptr;
429cc290419Sopenharmony_ci    if (!hChannel->connectKey.empty()) {
430cc290419Sopenharmony_ci        ptrServer->AdminDaemonMap(OP_WAIT_FOR_ANY, hChannel->connectKey, hdi);
431cc290419Sopenharmony_ci    } else {
432cc290419Sopenharmony_ci        ptrServer->AdminDaemonMap(OP_WAIT_FOR_ANY, STRING_EMPTY, hdi);
433cc290419Sopenharmony_ci    }
434cc290419Sopenharmony_ci    if (!hdi) {
435cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_FAIL, "No any connected target");
436cc290419Sopenharmony_ci        return false;
437cc290419Sopenharmony_ci    }
438cc290419Sopenharmony_ci    string key = hdi->connectKey;
439cc290419Sopenharmony_ci    EchoClient(hChannel, MSG_OK, "Wait for connected target is %s", key.c_str());
440cc290419Sopenharmony_ci    return true;
441cc290419Sopenharmony_ci}
442cc290419Sopenharmony_ci
443cc290419Sopenharmony_cibool HdcServerForClient::RemoveForward(HChannel hChannel, const char *parameterString)
444cc290419Sopenharmony_ci{
445cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
446cc290419Sopenharmony_ci    if (parameterString == nullptr) {  // remove all
447cc290419Sopenharmony_ci        HForwardInfo hfi = nullptr;    // dummy
448cc290419Sopenharmony_ci        string echo = ptrServer->AdminForwardMap(OP_GET_STRLIST, "", hfi);
449cc290419Sopenharmony_ci        if (!echo.length()) {
450cc290419Sopenharmony_ci            return false;
451cc290419Sopenharmony_ci        }
452cc290419Sopenharmony_ci        vector<string> filterStrings;
453cc290419Sopenharmony_ci        Base::SplitString(echo, string("\n"), filterStrings);
454cc290419Sopenharmony_ci        for (auto &&s : filterStrings) {
455cc290419Sopenharmony_ci            if (CommandRemoveForward(s.c_str())) {
456cc290419Sopenharmony_ci                EchoClient(hChannel, MSG_OK, "Remove forward ruler success, ruler:%s", s.c_str());
457cc290419Sopenharmony_ci            } else {
458cc290419Sopenharmony_ci                EchoClient(hChannel, MSG_FAIL, "Remove forward ruler failed, ruler is not exist %s", s.c_str());
459cc290419Sopenharmony_ci            }
460cc290419Sopenharmony_ci        }
461cc290419Sopenharmony_ci    } else {  // remove single
462cc290419Sopenharmony_ci        if (CommandRemoveForward(parameterString)) {
463cc290419Sopenharmony_ci            EchoClient(hChannel, MSG_OK, "Remove forward ruler success, ruler:%s", parameterString);
464cc290419Sopenharmony_ci        } else {
465cc290419Sopenharmony_ci            EchoClient(hChannel, MSG_FAIL, "Remove forward ruler failed, ruler is not exist %s", parameterString);
466cc290419Sopenharmony_ci        }
467cc290419Sopenharmony_ci    }
468cc290419Sopenharmony_ci    return true;
469cc290419Sopenharmony_ci}
470cc290419Sopenharmony_ci
471cc290419Sopenharmony_cibool HdcServerForClient::DoCommandLocal(HChannel hChannel, void *formatCommandInput)
472cc290419Sopenharmony_ci{
473cc290419Sopenharmony_ci    TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput;
474cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
475cc290419Sopenharmony_ci    bool ret = false;
476cc290419Sopenharmony_ci    // Main thread command, direct Listen main thread
477cc290419Sopenharmony_ci    switch (formatCommand->cmdFlag) {
478cc290419Sopenharmony_ci        case CMD_KERNEL_TARGET_DISCOVER: {
479cc290419Sopenharmony_ci            OrderFindTargets(hChannel);
480cc290419Sopenharmony_ci            ret = false;
481cc290419Sopenharmony_ci            break;
482cc290419Sopenharmony_ci        }
483cc290419Sopenharmony_ci        case CMD_KERNEL_TARGET_LIST: {
484cc290419Sopenharmony_ci            GetTargetList(hChannel, formatCommandInput);
485cc290419Sopenharmony_ci            ret = false;
486cc290419Sopenharmony_ci            break;
487cc290419Sopenharmony_ci        }
488cc290419Sopenharmony_ci        case CMD_CHECK_SERVER: {
489cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "CMD_CHECK_SERVER command");
490cc290419Sopenharmony_ci            ReportServerVersion(hChannel);
491cc290419Sopenharmony_ci            ret = false;
492cc290419Sopenharmony_ci            break;
493cc290419Sopenharmony_ci        }
494cc290419Sopenharmony_ci        case CMD_WAIT_FOR: {
495cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "CMD_WAIT_FOR command");
496cc290419Sopenharmony_ci            ret = !WaitForAny(hChannel);
497cc290419Sopenharmony_ci            break;
498cc290419Sopenharmony_ci        }
499cc290419Sopenharmony_ci        case CMD_KERNEL_TARGET_ANY: {
500cc290419Sopenharmony_ci#ifdef HDC_DEBUG
501cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "%s CMD_KERNEL_TARGET_ANY %s", __FUNCTION__, formatCommand->parameters.c_str());
502cc290419Sopenharmony_ci#endif
503cc290419Sopenharmony_ci            ret = GetAnyTarget(hChannel);
504cc290419Sopenharmony_ci            break;
505cc290419Sopenharmony_ci        }
506cc290419Sopenharmony_ci        case CMD_KERNEL_TARGET_CONNECT: {
507cc290419Sopenharmony_ci#ifdef HDC_DEBUG
508cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "%s CMD_KERNEL_TARGET_CONNECT %s", __FUNCTION__, formatCommand->parameters.c_str());
509cc290419Sopenharmony_ci#endif
510cc290419Sopenharmony_ci            ret = NewConnectTry(ptrServer, hChannel, formatCommand->parameters.c_str());
511cc290419Sopenharmony_ci            break;
512cc290419Sopenharmony_ci        }
513cc290419Sopenharmony_ci        case CMD_CHECK_DEVICE: {
514cc290419Sopenharmony_ci            WRITE_LOG(LOG_INFO, "%s CMD_CHECK_DEVICE %s", __FUNCTION__, formatCommand->parameters.c_str());
515cc290419Sopenharmony_ci            hChannel->isCheck = true;
516cc290419Sopenharmony_ci            hChannel->key = formatCommand->parameters.c_str();
517cc290419Sopenharmony_ci            ret = NewConnectTry(ptrServer, hChannel, formatCommand->parameters.c_str(), true);
518cc290419Sopenharmony_ci            break;
519cc290419Sopenharmony_ci        }
520cc290419Sopenharmony_ci        case CMD_KERNEL_TARGET_DISCONNECT: {
521cc290419Sopenharmony_ci            CommandRemoveSession(hChannel, formatCommand->parameters.c_str());
522cc290419Sopenharmony_ci            break;
523cc290419Sopenharmony_ci        }
524cc290419Sopenharmony_ci        // task will be global task,Therefore, it can only be controlled in the global session.
525cc290419Sopenharmony_ci        case CMD_FORWARD_LIST: {
526cc290419Sopenharmony_ci            HForwardInfo hfi = nullptr;  // dummy
527cc290419Sopenharmony_ci            string echo = ptrServer->AdminForwardMap(OP_GET_STRLIST_FULL, "", hfi);
528cc290419Sopenharmony_ci            if (!echo.length()) {
529cc290419Sopenharmony_ci                echo = EMPTY_ECHO;
530cc290419Sopenharmony_ci            }
531cc290419Sopenharmony_ci            EchoClient(hChannel, MSG_OK, const_cast<char *>(echo.c_str()));
532cc290419Sopenharmony_ci            break;
533cc290419Sopenharmony_ci        }
534cc290419Sopenharmony_ci        case CMD_FORWARD_REMOVE: {
535cc290419Sopenharmony_ci            RemoveForward(hChannel, formatCommand->parameters.c_str());
536cc290419Sopenharmony_ci            break;
537cc290419Sopenharmony_ci        }
538cc290419Sopenharmony_ci        case CMD_KERNEL_ENABLE_KEEPALIVE: {
539cc290419Sopenharmony_ci            // just use for 'list targets' now
540cc290419Sopenharmony_ci            hChannel->keepAlive = true;
541cc290419Sopenharmony_ci            ret = true;
542cc290419Sopenharmony_ci            break;
543cc290419Sopenharmony_ci        }
544cc290419Sopenharmony_ci        default: {
545cc290419Sopenharmony_ci            EchoClient(hChannel, MSG_FAIL, "ExecuteCommand need connect-key? please confirm a device by help info");
546cc290419Sopenharmony_ci            break;
547cc290419Sopenharmony_ci        }
548cc290419Sopenharmony_ci    }
549cc290419Sopenharmony_ci    return ret;
550cc290419Sopenharmony_ci}
551cc290419Sopenharmony_ci
552cc290419Sopenharmony_cibool HdcServerForClient::TaskCommand(HChannel hChannel, void *formatCommandInput)
553cc290419Sopenharmony_ci{
554cc290419Sopenharmony_ci    TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput;
555cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
556cc290419Sopenharmony_ci    string cmdFlag;
557cc290419Sopenharmony_ci    uint8_t sizeCmdFlag = 0;
558cc290419Sopenharmony_ci    if (formatCommand->cmdFlag == CMD_FILE_INIT) {
559cc290419Sopenharmony_ci        cmdFlag = "send ";
560cc290419Sopenharmony_ci        sizeCmdFlag = 5;  // 5: cmdFlag send size
561cc290419Sopenharmony_ci        HandleRemote(hChannel, formatCommand->parameters, RemoteType::REMOTE_FILE);
562cc290419Sopenharmony_ci    } else if (formatCommand->cmdFlag == CMD_FORWARD_INIT) {
563cc290419Sopenharmony_ci        cmdFlag = "fport ";
564cc290419Sopenharmony_ci        sizeCmdFlag = 6;  // 6: cmdFlag fport size
565cc290419Sopenharmony_ci    } else if (formatCommand->cmdFlag == CMD_APP_INIT) {
566cc290419Sopenharmony_ci        cmdFlag = "install ";
567cc290419Sopenharmony_ci        sizeCmdFlag = 8;  // 8: cmdFlag install size
568cc290419Sopenharmony_ci        HandleRemote(hChannel, formatCommand->parameters, RemoteType::REMOTE_APP);
569cc290419Sopenharmony_ci    } else if (formatCommand->cmdFlag == CMD_APP_UNINSTALL) {
570cc290419Sopenharmony_ci        cmdFlag = "uninstall ";
571cc290419Sopenharmony_ci        sizeCmdFlag = 10;  // 10: cmdFlag uninstall size
572cc290419Sopenharmony_ci    } else if (formatCommand->cmdFlag == CMD_UNITY_BUGREPORT_INIT) {
573cc290419Sopenharmony_ci        cmdFlag = "bugreport ";
574cc290419Sopenharmony_ci        sizeCmdFlag = 10;  // 10: cmdFlag bugreport size
575cc290419Sopenharmony_ci    } else if (formatCommand->cmdFlag == CMD_APP_SIDELOAD) {
576cc290419Sopenharmony_ci        cmdFlag = "sideload ";
577cc290419Sopenharmony_ci        sizeCmdFlag = 9; // 9: cmdFlag sideload size
578cc290419Sopenharmony_ci    } else if (formatCommand->cmdFlag == CMD_FLASHD_UPDATE_INIT) {
579cc290419Sopenharmony_ci        cmdFlag = "update ";
580cc290419Sopenharmony_ci        sizeCmdFlag = 7; // 7: cmdFlag update size
581cc290419Sopenharmony_ci    } else if (formatCommand->cmdFlag == CMD_FLASHD_FLASH_INIT) {
582cc290419Sopenharmony_ci        cmdFlag = "flash ";
583cc290419Sopenharmony_ci        sizeCmdFlag = 6; // 6: cmdFlag flash size
584cc290419Sopenharmony_ci    }
585cc290419Sopenharmony_ci    int sizeSend = formatCommand->parameters.size();
586cc290419Sopenharmony_ci    if (!strncmp(formatCommand->parameters.c_str(), cmdFlag.c_str(), sizeCmdFlag)) {  // local do
587cc290419Sopenharmony_ci        HSession hSession = FindAliveSession(hChannel->targetSessionId);
588cc290419Sopenharmony_ci        if (!hSession) {
589cc290419Sopenharmony_ci            return false;
590cc290419Sopenharmony_ci        }
591cc290419Sopenharmony_ci        if ((formatCommand->cmdFlag == CMD_FILE_INIT || formatCommand->cmdFlag == CMD_APP_INIT) &&
592cc290419Sopenharmony_ci            hChannel->fromClient) {
593cc290419Sopenharmony_ci            // remote client mode, CMD_FILE_INIT and CMD_APP_INIT command send back to client
594cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "command send back to remote client channelId:%u", hChannel->channelId);
595cc290419Sopenharmony_ci            SendChannelWithCmd(hChannel, formatCommand->cmdFlag,
596cc290419Sopenharmony_ci                reinterpret_cast<uint8_t *>(const_cast<char *>(formatCommand->parameters.c_str())) + sizeCmdFlag,
597cc290419Sopenharmony_ci                sizeSend - sizeCmdFlag);
598cc290419Sopenharmony_ci            return false;
599cc290419Sopenharmony_ci        }
600cc290419Sopenharmony_ci        ptrServer->DispatchTaskData(hSession, hChannel->channelId, formatCommand->cmdFlag,
601cc290419Sopenharmony_ci            reinterpret_cast<uint8_t *>(const_cast<char *>(formatCommand->parameters.c_str())) + sizeCmdFlag,
602cc290419Sopenharmony_ci            sizeSend - sizeCmdFlag);
603cc290419Sopenharmony_ci    } else {  // Send to Daemon-side to do
604cc290419Sopenharmony_ci        SendToDaemon(hChannel, formatCommand->cmdFlag,
605cc290419Sopenharmony_ci            reinterpret_cast<uint8_t *>(const_cast<char *>(formatCommand->parameters.c_str())) + sizeCmdFlag,
606cc290419Sopenharmony_ci            sizeSend - sizeCmdFlag);
607cc290419Sopenharmony_ci    }
608cc290419Sopenharmony_ci    return true;
609cc290419Sopenharmony_ci}
610cc290419Sopenharmony_ci
611cc290419Sopenharmony_civoid HdcServerForClient::HandleRemote(HChannel hChannel, string &parameters, RemoteType flag)
612cc290419Sopenharmony_ci{
613cc290419Sopenharmony_ci    hChannel->remote = flag;
614cc290419Sopenharmony_ci    int argc = 0;
615cc290419Sopenharmony_ci    char **argv = Base::SplitCommandToArgs(parameters.c_str(), &argc);
616cc290419Sopenharmony_ci    for (int i = 0; i < argc; i++) {
617cc290419Sopenharmony_ci        if (argv[i] == CMDSTR_REMOTE_PARAMETER) {
618cc290419Sopenharmony_ci            hChannel->fromClient = true;
619cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "remote client mode channelId:%u", hChannel->channelId);
620cc290419Sopenharmony_ci            break;
621cc290419Sopenharmony_ci        }
622cc290419Sopenharmony_ci    }
623cc290419Sopenharmony_ci    if (hChannel->fromClient) {
624cc290419Sopenharmony_ci        string remote = CMDSTR_REMOTE_PARAMETER + " ";
625cc290419Sopenharmony_ci        if (parameters.find(remote) != std::string::npos) {
626cc290419Sopenharmony_ci            parameters.replace(parameters.find(remote), remote.size(), "");
627cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "parameters: %s", parameters.c_str());
628cc290419Sopenharmony_ci        }
629cc290419Sopenharmony_ci    }
630cc290419Sopenharmony_ci}
631cc290419Sopenharmony_ci
632cc290419Sopenharmony_cibool HdcServerForClient::DoCommandRemote(HChannel hChannel, void *formatCommandInput)
633cc290419Sopenharmony_ci{
634cc290419Sopenharmony_ci    TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput;
635cc290419Sopenharmony_ci    bool ret = false;
636cc290419Sopenharmony_ci    int sizeSend = formatCommand->parameters.size();
637cc290419Sopenharmony_ci    string cmdFlag;
638cc290419Sopenharmony_ci    switch (formatCommand->cmdFlag) {
639cc290419Sopenharmony_ci        // Some simple commands only need to forward the instruction, no need to start Task
640cc290419Sopenharmony_ci        case CMD_SHELL_INIT:
641cc290419Sopenharmony_ci        case CMD_SHELL_DATA:
642cc290419Sopenharmony_ci        case CMD_UNITY_EXECUTE:
643cc290419Sopenharmony_ci        case CMD_UNITY_REMOUNT:
644cc290419Sopenharmony_ci        case CMD_UNITY_REBOOT:
645cc290419Sopenharmony_ci        case CMD_UNITY_RUNMODE:
646cc290419Sopenharmony_ci        case CMD_UNITY_HILOG:
647cc290419Sopenharmony_ci        case CMD_UNITY_ROOTRUN:
648cc290419Sopenharmony_ci        case CMD_JDWP_TRACK:
649cc290419Sopenharmony_ci        case CMD_JDWP_LIST: {
650cc290419Sopenharmony_ci            if (!SendToDaemon(hChannel, formatCommand->cmdFlag,
651cc290419Sopenharmony_ci                              reinterpret_cast<uint8_t *>(const_cast<char *>(formatCommand->parameters.c_str())),
652cc290419Sopenharmony_ci                              sizeSend)) {
653cc290419Sopenharmony_ci                break;
654cc290419Sopenharmony_ci            }
655cc290419Sopenharmony_ci            ret = true;
656cc290419Sopenharmony_ci            if (formatCommand->cmdFlag == CMD_SHELL_INIT) {
657cc290419Sopenharmony_ci                hChannel->interactiveShellMode = true;
658cc290419Sopenharmony_ci            }
659cc290419Sopenharmony_ci            break;
660cc290419Sopenharmony_ci        }
661cc290419Sopenharmony_ci        case CMD_FILE_INIT:
662cc290419Sopenharmony_ci        case CMD_FORWARD_INIT:
663cc290419Sopenharmony_ci        case CMD_APP_INIT:
664cc290419Sopenharmony_ci        case CMD_APP_UNINSTALL:
665cc290419Sopenharmony_ci        case CMD_UNITY_BUGREPORT_INIT:
666cc290419Sopenharmony_ci        case CMD_APP_SIDELOAD:
667cc290419Sopenharmony_ci        case CMD_FLASHD_UPDATE_INIT:
668cc290419Sopenharmony_ci        case CMD_FLASHD_FLASH_INIT:
669cc290419Sopenharmony_ci        case CMD_FLASHD_ERASE:
670cc290419Sopenharmony_ci        case CMD_FLASHD_FORMAT: {
671cc290419Sopenharmony_ci            TaskCommand(hChannel, formatCommandInput);
672cc290419Sopenharmony_ci            ret = true;
673cc290419Sopenharmony_ci            break;
674cc290419Sopenharmony_ci        }
675cc290419Sopenharmony_ci        default:
676cc290419Sopenharmony_ci            break;
677cc290419Sopenharmony_ci    }
678cc290419Sopenharmony_ci    if (!ret) {
679cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_FAIL, "Failed to communicate with daemon");
680cc290419Sopenharmony_ci    }
681cc290419Sopenharmony_ci    return ret;
682cc290419Sopenharmony_ci}
683cc290419Sopenharmony_ci// Do not specify Target's operations no longer need to put it in the thread.
684cc290419Sopenharmony_cibool HdcServerForClient::DoCommand(HChannel hChannel, void *formatCommandInput)
685cc290419Sopenharmony_ci{
686cc290419Sopenharmony_ci    bool ret = false;
687cc290419Sopenharmony_ci    TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput;
688cc290419Sopenharmony_ci    if (!hChannel->hChildWorkTCP.loop || formatCommand->cmdFlag == CMD_FORWARD_REMOVE) {
689cc290419Sopenharmony_ci        // Main thread command, direct Listen main thread
690cc290419Sopenharmony_ci        ret = DoCommandLocal(hChannel, formatCommandInput);
691cc290419Sopenharmony_ci    } else {  // CONNECT DAEMON's work thread command, non-primary thread
692cc290419Sopenharmony_ci        ret = DoCommandRemote(hChannel, formatCommandInput);
693cc290419Sopenharmony_ci    }
694cc290419Sopenharmony_ci    return ret;
695cc290419Sopenharmony_ci}
696cc290419Sopenharmony_ci
697cc290419Sopenharmony_ci// just call from BindChannelToSession
698cc290419Sopenharmony_ciHSession HdcServerForClient::FindAliveSessionFromDaemonMap(const HChannel hChannel)
699cc290419Sopenharmony_ci{
700cc290419Sopenharmony_ci    HSession hSession = nullptr;
701cc290419Sopenharmony_ci    HDaemonInfo hdi = nullptr;
702cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
703cc290419Sopenharmony_ci    ptrServer->AdminDaemonMap(OP_QUERY, hChannel->connectKey, hdi);
704cc290419Sopenharmony_ci    if (!hdi) {
705cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_FAIL, "Not match target founded, check connect-key please");
706cc290419Sopenharmony_ci        return nullptr;
707cc290419Sopenharmony_ci    }
708cc290419Sopenharmony_ci    if (hdi->connStatus != STATUS_CONNECTED) {
709cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_FAIL, "Device not founded or connected");
710cc290419Sopenharmony_ci        return nullptr;
711cc290419Sopenharmony_ci    }
712cc290419Sopenharmony_ci    if (hdi->hSession->isDead) {
713cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_FAIL, "Bind tartget session is dead");
714cc290419Sopenharmony_ci        return nullptr;
715cc290419Sopenharmony_ci    }
716cc290419Sopenharmony_ci    if (!hdi->hSession->handshakeOK) {
717cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "hSession handShake is false sid:%u cid:%u",
718cc290419Sopenharmony_ci            hdi->hSession->sessionId, hChannel->channelId);
719cc290419Sopenharmony_ci        const string errMsg = "[E000004]:The communication channel is being established.\r\n"\
720cc290419Sopenharmony_ci            "Please wait for several seconds and try again.";
721cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_FAIL, errMsg.c_str());
722cc290419Sopenharmony_ci        return nullptr;
723cc290419Sopenharmony_ci    }
724cc290419Sopenharmony_ci    hSession = reinterpret_cast<HSession>(hdi->hSession);
725cc290419Sopenharmony_ci    return hSession;
726cc290419Sopenharmony_ci}
727cc290419Sopenharmony_ci
728cc290419Sopenharmony_ciint HdcServerForClient::BindChannelToSession(HChannel hChannel, uint8_t *bufPtr, const int bytesIO)
729cc290419Sopenharmony_ci{
730cc290419Sopenharmony_ci    if (FindAliveSessionFromDaemonMap(hChannel) == nullptr) {
731cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Find no alive session channelId:%u", hChannel->channelId);
732cc290419Sopenharmony_ci        return ERR_SESSION_NOFOUND;
733cc290419Sopenharmony_ci    }
734cc290419Sopenharmony_ci    bool isClosing = uv_is_closing((const uv_handle_t *)&hChannel->hWorkTCP);
735cc290419Sopenharmony_ci    if (!isClosing && (hChannel->fdChildWorkTCP = Base::DuplicateUvSocket(&hChannel->hWorkTCP)) < 0) {
736cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "Duplicate socket failed channelId:%u", hChannel->channelId);
737cc290419Sopenharmony_ci        return ERR_SOCKET_DUPLICATE;
738cc290419Sopenharmony_ci    }
739cc290419Sopenharmony_ci    uv_close_cb funcWorkTcpClose = [](uv_handle_t *handle) -> void {
740cc290419Sopenharmony_ci        HChannel hChannel = (HChannel)handle->data;
741cc290419Sopenharmony_ci        --hChannel->ref;
742cc290419Sopenharmony_ci    };
743cc290419Sopenharmony_ci    ++hChannel->ref;
744cc290419Sopenharmony_ci    if (!isClosing) {
745cc290419Sopenharmony_ci        uv_close((uv_handle_t *)&hChannel->hWorkTCP, funcWorkTcpClose);
746cc290419Sopenharmony_ci    }
747cc290419Sopenharmony_ci    Base::DoNextLoop(loopMain, hChannel, [](const uint8_t flag, string &msg, const void *data) {
748cc290419Sopenharmony_ci        // Thread message can avoid using thread lock and improve program efficiency
749cc290419Sopenharmony_ci        // If not next loop call, ReadStream will thread conflict
750cc290419Sopenharmony_ci        HChannel hChannel = (HChannel)data;
751cc290419Sopenharmony_ci        auto thisClass = (HdcServerForClient *)hChannel->clsChannel;
752cc290419Sopenharmony_ci        HSession hSession = nullptr;
753cc290419Sopenharmony_ci        if ((hSession = thisClass->FindAliveSessionFromDaemonMap(hChannel)) == nullptr) {
754cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "hSession nullptr channelId:%u", hChannel->channelId);
755cc290419Sopenharmony_ci            return;
756cc290419Sopenharmony_ci        }
757cc290419Sopenharmony_ci        auto ctrl = HdcSessionBase::BuildCtrlString(SP_ATTACH_CHANNEL, hChannel->channelId, nullptr, 0);
758cc290419Sopenharmony_ci        Base::SendToPollFd(hSession->ctrlFd[STREAM_MAIN], ctrl.data(), ctrl.size());
759cc290419Sopenharmony_ci    });
760cc290419Sopenharmony_ci    return RET_SUCCESS;
761cc290419Sopenharmony_ci}
762cc290419Sopenharmony_ci
763cc290419Sopenharmony_cibool HdcServerForClient::CheckAutoFillTarget(HChannel hChannel)
764cc290419Sopenharmony_ci{
765cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
766cc290419Sopenharmony_ci    if (!hChannel->connectKey.size()) {
767cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "connectKey.size 0 channelId:%u", hChannel->channelId);
768cc290419Sopenharmony_ci        return false;  // Operation of non-bound destination of scanning
769cc290419Sopenharmony_ci    }
770cc290419Sopenharmony_ci    if (hChannel->connectKey == CMDSTR_CONNECT_ANY) {
771cc290419Sopenharmony_ci        HDaemonInfo hdiOld = nullptr;
772cc290419Sopenharmony_ci        ptrServer->AdminDaemonMap(OP_GET_ONLY, "", hdiOld);
773cc290419Sopenharmony_ci        if (!hdiOld) {
774cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "No any key found channelId:%u", hChannel->channelId);
775cc290419Sopenharmony_ci            return false;
776cc290419Sopenharmony_ci        }
777cc290419Sopenharmony_ci        if (!hdiOld->hSession) {
778cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "hSession is null. channelId:%u", hChannel->channelId);
779cc290419Sopenharmony_ci            return false;
780cc290419Sopenharmony_ci        }
781cc290419Sopenharmony_ci        if (!hdiOld->hSession->handshakeOK) {
782cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "hSession handShake is false SessionId:%u", hdiOld->hSession->sessionId);
783cc290419Sopenharmony_ci            return false;
784cc290419Sopenharmony_ci        }
785cc290419Sopenharmony_ci        hChannel->connectKey = hdiOld->connectKey;
786cc290419Sopenharmony_ci        return true;
787cc290419Sopenharmony_ci    }
788cc290419Sopenharmony_ci    return true;
789cc290419Sopenharmony_ci}
790cc290419Sopenharmony_ci
791cc290419Sopenharmony_ciint HdcServerForClient::ChannelHandShake(HChannel hChannel, uint8_t *bufPtr, const int bytesIO)
792cc290419Sopenharmony_ci{
793cc290419Sopenharmony_ci    vector<uint8_t> rebuildHandshake;
794cc290419Sopenharmony_ci    rebuildHandshake.insert(rebuildHandshake.end(), bufPtr, bufPtr + bytesIO);
795cc290419Sopenharmony_ci    rebuildHandshake.push_back(0x00);
796cc290419Sopenharmony_ci    struct ChannelHandShake *handShake = reinterpret_cast<struct ChannelHandShake *>(rebuildHandshake.data());
797cc290419Sopenharmony_ci    if (strncmp(handShake->banner, HANDSHAKE_MESSAGE.c_str(), HANDSHAKE_MESSAGE.size())) {
798cc290419Sopenharmony_ci        hChannel->availTailIndex = 0;
799cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Channel Hello failed");
800cc290419Sopenharmony_ci        return ERR_HANDSHAKE_NOTMATCH;
801cc290419Sopenharmony_ci    }
802cc290419Sopenharmony_ci    if (strlen(handShake->connectKey) > sizeof(handShake->connectKey)) {
803cc290419Sopenharmony_ci        hChannel->availTailIndex = 0;
804cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Connectkey's size incorrect");
805cc290419Sopenharmony_ci        return ERR_HANDSHAKE_CONNECTKEY_FAILED;
806cc290419Sopenharmony_ci    }
807cc290419Sopenharmony_ci    // channel handshake step3
808cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "ServerForClient cid:%u sid:%u handshake finished",
809cc290419Sopenharmony_ci        hChannel->channelId, hChannel->targetSessionId);
810cc290419Sopenharmony_ci    hChannel->connectKey = handShake->connectKey;
811cc290419Sopenharmony_ci    hChannel->handshakeOK = true;
812cc290419Sopenharmony_ci    if (handShake->banner[WAIT_TAG_OFFSET] == WAIT_DEVICE_TAG || !CheckAutoFillTarget(hChannel)) {
813cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "No target channelId:%u", hChannel->channelId);
814cc290419Sopenharmony_ci        return 0;
815cc290419Sopenharmony_ci    }
816cc290419Sopenharmony_ci    // channel handshake stBindChannelToSession
817cc290419Sopenharmony_ci    if (BindChannelToSession(hChannel, nullptr, 0)) {
818cc290419Sopenharmony_ci        hChannel->availTailIndex = 0;
819cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "BindChannelToSession failed channelId:%u sid:%u",
820cc290419Sopenharmony_ci            hChannel->channelId, hChannel->targetSessionId);
821cc290419Sopenharmony_ci        return ERR_GENERIC;
822cc290419Sopenharmony_ci    }
823cc290419Sopenharmony_ci    return 0;
824cc290419Sopenharmony_ci}
825cc290419Sopenharmony_ci
826cc290419Sopenharmony_civoid HdcServerForClient::ReportServerVersion(HChannel hChannel)
827cc290419Sopenharmony_ci{
828cc290419Sopenharmony_ci    string version = Base::GetVersion();
829cc290419Sopenharmony_ci    SendChannelWithCmd(hChannel, CMD_CHECK_SERVER,
830cc290419Sopenharmony_ci                       const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(version.c_str())),
831cc290419Sopenharmony_ci                       version.size());
832cc290419Sopenharmony_ci}
833cc290419Sopenharmony_ci
834cc290419Sopenharmony_ci// Here is Server to get data, the source is the SERVER's ChildWork to send data
835cc290419Sopenharmony_ciint HdcServerForClient::ReadChannel(HChannel hChannel, uint8_t *bufPtr, const int bytesIO)
836cc290419Sopenharmony_ci{
837cc290419Sopenharmony_ci    int ret = 0;
838cc290419Sopenharmony_ci    if (!hChannel->handshakeOK) {
839cc290419Sopenharmony_ci        return ChannelHandShake(hChannel, bufPtr, bytesIO);
840cc290419Sopenharmony_ci    }
841cc290419Sopenharmony_ci    HDaemonInfo hdi = nullptr;
842cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
843cc290419Sopenharmony_ci    ptrServer->AdminDaemonMap(OP_QUERY, hChannel->connectKey, hdi);
844cc290419Sopenharmony_ci    if (hdi && !hdi->emgmsg.empty()) {
845cc290419Sopenharmony_ci        EchoClient(hChannel, MSG_FAIL, hdi->emgmsg.c_str());
846cc290419Sopenharmony_ci        return ERR_GENERIC;
847cc290419Sopenharmony_ci    }
848cc290419Sopenharmony_ci    uint16_t command = *reinterpret_cast<uint16_t *>(bufPtr);
849cc290419Sopenharmony_ci    if (command != 0 && (hChannel->remote > RemoteType::REMOTE_NONE)) {
850cc290419Sopenharmony_ci        // server directly passthrough file command to daemon
851cc290419Sopenharmony_ci        if (!SendToDaemon(hChannel, command, bufPtr + sizeof(uint16_t), bytesIO - sizeof(uint16_t))) {
852cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "Client ReadChannel : direct send to daemon failed");
853cc290419Sopenharmony_ci        }
854cc290419Sopenharmony_ci        return ret;
855cc290419Sopenharmony_ci    }
856cc290419Sopenharmony_ci    struct TranslateCommand::FormatCommand formatCommand = { 0 };
857cc290419Sopenharmony_ci    if (!hChannel->interactiveShellMode) {
858cc290419Sopenharmony_ci        string retEcho = String2FormatCommand(reinterpret_cast<char *>(bufPtr), bytesIO, &formatCommand);
859cc290419Sopenharmony_ci        if (retEcho.length()) {
860cc290419Sopenharmony_ci            if (!strncmp(reinterpret_cast<char *>(bufPtr), CMDSTR_SOFTWARE_HELP.c_str(),
861cc290419Sopenharmony_ci                CMDSTR_SOFTWARE_HELP.size()) ||
862cc290419Sopenharmony_ci                !strcmp(reinterpret_cast<char *>(bufPtr), CMDSTR_SOFTWARE_VERSION.c_str()) ||
863cc290419Sopenharmony_ci                !strcmp(reinterpret_cast<char *>(bufPtr), "flash")) {
864cc290419Sopenharmony_ci                EchoClient(hChannel, MSG_OK, retEcho.c_str());
865cc290419Sopenharmony_ci            } else {
866cc290419Sopenharmony_ci                EchoClient(hChannel, MSG_FAIL, retEcho.c_str());
867cc290419Sopenharmony_ci            }
868cc290419Sopenharmony_ci        }
869cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "ReadChannel cid:%u sid:%u key:%s command: %s",
870cc290419Sopenharmony_ci            hChannel->channelId, hChannel->targetSessionId, Hdc::MaskString(hChannel->connectKey).c_str(), bufPtr);
871cc290419Sopenharmony_ci        if (formatCommand.bJumpDo) {
872cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "ReadChannel bJumpDo true");
873cc290419Sopenharmony_ci            return -10;  //  -10 error formatCommand
874cc290419Sopenharmony_ci        }
875cc290419Sopenharmony_ci    } else {
876cc290419Sopenharmony_ci        formatCommand.parameters = string(reinterpret_cast<char *>(bufPtr), bytesIO);
877cc290419Sopenharmony_ci        formatCommand.cmdFlag = CMD_SHELL_DATA;
878cc290419Sopenharmony_ci    }
879cc290419Sopenharmony_ci
880cc290419Sopenharmony_ci    if (!DoCommand(hChannel, &formatCommand)) {
881cc290419Sopenharmony_ci        return -3;  // -3: error or want close
882cc290419Sopenharmony_ci    }
883cc290419Sopenharmony_ci    ret = bytesIO;
884cc290419Sopenharmony_ci    return ret;
885cc290419Sopenharmony_ci};
886cc290419Sopenharmony_ci
887cc290419Sopenharmony_ci// avoid session dead
888cc290419Sopenharmony_ciHSession HdcServerForClient::FindAliveSession(uint32_t sessionId)
889cc290419Sopenharmony_ci{
890cc290419Sopenharmony_ci    HdcServer *ptrServer = (HdcServer *)clsServer;
891cc290419Sopenharmony_ci    HSession hSession = ptrServer->AdminSession(OP_QUERY, sessionId, nullptr);
892cc290419Sopenharmony_ci    if (!hSession || hSession->isDead) {
893cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "FindAliveSession hSession nullptr or isDead sessionId:%u", sessionId);
894cc290419Sopenharmony_ci        return nullptr;
895cc290419Sopenharmony_ci    } else {
896cc290419Sopenharmony_ci        return hSession;
897cc290419Sopenharmony_ci    }
898cc290419Sopenharmony_ci}
899cc290419Sopenharmony_ci
900cc290419Sopenharmony_cibool HdcServerForClient::ChannelSendSessionCtrlMsg(vector<uint8_t> &ctrlMsg, uint32_t sessionId)
901cc290419Sopenharmony_ci{
902cc290419Sopenharmony_ci    HSession hSession = FindAliveSession(sessionId);
903cc290419Sopenharmony_ci    if (!hSession) {
904cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "ChannelSendSessionCtrlMsg hSession nullptr sessionId:%u", sessionId);
905cc290419Sopenharmony_ci        return false;
906cc290419Sopenharmony_ci    }
907cc290419Sopenharmony_ci    int rc = Base::SendToPollFd(hSession->ctrlFd[STREAM_MAIN], ctrlMsg.data(), ctrlMsg.size());
908cc290419Sopenharmony_ci    if (rc <= 0) {
909cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "send ctrlmsg failed sessionId:%u rc:%d", sessionId, rc);
910cc290419Sopenharmony_ci    }
911cc290419Sopenharmony_ci    return rc > 0;
912cc290419Sopenharmony_ci}
913cc290419Sopenharmony_ci}  // namespace Hdc
914