• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "host_unity.h"
16 
17 namespace Hdc {
HdcHostUnity(HTaskInfo hTaskInfo)18 HdcHostUnity::HdcHostUnity(HTaskInfo hTaskInfo)
19     : HdcTaskBase(hTaskInfo)
20 {
21     opContext.thisClass = this;
22 }
23 
~HdcHostUnity()24 HdcHostUnity::~HdcHostUnity()
25 {
26     WRITE_LOG(LOG_DEBUG, "HdcHostUnity::~HdcHostUnity finish");
27 }
28 
ReadyForRelease()29 bool HdcHostUnity::ReadyForRelease()
30 {
31     if (!HdcTaskBase::ReadyForRelease()) {
32         return false;
33     }
34     if (opContext.enableLog && !opContext.hasFilelogClosed) {
35         return false;
36     }
37     return true;
38 }
39 
StopTask()40 void HdcHostUnity::StopTask()
41 {
42     // Do not detect RunningProtect, force to close
43     if (opContext.hasFilelogClosed) {
44         return;
45     }
46     if (opContext.enableLog) {
47         ++refCount;
48         opContext.fsClose.data = &opContext;
49         uv_fs_close(loopTask, &opContext.fsClose, opContext.fileLog, OnFileClose);
50     }
51 };
52 
OnFileClose(uv_fs_t * req)53 void HdcHostUnity::OnFileClose(uv_fs_t *req)
54 {
55     uv_fs_req_cleanup(req);
56     ContextUnity *context = (ContextUnity *)req->data;
57     HdcHostUnity *thisClass = (HdcHostUnity *)context->thisClass;
58     context->hasFilelogClosed = true;
59     --thisClass->refCount;
60     return;
61 }
62 
InitLocalLog(const char * path)63 bool HdcHostUnity::InitLocalLog(const char *path)
64 {
65     uv_fs_t reqFs;
66     // block open
67     if (uv_fs_open(nullptr, &reqFs, path, UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, nullptr)
68         < 0)
69         return false;
70     uv_fs_req_cleanup(&reqFs);
71     opContext.fileLog = reqFs.result;
72     return true;
73 }
74 
OnFileIO(uv_fs_t * req)75 void HdcHostUnity::OnFileIO(uv_fs_t *req)
76 {
77     CtxUnityIO *contextIO = (CtxUnityIO *)req->data;
78     ContextUnity *context = (ContextUnity *)contextIO->context;
79     HdcHostUnity *thisClass = (HdcHostUnity *)context->thisClass;
80     uint8_t *bufIO = contextIO->bufIO;
81     uv_fs_req_cleanup(req);
82     --thisClass->refCount;
83     while (true) {
84         if (req->result <= 0) {
85             if (req->result < 0) {
86                 constexpr int bufSize = 1024;
87                 char buf[bufSize] = { 0 };
88                 uv_strerror_r((int)req->result, buf, bufSize);
89                 WRITE_LOG(LOG_DEBUG, "Error OnFileIO: %s", buf);
90             }
91             break;
92         }
93         context->fileIOIndex += req->result;
94         break;
95     }
96     delete[] bufIO;
97     delete contextIO;  // req is part of contextIO, no need to release
98 }
99 
AppendLocalLog(const char * bufLog,const int sizeLog)100 bool HdcHostUnity::AppendLocalLog(const char *bufLog, const int sizeLog)
101 {
102     auto buf = new uint8_t[sizeLog];
103     auto contextIO = new CtxUnityIO();
104     if (!buf || !contextIO) {
105         if (buf) {
106             delete[] buf;
107         }
108         if (contextIO) {
109             delete contextIO;
110         }
111         return false;
112     }
113     uv_fs_t *req = &contextIO->fs;
114     contextIO->bufIO = buf;
115     contextIO->context = &opContext;
116     req->data = contextIO;
117     ++refCount;
118 
119     if (memcpy_s(buf, sizeLog, bufLog, sizeLog)) {
120     }
121     uv_buf_t iov = uv_buf_init((char *)buf, sizeLog);
122     uv_fs_write(loopTask, req, opContext.fileLog, &iov, 1, opContext.fileBufIndex, OnFileIO);
123     opContext.fileBufIndex += sizeLog;
124     return true;
125 }
126 
CommandDispatch(const uint16_t command,uint8_t * payload,const int payloadSize)127 bool HdcHostUnity::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize)
128 {
129     bool ret = true;
130     // Both are executed, do not need to detect ChildReady
131     switch (command) {
132         case CMD_UNITY_BUGREPORT_INIT: {
133             if (strlen((char *)payload)) {  // enable local log
134                 if (!InitLocalLog((const char *)payload)) {
135                     LogMsg(MSG_FAIL, "Cannot set locallog");
136                     ret = false;
137                     break;
138                 };
139                 opContext.enableLog = true;
140             }
141             SendToAnother(CMD_UNITY_BUGREPORT_INIT, nullptr, 0);
142             break;
143         }
144         case CMD_UNITY_BUGREPORT_DATA: {
145             if (opContext.enableLog) {
146                 AppendLocalLog((const char *)payload, payloadSize);
147             } else {
148                 ServerCommand(CMD_KERNEL_ECHO_RAW, payload, payloadSize);
149             }
150             break;
151         }
152         default:
153             break;
154     }
155     return ret;
156 };
157 }  // namespace Hdc
158