2727#include "rivr_ble_service_internal.h"
2828#include "../rivr_log.h"
2929#include "../rivr_metrics.h"
30+ #include "../timebase.h"
3031
3132extern uint32_t g_my_node_id ;
3233
3334#define TAG "RIVR_BLE"
3435#define ADV_CONFIG_FLAG (1u << 0)
3536#define SCAN_RSP_CONFIG_FLAG (1u << 1)
37+ #define RIVR_BLE_ADV_RETRY_DELAY_MS 1000u
3638#define RIVR_BLE_ATT_DEFAULT_MTU 23u
3739#define RIVR_BLE_CONN_INT_MIN 12u /* 15 ms */
3840#define RIVR_BLE_CONN_INT_MAX 24u /* 30 ms */
@@ -53,6 +55,7 @@ static volatile bool s_ble_active = false;
5355static volatile bool s_stack_ready = false;
5456static volatile bool s_adv_running = false;
5557static uint32_t s_activate_ms = 0u ;
58+ static uint32_t s_adv_retry_due_ms = 0u ;
5659static uint32_t s_timeout_ms = BLE_BOOT_WINDOW_MS ;
5760static uint8_t s_adv_config_done = 0u ;
5861static volatile uint16_t s_att_mtu = RIVR_BLE_ATT_DEFAULT_MTU ;
@@ -129,15 +132,49 @@ static void rivr_ble_set_device_name(void)
129132 RIVR_LOGI (TAG , "BLE device name: %s" , s_device_name );
130133}
131134
135+ static void rivr_ble_schedule_adv_retry (uint32_t delay_ms )
136+ {
137+ if (!s_ble_active ) return ;
138+ s_adv_retry_due_ms = tb_millis () + delay_ms ;
139+ }
140+
141+ static void rivr_ble_clear_adv_retry (void )
142+ {
143+ s_adv_retry_due_ms = 0u ;
144+ }
145+
146+ static void rivr_ble_set_tx_power_max (void )
147+ {
148+ esp_err_t err ;
149+
150+ err = esp_ble_tx_power_set (ESP_BLE_PWR_TYPE_DEFAULT , ESP_PWR_LVL_P9 );
151+ if (err != ESP_OK ) {
152+ RIVR_LOGW (TAG , "BLE TX power default set failed: %s" , esp_err_to_name (err ));
153+ }
154+
155+ err = esp_ble_tx_power_set (ESP_BLE_PWR_TYPE_ADV , ESP_PWR_LVL_P9 );
156+ if (err != ESP_OK ) {
157+ RIVR_LOGW (TAG , "BLE TX power advertising set failed: %s" , esp_err_to_name (err ));
158+ }
159+
160+ err = esp_ble_tx_power_set (ESP_BLE_PWR_TYPE_SCAN , ESP_PWR_LVL_P9 );
161+ if (err != ESP_OK ) {
162+ RIVR_LOGW (TAG , "BLE TX power scan set failed: %s" , esp_err_to_name (err ));
163+ }
164+ }
165+
132166static void rivr_ble_start_adv (void )
133167{
134168 if (!s_ble_active || !s_stack_ready || !rivr_ble_service_is_ready ()) return ;
135169 if (s_conn_handle != 0xFFFFu || s_pending_conn_handle != 0xFFFFu ) return ;
136170 if (s_adv_config_done != 0u ) return ;
171+ if (s_adv_running ) return ;
137172
173+ rivr_ble_clear_adv_retry ();
138174 esp_err_t err = esp_ble_gap_start_advertising (& s_adv_params );
139175 if (err != ESP_OK ) {
140176 RIVR_LOGW (TAG , "esp_ble_gap_start_advertising failed: %s" , esp_err_to_name (err ));
177+ rivr_ble_schedule_adv_retry (RIVR_BLE_ADV_RETRY_DELAY_MS );
141178 }
142179}
143180
@@ -182,11 +219,17 @@ static void rivr_ble_gap_event(esp_gap_ble_cb_event_t event,
182219 if (!s_adv_running ) {
183220 RIVR_LOGW (TAG , "BLE advertising start failed (status=%d)" ,
184221 param -> adv_start_cmpl .status );
222+ rivr_ble_schedule_adv_retry (RIVR_BLE_ADV_RETRY_DELAY_MS );
223+ } else {
224+ rivr_ble_clear_adv_retry ();
185225 }
186226 break ;
187227
188228 case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT :
189229 s_adv_running = false;
230+ if (s_ble_active && s_conn_handle == 0xFFFFu && s_pending_conn_handle == 0xFFFFu ) {
231+ rivr_ble_schedule_adv_retry (RIVR_BLE_ADV_RETRY_DELAY_MS );
232+ }
190233 break ;
191234
192235 case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT :
@@ -288,6 +331,7 @@ static void rivr_ble_gatts_event(esp_gatts_cb_event_t event, esp_gatt_if_t gatts
288331 case ESP_GATTS_CONNECT_EVT :
289332 g_rivr_metrics .ble_connections ++ ;
290333 s_adv_running = false;
334+ rivr_ble_clear_adv_retry ();
291335 s_att_mtu = RIVR_BLE_ATT_DEFAULT_MTU ;
292336 memcpy (s_remote_bda , param -> connect .remote_bda , sizeof (esp_bd_addr_t ));
293337 s_remote_bda_valid = true;
@@ -325,7 +369,7 @@ static void rivr_ble_gatts_event(esp_gatts_cb_event_t event, esp_gatt_if_t gatts
325369 s_remote_bda_valid = false;
326370 rivr_ble_service_clear_connection ();
327371 if (s_ble_active ) {
328- rivr_ble_start_adv ( );
372+ rivr_ble_schedule_adv_retry ( RIVR_BLE_ADV_RETRY_DELAY_MS );
329373 }
330374 break ;
331375
@@ -378,6 +422,8 @@ void rivr_ble_init(void)
378422 return ;
379423 }
380424
425+ rivr_ble_set_tx_power_max ();
426+
381427 err = esp_ble_gatts_register_callback (rivr_ble_gatts_event );
382428 if (err != ESP_OK ) {
383429 ESP_LOGE (TAG , "esp_ble_gatts_register_callback failed: %s" , esp_err_to_name (err ));
@@ -430,6 +476,7 @@ void rivr_ble_init(void)
430476 s_stack_ready = true;
431477 s_ble_active = true;
432478 s_activate_ms = 0u ;
479+ s_adv_retry_due_ms = 0u ;
433480#if RIVR_BLE_PASSKEY != 0
434481 s_timeout_ms = 0u ;
435482#else
@@ -455,6 +502,10 @@ void rivr_ble_tick(uint32_t now_ms)
455502 s_activate_ms = now_ms ;
456503 }
457504 if (!s_ble_active ) return ;
505+ if (s_adv_retry_due_ms != 0u && (int32_t )(now_ms - s_adv_retry_due_ms ) >= 0 ) {
506+ s_adv_retry_due_ms = 0u ;
507+ rivr_ble_start_adv ();
508+ }
458509 if (s_timeout_ms == 0u ) return ;
459510 if ((now_ms - s_activate_ms ) >= s_timeout_ms ) {
460511 RIVR_LOGI (TAG , "BLE: activation window expired (%lu ms) — deactivating" ,
@@ -486,12 +537,14 @@ void rivr_ble_activate(rivr_ble_mode_t mode)
486537
487538 s_ble_active = true;
488539 s_activate_ms = 0u ;
540+ s_adv_retry_due_ms = 0u ;
489541 rivr_ble_start_adv ();
490542}
491543
492544void rivr_ble_deactivate (void )
493545{
494546 s_ble_active = false;
547+ s_adv_retry_due_ms = 0u ;
495548 s_timeout_ms = 0u ;
496549
497550 if (s_adv_running ) {
0 commit comments