• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_tcp_direct_manager.h"
17 
18 #include <securec.h>
19 
20 #include "client_trans_tcp_direct_callback.h"
21 #include "client_trans_tcp_direct_listener.h"
22 #include "softbus_adapter_mem.h"
23 #include "softbus_def.h"
24 #include "softbus_errcode.h"
25 #include "softbus_socket.h"
26 #include "softbus_utils.h"
27 #include "trans_log.h"
28 #include "trans_pending_pkt.h"
29 #include "trans_server_proxy.h"
30 
31 #define HEART_TIME 300
32 #define USER_TIME_OUT (30 * 1000)
33 
34 static SoftBusList *g_tcpDirectChannelInfoList = NULL;
35 
CheckInfoAndMutexLock(TcpDirectChannelInfo * info)36 static bool CheckInfoAndMutexLock(TcpDirectChannelInfo *info)
37 {
38     if (info == NULL) {
39         TRANS_LOGE(TRANS_SDK, "param invalid.");
40         return false;
41     }
42     if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
43         TRANS_LOGE(TRANS_SDK, "lock failed");
44         return false;
45     }
46     return true;
47 }
48 
TransTdcGetInfoById(int32_t channelId,TcpDirectChannelInfo * info)49 TcpDirectChannelInfo *TransTdcGetInfoById(int32_t channelId, TcpDirectChannelInfo *info)
50 {
51     if (!CheckInfoAndMutexLock(info)) {
52         return NULL;
53     }
54 
55     TcpDirectChannelInfo *item = NULL;
56     LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
57         if (item->channelId == channelId) {
58             (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
59             (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
60             return item;
61         }
62     }
63 
64     (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
65     return NULL;
66 }
67 
TransTdcGetInfoByIdWithIncSeq(int32_t channelId,TcpDirectChannelInfo * info)68 TcpDirectChannelInfo *TransTdcGetInfoByIdWithIncSeq(int32_t channelId, TcpDirectChannelInfo *info)
69 {
70     if (!CheckInfoAndMutexLock(info)) {
71         return NULL;
72     }
73 
74     TcpDirectChannelInfo *item = NULL;
75     LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
76         if (item->channelId == channelId) {
77             (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
78             item->detail.sequence++;
79             (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
80             return item;
81         }
82     }
83 
84     (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
85     return NULL;
86 }
87 
TransTdcGetInfoByFd(int32_t fd,TcpDirectChannelInfo * info)88 TcpDirectChannelInfo *TransTdcGetInfoByFd(int32_t fd, TcpDirectChannelInfo *info)
89 {
90     if (!CheckInfoAndMutexLock(info)) {
91         return NULL;
92     }
93 
94     TcpDirectChannelInfo *item = NULL;
95     LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
96         if (item->detail.fd == fd) {
97             (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
98             (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
99             return item;
100         }
101     }
102 
103     (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
104     return NULL;
105 }
106 
TransTdcCloseChannel(int32_t channelId)107 void TransTdcCloseChannel(int32_t channelId)
108 {
109     TRANS_LOGI(TRANS_SDK, "Close tdc Channel, channelId=%{public}d.", channelId);
110     if (ServerIpcCloseChannel(channelId, CHANNEL_TYPE_TCP_DIRECT) != SOFTBUS_OK) {
111         TRANS_LOGE(TRANS_SDK, "close server tdc channelId=%{public}d err.", channelId);
112     }
113 
114     TcpDirectChannelInfo *item = NULL;
115     if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
116         TRANS_LOGE(TRANS_SDK, "lock failed");
117         return;
118     }
119 
120     LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
121         if (item->channelId == channelId) {
122             TransTdcReleaseFd(item->detail.fd);
123             ListDelete(&item->node);
124             SoftBusFree(item);
125             item = NULL;
126             (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
127             DelPendingPacket(channelId, PENDING_TYPE_DIRECT);
128             TRANS_LOGI(TRANS_SDK, "Delete tdc item success. channelId=%{public}d", channelId);
129             return;
130         }
131     }
132 
133     TRANS_LOGE(TRANS_SDK, "Target item not exist. channelId=%{public}d", channelId);
134     (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
135 }
136 
TransGetNewTcpChannel(const ChannelInfo * channel)137 static TcpDirectChannelInfo *TransGetNewTcpChannel(const ChannelInfo *channel)
138 {
139     if (channel == NULL) {
140         TRANS_LOGE(TRANS_SDK, "param invalid");
141         return NULL;
142     }
143     TcpDirectChannelInfo *item = (TcpDirectChannelInfo *)SoftBusCalloc(sizeof(TcpDirectChannelInfo));
144     if (item == NULL) {
145         TRANS_LOGE(TRANS_SDK, "calloc failed");
146         return NULL;
147     }
148     item->channelId = channel->channelId;
149     item->detail.fd = channel->fd;
150     item->detail.channelType = channel->channelType;
151     if (memcpy_s(item->detail.sessionKey, SESSION_KEY_LENGTH, channel->sessionKey, SESSION_KEY_LENGTH) != EOK) {
152         SoftBusFree(item);
153         TRANS_LOGE(TRANS_SDK, "sessionKey copy failed");
154         return NULL;
155     }
156     return item;
157 }
158 
ClientTransCheckTdcChannelExist(int32_t channelId)159 static int32_t ClientTransCheckTdcChannelExist(int32_t channelId)
160 {
161     if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
162         TRANS_LOGE(TRANS_SDK, "lock failed.");
163         return SOFTBUS_ERR;
164     }
165     TcpDirectChannelInfo *item = NULL;
166     LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
167         if (item->channelId == channelId) {
168             TRANS_LOGE(TRANS_SDK, "tcp direct already exist. channelId=%{public}d", channelId);
169             (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
170             return SOFTBUS_ERR;
171         }
172     }
173     (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
174     return SOFTBUS_OK;
175 }
176 
TransTdcDelChannelInfo(int32_t channelId)177 static void TransTdcDelChannelInfo(int32_t channelId)
178 {
179     TRANS_LOGI(TRANS_SDK, "Delete tdc channelId=%{public}d.", channelId);
180 
181     TcpDirectChannelInfo *item = NULL;
182     TcpDirectChannelInfo *nextNode = NULL;
183     if (g_tcpDirectChannelInfoList == NULL) {
184         return;
185     }
186     if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
187         TRANS_LOGE(TRANS_SDK, "lock failed");
188         return;
189     }
190 
191     LIST_FOR_EACH_ENTRY_SAFE(item, nextNode, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
192         if (item->channelId == channelId) {
193             TransTdcReleaseFd(item->detail.fd);
194             ListDelete(&item->node);
195             SoftBusFree(item);
196             item = NULL;
197             (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
198             TRANS_LOGI(TRANS_SDK, "Delete tdc item success. channelId=%{public}d", channelId);
199             return;
200         }
201     }
202 
203     TRANS_LOGE(TRANS_SDK, "Target item not exist. channelId=%{public}d", channelId);
204     (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
205 }
206 
ClientTransTdcOnChannelOpened(const char * sessionName,const ChannelInfo * channel)207 int32_t ClientTransTdcOnChannelOpened(const char *sessionName, const ChannelInfo *channel)
208 {
209     if (sessionName == NULL || channel == NULL) {
210         TRANS_LOGE(TRANS_SDK, "param invalid");
211         return SOFTBUS_ERR;
212     }
213     if (ClientTransCheckTdcChannelExist(channel->channelId) != SOFTBUS_OK) {
214         return SOFTBUS_ERR;
215     }
216     TcpDirectChannelInfo *item = TransGetNewTcpChannel(channel);
217     if (item == NULL) {
218         TRANS_LOGE(TRANS_SDK, "get new tcp channel err. channelId=%{public}d", channel->channelId);
219         return SOFTBUS_ERR;
220     }
221     if (TransAddDataBufNode(channel->channelId, channel->fd) != SOFTBUS_OK) {
222         TRANS_LOGE(TRANS_SDK,
223             "add data buf node fail. channelId=%{public}d, fd=%{public}d", channel->channelId, channel->fd);
224         SoftBusFree(item);
225         return SOFTBUS_ERR;
226     }
227     if (TransTdcCreateListener(channel->fd) != SOFTBUS_OK) {
228         TRANS_LOGE(TRANS_SDK, "trans tdc create listener failed. fd=%{public}d", channel->fd);
229         goto EXIT_ERR;
230     }
231     if (ConnSetTcpKeepAlive(channel->fd, HEART_TIME) != SOFTBUS_OK) {
232         TRANS_LOGE(TRANS_SDK, "ConnSetTcpKeepAlive failed, fd=%{public}d.", channel->fd);
233         goto EXIT_ERR;
234     }
235     if (ConnSetTcpUserTimeOut(channel->fd, USER_TIME_OUT) != SOFTBUS_OK) {
236         TRANS_LOGE(TRANS_SDK, "ConnSetTcpUserTimeOut failed, fd=%{public}d.", channel->fd);
237         goto EXIT_ERR;
238     }
239     if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
240         TRANS_LOGE(TRANS_SDK, "lock failed.");
241         goto EXIT_ERR;
242     }
243     ListAdd(&g_tcpDirectChannelInfoList->list, &item->node);
244     TRANS_LOGI(TRANS_SDK, "add channelId=%{public}d", item->channelId);
245     (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
246 
247     if (ClientTransTdcOnSessionOpened(sessionName, channel) != SOFTBUS_OK) {
248         TransDelDataBufNode(channel->channelId);
249         TransTdcDelChannelInfo(channel->channelId);
250         TRANS_LOGE(TRANS_SDK, "notify on session opened err.");
251         return SOFTBUS_ERR;
252     }
253     return SOFTBUS_OK;
254 EXIT_ERR:
255     TransDelDataBufNode(channel->channelId);
256     SoftBusFree(item);
257     return SOFTBUS_ERR;
258 }
259 
TransTdcManagerInit(const IClientSessionCallBack * callback)260 int32_t TransTdcManagerInit(const IClientSessionCallBack *callback)
261 {
262     g_tcpDirectChannelInfoList = CreateSoftBusList();
263     if (g_tcpDirectChannelInfoList == NULL || TransDataListInit() != SOFTBUS_OK) {
264         TRANS_LOGE(TRANS_INIT, "init tcp direct channel fail.");
265         return SOFTBUS_ERR;
266     }
267     if (ClientTransTdcSetCallBack(callback) != SOFTBUS_OK) {
268         TRANS_LOGE(TRANS_INIT, "ClientTransTdcSetCallBack fail.");
269         return SOFTBUS_ERR;
270     }
271     if (PendingInit(PENDING_TYPE_DIRECT) == SOFTBUS_ERR) {
272         TRANS_LOGE(TRANS_INIT, "trans direct pending init failed.");
273         return SOFTBUS_ERR;
274     }
275     TRANS_LOGE(TRANS_INIT, "init tcp direct channel success.");
276     return SOFTBUS_OK;
277 }
278 
TransTdcManagerDeinit(void)279 void TransTdcManagerDeinit(void)
280 {
281     if (g_tcpDirectChannelInfoList == NULL) {
282         return;
283     }
284 
285     TransDataListDeinit();
286     DestroySoftBusList(g_tcpDirectChannelInfoList);
287     g_tcpDirectChannelInfoList = NULL;
288     PendingDeinit(PENDING_TYPE_DIRECT);
289 }
290 
ClientTransTdcOnChannelOpenFailed(int32_t channelId,int32_t errCode)291 int32_t ClientTransTdcOnChannelOpenFailed(int32_t channelId, int32_t errCode)
292 {
293     return ClientTransTdcOnSessionOpenFailed(channelId, errCode);
294 }
295 
TransTdcGetSessionKey(int32_t channelId,char * key,unsigned int len)296 int32_t TransTdcGetSessionKey(int32_t channelId, char *key, unsigned int len)
297 {
298     if (key == NULL) {
299         TRANS_LOGW(TRANS_SDK, "invalid param.");
300         return SOFTBUS_INVALID_PARAM;
301     }
302     TcpDirectChannelInfo channel;
303     if (TransTdcGetInfoById(channelId, &channel) == NULL) {
304         TRANS_LOGE(TRANS_SDK, "get tdc info failed. channelId=%{public}d", channelId);
305         return SOFTBUS_ERR;
306     }
307     if (memcpy_s(key, len, channel.detail.sessionKey, SESSION_KEY_LENGTH) != EOK) {
308         TRANS_LOGE(TRANS_SDK, "copy session key failed.");
309         return SOFTBUS_MEM_ERR;
310     }
311     return SOFTBUS_OK;
312 }
313 
TransTdcGetHandle(int32_t channelId,int * handle)314 int32_t TransTdcGetHandle(int32_t channelId, int *handle)
315 {
316     if (handle == NULL) {
317         TRANS_LOGW(TRANS_SDK, "invalid param.");
318         return SOFTBUS_INVALID_PARAM;
319     }
320     TcpDirectChannelInfo channel;
321     if (TransTdcGetInfoById(channelId, &channel) == NULL) {
322         TRANS_LOGE(TRANS_SDK, "get tdc info failed. channelId=%{public}d", channelId);
323         return SOFTBUS_ERR;
324     }
325     *handle = channel.detail.fd;
326     return SOFTBUS_OK;
327 }
328 
TransDisableSessionListener(int32_t channelId)329 int32_t TransDisableSessionListener(int32_t channelId)
330 {
331     TcpDirectChannelInfo channel;
332     if (TransTdcGetInfoById(channelId, &channel) == NULL) {
333         TRANS_LOGE(TRANS_SDK, "get tdc info failed. channelId=%{public}d", channelId);
334         return SOFTBUS_ERR;
335     }
336     if (channel.detail.fd < 0) {
337         TRANS_LOGE(TRANS_SDK, "invalid handle.");
338         return SOFTBUS_ERR;
339     }
340     return TransTdcStopRead(channel.detail.fd);
341 }
342