esphome 2025.9.3__py3-none-any.whl → 2025.10.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +94 -31
- esphome/address_cache.py +142 -0
- esphome/automation.py +130 -32
- esphome/build_gen/platformio.py +1 -3
- esphome/codegen.py +1 -0
- esphome/components/animation/animation.cpp +2 -2
- esphome/components/api/__init__.py +166 -3
- esphome/components/api/api_connection.cpp +84 -41
- esphome/components/api/api_connection.h +22 -16
- esphome/components/api/api_frame_helper.cpp +33 -19
- esphome/components/api/api_frame_helper.h +19 -4
- esphome/components/api/api_frame_helper_noise.cpp +41 -53
- esphome/components/api/api_frame_helper_noise.h +1 -1
- esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
- esphome/components/api/api_frame_helper_plaintext.h +1 -1
- esphome/components/api/api_pb2.cpp +189 -15
- esphome/components/api/api_pb2.h +132 -20
- esphome/components/api/api_pb2_dump.cpp +97 -9
- esphome/components/api/api_pb2_service.cpp +118 -160
- esphome/components/api/api_pb2_service.h +31 -3
- esphome/components/api/api_server.cpp +68 -10
- esphome/components/api/api_server.h +32 -4
- esphome/components/api/custom_api_device.h +8 -8
- esphome/components/api/homeassistant_service.h +123 -6
- esphome/components/api/proto.h +6 -2
- esphome/components/api/user_services.h +2 -2
- esphome/components/as7341/sensor.py +1 -1
- esphome/components/audio/__init__.py +1 -1
- esphome/components/audio/audio.cpp +1 -1
- esphome/components/audio/audio_decoder.cpp +9 -9
- esphome/components/bl0906/bl0906.cpp +2 -2
- esphome/components/bl0942/bl0942.cpp +2 -2
- esphome/components/ble_client/__init__.py +1 -1
- esphome/components/bluetooth_proxy/__init__.py +4 -30
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
- esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
- esphome/components/camera_encoder/__init__.py +2 -4
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
- esphome/components/canbus/canbus.cpp +7 -5
- esphome/components/canbus/canbus.h +7 -7
- esphome/components/captive_portal/__init__.py +18 -1
- esphome/components/captive_portal/captive_portal.cpp +40 -46
- esphome/components/captive_portal/captive_portal.h +20 -22
- esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
- esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
- esphome/components/ccs811/ccs811.cpp +1 -1
- esphome/components/climate/climate.cpp +10 -7
- esphome/components/cm1106/cm1106.cpp +1 -1
- esphome/components/copy/lock/copy_lock.cpp +1 -1
- esphome/components/cover/cover.cpp +1 -0
- esphome/components/daikin_arc/daikin_arc.cpp +19 -12
- esphome/components/dashboard_import/dashboard_import.cpp +1 -1
- esphome/components/dashboard_import/dashboard_import.h +1 -1
- esphome/components/deep_sleep/__init__.py +9 -2
- esphome/components/deep_sleep/deep_sleep_component.h +11 -9
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
- esphome/components/ektf2232/touchscreen/__init__.py +8 -5
- esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
- esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
- esphome/components/epaper_spi/__init__.py +1 -0
- esphome/components/epaper_spi/display.py +80 -0
- esphome/components/epaper_spi/epaper_spi.cpp +227 -0
- esphome/components/epaper_spi/epaper_spi.h +93 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
- esphome/components/es7210/es7210.cpp +3 -3
- esphome/components/esp32/__init__.py +256 -340
- esphome/components/esp32/boards.py +81 -0
- esphome/components/esp32/preferences.cpp +23 -17
- esphome/components/esp32_ble/__init__.py +167 -44
- esphome/components/esp32_ble/ble.cpp +47 -3
- esphome/components/esp32_ble/ble.h +18 -0
- esphome/components/esp32_ble/ble_advertising.cpp +7 -3
- esphome/components/esp32_ble/ble_advertising.h +4 -0
- esphome/components/esp32_ble/ble_uuid.cpp +16 -42
- esphome/components/esp32_ble_beacon/__init__.py +3 -4
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +0 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
- esphome/components/esp32_ble_server/__init__.py +28 -14
- esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
- esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
- esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
- esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
- esphome/components/esp32_ble_server/ble_server.cpp +59 -24
- esphome/components/esp32_ble_server/ble_server.h +38 -20
- esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
- esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
- esphome/components/esp32_ble_tracker/__init__.py +25 -80
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -8
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
- esphome/components/esp32_camera/__init__.py +1 -3
- esphome/components/esp32_can/esp32_can.cpp +22 -4
- esphome/components/esp32_can/esp32_can.h +3 -0
- esphome/components/esp32_hosted/__init__.py +2 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +135 -65
- esphome/components/esp32_improv/esp32_improv_component.h +7 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp8266/__init__.py +3 -3
- esphome/components/esphome/ota/__init__.py +21 -2
- esphome/components/esphome/ota/ota_esphome.cpp +456 -146
- esphome/components/esphome/ota/ota_esphome.h +49 -2
- esphome/components/ethernet/__init__.py +39 -22
- esphome/components/ethernet/ethernet_component.cpp +28 -5
- esphome/components/ethernet/ethernet_component.h +5 -1
- esphome/components/external_components/__init__.py +8 -6
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
- esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
- esphome/components/font/__init__.py +5 -5
- esphome/components/graph/graph.cpp +1 -1
- esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
- esphome/components/haier/hon_climate.cpp +2 -2
- esphome/components/haier/hon_climate.h +1 -1
- esphome/components/hdc1080/hdc1080.cpp +42 -34
- esphome/components/hdc1080/hdc1080.h +1 -3
- esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
- esphome/components/http_request/__init__.py +3 -3
- esphome/components/htu21d/htu21d.cpp +13 -18
- esphome/components/htu21d/htu21d.h +1 -1
- esphome/components/i2s_audio/__init__.py +1 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
- esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
- esphome/components/improv_serial/improv_serial_component.cpp +12 -15
- esphome/components/improv_serial/improv_serial_component.h +6 -8
- esphome/components/json/json_util.cpp +42 -44
- esphome/components/json/json_util.h +57 -0
- esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
- esphome/components/key_collector/key_collector.h +4 -4
- esphome/components/libretiny/__init__.py +6 -6
- esphome/components/libretiny/preferences.cpp +23 -16
- esphome/components/light/light_call.cpp +98 -120
- esphome/components/light/light_call.h +17 -7
- esphome/components/lm75b/__init__.py +0 -0
- esphome/components/lm75b/lm75b.cpp +39 -0
- esphome/components/lm75b/lm75b.h +19 -0
- esphome/components/lm75b/sensor.py +34 -0
- esphome/components/lock/lock.h +12 -6
- esphome/components/logger/__init__.py +15 -27
- esphome/components/logger/logger.cpp +10 -20
- esphome/components/logger/logger.h +105 -62
- esphome/components/logger/logger_esp32.cpp +0 -48
- esphome/components/logger/logger_zephyr.cpp +2 -3
- esphome/components/logger/select/logger_level_select.cpp +6 -7
- esphome/components/logger/select/logger_level_select.h +7 -0
- esphome/components/ltr501/ltr501.cpp +7 -6
- esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
- esphome/components/matrix_keypad/matrix_keypad.h +4 -4
- esphome/components/max7219digit/max7219digit.cpp +1 -1
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +3 -3
- esphome/components/mcp2515/mcp2515.cpp +31 -3
- esphome/components/mcp2515/mcp2515_defs.h +3 -1
- esphome/components/md5/md5.cpp +0 -26
- esphome/components/md5/md5.h +10 -20
- esphome/components/mdns/__init__.py +93 -19
- esphome/components/mdns/mdns_component.cpp +57 -94
- esphome/components/mdns/mdns_component.h +35 -11
- esphome/components/mdns/mdns_esp32.cpp +7 -13
- esphome/components/mdns/mdns_esp8266.cpp +7 -7
- esphome/components/mdns/mdns_libretiny.cpp +3 -4
- esphome/components/mdns/mdns_rp2040.cpp +3 -4
- esphome/components/mipi/__init__.py +1 -5
- esphome/components/mipi_spi/display.py +24 -8
- esphome/components/mipi_spi/mipi_spi.h +3 -3
- esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
- esphome/components/mmc5603/mmc5603.cpp +3 -3
- esphome/components/modbus/modbus.cpp +27 -13
- esphome/components/modbus/modbus.h +5 -3
- esphome/components/modbus/modbus_definitions.h +86 -0
- esphome/components/modbus_controller/__init__.py +29 -1
- esphome/components/modbus_controller/const.py +4 -0
- esphome/components/modbus_controller/modbus_controller.cpp +38 -13
- esphome/components/modbus_controller/modbus_controller.h +18 -29
- esphome/components/mpr121/mpr121.cpp +41 -42
- esphome/components/mpr121/mpr121.h +0 -1
- esphome/components/nau7802/nau7802.cpp +2 -2
- esphome/components/network/__init__.py +7 -3
- esphome/components/nextion/display.py +4 -4
- esphome/components/nextion/nextion.cpp +8 -8
- esphome/components/number/__init__.py +2 -0
- esphome/components/number/number_call.cpp +23 -12
- esphome/components/number/number_call.h +5 -0
- esphome/components/online_image/bmp_image.cpp +2 -1
- esphome/components/online_image/jpeg_image.cpp +4 -2
- esphome/components/opentherm/opentherm.cpp +5 -5
- esphome/components/opentherm/opentherm.h +3 -3
- esphome/components/openthread/openthread.cpp +11 -10
- esphome/components/openthread/openthread.h +0 -1
- esphome/components/ota/ota_backend.h +1 -0
- esphome/components/packages/__init__.py +10 -8
- esphome/components/packet_transport/packet_transport.cpp +2 -0
- esphome/components/pid/pid_controller.cpp +1 -1
- esphome/components/prometheus/prometheus_handler.cpp +239 -239
- esphome/components/psram/__init__.py +30 -28
- esphome/components/qmc5883l/qmc5883l.cpp +15 -0
- esphome/components/qmc5883l/qmc5883l.h +3 -0
- esphome/components/qmc5883l/sensor.py +31 -12
- esphome/components/remote_base/gobox_protocol.cpp +3 -3
- esphome/components/remote_receiver/__init__.py +14 -2
- esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
- esphome/components/remote_receiver/remote_receiver.h +4 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
- esphome/components/remote_transmitter/__init__.py +2 -2
- esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
- esphome/components/rp2040/__init__.py +11 -11
- esphome/components/rtttl/rtttl.cpp +2 -2
- esphome/components/scd30/sensor.py +1 -1
- esphome/components/script/__init__.py +1 -1
- esphome/components/script/script.h +7 -7
- esphome/components/select/select.cpp +5 -4
- esphome/components/select/select_call.cpp +1 -1
- esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
- esphome/components/sensor/__init__.py +2 -0
- esphome/components/sha256/__init__.py +22 -0
- esphome/components/sha256/sha256.cpp +116 -0
- esphome/components/sha256/sha256.h +60 -0
- esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
- esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
- esphome/components/spi/__init__.py +0 -3
- esphome/components/split_buffer/__init__.py +5 -0
- esphome/components/split_buffer/split_buffer.cpp +133 -0
- esphome/components/split_buffer/split_buffer.h +40 -0
- esphome/components/sps30/sps30.cpp +14 -10
- esphome/components/sps30/sps30.h +2 -0
- esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
- esphome/components/st7789v/st7789v.cpp +3 -2
- esphome/components/statsd/statsd.cpp +1 -1
- esphome/components/substitutions/__init__.py +3 -1
- esphome/components/substitutions/jinja.py +13 -3
- esphome/components/sx126x/__init__.py +16 -0
- esphome/components/sx126x/sx126x.cpp +15 -1
- esphome/components/sx126x/sx126x.h +9 -1
- esphome/components/sx126x/sx126x_reg.h +2 -0
- esphome/components/text_sensor/text_sensor.cpp +16 -0
- esphome/components/text_sensor/text_sensor.h +3 -10
- esphome/components/tormatic/tormatic_cover.cpp +1 -1
- esphome/components/tuya/select/tuya_select.cpp +1 -1
- esphome/components/tuya/tuya.cpp +29 -4
- esphome/components/uart/__init__.py +37 -27
- esphome/components/uart/uart.h +6 -0
- esphome/components/uart/uart_component.cpp +8 -0
- esphome/components/uart/uart_component.h +28 -0
- esphome/components/uart/uart_component_esp_idf.cpp +64 -10
- esphome/components/uart/uart_component_esp_idf.h +5 -2
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
- esphome/components/usb_host/__init__.py +12 -2
- esphome/components/usb_host/usb_host.h +89 -14
- esphome/components/usb_host/usb_host_client.cpp +157 -22
- esphome/components/usb_host/usb_host_component.cpp +1 -1
- esphome/components/usb_uart/__init__.py +0 -1
- esphome/components/usb_uart/ch34x.cpp +4 -4
- esphome/components/usb_uart/cp210x.cpp +3 -3
- esphome/components/usb_uart/usb_uart.cpp +88 -32
- esphome/components/usb_uart/usb_uart.h +30 -6
- esphome/components/valve/valve.cpp +1 -0
- esphome/components/veml7700/veml7700.cpp +7 -6
- esphome/components/version/version_text_sensor.cpp +2 -1
- esphome/components/voice_assistant/voice_assistant.cpp +3 -2
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
- esphome/components/web_server/list_entities.cpp +3 -4
- esphome/components/web_server/list_entities.h +8 -10
- esphome/components/web_server/ota/__init__.py +1 -1
- esphome/components/web_server/ota/ota_web_server.cpp +9 -3
- esphome/components/web_server/web_server.cpp +509 -404
- esphome/components/web_server/web_server.h +5 -6
- esphome/components/web_server/web_server_v1.cpp +21 -19
- esphome/components/web_server_base/__init__.py +5 -2
- esphome/components/web_server_base/web_server_base.h +27 -7
- esphome/components/web_server_idf/__init__.py +1 -1
- esphome/components/web_server_idf/multipart.cpp +2 -2
- esphome/components/web_server_idf/multipart.h +2 -2
- esphome/components/web_server_idf/utils.cpp +2 -2
- esphome/components/web_server_idf/utils.h +2 -2
- esphome/components/web_server_idf/web_server_idf.cpp +118 -26
- esphome/components/web_server_idf/web_server_idf.h +12 -10
- esphome/components/wifi/__init__.py +13 -11
- esphome/components/wifi/wifi_component.cpp +74 -56
- esphome/components/wifi/wifi_component.h +4 -4
- esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
- esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
- esphome/components/wireguard/__init__.py +1 -1
- esphome/components/wts01/__init__.py +0 -0
- esphome/components/wts01/sensor.py +41 -0
- esphome/components/wts01/wts01.cpp +91 -0
- esphome/components/wts01/wts01.h +27 -0
- esphome/components/zephyr/__init__.py +5 -5
- esphome/components/zwave_proxy/__init__.py +43 -0
- esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
- esphome/components/zwave_proxy/zwave_proxy.h +93 -0
- esphome/config.py +79 -24
- esphome/config_validation.py +13 -15
- esphome/const.py +9 -2
- esphome/core/__init__.py +33 -22
- esphome/core/component.cpp +28 -18
- esphome/core/component_iterator.h +2 -1
- esphome/core/config.py +15 -15
- esphome/core/defines.h +21 -0
- esphome/core/entity_helpers.py +9 -6
- esphome/core/hash_base.h +56 -0
- esphome/core/helpers.cpp +19 -3
- esphome/core/helpers.h +26 -0
- esphome/core/scheduler.cpp +5 -21
- esphome/core/scheduler.h +19 -8
- esphome/core/string_ref.h +1 -1
- esphome/core/time.cpp +5 -5
- esphome/cpp_generator.py +4 -29
- esphome/dashboard/const.py +21 -4
- esphome/dashboard/core.py +10 -8
- esphome/dashboard/dns.py +15 -0
- esphome/dashboard/entries.py +15 -21
- esphome/dashboard/models.py +76 -0
- esphome/dashboard/settings.py +7 -7
- esphome/dashboard/status/mdns.py +46 -2
- esphome/dashboard/web_server.py +367 -93
- esphome/espota2.py +112 -32
- esphome/external_files.py +6 -7
- esphome/git.py +8 -0
- esphome/helpers.py +124 -77
- esphome/loader.py +8 -9
- esphome/pins.py +2 -2
- esphome/platformio_api.py +56 -18
- esphome/storage_json.py +26 -21
- esphome/types.py +30 -2
- esphome/util.py +32 -16
- esphome/vscode.py +8 -8
- esphome/wizard.py +10 -10
- esphome/writer.py +50 -15
- esphome/yaml_util.py +37 -31
- esphome/zeroconf.py +12 -3
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/METADATA +12 -12
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/RECORD +340 -320
- esphome/components/event_emitter/__init__.py +0 -5
- esphome/components/event_emitter/event_emitter.cpp +0 -14
- esphome/components/event_emitter/event_emitter.h +0 -63
- esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
- esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
- esphome/components/uart/uart_component_esp32_arduino.h +0 -60
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
- esphome/core/string_ref.cpp +0 -12
- esphome/dashboard/util/file.py +0 -63
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/WHEEL +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/top_level.txt +0 -0
@@ -49,13 +49,17 @@ void BLECharacteristic::notify() {
|
|
49
49
|
this->service_->get_server()->get_connected_client_count() == 0)
|
50
50
|
return;
|
51
51
|
|
52
|
-
|
52
|
+
const uint16_t *clients = this->service_->get_server()->get_clients();
|
53
|
+
uint8_t client_count = this->service_->get_server()->get_client_count();
|
54
|
+
|
55
|
+
for (uint8_t i = 0; i < client_count; i++) {
|
56
|
+
uint16_t client = clients[i];
|
53
57
|
size_t length = this->value_.size();
|
54
|
-
//
|
55
|
-
|
58
|
+
// Find the client in the list of clients to notify
|
59
|
+
auto *entry = this->find_client_in_notify_list_(client);
|
60
|
+
if (entry == nullptr)
|
56
61
|
continue;
|
57
|
-
|
58
|
-
bool require_ack = this->clients_to_notify_[client];
|
62
|
+
bool require_ack = entry->indicate;
|
59
63
|
// TODO: Remove this block when INDICATE acknowledgment is supported
|
60
64
|
if (require_ack) {
|
61
65
|
ESP_LOGW(TAG, "INDICATE acknowledgment is not yet supported (i.e. it works as a NOTIFY)");
|
@@ -73,16 +77,17 @@ void BLECharacteristic::notify() {
|
|
73
77
|
void BLECharacteristic::add_descriptor(BLEDescriptor *descriptor) {
|
74
78
|
// If the descriptor is the CCCD descriptor, listen to its write event to know if the client wants to be notified
|
75
79
|
if (descriptor->get_uuid() == ESPBTUUID::from_uint16(ESP_GATT_UUID_CHAR_CLIENT_CONFIG)) {
|
76
|
-
descriptor->
|
80
|
+
descriptor->on_write([this](std::span<const uint8_t> value, uint16_t conn_id) {
|
77
81
|
if (value.size() != 2)
|
78
82
|
return;
|
79
83
|
uint16_t cccd = encode_uint16(value[1], value[0]);
|
80
84
|
bool notify = (cccd & 1) != 0;
|
81
85
|
bool indicate = (cccd & 2) != 0;
|
86
|
+
// Remove existing entry if present
|
87
|
+
this->remove_client_from_notify_list_(conn_id);
|
88
|
+
// Add new entry if needed
|
82
89
|
if (notify || indicate) {
|
83
|
-
this->clients_to_notify_
|
84
|
-
} else {
|
85
|
-
this->clients_to_notify_.erase(conn_id);
|
90
|
+
this->clients_to_notify_.push_back({conn_id, indicate});
|
86
91
|
}
|
87
92
|
});
|
88
93
|
}
|
@@ -120,69 +125,49 @@ bool BLECharacteristic::is_created() {
|
|
120
125
|
if (this->state_ != CREATING_DEPENDENTS)
|
121
126
|
return false;
|
122
127
|
|
123
|
-
bool created = true;
|
124
128
|
for (auto *descriptor : this->descriptors_) {
|
125
|
-
|
129
|
+
if (!descriptor->is_created())
|
130
|
+
return false;
|
126
131
|
}
|
127
|
-
if
|
128
|
-
|
129
|
-
return
|
132
|
+
// All descriptors are created if we reach here
|
133
|
+
this->state_ = CREATED;
|
134
|
+
return true;
|
130
135
|
}
|
131
136
|
|
132
137
|
bool BLECharacteristic::is_failed() {
|
133
138
|
if (this->state_ == FAILED)
|
134
139
|
return true;
|
135
140
|
|
136
|
-
bool failed = false;
|
137
141
|
for (auto *descriptor : this->descriptors_) {
|
138
|
-
|
142
|
+
if (descriptor->is_failed()) {
|
143
|
+
this->state_ = FAILED;
|
144
|
+
return true;
|
145
|
+
}
|
139
146
|
}
|
140
|
-
|
141
|
-
this->state_ = FAILED;
|
142
|
-
return this->state_ == FAILED;
|
147
|
+
return false;
|
143
148
|
}
|
144
149
|
|
145
|
-
void BLECharacteristic::
|
150
|
+
void BLECharacteristic::set_property_bit_(esp_gatt_char_prop_t bit, bool value) {
|
146
151
|
if (value) {
|
147
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ |
|
152
|
+
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ | bit);
|
148
153
|
} else {
|
149
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ & ~
|
154
|
+
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ & ~bit);
|
150
155
|
}
|
151
156
|
}
|
157
|
+
|
158
|
+
void BLECharacteristic::set_broadcast_property(bool value) {
|
159
|
+
this->set_property_bit_(ESP_GATT_CHAR_PROP_BIT_BROADCAST, value);
|
160
|
+
}
|
152
161
|
void BLECharacteristic::set_indicate_property(bool value) {
|
153
|
-
|
154
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ | ESP_GATT_CHAR_PROP_BIT_INDICATE);
|
155
|
-
} else {
|
156
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_INDICATE);
|
157
|
-
}
|
162
|
+
this->set_property_bit_(ESP_GATT_CHAR_PROP_BIT_INDICATE, value);
|
158
163
|
}
|
159
164
|
void BLECharacteristic::set_notify_property(bool value) {
|
160
|
-
|
161
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ | ESP_GATT_CHAR_PROP_BIT_NOTIFY);
|
162
|
-
} else {
|
163
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_NOTIFY);
|
164
|
-
}
|
165
|
-
}
|
166
|
-
void BLECharacteristic::set_read_property(bool value) {
|
167
|
-
if (value) {
|
168
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ | ESP_GATT_CHAR_PROP_BIT_READ);
|
169
|
-
} else {
|
170
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_READ);
|
171
|
-
}
|
172
|
-
}
|
173
|
-
void BLECharacteristic::set_write_property(bool value) {
|
174
|
-
if (value) {
|
175
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ | ESP_GATT_CHAR_PROP_BIT_WRITE);
|
176
|
-
} else {
|
177
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_WRITE);
|
178
|
-
}
|
165
|
+
this->set_property_bit_(ESP_GATT_CHAR_PROP_BIT_NOTIFY, value);
|
179
166
|
}
|
167
|
+
void BLECharacteristic::set_read_property(bool value) { this->set_property_bit_(ESP_GATT_CHAR_PROP_BIT_READ, value); }
|
168
|
+
void BLECharacteristic::set_write_property(bool value) { this->set_property_bit_(ESP_GATT_CHAR_PROP_BIT_WRITE, value); }
|
180
169
|
void BLECharacteristic::set_write_no_response_property(bool value) {
|
181
|
-
|
182
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ | ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
|
183
|
-
} else {
|
184
|
-
this->properties_ = (esp_gatt_char_prop_t) (this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
|
185
|
-
}
|
170
|
+
this->set_property_bit_(ESP_GATT_CHAR_PROP_BIT_WRITE_NR, value);
|
186
171
|
}
|
187
172
|
|
188
173
|
void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
@@ -207,8 +192,9 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt
|
|
207
192
|
if (!param->read.need_rsp)
|
208
193
|
break; // For some reason you can request a read but not want a response
|
209
194
|
|
210
|
-
this->
|
211
|
-
|
195
|
+
if (this->on_read_callback_) {
|
196
|
+
(*this->on_read_callback_)(param->read.conn_id);
|
197
|
+
}
|
212
198
|
|
213
199
|
uint16_t max_offset = 22;
|
214
200
|
|
@@ -276,8 +262,9 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt
|
|
276
262
|
}
|
277
263
|
|
278
264
|
if (!param->write.is_prep) {
|
279
|
-
this->
|
280
|
-
|
265
|
+
if (this->on_write_callback_) {
|
266
|
+
(*this->on_write_callback_)(this->value_, param->write.conn_id);
|
267
|
+
}
|
281
268
|
}
|
282
269
|
|
283
270
|
break;
|
@@ -288,8 +275,9 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt
|
|
288
275
|
break;
|
289
276
|
this->write_event_ = false;
|
290
277
|
if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
|
291
|
-
this->
|
292
|
-
|
278
|
+
if (this->on_write_callback_) {
|
279
|
+
(*this->on_write_callback_)(this->value_, param->exec_write.conn_id);
|
280
|
+
}
|
293
281
|
}
|
294
282
|
esp_err_t err =
|
295
283
|
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, nullptr);
|
@@ -307,6 +295,28 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt
|
|
307
295
|
}
|
308
296
|
}
|
309
297
|
|
298
|
+
void BLECharacteristic::remove_client_from_notify_list_(uint16_t conn_id) {
|
299
|
+
// Since we typically have very few clients (often just 1), we can optimize
|
300
|
+
// for the common case by swapping with the last element and popping
|
301
|
+
for (size_t i = 0; i < this->clients_to_notify_.size(); i++) {
|
302
|
+
if (this->clients_to_notify_[i].conn_id == conn_id) {
|
303
|
+
// Swap with last element and pop (safe even when i is the last element)
|
304
|
+
this->clients_to_notify_[i] = this->clients_to_notify_.back();
|
305
|
+
this->clients_to_notify_.pop_back();
|
306
|
+
return;
|
307
|
+
}
|
308
|
+
}
|
309
|
+
}
|
310
|
+
|
311
|
+
BLECharacteristic::ClientNotificationEntry *BLECharacteristic::find_client_in_notify_list_(uint16_t conn_id) {
|
312
|
+
for (auto &entry : this->clients_to_notify_) {
|
313
|
+
if (entry.conn_id == conn_id) {
|
314
|
+
return &entry;
|
315
|
+
}
|
316
|
+
}
|
317
|
+
return nullptr;
|
318
|
+
}
|
319
|
+
|
310
320
|
} // namespace esp32_ble_server
|
311
321
|
} // namespace esphome
|
312
322
|
|
@@ -2,11 +2,12 @@
|
|
2
2
|
|
3
3
|
#include "ble_descriptor.h"
|
4
4
|
#include "esphome/components/esp32_ble/ble_uuid.h"
|
5
|
-
#include "esphome/components/event_emitter/event_emitter.h"
|
6
5
|
#include "esphome/components/bytebuffer/bytebuffer.h"
|
7
6
|
|
8
7
|
#include <vector>
|
9
|
-
#include <
|
8
|
+
#include <span>
|
9
|
+
#include <functional>
|
10
|
+
#include <memory>
|
10
11
|
|
11
12
|
#ifdef USE_ESP32
|
12
13
|
|
@@ -23,22 +24,10 @@ namespace esp32_ble_server {
|
|
23
24
|
|
24
25
|
using namespace esp32_ble;
|
25
26
|
using namespace bytebuffer;
|
26
|
-
using namespace event_emitter;
|
27
27
|
|
28
28
|
class BLEService;
|
29
29
|
|
30
|
-
|
31
|
-
enum VectorEvt {
|
32
|
-
ON_WRITE,
|
33
|
-
};
|
34
|
-
|
35
|
-
enum EmptyEvt {
|
36
|
-
ON_READ,
|
37
|
-
};
|
38
|
-
} // namespace BLECharacteristicEvt
|
39
|
-
|
40
|
-
class BLECharacteristic : public EventEmitter<BLECharacteristicEvt::VectorEvt, std::vector<uint8_t>, uint16_t>,
|
41
|
-
public EventEmitter<BLECharacteristicEvt::EmptyEvt, uint16_t> {
|
30
|
+
class BLECharacteristic {
|
42
31
|
public:
|
43
32
|
BLECharacteristic(ESPBTUUID uuid, uint32_t properties);
|
44
33
|
~BLECharacteristic();
|
@@ -77,6 +66,15 @@ class BLECharacteristic : public EventEmitter<BLECharacteristicEvt::VectorEvt, s
|
|
77
66
|
bool is_created();
|
78
67
|
bool is_failed();
|
79
68
|
|
69
|
+
// Direct callback registration - only allocates when callback is set
|
70
|
+
void on_write(std::function<void(std::span<const uint8_t>, uint16_t)> &&callback) {
|
71
|
+
this->on_write_callback_ =
|
72
|
+
std::make_unique<std::function<void(std::span<const uint8_t>, uint16_t)>>(std::move(callback));
|
73
|
+
}
|
74
|
+
void on_read(std::function<void(uint16_t)> &&callback) {
|
75
|
+
this->on_read_callback_ = std::make_unique<std::function<void(uint16_t)>>(std::move(callback));
|
76
|
+
}
|
77
|
+
|
80
78
|
protected:
|
81
79
|
bool write_event_{false};
|
82
80
|
BLEService *service_{};
|
@@ -89,7 +87,20 @@ class BLECharacteristic : public EventEmitter<BLECharacteristicEvt::VectorEvt, s
|
|
89
87
|
SemaphoreHandle_t set_value_lock_;
|
90
88
|
|
91
89
|
std::vector<BLEDescriptor *> descriptors_;
|
92
|
-
|
90
|
+
|
91
|
+
struct ClientNotificationEntry {
|
92
|
+
uint16_t conn_id;
|
93
|
+
bool indicate; // true = indicate, false = notify
|
94
|
+
};
|
95
|
+
std::vector<ClientNotificationEntry> clients_to_notify_;
|
96
|
+
|
97
|
+
void remove_client_from_notify_list_(uint16_t conn_id);
|
98
|
+
ClientNotificationEntry *find_client_in_notify_list_(uint16_t conn_id);
|
99
|
+
|
100
|
+
void set_property_bit_(esp_gatt_char_prop_t bit, bool value);
|
101
|
+
|
102
|
+
std::unique_ptr<std::function<void(std::span<const uint8_t>, uint16_t)>> on_write_callback_;
|
103
|
+
std::unique_ptr<std::function<void(uint16_t)>> on_read_callback_;
|
93
104
|
|
94
105
|
esp_gatt_perm_t permissions_ = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;
|
95
106
|
|
@@ -74,9 +74,10 @@ void BLEDescriptor::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
|
|
74
74
|
break;
|
75
75
|
this->value_.attr_len = param->write.len;
|
76
76
|
memcpy(this->value_.attr_value, param->write.value, param->write.len);
|
77
|
-
this->
|
78
|
-
|
79
|
-
|
77
|
+
if (this->on_write_callback_) {
|
78
|
+
(*this->on_write_callback_)(std::span<const uint8_t>(param->write.value, param->write.len),
|
79
|
+
param->write.conn_id);
|
80
|
+
}
|
80
81
|
break;
|
81
82
|
}
|
82
83
|
default:
|
@@ -1,30 +1,26 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
#include "esphome/components/esp32_ble/ble_uuid.h"
|
4
|
-
#include "esphome/components/event_emitter/event_emitter.h"
|
5
4
|
#include "esphome/components/bytebuffer/bytebuffer.h"
|
6
5
|
|
7
6
|
#ifdef USE_ESP32
|
8
7
|
|
9
8
|
#include <esp_gatt_defs.h>
|
10
9
|
#include <esp_gatts_api.h>
|
10
|
+
#include <span>
|
11
|
+
#include <functional>
|
12
|
+
#include <memory>
|
11
13
|
|
12
14
|
namespace esphome {
|
13
15
|
namespace esp32_ble_server {
|
14
16
|
|
15
17
|
using namespace esp32_ble;
|
16
18
|
using namespace bytebuffer;
|
17
|
-
using namespace event_emitter;
|
18
19
|
|
19
20
|
class BLECharacteristic;
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
ON_WRITE,
|
24
|
-
};
|
25
|
-
} // namespace BLEDescriptorEvt
|
26
|
-
|
27
|
-
class BLEDescriptor : public EventEmitter<BLEDescriptorEvt::VectorEvt, std::vector<uint8_t>, uint16_t> {
|
22
|
+
// Base class for BLE descriptors
|
23
|
+
class BLEDescriptor {
|
28
24
|
public:
|
29
25
|
BLEDescriptor(ESPBTUUID uuid, uint16_t max_len = 100, bool read = true, bool write = true);
|
30
26
|
virtual ~BLEDescriptor();
|
@@ -39,6 +35,12 @@ class BLEDescriptor : public EventEmitter<BLEDescriptorEvt::VectorEvt, std::vect
|
|
39
35
|
bool is_created() { return this->state_ == CREATED; }
|
40
36
|
bool is_failed() { return this->state_ == FAILED; }
|
41
37
|
|
38
|
+
// Direct callback registration - only allocates when callback is set
|
39
|
+
void on_write(std::function<void(std::span<const uint8_t>, uint16_t)> &&callback) {
|
40
|
+
this->on_write_callback_ =
|
41
|
+
std::make_unique<std::function<void(std::span<const uint8_t>, uint16_t)>>(std::move(callback));
|
42
|
+
}
|
43
|
+
|
42
44
|
protected:
|
43
45
|
BLECharacteristic *characteristic_{nullptr};
|
44
46
|
ESPBTUUID uuid_;
|
@@ -46,6 +48,8 @@ class BLEDescriptor : public EventEmitter<BLEDescriptorEvt::VectorEvt, std::vect
|
|
46
48
|
|
47
49
|
esp_attr_value_t value_{};
|
48
50
|
|
51
|
+
std::unique_ptr<std::function<void(std::span<const uint8_t>, uint16_t)>> on_write_callback_;
|
52
|
+
|
49
53
|
esp_gatt_perm_t permissions_{};
|
50
54
|
|
51
55
|
enum State : uint8_t {
|
@@ -70,11 +70,11 @@ void BLEServer::loop() {
|
|
70
70
|
// it is at the top of the GATT table
|
71
71
|
this->device_information_service_->do_create(this);
|
72
72
|
// Create all services previously created
|
73
|
-
for (auto &
|
74
|
-
if (
|
73
|
+
for (auto &entry : this->services_) {
|
74
|
+
if (entry.service == this->device_information_service_) {
|
75
75
|
continue;
|
76
76
|
}
|
77
|
-
|
77
|
+
entry.service->do_create(this);
|
78
78
|
}
|
79
79
|
this->state_ = STARTING_SERVICE;
|
80
80
|
}
|
@@ -118,7 +118,7 @@ BLEService *BLEServer::create_service(ESPBTUUID uuid, bool advertise, uint16_t n
|
|
118
118
|
}
|
119
119
|
BLEService *service = // NOLINT(cppcoreguidelines-owning-memory)
|
120
120
|
new BLEService(uuid, num_handles, inst_id, advertise);
|
121
|
-
this->services_.
|
121
|
+
this->services_.push_back({uuid, inst_id, service});
|
122
122
|
if (this->parent_->is_active() && this->registered_) {
|
123
123
|
service->do_create(this);
|
124
124
|
}
|
@@ -127,26 +127,32 @@ BLEService *BLEServer::create_service(ESPBTUUID uuid, bool advertise, uint16_t n
|
|
127
127
|
|
128
128
|
void BLEServer::remove_service(ESPBTUUID uuid, uint8_t inst_id) {
|
129
129
|
ESP_LOGV(TAG, "Removing BLE service - %s %d", uuid.to_string().c_str(), inst_id);
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
130
|
+
for (auto it = this->services_.begin(); it != this->services_.end(); ++it) {
|
131
|
+
if (it->uuid == uuid && it->inst_id == inst_id) {
|
132
|
+
it->service->do_delete();
|
133
|
+
delete it->service; // NOLINT(cppcoreguidelines-owning-memory)
|
134
|
+
this->services_.erase(it);
|
135
|
+
return;
|
136
|
+
}
|
134
137
|
}
|
135
|
-
service
|
136
|
-
delete service; // NOLINT(cppcoreguidelines-owning-memory)
|
137
|
-
this->services_.erase(BLEServer::get_service_key(uuid, inst_id));
|
138
|
+
ESP_LOGW(TAG, "BLE service %s %d does not exist", uuid.to_string().c_str(), inst_id);
|
138
139
|
}
|
139
140
|
|
140
141
|
BLEService *BLEServer::get_service(ESPBTUUID uuid, uint8_t inst_id) {
|
141
|
-
|
142
|
-
|
143
|
-
|
142
|
+
for (auto &entry : this->services_) {
|
143
|
+
if (entry.uuid == uuid && entry.inst_id == inst_id) {
|
144
|
+
return entry.service;
|
145
|
+
}
|
144
146
|
}
|
145
|
-
return
|
147
|
+
return nullptr;
|
146
148
|
}
|
147
149
|
|
148
|
-
|
149
|
-
|
150
|
+
void BLEServer::dispatch_callbacks_(CallbackType type, uint16_t conn_id) {
|
151
|
+
for (auto &entry : this->callbacks_) {
|
152
|
+
if (entry.type == type) {
|
153
|
+
entry.callback(conn_id);
|
154
|
+
}
|
155
|
+
}
|
150
156
|
}
|
151
157
|
|
152
158
|
void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
@@ -155,14 +161,14 @@ void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t ga
|
|
155
161
|
case ESP_GATTS_CONNECT_EVT: {
|
156
162
|
ESP_LOGD(TAG, "BLE Client connected");
|
157
163
|
this->add_client_(param->connect.conn_id);
|
158
|
-
this->
|
164
|
+
this->dispatch_callbacks_(CallbackType::ON_CONNECT, param->connect.conn_id);
|
159
165
|
break;
|
160
166
|
}
|
161
167
|
case ESP_GATTS_DISCONNECT_EVT: {
|
162
168
|
ESP_LOGD(TAG, "BLE Client disconnected");
|
163
169
|
this->remove_client_(param->disconnect.conn_id);
|
164
170
|
this->parent_->advertising_start();
|
165
|
-
this->
|
171
|
+
this->dispatch_callbacks_(CallbackType::ON_DISCONNECT, param->disconnect.conn_id);
|
166
172
|
break;
|
167
173
|
}
|
168
174
|
case ESP_GATTS_REG_EVT: {
|
@@ -174,17 +180,46 @@ void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t ga
|
|
174
180
|
break;
|
175
181
|
}
|
176
182
|
|
177
|
-
for (
|
178
|
-
|
183
|
+
for (auto &entry : this->services_) {
|
184
|
+
entry.service->gatts_event_handler(event, gatts_if, param);
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
int8_t BLEServer::find_client_index_(uint16_t conn_id) const {
|
189
|
+
for (uint8_t i = 0; i < this->client_count_; i++) {
|
190
|
+
if (this->clients_[i] == conn_id)
|
191
|
+
return i;
|
192
|
+
}
|
193
|
+
return -1;
|
194
|
+
}
|
195
|
+
|
196
|
+
void BLEServer::add_client_(uint16_t conn_id) {
|
197
|
+
// Check if already in list
|
198
|
+
if (this->find_client_index_(conn_id) >= 0)
|
199
|
+
return;
|
200
|
+
// Add if there's space
|
201
|
+
if (this->client_count_ < USE_ESP32_BLE_MAX_CONNECTIONS) {
|
202
|
+
this->clients_[this->client_count_++] = conn_id;
|
203
|
+
} else {
|
204
|
+
// This should never happen since max clients is known at compile time
|
205
|
+
ESP_LOGE(TAG, "Client array full");
|
206
|
+
}
|
207
|
+
}
|
208
|
+
|
209
|
+
void BLEServer::remove_client_(uint16_t conn_id) {
|
210
|
+
int8_t index = this->find_client_index_(conn_id);
|
211
|
+
if (index >= 0) {
|
212
|
+
// Replace with last element and decrement count (client order not preserved)
|
213
|
+
this->clients_[index] = this->clients_[--this->client_count_];
|
179
214
|
}
|
180
215
|
}
|
181
216
|
|
182
217
|
void BLEServer::ble_before_disabled_event_handler() {
|
183
218
|
// Delete all clients
|
184
|
-
this->
|
219
|
+
this->client_count_ = 0;
|
185
220
|
// Delete all services
|
186
|
-
for (auto &
|
187
|
-
|
221
|
+
for (auto &entry : this->services_) {
|
222
|
+
entry.service->do_delete();
|
188
223
|
}
|
189
224
|
this->registered_ = false;
|
190
225
|
this->state_ = INIT;
|
@@ -12,7 +12,7 @@
|
|
12
12
|
#include <memory>
|
13
13
|
#include <vector>
|
14
14
|
#include <unordered_map>
|
15
|
-
#include <
|
15
|
+
#include <functional>
|
16
16
|
|
17
17
|
#ifdef USE_ESP32
|
18
18
|
|
@@ -24,18 +24,7 @@ namespace esp32_ble_server {
|
|
24
24
|
using namespace esp32_ble;
|
25
25
|
using namespace bytebuffer;
|
26
26
|
|
27
|
-
|
28
|
-
enum EmptyEvt {
|
29
|
-
ON_CONNECT,
|
30
|
-
ON_DISCONNECT,
|
31
|
-
};
|
32
|
-
} // namespace BLEServerEvt
|
33
|
-
|
34
|
-
class BLEServer : public Component,
|
35
|
-
public GATTsEventHandler,
|
36
|
-
public BLEStatusEventHandler,
|
37
|
-
public Parented<ESP32BLE>,
|
38
|
-
public EventEmitter<BLEServerEvt::EmptyEvt, uint16_t> {
|
27
|
+
class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEventHandler, public Parented<ESP32BLE> {
|
39
28
|
public:
|
40
29
|
void setup() override;
|
41
30
|
void loop() override;
|
@@ -57,27 +46,56 @@ class BLEServer : public Component,
|
|
57
46
|
void set_device_information_service(BLEService *service) { this->device_information_service_ = service; }
|
58
47
|
|
59
48
|
esp_gatt_if_t get_gatts_if() { return this->gatts_if_; }
|
60
|
-
uint32_t get_connected_client_count() { return this->
|
61
|
-
const
|
49
|
+
uint32_t get_connected_client_count() { return this->client_count_; }
|
50
|
+
const uint16_t *get_clients() const { return this->clients_; }
|
51
|
+
uint8_t get_client_count() const { return this->client_count_; }
|
62
52
|
|
63
53
|
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
64
54
|
esp_ble_gatts_cb_param_t *param) override;
|
65
55
|
|
66
56
|
void ble_before_disabled_event_handler() override;
|
67
57
|
|
58
|
+
// Direct callback registration - supports multiple callbacks
|
59
|
+
void on_connect(std::function<void(uint16_t)> &&callback) {
|
60
|
+
this->callbacks_.push_back({CallbackType::ON_CONNECT, std::move(callback)});
|
61
|
+
}
|
62
|
+
void on_disconnect(std::function<void(uint16_t)> &&callback) {
|
63
|
+
this->callbacks_.push_back({CallbackType::ON_DISCONNECT, std::move(callback)});
|
64
|
+
}
|
65
|
+
|
68
66
|
protected:
|
69
|
-
|
67
|
+
enum class CallbackType : uint8_t {
|
68
|
+
ON_CONNECT,
|
69
|
+
ON_DISCONNECT,
|
70
|
+
};
|
71
|
+
|
72
|
+
struct CallbackEntry {
|
73
|
+
CallbackType type;
|
74
|
+
std::function<void(uint16_t)> callback;
|
75
|
+
};
|
76
|
+
|
77
|
+
struct ServiceEntry {
|
78
|
+
ESPBTUUID uuid;
|
79
|
+
uint8_t inst_id;
|
80
|
+
BLEService *service;
|
81
|
+
};
|
82
|
+
|
70
83
|
void restart_advertising_();
|
71
84
|
|
72
|
-
|
73
|
-
void
|
85
|
+
int8_t find_client_index_(uint16_t conn_id) const;
|
86
|
+
void add_client_(uint16_t conn_id);
|
87
|
+
void remove_client_(uint16_t conn_id);
|
88
|
+
void dispatch_callbacks_(CallbackType type, uint16_t conn_id);
|
89
|
+
|
90
|
+
std::vector<CallbackEntry> callbacks_;
|
74
91
|
|
75
92
|
std::vector<uint8_t> manufacturer_data_{};
|
76
93
|
esp_gatt_if_t gatts_if_{0};
|
77
94
|
bool registered_{false};
|
78
95
|
|
79
|
-
|
80
|
-
|
96
|
+
uint16_t clients_[USE_ESP32_BLE_MAX_CONNECTIONS]{};
|
97
|
+
uint8_t client_count_{0};
|
98
|
+
std::vector<ServiceEntry> services_{};
|
81
99
|
std::vector<BLEService *> services_to_start_{};
|
82
100
|
BLEService *device_information_service_{};
|
83
101
|
|