1 /*
2 * Copyright (c) 2021 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 "p2plink_interface.h"
17
18 #include <securec.h>
19 #include <semaphore.h>
20
21 #include "p2plink_common.h"
22 #include "p2plink_device.h"
23 #include "p2plink_loop.h"
24 #include "p2plink_manager.h"
25 #include "p2plink_negotiation.h"
26
27 #include "softbus_adapter_mem.h"
28 #include "softbus_def.h"
29 #include "softbus_errcode.h"
30 #include "softbus_log.h"
31
32 typedef struct {
33 RoleIsConflictInfo requestInfo;
34 sem_t wait;
35 int32_t result;
36 } RoleIsConfictLoopInfo;
37
38 typedef struct {
39 char peerIp[P2P_IP_LEN];
40 char peerMac[P2P_MAC_LEN];
41 sem_t wait;
42 } QueryP2pMacLoopInfo;
43
44 typedef struct {
45 char peerMac[P2P_MAC_LEN];
46 int32_t result;
47 sem_t wait;
48 } QueryP2pDevIsOnline;
49
P2pLinkGetRequestId(void)50 int32_t P2pLinkGetRequestId(void)
51 {
52 static int32_t requestId = 0;
53 requestId++;
54 if (requestId == 0) {
55 requestId++;
56 }
57 return requestId;
58 }
59
P2pLinkInit(void)60 int32_t P2pLinkInit(void)
61 {
62 return P2pLinkManagerInit();
63 }
64
P2pLinkConnectDevice(const P2pLinkConnectInfo * info)65 int32_t P2pLinkConnectDevice(const P2pLinkConnectInfo *info)
66 {
67 int32_t ret;
68
69 if (info == NULL) {
70 return SOFTBUS_ERR;
71 }
72 ConnectingNode *arg = SoftBusCalloc(sizeof(ConnectingNode));
73 if (arg == NULL) {
74 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "P2p Link connect malloc fail.");
75 return SOFTBUS_ERR;
76 }
77 ret = memcpy_s(&arg->connInfo, sizeof(P2pLinkConnectInfo), info, sizeof(P2pLinkConnectInfo));
78 if (ret != SOFTBUS_OK) {
79 SoftBusFree(arg);
80 return SOFTBUS_ERR;
81 }
82 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "conn info reqid %d, pid %d role %d",
83 info->requestId, info->pid, info->expectedRole);
84 ret = P2pLoopProc(P2pLinkLoopConnectDevice, (void *)arg, P2PLOOP_INTERFACE_LOOP_CONNECT);
85 if (ret != SOFTBUS_OK) {
86 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "P2pLinkLoopConnectDevice loop fail.");
87 SoftBusFree(arg);
88 }
89 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "P2pLinkLoopConnectDevice loop ok.");
90 return ret;
91 }
92
P2pLinkDisconnectDevice(const P2pLinkDisconnectInfo * info)93 int32_t P2pLinkDisconnectDevice(const P2pLinkDisconnectInfo *info)
94 {
95 int32_t ret;
96
97 if (info == NULL) {
98 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "P2p Link Disconnect arg err.");
99 return SOFTBUS_ERR;
100 }
101 P2pLinkDisconnectInfo *arg = SoftBusCalloc(sizeof(P2pLinkDisconnectInfo));
102 if (arg == NULL) {
103 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "P2p Link Disconnect malloc fail.");
104 return SOFTBUS_ERR;
105 }
106 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "disconn info, pid %d", info->pid);
107 ret = memcpy_s(arg, sizeof(P2pLinkDisconnectInfo), info, sizeof(P2pLinkDisconnectInfo));
108 if (ret != SOFTBUS_OK) {
109 SoftBusFree(arg);
110 return SOFTBUS_ERR;
111 }
112 ret = P2pLoopProc(P2pLinkLoopDisconnectDev, (void *)arg, P2PLOOP_INTERFACE_LOOP_DISCONNECT);
113 if (ret != SOFTBUS_OK) {
114 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "P2pLinkLoopConnectDevice loop fail.");
115 SoftBusFree(arg);
116 return ret;
117 }
118 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "disconnect loop ok.");
119 return SOFTBUS_OK;
120 }
121
LoopP2pLinkIsRoleConfict(P2pLoopMsg msgType,void * arg)122 static void LoopP2pLinkIsRoleConfict(P2pLoopMsg msgType, void *arg)
123 {
124 RoleIsConfictLoopInfo *loopInfo = NULL;
125 ConnectedNode *connedItem = NULL;
126 RoleIsConflictInfo *requestInfo = NULL;
127
128 (void)msgType;
129 if (arg == NULL) {
130 return;
131 }
132
133 loopInfo = (RoleIsConfictLoopInfo *)arg;
134 if (P2pLinkIsEnable() == false) {
135 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "in role p2p state is closed");
136 loopInfo->result = SOFTBUS_ERR;
137 sem_post(&loopInfo->wait);
138 return;
139 }
140 requestInfo = &loopInfo->requestInfo;
141 connedItem = P2pLinkGetConnedDevByMac(requestInfo->peerMac);
142 if (connedItem != NULL) {
143 if (strlen(connedItem->peerIp) == 0) {
144 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "dev is used by others");
145 loopInfo->result = ERROR_LINK_USED_BY_ANOTHER_SERVICE;
146 sem_post(&loopInfo->wait);
147 return;
148 }
149 if ((requestInfo->expectedRole != ROLE_AUTO) &&
150 (requestInfo->expectedRole != P2pLinkGetRole())) {
151 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "role is confict");
152 loopInfo->result = ERROR_CONNECTED_WITH_MISMATCHED_ROLE;
153 sem_post(&loopInfo->wait);
154 return;
155 }
156 loopInfo->result = SOFTBUS_OK;
157 sem_post(&loopInfo->wait);
158 } else {
159 loopInfo->result = P2pLinkNegoGetFinalRole(requestInfo->peerRole, requestInfo->peerRole,
160 requestInfo->peerGoMac, requestInfo->isBridgeSupported);
161 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "P2pLinkNegoGetFinalRole ret %d", loopInfo->result);
162 sem_post(&loopInfo->wait);
163 }
164 return;
165 }
166
P2pLinkIsRoleConflict(const RoleIsConflictInfo * info)167 int32_t P2pLinkIsRoleConflict(const RoleIsConflictInfo *info)
168 {
169 RoleIsConfictLoopInfo loopInfo;
170 (void)memset_s(&loopInfo, sizeof(loopInfo), 0, sizeof(loopInfo));
171 int32_t ret;
172
173 if (info == NULL) {
174 return SOFTBUS_ERR;
175 }
176
177 ret = memcpy_s(&loopInfo.requestInfo, sizeof(loopInfo.requestInfo),
178 info, sizeof(RoleIsConflictInfo));
179 if (ret != SOFTBUS_OK) {
180 return SOFTBUS_ERR;
181 }
182
183 if (sem_init(&loopInfo.wait, 0, 0)) {
184 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "sem init fail");
185 return SOFTBUS_ERR;
186 }
187
188 ret = P2pLoopProc(LoopP2pLinkIsRoleConfict, (void *)&loopInfo, P2PLOOP_INTERFACE_ROLE_CONFICT);
189 if (ret != SOFTBUS_OK) {
190 sem_destroy(&loopInfo.wait);
191 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "LoopP2pLinkIsRoleConfict loop fail");
192 return SOFTBUS_ERR;
193 }
194 sem_wait(&loopInfo.wait);
195 sem_destroy(&loopInfo.wait);
196 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "role confict res %d.", loopInfo.result);
197 if (loopInfo.result < 0) {
198 return SOFTBUS_ERR;
199 }
200 return SOFTBUS_OK;
201 }
202
LoopP2pLinkQueryIpByMac(P2pLoopMsg msgType,void * arg)203 static void LoopP2pLinkQueryIpByMac(P2pLoopMsg msgType, void *arg)
204 {
205 QueryP2pMacLoopInfo *queryInfo = NULL;
206 ConnectedNode *connedItem = NULL;
207
208 (void)msgType;
209 if (arg == NULL) {
210 return;
211 }
212
213 queryInfo = (QueryP2pMacLoopInfo *)arg;
214 connedItem = P2pLinkGetConnedDevByPeerIp(queryInfo->peerIp);
215 if (connedItem != NULL) {
216 if (strcpy_s(queryInfo->peerMac, sizeof(queryInfo->peerMac), connedItem->peerMac) != EOK) {
217 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "strcpy fail.");
218 }
219 }
220 sem_post(&queryInfo->wait);
221 return;
222 }
223
P2pLinkGetPeerMacByPeerIp(const char * peerIp,char * peerMac,int32_t macLen)224 int32_t P2pLinkGetPeerMacByPeerIp(const char *peerIp, char* peerMac, int32_t macLen)
225 {
226 QueryP2pMacLoopInfo queryInfo;
227 int32_t ret;
228
229 if (peerIp == NULL || peerMac == NULL) {
230 return SOFTBUS_ERR;
231 }
232 if (P2pLinkGetRole() == ROLE_NONE) {
233 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "p2p role is none");
234 return SOFTBUS_ERR;
235 }
236
237 (void)memset_s(&queryInfo, sizeof(queryInfo), 0, sizeof(queryInfo));
238 ret = strcpy_s(queryInfo.peerIp, sizeof(queryInfo.peerIp), peerIp);
239 if (ret != EOK) {
240 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "copy fail");
241 return SOFTBUS_ERR;
242 }
243
244 if (sem_init(&queryInfo.wait, 0, 0)) {
245 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "sem init fail");
246 return SOFTBUS_ERR;
247 }
248
249 ret = P2pLoopProc(LoopP2pLinkQueryIpByMac, (void *)&queryInfo, P2PLOOP_MSG_PROC);
250 if (ret != SOFTBUS_OK) {
251 sem_destroy(&queryInfo.wait);
252 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "LoopP2pLinkIsRoleConfict loop fail");
253 return SOFTBUS_ERR;
254 }
255 sem_wait(&queryInfo.wait);
256 sem_destroy(&queryInfo.wait);
257 if (strlen(queryInfo.peerMac) == 0) {
258 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "peerMac is null");
259 return SOFTBUS_ERR;
260 }
261 ret = strcpy_s(peerMac, macLen, queryInfo.peerMac);
262 if (ret != EOK) {
263 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "strcpy fail");
264 return SOFTBUS_ERR;
265 }
266 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "query ok ip");
267 return SOFTBUS_OK;
268 }
269
P2pLinkRegPeerDevStateChange(const P2pLinkPeerDevStateCb * cb)270 void P2pLinkRegPeerDevStateChange(const P2pLinkPeerDevStateCb *cb)
271 {
272 if (cb == NULL) {
273 return;
274 }
275 P2pLinkSetDevStateCallback(cb);
276 }
277
P2pLinkGetLocalIp(char * localIp,int32_t localIpLen)278 int32_t P2pLinkGetLocalIp(char *localIp, int32_t localIpLen)
279 {
280 char tmpIp[P2P_IP_LEN] = {0};
281 int32_t ret;
282
283 ret = strcpy_s(tmpIp, sizeof(tmpIp), P2pLinkGetMyIp());
284 if (ret != EOK) {
285 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "get myIp fail");
286 return SOFTBUS_ERR;
287 }
288
289 if (strlen(tmpIp) == 0) {
290 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "myIp is null");
291 return SOFTBUS_ERR;
292 }
293
294 ret = strcpy_s(localIp, localIpLen, tmpIp);
295 if (ret != EOK) {
296 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "copy tmpIp fail");
297 return SOFTBUS_ERR;
298 }
299 return SOFTBUS_OK;
300 }
301
LoopP2pLinkQueryDevOnline(P2pLoopMsg msgType,void * arg)302 static void LoopP2pLinkQueryDevOnline(P2pLoopMsg msgType, void *arg)
303 {
304 QueryP2pDevIsOnline *queryInfo = NULL;
305 ConnectedNode *connedItem = NULL;
306
307 (void)msgType;
308 if (arg == NULL) {
309 return;
310 }
311
312 queryInfo = (QueryP2pDevIsOnline *)arg;
313 connedItem = P2pLinkGetConnedDevByMac(queryInfo->peerMac);
314 if (connedItem != NULL) {
315 queryInfo->result = SOFTBUS_OK;
316 } else {
317 queryInfo->result = SOFTBUS_ERR;
318 }
319 sem_post(&queryInfo->wait);
320 return;
321 }
322
P2pLinkQueryDevIsOnline(const char * peerMac)323 int32_t P2pLinkQueryDevIsOnline(const char *peerMac)
324 {
325 QueryP2pDevIsOnline queryInfo;
326 int32_t ret;
327
328 if (peerMac == NULL) {
329 return SOFTBUS_ERR;
330 }
331
332 (void)memset_s(&queryInfo, sizeof(queryInfo), 0, sizeof(queryInfo));
333 if (P2pLinkGetRole() == ROLE_NONE) {
334 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "isonline role is none");
335 return SOFTBUS_ERR;
336 }
337
338 (void)memset_s(&queryInfo, sizeof(queryInfo), 0, sizeof(queryInfo));
339 ret = strcpy_s(queryInfo.peerMac, sizeof(queryInfo.peerMac), peerMac);
340 if (ret != EOK) {
341 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "copy fail");
342 return SOFTBUS_ERR;
343 }
344
345 if (sem_init(&queryInfo.wait, 0, 0)) {
346 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "sem init fail");
347 return SOFTBUS_ERR;
348 }
349
350 ret = P2pLoopProc(LoopP2pLinkQueryDevOnline, (void *)&queryInfo, P2PLOOP_MSG_PROC);
351 if (ret != SOFTBUS_OK) {
352 sem_destroy(&queryInfo.wait);
353 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "LoopP2pLinkIsRoleConfict loop fail");
354 return SOFTBUS_ERR;
355 }
356 sem_wait(&queryInfo.wait);
357 sem_destroy(&queryInfo.wait);
358 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "query result %d", queryInfo.result);
359 return queryInfo.result;
360 }
361