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 "host_unity.h" 16cc290419Sopenharmony_ci 17cc290419Sopenharmony_cinamespace Hdc { 18cc290419Sopenharmony_ciHdcHostUnity::HdcHostUnity(HTaskInfo hTaskInfo) 19cc290419Sopenharmony_ci : HdcTaskBase(hTaskInfo) 20cc290419Sopenharmony_ci{ 21cc290419Sopenharmony_ci opContext.thisClass = this; 22cc290419Sopenharmony_ci} 23cc290419Sopenharmony_ci 24cc290419Sopenharmony_ciHdcHostUnity::~HdcHostUnity() 25cc290419Sopenharmony_ci{ 26cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "~HdcHostUnity channelId:%u", taskInfo->channelId); 27cc290419Sopenharmony_ci} 28cc290419Sopenharmony_ci 29cc290419Sopenharmony_cibool HdcHostUnity::ReadyForRelease() 30cc290419Sopenharmony_ci{ 31cc290419Sopenharmony_ci if (!HdcTaskBase::ReadyForRelease()) { 32cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "not ready for release channelId:%u", taskInfo->channelId); 33cc290419Sopenharmony_ci return false; 34cc290419Sopenharmony_ci } 35cc290419Sopenharmony_ci if (opContext.enableLog && !opContext.hasFilelogClosed) { 36cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "enableLog true hasFilelogClosed false channelId:%u", taskInfo->channelId); 37cc290419Sopenharmony_ci return false; 38cc290419Sopenharmony_ci } 39cc290419Sopenharmony_ci return true; 40cc290419Sopenharmony_ci} 41cc290419Sopenharmony_ci 42cc290419Sopenharmony_civoid HdcHostUnity::StopTask() 43cc290419Sopenharmony_ci{ 44cc290419Sopenharmony_ci // Do not detect RunningProtect, force to close 45cc290419Sopenharmony_ci if (opContext.hasFilelogClosed) { 46cc290419Sopenharmony_ci WRITE_LOG(LOG_WARN, "StopTask hasFilelogClosed true channelId:%u", taskInfo->channelId); 47cc290419Sopenharmony_ci return; 48cc290419Sopenharmony_ci } 49cc290419Sopenharmony_ci if (opContext.enableLog) { 50cc290419Sopenharmony_ci ++refCount; 51cc290419Sopenharmony_ci opContext.fsClose.data = &opContext; 52cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "taskInfo->channelId:%u fileLog:%d", taskInfo->channelId, opContext.fileLog); 53cc290419Sopenharmony_ci uv_fs_close(loopTask, &opContext.fsClose, opContext.fileLog, OnFileClose); 54cc290419Sopenharmony_ci } 55cc290419Sopenharmony_ci}; 56cc290419Sopenharmony_ci 57cc290419Sopenharmony_civoid HdcHostUnity::OnFileClose(uv_fs_t *req) 58cc290419Sopenharmony_ci{ 59cc290419Sopenharmony_ci uv_fs_req_cleanup(req); 60cc290419Sopenharmony_ci ContextUnity *context = reinterpret_cast<ContextUnity *>(req->data); 61cc290419Sopenharmony_ci HdcHostUnity *thisClass = reinterpret_cast<HdcHostUnity *>(context->thisClass); 62cc290419Sopenharmony_ci context->hasFilelogClosed = true; 63cc290419Sopenharmony_ci --thisClass->refCount; 64cc290419Sopenharmony_ci return; 65cc290419Sopenharmony_ci} 66cc290419Sopenharmony_ci 67cc290419Sopenharmony_cibool HdcHostUnity::InitLocalLog(const char *path) 68cc290419Sopenharmony_ci{ 69cc290419Sopenharmony_ci uv_fs_t reqFs; 70cc290419Sopenharmony_ci // block open 71cc290419Sopenharmony_ci if (uv_fs_open(nullptr, &reqFs, path, UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, nullptr) 72cc290419Sopenharmony_ci < 0) { 73cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "InitLocalLog uv_fs_open failed taskInfo->channelId:%u", taskInfo->channelId); 74cc290419Sopenharmony_ci return false; 75cc290419Sopenharmony_ci } 76cc290419Sopenharmony_ci uv_fs_req_cleanup(&reqFs); 77cc290419Sopenharmony_ci opContext.fileLog = reqFs.result; 78cc290419Sopenharmony_ci return true; 79cc290419Sopenharmony_ci} 80cc290419Sopenharmony_ci 81cc290419Sopenharmony_civoid HdcHostUnity::OnFileIO(uv_fs_t *req) 82cc290419Sopenharmony_ci{ 83cc290419Sopenharmony_ci CtxUnityIO *contextIO = reinterpret_cast<CtxUnityIO *>(req->data); 84cc290419Sopenharmony_ci ContextUnity *context = reinterpret_cast<ContextUnity *>(contextIO->context); 85cc290419Sopenharmony_ci HdcHostUnity *thisClass = reinterpret_cast<HdcHostUnity *>(context->thisClass); 86cc290419Sopenharmony_ci uint8_t *bufIO = contextIO->bufIO; 87cc290419Sopenharmony_ci uv_fs_req_cleanup(req); 88cc290419Sopenharmony_ci --thisClass->refCount; 89cc290419Sopenharmony_ci while (true) { 90cc290419Sopenharmony_ci if (req->result <= 0) { 91cc290419Sopenharmony_ci if (req->result < 0) { 92cc290419Sopenharmony_ci constexpr int bufSize = 1024; 93cc290419Sopenharmony_ci char buf[bufSize] = { 0 }; 94cc290419Sopenharmony_ci uv_strerror_r((int)req->result, buf, bufSize); 95cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Error OnFileIO: %s", buf); 96cc290419Sopenharmony_ci } 97cc290419Sopenharmony_ci break; 98cc290419Sopenharmony_ci } 99cc290419Sopenharmony_ci context->fileIOIndex += req->result; 100cc290419Sopenharmony_ci break; 101cc290419Sopenharmony_ci } 102cc290419Sopenharmony_ci delete[] bufIO; 103cc290419Sopenharmony_ci delete contextIO; // req is part of contextIO, no need to release 104cc290419Sopenharmony_ci} 105cc290419Sopenharmony_ci 106cc290419Sopenharmony_cibool HdcHostUnity::AppendLocalLog(const char *bufLog, const int sizeLog) 107cc290419Sopenharmony_ci{ 108cc290419Sopenharmony_ci auto buf = new uint8_t[sizeLog]; 109cc290419Sopenharmony_ci auto contextIO = new CtxUnityIO(); 110cc290419Sopenharmony_ci if (!buf || !contextIO) { 111cc290419Sopenharmony_ci if (buf) { 112cc290419Sopenharmony_ci delete[] buf; 113cc290419Sopenharmony_ci } 114cc290419Sopenharmony_ci if (contextIO) { 115cc290419Sopenharmony_ci delete contextIO; 116cc290419Sopenharmony_ci } 117cc290419Sopenharmony_ci return false; 118cc290419Sopenharmony_ci } 119cc290419Sopenharmony_ci uv_fs_t *req = &contextIO->fs; 120cc290419Sopenharmony_ci contextIO->bufIO = buf; 121cc290419Sopenharmony_ci contextIO->context = &opContext; 122cc290419Sopenharmony_ci req->data = contextIO; 123cc290419Sopenharmony_ci ++refCount; 124cc290419Sopenharmony_ci 125cc290419Sopenharmony_ci if (memcpy_s(buf, sizeLog, bufLog, sizeLog)) { 126cc290419Sopenharmony_ci } 127cc290419Sopenharmony_ci uv_buf_t iov = uv_buf_init(reinterpret_cast<char *>(buf), sizeLog); 128cc290419Sopenharmony_ci uv_fs_write(loopTask, req, opContext.fileLog, &iov, 1, opContext.fileBufIndex, OnFileIO); 129cc290419Sopenharmony_ci opContext.fileBufIndex += sizeLog; 130cc290419Sopenharmony_ci return true; 131cc290419Sopenharmony_ci} 132cc290419Sopenharmony_ci 133cc290419Sopenharmony_cibool HdcHostUnity::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) 134cc290419Sopenharmony_ci{ 135cc290419Sopenharmony_ci bool ret = true; 136cc290419Sopenharmony_ci // Both are executed, do not need to detect ChildReady 137cc290419Sopenharmony_ci switch (command) { 138cc290419Sopenharmony_ci case CMD_UNITY_BUGREPORT_INIT: { 139cc290419Sopenharmony_ci if (strlen(reinterpret_cast<char *>(payload))) { // enable local log 140cc290419Sopenharmony_ci if (!InitLocalLog(reinterpret_cast<const char *>(payload))) { 141cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "Cannot set locallog"); 142cc290419Sopenharmony_ci ret = false; 143cc290419Sopenharmony_ci break; 144cc290419Sopenharmony_ci }; 145cc290419Sopenharmony_ci opContext.enableLog = true; 146cc290419Sopenharmony_ci } 147cc290419Sopenharmony_ci SendToAnother(CMD_UNITY_BUGREPORT_INIT, nullptr, 0); 148cc290419Sopenharmony_ci break; 149cc290419Sopenharmony_ci } 150cc290419Sopenharmony_ci case CMD_UNITY_BUGREPORT_DATA: { 151cc290419Sopenharmony_ci if (opContext.enableLog) { 152cc290419Sopenharmony_ci AppendLocalLog(reinterpret_cast<const char *>(payload), payloadSize); 153cc290419Sopenharmony_ci } else { 154cc290419Sopenharmony_ci ServerCommand(CMD_KERNEL_ECHO_RAW, payload, payloadSize); 155cc290419Sopenharmony_ci } 156cc290419Sopenharmony_ci break; 157cc290419Sopenharmony_ci } 158cc290419Sopenharmony_ci default: 159cc290419Sopenharmony_ci break; 160cc290419Sopenharmony_ci } 161cc290419Sopenharmony_ci return ret; 162cc290419Sopenharmony_ci}; 163cc290419Sopenharmony_ci} // namespace Hdc 164