1 /*
2 * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "common/bt_target.h"
8 #include <string.h>
9 #include "esp_bt_main.h"
10 #include "esp_gap_bt_api.h"
11 #include "common/bt_trace.h"
12 #include "bta/bta_api.h"
13 #include "btc/btc_manage.h"
14 #include "btc_gap_bt.h"
15 #include "btc/btc_storage.h"
16
17 #if (BTC_GAP_BT_INCLUDED == TRUE)
18
esp_bt_gap_register_callback(esp_bt_gap_cb_t callback)19 esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback)
20 {
21 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
22 return ESP_ERR_INVALID_STATE;
23 }
24
25 if (callback == NULL) {
26 return ESP_FAIL;
27 }
28
29 btc_profile_cb_set(BTC_PID_GAP_BT, callback);
30 return ESP_OK;
31 }
32
esp_bt_gap_set_scan_mode(esp_bt_connection_mode_t c_mode,esp_bt_discovery_mode_t d_mode)33 esp_err_t esp_bt_gap_set_scan_mode(esp_bt_connection_mode_t c_mode, esp_bt_discovery_mode_t d_mode)
34 {
35 btc_msg_t msg;
36 btc_gap_bt_args_t arg;
37
38 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
39 return ESP_ERR_INVALID_STATE;
40 }
41
42 msg.sig = BTC_SIG_API_CALL;
43 msg.pid = BTC_PID_GAP_BT;
44 msg.act = BTC_GAP_BT_ACT_SET_SCAN_MODE;
45 arg.set_scan_mode.c_mode = c_mode;
46 arg.set_scan_mode.d_mode = d_mode;
47
48 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
49 }
50
esp_bt_gap_start_discovery(esp_bt_inq_mode_t mode,uint8_t inq_len,uint8_t num_rsps)51 esp_err_t esp_bt_gap_start_discovery(esp_bt_inq_mode_t mode, uint8_t inq_len, uint8_t num_rsps)
52 {
53 btc_msg_t msg;
54 btc_gap_bt_args_t arg;
55
56 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
57 return ESP_ERR_INVALID_STATE;
58 }
59
60 if (mode != ESP_BT_INQ_MODE_GENERAL_INQUIRY &&
61 mode != ESP_BT_INQ_MODE_LIMITED_INQUIRY) {
62 return ESP_ERR_INVALID_ARG;
63 }
64
65 if (inq_len < ESP_BT_GAP_MIN_INQ_LEN ||
66 inq_len > ESP_BT_GAP_MAX_INQ_LEN) {
67 return ESP_ERR_INVALID_ARG;
68 }
69
70 msg.sig = BTC_SIG_API_CALL;
71 msg.pid = BTC_PID_GAP_BT;
72 msg.act = BTC_GAP_BT_ACT_START_DISCOVERY;
73
74 arg.start_disc.mode = mode;
75 arg.start_disc.inq_len = inq_len;
76 arg.start_disc.num_rsps = num_rsps;
77
78 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
79 }
80
esp_bt_gap_cancel_discovery(void)81 esp_err_t esp_bt_gap_cancel_discovery(void)
82 {
83 btc_msg_t msg;
84
85 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
86 return ESP_ERR_INVALID_STATE;
87 }
88
89 msg.sig = BTC_SIG_API_CALL;
90 msg.pid = BTC_PID_GAP_BT;
91 msg.act = BTC_GAP_BT_ACT_CANCEL_DISCOVERY;
92
93 return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
94 }
95
esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda)96 esp_err_t esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda)
97 {
98 btc_msg_t msg;
99 btc_gap_bt_args_t arg;
100
101 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
102 return ESP_ERR_INVALID_STATE;
103 }
104
105 msg.sig = BTC_SIG_API_CALL;
106 msg.pid = BTC_PID_GAP_BT;
107 msg.act = BTC_GAP_BT_ACT_GET_REMOTE_SERVICES;
108
109 memcpy(&arg.bda, remote_bda, sizeof(bt_bdaddr_t));
110 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
111 }
112
esp_bt_gap_get_remote_service_record(esp_bd_addr_t remote_bda,esp_bt_uuid_t * uuid)113 esp_err_t esp_bt_gap_get_remote_service_record(esp_bd_addr_t remote_bda, esp_bt_uuid_t *uuid)
114 {
115 btc_msg_t msg;
116 btc_gap_bt_args_t arg;
117
118 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
119 return ESP_ERR_INVALID_STATE;
120 }
121
122 msg.sig = BTC_SIG_API_CALL;
123 msg.pid = BTC_PID_GAP_BT;
124 msg.act = BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD;
125
126 memcpy(&arg.get_rmt_srv_rcd.bda, remote_bda, sizeof(bt_bdaddr_t));
127 memcpy(&arg.get_rmt_srv_rcd.uuid, uuid, sizeof(esp_bt_uuid_t));
128 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
129 }
130
esp_bt_gap_resolve_eir_data(uint8_t * eir,esp_bt_eir_type_t type,uint8_t * length)131 uint8_t *esp_bt_gap_resolve_eir_data(uint8_t *eir, esp_bt_eir_type_t type, uint8_t *length)
132 {
133 if (!eir) {
134 return NULL;
135 }
136
137 return BTM_CheckEirData(eir, type, length);
138 }
139
esp_bt_gap_config_eir_data(esp_bt_eir_data_t * eir_data)140 esp_err_t esp_bt_gap_config_eir_data(esp_bt_eir_data_t *eir_data)
141 {
142 btc_msg_t msg;
143 btc_gap_bt_args_t arg;
144
145 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
146 return ESP_ERR_INVALID_STATE;
147 }
148
149 if (eir_data == NULL) {
150 return ESP_ERR_INVALID_ARG;
151 }
152
153 if (eir_data->manufacturer_len > ESP_BT_EIR_MAX_LEN
154 || eir_data->url_len > ESP_BT_EIR_MAX_LEN) {
155 return ESP_ERR_INVALID_ARG;
156 }
157
158 if ((eir_data->manufacturer_len > 0 && eir_data->p_manufacturer_data == NULL)
159 || (eir_data->url_len > 0 && eir_data->p_url == NULL)) {
160 return ESP_ERR_INVALID_ARG;
161 }
162
163 msg.sig = BTC_SIG_API_CALL;
164 msg.pid = BTC_PID_GAP_BT;
165 msg.act = BTC_GAP_BT_ACT_CONFIG_EIR;
166
167 memcpy(&arg.config_eir, eir_data, sizeof(esp_bt_eir_data_t));
168
169 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy,
170 btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
171 }
172
esp_bt_gap_set_cod(esp_bt_cod_t cod,esp_bt_cod_mode_t mode)173 esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode)
174 {
175 btc_msg_t msg;
176 btc_gap_bt_args_t arg;
177
178 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
179 return ESP_ERR_INVALID_STATE;
180 }
181
182 switch (mode) {
183 case ESP_BT_SET_COD_RESERVED_2:
184 case ESP_BT_SET_COD_MAJOR_MINOR:
185 case ESP_BT_SET_COD_SERVICE_CLASS:
186 case ESP_BT_CLR_COD_SERVICE_CLASS:
187 case ESP_BT_SET_COD_ALL:
188 case ESP_BT_INIT_COD:
189 break;
190 default:
191 return ESP_ERR_INVALID_ARG;
192 break;
193 }
194
195 msg.sig = BTC_SIG_API_CALL;
196 msg.pid = BTC_PID_GAP_BT;
197 msg.act = BTC_GAP_BT_ACT_SET_COD;
198
199 arg.set_cod.mode = mode;
200 memcpy(&arg.set_cod.cod, &cod, sizeof(esp_bt_cod_t));
201 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
202 }
203
204
esp_bt_gap_get_cod(esp_bt_cod_t * cod)205 esp_err_t esp_bt_gap_get_cod(esp_bt_cod_t *cod)
206 {
207 return btc_gap_bt_get_cod(cod);
208 }
209
210
esp_bt_gap_read_rssi_delta(esp_bd_addr_t remote_addr)211 esp_err_t esp_bt_gap_read_rssi_delta(esp_bd_addr_t remote_addr)
212 {
213 btc_msg_t msg;
214 btc_gap_bt_args_t arg;
215 msg.sig = BTC_SIG_API_CALL;
216 msg.pid = BTC_PID_GAP_BT;
217 msg.act = BTC_GAP_BT_ACT_READ_RSSI_DELTA;
218 memcpy(arg.read_rssi_delta.bda.address, remote_addr, sizeof(esp_bd_addr_t));
219
220 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
221 }
222
esp_bt_gap_remove_bond_device(esp_bd_addr_t bd_addr)223 esp_err_t esp_bt_gap_remove_bond_device(esp_bd_addr_t bd_addr)
224 {
225 btc_msg_t msg;
226 btc_gap_bt_args_t arg;
227
228 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
229 return ESP_ERR_INVALID_STATE;
230 }
231
232 msg.sig = BTC_SIG_API_CALL;
233 msg.pid = BTC_PID_GAP_BT;
234 msg.act = BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE;
235
236 memcpy(arg.rm_bond_device.bda.address, bd_addr, sizeof(esp_bd_addr_t));
237 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
238 }
239
esp_bt_gap_get_bond_device_num(void)240 int esp_bt_gap_get_bond_device_num(void)
241 {
242 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
243 return ESP_ERR_INVALID_STATE;
244 }
245 return btc_storage_get_num_bt_bond_devices();
246 }
247
esp_bt_gap_get_bond_device_list(int * dev_num,esp_bd_addr_t * dev_list)248 esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list)
249 {
250 int ret;
251
252 if (dev_num == NULL || dev_list == NULL) {
253 return ESP_ERR_INVALID_ARG;
254 }
255
256 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
257 return ESP_ERR_INVALID_STATE;
258 }
259
260 ret = btc_storage_get_bonded_bt_devices_list((bt_bdaddr_t *)dev_list, dev_num);
261
262 return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
263 }
264
esp_bt_gap_set_pin(esp_bt_pin_type_t pin_type,uint8_t pin_code_len,esp_bt_pin_code_t pin_code)265 esp_err_t esp_bt_gap_set_pin(esp_bt_pin_type_t pin_type, uint8_t pin_code_len, esp_bt_pin_code_t pin_code)
266 {
267 btc_msg_t msg;
268 btc_gap_bt_args_t arg;
269
270 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
271 return ESP_ERR_INVALID_STATE;
272 }
273
274 msg.sig = BTC_SIG_API_CALL;
275 msg.pid = BTC_PID_GAP_BT;
276 msg.act = BTC_GAP_BT_ACT_SET_PIN_TYPE;
277 arg.set_pin_type.pin_type = pin_type;
278 if (pin_type == ESP_BT_PIN_TYPE_FIXED){
279 arg.set_pin_type.pin_code_len = pin_code_len;
280 memcpy(arg.set_pin_type.pin_code, pin_code, pin_code_len);
281 } else {
282 arg.set_pin_type.pin_code_len = 0;
283 memset(arg.set_pin_type.pin_code, 0, ESP_BT_PIN_CODE_LEN);
284 }
285
286 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy,
287 btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
288 }
289
esp_bt_gap_pin_reply(esp_bd_addr_t bd_addr,bool accept,uint8_t pin_code_len,esp_bt_pin_code_t pin_code)290 esp_err_t esp_bt_gap_pin_reply(esp_bd_addr_t bd_addr, bool accept, uint8_t pin_code_len, esp_bt_pin_code_t pin_code)
291 {
292 btc_msg_t msg;
293 btc_gap_bt_args_t arg;
294
295 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
296 return ESP_ERR_INVALID_STATE;
297 }
298
299 msg.sig = BTC_SIG_API_CALL;
300 msg.pid = BTC_PID_GAP_BT;
301 msg.act = BTC_GAP_BT_ACT_PIN_REPLY;
302 arg.pin_reply.accept = accept;
303 arg.pin_reply.pin_code_len = pin_code_len;
304 memcpy(arg.pin_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
305 memcpy(arg.pin_reply.pin_code, pin_code, pin_code_len);
306
307 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy,
308 btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
309 }
310
311 #if (BT_SSP_INCLUDED == TRUE)
esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,void * value,uint8_t len)312 esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
313 void *value, uint8_t len)
314 {
315 btc_msg_t msg;
316 btc_gap_bt_args_t arg;
317
318 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
319 return ESP_ERR_INVALID_STATE;
320 }
321
322 msg.sig = BTC_SIG_API_CALL;
323 msg.pid = BTC_PID_GAP_BT;
324 msg.act = BTC_GAP_BT_ACT_SET_SECURITY_PARAM;
325 arg.set_security_param.param_type = param_type;
326 arg.set_security_param.len = len;
327 arg.set_security_param.value = value;
328
329 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy,
330 btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
331 }
332
esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr,bool accept,uint32_t passkey)333 esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey)
334 {
335 btc_msg_t msg;
336 btc_gap_bt_args_t arg;
337
338 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
339 return ESP_ERR_INVALID_STATE;
340 }
341
342 msg.sig = BTC_SIG_API_CALL;
343 msg.pid = BTC_PID_GAP_BT;
344 msg.act = BTC_GAP_BT_ACT_PASSKEY_REPLY;
345 arg.passkey_reply.accept = accept;
346 arg.passkey_reply.passkey = passkey;
347 memcpy(arg.passkey_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
348 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy,
349 btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
350 }
351
esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr,bool accept)352 esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
353 {
354 btc_msg_t msg;
355 btc_gap_bt_args_t arg;
356
357 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
358 return ESP_ERR_INVALID_STATE;
359 }
360
361 msg.sig = BTC_SIG_API_CALL;
362 msg.pid = BTC_PID_GAP_BT;
363 msg.act = BTC_GAP_BT_ACT_CONFIRM_REPLY;
364 arg.confirm_reply.accept = accept;
365 memcpy(arg.confirm_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
366 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy,
367 btc_gap_bt_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
368 }
369
370 #endif /*(BT_SSP_INCLUDED == TRUE)*/
371
esp_bt_gap_set_afh_channels(esp_bt_gap_afh_channels channels)372 esp_err_t esp_bt_gap_set_afh_channels(esp_bt_gap_afh_channels channels)
373 {
374 btc_msg_t msg;
375 btc_gap_bt_args_t arg;
376
377 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
378 return ESP_ERR_INVALID_STATE;
379 }
380
381 msg.sig = BTC_SIG_API_CALL;
382 msg.pid = BTC_PID_GAP_BT;
383 msg.act = BTC_GAP_BT_ACT_SET_AFH_CHANNELS;
384
385 memcpy(&arg.set_afh_channels.channels, channels, ESP_BT_GAP_AFH_CHANNELS_LEN);
386 arg.set_afh_channels.channels[ESP_BT_GAP_AFH_CHANNELS_LEN -1] &= 0x7F;
387 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
388 }
389
esp_bt_gap_read_remote_name(esp_bd_addr_t remote_bda)390 esp_err_t esp_bt_gap_read_remote_name(esp_bd_addr_t remote_bda)
391 {
392 btc_msg_t msg;
393 btc_gap_bt_args_t arg;
394
395 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
396 return ESP_ERR_INVALID_STATE;
397 }
398
399 msg.sig = BTC_SIG_API_CALL;
400 msg.pid = BTC_PID_GAP_BT;
401 msg.act = BTC_GAP_BT_ACT_READ_REMOTE_NAME;
402
403 memcpy(&arg.rmt_name_bda, remote_bda, sizeof(bt_bdaddr_t));
404 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
405 }
406
esp_bt_gap_set_qos(esp_bd_addr_t remote_bda,uint32_t t_poll)407 esp_err_t esp_bt_gap_set_qos(esp_bd_addr_t remote_bda, uint32_t t_poll)
408 {
409 btc_msg_t msg;
410 btc_gap_bt_args_t arg;
411
412 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
413 return ESP_ERR_INVALID_STATE;
414 }
415
416 if (t_poll < ESP_BT_GAP_TPOLL_MIN || t_poll > ESP_BT_GAP_TPOLL_MAX) {
417 return ESP_ERR_INVALID_ARG;
418 }
419
420 msg.sig = BTC_SIG_API_CALL;
421 msg.pid = BTC_PID_GAP_BT;
422 msg.act = BTC_GAP_BT_ACT_SET_QOS;
423
424 memcpy(&arg.set_qos.bda, remote_bda, sizeof(bt_bdaddr_t));
425 arg.set_qos.t_poll = t_poll;
426 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
427 }
428
esp_bt_gap_set_acl_pkt_types(esp_bd_addr_t remote_bda,uint16_t pkt_types)429 esp_err_t esp_bt_gap_set_acl_pkt_types(esp_bd_addr_t remote_bda, uint16_t pkt_types)
430 {
431 btc_msg_t msg;
432 btc_gap_bt_args_t arg;
433
434 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
435 return ESP_ERR_INVALID_STATE;
436 }
437
438 msg.sig = BTC_SIG_API_CALL;
439 msg.pid = BTC_PID_GAP_BT;
440 msg.act = BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES;
441
442 memcpy(&arg.set_acl_pkt_types.bda, remote_bda, sizeof(bt_bdaddr_t));
443 arg.set_acl_pkt_types.pkt_types = pkt_types;
444 return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
445 }
446
447 #endif /* #if BTC_GAP_BT_INCLUDED == TRUE */
448