1 /*
2 * Copyright (C) 2021-2023 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 "peer_to_peer_group.h"
17
18 #include "alg_defs.h"
19 #include "callback_manager.h"
20 #include "channel_manager.h"
21 #include "data_manager.h"
22 #include "dev_auth_module_manager.h"
23 #include "group_operation_common.h"
24 #include "hc_dev_info.h"
25 #include "hc_log.h"
26 #include "hisysevent_adapter.h"
27 #include "hitrace_adapter.h"
28 #include "string_util.h"
29
IsSameNameGroupExist(int32_t osAccountId,const char * ownerName,const char * groupName)30 static bool IsSameNameGroupExist(int32_t osAccountId, const char *ownerName, const char *groupName)
31 {
32 QueryGroupParams queryParams = InitQueryGroupParams();
33 queryParams.ownerName = ownerName;
34 queryParams.groupName = groupName;
35 GroupEntryVec groupEntryVec = CreateGroupEntryVec();
36 int32_t result = QueryGroups(osAccountId, &queryParams, &groupEntryVec);
37 if (result != HC_SUCCESS) {
38 ClearGroupEntryVec(&groupEntryVec);
39 return result;
40 }
41 if (HC_VECTOR_SIZE(&groupEntryVec) > 0) {
42 ClearGroupEntryVec(&groupEntryVec);
43 return true;
44 }
45 ClearGroupEntryVec(&groupEntryVec);
46 return false;
47 }
48
CheckGroupName(int32_t osAccountId,const char * appId,const CJson * jsonParams)49 static int32_t CheckGroupName(int32_t osAccountId, const char *appId, const CJson *jsonParams)
50 {
51 const char *groupName = GetStringFromJson(jsonParams, FIELD_GROUP_NAME);
52 if (groupName == NULL) {
53 LOGE("Failed to get groupName from jsonParams!");
54 return HC_ERR_JSON_GET;
55 }
56
57 if (IsSameNameGroupExist(osAccountId, appId, groupName)) {
58 LOGE("A group with the same group name has been created! [AppId]: %s, [GroupName]: %s", appId, groupName);
59 return HC_ERR_INVALID_PARAMS;
60 }
61 return HC_SUCCESS;
62 }
63
GenerateGroupId(const char * groupName,const char * appId,char ** returnGroupId)64 static int32_t GenerateGroupId(const char *groupName, const char *appId, char **returnGroupId)
65 {
66 /* peer to peer group: groupId = sha256(groupName | appId) */
67 uint8_t *hashMessage = NULL;
68 uint32_t messageSize = 0;
69 Uint8Buff groupNameBuff = {(uint8_t *)groupName, HcStrlen(groupName)};
70 Uint8Buff appIdBuff = {(uint8_t *)appId, HcStrlen(appId)};
71 int32_t result = GetHashMessage(&groupNameBuff, &appIdBuff, &hashMessage, &messageSize);
72 if (result != HC_SUCCESS) {
73 return result;
74 }
75 int hashStrLen = SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH + 1;
76 *returnGroupId = (char *)HcMalloc(hashStrLen, 0);
77 if (*returnGroupId == NULL) {
78 LOGE("Failed to allocate returnGroupId memory!");
79 HcFree(hashMessage);
80 return HC_ERR_ALLOC_MEMORY;
81 }
82 result = GetHashResult(hashMessage, messageSize, *returnGroupId, hashStrLen);
83 HcFree(hashMessage);
84 if (result != HC_SUCCESS) {
85 LOGE("Failed to get hash for groupId! [AppId]: %s, [GroupName]: %s", appId, groupName);
86 HcFree(*returnGroupId);
87 *returnGroupId = NULL;
88 return HC_ERR_HASH_FAIL;
89 }
90 return HC_SUCCESS;
91 }
92
GeneratePeerToPeerGroupId(const CJson * jsonParams,char ** returnGroupId)93 static int32_t GeneratePeerToPeerGroupId(const CJson *jsonParams, char **returnGroupId)
94 {
95 const char *groupName = GetStringFromJson(jsonParams, FIELD_GROUP_NAME);
96 if (groupName == NULL) {
97 LOGE("Failed to get groupName from jsonParams!");
98 return HC_ERR_JSON_GET;
99 }
100 const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
101 if (appId == NULL) {
102 LOGE("Failed to get appId from jsonParams!");
103 return HC_ERR_JSON_GET;
104 }
105 int32_t result = GenerateGroupId(groupName, appId, returnGroupId);
106 if (result != HC_SUCCESS) {
107 LOGE("Failed to generate groupId! [GroupName]: %s, [AppId]: %s", groupName, appId);
108 return result;
109 }
110 return HC_SUCCESS;
111 }
112
CheckCreateParams(int32_t osAccountId,const CJson * jsonParams)113 static int32_t CheckCreateParams(int32_t osAccountId, const CJson *jsonParams)
114 {
115 const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
116 if (appId == NULL) {
117 LOGE("Failed to get appId from jsonParams!");
118 return HC_ERR_JSON_GET;
119 }
120 int32_t result;
121 if (((result = CheckGroupName(osAccountId, appId, jsonParams)) != HC_SUCCESS) ||
122 ((result = CheckUserTypeIfExist(jsonParams)) != HC_SUCCESS) ||
123 ((result = CheckGroupVisibilityIfExist(jsonParams)) != HC_SUCCESS) ||
124 ((result = CheckExpireTimeIfExist(jsonParams)) != HC_SUCCESS) ||
125 ((result = CheckGroupNumLimit(osAccountId, PEER_TO_PEER_GROUP, appId)) != HC_SUCCESS)) {
126 return result;
127 }
128 return HC_SUCCESS;
129 }
130
GenerateGroupParams(const CJson * jsonParams,const char * groupId,TrustedGroupEntry * groupParams)131 static int32_t GenerateGroupParams(const CJson *jsonParams, const char *groupId, TrustedGroupEntry *groupParams)
132 {
133 const char *groupName = GetStringFromJson(jsonParams, FIELD_GROUP_NAME);
134 if (groupName == NULL) {
135 LOGE("Failed to get groupName from jsonParams!");
136 return HC_ERR_JSON_GET;
137 }
138 const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
139 if (appId == NULL) {
140 LOGE("Failed to get appId from jsonParams!");
141 return HC_ERR_JSON_GET;
142 }
143 int32_t result;
144 if (((result = AddGroupTypeToParams(PEER_TO_PEER_GROUP, groupParams)) != HC_SUCCESS) ||
145 ((result = AddGroupNameToParams(groupName, groupParams)) != HC_SUCCESS) ||
146 ((result = AddGroupIdToParams(groupId, groupParams)) != HC_SUCCESS) ||
147 ((result = AddGroupOwnerToParams(appId, groupParams)) != HC_SUCCESS) ||
148 ((result = AddGroupVisibilityOrDefault(jsonParams, groupParams)) != HC_SUCCESS) ||
149 ((result = AddExpireTimeOrDefault(jsonParams, groupParams)) != HC_SUCCESS)) {
150 return result;
151 }
152 return HC_SUCCESS;
153 }
154
GenerateDevParams(const CJson * jsonParams,const char * groupId,TrustedDeviceEntry * devParams)155 static int32_t GenerateDevParams(const CJson *jsonParams, const char *groupId, TrustedDeviceEntry *devParams)
156 {
157 int32_t result;
158 if (((result = AddSelfUdidToParams(devParams)) != HC_SUCCESS) ||
159 ((result = AddAuthIdToParamsOrDefault(jsonParams, devParams)) != HC_SUCCESS) ||
160 ((result = AddSourceToParams(SELF_CREATED, devParams)) != HC_SUCCESS) ||
161 ((result = AddUserTypeToParamsOrDefault(jsonParams, devParams)) != HC_SUCCESS) ||
162 ((result = AddGroupIdToDevParams(groupId, devParams)) != HC_SUCCESS) ||
163 ((result = AddServiceTypeToParams(groupId, devParams)) != HC_SUCCESS)) {
164 return result;
165 }
166 return HC_SUCCESS;
167 }
168
CreateGroupInner(int32_t osAccountId,const CJson * jsonParams,char ** returnGroupId)169 static int32_t CreateGroupInner(int32_t osAccountId, const CJson *jsonParams, char **returnGroupId)
170 {
171 char *groupId = NULL;
172 int32_t result;
173 if (((result = CheckCreateParams(osAccountId, jsonParams)) != HC_SUCCESS) ||
174 ((result = GeneratePeerToPeerGroupId(jsonParams, &groupId)) != HC_SUCCESS) ||
175 ((result = ProcessKeyPair(osAccountId, CREATE_KEY_PAIR, jsonParams, groupId)) != HC_SUCCESS) ||
176 ((result = AddGroupToDatabaseByJson(osAccountId, GenerateGroupParams, jsonParams, groupId)) != HC_SUCCESS) ||
177 ((result = AddDeviceToDatabaseByJson(osAccountId, GenerateDevParams, jsonParams, groupId)) != HC_SUCCESS) ||
178 ((result = SaveOsAccountDb(osAccountId)) != HC_SUCCESS)) {
179 HcFree(groupId);
180 return result;
181 }
182 *returnGroupId = groupId;
183 return HC_SUCCESS;
184 }
185
GetPeerDevUserTypeFromDb(int32_t osAccountId,const char * groupId,const char * peerAuthId)186 static int32_t GetPeerDevUserTypeFromDb(int32_t osAccountId, const char *groupId, const char *peerAuthId)
187 {
188 int peerUserType = DEVICE_TYPE_ACCESSORY;
189 TrustedDeviceEntry *devAuthParams = CreateDeviceEntry();
190 if (devAuthParams == NULL) {
191 LOGE("Failed to allocate devEntry memory!");
192 return peerUserType;
193 }
194 if (GetTrustedDevInfoById(osAccountId, peerAuthId, false, groupId, devAuthParams) != HC_SUCCESS) {
195 LOGE("Failed to obtain the device information from the database!");
196 DestroyDeviceEntry(devAuthParams);
197 return peerUserType;
198 }
199 peerUserType = devAuthParams->devType;
200 DestroyDeviceEntry(devAuthParams);
201 return peerUserType;
202 }
203
DelPeerDevAndKeyInfo(int32_t osAccountId,const char * groupId,const char * peerAuthId)204 static int32_t DelPeerDevAndKeyInfo(int32_t osAccountId, const char *groupId, const char *peerAuthId)
205 {
206 int32_t peerUserType = GetPeerDevUserTypeFromDb(osAccountId, groupId, peerAuthId);
207 QueryDeviceParams queryDeviceParams = InitQueryDeviceParams();
208 queryDeviceParams.groupId = groupId;
209 queryDeviceParams.authId = peerAuthId;
210 int32_t result = DelTrustedDevice(osAccountId, &queryDeviceParams);
211 if (result != HC_SUCCESS) {
212 LOGE("Failed to delete peer device from database!");
213 return result;
214 }
215 /* Use the DeviceGroupManager package name. */
216 const char *appId = GROUP_MANAGER_PACKAGE_NAME;
217 Uint8Buff peerAuthIdBuff = {
218 .val = (uint8_t *)peerAuthId,
219 .length = HcStrlen(peerAuthId)
220 };
221 /*
222 * If the trusted device has been deleted from the database but the peer key fails to be deleted,
223 * the forcible unbinding is still considered successful. Only logs need to be printed.
224 */
225 AuthModuleParams params = {
226 .osAccountId = osAccountId,
227 .pkgName = appId,
228 .serviceType = groupId,
229 .authId = &peerAuthIdBuff,
230 .userType = peerUserType
231 };
232 result = DeletePeerAuthInfo(¶ms, DAS_MODULE);
233 if (result != HC_SUCCESS) {
234 LOGD("delete peer key fail! res: %d", result);
235 } else {
236 LOGD("delete peer key success!");
237 }
238 return HC_SUCCESS;
239 }
240
DelAllPeerDevAndKeyInfo(int32_t osAccountId,const char * groupId)241 static int32_t DelAllPeerDevAndKeyInfo(int32_t osAccountId, const char *groupId)
242 {
243 QueryDeviceParams queryParams = InitQueryDeviceParams();
244 queryParams.groupId = groupId;
245 DeviceEntryVec deviceEntryVec = CreateDeviceEntryVec();
246 int32_t result = QueryDevices(osAccountId, &queryParams, &deviceEntryVec);
247 if (result != HC_SUCCESS) {
248 ClearDeviceEntryVec(&deviceEntryVec);
249 return result;
250 }
251 uint32_t index;
252 TrustedDeviceEntry **entryPtr = NULL;
253 FOR_EACH_HC_VECTOR(deviceEntryVec, index, entryPtr) {
254 TrustedDeviceEntry *entry = (TrustedDeviceEntry *)(*entryPtr);
255 if (IsLocalDevice(StringGet(&entry->udid))) {
256 continue;
257 }
258 result = DelPeerDevAndKeyInfo(osAccountId, groupId, StringGet(&entry->authId));
259 if (result != HC_SUCCESS) {
260 ClearDeviceEntryVec(&deviceEntryVec);
261 return result;
262 }
263 }
264 ClearDeviceEntryVec(&deviceEntryVec);
265 return HC_SUCCESS;
266 }
267
AddAuthIdAndUserTypeToParams(int32_t osAccountId,const char * groupId,CJson * jsonParams)268 static int32_t AddAuthIdAndUserTypeToParams(int32_t osAccountId, const char *groupId, CJson *jsonParams)
269 {
270 TrustedDeviceEntry *deviceInfo = CreateDeviceEntry();
271 if (deviceInfo == NULL) {
272 LOGE("Failed to allocate deviceInfo memory!");
273 return HC_ERR_ALLOC_MEMORY;
274 }
275
276 char localUdid[INPUT_UDID_LEN] = { 0 };
277 int32_t res = HcGetUdid((uint8_t *)localUdid, INPUT_UDID_LEN);
278 if (res != HC_SUCCESS) {
279 LOGE("Failed to get local udid! res: %d", res);
280 DestroyDeviceEntry(deviceInfo);
281 return HC_ERR_DB;
282 }
283
284 if (GetTrustedDevInfoById(osAccountId, localUdid, true, groupId, deviceInfo) != HC_SUCCESS) {
285 LOGE("No local device information found in the group, udid changed.");
286 DestroyDeviceEntry(deviceInfo);
287 return HC_ERR_DB;
288 }
289
290 if (AddStringToJson(jsonParams, FIELD_DEVICE_ID, StringGet(&deviceInfo->authId)) != HC_SUCCESS) {
291 LOGE("Failed to add authId to params!");
292 DestroyDeviceEntry(deviceInfo);
293 return HC_ERR_JSON_FAIL;
294 }
295 if (AddIntToJson(jsonParams, FIELD_USER_TYPE, deviceInfo->devType) != HC_SUCCESS) {
296 LOGE("Failed to add userType to params!");
297 DestroyDeviceEntry(deviceInfo);
298 return HC_ERR_JSON_FAIL;
299 }
300 DestroyDeviceEntry(deviceInfo);
301 return HC_SUCCESS;
302 }
303
DelGroupAndSelfKeyInfo(int32_t osAccountId,const char * groupId,CJson * jsonParams)304 static int32_t DelGroupAndSelfKeyInfo(int32_t osAccountId, const char *groupId, CJson *jsonParams)
305 {
306 int32_t result = DelGroupFromDb(osAccountId, groupId);
307 if (result != HC_SUCCESS) {
308 return result;
309 }
310 /*
311 * If the group has been disbanded from the database but the key pair fails to be deleted,
312 * we still believe we succeeded in disbanding the group. Only logs need to be printed.
313 */
314 result = AddAuthIdAndUserTypeToParams(osAccountId, groupId, jsonParams);
315 if (result == HC_SUCCESS) {
316 result = ProcessKeyPair(osAccountId, DELETE_KEY_PAIR, jsonParams, groupId);
317 }
318 if (result != HC_SUCCESS) {
319 LOGW("delete self key fail! res: %d", result);
320 } else {
321 LOGI("delete self key success!");
322 }
323 return HC_SUCCESS;
324 }
325
HandleLocalUnbind(int64_t requestId,const CJson * jsonParams,const DeviceAuthCallback * callback)326 static int32_t HandleLocalUnbind(int64_t requestId, const CJson *jsonParams,
327 const DeviceAuthCallback *callback)
328 {
329 const char *peerAuthId = GetStringFromJson(jsonParams, FIELD_DELETE_ID);
330 if (peerAuthId == NULL) {
331 LOGE("Failed to get peerAuthId from jsonParams!");
332 return HC_ERR_JSON_GET;
333 }
334 const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
335 if (groupId == NULL) {
336 LOGE("Failed to get groupId from jsonParams!");
337 return HC_ERR_JSON_GET;
338 }
339 int32_t osAccountId;
340 if (GetIntFromJson(jsonParams, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
341 LOGE("Failed to get osAccountId from jsonParams!");
342 return HC_ERR_JSON_GET;
343 }
344 int result = DelPeerDevAndKeyInfo(osAccountId, groupId, peerAuthId);
345 if (result != HC_SUCCESS) {
346 return result;
347 }
348 result = SaveOsAccountDb(osAccountId);
349 if (result != HC_SUCCESS) {
350 LOGE("Failed to save osAccountDb!");
351 return result;
352 }
353 char *returnDataStr = NULL;
354 result = GenerateUnbindSuccessData(peerAuthId, groupId, &returnDataStr);
355 if (result != HC_SUCCESS) {
356 return result;
357 }
358 ProcessFinishCallback(requestId, MEMBER_DELETE, returnDataStr, callback);
359 FreeJsonString(returnDataStr);
360 return HC_SUCCESS;
361 }
362
CheckPeerDeviceStatus(int32_t osAccountId,const char * groupId,const CJson * jsonParams)363 static int32_t CheckPeerDeviceStatus(int32_t osAccountId, const char *groupId, const CJson *jsonParams)
364 {
365 const char *peerAuthId = GetStringFromJson(jsonParams, FIELD_DELETE_ID);
366 if (peerAuthId == NULL) {
367 LOGE("Failed to get peerAuthId from jsonParams!");
368 return HC_ERR_JSON_GET;
369 }
370 PRINT_SENSITIVE_DATA("PeerAuthId", peerAuthId);
371 TrustedDeviceEntry *deviceInfo = CreateDeviceEntry();
372 if (deviceInfo == NULL) {
373 LOGE("Failed to allocate deviceInfo memory!");
374 return HC_ERR_ALLOC_MEMORY;
375 }
376 int32_t result = GetTrustedDevInfoById(osAccountId, peerAuthId, false, groupId, deviceInfo);
377 if (result != HC_SUCCESS) {
378 LOGE("Failed to obtain the peer device information from the database!");
379 DestroyDeviceEntry(deviceInfo);
380 return result;
381 }
382 result = AssertPeerDeviceNotSelf(StringGet(&deviceInfo->udid));
383 DestroyDeviceEntry(deviceInfo);
384 return result;
385 }
386
CheckDeletePeerStatus(const CJson * jsonParams)387 static int32_t CheckDeletePeerStatus(const CJson *jsonParams)
388 {
389 const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
390 if (groupId == NULL) {
391 LOGE("Failed to get groupId from jsonParams!");
392 return HC_ERR_JSON_GET;
393 }
394 const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
395 if (appId == NULL) {
396 LOGE("Failed to get appId from jsonParams!");
397 return HC_ERR_JSON_GET;
398 }
399 int32_t osAccountId;
400 if (GetIntFromJson(jsonParams, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
401 LOGE("Failed to get osAccountId from jsonParams!");
402 return HC_ERR_JSON_GET;
403 }
404
405 uint32_t groupType = PEER_TO_PEER_GROUP;
406 int32_t result;
407 if (((result = CheckGroupExist(osAccountId, groupId)) != HC_SUCCESS) ||
408 ((result = GetGroupTypeFromDb(osAccountId, groupId, &groupType)) != HC_SUCCESS) ||
409 ((result = AssertGroupTypeMatch(groupType, PEER_TO_PEER_GROUP)) != HC_SUCCESS) ||
410 ((result = CheckPermForGroup(osAccountId, MEMBER_DELETE, appId, groupId)) != HC_SUCCESS) ||
411 ((result = CheckPeerDeviceStatus(osAccountId, groupId, jsonParams)) != HC_SUCCESS)) {
412 return result;
413 }
414 return HC_SUCCESS;
415 }
416
IsLocalForceUnbind(const CJson * jsonParams)417 static bool IsLocalForceUnbind(const CJson *jsonParams)
418 {
419 bool isForceDelete = false;
420 (void)GetBoolFromJson(jsonParams, FIELD_IS_FORCE_DELETE, &isForceDelete);
421 bool isIgnoreChannel = false;
422 (void)GetBoolFromJson(jsonParams, FIELD_IS_IGNORE_CHANNEL, &isIgnoreChannel);
423 return (isForceDelete && isIgnoreChannel);
424 }
425
CreateGroup(int32_t osAccountId,CJson * jsonParams,char ** returnJsonStr)426 static int32_t CreateGroup(int32_t osAccountId, CJson *jsonParams, char **returnJsonStr)
427 {
428 LOGI("[Start]: Start to create a peer to peer group!");
429 if ((jsonParams == NULL) || (returnJsonStr == NULL)) {
430 LOGE("The input parameters contains NULL value!");
431 return HC_ERR_INVALID_PARAMS;
432 }
433 char *groupId = NULL;
434 int32_t result = CreateGroupInner(osAccountId, jsonParams, &groupId);
435 if (result != HC_SUCCESS) {
436 return result;
437 }
438 result = ConvertGroupIdToJsonStr(groupId, returnJsonStr);
439 HcFree(groupId);
440 if (result != HC_SUCCESS) {
441 return result;
442 }
443 LOGI("[End]: Create a peer to peer group successfully!");
444 return HC_SUCCESS;
445 }
446
DeleteGroup(int32_t osAccountId,CJson * jsonParams,char ** returnJsonStr)447 static int32_t DeleteGroup(int32_t osAccountId, CJson *jsonParams, char **returnJsonStr)
448 {
449 LOGI("[Start]: Start to delete a peer to peer group!");
450 if ((jsonParams == NULL) || (returnJsonStr == NULL)) {
451 LOGE("The input parameters contains NULL value!");
452 return HC_ERR_INVALID_PARAMS;
453 }
454 int32_t result;
455 const char *groupId = NULL;
456 if (((result = GetGroupIdFromJson(jsonParams, &groupId)) != HC_SUCCESS) ||
457 ((result = DelAllPeerDevAndKeyInfo(osAccountId, groupId)) != HC_SUCCESS) ||
458 ((result = DelGroupAndSelfKeyInfo(osAccountId, groupId, jsonParams)) != HC_SUCCESS) ||
459 ((result = ConvertGroupIdToJsonStr(groupId, returnJsonStr)) != HC_SUCCESS)) {
460 return result;
461 }
462 LOGI("[End]: Delete a peer to peer group successfully!");
463 return HC_SUCCESS;
464 }
465
DeleteMemberFromGroup(int32_t osAccountId,int64_t requestId,CJson * jsonParams,const DeviceAuthCallback * callback)466 static int32_t DeleteMemberFromGroup(int32_t osAccountId, int64_t requestId, CJson *jsonParams,
467 const DeviceAuthCallback *callback)
468 {
469 LOGI("[Start]: Start to delete member from a peer to peer group!");
470 if ((jsonParams == NULL) || (callback == NULL)) {
471 LOGE("The input parameters contains NULL value!");
472 return HC_ERR_INVALID_PARAMS;
473 }
474 AddIntToJson(jsonParams, FIELD_OS_ACCOUNT_ID, osAccountId);
475 int32_t result = CheckDeletePeerStatus(jsonParams);
476 if (result != HC_SUCCESS) {
477 ProcessErrorCallback(requestId, MEMBER_DELETE, result, NULL, callback);
478 return result;
479 }
480 if (!IsLocalForceUnbind(jsonParams)) {
481 ProcessErrorCallback(requestId, MEMBER_DELETE, HC_ERR_INVALID_PARAMS, NULL, callback);
482 return HC_ERR_INVALID_PARAMS;
483 }
484 result = HandleLocalUnbind(requestId, jsonParams, callback);
485 if (result != HC_SUCCESS) {
486 ProcessErrorCallback(requestId, MEMBER_DELETE, result, NULL, callback);
487 }
488 return result;
489 }
490
491 static PeerToPeerGroup g_peerToPeerGroup = {
492 .base.type = PEER_TO_PEER_GROUP,
493 .base.createGroup = CreateGroup,
494 .base.deleteGroup = DeleteGroup,
495 .deleteMember = DeleteMemberFromGroup,
496 };
497
GetPeerToPeerGroupInstance(void)498 BaseGroup *GetPeerToPeerGroupInstance(void)
499 {
500 return (BaseGroup *)&g_peerToPeerGroup;
501 }
502
IsPeerToPeerGroupSupported(void)503 bool IsPeerToPeerGroupSupported(void)
504 {
505 return true;
506 }
507