• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "bind_session_server.h"
17 #include "bind_session_common_util.h"
18 #include "callback_manager.h"
19 #include "channel_manager.h"
20 #include "das_module_defines.h"
21 #include "group_operation_common.h"
22 #include "hc_log.h"
23 #include "os_account_adapter.h"
24 #include "session_manager.h"
25 
AddRecvModuleDataToParams(CJson * jsonParams,CJson * moduleParams)26 static int32_t AddRecvModuleDataToParams(CJson *jsonParams, CJson *moduleParams)
27 {
28     int32_t message = ERR_MESSAGE;
29     if (GetIntFromJson(jsonParams, FIELD_MESSAGE, &message) != HC_SUCCESS) {
30         LOGE("Failed to get message from in!");
31         return HC_ERR_JSON_GET;
32     }
33     int32_t authForm = AUTH_FORM_INVALID_TYPE;
34     (void)GetIntFromJson(jsonParams, FIELD_AUTH_FORM, &authForm);
35     CJson *payload = GetObjFromJson(jsonParams, FIELD_PAYLOAD);
36     if (payload == NULL) {
37         LOGE("Failed to get payload from in!");
38         return HC_ERR_JSON_GET;
39     }
40     if (AddIntToJson(moduleParams, FIELD_MESSAGE, message) != HC_SUCCESS) {
41         LOGE("Failed to add message to moduleParams!");
42         return HC_ERR_JSON_FAIL;
43     }
44     if (AddIntToJson(moduleParams, FIELD_AUTH_FORM, authForm) != HC_SUCCESS) {
45         LOGE("Failed to add authForm to moduleParams!");
46         return HC_ERR_JSON_FAIL;
47     }
48     if (AddObjToJson(moduleParams, FIELD_PAYLOAD, payload) != HC_SUCCESS) {
49         LOGE("Failed to add payload to moduleParams!");
50         return HC_ERR_JSON_FAIL;
51     }
52     return HC_SUCCESS;
53 }
54 
AddConfirmationToParams(CJson * moduleParams)55 static int32_t AddConfirmationToParams(CJson *moduleParams)
56 {
57     if (AddIntToJson(moduleParams, FIELD_CONFIRMATION, REQUEST_ACCEPTED) != HC_SUCCESS) {
58         LOGE("Failed to add confirmation to moduleParams!");
59         return HC_ERR_JSON_FAIL;
60     }
61     return HC_SUCCESS;
62 }
63 
GenerateServerModuleParams(BindSession * session,CJson * jsonParams,CJson * moduleParams)64 static int32_t GenerateServerModuleParams(BindSession *session, CJson *jsonParams, CJson *moduleParams)
65 {
66     int32_t result;
67     if (((result = GenerateBasicModuleParams(false, session, moduleParams)) != HC_SUCCESS) ||
68         ((result = AddConfirmationToParams(moduleParams)) != HC_SUCCESS) ||
69         ((result = AddRecvModuleDataToParams(jsonParams, moduleParams)) != HC_SUCCESS)) {
70         return result;
71     }
72     return HC_SUCCESS;
73 }
74 
GetServerModuleReturnData(BindSession * session,CJson * jsonParams,CJson * out,bool * isNeedInform)75 static int32_t GetServerModuleReturnData(BindSession *session, CJson *jsonParams, CJson *out, bool *isNeedInform)
76 {
77     CJson *moduleParams = CreateJson();
78     if (moduleParams == NULL) {
79         LOGE("Failed to allocate moduleParams memory!");
80         return HC_ERR_JSON_FAIL;
81     }
82 
83     int32_t result = GenerateServerModuleParams(session, jsonParams, moduleParams);
84     if (result != HC_SUCCESS) {
85         LOGE("Failed to generate all params sent to the module!");
86         FreeJson(moduleParams);
87         return result;
88     }
89     /* Release the memory in advance to reduce the memory usage. */
90     DeleteAllItem(jsonParams);
91 
92     result = CreateAndProcessModule(session, moduleParams, out);
93     FreeJson(moduleParams);
94     if (result != HC_SUCCESS) {
95         *isNeedInform = false;
96         InformPeerModuleError(out, session);
97         return result;
98     }
99     return HC_SUCCESS;
100 }
101 
PrepareData(BindSession * session,CJson * jsonParams,CJson ** sendData,bool * isNeedInform)102 static int32_t PrepareData(BindSession *session, CJson *jsonParams, CJson **sendData, bool *isNeedInform)
103 {
104     CJson *out = CreateJson();
105     if (out == NULL) {
106         LOGE("Failed to allocate out memory!");
107         return HC_ERR_JSON_FAIL;
108     }
109 
110     int32_t result = GetServerModuleReturnData(session, jsonParams, out, isNeedInform);
111     if (result != HC_SUCCESS) {
112         FreeJson(out);
113         return result;
114     }
115 
116     *sendData = DetachItemFromJson(out, FIELD_SEND_TO_PEER);
117     FreeJson(out);
118     if (*sendData == NULL) {
119         LOGE("Failed to get sendToPeer from out!");
120         return HC_ERR_JSON_GET;
121     }
122 
123     result = AddInfoToSendData((session->opCode == MEMBER_JOIN), session, *sendData);
124     if (result != HC_SUCCESS) {
125         LOGE("Failed to add information to sendData!");
126         FreeJson(*sendData);
127         *sendData = NULL;
128         return result;
129     }
130     return HC_SUCCESS;
131 }
132 
PrepareAndSendDataServer(BindSession * session,CJson * jsonParams,bool * isNeedInform)133 static int32_t PrepareAndSendDataServer(BindSession *session, CJson *jsonParams, bool *isNeedInform)
134 {
135     CJson *sendData = NULL;
136     int32_t result = PrepareData(session, jsonParams, &sendData, isNeedInform);
137     if (result != HC_SUCCESS) {
138         return result;
139     }
140 
141     result = SendBindSessionData(session, sendData);
142     FreeJson(sendData);
143     return result;
144 }
145 
GenerateRequestParams(const CJson * jsonParams,CJson * requestParams)146 static int32_t GenerateRequestParams(const CJson *jsonParams, CJson *requestParams)
147 {
148     const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
149     if (groupId == NULL) {
150         LOGE("Failed to get groupId from jsonParams!");
151         return HC_ERR_JSON_GET;
152     }
153     const char *peerAuthId = GetStringFromJson(jsonParams, FIELD_PEER_DEVICE_ID);
154     if (peerAuthId == NULL) {
155         LOGE("Failed to get peerAuthId from jsonParams!");
156         return HC_ERR_JSON_GET;
157     }
158     const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
159     if (appId == NULL) {
160         LOGE("Failed to get appId from jsonParams!");
161         return HC_ERR_JSON_GET;
162     }
163     int32_t groupType = PEER_TO_PEER_GROUP;
164     if (GetIntFromJson(jsonParams, FIELD_GROUP_TYPE, &groupType) != HC_SUCCESS) {
165         LOGE("Failed to get groupType from jsonParams!");
166         return HC_ERR_JSON_GET;
167     }
168     if (AddStringToJson(requestParams, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
169         LOGE("Failed to add groupId to requestParams!");
170         return HC_ERR_JSON_FAIL;
171     }
172     if (AddIntToJson(requestParams, FIELD_GROUP_TYPE, groupType) != HC_SUCCESS) {
173         LOGE("Failed to add groupType to requestParams!");
174         return HC_ERR_JSON_FAIL;
175     }
176     if (AddStringToJson(requestParams, FIELD_PEER_DEVICE_ID, peerAuthId) != HC_SUCCESS) {
177         LOGE("Failed to add peerDeviceId to requestParams!");
178         return HC_ERR_JSON_FAIL;
179     }
180     if (AddStringToJson(requestParams, FIELD_APP_ID, appId) != HC_SUCCESS) {
181         LOGE("Failed to add appId to requestParams!");
182         return HC_ERR_JSON_FAIL;
183     }
184     return HC_SUCCESS;
185 }
186 
RequestConfirmation(const CJson * jsonParams,const BindSession * session,char ** returnStr)187 static int32_t RequestConfirmation(const CJson *jsonParams, const BindSession *session, char **returnStr)
188 {
189     CJson *requestParams = CreateJson();
190     if (requestParams == NULL) {
191         LOGE("Failed to create json object!");
192         return HC_ERR_JSON_FAIL;
193     }
194     int32_t result = GenerateRequestParams(jsonParams, requestParams);
195     if (result != HC_SUCCESS) {
196         LOGE("An error occurs when the request parameters are generated!");
197         FreeJson(requestParams);
198         return result;
199     }
200     char *requestParamsStr = PackJsonToString(requestParams);
201     FreeJson(requestParams);
202     if (requestParamsStr == NULL) {
203         LOGE("An error occurred when converting JSON data to String data.!");
204         return HC_ERR_JSON_FAIL;
205     }
206     char *returnDataStr = ProcessRequestCallback(session->reqId, session->opCode,
207         requestParamsStr, session->base.callback);
208     FreeJsonString(requestParamsStr);
209     if (returnDataStr == NULL) {
210         LOGE("The OnRequest callback is fail!");
211         return HC_ERR_REQ_REJECTED;
212     }
213     *returnStr = returnDataStr;
214     return HC_SUCCESS;
215 }
216 
AddAuthIdIfExist(const CJson * returnData,CJson * jsonParams)217 static int32_t AddAuthIdIfExist(const CJson *returnData, CJson *jsonParams)
218 {
219     const char *authId = GetStringFromJson(returnData, FIELD_DEVICE_ID);
220     if (authId != NULL) {
221         if (AddStringToJson(jsonParams, FIELD_DEVICE_ID, authId) != HC_SUCCESS) {
222             LOGE("Failed to add authId to jsonParams!");
223             return HC_ERR_JSON_FAIL;
224         }
225     }
226     return HC_SUCCESS;
227 }
228 
AddUserTypeIfExistAndValid(const CJson * returnData,CJson * jsonParams)229 static int32_t AddUserTypeIfExistAndValid(const CJson *returnData, CJson *jsonParams)
230 {
231     int32_t userType = DEVICE_TYPE_ACCESSORY;
232     if (GetIntFromJson(returnData, FIELD_USER_TYPE, &userType) == HC_SUCCESS) {
233         if (!IsUserTypeValid(userType)) {
234             LOGE("The input userType is invalid!");
235             return HC_ERR_INVALID_PARAMS;
236         }
237         if (AddIntToJson(jsonParams, FIELD_USER_TYPE, userType) != HC_SUCCESS) {
238             LOGE("Failed to add userType to jsonParams!");
239             return HC_ERR_JSON_FAIL;
240         }
241     }
242     return HC_SUCCESS;
243 }
244 
AddGroupVisibilityIfExistAndValid(const CJson * returnData,CJson * jsonParams)245 static int32_t AddGroupVisibilityIfExistAndValid(const CJson *returnData, CJson *jsonParams)
246 {
247     int32_t groupVisibility = GROUP_VISIBILITY_PUBLIC;
248     if (GetIntFromJson(returnData, FIELD_GROUP_VISIBILITY, &groupVisibility) == HC_SUCCESS) {
249         if (!IsGroupVisibilityValid(groupVisibility)) {
250             LOGE("The input groupVisibility invalid!");
251             return HC_ERR_INVALID_PARAMS;
252         }
253         if (AddIntToJson(jsonParams, FIELD_GROUP_VISIBILITY, groupVisibility) != HC_SUCCESS) {
254             LOGE("Failed to add groupVisibility to jsonParams!");
255             return HC_ERR_JSON_FAIL;
256         }
257     }
258     return HC_SUCCESS;
259 }
260 
AddExpireTimeIfExistAndValid(const CJson * returnData,CJson * jsonParams)261 static int32_t AddExpireTimeIfExistAndValid(const CJson *returnData, CJson *jsonParams)
262 {
263     int32_t expireTime = DEFAULT_EXPIRE_TIME;
264     if (GetIntFromJson(returnData, FIELD_EXPIRE_TIME, &expireTime) == HC_SUCCESS) {
265         if (!IsExpireTimeValid(expireTime)) {
266             LOGE("The input expireTime invalid!");
267             return HC_ERR_INVALID_PARAMS;
268         }
269         if (AddIntToJson(jsonParams, FIELD_EXPIRE_TIME, expireTime) != HC_SUCCESS) {
270             LOGE("Failed to add expireTime to jsonParams!");
271             return HC_ERR_JSON_FAIL;
272         }
273     }
274     return HC_SUCCESS;
275 }
276 
AddPinCode(const CJson * returnData,CJson * jsonParams)277 static int32_t AddPinCode(const CJson *returnData, CJson *jsonParams)
278 {
279     const char *pinCode = GetStringFromJson(returnData, FIELD_PIN_CODE);
280     if (pinCode == NULL) {
281         LOGE("Failed to get pinCode from returnData!");
282         return HC_ERR_JSON_GET;
283     }
284     if (AddStringToJson(jsonParams, FIELD_PIN_CODE, pinCode) != HC_SUCCESS) {
285         LOGE("Failed to add pinCode to jsonParams!");
286         return HC_ERR_JSON_FAIL;
287     }
288     return HC_SUCCESS;
289 }
290 
CombineInfoWhenInvite(const CJson * returnData,CJson * jsonParams)291 static int32_t CombineInfoWhenInvite(const CJson *returnData, CJson *jsonParams)
292 {
293     int32_t result;
294     if (((result = AddPinCode(returnData, jsonParams)) != HC_SUCCESS) ||
295         ((result = AddAuthIdIfExist(returnData, jsonParams)) != HC_SUCCESS) ||
296         ((result = AddUserTypeIfExistAndValid(returnData, jsonParams)) != HC_SUCCESS) ||
297         ((result = AddGroupVisibilityIfExistAndValid(returnData, jsonParams)) != HC_SUCCESS) ||
298         ((result = AddExpireTimeIfExistAndValid(returnData, jsonParams)) != HC_SUCCESS)) {
299         return result;
300     }
301     return HC_SUCCESS;
302 }
303 
CombineInputData(int operationCode,const CJson * returnData,CJson * jsonParams)304 static int32_t CombineInputData(int operationCode, const CJson *returnData, CJson *jsonParams)
305 {
306     if (operationCode == MEMBER_DELETE) {
307         return HC_SUCCESS;
308     } else if (operationCode == MEMBER_JOIN) {
309         return AddPinCode(returnData, jsonParams);
310     } else {
311         return CombineInfoWhenInvite(returnData, jsonParams);
312     }
313 }
314 
CheckServerStatusIfNotInvite(int32_t osAccountId,int operationCode,const CJson * jsonParams)315 static int32_t CheckServerStatusIfNotInvite(int32_t osAccountId, int operationCode, const CJson *jsonParams)
316 {
317     if (operationCode == MEMBER_INVITE) {
318         return HC_SUCCESS;
319     }
320     const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
321     if (groupId == NULL) {
322         LOGE("Failed to get groupId from jsonParams!");
323         return HC_ERR_JSON_GET;
324     }
325     const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
326     if (appId == NULL) {
327         LOGE("Failed to get appId from jsonParams!");
328         return HC_ERR_JSON_GET;
329     }
330     const char *peerUdid = GetStringFromJson(jsonParams, FIELD_CONN_DEVICE_ID);
331     if (peerUdid == NULL) {
332         LOGE("Failed to get peerUdid from jsonParams!");
333         return HC_ERR_JSON_GET;
334     }
335     int32_t result = CheckGroupExist(osAccountId, groupId);
336     if (result != HC_SUCCESS) {
337         return result;
338     }
339     if (operationCode == MEMBER_JOIN) {
340         /* The client sends a join request, which is equivalent to the server performing an invitation operation. */
341         result = CheckPermForGroup(osAccountId, MEMBER_INVITE, appId, groupId);
342         if (result != HC_SUCCESS) {
343             return result;
344         }
345         result = CheckDeviceNumLimit(osAccountId, groupId, peerUdid);
346     } else if (operationCode == MEMBER_DELETE) {
347         result = CheckPermForGroup(osAccountId, MEMBER_DELETE, appId, groupId);
348         if (result != HC_SUCCESS) {
349             return result;
350         }
351         if (!IsTrustedDeviceInGroup(osAccountId, groupId, peerUdid, true)) {
352             result = HC_ERR_DEVICE_NOT_EXIST;
353         }
354     }
355     return result;
356 }
357 
PrepareServer(BindSession * session,CJson * returnData,bool * isNeedInform)358 static int32_t PrepareServer(BindSession *session, CJson *returnData, bool *isNeedInform)
359 {
360     CJson *jsonParams = DetachItemFromJson(session->params, FIELD_RECEIVED_DATA);
361     if (jsonParams == NULL) {
362         LOGE("Received data before request confirmation are lost!");
363         return HC_ERR_LOST_DATA;
364     }
365     int32_t osAccountId = ANY_OS_ACCOUNT;
366     (void)GetIntFromJson(returnData, FIELD_OS_ACCOUNT_ID, &osAccountId);
367     osAccountId = DevAuthGetRealOsAccountLocalId(osAccountId);
368     if (osAccountId == INVALID_OS_ACCOUNT) {
369         FreeJson(jsonParams);
370         return HC_ERR_INVALID_PARAMS;
371     }
372     int32_t result = CheckServerStatusIfNotInvite(osAccountId, session->opCode, jsonParams);
373     if (result != HC_SUCCESS) {
374         FreeJson(jsonParams);
375         return result;
376     }
377     session->osAccountId = osAccountId;
378     result = CombineInputData(session->opCode, returnData, jsonParams);
379     /* Release the memory in advance to reduce the memory usage. */
380     DeleteAllItem(returnData);
381     if (result != HC_SUCCESS) {
382         FreeJson(jsonParams);
383         return result;
384     }
385     result = GenerateBindParams(osAccountId, SERVER, jsonParams, session);
386     if (result != HC_SUCCESS) {
387         FreeJson(jsonParams);
388         return result;
389     }
390     /*
391      * If the service is invited to join the peer group,
392      * the identity key pair of the corresponding group needs to be generated here.
393      */
394     if (NeedCreateGroup(SERVER, session->opCode)) {
395         const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
396         if (groupId == NULL) {
397             LOGE("Failed to get groupId from jsonParams!");
398             FreeJson(jsonParams);
399             return HC_ERR_JSON_GET;
400         }
401         result = ProcessKeyPair(CREATE_KEY_PAIR, jsonParams, groupId);
402         if (result != HC_SUCCESS) {
403             FreeJson(jsonParams);
404             return result;
405         }
406     }
407     result = PrepareAndSendDataServer(session, jsonParams, isNeedInform);
408     FreeJson(jsonParams);
409     return result;
410 }
411 
BindSaveReceivedData(BindSession * session,const CJson * jsonParams)412 static int32_t BindSaveReceivedData(BindSession *session, const CJson *jsonParams)
413 {
414     if (session->params == NULL) {
415         session->params = CreateJson();
416         if (session->params == NULL) {
417             LOGE("Failed to allocate session params memory!");
418             return HC_ERR_ALLOC_MEMORY;
419         }
420     }
421     if (AddObjToJson(session->params, FIELD_RECEIVED_DATA, jsonParams) != HC_SUCCESS) {
422         LOGE("Failed to add received data to session params!");
423         return HC_ERR_JSON_FAIL;
424     }
425     return HC_SUCCESS;
426 }
427 
JudgeConfirmation(CJson * returnData,CJson * jsonParams,BindSession * session,bool * isNeedInform)428 static int32_t JudgeConfirmation(CJson *returnData, CJson *jsonParams, BindSession *session, bool *isNeedInform)
429 {
430     uint32_t confirmation = REQUEST_ACCEPTED;
431     if (GetUnsignedIntFromJson(returnData, FIELD_CONFIRMATION, &confirmation) != HC_SUCCESS) {
432         LOGE("Failed to get confirmation from returnData!");
433         return HC_ERR_JSON_FAIL;
434     }
435     int32_t result;
436     switch (confirmation) {
437         case REQUEST_ACCEPTED:
438             LOGI("The service accepts the request!");
439             result = BindSaveReceivedData(session, jsonParams);
440             if (result != HC_SUCCESS) {
441                 return result;
442             }
443             /* Release the memory in advance to reduce the memory usage. */
444             DeleteAllItem(jsonParams);
445             return PrepareServer(session, returnData, isNeedInform);
446         case REQUEST_REJECTED:
447             LOGE("The service rejects the request!");
448             return HC_ERR_REQ_REJECTED;
449         default:
450             LOGE("Enter the exception case!");
451             return HC_ERR_CASE;
452     }
453 }
454 
HandleRequest(CJson * jsonParams,BindSession * session,bool * isNeedInform)455 static int32_t HandleRequest(CJson *jsonParams, BindSession *session, bool *isNeedInform)
456 {
457     char *returnDataStr = NULL;
458     int32_t result = RequestConfirmation(jsonParams, session, &returnDataStr);
459     if (result != HC_SUCCESS) {
460         return result;
461     }
462 
463     CJson *returnData = CreateJsonFromString(returnDataStr);
464     FreeJsonString(returnDataStr);
465     if (returnData == NULL) {
466         LOGE("Failed to create returnData from string!");
467         return HC_ERR_JSON_FAIL;
468     }
469     result = JudgeConfirmation(returnData, jsonParams, session, isNeedInform);
470     FreeJson(returnData);
471     return result;
472 }
473 
CreateServerBindSession(CJson * jsonParams,const DeviceAuthCallback * callback)474 Session *CreateServerBindSession(CJson *jsonParams, const DeviceAuthCallback *callback)
475 {
476     int32_t opCode = MEMBER_INVITE;
477     if (GetIntFromJson(jsonParams, FIELD_GROUP_OP, &opCode) != HC_SUCCESS) {
478         LOGE("Failed to get opCode from jsonParams!");
479         return NULL;
480     }
481 
482     BindSession *session = CreateBaseBindSession(TYPE_SERVER_BIND_SESSION, opCode,
483         jsonParams, callback, ProcessBindSession);
484     if (session == NULL) {
485         return NULL;
486     }
487     InitServerChannel(jsonParams, session);
488     /* The server may receive the confirm request message. */
489 
490     bool isNeedInform = true;
491     int32_t result = HandleRequest(jsonParams, session, &isNeedInform);
492     if (result != HC_SUCCESS) {
493         InformPeerGroupErrorIfNeed(isNeedInform, result, session);
494         ProcessErrorCallback(session->reqId, session->opCode, result, NULL, session->base.callback);
495         CloseChannel(session->channelType, session->channelId);
496         DestroyBindSession((Session *)session);
497         return NULL;
498     }
499     return (Session *)session;
500 }
501