1 /*
2 * Copyright (c) 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 #include "proxy_manager.h"
16
17 #include "securec.h"
18 #include "conn_log.h"
19 #include "softbus_adapter_bt_common.h"
20 #include "softbus_adapter_mem.h"
21 #include "softbus_conn_common.h"
22 #include "softbus_conn_manager.h"
23 #include "softbus_error_code.h"
24 #include "proxy_connection.h"
25 #include "proxy_observer.h"
26
27 #define INNER_RECONNECT_TIMEOUT_MS 8000
28 #define INNER_RECONNECT_RETRY_WAIT_MS 1000
29 #define RECONNECT_AFTER_DISCONNECT_WAIT_MS 500
30 #define OPEN_PROXY_CHANNEL_WAIT_MS 200
31
32 typedef struct {
33 bool isSuccess;
34 uint32_t channelId;
35 int32_t status;
36 } ProxyChannelNotifyContext;
37
38 typedef struct {
39 char brMac[BT_MAC_LEN];
40 int32_t state;
41 } ProxyChannelAclStateContext;
42
43 enum BrProxyLooperMsgType {
44 MSG_OPEN_PROXY_CHANNEL = 100,
45 MSG_OPEN_PROXY_CHANNEL_TIMEOUT,
46 MSG_OPEN_PROXY_CHANNEL_RETRY,
47 MSG_OPEN_PROXY_CHANNEL_CONNECT_RESULT,
48 MSG_CLOSE_PROXY_CHANNEL,
49 MSG_CLOSE_PROXY_DISCONNECT,
50 MSG_ACL_STATE_CHANGE,
51 MSG_PROXY_RESET,
52 MSG_PROXY_UNPAIRED,
53 };
54
55 static void ProxyChannelMsgHandler(SoftBusMessage *msg);
56 static int ProxyChannelLooperEventFunc(const SoftBusMessage *msg, void *args);
57 static uint64_t g_retryIntervalMillis[] = {0, 1000, 2000, 4000, 8000, 16000, 32000};
58 #define RETRY_CONNECT_MAX_NUM ((sizeof(g_retryIntervalMillis) / sizeof(uint64_t)) - 1)
59
60 static SoftBusHandlerWrapper g_proxyChannelAsyncHandler = {
61 .handler = {
62 .name = (char *)"ProxyChannelAsyncHandler",
63 .HandleMessage = ProxyChannelMsgHandler,
64 // assign when initiation
65 .looper = NULL,
66 },
67 .eventCompareFunc = ProxyChannelLooperEventFunc,
68 };
69
70 static void DestoryProxyConnectInfo(ProxyConnectInfo **connectInfo);
71 static void DestoryProxyConnection(struct ProxyConnection *proxyConnection);
72 static struct ProxyConnection *GetProxyChannelByChannelId(uint32_t channelId);
73 static void NotifyOpenProxyChannelResult(struct ProxyConnection *channel, bool isSuccess, int32_t status);
74 static void ProxyChannelConnectResultHandler(ProxyChannelNotifyContext *ctx);
75 static void AddReconnectDeviceInfoUnsafe(ProxyConnectInfo *connectInfo);
76 static void RemoveReconnectDeviceInfoByAddrUnsafe(const char *addr);
77 static ProxyConnectInfo *GetReconnectDeviceInfoByAddrUnsafe(const char *addr);
78 static void AttemptReconnectDevice(char *brAddr);
79 static void RemoveProxyChannelByChannelId(uint32_t channelId);
80 static ProxyConnectInfo *CopyProxyConnectInfo(ProxyConnectInfo *srcInfo);
81
82 static ProxyConnectListener g_listener = { 0 };
83 static SoftBusMutex g_reqIdLock;
84 static uint32_t g_reqId = 1;
85
GenerateRequestId(void)86 static uint32_t GenerateRequestId(void)
87 {
88 int32_t ret = SoftBusMutexLock(&g_reqIdLock);
89 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, PROXY_CHANNEL_MAX_STATE, CONN_PROXY,
90 "lock channel failed=%{public}d", ret);
91 uint32_t reqId = g_reqId++;
92 SoftBusMutexUnlock(&g_reqIdLock);
93 return reqId;
94 }
95
GetProxyChannelState(struct ProxyConnection * proxyConnection)96 static ProxyChannelState GetProxyChannelState(struct ProxyConnection *proxyConnection)
97 {
98 int32_t ret = SoftBusMutexLock(&proxyConnection->lock);
99 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, PROXY_CHANNEL_MAX_STATE, CONN_PROXY,
100 "lock channel failed. channelId=%{public}u, error=%{public}d", proxyConnection->channelId, ret);
101 ProxyChannelState state = proxyConnection->state;
102 SoftBusMutexUnlock(&proxyConnection->lock);
103 return state;
104 }
105
SetProxyChannelState(struct ProxyConnection * proxyConnection,ProxyChannelState state)106 static ProxyChannelState SetProxyChannelState(struct ProxyConnection *proxyConnection, ProxyChannelState state)
107 {
108 int32_t ret = SoftBusMutexLock(&proxyConnection->lock);
109 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, PROXY_CHANNEL_MAX_STATE, CONN_PROXY,
110 "lock channel failed. channelId=%{public}u", proxyConnection->channelId);
111 proxyConnection->state = state;
112 SoftBusMutexUnlock(&proxyConnection->lock);
113 return state;
114 }
115
ProxyChannelDereference(struct ProxyConnection * proxyConnection)116 static void ProxyChannelDereference(struct ProxyConnection *proxyConnection)
117 {
118 CONN_CHECK_AND_RETURN_LOGE(proxyConnection != NULL, CONN_PROXY, "proxyConnection is null");
119 int32_t ret = SoftBusMutexLock(&proxyConnection->lock);
120 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_PROXY,
121 "lock channel failed. channelId=%{public}u", proxyConnection->channelId);
122 proxyConnection->refCount -= 1;
123 bool destruct = (proxyConnection->refCount <= 0);
124 SoftBusMutexUnlock(&proxyConnection->lock);
125 if (destruct) {
126 CONN_LOGW(CONN_PROXY, "destory proxy channel=%{public}u", proxyConnection->channelId);
127 DestoryProxyConnection(proxyConnection);
128 }
129 }
130
ProxyChannelReference(struct ProxyConnection * proxyConnection)131 static void ProxyChannelReference(struct ProxyConnection *proxyConnection)
132 {
133 CONN_CHECK_AND_RETURN_LOGE(proxyConnection != NULL, CONN_PROXY, "proxyConnection is null");
134 int32_t ret = SoftBusMutexLock(&proxyConnection->lock);
135 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_PROXY,
136 "lock channel failed. channelId=%{public}u", proxyConnection->channelId);
137 proxyConnection->refCount += 1;
138 SoftBusMutexUnlock(&proxyConnection->lock);
139 }
140
ProxyChannelSend(struct ProxyChannel * channel,const uint8_t * data,uint32_t dataLen)141 int32_t ProxyChannelSend(struct ProxyChannel *channel, const uint8_t *data, uint32_t dataLen)
142 {
143 CONN_CHECK_AND_RETURN_RET_LOGE(channel != NULL, SOFTBUS_INVALID_PARAM, CONN_PROXY, "channel is null");
144 CONN_CHECK_AND_RETURN_RET_LOGE(data != NULL, SOFTBUS_INVALID_PARAM, CONN_PROXY, "data is null");
145 struct ProxyConnection *proxyConnection = GetProxyChannelByChannelId(channel->channelId);
146 CONN_CHECK_AND_RETURN_RET_LOGE(proxyConnection != NULL, SOFTBUS_NOT_FIND, CONN_PROXY,
147 "get proxyConnection failed, channelId=%{public}u", channel->channelId);
148 int32_t ret = GetProxyBrConnectionManager()->send(proxyConnection, data, dataLen);
149 proxyConnection->dereference(proxyConnection);
150 return ret;
151 }
152
ProxyChannelCloseHandler(char * brAddr)153 static void ProxyChannelCloseHandler(char *brAddr)
154 {
155 RemoveReconnectDeviceInfoByAddrUnsafe(brAddr);
156 }
157
ProxyChannelClose(struct ProxyChannel * channel)158 static void ProxyChannelClose(struct ProxyChannel *channel)
159 {
160 CONN_CHECK_AND_RETURN_LOGE(channel != NULL, CONN_PROXY, "channel is null");
161 char *copyAddr = (char *)SoftBusCalloc(BT_MAC_MAX_LEN);
162 if (copyAddr == NULL || strcpy_s(copyAddr, BT_MAC_MAX_LEN, channel->brMac) != EOK) {
163 CONN_LOGE(CONN_PROXY, "copyAddr failed");
164 SoftBusFree(copyAddr);
165 return;
166 }
167 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_CLOSE_PROXY_CHANNEL, 0, 0, copyAddr, 0);
168 if (ret < 0) {
169 // fall-through
170 CONN_LOGE(CONN_PROXY, "send msg failed, error=%{public}d", ret);
171 SoftBusFree(copyAddr);
172 }
173
174 struct ProxyConnection *proxyConnection = GetProxyChannelByChannelId(channel->channelId);
175 CONN_CHECK_AND_RETURN_LOGE(proxyConnection != NULL, CONN_PROXY,
176 "get proxyConnection failed, channelId=%{public}u", channel->channelId);
177 SetProxyChannelState(proxyConnection, PROXY_CHANNEL_DISCONNECTING);
178 ret = GetProxyBrConnectionManager()->disconnect(proxyConnection);
179 CONN_LOGW(CONN_PROXY, "close proxy channel=%{public}u, ret=%{public}d", channel->channelId, ret);
180 proxyConnection->dereference(proxyConnection);
181 }
182
CreateProxyConnection(ProxyConnectInfo * connectInfo)183 static struct ProxyConnection *CreateProxyConnection(ProxyConnectInfo *connectInfo)
184 {
185 struct ProxyConnection *proxyConnection = (struct ProxyConnection *)SoftBusCalloc(sizeof(struct ProxyConnection));
186 CONN_CHECK_AND_RETURN_RET_LOGE(proxyConnection != NULL, NULL, CONN_PROXY, "proxyConnection is NULL");
187 proxyConnection->reference = ProxyChannelReference;
188 proxyConnection->dereference = ProxyChannelDereference;
189 proxyConnection->state = PROXY_CHANNEL_CONNECTING;
190 proxyConnection->refCount = 1;
191 proxyConnection->socketHandle = BR_INVALID_SOCKET_HANDLE;
192 proxyConnection->proxyChannel.send = ProxyChannelSend;
193 proxyConnection->proxyChannel.close = ProxyChannelClose;
194 proxyConnection->proxyChannel.requestId = connectInfo->requestId;
195 int32_t ret = connectInfo->isRealMac ?
196 strcpy_s(proxyConnection->proxyChannel.brMac, BT_MAC_MAX_LEN, connectInfo->brMac) :
197 strcpy_s(proxyConnection->proxyChannel.brMac, BT_MAC_MAX_LEN, connectInfo->brHashMac);
198 if (ret != EOK) {
199 CONN_LOGE(CONN_PROXY, "copy br mac failed, ret=%{public}d", ret);
200 SoftBusFree(proxyConnection);
201 return NULL;
202 }
203 if (strcpy_s(proxyConnection->brMac, BT_MAC_LEN, connectInfo->brMac) != EOK ||
204 strcpy_s(proxyConnection->proxyChannel.uuid, UUID_STRING_LEN, connectInfo->uuid) != EOK) {
205 CONN_LOGE(CONN_PROXY, "cpy br mac or uuid err");
206 SoftBusFree(proxyConnection);
207 return NULL;
208 }
209 ListInit(&proxyConnection->node);
210
211 if (SoftBusMutexInit(&proxyConnection->lock, NULL) != SOFTBUS_OK) {
212 CONN_LOGE(CONN_PROXY, "init lock failed");
213 SoftBusFree(proxyConnection);
214 return NULL;
215 }
216 return proxyConnection;
217 }
218
AllocateConnectionIdUnsafe(void)219 static uint32_t AllocateConnectionIdUnsafe(void)
220 {
221 static uint16_t nextId = 0;
222
223 uint32_t channelId = (CONNECT_PROXY_CHANNEL << CONNECT_TYPE_SHIFT) + (++nextId);
224 struct ProxyConnection *it = NULL;
225 LIST_FOR_EACH_ENTRY(it, &GetProxyChannelManager()->proxyConnectionList->list, struct ProxyConnection, node) {
226 if (channelId == it->channelId) {
227 return 0;
228 }
229 }
230 return channelId;
231 }
232
SaveProxyConnection(struct ProxyConnection * proxyConnection)233 static int32_t SaveProxyConnection(struct ProxyConnection *proxyConnection)
234 {
235 #define RETRY_MAX_NUM 100
236 int32_t ret = SoftBusMutexLock(&GetProxyChannelManager()->proxyConnectionList->lock);
237 if (ret != SOFTBUS_OK) {
238 CONN_LOGE(CONN_PROXY, "lock proxyConnectionList failed");
239 return SOFTBUS_LOCK_ERR;
240 }
241 uint32_t channelId = 0;
242 int32_t retryNum = 0;
243 do {
244 channelId = AllocateConnectionIdUnsafe();
245 retryNum++;
246 } while (channelId == 0 && retryNum < RETRY_MAX_NUM);
247 if (channelId == 0) {
248 CONN_LOGE(CONN_PROXY, "allocate channelId failed");
249 SoftBusMutexUnlock(&GetProxyChannelManager()->proxyConnectionList->lock);
250 return SOFTBUS_CONN_PROXY_INTERNAL_ERR;
251 }
252 proxyConnection->channelId = channelId;
253 proxyConnection->proxyChannel.channelId = channelId;
254 ListAdd(&GetProxyChannelManager()->proxyConnectionList->list, &proxyConnection->node);
255 proxyConnection->reference(proxyConnection);
256 SoftBusMutexUnlock(&GetProxyChannelManager()->proxyConnectionList->lock);
257 return SOFTBUS_OK;
258 }
259
DestoryProxyConnection(struct ProxyConnection * proxyConnection)260 static void DestoryProxyConnection(struct ProxyConnection *proxyConnection)
261 {
262 SoftBusMutexDestroy(&proxyConnection->lock);
263 SoftBusFree(proxyConnection);
264 }
265
ProcessConnectFailed(ProxyConnectInfo * connectingChannel,const char * brMac,int32_t reason)266 static void ProcessConnectFailed(ProxyConnectInfo *connectingChannel, const char *brMac, int32_t reason)
267 {
268 CONN_LOGE(CONN_PROXY, "notify open fail reqId=%{public}u, reason=%{public}d", connectingChannel->requestId, reason);
269 connectingChannel->result.onOpenFail(connectingChannel->requestId, reason);
270 bool isInnerRequest = connectingChannel->isInnerRequest;
271 uint32_t requestId = connectingChannel->requestId;
272 DestoryProxyConnectInfo(&GetProxyChannelManager()->proxyChannelRequestInfo);
273 CONN_CHECK_AND_RETURN_LOGW(isInnerRequest, CONN_PROXY, "not inner request, not retry");
274
275 // inner request retry connect after failed
276 CONN_LOGI(CONN_PROXY, "inner reconnect failed, retry reqId=%{public}u", requestId);
277 char *copyAddr = (char *)SoftBusCalloc(BT_MAC_LEN);
278 if (copyAddr == NULL || strcpy_s(copyAddr, BT_MAC_LEN, brMac) != EOK) {
279 CONN_LOGE(CONN_PROXY, "copyAddr failed");
280 SoftBusFree(copyAddr);
281 return;
282 }
283 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_OPEN_PROXY_CHANNEL_RETRY, 0, 0, copyAddr, 0);
284 if (ret != SOFTBUS_OK) {
285 CONN_LOGE(CONN_PROXY, "post msg err");
286 SoftBusFree(copyAddr);
287 }
288 }
289
NotifyOpenProxyChannelResult(struct ProxyConnection * proxyConnection,bool isSuccess,int32_t status)290 static void NotifyOpenProxyChannelResult(struct ProxyConnection *proxyConnection, bool isSuccess, int32_t status)
291 {
292 ProxyConnectInfo *connectingChannel = GetProxyChannelManager()->proxyChannelRequestInfo;
293 uint32_t requestId = connectingChannel->requestId;
294 if (isSuccess) {
295 CONN_LOGI(CONN_PROXY, "notify open success reqId=%{public}u, channelId=%{public}u",
296 requestId, proxyConnection->channelId);
297 SetProxyChannelState(proxyConnection, PROXY_CHANNEL_CONNECTED);
298 proxyConnection->proxyChannel.requestId = requestId;
299 AddReconnectDeviceInfoUnsafe(connectingChannel);
300 connectingChannel->result.onOpenSuccess(requestId, &proxyConnection->proxyChannel);
301 DestoryProxyConnectInfo(&GetProxyChannelManager()->proxyChannelRequestInfo);
302 return;
303 }
304
305 ProcessConnectFailed(connectingChannel, proxyConnection->brMac, status);
306 RemoveProxyChannelByChannelId(proxyConnection->channelId);
307 }
308
BrChannelConnectSuccess(uint32_t channelId)309 static void BrChannelConnectSuccess(uint32_t channelId)
310 {
311 ProxyChannelNotifyContext *ctx = (ProxyChannelNotifyContext *)SoftBusCalloc(sizeof(ProxyChannelNotifyContext));
312 CONN_CHECK_AND_RETURN_LOGE(ctx != NULL, CONN_PROXY, "on connect failed, calloc error context failed");
313 ctx->channelId = channelId;
314 ctx->isSuccess = true;
315 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_OPEN_PROXY_CHANNEL_CONNECT_RESULT, 0, 0, ctx, 0);
316 if (ret < 0) {
317 CONN_LOGE(CONN_PROXY, "send msg failed, error=%{public}d", ret);
318 SoftBusFree(ctx);
319 }
320 }
321
BrChannelConnectFail(uint32_t channelId,int32_t errorCode)322 static void BrChannelConnectFail(uint32_t channelId, int32_t errorCode)
323 {
324 ProxyChannelNotifyContext *ctx = (ProxyChannelNotifyContext *)SoftBusCalloc(sizeof(ProxyChannelNotifyContext));
325 CONN_CHECK_AND_RETURN_LOGE(ctx != NULL, CONN_PROXY, "on connect failed, calloc error context failed");
326 ctx->channelId = channelId;
327 ctx->status = errorCode;
328 ctx->isSuccess = false;
329 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_OPEN_PROXY_CHANNEL_CONNECT_RESULT, 0, 0, ctx, 0);
330 if (ret < 0) {
331 CONN_LOGE(CONN_PROXY, "send msg failed, error=%{public}d", ret);
332 SoftBusFree(ctx);
333 }
334 }
335
ProxyChannelConnectResultHandler(ProxyChannelNotifyContext * ctx)336 static void ProxyChannelConnectResultHandler(ProxyChannelNotifyContext *ctx)
337 {
338 uint32_t channelId = ctx->channelId;
339 struct ProxyConnection *connection = GetProxyChannelByChannelId(channelId);
340 CONN_CHECK_AND_RETURN_LOGE(connection != NULL, CONN_PROXY, "channelId=%{public}u not found", channelId);
341
342 ProxyConnectInfo *connectingChannel = GetProxyChannelManager()->proxyChannelRequestInfo;
343 if (connectingChannel == NULL || StrCmpIgnoreCase(connection->brMac, connectingChannel->brMac) != 0) {
344 CONN_LOGE(CONN_PROXY, "no connecting info channelId=%{public}u", channelId);
345 GetProxyBrConnectionManager()->disconnect(connection);
346 RemoveProxyChannelByChannelId(channelId);
347 connection->dereference(connection);
348 return;
349 }
350 ConnRemoveMsgFromLooper(&g_proxyChannelAsyncHandler, MSG_OPEN_PROXY_CHANNEL_TIMEOUT, channelId, 0, NULL);
351 NotifyOpenProxyChannelResult(connection, ctx->isSuccess, ctx->status);
352 connection->dereference(connection);
353 }
354
GetProxyChannelByAddr(char * addr)355 static struct ProxyConnection *GetProxyChannelByAddr(char *addr)
356 {
357 int32_t ret = SoftBusMutexLock(&GetProxyChannelManager()->proxyConnectionList->lock);
358 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, NULL, CONN_PROXY, "lock proxyConnectionList failed");
359 struct ProxyConnection *it = NULL;
360 LIST_FOR_EACH_ENTRY(it, &GetProxyChannelManager()->proxyConnectionList->list, struct ProxyConnection, node) {
361 if (StrCmpIgnoreCase(addr, it->brMac) == 0) {
362 it->reference(it);
363 SoftBusMutexUnlock(&GetProxyChannelManager()->proxyConnectionList->lock);
364 return it;
365 }
366 }
367 SoftBusMutexUnlock(&GetProxyChannelManager()->proxyConnectionList->lock);
368 return NULL;
369 }
370
GetProxyChannelByChannelId(uint32_t channelId)371 static struct ProxyConnection *GetProxyChannelByChannelId(uint32_t channelId)
372 {
373 int32_t ret = SoftBusMutexLock(&GetProxyChannelManager()->proxyConnectionList->lock);
374 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, NULL, CONN_PROXY, "lock proxyConnectionList failed");
375 struct ProxyConnection *it = NULL;
376 LIST_FOR_EACH_ENTRY(it, &GetProxyChannelManager()->proxyConnectionList->list, struct ProxyConnection, node) {
377 if (it->channelId == channelId) {
378 it->reference(it);
379 SoftBusMutexUnlock(&GetProxyChannelManager()->proxyConnectionList->lock);
380 return it;
381 }
382 }
383 SoftBusMutexUnlock(&GetProxyChannelManager()->proxyConnectionList->lock);
384 return NULL;
385 }
386
RemoveProxyChannelByChannelId(uint32_t channelId)387 static void RemoveProxyChannelByChannelId(uint32_t channelId)
388 {
389 int32_t ret = SoftBusMutexLock(&GetProxyChannelManager()->proxyConnectionList->lock);
390 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_PROXY, "lock proxyConnectionList failed");
391 struct ProxyConnection *it = NULL;
392 struct ProxyConnection *next = NULL;
393 LIST_FOR_EACH_ENTRY_SAFE(it, next, &GetProxyChannelManager()->proxyConnectionList->list,
394 struct ProxyConnection, node) {
395 if (it->channelId == channelId) {
396 ListDelete(&it->node);
397 CONN_LOGI(CONN_PROXY, "remove channel channelId=%{public}u", it->channelId);
398 it->dereference(it);
399 break;
400 }
401 }
402 SoftBusMutexUnlock(&GetProxyChannelManager()->proxyConnectionList->lock);
403 }
404
IsNeedReuseOrWait(ProxyConnectInfo * connectInfo)405 static bool IsNeedReuseOrWait(ProxyConnectInfo *connectInfo)
406 {
407 ProxyConnectInfo *connectingProxyChannel = GetProxyChannelManager()->proxyChannelRequestInfo;
408 if (connectingProxyChannel != NULL) {
409 if (StrCmpIgnoreCase(connectInfo->brMac, connectingProxyChannel->brMac) == 0) {
410 CONN_LOGI(CONN_PROXY, "wait connect result reqId=%{public}u, isInnerRequest=%{public}d",
411 connectInfo->requestId, connectInfo->isInnerRequest);
412 // wait connect finished and reuse
413 if (!connectInfo->isInnerRequest) {
414 connectingProxyChannel->result = connectInfo->result;
415 connectingProxyChannel->requestId = connectInfo->requestId;
416 }
417 } else {
418 connectInfo->result.onOpenFail(connectInfo->requestId, SOFTBUS_CONN_PROXY_CUCURRENT_OPRATION_ERR);
419 }
420 return true;
421 }
422
423 // reuse already exist proxy channel
424 struct ProxyConnection *proxyConnection = GetProxyChannelByAddr(connectInfo->brMac);
425 CONN_CHECK_AND_RETURN_RET_LOGE(proxyConnection != NULL, false, CONN_PROXY, "proxyConnection is null");
426 ProxyChannelState state = GetProxyChannelState(proxyConnection);
427 uint32_t channelId = proxyConnection->channelId;
428 CONN_LOGI(CONN_PROXY, "state=%{public}d", state);
429 if (state == PROXY_CHANNEL_CONNECTED) {
430 CONN_LOGI(CONN_PROXY, "reuse already exist proxy channel channelId=%{public}u, reqId=%{public}u",
431 channelId, connectInfo->requestId);
432 proxyConnection->proxyChannel.requestId = connectInfo->requestId;
433 connectInfo->result.onOpenSuccess(connectInfo->requestId, &proxyConnection->proxyChannel);
434 proxyConnection->dereference(proxyConnection);
435 return true;
436 }
437 proxyConnection->dereference(proxyConnection);
438 // retry after the previous connection ends
439 if (state == PROXY_CHANNEL_CONNECTING) {
440 CONN_LOGI(CONN_PROXY, "reqId=%{public}u, wait channelId=%{public}u stopped",
441 connectInfo->requestId, channelId);
442 ProxyConnectInfo *copyConnectInfo = CopyProxyConnectInfo(connectInfo);
443 CONN_CHECK_AND_RETURN_RET_LOGE(copyConnectInfo != NULL, false, CONN_PROXY, "copyProxyChannel err");
444 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_OPEN_PROXY_CHANNEL, 0, 0,
445 copyConnectInfo, OPEN_PROXY_CHANNEL_WAIT_MS);
446 if (ret < 0) {
447 CONN_LOGE(CONN_PROXY, "send msg failed, error=%{public}d", ret);
448 DestoryProxyConnectInfo(©ConnectInfo);
449 return false;
450 }
451 return true;
452 }
453 return false;
454 }
455
OpenProxyChannelTimeout(uint32_t channelId)456 static void OpenProxyChannelTimeout(uint32_t channelId)
457 {
458 CONN_LOGE(CONN_PROXY, "connect timeout, channelId=%{public}u", channelId);
459 struct ProxyConnection *connection = GetProxyChannelByChannelId(channelId);
460 CONN_CHECK_AND_RETURN_LOGE(connection != NULL, CONN_PROXY, "channelId=%{public}u not found", channelId);
461 ProxyConnectInfo *connectingChannel = GetProxyChannelManager()->proxyChannelRequestInfo;
462 if (connectingChannel == NULL ||
463 StrCmpIgnoreCase(connection->brMac, connectingChannel->brMac) != 0) {
464 CONN_LOGE(CONN_PROXY, "connectingChannel is null, or unexpected device");
465 connection->dereference(connection);
466 return;
467 }
468 ProcessConnectFailed(connectingChannel, connection->brMac, SOFTBUS_CONN_OPEN_PROXY_TIMEOUT);
469 connection->dereference(connection);
470 }
471
CopyProxyConnectInfo(ProxyConnectInfo * srcInfo)472 static ProxyConnectInfo *CopyProxyConnectInfo(ProxyConnectInfo *srcInfo)
473 {
474 ProxyConnectInfo *destInfo = (ProxyConnectInfo *)SoftBusCalloc(sizeof(ProxyConnectInfo));
475 CONN_CHECK_AND_RETURN_RET_LOGE(destInfo != NULL, NULL, CONN_PROXY, "data is NULL");
476 (void)memcpy_s(destInfo, sizeof(ProxyConnectInfo), srcInfo, sizeof(ProxyConnectInfo));
477 ListInit(&destInfo->node);
478 return destInfo;
479 }
480
AddReconnectDeviceInfoUnsafe(ProxyConnectInfo * connectInfo)481 static void AddReconnectDeviceInfoUnsafe(ProxyConnectInfo *connectInfo)
482 {
483 ProxyConnectInfo *target = GetReconnectDeviceInfoByAddrUnsafe(connectInfo->brMac);
484 if (target != NULL) {
485 target->requestId = connectInfo->requestId;
486 target->innerRetryNum = 0;
487 }
488 char anomizeAddress[BT_MAC_LEN] = { 0 };
489 ConvertAnonymizeMacAddress(anomizeAddress, BT_MAC_LEN, connectInfo->brMac, BT_MAC_LEN);
490 CONN_CHECK_AND_RETURN_LOGI(target == NULL, CONN_PROXY, "aleady exist, addr=%{public}s", anomizeAddress);
491
492 ProxyConnectInfo *info = CopyProxyConnectInfo(connectInfo);
493 CONN_CHECK_AND_RETURN_LOGE(info != NULL, CONN_PROXY, "CopyProxyConnectInfo failed");
494 info->isAclConnected = true;
495 info->innerRetryNum = 0;
496 ListAdd(&GetProxyChannelManager()->reconnectDeviceInfos, &info->node);
497 }
498
GetReconnectDeviceInfoByAddrUnsafe(const char * addr)499 static ProxyConnectInfo *GetReconnectDeviceInfoByAddrUnsafe(const char *addr)
500 {
501 ProxyConnectInfo *it = NULL;
502 ProxyConnectInfo *target = NULL;
503 LIST_FOR_EACH_ENTRY(it, &GetProxyChannelManager()->reconnectDeviceInfos, ProxyConnectInfo, node) {
504 if (StrCmpIgnoreCase(addr, it->brMac) == 0) {
505 target = it;
506 break;
507 }
508 }
509 return target;
510 }
511
RemoveReconnectDeviceInfoByAddrUnsafe(const char * addr)512 static void RemoveReconnectDeviceInfoByAddrUnsafe(const char *addr)
513 {
514 ProxyConnectInfo *it = NULL;
515 ProxyConnectInfo *next = NULL;
516 LIST_FOR_EACH_ENTRY_SAFE(it, next, &GetProxyChannelManager()->reconnectDeviceInfos, ProxyConnectInfo, node) {
517 if (StrCmpIgnoreCase(addr, it->brMac) == 0 || StrCmpIgnoreCase(addr, it->brHashMac) == 0) {
518 char anomizeAddress[BT_MAC_LEN] = { 0 };
519 ConvertAnonymizeMacAddress(anomizeAddress, BT_MAC_LEN, it->brMac, BT_MAC_LEN);
520 CONN_LOGW(CONN_PROXY, "remove reconnect device addr=%{public}s", anomizeAddress);
521 ListDelete(&it->node);
522 DestoryProxyConnectInfo(&it);
523 return;
524 }
525 }
526 }
527
OpenProxyChannelHandler(ProxyConnectInfo * connectInfo)528 static void OpenProxyChannelHandler(ProxyConnectInfo *connectInfo)
529 {
530 if (IsNeedReuseOrWait(connectInfo)) {
531 return;
532 }
533
534 GetProxyChannelManager()->proxyChannelRequestInfo = CopyProxyConnectInfo(connectInfo);
535 CONN_CHECK_AND_RETURN_LOGE(GetProxyChannelManager()->proxyChannelRequestInfo != NULL,
536 CONN_PROXY, "CopyProxyConnectInfo err");
537
538 struct ProxyConnection *connection = CreateProxyConnection(connectInfo);
539 if (connection == NULL) {
540 DestoryProxyConnectInfo(&GetProxyChannelManager()->proxyChannelRequestInfo);
541 connectInfo->result.onOpenFail(connectInfo->requestId, SOFTBUS_MALLOC_ERR);
542 return;
543 }
544 if (SaveProxyConnection(connection) != SOFTBUS_OK) {
545 connection->dereference(connection);
546 DestoryProxyConnectInfo(&GetProxyChannelManager()->proxyChannelRequestInfo);
547 connectInfo->result.onOpenFail(connectInfo->requestId, SOFTBUS_MALLOC_ERR);
548 return;
549 }
550
551 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_OPEN_PROXY_CHANNEL_TIMEOUT,
552 connection->channelId, 0, NULL, connectInfo->timeoutMs);
553 if (ret < 0) {
554 CONN_LOGE(CONN_PROXY, "send msg failed, error=%{public}d", ret);
555 DestoryProxyConnectInfo(&GetProxyChannelManager()->proxyChannelRequestInfo);
556 RemoveProxyChannelByChannelId(connection->channelId);
557 connection->dereference(connection);
558 connectInfo->result.onOpenFail(connectInfo->requestId, ret);
559 return;
560 }
561 CONN_LOGI(CONN_PROXY, "start connect br reqId=%{public}u, channelId=%{public}u", connectInfo->requestId,
562 connection->channelId);
563 ProxyBrConnectStateCallback callback = {
564 .onConnectSuccess = BrChannelConnectSuccess,
565 .onConnectFail = BrChannelConnectFail,
566 };
567 (void)GetProxyBrConnectionManager()->connect(connection, &callback);
568 connection->dereference(connection);
569 }
570
CreateProxyConnectInfo(ProxyChannelParam * param,const OpenProxyChannelCallback * callback,ProxyConnectInfo ** connectInfo,bool isRealMac)571 static int32_t CreateProxyConnectInfo(ProxyChannelParam *param, const OpenProxyChannelCallback *callback,
572 ProxyConnectInfo **connectInfo, bool isRealMac)
573 {
574 ProxyConnectInfo *ctx = (ProxyConnectInfo *)SoftBusCalloc(sizeof(ProxyConnectInfo));
575 CONN_CHECK_AND_RETURN_RET_LOGE(ctx != NULL, SOFTBUS_MALLOC_ERR, CONN_PROXY, "ctx is NULL");
576 ctx->requestId = param->requestId;
577 ctx->result = *callback;
578 ctx->timeoutMs = param->timeoutMs;
579 // the default acl is exist
580 ctx->isAclConnected = true;
581 ctx->isInnerRequest = false;
582 ctx->isRealMac = isRealMac;
583
584 char anomizeAddress[BT_MAC_MAX_LEN] = { 0 };
585 char anomizeUuid[UUID_STRING_LEN] = { 0 };
586 ConvertAnonymizeSensitiveString(anomizeAddress, BT_MAC_MAX_LEN, param->brMac);
587 ConvertAnonymizeSensitiveString(anomizeUuid, UUID_STRING_LEN, param->uuid);
588
589 int32_t ret = isRealMac ? strcpy_s(ctx->brMac, sizeof(ctx->brMac), param->brMac)
590 : strcpy_s(ctx->brHashMac, sizeof(ctx->brHashMac), param->brMac);
591 if (ret != EOK) {
592 CONN_LOGE(CONN_PROXY,
593 "reqId=%{public}u, addr=%{public}s, uuid=%{public}s", param->requestId, anomizeAddress, anomizeUuid);
594 DestoryProxyConnectInfo(&ctx);
595 return SOFTBUS_STRCPY_ERR;
596 }
597 if (!isRealMac && GetRealMac(ctx->brMac, BT_MAC_LEN, param->brMac) != SOFTBUS_OK) {
598 CONN_LOGE(CONN_PROXY, "reqId=%{public}u, addr=%{public}s, uuid=%{public}s",
599 param->requestId, anomizeAddress, anomizeUuid);
600 DestoryProxyConnectInfo(&ctx);
601 return SOFTBUS_CONN_PROXY_INTERNAL_ERR;
602 }
603
604 if (strcpy_s(ctx->uuid, UUID_STRING_LEN, param->uuid) != EOK) {
605 CONN_LOGE(CONN_PROXY,
606 "reqId=%{public}u, addr=%{public}s, uuid=%{public}s", param->requestId, anomizeAddress, anomizeUuid);
607 DestoryProxyConnectInfo(&ctx);
608 return SOFTBUS_STRCPY_ERR;
609 }
610 ListInit(&ctx->node);
611 *connectInfo = ctx;
612 return SOFTBUS_OK;
613 }
614
DestoryProxyConnectInfo(ProxyConnectInfo ** connectInfo)615 static void DestoryProxyConnectInfo(ProxyConnectInfo **connectInfo)
616 {
617 SoftBusFree(*connectInfo);
618 *connectInfo = NULL;
619 }
620
IsRealMac(const char * brMac)621 static bool IsRealMac(const char *brMac)
622 {
623 if (strlen(brMac) != BT_MAC_LEN - 1) {
624 CONN_LOGW(CONN_PROXY, "brMac length is not match, len=%{public}zu", strlen(brMac));
625 return false;
626 }
627 int32_t macConLonPos = 3;
628 for (int32_t i = 0; i < BT_MAC_LEN - 1; i++) {
629 if ((i + 1) % macConLonPos == 0) {
630 if (brMac[i] != ':') {
631 CONN_LOGE(CONN_PROXY, "brMac format error");
632 return false;
633 }
634 } else if (!(brMac[i] >= '0' && brMac[i] <= '9') &&
635 !(brMac[i] >= 'a' && brMac[i] <= 'f') &&
636 !(brMac[i] >= 'A' && brMac[i] <= 'F')) {
637 CONN_LOGE(CONN_PROXY, "brMac format error");
638 return false;
639 }
640 }
641 return true;
642 }
643
OpenProxyChannel(ProxyChannelParam * param,const OpenProxyChannelCallback * callback)644 static int32_t OpenProxyChannel(ProxyChannelParam *param, const OpenProxyChannelCallback *callback)
645 {
646 CONN_CHECK_AND_RETURN_RET_LOGE(param != NULL, SOFTBUS_INVALID_PARAM, CONN_PROXY, "param is NULL");
647 CONN_CHECK_AND_RETURN_RET_LOGE(callback != NULL, SOFTBUS_INVALID_PARAM, CONN_PROXY, "callback is NULL");
648 CONN_CHECK_AND_RETURN_RET_LOGE(callback->onOpenSuccess != NULL, SOFTBUS_INVALID_PARAM,
649 CONN_PROXY, "onOpenSuccess is NULL");
650 CONN_CHECK_AND_RETURN_RET_LOGE(callback->onOpenFail != NULL, SOFTBUS_INVALID_PARAM,
651 CONN_PROXY, "onOpenFail is NULL");
652 CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusGetBrState() == BR_ENABLE, SOFTBUS_CONN_BR_DISABLE_ERR,
653 CONN_PROXY, "br disable");
654 bool isRealMac = IsRealMac(param->brMac);
655 bool isPairedDevice = IsPairedDevice(param->brMac, isRealMac);
656 CONN_CHECK_AND_RETURN_RET_LOGE(isPairedDevice, SOFTBUS_CONN_BR_UNPAIRED,
657 CONN_PROXY, "is not paired device");
658 char anomizeAddress[BT_MAC_MAX_LEN] = { 0 };
659 char anomizeUuid[UUID_STRING_LEN] = { 0 };
660 ConvertAnonymizeSensitiveString(anomizeAddress, BT_MAC_MAX_LEN, param->brMac);
661 ConvertAnonymizeSensitiveString(anomizeUuid, UUID_STRING_LEN, param->uuid);
662 CONN_LOGI(CONN_PROXY, "reqId=%{public}u, brMac=%{public}s, uuid=%{public}s, timeoutMs=%{public}" PRIu64,
663 param->requestId, anomizeAddress, anomizeUuid, param->timeoutMs);
664
665 ProxyConnectInfo *connectInfo = NULL;
666 int32_t ret = CreateProxyConnectInfo(param, callback, &connectInfo, isRealMac);
667 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, CONN_PROXY,
668 "createProxyConnectInfo failed, ret=%{public}d", ret);
669 ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_OPEN_PROXY_CHANNEL, 0, 0, connectInfo, 0);
670 if (ret < 0) {
671 CONN_LOGE(CONN_PROXY, "send msg failed, error=%{public}d", ret);
672 DestoryProxyConnectInfo(&connectInfo);
673 return ret;
674 }
675 return SOFTBUS_OK;
676 }
677
OnProxyChannelDataReceived(uint32_t channelId,uint8_t * data,uint32_t dataLen)678 static void OnProxyChannelDataReceived(uint32_t channelId, uint8_t *data, uint32_t dataLen)
679 {
680 struct ProxyConnection *proxyConnection = GetProxyChannelByChannelId(channelId);
681 CONN_CHECK_AND_RETURN_LOGE(proxyConnection != NULL, CONN_PROXY,
682 "get proxyConnection failed, channelId=%{public}u", channelId);
683 CONN_LOGI(CONN_PROXY, "channelId=%{public}u, dataLen=%{public}u", channelId, dataLen);
684 if (g_listener.onProxyChannelDataReceived != NULL) {
685 g_listener.onProxyChannelDataReceived(&proxyConnection->proxyChannel, data, dataLen);
686 }
687 proxyConnection->dereference(proxyConnection);
688 }
689
NotifyDisconnected(struct ProxyChannel * proxyChannel,int32_t reason)690 static void NotifyDisconnected(struct ProxyChannel *proxyChannel, int32_t reason)
691 {
692 CONN_CHECK_AND_RETURN_LOGE(g_listener.onProxyChannelDisconnected != NULL, CONN_PROXY,
693 "disconnected listener is null");
694 g_listener.onProxyChannelDisconnected(proxyChannel, reason);
695 }
696
ProxyChannelDisconnectHandler(ProxyChannelNotifyContext * ctx)697 static void ProxyChannelDisconnectHandler(ProxyChannelNotifyContext *ctx)
698 {
699 uint32_t channelId = ctx->channelId;
700 int32_t reason = ctx->status;
701 struct ProxyConnection *proxyConnection = GetProxyChannelByChannelId(channelId);
702 CONN_CHECK_AND_RETURN_LOGE(proxyConnection != NULL, CONN_PROXY,
703 "get proxyConnection failed, channelId=%{public}u", channelId);
704 CONN_LOGE(CONN_PROXY, "channelId=%{public}u, disconnected err=%{public}d", channelId, reason);
705
706 SetProxyChannelState(proxyConnection, PROXY_CHANNEL_DISCONNECTED);
707 NotifyDisconnected(&proxyConnection->proxyChannel, reason);
708 RemoveProxyChannelByChannelId(channelId);
709 char *copyAddr = (char *)SoftBusCalloc(BT_MAC_LEN);
710 if (copyAddr == NULL || strcpy_s(copyAddr, BT_MAC_LEN, proxyConnection->brMac) != EOK) {
711 CONN_LOGE(CONN_PROXY, "copyAddr failed");
712 SoftBusFree(copyAddr);
713 proxyConnection->dereference(proxyConnection);
714 return;
715 }
716 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_OPEN_PROXY_CHANNEL_RETRY,
717 0, 0, copyAddr, RECONNECT_AFTER_DISCONNECT_WAIT_MS);
718 if (ret != SOFTBUS_OK) {
719 CONN_LOGE(CONN_PROXY, "post msg err");
720 SoftBusFree(copyAddr);
721 }
722 proxyConnection->dereference(proxyConnection);
723 }
724
OnProxyChannelDisconnected(uint32_t channelId,int32_t reason)725 static void OnProxyChannelDisconnected(uint32_t channelId, int32_t reason)
726 {
727 ProxyChannelNotifyContext *ctx = (ProxyChannelNotifyContext *)SoftBusCalloc(sizeof(ProxyChannelNotifyContext));
728 CONN_CHECK_AND_RETURN_LOGE(ctx != NULL, CONN_PROXY, "on connect failed, calloc error context failed");
729 ctx->channelId = channelId;
730 ctx->status = reason;
731 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_CLOSE_PROXY_DISCONNECT, 0, 0, ctx, 0);
732 if (ret < 0) {
733 CONN_LOGE(CONN_PROXY, "send msg failed, error=%{public}d", ret);
734 SoftBusFree(ctx);
735 }
736 }
737
RegisterProxyChannelListener(ProxyConnectListener * listener)738 static int32_t RegisterProxyChannelListener(ProxyConnectListener *listener)
739 {
740 CONN_CHECK_AND_RETURN_RET_LOGE(listener != NULL, SOFTBUS_INVALID_PARAM, CONN_PROXY, "listener is NULL");
741 CONN_CHECK_AND_RETURN_RET_LOGE(listener->onProxyChannelDisconnected != NULL, SOFTBUS_INVALID_PARAM,
742 CONN_PROXY, "Disconnected is NULL");
743 CONN_CHECK_AND_RETURN_RET_LOGE(listener->onProxyChannelDataReceived != NULL, SOFTBUS_INVALID_PARAM,
744 CONN_PROXY, "DataReceived is NULL");
745 CONN_CHECK_AND_RETURN_RET_LOGE(listener->onProxyChannelReconnected != NULL, SOFTBUS_INVALID_PARAM,
746 CONN_PROXY, "Reconnected is NULL");
747 g_listener = *listener;
748 return SOFTBUS_OK;
749 }
750
OnInnerReConnectSuccess(uint32_t requestId,struct ProxyChannel * channel)751 static void OnInnerReConnectSuccess(uint32_t requestId, struct ProxyChannel *channel)
752 {
753 CONN_CHECK_AND_RETURN_LOGE(g_listener.onProxyChannelReconnected != NULL, CONN_PROXY, "Reconnected is NULL");
754 // notify upper reconnect success
755 g_listener.onProxyChannelReconnected(channel->brMac, channel);
756 }
757
OnInnerReConnectFail(uint32_t requestId,int32_t reason)758 static void OnInnerReConnectFail(uint32_t requestId, int32_t reason)
759 {
760 CONN_LOGE(CONN_PROXY, "requestId=%{public}u, reason=%{public}d", requestId, reason);
761 }
762
IsTargetDeviceAlreadyConnected(char * brAddr)763 static bool IsTargetDeviceAlreadyConnected(char *brAddr)
764 {
765 struct ProxyConnection *proxyConnection = GetProxyChannelByAddr(brAddr);
766 CONN_CHECK_AND_RETURN_RET_LOGI(proxyConnection != NULL, false,
767 CONN_PROXY, "not exit same proxyConnection");
768 bool isValidProxyConnection = GetProxyChannelState(proxyConnection) == PROXY_CHANNEL_CONNECTED;
769 proxyConnection->dereference(proxyConnection);
770 return isValidProxyConnection;
771 }
772
CheckNeedToRetry(char * brAddr,ProxyConnectInfo * reconnectDeviceInfo)773 static bool CheckNeedToRetry(char *brAddr, ProxyConnectInfo *reconnectDeviceInfo)
774 {
775 bool isAclConnected = reconnectDeviceInfo->isAclConnected;
776 CONN_CHECK_AND_RETURN_RET_LOGW(isAclConnected, false, CONN_PROXY, "acl is disconnect not retry");
777
778 bool isAlreadyConnected = IsTargetDeviceAlreadyConnected(brAddr);
779 CONN_CHECK_AND_RETURN_RET_LOGW(!isAlreadyConnected, false, CONN_PROXY, "exist already connection");
780
781 bool isPairedDevice = IsPairedDevice(brAddr, true);
782 CONN_CHECK_AND_RETURN_RET_LOGE(isPairedDevice, false, CONN_PROXY, "is not paired device");
783 return true;
784 }
785
AttemptReconnectDevice(char * brAddr)786 static void AttemptReconnectDevice(char *brAddr)
787 {
788 char anomizeAddress[BT_MAC_LEN] = { 0 };
789 ConvertAnonymizeMacAddress(anomizeAddress, BT_MAC_LEN, brAddr, BT_MAC_LEN);
790 ProxyConnectInfo *reconnectDeviceInfo = GetReconnectDeviceInfoByAddrUnsafe(brAddr);
791 CONN_CHECK_AND_RETURN_LOGW(reconnectDeviceInfo != NULL, CONN_PROXY,
792 "not exit same addr=%{public}s need to reconnect", anomizeAddress);
793 bool checkNeedToRetry = CheckNeedToRetry(brAddr, reconnectDeviceInfo);
794 CONN_CHECK_AND_RETURN_LOGW(checkNeedToRetry, CONN_PROXY, "not retry");
795 uint32_t innerRetryNum = reconnectDeviceInfo->innerRetryNum;
796 if (innerRetryNum > RETRY_CONNECT_MAX_NUM) {
797 reconnectDeviceInfo->innerRetryNum = 0;
798 CONN_LOGE(CONN_PROXY, "retryNum=%{public}u, is max, retry failed", innerRetryNum);
799 struct ProxyChannel proxyChannel = { 0 };
800 int32_t ret = reconnectDeviceInfo->isRealMac ?
801 strcpy_s(proxyChannel.brMac, BT_MAC_MAX_LEN, reconnectDeviceInfo->brMac) :
802 strcpy_s(proxyChannel.brMac, BT_MAC_MAX_LEN, reconnectDeviceInfo->brHashMac);
803 CONN_CHECK_AND_RETURN_LOGE(ret == EOK, CONN_PROXY, "cpy mac err");
804 ret = strcpy_s(proxyChannel.uuid, UUID_STRING_LEN, reconnectDeviceInfo->uuid);
805 CONN_CHECK_AND_RETURN_LOGE(ret == EOK, CONN_PROXY, "cpy uuid err");
806 NotifyDisconnected(&proxyChannel, SOFTBUS_CONN_PROXY_RETRY_FAILED);
807 return;
808 }
809
810 ProxyConnectInfo *proxyChannelRequestInfo = CopyProxyConnectInfo(reconnectDeviceInfo);
811 CONN_CHECK_AND_RETURN_LOGW(proxyChannelRequestInfo != NULL, CONN_PROXY, "CopyProxyConnectInfo failed");
812 uint64_t delayMillis = g_retryIntervalMillis[innerRetryNum];
813 reconnectDeviceInfo->innerRetryNum += 1;
814 proxyChannelRequestInfo->result.onOpenSuccess = OnInnerReConnectSuccess;
815 proxyChannelRequestInfo->result.onOpenFail = OnInnerReConnectFail;
816 proxyChannelRequestInfo->isInnerRequest = true;
817 proxyChannelRequestInfo->timeoutMs = INNER_RECONNECT_TIMEOUT_MS;
818 CONN_LOGI(CONN_PROXY, "start reconnect requestId=%{public}u, addr=%{public}s, innerRetryNum=%{public}u",
819 proxyChannelRequestInfo->requestId, anomizeAddress, innerRetryNum);
820 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_OPEN_PROXY_CHANNEL,
821 0, 0, proxyChannelRequestInfo, delayMillis);
822 if (ret < 0) {
823 CONN_LOGE(CONN_PROXY, "post msg failed=%{public}d", ret);
824 DestoryProxyConnectInfo(&proxyChannelRequestInfo);
825 }
826 }
827
AclStateChangedHandler(ProxyChannelAclStateContext * context)828 static void AclStateChangedHandler(ProxyChannelAclStateContext *context)
829 {
830 ProxyConnectInfo *reconnectDeviceInfo = GetReconnectDeviceInfoByAddrUnsafe(context->brMac);
831 CONN_CHECK_AND_RETURN_LOGW(reconnectDeviceInfo != NULL, CONN_PROXY, "no reconnect device");
832 reconnectDeviceInfo->isAclConnected = (context->state == SOFTBUS_ACL_STATE_CONNECTED) ? true : false;
833 }
834
ProxyResetHandler(void)835 static void ProxyResetHandler(void)
836 {
837 ProxyConnectInfo *connectingChannel = GetProxyChannelManager()->proxyChannelRequestInfo;
838 if (connectingChannel != NULL) {
839 connectingChannel->result.onOpenFail(connectingChannel->requestId, SOFTBUS_CONN_BLUETOOTH_OFF);
840 DestoryProxyConnectInfo(&GetProxyChannelManager()->proxyChannelRequestInfo);
841 }
842 ListNode notifyConnectionList;
843 ListInit(¬ifyConnectionList);
844 int32_t ret = SoftBusMutexLock(&GetProxyChannelManager()->proxyConnectionList->lock);
845 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_PROXY, "lock proxyConnectionList failed");
846 struct ProxyConnection *item = NULL;
847 struct ProxyConnection *next = NULL;
848 LIST_FOR_EACH_ENTRY_SAFE(item, next, &GetProxyChannelManager()->proxyConnectionList->list,
849 struct ProxyConnection, node) {
850 ListDelete(&item->node);
851 ListAdd(¬ifyConnectionList, &item->node);
852 }
853 SoftBusMutexUnlock(&GetProxyChannelManager()->proxyConnectionList->lock);
854
855 item = NULL;
856 next = NULL;
857 LIST_FOR_EACH_ENTRY_SAFE(item, next, ¬ifyConnectionList, struct ProxyConnection, node) {
858 ListDelete(&item->node);
859 if (GetProxyChannelState(item) != PROXY_CHANNEL_CONNECTING) {
860 SetProxyChannelState(item, PROXY_CHANNEL_DISCONNECTED);
861 CONN_LOGW(CONN_PROXY, "bluetooth off, notify disconnected, channelId=%{public}u", item->channelId);
862 NotifyDisconnected(&item->proxyChannel, SOFTBUS_CONN_BLUETOOTH_OFF);
863 }
864 item->dereference(item);
865 }
866 }
867
ProxyDeviceUnpaired(const char * brAddr)868 static void ProxyDeviceUnpaired(const char *brAddr)
869 {
870 char anomizeAddress[BT_MAC_LEN] = { 0 };
871 ConvertAnonymizeMacAddress(anomizeAddress, BT_MAC_LEN, brAddr, BT_MAC_LEN);
872 CONN_LOGW(CONN_PROXY, "addr=%{public}s, unpaired", anomizeAddress);
873
874 ProxyConnectInfo *connectingChannel = GetProxyChannelManager()->proxyChannelRequestInfo;
875 if (connectingChannel != NULL && StrCmpIgnoreCase(brAddr, connectingChannel->brMac) == 0) {
876 connectingChannel->result.onOpenFail(connectingChannel->requestId, SOFTBUS_CONN_BR_UNPAIRED);
877 DestoryProxyConnectInfo(&GetProxyChannelManager()->proxyChannelRequestInfo);
878 }
879
880 ProxyConnectInfo *target = GetReconnectDeviceInfoByAddrUnsafe(brAddr);
881 CONN_CHECK_AND_RETURN_LOGE(target != NULL, CONN_PROXY, "ignore addr=%{public}s", anomizeAddress);
882 RemoveReconnectDeviceInfoByAddrUnsafe(brAddr);
883 struct ProxyChannel proxyChannel = { 0 };
884 int32_t ret = target->isRealMac ? strcpy_s(proxyChannel.brMac, BT_MAC_MAX_LEN, target->brMac) :
885 strcpy_s(proxyChannel.brMac, BT_MAC_MAX_LEN, target->brHashMac);
886 CONN_CHECK_AND_RETURN_LOGE(ret == EOK, CONN_PROXY, "cpy mac err");
887 ret = strcpy_s(proxyChannel.uuid, UUID_STRING_LEN, target->uuid);
888 CONN_CHECK_AND_RETURN_LOGE(ret == EOK, CONN_PROXY, "cpy uuid err");
889 NotifyDisconnected(&proxyChannel, SOFTBUS_CONN_BR_UNPAIRED);
890 }
891
OnProxyAclStateChanged(int32_t listenerId,const SoftBusBtAddr * btAddr,int32_t aclState,int32_t hciReason)892 static void OnProxyAclStateChanged(
893 int32_t listenerId, const SoftBusBtAddr *btAddr, int32_t aclState, int32_t hciReason)
894 {
895 CONN_CHECK_AND_RETURN_LOGW((aclState == SOFTBUS_ACL_STATE_CONNECTED || aclState == SOFTBUS_ACL_STATE_DISCONNECTED),
896 CONN_PROXY, "ignore state=%{public}d", aclState);
897 CONN_CHECK_AND_RETURN_LOGW(btAddr != NULL, CONN_PROXY, "addr is null");
898 char address[BT_MAC_LEN] = { 0 };
899 int32_t status = ConvertBtMacToStr(address, BT_MAC_LEN, btAddr->addr, BT_ADDR_LEN);
900 CONN_CHECK_AND_RETURN_LOGE(status == SOFTBUS_OK, CONN_PROXY, "convert binary mac address to string failed");
901 char anomizeAddress[BT_MAC_LEN] = { 0 };
902 ConvertAnonymizeMacAddress(anomizeAddress, BT_MAC_LEN, address, BT_MAC_LEN);
903 CONN_LOGW(CONN_PROXY, "state=%{public}d, addr=%{public}s", aclState, anomizeAddress);
904 ProxyChannelAclStateContext *context =
905 (ProxyChannelAclStateContext *)SoftBusCalloc(sizeof(ProxyChannelAclStateContext));
906 if (context == NULL || strcpy_s(context->brMac, BT_MAC_LEN, address) != EOK) {
907 CONN_LOGE(CONN_PROXY, "copyAddr failed");
908 SoftBusFree(context);
909 return;
910 }
911 context->state = aclState;
912 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_ACL_STATE_CHANGE, 0, 0, context, 0);
913 if (ret < 0) {
914 CONN_LOGE(CONN_PROXY, "post msg failed=%{public}d", ret);
915 SoftBusFree(context);
916 }
917 }
918
OnObserverStateChanged(const char * addr,int32_t state)919 static void OnObserverStateChanged(const char *addr, int32_t state)
920 {
921 CONN_CHECK_AND_RETURN_LOGW((state == SOFTBUS_HFP_CONNECTED || state == SOFTBUS_DEVICE_UNPAIRED),
922 CONN_PROXY, "ignore state=%{public}d", state);
923 CONN_LOGI(CONN_PROXY, "state=%{public}d", state);
924 CONN_CHECK_AND_RETURN_LOGW(addr != NULL, CONN_PROXY, "addr is NULL");
925 char *copyAddr = (char *)SoftBusCalloc(BT_MAC_LEN);
926 if (copyAddr == NULL || strncpy_s(copyAddr, BT_MAC_LEN, addr, BT_MAC_LEN - 1) != EOK) {
927 CONN_LOGE(CONN_PROXY, "copyAddr failed");
928 SoftBusFree(copyAddr);
929 return;
930 }
931
932 enum BrProxyLooperMsgType msgType = state == SOFTBUS_HFP_CONNECTED ?
933 MSG_OPEN_PROXY_CHANNEL_RETRY : MSG_PROXY_UNPAIRED;
934 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, msgType, 0, 0, copyAddr, 0);
935 if (ret != SOFTBUS_OK) {
936 CONN_LOGE(CONN_PROXY, "post msg failed=%{public}d", ret);
937 SoftBusFree(copyAddr);
938 return;
939 }
940 }
941
OnProxyBtStateChanged(int listenerId,int state)942 static void OnProxyBtStateChanged(int listenerId, int state)
943 {
944 (void)listenerId;
945 CONN_CHECK_AND_RETURN_LOGW(state == SOFTBUS_BR_STATE_TURN_OFF, CONN_PROXY, "ignore state=%{public}d", state);
946 int32_t ret = ConnPostMsgToLooper(&g_proxyChannelAsyncHandler, MSG_PROXY_RESET, 0, 0, 0, 0);
947 CONN_LOGI(CONN_PROXY, "post msg status=%{public}d", ret);
948 }
949
ProxyChannelMsgHandler(SoftBusMessage * msg)950 static void ProxyChannelMsgHandler(SoftBusMessage *msg)
951 {
952 CONN_CHECK_AND_RETURN_LOGW(msg != NULL, CONN_PROXY, "msg is NULL");
953 switch (msg->what) {
954 case MSG_OPEN_PROXY_CHANNEL:
955 CONN_CHECK_AND_RETURN_LOGW(msg->obj != NULL, CONN_PROXY, "msg->obj is NULL");
956 OpenProxyChannelHandler((ProxyConnectInfo *)msg->obj);
957 break;
958 case MSG_OPEN_PROXY_CHANNEL_TIMEOUT:
959 OpenProxyChannelTimeout(msg->arg1);
960 break;
961 case MSG_OPEN_PROXY_CHANNEL_RETRY:
962 CONN_CHECK_AND_RETURN_LOGW(msg->obj != NULL, CONN_PROXY, "msg->obj is NULL");
963 AttemptReconnectDevice((char*)msg->obj);
964 break;
965 case MSG_OPEN_PROXY_CHANNEL_CONNECT_RESULT:
966 CONN_CHECK_AND_RETURN_LOGW(msg->obj != NULL, CONN_PROXY, "msg->obj is NULL");
967 ProxyChannelConnectResultHandler((ProxyChannelNotifyContext *)msg->obj);
968 break;
969 case MSG_CLOSE_PROXY_CHANNEL:
970 CONN_CHECK_AND_RETURN_LOGW(msg->obj != NULL, CONN_PROXY, "msg->obj is NULL");
971 ProxyChannelCloseHandler((char *)msg->obj);
972 break;
973 case MSG_CLOSE_PROXY_DISCONNECT:
974 CONN_CHECK_AND_RETURN_LOGW(msg->obj != NULL, CONN_PROXY, "msg->obj is NULL");
975 ProxyChannelDisconnectHandler((ProxyChannelNotifyContext *)msg->obj);
976 break;
977 case MSG_ACL_STATE_CHANGE:
978 CONN_CHECK_AND_RETURN_LOGW(msg->obj != NULL, CONN_PROXY, "msg->obj is NULL");
979 AclStateChangedHandler((ProxyChannelAclStateContext *)msg->obj);
980 break;
981 case MSG_PROXY_RESET:
982 ProxyResetHandler();
983 break;
984 case MSG_PROXY_UNPAIRED:
985 CONN_CHECK_AND_RETURN_LOGW(msg->obj != NULL, CONN_PROXY, "msg->obj is NULL");
986 ProxyDeviceUnpaired((const char*)msg->obj);
987 break;
988 default:
989 CONN_LOGW(CONN_PROXY, "receive unexpected msg, what=%{public}d", msg->what);
990 break;
991 }
992 }
993
ProxyChannelLooperEventFunc(const SoftBusMessage * msg,void * args)994 static int ProxyChannelLooperEventFunc(const SoftBusMessage *msg, void *args)
995 {
996 SoftBusMessage *ctx = (SoftBusMessage *)args;
997 if (msg->what != ctx->what) {
998 return COMPARE_FAILED;
999 }
1000 switch (ctx->what) {
1001 case MSG_OPEN_PROXY_CHANNEL_TIMEOUT: {
1002 if (msg->arg1 == ctx->arg1) {
1003 return COMPARE_SUCCESS;
1004 }
1005 return COMPARE_FAILED;
1006 }
1007 default:
1008 break;
1009 }
1010 if (ctx->arg1 != 0 || ctx->arg2 != 0 || ctx->obj != NULL) {
1011 CONN_LOGE(CONN_PROXY, "failed to avoid fault silence, "
1012 "what=%{public}d, arg1=%{public}" PRIu64 ", arg2=%{public}" PRIu64 ", objIsNull=%{public}d",
1013 ctx->what, ctx->arg1, ctx->arg2, ctx->obj == NULL);
1014 return COMPARE_FAILED;
1015 }
1016 return COMPARE_SUCCESS;
1017 }
1018
1019 static ProxyChannelManager g_proxyChannelManager = {
1020 .generateRequestId = GenerateRequestId,
1021 .openProxyChannel = OpenProxyChannel,
1022 .registerProxyChannelListener = RegisterProxyChannelListener,
1023
1024 .getConnectionById = GetProxyChannelByChannelId,
1025 .proxyChannelRequestInfo = NULL,
1026 .proxyConnectionList = NULL,
1027 };
1028
GetProxyChannelManager(void)1029 ProxyChannelManager *GetProxyChannelManager(void)
1030 {
1031 return &g_proxyChannelManager;
1032 }
1033
ProxyChannelManagerInit(void)1034 int32_t ProxyChannelManagerInit(void)
1035 {
1036 g_proxyChannelManager.proxyConnectionList = CreateSoftBusList();
1037 CONN_CHECK_AND_RETURN_RET_LOGE(GetProxyChannelManager()->proxyConnectionList != NULL, SOFTBUS_CREATE_LIST_ERR,
1038 CONN_INIT, "create channels list failed");
1039 ListInit(&(GetProxyChannelManager()->reconnectDeviceInfos));
1040
1041 g_proxyChannelAsyncHandler.handler.looper = GetLooper(LOOP_TYPE_CONN);
1042 if (g_proxyChannelAsyncHandler.handler.looper == NULL) {
1043 CONN_LOGE(CONN_PROXY, "init conn ble looper failed");
1044 DestroySoftBusList(g_proxyChannelManager.proxyConnectionList);
1045 return SOFTBUS_LOOPER_ERR;
1046 }
1047 int32_t ret = SoftBusMutexInit(&g_reqIdLock, NULL);
1048 if (ret != SOFTBUS_OK) {
1049 CONN_LOGE(CONN_PROXY, "init lock falied");
1050 DestroySoftBusList(g_proxyChannelManager.proxyConnectionList);
1051 return ret;
1052 }
1053 static SoftBusBtStateListener btStateListener = {
1054 .OnBtAclStateChanged = OnProxyAclStateChanged,
1055 .OnBtStateChanged = OnProxyBtStateChanged,
1056 };
1057 int32_t listenerId = -1;
1058 ret = SoftBusAddBtStateListener(&btStateListener, &listenerId);
1059 if (ret != SOFTBUS_OK) {
1060 CONN_LOGE(CONN_PROXY, "add bt listener failed, listenerId=%{public}d", listenerId);
1061 DestroySoftBusList(g_proxyChannelManager.proxyConnectionList);
1062 return ret;
1063 }
1064 ret = RegisterHfpListener(OnObserverStateChanged);
1065 if (ret != SOFTBUS_OK) {
1066 CONN_LOGE(CONN_PROXY, "register hfp listener failed, ret=%{public}d", ret);
1067 DestroySoftBusList(g_proxyChannelManager.proxyConnectionList);
1068 SoftBusRemoveBtStateListener(listenerId);
1069 return ret;
1070 }
1071 static ProxyEventListener listener = {
1072 .onDataReceived = OnProxyChannelDataReceived,
1073 .onDisconnected = OnProxyChannelDisconnected,
1074 };
1075 ret = GetProxyBrConnectionManager()->registerEventListener(&listener);
1076 CONN_LOGI(CONN_PROXY, "ret=%{public}d", ret);
1077 return ret;
1078 }