• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (C) 2021 Huawei Device Co., Ltd.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <netinet/in.h>
17 #include <sys/socket.h>
18 #include <arpa/inet.h>
19 #include <unistd.h>
20 #include <iostream>
21 #include <functional>
22 #include <vector>
23 #include <thread>
24 #include <future>
25 #include <map>
26 #include <mutex>
27 #include <climits>
28 #include "parameters.h"
29 #include "include/sp_csv_util.h"
30 #include "include/sdk_data_recv.h"
31 #include "include/GpuCounter.h"
32 #include "include/lock_frequency.h"
33 #include "include/sp_thread_socket.h"
34 #include "include/sp_profiler_factory.h"
35 #include "include/sp_log.h"
36 #include "include/sp_task.h"
37 #include "include/heartbeat.h"
38 #include "include/control_call_cmd.h"
39 #include "include/sp_profiler_factory.h"
40 #include "include/Network.h"
41 #include "include/startup_delay.h"
42 #include "include/Dubai.h"
43 #include "include/GameEvent.h"
44 #include "include/GetLog.h"
45 #include "include/RAM.h"
46 #include "include/FPS.h"
47 #include "include/hiperf.h"
48 
49 #define SMARTPERF "smartperf"
50 namespace OHOS {
51 namespace SmartPerf {
52 std::string g_pkgName = "";
53 std::string g_pkgAndPid = "";
MapToString(std::map<std::string,std::string> & dataMap) const54 std::string SpThreadSocket::MapToString(std::map<std::string, std::string>& dataMap) const
55 {
56     std::string result;
57     int i = 0;
58     std::string splitStr = "";
59     for (auto iter = dataMap.cbegin(); iter != dataMap.cend(); ++iter) {
60         printf("%s = %s\n", iter->first.c_str(), iter->second.c_str());
61         if (i > 0) {
62             splitStr = "$$";
63         }
64         result += splitStr + iter->first.c_str() + "||" + iter->second.c_str();
65         i++;
66     }
67     return result;
68 }
SplitMsg(const std::string & recvBuf) const69 std::string SpThreadSocket::SplitMsg(const std::string &recvBuf) const
70 {
71     if (recvBuf.empty()) {
72         LOGE("SplitMsg recvBuf is null");
73         return recvBuf;
74     }
75     size_t pos = recvBuf.find("::");
76     if (pos != std::string::npos) {
77         std::vector<std::string> sps;
78         SPUtils::StrSplit(recvBuf, "::", sps);
79         if (sps.size() > 1) {
80             return sps[1];
81         } else {
82             LOGE("SplitMsg sps size is zreo");
83             return recvBuf;
84         }
85     } else {
86         return recvBuf;
87     }
88 }
89 
Process(ProtoType type)90 void SpThreadSocket::Process(ProtoType type)
91 {
92     std::cout << "Socket Process called!" << std::endl;
93     SpServerSocket spSocket;
94     spSocket.Init(type);
95     if (type == ProtoType::TCP) {
96         std::cout << "Socket TCP Init called!" << std::endl;
97         WLOGI("Socket TCP Init called!");
98         TypeTcp(spSocket);
99     }
100     if (type == ProtoType::UDP || type == ProtoType::UDPEX) {
101         SocketHeartbeat();
102         while (socketConnect == true) {
103             spSocket.Recvfrom();
104             HandleMsg(spSocket);
105         }
106     }
107     std::cout << "Socket Process finished!" << std::endl;
108     spSocket.Close();
109 }
CheckTcpToken(const std::string & recvStr,SpServerSocket & spSocket,const std::string & recvStrNoToken) const110 SocketErrorType SpThreadSocket::CheckTcpToken(const std::string& recvStr,
111     SpServerSocket &spSocket, const std::string& recvStrNoToken) const
112 {
113     if (recvStr.find_last_of(":") == std::string::npos) {
114         if (recvStr.find("SP_daemon -editor") != std::string::npos) {
115             LOGI("Received string contains 'SP_daemon -editor', token check passed.");
116             return SocketErrorType::OK;
117         } else {
118             LOGE("Token check failed: %s", recvStrNoToken.c_str());
119             return SocketErrorType::TOKEN_CHECK_FAILED;
120         }
121     }
122     std::string token = recvStr.substr(recvStr.find_last_of(":") + 1);
123     token = token.substr(0, token.find(' '));
124     std::string tcpSocketToken = SpThreadSocket::GetInstance().GetToken();
125     LOGD("Comparing token with TCP token...");
126     if (tcpSocketToken == "" && token == "-SESSIONID") {
127         LOGI("Token is empty but received token is '-SESSIONID', token check passed.");
128         return SocketErrorType::OK;
129     }
130     if (token != tcpSocketToken) {
131         LOGE("Token mismatch.");
132         return SocketErrorType::TOKEN_CHECK_FAILED;
133     }
134     LOGD("Token match");
135     return SocketErrorType::OK;
136 }
TypeTcp(SpServerSocket & spSocket)137 void SpThreadSocket::TypeTcp(SpServerSocket &spSocket)
138 {
139     SocketHeartbeat();
140     WLOGI("Socket TCP Init Finished, Wait Client Socket Connect...");
141     while (socketConnect == true) {
142         int procFd = spSocket.Accept();
143         std::cout << "Socket TCP procFd: " << procFd << std::endl;
144         WLOGI("Accepted socket connection, procFd: %d", procFd);
145         while (procFd > 0) {
146             int reFd = spSocket.Recv();
147             if (reFd < 0) {
148                 WLOGE("Error receiving data, reFd: %d", reFd);
149                 break;
150             }
151             std::string recvStr = spSocket.RecvBuf();
152             std::string recvStrNoToken = recvStr.substr(0, recvStr.find("::"));
153             LOGD("TCP recv data:%s", recvStr.c_str());
154             WLOGD("Received data: %s", recvStrNoToken.c_str());
155             // 解析消息 分发处理
156             const SocketErrorType tokenStatus = CheckTcpToken(recvStr, spSocket, recvStrNoToken);
157             WLOGI("Token check status: %d", tokenStatus);
158             DealMsg(recvStr, spSocket, tokenStatus);
159         }
160     }
161 }
162 // TCP
InitRecv(const std::string & recvStr,SpServerSocket & spSocket,SocketConnectType type) const163 void SpThreadSocket::InitRecv(const std::string& recvStr, SpServerSocket &spSocket, SocketConnectType type) const
164 {
165     std::string errorInfo;
166     std::string checkStr = recvStr.substr(std::string("init::").length());
167     if (!SPTask::GetInstance().CheckTcpParam(checkStr, errorInfo) &&
168         checkStr.find(SpThreadSocket::GetInstance().GetToken()) == std::string::npos) {
169         WLOGE("Init error(%s)", errorInfo.c_str());
170         if (type == SocketConnectType::CMD_SOCKET) {
171             spSocket.Send("init::False,\"error\":" + errorInfo);
172         } else {
173             spSocket.Send(std::string("init::") + SocketErrorTypeToString(SocketErrorType::INIT_FAILED));
174         }
175         return;
176     }
177     if (recvStr.find("-lockfreq") != std::string::npos && SpThreadSocket::GetInstance().GetToken() == "") {
178         WLOGE("'-lockfreq' must have a valid token.");
179         return;
180     }
181     ErrCode code = SPTask::GetInstance().InitTask(SplitMsg(recvStr));
182     if (type == SocketConnectType::CMD_SOCKET) {
183         spSocket.Send(std::string("init::") + ((code == ErrCode::OK) ? "True" : "False"));
184         WLOGI("Sent init::"  + ((code == ErrCode::OK) ? "True" : "False"));
185         return;
186     }
187     if (code == ErrCode::OK) {
188         spSocket.Send("init::True");
189         WLOGI("Sent init::True response");
190     } else {
191         spSocket.Send(std::string("init::") + SocketErrorTypeToString(SocketErrorType::INIT_FAILED));
192         WLOGE("Sent init::%d for failure", SocketErrorType::INIT_FAILED);
193     }
194 }
StartRecv(SpServerSocket & spSocket)195 void SpThreadSocket::StartRecv(SpServerSocket &spSocket)
196 {
197     if (flagRunning) {
198         spSocket.Send("SP_daemon is running");
199         return;
200     }
201     auto lambdaTask = [](const std::string &data) {
202         std::cout << data << std::endl;
203     };
204     ErrCode code = SPTask::GetInstance().StartTask(lambdaTask);
205     if (code == ErrCode::OK) {
206         spSocket.Send("start::True");
207         flagRunning = true;
208         WLOGI("Sent start::True message to socket.");
209     } else if (code == ErrCode::FAILED) {
210         spSocket.Send("start::False");
211         WLOGE("Sent start::False message to socket.");
212         return;
213     }
214     SPTask::GetInstance().StartRecord();
215 }
StartRecvRealtime(SpServerSocket & spSocket) const216 void SpThreadSocket::StartRecvRealtime(SpServerSocket &spSocket) const
217 {
218     auto lambdaTask = [&spSocket](const std::string &data) { spSocket.Send(data); };
219     ErrCode code = SPTask::GetInstance().StartTask(lambdaTask);
220     if (code == ErrCode::OK) {
221         spSocket.Send("start::True");
222         WLOGI("Sent start::True message to socket.");
223     } else if (code == ErrCode::FAILED) {
224         spSocket.Send(std::string("start::") + SocketErrorTypeToString(SocketErrorType::START_FAILED));
225         WLOGE("Sent start::" + SocketErrorTypeToString(SocketErrorType::START_FAILED) + " message to socket.");
226     }
227 }
StopRecvRealtime(SpServerSocket & spSocket)228 void SpThreadSocket::StopRecvRealtime(SpServerSocket &spSocket)
229 {
230     ErrCode code = SPTask::GetInstance().StopTask();
231     if (code == ErrCode::OK) {
232         spSocket.Send("stop::True");
233         WLOGI("Sent stop::True message to socket.");
234         flagRunning = false;
235         spSocket.Close();
236     } else if (code == ErrCode::FAILED) {
237         spSocket.Send(std::string("stop::") + SocketErrorTypeToString(SocketErrorType::STOP_FAILED));
238         WLOGE("Sent stop::" + SocketErrorTypeToString(SocketErrorType::STOP_FAILED) + " message to socket.");
239     }
240 }
StartRecvRecord(SpServerSocket & spSocket) const241 void SpThreadSocket::StartRecvRecord(SpServerSocket &spSocket) const
242 {
243     ErrCode code = SPTask::GetInstance().StartRecord();
244     if (code == ErrCode::OK) {
245         spSocket.Send("startRecord::True");
246         WLOGI("Sent startRecord::True message to socket.");
247     } else {
248         spSocket.Send(std::string("startRecord::") + SocketErrorTypeToString(SocketErrorType::START_RECORD_FAILED));
249         WLOGE("Sent startRecord::" + SocketErrorTypeToString(SocketErrorType::START_RECORD_FAILED) +
250         " message to socket.");
251     }
252 }
StopRecvRecord(SpServerSocket & spSocket) const253 void SpThreadSocket::StopRecvRecord(SpServerSocket &spSocket) const
254 {
255     ErrCode code = SPTask::GetInstance().StopRecord();
256     if (code == ErrCode::OK) {
257         spSocket.Send("stopRecord::True");
258         WLOGI("Sent stopRecord::True message to socket.");
259     } else {
260         spSocket.Send(std::string("stopRecord::") + SocketErrorTypeToString(SocketErrorType::STOP_RECORD_FAILED));
261         WLOGE("Sent stopRecord::" + SocketErrorTypeToString(SocketErrorType::STOP_RECORD_FAILED) +
262         " message to socket.");
263     }
264 }
SendTokenFailedMessage(SpServerSocket & socket,const std::string & message) const265 void SpThreadSocket::SendTokenFailedMessage(SpServerSocket &socket, const std::string &message) const
266 {
267     if (message.find("init:::") != std::string::npos ||
268         message.find("start:::") != std::string::npos) {
269         WLOGI("Skipping token check failure for init::: or start::: command.");
270         return;
271     }
272     const std::vector<std::string> messageType = {
273         "init::",
274         "start::",
275         "stop::",
276         "startRecord::",
277         "stopRecord::",
278     };
279     for (auto& it : messageType) {
280         if (message.find(it) != std::string::npos) {
281             WLOGE("Sending token check failed message for command: %s", it.c_str());
282             socket.Send(it + SocketErrorTypeToString(SocketErrorType::TOKEN_CHECK_FAILED));
283             return;
284         }
285     }
286     WLOGW("No matching command found for token check failure in message: %s", message.c_str());
287 }
CheckUdpToken(const std::string & recvStr) const288 SocketErrorType SpThreadSocket::CheckUdpToken(const std::string& recvStr) const
289 {
290     // 不需要校验 token
291     if (isNeedUdpToken == false) {
292         return SocketErrorType::OK;
293     }
294     // device 启动时发送,不做校验
295     if (recvStr == "get_daemon_version" || recvStr.find("set_pkgName::") != std::string::npos) {
296         return SocketErrorType::OK;
297     }
298     // command:::token
299     if (recvStr.find_last_of(":::") == std::string::npos) {
300         WLOGE("Token check failed: %s", recvStr.c_str());
301         return SocketErrorType::TOKEN_CHECK_FAILED;
302     }
303     // 提取 token
304     std::string token = recvStr.substr(recvStr.find_last_of(":::") + 1);
305     token = token.substr(0, token.find(' '));
306 
307     std::string udpSocketToken = SpThreadSocket::GetInstance().GetToken();
308     LOGD("Comparing token with Udp token...");
309     // token 校验
310     if (token != udpSocketToken) {
311         WLOGE("Token mismatch.");
312         return SocketErrorType::TOKEN_CHECK_FAILED;
313     }
314     LOGD("UDP token check passed");
315     return SocketErrorType::OK;
316 }
DealMsg(const std::string & recvStr,SpServerSocket & spSocket,SocketErrorType tokenStatus)317 void SpThreadSocket::DealMsg(const std::string& recvStr, SpServerSocket &spSocket, SocketErrorType tokenStatus)
318 {
319     SocketHeartbeat();
320     if (tokenStatus == SocketErrorType::TOKEN_CHECK_FAILED) {
321         SendTokenFailedMessage(spSocket, recvStr);
322         return;
323     }
324     if (recvStr.find("init:::") != std::string::npos) {
325         WLOGI("Processing 'init:::' command.");
326         InitRecv(recvStr, spSocket, SocketConnectType::CMD_SOCKET);
327         FPS::GetInstance().isNeedDump = true;
328     } else if (recvStr.find("start:::") != std::string::npos) {
329         WLOGI("Processing 'start:::' command.");
330         StartRecv(spSocket);
331     } else if (recvStr.find("init::") != std::string::npos) {
332         WLOGI("Processing 'init::' command.");
333         InitRecv(recvStr, spSocket, SocketConnectType::EDITOR_SOCKET);
334     } else if (recvStr.find("start::") != std::string::npos) {
335         WLOGI("Processing 'start::' command.");
336         StartRecvRealtime(spSocket);
337     } else if (recvStr.find("stop::") != std::string::npos) {
338         WLOGI("Processing 'stop::' command.");
339         SpProfilerFactory::editorFlag = false;
340         StopRecvRealtime(spSocket);
341     } else if (recvStr.find("startRecord::") != std::string::npos) {
342         WLOGI("Processing 'startRecord::' command.");
343         StartRecvRecord(spSocket);
344     } else if (recvStr.find("stopRecord::") != std::string::npos) {
345         WLOGI("Processing 'stopRecord::' command.");
346         SpProfilerFactory::editorFlag = false;
347         StopRecvRecord(spSocket);
348     } else if (recvStr.find("SP_daemon -editor") != std::string::npos) {
349         EditorRecv(recvStr, spSocket);
350     } else {
351         WLOGW("Received unknown command: %s", recvStr.c_str());
352     }
353 }
EditorRecv(const std::string & recvStr,const SpServerSocket & spSocket) const354 void SpThreadSocket::EditorRecv(const std::string& recvStr, const SpServerSocket &spSocket) const
355 {
356     std::vector<std::string> vec;
357     size_t size = recvStr.size();
358     size_t j = 0;
359     for (size_t i = 0; i < size; i++) {
360         if (recvStr[i] == ' ') {
361             vec.push_back(recvStr.substr(j, i - j));
362             j = i + 1;
363         }
364     }
365     vec.push_back(recvStr.substr(j, size - j));
366     const int type = 2;
367     if (vec[type] == "findAppPage") {
368         BackDesktop();
369     }
370     OHOS::SmartPerf::ControlCallCmd controlCallCmd;
371     std::string result = controlCallCmd.GetResult(vec);
372     spSocket.Send(result);
373 }
BackDesktop() const374 void SpThreadSocket::BackDesktop() const
375 {
376     std::string cmdResult;
377     std::string uinput = CMD_COMMAND_MAP.at(CmdCommand::UINPUT_BACK);
378     SPUtils::LoadCmd(uinput, cmdResult);
379 }
380 // UDP
RemoveToken(std::string & recvMessage)381 void SpThreadSocket::RemoveToken(std::string &recvMessage)
382 {
383     if (recvMessage.find(":::") != std::string::npos) {
384         recvMessage = recvMessage.substr(0, recvMessage.find(":::"));
385     }
386 }
387 
HandleMsg(SpServerSocket & spSocket)388 void SpThreadSocket::HandleMsg(SpServerSocket &spSocket)
389 {
390     std::string retCode = "";
391     auto iterator = MESSAGE_MAP.begin();
392     while (iterator != MESSAGE_MAP.end()) {
393         std::string recvBuf = spSocket.RecvBuf();
394         HeartbeatDetection(recvBuf);
395         const SocketErrorType tokenStatus = CheckUdpToken(recvBuf);
396         if (tokenStatus == SocketErrorType::TOKEN_CHECK_FAILED) {
397             std::string failStr = std::string("token failed");
398             spSocket.Sendto(failStr);
399             spSocket.Close();
400             return;
401         }
402         RemoveToken(recvBuf);
403         if (recvBuf.find("init::") != std::string::npos && firstFlag) {
404             HandleMsgTrace(recvBuf);
405             UdpStartInitFunc(recvBuf, spSocket);
406             firstFlag = false;
407             break;
408         }
409         if (!SPUtils::IsSubString(recvBuf, iterator->second)) {
410             ++iterator;
411             continue;
412         }
413         LOGD("UDP recv : %s", recvBuf.c_str());
414         SpProfiler *profiler = SpProfilerFactory::GetProfilerItem(iterator->first);
415         if (profiler == nullptr) {
416             HandleNullMsg(spSocket, profiler, retCode, recvBuf, iterator);
417         } else {
418             std::map<std::string, std::string> data;
419             if (iterator->first == MessageType::CATCH_NETWORK_TRAFFIC) {
420                 Network::GetInstance().IsFindHap();
421                 profiler->ItemData(); // record the collection point for the first time,no need to return
422                 data["network_traffic"] = "true";
423             } else if (iterator->first == MessageType::GET_NETWORK_TRAFFIC) {
424                 Network::GetInstance().IsStopFindHap();
425                 data = profiler->ItemData();
426                 data["network_traffic"] = "true";
427             } else if (iterator->first == MessageType::GET_LOG) {
428                 GetSocketPort(recvBuf);
429                 data = profiler->ItemData();
430             } else {
431                 GetProcessIdByPkgName(iterator);
432                 data = profiler->ItemData();
433             }
434             HandleUDPMsg(spSocket, data, retCode, iterator);
435         }
436         break;
437     }
438 }
439 
HandleMsgTrace(std::string & recvMessage)440 void SpThreadSocket::HandleMsgTrace(std::string& recvMessage)
441 {
442     const std::string traceWord = "-TRACE::";
443     const size_t startPos = recvMessage.find(traceWord);
444     const size_t tarceLength = traceWord.length();
445     const size_t colonLength = 2;
446     if (startPos != std::string::npos) {
447         size_t tracePos = startPos + tarceLength;
448         size_t endPos = recvMessage.find(" ", startPos);
449         bytrace.jittersAndLowFps = recvMessage.substr(tracePos, endPos - tracePos);
450         recvMessage.erase(tracePos - colonLength, colonLength + bytrace.jittersAndLowFps.length());
451     }
452 }
453 
HeartbeatDetection(const std::string & recvBuf)454 void SpThreadSocket::HeartbeatDetection(const std::string& recvBuf)
455 {
456     if (recvBuf.size() != 0) {
457         Heartbeat &heartbeat = Heartbeat::GetInstance();
458         heartbeat.UpdatestartTime();
459     }
460 }
461 
UdpStartInitFunc(const std::string & recvBuf,SpServerSocket & spSocket)462 void SpThreadSocket::UdpStartInitFunc(const std::string& recvBuf, SpServerSocket &spSocket)
463 {
464     if (taskMgr_ != nullptr) {
465         taskMgr_->Stop();
466         taskMgr_->WriteToCSV();
467     }
468     taskMgr_ = std::make_shared<TaskManager>(true);
469     auto lambdaTask = [&spSocket](const std::string &data) { spSocket.Sendto(data); };
470     taskMgr_->SetIPCCallback(lambdaTask);
471     taskMgr_->AddTask(recvBuf);
472     spTask.SetAppCmd(recvBuf);
473     spTask.SetAppInitFlag();
474 
475     std::string fileDir = "/data/local/tmp/smartperf/" + spTask.GetCurTaskInfo().sessionId;
476     spTask.CreatPath(fileDir);
477     taskMgr_->SetFilePath(fileDir + "/t_index_info.csv");
478 }
479 
FileSocketConnect()480 int SpThreadSocket::FileSocketConnect()
481 {
482     sendFileSocket = socket(AF_INET, SOCK_STREAM, 0);
483     if (sendFileSocket < 0) {
484         WLOGE("Create log file socket failed, errno: %d", errno);
485         return -1;
486     }
487     struct sockaddr_in socketAddr = {0};
488     socketAddr.sin_family = AF_INET;
489     socketAddr.sin_port = htons(sendFileSocketPort);
490     socketAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
491     if (connect(sendFileSocket, reinterpret_cast<struct sockaddr *>(&socketAddr), sizeof(socketAddr)) < 0) {
492         WLOGE("Connect log file socket failed, errno: %d", errno);
493         return -1;
494     }
495     WLOGI("Connect log file socket success, socket: %d", sendFileSocket);
496     return sendFileSocket;
497 }
498 
SendFile(const std::string & filePath)499 int SpThreadSocket::SendFile(const std::string& filePath)
500 {
501     char filePathChar[PATH_MAX] = {0x00};
502     if ((realpath(filePath.c_str(), filePathChar) == nullptr)) {
503         WLOGE("%s is not exist.", filePath.c_str());
504         return -1;
505     }
506     std::ifstream logFile(filePathChar, std::ios::binary);
507     if (!logFile.is_open()) {
508         WLOGE("Open log file failed");
509         close(sendFileSocket);
510         sendFileSocket = -1;
511         return -1;
512     }
513     WLOGI("logfile exists, sending...");
514     logFile.seekg(0, std::ios::end);
515     std::streamsize fileSize = logFile.tellg();
516     logFile.seekg(0, std::ios::beg);
517     std::streamsize totalSent = 0;
518     while (!logFile.eof()) {
519         logFile.read(fileSocketBuffer, sizeof(fileSocketBuffer));
520         std::streamsize bytesRead = logFile.gcount();
521         ssize_t bytesSent = send(sendFileSocket, fileSocketBuffer, bytesRead, 0);
522         if (bytesSent < 0) {
523             WLOGE("Send log file failed");
524             logFile.close();
525             close(sendFileSocket);
526             sendFileSocket = -1;
527             return -1;
528         }
529         totalSent += bytesSent;
530         if (bytesSent != bytesRead) {
531             WLOGE("Incomplete send: sent %zd bytes out of %zd", bytesSent, bytesRead);
532             logFile.close();
533             close(sendFileSocket);
534             sendFileSocket = -1;
535             return -1;
536         }
537     }
538     if (totalSent != fileSize) {
539         WLOGE("File size mismatch: sent %zd bytes, file size %zd", totalSent, fileSize);
540         return -1;
541     }
542     logFile.close();
543     close(sendFileSocket);
544     sendFileSocket = -1;
545     WLOGI("Send log file success, bytes: %zd", totalSent);
546     return 0;
547 }
548 
ConnectAndSendFile(SpServerSocket & spSocket,const std::string filePath)549 void SpThreadSocket::ConnectAndSendFile(SpServerSocket &spSocket, const std::string filePath)
550 {
551     if (filePath.empty()) {
552         WLOGE("Connect filePath does not exist.");
553         return;
554     }
555     if (sendFileSocketPort == -1) {
556         return;
557     }
558     std::thread sendSizeThread([&spSocket, filePath]() {
559         size_t fileSize = SPUtils::GetFileSize(filePath);
560         if (fileSize == 0) {
561             LOGE("UDP ConnectAndSendFile recv GetFileSize fileSize: (%d)", fileSize);
562             return;
563         }
564         std::string sendFileSizeMsg = "SendFileSize:::" + std::to_string(fileSize);
565         LOGI("UDP START sendFileSizeMsg = %s", sendFileSizeMsg.c_str());
566         spSocket.Sendto(sendFileSizeMsg);
567         LOGI("UDP Sendto sendFileSizeMsg = %s", sendFileSizeMsg.c_str());
568     });
569 
570     std::thread sendFileThread([this, filePath]() {
571         int fileSocket = -1;
572         int connectCount = 0;
573         const int maxTryCount = 2;
574 
575         while (fileSocket < 0) {
576             WLOGI("Connect file log socket, try times: %d", connectCount + 1);
577             if (connectCount > maxTryCount) {
578                 WLOGE("Connect file log socket failed");
579                 return;
580             }
581             connectCount++;
582             fileSocket = FileSocketConnect();
583         }
584 
585         int ret = SendFile(filePath);
586         if (ret < 0) {
587             WLOGE("Failed to send file");
588             return;
589         }
590     });
591 
592     sendSizeThread.join();
593     sendFileThread.join();
594 }
595 
HandleUDPMsg(SpServerSocket & spSocket,std::map<std::string,std::string> & data,std::string & retCode,std::unordered_map<MessageType,std::string>::const_iterator iterator)596 void SpThreadSocket::HandleUDPMsg(SpServerSocket &spSocket, std::map<std::string, std::string>& data,
597     std::string& retCode, std::unordered_map<MessageType, std::string>::const_iterator iterator)
598 {
599     std::cout << "iterator->first: " << static_cast<int>(iterator->first) << std::endl;
600     if (iterator->first == MessageType::GET_CUR_FPS) {
601         FPS::GetInstance().isLowCurFps = true;
602         std::string resultfps = "vfps||";
603         for (auto iter = data.cbegin(); iter != data.cend(); ++iter) {
604             if (iter->first != "fpsJitters") {
605                 std::string temp = iter->second + "@@";
606                 resultfps += std::string(temp.c_str());
607             }
608         }
609         spSocket.Sendto(resultfps);
610         LOGD("UDP send Cur_resultfps = %s", resultfps.c_str());
611     } else if (iterator->first == MessageType::GET_CPU_FREQ_LOAD) {
612         FetchCpuStats(spSocket, data);
613     } else if (iterator->first == MessageType::GET_LOG) {
614         ConnectAndSendFile(spSocket, logFilePath);
615         GetLog::GetInstance().RemoveLogFile();
616     } else {
617         retCode = MapToString(data);
618         spSocket.Sendto(retCode);
619         LOGD("UDP send retCode = %s", retCode.c_str());
620     }
621 }
SocketHeartbeat() const622 void SpThreadSocket::SocketHeartbeat() const
623 {
624     Heartbeat &heartbeat = Heartbeat::GetInstance();
625     heartbeat.UpdatestartTime();
626 }
FetchCpuStats(SpServerSocket & spSocket,std::map<std::string,std::string> & data) const627 void SpThreadSocket::FetchCpuStats(SpServerSocket &spSocket, std::map<std::string, std::string>& data) const
628 {
629     std::string resultCpuFrequency = "";
630     std::string resultCpuUsage = "";
631     std::string resultCpu = "";
632     int cpuFrequencyNum = 0;
633     int cpuUsageNum = 0;
634     int cpuFlag = 1;
635     while (cpuFlag) {
636         resultCpuFrequency = "cpu" + std::to_string(cpuFrequencyNum) + "Frequency";
637         resultCpuUsage = "cpu" + std::to_string(cpuUsageNum) + "Usage";
638         auto iterCpuFrequency = data.find(resultCpuFrequency);
639         auto iterCpuUsage = data.find(resultCpuUsage);
640         if (iterCpuFrequency != data.end()) {
641             resultCpuFrequency += "||" + iterCpuFrequency->second;
642             resultCpu += "$$" + resultCpuFrequency;
643             cpuFrequencyNum++;
644         } else {
645             cpuFlag = 0;
646         }
647         if (iterCpuUsage != data.end()) {
648             resultCpuUsage += "||" + iterCpuUsage->second;
649             resultCpu += "$$" + resultCpuUsage;
650             cpuUsageNum++;
651         } else {
652             cpuFlag = 0;
653         }
654     }
655     spSocket.Sendto(resultCpu);
656     LOGD("UDP send resultCpu = %s", resultCpu.c_str());
657 }
HandleNullMsg(SpServerSocket & spSocket,SpProfiler * profiler,std::string & retCode,const std::string & recvBuf,std::unordered_map<MessageType,std::string>::const_iterator iterator)658 void SpThreadSocket::HandleNullMsg(SpServerSocket &spSocket, SpProfiler *profiler, std::string& retCode,
659     const std::string& recvBuf, std::unordered_map<MessageType, std::string>::const_iterator iterator)
660 {
661     if (iterator->first == MessageType::SET_PKG_NAME) {
662         isSetPid = false;
663         retCode = SplitMsg(recvBuf);
664         if (recvBuf.find(SMARTPERF) != std::string::npos && retCode.find(SMARTPERF) != std::string::npos) {
665             Dubai::dubaiPkgName = retCode;
666             LOGD("UDP send smartperf: (%s)", Dubai::dubaiPkgName.c_str());
667         } else {
668             if (retCode.find("$") != std::string::npos) {
669                 g_pkgAndPid = retCode;
670                 g_pkgName = SpGetPkg(g_pkgAndPid);
671             } else {
672                 g_pkgName = retCode;
673             }
674             std::thread([this]() { this->ResetValue(g_pkgName); }).detach();
675             LOGD("HandleNullMsg pkgName: (%s)", g_pkgName.c_str());
676         }
677         spSocket.Sendto(retCode);
678         LOGD("UDP send PkgName = %s", retCode.c_str());
679     } else if (profiler == nullptr && (iterator->first == MessageType::GET_APP_TYPE)) {
680         retCode = SplitMsg(recvBuf);
681         std::thread([this, retCode]() { this->ResetValue(retCode); }).detach();
682     } else if (profiler == nullptr && (iterator->first == MessageType::GET_DAEMON_VERSION)) {
683         retCode = "Version: " + SPUtils::GetVersion();
684         spSocket.Sendto(retCode);
685     } else if (iterator->first == MessageType::CATCH_ONE_TRACE) {
686         bytrace.hiviewTrace = SplitMsg(recvBuf);
687         bytrace.CpTraceFile();
688     } else if (iterator->first == MessageType::CATCH_TRACE_FINISH) {
689         tracefilePath = "";
690         GetSocketPort(recvBuf);
691         ConnectAndSendFile(spSocket, tracefilePath);
692     } else if (iterator->first == MessageType::GET_CPU_NUM) {
693         retCode = SPUtils::GetCpuNum();
694         spSocket.Sendto(retCode);
695         LOGD("UDP send cpuNum = %s", retCode.c_str());
696     } else if (iterator->first == MessageType::BACK_TO_DESKTOP) {
697         BackDesktop();
698     } else {
699         HandleNullAddMsg(spSocket, profiler, retCode, recvBuf, iterator);
700     }
701 }
702 
GetProcessIdByPkgName(std::unordered_map<MessageType,std::string>::const_iterator iterator)703 void SpThreadSocket::GetProcessIdByPkgName(std::unordered_map<MessageType, std::string>::const_iterator iterator)
704 {
705     if (iterator->first == MessageType::GET_FPS_AND_JITTERS || iterator->first == MessageType::GET_CUR_FPS ||
706         iterator->first == MessageType::GET_RAM_INFO) {
707         if (!SpProfilerFactory::editorFlag && isSetPid == false) {
708             FPS::GetInstance().isHistoryHap = true;
709             std::string pkgName = g_pkgName;
710             std::string pkgAndPid = g_pkgAndPid;
711             LOGD("SpProfilerFactory::g_pkgName(%s)", g_pkgName.c_str());
712             std::string processId = "";
713             std::string processIds = "";
714             FPS::GetInstance().isPreset = IsPreset(pkgAndPid);
715             if (FPS::GetInstance().isPreset) {
716                 processId = SpGetPid(pkgAndPid);
717             } else {
718                 OHOS::SmartPerf::StartUpDelay sp;
719                 processId = sp.GetPidByPkg(pkgName, &processIds);
720             }
721             SpProfilerFactory::SetProfilerPidByPkg(processId, processIds);
722             SpProfilerFactory::SetProfilerPkg(pkgName);
723             isSetPid = true;
724         }
725     }
726 }
727 
ResetValue(std::string retCode) const728 void SpThreadSocket::ResetValue(std::string retCode) const
729 {
730     FPS::GetInstance().isGameApp = SPUtils::GetIsGameApp(retCode);
731     RAM::GetInstance().SetHapFirstFlag();
732 }
HandleNullAddMsg(SpServerSocket & spSocket,SpProfiler * profiler,std::string & retCode,const std::string & recvBuf,std::unordered_map<MessageType,std::string>::const_iterator iterator)733 void SpThreadSocket::HandleNullAddMsg(SpServerSocket &spSocket, SpProfiler *profiler, std::string& retCode,
734     const std::string& recvBuf, std::unordered_map<MessageType, std::string>::const_iterator iterator)
735 {
736     Dubai &db = Dubai::GetInstance();
737     if (iterator->first == MessageType::START_DUBAI_DB) {
738         std::thread dStart([&db]() { db.CallBeginAndFinish(); });
739         dStart.detach();
740     } else if (iterator->first == MessageType::SET_DUBAI_DB) {
741         GetSocketPort(recvBuf);
742         db.CallBeginAndFinish();
743         FPS::GetInstance().isLowCurFps = false;
744         db.MoveDubaiDb(dubaiXpower);
745         ConnectAndSendFile(spSocket, dubaiFilePath);
746         retCode = "get_dubai_db";
747         LOGD("UDP send GetDubaiDb Message: (%s)", retCode.c_str());
748         spSocket.Sendto(retCode);
749         LOGD("UDP send DuBai get finish");
750     } else if (iterator->first == MessageType::CHECK_UDP_STATUS) {
751         retCode = "UDP status is normal";
752         spSocket.Sendto(retCode);
753         LOGD("UDP status is normal");
754     } else if (iterator->first == MessageType::SAVE_GPU_COUNTER) {
755         GetSocketPort(recvBuf);
756         std::unique_lock<std::mutex> lock(GpuCounter::GetInstance().GetGpuCounterLock());
757         ConnectAndSendFile(spSocket, gpuCounterfilePath + "/gpu_counter.csv");
758     } else if (iterator->first == MessageType::APP_STOP_COLLECT) {
759         if (taskMgr_ != nullptr) {
760             // UDP (device) 停止时,设置GPU_COUNTER保存路径
761             SPUtils::CreateDir(gpuCounterfilePath);
762             GpuCounter::GetInstance().SetSavePathDirectory(gpuCounterfilePath);
763             taskMgr_->SetHapFlag(false);
764             taskMgr_->Stop();
765             retCode = Hiperf::GetInstance().ReturnHiperfData();
766             spSocket.Sendto(retCode);
767             taskMgr_->WriteToCSV();
768         }
769         spTask.ClearStopFlag();
770     } else {
771         UdpStartMessProcess(spSocket, profiler, retCode, recvBuf, iterator);
772     }
773 }
774 
UdpStartMessProcess(SpServerSocket & spSocket,SpProfiler * profiler,std::string & retCode,const std::string & recvBuf,std::unordered_map<MessageType,std::string>::const_iterator iterator)775 void SpThreadSocket::UdpStartMessProcess(SpServerSocket &spSocket, SpProfiler *profiler, std::string& retCode,
776     const std::string& recvBuf, std::unordered_map<MessageType, std::string>::const_iterator iterator)
777 {
778     if (iterator->first == MessageType::APP_START_COLLECT) {
779         if (taskMgr_ != nullptr) {
780             taskMgr_->AddTask(&SdkDataRecv::GetInstance(), false);
781         }
782         bytrace.ClearTraceFiles();
783         StartHapCollecting(spSocket);
784     } else if (iterator->first == MessageType::APP_RECEIVE_DATA_ON) {
785         if (taskMgr_ != nullptr) {
786             LOGD("Start to display data in real time");
787             taskMgr_->SetHapFlag(true);
788             taskMgr_->EnableIPCCallback();
789         }
790     } else if (iterator->first == MessageType::APP_RECEIVE_DATA_OFF) {
791         if (taskMgr_ != nullptr) {
792             LOGD("Real time data display ends");
793             taskMgr_->DisableIPCCallback();
794         }
795     } else if (iterator->first == MessageType::APP_PAUSE_COLLECT) {
796         if (taskMgr_ != nullptr) {
797             LOGD("Pause Collection");
798             SPUtils::CreateDir(gpuCounterfilePath);
799             GpuCounter::GetInstance().SetSavePathDirectory(gpuCounterfilePath);
800             GpuCounter::GetInstance().SetIsPause(true);
801             taskMgr_->Stop(true);
802         }
803     } else if (iterator->first == MessageType::APP_RESUME_COLLECT) {
804         LOGD("Resuming Collection");
805         StartHapCollecting(spSocket);
806         GpuCounter::GetInstance().SetIsPause(false);
807     } else if (iterator->first == MessageType::GET_INDEX_INFO) {
808         GetSocketPort(recvBuf);
809         ConnectAndSendFile(spSocket, indexFilePath);
810     } else {
811         retCode = iterator->second;
812         spSocket.Sendto(retCode);
813         LOGD("UDP sendData: (%s)", retCode.c_str());
814     }
815 }
SocketErrorTypeToString(SocketErrorType errorType) const816 std::string SpThreadSocket::SocketErrorTypeToString(SocketErrorType errorType) const
817 {
818     switch (errorType) {
819         case SocketErrorType::OK:
820             return "OK";
821         case SocketErrorType::TOKEN_CHECK_FAILED:
822             return "TOKEN_CHECK_FAILED";
823         case SocketErrorType::INIT_FAILED:
824             return "INIT_FAILED";
825         case SocketErrorType::START_FAILED:
826             return "START_FAILED";
827         case SocketErrorType::STOP_FAILED:
828             return "STOP_FAILED";
829         case SocketErrorType::START_RECORD_FAILED:
830             return "START_RECORD_FAILED";
831         case SocketErrorType::STOP_RECORD_FAILED:
832             return "STOP_RECORD_FAILED";
833         default:
834             return "UNKNOWN";
835     }
836 }
GetSocketPort(const std::string & buffer)837 void SpThreadSocket::GetSocketPort(const std::string& buffer)
838 {
839     if (buffer.find("::") != std::string::npos) {
840         std::string portStr = buffer.substr(buffer.find("::") + 2);
841         std::string fileName = "";
842         if (portStr.find(":::") != std::string::npos) {
843             portStr = portStr.substr(0, portStr.find(":::"));
844         }
845 
846         if (portStr.find("$") != std::string::npos) {
847             fileName = portStr.substr(portStr.find("$") + 1);
848             portStr = portStr.substr(0, portStr.find("$"));
849             tracefilePath = traceOriginPath + fileName;
850         }
851 
852         int port = SPUtilesTye::StringToSometype<int>(portStr);
853         if (port <= 0) {
854             WLOGE("Invalid port number: %d", port);
855             sendFileSocketPort = -1;
856         } else {
857             WLOGI("Get File log UDP message received, port is %d", port);
858             sendFileSocket = -1;
859             sendFileSocketPort = port;
860         }
861     } else {
862         WLOGE("Get File log UDP message received, but port is not found");
863         sendFileSocketPort = -1;
864     }
865 }
SpGetPkg(const std::string & spMsg) const866 std::string SpThreadSocket::SpGetPkg(const std::string &spMsg) const
867 {
868     if (spMsg.empty()) {
869         return spMsg;
870     }
871     size_t pos = spMsg.find("$");
872     if (pos != std::string::npos) {
873         std::vector<std::string> sps;
874         SPUtils::StrSplit(spMsg, "$", sps);
875         if (sps.size() > 1) {
876             return sps[0];
877         } else {
878             return spMsg;
879         }
880     } else {
881         return spMsg;
882     }
883 }
884 
SpGetPid(const std::string & spMsg) const885 std::string SpThreadSocket::SpGetPid(const std::string &spMsg) const
886 {
887     if (spMsg.empty()) {
888         LOGE("spMsg is null");
889         return spMsg;
890     }
891     size_t pos = spMsg.find("$");
892     if (pos != std::string::npos) {
893         std::vector<std::string> sps;
894         SPUtils::StrSplit(spMsg, "$", sps);
895         if (sps.size() > 1) {
896             return sps[1];
897         } else {
898             LOGE("SpGetPid sps size is zreo");
899             return "";
900         }
901     } else {
902         return "";
903     }
904 }
905 
IsPreset(const std::string & spMsg) const906 bool SpThreadSocket::IsPreset(const std::string &spMsg) const
907 {
908     return spMsg.find("$") != std::string::npos;
909 }
910 
SetToken(const std::string & token)911 void SpThreadSocket::SetToken(const std::string& token)
912 {
913     checkToken = token;
914 }
915 
GetToken() const916 std::string SpThreadSocket::GetToken() const
917 {
918     return checkToken;
919 }
920 
SetNeedUdpToken(bool isNeed)921 void SpThreadSocket::SetNeedUdpToken(bool isNeed)
922 {
923     isNeedUdpToken = isNeed;
924 }
925 
StartHapCollecting(SpServerSocket & spSocket)926 void SpThreadSocket::StartHapCollecting(SpServerSocket &spSocket)
927 {
928     LOGD("UDP START Task starting...");
929     RAM &ram = RAM::GetInstance();
930     ram.SetFirstFlag();
931     if (udpStartCollect.joinable()) {
932         udpStartCollect.join();
933     }
934     udpStartCollect = std::thread([this]() {
935         if (taskMgr_ == nullptr) {
936             return;
937         }
938         taskMgr_->Start();
939         taskMgr_->SetRecordState(true);
940         taskMgr_->Wait();
941         LOGD("Data collecting thread exiting.");
942     });
943     return;
944 }
945 }
946 }