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