1 /*
2 * Copyright (c) 2021 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 "bus_center_event.h"
17
18 #include <securec.h>
19 #include <stdlib.h>
20
21 #include "lnn_bus_center_ipc.h"
22 #include "message_handler.h"
23 #include "softbus_adapter_mem.h"
24 #include "softbus_adapter_thread.h"
25 #include "softbus_errcode.h"
26 #include "softbus_log.h"
27 #include "softbus_qos.h"
28
29 typedef struct {
30 ListNode node;
31 LnnEventHandler handler;
32 } LnnEventHandlerItem;
33
34 typedef struct {
35 ListNode handlers[LNN_EVENT_TYPE_MAX];
36 SoftBusMutex lock;
37 } BusCenterEventCtrl;
38
39 typedef enum {
40 NOTIFY_ONLINE_STATE_CHANGED = 0,
41 NOTIFY_NODE_BASIC_INFO_CHANGED,
42 } NotifyType;
43
44 static BusCenterEventCtrl g_eventCtrl;
45 static SoftBusHandler g_notifyHandler = {"NotifyHandler", NULL, NULL};
46
PostMessageToHandler(SoftBusMessage * msg)47 static int32_t PostMessageToHandler(SoftBusMessage *msg)
48 {
49 if (g_notifyHandler.looper == NULL) {
50 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "NotifyHandler not initialized.");
51 return SOFTBUS_NO_INIT;
52 }
53 if (g_notifyHandler.looper->PostMessage == NULL) {
54 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid looper.");
55 return SOFTBUS_ERR;
56 }
57 g_notifyHandler.looper->PostMessage(g_notifyHandler.looper, msg);
58 return SOFTBUS_OK;
59 }
60
HandleOnlineStateChangedMessage(SoftBusMessage * msg)61 static void HandleOnlineStateChangedMessage(SoftBusMessage *msg)
62 {
63 if (msg->obj == NULL) {
64 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid online state message.");
65 return;
66 }
67 bool isOnline = (bool)msg->arg1;
68 LnnIpcNotifyOnlineState(isOnline, msg->obj, sizeof(NodeBasicInfo));
69 }
70
HandleNodeBasicInfoChangedMessage(SoftBusMessage * msg)71 static void HandleNodeBasicInfoChangedMessage(SoftBusMessage *msg)
72 {
73 if (msg->obj == NULL) {
74 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid node basic info message.");
75 return;
76 }
77 int32_t type = (int32_t)msg->arg1;
78 LnnIpcNotifyBasicInfoChanged(msg->obj, sizeof(NodeBasicInfo), type);
79 }
80
HandleNotifyMessage(SoftBusMessage * msg)81 static void HandleNotifyMessage(SoftBusMessage *msg)
82 {
83 if (msg == NULL) {
84 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid notify message.");
85 return;
86 }
87 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "handle notify message, type = %d.", msg->what);
88 switch (msg->what) {
89 case NOTIFY_ONLINE_STATE_CHANGED:
90 HandleOnlineStateChangedMessage(msg);
91 break;
92 case NOTIFY_NODE_BASIC_INFO_CHANGED:
93 HandleNodeBasicInfoChangedMessage(msg);
94 break;
95 default:
96 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "unknown notify message, type = %d.", msg->what);
97 break;
98 }
99 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "handle notify message done, type = %d.", msg->what);
100 }
101
FreeNotifyMessage(SoftBusMessage * msg)102 static void FreeNotifyMessage(SoftBusMessage *msg)
103 {
104 if (msg == NULL) {
105 return;
106 }
107 if (msg->obj != NULL) {
108 SoftBusFree(msg->obj);
109 msg->obj = NULL;
110 }
111 SoftBusFree(msg);
112 }
113
DupNodeBasicInfo(const NodeBasicInfo * info)114 static NodeBasicInfo *DupNodeBasicInfo(const NodeBasicInfo *info)
115 {
116 if (info == NULL) {
117 return NULL;
118 }
119 NodeBasicInfo *dupInfo = SoftBusMalloc(sizeof(NodeBasicInfo));
120 if (dupInfo == NULL) {
121 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "malloc NodeBasicInfo err.");
122 return NULL;
123 }
124 if (memcpy_s(dupInfo, sizeof(NodeBasicInfo), info, sizeof(NodeBasicInfo)) != EOK) {
125 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "copy NodeBasicInfo fail.");
126 SoftBusFree(dupInfo);
127 return NULL;
128 }
129 return dupInfo;
130 }
131
PostNotifyMessage(int32_t what,uint64_t arg,const NodeBasicInfo * info)132 static int32_t PostNotifyMessage(int32_t what, uint64_t arg, const NodeBasicInfo *info)
133 {
134 SoftBusMessage *msg = SoftBusCalloc(sizeof(SoftBusMessage));
135 if (msg == NULL) {
136 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "malloc msg err.");
137 return SOFTBUS_MALLOC_ERR;
138 }
139 msg->what = what;
140 msg->arg1 = arg;
141 msg->obj = DupNodeBasicInfo(info);
142 if (msg->obj == NULL) {
143 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "dup NodeBasicInfo err.");
144 SoftBusFree(msg);
145 return SOFTBUS_MEM_ERR;
146 }
147 msg->handler = &g_notifyHandler;
148 msg->FreeMessage = FreeNotifyMessage;
149 return PostMessageToHandler(msg);
150 }
151
IsRepeatEventHandler(LnnEventType event,LnnEventHandler handler)152 static bool IsRepeatEventHandler(LnnEventType event, LnnEventHandler handler)
153 {
154 LnnEventHandlerItem *item = NULL;
155
156 LIST_FOR_EACH_ENTRY(item, &g_eventCtrl.handlers[event], LnnEventHandlerItem, node)
157 {
158 if (item->handler == handler) {
159 return true;
160 }
161 }
162 return false;
163 }
164
CreateEventHandlerItem(LnnEventHandler handler)165 static LnnEventHandlerItem *CreateEventHandlerItem(LnnEventHandler handler)
166 {
167 LnnEventHandlerItem *item = SoftBusMalloc(sizeof(LnnEventHandlerItem));
168
169 if (item == NULL) {
170 return NULL;
171 }
172 ListInit(&item->node);
173 item->handler = handler;
174 return item;
175 }
176
NotifyEvent(const LnnEventBasicInfo * info)177 static void NotifyEvent(const LnnEventBasicInfo *info)
178 {
179 LnnEventHandlerItem *item = NULL;
180
181 if (SoftBusMutexLock(&g_eventCtrl.lock) != 0) {
182 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "lock failed in notify event");
183 return;
184 }
185 LIST_FOR_EACH_ENTRY(item, &g_eventCtrl.handlers[info->event], LnnEventHandlerItem, node)
186 {
187 item->handler(info);
188 }
189 (void)SoftBusMutexUnlock(&g_eventCtrl.lock);
190 }
191
LnnNotifyOnlineState(bool isOnline,NodeBasicInfo * info)192 void LnnNotifyOnlineState(bool isOnline, NodeBasicInfo *info)
193 {
194 LnnOnlineStateEventInfo eventInfo;
195
196 if (info == NULL) {
197 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "para : info = null!");
198 return;
199 }
200 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "notify node %s %s",
201 info->deviceName, (isOnline == true) ? "online" : "offline");
202 SetDefaultQdisc();
203 (void)PostNotifyMessage(NOTIFY_ONLINE_STATE_CHANGED, (uint64_t)isOnline, info);
204 eventInfo.basic.event = LNN_EVENT_NODE_ONLINE_STATE_CHANGED;
205 eventInfo.isOnline = isOnline;
206 eventInfo.networkId = info->networkId;
207 NotifyEvent((LnnEventBasicInfo *)&eventInfo);
208 }
209
LnnNotifyBasicInfoChanged(NodeBasicInfo * info,NodeBasicInfoType type)210 void LnnNotifyBasicInfoChanged(NodeBasicInfo *info, NodeBasicInfoType type)
211 {
212 if (info == NULL) {
213 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "para : info = null!");
214 return;
215 }
216 if (type == TYPE_DEVICE_NAME) {
217 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "notify peer device name changed %s", info->deviceName);
218 }
219 (void)PostNotifyMessage(NOTIFY_NODE_BASIC_INFO_CHANGED, (uint64_t)type, info);
220 }
221
LnnNotifyJoinResult(ConnectionAddr * addr,const char * networkId,int32_t retCode)222 void LnnNotifyJoinResult(ConnectionAddr *addr, const char *networkId, int32_t retCode)
223 {
224 if (addr == NULL) {
225 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "para : addr or networkId = null!");
226 return;
227 }
228 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "notify join LNN result :%d", retCode);
229 LnnIpcNotifyJoinResult(addr, sizeof(ConnectionAddr), networkId, retCode);
230 }
231
MetaNodeNotifyJoinResult(ConnectionAddr * addr,const char * networkId,int32_t retCode)232 void MetaNodeNotifyJoinResult(ConnectionAddr *addr, const char *networkId, int32_t retCode)
233 {
234 if (addr == NULL) {
235 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "para : addr or networkId = null!");
236 return;
237 }
238 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "notify join MetaNode result :%d", retCode);
239 MetaNodeIpcNotifyJoinResult(addr, sizeof(ConnectionAddr), networkId, retCode);
240 }
241
LnnNotifyLeaveResult(const char * networkId,int32_t retCode)242 void LnnNotifyLeaveResult(const char *networkId, int32_t retCode)
243 {
244 if (networkId == NULL) {
245 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "para : networkId = null!");
246 return;
247 }
248 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "notify leave LNN result %d", retCode);
249 LnnIpcNotifyLeaveResult(networkId, retCode);
250 }
251
MetaNodeNotifyLeaveResult(const char * networkId,int32_t retCode)252 void MetaNodeNotifyLeaveResult(const char *networkId, int32_t retCode)
253 {
254 if (networkId == NULL) {
255 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "para : networkId = null!");
256 return;
257 }
258 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "notify leave MetaNode result %d", retCode);
259 MetaNodeIpcNotifyLeaveResult(networkId, retCode);
260 }
261
LnnNotifyLnnRelationChanged(const char * udid,ConnectionAddrType type,uint8_t relation,bool isJoin)262 void LnnNotifyLnnRelationChanged(const char *udid, ConnectionAddrType type, uint8_t relation, bool isJoin)
263 {
264 LnnRelationChanedEventInfo info;
265
266 info.basic.event = LNN_EVENT_RELATION_CHANGED;
267 info.type = type;
268 info.relation = relation;
269 info.isJoin = isJoin;
270 info.udid = udid;
271 NotifyEvent((LnnEventBasicInfo *)&info);
272 }
273
LnnNotifyTimeSyncResult(const char * pkgName,const TimeSyncResultInfo * info,int32_t retCode)274 void LnnNotifyTimeSyncResult(const char *pkgName, const TimeSyncResultInfo *info, int32_t retCode)
275 {
276 if (pkgName == NULL || info == NULL) {
277 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid paramters");
278 return;
279 }
280 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "notify time Sync result %d", retCode);
281 LnnIpcNotifyTimeSyncResult(pkgName, info, sizeof(TimeSyncResultInfo), retCode);
282 }
283
LnnNotifyWlanStateChangeEvent(SoftBusWifiState state)284 void LnnNotifyWlanStateChangeEvent(SoftBusWifiState state)
285 {
286 if (state < SOFTBUS_WIFI_CONNECTED || state > SOFTBUS_WIFI_UNKNOWN) {
287 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "bad state %d", state);
288 return;
289 }
290 LnnMonitorWlanStateChangedEvent event = {.basic.event = LNN_EVENT_WIFI_STATE_CHANGED, .status = state};
291 NotifyEvent((const LnnEventBasicInfo *)&event);
292 }
293
LnnNotifyScreenStateChangeEvent(SoftBusScreenState state)294 void LnnNotifyScreenStateChangeEvent(SoftBusScreenState state)
295 {
296 if (state < SOFTBUS_SCREEN_ON || state >= SOFTBUS_SCREEN_UNKNOWN) {
297 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "bad state %d", state);
298 return;
299 }
300 LnnMonitorScreenStateChangedEvent event = {.basic.event = LNN_EVENT_SCREEN_STATE_CHANGED, .status = state};
301 NotifyEvent((const LnnEventBasicInfo *)&event);
302 }
303
LnnNotifyBtStateChangeEvent(void * state)304 void LnnNotifyBtStateChangeEvent(void *state)
305 {
306 SoftBusBtState *btState = (SoftBusBtState *)state;
307 if (*btState < SOFTBUS_BLE_TURN_ON || *btState >= SOFTBUS_BT_UNKNOWN) {
308 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "bad btState %d", *btState);
309 SoftBusFree(btState);
310 return;
311 }
312 LnnMonitorBtStateChangedEvent event = {.basic.event = LNN_EVENT_BT_STATE_CHANGED, .status = (uint8_t)(*btState)};
313 NotifyEvent((const LnnEventBasicInfo *)&event);
314 SoftBusFree(btState);
315 }
316
LnnNotifyBtAclStateChangeEvent(const char * btMac,SoftBusBtAclState state)317 void LnnNotifyBtAclStateChangeEvent(const char *btMac, SoftBusBtAclState state)
318 {
319 if (btMac == NULL) {
320 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid btMac, state = %d", state);
321 return;
322 }
323 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO,
324 "notify bt acl state changed: state=%d, btMac=%s.", state, AnonymizesMac(btMac));
325 LnnMonitorBtAclStateChangedEvent event = {.basic.event = LNN_EVENT_BT_ACL_STATE_CHANGED, .status = state};
326 if (strcpy_s(event.btMac, sizeof(event.btMac), btMac) != EOK) {
327 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "copy bt mac fail");
328 return;
329 }
330 NotifyEvent((const LnnEventBasicInfo *)&event);
331 }
332
LnnNotifyAddressChangedEvent(const char * ifName)333 void LnnNotifyAddressChangedEvent(const char *ifName)
334 {
335 LnnMonitorAddressChangedEvent event = {.basic.event = LNN_EVENT_IP_ADDR_CHANGED, .ifName = {0}};
336 if (ifName != NULL) {
337 int32_t ret = strcpy_s(event.ifName, sizeof(event.ifName), ifName);
338 if (ret != EOK) {
339 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "copy ifName failed!ret=%d", ret);
340 return;
341 }
342 }
343 NotifyEvent((const LnnEventBasicInfo *)&event);
344 }
345
LnnNotifyMasterNodeChanged(bool isMaster,const char * masterNodeUdid,int32_t weight)346 void LnnNotifyMasterNodeChanged(bool isMaster, const char *masterNodeUdid, int32_t weight)
347 {
348 LnnMasterNodeChangedEvent event = {.basic.event = LNN_EVENT_NODE_MASTER_STATE_CHANGED,
349 .isMasterNode = isMaster,
350 .masterNodeUDID = masterNodeUdid,
351 .weight = weight};
352
353 NotifyEvent((const LnnEventBasicInfo *)&event);
354 }
355
LnnNotifyNodeAddressChanged(const char * addr)356 void LnnNotifyNodeAddressChanged(const char *addr)
357 {
358 if (addr == NULL) {
359 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "%s:nullptr!", __func__);
360 return;
361 }
362 LnnNodeAddrChangedEvent eventInfo;
363 (void)memset_s(&eventInfo, sizeof(eventInfo), 0, sizeof(eventInfo));
364 eventInfo.basic.event = LNN_EVENT_NODE_ADDR_CHANGED;
365 if (strcpy_s(eventInfo.addr, sizeof(eventInfo.addr), addr) != EOK) {
366 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "%s:strcpy_s failed", __func__);
367 return;
368 }
369 if (strcmp(addr, NODE_ADDR_LOOPBACK) == 0) {
370 eventInfo.delFlag = true;
371 } else {
372 eventInfo.delFlag = false;
373 }
374 NotifyEvent((LnnEventBasicInfo *)&eventInfo);
375 }
376
LnnInitBusCenterEvent(void)377 int32_t LnnInitBusCenterEvent(void)
378 {
379 int32_t i;
380 SoftBusLooper *looper = CreateNewLooper("NotifyLooper");
381 if (looper == NULL) {
382 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "create notify looper fail.");
383 return SOFTBUS_ERR;
384 }
385 g_notifyHandler.looper = looper;
386 g_notifyHandler.HandleMessage = HandleNotifyMessage;
387
388 SoftBusMutexAttr mutexAttr;
389 mutexAttr.type = SOFTBUS_MUTEX_RECURSIVE;
390 SoftBusMutexInit(&g_eventCtrl.lock, &mutexAttr);
391 for (i = 0; i < LNN_EVENT_TYPE_MAX; ++i) {
392 ListInit(&g_eventCtrl.handlers[i]);
393 }
394 return SOFTBUS_OK;
395 }
396
LnnDeinitBusCenterEvent(void)397 void LnnDeinitBusCenterEvent(void)
398 {
399 if (g_notifyHandler.looper != NULL) {
400 DestroyLooper(g_notifyHandler.looper);
401 g_notifyHandler.looper = NULL;
402 g_notifyHandler.HandleMessage = NULL;
403 }
404 SoftBusMutexDestroy(&g_eventCtrl.lock);
405 }
406
LnnRegisterEventHandler(LnnEventType event,LnnEventHandler handler)407 int32_t LnnRegisterEventHandler(LnnEventType event, LnnEventHandler handler)
408 {
409 LnnEventHandlerItem *item = NULL;
410
411 if (event == LNN_EVENT_TYPE_MAX || handler == NULL) {
412 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid event handler params");
413 return SOFTBUS_INVALID_PARAM;
414 }
415 if (SoftBusMutexLock(&g_eventCtrl.lock) != 0) {
416 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "lock failed in register event handler");
417 return SOFTBUS_LOCK_ERR;
418 }
419 if (IsRepeatEventHandler(event, handler)) {
420 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "event(%u) handler is already exist", event);
421 (void)SoftBusMutexUnlock(&g_eventCtrl.lock);
422 return SOFTBUS_INVALID_PARAM;
423 }
424 item = CreateEventHandlerItem(handler);
425 if (item == NULL) {
426 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "create event handler item failed");
427 (void)SoftBusMutexUnlock(&g_eventCtrl.lock);
428 return SOFTBUS_MEM_ERR;
429 }
430 ListAdd(&g_eventCtrl.handlers[event], &item->node);
431 (void)SoftBusMutexUnlock(&g_eventCtrl.lock);
432 return SOFTBUS_OK;
433 }
434
LnnUnregisterEventHandler(LnnEventType event,LnnEventHandler handler)435 void LnnUnregisterEventHandler(LnnEventType event, LnnEventHandler handler)
436 {
437 LnnEventHandlerItem *item = NULL;
438
439 if (event == LNN_EVENT_TYPE_MAX || handler == NULL) {
440 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid event handler params");
441 return;
442 }
443 if (SoftBusMutexLock(&g_eventCtrl.lock) != 0) {
444 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "hold lock failed in unregister event handler");
445 return;
446 }
447 LIST_FOR_EACH_ENTRY(item, &g_eventCtrl.handlers[event], LnnEventHandlerItem, node)
448 {
449 if (item->handler == handler) {
450 ListDelete(&item->node);
451 SoftBusFree(item);
452 break;
453 }
454 }
455 (void)SoftBusMutexUnlock(&g_eventCtrl.lock);
456 }