• 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_client.h"
17 #include "bind_session_common_util.h"
18 #include "callback_manager.h"
19 #include "channel_manager.h"
20 #include "group_operation_common.h"
21 #include "hc_log.h"
22 #include "session_manager.h"
23 
GenerateClientModuleParams(BindSession * session,CJson * moduleParams)24 static int32_t GenerateClientModuleParams(BindSession *session, CJson *moduleParams)
25 {
26     if (AddIntToJson(moduleParams, FIELD_OPERATION_CODE,
27         ((session->opCode == MEMBER_DELETE) ? OP_UNBIND : OP_BIND)) != HC_SUCCESS) {
28         LOGE("Failed to add operationCode to moduleParams!");
29         return HC_ERR_JSON_FAIL;
30     }
31     return GenerateBasicModuleParams(true, session, moduleParams);
32 }
33 
GetClientModuleReturnData(BindSession * session,CJson * out)34 static int32_t GetClientModuleReturnData(BindSession *session, CJson *out)
35 {
36     CJson *moduleParams = CreateJson();
37     if (moduleParams == NULL) {
38         LOGE("Failed to allocate moduleParams memory!");
39         return HC_ERR_JSON_FAIL;
40     }
41 
42     int32_t result = GenerateClientModuleParams(session, moduleParams);
43     if (result != HC_SUCCESS) {
44         LOGE("Failed to generate all params sent to the module!");
45         FreeJson(moduleParams);
46         return result;
47     }
48 
49     result = CreateAndProcessModule(session, moduleParams, out);
50     FreeJson(moduleParams);
51     if (result != HC_SUCCESS) {
52         return result;
53     }
54     return HC_SUCCESS;
55 }
56 
PrepareData(BindSession * session,CJson ** sendData)57 static int32_t PrepareData(BindSession *session, CJson **sendData)
58 {
59     CJson *out = CreateJson();
60     if (out == NULL) {
61         LOGE("Failed to allocate out memory!");
62         return HC_ERR_JSON_FAIL;
63     }
64     int32_t result = GetClientModuleReturnData(session, out);
65     if (result != HC_SUCCESS) {
66         FreeJson(out);
67         return result;
68     }
69 
70     *sendData = DetachItemFromJson(out, FIELD_SEND_TO_PEER);
71     FreeJson(out);
72     if (*sendData == NULL) {
73         LOGE("Failed to get sendToPeer from out!");
74         return HC_ERR_JSON_GET;
75     }
76 
77     result = AddInfoToSendData(false, session, *sendData);
78     if (result != HC_SUCCESS) {
79         LOGE("Failed to add information to sendData!");
80         FreeJson(*sendData);
81         *sendData = NULL;
82         return result;
83     }
84     return HC_SUCCESS;
85 }
86 
PrepareAndSendData(BindSession * session)87 static int32_t PrepareAndSendData(BindSession *session)
88 {
89     CJson *sendData = NULL;
90     int32_t result = PrepareData(session, &sendData);
91     if (result != HC_SUCCESS) {
92         return result;
93     }
94 
95     result = SendBindSessionData(session, sendData);
96     FreeJson(sendData);
97     return result;
98 }
99 
DoubleCheckChannelId(int64_t channelId,int64_t oldChannelId)100 static int32_t DoubleCheckChannelId(int64_t channelId, int64_t oldChannelId)
101 {
102     if (oldChannelId != channelId) {
103         /* If the two channelIds are different, the soft bus channel must be used. */
104         LOGE("The channelId returned by the soft bus are inconsistent, causing a channel error!");
105         return HC_ERR_CHANNEL_NOT_EXIST;
106     }
107     return HC_SUCCESS;
108 }
109 
OnBindChannelOpened(Session * session,int64_t channelId,int64_t requestId)110 static void OnBindChannelOpened(Session *session, int64_t channelId, int64_t requestId)
111 {
112     if (session == NULL) {
113         LOGE("The input session is NULL!");
114         return;
115     }
116 
117     BindSession *realSession = (BindSession *)session;
118     /* Double check channelId. If the two channelIds are different, the channel fails to be established. */
119     int32_t result = DoubleCheckChannelId(channelId, realSession->channelId);
120     if (result != HC_SUCCESS) {
121         ProcessErrorCallback(requestId, realSession->opCode, result, NULL, realSession->base.callback);
122         DestroySession(requestId);
123         return;
124     }
125 
126     result = PrepareAndSendData(realSession);
127     if (result != HC_SUCCESS) {
128         LOGI("An error occurs before the client send data to the server. We need to notify the service!");
129         if ((!NeedForceDelete(realSession)) || (ForceUnbindDevice(realSession) != HC_SUCCESS)) {
130             ProcessErrorCallback(requestId, realSession->opCode, result, NULL, realSession->base.callback);
131         }
132         CloseChannel(realSession->channelType, realSession->channelId);
133         DestroySession(requestId);
134     }
135 }
136 
PrepareClient(const CJson * jsonParams,BindSession * session)137 static int32_t PrepareClient(const CJson *jsonParams, BindSession *session)
138 {
139     int32_t result = GenerateBindParams(session->osAccountId, CLIENT, jsonParams, session);
140     if (result != HC_SUCCESS) {
141         return result;
142     }
143     return OpenChannel(session->channelType, jsonParams, session->reqId, &session->channelId);
144 }
145 
CreateClientBindSession(CJson * jsonParams,const DeviceAuthCallback * callback)146 Session *CreateClientBindSession(CJson *jsonParams, const DeviceAuthCallback *callback)
147 {
148     int32_t opCode = MEMBER_INVITE;
149     if (GetIntFromJson(jsonParams, FIELD_OPERATION_CODE, &opCode) != HC_SUCCESS) {
150         LOGE("Failed to get opCode from json!");
151         return NULL;
152     }
153     /*
154      * If service want to join the peer group,
155      * the identity key pair of the corresponding group needs to be generated here.
156      */
157     int32_t result;
158     if (NeedCreateGroup(CLIENT, opCode)) {
159         const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
160         if (groupId == NULL) {
161             LOGE("Failed to get groupId from jsonParams!");
162             return NULL;
163         }
164         result = ProcessKeyPair(CREATE_KEY_PAIR, jsonParams, groupId);
165         if (result != HC_SUCCESS) {
166             return NULL;
167         }
168     }
169 
170     BindSession *session = CreateBaseBindSession(TYPE_CLIENT_BIND_SESSION, opCode,
171         jsonParams, callback, ProcessBindSession);
172     if (session == NULL) {
173         return NULL;
174     }
175     InitClientChannel(callback, jsonParams, session);
176     /* The client bind session needs to receive a message indicating that the channel is open. */
177     session->onChannelOpened = OnBindChannelOpened;
178 
179     result = PrepareClient(jsonParams, session);
180     if (result != HC_SUCCESS) {
181         ProcessErrorCallback(session->reqId, session->opCode, result, NULL, session->base.callback);
182         DestroyBindSession((Session *)session);
183         return NULL;
184     }
185     return (Session *)session;
186 }
187