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