From db09ca8c162a096271333ff3fbdfea1bf5be761c Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 22 May 2017 17:50:57 +0300 Subject: [PATCH] Make SimpleBLE work again Fixes: https://github.com/espressif/arduino-esp32/issues/373 --- libraries/SimpleBLE/src/SimpleBLE.cpp | 345 +++++--------------------- libraries/SimpleBLE/src/SimpleBLE.h | 3 - libraries/WiFi/src/WiFiGeneric.cpp | 4 +- 3 files changed, 70 insertions(+), 282 deletions(-) diff --git a/libraries/SimpleBLE/src/SimpleBLE.cpp b/libraries/SimpleBLE/src/SimpleBLE.cpp index b2e5523b..01753052 100644 --- a/libraries/SimpleBLE/src/SimpleBLE.cpp +++ b/libraries/SimpleBLE/src/SimpleBLE.cpp @@ -15,324 +15,113 @@ #include "SimpleBLE.h" #include "esp32-hal-log.h" -/* HCI Command opcode group field(OGF) */ -#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */ -#define HCI_GRP_BLE_CMDS (0x08 << 10) +#include "bt.h" +#include "bta_api.h" +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_bt_defs.h" +#include "esp_bt_main.h" -/* HCI Command opcode command field(OCF) */ -#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_BLE_WRITE_ADV_ENABLE (0x000A | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_ADV_PARAMS (0x0006 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_ADV_DATA (0x0008 | HCI_GRP_BLE_CMDS) - -#define HCI_H4_CMD_PREAMBLE_SIZE (4) -#define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE (1) -#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS (15) -#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA (31) - -/* EIR/AD data type definitions */ -#define BT_DATA_FLAGS 0x01 /* AD flags */ -#define BT_DATA_UUID16_SOME 0x02 /* 16-bit UUID, more available */ -#define BT_DATA_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ -#define BT_DATA_UUID32_SOME 0x04 /* 32-bit UUID, more available */ -#define BT_DATA_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ -#define BT_DATA_UUID128_SOME 0x06 /* 128-bit UUID, more available */ -#define BT_DATA_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ -#define BT_DATA_NAME_SHORTENED 0x08 /* Shortened name */ -#define BT_DATA_NAME_COMPLETE 0x09 /* Complete name */ -#define BT_DATA_TX_POWER 0x0a /* Tx Power */ -#define BT_DATA_SOLICIT16 0x14 /* Solicit UUIDs, 16-bit */ -#define BT_DATA_SOLICIT128 0x15 /* Solicit UUIDs, 128-bit */ -#define BT_DATA_SVC_DATA16 0x16 /* Service data, 16-bit UUID */ -#define BT_DATA_GAP_APPEARANCE 0x19 /* GAP appearance */ -#define BT_DATA_SOLICIT32 0x1f /* Solicit UUIDs, 32-bit */ -#define BT_DATA_SVC_DATA32 0x20 /* Service data, 32-bit UUID */ -#define BT_DATA_SVC_DATA128 0x21 /* Service data, 128-bit UUID */ -#define BT_DATA_MANUFACTURER_DATA 0xff /* Manufacturer Specific Data */ - - -/* Advertising types */ -#define BLE_GAP_ADV_TYPE_ADV_IND 0x00 -#define BLE_GAP_ADV_TYPE_ADV_DIRECT_IND 0x01 -#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND 0x02 -#define BLE_GAP_ADV_TYPE_ADV_NONCONN_IND 0x03 - - -/* Advertising Discovery Flags */ -#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) -#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) -#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) -#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) -#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) -#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) -#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) - - -/* Advertising Filter Policies */ -#define BLE_GAP_ADV_FP_ANY 0x00 -#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 -#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 -#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 - - -/* Advertising Device Address Types */ -#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 -#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 -#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 -#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 - - -/* GAP Advertising Channel Maps */ -#define GAP_ADVCHAN_37 0x01 -#define GAP_ADVCHAN_38 0x02 -#define GAP_ADVCHAN_39 0x04 -#define GAP_ADVCHAN_ALL GAP_ADVCHAN_37 | GAP_ADVCHAN_38 | GAP_ADVCHAN_39 - - -/* GAP Filter Policies */ -#define BLE_GAP_ADV_FP_ANY 0x00 -#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 -#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 -#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 - -#define BD_ADDR_LEN (6) /* Device address length */ - - -/* - * BLE System - * - * */ - -/* HCI H4 message type definitions */ -enum { - H4_TYPE_COMMAND = 1, - H4_TYPE_ACL = 2, - H4_TYPE_SCO = 3, - H4_TYPE_EVENT = 4 +static esp_ble_adv_data_t _adv_config = { + .set_scan_rsp = false, + .include_name = true, + .include_txpower = true, + .min_interval = 512, + .max_interval = 1024, + .appearance = 0, + .manufacturer_len = 0, + .p_manufacturer_data = NULL, + .service_data_len = 0, + .p_service_data = NULL, + .service_uuid_len = 0, + .p_service_uuid = NULL, + .flag = (ESP_BLE_ADV_FLAG_GEN_DISC|ESP_BLE_ADV_FLAG_BREDR_NOT_SPT) }; -volatile bool _vhci_host_send_available = false; -volatile bool _vhci_host_command_running = false; -static uint16_t _vhci_host_command = 0x0000; -static uint8_t _vhci_host_command_result = 0x00; +static esp_ble_adv_params_t _adv_params = { + .adv_int_min = 512, + .adv_int_max = 1024, + .adv_type = ADV_TYPE_NONCONN_IND, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .peer_addr = {0x00, }, + .peer_addr_type = BLE_ADDR_TYPE_PUBLIC, + .channel_map = ADV_CHNL_ALL, + .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, +}; -//controller is ready to receive command -static void _on_tx_ready(void) -{ - _vhci_host_send_available = true; -} -/* -static void _dump_buf(const char * txt, uint8_t *data, uint16_t len){ - log_printf("%s[%u]:", txt, len); - for (uint16_t i=0; i= 100){ - log_e("esp_vhci_host_check_send_available failed"); +static bool _init_gap(const char * name){ + if(!btStarted() && !btStart()){ + log_e("btStart failed"); + return false; + } + esp_bluedroid_status_t bt_state = esp_bluedroid_get_status(); + if(bt_state == ESP_BLUEDROID_STATUS_UNINITIALIZED){ + if (esp_bluedroid_init()) { + log_e("esp_bluedroid_init failed"); return false; } - _vhci_host_send_available = true; - } else - log_e("BT Failed"); + } + if(bt_state != ESP_BLUEDROID_STATUS_ENABLED){ + if (esp_bluedroid_enable()) { + log_e("esp_bluedroid_enable failed"); + return false; + } + } + if(esp_ble_gap_set_device_name(name)){ + log_e("gap_set_device_name failed"); + return false; + } + if(esp_ble_gap_config_adv_data(&_adv_config)){ + log_e("gap_config_adv_data failed"); + return false; + } + if(esp_ble_gap_register_callback(_on_gap)){ + log_e("gap_register_callback failed"); + return false; + } return true; } -static bool _esp_ble_stop() +static bool _stop_gap() { if(btStarted()){ - _vhci_host_send_available = false; + esp_bluedroid_disable(); + esp_bluedroid_deinit(); btStop(); - esp_vhci_host_register_callback(NULL); } return true; } -//public - -static uint8_t ble_send_cmd(uint16_t cmd, uint8_t * data, uint8_t len){ - static uint8_t buf[36]; - if(len > 32){ - //too much data - return 2; - } - uint16_t i = 0; - while(!_vhci_host_send_available && i++ < 1000){ - delay(1); - } - if(i >= 1000){ - log_e("_vhci_host_send_available failed"); - return 1; - } - uint8_t outlen = len + HCI_H4_CMD_PREAMBLE_SIZE; - buf[0] = H4_TYPE_COMMAND; - buf[1] = (uint8_t)(cmd & 0xFF); - buf[2] = (uint8_t)(cmd >> 8); - buf[3] = len; - if(len){ - memcpy(buf+4, data, len); - } - _vhci_host_send_available = false; - _vhci_host_command_running = true; - _vhci_host_command = cmd; - - //log_printf("BLE: cmd: 0x%04X, data[%u]:", cmd, len); - //for (uint16_t i=0; i> 8);} -#define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);} -#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];} -#define ARRAY_TO_STREAM(p, a, len) {int i; for (i = 0; i < len; i++) *(p)++ = (uint8_t) a[i];} - SimpleBLE::SimpleBLE() { - uint8_t peerAddr[BD_ADDR_LEN] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85}; - _ble_adv_param = (ble_adv_params_t*)malloc(sizeof(ble_adv_params_t)); - memset(_ble_adv_param, 0x00, sizeof(ble_adv_params_t)); - _ble_adv_param->type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;//not connectable - _ble_adv_param->chn_map = GAP_ADVCHAN_ALL; // 37, 38, 39 channels - _ble_adv_param->fp = 0;//any - _ble_adv_param->interval_min = 512; - _ble_adv_param->interval_max = 1024; - _ble_adv_param->addr_type = 0;//public - memcpy(_ble_adv_param->addr, peerAddr, BD_ADDR_LEN); local_name = "esp32"; } SimpleBLE::~SimpleBLE(void) { - free(_ble_adv_param); - _esp_ble_stop(); + _stop_gap(); } bool SimpleBLE::begin(String localName) { - if(!_esp_ble_start()){ - return false; - } - ble_send_cmd(HCI_RESET, NULL, 0); if(localName.length()){ local_name = localName; } - _ble_send_adv_param(); - _ble_send_adv_data(); - - uint8_t adv_enable = 1; - ble_send_cmd(HCI_BLE_WRITE_ADV_ENABLE, &adv_enable, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE); - return true; + return _init_gap(local_name.c_str()); } void SimpleBLE::end() { - uint8_t adv_enable = 0; - ble_send_cmd(HCI_BLE_WRITE_ADV_ENABLE, &adv_enable, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE); - ble_send_cmd(HCI_RESET, NULL, 0); - _esp_ble_stop(); -} - -void SimpleBLE::_ble_send_adv_param(void) -{ - uint8_t dbuf[HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS]; - uint8_t *buf = dbuf; - UINT16_TO_STREAM (buf, _ble_adv_param->interval_min); - UINT16_TO_STREAM (buf, _ble_adv_param->interval_max); - UINT8_TO_STREAM (buf, _ble_adv_param->type); - UINT8_TO_STREAM (buf, _ble_adv_param->own_addr_type); - UINT8_TO_STREAM (buf, _ble_adv_param->addr_type); - ARRAY_TO_STREAM (buf, _ble_adv_param->addr, BD_ADDR_LEN); - UINT8_TO_STREAM (buf, _ble_adv_param->chn_map); - UINT8_TO_STREAM (buf, _ble_adv_param->fp); - ble_send_cmd(HCI_BLE_WRITE_ADV_PARAMS, dbuf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS); -} - -void SimpleBLE::_ble_send_adv_data(void) -{ - uint8_t adv_data[HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1] = { - 0x03, 0x02, BT_DATA_FLAGS, BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE - }; - //zerofill the buffer - memset(adv_data+4, 0x00, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA-4); - uint8_t adv_data_len = 4; - - // Advertising data device local name - uint8_t name_len = (uint8_t) local_name.length(); - adv_data[adv_data_len++] = name_len + 1; - adv_data[adv_data_len++] = BT_DATA_NAME_COMPLETE; - for (int i=0; i