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 }