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