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->base.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->base.appId = GetDuplicateAppId(params);
81 if (session->base.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->params = NULL;
99 session->onChannelOpened = NULL;
100 return session;
101 }
102
DestroyBindSession(Session * session)103 void DestroyBindSession(Session *session)
104 {
105 if (session == NULL) {
106 return;
107 }
108 BindSession *realSession = (BindSession *)session;
109 DestroyTask(realSession->curTaskId, realSession->moduleType);
110 HcFree(realSession->base.appId);
111 realSession->base.appId = NULL;
112 FreeJson(realSession->params);
113 realSession->params = NULL;
114 HcFree(realSession);
115 realSession = NULL;
116 }
117
InitClientChannel(const DeviceAuthCallback * callback,const CJson * params,BindSession * session)118 void InitClientChannel(const DeviceAuthCallback *callback, const CJson *params, BindSession *session)
119 {
120 session->channelType = GetChannelType(callback, params);
121 }
122
InitServerChannel(const CJson * params,BindSession * session)123 void InitServerChannel(const CJson *params, BindSession *session)
124 {
125 int64_t channelId = DEFAULT_CHANNEL_ID;
126 if (GetByteFromJson(params, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) == HC_SUCCESS) {
127 session->channelType = SOFT_BUS;
128 session->channelId = channelId;
129 } else {
130 session->channelType = SERVICE_CHANNEL;
131 }
132 }
133
IsAcceptRequest(const CJson * params)134 bool IsAcceptRequest(const CJson *params)
135 {
136 uint32_t confirmation = REQUEST_REJECTED;
137 if (GetUnsignedIntFromJson(params, FIELD_CONFIRMATION, &confirmation) != HC_SUCCESS) {
138 LOGE("Failed to get confimation from json!");
139 return false;
140 }
141 return (confirmation == REQUEST_ACCEPTED);
142 }
143
CheckPeerStatus(const CJson * params,bool * isNeedInform)144 int32_t CheckPeerStatus(const CJson *params, bool *isNeedInform)
145 {
146 int32_t errorCode = HC_SUCCESS;
147 if (GetIntFromJson(params, FIELD_GROUP_ERROR_MSG, &errorCode) == HC_SUCCESS) {
148 LOGE("An error occurs in the peer device! [ErrorCode]: %d", errorCode);
149 *isNeedInform = false;
150 return errorCode;
151 }
152 return HC_SUCCESS;
153 }
154
SendBindSessionData(const BindSession * session,const CJson * sendData)155 int32_t SendBindSessionData(const BindSession *session, const CJson *sendData)
156 {
157 char *sendDataStr = PackJsonToString(sendData);
158 if (sendDataStr == NULL) {
159 LOGE("An error occurred when converting json to string!");
160 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
161 }
162 int32_t res = HcSendMsg(session->channelType, session->reqId, session->channelId,
163 session->base.callback, sendDataStr);
164 FreeJsonString(sendDataStr);
165 if (res != HC_SUCCESS) {
166 LOGE("Failed to send msg to peer device! res: %d", res);
167 return res;
168 }
169 return HC_SUCCESS;
170 }
171
CreateAndProcessModule(BindSession * session,const CJson * in,CJson * out)172 int32_t CreateAndProcessModule(BindSession *session, const CJson *in, CJson *out)
173 {
174 int32_t status = 0;
175 LOGI("Start to create and process module task! [ModuleType]: %d", session->moduleType);
176 int32_t res = CreateTask(&(session->curTaskId), in, out, session->moduleType);
177 if (res != HC_SUCCESS) {
178 LOGE("Failed to create module task! res: %d", res);
179 return res;
180 }
181 res = ProcessTask(session->curTaskId, in, out, &status, session->moduleType);
182 if (res != HC_SUCCESS) {
183 LOGE("Failed to process module task! res: %d", res);
184 return res;
185 }
186 LOGI("Create and process module task successfully!");
187 return HC_SUCCESS;
188 }
189
ProcessModule(const BindSession * session,const CJson * in,CJson * out,int32_t * status)190 int32_t ProcessModule(const BindSession *session, const CJson *in, CJson *out, int32_t *status)
191 {
192 LOGI("Start to process module task! [ModuleType]: %d", session->moduleType);
193 int32_t res = ProcessTask(session->curTaskId, in, out, status, session->moduleType);
194 if (res != HC_SUCCESS) {
195 LOGE("Failed to process module task! res: %d", res);
196 return res;
197 }
198 LOGI("Process module task successfully!");
199 return HC_SUCCESS;
200 }
201
InformPeerGroupErrorIfNeed(bool isNeedInform,int32_t errorCode,const BindSession * session)202 void InformPeerGroupErrorIfNeed(bool isNeedInform, int32_t errorCode, const BindSession *session)
203 {
204 if (!isNeedInform) {
205 return;
206 }
207 CJson *errorData = CreateJson();
208 if (errorData == NULL) {
209 LOGE("Failed to allocate errorData memory!");
210 return;
211 }
212 int32_t res = GenerateGroupErrorMsg(errorCode, session, errorData);
213 if (res != HC_SUCCESS) {
214 FreeJson(errorData);
215 return;
216 }
217 res = SendBindSessionData(session, errorData);
218 FreeJson(errorData);
219 if (res != HC_SUCCESS) {
220 return;
221 }
222 LOGI("Notify the peer device that an error occurred at the local end successfully!");
223 }
224
InformPeerModuleError(CJson * out,const BindSession * session)225 void InformPeerModuleError(CJson *out, const BindSession *session)
226 {
227 CJson *errorData = GetObjFromJson(out, FIELD_SEND_TO_PEER);
228 if (errorData == NULL) {
229 return;
230 }
231 if (AddStringToJson(errorData, FIELD_APP_ID, session->base.appId) != HC_SUCCESS) {
232 LOGE("Failed to add appId to errorData!");
233 return;
234 }
235 if (AddInt64StringToJson(errorData, FIELD_REQUEST_ID, session->reqId) != HC_SUCCESS) {
236 LOGE("Failed to add requestId to errorData!");
237 return;
238 }
239 int32_t result = SendBindSessionData(session, errorData);
240 if (result != HC_SUCCESS) {
241 LOGE("An error occurred when notifying the peer service!");
242 return;
243 }
244 LOGI("Succeeded in notifying the peer device that an error occurred at the local end!");
245 }
246