1 /*
2 * Copyright (c) 2020-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 "pub_sub_feature.h"
17 #include <ohos_init.h>
18 #include "samgr_lite.h"
19 #include "thread_adapter.h"
20 #include "pub_sub_implement.h"
21
22 static const char *GetName(Feature *feature);
23 static void OnInitialize(Feature *feature, Service *parent, Identity identity);
24 static void OnStop(Feature *feature, Identity identity);
25 static BOOL OnMessage(Feature *feature, Request *request);
26 static Relation *GetRelation(PubSubFeature *feature, const Topic *topic);
27 static BOOL IsTopicEqual(const Topic *current, const Topic *other);
28 static PubSubFeature g_broadcastFeature = {
29 .GetName = GetName,
30 .OnInitialize = OnInitialize,
31 .OnStop = OnStop,
32 .OnMessage = OnMessage,
33 .GetRelation = GetRelation,
34 };
35
Init(void)36 static void Init(void)
37 {
38 PubSubFeature *feature = &g_broadcastFeature;
39 feature->relations.topic = -1;
40 feature->relations.callbacks.consumer = NULL;
41 UtilsListInit(&feature->relations.callbacks.node);
42 UtilsListInit(&feature->relations.node);
43 feature->mutex = MUTEX_InitValue();
44 SAMGR_GetInstance()->RegisterFeature(BROADCAST_SERVICE, (Feature *)feature);
45
46 PubSubImplement *apiEntry = BCE_CreateInstance((Feature *)feature);
47 SAMGR_GetInstance()->RegisterFeatureApi(BROADCAST_SERVICE, PUB_SUB_FEATURE, GET_IUNKNOWN(*apiEntry));
48 }
49 SYS_FEATURE_INIT(Init);
50
GetName(Feature * feature)51 static const char *GetName(Feature *feature)
52 {
53 (void)feature;
54 return PUB_SUB_FEATURE;
55 }
56
OnInitialize(Feature * feature,Service * parent,Identity identity)57 static void OnInitialize(Feature *feature, Service *parent, Identity identity)
58 {
59 (void)parent;
60 ((PubSubFeature *)feature)->identity = identity;
61 }
62
OnStop(Feature * feature,Identity identity)63 static void OnStop(Feature *feature, Identity identity)
64 {
65 (void)feature;
66 (void)identity;
67 }
68
OnMessage(Feature * feature,Request * request)69 static BOOL OnMessage(Feature *feature, Request *request)
70 {
71 PubSubFeature *broadcast = (PubSubFeature *)feature;
72 switch (request->msgId) {
73 case MSG_PUBLISH: {
74 Topic topic = request->msgValue;
75 Relation *relation = broadcast->GetRelation(broadcast, &topic);
76 if (relation == NULL) {
77 return FALSE;
78 }
79 MUTEX_Lock(broadcast->mutex);
80 ConsumerNode *item = NULL;
81 UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
82 if (item->consumer->identity == NULL) {
83 item->consumer->Notify(item->consumer, &topic, request);
84 }
85 }
86 MUTEX_Unlock(broadcast->mutex);
87 }
88 break;
89 default:
90 break;
91 }
92 return TRUE;
93 }
94
GetRelation(PubSubFeature * feature,const Topic * topic)95 static Relation *GetRelation(PubSubFeature *feature, const Topic *topic)
96 {
97 if (feature == NULL || topic == NULL) {
98 return NULL;
99 }
100
101 UTILS_DL_LIST *list = &feature->relations.node;
102 Relation *item = NULL;
103 MUTEX_Lock(feature->mutex);
104 UTILS_DL_LIST_FOR_EACH_ENTRY(item, list, Relation, node) {
105 if (IsTopicEqual(&item->topic, topic)) {
106 MUTEX_Unlock(feature->mutex);
107 return item;
108 }
109 }
110 MUTEX_Unlock(feature->mutex);
111 return NULL;
112 }
113
IsTopicEqual(const Topic * current,const Topic * other)114 static BOOL IsTopicEqual(const Topic *current, const Topic *other)
115 {
116 return *current == *other;
117 }
118