• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "tooling/client/session/session.h"
17 
18 #include "common/log_wrapper.h"
19 #include "tooling/client/manager/message_manager.h"
20 #include "tooling/base/pt_json.h"
21 #include "tooling/utils/utils.h"
22 
23 #include <iomanip>
24 
25 using PtJson = panda::ecmascript::tooling::PtJson;
26 using Result = panda::ecmascript::tooling::Result;
27 namespace OHOS::ArkCompiler::Toolchain {
28 uv_async_t* g_socketSignal;
SocketMessageThread(void * arg)29 void SocketMessageThread(void *arg)
30 {
31     int sessionId = *(uint32_t *)arg;
32     Session *session = SessionManager::getInstance().GetSessionById(sessionId);
33 
34     session->SocketMessageLoop();
35 }
36 
Session(uint32_t sessionId,std::string & sockInfo)37 Session::Session(uint32_t sessionId, std::string& sockInfo)
38     : sessionId_(sessionId), sockInfo_(sockInfo), domainManager_(sessionId), breakpoint_(sessionId),
39       stackManager_(sessionId), variableManager_(sessionId), sourceManager_(sessionId), watchManager_(sessionId)
40 {
41 }
42 
SocketMessageLoop()43 void Session::SocketMessageLoop()
44 {
45     while (cliSocket_.IsConnected()) {
46         std::string decMessage = cliSocket_.Decode();
47         uint32_t len = decMessage.length();
48         if (len == 0) {
49             continue;
50         }
51         LOGI("arkdb [%{public}u] message = %{public}s", sessionId_, decMessage.c_str());
52 
53         MessageManager::getInstance().MessagePush(sessionId_, decMessage);
54 
55         if (uv_is_active(reinterpret_cast<uv_handle_t*>(g_socketSignal))) {
56             uv_async_send(g_socketSignal);
57         }
58     }
59 }
60 
CreateSocket()61 int Session::CreateSocket()
62 {
63     uint32_t port = 0;
64     if (Utils::StrToUInt(sockInfo_.c_str(), &port)) {
65         if ((port <= 0) || (port >= 65535)) { // 65535: max port
66             LOGE("arkdb:InitToolchainWebSocketForPort the port = %{public}d is wrong.", port);
67             return -1;
68         }
69         if (!cliSocket_.InitToolchainWebSocketForPort(port, 5)) { // 5: five times
70             LOGE("arkdb:InitToolchainWebSocketForPort failed");
71             return -1;
72         }
73     } else {
74         if (!cliSocket_.InitToolchainWebSocketForSockName(sockInfo_)) {
75             LOGE("arkdb:InitToolchainWebSocketForSockName failed");
76             return -1;
77         }
78     }
79 
80     if (!cliSocket_.ClientSendWSUpgradeReq()) {
81         LOGE("arkdb:ClientSendWSUpgradeReq failed");
82         return -1;
83     }
84     if (!cliSocket_.ClientRecvWSUpgradeRsp()) {
85         LOGE("arkdb:ClientRecvWSUpgradeRsp failed");
86         return -1;
87     }
88 
89     return 0;
90 }
91 
Start()92 int Session::Start()
93 {
94     if (CreateSocket()) {
95         return -1;
96     }
97 
98     uv_thread_create(&socketTid_, SocketMessageThread, &sessionId_);
99     return 0;
100 }
101 
Stop()102 int Session::Stop()
103 {
104     cliSocket_.Close();
105     return 0;
106 }
107 
CreateSessionById(uint32_t sessionId,std::string & sockInfo)108 int SessionManager::CreateSessionById(uint32_t sessionId, std::string& sockInfo)
109 {
110     sessions_[sessionId] = std::make_unique<Session>(sessionId, sockInfo);
111     if (sessions_[sessionId]->Start()) {
112         sessions_[sessionId] = nullptr;
113         return -1;
114     }
115 
116     return 0;
117 }
118 
CreateNewSession(std::string & sockInfo)119 int SessionManager::CreateNewSession(std::string& sockInfo)
120 {
121     uint32_t sessionId = MAX_SESSION_NUM;
122     for (uint32_t i = 0; i < MAX_SESSION_NUM; ++i) {
123         if (sessions_[i] == nullptr) {
124             if (sessionId == MAX_SESSION_NUM) {
125                 sessionId = i;
126             }
127             continue;
128         }
129         if (sessions_[i]->GetSockInfo() == sockInfo) {
130             return -1;
131         }
132     }
133 
134     if (sessionId < MAX_SESSION_NUM) {
135         return CreateSessionById(sessionId, sockInfo);
136     }
137 
138     return -1;
139 }
140 
CreateDefaultSession(std::string & sockInfo)141 int SessionManager::CreateDefaultSession(std::string& sockInfo)
142 {
143     return CreateSessionById(0, sockInfo);
144 }
145 
DelSessionById(uint32_t sessionId)146 int SessionManager::DelSessionById(uint32_t sessionId)
147 {
148     Session *session = GetSessionById(sessionId);
149     if (session == nullptr) {
150         return -1;
151     }
152     session->Stop();
153     sessions_[sessionId] = nullptr;
154 
155     if (sessionId == currentSessionId_) {
156         currentSessionId_ = 0;
157         std::cout << "session switch to 0" << std::endl;
158     }
159 
160     return 0;
161 }
162 
SessionList()163 int SessionManager::SessionList()
164 {
165     for (uint32_t i = 0; i < MAX_SESSION_NUM; ++i) {
166         if (sessions_[i] != nullptr) {
167             std::string flag = (i == currentSessionId_) ? "* " : "  ";
168             std::string sockState = sessions_[i]->GetSocketStateString();
169             std::cout << flag << i << ": ";
170             std::cout << std::setw(32) << std::left << sessions_[i]->GetSockInfo(); // 32: max length of socket info
171             std::cout << sockState << std::endl;
172         }
173     }
174     return 0;
175 }
176 
SessionSwitch(uint32_t sessionId)177 int SessionManager::SessionSwitch(uint32_t sessionId)
178 {
179     Session *session = GetSessionById(sessionId);
180     if (session == nullptr) {
181         return -1;
182     }
183     currentSessionId_ = sessionId;
184     return 0;
185 }
186 
CmdForAllSessions(CmdForAllCB callback)187 void SessionManager::CmdForAllSessions(CmdForAllCB callback)
188 {
189     for (uint32_t sessionId = 0; sessionId < MAX_SESSION_NUM; ++sessionId) {
190         if (sessions_[sessionId] != nullptr) {
191             std::cout << "Executing command in session " << sessionId << ":" << std::endl;
192             callback(sessionId);
193         }
194     }
195 }
196 
CreateTestSession(std::string & sockInfo)197 int SessionManager::CreateTestSession(std::string& sockInfo)
198 {
199     uint32_t sessionId = 0;
200     sessions_[sessionId] = std::make_unique<Session>(sessionId, sockInfo);
201     if (sessions_[sessionId]->CreateSocket()) {
202         sessions_[sessionId] = nullptr;
203         return -1;
204     }
205 
206     return 0;
207 }
208 }