• 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 
16 #include "rpc_server.h"
17 
18 #include <cstdint>
19 #include <cstring>
20 #include <functional>
21 #if IS_WASM
22 #include <filesystem>
23 #endif
24 #include "json.hpp"
25 #include "log.h"
26 #include "string_help.h"
27 #include "version.h"
28 
29 #define UNUSED(expr)             \
30     do {                         \
31         static_cast<void>(expr); \
32     } while (0)
33 namespace SysTuning {
34 namespace TraceStreamer {
35 uint32_t g_fileLen = 0;
36 FILE* g_importFileFd = nullptr;
37 using json = nlohmann::json;
38 namespace jsonns {
39 struct ParserConfig {
40     int32_t taskConfigValue;
41     int32_t appConfigValue;
42     int32_t aniConfigValue;
43 };
from_json(const json & j,ParserConfig & v)44 void from_json(const json& j, ParserConfig& v)
45 {
46     j.at("TaskPool").get_to(v.taskConfigValue);
47     j.at("AppStartup").get_to(v.appConfigValue);
48     j.at("AnimationAnalysis").get_to(v.aniConfigValue);
49 }
50 } // namespace jsonns
ParseData(const uint8_t * data,size_t len,ResultCallBack resultCallBack)51 bool RpcServer::ParseData(const uint8_t* data, size_t len, ResultCallBack resultCallBack)
52 {
53     g_loadSize += len;
54     size_t blockSize = 1024 * 1024;
55     do {
56         size_t parseSize = std::min(len, blockSize);
57         std::unique_ptr<uint8_t[]> buf = std::make_unique<uint8_t[]>(parseSize);
58         std::copy(data, data + parseSize, buf.get());
59         if (!ts_->ParseTraceDataSegment(std::move(buf), parseSize)) {
60             if (resultCallBack) {
61                 resultCallBack("formaterror\r\n", SEND_FINISH);
62             }
63             return false;
64         }
65         data += parseSize;
66         len -= parseSize;
67         lenParseData_ += parseSize;
68     } while (len > 0);
69     if (resultCallBack) {
70         resultCallBack("ok\r\n", SEND_FINISH);
71     }
72     return true;
73 }
74 
UpdateTraceTime(const uint8_t * data,int32_t len)75 int32_t RpcServer::UpdateTraceTime(const uint8_t* data, int32_t len)
76 {
77     std::unique_ptr<uint8_t[]> buf = std::make_unique<uint8_t[]>(len);
78     std::copy(data, data + len, buf.get());
79     ts_->UpdateTraceRangeTime(buf.get(), len);
80     return 0;
81 }
82 
TraceStreamer_Init_ThirdParty_Config(const uint8_t * data,int32_t len)83 int32_t RpcServer::TraceStreamer_Init_ThirdParty_Config(const uint8_t* data, int32_t len)
84 {
85     TS_LOGE("TraceStreamer_Init_ThirdParty_Config is comming!");
86     std::string thirdPartyConfig = reinterpret_cast<const char*>(data);
87     TS_LOGE("thirdPartyConfig = %s", thirdPartyConfig.c_str());
88     std::vector<std::string> comPonentStr = SplitStringToVec(thirdPartyConfig, ";");
89     const int32_t EVENT_COUNT_PAIR = 2;
90     if (comPonentStr.size() % EVENT_COUNT_PAIR != 0) {
91         TS_LOGE("thirdPartyConfig is wrong!");
92         return -1;
93     }
94     for (int32_t m = 0; m < comPonentStr.size(); m += EVENT_COUNT_PAIR) {
95         int32_t componentId = std::stoi(comPonentStr.at(m));
96         std::string componentName = comPonentStr.at(m + 1);
97         TS_LOGE("comPonentStr[m] = %d, comPonentStr[m + 1] = %s", componentId, componentName.c_str());
98         g_thirdPartyConfig.insert((std::map<int32_t, std::string>::value_type(componentId, componentName)));
99     }
100     return 0;
101 }
102 
ParseDataOver(const uint8_t * data,size_t len,ResultCallBack resultCallBack)103 bool RpcServer::ParseDataOver(const uint8_t* data, size_t len, ResultCallBack resultCallBack)
104 {
105     UNUSED(data);
106     UNUSED(len);
107     MetaData* metaData = ts_->GetMetaData();
108     metaData->SetSourceFileName("input stream mode");
109     metaData->SetOutputFileName("wasm mode");
110     metaData->SetParserToolVersion(g_traceStreamerVersion);
111     metaData->SetParserToolPublishDateTime(g_traceStreamerPublishVersion);
112     metaData->SetTraceDataSize(g_loadSize);
113     metaData->SetTraceType((ts_->DataType() == TRACE_FILETYPE_H_TRACE) ? "proto-based-trace" : "txt-based-trace");
114     TS_LOGI("RPC ParseDataOver, has parsed len %zu", lenParseData_);
115 
116     ts_->WaitForParserEnd();
117 #ifndef USE_VTABLE
118     ts_->Clear();
119 #endif
120     if (resultCallBack) {
121         resultCallBack("ok\r\n", SEND_FINISH);
122     }
123     lenParseData_ = 0;
124     g_loadSize = 0;
125     return true;
126 }
127 
SqlOperate(const uint8_t * data,size_t len,ResultCallBack resultCallBack)128 bool RpcServer::SqlOperate(const uint8_t* data, size_t len, ResultCallBack resultCallBack)
129 {
130     ts_->SetCancel(false);
131     std::string sql(reinterpret_cast<const char*>(data), len);
132     TS_LOGI("RPC SqlOperate(%s, %zu)", sql.c_str(), len);
133 
134     int32_t ret = ts_->OperateDatabase(sql);
135     if (resultCallBack) {
136         std::string response = "ok\r\n";
137         if (ret != 0) {
138             response = "dberror\r\n";
139         }
140         resultCallBack(response, SEND_FINISH);
141     }
142     return (ret == 0);
143 }
144 
SqlQuery(const uint8_t * data,size_t len,ResultCallBack resultCallBack)145 bool RpcServer::SqlQuery(const uint8_t* data, size_t len, ResultCallBack resultCallBack)
146 {
147     ts_->SetCancel(false);
148     std::string sql(reinterpret_cast<const char*>(data), len);
149     TS_LOGI("RPC SqlQuery %zu:%s", len, sql.c_str());
150 
151     int32_t ret = ts_->SearchDatabase(sql, resultCallBack);
152     if (resultCallBack && ret != 0) {
153         resultCallBack("dberror\r\n", SEND_FINISH);
154     }
155     ts_->SetCancel(false);
156     return (ret == 0);
157 }
158 
CancelSqlQuery()159 void RpcServer::CancelSqlQuery()
160 {
161     ts_->SetCancel(true);
162 }
163 
Reset(const uint8_t * data,size_t len,ResultCallBack resultCallBack)164 bool RpcServer::Reset(const uint8_t* data, size_t len, ResultCallBack resultCallBack)
165 {
166     UNUSED(data);
167     UNUSED(len);
168     TS_LOGI("RPC reset trace_streamer");
169 
170     ts_->WaitForParserEnd();
171     ts_ = std::make_unique<TraceStreamerSelector>();
172     if (resultCallBack) {
173         resultCallBack("ok\r\n", SEND_FINISH);
174     }
175     return true;
176 }
177 
WasmSqlQuery(const uint8_t * data,size_t len,uint8_t * out,int32_t outLen)178 int32_t RpcServer::WasmSqlQuery(const uint8_t* data, size_t len, uint8_t* out, int32_t outLen)
179 {
180     ts_->SetCancel(false);
181     std::string sql(reinterpret_cast<const char*>(data), len);
182     TS_LOGI("WASM RPC SqlQuery outlen(%d) sql(%zu:%s)", outLen, len, sql.c_str());
183 
184     int32_t ret = ts_->SearchDatabase(sql, out, outLen);
185     return ret;
186 }
WasmSqlQueryWithCallback(const uint8_t * data,size_t len,ResultCallBack callback) const187 int32_t RpcServer::WasmSqlQueryWithCallback(const uint8_t* data, size_t len, ResultCallBack callback) const
188 {
189     ts_->SetCancel(false);
190     std::string sql(reinterpret_cast<const char*>(data), len);
191     TS_LOGI("WASM RPC SqlQuery sql(%zu:%s)", len, sql.c_str());
192 
193     int32_t ret = ts_->SearchDatabase(sql, callback);
194     return ret;
195 }
196 
WasmExportDatabase(ResultCallBack resultCallBack)197 int32_t RpcServer::WasmExportDatabase(ResultCallBack resultCallBack)
198 {
199     return ts_->ExportDatabase("default.db", resultCallBack);
200 }
201 
202 #if IS_WASM
DownloadELFCallback(const std::string & fileName,size_t totalLen,const uint8_t * data,size_t len,int32_t finish,ParseELFFileCallBack parseELFFile)203 int32_t RpcServer::DownloadELFCallback(const std::string& fileName,
204                                        size_t totalLen,
205                                        const uint8_t* data,
206                                        size_t len,
207                                        int32_t finish,
208                                        ParseELFFileCallBack parseELFFile)
209 {
210     g_fileLen += len;
211     std::string filePath = "";
212     TS_LOGI("fileName = %s", fileName.c_str());
213     std::string symbolsPath = fileName.substr(0, fileName.find("/"));
214     TS_LOGI("symbolsPath = %s", symbolsPath.c_str());
215     filePath = fileName.substr(0, fileName.find_last_of("/"));
216     if (std::filesystem::exists(filePath)) {
217         TS_LOGE("%s exist", filePath.c_str());
218     } else {
219         if (std::filesystem::create_directories(filePath)) {
220             TS_LOGI("create_directories success");
221         } else {
222             TS_LOGI("create_directories failed!");
223         }
224     }
225     TS_LOGI("filePath = %s", filePath.c_str());
226     if (g_fileLen < totalLen) {
227         if (g_importFileFd == nullptr) {
228             g_importFileFd = fopen(fileName.c_str(), "a+");
229             if (g_importFileFd == nullptr) {
230                 TS_LOGE("wasm file create failed");
231                 return false;
232             }
233         }
234         int32_t writeLength = fwrite(data, len, 1, g_importFileFd);
235         if (!writeLength) {
236             fclose(g_importFileFd);
237             TS_LOGE("wasm write file failed");
238             return false;
239         }
240         return false;
241     }
242     g_fileLen = 0;
243     if (g_importFileFd == nullptr) {
244         g_importFileFd = fopen(fileName.c_str(), "a+");
245         if (g_importFileFd == nullptr) {
246             TS_LOGE("wasm file create failed");
247             return false;
248         }
249     }
250     int32_t writeLength = fwrite(data, len, 1, g_importFileFd);
251     (void)fclose(g_importFileFd);
252     g_importFileFd = nullptr;
253     if (!writeLength) {
254         TS_LOGE("wasm write file failed");
255         return false;
256     }
257     TS_LOGI("symbolsPath = %s, fileName = %s", symbolsPath.c_str(), fileName.c_str());
258     symbolsPathFiles_.emplace_back(fileName);
259     parseELFFile("file send over\r\n", SEND_FINISH);
260 
261     if (finish) {
262         if (!ts_->ReloadSymbolFiles(symbolsPath, symbolsPathFiles_)) {
263             symbolsPathFiles_.clear();
264             if (parseELFFile) {
265                 parseELFFile("formaterror\r\n", SEND_FINISH);
266             }
267             return false;
268         }
269         symbolsPathFiles_.clear();
270         if (parseELFFile) {
271             parseELFFile("ok\r\n", SEND_FINISH);
272         }
273         std::filesystem::remove_all(symbolsPath);
274     }
275     return true;
276 }
277 #endif
278 
ParserConfig(std::string parserConfigJson)279 bool RpcServer::ParserConfig(std::string parserConfigJson)
280 {
281     json jMessage = json::parse(parserConfigJson);
282     jsonns::ParserConfig parserConfig = jMessage.at("config");
283     ts_->UpdateAppStartTraceStatus(parserConfig.appConfigValue);
284     ts_->UpdateAnimationTraceStatus(parserConfig.aniConfigValue);
285     ts_->UpdateTaskPoolTraceStatus(parserConfig.taskConfigValue);
286     return true;
287 }
288 } // namespace TraceStreamer
289 } // namespace SysTuning
290