/* * Copyright (C) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file att_connect.c * * @brief implement connect function to be called. * */ #include "att_connect.h" #include <string.h> #include "log.h" #include "platform/include/allocator.h" typedef struct AttDisconnectReqAsync { uint16_t connectHandle; } AttDisconnectReqAsync; typedef struct AttConnectRspAsync { uint16_t connectHandle; uint16_t result; uint16_t status; AttConnect *g_attConnectParaObj; } AttConnectRspAsync; typedef struct AttConnectReqAsync { uint8_t transportType; AttConnect *connParaPtr; BtAddr *btAddress; uint16_t *bredrconnectHandle; } AttConnectReqAsync; typedef struct AttLeConnectedAsyncContext { BtAddr *addr; uint16_t aclHandle; uint8_t role; uint8_t status; } AttLeConnectedAsyncContext; typedef struct AttLeDisconnectedAsyncContext { uint16_t aclHandle; uint8_t status; uint8_t reason; } AttLeDisconnectedAsyncContext; typedef struct DisconnectRespCallbackContext { uint16_t lcid; int result; } DisconnectRespCallbackContext; typedef struct ConnectCallBackContext { BtAddr *addr; int result; } ConnectCallBackContext; typedef struct ConnectReqCallbackContext { BtAddr *addr; uint16_t lcid; int result; } ConnectReqCallbackContext; typedef struct ConfigReqCallbackContext { uint16_t lcid; int result; } ConfigReqCallbackContext; typedef struct ConnectRspResultCallbackContext { uint16_t lcid; int result; } ConnectRspResultCallbackContext; typedef struct BREDRDisconnectReqCallBackContext { uint16_t lcid; int result; void *context; } BREDRDisconnectReqCallBackContext; typedef struct LeDisconnectReqCallBackContext { uint16_t aclHandle; int result; } LeDisconnectReqCallBackContext; typedef struct ConnectRspPendingContext { uint16_t lcid; int result; } ConnectRspPendingContext; typedef struct AttReceiveConnectReqContext { uint16_t lcid; uint8_t id; L2capConnectionInfo *info; uint16_t lpsm; void *ctx; } AttReceiveConnectReqContext; typedef struct AttReceiveConnectionRspContext { uint16_t lcid; L2capConnectionInfo *info; uint16_t result; uint16_t status; void *ctx; } AttReceiveConnectionRspContext; typedef struct AttReceiveConfigRspContext { uint16_t lcid; L2capConfigInfo *info; uint16_t result; void *ctx; } AttReceiveConfigRspContext; typedef struct AttReceiveDisconnectReqContext { uint16_t lcid; uint8_t id; void *ctx; } AttReceiveDisconnectReqContext; typedef struct AttDisconnectAbnormalContext { uint16_t lcid; uint8_t reason; void *ctx; } AttDisconnectAbnormalContext; typedef struct AttRecvDisconnectionRspContext { uint16_t lcid; void *ctx; } AttRecvDisconnectionRspContext; typedef struct ConfigRspCallbackContext { uint16_t lcid; int result; } ConfigRspCallbackContext; typedef struct AttReceiveConfigReqContext { uint16_t lcid; uint8_t id; L2capConfigInfo *cfg; void *ctx; } AttReceiveConfigReqContext; typedef struct ConnectTimeOutContext { uint16_t connectHandle; } ConnectTimeOutContext; typedef struct ConnectCancelContext { BtAddr addr; } ConnectCancelContext; typedef struct GAPSecCallbackContext { uint16_t result; GapServiceSecurityInfo serviceInfo; uint16_t connectHandle; } GAPSecCallbackContext; static void AttRecvConfigReqAssignBredrConnect(const L2capConfigInfo *cfg, AttConnectingInfo *connecting); static void AttClearConnectingInfo(AttConnectingInfo *connecting); static void AttClearConnectInfo(AttConnectInfo *connect); static int AttBredrConnectStatusChange(uint8_t inputStatus, uint8_t *outStatus, uint8_t flag); static void AttCopyToConnectingInfo( const BtAddr *addr, uint16_t aclHandle, uint16_t lcid, uint8_t id, AttConnectingInfo *connecting); static void AttAssignGAPRequestSecurity( GapRequestSecurityParam *gapSecurity, uint8_t direction, const AttConnectingInfo *connecting); static void AttConnectReqAssignBredrConnect(AttConnectingInfo **connecting, const BtAddr *btAddress, const AttConnect *connParaPtr, uint16_t *bredrconnectHandle); static void AttConnectRequestLEParaAssign( L2capLeConnectionParameter *l2capObjptr, const AttConnectReqAsync *attConnectReqAsyncPtr); static void GAPSecCallback(uint16_t result, GapServiceSecurityInfo serviceInfo, const void *context); static int AttBredrConnectProcess(AttConnectingInfo *connecting); static void AttBredrConnectTimeOut(void *parameter); static void AttConnectCompletedCallback(AttConnectingInfo *connecting, uint16_t result); static void AttCopyToConnectInfo(const AttConnectingInfo *connecting, AttConnectInfo **connect); static void AttConnectInfoAddLe( const BtAddr *addr, uint16_t aclHandle, AttConnectInfo **connect, uint8_t initPassConnFlag); static void L2cifConnectReqCallback(const BtAddr *addr, uint16_t lcid, int result, const void *context); static void L2cifConnectRspPendingCallback(uint16_t lcid, int result); static void L2cifConnectRspResultCallback(uint16_t lcid, int result); static void L2cifConfigReqCallback(uint16_t lcid, int result); static void L2cifConfigRspCallback(uint16_t lcid, int result); static int AttLeConnectProcess(const BtAddr *addr, L2capLeConnectionParameter var, const AttConnectingInfo *connecting); static void DisconnectRespCallback(uint16_t lcid, int result); static void AttConnectRequestAsync(const void *context); static void AttConnectRequestAsyncDestroy(const void *context); static void AttConnectRsponseAsync(const void *context); static void AttConnectRsponseAsyncDestroy(const void *context); static void AttDisconnectRequestAsync(const void *context); static void AttDisconnectRequestAsyncDestroy(const void *context); static void AttLeConnectedAsync(const void *context); static void AttLeConnectedAsyncDestroy(const void *context); static void AttLeDisconnectedAsync(const void *context); static void AttLeDisconnectedAsyncDestroy(const void *context); static void DisconnectRespCallbackAsync(const void *context); static void DisconnectRespCallbackAsyncDestroy(const void *context); static void L2cifLeConnectCallBackAsync(const void *context); static void L2cifLeConnectCallBackAsyncDestroy(const void *context); static void L2cifConnectReqCallbackAsync(const void *context); static void L2cifConnectReqCallbackAsyncDestroy(const void *context); static void L2cifConfigReqCallbackAsync(const void *context); static void L2cifConfigReqCallbackAsyncDestroy(const void *context); static void L2cifConnectRspResultCallbackAsync(const void *context); static void L2cifConnectRspResultCallbackAsyncDestroy(const void *context); static void L2cifConnectRspPendingCallbackAsync(const void *context); static void L2cifConnectRspPendingCallbackAsyncDestroy(const void *context); static void AttReceiveConnectionReqAsync(const void *context); static void AttReceiveConnectionReqAsyncDestroy(const void *context); static void AttReceiveConnectionRspAsync(const void *context); static void AttReceiveConnectionRspAsyncDestroy(const void *context); static void AttReceiveConfigRspAsync(const void *context); static void AttReceiveConfigRspAsyncDestroy(const void *context); static void AttReceiveDisconnectionReqAsync(const void *context); static void AttReceiveDisconnectionReqAsyncDestroy(const void *context); static void AttDisconnectAbnormalAsync(const void *context); static void AttDisconnectAbnormalAsyncDestroy(const void *context); static void AttRecvDisconnectionRspAsync(const void *context); static void AttRecvDisconnectionRspAsyncDestroy(const void *context); static void L2cifConfigRspCallbackAsync(const void *context); static void L2cifConfigRspCallbackAsyncDestroy(const void *context); static void AttReceiveConfigReqAsync(const void *context); static void AttReceiveConfigReqAsyncDestroy(const void *context); static void AttBredrConnectTimeOutAsync(const void *context); static void AttBredrConnectTimeOutAsyncDestroy(const void *context); static void GAPSecCallbackAsync(const void *context); static void GAPSecCallbackAsyncDestroy(const void *context); /** * @brief disconnect response call back async. * * @param ctx Indicates the pointer to context. */ static void DisconnectRespCallbackAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); DisconnectRespCallbackContext *disConnectRspPtr = (DisconnectRespCallbackContext *)context; AttBredrDisconnectCallback bredrDisConnObj; int listSize; AttConnectedCallback *attConnectCallback = NULL; AttConnectInfo *connect = NULL; AttGetConnectInfoIndexByCid(disConnectRspPtr->lcid, &connect); if (connect == NULL) { goto DISCONNECTRESPCALLBACK_END; } AlarmCancel(connect->alarm); attConnectCallback = AttGetATTConnectCallback(); if ((attConnectCallback == NULL) || (attConnectCallback->attConnect.attBREDRDisconnectCompleted == NULL)) { LOG_WARN("%{public}s attConnectCallback or attBREDRDisconnectCompleted is NULL", __FUNCTION__); } else { if (disConnectRspPtr->result == BT_SUCCESS) { bredrDisConnObj.reason = PASSIVECONNECT_DISCONNECT_SUCCESS; } else { bredrDisConnObj.reason = PASSIVECONNECT_DISCONNECT_FAIL; } attConnectCallback->attConnect.attBREDRDisconnectCompleted( connect->retGattConnectHandle, &bredrDisConnObj, attConnectCallback->context); } listSize = ListGetSize(connect->instruct); for (; listSize > 0; --listSize) { ListRemoveLast(connect->instruct); } AttClearConnectInfo(connect); DISCONNECTRESPCALLBACK_END: MEM_MALLOC.free(disConnectRspPtr); return; } /** * @brief disconnect response call back async destroy. * * @param ctx Indicates the pointer to context. */ static void DisconnectRespCallbackAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); DisconnectRespCallbackContext *disConnectRspPtr = (DisconnectRespCallbackContext *)context; MEM_MALLOC.free(disConnectRspPtr); return; } /** * @brief disconnect response call back. * * @param1 lcid Indicates the lcid. * @param2 result Indicates the result. */ static void DisconnectRespCallback(uint16_t lcid, int result) { LOG_INFO("%{public}s enter", __FUNCTION__); DisconnectRespCallbackContext *disConnectRspPtr = MEM_MALLOC.alloc(sizeof(DisconnectRespCallbackContext)); if (disConnectRspPtr == NULL) { LOG_ERROR("point to NULL"); return; } disConnectRspPtr->lcid = lcid; disConnectRspPtr->result = result; AttAsyncProcess(DisconnectRespCallbackAsync, DisconnectRespCallbackAsyncDestroy, disConnectRspPtr); return; } /** * @brief att assign bredr connect receive config request parameter. * * @param1 cfg Indicates the pointer to const L2capConfigInfo. * @param2 connecting Indicates the pointer to AttConnectingInfo. */ static void AttRecvConfigReqAssignBredrConnect(const L2capConfigInfo *cfg, AttConnectingInfo *connecting) { LOG_INFO("%{public}s enter", __FUNCTION__); connecting->remotel2capConfigInfoObj.mtu = cfg->mtu; connecting->remotel2capConfigInfoObj.flushTimeout = cfg->flushTimeout; connecting->remotel2capConfigInfoObj.rfc.mode = cfg->rfc.mode; connecting->mtu = Min(connecting->locall2capConfigInfoObj.mtu, connecting->remotel2capConfigInfoObj.mtu); return; } /** * @brief att clear connecting information. * * @param connecting Indicates the pointer to AttConnectingInfo. */ static void AttClearConnectingInfo(AttConnectingInfo *connecting) { LOG_INFO("%{public}s enter", __FUNCTION__); connecting->aclHandle = 0; connecting->cid = 0; connecting->id = 0; connecting->mtu = 0; connecting->connectHandle = 0; connecting->initiativeConnectStatus = 0; connecting->passiveConnectSatatus = 0; connecting->initPassConnFlag = 0; (void)memset_s( &connecting->locall2capConfigInfoObj, sizeof(connecting->locall2capConfigInfoObj), 0, sizeof(L2capConfigInfo)); (void)memset_s(&connecting->remotel2capConfigInfoObj, sizeof(connecting->remotel2capConfigInfoObj), 0, sizeof(L2capConfigInfo)); (void)memset_s(&connecting->addr, sizeof(connecting->addr), 0, sizeof(BtAddr)); if (connecting->transportType == BT_TRANSPORT_BR_EDR) { if (connecting->bredrAlarm != NULL) { AlarmCancel(connecting->bredrAlarm); } } return; } /** * @brief att clear connected information. * * @param connect Indicates the pointer to AttConnectInfo. */ static void AttClearConnectInfo(AttConnectInfo *connect) { LOG_INFO("%{public}s enter", __FUNCTION__); connect->aclHandle = 0; connect->AttConnectID.bredrcid = 0; connect->AttConnectID.lecid = 0; connect->retGattConnectHandle = 0; connect->transportType = 0; connect->mtu = 0; connect->mtuFlag = false; connect->initPassConnFlag = 0; connect->sendMtu = 0; connect->receiveMtu = 0; connect->serverSendFlag = false; (void)memset_s(&connect->addr, sizeof(connect->addr), 0, sizeof(BtAddr)); if (connect->alarm != NULL) { AlarmCancel(connect->alarm); } return; } /** * @brief att bredr connect statuc change. * * @param1 inputStatus Indicates the input parameter. * @param2 outStatus Indicates the pointer to output parameter. * @param3 flag Indicates the flag of connect mode. * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails. */ static int AttBredrConnectStatusChange(uint8_t inputStatus, uint8_t *outStatus, uint8_t flag) { LOG_INFO("%{public}s enter,inputStatus = %hhu,flag=%hhu", __FUNCTION__, inputStatus, flag); int ret = BT_OPERATION_FAILED; if (flag == INITIATIVECONNECT) { if (inputStatus == DISCONNECTED) { ret = BT_OPERATION_FAILED; goto ATTBREDRCONNECTSTATUSCHANGE_END; } if (inputStatus == CONNECTING) { *outStatus = CONFIGED; } else if (inputStatus == CONFIGED) { *outStatus = CONNECTED; } } else if (flag == PASSIVECONNECT) { if (inputStatus == DISCONNECTED) { ret = BT_OPERATION_FAILED; goto ATTBREDRCONNECTSTATUSCHANGE_END; } if (inputStatus == CONNECTIND) { *outStatus = CONFIGED; } else if (inputStatus == CONFIGED) { *outStatus = CONNECTED; } } ret = BT_SUCCESS; ATTBREDRCONNECTSTATUSCHANGE_END: return ret; } /** * @brief att connecting information storage. * * @param1 addr Indicates the pointer to BtAddr. * @param2 aclHandle Indicates the aclHandle. * @param3 lcid Indicates the lcid. * @param4 id Indicates the id. * @param5 connecting Indicates the pointer to AttConnectingInfo. */ static void AttCopyToConnectingInfo( const BtAddr *addr, uint16_t aclHandle, uint16_t lcid, uint8_t id, AttConnectingInfo *connecting) { LOG_INFO("%{public}s enter,aclHandle=%hu,lcid=%hu,id=%hhu", __FUNCTION__, aclHandle, lcid, id); uint16_t index = 0; AttGetConnectingIndexByCidOutIndex(0, &index, &connecting); if (connecting != NULL) { connecting->cid = lcid; (void)memcpy_s(connecting->addr.addr, ADDRESSLEN, addr->addr, ADDRESSLEN); connecting->addr.type = addr->type; connecting->connectHandle = index + 1; connecting->initPassConnFlag = PASSIVECONNECT; connecting->passiveConnectSatatus = DISCONNECTED; connecting->id = id; connecting->aclHandle = aclHandle; connecting->mtu = DEFAULTBREDRMTU; } return; } /** * @brief gap security callback async. * * @param ctx Indicates the pointer to context. */ static void GAPSecCallbackAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); GAPSecCallbackContext *gapSecCallbackPtr = (GAPSecCallbackContext *)context; AttConnectingInfo *connecting = NULL; AttConnectedCallback *attConnectCallback = NULL; AttBredrConnectCallback bredrConnectCallback; AttGetConnectingIndexByConnectHandle(gapSecCallbackPtr->connectHandle, &connecting); attConnectCallback = AttGetATTConnectCallback(); if (gapSecCallbackPtr->result != 0) { LOG_INFO("%{public}s gap security authen callback error", __FUNCTION__); if ((attConnectCallback == NULL) || (attConnectCallback->attConnect.attBREDRConnectCompleted == NULL)) { LOG_WARN("%{public}s attConnectCallback or attBREDRConnectCompleted is NULL", __FUNCTION__); goto GAPSECCALLBACK_END; } bredrConnectCallback.addr.type = connecting->addr.type; (void)memcpy_s(bredrConnectCallback.addr.addr, ADDRESSLEN, connecting->addr.addr, ADDRESSLEN); bredrConnectCallback.status = SECURITY_AUTHENTICATION_FAIL; bredrConnectCallback.mtu = DEFAULTBREDRMTU; attConnectCallback->attConnect.attBREDRConnectCompleted( connecting->connectHandle, &bredrConnectCallback, attConnectCallback->context); AttClearConnectingInfo(connecting); goto GAPSECCALLBACK_END; } if (connecting->initPassConnFlag == INITIATIVECONNECT) { AttBredrConnectProcess(connecting); } else if (connecting->initPassConnFlag == PASSIVECONNECT) { if (connecting->passiveConnectSatatus == DISCONNECTED) { connecting->passiveConnectSatatus = CONNECTIND; } if ((attConnectCallback == NULL) || (attConnectCallback->attConnect.attBREDRConnectInd == NULL)) { LOG_WARN("%{public}s attConnectCallback or attConnectCallback->attConnect.attBREDRConnectInd is NULL", __FUNCTION__); goto GAPSECCALLBACK_END; } attConnectCallback->attConnect.attBREDRConnectInd(connecting->connectHandle, attConnectCallback->context); } GAPSECCALLBACK_END: MEM_MALLOC.free(gapSecCallbackPtr); return; } /** * @brief gap security callback async destroy. * * @param ctx Indicates the pointer to context. */ static void GAPSecCallbackAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); GAPSecCallbackContext *gapSecCallbackPtr = (GAPSecCallbackContext *)context; MEM_MALLOC.free(gapSecCallbackPtr); return; } /** * @brief gap security callback. * * @param1 result Indicates the result. * @param2 serviceInfo Indicates the struct GapServiceSecurityInfo. * @param3 context Indicates the pointer to context. */ static void GAPSecCallback(uint16_t result, GapServiceSecurityInfo serviceInfo, const void *context) { LOG_INFO("%{public}s enter,result = %hu", __FUNCTION__, result); uint16_t connectHandle = *(uint16_t *)context; GAPSecCallbackContext *gapSecCallbackPtr = MEM_MALLOC.alloc(sizeof(GAPSecCallbackContext)); if (gapSecCallbackPtr == NULL) { LOG_ERROR("point to NULL"); return; } gapSecCallbackPtr->result = result; (void)memcpy_s(&(gapSecCallbackPtr->serviceInfo), sizeof(gapSecCallbackPtr->serviceInfo), &serviceInfo, sizeof(GapServiceSecurityInfo)); gapSecCallbackPtr->connectHandle = connectHandle; AttAsyncProcess(GAPSecCallbackAsync, GAPSecCallbackAsyncDestroy, gapSecCallbackPtr); return; } /** * @brief assign gap request security parameter. * * @param1 gapSecurity Indicates the pointer to GapRequestSecurityParam. * @param2 direction Indicates the direction. * @param3 connecting Indicates the pointer to AttConnectingInfo. */ static void AttAssignGAPRequestSecurity( GapRequestSecurityParam *gapSecurity, uint8_t direction, const AttConnectingInfo *connecting) { LOG_INFO("%{public}s enter,direction = %hhu", __FUNCTION__, direction); if (direction == OUTGOING) { gapSecurity->info.direction = OUTGOING; gapSecurity->info.serviceId = GATT_CLIENT; } else if (direction == INCOMING) { gapSecurity->info.direction = INCOMING; gapSecurity->info.serviceId = GATT_SERVER; } gapSecurity->info.protocolId = SEC_PROTOCOL_L2CAP; gapSecurity->info.channelId.l2capPsm = 0x001F; gapSecurity->callback = (void (*)(uint16_t, GapServiceSecurityInfo, void *))GAPSecCallback; gapSecurity->context = &(((AttConnectingInfo *)connecting)->connectHandle); return; } /** * @brief assign bredr connecting request parameter. * * @param1 connecting Indicates the pointer to AttConnectingInfo. * @param2 btAddress Indicates the pointer to const BtAddr. * @param3 connParaPtr Indicates the pointer to const AttConnect. * @param4 bredrconnectHandle Indicates the pointer to bredr connecthandle. */ static void AttConnectReqAssignBredrConnect(AttConnectingInfo **connecting, const BtAddr *btAddress, const AttConnect *connParaPtr, uint16_t *bredrconnectHandle) { LOG_INFO("%{public}s enter", __FUNCTION__); uint16_t index = 0; AttGetConnectingIndexByCidConnectHandle(0, 0, &index, connecting); if (*connecting == NULL) { goto ATTCONNECTREQASSIGNBREDRCONNECT_END; } (void)memcpy_s((*connecting)->addr.addr, ADDRESSLEN, btAddress->addr, ADDRESSLEN); (*connecting)->addr.type = btAddress->type; (*connecting)->connectHandle = index + 1; *bredrconnectHandle = index + 1; (*connecting)->initPassConnFlag = INITIATIVECONNECT; (*connecting)->initiativeConnectStatus = CONNECTING; (*connecting)->locall2capConfigInfoObj.mtu = connParaPtr->bredrConnParaVar.mtu; (*connecting)->locall2capConfigInfoObj.flushTimeout = connParaPtr->bredrConnParaVar.flushTimeout; (*connecting)->locall2capConfigInfoObj.rfc.mode = connParaPtr->bredrConnParaVar.mode; (*connecting)->mtu = DEFAULTBREDRMTU; (*connecting)->transportType = BT_TRANSPORT_BR_EDR; ATTCONNECTREQASSIGNBREDRCONNECT_END: return; } /** * @brief att bredr connect timeout async. * * @param ctx Indicates the pointer to context. */ static void AttBredrConnectTimeOutAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConnectTimeOutContext *attBredrTimeOutPtr = (ConnectTimeOutContext *)context; AttConnectingInfo *connecting = NULL; AttGetConnectingIndexByConnectHandle(attBredrTimeOutPtr->connectHandle, &connecting); if (connecting == NULL) { LOG_INFO("%{public}s connecting == NULL and goto ATTBREDRCONNECTTIMEOUT_END", __FUNCTION__); goto ATTBREDRCONNECTTIMEOUT_END; } AttConnectCompletedCallback(connecting, ATT_CONNECT_TIMEOUT); ATTBREDRCONNECTTIMEOUT_END: MEM_MALLOC.free(attBredrTimeOutPtr); return; } /** * @brief att bredr connect timeout async destroy. * * @param ctx Indicates the pointer to context. */ static void AttBredrConnectTimeOutAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConnectTimeOutContext *attBredrTimeOutPtr = (ConnectTimeOutContext *)context; MEM_MALLOC.free(attBredrTimeOutPtr); return; } /** * @brief att bredr connect timeout. * * @param parameter Indicates the pointer to parameter. */ static void AttBredrConnectTimeOut(void *parameter) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnectingInfo *connecting = (AttConnectingInfo *)parameter; ConnectTimeOutContext *attBredrTimeOutPtr = MEM_MALLOC.alloc(sizeof(ConnectTimeOutContext)); if (attBredrTimeOutPtr == NULL) { LOG_ERROR("point to NULL"); return; } attBredrTimeOutPtr->connectHandle = connecting->connectHandle; AttAsyncProcess(AttBredrConnectTimeOutAsync, AttBredrConnectTimeOutAsyncDestroy, attBredrTimeOutPtr); return; } /** * @brief att connect completed call back. * * @param1 connecting Indicates the pointer to AttConnectingInfo. * @param2 result Indicates the result. */ static void AttConnectCompletedCallback(AttConnectingInfo *connecting, uint16_t result) { LOG_INFO("%{public}s enter, result = %hu", __FUNCTION__, result); AttConnectInfo *connect = NULL; if (connecting == NULL) { LOG_INFO("%{public}s enter, result = %hu", __FUNCTION__, result); return; } if (result != ATT_CONNECT_TIMEOUT) { AlarmCancel(connecting->bredrAlarm); } AttBredrConnectCallback bredrConnectCallback; AttConnectedCallback *attConnectCallback = AttGetATTConnectCallback(); if ((attConnectCallback == NULL) || (attConnectCallback->attConnect.attBREDRConnectCompleted == NULL)) { LOG_WARN("%{public}s attConnectCallback or attBREDRConnectCompleted is NULL", __FUNCTION__); goto ATTCONNECTCOMPLETEDCALLBACK_END; } (void)memcpy_s(bredrConnectCallback.addr.addr, ADDRESSLEN, connecting->addr.addr, ADDRESSLEN); bredrConnectCallback.addr.type = connecting->addr.type; bredrConnectCallback.status = result; bredrConnectCallback.mtu = connecting->mtu; if (result == BREDR_CONNECT_SUCCESS) { AttCopyToConnectInfo(connecting, &connect); if (connect == NULL) { goto ATTCONNECTCOMPLETEDCALLBACK_END; } attConnectCallback->attConnect.attBREDRConnectCompleted( connect->retGattConnectHandle, &bredrConnectCallback, attConnectCallback->context); goto ATTCONNECTCOMPLETEDCALLBACK_END; } if (connecting->initPassConnFlag == INITIATIVECONNECT) { if (connecting->initiativeConnectStatus == DISCONNECTED) { goto ATTCONNECTCOMPLETEDCALLBACK_END; } else { attConnectCallback->attConnect.attBREDRConnectCompleted( connecting->connectHandle, &bredrConnectCallback, attConnectCallback->context); } } if (connecting->initPassConnFlag == PASSIVECONNECT) { if (connecting->passiveConnectSatatus == DISCONNECTED) { goto ATTCONNECTCOMPLETEDCALLBACK_END; } else { attConnectCallback->attConnect.attBREDRConnectCompleted( connecting->connectHandle, &bredrConnectCallback, attConnectCallback->context); } } ATTCONNECTCOMPLETEDCALLBACK_END: AttClearConnectingInfo(connecting); return; } /** * @brief att copy to connected. * * @param connecting Indicates the pointer to AttConnectingInfo. */ static void AttCopyToConnectInfo(const AttConnectingInfo *connecting, AttConnectInfo **connect) { LOG_INFO("%{public}s enter ", __FUNCTION__); uint16_t index = 0; AttGetConnectInfoIndexByCidOutIndex(0, &index, connect); if (*connect == NULL) { LOG_INFO("%{public}s connect == NULL", __FUNCTION__); goto ATTCOPYTOCONNECTINFO_END; } (*connect)->aclHandle = connecting->aclHandle; (*connect)->AttConnectID.bredrcid = connecting->cid; (*connect)->retGattConnectHandle = index + 1; (*connect)->transportType = BT_TRANSPORT_BR_EDR; (*connect)->initPassConnFlag = connecting->initPassConnFlag; (*connect)->addr.type = connecting->addr.type; (void)memcpy_s((*connect)->addr.addr, ADDRESSLEN, connecting->addr.addr, ADDRESSLEN); (*connect)->mtu = connecting->mtu; ATTCOPYTOCONNECTINFO_END: return; } /** * @brief add le connect information to AttConnectInfo. * * @param1 addr Indicates the pointer to const BtAddr. * @param2 aclHandle Indicates the aclHandle. * @param3 connect Indicates the secondary pointer to AttConnectInfo. */ static void AttConnectInfoAddLe( const BtAddr *addr, uint16_t aclHandle, AttConnectInfo **connect, uint8_t initPassConnFlag) { LOG_INFO("%{public}s enter,aclHandle = %hu", __FUNCTION__, aclHandle); uint16_t index = 0; AttGetConnectInfoIndexByConnectHandle(0, &index, connect); if ((*connect) == NULL) { LOG_INFO("%{public}s *connect == NULL", __FUNCTION__); goto ATTCONNECTINFOADDLE_END; } (*connect)->aclHandle = aclHandle; (*connect)->AttConnectID.lecid = LE_CID; (*connect)->retGattConnectHandle = index + 1; (*connect)->transportType = BT_TRANSPORT_LE; (*connect)->addr.type = addr->type; (*connect)->mtu = DEFAULTLEATTMTU; (*connect)->initPassConnFlag = initPassConnFlag; (void)memcpy_s((*connect)->addr.addr, ADDRESSLEN, addr->addr, ADDRESSLEN); ATTCONNECTINFOADDLE_END: return; } /** * @brief call l2cap interface for le connect call back async. * * @param ctx Indicates the pointer to context. */ static void L2cifLeConnectCallBackAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConnectCallBackContext *connectCallContextPtr = (ConnectCallBackContext *)context; AttConnectingInfo *connecting = NULL; AttLeConnectCallback data; AttConnectedCallback *attConnectCallback = NULL; AttGetConnectingIndexByAddr(connectCallContextPtr->addr, &connecting); if (connecting == NULL) { goto L2CIFLECONNECTCALLBACK_END; } attConnectCallback = AttGetATTConnectCallback(); if (connectCallContextPtr->result == BT_SUCCESS) { connecting->transportType = BT_TRANSPORT_LE; } else { LOG_WARN("%{public}s:L2CIF_ConnectReq error", __FUNCTION__); (void)memcpy_s(&data.addr, sizeof(BtAddr), connectCallContextPtr->addr, sizeof(BtAddr)); data.status = LE_CONNECT_FAIL; attConnectCallback->attConnect.attLEConnectCompleted(0, &data, attConnectCallback->context); AttClearConnectingInfo(connecting); } L2CIFLECONNECTCALLBACK_END: MEM_MALLOC.free(connectCallContextPtr->addr); MEM_MALLOC.free(connectCallContextPtr); return; } /** * @brief call l2cap interface for le connect call back async destroy. * * @param ctx Indicates the pointer to context. */ static void L2cifLeConnectCallBackAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConnectCallBackContext *connectCallContextPtr = (ConnectCallBackContext *)context; MEM_MALLOC.free(connectCallContextPtr->addr); MEM_MALLOC.free(connectCallContextPtr); return; } /** * @brief call l2cap interface for le connect call back. * * @param1 addr Indicates the pointer to const BtAddr. * @param2 result Indicates the result. */ void L2cifLeConnectCallBack(const BtAddr *addr, int result) { LOG_INFO("%{public}s enter result = %{public}d", __FUNCTION__, result); BtAddr *btaddr = NULL; ConnectCallBackContext *connectCallContextPtr = NULL; btaddr = MEM_MALLOC.alloc(sizeof(BtAddr)); if (btaddr == NULL) { LOG_ERROR("point to NULL"); return; } (void)memcpy_s(btaddr->addr, ADDRESSLEN, addr, ADDRESSLEN); btaddr->type = addr->type; connectCallContextPtr = MEM_MALLOC.alloc(sizeof(ConnectCallBackContext)); if (connectCallContextPtr == NULL) { LOG_ERROR("point to NULL"); return; } connectCallContextPtr->addr = btaddr; connectCallContextPtr->result = result; AttAsyncProcess(L2cifLeConnectCallBackAsync, L2cifLeConnectCallBackAsyncDestroy, connectCallContextPtr); return; } /** * @brief call l2cap interface for le connect. * * @param1 addr Indicates the pointer to const BtAddr. * @param2 var Indicates the struct L2capLeConnectionParameter. * @param3 connecting Indicates the pointer to AttConnectingInfo. * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails. */ static int AttLeConnectProcess(const BtAddr *addr, L2capLeConnectionParameter var, const AttConnectingInfo *connecting) { LOG_INFO("%{public}s enter", __FUNCTION__); int ret; ret = L2CIF_LeConnect(addr, &var, L2cifLeConnectCallBack); return ret; } /** * @brief callback of bredr connect request async. * * @param ctx Indicates the pointer to context. */ static void L2cifConnectReqCallbackAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConnectReqCallbackContext *connectReqContextPtr = NULL; AttConnectingInfo *connecting = NULL; connectReqContextPtr = (ConnectReqCallbackContext *)context; AttGetConnectingIndexByAddrUninitializedCid(connectReqContextPtr->addr, &connecting); if (connecting == NULL) { goto L2CIFCONNECTREQCALLBACK_END; } if (connectReqContextPtr->result == BT_SUCCESS) { connecting->cid = connectReqContextPtr->lcid; connecting->transportType = BT_TRANSPORT_BR_EDR; connecting->mtu = DEFAULTBREDRMTU; } else { LOG_WARN("%{public}s:L2CIF_ConnectReq error", __FUNCTION__); AlarmCancel(connecting->bredrAlarm); AttConnectCompletedCallback(connecting, BREDR_CONNECT_FAIL); AttClearConnectingInfo(connecting); } L2CIFCONNECTREQCALLBACK_END: MEM_MALLOC.free(connectReqContextPtr->addr); MEM_MALLOC.free(connectReqContextPtr); return; } /** * @brief callback of bredr connect request async destroy. * * @param ctx Indicates the pointer to context. */ static void L2cifConnectReqCallbackAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConnectReqCallbackContext *connectReqContextPtr = (ConnectReqCallbackContext *)context; MEM_MALLOC.free(connectReqContextPtr->addr); MEM_MALLOC.free(connectReqContextPtr); return; } /** * @brief callback of bredr connect request. * * @param addr Indicates the pointer to BtAddr. * @param lcid Indicates the lcid. * @param result Indicates the result. */ static void L2cifConnectReqCallback(const BtAddr *addr, uint16_t lcid, int result, const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); BtAddr *btaddr = NULL; ConnectReqCallbackContext *connectReqContextPtr = NULL; btaddr = MEM_MALLOC.alloc(sizeof(BtAddr)); if (btaddr == NULL) { LOG_ERROR("point to NULL"); return; } (void)memcpy_s(btaddr->addr, ADDRESSLEN, addr, ADDRESSLEN); btaddr->type = addr->type; connectReqContextPtr = MEM_MALLOC.alloc(sizeof(ConnectReqCallbackContext)); if (connectReqContextPtr == NULL) { LOG_ERROR("point to NULL"); return; } connectReqContextPtr->addr = btaddr; connectReqContextPtr->lcid = lcid; connectReqContextPtr->result = result; AttAsyncProcess(L2cifConnectReqCallbackAsync, L2cifConnectReqCallbackAsyncDestroy, connectReqContextPtr); return; } /** * @brief call l2cap interface for bredr connect. * * @param connecting Indicates the pointer to AttConnectingInfo. * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails. */ static int AttBredrConnectProcess(AttConnectingInfo *connecting) { LOG_INFO("%{public}s enter", __FUNCTION__); int ret; AlarmSet(connecting->bredrAlarm, (uint64_t)CONNECTTIMEOUT, AttBredrConnectTimeOut, connecting); ret = L2CIF_ConnectReq(&(connecting->addr), BT_PSM_ATT, BT_PSM_ATT, NULL, (void (*)(const BtAddr *, uint16_t, int, void *))L2cifConnectReqCallback); return ret; } /** * @brief gatt send connect request para assign. * * @param1 l2capObjptr Indicates the pointer to L2capLeConnectionParameter. * @param2 attConnectReqAsyncPtr Indicates the pointer to AttConnectReqAsync. */ static void AttConnectRequestLEParaAssign( L2capLeConnectionParameter *l2capObjptr, const AttConnectReqAsync *attConnectReqAsyncPtr) { LOG_INFO("%{public}s enter", __FUNCTION__); l2capObjptr->connIntervalMin = attConnectReqAsyncPtr->connParaPtr->leConnParaVar.connIntervalMin; l2capObjptr->connIntervalMax = attConnectReqAsyncPtr->connParaPtr->leConnParaVar.connIntervalMax; l2capObjptr->connLatency = attConnectReqAsyncPtr->connParaPtr->leConnParaVar.connLatency; l2capObjptr->supervisionTimeout = attConnectReqAsyncPtr->connParaPtr->leConnParaVar.supervisionTimeout; return; } /** * @brief send connect request in self thread. * * @param context Indicates the pointer to context. */ static void AttConnectRequestAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); uint16_t index; L2capLeConnectionParameter l2capObj; GapRequestSecurityParam gapReqSecurity; AttConnectingInfo *connecting = NULL; AttConnectReqAsync *attConnectReqAsyncPtr = (AttConnectReqAsync *)context; if (attConnectReqAsyncPtr->btAddress == NULL) { LOG_WARN("%{public}s:btAddress == NULL and goto ATT_CONNECTREQ_END", __FUNCTION__); goto ATT_CONNECTREQ_END; } if (attConnectReqAsyncPtr->transportType == BT_TRANSPORT_BR_EDR) { AttConnectReqAssignBredrConnect(&connecting, attConnectReqAsyncPtr->btAddress, attConnectReqAsyncPtr->connParaPtr, attConnectReqAsyncPtr->bredrconnectHandle); AttAssignGAPRequestSecurity(&gapReqSecurity, OUTGOING, connecting); GAPIF_RequestSecurityAsync(&(connecting->addr), &gapReqSecurity); } else if (attConnectReqAsyncPtr->transportType == BT_TRANSPORT_LE) { AttConnectRequestLEParaAssign(&l2capObj, attConnectReqAsyncPtr); connecting = AttGetConnectingStart(); for (index = 0; index < MAXCONNECT; ++index, connecting++) { if (connecting->connectHandle == 0) { (void)memcpy_s(connecting->addr.addr, ADDRESSLEN, attConnectReqAsyncPtr->btAddress->addr, ADDRESSLEN); connecting->addr.type = attConnectReqAsyncPtr->btAddress->type; connecting->connectHandle = index + 1; connecting->transportType = BT_TRANSPORT_LE; connecting->cid = LE_CID; connecting->initPassConnFlag = INITIATIVECONNECT; break; } } AttLeConnectProcess(attConnectReqAsyncPtr->btAddress, l2capObj, connecting); } ATT_CONNECTREQ_END: MEM_MALLOC.free(attConnectReqAsyncPtr->connParaPtr); MEM_MALLOC.free(attConnectReqAsyncPtr->btAddress); MEM_MALLOC.free(attConnectReqAsyncPtr->bredrconnectHandle); MEM_MALLOC.free(attConnectReqAsyncPtr); return; } /** * @brief destroy connect request data in self thread. * * @param context Indicates the pointer to context. */ static void AttConnectRequestAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnectReqAsync *attConnectReqAsyncPtr = (AttConnectReqAsync *)context; MEM_MALLOC.free(attConnectReqAsyncPtr->connParaPtr); MEM_MALLOC.free(attConnectReqAsyncPtr->btAddress); MEM_MALLOC.free(attConnectReqAsyncPtr->bredrconnectHandle); MEM_MALLOC.free(attConnectReqAsyncPtr); return; } /** * @brief gatt send connect request to att. * * @param1 transportType Indicates the connect type. * @param2 connParaPtr Indicates the pointer to connect parameter. * @param3 btAddress Indicates the pointer to address. * @param4 bredrconnectHandle Indicates the pointer to connecthandle be outputted. * @return Returns the result of connect request. */ void ATT_ConnectReq( uint8_t transportType, const AttConnect *connParaPtr, const BtAddr *btAddress, const uint16_t *bredrconnectHandle) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnect *connectAsyncPtr = MEM_MALLOC.alloc(sizeof(AttConnect)); BtAddr *btAddrAsyncPtr = MEM_MALLOC.alloc(sizeof(BtAddr)); uint16_t *bredrConnectHandleAsyncPtr = MEM_MALLOC.alloc(sizeof(uint16_t)); AttConnectReqAsync *attConnectReqAsyncPtr = MEM_MALLOC.alloc(sizeof(AttConnectReqAsync)); if (connectAsyncPtr == NULL) { LOG_ERROR("point to NULL"); return; } if (btAddrAsyncPtr == NULL) { LOG_ERROR("point to NULL"); return; } if (bredrConnectHandleAsyncPtr == NULL) { LOG_ERROR("point to NULL"); return; } if (attConnectReqAsyncPtr == NULL) { LOG_ERROR("point to NULL"); return; } if (transportType == BT_TRANSPORT_BR_EDR) { connectAsyncPtr->bredrConnParaVar = connParaPtr->bredrConnParaVar; } else if (transportType == BT_TRANSPORT_LE) { connectAsyncPtr->leConnParaVar = connParaPtr->leConnParaVar; } (void)memcpy_s(btAddrAsyncPtr, sizeof(BtAddr), btAddress, sizeof(BtAddr)); attConnectReqAsyncPtr->transportType = transportType; attConnectReqAsyncPtr->connParaPtr = connectAsyncPtr; attConnectReqAsyncPtr->btAddress = btAddrAsyncPtr; attConnectReqAsyncPtr->bredrconnectHandle = bredrConnectHandleAsyncPtr; AttAsyncProcess(AttConnectRequestAsync, AttConnectRequestAsyncDestroy, attConnectReqAsyncPtr); return; } /** * @brief gatt send connect request to att async. * * @param ctx Indicates the pointer to context. */ static void L2cifConfigReqCallbackAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnectingInfo *connecting = NULL; ConfigReqCallbackContext *configReqPtr = (ConfigReqCallbackContext *)context; AttGetConnectingIndexByCid(configReqPtr->lcid, &connecting); if (connecting == NULL) { goto L2CIFCONFIGREQCALLBACK_END; } if (configReqPtr->result != BT_SUCCESS) { AttConnectCompletedCallback(connecting, BREDR_CONNECT_FAIL); AttClearConnectingInfo(connecting); } L2CIFCONFIGREQCALLBACK_END: MEM_MALLOC.free(configReqPtr); return; } /** * @brief gatt send connect request to att async destroy. * * @param ctx Indicates the pointer to context. */ static void L2cifConfigReqCallbackAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConfigReqCallbackContext *configReqPtr = (ConfigReqCallbackContext *)context; MEM_MALLOC.free(configReqPtr); return; } /** * @brief gatt send connect request to att. * * @param1 lcid Indicates the connect lcid. * @param2 result Indicates the variable of result. */ static void L2cifConfigReqCallback(uint16_t lcid, int result) { LOG_INFO("%{public}s enter, lcid = %hu, result = %{public}d", __FUNCTION__, lcid, result); ConfigReqCallbackContext *configReqPtr = MEM_MALLOC.alloc(sizeof(ConfigReqCallbackContext)); if (configReqPtr == NULL) { LOG_ERROR("point to NULL"); return; } configReqPtr->lcid = lcid; configReqPtr->result = result; AttAsyncProcess(L2cifConfigReqCallbackAsync, L2cifConfigReqCallbackAsyncDestroy, configReqPtr); return; } /** * @brief gatt send connect response to att async. * * @param ctx Indicates the pointer to context. */ static void L2cifConnectRspResultCallbackAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnectingInfo *connecting = NULL; ConnectRspResultCallbackContext *connectRspPtr = (ConnectRspResultCallbackContext *)context; AttGetConnectingIndexByCid(connectRspPtr->lcid, &connecting); if (connecting == NULL) { goto L2CIFCONNECTRSPRESULTCALLBACK_END; } if (connectRspPtr->result == L2CAP_SUCCESS) { L2CIF_ConfigReq(connecting->cid, &(connecting->locall2capConfigInfoObj), L2cifConfigReqCallback); } L2CIFCONNECTRSPRESULTCALLBACK_END: MEM_MALLOC.free(connectRspPtr); return; } /** * @brief gatt send connect response to att async destroy. * * @param ctx Indicates the pointer to context. */ static void L2cifConnectRspResultCallbackAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConnectRspResultCallbackContext *connectRspPtr = (ConnectRspResultCallbackContext *)context; MEM_MALLOC.free(connectRspPtr); return; } /** * @brief gatt send connect response to att. * * @param1 lcid Indicates the connect lcid. * @param2 result Indicates the variable of result. */ static void L2cifConnectRspResultCallback(uint16_t lcid, int result) { LOG_INFO("%{public}s enter, lcid = %hu, result = %{public}d", __FUNCTION__, lcid, result); ConnectRspResultCallbackContext *connectRspPtr = MEM_MALLOC.alloc(sizeof(ConnectRspResultCallbackContext)); if (connectRspPtr == NULL) { LOG_ERROR("point to NULL"); return; } connectRspPtr->lcid = lcid; connectRspPtr->result = result; AttAsyncProcess(L2cifConnectRspResultCallbackAsync, L2cifConnectRspResultCallbackAsyncDestroy, connectRspPtr); return; } /** * @brief perform the connect rsp operation in self thread. * * @param context Indicates the pointer to context. */ static void AttConnectRsponseAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnectingInfo *connecting = NULL; AttConnectRspAsync *attConnectRspAsyncPtr = (AttConnectRspAsync *)context; AttGetConnectingIndexByConnectHandle(attConnectRspAsyncPtr->connectHandle, &connecting); if (connecting == NULL) { LOG_INFO("connecting == NULL and goto ATTCONNECTRSP_END"); goto ATTCONNECTRSP_END; } connecting->locall2capConfigInfoObj.mtu = attConnectRspAsyncPtr->g_attConnectParaObj->bredrConnParaVar.mtu; connecting->locall2capConfigInfoObj.flushTimeout = attConnectRspAsyncPtr->g_attConnectParaObj->bredrConnParaVar.flushTimeout; connecting->locall2capConfigInfoObj.rfc.mode = attConnectRspAsyncPtr->g_attConnectParaObj->bredrConnParaVar.mode; L2CIF_ConnectRsp(connecting->cid, connecting->id, attConnectRspAsyncPtr->result, attConnectRspAsyncPtr->status, L2cifConnectRspResultCallback); ATTCONNECTRSP_END: MEM_MALLOC.free(attConnectRspAsyncPtr->g_attConnectParaObj); MEM_MALLOC.free(attConnectRspAsyncPtr); return; } /** * @brief destroy connect response data in self thread. * * @param context Indicates the pointer to context. */ static void AttConnectRsponseAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnectRspAsync *attConnectRspAsyncPtr = (AttConnectRspAsync *)context; MEM_MALLOC.free(attConnectRspAsyncPtr->g_attConnectParaObj); MEM_MALLOC.free(attConnectRspAsyncPtr); return; } /** * @brief gatt send connect response to att. * * @param1 connectHandle Indicates the connect handle. * @param2 result Indicates the variable of result. * @param3 status Indicates the result of status. * @param4 g_attConnectParaObj Indicates the pointer to connect parameter. * @return Returns the result of connect response. */ void ATT_ConnectRsp(uint16_t connectHandle, uint16_t result, uint16_t status, const AttConnect *cfg) { LOG_INFO("%{public}s enter,connectHandle = %hu,result = %hu,status=%hu, mtu = %{public}d", __FUNCTION__, connectHandle, result, status, cfg->bredrConnParaVar.mtu); AttConnect *attConnectBredrConnPtr = NULL; AttConnectRspAsync *attConnectRspAsyncPtr = NULL; attConnectBredrConnPtr = MEM_MALLOC.alloc(sizeof(AttConnect)); attConnectRspAsyncPtr = MEM_MALLOC.alloc(sizeof(AttConnectRspAsync)); if (attConnectBredrConnPtr == NULL) { LOG_ERROR("point to NULL"); return; } if (attConnectRspAsyncPtr == NULL) { LOG_ERROR("point to NULL"); return; } attConnectBredrConnPtr->bredrConnParaVar.mtu = cfg->bredrConnParaVar.mtu; attConnectBredrConnPtr->bredrConnParaVar.flushTimeout = cfg->bredrConnParaVar.flushTimeout; attConnectBredrConnPtr->bredrConnParaVar.mode = cfg->bredrConnParaVar.mode; attConnectRspAsyncPtr->connectHandle = connectHandle; attConnectRspAsyncPtr->result = result; attConnectRspAsyncPtr->status = status; attConnectRspAsyncPtr->g_attConnectParaObj = attConnectBredrConnPtr; AttAsyncProcess(AttConnectRsponseAsync, AttConnectRsponseAsyncDestroy, attConnectRspAsyncPtr); return; } /** * @brief gatt send disconnect request to att async. * * @param ctx Indicates the pointer to context. */ void L2cifBREDRDisconnectReqCallBackAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnectInfo *connect = NULL; BREDRDisconnectReqCallBackContext *disBredrConnectReqPtr = (BREDRDisconnectReqCallBackContext *)context; AttBredrDisconnectCallback BredrData; AttConnectedCallback *attConnectCallback = NULL; AttGetConnectInfoIndexByCid(disBredrConnectReqPtr->lcid, &connect); if (connect == NULL) { goto L2CIFDISCONNECTREQCALLBACK_END; } attConnectCallback = AttGetATTConnectCallback(); if (disBredrConnectReqPtr->result != BT_SUCCESS) { if (connect->transportType == BT_TRANSPORT_BR_EDR) { BredrData.reason = INITIATIVECONNECT_DISCONNECT_FAIL; attConnectCallback->attConnect.attBREDRDisconnectCompleted( connect->retGattConnectHandle, &BredrData, attConnectCallback->context); } } L2CIFDISCONNECTREQCALLBACK_END: MEM_MALLOC.free(disBredrConnectReqPtr); return; } /** * @brief gatt send disconnect request to att async destroy. * * @param ctx Indicates the pointer to context. */ void L2cifBREDRDisconnectReqCallBackAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); BREDRDisconnectReqCallBackContext *disBredrConnectReqPtr = (BREDRDisconnectReqCallBackContext *)context; MEM_MALLOC.free(disBredrConnectReqPtr); return; } /** * @brief gatt send disconnect request to att. * * @param lcid Indicates the connect lcid. * @return Returns the result of disconnect request. */ void L2cifBREDRDisconnectReqCallBack(uint16_t lcid, int result) { LOG_INFO("%{public}s enter, result = %{public}d", __FUNCTION__, result); BREDRDisconnectReqCallBackContext *disBredrConnectReqPtr = MEM_MALLOC.alloc(sizeof(BREDRDisconnectReqCallBackContext)); if (disBredrConnectReqPtr == NULL) { LOG_ERROR("point to NULL"); return; } disBredrConnectReqPtr->lcid = lcid; disBredrConnectReqPtr->result = result; AttAsyncProcess( L2cifBREDRDisconnectReqCallBackAsync, L2cifBREDRDisconnectReqCallBackAsyncDestroy, disBredrConnectReqPtr); return; } /** * @brief le disconnect request callback async. * * @param ctx Indicates the pointer to context. */ void LeDisconnectReqCallBackAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnectInfo *connect = NULL; LeDisconnectReqCallBackContext *disLeConnectReqPtr = (LeDisconnectReqCallBackContext *)context; AttLeDisconnectCallback leData; AttConnectedCallback *attConnectCallback = NULL; AttGetConnectInfoIndexByCid(disLeConnectReqPtr->aclHandle, &connect); if (connect == NULL) { goto LEDISCONNECTREQCALLBACK_END; } attConnectCallback = AttGetATTConnectCallback(); if (disLeConnectReqPtr->result != BT_SUCCESS) { if (connect->transportType == BT_TRANSPORT_LE) { leData.status = LE_DISCONNECT_FAIL; if (attConnectCallback->attConnect.attLEDisconnectCompleted != NULL) { attConnectCallback->attConnect.attLEDisconnectCompleted( connect->retGattConnectHandle, &leData, attConnectCallback->context); } } } LEDISCONNECTREQCALLBACK_END: MEM_MALLOC.free(disLeConnectReqPtr); return; } /** * @brief le disconnect request callback async destroy. * * @param ctx Indicates the pointer to context. */ void LeDisconnectReqCallBackAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); LeDisconnectReqCallBackContext *disLeConnectReqPtr = (LeDisconnectReqCallBackContext *)context; MEM_MALLOC.free(disLeConnectReqPtr); return; } /** * @brief le disconnect request callback. * * @param aclHandle Indicates the aclHandle. * @param result Indicates the result. */ void LeDisconnectReqCallback(uint16_t aclHandle, int result) { LOG_INFO("%{public}s enter, result = %{public}d", __FUNCTION__, result); LeDisconnectReqCallBackContext *disLeConnectReqPtr = MEM_MALLOC.alloc(sizeof(LeDisconnectReqCallBackContext)); if (disLeConnectReqPtr == NULL) { LOG_ERROR("point to NULL"); return; } disLeConnectReqPtr->aclHandle = aclHandle; disLeConnectReqPtr->result = result; AttAsyncProcess(LeDisconnectReqCallBackAsync, LeDisconnectReqCallBackAsyncDestroy, disLeConnectReqPtr); return; } /** * @brief send disconnect request in self thread. * * @param context Indicates the pointer to context. */ static void AttDisconnectRequestAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttDisconnectReqAsync *attDisconnectReqAsyncPtr = (AttDisconnectReqAsync *)context; InitiativeDisconnect(attDisconnectReqAsyncPtr->connectHandle); MEM_MALLOC.free(attDisconnectReqAsyncPtr); return; } /** * @brief destroy disconnect request async destroy. * * @param context Indicates the pointer to context. */ static void AttDisconnectRequestAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttDisconnectReqAsync *attDisconnectReqAsyncPtr = (AttDisconnectReqAsync *)context; MEM_MALLOC.free(attDisconnectReqAsyncPtr); return; } /** * @brief gatt send disconnect request to att. * * @param connectHandle Indicates the connect handle. * @return Returns the result of disconnect request. */ void ATT_DisconnectReq(uint16_t connectHandle) { LOG_INFO("%{public}s enter,connectHandle = %hu", __FUNCTION__, connectHandle); AttDisconnectReqAsync *attDisconnectReqAsyncPtr = MEM_MALLOC.alloc(sizeof(AttDisconnectReqAsync)); if (attDisconnectReqAsyncPtr == NULL) { LOG_ERROR("point to NULL"); return; } attDisconnectReqAsyncPtr->connectHandle = connectHandle; AttAsyncProcess(AttDisconnectRequestAsync, AttDisconnectRequestAsyncDestroy, attDisconnectReqAsyncPtr); return; } /** * @brief receive le connected async. * * @param ctx Indicates the pointer to context. */ NO_SANITIZE("cfi") static void AttLeConnectedAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttLeConnectedAsyncContext *attLeConnectedAsyncPtr = (AttLeConnectedAsyncContext *)context; AttLeConnectCallback leConnectCallbackParaObj; AttConnectInfo *connect = NULL; AttConnectingInfo *connecting = NULL; uint8_t initPassConnFlag = 0; AttConnectedCallback *attConnectCallback = AttGetATTConnectCallback(); if (attLeConnectedAsyncPtr->role == LEROLEMASTER) { AttGetConnectingIndexByAddrAclhandleCid(attLeConnectedAsyncPtr->addr, 0, LE_CID, &connecting); if (connecting != NULL) { AttClearConnectingInfo(connecting); } initPassConnFlag = INITIATIVECONNECT; } else if (attLeConnectedAsyncPtr->role == LEROLESLAVE) { initPassConnFlag = PASSIVECONNECT; } if ((attConnectCallback == NULL) || (attConnectCallback->attConnect.attLEConnectCompleted == NULL)) { LOG_WARN("%{public}s attConnectCallback or attLEConnectCompleted is NULL", __FUNCTION__); goto ATTLECONNECTED_END; } leConnectCallbackParaObj.addr.type = attLeConnectedAsyncPtr->addr->type; leConnectCallbackParaObj.role = attLeConnectedAsyncPtr->role; (void)memcpy_s(leConnectCallbackParaObj.addr.addr, ADDRESSLEN, attLeConnectedAsyncPtr->addr->addr, ADDRESSLEN); if (attLeConnectedAsyncPtr->status == BT_SUCCESS) { leConnectCallbackParaObj.status = LE_CONNECT_SUCCESS; AttConnectInfoAddLe( attLeConnectedAsyncPtr->addr, attLeConnectedAsyncPtr->aclHandle, &connect, initPassConnFlag); if (connect != NULL) { attConnectCallback->attConnect.attLEConnectCompleted( connect->retGattConnectHandle, &leConnectCallbackParaObj, attConnectCallback->context); } } else { leConnectCallbackParaObj.status = LE_CONNECT_FAIL; attConnectCallback->attConnect.attLEConnectCompleted(0, &leConnectCallbackParaObj, attConnectCallback->context); } ATTLECONNECTED_END: MEM_MALLOC.free(attLeConnectedAsyncPtr->addr); MEM_MALLOC.free(attLeConnectedAsyncPtr); return; } /** * @brief receive le connected async destroy. * * @param ctx Indicates the pointer to context. */ static void AttLeConnectedAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttLeConnectedAsyncContext *attLeConnectedAsyncPtr = (AttLeConnectedAsyncContext *)context; MEM_MALLOC.free(attLeConnectedAsyncPtr->addr); MEM_MALLOC.free(attLeConnectedAsyncPtr); return; } /** * @brief receive le connected. * * @param1 addr Indicates the pointer to BtAddr. * @param2 aclHandle Indicates the aclHandle. * @param3 role Indicates the role. * @param4 status Indicates the status. */ void AttLeConnected(const BtAddr *addr, uint16_t aclHandle, uint8_t role, uint8_t status) { LOG_INFO("%{public}s enter, aclHandle = %hu, role = %hhu", __FUNCTION__, aclHandle, role); BtAddr *btAddrPtr = MEM_MALLOC.alloc(sizeof(BtAddr)); if (btAddrPtr == NULL) { LOG_ERROR("point to NULL"); return; } (void)memcpy_s(btAddrPtr->addr, ADDRESSLEN, addr, ADDRESSLEN); btAddrPtr->type = addr->type; AttLeConnectedAsyncContext *attLeConnectedAsyncPtr = MEM_MALLOC.alloc(sizeof(AttLeConnectedAsyncContext)); if (attLeConnectedAsyncPtr == NULL) { LOG_ERROR("point to NULL"); return; } attLeConnectedAsyncPtr->addr = btAddrPtr; attLeConnectedAsyncPtr->aclHandle = aclHandle; attLeConnectedAsyncPtr->role = role; attLeConnectedAsyncPtr->status = status; AttAsyncProcess(AttLeConnectedAsync, AttLeConnectedAsyncDestroy, attLeConnectedAsyncPtr); return; } /** * @brief receive le disconnected async. * * @param ctx Indicates the pointer to context. */ static void AttLeDisconnectedAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttLeDisconnectedAsyncContext *attLeDisconnectedPtr = (AttLeDisconnectedAsyncContext *)context; AttLeDisconnectCallback leDisConnCallbackObj; int listSize; AttConnectInfo *connect = NULL; AttConnectedCallback *attConnectCallback = AttGetATTConnectCallback(); leDisConnCallbackObj.reason = attLeDisconnectedPtr->reason; if (attLeDisconnectedPtr->status == BT_SUCCESS) { leDisConnCallbackObj.status = LE_DISCONNECT_SUCCESS; } else { leDisConnCallbackObj.status = LE_DISCONNECT_FAIL; } AttGetConnectInfoIndexByAclHandle(attLeDisconnectedPtr->aclHandle, &connect); if (connect == NULL) { goto ATTLEDISCONNECTED_END; } if ((attConnectCallback == NULL) || (attConnectCallback->attConnect.attLEDisconnectCompleted == NULL)) { LOG_WARN("%{public}s attConnectCallback or attLEDisconnectCompleted is NULL", __FUNCTION__); } else { attConnectCallback->attConnect.attLEDisconnectCompleted( connect->retGattConnectHandle, &leDisConnCallbackObj, attConnectCallback->context); } if (leDisConnCallbackObj.status == LE_DISCONNECT_SUCCESS) { listSize = ListGetSize(connect->instruct); LOG_INFO("%{public}s listSize = %u", __FUNCTION__, listSize); for (; listSize > 0; --listSize) { ListRemoveLast(connect->instruct); } AttClearConnectInfo(connect); } ATTLEDISCONNECTED_END: MEM_MALLOC.free(attLeDisconnectedPtr); return; } /** * @brief receive le disconnected async destroy. * * @param ctx Indicates the pointer to context. */ static void AttLeDisconnectedAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttLeDisconnectedAsyncContext *attLeDisconnectedPtr = (AttLeDisconnectedAsyncContext *)context; MEM_MALLOC.free(attLeDisconnectedPtr); return; } /** * @brief receive le disconnected. * * @param1 aclHandle Indicates the aclHandle. * @param2 status Indicates the status. * @param3 reason Indicates the reason. */ void AttLeDisconnected(uint16_t aclHandle, uint8_t status, uint8_t reason) { LOG_INFO("%{public}s enter, aclHandle = %hu,status = %hhu,reason = %hhu", __FUNCTION__, aclHandle, status, reason); AttLeDisconnectedAsyncContext *attLeDisconnectedPtr = MEM_MALLOC.alloc(sizeof(AttLeDisconnectedAsyncContext)); if (attLeDisconnectedPtr == NULL) { LOG_ERROR("point to NULL"); return; } attLeDisconnectedPtr->aclHandle = aclHandle; attLeDisconnectedPtr->status = status; attLeDisconnectedPtr->reason = reason; AttAsyncProcess(AttLeDisconnectedAsync, AttLeDisconnectedAsyncDestroy, attLeDisconnectedPtr); return; } /** * @brief bredr connect response pending call backt async. * * @param ctx Indicates the pointer to context. */ static void L2cifConnectRspPendingCallbackAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnectingInfo *connecting = NULL; ConnectRspPendingContext *connectRspPendingPtr = (ConnectRspPendingContext *)context; GapRequestSecurityParam gapReqSecurity; AttGetConnectingIndexByCid(connectRspPendingPtr->lcid, &connecting); if (connecting == NULL) { goto L2CIFCONNECTRSPPENDINGCALLBACK_END; } if (connectRspPendingPtr->result == BT_SUCCESS) { AttAssignGAPRequestSecurity(&gapReqSecurity, INCOMING, connecting); GAPIF_RequestSecurityAsync(&(connecting->addr), &gapReqSecurity); } else { LOG_WARN("%{public}s:L2CIF_ConnectRsp error", __FUNCTION__); AttConnectCompletedCallback(connecting, BREDR_CONNECT_FAIL); AttClearConnectingInfo(connecting); } L2CIFCONNECTRSPPENDINGCALLBACK_END: MEM_MALLOC.free(connectRspPendingPtr); return; } /** * @brief bredr connect response pending call backt async destroy. * * @param ctx Indicates the pointer to context. */ static void L2cifConnectRspPendingCallbackAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConnectRspPendingContext *connectRspPendingPtr = (ConnectRspPendingContext *)context; MEM_MALLOC.free(connectRspPendingPtr); return; } /** * @brief bredr connect response pending call backt. * * @param1 lcid Indicates the lcid. * @param2 result Indicates the result. */ static void L2cifConnectRspPendingCallback(uint16_t lcid, int result) { LOG_INFO("%{public}s enter, lcid = %hu, result = %{public}d", __FUNCTION__, lcid, result); ConnectRspPendingContext *connectRspPendingPtr = MEM_MALLOC.alloc(sizeof(ConnectRspPendingContext)); if (connectRspPendingPtr == NULL) { LOG_ERROR("point to NULL"); return; } connectRspPendingPtr->lcid = lcid; connectRspPendingPtr->result = result; AttAsyncProcess( L2cifConnectRspPendingCallbackAsync, L2cifConnectRspPendingCallbackAsyncDestroy, connectRspPendingPtr); return; } /** * @brief received bredr connect request async. * * @param ctx Indicates the pointer to context. */ static void AttReceiveConnectionReqAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttReceiveConnectReqContext *attRecevieConnectPtr = (AttReceiveConnectReqContext *)context; AttConnectingInfo *connecting = AttGetConnectingStart(); if (connecting == NULL) { LOG_WARN("%{public}s connecting == NULL", __FUNCTION__); L2CIF_ConnectRsp(attRecevieConnectPtr->lcid, attRecevieConnectPtr->id, L2CAP_NO_RESOURCES_AVAILABLE, L2CAP_NO_FURTHER_INFORMATION_AVAILABLE, NULL); goto ATTRECEIVECONNECTIONREQ_END; } AttCopyToConnectingInfo(&(attRecevieConnectPtr->info->addr), attRecevieConnectPtr->info->handle, attRecevieConnectPtr->lcid, attRecevieConnectPtr->id, connecting); L2CIF_ConnectRsp(attRecevieConnectPtr->lcid, attRecevieConnectPtr->id, CONNECTIONPENDING, AUTHENTICATIONPENDING, L2cifConnectRspPendingCallback); ATTRECEIVECONNECTIONREQ_END: MEM_MALLOC.free(attRecevieConnectPtr->info); MEM_MALLOC.free(attRecevieConnectPtr); return; } /** * @brief received bredr connect request async destroy. * * @param ctx Indicates the pointer to context. */ static void AttReceiveConnectionReqAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttReceiveConnectReqContext *attRecevieConnectPtr = (AttReceiveConnectReqContext *)context; MEM_MALLOC.free(attRecevieConnectPtr->info); MEM_MALLOC.free(attRecevieConnectPtr); return; } /** * @brief received bredr connect request. * * @param1 lcid Indicates the lcid. * @param2 id Indicates the id. * @param3 info Indicates the pointer to L2capConnectionInfo. * @param4 lpsm Indicates the lpsm. * @param5 ctx Indicates the pointer to context. */ void AttReceiveConnectionReq(uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t lpsm, const void *ctx) { LOG_INFO("%{public}s enter", __FUNCTION__); L2capConnectionInfo *connectInfoPtr = NULL; AttReceiveConnectReqContext *attRecevieConnectPtr = NULL; connectInfoPtr = MEM_MALLOC.alloc(sizeof(L2capConnectionInfo)); if (connectInfoPtr == NULL) { LOG_ERROR("point to NULL"); return; } (void)memcpy_s(&(connectInfoPtr->addr), sizeof(BtAddr), &(info->addr), sizeof(BtAddr)); connectInfoPtr->handle = info->handle; attRecevieConnectPtr = MEM_MALLOC.alloc(sizeof(AttReceiveConnectReqContext)); if (attRecevieConnectPtr == NULL) { LOG_ERROR("point to NULL"); return; } attRecevieConnectPtr->lcid = lcid; attRecevieConnectPtr->id = id; attRecevieConnectPtr->info = connectInfoPtr; attRecevieConnectPtr->lpsm = lpsm; attRecevieConnectPtr->ctx = (void *)ctx; AttAsyncProcess(AttReceiveConnectionReqAsync, AttReceiveConnectionReqAsyncDestroy, attRecevieConnectPtr); return; } /** * @brief received bredr connect response async. * * @param ctx Indicates the pointer to context. */ static void AttReceiveConnectionRspAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttReceiveConnectionRspContext *attRecevieRspConnectPtr = (AttReceiveConnectionRspContext *)context; AttConnectingInfo *connecting = NULL; L2capConfigInfo l2capConfigInfoPtr; AttGetConnectingIndexByCid(attRecevieRspConnectPtr->lcid, &connecting); if (connecting == NULL) { goto ATTRECVCONNECTIONRSP_END; } connecting->aclHandle = attRecevieRspConnectPtr->info->handle; if (attRecevieRspConnectPtr->result == L2CAP_CONNECTION_SUCCESSFUL) { if (connecting->locall2capConfigInfoObj.rfc.mode == BR_EDR_BASIC_MODE) { l2capConfigInfoPtr.mtu = connecting->locall2capConfigInfoObj.mtu; l2capConfigInfoPtr.flushTimeout = connecting->locall2capConfigInfoObj.flushTimeout; l2capConfigInfoPtr.rfc.mode = connecting->locall2capConfigInfoObj.rfc.mode; } L2CIF_ConfigReq(attRecevieRspConnectPtr->lcid, &l2capConfigInfoPtr, L2cifConfigReqCallback); } else if (attRecevieRspConnectPtr->result == L2CAP_CONNECTION_PENDING) { goto ATTRECVCONNECTIONRSP_END; } else { attRecevieRspConnectPtr->result = BREDR_CONNECT_FAIL; AttConnectCompletedCallback(connecting, attRecevieRspConnectPtr->result); } ATTRECVCONNECTIONRSP_END: MEM_MALLOC.free(attRecevieRspConnectPtr->info); MEM_MALLOC.free(attRecevieRspConnectPtr); return; } /** * @brief received bredr connect response async destroy. * * @param ctx Indicates the pointer to context. */ static void AttReceiveConnectionRspAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttReceiveConnectionRspContext *attRecevieRspConnectPtr = (AttReceiveConnectionRspContext *)context; MEM_MALLOC.free(attRecevieRspConnectPtr->info); MEM_MALLOC.free(attRecevieRspConnectPtr); return; } /** * @brief received bredr connect response. * * @param1 lcid Indicates the lcid. * @param2 info Indicates the pointer to L2capConnectionInfo. * @param3 result Indicates the result. * @param4 status Indicates the status. * @param5 ctx Indicates the pointer to context. */ void AttReceiveConnectionRsp( uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, const void *ctx) { LOG_INFO("%{public}s enter, result = %hu, status = %hu", __FUNCTION__, result, status); L2capConnectionInfo *connectInfoPtr = NULL; AttReceiveConnectionRspContext *attRecevieRspConnectPtr = NULL; connectInfoPtr = MEM_MALLOC.alloc(sizeof(L2capConnectionInfo)); if (connectInfoPtr == NULL) { LOG_ERROR("point to NULL"); return; } (void)memcpy_s(&(connectInfoPtr->addr), sizeof(BtAddr), &(info->addr), sizeof(BtAddr)); connectInfoPtr->handle = info->handle; attRecevieRspConnectPtr = MEM_MALLOC.alloc(sizeof(AttReceiveConnectionRspContext)); if (attRecevieRspConnectPtr == NULL) { LOG_ERROR("point to NULL"); return; } attRecevieRspConnectPtr->lcid = lcid; attRecevieRspConnectPtr->info = connectInfoPtr; attRecevieRspConnectPtr->result = result; attRecevieRspConnectPtr->status = status; attRecevieRspConnectPtr->ctx = (void *)ctx; AttAsyncProcess(AttReceiveConnectionRspAsync, AttReceiveConnectionRspAsyncDestroy, attRecevieRspConnectPtr); return; } /** * @brief receive config response async. * * @param ctx Indicates the pointer to context. */ static void AttReceiveConfigRspAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttReceiveConfigRspContext *attRecevieConfigRspPtr = (AttReceiveConfigRspContext *)context; uint8_t outPara = 0; AttConnectingInfo *connecting = NULL; AttGetConnectingIndexByCid(attRecevieConfigRspPtr->lcid, &connecting); if (connecting == NULL) { goto ATTRECVCONFIGRSP_END; } if (attRecevieConfigRspPtr->result == L2CAP_SUCCESS) { if (connecting->initPassConnFlag == INITIATIVECONNECT) { AttBredrConnectStatusChange(connecting->initiativeConnectStatus, &outPara, INITIATIVECONNECT); connecting->initiativeConnectStatus = outPara; if (connecting->initiativeConnectStatus == CONNECTED) { AttConnectCompletedCallback(connecting, BREDR_CONNECT_SUCCESS); } } else if (connecting->initPassConnFlag == PASSIVECONNECT) { AttBredrConnectStatusChange(connecting->passiveConnectSatatus, &outPara, PASSIVECONNECT); connecting->passiveConnectSatatus = outPara; if (connecting->passiveConnectSatatus == CONNECTED) { AttConnectCompletedCallback(connecting, BREDR_CONNECT_SUCCESS); } } } else if (attRecevieConfigRspPtr->result == L2CAP_PENDING) { goto ATTRECVCONFIGRSP_END; } else { if (connecting->initPassConnFlag == INITIATIVECONNECT) { connecting->initiativeConnectStatus = DISCONNECTED; } else if (connecting->initPassConnFlag == PASSIVECONNECT) { connecting->passiveConnectSatatus = DISCONNECTED; } AttConnectCompletedCallback(connecting, BREDR_CONNECT_FAIL); } ATTRECVCONFIGRSP_END: MEM_MALLOC.free(attRecevieConfigRspPtr->info); MEM_MALLOC.free(attRecevieConfigRspPtr); return; } /** * @brief receive config response async destroy. * * @param ctx Indicates the pointer to context. */ static void AttReceiveConfigRspAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttReceiveConfigRspContext *attRecevieConfigRspPtr = (AttReceiveConfigRspContext *)context; MEM_MALLOC.free(attRecevieConfigRspPtr->info); MEM_MALLOC.free(attRecevieConfigRspPtr); return; } /** * @brief receive config response. * * @param1 lcid Indicates the lcid. * @param2 cfg Indicates the pointer to const L2capConfigInfo. * @param3 result Indicates the result. * @param4 ctx Indicates the pointer to context. */ void AttReceiveConfigRsp(uint16_t lcid, const L2capConfigInfo *cfg, uint16_t result, const void *ctx) { LOG_INFO("%{public}s enter, lcid = %hu, mtu = %hu, flushTimeout = %hu, mode = %hhu, result = %hu", __FUNCTION__, lcid, cfg->mtu, cfg->flushTimeout, cfg->rfc.mode, result); L2capConfigInfo *configInfoPtr = NULL; AttReceiveConfigRspContext *attRecevieConfigRspPtr = NULL; configInfoPtr = MEM_MALLOC.alloc(sizeof(L2capConfigInfo)); if (configInfoPtr == NULL) { LOG_ERROR("point to NULL"); return; } (void)memcpy_s(configInfoPtr, sizeof(L2capConfigInfo), cfg, sizeof(L2capConfigInfo)); attRecevieConfigRspPtr = MEM_MALLOC.alloc(sizeof(AttReceiveConfigRspContext)); if (attRecevieConfigRspPtr == NULL) { LOG_ERROR("point to NULL"); return; } attRecevieConfigRspPtr->lcid = lcid; attRecevieConfigRspPtr->info = configInfoPtr; attRecevieConfigRspPtr->result = result; attRecevieConfigRspPtr->ctx = (void *)ctx; AttAsyncProcess(AttReceiveConfigRspAsync, AttReceiveConfigRspAsyncDestroy, attRecevieConfigRspPtr); return; } /** * @brief receive disconnect req async. * * @param1 ctx Indicates the pointer to context. */ static void AttReceiveDisconnectionReqAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttReceiveDisconnectReqContext *attRecDisReqPtr = NULL; attRecDisReqPtr = (AttReceiveDisconnectReqContext *)context; L2CIF_DisconnectionRsp(attRecDisReqPtr->lcid, attRecDisReqPtr->id, DisconnectRespCallback); MEM_MALLOC.free(attRecDisReqPtr); return; } /** * @brief receive disconnect req async destroy. * * @param1 ctx Indicates the pointer to context. */ static void AttReceiveDisconnectionReqAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttReceiveDisconnectReqContext *attRecDisReqPtr = NULL; attRecDisReqPtr = (AttReceiveDisconnectReqContext *)context; MEM_MALLOC.free(attRecDisReqPtr); return; } /** * @brief receive disconnect request. * * @param1 lcid Indicates the lcid. * @param2 id Indicates the id. * @param3 ctx Indicates the pointer to context. */ void AttReceiveDisconnectionReq(uint16_t lcid, uint8_t id, const void *ctx) { LOG_INFO("%{public}s enter, lcid = %hu, id = %hhu", __FUNCTION__, lcid, id); AttReceiveDisconnectReqContext *attRecDisReqPtr = NULL; attRecDisReqPtr = MEM_MALLOC.alloc(sizeof(AttReceiveDisconnectReqContext)); if (attRecDisReqPtr == NULL) { LOG_ERROR("point to NULL"); return; } attRecDisReqPtr->lcid = lcid; attRecDisReqPtr->id = id; attRecDisReqPtr->ctx = (void *)ctx; AttAsyncProcess(AttReceiveDisconnectionReqAsync, AttReceiveDisconnectionReqAsyncDestroy, attRecDisReqPtr); return; } /** * @brief receive disconnect abnormal async. * * @param ctx Indicates the pointer to context. */ static void AttDisconnectAbnormalAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttDisconnectAbnormalContext *attDisconnectAbnormalPtr = (AttDisconnectAbnormalContext *)context; AttBredrDisconnectCallback bredrDisConnObj; int listSize; AttConnectedCallback *attConnectCallback = NULL; AttConnectInfo *connect = NULL; if (attDisconnectAbnormalPtr->reason == L2CAP_STATE_COLLISION) { AttConnectingInfo *connecting = NULL; GapRequestSecurityParam gapReqSecurity; AttGetConnectingIndexByCid(attDisconnectAbnormalPtr->lcid, &connecting); if (connecting == NULL) { goto ATTDISCONNECTABNORMAL_END; } connecting->cid = 0; AttAssignGAPRequestSecurity(&gapReqSecurity, OUTGOING, connecting); GAPIF_RequestSecurityAsync(&(connecting->addr), &gapReqSecurity); } AttGetConnectInfoIndexByCid(attDisconnectAbnormalPtr->lcid, &connect); if (connect == NULL) { goto ATTDISCONNECTABNORMAL_END; } AlarmCancel(connect->alarm); attConnectCallback = AttGetATTConnectCallback(); if ((attConnectCallback == NULL) || (attConnectCallback->attConnect.attBREDRDisconnectCompleted == NULL)) { LOG_WARN("%{public}s attConnectCallback or attBREDRDisconnectCompleted is NULL", __FUNCTION__); } else { bredrDisConnObj.reason = DISCONNECT_ABNORMAL; attConnectCallback->attConnect.attBREDRDisconnectCompleted( connect->retGattConnectHandle, &bredrDisConnObj, attConnectCallback->context); } listSize = ListGetSize(connect->instruct); for (; listSize > 0; --listSize) { ListRemoveLast(connect->instruct); } AttClearConnectInfo(connect); ATTDISCONNECTABNORMAL_END: MEM_MALLOC.free(attDisconnectAbnormalPtr); return; } /** * @brief receive disconnect abnormal async destroy. * * @param ctx Indicates the pointer to context. */ static void AttDisconnectAbnormalAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttDisconnectAbnormalContext *attDisconnectAbnormalPtr = (AttDisconnectAbnormalContext *)context; MEM_MALLOC.free(attDisconnectAbnormalPtr); return; } /** * @brief receive disconnect abnormal. * * @param1 lcid Indicates the lcid. * @param2 reason Indicates the reason. * @param3 ctx Indicates the pointer to context. */ void AttDisconnectAbnormal(uint16_t lcid, uint8_t reason, const void *ctx) { LOG_INFO("%{public}s enter,lcid = %hu, reason = %hhu", __FUNCTION__, lcid, reason); AttDisconnectAbnormalContext *attDisconnectAbnormalPtr = MEM_MALLOC.alloc(sizeof(AttDisconnectAbnormalContext)); if (attDisconnectAbnormalPtr == NULL) { LOG_ERROR("point to NULL"); return; } attDisconnectAbnormalPtr->lcid = lcid; attDisconnectAbnormalPtr->reason = reason; attDisconnectAbnormalPtr->ctx = (void *)ctx; AttAsyncProcess(AttDisconnectAbnormalAsync, AttDisconnectAbnormalAsyncDestroy, attDisconnectAbnormalPtr); return; } /** * @brief receive disconnect response async. * * @param2 ctx Indicates the pointer to context. */ static void AttRecvDisconnectionRspAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttRecvDisconnectionRspContext *attRecvDisconnRspPtr = (AttRecvDisconnectionRspContext *)context; AttBredrDisconnectCallback bredrDisConnObj; int listSize; AttConnectInfo *connect = NULL; AttConnectedCallback *attConnectCallback = NULL; AttGetConnectInfoIndexByCid(attRecvDisconnRspPtr->lcid, &connect); if (connect == NULL) { goto ATTRECVDISCONNECTIONRSP_END; } attConnectCallback = AttGetATTConnectCallback(); AlarmCancel(connect->alarm); if ((attConnectCallback == NULL) || (attConnectCallback->attConnect.attBREDRDisconnectCompleted == NULL)) { LOG_WARN("%{public}s attConnectCallback or attBREDRDisconnectCompleted is NULL", __FUNCTION__); } else { bredrDisConnObj.reason = INITIATIVECONNECT_DISCONNECT_SUCCESS; attConnectCallback->attConnect.attBREDRDisconnectCompleted( connect->retGattConnectHandle, &bredrDisConnObj, attConnectCallback->context); } listSize = ListGetSize(connect->instruct); for (; listSize > 0; --listSize) { ListRemoveLast(connect->instruct); } AttClearConnectInfo(connect); ATTRECVDISCONNECTIONRSP_END: MEM_MALLOC.free(attRecvDisconnRspPtr); return; } /** * @brief receive disconnect response async destroy. * * @param2 ctx Indicates the pointer to context. */ static void AttRecvDisconnectionRspAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttRecvDisconnectionRspContext *attRecvDisconnRspPtr = (AttRecvDisconnectionRspContext *)context; MEM_MALLOC.free(attRecvDisconnRspPtr); return; } /** * @brief receive disconnect response. * * @param1 lcid Indicates the lcid. * @param2 ctx Indicates the pointer to context. */ void AttRecvDisconnectionRsp(uint16_t lcid, const void *ctx) { LOG_INFO("%{public}s enter,lcid = %hu", __FUNCTION__, lcid); AttRecvDisconnectionRspContext *attRecvDisconnRspPtr = MEM_MALLOC.alloc(sizeof(AttRecvDisconnectionRspContext)); if (attRecvDisconnRspPtr == NULL) { LOG_ERROR("point to NULL"); return; } attRecvDisconnRspPtr->lcid = lcid; attRecvDisconnRspPtr->ctx = (void *)ctx; AttAsyncProcess(AttRecvDisconnectionRspAsync, AttRecvDisconnectionRspAsyncDestroy, attRecvDisconnRspPtr); return; } /** * @brief receive configrsp callback async. * * @param ctx Indicates the pointer to context. */ static void L2cifConfigRspCallbackAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConfigRspCallbackContext *configRspPtr = (ConfigRspCallbackContext *)context; AttConnectingInfo *connecting = NULL; uint8_t outPara = 0; int ret; AttGetConnectingIndexByCid(configRspPtr->lcid, &connecting); if (connecting == NULL) { goto L2CIFCONFIGRSPCALLBACK_END; } if (configRspPtr->result == BT_SUCCESS) { if (connecting->initPassConnFlag == INITIATIVECONNECT) { ret = AttBredrConnectStatusChange(connecting->initiativeConnectStatus, &outPara, INITIATIVECONNECT); if (ret == BT_OPERATION_FAILED) { AttConnectCompletedCallback(connecting, BREDR_CONNECT_FAIL); goto L2CIFCONFIGRSPCALLBACK_END; } connecting->initiativeConnectStatus = outPara; if (connecting->initiativeConnectStatus == CONNECTED) { AttConnectCompletedCallback(connecting, BREDR_CONNECT_SUCCESS); } } else if (connecting->initPassConnFlag == PASSIVECONNECT) { ret = AttBredrConnectStatusChange(connecting->passiveConnectSatatus, &outPara, PASSIVECONNECT); if (ret == BT_OPERATION_FAILED) { AttConnectCompletedCallback(connecting, BREDR_CONNECT_FAIL); goto L2CIFCONFIGRSPCALLBACK_END; } connecting->passiveConnectSatatus = outPara; if (connecting->passiveConnectSatatus == CONNECTED) { AttConnectCompletedCallback(connecting, BREDR_CONNECT_SUCCESS); } } } else { AttConnectCompletedCallback(connecting, BREDR_CONNECT_FAIL); } L2CIFCONFIGRSPCALLBACK_END: MEM_MALLOC.free(configRspPtr); return; } /** * @brief receive configrsp callback async destroy. * * @param ctx Indicates the pointer to context. */ static void L2cifConfigRspCallbackAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConfigRspCallbackContext *configRspPtr = (ConfigRspCallbackContext *)context; MEM_MALLOC.free(configRspPtr); return; } /** * @brief receive configrsp callback. * * @param1 lcid Indicates the lcid. * @param2 result Indicates the result. */ static void L2cifConfigRspCallback(uint16_t lcid, int result) { LOG_INFO("%{public}s enter,lcid = %hu, result = %{public}d", __FUNCTION__, lcid, result); ConfigRspCallbackContext *configRspPtr = MEM_MALLOC.alloc(sizeof(ConfigRspCallbackContext)); if (configRspPtr == NULL) { LOG_ERROR("point to NULL"); return; } configRspPtr->lcid = lcid; configRspPtr->result = result; AttAsyncProcess(L2cifConfigRspCallbackAsync, L2cifConfigRspCallbackAsyncDestroy, configRspPtr); return; } /** * @brief receive Config request async. * * @param ctx Indicates the pointer to context. */ static void AttReceiveConfigReqAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttReceiveConfigReqContext *attRecevieConfigReqPtr = (AttReceiveConfigReqContext *)context; AttConnectingInfo *connecting = NULL; AttGetConnectingIndexByCid(attRecevieConfigReqPtr->lcid, &connecting); if (connecting == NULL) { L2CIF_ConfigRsp(attRecevieConfigReqPtr->lcid, attRecevieConfigReqPtr->id, attRecevieConfigReqPtr->cfg, L2CAP_REJECTED, NULL); AttConnectCompletedCallback(connecting, BREDR_CONNECT_FAIL); goto ATTRECVCONFIGREQ_END; } AttRecvConfigReqAssignBredrConnect(attRecevieConfigReqPtr->cfg, connecting); if (attRecevieConfigReqPtr->cfg->rfc.mode != L2CAP_BASIC_MODE) { L2CIF_ConfigRsp( connecting->cid, attRecevieConfigReqPtr->id, &(connecting->remotel2capConfigInfoObj), L2CAP_REJECTED, NULL); goto ATTRECVCONFIGREQ_END; } L2CIF_ConfigRsp(connecting->cid, attRecevieConfigReqPtr->id, &(connecting->remotel2capConfigInfoObj), L2CAP_SUCCESS, L2cifConfigRspCallback); ATTRECVCONFIGREQ_END: MEM_MALLOC.free(attRecevieConfigReqPtr->cfg); MEM_MALLOC.free(attRecevieConfigReqPtr); return; } /** * @brief receive Config request async destroy. * * @param ctx Indicates the pointer to context. */ static void AttReceiveConfigReqAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttReceiveConfigReqContext *attRecevieConfigReqPtr = (AttReceiveConfigReqContext *)context; MEM_MALLOC.free(attRecevieConfigReqPtr->cfg); MEM_MALLOC.free(attRecevieConfigReqPtr); return; } /** * @brief receive disconnect response. * * @param1 lcid Indicates the lcid. * @param2 id Indicates the id. * @param3 cfg Indicates the pointer to const L2capConfigInfo. * @param4 ctx Indicates the pointer to context. */ void AttReceiveConfigReq(uint16_t lcid, uint8_t id, const L2capConfigInfo *cfg, const void *ctx) { LOG_INFO("%{public}s enter,lcid = %hu, id = %hhu, mtu = %hu, flushTimeout = %hu, mode = %hhu", __FUNCTION__, lcid, id, cfg->mtu, cfg->flushTimeout, cfg->rfc.mode); L2capConfigInfo *configInfoPtr = NULL; AttReceiveConfigReqContext *attRecevieConfigReqPtr = NULL; configInfoPtr = MEM_MALLOC.alloc(sizeof(L2capConfigInfo)); if (configInfoPtr == NULL) { LOG_ERROR("point to NULL"); return; } (void)memcpy_s(configInfoPtr, sizeof(L2capConfigInfo), cfg, sizeof(L2capConfigInfo)); attRecevieConfigReqPtr = MEM_MALLOC.alloc(sizeof(AttReceiveConfigReqContext)); attRecevieConfigReqPtr->lcid = lcid; attRecevieConfigReqPtr->id = id; attRecevieConfigReqPtr->cfg = configInfoPtr; attRecevieConfigReqPtr->ctx = (void *)ctx; AttAsyncProcess(AttReceiveConfigReqAsync, AttReceiveConfigReqAsyncDestroy, attRecevieConfigReqPtr); return; } /** * @brief Initiative disconnect. * * @param1 connectHandle Att connectinfo handle. */ void InitiativeDisconnect(uint16_t connectHandle) { LOG_DEBUG("%{public}s enter", __FUNCTION__); uint16_t transportType; uint16_t index = 0; AttConnectInfo *connect = NULL; AttConnectingInfo *connecting = NULL; AttGetConnectInfoIndexByConnectHandle(connectHandle, &index, &connect); if (connect == NULL) { LOG_WARN("InitiativeDisconnect connect == NULL"); return; } transportType = connect->transportType; if (transportType == BT_TRANSPORT_BR_EDR) { AttGetConnectingIndexByAddrAclhandleCid( &(connect->addr), connect->aclHandle, connect->AttConnectID.bredrcid, &connecting); } else { AttGetConnectingIndexByAddrAclhandleCid( &(connect->addr), connect->aclHandle, connect->AttConnectID.lecid, &connecting); } if (connecting != NULL) { if (transportType == BT_TRANSPORT_BR_EDR) { AlarmCancel(connecting->bredrAlarm); } } if (transportType == BT_TRANSPORT_BR_EDR) { L2CIF_DisconnectionReq(connect->AttConnectID.bredrcid, L2cifBREDRDisconnectReqCallBack); } else if (transportType == BT_TRANSPORT_LE) { L2CIF_LeDisconnect(connect->aclHandle, LeDisconnectReqCallback); } return; } static void AttLeConnectCancelAsyn(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttConnectingInfo *connecting = NULL; ConnectCancelContext *connectCancelPtr = (ConnectCancelContext *)context; AttGetConnectingIndexByAddr(&connectCancelPtr->addr, &connecting); if (connecting != NULL) { AttClearConnectingInfo(connecting); } L2CIF_LeConnectCancel(&connectCancelPtr->addr); MEM_MALLOC.free(connectCancelPtr); return; } static void AttLeConnectCancelAsyndestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); ConnectCancelContext *connectCancelPtr = (ConnectCancelContext *)context; MEM_MALLOC.free(connectCancelPtr); } int ATT_LeConnectCancel(const BtAddr *addr) { LOG_INFO("%{public}s enter", __FUNCTION__); if (addr == NULL) { return BT_BAD_PARAM; } ConnectCancelContext *context = MEM_MALLOC.alloc(sizeof(ConnectCancelContext)); if (context == NULL) { return BT_NO_MEMORY; } context->addr.type = addr->type; (void)memcpy_s(context->addr.addr, ADDRESSLEN, addr->addr, ADDRESSLEN); AttAsyncProcess(AttLeConnectCancelAsyn, AttLeConnectCancelAsyndestroy, context); return BT_SUCCESS; }