1 /*
2 * Copyright (c) 2021 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 "client_trans_session_callback.h"
17
18 #include <securec.h>
19
20 #include "anonymizer.h"
21 #include "client_trans_proxy_manager.h"
22 #include "client_trans_session_manager.h"
23 #include "softbus_adapter_mem.h"
24 #include "softbus_def.h"
25 #include "softbus_errcode.h"
26 #include "trans_log.h"
27
28 static IClientSessionCallBack g_sessionCb;
29
AcceptSessionAsServer(const char * sessionName,const ChannelInfo * channel,uint32_t flag,int32_t * sessionId)30 static int32_t AcceptSessionAsServer(const char *sessionName, const ChannelInfo *channel, uint32_t flag,
31 int32_t *sessionId)
32 {
33 TRANS_LOGD(TRANS_SDK, "enter.");
34 SessionInfo *session = (SessionInfo *)SoftBusCalloc(sizeof(SessionInfo));
35 if (session == NULL) {
36 TRANS_LOGE(TRANS_SDK, "malloc failed");
37 return SOFTBUS_MALLOC_ERR;
38 }
39
40 session->channelId = channel->channelId;
41 session->channelType = (ChannelType)channel->channelType;
42 session->peerPid = channel->peerPid;
43 session->peerUid = channel->peerUid;
44 session->isServer = channel->isServer;
45 session->isEnable = true;
46 session->info.flag = (int32_t)flag;
47 session->isEncrypt = channel->isEncrypt;
48 session->businessType = channel->businessType;
49 session->routeType = channel->routeType;
50 session->fileEncrypt = channel->fileEncrypt;
51 session->algorithm = channel->algorithm;
52 session->crc = channel->crc;
53 session->dataConfig = channel->dataConfig;
54 if (strcpy_s(session->info.peerSessionName, SESSION_NAME_SIZE_MAX, channel->peerSessionName) != EOK ||
55 strcpy_s(session->info.peerDeviceId, DEVICE_ID_SIZE_MAX, channel->peerDeviceId) != EOK ||
56 strcpy_s(session->info.groupId, GROUP_ID_SIZE_MAX, channel->groupId) != EOK) {
57 TRANS_LOGE(TRANS_SDK, "client or peer session name, device id, group id failed");
58 SoftBusFree(session);
59 return SOFTBUS_MEM_ERR;
60 }
61
62 int32_t ret = ClientAddNewSession(sessionName, session);
63 if (ret != SOFTBUS_OK) {
64 TRANS_LOGE(TRANS_SDK, "client add session failed");
65 SoftBusFree(session);
66 return SOFTBUS_ERR;
67 }
68 *sessionId = session->sessionId;
69 TRANS_LOGE(TRANS_SDK, "ok");
70 return SOFTBUS_OK;
71 }
72
GetSessionCallbackByChannelId(int32_t channelId,int32_t channelType,int32_t * sessionId,ISessionListener * listener)73 static int32_t GetSessionCallbackByChannelId(int32_t channelId, int32_t channelType,
74 int32_t *sessionId, ISessionListener *listener)
75 {
76 if ((channelId < 0) || (sessionId == NULL) || (listener == NULL)) {
77 TRANS_LOGW(TRANS_SDK, "Invalid param");
78 return SOFTBUS_INVALID_PARAM;
79 }
80 int32_t ret = ClientGetSessionIdByChannelId(channelId, channelType, sessionId);
81 if (ret != SOFTBUS_OK) {
82 TRANS_LOGE(TRANS_SDK, "get sessionId failed, channelId=%{public}d", channelId);
83 return SOFTBUS_ERR;
84 }
85 ret = ClientGetSessionCallbackById(*sessionId, listener);
86 if (ret != SOFTBUS_OK) {
87 TRANS_LOGE(TRANS_SDK, "get session listener failed");
88 return SOFTBUS_ERR;
89 }
90 return SOFTBUS_OK;
91 }
92
GetSocketCallbackAdapterByChannelId(int32_t channelId,int32_t channelType,int32_t * sessionId,SessionListenerAdapter * sessionCallback,bool * isServer)93 static int32_t GetSocketCallbackAdapterByChannelId(int32_t channelId, int32_t channelType, int32_t *sessionId,
94 SessionListenerAdapter *sessionCallback, bool *isServer)
95 {
96 if ((channelId < 0) || (sessionId == NULL) || (sessionCallback == NULL)) {
97 TRANS_LOGE(TRANS_SDK, "Invalid param");
98 return SOFTBUS_INVALID_PARAM;
99 }
100
101 int32_t ret = ClientGetSessionIdByChannelId(channelId, channelType, sessionId);
102 if (ret != SOFTBUS_OK) {
103 TRANS_LOGE(TRANS_SDK, "get sessionId failed, channelId=%{public}d", channelId);
104 return SOFTBUS_ERR;
105 }
106 ret = ClientGetSessionCallbackAdapterById(*sessionId, sessionCallback, isServer);
107 if (ret != SOFTBUS_OK) {
108 TRANS_LOGE(TRANS_SDK, "get socket callback failed");
109 return SOFTBUS_ERR;
110 }
111 return SOFTBUS_OK;
112 }
113
TransOnServerBindSuccess(int32_t sessionId,const ISocketListener * socketCallback)114 NO_SANITIZE("cfi") static int32_t TransOnServerBindSuccess(int32_t sessionId, const ISocketListener *socketCallback)
115 {
116 PeerSocketInfo info;
117 int32_t ret = ClientGetPeerSocketInfoById(sessionId, &info);
118 if (ret != SOFTBUS_OK) {
119 TRANS_LOGE(TRANS_SDK, "Get peer socket info failed");
120 return SOFTBUS_ERR;
121 }
122
123 if (socketCallback->OnBind == NULL) {
124 TRANS_LOGE(TRANS_SDK, "Invalid OnBind callback function");
125 return SOFTBUS_ERR;
126 }
127
128 (void)socketCallback->OnBind(sessionId, info);
129 TRANS_LOGI(TRANS_SDK, "OnBind success, server socket=%{public}d", sessionId);
130 return SOFTBUS_OK;
131 }
132
TransOnSessionOpened(const char * sessionName,const ChannelInfo * channel,SessionType flag)133 NO_SANITIZE("cfi") int32_t TransOnSessionOpened(const char *sessionName, const ChannelInfo *channel, SessionType flag)
134 {
135 if ((sessionName == NULL) || (channel == NULL)) {
136 TRANS_LOGW(TRANS_SDK, "Invalid param");
137 return SOFTBUS_INVALID_PARAM;
138 }
139 char *tmpName = NULL;
140 Anonymize(sessionName, &tmpName);
141 TRANS_LOGI(TRANS_SDK,
142 "TransOnSessionOpened: sessionName=%{public}s, flag=%{public}d, isServer=%{public}d, type=%{public}d, "
143 "crc=%{public}d",
144 tmpName, flag, channel->isServer, channel->routeType, channel->crc);
145 AnonymizeFree(tmpName);
146
147 SessionListenerAdapter sessionCallback;
148 (void)memset_s(&sessionCallback, sizeof(SessionListenerAdapter), 0, sizeof(SessionListenerAdapter));
149 int32_t ret = ClientGetSessionCallbackAdapterByName(sessionName, &sessionCallback);
150 if (ret != SOFTBUS_OK) {
151 TRANS_LOGE(TRANS_SDK, "get session listener failed");
152 return SOFTBUS_ERR;
153 }
154
155 int32_t sessionId = INVALID_SESSION_ID;
156 if (channel->isServer) {
157 ret = AcceptSessionAsServer(sessionName, channel, flag, &sessionId);
158 } else {
159 ret = ClientEnableSessionByChannelId(channel, &sessionId);
160 }
161
162 if (ret != SOFTBUS_OK) {
163 TRANS_LOGE(TRANS_SDK, "accept session failed");
164 return SOFTBUS_ERR;
165 }
166
167 if (sessionCallback.isSocketListener) {
168 if (!channel->isServer) {
169 TRANS_LOGI(TRANS_SDK, "OnBind success, client socket=%{public}d", sessionId);
170 return SOFTBUS_OK;
171 }
172 ret = TransOnServerBindSuccess(sessionId, &sessionCallback.socketServer);
173 if (ret != SOFTBUS_OK) {
174 (void)ClientDeleteSession(sessionId);
175 }
176 return ret;
177 }
178 TRANS_LOGI(TRANS_SDK, "trigger session open callback");
179 if ((sessionCallback.session.OnSessionOpened == NULL) ||
180 (sessionCallback.session.OnSessionOpened(sessionId, SOFTBUS_OK) != SOFTBUS_OK)) {
181 TRANS_LOGE(TRANS_SDK, "OnSessionOpened failed");
182 (void)ClientDeleteSession(sessionId);
183 return SOFTBUS_ERR;
184 }
185 TRANS_LOGI(TRANS_SDK, "ok, sessionId=%{public}d", sessionId);
186 return SOFTBUS_OK;
187 }
188
TransOnSessionOpenFailed(int32_t channelId,int32_t channelType,int32_t errCode)189 NO_SANITIZE("cfi") int32_t TransOnSessionOpenFailed(int32_t channelId, int32_t channelType, int32_t errCode)
190 {
191 TRANS_LOGI(TRANS_SDK, "channelId=%{public}d, channelType=%{public}d", channelId, channelType);
192 int32_t sessionId = INVALID_SESSION_ID;
193 SessionListenerAdapter sessionCallback;
194 bool isServer = false;
195 (void)memset_s(&sessionCallback, sizeof(SessionListenerAdapter), 0, sizeof(SessionListenerAdapter));
196 (void)GetSocketCallbackAdapterByChannelId(channelId, channelType, &sessionId, &sessionCallback, &isServer);
197 TRANS_LOGI(TRANS_SDK, "trigger session open failed callback");
198 if (sessionCallback.session.OnSessionOpened != NULL) {
199 (void)sessionCallback.session.OnSessionOpened(sessionId, errCode);
200 }
201 (void)ClientDeleteSession(sessionId);
202 TRANS_LOGI(TRANS_SDK, "ok, sessionid=%{public}d", sessionId);
203 return SOFTBUS_OK;
204 }
205
TransOnSessionClosed(int32_t channelId,int32_t channelType,ShutdownReason reason)206 NO_SANITIZE("cfi") int32_t TransOnSessionClosed(int32_t channelId, int32_t channelType, ShutdownReason reason)
207 {
208 TRANS_LOGI(TRANS_SDK, "channelId=%{public}d, channelType=%{public}d", channelId, channelType);
209 int32_t sessionId = INVALID_SESSION_ID;
210 int32_t ret;
211 SessionListenerAdapter sessionCallback;
212 bool isServer = false;
213 (void)memset_s(&sessionCallback, sizeof(SessionListenerAdapter), 0, sizeof(SessionListenerAdapter));
214 (void)GetSocketCallbackAdapterByChannelId(channelId, channelType, &sessionId, &sessionCallback, &isServer);
215
216 TRANS_LOGI(TRANS_SDK, "trigger session close callback");
217 if (sessionCallback.isSocketListener) {
218 ISocketListener *listener = isServer ? &sessionCallback.socketServer : &sessionCallback.socketClient;
219 if (listener->OnShutdown != NULL) {
220 listener->OnShutdown(sessionId, reason);
221 }
222 } else if (sessionCallback.session.OnSessionClosed != NULL) {
223 sessionCallback.session.OnSessionClosed(sessionId);
224 }
225
226 ret = ClientDeleteSession(sessionId);
227 if (ret != SOFTBUS_OK) {
228 TRANS_LOGE(TRANS_SDK, "client delete session failed");
229 return SOFTBUS_ERR;
230 }
231 TRANS_LOGI(TRANS_SDK, "ok, sessionId=%{public}d", sessionId);
232 return SOFTBUS_OK;
233 }
234
ProcessReceivedFileData(int32_t sessionId,int32_t channelId,const char * data,uint32_t len,SessionPktType type)235 static int32_t ProcessReceivedFileData(int32_t sessionId, int32_t channelId, const char *data, uint32_t len,
236 SessionPktType type)
237 {
238 char sessionName[SESSION_NAME_SIZE_MAX] = {0};
239 if (ClientGetSessionDataById(sessionId, sessionName, SESSION_NAME_SIZE_MAX, KEY_SESSION_NAME)
240 != SOFTBUS_OK) {
241 TRANS_LOGE(TRANS_FILE, "get session name failed");
242 return SOFTBUS_ERR;
243 }
244
245 if (ProcessFileFrameData(sessionId, channelId, data, len, type) != SOFTBUS_OK) {
246 TRANS_LOGE(TRANS_FILE, "process fileframe data failed");
247 return SOFTBUS_ERR;
248 }
249 return SOFTBUS_OK;
250 }
251
TransOnDataReceived(int32_t channelId,int32_t channelType,const void * data,uint32_t len,SessionPktType type)252 NO_SANITIZE("cfi") int32_t TransOnDataReceived(int32_t channelId, int32_t channelType,
253 const void *data, uint32_t len, SessionPktType type)
254 {
255 int32_t sessionId;
256 SessionListenerAdapter sessionCallback;
257 bool isServer = false;
258 (void)memset_s(&sessionCallback, sizeof(SessionListenerAdapter), 0, sizeof(SessionListenerAdapter));
259 int32_t ret = GetSocketCallbackAdapterByChannelId(channelId, channelType, &sessionId, &sessionCallback, &isServer);
260 if (ret != SOFTBUS_OK) {
261 TRANS_LOGE(TRANS_SDK, "get session callback failed");
262 return ret;
263 }
264 (void)ClientResetIdleTimeoutById(sessionId);
265 ISocketListener *listener = isServer ? &sessionCallback.socketServer : &sessionCallback.socketClient;
266 switch (type) {
267 case TRANS_SESSION_BYTES:
268 if (sessionCallback.isSocketListener) {
269 if (listener->OnBytes != NULL) {
270 listener->OnBytes(sessionId, data, len);
271 }
272 } else if (sessionCallback.session.OnBytesReceived != NULL) {
273 sessionCallback.session.OnBytesReceived(sessionId, data, len);
274 }
275 break;
276 case TRANS_SESSION_MESSAGE:
277 if (sessionCallback.isSocketListener) {
278 if (listener->OnMessage != NULL) {
279 listener->OnMessage(sessionId, data, len);
280 }
281 } else if (sessionCallback.session.OnMessageReceived != NULL) {
282 sessionCallback.session.OnMessageReceived(sessionId, data, len);
283 }
284 break;
285 case TRANS_SESSION_FILE_FIRST_FRAME:
286 case TRANS_SESSION_FILE_ONGOINE_FRAME:
287 case TRANS_SESSION_FILE_LAST_FRAME:
288 case TRANS_SESSION_FILE_ONLYONE_FRAME:
289 case TRANS_SESSION_FILE_ALLFILE_SENT:
290 case TRANS_SESSION_FILE_CRC_CHECK_FRAME:
291 case TRANS_SESSION_FILE_RESULT_FRAME:
292 case TRANS_SESSION_FILE_ACK_REQUEST_SENT:
293 case TRANS_SESSION_FILE_ACK_RESPONSE_SENT:
294 if (channelType == CHANNEL_TYPE_PROXY) {
295 return ProcessReceivedFileData(sessionId, channelId, (char *)data, len, type);
296 }
297 break;
298 default:
299 TRANS_LOGE(TRANS_FILE, "revc unknown session type");
300 return SOFTBUS_ERR;
301 }
302
303 return SOFTBUS_OK;
304 }
305
TransOnOnStreamRecevied(int32_t channelId,int32_t channelType,const StreamData * data,const StreamData * ext,const StreamFrameInfo * param)306 NO_SANITIZE("cfi") int32_t TransOnOnStreamRecevied(int32_t channelId, int32_t channelType,
307 const StreamData *data, const StreamData *ext, const StreamFrameInfo *param)
308 {
309 int32_t sessionId;
310 SessionListenerAdapter sessionCallback;
311 bool isServer = false;
312 (void)memset_s(&sessionCallback, sizeof(SessionListenerAdapter), 0, sizeof(SessionListenerAdapter));
313 int32_t ret = GetSocketCallbackAdapterByChannelId(channelId, channelType, &sessionId, &sessionCallback, &isServer);
314 if (ret != SOFTBUS_OK) {
315 TRANS_LOGE(TRANS_STREAM, "get session callback failed");
316 return ret;
317 }
318
319 (void)ClientResetIdleTimeoutById(sessionId);
320 if (sessionCallback.isSocketListener) {
321 ISocketListener *listener = isServer ? &sessionCallback.socketServer : &sessionCallback.socketClient;
322 if (listener->OnStream != NULL) {
323 listener->OnStream(sessionId, data, ext, param);
324 }
325 return SOFTBUS_OK;
326 }
327
328 if (sessionCallback.session.OnStreamReceived == NULL) {
329 TRANS_LOGE(TRANS_STREAM, "listener OnStreamReceived is NULL");
330 return SOFTBUS_ERR;
331 }
332
333 sessionCallback.session.OnStreamReceived(sessionId, data, ext, param);
334 return SOFTBUS_OK;
335 }
336
TransOnQosEvent(int32_t channelId,int32_t channelType,int32_t eventId,int32_t tvCount,const QosTv * tvList)337 NO_SANITIZE("cfi") int32_t TransOnQosEvent(int32_t channelId, int32_t channelType, int32_t eventId,
338 int32_t tvCount, const QosTv *tvList)
339 {
340 int32_t sessionId;
341 ISessionListener listener = {0};
342 int32_t ret = GetSessionCallbackByChannelId(channelId, channelType, &sessionId, &listener);
343 if (ret != SOFTBUS_OK) {
344 TRANS_LOGE(TRANS_QOS, "get session callback failed");
345 return ret;
346 }
347 if (listener.OnQosEvent == NULL) {
348 TRANS_LOGE(TRANS_QOS, "listener OnQosEvent is NULL");
349 return SOFTBUS_ERR;
350 }
351 listener.OnQosEvent(sessionId, eventId, tvCount, tvList);
352 return SOFTBUS_OK;
353 }
354
GetClientSessionCb(void)355 IClientSessionCallBack *GetClientSessionCb(void)
356 {
357 g_sessionCb.OnSessionOpened = TransOnSessionOpened;
358 g_sessionCb.OnSessionClosed = TransOnSessionClosed;
359 g_sessionCb.OnSessionOpenFailed = TransOnSessionOpenFailed;
360 g_sessionCb.OnDataReceived = TransOnDataReceived;
361 g_sessionCb.OnStreamReceived = TransOnOnStreamRecevied;
362 g_sessionCb.OnGetSessionId = ClientGetSessionIdByChannelId;
363 g_sessionCb.OnQosEvent = TransOnQosEvent;
364 g_sessionCb.OnIdleTimeoutReset = ClientResetIdleTimeoutById;
365 return &g_sessionCb;
366 }
367