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