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