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 (size < GetAuthDataSize(head->len)) {
214         return SOFTBUS_NO_ENOUGH_DATA;
215     }
216     uint32_t offset = 0;
217     *(uint32_t *)buf = SoftBusHtoLl(head->dataType);
218     offset += sizeof(uint32_t);
219     *(uint32_t *)(buf + offset) = SoftBusHtoLl((uint32_t)head->module);
220     offset += sizeof(uint32_t);
221     *(uint64_t *)(buf + offset) = SoftBusHtoLll((uint64_t)head->seq);
222     offset += sizeof(uint64_t);
223     *(uint32_t *)(buf + offset) = SoftBusHtoLl((uint32_t)head->flag);
224     offset += sizeof(uint32_t);
225     *(uint32_t *)(buf + offset) = SoftBusHtoLl(head->len);
226     offset += sizeof(uint32_t);
227 
228     if (memcpy_s(buf + offset, size - offset, data, head->len) != EOK) {
229         AUTH_LOGE(AUTH_CONN, "pack AuthData fail");
230         return SOFTBUS_MEM_ERR;
231     }
232     return SOFTBUS_OK;
233 }
234 
UnpackAuthData(const uint8_t * data,uint32_t len,AuthDataHead * head)235 const uint8_t *UnpackAuthData(const uint8_t *data, uint32_t len, AuthDataHead *head)
236 {
237     if (len < GetAuthDataSize(0)) {
238         AUTH_LOGE(AUTH_CONN, "head not enough");
239         return NULL;
240     }
241     uint32_t offset = 0;
242     head->dataType = SoftBusLtoHl(*(uint32_t *)data);
243     offset += sizeof(uint32_t);
244     head->module = (int32_t)SoftBusLtoHl(*(uint32_t *)(data + offset));
245     offset += sizeof(uint32_t);
246     head->seq = (int64_t)SoftBusLtoHll(*(uint64_t *)(data + offset));
247     offset += sizeof(uint64_t);
248     head->flag = (int32_t)SoftBusLtoHl(*(uint32_t *)(data + offset));
249     offset += sizeof(uint32_t);
250     head->len = SoftBusLtoHl(*(uint32_t *)(data + offset));
251     offset += sizeof(uint32_t);
252     uint32_t dataLen = GetAuthDataSize(head->len);
253     if (len < dataLen || dataLen < GetAuthDataSize(0)) {
254         AUTH_LOGE(AUTH_CONN, "data not enough");
255         return NULL;
256     }
257     return (data + offset);
258 }
259 
260 /* EVENT_CONNECT_TIMEOUT */
HandleConnConnectTimeout(const void * para)261 static void HandleConnConnectTimeout(const void *para)
262 {
263     CHECK_NULL_PTR_RETURN_VOID(para);
264     uint32_t requestId = *(uint32_t *)(para);
265     AUTH_LOGE(AUTH_CONN, "connect timeout, requestId=%{public}u", requestId);
266     ConnRequest *item = FindConnRequestByRequestId(requestId);
267     if (item != NULL) {
268         ListenerModule module = item->connInfo.type == AUTH_LINK_TYPE_RAW_ENHANCED_P2P ? AUTH_RAW_P2P_SERVER : AUTH;
269         SocketDisconnectDevice(module, item->fd);
270         DelConnRequest(item);
271     }
272     NotifyClientConnected(requestId, 0, SOFTBUS_AUTH_CONN_TIMEOUT, NULL);
273 }
274 
PostConnConnectTimeout(uint32_t requestId,AuthLinkType type)275 static void PostConnConnectTimeout(uint32_t requestId, AuthLinkType type)
276 {
277     if (type == AUTH_LINK_TYPE_ENHANCED_P2P) {
278         PostAuthEvent(EVENT_CONNECT_TIMEOUT, HandleConnConnectTimeout, &requestId, sizeof(requestId),
279             AUTH_ENHANCE_P2P_CONNECT_TIMEOUT_MS);
280     } else {
281         PostAuthEvent(EVENT_CONNECT_TIMEOUT, HandleConnConnectTimeout, &requestId, sizeof(requestId),
282             AUTH_CONN_CONNECT_TIMEOUT_MS);
283     }
284 }
285 
RemoveFunc(const void * obj,void * param)286 static int32_t RemoveFunc(const void *obj, void *param)
287 {
288     CHECK_NULL_PTR_RETURN_VALUE(obj, SOFTBUS_ERR);
289     CHECK_NULL_PTR_RETURN_VALUE(param, SOFTBUS_ERR);
290     return ((*(uint32_t *)(obj) == *(uint32_t *)(param)) ? SOFTBUS_OK : SOFTBUS_ERR);
291 }
292 
RemoveConnConnectTimeout(uint32_t requestId)293 static void RemoveConnConnectTimeout(uint32_t requestId)
294 {
295     RemoveAuthEvent(EVENT_CONNECT_TIMEOUT, RemoveFunc, (void *)(&requestId));
296 }
297 
298 /* EVENT_CONNECT_CMD */
HandleConnConnectCmd(const void * para)299 static void HandleConnConnectCmd(const void *para)
300 {
301     CHECK_NULL_PTR_RETURN_VOID(para);
302     ConnCmdInfo *info = (ConnCmdInfo *)para;
303     if (info->connInfo.type != AUTH_LINK_TYPE_WIFI) {
304         AUTH_LOGE(AUTH_CONN, "invalid connType=%{public}d", info->connInfo.type);
305         return;
306     }
307     int32_t fd = SocketConnectDevice(info->connInfo.info.ipInfo.ip, info->connInfo.info.ipInfo.port, false);
308     if (fd < 0) {
309         AUTH_LOGE(AUTH_CONN, "SocketConnectDevice fail");
310         RemoveConnConnectTimeout(info->requestId);
311         NotifyClientConnected(info->requestId, 0, SOFTBUS_AUTH_CONN_FAIL, NULL);
312         return;
313     }
314     (void)AddConnRequest(&info->connInfo, info->requestId, fd);
315 }
316 
317 /* EVENT_CONNECT_RESULT */
HandleConnConnectResult(const void * para)318 static void HandleConnConnectResult(const void *para)
319 {
320     CHECK_NULL_PTR_RETURN_VOID(para);
321     AuthConnectResult *connResult = (AuthConnectResult *)(para);
322     RouteBuildClientAuthManager(connResult->fd);
323     ConnRequest *item = FindConnRequestByFd(connResult->fd);
324     if (item == NULL) {
325         AUTH_LOGE(AUTH_CONN, "ConnRequest not found, fd=%{public}d", connResult->fd);
326         return;
327     }
328     RemoveConnConnectTimeout(item->requestId);
329     if (connResult->ret == SOFTBUS_OK) {
330         NotifyClientConnected(item->requestId, GenConnId(AUTH_LINK_TYPE_WIFI, connResult->fd),
331             SOFTBUS_OK, &item->connInfo);
332     } else {
333         NotifyClientConnected(item->requestId, 0, connResult->ret, NULL);
334     }
335     DelConnRequest(item);
336 }
337 
AsyncCallDeviceIdReceived(void * para)338 static void AsyncCallDeviceIdReceived(void *para)
339 {
340     RepeatDeviceIdData *recvData = (RepeatDeviceIdData *)para;
341     if (recvData == NULL) {
342         return;
343     }
344     NotifyDataReceived(recvData->connId, &recvData->connInfo, recvData->fromServer, &recvData->head, recvData->data);
345     SoftBusFree(para);
346 }
347 
HandleDataReceivedProcess(uint64_t connId,const AuthConnInfo * connInfo,bool fromServer,const AuthDataHead * head,const uint8_t * data)348 static void HandleDataReceivedProcess(
349     uint64_t connId, const AuthConnInfo *connInfo, bool fromServer, const AuthDataHead *head, const uint8_t *data)
350 {
351     RepeatDeviceIdData *request = (RepeatDeviceIdData *)SoftBusCalloc(sizeof(RepeatDeviceIdData) + head->len);
352     if (request == NULL) {
353         AUTH_LOGE(AUTH_CONN, "malloc RepeatDeviceIdData fail");
354         return;
355     }
356     request->len = head->len;
357     if (data != NULL && head->len > 0 && memcpy_s(request->data, head->len, data, head->len) != EOK) {
358         AUTH_LOGE(AUTH_CONN, "copy data fail");
359         SoftBusFree(request);
360         return;
361     }
362     request->connId = connId;
363     request->connInfo = *connInfo;
364     request->fromServer = fromServer;
365     request->head = *head;
366     if (LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), AsyncCallDeviceIdReceived, request, 0) !=
367         SOFTBUS_OK) {
368         SoftBusFree(request);
369     }
370 }
371 
372 /* WiFi Connection */
OnWiFiConnected(ListenerModule module,int32_t fd,bool isClient)373 static void OnWiFiConnected(ListenerModule module, int32_t fd, bool isClient)
374 {
375     AUTH_LOGI(AUTH_CONN, "OnWiFiConnected: fd=%{public}d, side=%{public}s", fd,
376         isClient ? "client" : "server(ignored)");
377     if (!isClient) {
378         /* do nothing, wait auth message. */
379         return;
380     }
381     AuthConnectResult info = {
382         .fd = fd,
383         .ret = SOFTBUS_OK,
384     };
385     (void)PostAuthEvent(EVENT_CONNECT_RESULT, HandleConnConnectResult, &info, sizeof(AuthConnectResult), 0);
386 }
387 
OnWiFiDisconnected(int32_t fd)388 static void OnWiFiDisconnected(int32_t fd)
389 {
390     AUTH_LOGI(AUTH_CONN, "OnWiFiDisconnected: fd=%{public}d", fd);
391     AuthConnInfo connInfo;
392     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
393     connInfo.type = AUTH_LINK_TYPE_WIFI;
394     NotifyDisconnected(GenConnId(connInfo.type, fd), &connInfo);
395     AuthConnectResult info = {
396         .fd = fd,
397         .ret = SOFTBUS_AUTH_CONN_FAIL,
398     };
399     (void)PostAuthEvent(EVENT_CONNECT_RESULT, HandleConnConnectResult, &info, sizeof(AuthConnectResult), 0);
400     RouteClearAuthChannelId(fd);
401 }
402 
OnWiFiDataReceived(ListenerModule module,int32_t fd,const AuthDataHead * head,const uint8_t * data)403 static void OnWiFiDataReceived(ListenerModule module, int32_t fd, const AuthDataHead *head, const uint8_t *data)
404 {
405     CHECK_NULL_PTR_RETURN_VOID(head);
406     CHECK_NULL_PTR_RETURN_VOID(data);
407 
408     if (module != AUTH && module != AUTH_P2P && module != AUTH_RAW_P2P_SERVER && !IsEnhanceP2pModuleId(module)) {
409         return;
410     }
411     bool fromServer = false;
412     AuthConnInfo connInfo;
413     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
414     if (SocketGetConnInfo(fd, &connInfo, &fromServer) != SOFTBUS_OK) {
415         AUTH_LOGE(AUTH_CONN, "get connInfo fail, fd=%{public}d", fd);
416         return;
417     }
418     HandleDataReceivedProcess(GenConnId(connInfo.type, fd), &connInfo, fromServer, head, data);
419 }
420 
InitWiFiConn(void)421 static int32_t InitWiFiConn(void)
422 {
423     SocketCallback socketCb = {
424         .onConnected = OnWiFiConnected,
425         .onDisconnected = OnWiFiDisconnected,
426         .onDataReceived = OnWiFiDataReceived,
427     };
428     return SetSocketCallback(&socketCb);
429 }
430 
431 /* BR/BLE/P2P Connection */
OnCommConnected(uint32_t connectionId,const ConnectionInfo * info)432 static void OnCommConnected(uint32_t connectionId, const ConnectionInfo *info)
433 {
434     AUTH_LOGI(AUTH_CONN, "(ignored)OnCommConnected: connectionId=%{public}u", connectionId);
435 }
436 
OnCommDisconnected(uint32_t connectionId,const ConnectionInfo * info)437 static void OnCommDisconnected(uint32_t connectionId, const ConnectionInfo *info)
438 {
439     AUTH_LOGI(AUTH_CONN, "connectionId=%{public}u", connectionId);
440     CHECK_NULL_PTR_RETURN_VOID(info);
441     AuthConnInfo connInfo;
442     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
443     (void)ConvertToAuthConnInfo(info, &connInfo);
444     NotifyDisconnected(GenConnId(connInfo.type, connectionId), &connInfo);
445 }
446 
GetConnInfoByConnectionId(uint32_t connectionId,AuthConnInfo * connInfo)447 int32_t GetConnInfoByConnectionId(uint32_t connectionId, AuthConnInfo *connInfo)
448 {
449     ConnectionInfo info = { 0 };
450     int32_t ret = ConnGetConnectionInfo(connectionId, &info);
451     if (ret != SOFTBUS_OK) {
452         AUTH_LOGE(AUTH_CONN, "GetConnectionInfo err=%{public}d, connectionId=%{public}u", ret, connectionId);
453         return ret;
454     }
455     return ConvertToAuthConnInfo(&info, connInfo);
456 }
457 
OnCommDataReceived(uint32_t connectionId,ConnModule moduleId,int64_t seq,char * data,int32_t len)458 static void OnCommDataReceived(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int32_t len)
459 {
460     if (data == NULL || moduleId != MODULE_DEVICE_AUTH || len <= 0) {
461         AUTH_LOGE(AUTH_CONN, "invalid param");
462         return;
463     }
464     bool fromServer = ((seq % SEQ_INTERVAL) != 0);
465     AUTH_LOGI(AUTH_CONN,
466         "connectionId=%{public}u, module=%{public}d, seq=%{public}" PRId64 ", len=%{public}d, from=%{public}s",
467         connectionId, moduleId, seq, len, GetAuthSideStr(fromServer));
468     AuthConnInfo connInfo;
469     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
470     if (GetConnInfoByConnectionId(connectionId, &connInfo) != SOFTBUS_OK) {
471         return;
472     }
473     AuthDataHead head = { 0 };
474     const uint8_t *body = UnpackAuthData((const uint8_t *)data, (uint32_t)len, &head);
475     if (body == NULL) {
476         AUTH_LOGE(AUTH_CONN, "empty body");
477         return;
478     }
479     HandleDataReceivedProcess(GenConnId(connInfo.type, connectionId), &connInfo, fromServer, &head, body);
480 }
481 
HandleRepeatDeviceIdDataDelay(uint64_t connId,const AuthConnInfo * connInfo,bool fromServer,const AuthDataHead * head,const uint8_t * data)482 void HandleRepeatDeviceIdDataDelay(uint64_t connId, const AuthConnInfo *connInfo, bool fromServer,
483     const AuthDataHead *head, const uint8_t *data)
484 {
485     RepeatDeviceIdData *request = (RepeatDeviceIdData *)SoftBusCalloc(sizeof(RepeatDeviceIdData) + head->len);
486     if (request == NULL) {
487         AUTH_LOGE(AUTH_CONN, "malloc RepeatDeviceIdData fail");
488         return;
489     }
490     request->len = head->len;
491     if (data != NULL && head->len > 0 && memcpy_s(request->data, head->len, data, head->len) != EOK) {
492         AUTH_LOGE(AUTH_CONN, "copy data fail");
493         SoftBusFree(request);
494         return;
495     }
496     request->connId = connId;
497     request->connInfo = *connInfo;
498     request->fromServer = fromServer;
499     request->head = *head;
500     if (LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), AsyncCallDeviceIdReceived, request,
501         AUTH_REPEAT_DEVICE_ID_HANDLE_DELAY) != SOFTBUS_OK) {
502         SoftBusFree(request);
503     }
504 }
505 
InitCommConn(void)506 static int32_t InitCommConn(void)
507 {
508     ConnectCallback connCb = {
509         .OnConnected = OnCommConnected,
510         .OnDisconnected = OnCommDisconnected,
511         .OnDataReceived = OnCommDataReceived,
512     };
513     return ConnSetConnectCallback(MODULE_DEVICE_AUTH, &connCb);
514 }
515 
OnCommConnectSucc(uint32_t requestId,uint32_t connectionId,const ConnectionInfo * info)516 static void OnCommConnectSucc(uint32_t requestId, uint32_t connectionId, const ConnectionInfo *info)
517 {
518     AuthConnInfo connInfo;
519     AUTH_LOGI(AUTH_CONN, "requestId=%{public}u, connectionId=%{public}u", requestId, connectionId);
520     CHECK_NULL_PTR_RETURN_VOID(info);
521     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
522     (void)ConvertToAuthConnInfo(info, &connInfo);
523     RemoveConnConnectTimeout(requestId);
524     uint64_t connId = GenConnId(connInfo.type, connectionId);
525     NotifyClientConnected(requestId, connId, SOFTBUS_OK, &connInfo);
526 }
527 
OnCommConnectFail(uint32_t requestId,int32_t reason)528 static void OnCommConnectFail(uint32_t requestId, int32_t reason)
529 {
530     AUTH_LOGI(AUTH_CONN, "requestId=%{public}u, reason=%{public}d", requestId, reason);
531     RemoveConnConnectTimeout(requestId);
532     NotifyClientConnected(requestId, 0, reason, NULL);
533 }
534 
ConnectCommDevice(const AuthConnInfo * info,uint32_t requestId,ConnSideType sideType)535 static int32_t ConnectCommDevice(const AuthConnInfo *info, uint32_t requestId, ConnSideType sideType)
536 {
537     ConnectOption option;
538     (void)memset_s(&option, sizeof(ConnectOption), 0, sizeof(ConnectOption));
539     int32_t ret = ConvertToConnectOption(info, &option);
540     if (ret != SOFTBUS_OK) {
541         AUTH_LOGE(AUTH_CONN, "ConvertToConnectOption fail=%{public}d", ret);
542         return ret;
543     }
544     if (option.type == CONNECT_BR) {
545         option.brOption.sideType = sideType;
546     }
547     ConnectResult result = {
548         .OnConnectSuccessed = OnCommConnectSucc,
549         .OnConnectFailed = OnCommConnectFail,
550     };
551     ret = ConnConnectDevice(&option, requestId, &result);
552     if (ret != SOFTBUS_OK) {
553         AUTH_LOGE(AUTH_CONN, "ConnConnectDevice fail. ret=%{public}d", ret);
554         return ret;
555     }
556     return SOFTBUS_OK;
557 }
558 
PostCommData(uint32_t connectionId,bool toServer,const AuthDataHead * head,const uint8_t * data)559 static int32_t PostCommData(uint32_t connectionId, bool toServer, const AuthDataHead *head, const uint8_t *data)
560 {
561     uint32_t size = ConnGetHeadSize() + GetAuthDataSize(head->len);
562     uint8_t *buf = (uint8_t *)SoftBusMalloc(size);
563     if (buf == NULL) {
564         AUTH_LOGE(AUTH_CONN, "malloc fail");
565         return SOFTBUS_MALLOC_ERR;
566     }
567     int32_t ret = PackAuthData(head, data, buf + ConnGetHeadSize(), size - ConnGetHeadSize());
568     if (ret != SOFTBUS_OK) {
569         AUTH_LOGE(AUTH_CONN, "pack data fail=%{public}d", ret);
570         SoftBusFree(buf);
571         return ret;
572     }
573     ConnPostData connData = {
574         .module = MODULE_DEVICE_AUTH,
575         .seq = GenSeq(!toServer),
576         .flag = CONN_HIGH,
577         .pid = 0,
578         .len = size,
579         .buf = (char *)buf,
580     };
581     AUTH_LOGI(AUTH_CONN,
582         "dataSeq=%{public}" PRId64 ", dataLen=%{public}u, "
583         "connId=%{public}u, connSeq=%{public}" PRId64 ", connLen=%{public}u}",
584         head->seq, head->len, connectionId, connData.seq, connData.len);
585     return ConnPostBytes(connectionId, &connData);
586 }
587 
AuthConnInit(const AuthConnListener * listener)588 int32_t AuthConnInit(const AuthConnListener *listener)
589 {
590     CHECK_NULL_PTR_RETURN_VALUE(listener, SOFTBUS_INVALID_PARAM);
591     g_listener = *listener;
592     ListInit(&g_connRequestList);
593     if (InitCommConn() != SOFTBUS_OK) {
594         (void)memset_s(&g_listener, sizeof(g_listener), 0, sizeof(AuthConnListener));
595         AUTH_LOGE(AUTH_CONN, "init br/ble/p2p conn fail");
596         return SOFTBUS_AUTH_CONN_INIT_FAIL;
597     }
598     if (InitWiFiConn() != SOFTBUS_OK) {
599         (void)memset_s(&g_listener, sizeof(g_listener), 0, sizeof(AuthConnListener));
600         AUTH_LOGE(AUTH_CONN, "init wifi conn fail");
601         return SOFTBUS_AUTH_CONN_INIT_FAIL;
602     }
603     return SOFTBUS_OK;
604 }
605 
AuthConnDeinit(void)606 void AuthConnDeinit(void)
607 {
608     UnsetSocketCallback();
609     ConnUnSetConnectCallback(MODULE_DEVICE_AUTH);
610     ClearConnRequest();
611     (void)memset_s(&g_listener, sizeof(g_listener), 0, sizeof(AuthConnListener));
612 }
613 
ConnectAuthDevice(uint32_t requestId,const AuthConnInfo * connInfo,ConnSideType sideType)614 int32_t ConnectAuthDevice(uint32_t requestId, const AuthConnInfo *connInfo, ConnSideType sideType)
615 {
616     CHECK_NULL_PTR_RETURN_VALUE(connInfo, SOFTBUS_INVALID_PARAM);
617     AUTH_LOGI(AUTH_CONN, "requestId=%{public}u, connType=%{public}d, sideType=%{public}d", requestId,
618         connInfo->type, sideType);
619     PostConnConnectTimeout(requestId, connInfo->type);
620     int32_t ret = 0;
621     switch (connInfo->type) {
622         case AUTH_LINK_TYPE_WIFI: {
623             ConnCmdInfo info = {
624                 .requestId = requestId,
625                 .connInfo = *connInfo,
626                 .retryTimes = 0,
627             };
628             ret = PostAuthEvent(EVENT_CONNECT_CMD, HandleConnConnectCmd, &info, sizeof(ConnCmdInfo), 0);
629             break;
630         }
631         case AUTH_LINK_TYPE_BLE:
632             __attribute__((fallthrough));
633         case AUTH_LINK_TYPE_BR:
634             if (SoftBusGetBtState() != BLE_ENABLE) {
635                 ret = SOFTBUS_AUTH_CONN_FAIL;
636                 break;
637             }
638             __attribute__((fallthrough));
639         case AUTH_LINK_TYPE_P2P:
640         case AUTH_LINK_TYPE_ENHANCED_P2P:
641             ret = ConnectCommDevice(connInfo, requestId, sideType);
642             break;
643         default:
644             ret = SOFTBUS_OK;
645             break;
646     }
647     if (ret != SOFTBUS_OK) {
648         RemoveConnConnectTimeout(requestId);
649         AUTH_LOGE(AUTH_CONN, "ConnectDevice fail, requestId=%{public}u", requestId);
650     }
651     return ret;
652 }
653 
UpdateAuthDevicePriority(uint64_t connId)654 void UpdateAuthDevicePriority(uint64_t connId)
655 {
656     if (GetConnType(connId) != AUTH_LINK_TYPE_BLE) {
657         return;
658     }
659     UpdateOption option = {
660         .type = CONNECT_BLE,
661         .bleOption = {
662             .priority = CONN_BLE_PRIORITY_BALANCED,
663         }
664     };
665     int32_t ret = ConnUpdateConnection(GetConnId(connId), &option);
666     AUTH_LOGI(AUTH_CONN, "update connecton priority to balanced, connType=%{public}d, id=%{public}u, ret=%{public}d",
667         GetConnType(connId), GetConnId(connId), ret);
668 }
669 
DisconnectAuthDevice(uint64_t * connId)670 void DisconnectAuthDevice(uint64_t *connId)
671 {
672     if (connId == NULL) {
673         AUTH_LOGW(AUTH_CONN, "connId nulptr");
674         return;
675     }
676     AUTH_LOGI(AUTH_CONN, "connType=%{public}d, connectionId=%{public}u", GetConnType(*connId), GetConnId(*connId));
677     switch (GetConnType(*connId)) {
678         case AUTH_LINK_TYPE_RAW_ENHANCED_P2P:
679             SocketDisconnectDevice(AUTH_RAW_P2P_SERVER, GetFd(*connId));
680             UpdateFd(connId, AUTH_INVALID_FD);
681             break;
682         case AUTH_LINK_TYPE_WIFI:
683             SocketDisconnectDevice(AUTH, GetFd(*connId));
684             UpdateFd(connId, AUTH_INVALID_FD);
685             break;
686         case AUTH_LINK_TYPE_BLE:
687             __attribute__((fallthrough));
688         case AUTH_LINK_TYPE_BR:
689             ConnDisconnectDevice(GetConnId(*connId));
690             __attribute__((fallthrough));
691         case AUTH_LINK_TYPE_P2P:
692         case AUTH_LINK_TYPE_ENHANCED_P2P:
693             break;
694         default:
695             AUTH_LOGI(AUTH_CONN, "unknown connType");
696             break;
697     }
698 }
699 
PostAuthData(uint64_t connId,bool toServer,const AuthDataHead * head,const uint8_t * data)700 int32_t PostAuthData(uint64_t connId, bool toServer, const AuthDataHead *head, const uint8_t *data)
701 {
702     CHECK_NULL_PTR_RETURN_VALUE(head, SOFTBUS_INVALID_PARAM);
703     CHECK_NULL_PTR_RETURN_VALUE(data, SOFTBUS_INVALID_PARAM);
704     AUTH_LOGI(AUTH_CONN,
705         "auth post dataType=0x%{public}x, dataModule=%{public}d, dataSeq=%{public}" PRId64 ", "
706         "dataFlag=%{public}d, dataLen=%{public}u, " CONN_INFO ", toServer=%{public}s",
707         head->dataType, head->module, head->seq, head->flag, head->len, CONN_DATA(connId),
708         GetAuthSideStr(toServer));
709     switch (GetConnType(connId)) {
710         case AUTH_LINK_TYPE_WIFI:
711             return SocketPostBytes(GetFd(connId), head, data);
712         case AUTH_LINK_TYPE_BLE:
713         case AUTH_LINK_TYPE_BR:
714         case AUTH_LINK_TYPE_P2P:
715         case AUTH_LINK_TYPE_ENHANCED_P2P:
716             return PostCommData(GetConnId(connId), toServer, head, data);
717         default:
718             AUTH_LOGI(AUTH_CONN, "unknown connType");
719             break;
720     }
721     return SOFTBUS_AUTH_SEND_FAIL;
722 }
723 
GetConnSideType(uint64_t connId)724 ConnSideType GetConnSideType(uint64_t connId)
725 {
726     if (GetConnType(connId) == AUTH_LINK_TYPE_WIFI) {
727         AUTH_LOGE(AUTH_CONN, "WiFi not supported, " CONN_INFO, CONN_DATA(connId));
728         return CONN_SIDE_ANY;
729     }
730     ConnectionInfo info;
731     (void)memset_s(&info, sizeof(ConnectionInfo), 0, sizeof(ConnectionInfo));
732     if (ConnGetConnectionInfo(GetConnId(connId), &info)) {
733         AUTH_LOGE(AUTH_CONN, "ConnGetConnectionInfo fail, " CONN_INFO, CONN_DATA(connId));
734         return CONN_SIDE_ANY;
735     }
736     if (!info.isAvailable) {
737         AUTH_LOGE(AUTH_CONN, "connection not available, " CONN_INFO, CONN_DATA(connId));
738     }
739     return info.isServer ? CONN_SIDE_SERVER : CONN_SIDE_CLIENT;
740 }
741 
CheckActiveAuthConnection(const AuthConnInfo * connInfo)742 bool CheckActiveAuthConnection(const AuthConnInfo *connInfo)
743 {
744     ConnectOption connOpt;
745     CHECK_NULL_PTR_RETURN_VALUE(connInfo, false);
746     (void)memset_s(&connOpt, sizeof(ConnectOption), 0, sizeof(ConnectOption));
747     if (ConvertToConnectOption(connInfo, &connOpt) != SOFTBUS_OK) {
748         AUTH_LOGE(AUTH_CONN, "convert to connect option fail, connType=%{public}d.", connInfo->type);
749         return false;
750     }
751     if (connInfo->type == AUTH_LINK_TYPE_BLE) {
752         connOpt.bleOption.protocol = BLE_PROTOCOL_ANY;
753     }
754     return CheckActiveConnection(&connOpt, true);
755 }
756 
AuthStartListening(AuthLinkType type,const char * ip,int32_t port)757 int32_t AuthStartListening(AuthLinkType type, const char *ip, int32_t port)
758 {
759     if (ip == NULL) {
760         AUTH_LOGW(AUTH_CONN, "invalid param");
761         return SOFTBUS_INVALID_PARAM;
762     }
763     AUTH_LOGI(AUTH_CONN, "start auth listening, linkType=%{public}d, port=%{public}d", type, port);
764     LocalListenerInfo info = {
765         .type = CONNECT_TCP,
766         .socketOption = {
767             .addr = "",
768             .port = port,
769             .moduleId = AUTH,
770             .protocol = LNN_PROTOCOL_IP,
771         },
772     };
773 
774     if (strcpy_s(info.socketOption.addr, sizeof(info.socketOption.addr), ip) != EOK) {
775         AUTH_LOGE(AUTH_CONN, "strcpy_s ip fail");
776         return SOFTBUS_STRCPY_ERR;
777     }
778     switch (type) {
779         case AUTH_LINK_TYPE_WIFI: {
780             info.socketOption.moduleId = AUTH;
781             return StartSocketListening(AUTH, &info);
782         }
783         case AUTH_LINK_TYPE_RAW_ENHANCED_P2P: {
784             info.socketOption.moduleId = AUTH_RAW_P2P_SERVER;
785             info.socketOption.port = 0;
786             return StartSocketListening(AUTH_RAW_P2P_SERVER, &info);
787         }
788         default:
789             AUTH_LOGE(AUTH_CONN, "unsupport linkType=%{public}d", type);
790             break;
791     }
792     return SOFTBUS_INVALID_PARAM;
793 }
794 
AuthStopListening(AuthLinkType type)795 void AuthStopListening(AuthLinkType type)
796 {
797     AUTH_LOGI(AUTH_CONN, "stop auth listening, linkType=%{public}d", type);
798     switch (type) {
799         case AUTH_LINK_TYPE_WIFI:
800             StopSocketListening(AUTH);
801             break;
802         case AUTH_LINK_TYPE_RAW_ENHANCED_P2P:
803             StopSocketListening(AUTH_RAW_P2P_SERVER);
804             break;
805         default:
806             AUTH_LOGE(AUTH_CONN, "unsupport linkType=%{public}d", type);
807             break;
808     }
809 }
810 
AuthStartListeningForWifiDirect(AuthLinkType type,const char * ip,int32_t port,ListenerModule * moduleId)811 int32_t AuthStartListeningForWifiDirect(AuthLinkType type, const char *ip, int32_t port, ListenerModule *moduleId)
812 {
813     AUTH_CHECK_AND_RETURN_RET_LOGE(ip != NULL, SOFTBUS_INVALID_PARAM, AUTH_CONN, "ip is null");
814     AUTH_CHECK_AND_RETURN_RET_LOGE(moduleId != NULL, SOFTBUS_INVALID_PARAM, AUTH_CONN, "moduleId is null");
815 
816     LocalListenerInfo local;
817     local.type = CONNECT_TCP;
818     local.socketOption.port = port;
819     local.socketOption.protocol = LNN_PROTOCOL_IP;
820     int32_t ret = strcpy_s(local.socketOption.addr, sizeof(local.socketOption.addr), ip);
821     AUTH_CHECK_AND_RETURN_RET_LOGE(ret == EOK, SOFTBUS_STRCPY_ERR, AUTH_CONN, "copy ip failed");
822 
823     if (type == AUTH_LINK_TYPE_P2P) {
824         local.socketOption.moduleId = AUTH_P2P;
825     } else if (type == AUTH_LINK_TYPE_ENHANCED_P2P) {
826         local.socketOption.moduleId = (ListenerModule)(GetWifiDirectManager()->allocateListenerModuleId());
827         AUTH_CHECK_AND_RETURN_RET_LOGE(local.socketOption.moduleId < UNUSE_BUTT, SOFTBUS_ERR, AUTH_CONN,
828                                        "alloc listener module id failed");
829     } else {
830         AUTH_LOGE(AUTH_CONN, "invalid type=%{public}d", type);
831         return SOFTBUS_INVALID_PARAM;
832     }
833 
834     int32_t realPort = ConnStartLocalListening(&local);
835     if (realPort <= 0) {
836         if (type == AUTH_LINK_TYPE_ENHANCED_P2P) {
837             GetWifiDirectManager()->freeListenerModuleId(local.socketOption.moduleId);
838         }
839         AUTH_LOGE(AUTH_CONN, "start local listening failed");
840         return realPort;
841     }
842     AUTH_LOGI(AUTH_CONN, "moduleId=%{public}u, port=%{public}d", local.socketOption.moduleId, realPort);
843     *moduleId = local.socketOption.moduleId;
844     return realPort;
845 }
846 
AuthStopListeningForWifiDirect(AuthLinkType type,ListenerModule moduleId)847 void AuthStopListeningForWifiDirect(AuthLinkType type, ListenerModule moduleId)
848 {
849     AUTH_CHECK_AND_RETURN_LOGE(type == AUTH_LINK_TYPE_P2P || type == AUTH_LINK_TYPE_ENHANCED_P2P, AUTH_CONN,
850                                "invalid type=%{public}d", type);
851     LocalListenerInfo local = {
852         .type = CONNECT_TCP,
853         .socketOption = {
854             .moduleId = moduleId,
855             .protocol = LNN_PROTOCOL_IP,
856         },
857     };
858 
859     if (ConnStopLocalListening(&local) != SOFTBUS_OK) {
860         AUTH_LOGE(AUTH_CONN, "ConnStopLocalListening fail");
861     }
862     GetWifiDirectManager()->freeListenerModuleId(moduleId);
863 }