1 /*
2  * Copyright (c) 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 "auth_connection.h"
17 
18 #include <securec.h>
19 
20 #include "auth_common.h"
21 #include "auth_log.h"
22 #include "auth_tcp_connection.h"
23 #include "lnn_async_callback_utils.h"
24 #include "softbus_adapter_bt_common.h"
25 #include "softbus_adapter_errcode.h"
26 #include "softbus_adapter_mem.h"
27 #include "softbus_adapter_socket.h"
28 #include "softbus_conn_interface.h"
29 #include "softbus_def.h"
30 #include "wifi_direct_manager.h"
31 
32 #define AUTH_CONN_DATA_HEAD_SIZE             24
33 #define AUTH_ENHANCE_P2P_CONNECT_TIMEOUT_MS  4500
34 #define AUTH_CONN_CONNECT_TIMEOUT_MS         11000
35 #define AUTH_REPEAT_DEVICE_ID_HANDLE_DELAY   1000
36 #define AUTH_CONN_MAX_RETRY_TIMES            1
37 #define AUTH_CONN_RETRY_DELAY_MILLIS         3000
38 
39 typedef struct {
40     uint32_t requestId;
41     AuthConnInfo connInfo;
42     uint32_t retryTimes;
43 } ConnCmdInfo;
44 
45 typedef struct {
46     uint32_t requestId;
47     int32_t fd;
48     AuthConnInfo connInfo;
49     uint32_t retryTimes;
50     ListNode node;
51 } ConnRequest;
52 
53 static ListNode g_connRequestList = { &g_connRequestList, &g_connRequestList };
54 static AuthConnListener g_listener = { 0 };
55 
RouteBuildClientAuthManager(int32_t cfd)56 void __attribute__((weak)) RouteBuildClientAuthManager(int32_t cfd)
57 {
58     (void)cfd;
59 }
RouteClearAuthChannelId(int32_t cfd)60 void __attribute__((weak)) RouteClearAuthChannelId(int32_t cfd)
61 {
62     (void)cfd;
63 }
64 
IsEnhanceP2pModuleId(ListenerModule moduleId)65 static bool IsEnhanceP2pModuleId(ListenerModule moduleId)
66 {
67     if (moduleId >= AUTH_ENHANCED_P2P_START && moduleId <= AUTH_ENHANCED_P2P_END) {
68         return true;
69     }
70     return false;
71 }
72 
GenConnId(int32_t connType, int32_t id)73 uint64_t GenConnId(int32_t connType, int32_t id)
74 {
75     uint64_t connId = (uint64_t)connType;
76     connId = (connId << INT32_BIT_NUM) & MASK_UINT64_H32;
77     connId |= (((uint64_t)id) & MASK_UINT64_L32);
78     return connId;
79 }
80 
GetConnType(uint64_t connId)81 int32_t GetConnType(uint64_t connId)
82 {
83     return (int32_t)((connId >> INT32_BIT_NUM) & MASK_UINT64_L32);
84 }
85 
GetConnTypeStr(uint64_t connId)86 const char *GetConnTypeStr(uint64_t connId)
87 {
88     int32_t type = GetConnType(connId);
89     switch (type) {
90         case AUTH_LINK_TYPE_WIFI:
91             return "wifi/eth";
92         case AUTH_LINK_TYPE_BR:
93             return "br";
94         case AUTH_LINK_TYPE_BLE:
95             return "ble";
96         case AUTH_LINK_TYPE_P2P:
97             return "p2p";
98         case AUTH_LINK_TYPE_ENHANCED_P2P:
99             return "enhanced_p2p";
100         default:
101             break;
102     }
103     return "unknown";
104 }
105 
GetConnId(uint64_t connId)106 uint32_t GetConnId(uint64_t connId)
107 {
108     return (uint32_t)(connId & MASK_UINT64_L32);
109 }
110 
GetFd(uint64_t connId)111 int32_t GetFd(uint64_t connId)
112 {
113     return (int32_t)(connId & MASK_UINT64_L32);
114 }
115 
UpdateFd(uint64_t *connId, int32_t id)116 void UpdateFd(uint64_t *connId, int32_t id)
117 {
118     CHECK_NULL_PTR_RETURN_VOID(connId);
119     *connId &= MASK_UINT64_H32;
120     *connId |= (((uint64_t)id) & MASK_UINT64_L32);
121 }
122 
123 /* Conn Request */
AddConnRequest(const AuthConnInfo *connInfo, uint32_t requestId, int32_t fd)124 static int32_t AddConnRequest(const AuthConnInfo *connInfo, uint32_t requestId, int32_t fd)
125 {
126     ConnRequest *item = (ConnRequest *)SoftBusMalloc(sizeof(ConnRequest));
127     if (item == NULL) {
128         AUTH_LOGE(AUTH_CONN, "malloc ConnRequest fail");
129         return SOFTBUS_MALLOC_ERR;
130     }
131     item->fd = fd;
132     item->requestId = requestId;
133     if (memcpy_s(&item->connInfo, sizeof(item->connInfo), connInfo, sizeof(AuthConnInfo)) != EOK) {
134         AUTH_LOGE(AUTH_CONN, "set AuthConnInfo fail");
135         SoftBusFree(item);
136         return SOFTBUS_MEM_ERR;
137     }
138     ListTailInsert(&g_connRequestList, &item->node);
139     return SOFTBUS_OK;
140 }
141 
FindConnRequestByFd(int32_t fd)142 static ConnRequest *FindConnRequestByFd(int32_t fd)
143 {
144     ConnRequest *item = NULL;
145     LIST_FOR_EACH_ENTRY(item, &g_connRequestList, ConnRequest, node) {
146         if (item->fd == fd) {
147             return item;
148         }
149     }
150     return NULL;
151 }
152 
FindConnRequestByRequestId(uint32_t requestId)153 static ConnRequest *FindConnRequestByRequestId(uint32_t requestId)
154 {
155     ConnRequest *item = NULL;
156     LIST_FOR_EACH_ENTRY(item, &g_connRequestList, ConnRequest, node) {
157         if (item->requestId == requestId) {
158             return item;
159         }
160     }
161     return NULL;
162 }
163 
DelConnRequest(ConnRequest *item)164 static void DelConnRequest(ConnRequest *item)
165 {
166     CHECK_NULL_PTR_RETURN_VOID(item);
167     ListDelete(&item->node);
168     SoftBusFree(item);
169 }
170 
ClearConnRequest(void)171 static void ClearConnRequest(void)
172 {
173     ConnRequest *item = NULL;
174     ConnRequest *next = NULL;
175     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_connRequestList, ConnRequest, node) {
176         DelConnRequest(item);
177     }
178 }
179 
180 /* Notify Conn Listener */
181 
NotifyClientConnected(uint32_t requestId, uint64_t connId, int32_t result, const AuthConnInfo *connInfo)182 static void NotifyClientConnected(uint32_t requestId, uint64_t connId, int32_t result, const AuthConnInfo *connInfo)
183 {
184     if (g_listener.onConnectResult != NULL) {
185         g_listener.onConnectResult(requestId, connId, result, connInfo);
186     }
187 }
188 
NotifyDisconnected(uint64_t connId, const AuthConnInfo *connInfo)189 static void NotifyDisconnected(uint64_t connId, const AuthConnInfo *connInfo)
190 {
191     if (g_listener.onDisconnected != NULL) {
192         g_listener.onDisconnected(connId, connInfo);
193     }
194 }
195 
NotifyDataReceived( uint64_t connId, const AuthConnInfo *connInfo, bool fromServer, const AuthDataHead *head, const uint8_t *data)196 static void NotifyDataReceived(
197     uint64_t connId, const AuthConnInfo *connInfo, bool fromServer, const AuthDataHead *head, const uint8_t *data)
198 {
199     if (g_listener.onDataReceived != NULL) {
200         g_listener.onDataReceived(connId, connInfo, fromServer, head, data);
201     }
202 }
203 
204 /* AuthData */
GetAuthDataSize(uint32_t len)205 uint32_t GetAuthDataSize(uint32_t len)
206 {
207     return AUTH_CONN_DATA_HEAD_SIZE + len;
208 }
209 
PackAuthData(const AuthDataHead *head, const uint8_t *data, uint8_t *buf, uint32_t size)210 int32_t PackAuthData(const AuthDataHead *head, const uint8_t *data,
211     uint8_t *buf, uint32_t size)
212 {
213     if (head == NULL || data == NULL || buf == NULL) {
214         AUTH_LOGE(AUTH_CONN, "param error");
215         return SOFTBUS_INVALID_PARAM;
216     }
217     if (size < GetAuthDataSize(head->len)) {
218         return SOFTBUS_NO_ENOUGH_DATA;
219     }
220     uint32_t offset = 0;
221     *(uint32_t *)buf = SoftBusHtoLl(head->dataType);
222     offset += sizeof(uint32_t);
223     *(uint32_t *)(buf + offset) = SoftBusHtoLl((uint32_t)head->module);
224     offset += sizeof(uint32_t);
225     *(uint64_t *)(buf + offset) = SoftBusHtoLll((uint64_t)head->seq);
226     offset += sizeof(uint64_t);
227     *(uint32_t *)(buf + offset) = SoftBusHtoLl((uint32_t)head->flag);
228     offset += sizeof(uint32_t);
229     *(uint32_t *)(buf + offset) = SoftBusHtoLl(head->len);
230     offset += sizeof(uint32_t);
231 
232     if (memcpy_s(buf + offset, size - offset, data, head->len) != EOK) {
233         AUTH_LOGE(AUTH_CONN, "pack AuthData fail");
234         return SOFTBUS_MEM_ERR;
235     }
236     return SOFTBUS_OK;
237 }
238 
UnpackAuthData(const uint8_t *data, uint32_t len, AuthDataHead *head)239 const uint8_t *UnpackAuthData(const uint8_t *data, uint32_t len, AuthDataHead *head)
240 {
241     if (len < GetAuthDataSize(0)) {
242         AUTH_LOGE(AUTH_CONN, "head not enough");
243         return NULL;
244     }
245     uint32_t offset = 0;
246     head->dataType = SoftBusLtoHl(*(uint32_t *)data);
247     offset += sizeof(uint32_t);
248     head->module = (int32_t)SoftBusLtoHl(*(uint32_t *)(data + offset));
249     offset += sizeof(uint32_t);
250     head->seq = (int64_t)SoftBusLtoHll(*(uint64_t *)(data + offset));
251     offset += sizeof(uint64_t);
252     head->flag = (int32_t)SoftBusLtoHl(*(uint32_t *)(data + offset));
253     offset += sizeof(uint32_t);
254     head->len = SoftBusLtoHl(*(uint32_t *)(data + offset));
255     offset += sizeof(uint32_t);
256     uint32_t dataLen = GetAuthDataSize(head->len);
257     if (len < dataLen || dataLen < GetAuthDataSize(0)) {
258         AUTH_LOGE(AUTH_CONN, "data not enough");
259         return NULL;
260     }
261     return (data + offset);
262 }
263 
264 /* EVENT_CONNECT_TIMEOUT */
HandleConnConnectTimeout(const void *para)265 static void HandleConnConnectTimeout(const void *para)
266 {
267     CHECK_NULL_PTR_RETURN_VOID(para);
268     uint32_t requestId = *(uint32_t *)(para);
269     AUTH_LOGE(AUTH_CONN, "connect timeout, requestId=%{public}u", requestId);
270     ConnRequest *item = FindConnRequestByRequestId(requestId);
271     if (item != NULL) {
272         ListenerModule module = item->connInfo.type == AUTH_LINK_TYPE_RAW_ENHANCED_P2P ? AUTH_RAW_P2P_SERVER : AUTH;
273         SocketDisconnectDevice(module, item->fd);
274         DelConnRequest(item);
275     }
276     NotifyClientConnected(requestId, 0, SOFTBUS_AUTH_CONN_TIMEOUT, NULL);
277 }
278 
PostConnConnectTimeout(uint32_t requestId, AuthLinkType type)279 static void PostConnConnectTimeout(uint32_t requestId, AuthLinkType type)
280 {
281     if (type == AUTH_LINK_TYPE_ENHANCED_P2P) {
282         PostAuthEvent(EVENT_CONNECT_TIMEOUT, HandleConnConnectTimeout, &requestId, sizeof(requestId),
283             AUTH_ENHANCE_P2P_CONNECT_TIMEOUT_MS);
284     } else {
285         PostAuthEvent(EVENT_CONNECT_TIMEOUT, HandleConnConnectTimeout, &requestId, sizeof(requestId),
286             AUTH_CONN_CONNECT_TIMEOUT_MS);
287     }
288 }
289 
RemoveFunc(const void *obj, void *param)290 static int32_t RemoveFunc(const void *obj, void *param)
291 {
292     CHECK_NULL_PTR_RETURN_VALUE(obj, SOFTBUS_ERR);
293     CHECK_NULL_PTR_RETURN_VALUE(param, SOFTBUS_ERR);
294     return ((*(uint32_t *)(obj) == *(uint32_t *)(param)) ? SOFTBUS_OK : SOFTBUS_ERR);
295 }
296 
RemoveConnConnectTimeout(uint32_t requestId)297 static void RemoveConnConnectTimeout(uint32_t requestId)
298 {
299     RemoveAuthEvent(EVENT_CONNECT_TIMEOUT, RemoveFunc, (void *)(&requestId));
300 }
301 
302 /* EVENT_CONNECT_CMD */
HandleConnConnectCmd(const void *para)303 static void HandleConnConnectCmd(const void *para)
304 {
305     CHECK_NULL_PTR_RETURN_VOID(para);
306     ConnCmdInfo *info = (ConnCmdInfo *)para;
307     if (info->connInfo.type != AUTH_LINK_TYPE_WIFI) {
308         AUTH_LOGE(AUTH_CONN, "invalid connType=%{public}d", info->connInfo.type);
309         return;
310     }
311     int32_t fd = SocketConnectDevice(info->connInfo.info.ipInfo.ip, info->connInfo.info.ipInfo.port, false);
312     if (fd < 0) {
313         AUTH_LOGE(AUTH_CONN, "SocketConnectDevice fail");
314         RemoveConnConnectTimeout(info->requestId);
315         NotifyClientConnected(info->requestId, 0, SOFTBUS_AUTH_CONN_FAIL, NULL);
316         return;
317     }
318     (void)AddConnRequest(&info->connInfo, info->requestId, fd);
319 }
320 
321 /* EVENT_CONNECT_RESULT */
HandleConnConnectResult(const void *para)322 static void HandleConnConnectResult(const void *para)
323 {
324     CHECK_NULL_PTR_RETURN_VOID(para);
325     AuthConnectResult *connResult = (AuthConnectResult *)(para);
326     RouteBuildClientAuthManager(connResult->fd);
327     ConnRequest *item = FindConnRequestByFd(connResult->fd);
328     if (item == NULL) {
329         AUTH_LOGE(AUTH_CONN, "ConnRequest not found, fd=%{public}d", connResult->fd);
330         return;
331     }
332     RemoveConnConnectTimeout(item->requestId);
333     if (connResult->ret == SOFTBUS_OK) {
334         NotifyClientConnected(item->requestId, GenConnId(AUTH_LINK_TYPE_WIFI, connResult->fd),
335             SOFTBUS_OK, &item->connInfo);
336     } else {
337         NotifyClientConnected(item->requestId, 0, connResult->ret, NULL);
338     }
339     DelConnRequest(item);
340 }
341 
AsyncCallDeviceIdReceived(void *para)342 static void AsyncCallDeviceIdReceived(void *para)
343 {
344     RepeatDeviceIdData *recvData = (RepeatDeviceIdData *)para;
345     if (recvData == NULL) {
346         return;
347     }
348     NotifyDataReceived(recvData->connId, &recvData->connInfo, recvData->fromServer, &recvData->head, recvData->data);
349     SoftBusFree(para);
350 }
351 
HandleDataReceivedProcess( uint64_t connId, const AuthConnInfo *connInfo, bool fromServer, const AuthDataHead *head, const uint8_t *data)352 static void HandleDataReceivedProcess(
353     uint64_t connId, const AuthConnInfo *connInfo, bool fromServer, const AuthDataHead *head, const uint8_t *data)
354 {
355     RepeatDeviceIdData *request = (RepeatDeviceIdData *)SoftBusCalloc(sizeof(RepeatDeviceIdData) + head->len);
356     if (request == NULL) {
357         AUTH_LOGE(AUTH_CONN, "malloc RepeatDeviceIdData fail");
358         return;
359     }
360     request->len = head->len;
361     if (data != NULL && head->len > 0 && memcpy_s(request->data, head->len, data, head->len) != EOK) {
362         AUTH_LOGE(AUTH_CONN, "copy data fail");
363         SoftBusFree(request);
364         return;
365     }
366     request->connId = connId;
367     request->connInfo = *connInfo;
368     request->fromServer = fromServer;
369     request->head = *head;
370     if (LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), AsyncCallDeviceIdReceived, request, 0) !=
371         SOFTBUS_OK) {
372         SoftBusFree(request);
373     }
374 }
375 
376 /* WiFi Connection */
OnWiFiConnected(ListenerModule module, int32_t fd, bool isClient)377 static void OnWiFiConnected(ListenerModule module, int32_t fd, bool isClient)
378 {
379     AUTH_LOGI(AUTH_CONN, "OnWiFiConnected: fd=%{public}d, side=%{public}s", fd,
380         isClient ? "client" : "server(ignored)");
381     if (!isClient) {
382         /* do nothing, wait auth message. */
383         return;
384     }
385     AuthConnectResult info = {
386         .fd = fd,
387         .ret = SOFTBUS_OK,
388     };
389     (void)PostAuthEvent(EVENT_CONNECT_RESULT, HandleConnConnectResult, &info, sizeof(AuthConnectResult), 0);
390 }
391 
OnWiFiDisconnected(int32_t fd)392 static void OnWiFiDisconnected(int32_t fd)
393 {
394     AUTH_LOGI(AUTH_CONN, "OnWiFiDisconnected: fd=%{public}d", fd);
395     AuthConnInfo connInfo;
396     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
397     connInfo.type = AUTH_LINK_TYPE_WIFI;
398     NotifyDisconnected(GenConnId(connInfo.type, fd), &connInfo);
399     AuthConnectResult info = {
400         .fd = fd,
401         .ret = SOFTBUS_AUTH_CONN_FAIL,
402     };
403     (void)PostAuthEvent(EVENT_CONNECT_RESULT, HandleConnConnectResult, &info, sizeof(AuthConnectResult), 0);
404     RouteClearAuthChannelId(fd);
405 }
406 
OnWiFiDataReceived(ListenerModule module, int32_t fd, const AuthDataHead *head, const uint8_t *data)407 static void OnWiFiDataReceived(ListenerModule module, int32_t fd, const AuthDataHead *head, const uint8_t *data)
408 {
409     CHECK_NULL_PTR_RETURN_VOID(head);
410     CHECK_NULL_PTR_RETURN_VOID(data);
411 
412     if (module != AUTH && module != AUTH_P2P && module != AUTH_RAW_P2P_SERVER && !IsEnhanceP2pModuleId(module)) {
413         return;
414     }
415     bool fromServer = false;
416     AuthConnInfo connInfo;
417     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
418     if (SocketGetConnInfo(fd, &connInfo, &fromServer) != SOFTBUS_OK) {
419         AUTH_LOGE(AUTH_CONN, "get connInfo fail, fd=%{public}d", fd);
420         return;
421     }
422     HandleDataReceivedProcess(GenConnId(connInfo.type, fd), &connInfo, fromServer, head, data);
423 }
424 
InitWiFiConn(void)425 static int32_t InitWiFiConn(void)
426 {
427     SocketCallback socketCb = {
428         .onConnected = OnWiFiConnected,
429         .onDisconnected = OnWiFiDisconnected,
430         .onDataReceived = OnWiFiDataReceived,
431     };
432     return SetSocketCallback(&socketCb);
433 }
434 
435 /* BR/BLE/P2P Connection */
OnCommConnected(uint32_t connectionId, const ConnectionInfo *info)436 static void OnCommConnected(uint32_t connectionId, const ConnectionInfo *info)
437 {
438     AUTH_LOGI(AUTH_CONN, "(ignored)OnCommConnected: connectionId=%{public}u", connectionId);
439 }
440 
OnCommDisconnected(uint32_t connectionId, const ConnectionInfo *info)441 static void OnCommDisconnected(uint32_t connectionId, const ConnectionInfo *info)
442 {
443     AUTH_LOGI(AUTH_CONN, "connectionId=%{public}u", connectionId);
444     CHECK_NULL_PTR_RETURN_VOID(info);
445     AuthConnInfo connInfo;
446     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
447     (void)ConvertToAuthConnInfo(info, &connInfo);
448     NotifyDisconnected(GenConnId(connInfo.type, connectionId), &connInfo);
449 }
450 
GetConnInfoByConnectionId(uint32_t connectionId, AuthConnInfo *connInfo)451 int32_t GetConnInfoByConnectionId(uint32_t connectionId, AuthConnInfo *connInfo)
452 {
453     ConnectionInfo info = { 0 };
454     int32_t ret = ConnGetConnectionInfo(connectionId, &info);
455     if (ret != SOFTBUS_OK) {
456         AUTH_LOGE(AUTH_CONN, "GetConnectionInfo err=%{public}d, connectionId=%{public}u", ret, connectionId);
457         return ret;
458     }
459     return ConvertToAuthConnInfo(&info, connInfo);
460 }
461 
OnCommDataReceived(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int32_t len)462 static void OnCommDataReceived(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int32_t len)
463 {
464     if (data == NULL || moduleId != MODULE_DEVICE_AUTH || len <= 0) {
465         AUTH_LOGE(AUTH_CONN, "invalid param");
466         return;
467     }
468     bool fromServer = ((seq % SEQ_INTERVAL) != 0);
469     AUTH_LOGI(AUTH_CONN,
470         "connectionId=%{public}u, module=%{public}d, seq=%{public}" PRId64 ", len=%{public}d, from=%{public}s",
471         connectionId, moduleId, seq, len, GetAuthSideStr(fromServer));
472     AuthConnInfo connInfo;
473     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
474     if (GetConnInfoByConnectionId(connectionId, &connInfo) != SOFTBUS_OK) {
475         return;
476     }
477     AuthDataHead head = { 0 };
478     const uint8_t *body = UnpackAuthData((const uint8_t *)data, (uint32_t)len, &head);
479     if (body == NULL) {
480         AUTH_LOGE(AUTH_CONN, "empty body");
481         return;
482     }
483     HandleDataReceivedProcess(GenConnId(connInfo.type, connectionId), &connInfo, fromServer, &head, body);
484 }
485 
HandleRepeatDeviceIdDataDelay(uint64_t connId, const AuthConnInfo *connInfo, bool fromServer, const AuthDataHead *head, const uint8_t *data)486 void HandleRepeatDeviceIdDataDelay(uint64_t connId, const AuthConnInfo *connInfo, bool fromServer,
487     const AuthDataHead *head, const uint8_t *data)
488 {
489     if (connInfo == NULL || head == NULL || data == NULL) {
490         AUTH_LOGE(AUTH_CONN, "param error");
491         return;
492     }
493     RepeatDeviceIdData *request = (RepeatDeviceIdData *)SoftBusCalloc(sizeof(RepeatDeviceIdData) + head->len);
494     if (request == NULL) {
495         AUTH_LOGE(AUTH_CONN, "malloc RepeatDeviceIdData fail");
496         return;
497     }
498     request->len = head->len;
499     if (data != NULL && head->len > 0 && memcpy_s(request->data, head->len, data, head->len) != EOK) {
500         AUTH_LOGE(AUTH_CONN, "copy data fail");
501         SoftBusFree(request);
502         return;
503     }
504     request->connId = connId;
505     request->connInfo = *connInfo;
506     request->fromServer = fromServer;
507     request->head = *head;
508     if (LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), AsyncCallDeviceIdReceived, request,
509         AUTH_REPEAT_DEVICE_ID_HANDLE_DELAY) != SOFTBUS_OK) {
510         SoftBusFree(request);
511     }
512 }
513 
InitCommConn(void)514 static int32_t InitCommConn(void)
515 {
516     ConnectCallback connCb = {
517         .OnConnected = OnCommConnected,
518         .OnDisconnected = OnCommDisconnected,
519         .OnDataReceived = OnCommDataReceived,
520     };
521     return ConnSetConnectCallback(MODULE_DEVICE_AUTH, &connCb);
522 }
523 
OnCommConnectSucc(uint32_t requestId, uint32_t connectionId, const ConnectionInfo *info)524 static void OnCommConnectSucc(uint32_t requestId, uint32_t connectionId, const ConnectionInfo *info)
525 {
526     AuthConnInfo connInfo;
527     AUTH_LOGI(AUTH_CONN, "requestId=%{public}u, connectionId=%{public}u", requestId, connectionId);
528     CHECK_NULL_PTR_RETURN_VOID(info);
529     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
530     (void)ConvertToAuthConnInfo(info, &connInfo);
531     RemoveConnConnectTimeout(requestId);
532     uint64_t connId = GenConnId(connInfo.type, connectionId);
533     NotifyClientConnected(requestId, connId, SOFTBUS_OK, &connInfo);
534 }
535 
OnCommConnectFail(uint32_t requestId, int32_t reason)536 static void OnCommConnectFail(uint32_t requestId, int32_t reason)
537 {
538     AUTH_LOGI(AUTH_CONN, "requestId=%{public}u, reason=%{public}d", requestId, reason);
539     RemoveConnConnectTimeout(requestId);
540     NotifyClientConnected(requestId, 0, reason, NULL);
541 }
542 
ConnectCommDevice(const AuthConnInfo *info, uint32_t requestId, ConnSideType sideType)543 static int32_t ConnectCommDevice(const AuthConnInfo *info, uint32_t requestId, ConnSideType sideType)
544 {
545     ConnectOption option;
546     (void)memset_s(&option, sizeof(ConnectOption), 0, sizeof(ConnectOption));
547     int32_t ret = ConvertToConnectOption(info, &option);
548     if (ret != SOFTBUS_OK) {
549         AUTH_LOGE(AUTH_CONN, "ConvertToConnectOption fail=%{public}d", ret);
550         return ret;
551     }
552     if (option.type == CONNECT_BR) {
553         option.brOption.sideType = sideType;
554     }
555     ConnectResult result = {
556         .OnConnectSuccessed = OnCommConnectSucc,
557         .OnConnectFailed = OnCommConnectFail,
558     };
559     ret = ConnConnectDevice(&option, requestId, &result);
560     if (ret != SOFTBUS_OK) {
561         AUTH_LOGE(AUTH_CONN, "ConnConnectDevice fail=%{public}d", ret);
562         return ret;
563     }
564     return SOFTBUS_OK;
565 }
566 
PostCommData(uint32_t connectionId, bool toServer, const AuthDataHead *head, const uint8_t *data)567 static int32_t PostCommData(uint32_t connectionId, bool toServer, const AuthDataHead *head, const uint8_t *data)
568 {
569     uint32_t size = ConnGetHeadSize() + GetAuthDataSize(head->len);
570     uint8_t *buf = (uint8_t *)SoftBusMalloc(size);
571     if (buf == NULL) {
572         AUTH_LOGE(AUTH_CONN, "malloc fail");
573         return SOFTBUS_MALLOC_ERR;
574     }
575     int32_t ret = PackAuthData(head, data, buf + ConnGetHeadSize(), size - ConnGetHeadSize());
576     if (ret != SOFTBUS_OK) {
577         AUTH_LOGE(AUTH_CONN, "pack data fail=%{public}d", ret);
578         SoftBusFree(buf);
579         return ret;
580     }
581     ConnPostData connData = {
582         .module = MODULE_DEVICE_AUTH,
583         .seq = GenSeq(!toServer),
584         .flag = CONN_HIGH,
585         .pid = 0,
586         .len = size,
587         .buf = (char *)buf,
588     };
589     AUTH_LOGI(AUTH_CONN,
590         "dataSeq=%{public}" PRId64 ", dataLen=%{public}u, "
591         "connId=%{public}u, connSeq=%{public}" PRId64 ", connLen=%{public}u}",
592         head->seq, head->len, connectionId, connData.seq, connData.len);
593     return ConnPostBytes(connectionId, &connData);
594 }
595 
AuthConnInit(const AuthConnListener *listener)596 int32_t AuthConnInit(const AuthConnListener *listener)
597 {
598     CHECK_NULL_PTR_RETURN_VALUE(listener, SOFTBUS_INVALID_PARAM);
599     g_listener = *listener;
600     ListInit(&g_connRequestList);
601     if (InitCommConn() != SOFTBUS_OK) {
602         (void)memset_s(&g_listener, sizeof(g_listener), 0, sizeof(AuthConnListener));
603         AUTH_LOGE(AUTH_CONN, "init br/ble/p2p conn fail");
604         return SOFTBUS_AUTH_CONN_INIT_FAIL;
605     }
606     if (InitWiFiConn() != SOFTBUS_OK) {
607         (void)memset_s(&g_listener, sizeof(g_listener), 0, sizeof(AuthConnListener));
608         AUTH_LOGE(AUTH_CONN, "init wifi conn fail");
609         return SOFTBUS_AUTH_CONN_INIT_FAIL;
610     }
611     return SOFTBUS_OK;
612 }
613 
AuthConnDeinit(void)614 void AuthConnDeinit(void)
615 {
616     UnsetSocketCallback();
617     ConnUnSetConnectCallback(MODULE_DEVICE_AUTH);
618     ClearConnRequest();
619     (void)memset_s(&g_listener, sizeof(g_listener), 0, sizeof(AuthConnListener));
620 }
621 
ConnectAuthDevice(uint32_t requestId, const AuthConnInfo *connInfo, ConnSideType sideType)622 int32_t ConnectAuthDevice(uint32_t requestId, const AuthConnInfo *connInfo, ConnSideType sideType)
623 {
624     CHECK_NULL_PTR_RETURN_VALUE(connInfo, SOFTBUS_INVALID_PARAM);
625     AUTH_LOGI(AUTH_CONN, "requestId=%{public}u, connType=%{public}d, sideType=%{public}d", requestId,
626         connInfo->type, sideType);
627     PostConnConnectTimeout(requestId, connInfo->type);
628     int32_t ret = 0;
629     switch (connInfo->type) {
630         case AUTH_LINK_TYPE_WIFI: {
631             ConnCmdInfo info = {
632                 .requestId = requestId,
633                 .connInfo = *connInfo,
634                 .retryTimes = 0,
635             };
636             ret = PostAuthEvent(EVENT_CONNECT_CMD, HandleConnConnectCmd, &info, sizeof(ConnCmdInfo), 0);
637             break;
638         }
639         case AUTH_LINK_TYPE_BLE:
640             __attribute__((fallthrough));
641         case AUTH_LINK_TYPE_BR:
642             if (SoftBusGetBtState() != BLE_ENABLE) {
643                 ret = SOFTBUS_AUTH_CONN_FAIL;
644                 break;
645             }
646             __attribute__((fallthrough));
647         case AUTH_LINK_TYPE_P2P:
648         case AUTH_LINK_TYPE_ENHANCED_P2P:
649             ret = ConnectCommDevice(connInfo, requestId, sideType);
650             break;
651         default:
652             ret = SOFTBUS_OK;
653             break;
654     }
655     if (ret != SOFTBUS_OK) {
656         RemoveConnConnectTimeout(requestId);
657         AUTH_LOGE(AUTH_CONN, "ConnectDevice fail, requestId=%{public}u", requestId);
658     }
659     return ret;
660 }
661 
UpdateAuthDevicePriority(uint64_t connId)662 void UpdateAuthDevicePriority(uint64_t connId)
663 {
664     if (GetConnType(connId) != AUTH_LINK_TYPE_BLE) {
665         return;
666     }
667     UpdateOption option = {
668         .type = CONNECT_BLE,
669         .bleOption = {
670             .priority = CONN_BLE_PRIORITY_BALANCED,
671         }
672     };
673     int32_t ret = ConnUpdateConnection(GetConnId(connId), &option);
674     AUTH_LOGI(AUTH_CONN, "update connecton priority to balanced, connType=%{public}d, id=%{public}u, ret=%{public}d",
675         GetConnType(connId), GetConnId(connId), ret);
676 }
677 
DisconnectAuthDevice(uint64_t *connId)678 void DisconnectAuthDevice(uint64_t *connId)
679 {
680     if (connId == NULL) {
681         AUTH_LOGW(AUTH_CONN, "connId nulptr");
682         return;
683     }
684     AUTH_LOGI(AUTH_CONN, "connType=%{public}d, connectionId=%{public}u", GetConnType(*connId), GetConnId(*connId));
685     switch (GetConnType(*connId)) {
686         case AUTH_LINK_TYPE_RAW_ENHANCED_P2P:
687             SocketDisconnectDevice(AUTH_RAW_P2P_SERVER, GetFd(*connId));
688             UpdateFd(connId, AUTH_INVALID_FD);
689             break;
690         case AUTH_LINK_TYPE_WIFI:
691             SocketDisconnectDevice(AUTH, GetFd(*connId));
692             UpdateFd(connId, AUTH_INVALID_FD);
693             break;
694         case AUTH_LINK_TYPE_BLE:
695             __attribute__((fallthrough));
696         case AUTH_LINK_TYPE_BR:
697             ConnDisconnectDevice(GetConnId(*connId));
698             __attribute__((fallthrough));
699         case AUTH_LINK_TYPE_P2P:
700         case AUTH_LINK_TYPE_ENHANCED_P2P:
701             break;
702         default:
703             AUTH_LOGI(AUTH_CONN, "unknown connType");
704             break;
705     }
706 }
707 
PostAuthData(uint64_t connId, bool toServer, const AuthDataHead *head, const uint8_t *data)708 int32_t PostAuthData(uint64_t connId, bool toServer, const AuthDataHead *head, const uint8_t *data)
709 {
710     CHECK_NULL_PTR_RETURN_VALUE(head, SOFTBUS_INVALID_PARAM);
711     CHECK_NULL_PTR_RETURN_VALUE(data, SOFTBUS_INVALID_PARAM);
712     AUTH_LOGI(AUTH_CONN,
713         "auth post dataType=0x%{public}x, dataModule=%{public}d, dataSeq=%{public}" PRId64 ", "
714         "dataFlag=%{public}d, dataLen=%{public}u, " CONN_INFO ", toServer=%{public}s",
715         head->dataType, head->module, head->seq, head->flag, head->len, CONN_DATA(connId),
716         GetAuthSideStr(toServer));
717     switch (GetConnType(connId)) {
718         case AUTH_LINK_TYPE_WIFI:
719             return SocketPostBytes(GetFd(connId), head, data);
720         case AUTH_LINK_TYPE_BLE:
721         case AUTH_LINK_TYPE_BR:
722         case AUTH_LINK_TYPE_P2P:
723         case AUTH_LINK_TYPE_ENHANCED_P2P:
724             return PostCommData(GetConnId(connId), toServer, head, data);
725         default:
726             AUTH_LOGI(AUTH_CONN, "unknown connType");
727             break;
728     }
729     return SOFTBUS_AUTH_SEND_FAIL;
730 }
731 
GetConnSideType(uint64_t connId)732 ConnSideType GetConnSideType(uint64_t connId)
733 {
734     if (GetConnType(connId) == AUTH_LINK_TYPE_WIFI) {
735         AUTH_LOGE(AUTH_CONN, "WiFi not supported, " CONN_INFO, CONN_DATA(connId));
736         return CONN_SIDE_ANY;
737     }
738     ConnectionInfo info;
739     (void)memset_s(&info, sizeof(ConnectionInfo), 0, sizeof(ConnectionInfo));
740     if (ConnGetConnectionInfo(GetConnId(connId), &info)) {
741         AUTH_LOGE(AUTH_CONN, "ConnGetConnectionInfo fail, " CONN_INFO, CONN_DATA(connId));
742         return CONN_SIDE_ANY;
743     }
744     if (!info.isAvailable) {
745         AUTH_LOGE(AUTH_CONN, "connection not available, " CONN_INFO, CONN_DATA(connId));
746     }
747     return info.isServer ? CONN_SIDE_SERVER : CONN_SIDE_CLIENT;
748 }
749 
CheckActiveAuthConnection(const AuthConnInfo *connInfo)750 bool CheckActiveAuthConnection(const AuthConnInfo *connInfo)
751 {
752     ConnectOption connOpt;
753     CHECK_NULL_PTR_RETURN_VALUE(connInfo, false);
754     (void)memset_s(&connOpt, sizeof(ConnectOption), 0, sizeof(ConnectOption));
755     if (ConvertToConnectOption(connInfo, &connOpt) != SOFTBUS_OK) {
756         AUTH_LOGE(AUTH_CONN, "convert to connect option fail, connType=%{public}d.", connInfo->type);
757         return false;
758     }
759     if (connInfo->type == AUTH_LINK_TYPE_BLE) {
760         connOpt.bleOption.protocol = BLE_PROTOCOL_ANY;
761     }
762     return CheckActiveConnection(&connOpt, true);
763 }
764 
AuthStartListening(AuthLinkType type, const char *ip, int32_t port)765 int32_t AuthStartListening(AuthLinkType type, const char *ip, int32_t port)
766 {
767     if (ip == NULL) {
768         AUTH_LOGW(AUTH_CONN, "invalid param");
769         return SOFTBUS_INVALID_PARAM;
770     }
771     AUTH_LOGI(AUTH_CONN, "start auth listening, linkType=%{public}d, port=%{public}d", type, port);
772     LocalListenerInfo info = {
773         .type = CONNECT_TCP,
774         .socketOption = {
775             .addr = "",
776             .port = port,
777             .moduleId = AUTH,
778             .protocol = LNN_PROTOCOL_IP,
779         },
780     };
781     if (strcpy_s(info.socketOption.addr, sizeof(info.socketOption.addr), ip) != EOK) {
782         AUTH_LOGE(AUTH_CONN, "strcpy_s ip fail");
783         return SOFTBUS_STRCPY_ERR;
784     }
785     switch (type) {
786         case AUTH_LINK_TYPE_WIFI: {
787             info.socketOption.moduleId = AUTH;
788             return StartSocketListening(AUTH, &info);
789         }
790         case AUTH_LINK_TYPE_RAW_ENHANCED_P2P: {
791             info.socketOption.moduleId = AUTH_RAW_P2P_SERVER;
792             info.socketOption.port = 0;
793             return StartSocketListening(AUTH_RAW_P2P_SERVER, &info);
794         }
795         default:
796             AUTH_LOGE(AUTH_CONN, "unsupport linkType=%{public}d", type);
797             break;
798     }
799     return SOFTBUS_INVALID_PARAM;
800 }
801 
AuthStopListening(AuthLinkType type)802 void AuthStopListening(AuthLinkType type)
803 {
804     AUTH_LOGI(AUTH_CONN, "stop auth listening, linkType=%{public}d", type);
805     switch (type) {
806         case AUTH_LINK_TYPE_WIFI:
807             StopSocketListening(AUTH);
808             break;
809         case AUTH_LINK_TYPE_RAW_ENHANCED_P2P:
810             StopSocketListening(AUTH_RAW_P2P_SERVER);
811             break;
812         default:
813             AUTH_LOGE(AUTH_CONN, "unsupport linkType=%{public}d", type);
814             break;
815     }
816 }
817 
AuthStartListeningForWifiDirect(AuthLinkType type, const char *ip, int32_t port, ListenerModule *moduleId)818 int32_t AuthStartListeningForWifiDirect(AuthLinkType type, const char *ip, int32_t port, ListenerModule *moduleId)
819 {
820     AUTH_CHECK_AND_RETURN_RET_LOGE(ip != NULL, SOFTBUS_INVALID_PARAM, AUTH_CONN, "ip is null");
821     AUTH_CHECK_AND_RETURN_RET_LOGE(moduleId != NULL, SOFTBUS_INVALID_PARAM, AUTH_CONN, "moduleId is null");
822 
823     LocalListenerInfo local;
824     local.type = CONNECT_TCP;
825     local.socketOption.port = port;
826     local.socketOption.protocol = LNN_PROTOCOL_IP;
827     int32_t ret = strcpy_s(local.socketOption.addr, sizeof(local.socketOption.addr), ip);
828     AUTH_CHECK_AND_RETURN_RET_LOGE(ret == EOK, SOFTBUS_STRCPY_ERR, AUTH_CONN, "copy ip failed");
829 
830     if (type == AUTH_LINK_TYPE_P2P) {
831         local.socketOption.moduleId = AUTH_P2P;
832     } else if (type == AUTH_LINK_TYPE_ENHANCED_P2P) {
833         local.socketOption.moduleId = (ListenerModule)(GetWifiDirectManager()->allocateListenerModuleId());
834         AUTH_CHECK_AND_RETURN_RET_LOGE(local.socketOption.moduleId < UNUSE_BUTT, SOFTBUS_ERR, AUTH_CONN,
835                                        "alloc listener module id failed");
836     } else {
837         AUTH_LOGE(AUTH_CONN, "type invalid. type=%{public}d", type);
838         return SOFTBUS_INVALID_PARAM;
839     }
840 
841     int32_t realPort = ConnStartLocalListening(&local);
842     if (realPort <= 0) {
843         if (type == AUTH_LINK_TYPE_ENHANCED_P2P) {
844             GetWifiDirectManager()->freeListenerModuleId(local.socketOption.moduleId);
845         }
846         AUTH_LOGE(AUTH_CONN, "start local listening failed");
847         return realPort;
848     }
849     AUTH_LOGI(AUTH_CONN, "moduleId=%{public}u, port=%{public}d", local.socketOption.moduleId, realPort);
850     *moduleId = local.socketOption.moduleId;
851     return realPort;
852 }
853 
AuthStopListeningForWifiDirect(AuthLinkType type, ListenerModule moduleId)854 void AuthStopListeningForWifiDirect(AuthLinkType type, ListenerModule moduleId)
855 {
856     AUTH_CHECK_AND_RETURN_LOGE(type == AUTH_LINK_TYPE_P2P || type == AUTH_LINK_TYPE_ENHANCED_P2P, AUTH_CONN,
857                                "type invalid. type=%{public}d", type);
858     LocalListenerInfo local = {
859         .type = CONNECT_TCP,
860         .socketOption = {
861             .moduleId = moduleId,
862             .protocol = LNN_PROTOCOL_IP,
863         },
864     };
865 
866     if (ConnStopLocalListening(&local) != SOFTBUS_OK) {
867         AUTH_LOGE(AUTH_CONN, "ConnStopLocalListening fail");
868     }
869     GetWifiDirectManager()->freeListenerModuleId(moduleId);
870 }