1 /*
2 * Copyright (c) 2022-2025 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 "trans_tcp_direct_wifi.h"
17
18 #include <securec.h>
19
20 #include "auth_interface.h"
21 #include "bus_center_manager.h"
22 #include "lnn_network_manager.h"
23 #include "legacy/softbus_adapter_hitrace.h"
24 #include "softbus_adapter_mem.h"
25 #include "softbus_error_code.h"
26 #include "softbus_socket.h"
27 #include "trans_log.h"
28 #include "trans_tcp_direct_message.h"
29 #include "trans_tcp_direct_sessionconn.h"
30 #include "trans_tcp_direct_p2p.h"
31 #include "wifi_direct_manager.h"
32
33 #define ID_OFFSET (1)
34
FreeFastTransData(AppInfo * appInfo)35 static void FreeFastTransData(AppInfo *appInfo)
36 {
37 if (appInfo != NULL && appInfo->fastTransData != NULL) {
38 SoftBusFree((void *)(appInfo->fastTransData));
39 }
40 }
41
AddTcpConnAndSessionInfo(int32_t newchannelId,int32_t fd,SessionConn * newConn,ListenerModule module)42 static int32_t AddTcpConnAndSessionInfo(int32_t newchannelId, int32_t fd, SessionConn *newConn,
43 ListenerModule module)
44 {
45 if (TransSrvAddDataBufNode(newchannelId, fd) != SOFTBUS_OK) {
46 FreeFastTransData(&(newConn->appInfo));
47 SoftBusFree(newConn);
48 TRANS_LOGE(TRANS_CTRL, "OpenTcpDirectChannel create databuf fail");
49 return SOFTBUS_MALLOC_ERR;
50 }
51
52 if (TransTdcAddSessionConn(newConn) != SOFTBUS_OK) {
53 TransSrvDelDataBufNode(newchannelId);
54 FreeFastTransData(&(newConn->appInfo));
55 SoftBusFree(newConn);
56 return SOFTBUS_TRANS_ADD_SESSION_CONN_FAILED;
57 }
58 if (AddTrigger(module, fd, WRITE_TRIGGER) != SOFTBUS_OK) {
59 TRANS_LOGE(TRANS_CTRL, "OpenTcpDirectChannel add trigger fail");
60 TransDelSessionConnById(newchannelId);
61 TransSrvDelDataBufNode(newchannelId);
62 return SOFTBUS_TRANS_ADD_TRIGGER_FAILED;
63 }
64 return SOFTBUS_OK;
65 }
66
GetMoudleType(ConnectType type,const char * peerIp)67 static ListenerModule GetMoudleType(ConnectType type, const char *peerIp)
68 {
69 ListenerModule module = UNUSE_BUTT;
70 if (type == CONNECT_P2P_REUSE) {
71 char myIp[IP_LEN] = {0};
72 struct WifiDirectManager *mgr = GetWifiDirectManager();
73 if (mgr == NULL || mgr->getLocalIpByRemoteIp == NULL) {
74 TRANS_LOGE(TRANS_CTRL, "GetWifiDirectManager failed");
75 return SOFTBUS_WIFI_DIRECT_INIT_FAILED;
76 }
77
78 int32_t ret = mgr->getLocalIpByRemoteIp(peerIp, myIp, sizeof(myIp));
79 if (ret != SOFTBUS_OK) {
80 TRANS_LOGE(TRANS_CTRL, "get Local Ip fail, ret = %{public}d", ret);
81 return module;
82 }
83
84 if (IsHmlIpAddr(myIp)) {
85 module = GetModuleByHmlIp(myIp);
86 } else {
87 module = DIRECT_CHANNEL_SERVER_P2P;
88 }
89 } else {
90 module = DIRECT_CHANNEL_SERVER_WIFI;
91 }
92 return module;
93 }
94
CopyAppInfoFastTransData(SessionConn * conn,const AppInfo * appInfo)95 static int32_t CopyAppInfoFastTransData(SessionConn *conn, const AppInfo *appInfo)
96 {
97 if (appInfo->fastTransData != NULL && appInfo->fastTransDataSize > 0) {
98 uint8_t *fastTransData = (uint8_t *)SoftBusCalloc(appInfo->fastTransDataSize);
99 if (fastTransData == NULL) {
100 return SOFTBUS_MALLOC_ERR;
101 }
102 if (memcpy_s((char *)fastTransData, appInfo->fastTransDataSize, (const char *)appInfo->fastTransData,
103 appInfo->fastTransDataSize) != EOK) {
104 SoftBusFree(fastTransData);
105 TRANS_LOGE(TRANS_CTRL, "memcpy fastTransData fail");
106 return SOFTBUS_MEM_ERR;
107 }
108 conn->appInfo.fastTransData = fastTransData;
109 }
110 return SOFTBUS_OK;
111 }
112
OpenTcpDirectChannel(const AppInfo * appInfo,const ConnectOption * connInfo,int32_t * channelId)113 int32_t OpenTcpDirectChannel(const AppInfo *appInfo, const ConnectOption *connInfo, int32_t *channelId)
114 {
115 TRANS_LOGI(TRANS_CTRL, "enter.");
116 if (appInfo == NULL || connInfo == NULL || channelId == NULL) {
117 return SOFTBUS_INVALID_PARAM;
118 }
119
120 ListenerModule module = GetMoudleType(connInfo->type, connInfo->socketOption.addr);
121 TRANS_LOGI(TRANS_CTRL, "get listener module=%{public}d!", module);
122 if (module == DIRECT_CHANNEL_SERVER_WIFI) {
123 module = LnnGetProtocolListenerModule(connInfo->socketOption.protocol, LNN_LISTENER_MODE_DIRECT);
124 }
125 if (module == UNUSE_BUTT) {
126 return SOFTBUS_TRANS_TCP_UNUSE_LISTENER_MODE;
127 }
128
129 SessionConn *newConn = CreateNewSessinConn(module, false);
130 if (newConn == NULL) {
131 return SOFTBUS_MALLOC_ERR;
132 }
133 SoftbusHitraceStart(SOFTBUS_HITRACE_ID_VALID, (uint64_t)(newConn->channelId + ID_OFFSET));
134 TRANS_LOGI(TRANS_CTRL,
135 "SoftbusHitraceChainBegin: set HitraceId=%{public}" PRIu64, (uint64_t)(newConn->channelId + ID_OFFSET));
136 int32_t newchannelId = newConn->channelId;
137 if (memcpy_s(&newConn->appInfo, sizeof(AppInfo), appInfo, sizeof(AppInfo)) != EOK) {
138 TRANS_LOGE(TRANS_CTRL, "copy appInfo fail");
139 SoftBusFree(newConn);
140 return SOFTBUS_MEM_ERR;
141 }
142 int32_t ret = CopyAppInfoFastTransData(newConn, appInfo);
143 if (ret != SOFTBUS_OK) {
144 SoftBusFree(newConn);
145 TRANS_LOGE(TRANS_CTRL, "copy appinfo fast trans data fail");
146 return ret;
147 }
148 if (module == DIRECT_CHANNEL_SERVER_USB) {
149 AuthGetLatestIdByUuid(newConn->appInfo.peerData.deviceId, AUTH_LINK_TYPE_USB, false, &newConn->authHandle);
150 if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP6_WITH_IF, newConn->appInfo.myData.addr,
151 sizeof(newConn->appInfo.myData.addr), USB_IF) != SOFTBUS_OK) {
152 TRANS_LOGE(TRANS_CTRL, "get local ip failed");
153 return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
154 }
155 } else {
156 AuthGetLatestIdByUuid(newConn->appInfo.peerData.deviceId, AUTH_LINK_TYPE_WIFI, false, &newConn->authHandle);
157 }
158 if ((newConn->authHandle.authId == AUTH_INVALID_ID) && (connInfo->type == CONNECT_P2P_REUSE)) {
159 AuthGetLatestIdByUuid(newConn->appInfo.peerData.deviceId, AUTH_LINK_TYPE_BR, false, &newConn->authHandle);
160 }
161
162 if (newConn->authHandle.authId == AUTH_INVALID_ID) {
163 FreeFastTransData(&(newConn->appInfo));
164 SoftBusFree(newConn);
165 TRANS_LOGE(TRANS_CTRL, "get authId fail");
166 return SOFTBUS_TRANS_TCP_GET_AUTHID_FAILED;
167 }
168
169 int32_t fd = ConnOpenClientSocket(connInfo, newConn->appInfo.myData.addr, true);
170 if (fd < 0) {
171 FreeFastTransData(&(newConn->appInfo));
172 SoftBusFree(newConn);
173 TRANS_LOGE(TRANS_CTRL, "connect failed. fd=%{public}d", fd);
174 return fd;
175 }
176 newConn->appInfo.fd = fd;
177
178 ret = AddTcpConnAndSessionInfo(newchannelId, fd, newConn, module);
179 if (ret != SOFTBUS_OK) {
180 ConnShutdownSocket(fd);
181 return ret;
182 }
183 *channelId = newchannelId;
184 TRANS_LOGI(TRANS_CTRL,
185 "ok: channelId=%{public}d, module=%{public}d, fd=%{public}d",
186 newchannelId, (int32_t)module, fd);
187 return SOFTBUS_OK;
188 }
189