• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&copyConnectInfo);
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(&notifyConnectionList);
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(&notifyConnectionList, &item->node);
852     }
853     SoftBusMutexUnlock(&GetProxyChannelManager()->proxyConnectionList->lock);
854 
855     item = NULL;
856     next = NULL;
857     LIST_FOR_EACH_ENTRY_SAFE(item, next, &notifyConnectionList, 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 }