1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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 "wasm_func.h"
17
18 #ifndef NAME_MAX
19 #define NAME_MAX 255
20 #endif
21 namespace SysTuning {
22 namespace TraceStreamer {
23 RpcServer g_wasmTraceStreamer;
24 extern "C" {
25 using ReplyFunction = void (*)(const char *data, uint32_t len, int32_t finish);
26 using TLVReplyFunction = void (*)(const char *data, uint32_t len, uint32_t type, int32_t finish);
27 ReplyFunction g_reply;
28 ReplyFunction g_ffrtConvertedReply;
29 TLVReplyFunction g_replyTLV;
30 uint8_t *g_reqBuf;
31 uint32_t g_reqBufferSize;
32
33 using SplitFileFunction = void (*)(const char *data, uint32_t len, int32_t dataType, int32_t isFinish);
34 SplitFileFunction g_splitFile;
35 uint8_t *g_splitFileBuf;
36 uint32_t g_splitFileBufferSize;
37
38 uint8_t *g_parserConfigBuf;
39 uint32_t g_parserConfigSize;
40
41 using SendDataCallBack = void (*)(const char *data, int32_t len, int32_t componentId);
42 SendDataCallBack g_sendData = nullptr;
43 uint8_t *g_sendDataBuf;
44 uint32_t g_sendDataBufSize;
45
46 using ExportDBCallback = void (*)(const char *data, uint32_t len, int32_t finish);
47 ExportDBCallback g_dbCallback;
48
49 using ParseELFFunction = void (*)(const char *data, uint32_t len, int32_t finish);
50 ParseELFFunction g_parseELFCallback;
51 uint8_t *g_fileNameBuf;
52 uint32_t g_fileNameSize;
53 bool g_isSystrace = false;
54 bool g_isZipTrace = false;
55 bool g_isZlibTrace = false;
56 bool g_hasDeterminedSystrace = false;
57
ResultCallback(const std::string & jsonResult,int32_t finish)58 void ResultCallback(const std::string &jsonResult, int32_t finish)
59 {
60 g_reply(jsonResult.data(), jsonResult.size(), finish);
61 }
TLVResultCallback(const char * data,uint32_t len,uint32_t type,int32_t finish)62 void TLVResultCallback(const char *data, uint32_t len, uint32_t type, int32_t finish)
63 {
64 g_replyTLV(data, len, type, finish);
65 }
FfrtConvertedResultCallback(const std::string & content,int32_t finish)66 void FfrtConvertedResultCallback(const std::string &content, int32_t finish)
67 {
68 g_ffrtConvertedReply(content.data(), content.size(), finish);
69 }
SplitFileCallback(const std::string & jsonResult,int32_t dataType,int32_t finish)70 void SplitFileCallback(const std::string &jsonResult, int32_t dataType, int32_t finish)
71 {
72 g_splitFile(jsonResult.data(), jsonResult.size(), dataType, finish);
73 }
74
ParseELFCallback(const std::string & soDataResult,int32_t finish)75 void ParseELFCallback(const std::string &soDataResult, int32_t finish)
76 {
77 g_parseELFCallback(soDataResult.data(), soDataResult.size(), finish);
78 }
Initialize(uint32_t reqBufferSize,ReplyFunction replyFunction,TLVReplyFunction replyTLVFunction,ReplyFunction ffrtConvertedReply)79 EMSCRIPTEN_KEEPALIVE uint8_t *Initialize(uint32_t reqBufferSize,
80 ReplyFunction replyFunction,
81 TLVReplyFunction replyTLVFunction,
82 ReplyFunction ffrtConvertedReply)
83 {
84 if (g_reqBuf != nullptr) {
85 delete[] g_reqBuf;
86 }
87 g_reqBuf = new uint8_t[reqBufferSize];
88 g_reqBufferSize = reqBufferSize;
89 g_reply = replyFunction;
90 g_replyTLV = replyTLVFunction;
91 g_ffrtConvertedReply = ffrtConvertedReply;
92 return g_reqBuf;
93 }
94
InitializeSplitFile(SplitFileFunction splitFileFunction,uint32_t reqBufferSize)95 EMSCRIPTEN_KEEPALIVE uint8_t *InitializeSplitFile(SplitFileFunction splitFileFunction, uint32_t reqBufferSize)
96 {
97 if (g_splitFileBuf != nullptr) {
98 delete[] g_splitFileBuf;
99 }
100 g_splitFile = splitFileFunction;
101 g_splitFileBuf = new uint8_t[reqBufferSize];
102 g_splitFileBufferSize = reqBufferSize;
103 return g_splitFileBuf;
104 }
105
TraceStreamerSplitFileEx(int dataLen)106 EMSCRIPTEN_KEEPALIVE int TraceStreamerSplitFileEx(int dataLen)
107 {
108 std::string timeSnaps(reinterpret_cast<const char *>(g_splitFileBuf), dataLen);
109 if (g_wasmTraceStreamer.SplitFile(timeSnaps)) {
110 return 0;
111 }
112 return -1;
113 }
114
TraceStreamerReciveFileEx(int32_t dataLen,int32_t isFinish)115 EMSCRIPTEN_KEEPALIVE int TraceStreamerReciveFileEx(int32_t dataLen, int32_t isFinish)
116 {
117 if (g_wasmTraceStreamer.ParseSplitFileData(g_splitFileBuf, dataLen, isFinish, &SplitFileCallback, true)) {
118 return 0;
119 }
120 return -1;
121 }
122
InitializeParseConfig(uint32_t reqBufferSize)123 EMSCRIPTEN_KEEPALIVE uint8_t *InitializeParseConfig(uint32_t reqBufferSize)
124 {
125 if (g_parserConfigBuf != nullptr) {
126 delete[] g_parserConfigBuf;
127 }
128 g_parserConfigBuf = new uint8_t[reqBufferSize];
129 g_parserConfigSize = reqBufferSize;
130 return g_parserConfigBuf;
131 }
132
TraceStreamerParserConfigEx(int dataLen)133 EMSCRIPTEN_KEEPALIVE int TraceStreamerParserConfigEx(int dataLen)
134 {
135 std::string parserConfig(reinterpret_cast<const char *>(g_parserConfigBuf), dataLen);
136 if (g_wasmTraceStreamer.ParserConfig(parserConfig)) {
137 return 0;
138 }
139 return -1;
140 }
TraceStreamerGetLongTraceTimeSnapEx(int dataLen)141 EMSCRIPTEN_KEEPALIVE int TraceStreamerGetLongTraceTimeSnapEx(int dataLen)
142 {
143 std::string dataString(reinterpret_cast<const char *>(g_splitFileBuf), dataLen);
144 if (g_wasmTraceStreamer.GetLongTraceTimeSnap(dataString)) {
145 return 0;
146 }
147 return -1;
148 }
149
TraceStreamerLongTraceSplitFileEx(int dataLen,int32_t isFinish,uint32_t pageNum)150 EMSCRIPTEN_KEEPALIVE int TraceStreamerLongTraceSplitFileEx(int dataLen, int32_t isFinish, uint32_t pageNum)
151 {
152 if (g_wasmTraceStreamer.LongTraceSplitFile(g_splitFileBuf, dataLen, isFinish, pageNum, &SplitFileCallback)) {
153 return 0;
154 }
155 return -1;
156 }
157
InitFileName(ParseELFFunction parseELFCallback,uint32_t reqBufferSize)158 EMSCRIPTEN_KEEPALIVE uint8_t *InitFileName(ParseELFFunction parseELFCallback, uint32_t reqBufferSize)
159 {
160 if (g_fileNameBuf != nullptr) {
161 delete[] g_fileNameBuf;
162 }
163 g_parseELFCallback = parseELFCallback;
164 if (reqBufferSize > NAME_MAX) {
165 return nullptr;
166 }
167 g_fileNameBuf = new uint8_t[reqBufferSize];
168 if (!g_fileNameBuf) {
169 return nullptr;
170 }
171 g_fileNameSize = reqBufferSize;
172 return g_fileNameBuf;
173 }
174
UpdateTraceTime(int32_t len)175 EMSCRIPTEN_KEEPALIVE int32_t UpdateTraceTime(int32_t len)
176 {
177 return g_wasmTraceStreamer.UpdateTraceTime(g_reqBuf, len);
178 }
179
ThirdParySendDataCallback(const char * pluginData,int32_t len,int32_t componentId)180 void ThirdParySendDataCallback(const char *pluginData, int32_t len, int32_t componentId)
181 {
182 if (g_sendData) {
183 g_sendData(pluginData, len, componentId);
184 }
185 }
186
TraceStreamerSetThirdPartyDataDealer(SendDataCallBack sendDataCallBack,uint32_t reqBufferSize)187 EMSCRIPTEN_KEEPALIVE uint8_t *TraceStreamerSetThirdPartyDataDealer(SendDataCallBack sendDataCallBack,
188 uint32_t reqBufferSize)
189 {
190 if (g_sendDataBuf != nullptr) {
191 delete[] g_sendDataBuf;
192 }
193 g_sendData = sendDataCallBack;
194 g_sendDataBuf = new uint8_t[reqBufferSize];
195 g_sendDataBufSize = reqBufferSize;
196 return g_sendDataBuf;
197 }
198
TraceStreamerSetLogLevel(uint32_t level)199 EMSCRIPTEN_KEEPALIVE void TraceStreamerSetLogLevel(uint32_t level)
200 {
201 if (level >= LOG_DEBUG && level <= LOG_OFF) {
202 g_curLogLevel = static_cast<enum LogLevel>(level);
203 }
204 }
205
TraceStreamerPluginOutFilter(const char * pluginData,int32_t len,const std::string & componentName)206 int32_t TraceStreamerPluginOutFilter(const char *pluginData, int32_t len, const std::string &componentName)
207 {
208 std::map<int32_t, std::string>::iterator itor = g_wasmTraceStreamer.g_thirdPartyConfig.begin();
209 int32_t componentId;
210 for (; itor != g_wasmTraceStreamer.g_thirdPartyConfig.end(); ++itor) {
211 if (itor->second == componentName) {
212 componentId = itor->first;
213 return TraceStreamerPluginOutSendData(pluginData, len, componentId);
214 }
215 }
216 return -1;
217 }
218
219 // Tell js to call the corresponding third-party parser interface according to the compositeId
TraceStreamerPluginOutSendData(const char * pluginData,int32_t len,int32_t componentId)220 int32_t TraceStreamerPluginOutSendData(const char *pluginData, int32_t len, int32_t componentId)
221 {
222 ThirdParySendDataCallback(pluginData, len, componentId);
223 return 0;
224 }
225
TraceStreamerInitThirdPartyConfig(int32_t dataLen)226 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerInitThirdPartyConfig(int32_t dataLen)
227 {
228 return g_wasmTraceStreamer.TraceStreamerInitThirdPartyConfig(g_reqBuf, dataLen);
229 }
230
231 // return 0 while ok, -1 while failed
TraceStreamerParseData(const uint8_t * data,int32_t dataLen)232 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerParseData(const uint8_t *data, int32_t dataLen)
233 {
234 if (g_wasmTraceStreamer.ParseData(data, dataLen, nullptr, false)) {
235 return 0;
236 }
237 return -1;
238 }
239 // return 0 while ok, -1 while failed
TraceStreamerParseDataEx(int32_t dataLen,bool isFinish)240 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerParseDataEx(int32_t dataLen, bool isFinish)
241 {
242 if (!g_hasDeterminedSystrace) {
243 g_isSystrace = g_wasmTraceStreamer.DetermineSystrace(g_reqBuf, dataLen);
244 g_isZipTrace = g_wasmTraceStreamer.DetermineZipTrace(g_reqBuf, dataLen);
245 #if IS_WASM
246 g_isZlibTrace = g_wasmTraceStreamer.DetermineZlibTrace(g_reqBuf, dataLen);
247 #endif
248 g_hasDeterminedSystrace = true;
249 }
250 if (g_wasmTraceStreamer.GetFfrtConvertStatus() && g_isSystrace) {
251 #if IS_WASM
252 return g_wasmTraceStreamer.SaveAndParseFfrtData(g_reqBuf, dataLen, &FfrtConvertedResultCallback, isFinish);
253 #endif
254 } else if (g_isZipTrace) {
255 #if IS_WASM
256 return g_wasmTraceStreamer.SaveAndParseZipTraceData(g_reqBuf, dataLen, nullptr, isFinish) ? 0 : -1;
257 #endif
258 } else if (g_isZlibTrace) {
259 #if IS_WASM
260 return g_wasmTraceStreamer.SaveAndParseZlibTraceData(g_reqBuf, dataLen, nullptr, isFinish) ? 0 : -1;
261 #endif
262 } else if (g_wasmTraceStreamer.ParseData(g_reqBuf, dataLen, nullptr, isFinish)) {
263 return 0;
264 }
265 return -1;
266 }
TraceStreamerDownloadELFEx(int32_t totalLen,int32_t fileNameLen,int32_t dataLen,int32_t finish)267 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerDownloadELFEx(int32_t totalLen,
268 int32_t fileNameLen,
269 int32_t dataLen,
270 int32_t finish)
271 {
272 std::string filePath(reinterpret_cast<const char *>(g_fileNameBuf), fileNameLen);
273 #if IS_WASM
274 if (g_wasmTraceStreamer.DownloadELFCallback(filePath, totalLen, g_reqBuf, dataLen, finish, &ParseELFCallback)) {
275 return 0;
276 }
277 #endif
278 return -1;
279 }
TraceStreamerParseDataOver()280 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerParseDataOver()
281 {
282 if (g_wasmTraceStreamer.ParseDataOver(nullptr, 0, nullptr)) {
283 return 0;
284 }
285 return -1;
286 }
TraceStreamerSqlOperateEx(int32_t sqlLen)287 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerSqlOperateEx(int32_t sqlLen)
288 {
289 if (g_wasmTraceStreamer.SqlOperate(g_reqBuf, sqlLen, nullptr)) {
290 return 0;
291 }
292 return -1;
293 }
TraceStreamerReset()294 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerReset()
295 {
296 g_wasmTraceStreamer.Reset(nullptr, 0, nullptr);
297 return 0;
298 }
299 // return the length of result, -1 while failed
TraceStreamerSqlQuery(const uint8_t * sql,int32_t sqlLen,uint8_t * out,int32_t outLen)300 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerSqlQuery(const uint8_t *sql, int32_t sqlLen, uint8_t *out, int32_t outLen)
301 {
302 return g_wasmTraceStreamer.WasmSqlQuery(sql, sqlLen, out, outLen);
303 }
304 // return the length of result, -1 while failed
TraceStreamerSqlQueryEx(int32_t sqlLen)305 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerSqlQueryEx(int32_t sqlLen)
306 {
307 return g_wasmTraceStreamer.WasmSqlQueryWithCallback(g_reqBuf, sqlLen, &ResultCallback);
308 }
TraceStreamerSqlQueryToProtoCallback(int32_t sqlLen)309 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerSqlQueryToProtoCallback(int32_t sqlLen)
310 {
311 return g_wasmTraceStreamer.WasmSqlQueryToProtoCallback(g_reqBuf, sqlLen, &TLVResultCallback);
312 }
TraceStreamerSqlMetricsQuery(int32_t sqlLen)313 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerSqlMetricsQuery(int32_t sqlLen)
314 {
315 if (g_wasmTraceStreamer.SqlMetricsQueryWithCallback(g_reqBuf, sqlLen, &ResultCallback)) {
316 return 0;
317 }
318 return -1;
319 }
TraceStreamerCancel()320 EMSCRIPTEN_KEEPALIVE int32_t TraceStreamerCancel()
321 {
322 g_wasmTraceStreamer.CancelSqlQuery();
323 return 0;
324 }
325
ExportDatabaseCallback(const std::string & jsonResult,int32_t finish)326 void ExportDatabaseCallback(const std::string &jsonResult, int32_t finish)
327 {
328 g_dbCallback(jsonResult.data(), jsonResult.size(), finish);
329 }
330
WasmExportDatabase(ExportDBCallback fun)331 EMSCRIPTEN_KEEPALIVE int32_t WasmExportDatabase(ExportDBCallback fun)
332 {
333 g_dbCallback = fun;
334 return g_wasmTraceStreamer.WasmExportDatabase(&ExportDatabaseCallback);
335 }
336 } // extern "C"
337 } // namespace TraceStreamer
338 } // namespace SysTuning
339