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 }