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