1 /*
2 * Copyright (C) 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 "compatible_bind_sub_session_util.h"
17
18 #include "channel_manager.h"
19 #include "dev_auth_module_manager.h"
20 #include "group_operation_common.h"
21 #include "hc_log.h"
22 #include "hc_time.h"
23 #include "hitrace_adapter.h"
24 #include "performance_dumper.h"
25
AddPinCode(const CJson * returnData,CJson * jsonParams)26 static int32_t AddPinCode(const CJson *returnData, CJson *jsonParams)
27 {
28 const char *pinCode = GetStringFromJson(returnData, FIELD_PIN_CODE);
29 if (pinCode == NULL) {
30 LOGE("Failed to get pinCode from returnData!");
31 return HC_ERR_JSON_GET;
32 }
33 if (AddStringToJson(jsonParams, FIELD_PIN_CODE, pinCode) != HC_SUCCESS) {
34 LOGE("Failed to add pinCode to jsonParams!");
35 return HC_ERR_JSON_ADD;
36 }
37 return HC_SUCCESS;
38 }
39
AddAuthIdIfExist(const CJson * returnData,CJson * jsonParams)40 static int32_t AddAuthIdIfExist(const CJson *returnData, CJson *jsonParams)
41 {
42 const char *authId = GetStringFromJson(returnData, FIELD_DEVICE_ID);
43 if (authId != NULL && AddStringToJson(jsonParams, FIELD_DEVICE_ID, authId) != HC_SUCCESS) {
44 LOGE("Failed to add authId to jsonParams!");
45 return HC_ERR_JSON_ADD;
46 }
47 return HC_SUCCESS;
48 }
49
AddUserTypeIfExistAndValid(const CJson * returnData,CJson * jsonParams)50 static int32_t AddUserTypeIfExistAndValid(const CJson *returnData, CJson *jsonParams)
51 {
52 int32_t userType = DEVICE_TYPE_ACCESSORY;
53 if (GetIntFromJson(returnData, FIELD_USER_TYPE, &userType) == HC_SUCCESS) {
54 if (!IsUserTypeValid(userType)) {
55 LOGE("The input userType is invalid!");
56 return HC_ERR_INVALID_PARAMS;
57 }
58 if (AddIntToJson(jsonParams, FIELD_USER_TYPE, userType) != HC_SUCCESS) {
59 LOGE("Failed to add userType to jsonParams!");
60 return HC_ERR_JSON_ADD;
61 }
62 }
63 return HC_SUCCESS;
64 }
65
AddGroupVisibilityIfExistAndValid(const CJson * returnData,CJson * jsonParams)66 static int32_t AddGroupVisibilityIfExistAndValid(const CJson *returnData, CJson *jsonParams)
67 {
68 int32_t groupVisibility = GROUP_VISIBILITY_PUBLIC;
69 if (GetIntFromJson(returnData, FIELD_GROUP_VISIBILITY, &groupVisibility) == HC_SUCCESS) {
70 if (!IsGroupVisibilityValid(groupVisibility)) {
71 LOGE("The input groupVisibility invalid!");
72 return HC_ERR_INVALID_PARAMS;
73 }
74 if (AddIntToJson(jsonParams, FIELD_GROUP_VISIBILITY, groupVisibility) != HC_SUCCESS) {
75 LOGE("Failed to add groupVisibility to jsonParams!");
76 return HC_ERR_JSON_ADD;
77 }
78 }
79 return HC_SUCCESS;
80 }
81
AddExpireTimeIfExistAndValid(const CJson * returnData,CJson * jsonParams)82 static int32_t AddExpireTimeIfExistAndValid(const CJson *returnData, CJson *jsonParams)
83 {
84 int32_t expireTime = DEFAULT_EXPIRE_TIME;
85 if (GetIntFromJson(returnData, FIELD_EXPIRE_TIME, &expireTime) == HC_SUCCESS) {
86 if (!IsExpireTimeValid(expireTime)) {
87 LOGE("The input expireTime invalid!");
88 return HC_ERR_INVALID_PARAMS;
89 }
90 if (AddIntToJson(jsonParams, FIELD_EXPIRE_TIME, expireTime) != HC_SUCCESS) {
91 LOGE("Failed to add expireTime to jsonParams!");
92 return HC_ERR_JSON_ADD;
93 }
94 }
95 return HC_SUCCESS;
96 }
97
CombineInfoWhenInvite(const CJson * returnData,CJson * jsonParams)98 static int32_t CombineInfoWhenInvite(const CJson *returnData, CJson *jsonParams)
99 {
100 int32_t result;
101 if (((result = AddPinCode(returnData, jsonParams)) != HC_SUCCESS) ||
102 ((result = AddAuthIdIfExist(returnData, jsonParams)) != HC_SUCCESS) ||
103 ((result = AddUserTypeIfExistAndValid(returnData, jsonParams)) != HC_SUCCESS) ||
104 ((result = AddGroupVisibilityIfExistAndValid(returnData, jsonParams)) != HC_SUCCESS) ||
105 ((result = AddExpireTimeIfExistAndValid(returnData, jsonParams)) != HC_SUCCESS)) {
106 return result;
107 }
108 return HC_SUCCESS;
109 }
110
AddGroupErrorInfo(int32_t errorCode,const CompatibleBindSubSession * session,CJson * errorData)111 static int32_t AddGroupErrorInfo(int32_t errorCode, const CompatibleBindSubSession *session,
112 CJson *errorData)
113 {
114 if (AddIntToJson(errorData, FIELD_GROUP_ERROR_MSG, errorCode) != HC_SUCCESS) {
115 LOGE("Failed to add errorCode to errorData!");
116 return HC_ERR_JSON_ADD;
117 }
118 if (AddStringToJson(errorData, FIELD_APP_ID, session->base.appId) != HC_SUCCESS) {
119 LOGE("Failed to add appId to errorData!");
120 return HC_ERR_JSON_ADD;
121 }
122 if (AddInt64StringToJson(errorData, FIELD_REQUEST_ID, session->reqId) != HC_SUCCESS) {
123 LOGE("Failed to add requestId to errorData!");
124 return HC_ERR_JSON_ADD;
125 }
126 return HC_SUCCESS;
127 }
128
GenerateGroupErrorMsg(int32_t errorCode,int64_t requestId,const CJson * jsonParams,CJson ** errorData)129 static int32_t GenerateGroupErrorMsg(int32_t errorCode, int64_t requestId, const CJson *jsonParams, CJson **errorData)
130 {
131 const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
132 if (appId == NULL) {
133 LOGE("Failed to get appId from jsonParams!");
134 return HC_ERR_JSON_GET;
135 }
136 *errorData = CreateJson();
137 if (*errorData == NULL) {
138 LOGE("Failed to allocate errorData memory!");
139 return HC_ERR_JSON_CREATE;
140 }
141 if (AddIntToJson(*errorData, FIELD_GROUP_ERROR_MSG, errorCode) != HC_SUCCESS) {
142 LOGE("Failed to add errorCode to errorData!");
143 FreeJson(*errorData);
144 *errorData = NULL;
145 return HC_ERR_JSON_ADD;
146 }
147 if (AddStringToJson(*errorData, FIELD_APP_ID, appId) != HC_SUCCESS) {
148 LOGE("Failed to add appId to errorData!");
149 FreeJson(*errorData);
150 *errorData = NULL;
151 return HC_ERR_JSON_ADD;
152 }
153 if (AddInt64StringToJson(*errorData, FIELD_REQUEST_ID, requestId) != HC_SUCCESS) {
154 LOGE("Failed to add requestId to errorData!");
155 FreeJson(*errorData);
156 *errorData = NULL;
157 return HC_ERR_JSON_ADD;
158 }
159 return HC_SUCCESS;
160 }
161
CreateAndProcessBindTask(CompatibleBindSubSession * session,const CJson * in,CJson * out,int32_t * status)162 int32_t CreateAndProcessBindTask(CompatibleBindSubSession *session, const CJson *in, CJson *out, int32_t *status)
163 {
164 LOGI("Start to create and process module task! [ModuleType]: %d", session->moduleType);
165 DEV_AUTH_START_TRACE(TRACE_TAG_CREATE_AUTH_TASK);
166 int32_t res = CreateTask(&(session->base.curTaskId), in, out, session->moduleType);
167 DEV_AUTH_FINISH_TRACE();
168 if (res != HC_SUCCESS) {
169 LOGE("Failed to create module task! res: %d", res);
170 return res;
171 }
172 DEV_AUTH_START_TRACE(TRACE_TAG_PROCESS_AUTH_TASK);
173 res = ProcessTask(session->base.curTaskId, in, out, status, session->moduleType);
174 DEV_AUTH_FINISH_TRACE();
175 if (res != HC_SUCCESS) {
176 LOGE("Failed to process module task! res: %d", res);
177 return res;
178 }
179 LOGI("Create and process module task successfully!");
180 return HC_SUCCESS;
181 }
182
TransmitBindSessionData(const CompatibleBindSubSession * session,const CJson * sendData)183 int32_t TransmitBindSessionData(const CompatibleBindSubSession *session, const CJson *sendData)
184 {
185 char *sendDataStr = PackJsonToString(sendData);
186 if (sendDataStr == NULL) {
187 LOGE("An error occurred when converting json to string!");
188 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
189 }
190 DEV_AUTH_START_TRACE(TRACE_TAG_SEND_DATA);
191 UPDATE_PERFORM_DATA_BY_SELF_INDEX(session->reqId, HcGetCurTimeInMillis());
192 int32_t res = HcSendMsg(session->channelType, session->reqId, session->channelId,
193 session->base.callback, sendDataStr);
194 DEV_AUTH_FINISH_TRACE();
195 FreeJsonString(sendDataStr);
196 if (res != HC_SUCCESS) {
197 LOGE("Failed to send msg to peer device! res: %d", res);
198 return res;
199 }
200 return HC_SUCCESS;
201 }
202
CombineConfirmData(int operationCode,const CJson * returnData,CJson * jsonParams)203 int32_t CombineConfirmData(int operationCode, const CJson *returnData, CJson *jsonParams)
204 {
205 if (operationCode == MEMBER_JOIN) {
206 return AddPinCode(returnData, jsonParams);
207 } else {
208 return CombineInfoWhenInvite(returnData, jsonParams);
209 }
210 }
211
InformPeerGroupErrorIfNeeded(bool isNeedInform,int32_t errorCode,const CompatibleBindSubSession * session)212 void InformPeerGroupErrorIfNeeded(bool isNeedInform, int32_t errorCode, const CompatibleBindSubSession *session)
213 {
214 if (!isNeedInform) {
215 return;
216 }
217 CJson *errorData = CreateJson();
218 if (errorData == NULL) {
219 LOGE("Failed to allocate errorData memory!");
220 return;
221 }
222 int32_t res = AddGroupErrorInfo(errorCode, session, errorData);
223 if (res != HC_SUCCESS) {
224 FreeJson(errorData);
225 return;
226 }
227 res = TransmitBindSessionData(session, errorData);
228 FreeJson(errorData);
229 if (res != HC_SUCCESS) {
230 LOGE("Failed to transmit group error to peer!");
231 return;
232 }
233 LOGI("Notify the peer device that an error occurred at the local end successfully!");
234 }
235
InformPeerProcessError(int64_t requestId,const CJson * jsonParams,const DeviceAuthCallback * callback,int32_t errorCode)236 void InformPeerProcessError(int64_t requestId, const CJson *jsonParams, const DeviceAuthCallback *callback,
237 int32_t errorCode)
238 {
239 int64_t channelId = DEFAULT_CHANNEL_ID;
240 ChannelType channelType = SOFT_BUS;
241 if (GetByteFromJson(jsonParams, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) != HC_SUCCESS) {
242 channelType = SERVICE_CHANNEL;
243 }
244 CJson *errorData = NULL;
245 int32_t res = GenerateGroupErrorMsg(errorCode, requestId, jsonParams, &errorData);
246 if (res != HC_SUCCESS) {
247 return;
248 }
249 char *errorDataStr = PackJsonToString(errorData);
250 FreeJson(errorData);
251 if (errorDataStr == NULL) {
252 LOGE("An error occurred when converting json to string!");
253 return;
254 }
255 (void)HcSendMsg(channelType, requestId, channelId, callback, errorDataStr);
256 FreeJsonString(errorDataStr);
257 }