The ESP32 BLE controller glue guards ble_enc_funcs_reset() on
CONFIG_BT_CTRL_BLE_SECURITY_ENABLE, an ESP-IDF sdkconfig symbol that is never
defined in a Zephyr build. The call is therefore compiled out and the
controller's LE Secure Connections encryption table is left uninitialised, so
SC pairing derives a wrong session key and the link is terminated with HCI
reason 0x3D (MIC failure).
This breaks pairing for SC-capable centrals (e.g. Pixel 7 / recent Android);
legacy-pairing centrals use a different path and are unaffected. The existing
CONFIG_ESP32_BT_CTLR_LE_SECURITY_ENABLE=y only sets .enc_en and does not reach
this guard.
Correct the guard to BLE_SECURITY_ENABLE, which esp_bt.h already derives from
CONFIG_ESP32_BT_CTLR_LE_SECURITY_ENABLE (the Zephyr knob) and already uses for
.enc_en. Carried as a managed hal_espressif patch via the existing
zephcore_apply_patches() mechanism (mirrors the loramac-node patch).
Verified on Heltec Wireless Tracker (ESP32-S3): device reaches security
level 4, pairing complete bonded=1; Pixel 7 bonds over SC and the companion app
communicates; older Samsung still pairs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New companion variant for the Heltec Wireless Tracker V1.1 (ESP32-S3-FN8 +
SX1262 + ST7735R 160x80 TFT + UC6580 GPS). Overlay + conf only; no driver,
CMake, or patch changes.
Board-specific fixes worth calling out:
- Battery ADC on &adc0 (ADC unit 1 -> GPIO1), NOT &adc1. In the upstream
esp32s3 DTS the node *labelled* adc1 is unit 2, whose channel 0 is GPIO11 =
the SX1262 MISO. adc_esp32_channel_setup() drives the channel pad to
GPIO_DISCONNECTED, clearing GPIO11's input buffer — which silently broke ALL
LoRa SPI reads (reads returned 0x00 -> every LBT CAD timed out) and also
sampled the wrong pin (battery read 0%). Removed the upstream 'vbatt'
voltage-divider (also on &adc1) and disabled adc1 so nothing claims GPIO11.
- Battery divider enable on GPIO2 active-HIGH (v1.1 ADC_CTRL), not the V3's
GPIO37/active-LOW (which never powered this board's divider).
- SX1262 on SPI2 with driver GPIO CS; DIO1 pull-down + rx-boosted.
- GPS run line (GPIO35) exposed via the gps-enable alias; GPS is powered from
the always-on Vext rail. GPIO36 (GPS PPS, an output) left unconfigured.
- Status LED on GPIO18 exposed as led0 (ZephCore heartbeat). UART1 — which the
upstream DTS parks on GPIO17/18 — disabled so the LED isn't stuck on.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>