|
15 | 15 | #include"SimpleBLE.h" |
16 | 16 | #include"esp32-hal-log.h" |
17 | 17 |
|
18 | | -/* HCI Command opcode group field(OGF) */ |
19 | | -#defineHCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */ |
20 | | -#defineHCI_GRP_BLE_CMDS (0x08 << 10) |
21 | | - |
22 | | -/* HCI Command opcode command field(OCF) */ |
23 | | -#defineHCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) |
24 | | -#defineHCI_BLE_WRITE_ADV_ENABLE (0x000A | HCI_GRP_BLE_CMDS) |
25 | | -#defineHCI_BLE_WRITE_ADV_PARAMS (0x0006 | HCI_GRP_BLE_CMDS) |
26 | | -#defineHCI_BLE_WRITE_ADV_DATA (0x0008 | HCI_GRP_BLE_CMDS) |
27 | | - |
28 | | -#defineHCI_H4_CMD_PREAMBLE_SIZE (4) |
29 | | -#defineHCIC_PARAM_SIZE_WRITE_ADV_ENABLE (1) |
30 | | -#defineHCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS (15) |
31 | | -#defineHCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA (31) |
32 | | - |
33 | | -/* EIR/AD data type definitions */ |
34 | | -#defineBT_DATA_FLAGS0x01/* AD flags */ |
35 | | -#defineBT_DATA_UUID16_SOME0x02/* 16-bit UUID, more available */ |
36 | | -#defineBT_DATA_UUID16_ALL0x03/* 16-bit UUID, all listed */ |
37 | | -#defineBT_DATA_UUID32_SOME0x04/* 32-bit UUID, more available */ |
38 | | -#defineBT_DATA_UUID32_ALL0x05/* 32-bit UUID, all listed */ |
39 | | -#defineBT_DATA_UUID128_SOME0x06/* 128-bit UUID, more available */ |
40 | | -#defineBT_DATA_UUID128_ALL0x07/* 128-bit UUID, all listed */ |
41 | | -#defineBT_DATA_NAME_SHORTENED0x08/* Shortened name */ |
42 | | -#defineBT_DATA_NAME_COMPLETE0x09/* Complete name */ |
43 | | -#defineBT_DATA_TX_POWER0x0a/* Tx Power */ |
44 | | -#defineBT_DATA_SOLICIT160x14/* Solicit UUIDs, 16-bit */ |
45 | | -#defineBT_DATA_SOLICIT1280x15/* Solicit UUIDs, 128-bit */ |
46 | | -#defineBT_DATA_SVC_DATA160x16/* Service data, 16-bit UUID */ |
47 | | -#defineBT_DATA_GAP_APPEARANCE0x19/* GAP appearance */ |
48 | | -#defineBT_DATA_SOLICIT320x1f/* Solicit UUIDs, 32-bit */ |
49 | | -#defineBT_DATA_SVC_DATA320x20/* Service data, 32-bit UUID */ |
50 | | -#defineBT_DATA_SVC_DATA1280x21/* Service data, 128-bit UUID */ |
51 | | -#defineBT_DATA_MANUFACTURER_DATA0xff/* Manufacturer Specific Data */ |
52 | | - |
53 | | - |
54 | | -/* Advertising types */ |
55 | | -#defineBLE_GAP_ADV_TYPE_ADV_IND0x00 |
56 | | -#defineBLE_GAP_ADV_TYPE_ADV_DIRECT_IND0x01 |
57 | | -#defineBLE_GAP_ADV_TYPE_ADV_SCAN_IND0x02 |
58 | | -#defineBLE_GAP_ADV_TYPE_ADV_NONCONN_IND0x03 |
59 | | - |
60 | | - |
61 | | -/* Advertising Discovery Flags */ |
62 | | -#defineBLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) |
63 | | -#defineBLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) |
64 | | -#defineBLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) |
65 | | -#defineBLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) |
66 | | -#defineBLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) |
67 | | -#defineBLE_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 | | -#defineBLE_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 | | -#defineBLE_GAP_ADV_FP_ANY0x00 |
73 | | -#defineBLE_GAP_ADV_FP_FILTER_SCANREQ0x01 |
74 | | -#defineBLE_GAP_ADV_FP_FILTER_CONNREQ0x02 |
75 | | -#defineBLE_GAP_ADV_FP_FILTER_BOTH0x03 |
76 | | - |
77 | | - |
78 | | -/* Advertising Device Address Types */ |
79 | | -#defineBLE_GAP_ADDR_TYPE_PUBLIC0x00 |
80 | | -#defineBLE_GAP_ADDR_TYPE_RANDOM_STATIC0x01 |
81 | | -#defineBLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE0x02 |
82 | | -#defineBLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE0x03 |
83 | | - |
84 | | - |
85 | | -/* GAP Advertising Channel Maps */ |
86 | | -#defineGAP_ADVCHAN_370x01 |
87 | | -#defineGAP_ADVCHAN_380x02 |
88 | | -#defineGAP_ADVCHAN_390x04 |
89 | | -#defineGAP_ADVCHAN_ALL GAP_ADVCHAN_37 | GAP_ADVCHAN_38 | GAP_ADVCHAN_39 |
90 | | - |
91 | | - |
92 | | -/* GAP Filter Policies */ |
93 | | -#defineBLE_GAP_ADV_FP_ANY0x00 |
94 | | -#defineBLE_GAP_ADV_FP_FILTER_SCANREQ0x01 |
95 | | -#defineBLE_GAP_ADV_FP_FILTER_CONNREQ0x02 |
96 | | -#defineBLE_GAP_ADV_FP_FILTER_BOTH0x03 |
97 | | - |
98 | | -#defineBD_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 | +staticesp_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 | | -volatilebool _vhci_host_send_available = false; |
115 | | -volatilebool _vhci_host_command_running = false; |
116 | | -staticuint16_t _vhci_host_command = 0x0000; |
117 | | -staticuint8_t _vhci_host_command_result = 0x00; |
| 41 | +staticesp_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 | | -staticvoid_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 | | -staticint_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 | | -return0; |
144 | | - } elseif(cmd == 0){ |
145 | | -log_e("error %u", res); |
146 | | - } |
| 52 | +staticvoid_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 | | -return0; |
151 | 56 | } |
152 | 57 |
|
153 | | - |
154 | | - |
155 | | - |
156 | | -staticesp_vhci_host_callback_t vhci_host_cb ={ |
157 | | - _on_tx_ready, |
158 | | - _on_rx_data |
159 | | -}; |
160 | | - |
161 | | -staticbool_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 | +staticbool_init_gap(constchar * name){ |
| 59 | +if(!btStarted() && !btStart()){ |
| 60 | +log_e("btStart failed"); |
| 61 | +returnfalse; |
| 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 | +returnfalse; |
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 | returnfalse; |
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 | +returnfalse; |
| 79 | + } |
| 80 | +if(esp_ble_gap_config_adv_data(&_adv_config)){ |
| 81 | +log_e("gap_config_adv_data failed"); |
| 82 | +returnfalse; |
| 83 | + } |
| 84 | +if(esp_ble_gap_register_callback(_on_gap)){ |
| 85 | +log_e("gap_register_callback failed"); |
| 86 | +returnfalse; |
| 87 | + } |
176 | 88 | returntrue; |
177 | 89 | } |
178 | 90 |
|
179 | | -staticbool_esp_ble_stop() |
| 91 | +staticbool_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 | returntrue; |
187 | 99 | } |
188 | 100 |
|
189 | | -//public |
190 | | - |
191 | | -staticuint8_tble_send_cmd(uint16_t cmd, uint8_t * data, uint8_t len){ |
192 | | -staticuint8_t buf[36]; |
193 | | -if(len > 32){ |
194 | | -//too much data |
195 | | -return2; |
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 | | -return1; |
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 | | -typedefstructble_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 | | -#defineMSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) |
253 | | -#defineUINT16_TO_STREAM(p, u16){*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8)} |
254 | | -#defineUINT8_TO_STREAM(p, u8){*(p)++ = (uint8_t)(u8)} |
255 | | -#defineBDADDR_TO_STREAM(p, a){int i; for (i = 0; i < BD_ADDR_LEN; i++) *(p)++ = (uint8_t) a[BD_ADDR_LEN - 1 - i]} |
256 | | -#defineARRAY_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 | boolSimpleBLE::begin(String localName) |
280 | 117 | { |
281 | | -if(!_esp_ble_start()){ |
282 | | -returnfalse; |
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 | | -returntrue; |
| 121 | +return_init_gap(local_name.c_str()); |
294 | 122 | } |
295 | 123 |
|
296 | 124 | voidSimpleBLE::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 | | -voidSimpleBLE::_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 | | -voidSimpleBLE::_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