Skip to content

Allow BluetoothSerial::connect() with specified channel and more options #6380

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 26, 2022
Empty file.
Empty file.
110 changes: 110 additions & 0 deletions libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**
* Bluetooth Classic Example
* Scan for devices - asyncronously, print device as soon as found
* query devices for SPP - SDP profile
* connect to first device offering a SPP connection
*
* Example python server:
* source: https://gist.github.com/ukBaz/217875c83c2535d22a16ba38fc8f2a91
*
* Tested with Raspberry Pi onboard Wifi/BT, USB BT 4.0 dongles, USB BT 1.1 dongles,
* 202202: does NOT work with USB BT 2.0 dongles when esp32 aduino lib is compiled with SSP support!
* see https://github.com/espressif/esp-idf/issues/8394
*
* use ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE in connect() if remote side requests 'RequireAuthentication': dbus.Boolean(True),
* use ESP_SPP_SEC_NONE or ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE in connect() if remote side has Authentication: False
*/

#include <map>
#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

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add this test as well (it is in every SPP example in order to warn users that try to run it in any chip but ESP32).

#if !defined(CONFIG_BT_SPP_ENABLED)
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
#endif

BluetoothSerial SerialBT;


#define BT_DISCOVER_TIME 10000
esp_spp_sec_t sec_mask=ESP_SPP_SEC_NONE; // or ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE to request pincode confirmation
esp_spp_role_t role=ESP_SPP_ROLE_SLAVE; // or ESP_SPP_ROLE_MASTER

// std::map<BTAddress, BTAdvertisedDeviceSet> btDeviceList;

void setup() {
Serial.begin(115200);
if(! SerialBT.begin("ESP32test", true) ) {
Serial.println("========== serialBT failed!");
abort();
}
// SerialBT.setPin("1234"); // doesn't seem to change anything
// SerialBT.enableSSP(); // doesn't seem to change anything


Serial.println("Starting discoverAsync...");
BTScanResults* btDeviceList = SerialBT.getScanResults(); // maybe accessing from different threads!
if (SerialBT.discoverAsync([](BTAdvertisedDevice* pDevice) {
// BTAdvertisedDeviceSet*set = reinterpret_cast<BTAdvertisedDeviceSet*>(pDevice);
// btDeviceList[pDevice->getAddress()] = * set;
Serial.printf(">>>>>>>>>>>Found a new device asynchronously: %s\n", pDevice->toString().c_str());
} )
) {
delay(BT_DISCOVER_TIME);
Serial.print("Stopping discoverAsync... ");
SerialBT.discoverAsyncStop();
Serial.println("discoverAsync stopped");
delay(5000);
if(btDeviceList->getCount() > 0) {
BTAddress addr;
int channel=0;
Serial.println("Found devices:");
for (int i=0; i < btDeviceList->getCount(); i++) {
BTAdvertisedDevice *device=btDeviceList->getDevice(i);
Serial.printf(" ----- %s %s %d\n", device->getAddress().toString().c_str(), device->getName().c_str(), device->getRSSI());
std::map<int,std::string> channels=SerialBT.getChannels(device->getAddress());
Serial.printf("scanned for services, found %d\n", channels.size());
for(auto const &entry : channels) {
Serial.printf(" channel %d (%s)\n", entry.first, entry.second.c_str());
}
if(channels.size() > 0) {
addr = device->getAddress();
channel=channels.begin()->first;
}
}
if(addr) {
Serial.printf("connecting to %s - %d\n", addr.toString().c_str(), channel);
SerialBT.connect(addr, channel, sec_mask, role);
}
} else {
Serial.println("Didn't find any devices");
}
} else {
Serial.println("Error on discoverAsync f.e. not workin after a \"connect\"");
}
}


String sendData="Hi from esp32!\n";

void loop() {
if(! SerialBT.isClosed() && SerialBT.connected()) {
if( SerialBT.write((const uint8_t*) sendData.c_str(),sendData.length()) != sendData.length()) {
Serial.println("tx: error");
} else {
Serial.printf("tx: %s",sendData.c_str());
}
if(SerialBT.available()) {
Serial.print("rx: ");
while(SerialBT.available()) {
int c=SerialBT.read();
if(c >= 0) {
Serial.print((char) c);
}
}
Serial.println();
}
} else {
Serial.println("not connected");
}
delay(1000);
}
16 changes: 13 additions & 3 deletions libraries/BluetoothSerial/src/BTAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ BTAddress::BTAddress(esp_bd_addr_t address) {
memcpy(m_address, address, ESP_BD_ADDR_LEN);
} // BTAddress

BTAddress::BTAddress() {
bzero(m_address, ESP_BD_ADDR_LEN);
} // BTAddress

/**
* @brief Create an address from a hex string
Expand Down Expand Up @@ -64,13 +67,20 @@ bool BTAddress::equals(BTAddress otherAddress) {
return memcmp(otherAddress.getNative(), m_address, 6) == 0;
} // equals

BTAddress::operator bool () const {
for(int i = 0; i < ESP_BD_ADDR_LEN; i++){
if(this->m_address[i])
return true;
}
return false;
} // operator ()

/**
* @brief Return the native representation of the address.
* @return The native representation of the address.
*/
esp_bd_addr_t *BTAddress::getNative() {
return &m_address;
esp_bd_addr_t *BTAddress::getNative() const {
return const_cast<esp_bd_addr_t *>(&m_address);
} // getNative


Expand All @@ -85,7 +95,7 @@ esp_bd_addr_t *BTAddress::getNative() {
*
* @return The string representation of the address.
*/
std::string BTAddress::toString() {
std::string BTAddress::toString() const {
auto size = 18;
char *res = (char*)malloc(size);
snprintf(res, size, "%02x:%02x:%02x:%02x:%02x:%02x", m_address[0], m_address[1], m_address[2], m_address[3], m_address[4], m_address[5]);
Expand Down
7 changes: 5 additions & 2 deletions libraries/BluetoothSerial/src/BTAddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
*/
class BTAddress {
public:
BTAddress();
BTAddress(esp_bd_addr_t address);
BTAddress(std::string stringAddress);
bool equals(BTAddress otherAddress);
esp_bd_addr_t* getNative();
std::string toString();
operator bool () const;

esp_bd_addr_t* getNative() const;
std::string toString() const;

private:
esp_bd_addr_t m_address;
Expand Down
26 changes: 13 additions & 13 deletions libraries/BluetoothSerial/src/BTAdvertisedDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ class BTAdvertisedDevice {
virtual ~BTAdvertisedDevice() = default;

virtual BTAddress getAddress();
virtual uint32_t getCOD();
virtual std::string getName();
virtual int8_t getRSSI();
virtual uint32_t getCOD() const;
virtual std::string getName() const;
virtual int8_t getRSSI() const;


virtual bool haveCOD();
virtual bool haveName();
virtual bool haveRSSI();
virtual bool haveCOD() const;
virtual bool haveName() const;
virtual bool haveRSSI() const;

virtual std::string toString();
};
Expand All @@ -35,14 +35,14 @@ class BTAdvertisedDeviceSet : public virtual BTAdvertisedDevice {


BTAddress getAddress();
uint32_t getCOD();
std::string getName();
int8_t getRSSI();
uint32_t getCOD() const;
std::string getName() const;
int8_t getRSSI() const;


bool haveCOD();
bool haveName();
bool haveRSSI();
bool haveCOD() const;
bool haveName() const;
bool haveRSSI() const;

std::string toString();

Expand All @@ -62,4 +62,4 @@ class BTAdvertisedDeviceSet : public virtual BTAdvertisedDevice {
int8_t m_rssi;
};

#endif
#endif
12 changes: 6 additions & 6 deletions libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ BTAdvertisedDeviceSet::BTAdvertisedDeviceSet() {
} // BTAdvertisedDeviceSet

BTAddress BTAdvertisedDeviceSet::getAddress() { return m_address; }
uint32_t BTAdvertisedDeviceSet::getCOD() { return m_cod; }
std::string BTAdvertisedDeviceSet::getName() { return m_name; }
int8_t BTAdvertisedDeviceSet::getRSSI() { return m_rssi; }
uint32_t BTAdvertisedDeviceSet::getCOD() const { return m_cod; }
std::string BTAdvertisedDeviceSet::getName() const { return m_name; }
int8_t BTAdvertisedDeviceSet::getRSSI() const { return m_rssi; }


bool BTAdvertisedDeviceSet::haveCOD() { return m_haveCOD; }
bool BTAdvertisedDeviceSet::haveName() { return m_haveName; }
bool BTAdvertisedDeviceSet::haveRSSI() { return m_haveRSSI; }
bool BTAdvertisedDeviceSet::haveCOD() const { return m_haveCOD; }
bool BTAdvertisedDeviceSet::haveName() const { return m_haveName; }
bool BTAdvertisedDeviceSet::haveRSSI() const { return m_haveRSSI; }

/**
* @brief Create a string representation of this device.
Expand Down
Loading