1e509ee18Sopenharmony_ci/* 2e509ee18Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3e509ee18Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e509ee18Sopenharmony_ci * you may not use this file except in compliance with the License. 5e509ee18Sopenharmony_ci * You may obtain a copy of the License at 6e509ee18Sopenharmony_ci * 7e509ee18Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e509ee18Sopenharmony_ci * 9e509ee18Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e509ee18Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e509ee18Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e509ee18Sopenharmony_ci * See the License for the specific language governing permissions and 13e509ee18Sopenharmony_ci * limitations under the License. 14e509ee18Sopenharmony_ci */ 15e509ee18Sopenharmony_ci#include "tooling/client/tcpServer/tcp_server.h" 16e509ee18Sopenharmony_ci 17e509ee18Sopenharmony_ci#include "tooling/utils/utils.h" 18e509ee18Sopenharmony_ci 19e509ee18Sopenharmony_cinamespace OHOS::ArkCompiler::Toolchain { 20e509ee18Sopenharmony_ciuv_async_t* g_inputSignal; 21e509ee18Sopenharmony_ciuv_async_t* g_releaseHandle; 22e509ee18Sopenharmony_cistd::string g_inputStr = ""; 23e509ee18Sopenharmony_cistd::vector<std::string> g_allCmds = { "allocationtrack", "at", "allocationtrack-stop", "at-stop", "heapdump", "hd", 24e509ee18Sopenharmony_ci "heapprofiler-enable", "hp-enable", "heapprofiler-disable", "hp-disable", "sampling", "sampling", "sampling-stop", 25e509ee18Sopenharmony_ci "sampling-stop", "collectgarbage", "gc", "cpuprofile", "cp", "cpuprofile-stop", "cp-stop", "cpuprofile-enable", 26e509ee18Sopenharmony_ci "cp-enable", "cpuprofile-disable", "cp-disable", "cpuprofile-show", "cp-show", "cpuprofile-setSamplingInterval", 27e509ee18Sopenharmony_ci "cp-ssi", "runtime-enable", "rt-enable", "heapusage", "hu", "break", "b", "backtrack", "bt", "continue", "c", 28e509ee18Sopenharmony_ci "delete", "d", "disable", "disable", "display", "display", "enable", "enable", "finish", "fin", "frame", "f", 29e509ee18Sopenharmony_ci "help", "h", "ignore", "ig", "infobreakpoints", "infob", "infosource", "infos", "jump", "j", "list", "l", "next", 30e509ee18Sopenharmony_ci "n", "print", "p", "ptype", "ptype", "run", "r", "setvar", "sv", "step", "s", "undisplay", "undisplay", "watch", 31e509ee18Sopenharmony_ci "wa", "resume", "resume", "showstack", "ss", "step-into", "si", "step-out", "so", "step-over", "sov", 32e509ee18Sopenharmony_ci "runtime-disable", "rt-disable" }; 33e509ee18Sopenharmony_cistd::vector<std::string> g_noRecvCmds = { "cpuprofile-enable", "cp-enable", "cpuprofile-disable", "cp-disable", 34e509ee18Sopenharmony_ci "cpuprofile-stop", "cp-stop" }; 35e509ee18Sopenharmony_cistd::vector<std::string> g_inputOnMessages = { "b", "break", "bt", "backtrack", "d", "delete", "display", "fin", 36e509ee18Sopenharmony_ci "finish", "f", "frame", "h", "help", "ig", "ignore", "infob", "infobreakpoints", "infos", "infosource", "j", "jump", 37e509ee18Sopenharmony_ci "l", "list", "n", "next", "ptype", "s", "step", "ss", "showstack", "watch", "wa" }; 38e509ee18Sopenharmony_ci 39e509ee18Sopenharmony_civoid CreateServer(void* arg) 40e509ee18Sopenharmony_ci{ 41e509ee18Sopenharmony_ci TcpServer::getInstance().StartTcpServer(arg); 42e509ee18Sopenharmony_ci} 43e509ee18Sopenharmony_ci 44e509ee18Sopenharmony_civoid TcpServer::CloseServer() 45e509ee18Sopenharmony_ci{ 46e509ee18Sopenharmony_ci if (uv_is_active(reinterpret_cast<uv_handle_t*>(g_releaseHandle))) { 47e509ee18Sopenharmony_ci uv_async_send(g_releaseHandle); 48e509ee18Sopenharmony_ci } 49e509ee18Sopenharmony_ci} 50e509ee18Sopenharmony_ci 51e509ee18Sopenharmony_civoid TcpServer::ServerConnect() 52e509ee18Sopenharmony_ci{ 53e509ee18Sopenharmony_ci isServerActive = 1; 54e509ee18Sopenharmony_ci struct sockaddr_in saddr; 55e509ee18Sopenharmony_ci saddr.sin_family = AF_INET; 56e509ee18Sopenharmony_ci saddr.sin_addr.s_addr = INADDR_ANY; 57e509ee18Sopenharmony_ci saddr.sin_port = htons(9999); // 9999: tcp bind port 58e509ee18Sopenharmony_ci 59e509ee18Sopenharmony_ci lfd = socket(AF_INET, SOCK_STREAM, 0); 60e509ee18Sopenharmony_ci if (lfd == -1) { 61e509ee18Sopenharmony_ci std::cout << "socket failed" << std::endl; 62e509ee18Sopenharmony_ci CloseServer(); 63e509ee18Sopenharmony_ci return; 64e509ee18Sopenharmony_ci } 65e509ee18Sopenharmony_ci 66e509ee18Sopenharmony_ci int ret = bind(lfd, (struct sockaddr*)&saddr, sizeof(saddr)); 67e509ee18Sopenharmony_ci if (ret == -1) { 68e509ee18Sopenharmony_ci std::cout << "bind failed" << std::endl; 69e509ee18Sopenharmony_ci CloseServer(); 70e509ee18Sopenharmony_ci return; 71e509ee18Sopenharmony_ci } 72e509ee18Sopenharmony_ci 73e509ee18Sopenharmony_ci ret = listen(lfd, 6); // 6: Number of backlogs 74e509ee18Sopenharmony_ci if (ret == -1) { 75e509ee18Sopenharmony_ci std::cout << "listen failed" << std::endl; 76e509ee18Sopenharmony_ci CloseServer(); 77e509ee18Sopenharmony_ci return; 78e509ee18Sopenharmony_ci } 79e509ee18Sopenharmony_ci 80e509ee18Sopenharmony_ci struct sockaddr_in clientaddr; 81e509ee18Sopenharmony_ci socklen_t len = sizeof(clientaddr); 82e509ee18Sopenharmony_ci cfd = accept(lfd, (struct sockaddr*)&clientaddr, &len); 83e509ee18Sopenharmony_ci if (cfd == -1) { 84e509ee18Sopenharmony_ci std::cout << "accept failed" << std::endl; 85e509ee18Sopenharmony_ci CloseServer(); 86e509ee18Sopenharmony_ci return; 87e509ee18Sopenharmony_ci } 88e509ee18Sopenharmony_ci} 89e509ee18Sopenharmony_ci 90e509ee18Sopenharmony_civoid TcpServer::SendCommand(std::string inputStr) 91e509ee18Sopenharmony_ci{ 92e509ee18Sopenharmony_ci inputStr.erase(0, inputStr.find_first_not_of(" ")); 93e509ee18Sopenharmony_ci if (inputStr.empty()) { 94e509ee18Sopenharmony_ci std::cout << "cmd is empty" << std::endl; 95e509ee18Sopenharmony_ci return; 96e509ee18Sopenharmony_ci } 97e509ee18Sopenharmony_ci 98e509ee18Sopenharmony_ci if (uv_is_active(reinterpret_cast<uv_handle_t*>(g_inputSignal))) { 99e509ee18Sopenharmony_ci uint32_t len = inputStr.length(); 100e509ee18Sopenharmony_ci if (len < 0) { 101e509ee18Sopenharmony_ci CloseServer(); 102e509ee18Sopenharmony_ci return; 103e509ee18Sopenharmony_ci } 104e509ee18Sopenharmony_ci char* msg = (char*)malloc(len + 1); 105e509ee18Sopenharmony_ci if (msg == nullptr) { 106e509ee18Sopenharmony_ci return; 107e509ee18Sopenharmony_ci } 108e509ee18Sopenharmony_ci if (strncpy_s(msg, len + 1, inputStr.c_str(), len) != 0) { 109e509ee18Sopenharmony_ci free(msg); 110e509ee18Sopenharmony_ci CloseServer(); 111e509ee18Sopenharmony_ci return; 112e509ee18Sopenharmony_ci } 113e509ee18Sopenharmony_ci g_inputSignal->data = std::move(msg); 114e509ee18Sopenharmony_ci uv_async_send(g_inputSignal); 115e509ee18Sopenharmony_ci } 116e509ee18Sopenharmony_ci return; 117e509ee18Sopenharmony_ci} 118e509ee18Sopenharmony_ci 119e509ee18Sopenharmony_civoid TcpServer::StartTcpServer([[maybe_unused]] void* arg) 120e509ee18Sopenharmony_ci{ 121e509ee18Sopenharmony_ci ServerConnect(); 122e509ee18Sopenharmony_ci 123e509ee18Sopenharmony_ci const char* data = "connect success"; 124e509ee18Sopenharmony_ci write(cfd, data, strlen(data)); 125e509ee18Sopenharmony_ci int num = 0; 126e509ee18Sopenharmony_ci do { 127e509ee18Sopenharmony_ci char recvBuf[1024] = { 0 }; 128e509ee18Sopenharmony_ci num = read(cfd, recvBuf, sizeof(recvBuf)); 129e509ee18Sopenharmony_ci if (num < 0) { 130e509ee18Sopenharmony_ci std::cout << "read failed" << std::endl; 131e509ee18Sopenharmony_ci } else if (num > 0) { 132e509ee18Sopenharmony_ci g_inputStr = std::string(recvBuf); 133e509ee18Sopenharmony_ci SendCommand(recvBuf); 134e509ee18Sopenharmony_ci TcpServerWrite(); 135e509ee18Sopenharmony_ci } else if (num == 0) { 136e509ee18Sopenharmony_ci std::cout << "clinet closed" << std::endl; 137e509ee18Sopenharmony_ci } 138e509ee18Sopenharmony_ci } while (num > 0); 139e509ee18Sopenharmony_ci 140e509ee18Sopenharmony_ci close(cfd); 141e509ee18Sopenharmony_ci close(lfd); 142e509ee18Sopenharmony_ci 143e509ee18Sopenharmony_ci CloseServer(); 144e509ee18Sopenharmony_ci return; 145e509ee18Sopenharmony_ci} 146e509ee18Sopenharmony_ci 147e509ee18Sopenharmony_civoid TcpServer::TcpServerWrite(std::string msg) 148e509ee18Sopenharmony_ci{ 149e509ee18Sopenharmony_ci if (g_inputStr.empty()) { 150e509ee18Sopenharmony_ci return; 151e509ee18Sopenharmony_ci } 152e509ee18Sopenharmony_ci 153e509ee18Sopenharmony_ci std::vector<std::string> cliCmdStr = Utils::SplitString(g_inputStr, " "); 154e509ee18Sopenharmony_ci if (!FindCommand(g_allCmds, cliCmdStr[0])) { 155e509ee18Sopenharmony_ci g_inputStr = "error cmd"; 156e509ee18Sopenharmony_ci write(cfd, g_inputStr.c_str(), strlen(g_inputStr.c_str())); 157e509ee18Sopenharmony_ci g_inputStr.clear(); 158e509ee18Sopenharmony_ci return; 159e509ee18Sopenharmony_ci } 160e509ee18Sopenharmony_ci if (msg == "inner") { 161e509ee18Sopenharmony_ci if (FindCommand(g_noRecvCmds, cliCmdStr[0])) { 162e509ee18Sopenharmony_ci write(cfd, g_inputStr.c_str(), strlen(g_inputStr.c_str())); 163e509ee18Sopenharmony_ci g_inputStr.clear(); 164e509ee18Sopenharmony_ci } 165e509ee18Sopenharmony_ci } else if (msg == "InputOnMessage") { 166e509ee18Sopenharmony_ci if (FindCommand(g_inputOnMessages, cliCmdStr[0])) { 167e509ee18Sopenharmony_ci write(cfd, g_inputStr.c_str(), strlen(g_inputStr.c_str())); 168e509ee18Sopenharmony_ci g_inputStr.clear(); 169e509ee18Sopenharmony_ci } 170e509ee18Sopenharmony_ci } else if (msg == "SocketOnMessage") { 171e509ee18Sopenharmony_ci if (FindCommand(g_inputOnMessages, cliCmdStr[0])) { 172e509ee18Sopenharmony_ci return; 173e509ee18Sopenharmony_ci } 174e509ee18Sopenharmony_ci if (g_inputStr.empty()) { 175e509ee18Sopenharmony_ci return; 176e509ee18Sopenharmony_ci } 177e509ee18Sopenharmony_ci write(cfd, g_inputStr.c_str(), strlen(g_inputStr.c_str())); 178e509ee18Sopenharmony_ci g_inputStr.clear(); 179e509ee18Sopenharmony_ci } 180e509ee18Sopenharmony_ci return; 181e509ee18Sopenharmony_ci} 182e509ee18Sopenharmony_ci 183e509ee18Sopenharmony_ciint TcpServer::CreateTcpServer([[maybe_unused]] void* arg) 184e509ee18Sopenharmony_ci{ 185e509ee18Sopenharmony_ci uv_thread_create(&serverTid_, CreateServer, nullptr); 186e509ee18Sopenharmony_ci return 0; 187e509ee18Sopenharmony_ci} 188e509ee18Sopenharmony_ci 189e509ee18Sopenharmony_cibool TcpServer::FindCommand(std::vector<std::string> cmds, std::string cmd) 190e509ee18Sopenharmony_ci{ 191e509ee18Sopenharmony_ci return find(cmds.begin(), cmds.end(), cmd) != cmds.end(); 192e509ee18Sopenharmony_ci} 193e509ee18Sopenharmony_ci} // namespace OHOS::ArkCompiler::Toolchain