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