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