|
15 | 15 | #include "SimpleBLE.h"
|
16 | 16 | #include "esp32-hal-log.h"
|
17 | 17 |
|
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) |
112 | 39 | };
|
113 | 40 |
|
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 | +}; |
118 | 51 |
|
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); |
147 | 55 | }
|
148 |
| - |
149 |
| - //_dump_buf("BLE: rx", data, len); |
150 |
| - return 0; |
151 | 56 | }
|
152 | 57 |
|
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; |
168 | 68 | }
|
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"); |
171 | 73 | return false;
|
172 | 74 | }
|
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 | + } |
176 | 88 | return true;
|
177 | 89 | }
|
178 | 90 |
|
179 |
| -static bool _esp_ble_stop() |
| 91 | +static bool _stop_gap() |
180 | 92 | {
|
181 | 93 | if(btStarted()){
|
182 |
| - _vhci_host_send_available = false; |
| 94 | + esp_bluedroid_disable(); |
| 95 | + esp_bluedroid_deinit(); |
183 | 96 | btStop();
|
184 |
| - esp_vhci_host_register_callback(NULL); |
185 | 97 | }
|
186 | 98 | return true;
|
187 | 99 | }
|
188 | 100 |
|
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 |
| - |
229 | 101 | /*
|
230 | 102 | * BLE Arduino
|
231 | 103 | *
|
232 | 104 | * */
|
233 | 105 |
|
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 |
| - |
258 | 106 | SimpleBLE::SimpleBLE()
|
259 | 107 | {
|
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); |
270 | 108 | local_name = "esp32";
|
271 | 109 | }
|
272 | 110 |
|
273 | 111 | SimpleBLE::~SimpleBLE(void)
|
274 | 112 | {
|
275 |
| - free(_ble_adv_param); |
276 |
| - _esp_ble_stop(); |
| 113 | + _stop_gap(); |
277 | 114 | }
|
278 | 115 |
|
279 | 116 | bool SimpleBLE::begin(String localName)
|
280 | 117 | {
|
281 |
| - if(!_esp_ble_start()){ |
282 |
| - return false; |
283 |
| - } |
284 |
| - ble_send_cmd(HCI_RESET, NULL, 0); |
285 | 118 | if(localName.length()){
|
286 | 119 | local_name = localName;
|
287 | 120 | }
|
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()); |
294 | 122 | }
|
295 | 123 |
|
296 | 124 | void SimpleBLE::end()
|
297 | 125 | {
|
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(); |
338 | 127 | }
|
0 commit comments