Skip to content

Bad handling of multiple devices connecting to BluetoothSerial. How to set a max limit of allowed BT connections. #2055

@mouridis

Description

@mouridis

Hardware:

Board: WeMOS Lolin32 v.1.0.0 (using revision 1 ESP-WROOM-32 module)
Core Installation/update date: Commit 85032b2
IDE name: Arduino IDE 1.8.6
Flash Frequency: 80MHz
PSRAM enabled: No
Upload Speed: 921600
Computer OS: Windows 10 x64

Description:

Using BluetoothSerial, it's allowed for more than one device to pair and connect at the same time to ESP32. As it is now, if indeed a second device connects to ESP32, essentially it hijacks the connection. ESP32 receives data from both connected devices but all outgoing data is directed to the second (last) device that connected to it.

Searching through the library code, it seems the reason for this behavior is that the library only stores the BT handle of the last connected device and discards the old one. The following lines in BluetoothSerial.cpp are responsible for this:

    case ESP_SPP_SRV_OPEN_EVT://Server connection open
        _spp_client = param->open.handle;
        xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
        log_i("ESP_SPP_SRV_OPEN_EVT");
        break;

I understand that modifying the library to handle multiple simultaneous connections, and offering methods to identify the source device of incoming data and recipient device for outgoing data, would require a huge overhaul of the library.

In the meantime, and in order to avoid BluetoothSerial misbehavior, maybe it would be a good idea to limit the number of allowed simultaneous connections to only 1.

The quick dirty fix that I did in my project is modifying this part of the BluetoothSerial.cpp:

    case ESP_SPP_SRV_OPEN_EVT://Server connection open
        _spp_client = 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
        _spp_client = 0;
        xEventGroupClearBits(_spp_event_group, SPP_CONNECTED);
        log_i("ESP_SPP_CLOSE_EVT");
        break;

to this:

    case ESP_SPP_SRV_OPEN_EVT://Server 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_SRV_OPEN_EVT");
        break;

    case ESP_SPP_CLOSE_EVT://Client connection closed
        if(secondConnectionAttempt) {
            secondConnectionAttempt = false;
        } else {
            _spp_client = 0;
        }
        xEventGroupClearBits(_spp_event_group, SPP_CONNECTED);
        log_i("ESP_SPP_CLOSE_EVT");
        break;

and of course adding the needed declaration for secondConnectionAttempt somewhere on the declarations section:

static boolean secondConnectionAttempt;

In this way, when a second device attempts to connect, ESP32 disconnects from it immediately after connection and does not store it's BT handle.

The question is if the IDF offers a cleaner way to implement similar functionality by limiting the number of allowed simultaneous connections.

Metadata

Metadata

Assignees

Labels

Area: BT&WifiBT & Wifi related issuesStatus: SolvedThe issue has been resolved and requires no further action.

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions