1 /*
2  * Copyright (c) 2022-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 "client_trans_file_listener.h"
17 
18 #include <securec.h>
19 
20 #include "anonymizer.h"
21 #include "softbus_adapter_mem.h"
22 #include "softbus_adapter_thread.h"
23 #include "softbus_def.h"
24 #include "softbus_errcode.h"
25 #include "softbus_utils.h"
26 #include "trans_log.h"
27 
28 static SoftBusList *g_fileListener = NULL;
29 
TransFileInit(void)30 int TransFileInit(void)
31 {
32     if (g_fileListener != NULL) {
33         TRANS_LOGI(TRANS_INIT, "file listener has init.");
34         return SOFTBUS_OK;
35     }
36     g_fileListener = CreateSoftBusList();
37     if (g_fileListener == NULL) {
38         TRANS_LOGE(TRANS_INIT, "create file listener list failed.");
39         return SOFTBUS_MALLOC_ERR;
40     }
41     return SOFTBUS_OK;
42 }
43 
TransFileDeinit(void)44 void TransFileDeinit(void)
45 {
46     if (g_fileListener == NULL) {
47         return;
48     }
49     if (SoftBusMutexLock(&(g_fileListener->lock)) != SOFTBUS_OK) {
50         TRANS_LOGE(TRANS_INIT, "file listener deinit lock failed");
51         return;
52     }
53     FileListener *fileNode = NULL;
54     FileListener *nextNode = NULL;
55     LIST_FOR_EACH_ENTRY_SAFE(fileNode, nextNode, &(g_fileListener->list), FileListener, node) {
56         ListDelete(&(fileNode->node));
57         SoftBusFree(fileNode);
58     }
59     (void)SoftBusMutexUnlock(&(g_fileListener->lock));
60     DestroySoftBusList(g_fileListener);
61     g_fileListener = NULL;
62 }
63 
TransSetFileReceiveListener(const char * sessionName,const IFileReceiveListener * recvListener,const char * rootDir)64 int32_t TransSetFileReceiveListener(const char *sessionName,
65     const IFileReceiveListener *recvListener, const char *rootDir)
66 {
67     TRANS_CHECK_AND_RETURN_RET_LOGE(
68         g_fileListener != NULL, SOFTBUS_TRANS_FILE_LISTENER_NOT_INIT, TRANS_CTRL, "file listener hasn't init.");
69     if (SoftBusMutexLock(&(g_fileListener->lock)) != SOFTBUS_OK) {
70         TRANS_LOGE(TRANS_FILE, "file receive listener lock failed");
71         return SOFTBUS_LOCK_ERR;
72     }
73     FileListener *fileNode = NULL;
74     bool exist = false;
75     LIST_FOR_EACH_ENTRY(fileNode, &(g_fileListener->list), FileListener, node) {
76         if (strcmp(fileNode->mySessionName, sessionName) == 0) {
77             exist = true;
78             break;
79         }
80     }
81     if (exist) {
82         if (strcpy_s(fileNode->rootDir, FILE_RECV_ROOT_DIR_SIZE_MAX, rootDir) != EOK ||
83             memcpy_s(&(fileNode->recvListener), sizeof(IFileReceiveListener),
84                 recvListener, sizeof(IFileReceiveListener)) != EOK) {
85             (void)SoftBusMutexUnlock(&(g_fileListener->lock));
86             TRANS_LOGE(TRANS_FILE, "update file receive listener failed");
87             return SOFTBUS_MEM_ERR;
88         }
89         (void)SoftBusMutexUnlock(&(g_fileListener->lock));
90         TRANS_LOGI(TRANS_FILE, "update file receive listener success");
91         return SOFTBUS_OK;
92     }
93     fileNode = (FileListener *)SoftBusCalloc(sizeof(FileListener));
94     if (fileNode == NULL) {
95         (void)SoftBusMutexUnlock(&(g_fileListener->lock));
96         TRANS_LOGE(TRANS_FILE, "file receive listener calloc failed");
97         return SOFTBUS_MALLOC_ERR;
98     }
99     if (strcpy_s(fileNode->mySessionName, SESSION_NAME_SIZE_MAX, sessionName) != EOK ||
100         strcpy_s(fileNode->rootDir, FILE_RECV_ROOT_DIR_SIZE_MAX, rootDir) != EOK ||
101         memcpy_s(&(fileNode->recvListener), sizeof(IFileReceiveListener),
102             recvListener, sizeof(IFileReceiveListener)) != EOK) {
103         TRANS_LOGE(TRANS_FILE, "file node copy failed.");
104         SoftBusFree(fileNode);
105         (void)SoftBusMutexUnlock(&(g_fileListener->lock));
106         return SOFTBUS_MEM_ERR;
107     }
108     ListAdd(&(g_fileListener->list), &(fileNode->node));
109     char *tmpName = NULL;
110     Anonymize(sessionName, &tmpName);
111     TRANS_LOGI(TRANS_FILE, "add sessionName=%{public}s", tmpName);
112     AnonymizeFree(tmpName);
113     (void)SoftBusMutexUnlock(&(g_fileListener->lock));
114     return SOFTBUS_OK;
115 }
116 
TransSetFileSendListener(const char * sessionName,const IFileSendListener * sendListener)117 int32_t TransSetFileSendListener(const char *sessionName, const IFileSendListener *sendListener)
118 {
119     if (g_fileListener == NULL) {
120         TRANS_LOGE(TRANS_FILE, "file listener hasn't init.");
121         return SOFTBUS_TRANS_FILE_LISTENER_NOT_INIT;
122     }
123     if (SoftBusMutexLock(&(g_fileListener->lock)) != SOFTBUS_OK) {
124         TRANS_LOGE(TRANS_FILE, "file send listener lock failed");
125         return SOFTBUS_LOCK_ERR;
126     }
127     FileListener *fileNode = NULL;
128     bool exist = false;
129     LIST_FOR_EACH_ENTRY(fileNode, &(g_fileListener->list), FileListener, node) {
130         if (strcmp(fileNode->mySessionName, sessionName) == 0) {
131             exist = true;
132             break;
133         }
134     }
135     if (exist) {
136         if (memcpy_s(&(fileNode->sendListener), sizeof(IFileSendListener),
137             sendListener, sizeof(IFileSendListener)) != EOK) {
138             (void)SoftBusMutexUnlock(&(g_fileListener->lock));
139             TRANS_LOGE(TRANS_FILE, "memcpy_s file send listener failed");
140             return SOFTBUS_MEM_ERR;
141         }
142         (void)SoftBusMutexUnlock(&(g_fileListener->lock));
143         TRANS_LOGE(TRANS_FILE, "update file send listener success");
144         return SOFTBUS_OK;
145     }
146     fileNode = (FileListener *)SoftBusCalloc(sizeof(FileListener));
147     if (fileNode == NULL) {
148         (void)SoftBusMutexUnlock(&(g_fileListener->lock));
149         TRANS_LOGE(TRANS_FILE, "file send listener calloc failed");
150         return SOFTBUS_MALLOC_ERR;
151     }
152     if (strcpy_s(fileNode->mySessionName, SESSION_NAME_SIZE_MAX, sessionName) != EOK ||
153         memcpy_s(&(fileNode->sendListener), sizeof(IFileSendListener),
154             sendListener, sizeof(IFileSendListener)) != EOK) {
155         TRANS_LOGE(TRANS_FILE, "file node copy failed.");
156         SoftBusFree(fileNode);
157         (void)SoftBusMutexUnlock(&(g_fileListener->lock));
158         return SOFTBUS_MEM_ERR;
159     }
160     ListAdd(&(g_fileListener->list), &(fileNode->node));
161     TRANS_LOGI(TRANS_FILE, "add sessionName = %{public}s", sessionName);
162     (void)SoftBusMutexUnlock(&(g_fileListener->lock));
163     return SOFTBUS_OK;
164 }
165 
TransAddNewSocketFileListener(const char * sessionName,SocketFileCallbackFunc fileCallback,bool isReceiver)166 static int32_t TransAddNewSocketFileListener(const char *sessionName, SocketFileCallbackFunc fileCallback,
167     bool isReceiver)
168 {
169     if (sessionName == NULL || fileCallback == NULL) {
170         TRANS_LOGE(TRANS_SDK, "invalid param.");
171         return SOFTBUS_INVALID_PARAM;
172     }
173     FileListener *listener = (FileListener *)SoftBusCalloc(sizeof(FileListener));
174     if (listener == NULL) {
175         TRANS_LOGE(TRANS_SDK, "file send listener calloc failed");
176         return SOFTBUS_MALLOC_ERR;
177     }
178     if (strcpy_s(listener->mySessionName, SESSION_NAME_SIZE_MAX, sessionName) != EOK) {
179         TRANS_LOGE(TRANS_SDK, "file node copy failed.");
180         SoftBusFree(listener);
181         return SOFTBUS_STRCPY_ERR;
182     }
183     if (isReceiver) {
184         listener->socketRecvCallback = fileCallback;
185     } else {
186         listener->socketSendCallback = fileCallback;
187     }
188     ListAdd(&(g_fileListener->list), &(listener->node));
189     return SOFTBUS_OK;
190 }
191 
TransSetSocketFileListener(const char * sessionName,SocketFileCallbackFunc fileCallback,bool isReceiver)192 int32_t TransSetSocketFileListener(const char *sessionName, SocketFileCallbackFunc fileCallback, bool isReceiver)
193 {
194     if (sessionName == NULL || fileCallback == NULL) {
195         TRANS_LOGE(TRANS_SDK, "[client] invalid param.");
196         return SOFTBUS_INVALID_PARAM;
197     }
198     if (g_fileListener == NULL) {
199         TRANS_LOGE(TRANS_FILE, "file listener hasn't init.");
200         return SOFTBUS_TRANS_FILE_LISTENER_NOT_INIT;
201     }
202     if (SoftBusMutexLock(&(g_fileListener->lock)) != SOFTBUS_OK) {
203         TRANS_LOGE(TRANS_SDK, "file delete lock failed");
204         return SOFTBUS_LOCK_ERR;
205     }
206 
207     FileListener *fileNode = NULL;
208     bool exist = false;
209     LIST_FOR_EACH_ENTRY(fileNode, &(g_fileListener->list), FileListener, node) {
210         if (strcmp(fileNode->mySessionName, sessionName) == 0) {
211             exist = true;
212             break;
213         }
214     }
215     if (exist) {
216         if (isReceiver) {
217             fileNode->socketRecvCallback = fileCallback;
218         } else {
219             fileNode->socketSendCallback = fileCallback;
220         }
221         (void)SoftBusMutexUnlock(&(g_fileListener->lock));
222         TRANS_LOGI(TRANS_SDK, "update file callback of socket");
223         return SOFTBUS_OK;
224     }
225     int32_t ret = TransAddNewSocketFileListener(sessionName, fileCallback, isReceiver);
226     if (ret != SOFTBUS_OK) {
227         (void)SoftBusMutexUnlock(&(g_fileListener->lock));
228         TRANS_LOGE(TRANS_SDK, "failed to add new socket file listener");
229         return ret;
230     }
231     (void)SoftBusMutexUnlock(&(g_fileListener->lock));
232 
233     char *tmpName = NULL;
234     Anonymize(sessionName, &tmpName);
235     TRANS_LOGI(TRANS_SDK, "set socket file listener ok, sessionName=%{public}s, isReceiver=%{public}d",
236         tmpName, isReceiver);
237     AnonymizeFree(tmpName);
238     return SOFTBUS_OK;
239 }
240 
TransGetFileListener(const char * sessionName,FileListener * fileListener)241 int32_t TransGetFileListener(const char *sessionName, FileListener *fileListener)
242 {
243     if (g_fileListener == NULL) {
244         TRANS_LOGE(TRANS_FILE, "file listener hasn't init.");
245         return SOFTBUS_TRANS_FILE_LISTENER_NOT_INIT;
246     }
247     if (SoftBusMutexLock(&(g_fileListener->lock)) != SOFTBUS_OK) {
248         TRANS_LOGE(TRANS_FILE, "file get listener lock failed");
249         return SOFTBUS_LOCK_ERR;
250     }
251 
252     FileListener *fileNode = NULL;
253     LIST_FOR_EACH_ENTRY(fileNode, &(g_fileListener->list), FileListener, node) {
254         if (strcmp(fileNode->mySessionName, sessionName) == 0) {
255             if (memcpy_s(fileListener, sizeof(FileListener), fileNode, sizeof(FileListener)) != EOK) {
256                 TRANS_LOGE(TRANS_FILE, "memcpy_s file listener failed.");
257                 (void)SoftBusMutexUnlock(&(g_fileListener->lock));
258                 return SOFTBUS_MEM_ERR;
259             }
260             (void)SoftBusMutexUnlock(&(g_fileListener->lock));
261             return SOFTBUS_OK;
262         }
263     }
264     (void)SoftBusMutexUnlock(&(g_fileListener->lock));
265     return SOFTBUS_TRANS_NODE_NOT_FOUND;
266 }
267 
TransDeleteFileListener(const char * sessionName)268 void TransDeleteFileListener(const char *sessionName)
269 {
270     if (sessionName == NULL) {
271         TRANS_LOGW(TRANS_FILE, "invalid param.");
272         return;
273     }
274     if (g_fileListener == NULL) {
275         TRANS_LOGE(TRANS_FILE, "file listener hasn't init.");
276         return;
277     }
278     if (SoftBusMutexLock(&(g_fileListener->lock)) != SOFTBUS_OK) {
279         TRANS_LOGE(TRANS_FILE, "file delete lock failed");
280         return;
281     }
282 
283     FileListener *fileNode = NULL;
284     LIST_FOR_EACH_ENTRY(fileNode, &(g_fileListener->list), FileListener, node) {
285         if (strcmp(fileNode->mySessionName, sessionName) == 0) {
286             ListDelete(&fileNode->node);
287             char *tmpName = NULL;
288             Anonymize(sessionName, &tmpName);
289             TRANS_LOGI(TRANS_FILE, "delete sessionName=%{public}s", AnonymizeWrapper(tmpName));
290             AnonymizeFree(tmpName);
291             SoftBusFree(fileNode);
292             break;
293         }
294     }
295     (void)SoftBusMutexUnlock(&(g_fileListener->lock));
296 }
297