Pārlūkot izejas kodu

fix timer collision in role switch

Closes https://github.com/espressif/esp-idf/issues/7203
jincheng 4 gadi atpakaļ
vecāks
revīzija
55ca8774ba

+ 13 - 0
components/bt/common/osi/alarm.c

@@ -318,3 +318,16 @@ uint32_t osi_time_get_os_boottime_ms(void)
 {
     return (uint32_t)(esp_timer_get_time() / 1000);
 }
+
+bool osi_alarm_is_active(osi_alarm_t *alarm)
+{
+    assert(alarm != NULL);
+    assert(alarm_mutex != NULL);
+    bool is_active = false;
+
+    osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT);
+    is_active = alarm->deadline_us > 0;
+    osi_mutex_unlock(&alarm_mutex);
+
+    return is_active;
+}

+ 5 - 0
components/bt/common/osi/include/osi/alarm.h

@@ -20,6 +20,7 @@
 #define _ALARM_H_
 
 #include <stdint.h>
+#include <stdbool.h>
 #include "esp_timer.h"
 
 typedef struct alarm_t osi_alarm_t;
@@ -77,4 +78,8 @@ period_ms_t osi_alarm_get_remaining_ms(const osi_alarm_t *alarm);
 
 uint32_t osi_time_get_os_boottime_ms(void);
 
+// This function returns whether the alarm which encapsulated 
+// a one-shot timer is active or not
+bool osi_alarm_is_active(osi_alarm_t *alarm);
+
 #endif /*_ALARM_H_*/

+ 4 - 1
components/bt/host/bluedroid/bta/dm/bta_dm_act.c

@@ -3761,7 +3761,10 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
                     } else {
                         bta_dm_cb.switch_delay_timer[i].p_cback =
                             (TIMER_CBACK *)&bta_dm_delay_role_switch_cback;
-                        bta_sys_start_timer(&bta_dm_cb.switch_delay_timer[i], 0, 500);
+                        /* Start the timer if not active */
+                        if (!bta_sys_timer_is_active(&bta_dm_cb.switch_delay_timer[i])) {
+                            bta_sys_start_timer(&bta_dm_cb.switch_delay_timer[i], 0, 500);
+                        }
                     }
                 }
 

+ 1 - 0
components/bt/host/bluedroid/bta/include/bta/bta_sys.h

@@ -225,6 +225,7 @@ extern void bta_sys_sendmsg(void *p_msg);
 extern void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms);
 extern void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle);
 extern void bta_sys_free_timer(TIMER_LIST_ENT *p_tle);
+extern BOOLEAN bta_sys_timer_is_active(TIMER_LIST_ENT *p_tle);
 extern void bta_sys_disable(tBTA_SYS_HW_MODULE module);
 extern UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle);
 

+ 21 - 0
components/bt/host/bluedroid/bta/sys/bta_sys_main.c

@@ -638,6 +638,27 @@ UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle)
 }
 
 
+/*******************************************************************************
+**
+** Function         bta_sys_timer_is_active
+**
+** Description      Get info of one-shot timer is active or not.
+**
+** Returns          true if timer is exist and active, false otherwise.
+**
+*******************************************************************************/
+BOOLEAN bta_sys_timer_is_active(TIMER_LIST_ENT *p_tle)
+{
+    assert(p_tle != NULL);
+
+    osi_alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
+    if (alarm != NULL && osi_alarm_is_active(alarm)) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
 /*******************************************************************************
 **
 ** Function         bta_sys_stop_timer