• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 "nstackx_dfinder_hidump.h"
17 #include <inttypes.h>
18 #include "nstackx_dfinder_log.h"
19 #include "nstackx_dfinder_mgt_msg_log.h"
20 #include "nstackx_util.h"
21 #include "nstackx_getopt.h"
22 #include "nstackx_statistics.h"
23 #include "nstackx_common.h"
24 #include "nstackx_event.h"
25 #include "nstackx_error.h"
26 #include "securec.h"
27 
28 #ifdef NSTACKX_DFINDER_HIDUMP
29 
30 #define TAG "nStackXDFinder"
31 #define CRLF "\r\n"
32 
33 #define DUMP_BUF_LEN (2048U)
34 
35 typedef struct {
36     char *buf;
37     uint32_t size;
38     int err;
39     sem_t wait;
40 } DumpMsg;
41 
CreateDumpMsg(char * buf,uint32_t size)42 static DumpMsg *CreateDumpMsg(char *buf, uint32_t size)
43 {
44     DumpMsg *msg = (DumpMsg *)malloc(sizeof(DumpMsg));
45     if (msg == NULL) {
46         return NULL;
47     }
48 
49     if (SemInit(&(msg->wait), 0, 0)) {
50         free(msg);
51         return NULL;
52     }
53 
54     msg->err = NSTACKX_EOK;
55     msg->buf = buf;
56     msg->size = size;
57     return msg;
58 }
59 
DestroyDumpMsg(DumpMsg * msg)60 static void DestroyDumpMsg(DumpMsg *msg)
61 {
62     SemDestroy(&(msg->wait));
63     free(msg);
64 }
65 
PostDumpMsg(char * buf,uint32_t size,EventHandle handle)66 static int PostDumpMsg(char *buf, uint32_t size, EventHandle handle)
67 {
68     int ret = NSTACKX_EFAILED;
69     DumpMsg *msg = CreateDumpMsg(buf, size);
70     if (msg == NULL) {
71         return ret;
72     }
73 
74     if (PostEvent(GetEventNodeChain(), GetEpollFD(), handle, msg) != NSTACKX_EOK) {
75         DestroyDumpMsg(msg);
76         return ret;
77     }
78 
79     SemWait(&(msg->wait));
80     ret = msg->err;
81     DestroyDumpMsg(msg);
82     return ret;
83 }
84 
85 typedef int (*DumpFunc)(char *buf, uint32_t size);
Dump(void * softObj,DFinderDumpFunc dump,DumpFunc func)86 static int Dump(void *softObj, DFinderDumpFunc dump, DumpFunc func)
87 {
88     char *buf = (char *)calloc(DUMP_BUF_LEN, sizeof(char));
89     if (buf == NULL) {
90         return NSTACKX_EFAILED;
91     }
92 
93     if (func(buf, DUMP_BUF_LEN) != NSTACKX_EOK) {
94         free(buf);
95         return NSTACKX_EFAILED;
96     }
97 
98     dump(softObj, buf, strlen(buf) + 1);
99     free(buf);
100     return NSTACKX_EOK;
101 }
102 
DumpStatisticsInfo(char * buf,uint32_t size)103 static int DumpStatisticsInfo(char *buf, uint32_t size)
104 {
105     int ret;
106     uint32_t index = 0;
107     const uint64_t *stat = GetStatistics();
108     DUMP_MSG_ADD_CHECK(ret, buf, index, size, CRLF"DFinder statistics:"CRLF);
109     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_INVALID_OPT_AND_PAYLOAD: %" PRIu64 CRLF,
110         stat[STATS_INVALID_OPT_AND_PAYLOAD]);
111     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_DECODE_FAILED: %" PRIu64 CRLF, stat[STATS_DECODE_FAILED]);
112     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_ENCODE_FAILED: %" PRIu64 CRLF, stat[STATS_ENCODE_FAILED]);
113     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_CREATE_HEADER_FAILED: %" PRIu64 CRLF,
114         stat[STATS_CREATE_HEADER_FAILED]);
115     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_BUILD_PKT_FAILED: %" PRIu64 CRLF, stat[STATS_BUILD_PKT_FAILED]);
116     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_SOCKET_ERROR: %" PRIu64 CRLF, stat[STATS_SOCKET_ERROR]);
117     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_EPOLL_ERROR: %" PRIu64 CRLF, stat[STATS_EPOLL_ERROR]);
118     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_CREATE_SERVER_FAILED: %" PRIu64 CRLF,
119         stat[STATS_CREATE_SERVER_FAILED]);
120     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_CREATE_CLIENT_FAILED: %" PRIu64 CRLF,
121         stat[STATS_CREATE_CLIENT_FAILED]);
122     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_DROP_LOOPBACK_PKT: %" PRIu64 CRLF, stat[STATS_DROP_LOOPBACK_PKT]);
123     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_SEND_MSG_FAILED: %" PRIu64 CRLF, stat[STATS_SEND_MSG_FAILED]);
124     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_SEND_REQUEST_FAILED: %" PRIu64 CRLF,
125         stat[STATS_SEND_REQUEST_FAILED]);
126     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_DROP_MSG_ID: %" PRIu64 CRLF, stat[STATS_DROP_MSG_ID]);
127     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_HANDLE_SERVICE_MSG_FAILED: %" PRIu64 CRLF,
128         stat[STATS_HANDLE_SERVICE_MSG_FAILED]);
129     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_HANDLE_DEVICE_DISCOVER_MSG_FAILED: %" PRIu64 CRLF,
130         stat[STATS_HANDLE_DEVICE_DISCOVER_MSG_FAILED]);
131     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_INVALID_RESPONSE_MSG: %" PRIu64 CRLF,
132         stat[STATS_INVALID_RESPONSE_MSG]);
133     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_POST_SD_REQUEST_FAILED: %" PRIu64 CRLF,
134         stat[STATS_POST_SD_REQUEST_FAILED]);
135     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_ABORT_SD: %" PRIu64 CRLF, stat[STATS_ABORT_SD]);
136     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_START_SD_FAILED: %" PRIu64 CRLF, stat[STATS_START_SD_FAILED]);
137     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_CREATE_SERVICE_MSG_FAILED: %" PRIu64 CRLF,
138         stat[STATS_CREATE_SERVICE_MSG_FAILED]);
139     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_SEND_SD_RESPONSE_FAILED: %" PRIu64 CRLF,
140         stat[STATS_SEND_SD_RESPONSE_FAILED]);
141     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_BACKUP_DEVICE_DB_FAILED: %" PRIu64 CRLF,
142         stat[STATS_BACKUP_DEVICE_DB_FAILED]);
143     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_UPDATE_DEVICE_DB_FAILED: %" PRIu64 CRLF,
144         stat[STATS_UPDATE_DEVICE_DB_FAILED]);
145     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_CREATE_CONTEX_FAILED: %" PRIu64 CRLF,
146         stat[STATS_CREATE_CONTEX_FAILED]);
147     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_CREATE_SESSION_FAILED: %" PRIu64 CRLF,
148         stat[STATS_CREATE_SESSION_FAILED]);
149     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_PREPARE_SD_MSG_FAILED: %" PRIu64 CRLF,
150         stat[STATS_PREPARE_SD_MSG_FAILED]);
151     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_PARSE_SD_MSG_FAILED: %" PRIu64 CRLF,
152         stat[STATS_PARSE_SD_MSG_FAILED]);
153     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_ALLOC_RECORD_FAILED: %" PRIu64 CRLF,
154         stat[STATS_ALLOC_RECORD_FAILED]);
155     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_FREE_RECORD_FAILED: %" PRIu64 CRLF,
156         stat[STATS_FREE_RECORD_FAILED]);
157     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "STATS_OVER_DEVICE_LIMIT: %" PRIu64 CRLF, stat[STATS_OVER_DEVICE_LIMIT]);
158     return NSTACKX_EOK;
159 }
160 
DumpStatisticsInner(void * arg)161 static void DumpStatisticsInner(void *arg)
162 {
163     DumpMsg *msg = (DumpMsg *)arg;
164     msg->err = DumpStatisticsInfo(msg->buf, msg->size);
165     SemPost(&(msg->wait));
166 }
167 
DumpStatistics(char * buf,uint32_t size)168 int DumpStatistics(char *buf, uint32_t size)
169 {
170     return PostDumpMsg(buf, size, DumpStatisticsInner);
171 }
172 
DumpHelp(char * buf,uint32_t size)173 static int DumpHelp(char *buf, uint32_t size)
174 {
175     int ret;
176     int index = 0;
177     DUMP_MSG_ADD_CHECK(ret, buf, index, size, CRLF"Usage: dfinder <opt>"CRLF);
178     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "       -h         show this help"CRLF);
179     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "       -s         show statistics info"CRLF);
180     DUMP_MSG_ADD_CHECK(ret, buf, index, size, "       -m <0/1>   enable control message log"CRLF);
181     return NSTACKX_EOK;
182 }
183 
184 #define DFINDER_DUMP_STRTOL_BASE 10
185 static const char *g_dfinderDumpOpts = "hsm:";
DFinderDump(const char ** argv,uint32_t argc,void * softObj,DFinderDumpFunc dump)186 int DFinderDump(const char **argv, uint32_t argc, void *softObj, DFinderDumpFunc dump)
187 {
188     int32_t opt;
189     NstackGetOptMsg optMsg;
190     int32_t ret = NstackInitGetOptMsg(&optMsg);
191     if (ret != NSTACKX_EOK) {
192         return ret;
193     }
194 
195     while ((opt = NstackGetOpt(&optMsg, argc, argv, g_dfinderDumpOpts)) != NSTACK_GETOPT_END_OF_STR) {
196         switch (opt) {
197             case 'h':
198                 ret = Dump(softObj, dump, DumpHelp);
199                 break;
200             case 's':
201                 ret = Dump(softObj, dump, DumpStatistics);
202                 break;
203             case 'm':
204 #ifdef DFINDER_MGT_MSG_LOG
205                 (void)DFinderSetMgtMsgLog((int32_t)strtol(NstackGetOptArgs(&optMsg), NULL, DFINDER_DUMP_STRTOL_BASE));
206 #endif
207                 break;
208             default:
209                 ret = NSTACKX_EFAILED;
210                 DFINDER_LOGE(TAG, "Unknown option");
211                 break;
212         }
213 
214         if (ret != NSTACKX_EOK) {
215             break;
216         }
217     }
218 
219     return ret;
220 }
221 
222 #endif /* NSTACKX_DFINDER_HIDUMP */
223