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
16cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
17cc290419Sopenharmony_ci
18cc290419Sopenharmony_ci#include "daemon_uart.h"
19cc290419Sopenharmony_ci
20cc290419Sopenharmony_ci#include <thread>
21cc290419Sopenharmony_ci#include <fcntl.h>
22cc290419Sopenharmony_ci#include <file_ex.h>
23cc290419Sopenharmony_ci#include <string_ex.h>
24cc290419Sopenharmony_ci
25cc290419Sopenharmony_ci#include <sys/file.h>
26cc290419Sopenharmony_ci#include <sys/mount.h>
27cc290419Sopenharmony_ci#include <sys/select.h>
28cc290419Sopenharmony_ci#include <sys/time.h>
29cc290419Sopenharmony_ci
30cc290419Sopenharmony_cinamespace Hdc {
31cc290419Sopenharmony_ciHdcDaemonUART::HdcDaemonUART(HdcDaemon &daemonSessionIn, ExternInterface &externInterface)
32cc290419Sopenharmony_ci    : HdcUARTBase(daemonSessionIn, externInterface), daemon(daemonSessionIn)
33cc290419Sopenharmony_ci{
34cc290419Sopenharmony_ci    checkSerialPort.data = nullptr;
35cc290419Sopenharmony_ci}
36cc290419Sopenharmony_ci
37cc290419Sopenharmony_ciint HdcDaemonUART::Initial(const std::string &devPathIn)
38cc290419Sopenharmony_ci{
39cc290419Sopenharmony_ci    int ret = 0;
40cc290419Sopenharmony_ci    devPath = devPathIn;
41cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "HdcDaemonUART init");
42cc290419Sopenharmony_ci    if (access(devPath.c_str(), F_OK) != 0) {
43cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "uartMod Disable, path is %s and errno is %d.", devPath.c_str(), errno);
44cc290419Sopenharmony_ci        return -1;
45cc290419Sopenharmony_ci    }
46cc290419Sopenharmony_ci#ifndef HDC_UT
47cc290419Sopenharmony_ci    std::string consoleActive;
48cc290419Sopenharmony_ci    if (OHOS::LoadStringFromFile(CONSOLE_ACTIVE_NODE, consoleActive)) {
49cc290419Sopenharmony_ci        consoleActive = OHOS::TrimStr(consoleActive, '\n');
50cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "consoleActive (%d):%s", consoleActive.length(),
51cc290419Sopenharmony_ci                  consoleActive.c_str());
52cc290419Sopenharmony_ci        if (!consoleActive.empty() and devPathIn.find(consoleActive.c_str()) != std::string::npos) {
53cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL,
54cc290419Sopenharmony_ci                      "kernel use this dev(%s) as console , we can't open it as hdc uart dev",
55cc290419Sopenharmony_ci                      devPathIn.c_str());
56cc290419Sopenharmony_ci            return -1;
57cc290419Sopenharmony_ci        }
58cc290419Sopenharmony_ci    }
59cc290419Sopenharmony_ci#endif
60cc290419Sopenharmony_ci    constexpr int bufSize = 1024;
61cc290419Sopenharmony_ci    char buf[bufSize] = { 0 };
62cc290419Sopenharmony_ci    const uint16_t uartScanInterval = 1500;
63cc290419Sopenharmony_ci    ret = uv_timer_init(&daemon.loopMain, &checkSerialPort);
64cc290419Sopenharmony_ci    if (ret != 0) {
65cc290419Sopenharmony_ci        uv_err_name_r(ret, buf, bufSize);
66cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "uv_timer_init failed %s", buf);
67cc290419Sopenharmony_ci    } else {
68cc290419Sopenharmony_ci        checkSerialPort.data = this;
69cc290419Sopenharmony_ci        ret = uv_timer_start(&checkSerialPort, UvWatchTimer, 0, uartScanInterval);
70cc290419Sopenharmony_ci        if (ret != 0) {
71cc290419Sopenharmony_ci            uv_err_name_r(ret, buf, bufSize);
72cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "uv_timer_start failed %s", buf);
73cc290419Sopenharmony_ci        } else {
74cc290419Sopenharmony_ci            return 0;
75cc290419Sopenharmony_ci        }
76cc290419Sopenharmony_ci    }
77cc290419Sopenharmony_ci    return -1;
78cc290419Sopenharmony_ci}
79cc290419Sopenharmony_ci
80cc290419Sopenharmony_ciint HdcDaemonUART::PrepareBufForRead()
81cc290419Sopenharmony_ci{
82cc290419Sopenharmony_ci    constexpr int bufCoefficient = 1;
83cc290419Sopenharmony_ci    int readMax = MAX_UART_SIZE_IOBUF * bufCoefficient;
84cc290419Sopenharmony_ci    dataReadBuf.clear();
85cc290419Sopenharmony_ci    dataReadBuf.reserve(readMax);
86cc290419Sopenharmony_ci    return RET_SUCCESS;
87cc290419Sopenharmony_ci}
88cc290419Sopenharmony_ci
89cc290419Sopenharmony_civoid HdcDaemonUART::WatcherTimerCallBack()
90cc290419Sopenharmony_ci{
91cc290419Sopenharmony_ci    // try reanbel the uart device (reopen)
92cc290419Sopenharmony_ci    if (isAlive) {
93cc290419Sopenharmony_ci        return;
94cc290419Sopenharmony_ci    }
95cc290419Sopenharmony_ci    do {
96cc290419Sopenharmony_ci        if (uartHandle >= 0) {
97cc290419Sopenharmony_ci            if (CloseUartDevice() != RET_SUCCESS) {
98cc290419Sopenharmony_ci                break;
99cc290419Sopenharmony_ci            }
100cc290419Sopenharmony_ci        }
101cc290419Sopenharmony_ci        if ((OpenUartDevice() != RET_SUCCESS)) {
102cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "OpenUartdevice fail ! ");
103cc290419Sopenharmony_ci            break;
104cc290419Sopenharmony_ci        }
105cc290419Sopenharmony_ci        if ((PrepareBufForRead() != RET_SUCCESS)) {
106cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "PrepareBufForRead fail ! ");
107cc290419Sopenharmony_ci            break;
108cc290419Sopenharmony_ci        }
109cc290419Sopenharmony_ci        // read and write thread need this flag
110cc290419Sopenharmony_ci        isAlive = true;
111cc290419Sopenharmony_ci        if ((LoopUARTRead() != RET_SUCCESS)) {
112cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "LoopUARTRead fail ! ");
113cc290419Sopenharmony_ci            break;
114cc290419Sopenharmony_ci        }
115cc290419Sopenharmony_ci        if ((LoopUARTWrite() != RET_SUCCESS)) {
116cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "LoopUARTWrite fail ! ");
117cc290419Sopenharmony_ci            break;
118cc290419Sopenharmony_ci        }
119cc290419Sopenharmony_ci        return;
120cc290419Sopenharmony_ci    } while (false);
121cc290419Sopenharmony_ci    WRITE_LOG(LOG_FATAL, "WatcherTimerCallBack found some issue");
122cc290419Sopenharmony_ci    isAlive = false;
123cc290419Sopenharmony_ci}
124cc290419Sopenharmony_ci
125cc290419Sopenharmony_ciint HdcDaemonUART::CloseUartDevice()
126cc290419Sopenharmony_ci{
127cc290419Sopenharmony_ci    int ret = Base::CloseFd(uartHandle);
128cc290419Sopenharmony_ci    if (ret < 0) {
129cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "CloseUartDevice failed ret: %d", ret);
130cc290419Sopenharmony_ci    }
131cc290419Sopenharmony_ci    isAlive = false;
132cc290419Sopenharmony_ci    return ret;
133cc290419Sopenharmony_ci}
134cc290419Sopenharmony_ci
135cc290419Sopenharmony_ciint HdcDaemonUART::OpenUartDevice()
136cc290419Sopenharmony_ci{
137cc290419Sopenharmony_ci    int ret = ERR_GENERIC;
138cc290419Sopenharmony_ci    while (true) {
139cc290419Sopenharmony_ci        if ((uartHandle = open(devPath.c_str(), O_RDWR | O_NOCTTY | O_NDELAY)) < 0) {
140cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "%s: cannot open uartHandle: errno=%d", devPath.c_str(), errno);
141cc290419Sopenharmony_ci            break;
142cc290419Sopenharmony_ci        }
143cc290419Sopenharmony_ci        uv_sleep(UART_IO_WAIT_TIME_100);
144cc290419Sopenharmony_ci        // cannot open with O_CLOEXEC, must fcntl
145cc290419Sopenharmony_ci        fcntl(uartHandle, F_SETFD, FD_CLOEXEC);
146cc290419Sopenharmony_ci        int flag = fcntl(uartHandle, F_GETFL);
147cc290419Sopenharmony_ci        flag &= ~O_NONBLOCK;
148cc290419Sopenharmony_ci        fcntl(uartHandle, F_SETFL, flag);
149cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Set SetSerial ");
150cc290419Sopenharmony_ci        if (SetSerial(uartHandle, DEFAULT_BAUD_RATE_VALUE, UART_BIT2, 'N', 1) != RET_SUCCESS) {
151cc290419Sopenharmony_ci            break;
152cc290419Sopenharmony_ci        }
153cc290419Sopenharmony_ci        ret = RET_SUCCESS;
154cc290419Sopenharmony_ci        break;
155cc290419Sopenharmony_ci    }
156cc290419Sopenharmony_ci    if (ret != RET_SUCCESS) {
157cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "OpenUartdevice SerialHandle:%d fail.", uartHandle);
158cc290419Sopenharmony_ci    }
159cc290419Sopenharmony_ci    return ret;
160cc290419Sopenharmony_ci}
161cc290419Sopenharmony_ci
162cc290419Sopenharmony_civoid HdcDaemonUART::ResetOldSession(uint32_t sessionId)
163cc290419Sopenharmony_ci{
164cc290419Sopenharmony_ci    if (sessionId == 0) {
165cc290419Sopenharmony_ci        sessionId = currentSessionId;
166cc290419Sopenharmony_ci    }
167cc290419Sopenharmony_ci    HSession hSession = daemon.AdminSession(OP_QUERY, sessionId, nullptr);
168cc290419Sopenharmony_ci    if (hSession == nullptr) {
169cc290419Sopenharmony_ci        return;
170cc290419Sopenharmony_ci    }
171cc290419Sopenharmony_ci    if (hSession->hUART != nullptr) {
172cc290419Sopenharmony_ci        hSession->hUART->resetIO = true;
173cc290419Sopenharmony_ci    }
174cc290419Sopenharmony_ci    // The Host side is restarted, but the USB cable is still connected
175cc290419Sopenharmony_ci    WRITE_LOG(LOG_WARN, "Hostside softreset to restart daemon, old sessionId:%u", sessionId);
176cc290419Sopenharmony_ci    OnTransferError(hSession);
177cc290419Sopenharmony_ci}
178cc290419Sopenharmony_ci
179cc290419Sopenharmony_ciHSession HdcDaemonUART::GetSession(const uint32_t sessionId, bool create = false)
180cc290419Sopenharmony_ci{
181cc290419Sopenharmony_ci    HSession hSession = daemon.AdminSession(OP_QUERY, sessionId, nullptr);
182cc290419Sopenharmony_ci    if (hSession == nullptr and create) {
183cc290419Sopenharmony_ci        hSession = PrepareNewSession(sessionId);
184cc290419Sopenharmony_ci    }
185cc290419Sopenharmony_ci    return hSession;
186cc290419Sopenharmony_ci}
187cc290419Sopenharmony_ci
188cc290419Sopenharmony_civoid HdcDaemonUART::OnTransferError(const HSession session)
189cc290419Sopenharmony_ci{
190cc290419Sopenharmony_ci    // review maybe we can do something more ?
191cc290419Sopenharmony_ci    if (session != nullptr) {
192cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "%s %s", __FUNCTION__, session->ToDebugString().c_str());
193cc290419Sopenharmony_ci        daemon.FreeSession(session->sessionId);
194cc290419Sopenharmony_ci        ClearUARTOutMap(session->sessionId);
195cc290419Sopenharmony_ci    }
196cc290419Sopenharmony_ci}
197cc290419Sopenharmony_ci
198cc290419Sopenharmony_civoid HdcDaemonUART::OnNewHandshakeOK(const uint32_t sessionId)
199cc290419Sopenharmony_ci{
200cc290419Sopenharmony_ci    currentSessionId = sessionId;
201cc290419Sopenharmony_ci}
202cc290419Sopenharmony_ci
203cc290419Sopenharmony_ciHSession HdcDaemonUART::PrepareNewSession(uint32_t sessionId)
204cc290419Sopenharmony_ci{
205cc290419Sopenharmony_ci    WRITE_LOG(LOG_FATAL, "%s sessionId:%u", __FUNCTION__, sessionId);
206cc290419Sopenharmony_ci    HSession hSession = daemon.MallocSession(false, CONN_SERIAL, this, sessionId);
207cc290419Sopenharmony_ci    if (!hSession) {
208cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "new session malloc failed for sessionId:%u", sessionId);
209cc290419Sopenharmony_ci        return nullptr;
210cc290419Sopenharmony_ci    }
211cc290419Sopenharmony_ci    if (currentSessionId != 0) {
212cc290419Sopenharmony_ci        // reset old session
213cc290419Sopenharmony_ci        // The Host side is restarted, but the cable is still connected
214cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "New session coming, restart old sessionId:%u", currentSessionId);
215cc290419Sopenharmony_ci        daemon.PushAsyncMessage(currentSessionId, ASYNC_FREE_SESSION, nullptr, 0);
216cc290419Sopenharmony_ci    }
217cc290419Sopenharmony_ci    externInterface.StartWorkThread(&daemon.loopMain, daemon.SessionWorkThread,
218cc290419Sopenharmony_ci                                    Base::FinishWorkThread, hSession);
219cc290419Sopenharmony_ci    auto funcNewSessionUp = [](uv_timer_t *handle) -> void {
220cc290419Sopenharmony_ci        HSession hSession = reinterpret_cast<HSession>(handle->data);
221cc290419Sopenharmony_ci        HdcDaemon &daemonSession = *reinterpret_cast<HdcDaemon *>(hSession->classInstance);
222cc290419Sopenharmony_ci        if (hSession->childLoop.active_handles == 0) {
223cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "No active_handles.");
224cc290419Sopenharmony_ci            return;
225cc290419Sopenharmony_ci        }
226cc290419Sopenharmony_ci        if (!hSession->isDead) {
227cc290419Sopenharmony_ci            auto ctrl = daemonSession.BuildCtrlString(SP_START_SESSION, 0, nullptr, 0);
228cc290419Sopenharmony_ci            Base::SendToPollFd(hSession->ctrlFd[STREAM_MAIN], ctrl.data(), ctrl.size());
229cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "Main thread uartio migrate finish");
230cc290419Sopenharmony_ci        }
231cc290419Sopenharmony_ci        Base::TryCloseHandle(reinterpret_cast<uv_handle_t *>(handle), Base::CloseTimerCallback);
232cc290419Sopenharmony_ci    };
233cc290419Sopenharmony_ci    externInterface.TimerUvTask(&daemon.loopMain, hSession, funcNewSessionUp);
234cc290419Sopenharmony_ci    return hSession;
235cc290419Sopenharmony_ci}
236cc290419Sopenharmony_ci
237cc290419Sopenharmony_ci// review Merge this with Host side
238cc290419Sopenharmony_civoid HdcDaemonUART::DeamonReadThread()
239cc290419Sopenharmony_ci{
240cc290419Sopenharmony_ci    HdcUART deamonUart;
241cc290419Sopenharmony_ci    deamonUart.devUartHandle = uartHandle;
242cc290419Sopenharmony_ci    dataReadBuf.clear();
243cc290419Sopenharmony_ci    // after we got the head or something , we will expected some size
244cc290419Sopenharmony_ci    size_t expectedSize = 0;
245cc290419Sopenharmony_ci    // use < not <= because if it full , should not read again
246cc290419Sopenharmony_ci    while (isAlive && dataReadBuf.size() < MAX_READ_BUFFER) {
247cc290419Sopenharmony_ci        ssize_t bytesRead = ReadUartDev(dataReadBuf, expectedSize, deamonUart);
248cc290419Sopenharmony_ci        if (bytesRead == 0) {
249cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "%s read %zd, clean the data try read again.", __FUNCTION__,
250cc290419Sopenharmony_ci                      bytesRead);
251cc290419Sopenharmony_ci            // drop current cache
252cc290419Sopenharmony_ci            expectedSize = 0;
253cc290419Sopenharmony_ci            dataReadBuf.clear();
254cc290419Sopenharmony_ci            continue;
255cc290419Sopenharmony_ci        } else if (bytesRead < 0) {
256cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "%s read abnormal, stop uart module.", __FUNCTION__);
257cc290419Sopenharmony_ci            Stop();
258cc290419Sopenharmony_ci            break;
259cc290419Sopenharmony_ci        }
260cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "DeamonReadThread bytesRead:%d, totalReadBytes.size():%d.", bytesRead,
261cc290419Sopenharmony_ci                  dataReadBuf.size());
262cc290419Sopenharmony_ci
263cc290419Sopenharmony_ci        if (dataReadBuf.size() < sizeof(UartHead)) {
264cc290419Sopenharmony_ci            continue; // no enough ,read again
265cc290419Sopenharmony_ci        }
266cc290419Sopenharmony_ci        expectedSize = PackageProcess(dataReadBuf);
267cc290419Sopenharmony_ci    }
268cc290419Sopenharmony_ci    if (isAlive) {
269cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "totalReadSize is full %zu/%zu, DeamonReadThread exit..",
270cc290419Sopenharmony_ci                  dataReadBuf.size(), expectedSize);
271cc290419Sopenharmony_ci    } else {
272cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "dev is not alive, DeamonReadThread exit..");
273cc290419Sopenharmony_ci    }
274cc290419Sopenharmony_ci    // why not free session here
275cc290419Sopenharmony_ci    isAlive = false;
276cc290419Sopenharmony_ci    return;
277cc290419Sopenharmony_ci}
278cc290419Sopenharmony_ci
279cc290419Sopenharmony_civoid HdcDaemonUART::DeamonWriteThread()
280cc290419Sopenharmony_ci{
281cc290419Sopenharmony_ci    while (isAlive) {
282cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "DeamonWriteThread wait sendLock.");
283cc290419Sopenharmony_ci        transfer.Wait();
284cc290419Sopenharmony_ci        SendPkgInUARTOutMap();
285cc290419Sopenharmony_ci    }
286cc290419Sopenharmony_ci    WRITE_LOG(LOG_WARN, "dev is not alive, DeamonWriteThread exit..");
287cc290419Sopenharmony_ci    return;
288cc290419Sopenharmony_ci}
289cc290419Sopenharmony_ci
290cc290419Sopenharmony_ciint HdcDaemonUART::LoopUARTRead()
291cc290419Sopenharmony_ci{
292cc290419Sopenharmony_ci    try {
293cc290419Sopenharmony_ci        std::thread deamonReadThread([this]() { this->DeamonReadThread(); });
294cc290419Sopenharmony_ci        deamonReadThread.detach();
295cc290419Sopenharmony_ci        return 0;
296cc290419Sopenharmony_ci    } catch (...) {
297cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "create thread DeamonReadThread failed");
298cc290419Sopenharmony_ci    }
299cc290419Sopenharmony_ci    return -1;
300cc290419Sopenharmony_ci}
301cc290419Sopenharmony_ci
302cc290419Sopenharmony_ciint HdcDaemonUART::LoopUARTWrite()
303cc290419Sopenharmony_ci{
304cc290419Sopenharmony_ci    try {
305cc290419Sopenharmony_ci        std::thread deamonWriteThread([this]() { this->DeamonWriteThread(); });
306cc290419Sopenharmony_ci        deamonWriteThread.detach();
307cc290419Sopenharmony_ci        return 0;
308cc290419Sopenharmony_ci    } catch (...) {
309cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "create thread DeamonWriteThread failed");
310cc290419Sopenharmony_ci    }
311cc290419Sopenharmony_ci    return -1;
312cc290419Sopenharmony_ci}
313cc290419Sopenharmony_ci
314cc290419Sopenharmony_cibool HdcDaemonUART::IsSendReady(HSession hSession)
315cc290419Sopenharmony_ci{
316cc290419Sopenharmony_ci    if (isAlive and !hSession->isDead and uartHandle >= 0 and !hSession->hUART->resetIO) {
317cc290419Sopenharmony_ci        return true;
318cc290419Sopenharmony_ci    } else {
319cc290419Sopenharmony_ci        if (!isAlive) {
320cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "!isAlive");
321cc290419Sopenharmony_ci        } else if (hSession->isDead) {
322cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "session isDead");
323cc290419Sopenharmony_ci        } else if (uartHandle < 0) {
324cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "uartHandle is not valid");
325cc290419Sopenharmony_ci        } else if (hSession->hUART->resetIO) {
326cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "session have resetIO");
327cc290419Sopenharmony_ci        }
328cc290419Sopenharmony_ci        return false;
329cc290419Sopenharmony_ci    }
330cc290419Sopenharmony_ci};
331cc290419Sopenharmony_ci
332cc290419Sopenharmony_ciHdcDaemonUART::~HdcDaemonUART()
333cc290419Sopenharmony_ci{
334cc290419Sopenharmony_ci    Stop();
335cc290419Sopenharmony_ci}
336cc290419Sopenharmony_ci
337cc290419Sopenharmony_civoid HdcDaemonUART::Stop()
338cc290419Sopenharmony_ci{
339cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "%s run!", __FUNCTION__);
340cc290419Sopenharmony_ci    if (!stopped) {
341cc290419Sopenharmony_ci        stopped = true;
342cc290419Sopenharmony_ci        std::lock_guard<std::mutex> lock(workThreadProcessingData);
343cc290419Sopenharmony_ci
344cc290419Sopenharmony_ci        // maybe some data response not back to host
345cc290419Sopenharmony_ci        // like smode need response.
346cc290419Sopenharmony_ci        ResponseUartTrans(currentSessionId, 0, PKG_OPTION_FREE);
347cc290419Sopenharmony_ci        EnsureAllPkgsSent();
348cc290419Sopenharmony_ci        isAlive = false;
349cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "%s free main session", __FUNCTION__);
350cc290419Sopenharmony_ci        if (checkSerialPort.data != nullptr) {
351cc290419Sopenharmony_ci            externInterface.TryCloseHandle((uv_handle_t *)&checkSerialPort);
352cc290419Sopenharmony_ci            checkSerialPort.data = nullptr;
353cc290419Sopenharmony_ci        }
354cc290419Sopenharmony_ci        CloseUartDevice();
355cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "%s free main session finish", __FUNCTION__);
356cc290419Sopenharmony_ci    }
357cc290419Sopenharmony_ci}
358cc290419Sopenharmony_ci} // namespace Hdc
359cc290419Sopenharmony_ci#endif // HDC_SUPPORT_UART
360