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 = &param->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, &param->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(&param->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