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_common_util.h"
17 #include "channel_manager.h"
18 #include "dev_auth_module_manager.h"
19 #include "hc_log.h"
20 #include "hc_types.h"
21 #include "session_common.h"
22
GenerateGroupErrorMsg(int32_t errorCode,const BindSession * session,CJson * errorData)23 static int32_t GenerateGroupErrorMsg(int32_t errorCode, const BindSession *session, CJson *errorData)
24 {
25 if (AddIntToJson(errorData, FIELD_GROUP_ERROR_MSG, errorCode) != HC_SUCCESS) {
26 LOGE("Failed to add errorCode to errorData!");
27 return HC_ERR_JSON_ADD;
28 }
29 if (AddStringToJson(errorData, FIELD_APP_ID, session->appId) != HC_SUCCESS) {
30 LOGE("Failed to add appId to errorData!");
31 return HC_ERR_JSON_ADD;
32 }
33 if (AddInt64StringToJson(errorData, FIELD_REQUEST_ID, session->reqId) != HC_SUCCESS) {
34 LOGE("Failed to add requestId to errorData!");
35 return HC_ERR_JSON_ADD;
36 }
37 return HC_SUCCESS;
38 }
39
GetDuplicateAppId(const CJson * params)40 static char *GetDuplicateAppId(const CJson *params)
41 {
42 const char *appId = GetStringFromJson(params, FIELD_APP_ID);
43 if (appId == NULL) {
44 LOGE("Failed to get appId from json!");
45 return NULL;
46 }
47 int32_t appIdLen = HcStrlen(appId);
48 char *copyAppId = (char *)HcMalloc(appIdLen + 1, 0);
49 if (copyAppId == NULL) {
50 LOGE("Failed to allocate copyAppId memory!");
51 return NULL;
52 }
53 if (memcpy_s(copyAppId, appIdLen + 1, appId, appIdLen) != EOK) {
54 LOGE("Failed to copy appId!");
55 HcFree(copyAppId);
56 return NULL;
57 }
58 return copyAppId;
59 }
60
CreateBaseBindSession(int32_t sessionType,int32_t opCode,const CJson * params,const DeviceAuthCallback * callback,ProcessSessionFunc func)61 BindSession *CreateBaseBindSession(int32_t sessionType, int32_t opCode, const CJson *params,
62 const DeviceAuthCallback *callback, ProcessSessionFunc func)
63 {
64 int64_t reqId = DEFAULT_REQUEST_ID;
65 if (GetInt64FromJson(params, FIELD_REQUEST_ID, &reqId) != HC_SUCCESS) {
66 LOGE("Failed to get reqId from json!");
67 return NULL;
68 }
69 BindSession *session = (BindSession *)HcMalloc(sizeof(BindSession), 0);
70 if (session == NULL) {
71 LOGE("Failed to allocate session memory!");
72 return NULL;
73 }
74 int32_t res = GenerateSessionOrTaskId(&session->base.sessionId);
75 if (res != HC_SUCCESS) {
76 LOGE("Failed to generate session id! res: %d", res);
77 HcFree(session);
78 return NULL;
79 }
80 session->appId = GetDuplicateAppId(params);
81 if (session->appId == NULL) {
82 HcFree(session);
83 return NULL;
84 }
85 int32_t osAccountId = 0;
86 (void)GetIntFromJson(params, FIELD_OS_ACCOUNT_ID, &osAccountId);
87 session->base.type = sessionType;
88 session->base.process = func;
89 session->base.destroy = DestroyBindSession;
90 session->base.callback = callback;
91 session->osAccountId = osAccountId;
92 session->curTaskId = 0;
93 session->opCode = opCode;
94 session->moduleType = DAS_MODULE;
95 session->reqId = reqId;
96 session->channelType = NO_CHANNEL;
97 session->channelId = DEFAULT_CHANNEL_ID;
98 session->isWaiting = false;
99 session->params = NULL;
100 session->onChannelOpened = NULL;
101 session->onConfirmed = NULL;
102 return session;
103 }
104
DestroyBindSession(Session * session)105 void DestroyBindSession(Session *session)
106 {
107 if (session == NULL) {
108 return;
109 }
110 BindSession *realSession = (BindSession *)session;
111 DestroyTask(realSession->curTaskId, realSession->moduleType);
112 HcFree(realSession->appId);
113 realSession->appId = NULL;
114 FreeJson(realSession->params);
115 realSession->params = NULL;
116 HcFree(realSession);
117 realSession = NULL;
118 }
119
InitClientChannel(const DeviceAuthCallback * callback,const CJson * params,BindSession * session)120 void InitClientChannel(const DeviceAuthCallback *callback, const CJson *params, BindSession *session)
121 {
122 session->channelType = GetChannelType(callback, params);
123 }
124
InitServerChannel(const CJson * params,BindSession * session)125 void InitServerChannel(const CJson *params, BindSession *session)
126 {
127 int64_t channelId = DEFAULT_CHANNEL_ID;
128 if (GetByteFromJson(params, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) == HC_SUCCESS) {
129 session->channelType = SOFT_BUS;
130 session->channelId = channelId;
131 } else {
132 session->channelType = SERVICE_CHANNEL;
133 }
134 }
135
IsAcceptRequest(const CJson * params)136 bool IsAcceptRequest(const CJson *params)
137 {
138 uint32_t confirmation = REQUEST_REJECTED;
139 if (GetUnsignedIntFromJson(params, FIELD_CONFIRMATION, &confirmation) != HC_SUCCESS) {
140 LOGE("Failed to get confimation from json!");
141 return false;
142 }
143 return (confirmation == REQUEST_ACCEPTED);
144 }
145
CheckPeerStatus(const CJson * params,bool * isNeedInform)146 int32_t CheckPeerStatus(const CJson *params, bool *isNeedInform)
147 {
148 int32_t errorCode = HC_SUCCESS;
149 if (GetIntFromJson(params, FIELD_GROUP_ERROR_MSG, &errorCode) == HC_SUCCESS) {
150 LOGE("An error occurs in the peer device! [ErrorCode]: %d", errorCode);
151 *isNeedInform = false;
152 return errorCode;
153 }
154 return HC_SUCCESS;
155 }
156
SendBindSessionData(const BindSession * session,const CJson * sendData)157 int32_t SendBindSessionData(const BindSession *session, const CJson *sendData)
158 {
159 char *sendDataStr = PackJsonToString(sendData);
160 if (sendDataStr == NULL) {
161 LOGE("An error occurred when converting json to string!");
162 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
163 }
164 int32_t res = HcSendMsg(session->channelType, session->reqId, session->channelId,
165 session->base.callback, sendDataStr);
166 FreeJsonString(sendDataStr);
167 if (res != HC_SUCCESS) {
168 LOGE("Failed to send msg to peer device! res: %d", res);
169 return res;
170 }
171 return HC_SUCCESS;
172 }
173
CreateAndProcessModule(BindSession * session,const CJson * in,CJson * out)174 int32_t CreateAndProcessModule(BindSession *session, const CJson *in, CJson *out)
175 {
176 int32_t status = 0;
177 LOGI("Start to create and process module task! [ModuleType]: %d", session->moduleType);
178 int32_t res = CreateTask(&(session->curTaskId), in, out, session->moduleType);
179 if (res != HC_SUCCESS) {
180 LOGE("Failed to create module task! res: %d", res);
181 return res;
182 }
183 res = ProcessTask(session->curTaskId, in, out, &status, session->moduleType);
184 if (res != HC_SUCCESS) {
185 LOGE("Failed to process module task! res: %d", res);
186 return res;
187 }
188 LOGI("Create and process module task successfully!");
189 return HC_SUCCESS;
190 }
191
ProcessModule(const BindSession * session,const CJson * in,CJson * out,int32_t * status)192 int32_t ProcessModule(const BindSession *session, const CJson *in, CJson *out, int32_t *status)
193 {
194 LOGI("Start to process module task! [ModuleType]: %d", session->moduleType);
195 int32_t res = ProcessTask(session->curTaskId, in, out, status, session->moduleType);
196 if (res != HC_SUCCESS) {
197 LOGE("Failed to process module task! res: %d", res);
198 return res;
199 }
200 LOGI("Process module task successfully!");
201 return HC_SUCCESS;
202 }
203
InformPeerGroupErrorIfNeed(bool isNeedInform,int32_t errorCode,const BindSession * session)204 void InformPeerGroupErrorIfNeed(bool isNeedInform, int32_t errorCode, const BindSession *session)
205 {
206 if (!isNeedInform) {
207 return;
208 }
209 CJson *errorData = CreateJson();
210 if (errorData == NULL) {
211 LOGE("Failed to allocate errorData memory!");
212 return;
213 }
214 int32_t res = GenerateGroupErrorMsg(errorCode, session, errorData);
215 if (res != HC_SUCCESS) {
216 FreeJson(errorData);
217 return;
218 }
219 res = SendBindSessionData(session, errorData);
220 FreeJson(errorData);
221 if (res != HC_SUCCESS) {
222 return;
223 }
224 LOGI("Notify the peer device that an error occurred at the local end successfully!");
225 }
226
InformPeerModuleError(CJson * out,const BindSession * session)227 void InformPeerModuleError(CJson *out, const BindSession *session)
228 {
229 CJson *errorData = GetObjFromJson(out, FIELD_SEND_TO_PEER);
230 if (errorData == NULL) {
231 return;
232 }
233 if (AddStringToJson(errorData, FIELD_APP_ID, session->appId) != HC_SUCCESS) {
234 LOGE("Failed to add appId to errorData!");
235 return;
236 }
237 if (AddInt64StringToJson(errorData, FIELD_REQUEST_ID, session->reqId) != HC_SUCCESS) {
238 LOGE("Failed to add requestId to errorData!");
239 return;
240 }
241 int32_t result = SendBindSessionData(session, errorData);
242 if (result != HC_SUCCESS) {
243 LOGE("An error occurred when notifying the peer service!");
244 return;
245 }
246 LOGI("Succeeded in notifying the peer device that an error occurred at the local end!");
247 }
248