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