/* * Copyright (C) 2021-2022 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. */ #include "gap_internal.h" #include "gap_task_internal.h" #include #include "allocator.h" #include "log.h" #include "btm.h" #include "btm/btm_acl.h" #include "btm/btm_thread.h" #ifdef GAP_BREDR_SUPPORT typedef struct { uint8_t status; uint16_t connectionHandle; BtAddr addr; uint8_t classOfDevice[BT_COD_SIZE]; bool encyptionEnabled; void *context; } GapAclConnectionCompleteParam; typedef struct { uint8_t status; uint16_t connectionHandle; uint8_t reason; void *context; } GapAclDisconnectionCompleteParam; typedef struct { BtAddr addr; bool support; } GapRemoteDeviceSupportCallbackParam; static void GapAclConnectionCompleteTask(void *ctx) { GapAclConnectionCompleteParam *param = ctx; BtmAclConnectCompleteParam btmParam = {.addr = ¶m->addr}; btmParam.status = param->status; btmParam.connectionHandle = param->connectionHandle; (void)memcpy_s( btmParam.classOfDevice, sizeof(btmParam.classOfDevice), param->classOfDevice, sizeof(param->classOfDevice)); btmParam.encyptionEnabled = param->encyptionEnabled; GapAclConnectionComplete(&btmParam, param->context); } static void GapRecvAclConnectionComplete(const BtmAclConnectCompleteParam *param, void *context) { LOG_INFO("%{public}s: status:0x%{public}02x handle:0x%{public}04x " BT_ADDR_FMT, __FUNCTION__, param->status, param->connectionHandle, BT_ADDR_FMT_OUTPUT(param->addr->addr)); GapAclConnectionCompleteParam *btmParam = MEM_MALLOC.alloc(sizeof(GapAclConnectionCompleteParam)); if (btmParam == NULL) { LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__); return; } btmParam->status = param->status; btmParam->connectionHandle = param->connectionHandle; btmParam->addr = *param->addr; (void)memcpy_s( btmParam->classOfDevice, sizeof(btmParam->classOfDevice), param->classOfDevice, sizeof(param->classOfDevice)); btmParam->encyptionEnabled = param->encyptionEnabled; btmParam->context = context; int ret = GapRunTaskUnBlockProcess(GapAclConnectionCompleteTask, btmParam, NULL); if (ret != BT_SUCCESS) { LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret); } } static void GapAclDisconnectionCompleteTask(void *ctx) { GapAclDisconnectionCompleteParam *param = ctx; GapAclDisconnectionComplete(param->status, param->connectionHandle, param->reason, param->context); } static void GapRecvAclDisconnectionComplete(uint8_t status, uint16_t connectionHandle, uint8_t reason, void *context) { LOG_INFO("%{public}s: status:0x%{public}02x handle:0x%{public}04x reason:0x%{public}02x", __FUNCTION__, status, connectionHandle, reason); GapAclDisconnectionCompleteParam *btmParam = MEM_MALLOC.alloc(sizeof(GapAclDisconnectionCompleteParam)); if (btmParam == NULL) { LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__); return; } btmParam->status = status; btmParam->connectionHandle = connectionHandle; btmParam->reason = reason; btmParam->context = context; int ret = GapRunTaskUnBlockProcess(GapAclDisconnectionCompleteTask, btmParam, NULL); if (ret != BT_SUCCESS) { LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret); } } #endif #ifdef GAP_LE_SUPPORT typedef struct { uint8_t status; uint16_t connectionHandle; BtAddr addr; uint8_t role; void *context; } GapLeConnectionCompleteParam; typedef struct { uint8_t status; uint16_t connectionHandle; uint8_t reason; void *context; } GapLeDisconnectionCompleteParam; static void GapLeConnectionCompleteTask(void *ctx) { GapLeConnectionCompleteParam *param = ctx; GapLeConnectionComplete(param->status, param->connectionHandle, ¶m->addr, param->role, param->context); } static void GapRecvLeConnectionComplete( uint8_t status, uint16_t connectionHandle, const BtAddr *addr, uint8_t role, void *context) { LOG_INFO("%{public}s: status:0x%{public}02x role:%{public}hhu handle:0x%{public}04x " BT_ADDR_FMT, __FUNCTION__, status, role, connectionHandle, BT_ADDR_FMT_OUTPUT(addr->addr)); GapLeConnectionCompleteParam *btmParam = MEM_MALLOC.alloc(sizeof(GapLeConnectionCompleteParam)); if (btmParam == NULL) { LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__); return; } btmParam->status = status; btmParam->connectionHandle = connectionHandle; btmParam->addr = *addr; btmParam->role = role; btmParam->context = context; int ret = GapRunTaskUnBlockProcess(GapLeConnectionCompleteTask, btmParam, NULL); if (ret != BT_SUCCESS) { LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret); } } static void GapLeDisconnectionCompleteTask(void *ctx) { GapLeDisconnectionCompleteParam *param = ctx; GapLeDisconnectionComplete(param->status, param->connectionHandle, param->reason, param->context); } static void GapRecvLeDisconnectionComplete(uint8_t status, uint16_t connectionHandle, uint8_t reason, void *context) { LOG_INFO("%{public}s: status:0x%{public}02x handle:0x%{public}04x reason:0x%{public}02x", __FUNCTION__, status, connectionHandle, reason); GapLeDisconnectionCompleteParam *btmParam = MEM_MALLOC.alloc(sizeof(GapLeDisconnectionCompleteParam)); if (btmParam == NULL) { LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__); return; } btmParam->status = status; btmParam->connectionHandle = connectionHandle; btmParam->reason = reason; btmParam->context = context; int ret = GapRunTaskUnBlockProcess(GapLeDisconnectionCompleteTask, btmParam, NULL); if (ret != BT_SUCCESS) { LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret); } } #endif static BtmAclCallbacks g_aclCallback = {0}; void GapRegisterBtmAclCallbacks(void) { #ifdef GAP_BREDR_SUPPORT g_aclCallback.connectionComplete = GapRecvAclConnectionComplete; g_aclCallback.disconnectionComplete = GapRecvAclDisconnectionComplete; #endif #ifdef GAP_LE_SUPPORT g_aclCallback.leConnectionComplete = GapRecvLeConnectionComplete; g_aclCallback.leDisconnectionComplete = GapRecvLeDisconnectionComplete; #endif BTM_RegisterAclCallbacks(&g_aclCallback, NULL); } void GapDeregisterBtmAclCallbacks(void) { BTM_DeregisterAclCallbacks(&g_aclCallback); } static void GapRemoteDeviceSupportHostSecureSimplePairingCallbackTask(void *ctx) { GapRemoteDeviceSupportCallbackParam *param = ctx; GapRemoteDeviceSupportHostSecureSimplePairingCallback(¶m->addr, param->support); } static void GapRecvRemoteDeviceSupportHostSecureSimplePairingCallback(const BtAddr *addr, bool support) { LOG_INFO("%{public}s: " BT_ADDR_FMT " support:%{public}d", __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr->addr), support); GapRemoteDeviceSupportCallbackParam *supportParam = MEM_MALLOC.alloc(sizeof(GapRemoteDeviceSupportCallbackParam)); if (supportParam == NULL) { LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__); return; } supportParam->addr = *addr; supportParam->support = support; int ret = GapRunTaskUnBlockProcess(GapRemoteDeviceSupportHostSecureSimplePairingCallbackTask, supportParam, NULL); if (ret != BT_SUCCESS) { LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret); } } void GapIsRemoteDeviceSupportHostSecureSimplePairingAsync(const BtAddr *addr) { BTM_IsRemoteDeviceSupportHostSecureSimplePairing(addr, GapRecvRemoteDeviceSupportHostSecureSimplePairingCallback); }