From bc2cafc1dedacc69adcfc304bf450007fc9660d2 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Mon, 16 Sep 2019 19:55:44 -0400 Subject: [PATCH 01/39] 20190916 - initial: support for Master mode, Pin and SSP --- .../BluetoothSerial/src/BluetoothSerial.cpp | 299 +++++++++++++++++- .../BluetoothSerial/src/BluetoothSerial.h | 11 +- 2 files changed, 304 insertions(+), 6 deletions(-) mode change 100644 => 100755 libraries/BluetoothSerial/src/BluetoothSerial.cpp mode change 100644 => 100755 libraries/BluetoothSerial/src/BluetoothSerial.h diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp old mode 100644 new mode 100755 index a8332b8bc99..1a52bb34c6a --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -53,6 +53,26 @@ static EventGroupHandle_t _spp_event_group = NULL; static boolean secondConnectionAttempt; static esp_spp_cb_t * custom_spp_callback = NULL; +#define SPP_TAG "BluetoothSerial" +static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE; +static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER; +static esp_bd_addr_t _peer_bd_addr; +static uint8_t peer_bdname_len; +static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; +static const esp_bt_inq_mode_t inq_mode = ESP_BT_INQ_MODE_GENERAL_INQUIRY; +static const uint8_t inq_len = 30; +static const uint8_t inq_num_rsps = 0; +static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; +static bool _isRemoteAddressSet; +static esp_bd_addr_t _remote_address; +static bool _isMaster; +static esp_bt_pin_code_t _pin_code; +static int _pin_len; +static bool _isPinSet; +static bool _enableSSP; +static bool _isInitializing; +static bool _isInitialized; + #define SPP_RUNNING 0x01 #define SPP_CONNECTED 0x02 #define SPP_CONGESTED 0x04 @@ -62,6 +82,47 @@ typedef struct { uint8_t data[]; } spp_packet_t; +static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len) +{ + uint8_t *rmt_bdname = NULL; + uint8_t rmt_bdname_len = 0; + + if (!eir) { + return false; + } + + rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len); + if (!rmt_bdname) { + rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len); + } + + if (rmt_bdname) { + if (rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN) { + rmt_bdname_len = ESP_BT_GAP_MAX_BDNAME_LEN; + } + + if (bdname) { + memcpy(bdname, rmt_bdname, rmt_bdname_len); + bdname[rmt_bdname_len] = '\0'; + } + if (bdname_len) { + *bdname_len = rmt_bdname_len; + } + return true; + } + + return false; +} + +static bool btSetPin() { + if (_isPinSet) { + log_i("pin set"); + esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED; + return (esp_bt_gap_set_pin(pin_type, _pin_len, _pin_code) == ESP_OK); + } + return false; +} + static esp_err_t _spp_queue_packet(uint8_t *data, size_t len){ if(!data || !len){ log_w("No data provided"); @@ -159,8 +220,14 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) case ESP_SPP_INIT_EVT: log_i("ESP_SPP_INIT_EVT"); esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); - esp_spp_start_srv(ESP_SPP_SEC_NONE, ESP_SPP_ROLE_SLAVE, 0, _spp_server_name); + if (!_isMaster) { + log_i("ESP_SPP_INIT_EVT: slave: start"); + esp_spp_start_srv(ESP_SPP_SEC_NONE, ESP_SPP_ROLE_SLAVE, 0, _spp_server_name); + } xEventGroupSetBits(_spp_event_group, SPP_RUNNING); + _isInitialized = true; + _isInitializing = false; + break; case ESP_SPP_SRV_OPEN_EVT://Server connection open @@ -219,10 +286,21 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) //should maybe delete those. case ESP_SPP_DISCOVERY_COMP_EVT://discovery complete log_i("ESP_SPP_DISCOVERY_COMP_EVT"); + if (param->disc_comp.status == ESP_SPP_SUCCESS) { + log_i("ESP_SPP_DISCOVERY_COMP_EVT: spp connect to remote"); + esp_spp_connect(sec_mask, role_master, param->disc_comp.scn[0], _peer_bd_addr); + } break; case ESP_SPP_OPEN_EVT://Client connection open - log_i("ESP_SPP_OPEN_EVT"); - break; + if (!_spp_client){ + _spp_client = param->open.handle; + } else { + secondConnectionAttempt = true; + esp_spp_disconnect(param->open.handle); + } + xEventGroupSetBits(_spp_event_group, SPP_CONNECTED); + log_i("ESP_SPP_OPEN_EVT"); + break; case ESP_SPP_START_EVT://server started log_i("ESP_SPP_START_EVT"); break; @@ -235,8 +313,93 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) if(custom_spp_callback)(*custom_spp_callback)(event, param); } +static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + switch(event){ + case ESP_BT_GAP_DISC_RES_EVT: + log_i("ESP_BT_GAP_DISC_RES_EVT"); + esp_log_buffer_hex(SPP_TAG, param->disc_res.bda, ESP_BD_ADDR_LEN); + for (int i = 0; i < param->disc_res.num_prop; i++){ + if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_EIR + && get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)){ + log_v("ESP_BT_GAP_DISC_RES_EVT : EIR : %s", peer_bdname); + if (strlen(_remote_name) == peer_bdname_len + && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { + log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_DISCOVERY_EIR : %s", peer_bdname); + _isRemoteAddressSet = true; + memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); + esp_spp_start_discovery(_peer_bd_addr); + esp_bt_gap_cancel_discovery(); + } + } else if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_BDNAME) { + strcpy(peer_bdname, (char *)param->disc_res.prop[i].val); + peer_bdname_len = strlen(peer_bdname); + log_v("ESP_BT_GAP_DISC_RES_EVT : BDNAME : %s", peer_bdname); + if (strlen(_remote_name) == peer_bdname_len + && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { + log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_DISCOVERY_BDNAME : %s", peer_bdname); + _isRemoteAddressSet = true; + memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); + esp_spp_start_discovery(_peer_bd_addr); + esp_bt_gap_cancel_discovery(); + } + } + } + break; + case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: + log_i("ESP_BT_GAP_DISC_STATE_CHANGED_EVT"); + break; + case ESP_BT_GAP_RMT_SRVCS_EVT: + log_i( "ESP_BT_GAP_RMT_SRVCS_EVT"); + break; + case ESP_BT_GAP_RMT_SRVC_REC_EVT: + log_i("ESP_BT_GAP_RMT_SRVC_REC_EVT"); + break; + case ESP_BT_GAP_AUTH_CMPL_EVT:{ + if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { + log_v("authentication success: %s", param->auth_cmpl.device_name); + esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); + } else { + log_e("authentication failed, status:%d", param->auth_cmpl.stat); + } + break; + } + case ESP_BT_GAP_PIN_REQ_EVT:{ + // default pairing pins + log_i("ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit); + if (param->pin_req.min_16_digit) { + log_i("Input pin code: 0000 0000 0000 0000"); + esp_bt_pin_code_t pin_code = {0}; + esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code); + } else { + log_i("Input pin code: 1234"); + esp_bt_pin_code_t pin_code; + pin_code[0] = '1'; + pin_code[1] = '2'; + pin_code[2] = '3'; + pin_code[3] = '4'; + esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code); + } + break; + } + case ESP_BT_GAP_CFM_REQ_EVT: + log_i("ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val); + esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); + break; + case ESP_BT_GAP_KEY_NOTIF_EVT: + log_i("ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey); + break; + case ESP_BT_GAP_KEY_REQ_EVT: + log_i("ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!"); + break; + default: + break; + } +} + static bool _init_bt(const char *deviceName) { + _isInitializing = false; if(!_spp_event_group){ _spp_event_group = xEventGroupCreate(); if(!_spp_event_group){ @@ -297,6 +460,11 @@ static bool _init_bt(const char *deviceName) } } + if (_isMaster && esp_bt_gap_register_callback(esp_bt_gap_cb) != ESP_OK) { + log_e("gap register failed"); + return false; + } + if (esp_spp_register_callback(esp_spp_cb) != ESP_OK){ log_e("spp register failed"); return false; @@ -307,8 +475,20 @@ static bool _init_bt(const char *deviceName) return false; } + log_i("device name set"); esp_bt_dev_set_device_name(deviceName); + if (_isPinSet) { + btSetPin(); + } + + if (_enableSSP) { + log_i("Simple Secure Pairing"); + esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; + esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; + esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); + } + // the default BTA_DM_COD_LOUDSPEAKER does not work with the macOS BT stack esp_bt_cod_t cod; cod.major = 0b00001; @@ -318,12 +498,14 @@ static bool _init_bt(const char *deviceName) log_e("set cod failed"); return false; } - + _isInitializing = true; return true; } static bool _stop_bt() { + _isInitialized = false; + _isInitializing = false; if (btStarted()){ if(_spp_client) esp_spp_disconnect(_spp_client); @@ -376,8 +558,9 @@ BluetoothSerial::~BluetoothSerial(void) _stop_bt(); } -bool BluetoothSerial::begin(String localName) +bool BluetoothSerial::begin(String localName, bool isMaster) { + _isMaster = isMaster; if (localName.length()){ local_name = localName; } @@ -445,4 +628,110 @@ esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback) return ESP_OK; } + +//Simple Secure Pairing +void BluetoothSerial::enableSSP() { + _enableSSP = true; +} +/* + * Set default parameters for Legacy Pairing + * Use fixed pin code +*/ +bool BluetoothSerial::setPin(const char * pin) { + if (pin && *pin) { + int i = 0; + while(*(pin + i) && i < ESP_BT_PIN_CODE_LEN) { + _pin_code[i] = *(pin+i); + i++; + } + _pin_len = i; + } else if (pin){ + _pin_len = 0; // resetting pin to none + } else { + log_e("No pin is provided"); + return false; + } + _isPinSet = true; + if (isReady(false)) { + btSetPin(); + } + return true; +} + +bool BluetoothSerial::connect(String remoteName) +{ + if (!isReady(true)) return false; + if (remoteName && remoteName.length() < 1) { + log_e("No remote name is provided"); + return false; + } + _isRemoteAddressSet = false; + strncpy(_remote_name, remoteName.c_str(), ESP_BT_GAP_MAX_BDNAME_LEN); + _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN] = 0; + log_i("master : remoteName"); + return (esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps) == ESP_OK); +} + +bool BluetoothSerial::connect(uint8_t remoteAddress[]) +{ + if (!isReady(true)) return false; + if (!remoteAddress) { + log_e("No remote address is provided"); + return false; + } + _remote_name[0] = 0; + _isRemoteAddressSet = true; + memcpy(_remote_address, remoteAddress, ESP_BD_ADDR_LEN); + memcpy(_peer_bd_addr, _remote_address, ESP_BD_ADDR_LEN); + log_i("master : remoteAddress"); + return ( esp_spp_start_discovery(_peer_bd_addr) == ESP_OK); +} + +bool BluetoothSerial::connect() +{ + if (!isReady(true)) return false; + if (_remote_name[0]) { + log_i("master : remoteName"); + return (esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps) == ESP_OK); + } else if (_isRemoteAddressSet){ + log_i("master : remoteAddress"); + memcpy(_peer_bd_addr, _remote_address, ESP_BD_ADDR_LEN); + return (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK); + } else { + log_e("Neither Remote name nor address was provided"); + } + return false; +} + +bool BluetoothSerial::disconnect() { + if (_spp_client) { + return (esp_spp_disconnect(_spp_client) == ESP_OK); + } + return false; +} + +bool BluetoothSerial::connected() { + return _spp_client != 0; +} + +bool BluetoothSerial::isReady(bool checkMaster) +{ + if (checkMaster && !_isMaster) { + log_e("Master mode is not active. Call begin(localName, true) to enanbe Master mode"); + return false; + } + // btStarted() is not sufficient to indicate ESP_SPP_INIT_EVT is complete + if (_isInitializing) { + int retry = 10; + do { + delay(500); + log_i("waiting for intialization to complete..."); + } while(!_isInitialized && retry-- > 0); + } + if (!_isInitialized) { + log_e("Timeout waiting for bt initialization to complete"); + return false; + } + return true; + } #endif diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h old mode 100644 new mode 100755 index 3f4372e55d2..8ce7608dcac --- a/libraries/BluetoothSerial/src/BluetoothSerial.h +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -30,7 +30,7 @@ class BluetoothSerial: public Stream BluetoothSerial(void); ~BluetoothSerial(void); - bool begin(String localName=String()); + bool begin(String localName=String(), bool isMaster=false); int available(void); int peek(void); bool hasClient(void); @@ -41,6 +41,15 @@ class BluetoothSerial: public Stream void end(void); esp_err_t register_callback(esp_spp_cb_t * callback); + void enableSSP(); + bool setPin(const char *pin); + bool connect(String remoteName); + bool connect(uint8_t remoteAddress[]); + bool connect(); + bool connected(); + bool isReady(bool checkMaster=false); + bool disconnect(); + private: String local_name; From 94abf9f09d086ea3023b34fd071854be42ea88ca Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Mon, 16 Sep 2019 20:02:43 -0400 Subject: [PATCH 02/39] 20190916 - initial: Add example app for Master mode --- .../SerialToSerialBTM/SerialToSerialBTM.ino | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100755 libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino new file mode 100755 index 00000000000..62e77773e7e --- /dev/null +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -0,0 +1,39 @@ +//This example code is in the Public Domain (or CC0 licensed, at your option.) +//By Evandro Copercini - 2018 +// +//This example creates a bridge between Serial and Classical Bluetooth (SPP) +//and also demonstrate that SerialBT have the same functionalities of a normal Serial + +#include "BluetoothSerial.h" + +#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) +#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it +#endif + +BluetoothSerial SerialBT; + +uint8_t address[6] = {0xAA, 0xBB, 0xCC, 0x11, 0x22, 0x33}; +String MACadd = "AA:BB:CC:11:22:33"; +String name = "OBDII"; +char *pin = "1234"; //<- standard pin would be provided by default + +void setup() { + Serial.begin(115200); + //SerialBT.setPin(pin); + SerialBT.begin("ESP32test", true); + //SerialBT.setPin(pin); + Serial.println("The device started in master mode, make sure remote BT device is on!"); + //delay(2000); + SerialBT.connect(address); + //SerialBT.connect(name); +} + +void loop() { + if (Serial.available()) { + SerialBT.write(Serial.read()); + } + if (SerialBT.available()) { + Serial.write(SerialBT.read()); + } + delay(20); +} From 9eb5e3a147de0353edb52079829fd0b359254b21 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Mon, 16 Sep 2019 22:25:14 -0400 Subject: [PATCH 03/39] 20190916 - initial: Force another build --- .../examples/SerialToSerialBTM/SerialToSerialBTM.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index 62e77773e7e..27d5fd6984f 100755 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -12,8 +12,8 @@ BluetoothSerial SerialBT; -uint8_t address[6] = {0xAA, 0xBB, 0xCC, 0x11, 0x22, 0x33}; String MACadd = "AA:BB:CC:11:22:33"; +uint8_t address[6] = {0xAA, 0xBB, 0xCC, 0x11, 0x22, 0x33}; String name = "OBDII"; char *pin = "1234"; //<- standard pin would be provided by default From b346290cbf2b052f1a79f36655a50a94ff3b72c0 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 08:09:06 -0400 Subject: [PATCH 04/39] 20190916 - connect would use resolved address as preference and remove now redundant _remote_address --- .../SerialToSerialBTM/SerialToSerialBTM.ino | 7 ++++++- .../BluetoothSerial/src/BluetoothSerial.cpp | 21 +++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index 27d5fd6984f..abd3dae3e05 100755 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -14,6 +14,7 @@ BluetoothSerial SerialBT; String MACadd = "AA:BB:CC:11:22:33"; uint8_t address[6] = {0xAA, 0xBB, 0xCC, 0x11, 0x22, 0x33}; +//uint8_t address[6] = {0x00, 0x1D, 0xA5, 0x02, 0xC3, 0x22}; String name = "OBDII"; char *pin = "1234"; //<- standard pin would be provided by default @@ -25,7 +26,11 @@ void setup() { Serial.println("The device started in master mode, make sure remote BT device is on!"); //delay(2000); SerialBT.connect(address); - //SerialBT.connect(name); + //SerialBT.connect(name); //slow as it needs to resolve name to address first, but allows to connect to different devices with the same name + while(!SerialBT.connected()) {delay(1000); } + SerialBT.disconnect(); + while(SerialBT.connected()) {delay(1000); } + SerialBT.connect(); } void loop() { diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 1a52bb34c6a..5eef7aac33e 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -669,7 +669,8 @@ bool BluetoothSerial::connect(String remoteName) strncpy(_remote_name, remoteName.c_str(), ESP_BT_GAP_MAX_BDNAME_LEN); _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN] = 0; log_i("master : remoteName"); - return (esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps) == ESP_OK); + // will first resolve name to address + return (esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps) == ESP_OK); } bool BluetoothSerial::connect(uint8_t remoteAddress[]) @@ -681,8 +682,7 @@ bool BluetoothSerial::connect(uint8_t remoteAddress[]) } _remote_name[0] = 0; _isRemoteAddressSet = true; - memcpy(_remote_address, remoteAddress, ESP_BD_ADDR_LEN); - memcpy(_peer_bd_addr, _remote_address, ESP_BD_ADDR_LEN); + memcpy(_peer_bd_addr, remoteAddress, ESP_BD_ADDR_LEN); log_i("master : remoteAddress"); return ( esp_spp_start_discovery(_peer_bd_addr) == ESP_OK); } @@ -690,14 +690,15 @@ bool BluetoothSerial::connect(uint8_t remoteAddress[]) bool BluetoothSerial::connect() { if (!isReady(true)) return false; - if (_remote_name[0]) { - log_i("master : remoteName"); - return (esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps) == ESP_OK); - } else if (_isRemoteAddressSet){ + if (_isRemoteAddressSet){ + // use resolved or set address first log_i("master : remoteAddress"); - memcpy(_peer_bd_addr, _remote_address, ESP_BD_ADDR_LEN); return (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK); - } else { + } else if (_remote_name[0]) { + log_i("master : remoteName"); + // will resolve name to address first - it may take a while + return (esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps) == ESP_OK); + } else { log_e("Neither Remote name nor address was provided"); } return false; @@ -705,6 +706,8 @@ bool BluetoothSerial::connect() bool BluetoothSerial::disconnect() { if (_spp_client) { + flush(); + log_i("disconnecting"); return (esp_spp_disconnect(_spp_client) == ESP_OK); } return false; From dcefa81ab79015d5ae9ce2a7ae5e235caed34f47 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 15:12:08 -0400 Subject: [PATCH 05/39] 20190916 - rework set/reset/default pin logic --- .../BluetoothSerial/src/BluetoothSerial.cpp | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 5eef7aac33e..7e22075d4ac 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -115,9 +115,16 @@ static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len) } static bool btSetPin() { + esp_bt_pin_type_t pin_type; if (_isPinSet) { - log_i("pin set"); - esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED; + if (_pin_len) { + log_i("pin set"); + pin_type = ESP_BT_PIN_TYPE_FIXED; + } else { + _isPinSet = false; + log_i("pin reset"); + pin_type = ESP_BT_PIN_TYPE_VARIABLE; // pin_code would be ignored (default) + } return (esp_bt_gap_set_pin(pin_type, _pin_len, _pin_code) == ESP_OK); } return false; @@ -294,13 +301,13 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) case ESP_SPP_OPEN_EVT://Client connection open if (!_spp_client){ _spp_client = param->open.handle; - } else { - secondConnectionAttempt = true; - esp_spp_disconnect(param->open.handle); - } - xEventGroupSetBits(_spp_event_group, SPP_CONNECTED); - log_i("ESP_SPP_OPEN_EVT"); - break; + } else { + secondConnectionAttempt = true; + esp_spp_disconnect(param->open.handle); + } + xEventGroupSetBits(_spp_event_group, SPP_CONNECTED); + log_i("ESP_SPP_OPEN_EVT"); + break; case ESP_SPP_START_EVT://server started log_i("ESP_SPP_START_EVT"); break; @@ -332,8 +339,9 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa esp_bt_gap_cancel_discovery(); } } else if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_BDNAME) { - strcpy(peer_bdname, (char *)param->disc_res.prop[i].val); - peer_bdname_len = strlen(peer_bdname); + peer_bdname_len = param->disc_res.prop[i].len; + memcpy(peer_bdname, param->disc_res.prop[i].val, peer_bdname_len); + peer_bdname[peer_bdname_len] = '\0'; log_v("ESP_BT_GAP_DISC_RES_EVT : BDNAME : %s", peer_bdname); if (strlen(_remote_name) == peer_bdname_len && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { @@ -369,7 +377,8 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa log_i("ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit); if (param->pin_req.min_16_digit) { log_i("Input pin code: 0000 0000 0000 0000"); - esp_bt_pin_code_t pin_code = {0}; + esp_bt_pin_code_t pin_code; + memset(pin_code, '0', ESP_BT_PIN_CODE_LEN); esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code); } else { log_i("Input pin code: 1234"); @@ -637,19 +646,15 @@ void BluetoothSerial::enableSSP() { * Set default parameters for Legacy Pairing * Use fixed pin code */ -bool BluetoothSerial::setPin(const char * pin) { - if (pin && *pin) { - int i = 0; - while(*(pin + i) && i < ESP_BT_PIN_CODE_LEN) { - _pin_code[i] = *(pin+i); - i++; - } - _pin_len = i; - } else if (pin){ - _pin_len = 0; // resetting pin to none +bool BluetoothSerial::setPin(const char *pin) { + bool isEmpty = !(pin && *pin); + if (isEmpty && !_isPinSet) { + return true; // nothing to do + } else if (!isEmpty){ + _pin_len = strlen(pin); + memcpy(_pin_code, pin, _pin_len); } else { - log_e("No pin is provided"); - return false; + _pin_len = 0; // resetting pin to none (default) } _isPinSet = true; if (isReady(false)) { From bc06174ccb327c5459029f9d1441fb2ec1ebb257 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 15:33:36 -0400 Subject: [PATCH 06/39] 20190916 - cleanup: remove static vars, add/use constants, fix typos --- .../BluetoothSerial/src/BluetoothSerial.cpp | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 7e22075d4ac..2cc9597733e 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -53,18 +53,11 @@ static EventGroupHandle_t _spp_event_group = NULL; static boolean secondConnectionAttempt; static esp_spp_cb_t * custom_spp_callback = NULL; -#define SPP_TAG "BluetoothSerial" -static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE; -static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER; +#define INQ_LEN 30; +#define INQ_NUM_RSPS 0; static esp_bd_addr_t _peer_bd_addr; -static uint8_t peer_bdname_len; -static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; -static const esp_bt_inq_mode_t inq_mode = ESP_BT_INQ_MODE_GENERAL_INQUIRY; -static const uint8_t inq_len = 30; -static const uint8_t inq_num_rsps = 0; static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; static bool _isRemoteAddressSet; -static esp_bd_addr_t _remote_address; static bool _isMaster; static esp_bt_pin_code_t _pin_code; static int _pin_len; @@ -295,7 +288,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) log_i("ESP_SPP_DISCOVERY_COMP_EVT"); if (param->disc_comp.status == ESP_SPP_SUCCESS) { log_i("ESP_SPP_DISCOVERY_COMP_EVT: spp connect to remote"); - esp_spp_connect(sec_mask, role_master, param->disc_comp.scn[0], _peer_bd_addr); + esp_spp_connect(ESP_SPP_SEC_AUTHENTICATE, ESP_SPP_ROLE_MASTER, param->disc_comp.scn[0], _peer_bd_addr); } break; case ESP_SPP_OPEN_EVT://Client connection open @@ -325,8 +318,9 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa switch(event){ case ESP_BT_GAP_DISC_RES_EVT: log_i("ESP_BT_GAP_DISC_RES_EVT"); - esp_log_buffer_hex(SPP_TAG, param->disc_res.bda, ESP_BD_ADDR_LEN); for (int i = 0; i < param->disc_res.num_prop; i++){ + uint8_t peer_bdname_len; + peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_EIR && get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)){ log_v("ESP_BT_GAP_DISC_RES_EVT : EIR : %s", peer_bdname); @@ -366,7 +360,6 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa case ESP_BT_GAP_AUTH_CMPL_EVT:{ if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { log_v("authentication success: %s", param->auth_cmpl.device_name); - esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); } else { log_e("authentication failed, status:%d", param->auth_cmpl.stat); } @@ -675,7 +668,7 @@ bool BluetoothSerial::connect(String remoteName) _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN] = 0; log_i("master : remoteName"); // will first resolve name to address - return (esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps) == ESP_OK); + return (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK); } bool BluetoothSerial::connect(uint8_t remoteAddress[]) @@ -702,7 +695,7 @@ bool BluetoothSerial::connect() } else if (_remote_name[0]) { log_i("master : remoteName"); // will resolve name to address first - it may take a while - return (esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps) == ESP_OK); + return (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK); } else { log_e("Neither Remote name nor address was provided"); } @@ -725,7 +718,7 @@ bool BluetoothSerial::connected() { bool BluetoothSerial::isReady(bool checkMaster) { if (checkMaster && !_isMaster) { - log_e("Master mode is not active. Call begin(localName, true) to enanbe Master mode"); + log_e("Master mode is not active. Call begin(localName, true) to enable Master mode"); return false; } // btStarted() is not sufficient to indicate ESP_SPP_INIT_EVT is complete @@ -733,7 +726,7 @@ bool BluetoothSerial::isReady(bool checkMaster) int retry = 10; do { delay(500); - log_i("waiting for intialization to complete..."); + log_i("waiting for initialization to complete..."); } while(!_isInitialized && retry-- > 0); } if (!_isInitialized) { From c6efba2a365da98b117c18196444ad4b3c60b2a1 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 16:08:26 -0400 Subject: [PATCH 07/39] 20190916 - fix build issues and implement geoup events for status verification. --- .../BluetoothSerial/src/BluetoothSerial.cpp | 48 +++++++++---------- .../BluetoothSerial/src/BluetoothSerial.h | 4 +- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 2cc9597733e..c6c24a52c86 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -53,8 +53,8 @@ static EventGroupHandle_t _spp_event_group = NULL; static boolean secondConnectionAttempt; static esp_spp_cb_t * custom_spp_callback = NULL; -#define INQ_LEN 30; -#define INQ_NUM_RSPS 0; +#define INQ_LEN 30 +#define INQ_NUM_RSPS 0 static esp_bd_addr_t _peer_bd_addr; static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; static bool _isRemoteAddressSet; @@ -63,8 +63,6 @@ static esp_bt_pin_code_t _pin_code; static int _pin_len; static bool _isPinSet; static bool _enableSSP; -static bool _isInitializing; -static bool _isInitialized; #define SPP_RUNNING 0x01 #define SPP_CONNECTED 0x02 @@ -225,9 +223,6 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) esp_spp_start_srv(ESP_SPP_SEC_NONE, ESP_SPP_ROLE_SLAVE, 0, _spp_server_name); } xEventGroupSetBits(_spp_event_group, SPP_RUNNING); - _isInitialized = true; - _isInitializing = false; - break; case ESP_SPP_SRV_OPEN_EVT://Server connection open @@ -320,7 +315,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa log_i("ESP_BT_GAP_DISC_RES_EVT"); for (int i = 0; i < param->disc_res.num_prop; i++){ uint8_t peer_bdname_len; - peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; + char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_EIR && get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)){ log_v("ESP_BT_GAP_DISC_RES_EVT : EIR : %s", peer_bdname); @@ -401,7 +396,6 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa static bool _init_bt(const char *deviceName) { - _isInitializing = false; if(!_spp_event_group){ _spp_event_group = xEventGroupCreate(); if(!_spp_event_group){ @@ -500,14 +494,11 @@ static bool _init_bt(const char *deviceName) log_e("set cod failed"); return false; } - _isInitializing = true; return true; } static bool _stop_bt() { - _isInitialized = false; - _isInitializing = false; if (btStarted()){ if(_spp_client) esp_spp_disconnect(_spp_client); @@ -711,28 +702,33 @@ bool BluetoothSerial::disconnect() { return false; } -bool BluetoothSerial::connected() { +bool BluetoothSerial::connected(int timeout) { + TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; + if((xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED)) { + return true; + } else { + log_e("Timeout waiting for connected state"); + return false; + } return _spp_client != 0; } -bool BluetoothSerial::isReady(bool checkMaster) -{ +bool BluetoothSerial::isReady(bool checkMaster, int timeout) { if (checkMaster && !_isMaster) { log_e("Master mode is not active. Call begin(localName, true) to enable Master mode"); return false; } - // btStarted() is not sufficient to indicate ESP_SPP_INIT_EVT is complete - if (_isInitializing) { - int retry = 10; - do { - delay(500); - log_i("waiting for initialization to complete..."); - } while(!_isInitialized && retry-- > 0); + if (!btStarted()) { + log_e("BT is not initialized. Call begin() first"); + return false; } - if (!_isInitialized) { + TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; + if((xEventGroupWaitBits(_spp_event_group, SPP_RUNNING, pdFALSE, pdTRUE, xTicksToWait) & SPP_RUNNING)) { + return true; + } else { log_e("Timeout waiting for bt initialization to complete"); - return false; + return false; } - return true; - } + +} #endif diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h index 8ce7608dcac..52628983537 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.h +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -46,8 +46,8 @@ class BluetoothSerial: public Stream bool connect(String remoteName); bool connect(uint8_t remoteAddress[]); bool connect(); - bool connected(); - bool isReady(bool checkMaster=false); + bool connected(int timeout=0); + bool isReady(bool checkMaster=false, int timeout=0); bool disconnect(); private: From 784e388aafe53e3e566e5749606c978f8c970873 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 16:26:50 -0400 Subject: [PATCH 08/39] 20190916 - remove extra lines,misc --- .../BluetoothSerial/src/BluetoothSerial.cpp | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index c6c24a52c86..0532964e44a 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -371,10 +371,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa } else { log_i("Input pin code: 1234"); esp_bt_pin_code_t pin_code; - pin_code[0] = '1'; - pin_code[1] = '2'; - pin_code[2] = '3'; - pin_code[3] = '4'; + memcpy(pin_code, "1234", 4); esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code); } break; @@ -687,10 +684,9 @@ bool BluetoothSerial::connect() log_i("master : remoteName"); // will resolve name to address first - it may take a while return (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK); - } else { - log_e("Neither Remote name nor address was provided"); } - return false; + log_e("Neither Remote name nor address was provided"); + return false; } bool BluetoothSerial::disconnect() { @@ -706,11 +702,9 @@ bool BluetoothSerial::connected(int timeout) { TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; if((xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED)) { return true; - } else { - log_e("Timeout waiting for connected state"); - return false; } - return _spp_client != 0; + log_e("Timeout waiting for connected state"); + return false; } bool BluetoothSerial::isReady(bool checkMaster, int timeout) { @@ -725,10 +719,9 @@ bool BluetoothSerial::isReady(bool checkMaster, int timeout) { TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; if((xEventGroupWaitBits(_spp_event_group, SPP_RUNNING, pdFALSE, pdTRUE, xTicksToWait) & SPP_RUNNING)) { return true; - } else { - log_e("Timeout waiting for bt initialization to complete"); - return false; } + log_e("Timeout waiting for bt initialization to complete"); + return false; } #endif From c786489770ae00ba691ebda55d2ebaf49723f198 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 19:00:40 -0400 Subject: [PATCH 09/39] 20190916 - rework ESP_BT_GAP_DISC_RES_EVT, added SPP_DISCONNECTED bit for disconnect event. + timeout for disconnect() --- .../SerialToSerialBTM/SerialToSerialBTM.ino | 13 ++- .../BluetoothSerial/src/BluetoothSerial.cpp | 86 +++++++++++-------- .../BluetoothSerial/src/BluetoothSerial.h | 2 +- 3 files changed, 63 insertions(+), 38 deletions(-) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index abd3dae3e05..c67b163966e 100755 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -27,9 +27,16 @@ void setup() { //delay(2000); SerialBT.connect(address); //SerialBT.connect(name); //slow as it needs to resolve name to address first, but allows to connect to different devices with the same name - while(!SerialBT.connected()) {delay(1000); } - SerialBT.disconnect(); - while(SerialBT.connected()) {delay(1000); } + if(SerialBT.connected(60*1000)) { + Serial.println("Connected Succesfully!"); + } else { + Serial.println("Not connected yet?"); + } + if (SerialBT.disconnect(2000)) { + Serial.println("Disconnected Succesfully!"); + } else { + Serial.println("Not disconnected yet?"); + } SerialBT.connect(); } diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 0532964e44a..8c3b5602bbf 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -55,6 +55,7 @@ static esp_spp_cb_t * custom_spp_callback = NULL; #define INQ_LEN 30 #define INQ_NUM_RSPS 0 +#define READY_TIMEOUT 5000 static esp_bd_addr_t _peer_bd_addr; static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; static bool _isRemoteAddressSet; @@ -67,6 +68,7 @@ static bool _enableSSP; #define SPP_RUNNING 0x01 #define SPP_CONNECTED 0x02 #define SPP_CONGESTED 0x04 +#define SPP_DISCONNECTED 0x08 typedef struct { size_t len; @@ -241,7 +243,8 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) secondConnectionAttempt = false; } else { _spp_client = 0; - } + xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED); + } xEventGroupClearBits(_spp_event_group, SPP_CONNECTED); log_i("ESP_SPP_CLOSE_EVT"); break; @@ -314,32 +317,38 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa case ESP_BT_GAP_DISC_RES_EVT: log_i("ESP_BT_GAP_DISC_RES_EVT"); for (int i = 0; i < param->disc_res.num_prop; i++){ - uint8_t peer_bdname_len; - char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; - if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_EIR - && get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)){ - log_v("ESP_BT_GAP_DISC_RES_EVT : EIR : %s", peer_bdname); - if (strlen(_remote_name) == peer_bdname_len - && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { - log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_DISCOVERY_EIR : %s", peer_bdname); - _isRemoteAddressSet = true; - memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); - esp_spp_start_discovery(_peer_bd_addr); - esp_bt_gap_cancel_discovery(); - } - } else if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_BDNAME) { - peer_bdname_len = param->disc_res.prop[i].len; - memcpy(peer_bdname, param->disc_res.prop[i].val, peer_bdname_len); - peer_bdname[peer_bdname_len] = '\0'; - log_v("ESP_BT_GAP_DISC_RES_EVT : BDNAME : %s", peer_bdname); - if (strlen(_remote_name) == peer_bdname_len - && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { - log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_DISCOVERY_BDNAME : %s", peer_bdname); - _isRemoteAddressSet = true; - memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); - esp_spp_start_discovery(_peer_bd_addr); - esp_bt_gap_cancel_discovery(); - } + static uint8_t peer_bdname_len; + static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; + switch(param->disc_res.prop[i].type) { + case ESP_BT_GAP_DEV_PROP_EIR: + if (get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)) { + log_v("ESP_BT_GAP_DISC_RES_EVT : EIR : %s : %d", peer_bdname, peer_bdname_len); + if (strlen(_remote_name) == peer_bdname_len + && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { + log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_DISCOVERY_EIR : %s", peer_bdname, peer_bdname_len); + _isRemoteAddressSet = true; + memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); + esp_spp_start_discovery(_peer_bd_addr); + esp_bt_gap_cancel_discovery(); + } + } + break; + case ESP_BT_GAP_DEV_PROP_BDNAME: + peer_bdname_len = param->disc_res.prop[i].len; + memcpy(peer_bdname, param->disc_res.prop[i].val, peer_bdname_len); + peer_bdname_len--; // the len include 0 terminator + log_v("ESP_BT_GAP_DISC_RES_EVT : BDNAME : %s : %d", peer_bdname, peer_bdname_len); + if (strlen(_remote_name) == peer_bdname_len + && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { + log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_DISCOVERY_BDNAME : %s", peer_bdname); + _isRemoteAddressSet = true; + memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); + esp_spp_start_discovery(_peer_bd_addr); + esp_bt_gap_cancel_discovery(); + } + break; + default: + break; } } break; @@ -646,7 +655,7 @@ bool BluetoothSerial::setPin(const char *pin) { bool BluetoothSerial::connect(String remoteName) { - if (!isReady(true)) return false; + if (!isReady(true, READY_TIMEOUT)) return false; if (remoteName && remoteName.length() < 1) { log_e("No remote name is provided"); return false; @@ -661,7 +670,7 @@ bool BluetoothSerial::connect(String remoteName) bool BluetoothSerial::connect(uint8_t remoteAddress[]) { - if (!isReady(true)) return false; + if (!isReady(true, READY_TIMEOUT)) return false; if (!remoteAddress) { log_e("No remote address is provided"); return false; @@ -675,7 +684,7 @@ bool BluetoothSerial::connect(uint8_t remoteAddress[]) bool BluetoothSerial::connect() { - if (!isReady(true)) return false; + if (!isReady(true, READY_TIMEOUT)) return false; if (_isRemoteAddressSet){ // use resolved or set address first log_i("master : remoteAddress"); @@ -689,11 +698,18 @@ bool BluetoothSerial::connect() return false; } -bool BluetoothSerial::disconnect() { +bool BluetoothSerial::disconnect(int timeout) { if (_spp_client) { flush(); log_i("disconnecting"); - return (esp_spp_disconnect(_spp_client) == ESP_OK); + if (esp_spp_disconnect(_spp_client) == ESP_OK) { + if (timeout) { + TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; + if((xEventGroupWaitBits(_spp_event_group, SPP_DISCONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_DISCONNECTED)) { + return true; + } + } + } } return false; } @@ -703,7 +719,8 @@ bool BluetoothSerial::connected(int timeout) { if((xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED)) { return true; } - log_e("Timeout waiting for connected state"); + if (timeout) + log_e("Timeout waiting for connected state"); return false; } @@ -720,7 +737,8 @@ bool BluetoothSerial::isReady(bool checkMaster, int timeout) { if((xEventGroupWaitBits(_spp_event_group, SPP_RUNNING, pdFALSE, pdTRUE, xTicksToWait) & SPP_RUNNING)) { return true; } - log_e("Timeout waiting for bt initialization to complete"); + if (timeout) + log_e("Timeout waiting for bt initialization to complete"); return false; } diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h index 52628983537..55c7c692f6a 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.h +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -48,7 +48,7 @@ class BluetoothSerial: public Stream bool connect(); bool connected(int timeout=0); bool isReady(bool checkMaster=false, int timeout=0); - bool disconnect(); + bool disconnect(int timeout=0); private: String local_name; From 04783c039e90973130ca7ebd37546e2f9d7ca539 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 19:18:35 -0400 Subject: [PATCH 10/39] 20190916 - Small log change to improve log sequencing --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 8c3b5602bbf..3ea81033062 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -228,6 +228,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) break; case ESP_SPP_SRV_OPEN_EVT://Server connection open + log_i("ESP_SPP_SRV_OPEN_EVT"); if (!_spp_client){ _spp_client = param->open.handle; } else { @@ -235,10 +236,10 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) esp_spp_disconnect(param->open.handle); } xEventGroupSetBits(_spp_event_group, SPP_CONNECTED); - log_i("ESP_SPP_SRV_OPEN_EVT"); break; case ESP_SPP_CLOSE_EVT://Client connection closed + log_i("ESP_SPP_CLOSE_EVT"); if(secondConnectionAttempt) { secondConnectionAttempt = false; } else { @@ -246,7 +247,6 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED); } xEventGroupClearBits(_spp_event_group, SPP_CONNECTED); - log_i("ESP_SPP_CLOSE_EVT"); break; case ESP_SPP_CONG_EVT://connection congestion status changed @@ -290,6 +290,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) } break; case ESP_SPP_OPEN_EVT://Client connection open + log_i("ESP_SPP_OPEN_EVT"); if (!_spp_client){ _spp_client = param->open.handle; } else { @@ -297,7 +298,6 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) esp_spp_disconnect(param->open.handle); } xEventGroupSetBits(_spp_event_group, SPP_CONNECTED); - log_i("ESP_SPP_OPEN_EVT"); break; case ESP_SPP_START_EVT://server started log_i("ESP_SPP_START_EVT"); From d9dfb29063aa8c335233f296d737320027015599 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 19:32:48 -0400 Subject: [PATCH 11/39] 20190916 - remove static from local vars --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 3ea81033062..3cfcf5e511e 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -317,8 +317,8 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa case ESP_BT_GAP_DISC_RES_EVT: log_i("ESP_BT_GAP_DISC_RES_EVT"); for (int i = 0; i < param->disc_res.num_prop; i++){ - static uint8_t peer_bdname_len; - static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; + uint8_t peer_bdname_len; + char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; switch(param->disc_res.prop[i].type) { case ESP_BT_GAP_DEV_PROP_EIR: if (get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)) { From ad72ac3673513a9791f1e246a9e2a9a0d1539919 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 21:20:49 -0400 Subject: [PATCH 12/39] 20190916 - Limited scope and duration for the scan, log device address during scan in info mode as it is very difficult to find out sometimes. Fixed get_name_from_eir() not resetting the name when called. --- .../BluetoothSerial/src/BluetoothSerial.cpp | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 3cfcf5e511e..cb1edf41c43 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -53,8 +53,8 @@ static EventGroupHandle_t _spp_event_group = NULL; static boolean secondConnectionAttempt; static esp_spp_cb_t * custom_spp_callback = NULL; -#define INQ_LEN 30 -#define INQ_NUM_RSPS 0 +#define INQ_LEN 0x10 +#define INQ_NUM_RSPS 20 #define READY_TIMEOUT 5000 static esp_bd_addr_t _peer_bd_addr; static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; @@ -75,12 +75,29 @@ typedef struct { uint8_t data[]; } spp_packet_t; +static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} + static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len) { uint8_t *rmt_bdname = NULL; uint8_t rmt_bdname_len = 0; - if (!eir) { + if (bdname) { + *bdname_len = 0; + *bdname = 0; + } + + if (!eir || !bdname || !bdname_len) { return false; } @@ -316,16 +333,18 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa switch(event){ case ESP_BT_GAP_DISC_RES_EVT: log_i("ESP_BT_GAP_DISC_RES_EVT"); + char bda_str[18]; + log_i("Scanned device: %s", bda2str(param->disc_res.bda, bda_str, 18)); for (int i = 0; i < param->disc_res.num_prop; i++){ uint8_t peer_bdname_len; char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; switch(param->disc_res.prop[i].type) { - case ESP_BT_GAP_DEV_PROP_EIR: + case ESP_BT_GAP_DEV_PROP_EIR: if (get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)) { log_v("ESP_BT_GAP_DISC_RES_EVT : EIR : %s : %d", peer_bdname, peer_bdname_len); if (strlen(_remote_name) == peer_bdname_len && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { - log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_DISCOVERY_EIR : %s", peer_bdname, peer_bdname_len); + log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_EIR : %s", peer_bdname, peer_bdname_len); _isRemoteAddressSet = true; memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); esp_spp_start_discovery(_peer_bd_addr); @@ -340,13 +359,19 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa log_v("ESP_BT_GAP_DISC_RES_EVT : BDNAME : %s : %d", peer_bdname, peer_bdname_len); if (strlen(_remote_name) == peer_bdname_len && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { - log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_DISCOVERY_BDNAME : %s", peer_bdname); + log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_BDNAME : %s", peer_bdname); _isRemoteAddressSet = true; memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); esp_spp_start_discovery(_peer_bd_addr); esp_bt_gap_cancel_discovery(); } break; + case ESP_BT_GAP_DEV_PROP_COD: + //log_i("ESP_BT_GAP_DEV_PROP_COD"); + break; + case ESP_BT_GAP_DEV_PROP_RSSI: + //log_i("ESP_BT_GAP_DEV_PROP_RSSI"); + break; default: break; } @@ -665,6 +690,7 @@ bool BluetoothSerial::connect(String remoteName) _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN] = 0; log_i("master : remoteName"); // will first resolve name to address + esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE); return (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK); } @@ -692,6 +718,7 @@ bool BluetoothSerial::connect() } else if (_remote_name[0]) { log_i("master : remoteName"); // will resolve name to address first - it may take a while + esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE); return (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK); } log_e("Neither Remote name nor address was provided"); From 0531490c07ec9059185c9731bd2893d798a60d0e Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 21:45:06 -0400 Subject: [PATCH 13/39] 20190916 - break property for loop during scan when name matches. --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index cb1edf41c43..4badee34e7d 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -335,7 +335,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa log_i("ESP_BT_GAP_DISC_RES_EVT"); char bda_str[18]; log_i("Scanned device: %s", bda2str(param->disc_res.bda, bda_str, 18)); - for (int i = 0; i < param->disc_res.num_prop; i++){ + for (int i = 0; i < param->disc_res.num_prop; i++) { uint8_t peer_bdname_len; char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; switch(param->disc_res.prop[i].type) { @@ -375,6 +375,8 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa default: break; } + if (_isRemoteAddressSet) + break; } break; case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: From 25facff010357bb7b2ec02c513818bcc976c0864 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 17 Sep 2019 21:52:21 -0400 Subject: [PATCH 14/39] 20190916 - misc --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 4badee34e7d..1cb27e7165a 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -92,15 +92,13 @@ static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len) uint8_t *rmt_bdname = NULL; uint8_t rmt_bdname_len = 0; - if (bdname) { - *bdname_len = 0; - *bdname = 0; - } - if (!eir || !bdname || !bdname_len) { return false; } + *bdname_len = 0; + *bdname = 0; + rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len); if (!rmt_bdname) { rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len); From 21248d09394932e8b125c0a8f6f3923999b0a26c Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 00:17:48 -0400 Subject: [PATCH 15/39] 20190916 - SPP_DISCONNECT state updates --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 1cb27e7165a..1cc40ff297c 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -250,6 +250,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) secondConnectionAttempt = true; esp_spp_disconnect(param->open.handle); } + xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED); xEventGroupSetBits(_spp_event_group, SPP_CONNECTED); break; @@ -312,6 +313,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) secondConnectionAttempt = true; esp_spp_disconnect(param->open.handle); } + xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED); xEventGroupSetBits(_spp_event_group, SPP_CONNECTED); break; case ESP_SPP_START_EVT://server started @@ -435,6 +437,7 @@ static bool _init_bt(const char *deviceName) } xEventGroupClearBits(_spp_event_group, 0xFFFFFF); xEventGroupSetBits(_spp_event_group, SPP_CONGESTED); + xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED); } if (_spp_rx_queue == NULL){ _spp_rx_queue = xQueueCreate(RX_QUEUE_SIZE, sizeof(uint8_t)); //initialize the queue From e17beb1a62cc7032043a8d96d7a84230940598b4 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 00:39:26 -0400 Subject: [PATCH 16/39] 20190916 - formatting, remove some strange syntax from initiator code --- .../BluetoothSerial/src/BluetoothSerial.cpp | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 1cc40ff297c..2abfe88789f 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -297,7 +297,6 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) } break; - //should maybe delete those. case ESP_SPP_DISCOVERY_COMP_EVT://discovery complete log_i("ESP_SPP_DISCOVERY_COMP_EVT"); if (param->disc_comp.status == ESP_SPP_SUCCESS) { @@ -305,6 +304,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) esp_spp_connect(ESP_SPP_SEC_AUTHENTICATE, ESP_SPP_ROLE_MASTER, param->disc_comp.scn[0], _peer_bd_addr); } break; + case ESP_SPP_OPEN_EVT://Client connection open log_i("ESP_SPP_OPEN_EVT"); if (!_spp_client){ @@ -316,12 +316,15 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED); xEventGroupSetBits(_spp_event_group, SPP_CONNECTED); break; + case ESP_SPP_START_EVT://server started log_i("ESP_SPP_START_EVT"); break; + case ESP_SPP_CL_INIT_EVT://client initiated a connection log_i("ESP_SPP_CL_INIT_EVT"); break; + default: break; } @@ -347,11 +350,12 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_EIR : %s", peer_bdname, peer_bdname_len); _isRemoteAddressSet = true; memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); - esp_spp_start_discovery(_peer_bd_addr); esp_bt_gap_cancel_discovery(); + esp_spp_start_discovery(_peer_bd_addr); } } break; + case ESP_BT_GAP_DEV_PROP_BDNAME: peer_bdname_len = param->disc_res.prop[i].len; memcpy(peer_bdname, param->disc_res.prop[i].val, peer_bdname_len); @@ -362,16 +366,19 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_BDNAME : %s", peer_bdname); _isRemoteAddressSet = true; memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); - esp_spp_start_discovery(_peer_bd_addr); esp_bt_gap_cancel_discovery(); + esp_spp_start_discovery(_peer_bd_addr); } break; + case ESP_BT_GAP_DEV_PROP_COD: //log_i("ESP_BT_GAP_DEV_PROP_COD"); break; + case ESP_BT_GAP_DEV_PROP_RSSI: //log_i("ESP_BT_GAP_DEV_PROP_RSSI"); break; + default: break; } @@ -382,21 +389,24 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: log_i("ESP_BT_GAP_DISC_STATE_CHANGED_EVT"); break; + case ESP_BT_GAP_RMT_SRVCS_EVT: log_i( "ESP_BT_GAP_RMT_SRVCS_EVT"); break; + case ESP_BT_GAP_RMT_SRVC_REC_EVT: log_i("ESP_BT_GAP_RMT_SRVC_REC_EVT"); break; - case ESP_BT_GAP_AUTH_CMPL_EVT:{ + + case ESP_BT_GAP_AUTH_CMPL_EVT: if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { log_v("authentication success: %s", param->auth_cmpl.device_name); } else { log_e("authentication failed, status:%d", param->auth_cmpl.stat); } break; - } - case ESP_BT_GAP_PIN_REQ_EVT:{ + + case ESP_BT_GAP_PIN_REQ_EVT: // default pairing pins log_i("ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit); if (param->pin_req.min_16_digit) { @@ -411,17 +421,20 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code); } break; - } + case ESP_BT_GAP_CFM_REQ_EVT: log_i("ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val); esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); break; + case ESP_BT_GAP_KEY_NOTIF_EVT: log_i("ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey); break; + case ESP_BT_GAP_KEY_REQ_EVT: log_i("ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!"); break; + default: break; } From 54c2a0aefc0869535fd53e15dda8ffa3908656af Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 07:56:12 -0400 Subject: [PATCH 17/39] 20190916 - Add comments to the example about connect(...) usage and timeouts --- .../SerialToSerialBTM/SerialToSerialBTM.ino | 14 +++++++++++--- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) mode change 100755 => 100644 libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino old mode 100755 new mode 100644 index c67b163966e..68fe7f09660 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -27,17 +27,25 @@ void setup() { //delay(2000); SerialBT.connect(address); //SerialBT.connect(name); //slow as it needs to resolve name to address first, but allows to connect to different devices with the same name - if(SerialBT.connected(60*1000)) { + + // wait at least 30 secs after connect(name) or 5 secs after connect(address) + if(SerialBT.connected(30*1000)) { Serial.println("Connected Succesfully!"); } else { - Serial.println("Not connected yet?"); + while(!SerialBT.connected()) { + Serial.println("Not connected yet?"); + delay(10000); + } } + // wait for a few second for disconnect to complete if (SerialBT.disconnect(2000)) { Serial.println("Disconnected Succesfully!"); } else { Serial.println("Not disconnected yet?"); } - SerialBT.connect(); + // calling another connect(...) while other connect(...) still in progress may cause crash, + // use connected(timeout) with recommended timeout before issuing another connect(...) + SerialBT.connect(); } void loop() { diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 2abfe88789f..71ab172769d 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -359,7 +359,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa case ESP_BT_GAP_DEV_PROP_BDNAME: peer_bdname_len = param->disc_res.prop[i].len; memcpy(peer_bdname, param->disc_res.prop[i].val, peer_bdname_len); - peer_bdname_len--; // the len include 0 terminator + peer_bdname_len--; // len includes 0 terminator log_v("ESP_BT_GAP_DISC_RES_EVT : BDNAME : %s : %d", peer_bdname, peer_bdname_len); if (strlen(_remote_name) == peer_bdname_len && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { From e7c049a6c11a15baabff207c150b7cba40feb337 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 08:03:23 -0400 Subject: [PATCH 18/39] 20190916 - fix disconnect() without timeout --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 71ab172769d..93264784c97 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -751,6 +751,8 @@ bool BluetoothSerial::disconnect(int timeout) { if((xEventGroupWaitBits(_spp_event_group, SPP_DISCONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_DISCONNECTED)) { return true; } + } else { + return true; } } } From 5254e6c81aebcab5a4b6fc2cc734f91eea81f8f0 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 08:18:39 -0400 Subject: [PATCH 19/39] 20190916 - Add example comment to view BT address and name during connect(name) --- .../examples/SerialToSerialBTM/SerialToSerialBTM.ino | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index 68fe7f09660..1768c00d475 100644 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -24,9 +24,12 @@ void setup() { SerialBT.begin("ESP32test", true); //SerialBT.setPin(pin); Serial.println("The device started in master mode, make sure remote BT device is on!"); - //delay(2000); + + // connect(name) is slow as it needs to resolve name to address first, + // but allows to connect to different devices with the same name + // Enable CoreDebugLevel to Info to view devices bluetooth address or Verbose to see device names + //SerialBT.connect(name); SerialBT.connect(address); - //SerialBT.connect(name); //slow as it needs to resolve name to address first, but allows to connect to different devices with the same name // wait at least 30 secs after connect(name) or 5 secs after connect(address) if(SerialBT.connected(30*1000)) { From 9d927093ab482d7f94f81bfa7a4b5ed8814db215 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 08:40:41 -0400 Subject: [PATCH 20/39] 20190916 - wording in example comments --- .../examples/SerialToSerialBTM/SerialToSerialBTM.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index 1768c00d475..3a2281d7751 100644 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -26,8 +26,8 @@ void setup() { Serial.println("The device started in master mode, make sure remote BT device is on!"); // connect(name) is slow as it needs to resolve name to address first, - // but allows to connect to different devices with the same name - // Enable CoreDebugLevel to Info to view devices bluetooth address or Verbose to see device names + // but it allows to connect to different devices with the same name + // Set CoreDebugLevel to Info to view devices bluetooth address or Verbose to see device names //SerialBT.connect(name); SerialBT.connect(address); @@ -40,13 +40,13 @@ void setup() { delay(10000); } } - // wait for a few second for disconnect to complete + // wait for a few secs for disconnect to complete if (SerialBT.disconnect(2000)) { Serial.println("Disconnected Succesfully!"); } else { Serial.println("Not disconnected yet?"); } - // calling another connect(...) while other connect(...) still in progress may cause crash, + // calling connect(...) while other connect(...) still in progress may cause crash, // use connected(timeout) with recommended timeout before issuing another connect(...) SerialBT.connect(); } From 86c3e04ca7588c2f354493a0d03b3d6c746210a7 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 11:04:15 -0400 Subject: [PATCH 21/39] 20190916 - rework connect() and disconnect() methods to help with concurrency and more authoritative status returned back to caller. Automatic disconnect in connect() methods --- .../SerialToSerialBTM/SerialToSerialBTM.ino | 22 ++++---- .../BluetoothSerial/src/BluetoothSerial.cpp | 51 ++++++++++++++----- .../BluetoothSerial/src/BluetoothSerial.h | 2 +- 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index 3a2281d7751..febb79ed0db 100644 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -17,6 +17,7 @@ uint8_t address[6] = {0xAA, 0xBB, 0xCC, 0x11, 0x22, 0x33}; //uint8_t address[6] = {0x00, 0x1D, 0xA5, 0x02, 0xC3, 0x22}; String name = "OBDII"; char *pin = "1234"; //<- standard pin would be provided by default +bool connected; void setup() { Serial.begin(115200); @@ -25,14 +26,13 @@ void setup() { //SerialBT.setPin(pin); Serial.println("The device started in master mode, make sure remote BT device is on!"); - // connect(name) is slow as it needs to resolve name to address first, - // but it allows to connect to different devices with the same name - // Set CoreDebugLevel to Info to view devices bluetooth address or Verbose to see device names - //SerialBT.connect(name); - SerialBT.connect(address); + // connect(address) is fast (upto 5 secs max), connect(name) is slow (upto 30 secs max) as it needs + // to resolve name to address first, but it allows to connect to different devices with the same name. + // Set CoreDebugLevel to Info to view devices bluetooth address and device names + //connected = SerialBT.connect(name); + connected = SerialBT.connect(address); - // wait at least 30 secs after connect(name) or 5 secs after connect(address) - if(SerialBT.connected(30*1000)) { + if(SerialBT.connected(5000)) { Serial.println("Connected Succesfully!"); } else { while(!SerialBT.connected()) { @@ -40,15 +40,13 @@ void setup() { delay(10000); } } - // wait for a few secs for disconnect to complete - if (SerialBT.disconnect(2000)) { + // disconnect() may take upto 5 secs max + if (SerialBT.disconnect()) { Serial.println("Disconnected Succesfully!"); } else { Serial.println("Not disconnected yet?"); } - // calling connect(...) while other connect(...) still in progress may cause crash, - // use connected(timeout) with recommended timeout before issuing another connect(...) - SerialBT.connect(); + SerialBT.connect(); } void loop() { diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 93264784c97..65d092b40c9 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -56,6 +56,7 @@ static esp_spp_cb_t * custom_spp_callback = NULL; #define INQ_LEN 0x10 #define INQ_NUM_RSPS 20 #define READY_TIMEOUT 5000 +#define SCAN_TIMEOUT (INQ_LEN * 2 * 1000) static esp_bd_addr_t _peer_bd_addr; static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; static bool _isRemoteAddressSet; @@ -344,7 +345,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa switch(param->disc_res.prop[i].type) { case ESP_BT_GAP_DEV_PROP_EIR: if (get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)) { - log_v("ESP_BT_GAP_DISC_RES_EVT : EIR : %s : %d", peer_bdname, peer_bdname_len); + log_i("ESP_BT_GAP_DISC_RES_EVT : EIR : %s : %d", peer_bdname, peer_bdname_len); if (strlen(_remote_name) == peer_bdname_len && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_EIR : %s", peer_bdname, peer_bdname_len); @@ -363,7 +364,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa log_v("ESP_BT_GAP_DISC_RES_EVT : BDNAME : %s : %d", peer_bdname, peer_bdname_len); if (strlen(_remote_name) == peer_bdname_len && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) { - log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_BDNAME : %s", peer_bdname); + log_i("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_BDNAME : %s", peer_bdname); _isRemoteAddressSet = true; memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); esp_bt_gap_cancel_discovery(); @@ -701,13 +702,20 @@ bool BluetoothSerial::connect(String remoteName) log_e("No remote name is provided"); return false; } + disconnect(); _isRemoteAddressSet = false; strncpy(_remote_name, remoteName.c_str(), ESP_BT_GAP_MAX_BDNAME_LEN); _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN] = 0; log_i("master : remoteName"); // will first resolve name to address esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE); - return (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK); + if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) { + TickType_t xTicksToWait = SCAN_TIMEOUT / portTICK_PERIOD_MS; + if((xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED)) { + return true; + } + } + return false; } bool BluetoothSerial::connect(uint8_t remoteAddress[]) @@ -717,41 +725,58 @@ bool BluetoothSerial::connect(uint8_t remoteAddress[]) log_e("No remote address is provided"); return false; } + disconnect(); _remote_name[0] = 0; _isRemoteAddressSet = true; memcpy(_peer_bd_addr, remoteAddress, ESP_BD_ADDR_LEN); log_i("master : remoteAddress"); - return ( esp_spp_start_discovery(_peer_bd_addr) == ESP_OK); + if (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK) { + TickType_t xTicksToWait = READY_TIMEOUT / portTICK_PERIOD_MS; + if((xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED)) { + return true; + } + } + return false; } bool BluetoothSerial::connect() { if (!isReady(true, READY_TIMEOUT)) return false; if (_isRemoteAddressSet){ + disconnect(); // use resolved or set address first log_i("master : remoteAddress"); - return (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK); + if (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK) { + TickType_t xTicksToWait = READY_TIMEOUT / portTICK_PERIOD_MS; + if(xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED) { + return true; + } + } + return false; } else if (_remote_name[0]) { + disconnect(); log_i("master : remoteName"); // will resolve name to address first - it may take a while esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE); - return (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK); + if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) { + TickType_t xTicksToWait = SCAN_TIMEOUT / portTICK_PERIOD_MS; + if(xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED) { + return true; + } + } + return false; } log_e("Neither Remote name nor address was provided"); return false; } -bool BluetoothSerial::disconnect(int timeout) { +bool BluetoothSerial::disconnect() { if (_spp_client) { flush(); log_i("disconnecting"); if (esp_spp_disconnect(_spp_client) == ESP_OK) { - if (timeout) { - TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; - if((xEventGroupWaitBits(_spp_event_group, SPP_DISCONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_DISCONNECTED)) { - return true; - } - } else { + TickType_t xTicksToWait = READY_TIMEOUT / portTICK_PERIOD_MS; + if((xEventGroupWaitBits(_spp_event_group, SPP_DISCONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_DISCONNECTED)) { return true; } } diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h index 55c7c692f6a..52628983537 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.h +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -48,7 +48,7 @@ class BluetoothSerial: public Stream bool connect(); bool connected(int timeout=0); bool isReady(bool checkMaster=false, int timeout=0); - bool disconnect(int timeout=0); + bool disconnect(); private: String local_name; From 55793e6a12533262ccae41dcafe989f8c837c483 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 12:05:39 -0400 Subject: [PATCH 22/39] 20190916 - optimize code --- .../BluetoothSerial/src/BluetoothSerial.cpp | 44 +++++-------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 65d092b40c9..a00c5be71c6 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -669,6 +669,10 @@ esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback) return ESP_OK; } +static bool waitForConnect(int timeout) { + TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; + return (xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED); +} //Simple Secure Pairing void BluetoothSerial::enableSSP() { @@ -710,10 +714,7 @@ bool BluetoothSerial::connect(String remoteName) // will first resolve name to address esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE); if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) { - TickType_t xTicksToWait = SCAN_TIMEOUT / portTICK_PERIOD_MS; - if((xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED)) { - return true; - } + return waitForConnect(SCAN_TIMEOUT); } return false; } @@ -731,10 +732,7 @@ bool BluetoothSerial::connect(uint8_t remoteAddress[]) memcpy(_peer_bd_addr, remoteAddress, ESP_BD_ADDR_LEN); log_i("master : remoteAddress"); if (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK) { - TickType_t xTicksToWait = READY_TIMEOUT / portTICK_PERIOD_MS; - if((xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED)) { - return true; - } + return waitForConnect(READY_TIMEOUT); } return false; } @@ -747,10 +745,7 @@ bool BluetoothSerial::connect() // use resolved or set address first log_i("master : remoteAddress"); if (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK) { - TickType_t xTicksToWait = READY_TIMEOUT / portTICK_PERIOD_MS; - if(xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED) { - return true; - } + return waitForConnect(READY_TIMEOUT); } return false; } else if (_remote_name[0]) { @@ -759,10 +754,7 @@ bool BluetoothSerial::connect() // will resolve name to address first - it may take a while esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE); if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) { - TickType_t xTicksToWait = SCAN_TIMEOUT / portTICK_PERIOD_MS; - if(xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED) { - return true; - } + return waitForConnect(SCAN_TIMEOUT); } return false; } @@ -776,22 +768,14 @@ bool BluetoothSerial::disconnect() { log_i("disconnecting"); if (esp_spp_disconnect(_spp_client) == ESP_OK) { TickType_t xTicksToWait = READY_TIMEOUT / portTICK_PERIOD_MS; - if((xEventGroupWaitBits(_spp_event_group, SPP_DISCONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_DISCONNECTED)) { - return true; - } + return (xEventGroupWaitBits(_spp_event_group, SPP_DISCONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_DISCONNECTED); } } return false; } bool BluetoothSerial::connected(int timeout) { - TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; - if((xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED)) { - return true; - } - if (timeout) - log_e("Timeout waiting for connected state"); - return false; + return waitForConnect(timeout); } bool BluetoothSerial::isReady(bool checkMaster, int timeout) { @@ -804,12 +788,6 @@ bool BluetoothSerial::isReady(bool checkMaster, int timeout) { return false; } TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; - if((xEventGroupWaitBits(_spp_event_group, SPP_RUNNING, pdFALSE, pdTRUE, xTicksToWait) & SPP_RUNNING)) { - return true; - } - if (timeout) - log_e("Timeout waiting for bt initialization to complete"); - return false; - + return (xEventGroupWaitBits(_spp_event_group, SPP_RUNNING, pdFALSE, pdTRUE, xTicksToWait) & SPP_RUNNING); } #endif From d6c8137a15cf882ad76bcb7bcd770024ba01aace Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 12:19:11 -0400 Subject: [PATCH 23/39] 20190916 - optimize code - more --- .../BluetoothSerial/src/BluetoothSerial.cpp | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index a00c5be71c6..8253f863b6b 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -90,36 +90,24 @@ static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len) { - uint8_t *rmt_bdname = NULL; - uint8_t rmt_bdname_len = 0; - if (!eir || !bdname || !bdname_len) { return false; } - *bdname_len = 0; - *bdname = 0; + uint8_t *rmt_bdname, rmt_bdname_len; + *bdname = *bdname_len = rmt_bdname_len = 0; rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len); if (!rmt_bdname) { rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len); } - if (rmt_bdname) { - if (rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN) { - rmt_bdname_len = ESP_BT_GAP_MAX_BDNAME_LEN; - } - - if (bdname) { - memcpy(bdname, rmt_bdname, rmt_bdname_len); - bdname[rmt_bdname_len] = '\0'; - } - if (bdname_len) { - *bdname_len = rmt_bdname_len; - } + rmt_bdname_len = rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN ? ESP_BT_GAP_MAX_BDNAME_LEN : rmt_bdname_len; + memcpy(bdname, rmt_bdname, rmt_bdname_len); + bdname[rmt_bdname_len] = 0; + *bdname_len = rmt_bdname_len; return true; } - return false; } From 8bc26ef7803932a77b396561df19890adcb67db0 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 14:57:32 -0400 Subject: [PATCH 24/39] 20190916 - add timeout for pin set --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 8253f863b6b..15fda612337 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -681,7 +681,7 @@ bool BluetoothSerial::setPin(const char *pin) { _pin_len = 0; // resetting pin to none (default) } _isPinSet = true; - if (isReady(false)) { + if (isReady(false, READY_TIMEOUT)) { btSetPin(); } return true; From d975955ae688059b25d69f73c21ab3b899f963cf Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 16:27:32 -0400 Subject: [PATCH 25/39] 20190916 - change scan mode to ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 15fda612337..b4b6efbdc70 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -700,7 +700,7 @@ bool BluetoothSerial::connect(String remoteName) _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN] = 0; log_i("master : remoteName"); // will first resolve name to address - esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE); + esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) { return waitForConnect(SCAN_TIMEOUT); } @@ -740,7 +740,7 @@ bool BluetoothSerial::connect() disconnect(); log_i("master : remoteName"); // will resolve name to address first - it may take a while - esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE); + esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) { return waitForConnect(SCAN_TIMEOUT); } From 9e5c678c01f75fca8b7a0ab5ffab724e2e040c46 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 18:00:12 -0400 Subject: [PATCH 26/39] 20190916 - update example code slightly --- .../examples/SerialToSerialBTM/SerialToSerialBTM.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index febb79ed0db..cde925b0acb 100644 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -29,10 +29,10 @@ void setup() { // connect(address) is fast (upto 5 secs max), connect(name) is slow (upto 30 secs max) as it needs // to resolve name to address first, but it allows to connect to different devices with the same name. // Set CoreDebugLevel to Info to view devices bluetooth address and device names - //connected = SerialBT.connect(name); - connected = SerialBT.connect(address); + connected = SerialBT.connect(name); + //connected = SerialBT.connect(address); - if(SerialBT.connected(5000)) { + if(connected)) { Serial.println("Connected Succesfully!"); } else { while(!SerialBT.connected()) { From 470d592e8949bf906c4238f5e5640cc31937ebca Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 18:07:33 -0400 Subject: [PATCH 27/39] 20190916 - increase READY_TIMEOUT to 10 secs --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index b4b6efbdc70..8a7dd4c1f4c 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -55,7 +55,7 @@ static esp_spp_cb_t * custom_spp_callback = NULL; #define INQ_LEN 0x10 #define INQ_NUM_RSPS 20 -#define READY_TIMEOUT 5000 +#define READY_TIMEOUT (10 * 1000) #define SCAN_TIMEOUT (INQ_LEN * 2 * 1000) static esp_bd_addr_t _peer_bd_addr; static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; From 58ad4c02fd0766cde015b8fbc61856d73a5620a8 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Wed, 18 Sep 2019 18:50:48 -0400 Subject: [PATCH 28/39] 20190916 - typo in example and move waitForConnect() to static area --- .../examples/SerialToSerialBTM/SerialToSerialBTM.ino | 2 +- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index cde925b0acb..4b838f4d033 100644 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -32,7 +32,7 @@ void setup() { connected = SerialBT.connect(name); //connected = SerialBT.connect(address); - if(connected)) { + if(connected) { Serial.println("Connected Succesfully!"); } else { while(!SerialBT.connected()) { diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 8a7dd4c1f4c..e8d553e508f 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -572,6 +572,11 @@ static bool _stop_bt() return true; } +static bool waitForConnect(int timeout) { + TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; + return (xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED); +} + /* * Serial Bluetooth Arduino * @@ -657,11 +662,6 @@ esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback) return ESP_OK; } -static bool waitForConnect(int timeout) { - TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; - return (xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED); -} - //Simple Secure Pairing void BluetoothSerial::enableSSP() { _enableSSP = true; From a3e8b489871cc31e92d1aaa7a5ad49ceaf23f932 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Thu, 19 Sep 2019 11:09:50 -0400 Subject: [PATCH 29/39] 20190916 - update example comments --- .../SerialToSerialBTM/SerialToSerialBTM.ino | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index 4b838f4d033..8d72e3ceb65 100644 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -1,8 +1,10 @@ //This example code is in the Public Domain (or CC0 licensed, at your option.) -//By Evandro Copercini - 2018 +//By Victor Tchistiak - 2019 +// +//This example demostrates master mode bluetooth connection and pin +//it creates a bridge between Serial and Classical Bluetooth (SPP) +//this is an extention of the SerialToSerialBT example by Evandro Copercini - 2018 // -//This example creates a bridge between Serial and Classical Bluetooth (SPP) -//and also demonstrate that SerialBT have the same functionalities of a normal Serial #include "BluetoothSerial.h" @@ -26,7 +28,7 @@ void setup() { //SerialBT.setPin(pin); Serial.println("The device started in master mode, make sure remote BT device is on!"); - // connect(address) is fast (upto 5 secs max), connect(name) is slow (upto 30 secs max) as it needs + // connect(address) is fast (upto 10 secs max), connect(name) is slow (upto 30 secs max) as it needs // to resolve name to address first, but it allows to connect to different devices with the same name. // Set CoreDebugLevel to Info to view devices bluetooth address and device names connected = SerialBT.connect(name); @@ -35,16 +37,13 @@ void setup() { if(connected) { Serial.println("Connected Succesfully!"); } else { - while(!SerialBT.connected()) { - Serial.println("Not connected yet?"); - delay(10000); + while(!SerialBT.connected(10000)) { + Serial.println("Failed to connect. Make sure remote device is available and in range, then restart app."); } } - // disconnect() may take upto 5 secs max + // disconnect() may take upto 10 secs max if (SerialBT.disconnect()) { Serial.println("Disconnected Succesfully!"); - } else { - Serial.println("Not disconnected yet?"); } SerialBT.connect(); } From 1b36dad0655d3308ec7ba03dbb4d8289cbce4c74 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Thu, 19 Sep 2019 11:11:11 -0400 Subject: [PATCH 30/39] 20190916 - update example comments --- .../examples/SerialToSerialBTM/SerialToSerialBTM.ino | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index 8d72e3ceb65..bbc4339b9b0 100644 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -8,10 +8,6 @@ #include "BluetoothSerial.h" -#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) -#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it -#endif - BluetoothSerial SerialBT; String MACadd = "AA:BB:CC:11:22:33"; From 2ea5089ebab8357c92647def1d29a20926db7c9c Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Thu, 19 Sep 2019 11:15:03 -0400 Subject: [PATCH 31/39] 20190916 - update example comments --- .../examples/SerialToSerialBTM/SerialToSerialBTM.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino index bbc4339b9b0..73f3dc058b4 100644 --- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino +++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino @@ -41,6 +41,7 @@ void setup() { if (SerialBT.disconnect()) { Serial.println("Disconnected Succesfully!"); } + // this would reconnect to the name(will use address, if resolved) or address used with connect(name/address). SerialBT.connect(); } From 839baa845ebcd09badf8d5655f457451cd0ce676 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Fri, 27 Sep 2019 21:34:32 -0400 Subject: [PATCH 32/39] 20190916 - add new example to remove paired devices from ESP32 --- .../bt_remove_paired_devices.ino | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100755 libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino diff --git a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino new file mode 100755 index 00000000000..f603968e099 --- /dev/null +++ b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino @@ -0,0 +1,87 @@ +//This example code is in the Public Domain (or CC0 licensed, at your option.) +//By Victor Tchistiak - 2019 +// +//This example demonstrates reading and removing paired devices stored on the ESP32 flash memory +//Sometimes you may find your ESP32 device could not connect to the remote device despite many +//successful connections earlier. It may be a result of loading sketch to multiple ESP32 devices +//but using the same bluetooth localName (default is "ESP32"). +//The only remedy is to delete this saved bound device from your device flash memory +//and pair with the other device again. +// +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#include"esp_gap_bt_api.h" +#include "esp_err.h" + +#define REMOVE_BONDED_DEVICES 0 // <- Set to 0 to view all bonded devices addresses, set to 1 to remove + +#define PAIR_MAX_DEVICES 20 +uint8_t pairedDeviceBtAddr[PAIR_MAX_DEVICES][6]; +char bda_str[18]; + +bool initBluetooth() +{ + if (!btStart()) { + Serial.println("Failed to initialize controller"); + return false; + } + + if (esp_bluedroid_init() != ESP_OK) { + Serial.println("Failed to initialize bluedroid"); + return false; + } + + if (esp_bluedroid_enable() != ESP_OK) { + Serial.println("Failed to enable bluedroid"); + return false; + } + +} + +char *bda2str(const uint8_t* bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + return str; +} + +void setup() { + Serial.begin(115200); + + initBluetooth(); + Serial.print("ESP32 bluetooth address: "); Serial.println(bda2str(esp_bt_dev_get_address(), bda_str, 18)); + /*********************************************************** + * Get the numbers of bonded/paired devices to the BT module + ************************************************************/ + int count = esp_bt_gap_get_bond_device_num(); + if (count) + { + Serial.print("Bonded device count: "); Serial.println(count); + if (PAIR_MAX_DEVICES < count) { + count = PAIR_MAX_DEVICES; + Serial.print("Reset bonded device count: "); Serial.println(count); + } + esp_err_t tError = esp_bt_gap_get_bond_device_list(&count, pairedDeviceBtAddr); + if (ESP_OK == tError) { + for (int i = 0; i < count; i++) { + Serial.print("Found bonded device # "); Serial.print(i); Serial.print(" -> "); + Serial.println(bda2str(pairedDeviceBtAddr[i], bda_str, 18)); + if(REMOVE_BONDED_DEVICES) { + esp_err_t tError = esp_bt_gap_remove_bond_device(pairedDeviceBtAddr[i]); + if(ESP_OK == tError) { + Serial.print("Removed bonded device # "); + } else { + Serial.print("Failed to Bonded bonded device # "); + } + Serial.println(i); + } + } + + } + } +} + +void loop() {} From 4f0727db89d3b1adb2ea96ce59b05f3d8b9c6a71 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Fri, 27 Sep 2019 21:54:16 -0400 Subject: [PATCH 33/39] 20190916 - correct typo in example --- .../bt_remove_paired_devices.ino | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino index f603968e099..49a20db0a7b 100755 --- a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino +++ b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino @@ -21,17 +21,17 @@ char bda_str[18]; bool initBluetooth() { - if (!btStart()) { + if(!btStart()) { Serial.println("Failed to initialize controller"); return false; } - if (esp_bluedroid_init() != ESP_OK) { + if(esp_bluedroid_init() != ESP_OK) { Serial.println("Failed to initialize bluedroid"); return false; } - if (esp_bluedroid_enable() != ESP_OK) { + if(esp_bluedroid_enable() != ESP_OK) { Serial.println("Failed to enable bluedroid"); return false; } @@ -53,20 +53,19 @@ void setup() { initBluetooth(); Serial.print("ESP32 bluetooth address: "); Serial.println(bda2str(esp_bt_dev_get_address(), bda_str, 18)); - /*********************************************************** - * Get the numbers of bonded/paired devices to the BT module - ************************************************************/ + // Get the numbers of bonded/paired devices to the BT module int count = esp_bt_gap_get_bond_device_num(); - if (count) - { + if(!count) { + Serial.println("No bonded device found."); + } else { Serial.print("Bonded device count: "); Serial.println(count); - if (PAIR_MAX_DEVICES < count) { + if(PAIR_MAX_DEVICES < count) { count = PAIR_MAX_DEVICES; Serial.print("Reset bonded device count: "); Serial.println(count); } esp_err_t tError = esp_bt_gap_get_bond_device_list(&count, pairedDeviceBtAddr); - if (ESP_OK == tError) { - for (int i = 0; i < count; i++) { + if(ESP_OK == tError) { + for(int i = 0; i < count; i++) { Serial.print("Found bonded device # "); Serial.print(i); Serial.print(" -> "); Serial.println(bda2str(pairedDeviceBtAddr[i], bda_str, 18)); if(REMOVE_BONDED_DEVICES) { @@ -74,12 +73,11 @@ void setup() { if(ESP_OK == tError) { Serial.print("Removed bonded device # "); } else { - Serial.print("Failed to Bonded bonded device # "); + Serial.print("Failed to remove bonded device # "); } Serial.println(i); } - } - + } } } } From 557221b79079f42949df7b3b608139c2a84f328b Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Sat, 28 Sep 2019 08:45:45 -0400 Subject: [PATCH 34/39] 20190916 - update example comment, add remove_bond_device() method for convenience. --- .../bt_remove_paired_devices.ino | 12 +++++++----- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 8 ++++++++ libraries/BluetoothSerial/src/BluetoothSerial.h | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino index 49a20db0a7b..c86c53417d8 100755 --- a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino +++ b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino @@ -2,9 +2,11 @@ //By Victor Tchistiak - 2019 // //This example demonstrates reading and removing paired devices stored on the ESP32 flash memory -//Sometimes you may find your ESP32 device could not connect to the remote device despite many -//successful connections earlier. It may be a result of loading sketch to multiple ESP32 devices -//but using the same bluetooth localName (default is "ESP32"). +//Sometimes you may find your ESP32 device could not connect to the remote device despite +//many successful connections earlier. This is most likely a result of client replacing your paired +//device info with new one from other device. The BT clients stores connection info for paired devices, +//but it is limited to a few devices only, when new device pairs one of the previously paired devices +//would be replaced with new one, if number of stored devices is exceeded. //The only remedy is to delete this saved bound device from your device flash memory //and pair with the other device again. // @@ -53,7 +55,7 @@ void setup() { initBluetooth(); Serial.print("ESP32 bluetooth address: "); Serial.println(bda2str(esp_bt_dev_get_address(), bda_str, 18)); - // Get the numbers of bonded/paired devices to the BT module + // Get the numbers of bonded/paired devices in the BT module int count = esp_bt_gap_get_bond_device_num(); if(!count) { Serial.println("No bonded device found."); @@ -77,7 +79,7 @@ void setup() { } Serial.println(i); } - } + } } } } diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index e8d553e508f..a0600209f53 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -762,6 +762,14 @@ bool BluetoothSerial::disconnect() { return false; } +bool BluetoothSerial::remove_bond_device(uint8_t remoteAddress[]) { + if (isReady(false, READY_TIMEOUT)) { + log_i("removing bonded device"); + return (esp_bt_gap_remove_bond_device(remoteAddress) == ESP_OK); + } + return false; +} + bool BluetoothSerial::connected(int timeout) { return waitForConnect(timeout); } diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h index 52628983537..b862a2edf82 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.h +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -49,6 +49,7 @@ class BluetoothSerial: public Stream bool connected(int timeout=0); bool isReady(bool checkMaster=false, int timeout=0); bool disconnect(); + bool remove_bond_device(uint8_t remoteAddress[]); private: String local_name; From 25cf9d945ebbc8cfb5b77dd4048e7eb22abd78ab Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Sat, 28 Sep 2019 08:56:30 -0400 Subject: [PATCH 35/39] 20190916 - reword example comment. --- .../bt_remove_paired_devices/bt_remove_paired_devices.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino index c86c53417d8..7c263924961 100755 --- a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino +++ b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino @@ -4,9 +4,9 @@ //This example demonstrates reading and removing paired devices stored on the ESP32 flash memory //Sometimes you may find your ESP32 device could not connect to the remote device despite //many successful connections earlier. This is most likely a result of client replacing your paired -//device info with new one from other device. The BT clients stores connection info for paired devices, -//but it is limited to a few devices only, when new device pairs one of the previously paired devices -//would be replaced with new one, if number of stored devices is exceeded. +//device info with new one from other device. The BT clients store connection info for paired devices, +//but it is limited to a few devices only. When new device pairs and number of stored devices is exceeded, +//one of the previously paired devices would be replaced with new one. //The only remedy is to delete this saved bound device from your device flash memory //and pair with the other device again. // From 8105bc9c2e2707ff8aa4d59a33d37a320fc0d3a5 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Sat, 28 Sep 2019 11:01:17 -0400 Subject: [PATCH 36/39] 20190916 - rename remove_bond_device() --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 2 +- libraries/BluetoothSerial/src/BluetoothSerial.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index a0600209f53..3cee73bb2cd 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -762,7 +762,7 @@ bool BluetoothSerial::disconnect() { return false; } -bool BluetoothSerial::remove_bond_device(uint8_t remoteAddress[]) { +bool BluetoothSerial::removePairedDevice(uint8_t remoteAddress[]) { if (isReady(false, READY_TIMEOUT)) { log_i("removing bonded device"); return (esp_bt_gap_remove_bond_device(remoteAddress) == ESP_OK); diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h index b862a2edf82..295b9535f43 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.h +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -49,7 +49,7 @@ class BluetoothSerial: public Stream bool connected(int timeout=0); bool isReady(bool checkMaster=false, int timeout=0); bool disconnect(); - bool remove_bond_device(uint8_t remoteAddress[]); + bool removePairedDevice(uint8_t remoteAddress[]); private: String local_name; From 8483a1280d0683f036fa2ab5c6fb44c3eb88cd4d Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Sat, 28 Sep 2019 14:40:35 -0400 Subject: [PATCH 37/39] 20190916 - rename removePairedDevice() to unpairDevice() --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 2 +- libraries/BluetoothSerial/src/BluetoothSerial.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 3cee73bb2cd..21a71a29578 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -762,7 +762,7 @@ bool BluetoothSerial::disconnect() { return false; } -bool BluetoothSerial::removePairedDevice(uint8_t remoteAddress[]) { +bool BluetoothSerial::unpairDevice(uint8_t remoteAddress[]) { if (isReady(false, READY_TIMEOUT)) { log_i("removing bonded device"); return (esp_bt_gap_remove_bond_device(remoteAddress) == ESP_OK); diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h index 295b9535f43..68269fa9ae6 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.h +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -49,7 +49,7 @@ class BluetoothSerial: public Stream bool connected(int timeout=0); bool isReady(bool checkMaster=false, int timeout=0); bool disconnect(); - bool removePairedDevice(uint8_t remoteAddress[]); + bool unpairDevice(uint8_t remoteAddress[]); private: String local_name; From 15788663dbb34f4c3aa82c5706e68c1b33c55b6b Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 1 Oct 2019 09:51:17 -0400 Subject: [PATCH 38/39] 20190916 - code review changes --- libraries/BluetoothSerial/src/BluetoothSerial.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index c439097380d..758ee08c296 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -574,7 +574,7 @@ static bool _stop_bt() static bool waitForConnect(int timeout) { TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; - return (xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED); + return (xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) != 0); } /* @@ -680,6 +680,7 @@ bool BluetoothSerial::setPin(const char *pin) { } else { _pin_len = 0; // resetting pin to none (default) } + _pin_code[_pin_len] = 0; _isPinSet = true; if (isReady(false, READY_TIMEOUT)) { btSetPin(); @@ -756,7 +757,7 @@ bool BluetoothSerial::disconnect() { log_i("disconnecting"); if (esp_spp_disconnect(_spp_client) == ESP_OK) { TickType_t xTicksToWait = READY_TIMEOUT / portTICK_PERIOD_MS; - return (xEventGroupWaitBits(_spp_event_group, SPP_DISCONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_DISCONNECTED); + return (xEventGroupWaitBits(_spp_event_group, SPP_DISCONNECTED, pdFALSE, pdTRUE, xTicksToWait) != 0); } } return false; @@ -784,6 +785,6 @@ bool BluetoothSerial::isReady(bool checkMaster, int timeout) { return false; } TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; - return (xEventGroupWaitBits(_spp_event_group, SPP_RUNNING, pdFALSE, pdTRUE, xTicksToWait) & SPP_RUNNING); + return (xEventGroupWaitBits(_spp_event_group, SPP_RUNNING, pdFALSE, pdTRUE, xTicksToWait) != 0); } #endif From 7add4bc4791f0a49e9dc610f35c9bbe46a493063 Mon Sep 17 00:00:00 2001 From: Victor Tchistiak Date: Tue, 1 Oct 2019 09:54:55 -0400 Subject: [PATCH 39/39] 20190916 - fix return value in setup() od example --- .../bt_remove_paired_devices/bt_remove_paired_devices.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino index 7c263924961..c316a73b2bc 100755 --- a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino +++ b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino @@ -37,7 +37,7 @@ bool initBluetooth() Serial.println("Failed to enable bluedroid"); return false; } - + return true; } char *bda2str(const uint8_t* bda, char *str, size_t size)