1 /*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "gap_internal.h"
17 #include "gap_task_internal.h"
18
19 #include <securec.h>
20
21 #include "allocator.h"
22 #include "log.h"
23
24 #include "btm.h"
25 #include "btm/btm_acl.h"
26 #include "btm/btm_thread.h"
27
28 #ifdef GAP_BREDR_SUPPORT
29
30 typedef struct {
31 uint8_t status;
32 uint16_t connectionHandle;
33 BtAddr addr;
34 uint8_t classOfDevice[BT_COD_SIZE];
35 bool encyptionEnabled;
36 void *context;
37 } GapAclConnectionCompleteParam;
38
39 typedef struct {
40 uint8_t status;
41 uint16_t connectionHandle;
42 uint8_t reason;
43 void *context;
44 } GapAclDisconnectionCompleteParam;
45
46 typedef struct {
47 BtAddr addr;
48 bool support;
49 } GapRemoteDeviceSupportCallbackParam;
50
GapAclConnectionCompleteTask(void * ctx)51 static void GapAclConnectionCompleteTask(void *ctx)
52 {
53 GapAclConnectionCompleteParam *param = ctx;
54 BtmAclConnectCompleteParam btmParam = {.addr = ¶m->addr};
55 btmParam.status = param->status;
56 btmParam.connectionHandle = param->connectionHandle;
57 (void)memcpy_s(
58 btmParam.classOfDevice, sizeof(btmParam.classOfDevice), param->classOfDevice, sizeof(param->classOfDevice));
59 btmParam.encyptionEnabled = param->encyptionEnabled;
60 GapAclConnectionComplete(&btmParam, param->context);
61 }
62
GapRecvAclConnectionComplete(const BtmAclConnectCompleteParam * param,void * context)63 static void GapRecvAclConnectionComplete(const BtmAclConnectCompleteParam *param, void *context)
64 {
65 LOG_INFO("%{public}s: status:0x%{public}02x handle:0x%{public}04x " BT_ADDR_FMT,
66 __FUNCTION__,
67 param->status,
68 param->connectionHandle,
69 BT_ADDR_FMT_OUTPUT(param->addr->addr));
70 GapAclConnectionCompleteParam *btmParam = MEM_MALLOC.alloc(sizeof(GapAclConnectionCompleteParam));
71 if (btmParam == NULL) {
72 LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
73 return;
74 }
75
76 btmParam->status = param->status;
77 btmParam->connectionHandle = param->connectionHandle;
78 btmParam->addr = *param->addr;
79 (void)memcpy_s(
80 btmParam->classOfDevice, sizeof(btmParam->classOfDevice), param->classOfDevice, sizeof(param->classOfDevice));
81 btmParam->encyptionEnabled = param->encyptionEnabled;
82 btmParam->context = context;
83
84 int ret = GapRunTaskUnBlockProcess(GapAclConnectionCompleteTask, btmParam, NULL);
85 if (ret != BT_SUCCESS) {
86 LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
87 }
88 }
89
GapAclDisconnectionCompleteTask(void * ctx)90 static void GapAclDisconnectionCompleteTask(void *ctx)
91 {
92 GapAclDisconnectionCompleteParam *param = ctx;
93 GapAclDisconnectionComplete(param->status, param->connectionHandle, param->reason, param->context);
94 }
95
GapRecvAclDisconnectionComplete(uint8_t status,uint16_t connectionHandle,uint8_t reason,void * context)96 static void GapRecvAclDisconnectionComplete(uint8_t status, uint16_t connectionHandle, uint8_t reason, void *context)
97 {
98 LOG_INFO("%{public}s: status:0x%{public}02x handle:0x%{public}04x reason:0x%{public}02x", __FUNCTION__,
99 status, connectionHandle, reason);
100 GapAclDisconnectionCompleteParam *btmParam = MEM_MALLOC.alloc(sizeof(GapAclDisconnectionCompleteParam));
101 if (btmParam == NULL) {
102 LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
103 return;
104 }
105
106 btmParam->status = status;
107 btmParam->connectionHandle = connectionHandle;
108 btmParam->reason = reason;
109 btmParam->context = context;
110
111 int ret = GapRunTaskUnBlockProcess(GapAclDisconnectionCompleteTask, btmParam, NULL);
112 if (ret != BT_SUCCESS) {
113 LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
114 }
115 }
116
117 #endif
118
119 #ifdef GAP_LE_SUPPORT
120
121 typedef struct {
122 uint8_t status;
123 uint16_t connectionHandle;
124 BtAddr addr;
125 uint8_t role;
126 void *context;
127 } GapLeConnectionCompleteParam;
128
129 typedef struct {
130 uint8_t status;
131 uint16_t connectionHandle;
132 uint8_t reason;
133 void *context;
134 } GapLeDisconnectionCompleteParam;
135
GapLeConnectionCompleteTask(void * ctx)136 static void GapLeConnectionCompleteTask(void *ctx)
137 {
138 GapLeConnectionCompleteParam *param = ctx;
139 GapLeConnectionComplete(param->status, param->connectionHandle, ¶m->addr, param->role, param->context);
140 }
141
GapRecvLeConnectionComplete(uint8_t status,uint16_t connectionHandle,const BtAddr * addr,uint8_t role,void * context)142 static void GapRecvLeConnectionComplete(
143 uint8_t status, uint16_t connectionHandle, const BtAddr *addr, uint8_t role, void *context)
144 {
145 LOG_INFO("%{public}s: status:0x%{public}02x role:%{public}hhu handle:0x%{public}04x " BT_ADDR_FMT,
146 __FUNCTION__,
147 status,
148 role,
149 connectionHandle,
150 BT_ADDR_FMT_OUTPUT(addr->addr));
151 GapLeConnectionCompleteParam *btmParam = MEM_MALLOC.alloc(sizeof(GapLeConnectionCompleteParam));
152 if (btmParam == NULL) {
153 LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
154 return;
155 }
156
157 btmParam->status = status;
158 btmParam->connectionHandle = connectionHandle;
159 btmParam->addr = *addr;
160 btmParam->role = role;
161 btmParam->context = context;
162
163 int ret = GapRunTaskUnBlockProcess(GapLeConnectionCompleteTask, btmParam, NULL);
164 if (ret != BT_SUCCESS) {
165 LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
166 }
167 }
168
GapLeDisconnectionCompleteTask(void * ctx)169 static void GapLeDisconnectionCompleteTask(void *ctx)
170 {
171 GapLeDisconnectionCompleteParam *param = ctx;
172 GapLeDisconnectionComplete(param->status, param->connectionHandle, param->reason, param->context);
173 }
174
GapRecvLeDisconnectionComplete(uint8_t status,uint16_t connectionHandle,uint8_t reason,void * context)175 static void GapRecvLeDisconnectionComplete(uint8_t status, uint16_t connectionHandle, uint8_t reason, void *context)
176 {
177 LOG_INFO("%{public}s: status:0x%{public}02x handle:0x%{public}04x reason:0x%{public}02x", __FUNCTION__,
178 status, connectionHandle, reason);
179 GapLeDisconnectionCompleteParam *btmParam = MEM_MALLOC.alloc(sizeof(GapLeDisconnectionCompleteParam));
180 if (btmParam == NULL) {
181 LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
182 return;
183 }
184
185 btmParam->status = status;
186 btmParam->connectionHandle = connectionHandle;
187 btmParam->reason = reason;
188 btmParam->context = context;
189
190 int ret = GapRunTaskUnBlockProcess(GapLeDisconnectionCompleteTask, btmParam, NULL);
191 if (ret != BT_SUCCESS) {
192 LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
193 }
194 }
195
196 #endif
197
198 static BtmAclCallbacks g_aclCallback = {0};
199
GapRegisterBtmAclCallbacks(void)200 void GapRegisterBtmAclCallbacks(void)
201 {
202 #ifdef GAP_BREDR_SUPPORT
203 g_aclCallback.connectionComplete = GapRecvAclConnectionComplete;
204 g_aclCallback.disconnectionComplete = GapRecvAclDisconnectionComplete;
205 #endif
206 #ifdef GAP_LE_SUPPORT
207 g_aclCallback.leConnectionComplete = GapRecvLeConnectionComplete;
208 g_aclCallback.leDisconnectionComplete = GapRecvLeDisconnectionComplete;
209 #endif
210 BTM_RegisterAclCallbacks(&g_aclCallback, NULL);
211 }
212
GapDeregisterBtmAclCallbacks(void)213 void GapDeregisterBtmAclCallbacks(void)
214 {
215 BTM_DeregisterAclCallbacks(&g_aclCallback);
216 }
217
GapRemoteDeviceSupportHostSecureSimplePairingCallbackTask(void * ctx)218 static void GapRemoteDeviceSupportHostSecureSimplePairingCallbackTask(void *ctx)
219 {
220 GapRemoteDeviceSupportCallbackParam *param = ctx;
221 GapRemoteDeviceSupportHostSecureSimplePairingCallback(¶m->addr, param->support);
222 }
223
GapRecvRemoteDeviceSupportHostSecureSimplePairingCallback(const BtAddr * addr,bool support)224 static void GapRecvRemoteDeviceSupportHostSecureSimplePairingCallback(const BtAddr *addr, bool support)
225 {
226 LOG_INFO("%{public}s: " BT_ADDR_FMT " support:%{public}d", __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr->addr), support);
227 GapRemoteDeviceSupportCallbackParam *supportParam = MEM_MALLOC.alloc(sizeof(GapRemoteDeviceSupportCallbackParam));
228 if (supportParam == NULL) {
229 LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
230 return;
231 }
232
233 supportParam->addr = *addr;
234 supportParam->support = support;
235
236 int ret = GapRunTaskUnBlockProcess(GapRemoteDeviceSupportHostSecureSimplePairingCallbackTask, supportParam, NULL);
237 if (ret != BT_SUCCESS) {
238 LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
239 }
240 }
241
GapIsRemoteDeviceSupportHostSecureSimplePairingAsync(const BtAddr * addr)242 void GapIsRemoteDeviceSupportHostSecureSimplePairingAsync(const BtAddr *addr)
243 {
244 BTM_IsRemoteDeviceSupportHostSecureSimplePairing(addr, GapRecvRemoteDeviceSupportHostSecureSimplePairingCallback);
245 }
246