• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "message_server.h"
24 
25 #include <fstream>
26 #include <functional>
27 #include <iostream>
28 #include <list>
29 #include <map>
30 #include <string>
31 #include <sys/socket.h>
32 #include <sys/types.h>
33 #include <sys/un.h>
34 #include <unistd.h>
35 
36 #include "debugger.h"
37 #include "securec.h"
38 
39 static std::mutex g_mtx;
40 static std::map<int, std::list<std::string>> g_readMsgQueues;
41 static constexpr int MSG_LEN = 9;
42 static constexpr int MAX_CONNECT_CLIENT_NUM = 1;
43 
DBG_CopyComponentNameFromAce(const char * srcStr,char * destStr,int maxLen)44 bool DBG_CopyComponentNameFromAce(const char *srcStr, char *destStr, int maxLen)
45 {
46     if (strcpy_s(destStr, maxLen, srcStr) != 0) {
47         DEBUGGER_LOGE("GetInstanceName strcpy_s fail");
48         return false;
49     }
50     return true;
51 }
52 
QueueFront(int client)53 const char* QueueFront(int client)
54 {
55     g_mtx.lock();
56     const char* res = g_readMsgQueues[client].front().c_str();
57     g_mtx.unlock();
58     return res;
59 }
60 
QueuePop(int client)61 void QueuePop(int client)
62 {
63     g_mtx.lock();
64     g_readMsgQueues[client].pop_front();
65     g_mtx.unlock();
66 }
67 
QueueIsEmpty(int client)68 int QueueIsEmpty(int client)
69 {
70     g_mtx.lock();
71     int ret = g_readMsgQueues[client].empty();
72     g_mtx.unlock();
73     return ret;
74 }
75 
DBG_SocketRead(int client,char * buf,int len)76 static int DBG_SocketRead(int client, char *buf, int len)
77 {
78     if (client <= 0 || len == 0 || buf == nullptr) {
79         DEBUGGER_LOGE("DBG_SocketRead fail client=%d, len=%d, buf=%s", client, len, buf);
80         return 0;
81     }
82 
83     int loc = 0;
84     while (loc < len) {
85         int ret = TEMP_FAILURE_RETRY(read(client, reinterpret_cast<void*>(buf + loc), len - loc));
86         if (ret <= 0 || ret > (len - loc)) {
87             return 0;
88         }
89         loc = loc + ret;
90     }
91 
92     return 1;
93 }
94 
DBG_ReadMsgLen(int client)95 static int DBG_ReadMsgLen(int client)
96 {
97     char msgLenChar[MSG_LEN] = {0};
98     int readRet = DBG_SocketRead(client, msgLenChar, MSG_LEN);
99     if (readRet != 1) {
100         return 0;
101     }
102     msgLenChar[MSG_LEN - 1] = '\0';
103     // turn str to hex
104     const int base = 16;
105     int msgLen = strtol(msgLenChar, nullptr, base);
106     if (msgLen <= 0) {
107         DEBUGGER_LOGE("DBG_ReadMsgLen fail msgLen=%d", msgLen);
108         return 0;
109     }
110 
111     return msgLen;
112 }
113 
ReadMsg(int client)114 static void ReadMsg(int client)
115 {
116     int msgLen = DBG_ReadMsgLen(client);
117     if (msgLen <= 0) {
118         return;
119     }
120     std::unique_ptr<char[]> msgBuf = std::make_unique<char[]>(msgLen + 1);
121     if (msgBuf == nullptr) {
122         DEBUGGER_LOGE("DBG_ReadMsg fail msgBuf=nullptr");
123         return;
124     }
125 
126     int readRet = DBG_SocketRead(client, msgBuf.get(), msgLen);
127     if (!readRet) {
128         DEBUGGER_LOGE("DBG_ReadMsg fail readRet=%d", readRet);
129         return;
130     }
131 
132     g_mtx.lock();
133     msgBuf.get()[msgLen] = '\0';
134     DEBUGGER_LOGI("dbg msg %s", msgBuf.get());
135     std::string message(msgBuf.get());
136     g_readMsgQueues[client].push_back(message);
137     g_mtx.unlock();
138 
139     return;
140 }
141 
142 
143 static std::string g_componentName;
144 static int g_instanceId;
145 
DBG_SetComponentNameAndInstanceId(const char * name,int size,int instanceId)146 void DBG_SetComponentNameAndInstanceId(const char *name, int size, int instanceId)
147 {
148     if (size <= 0) {
149         DEBUGGER_LOGE("DBG_SetComponentName fail");
150         return;
151     }
152     g_componentName = name;
153     g_instanceId = instanceId;
154 }
155 
DBG_SetNeedDebugBreakPoint(bool needDebugBreakPoint)156 void DBG_SetNeedDebugBreakPoint(bool needDebugBreakPoint)
157 {
158     DEBUGGER_LOGI("NeedDebugBreakPoint: %d", needDebugBreakPoint);
159     DBG_SetDebugMode(!needDebugBreakPoint);
160 }
161 
DBG_GetComponentName()162 static std::string DBG_GetComponentName()
163 {
164     if (g_componentName.empty()) {
165         DEBUGGER_LOGE("DBG_GetComponentName fail");
166     }
167     return g_componentName;
168 }
169 
DBG_StartServer()170 static int DBG_StartServer()
171 {
172     DEBUGGER_LOGI("DBG_StartServer");
173     int fd = socket(AF_UNIX, SOCK_STREAM, 0);
174     if (fd < 0) {
175         return FAIL_CAUSE_SOCKET_COMMON_FAIL;
176     }
177 
178     std::string instanceIdStr = std::to_string(g_instanceId);
179     std::string component = DBG_GetComponentName();
180     std::string sockName = instanceIdStr + component;
181     struct sockaddr_un  un;
182     if (memset_s(&un, sizeof(un), 0, sizeof(un)) != EOK) {
183         DEBUGGER_LOGE("DBG_StartServer memset_s fail");
184         close(fd);
185         return FAIL_CAUSE_SOCKET_COMMON_FAIL;
186     }
187     un.sun_family = AF_UNIX;
188     if (strcpy_s(un.sun_path + 1, sizeof(un.sun_path) - 1, sockName.c_str()) != EOK) {
189         DEBUGGER_LOGE("DBG_StartServer strcpy_s fail");
190         close(fd);
191         return FAIL_CAUSE_SOCKET_COMMON_FAIL;
192     }
193     un.sun_path[0] = '\0';
194     int len = offsetof(struct sockaddr_un, sun_path) + strlen(sockName.c_str()) + 1;
195     if (bind(fd, reinterpret_cast<struct sockaddr*>(&un), len) < 0) {
196         close(fd);
197         return FAIL_CAUSE_SOCKET_COMMON_FAIL;
198     }
199     if (listen(fd, MAX_CONNECT_CLIENT_NUM) < 0) {
200         close(fd);
201         return FAIL_CAUSE_SOCKET_COMMON_FAIL;
202     }
203     int client = 0;
204     if ((client = accept(fd, nullptr, nullptr)) < 0) {
205         close(fd);
206         return FAIL_CAUSE_SOCKET_COMMON_FAIL;
207     }
208     return client;
209 }
210 
DBG_StartAgent(void * args)211 void *DBG_StartAgent(void *args)
212 {
213     int client = DBG_StartServer();
214     if (client < 0) {
215         DEBUGGER_LOGE("DBG_StartAgent fail");
216         return nullptr;
217     }
218 
219     auto debugger_info = (DebuggerInfo*)args;
220     g_mtx.lock();
221     debugger_info->client = client;
222     debugger_info->isConnected = 1;
223     g_mtx.unlock();
224 
225     std::list<std::string> messageList;
226     g_readMsgQueues[client] = messageList;
227     DEBUGGER_LOGI("DBG_StartAgent client = %d", client);
228 
229     while (true) {
230         ReadMsg(client);
231     }
232 }
233