Skip to content

Commit db09ca8

Browse files
committed
Make SimpleBLE work again
Fixes: espressif#373
1 parent b6e83fa commit db09ca8

File tree

3 files changed

+70
-282
lines changed

3 files changed

+70
-282
lines changed

libraries/SimpleBLE/src/SimpleBLE.cpp

+67-278
Original file line numberDiff line numberDiff line change
@@ -15,324 +15,113 @@
1515
#include "SimpleBLE.h"
1616
#include "esp32-hal-log.h"
1717

18-
/* HCI Command opcode group field(OGF) */
19-
#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */
20-
#define HCI_GRP_BLE_CMDS (0x08 << 10)
21-
22-
/* HCI Command opcode command field(OCF) */
23-
#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
24-
#define HCI_BLE_WRITE_ADV_ENABLE (0x000A | HCI_GRP_BLE_CMDS)
25-
#define HCI_BLE_WRITE_ADV_PARAMS (0x0006 | HCI_GRP_BLE_CMDS)
26-
#define HCI_BLE_WRITE_ADV_DATA (0x0008 | HCI_GRP_BLE_CMDS)
27-
28-
#define HCI_H4_CMD_PREAMBLE_SIZE (4)
29-
#define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE (1)
30-
#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS (15)
31-
#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA (31)
32-
33-
/* EIR/AD data type definitions */
34-
#define BT_DATA_FLAGS 0x01 /* AD flags */
35-
#define BT_DATA_UUID16_SOME 0x02 /* 16-bit UUID, more available */
36-
#define BT_DATA_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
37-
#define BT_DATA_UUID32_SOME 0x04 /* 32-bit UUID, more available */
38-
#define BT_DATA_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
39-
#define BT_DATA_UUID128_SOME 0x06 /* 128-bit UUID, more available */
40-
#define BT_DATA_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
41-
#define BT_DATA_NAME_SHORTENED 0x08 /* Shortened name */
42-
#define BT_DATA_NAME_COMPLETE 0x09 /* Complete name */
43-
#define BT_DATA_TX_POWER 0x0a /* Tx Power */
44-
#define BT_DATA_SOLICIT16 0x14 /* Solicit UUIDs, 16-bit */
45-
#define BT_DATA_SOLICIT128 0x15 /* Solicit UUIDs, 128-bit */
46-
#define BT_DATA_SVC_DATA16 0x16 /* Service data, 16-bit UUID */
47-
#define BT_DATA_GAP_APPEARANCE 0x19 /* GAP appearance */
48-
#define BT_DATA_SOLICIT32 0x1f /* Solicit UUIDs, 32-bit */
49-
#define BT_DATA_SVC_DATA32 0x20 /* Service data, 32-bit UUID */
50-
#define BT_DATA_SVC_DATA128 0x21 /* Service data, 128-bit UUID */
51-
#define BT_DATA_MANUFACTURER_DATA 0xff /* Manufacturer Specific Data */
52-
53-
54-
/* Advertising types */
55-
#define BLE_GAP_ADV_TYPE_ADV_IND 0x00
56-
#define BLE_GAP_ADV_TYPE_ADV_DIRECT_IND 0x01
57-
#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND 0x02
58-
#define BLE_GAP_ADV_TYPE_ADV_NONCONN_IND 0x03
59-
60-
61-
/* Advertising Discovery Flags */
62-
#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01)
63-
#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02)
64-
#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04)
65-
#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08)
66-
#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10)
67-
#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED)
68-
#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED)
69-
70-
71-
/* Advertising Filter Policies */
72-
#define BLE_GAP_ADV_FP_ANY 0x00
73-
#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01
74-
#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02
75-
#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03
76-
77-
78-
/* Advertising Device Address Types */
79-
#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00
80-
#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01
81-
#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02
82-
#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03
83-
84-
85-
/* GAP Advertising Channel Maps */
86-
#define GAP_ADVCHAN_37 0x01
87-
#define GAP_ADVCHAN_38 0x02
88-
#define GAP_ADVCHAN_39 0x04
89-
#define GAP_ADVCHAN_ALL GAP_ADVCHAN_37 | GAP_ADVCHAN_38 | GAP_ADVCHAN_39
90-
91-
92-
/* GAP Filter Policies */
93-
#define BLE_GAP_ADV_FP_ANY 0x00
94-
#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01
95-
#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02
96-
#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03
97-
98-
#define BD_ADDR_LEN (6) /* Device address length */
99-
100-
101-
/*
102-
* BLE System
103-
*
104-
* */
105-
106-
/* HCI H4 message type definitions */
107-
enum {
108-
H4_TYPE_COMMAND = 1,
109-
H4_TYPE_ACL = 2,
110-
H4_TYPE_SCO = 3,
111-
H4_TYPE_EVENT = 4
18+
#include "bt.h"
19+
#include "bta_api.h"
20+
#include "esp_gap_ble_api.h"
21+
#include "esp_gatts_api.h"
22+
#include "esp_bt_defs.h"
23+
#include "esp_bt_main.h"
24+
25+
static esp_ble_adv_data_t _adv_config = {
26+
.set_scan_rsp = false,
27+
.include_name = true,
28+
.include_txpower = true,
29+
.min_interval = 512,
30+
.max_interval = 1024,
31+
.appearance = 0,
32+
.manufacturer_len = 0,
33+
.p_manufacturer_data = NULL,
34+
.service_data_len = 0,
35+
.p_service_data = NULL,
36+
.service_uuid_len = 0,
37+
.p_service_uuid = NULL,
38+
.flag = (ESP_BLE_ADV_FLAG_GEN_DISC|ESP_BLE_ADV_FLAG_BREDR_NOT_SPT)
11239
};
11340

114-
volatile bool _vhci_host_send_available = false;
115-
volatile bool _vhci_host_command_running = false;
116-
static uint16_t _vhci_host_command = 0x0000;
117-
static uint8_t _vhci_host_command_result = 0x00;
41+
static esp_ble_adv_params_t _adv_params = {
42+
.adv_int_min = 512,
43+
.adv_int_max = 1024,
44+
.adv_type = ADV_TYPE_NONCONN_IND,
45+
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
46+
.peer_addr = {0x00, },
47+
.peer_addr_type = BLE_ADDR_TYPE_PUBLIC,
48+
.channel_map = ADV_CHNL_ALL,
49+
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
50+
};
11851

119-
//controller is ready to receive command
120-
static void _on_tx_ready(void)
121-
{
122-
_vhci_host_send_available = true;
123-
}
124-
/*
125-
static void _dump_buf(const char * txt, uint8_t *data, uint16_t len){
126-
log_printf("%s[%u]:", txt, len);
127-
for (uint16_t i=0; i<len; i++)
128-
log_printf(" %02x", data[i]);
129-
log_printf("\n");
130-
}
131-
*/
132-
//controller has a packet
133-
static int _on_rx_data(uint8_t *data, uint16_t len)
134-
{
135-
if(len == 7 && *data == 0x04){
136-
//baseband response
137-
uint16_t cmd = (((uint16_t)data[5] << 8) | data[4]);
138-
uint8_t res = data[6];
139-
if(_vhci_host_command_running && _vhci_host_command == cmd){
140-
//_dump_buf("BLE: res", data, len);
141-
_vhci_host_command_result = res;
142-
_vhci_host_command_running = false;
143-
return 0;
144-
} else if(cmd == 0){
145-
log_e("error %u", res);
146-
}
52+
static void _on_gap(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param){
53+
if(event == ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT){
54+
esp_ble_gap_start_advertising(&_adv_params);
14755
}
148-
149-
//_dump_buf("BLE: rx", data, len);
150-
return 0;
15156
}
15257

153-
154-
155-
156-
static esp_vhci_host_callback_t vhci_host_cb = {
157-
_on_tx_ready,
158-
_on_rx_data
159-
};
160-
161-
static bool _esp_ble_start()
162-
{
163-
if(btStart()){
164-
esp_vhci_host_register_callback(&vhci_host_cb);
165-
uint8_t i = 0;
166-
while(!esp_vhci_host_check_send_available() && i++ < 100){
167-
delay(10);
58+
static bool _init_gap(const char * name){
59+
if(!btStarted() && !btStart()){
60+
log_e("btStart failed");
61+
return false;
62+
}
63+
esp_bluedroid_status_t bt_state = esp_bluedroid_get_status();
64+
if(bt_state == ESP_BLUEDROID_STATUS_UNINITIALIZED){
65+
if (esp_bluedroid_init()) {
66+
log_e("esp_bluedroid_init failed");
67+
return false;
16868
}
169-
if(i >= 100){
170-
log_e("esp_vhci_host_check_send_available failed");
69+
}
70+
if(bt_state != ESP_BLUEDROID_STATUS_ENABLED){
71+
if (esp_bluedroid_enable()) {
72+
log_e("esp_bluedroid_enable failed");
17173
return false;
17274
}
173-
_vhci_host_send_available = true;
174-
} else
175-
log_e("BT Failed");
75+
}
76+
if(esp_ble_gap_set_device_name(name)){
77+
log_e("gap_set_device_name failed");
78+
return false;
79+
}
80+
if(esp_ble_gap_config_adv_data(&_adv_config)){
81+
log_e("gap_config_adv_data failed");
82+
return false;
83+
}
84+
if(esp_ble_gap_register_callback(_on_gap)){
85+
log_e("gap_register_callback failed");
86+
return false;
87+
}
17688
return true;
17789
}
17890

179-
static bool _esp_ble_stop()
91+
static bool _stop_gap()
18092
{
18193
if(btStarted()){
182-
_vhci_host_send_available = false;
94+
esp_bluedroid_disable();
95+
esp_bluedroid_deinit();
18396
btStop();
184-
esp_vhci_host_register_callback(NULL);
18597
}
18698
return true;
18799
}
188100

189-
//public
190-
191-
static uint8_t ble_send_cmd(uint16_t cmd, uint8_t * data, uint8_t len){
192-
static uint8_t buf[36];
193-
if(len > 32){
194-
//too much data
195-
return 2;
196-
}
197-
uint16_t i = 0;
198-
while(!_vhci_host_send_available && i++ < 1000){
199-
delay(1);
200-
}
201-
if(i >= 1000){
202-
log_e("_vhci_host_send_available failed");
203-
return 1;
204-
}
205-
uint8_t outlen = len + HCI_H4_CMD_PREAMBLE_SIZE;
206-
buf[0] = H4_TYPE_COMMAND;
207-
buf[1] = (uint8_t)(cmd & 0xFF);
208-
buf[2] = (uint8_t)(cmd >> 8);
209-
buf[3] = len;
210-
if(len){
211-
memcpy(buf+4, data, len);
212-
}
213-
_vhci_host_send_available = false;
214-
_vhci_host_command_running = true;
215-
_vhci_host_command = cmd;
216-
217-
//log_printf("BLE: cmd: 0x%04X, data[%u]:", cmd, len);
218-
//for (uint16_t i=0; i<len; i++) log_printf(" %02x", buf[i+4]);
219-
//log_printf("\n");
220-
221-
esp_vhci_host_send_packet(buf, outlen);
222-
while(_vhci_host_command_running);
223-
int res = _vhci_host_command_result;
224-
//log_printf("BLE: cmd: 0x%04X, res: %u\n", cmd, res);
225-
return res;
226-
}
227-
228-
229101
/*
230102
* BLE Arduino
231103
*
232104
* */
233105

234-
enum {
235-
UNIT_0_625_MS = 625, /* Number of microseconds in 0.625 milliseconds. */
236-
UNIT_1_25_MS = 1250, /* Number of microseconds in 1.25 milliseconds. */
237-
UNIT_10_MS = 10000 /* Number of microseconds in 10 milliseconds. */
238-
};
239-
240-
/* BLE Advertising parameters struct */
241-
typedef struct ble_gap_adv_params_s {
242-
uint8_t type;
243-
uint8_t own_addr_type;
244-
uint8_t addr_type;
245-
uint8_t addr[BD_ADDR_LEN];
246-
uint8_t fp; // filter policy
247-
uint16_t interval_min; // minimum advertising interval between 0x0020 and 0x4000 in 0.625 ms units (20ms to 10.24s)
248-
uint16_t interval_max;
249-
uint8_t chn_map;
250-
} ble_adv_params_t;
251-
252-
#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
253-
#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
254-
#define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);}
255-
#define BDADDR_TO_STREAM(p, a) {int i; for (i = 0; i < BD_ADDR_LEN; i++) *(p)++ = (uint8_t) a[BD_ADDR_LEN - 1 - i];}
256-
#define ARRAY_TO_STREAM(p, a, len) {int i; for (i = 0; i < len; i++) *(p)++ = (uint8_t) a[i];}
257-
258106
SimpleBLE::SimpleBLE()
259107
{
260-
uint8_t peerAddr[BD_ADDR_LEN] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85};
261-
_ble_adv_param = (ble_adv_params_t*)malloc(sizeof(ble_adv_params_t));
262-
memset(_ble_adv_param, 0x00, sizeof(ble_adv_params_t));
263-
_ble_adv_param->type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;//not connectable
264-
_ble_adv_param->chn_map = GAP_ADVCHAN_ALL; // 37, 38, 39 channels
265-
_ble_adv_param->fp = 0;//any
266-
_ble_adv_param->interval_min = 512;
267-
_ble_adv_param->interval_max = 1024;
268-
_ble_adv_param->addr_type = 0;//public
269-
memcpy(_ble_adv_param->addr, peerAddr, BD_ADDR_LEN);
270108
local_name = "esp32";
271109
}
272110

273111
SimpleBLE::~SimpleBLE(void)
274112
{
275-
free(_ble_adv_param);
276-
_esp_ble_stop();
113+
_stop_gap();
277114
}
278115

279116
bool SimpleBLE::begin(String localName)
280117
{
281-
if(!_esp_ble_start()){
282-
return false;
283-
}
284-
ble_send_cmd(HCI_RESET, NULL, 0);
285118
if(localName.length()){
286119
local_name = localName;
287120
}
288-
_ble_send_adv_param();
289-
_ble_send_adv_data();
290-
291-
uint8_t adv_enable = 1;
292-
ble_send_cmd(HCI_BLE_WRITE_ADV_ENABLE, &adv_enable, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE);
293-
return true;
121+
return _init_gap(local_name.c_str());
294122
}
295123

296124
void SimpleBLE::end()
297125
{
298-
uint8_t adv_enable = 0;
299-
ble_send_cmd(HCI_BLE_WRITE_ADV_ENABLE, &adv_enable, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE);
300-
ble_send_cmd(HCI_RESET, NULL, 0);
301-
_esp_ble_stop();
302-
}
303-
304-
void SimpleBLE::_ble_send_adv_param(void)
305-
{
306-
uint8_t dbuf[HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS];
307-
uint8_t *buf = dbuf;
308-
UINT16_TO_STREAM (buf, _ble_adv_param->interval_min);
309-
UINT16_TO_STREAM (buf, _ble_adv_param->interval_max);
310-
UINT8_TO_STREAM (buf, _ble_adv_param->type);
311-
UINT8_TO_STREAM (buf, _ble_adv_param->own_addr_type);
312-
UINT8_TO_STREAM (buf, _ble_adv_param->addr_type);
313-
ARRAY_TO_STREAM (buf, _ble_adv_param->addr, BD_ADDR_LEN);
314-
UINT8_TO_STREAM (buf, _ble_adv_param->chn_map);
315-
UINT8_TO_STREAM (buf, _ble_adv_param->fp);
316-
ble_send_cmd(HCI_BLE_WRITE_ADV_PARAMS, dbuf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS);
317-
}
318-
319-
void SimpleBLE::_ble_send_adv_data(void)
320-
{
321-
uint8_t adv_data[HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1] = {
322-
0x03, 0x02, BT_DATA_FLAGS, BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE
323-
};
324-
//zerofill the buffer
325-
memset(adv_data+4, 0x00, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA-4);
326-
uint8_t adv_data_len = 4;
327-
328-
// Advertising data device local name
329-
uint8_t name_len = (uint8_t) local_name.length();
330-
adv_data[adv_data_len++] = name_len + 1;
331-
adv_data[adv_data_len++] = BT_DATA_NAME_COMPLETE;
332-
for (int i=0; i<name_len; i++) {
333-
adv_data[adv_data_len++] = (uint8_t) local_name.charAt(i);
334-
}
335-
//send data
336-
adv_data[0] = adv_data_len - 1;
337-
ble_send_cmd(HCI_BLE_WRITE_ADV_DATA, (uint8_t *)adv_data, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
126+
_stop_gap();
338127
}

0 commit comments

Comments
 (0)