Browse Source

revert bluefruit patch

in preparation to switch to using our own fork of Adafruit NRF52 Arduino with the patch included
taco 3 tháng trước cách đây
mục cha
commit
04b69e86be
2 tập tin đã thay đổi với 1 bổ sung201 xóa
  1. 0 198
      arch/nrf52/extra_scripts/patch_bluefruit.py
  2. 1 3
      platformio.ini

+ 0 - 198
arch/nrf52/extra_scripts/patch_bluefruit.py

@@ -1,198 +0,0 @@
-"""
-Bluefruit BLE Patch Script
-
-Patches Bluefruit library to fix semaphore leak bug that causes device lockup
-when BLE central disconnects unexpectedly (e.g., going out of range, supervision timeout).
-
-Patches applied:
-1. BLEConnection.h: Add _hvn_qsize member to track semaphore queue size
-2. BLEConnection.cpp: Store hvn_qsize and restore semaphore on disconnect
-
-Bug description:
-- When a BLE central disconnects unexpectedly (reason=8 supervision timeout),
-  the BLE_GATTS_EVT_HVN_TX_COMPLETE event may never fire
-- This leaves the _hvn_sem counting semaphore in a decremented state
-- Since BLEConnection objects are reused (destructor never called), the
-  semaphore count is never restored
-- Eventually all semaphore counts are exhausted and notify() blocks/fails
-
-"""
-
-from pathlib import Path
-
-Import("env")  # pylint: disable=undefined-variable
-
-
-def _patch_ble_connection_header(source: Path) -> bool:
-    """
-    Add _hvn_qsize member variable to BLEConnection class.
-    
-    This is needed to restore the semaphore to its correct count on disconnect.
-    
-    Returns True if patch was applied or already applied, False on error.
-    """
-    try:
-        content = source.read_text()
-        
-        # Check if already patched
-        if "_hvn_qsize" in content:
-            return True  # Already patched
-        
-        # Find the location to insert - after _phy declaration
-        original_pattern = '''    uint8_t  _phy;
-
-    uint8_t  _role;'''
-        
-        patched_pattern = '''    uint8_t  _phy;
-    uint8_t  _hvn_qsize;
-
-    uint8_t  _role;'''
-        
-        if original_pattern not in content:
-            print("Bluefruit patch: WARNING - BLEConnection.h pattern not found")
-            return False
-        
-        content = content.replace(original_pattern, patched_pattern)
-        source.write_text(content)
-        
-        # Verify
-        if "_hvn_qsize" not in source.read_text():
-            return False
-        
-        return True
-    except Exception as e:
-        print(f"Bluefruit patch: ERROR patching BLEConnection.h: {e}")
-        return False
-
-
-def _patch_ble_connection_source(source: Path) -> bool:
-    """
-    Patch BLEConnection.cpp to:
-    1. Store hvn_qsize in constructor
-    2. Restore _hvn_sem semaphore to full count on disconnect
-    
-    Returns True if patch was applied or already applied, False on error.
-    """
-    try:
-        content = source.read_text()
-        
-        # Check if already patched (look for the restore loop)
-        if "uxSemaphoreGetCount(_hvn_sem)" in content:
-            return True  # Already patched
-        
-        # Patch 1: Store queue size in constructor
-        constructor_original = '''  _hvn_sem   = xSemaphoreCreateCounting(hvn_qsize, hvn_qsize);'''
-        
-        constructor_patched = '''  _hvn_qsize = hvn_qsize;
-  _hvn_sem   = xSemaphoreCreateCounting(hvn_qsize, hvn_qsize);'''
-        
-        if constructor_original not in content:
-            print("Bluefruit patch: WARNING - BLEConnection.cpp constructor pattern not found")
-            return False
-        
-        content = content.replace(constructor_original, constructor_patched)
-        
-        # Patch 2: Restore semaphore on disconnect
-        disconnect_original = '''    case BLE_GAP_EVT_DISCONNECTED:
-      // mark as disconnected
-      _connected = false;
-    break;'''
-        
-        disconnect_patched = '''    case BLE_GAP_EVT_DISCONNECTED:
-      // Restore notification semaphore to full count
-      // This fixes lockup when disconnect occurs with notifications in flight
-      while (uxSemaphoreGetCount(_hvn_sem) < _hvn_qsize) {
-        xSemaphoreGive(_hvn_sem);
-      }
-      // Release indication semaphore if waiting
-      if (_hvc_sem) {
-        _hvc_received = false;
-        xSemaphoreGive(_hvc_sem);
-      }
-      // mark as disconnected
-      _connected = false;
-    break;'''
-        
-        if disconnect_original not in content:
-            print("Bluefruit patch: WARNING - BLEConnection.cpp disconnect pattern not found")
-            return False
-        
-        content = content.replace(disconnect_original, disconnect_patched)
-        source.write_text(content)
-        
-        # Verify
-        verify_content = source.read_text()
-        if "uxSemaphoreGetCount(_hvn_sem)" not in verify_content:
-            return False
-        if "_hvn_qsize = hvn_qsize" not in verify_content:
-            return False
-        
-        return True
-    except Exception as e:
-        print(f"Bluefruit patch: ERROR patching BLEConnection.cpp: {e}")
-        return False
-
-
-def _apply_bluefruit_patches(target, source, env):  # pylint: disable=unused-argument
-    framework_path = env.get("PLATFORMFW_DIR")
-    if not framework_path:
-        framework_path = env.PioPlatform().get_package_dir("framework-arduinoadafruitnrf52")
-
-    if not framework_path:
-        print("Bluefruit patch: ERROR - framework directory not found")
-        env.Exit(1)
-        return
-
-    framework_dir = Path(framework_path)
-    bluefruit_lib = framework_dir / "libraries" / "Bluefruit52Lib" / "src"
-    patch_failed = False
-    
-    # Patch BLEConnection.h
-    conn_header = bluefruit_lib / "BLEConnection.h"
-    if conn_header.exists():
-        before = conn_header.read_text()
-        success = _patch_ble_connection_header(conn_header)
-        after = conn_header.read_text()
-        
-        if success:
-            if before != after:
-                print("Bluefruit patch: OK - Applied BLEConnection.h fix (added _hvn_qsize member)")
-            else:
-                print("Bluefruit patch: OK - BLEConnection.h already patched")
-        else:
-            print("Bluefruit patch: FAILED - BLEConnection.h")
-            patch_failed = True
-    else:
-        print(f"Bluefruit patch: ERROR - BLEConnection.h not found at {conn_header}")
-        patch_failed = True
-    
-    # Patch BLEConnection.cpp
-    conn_source = bluefruit_lib / "BLEConnection.cpp"
-    if conn_source.exists():
-        before = conn_source.read_text()
-        success = _patch_ble_connection_source(conn_source)
-        after = conn_source.read_text()
-        
-        if success:
-            if before != after:
-                print("Bluefruit patch: OK - Applied BLEConnection.cpp fix (restore semaphore on disconnect)")
-            else:
-                print("Bluefruit patch: OK - BLEConnection.cpp already patched")
-        else:
-            print("Bluefruit patch: FAILED - BLEConnection.cpp")
-            patch_failed = True
-    else:
-        print(f"Bluefruit patch: ERROR - BLEConnection.cpp not found at {conn_source}")
-        patch_failed = True
-    
-    if patch_failed:
-        print("Bluefruit patch: CRITICAL - Patch failed! Build aborted.")
-        env.Exit(1)
-
-
-# Register the patch to run before build
-bluefruit_action = env.VerboseAction(_apply_bluefruit_patches, "Applying Bluefruit BLE patches...")
-env.AddPreAction("$BUILD_DIR/${PROGNAME}.elf", bluefruit_action)
-
-# Also run immediately to patch before any compilation
-_apply_bluefruit_patches(None, None, env)

+ 1 - 3
platformio.ini

@@ -82,9 +82,7 @@ extends = arduino_base
 platform = nordicnrf52
 platform_packages =
   framework-arduinoadafruitnrf52 @ 1.10700.0
-extra_scripts =
-  create-uf2.py
-  arch/nrf52/extra_scripts/patch_bluefruit.py
+extra_scripts = create-uf2.py
 build_flags = ${arduino_base.build_flags}
   -D NRF52_PLATFORM
   -D LFS_NO_ASSERT=1