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