1 /*
2 * Copyright (C) 2021-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 "broadcast_manager.h"
17 #include "common_defs.h"
18 #include "device_auth_defines.h"
19 #include "hc_log.h"
20 #include "hc_mutex.h"
21 #include "hc_types.h"
22 #include "hc_vector.h"
23 #include "securec.h"
24
25 typedef struct {
26 char *appId;
27 DataChangeListener *listener;
28 } ListenerEntry;
29
30 DECLARE_HC_VECTOR(ListenerEntryVec, ListenerEntry);
31 IMPLEMENT_HC_VECTOR(ListenerEntryVec, ListenerEntry, 1);
32 static ListenerEntryVec g_listenerEntryVec;
33 static HcMutex *g_broadcastMutex = NULL;
34
PostOnGroupCreated(const char * messageStr)35 static void PostOnGroupCreated(const char *messageStr)
36 {
37 if (messageStr == NULL) {
38 LOGE("The messageStr is NULL!");
39 return;
40 }
41 uint32_t index;
42 ListenerEntry *entry = NULL;
43 (void)LockHcMutex(g_broadcastMutex);
44 FOR_EACH_HC_VECTOR(g_listenerEntryVec, index, entry) {
45 if (entry->listener->onGroupCreated != NULL) {
46 LOGI("[Broadcaster]: PostOnGroupCreated! [AppId]: %" LOG_PUB "s", entry->appId);
47 entry->listener->onGroupCreated(messageStr);
48 }
49 }
50 UnlockHcMutex(g_broadcastMutex);
51 }
52
PostOnGroupDeleted(const char * messageStr)53 static void PostOnGroupDeleted(const char *messageStr)
54 {
55 if (messageStr == NULL) {
56 LOGE("The messageStr is NULL!");
57 return;
58 }
59 uint32_t index;
60 ListenerEntry *entry = NULL;
61 (void)LockHcMutex(g_broadcastMutex);
62 FOR_EACH_HC_VECTOR(g_listenerEntryVec, index, entry) {
63 if (entry->listener->onGroupDeleted != NULL) {
64 LOGI("[Broadcaster]: PostOnGroupDeleted! [AppId]: %" LOG_PUB "s", entry->appId);
65 entry->listener->onGroupDeleted(messageStr);
66 }
67 }
68 UnlockHcMutex(g_broadcastMutex);
69 }
70
PostOnDeviceBound(const char * peerUdid,const char * messageStr)71 static void PostOnDeviceBound(const char *peerUdid, const char *messageStr)
72 {
73 if ((peerUdid == NULL) || (messageStr == NULL)) {
74 LOGE("The peerUdid or messageStr is NULL!");
75 return;
76 }
77 uint32_t index;
78 ListenerEntry *entry = NULL;
79 (void)LockHcMutex(g_broadcastMutex);
80 FOR_EACH_HC_VECTOR(g_listenerEntryVec, index, entry) {
81 if (entry->listener->onDeviceBound != NULL) {
82 LOGI("[Broadcaster]: PostOnDeviceBound! [AppId]: %" LOG_PUB "s", entry->appId);
83 entry->listener->onDeviceBound(peerUdid, messageStr);
84 }
85 }
86 UnlockHcMutex(g_broadcastMutex);
87 }
88
PostOnDeviceUnBound(const char * peerUdid,const char * messageStr)89 static void PostOnDeviceUnBound(const char *peerUdid, const char *messageStr)
90 {
91 if ((peerUdid == NULL) || (messageStr == NULL)) {
92 LOGE("The peerUdid or messageStr is NULL!");
93 return;
94 }
95 uint32_t index;
96 ListenerEntry *entry = NULL;
97 (void)LockHcMutex(g_broadcastMutex);
98 FOR_EACH_HC_VECTOR(g_listenerEntryVec, index, entry) {
99 if (entry->listener->onDeviceUnBound != NULL) {
100 LOGI("[Broadcaster]: PostOnDeviceUnBound! [AppId]: %" LOG_PUB "s", entry->appId);
101 entry->listener->onDeviceUnBound(peerUdid, messageStr);
102 }
103 }
104 UnlockHcMutex(g_broadcastMutex);
105 }
106
PostOnDeviceNotTrusted(const char * peerUdid)107 static void PostOnDeviceNotTrusted(const char *peerUdid)
108 {
109 if (peerUdid == NULL) {
110 LOGE("The peerUdid is NULL!");
111 return;
112 }
113 uint32_t index;
114 ListenerEntry *entry = NULL;
115 (void)LockHcMutex(g_broadcastMutex);
116 FOR_EACH_HC_VECTOR(g_listenerEntryVec, index, entry) {
117 if (entry->listener->onDeviceNotTrusted != NULL) {
118 LOGI("[Broadcaster]: PostOnDeviceNotTrusted! [AppId]: %" LOG_PUB "s", entry->appId);
119 entry->listener->onDeviceNotTrusted(peerUdid);
120 }
121 }
122 UnlockHcMutex(g_broadcastMutex);
123 }
124
PostOnLastGroupDeleted(const char * peerUdid,int groupType)125 static void PostOnLastGroupDeleted(const char *peerUdid, int groupType)
126 {
127 if (peerUdid == NULL) {
128 LOGE("The peerUdid is NULL!");
129 return;
130 }
131 uint32_t index;
132 ListenerEntry *entry = NULL;
133 (void)LockHcMutex(g_broadcastMutex);
134 FOR_EACH_HC_VECTOR(g_listenerEntryVec, index, entry) {
135 if (entry->listener->onLastGroupDeleted != NULL) {
136 LOGI("[Broadcaster]: PostOnLastGroupDeleted! [AppId]: %" LOG_PUB "s, [GroupType]: %" LOG_PUB "d",
137 entry->appId, groupType);
138 entry->listener->onLastGroupDeleted(peerUdid, groupType);
139 }
140 }
141 UnlockHcMutex(g_broadcastMutex);
142 }
143
PostOnTrustedDeviceNumChanged(int curTrustedDeviceNum)144 static void PostOnTrustedDeviceNumChanged(int curTrustedDeviceNum)
145 {
146 uint32_t index;
147 ListenerEntry *entry = NULL;
148 (void)LockHcMutex(g_broadcastMutex);
149 FOR_EACH_HC_VECTOR(g_listenerEntryVec, index, entry) {
150 if (entry->listener->onTrustedDeviceNumChanged != NULL) {
151 LOGI("[Broadcaster]: PostOnTrustedDeviceNumChanged! [AppId]: %" LOG_PUB "s", entry->appId);
152 entry->listener->onTrustedDeviceNumChanged(curTrustedDeviceNum);
153 }
154 }
155 UnlockHcMutex(g_broadcastMutex);
156 }
157
UpdateListenerIfExist(const char * appId,const DataChangeListener * listener)158 static int32_t UpdateListenerIfExist(const char *appId, const DataChangeListener *listener)
159 {
160 uint32_t index;
161 ListenerEntry *entry = NULL;
162 (void)LockHcMutex(g_broadcastMutex);
163 FOR_EACH_HC_VECTOR(g_listenerEntryVec, index, entry) {
164 if (strcmp(entry->appId, appId) == 0) {
165 if (memcpy_s(entry->listener, sizeof(DataChangeListener),
166 listener, sizeof(DataChangeListener)) != HC_SUCCESS) {
167 UnlockHcMutex(g_broadcastMutex);
168 LOGE("Failed to copy listener!");
169 return HC_ERR_MEMORY_COPY;
170 }
171 UnlockHcMutex(g_broadcastMutex);
172 LOGI("Successfully updated a listener. [AppId]: %" LOG_PUB "s", appId);
173 return HC_SUCCESS;
174 }
175 }
176 UnlockHcMutex(g_broadcastMutex);
177 return HC_ERR_LISTENER_NOT_EXIST;
178 }
179
AddListenerIfNotExist(const char * appId,const DataChangeListener * listener)180 static int32_t AddListenerIfNotExist(const char *appId, const DataChangeListener *listener)
181 {
182 uint32_t appIdLen = HcStrlen(appId) + 1;
183 char *copyAppId = (char *)HcMalloc(appIdLen, 0);
184 if (copyAppId == NULL) {
185 LOGE("Failed to allocate copyAppId memory!");
186 return HC_ERR_ALLOC_MEMORY;
187 }
188 if (strcpy_s(copyAppId, appIdLen, appId) != HC_SUCCESS) {
189 LOGE("Failed to copy appId!");
190 HcFree(copyAppId);
191 return HC_ERR_MEMORY_COPY;
192 }
193 DataChangeListener *copyListener = (DataChangeListener *)HcMalloc(sizeof(DataChangeListener), 0);
194 if (copyListener == NULL) {
195 LOGE("Failed to allocate saveCallback memory!");
196 HcFree(copyAppId);
197 return HC_ERR_ALLOC_MEMORY;
198 }
199 if (memcpy_s(copyListener, sizeof(DataChangeListener),
200 listener, sizeof(DataChangeListener)) != HC_SUCCESS) {
201 LOGE("Failed to copy listener!");
202 HcFree(copyAppId);
203 HcFree(copyListener);
204 return HC_ERR_MEMORY_COPY;
205 }
206 ListenerEntry entry;
207 entry.appId = copyAppId;
208 entry.listener = copyListener;
209 (void)LockHcMutex(g_broadcastMutex);
210 if (g_listenerEntryVec.pushBack(&g_listenerEntryVec, &entry) == NULL) {
211 LOGE("Failed to push listener entity!");
212 HcFree(copyAppId);
213 HcFree(copyListener);
214 UnlockHcMutex(g_broadcastMutex);
215 return HC_ERR_ALLOC_MEMORY;
216 }
217 UnlockHcMutex(g_broadcastMutex);
218 LOGI("Successfully added a listener. [AppId]: %" LOG_PUB "s", appId);
219 return HC_SUCCESS;
220 }
221
222 static Broadcaster g_broadcaster = {
223 .postOnGroupCreated = PostOnGroupCreated,
224 .postOnGroupDeleted = PostOnGroupDeleted,
225 .postOnDeviceBound = PostOnDeviceBound,
226 .postOnDeviceUnBound = PostOnDeviceUnBound,
227 .postOnDeviceNotTrusted = PostOnDeviceNotTrusted,
228 .postOnLastGroupDeleted = PostOnLastGroupDeleted,
229 .postOnTrustedDeviceNumChanged = PostOnTrustedDeviceNumChanged
230 };
231
IsBroadcastSupported(void)232 bool IsBroadcastSupported(void)
233 {
234 return true;
235 }
236
InitBroadcastManager(void)237 int32_t InitBroadcastManager(void)
238 {
239 if (g_broadcastMutex == NULL) {
240 g_broadcastMutex = (HcMutex *)HcMalloc(sizeof(HcMutex), 0);
241 if (g_broadcastMutex == NULL) {
242 LOGE("Failed to allocate broadcast mutex memory!");
243 return HC_ERR_ALLOC_MEMORY;
244 }
245 if (InitHcMutex(g_broadcastMutex, false) != HC_SUCCESS) {
246 LOGE("Init mutex failed");
247 HcFree(g_broadcastMutex);
248 g_broadcastMutex = NULL;
249 return HC_ERROR;
250 }
251 }
252 g_listenerEntryVec = CREATE_HC_VECTOR(ListenerEntryVec);
253 LOGI("[Broadcaster]: Init broadcast manager module successfully!");
254 return HC_SUCCESS;
255 }
256
DestroyBroadcastManager(void)257 void DestroyBroadcastManager(void)
258 {
259 uint32_t index;
260 ListenerEntry *entry = NULL;
261 (void)LockHcMutex(g_broadcastMutex);
262 FOR_EACH_HC_VECTOR(g_listenerEntryVec, index, entry) {
263 HcFree(entry->appId);
264 HcFree(entry->listener);
265 }
266 DESTROY_HC_VECTOR(ListenerEntryVec, &g_listenerEntryVec);
267 UnlockHcMutex(g_broadcastMutex);
268 DestroyHcMutex(g_broadcastMutex);
269 HcFree(g_broadcastMutex);
270 g_broadcastMutex = NULL;
271 }
272
GetBroadcaster(void)273 const Broadcaster *GetBroadcaster(void)
274 {
275 return &g_broadcaster;
276 }
277
AddListener(const char * appId,const DataChangeListener * listener)278 int32_t AddListener(const char *appId, const DataChangeListener *listener)
279 {
280 if ((appId == NULL) || (listener == NULL)) {
281 LOGE("The input appId or listener is NULL!");
282 return HC_ERR_INVALID_PARAMS;
283 }
284 if (UpdateListenerIfExist(appId, listener) == HC_SUCCESS) {
285 return HC_SUCCESS;
286 }
287 return AddListenerIfNotExist(appId, listener);
288 }
289
RemoveListener(const char * appId)290 int32_t RemoveListener(const char *appId)
291 {
292 if (appId == NULL) {
293 LOGE("The input appId is NULL!");
294 return HC_ERR_INVALID_PARAMS;
295 }
296 uint32_t index;
297 ListenerEntry *entry = NULL;
298 FOR_EACH_HC_VECTOR(g_listenerEntryVec, index, entry) {
299 if (strcmp(entry->appId, appId) == 0) {
300 HcFree(entry->appId);
301 HcFree(entry->listener);
302 ListenerEntry tempEntry;
303 HC_VECTOR_POPELEMENT(&g_listenerEntryVec, &tempEntry, index);
304 LOGI("Successfully removed a listener. [AppId]: %" LOG_PUB "s", appId);
305 return HC_SUCCESS;
306 }
307 }
308 LOGI("The listener does not exist! [AppId]: %" LOG_PUB "s", appId);
309 return HC_SUCCESS;
310 }
311