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 }