1 /*
2  * Copyright (c) 2024 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 #include <stdio.h>
16 #include <string.h>
17 
18 #include "comm_log.h"
19 #include "message_handler.h"
20 #include "softbus_adapter_mem.h"
21 #include "softbus_def.h"
22 #include "softbus_errcode.h"
23 #include "softbus_hidumper_broadcast.h"
24 
25 #define SOFTBUS_BROADCAST_MODULE_NAME "broadcast"
26 #define SOFTBUS_BROADCAST_MODULE_HELP "List all the dump item of broadcast"
27 #define SOFTBUS_BROADCAST_DUMP_HANDLER_NAME "bc_dump_handler"
28 #define EVENT_BROADCAT_DUMP 0
29 typedef int32_t (*BroadcastExecuteFunc)(SoftbusBroadcastDumpTask cb, uint64_t delayMillis);
30 
31 static bool g_isInit = false;
32 static SoftBusHandler g_bcDumphandler = {0};
33 static LIST_HEAD(g_bc_var_list);
34 
35 static int32_t SoftbusBroadcastDumpLooperInit(void);
36 
CreateBroadcastHandlerMsg(int32_t what,uint64_t arg1,uint64_t arg2,void * obj)37 static SoftBusMessage *CreateBroadcastHandlerMsg(int32_t what, uint64_t arg1, uint64_t arg2, void *obj)
38 {
39     SoftBusMessage *msg = (SoftBusMessage *)SoftBusCalloc(sizeof(SoftBusMessage));
40     if (msg == NULL) {
41         COMM_LOGE(COMM_DFX, "create broadcast handler msg failed");
42         return NULL;
43     }
44 
45     msg->what = what;
46     msg->arg1 = arg1;
47     msg->arg2 = arg2;
48     msg->handler = &g_bcDumphandler;
49     msg->FreeMessage = NULL;
50     msg->obj = obj;
51     return msg;
52 }
53 
ExecuteBroadcastTask(SoftbusBroadcastDumpTask cb,uint64_t delayMillis)54 static int32_t ExecuteBroadcastTask(SoftbusBroadcastDumpTask cb, uint64_t delayMillis)
55 {
56     cb();
57     SoftBusMessage *msg = CreateBroadcastHandlerMsg(EVENT_BROADCAT_DUMP, delayMillis, 0, (void *)cb);
58     if (msg == NULL) {
59         COMM_LOGE(COMM_DFX, "create msg failed");
60         return SOFTBUS_MALLOC_ERR;
61     }
62 
63     g_bcDumphandler.looper->PostMessageDelay(g_bcDumphandler.looper, msg, delayMillis);
64     return SOFTBUS_OK;
65 }
66 
SoftbusRegBroadcastDumpTask(const SoftbusBroadcastDumpTask cb,uint64_t delayMillis)67 int32_t SoftbusRegBroadcastDumpTask(const SoftbusBroadcastDumpTask cb, uint64_t delayMillis)
68 {
69     if (cb == NULL) {
70         COMM_LOGE(COMM_DFX, "invalid param cb");
71         return SOFTBUS_INVALID_PARAM;
72     }
73 
74     int32_t ret = SoftbusBroadcastDumpLooperInit();
75     if (ret != SOFTBUS_OK) {
76         COMM_LOGE(COMM_DFX, "init looper fail");
77         return ret;
78     }
79 
80     SoftBusMessage *msg = CreateBroadcastHandlerMsg(EVENT_BROADCAT_DUMP, delayMillis, 0, (void *)cb);
81     if (msg == NULL) {
82         COMM_LOGE(COMM_DFX, "create msg failed");
83         return SOFTBUS_MALLOC_ERR;
84     }
85 
86     g_bcDumphandler.looper->PostMessageDelay(g_bcDumphandler.looper, msg, delayMillis);
87     return SOFTBUS_OK;
88 }
89 
90 
SoftBusRegBroadcastVarDump(const char * dumpVar,const SoftBusVarDumpCb cb)91 int32_t SoftBusRegBroadcastVarDump(const char *dumpVar, const SoftBusVarDumpCb cb)
92 {
93     if (dumpVar == NULL || strlen(dumpVar) >= SOFTBUS_DUMP_VAR_NAME_LEN || cb == NULL) {
94         COMM_LOGE(COMM_DFX, "invalid param cb");
95         return SOFTBUS_INVALID_PARAM;
96     }
97 
98     return SoftBusAddDumpVarToList(dumpVar, cb, &g_bc_var_list);
99 }
100 
SoftBusBroadcastDumpHander(int fd,int32_t argc,const char ** argv)101 static int32_t SoftBusBroadcastDumpHander(int fd, int32_t argc, const char **argv)
102 {
103     if (fd < 0 || argc < 0 || argv == NULL) {
104         COMM_LOGE(COMM_DFX, "invalid param");
105         return SOFTBUS_INVALID_PARAM;
106     }
107 
108     if (argc == 0 || strcmp(argv[0], "-h") == 0) {
109         SoftBusDumpSubModuleHelp(fd, SOFTBUS_BROADCAST_MODULE_NAME, &g_bc_var_list);
110         return SOFTBUS_OK;
111     }
112 
113     if (argc == 1 && strcmp(argv[0], "-l") == 0) {
114         SoftBusDumpSubModuleHelp(fd, SOFTBUS_BROADCAST_MODULE_NAME, &g_bc_var_list);
115         return SOFTBUS_OK;
116     }
117     int32_t ret = SOFTBUS_OK;
118     int32_t isModuleExist = SOFTBUS_DUMP_NOT_EXIST;
119     if (strcmp(argv[0], "-l") == 0) {
120         ListNode *item = NULL;
121         LIST_FOR_EACH(item, &g_bc_var_list) {
122             SoftBusDumpVarNode *itemNode = LIST_ENTRY(item, SoftBusDumpVarNode, node);
123             if (strcmp(itemNode->varName, argv[1]) == 0) {
124                 ret = itemNode->dumpCallback(fd);
125                 isModuleExist = SOFTBUS_DUMP_EXIST;
126                 break;
127             }
128         }
129         if (isModuleExist == SOFTBUS_DUMP_NOT_EXIST) {
130             SoftBusDumpErrInfo(fd, argv[1]);
131             SoftBusDumpSubModuleHelp(fd, SOFTBUS_BROADCAST_MODULE_NAME, &g_bc_var_list);
132         }
133     }
134 
135     return ret;
136 }
137 
BroadcastMsgHandler(SoftBusMessage * msg)138 static void BroadcastMsgHandler(SoftBusMessage *msg)
139 {
140     if (msg == NULL) {
141         COMM_LOGE(COMM_DFX, "msg is null");
142         return;
143     }
144 
145     if (msg->what != EVENT_BROADCAT_DUMP) {
146         return;
147     }
148     ExecuteBroadcastTask((SoftbusBroadcastDumpTask)msg->obj, msg->arg1);
149 }
150 
SoftbusBroadcastDumpLooperInit(void)151 static int32_t SoftbusBroadcastDumpLooperInit(void)
152 {
153     if (g_bcDumphandler.looper != NULL) {
154         COMM_LOGI(COMM_DFX, "looper already inited");
155         return SOFTBUS_OK;
156     }
157     g_bcDumphandler.looper = GetLooper(LOOP_TYPE_DEFAULT);
158     if (g_bcDumphandler.looper == NULL) {
159         COMM_LOGE(COMM_DFX, "get looper fail!");
160         return SOFTBUS_LOOPER_ERR;
161     }
162 
163     g_bcDumphandler.name = SOFTBUS_BROADCAST_DUMP_HANDLER_NAME;
164     g_bcDumphandler.HandleMessage = BroadcastMsgHandler;
165     return SOFTBUS_OK;
166 }
167 
SoftBusHiDumperBroadcastInit(void)168 int32_t SoftBusHiDumperBroadcastInit(void)
169 {
170     if (g_isInit) {
171         COMM_LOGI(COMM_INIT, "already inited");
172         return SOFTBUS_OK;
173     }
174 
175     int32_t ret = SoftBusRegHiDumperHandler(SOFTBUS_BROADCAST_MODULE_NAME, SOFTBUS_BROADCAST_MODULE_HELP,
176         &SoftBusBroadcastDumpHander);
177     if (ret != SOFTBUS_OK) {
178         COMM_LOGE(COMM_INIT, "SoftBusBroadcastDumpHander register fail");
179         return ret;
180     }
181 
182     ret = SoftbusBroadcastDumpLooperInit();
183     if (ret != SOFTBUS_OK) {
184         COMM_LOGE(COMM_INIT, "init broadcast hidumper looper fail");
185     }
186     g_isInit = true;
187     return SOFTBUS_OK;
188 }
189 
SoftBusHiDumperBroadcastDeInit(void)190 void SoftBusHiDumperBroadcastDeInit(void)
191 {
192     SoftBusReleaseDumpVar(&g_bc_var_list);
193     g_isInit = false;
194 }
195