Skip to content

Commit b88a70a

Browse files
authored
Allow BluetoothSerial::connect() with specified channel and more options (espressif#6380)
* BTAddress const, add bool() * BTAdvertisedDevice: const functions * BluetoothSerial: add: getChannels, add isClosed, add read/peek timeout, add connect with channel# * BluetoothSerial: add sec_mask, role in ::connect * BluetoothSerial add discover and connect with channel number example * DiscoverConnect: add SPP_ENABLED check * DiscoverConnect: disable on esp32s3
1 parent f3bdfb3 commit b88a70a

File tree

10 files changed

+341
-43
lines changed

10 files changed

+341
-43
lines changed

Diff for: libraries/BluetoothSerial/examples/DiscoverConnect/.skip.esp32c3

Whitespace-only changes.

Diff for: libraries/BluetoothSerial/examples/DiscoverConnect/.skip.esp32s2

Whitespace-only changes.

Diff for: libraries/BluetoothSerial/examples/DiscoverConnect/.skip.esp32s3

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/**
2+
* Bluetooth Classic Example
3+
* Scan for devices - asyncronously, print device as soon as found
4+
* query devices for SPP - SDP profile
5+
* connect to first device offering a SPP connection
6+
*
7+
* Example python server:
8+
* source: https://gist.github.com/ukBaz/217875c83c2535d22a16ba38fc8f2a91
9+
*
10+
* Tested with Raspberry Pi onboard Wifi/BT, USB BT 4.0 dongles, USB BT 1.1 dongles,
11+
* 202202: does NOT work with USB BT 2.0 dongles when esp32 aduino lib is compiled with SSP support!
12+
* see https://github.com/espressif/esp-idf/issues/8394
13+
*
14+
* use ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE in connect() if remote side requests 'RequireAuthentication': dbus.Boolean(True),
15+
* use ESP_SPP_SEC_NONE or ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE in connect() if remote side has Authentication: False
16+
*/
17+
18+
#include <map>
19+
#include <BluetoothSerial.h>
20+
21+
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
22+
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
23+
#endif
24+
25+
#if !defined(CONFIG_BT_SPP_ENABLED)
26+
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
27+
#endif
28+
29+
BluetoothSerial SerialBT;
30+
31+
32+
#define BT_DISCOVER_TIME 10000
33+
esp_spp_sec_t sec_mask=ESP_SPP_SEC_NONE; // or ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE to request pincode confirmation
34+
esp_spp_role_t role=ESP_SPP_ROLE_SLAVE; // or ESP_SPP_ROLE_MASTER
35+
36+
// std::map<BTAddress, BTAdvertisedDeviceSet> btDeviceList;
37+
38+
void setup() {
39+
Serial.begin(115200);
40+
if(! SerialBT.begin("ESP32test", true) ) {
41+
Serial.println("========== serialBT failed!");
42+
abort();
43+
}
44+
// SerialBT.setPin("1234"); // doesn't seem to change anything
45+
// SerialBT.enableSSP(); // doesn't seem to change anything
46+
47+
48+
Serial.println("Starting discoverAsync...");
49+
BTScanResults* btDeviceList = SerialBT.getScanResults(); // maybe accessing from different threads!
50+
if (SerialBT.discoverAsync([](BTAdvertisedDevice* pDevice) {
51+
// BTAdvertisedDeviceSet*set = reinterpret_cast<BTAdvertisedDeviceSet*>(pDevice);
52+
// btDeviceList[pDevice->getAddress()] = * set;
53+
Serial.printf(">>>>>>>>>>>Found a new device asynchronously: %s\n", pDevice->toString().c_str());
54+
} )
55+
) {
56+
delay(BT_DISCOVER_TIME);
57+
Serial.print("Stopping discoverAsync... ");
58+
SerialBT.discoverAsyncStop();
59+
Serial.println("discoverAsync stopped");
60+
delay(5000);
61+
if(btDeviceList->getCount() > 0) {
62+
BTAddress addr;
63+
int channel=0;
64+
Serial.println("Found devices:");
65+
for (int i=0; i < btDeviceList->getCount(); i++) {
66+
BTAdvertisedDevice *device=btDeviceList->getDevice(i);
67+
Serial.printf(" ----- %s %s %d\n", device->getAddress().toString().c_str(), device->getName().c_str(), device->getRSSI());
68+
std::map<int,std::string> channels=SerialBT.getChannels(device->getAddress());
69+
Serial.printf("scanned for services, found %d\n", channels.size());
70+
for(auto const &entry : channels) {
71+
Serial.printf(" channel %d (%s)\n", entry.first, entry.second.c_str());
72+
}
73+
if(channels.size() > 0) {
74+
addr = device->getAddress();
75+
channel=channels.begin()->first;
76+
}
77+
}
78+
if(addr) {
79+
Serial.printf("connecting to %s - %d\n", addr.toString().c_str(), channel);
80+
SerialBT.connect(addr, channel, sec_mask, role);
81+
}
82+
} else {
83+
Serial.println("Didn't find any devices");
84+
}
85+
} else {
86+
Serial.println("Error on discoverAsync f.e. not workin after a \"connect\"");
87+
}
88+
}
89+
90+
91+
String sendData="Hi from esp32!\n";
92+
93+
void loop() {
94+
if(! SerialBT.isClosed() && SerialBT.connected()) {
95+
if( SerialBT.write((const uint8_t*) sendData.c_str(),sendData.length()) != sendData.length()) {
96+
Serial.println("tx: error");
97+
} else {
98+
Serial.printf("tx: %s",sendData.c_str());
99+
}
100+
if(SerialBT.available()) {
101+
Serial.print("rx: ");
102+
while(SerialBT.available()) {
103+
int c=SerialBT.read();
104+
if(c >= 0) {
105+
Serial.print((char) c);
106+
}
107+
}
108+
Serial.println();
109+
}
110+
} else {
111+
Serial.println("not connected");
112+
}
113+
delay(1000);
114+
}

Diff for: libraries/BluetoothSerial/src/BTAddress.cpp

+13-3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ BTAddress::BTAddress(esp_bd_addr_t address) {
2929
memcpy(m_address, address, ESP_BD_ADDR_LEN);
3030
} // BTAddress
3131

32+
BTAddress::BTAddress() {
33+
bzero(m_address, ESP_BD_ADDR_LEN);
34+
} // BTAddress
3235

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

70+
BTAddress::operator bool () const {
71+
for(int i = 0; i < ESP_BD_ADDR_LEN; i++){
72+
if(this->m_address[i])
73+
return true;
74+
}
75+
return false;
76+
} // operator ()
6777

6878
/**
6979
* @brief Return the native representation of the address.
7080
* @return The native representation of the address.
7181
*/
72-
esp_bd_addr_t *BTAddress::getNative() {
73-
return &m_address;
82+
esp_bd_addr_t *BTAddress::getNative() const {
83+
return const_cast<esp_bd_addr_t *>(&m_address);
7484
} // getNative
7585

7686

@@ -85,7 +95,7 @@ esp_bd_addr_t *BTAddress::getNative() {
8595
*
8696
* @return The string representation of the address.
8797
*/
88-
std::string BTAddress::toString() {
98+
std::string BTAddress::toString() const {
8999
auto size = 18;
90100
char *res = (char*)malloc(size);
91101
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]);

Diff for: libraries/BluetoothSerial/src/BTAddress.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
*/
2323
class BTAddress {
2424
public:
25+
BTAddress();
2526
BTAddress(esp_bd_addr_t address);
2627
BTAddress(std::string stringAddress);
2728
bool equals(BTAddress otherAddress);
28-
esp_bd_addr_t* getNative();
29-
std::string toString();
29+
operator bool () const;
30+
31+
esp_bd_addr_t* getNative() const;
32+
std::string toString() const;
3033

3134
private:
3235
esp_bd_addr_t m_address;

Diff for: libraries/BluetoothSerial/src/BTAdvertisedDevice.h

+13-13
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ class BTAdvertisedDevice {
1616
virtual ~BTAdvertisedDevice() = default;
1717

1818
virtual BTAddress getAddress();
19-
virtual uint32_t getCOD();
20-
virtual std::string getName();
21-
virtual int8_t getRSSI();
19+
virtual uint32_t getCOD() const;
20+
virtual std::string getName() const;
21+
virtual int8_t getRSSI() const;
2222

2323

24-
virtual bool haveCOD();
25-
virtual bool haveName();
26-
virtual bool haveRSSI();
24+
virtual bool haveCOD() const;
25+
virtual bool haveName() const;
26+
virtual bool haveRSSI() const;
2727

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

3636

3737
BTAddress getAddress();
38-
uint32_t getCOD();
39-
std::string getName();
40-
int8_t getRSSI();
38+
uint32_t getCOD() const;
39+
std::string getName() const;
40+
int8_t getRSSI() const;
4141

4242

43-
bool haveCOD();
44-
bool haveName();
45-
bool haveRSSI();
43+
bool haveCOD() const;
44+
bool haveName() const;
45+
bool haveRSSI() const;
4646

4747
std::string toString();
4848

@@ -62,4 +62,4 @@ class BTAdvertisedDeviceSet : public virtual BTAdvertisedDevice {
6262
int8_t m_rssi;
6363
};
6464

65-
#endif
65+
#endif

Diff for: libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ BTAdvertisedDeviceSet::BTAdvertisedDeviceSet() {
2525
} // BTAdvertisedDeviceSet
2626

2727
BTAddress BTAdvertisedDeviceSet::getAddress() { return m_address; }
28-
uint32_t BTAdvertisedDeviceSet::getCOD() { return m_cod; }
29-
std::string BTAdvertisedDeviceSet::getName() { return m_name; }
30-
int8_t BTAdvertisedDeviceSet::getRSSI() { return m_rssi; }
28+
uint32_t BTAdvertisedDeviceSet::getCOD() const { return m_cod; }
29+
std::string BTAdvertisedDeviceSet::getName() const { return m_name; }
30+
int8_t BTAdvertisedDeviceSet::getRSSI() const { return m_rssi; }
3131

3232

33-
bool BTAdvertisedDeviceSet::haveCOD() { return m_haveCOD; }
34-
bool BTAdvertisedDeviceSet::haveName() { return m_haveName; }
35-
bool BTAdvertisedDeviceSet::haveRSSI() { return m_haveRSSI; }
33+
bool BTAdvertisedDeviceSet::haveCOD() const { return m_haveCOD; }
34+
bool BTAdvertisedDeviceSet::haveName() const { return m_haveName; }
35+
bool BTAdvertisedDeviceSet::haveRSSI() const { return m_haveRSSI; }
3636

3737
/**
3838
* @brief Create a string representation of this device.

0 commit comments

Comments
 (0)