1#!/usr/bin/python 2""" 3SPDX-License-Identifier: Apache-2.0 4Copyright (c) 2024 STMicroelectronics. 5This script updates ble library 6""" 7 8import sys 9import os 10import shutil 11import subprocess 12from pathlib import Path 13import logging 14from common_utils import common_utils 15 16file_list_wb = [ 17 "Middlewares/ST/STM32_WPAN/ble/core/ble_bufsize.h", 18 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/hw.h", 19 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci/shci.c", 20 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci/shci.h", 21 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl.h", 22 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/mbox_def.h", 23 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/shci_tl_if.c", 24 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/shci_tl.c", 25 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/shci_tl.h", 26 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/tl.h", 27 "Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/tl_mbox.c", 28 "Middlewares/ST/STM32_WPAN/stm32_wpan_common.h", 29 "Middlewares/ST/STM32_WPAN/utilities/dbg_trace.h", 30 "Middlewares/ST/STM32_WPAN/utilities/stm_list.c", 31 "Middlewares/ST/STM32_WPAN/utilities/stm_list.h", 32 "Middlewares/ST/STM32_WPAN/utilities/utilities_common.h", 33 "Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Hid/Core/Inc/app_common.h", 34 "Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Hid/Core/Inc/app_conf.h", 35 "Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Hid/Core/Inc/hw_if.h", 36 "Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Hid/STM32_WPAN/Target/" 37 + "hw_ipcc.c", 38 "Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Hid/STM32_WPAN/App/" 39 + "tl_dbg_conf.h", 40] 41 42ble_transparent_mode_app_path = "Projects/NUCLEO-WBA55CG/Applications/BLE/" \ 43 + "BLE_TransparentMode" 44file_list_wba = { 45 "STM32_WPAN": [ 46 "Middlewares/ST/STM32_WPAN/ble/stack/include/auto/ble_types.h", 47 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/_40nm_reg_files/" 48 + "DWC_ble154combo.h", 49 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/bsp.h", 50 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/common_types.h", 51 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/event_manager.h", 52 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/evnt_schdlr_gnrc_if.h", 53 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/hci.h", 54 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/ll_intf.h", 55 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/ll_intf_cmn.h", 56 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/mem_intf.h", 57 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/os_wrapper.h", 58 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/power_table.h", 59 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/inc/pta.h", 60 "Middlewares/ST/STM32_WPAN/link_layer/ll_cmd_lib/config/ble_full/" 61 + "ll_fw_config.h", 62 "Middlewares/ST/STM32_WPAN/ble/stack/include/ble_bufsize.h", 63 "Middlewares/ST/STM32_WPAN/ble/stack/include/ble_const.h", 64 "Middlewares/ST/STM32_WPAN/ble/stack/include/ble_defs.h", 65 "Middlewares/ST/STM32_WPAN/ble/stack/include/ble_std.h", 66 "Middlewares/ST/STM32_WPAN/ble/stack/include/bleplat.h", 67 "Middlewares/ST/STM32_WPAN/ble/stack/include/blestack.h", 68 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/inc/linklayer_plat.h", 69 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/inc/ll_sys.h", 70 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/src/ll_sys_cs.c", 71 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/src/ll_sys_dp_slp.c", 72 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/src/ll_sys_intf.c", 73 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/src/ll_sys_startup.c", 74 "Middlewares/ST/STM32_WPAN/link_layer/ll_sys/inc/ll_sys_startup.h", 75 "Middlewares/ST/STM32_WPAN/stm32_wpan_common.h", 76 ], 77 "BLE_TransparentMode": [ 78 ble_transparent_mode_app_path + "/Core/Inc/app_common.h", 79 ble_transparent_mode_app_path + "/Core/Inc/app_conf.h", 80 ble_transparent_mode_app_path + "/Core/Inc/app_entry.h", 81 ble_transparent_mode_app_path + "/Core/Inc/utilities_conf.h", 82 ble_transparent_mode_app_path + "/Core/Inc/main.h", 83 ble_transparent_mode_app_path + "/System/Modules/Flash/rf_timing_synchro.c", 84 ble_transparent_mode_app_path + "/System/Modules/Flash/rf_timing_synchro.h", 85 ble_transparent_mode_app_path + "/System/Modules/Flash/flash_driver.c", 86 ble_transparent_mode_app_path + "/System/Modules/Flash/flash_driver.h", 87 ble_transparent_mode_app_path + "/System/Modules/Flash/flash_manager.c", 88 ble_transparent_mode_app_path + "/System/Modules/Flash/flash_manager.h", 89 ble_transparent_mode_app_path + "/System/Modules/RTDebug/debug_signals.h", 90 ble_transparent_mode_app_path + "/System/Modules/RTDebug/RTDebug.c", 91 ble_transparent_mode_app_path + "/System/Modules/RTDebug/RTDebug.h", 92 ble_transparent_mode_app_path + "/System/Modules/RTDebug/local_debug_tables.h", 93 ble_transparent_mode_app_path + "/System/Modules/scm.c", 94 ble_transparent_mode_app_path + "/System/Modules/scm.h", 95 ble_transparent_mode_app_path + "/System/Modules/stm_list.c", 96 ble_transparent_mode_app_path + "/System/Modules/stm_list.h", 97 ble_transparent_mode_app_path + "/System/Modules/utilities_common.h", 98 ble_transparent_mode_app_path + "/System/Interfaces/hw.h", 99 ble_transparent_mode_app_path + "/System/Interfaces/hw_aes.c", 100 ble_transparent_mode_app_path + "/System/Interfaces/hw_if.h", 101 ble_transparent_mode_app_path + "/System/Interfaces/hw_pka.c", 102 ble_transparent_mode_app_path + "/System/Interfaces/hw_pka_p256.c", 103 ble_transparent_mode_app_path + "/System/Config/Log/log_module.c", 104 ble_transparent_mode_app_path + "/System/Config/Log/log_module.h", 105 ble_transparent_mode_app_path + "/System/Config/Debug_GPIO/app_debug.h", 106 ble_transparent_mode_app_path + "/System/Config/Debug_GPIO/debug_config.h", 107 ble_transparent_mode_app_path + "/STM32_WPAN/Target/power_table.c", 108 ble_transparent_mode_app_path + "/STM32_WPAN/Target/bpka.c", 109 ble_transparent_mode_app_path + "/STM32_WPAN/Target/bpka.h", 110 ble_transparent_mode_app_path + "/STM32_WPAN/Target/linklayer_plat.c", 111 ble_transparent_mode_app_path + "/STM32_WPAN/Target/ll_sys_if.c", 112 ], 113 "Utilities": [ 114 "Utilities/trace/adv_trace/stm32_adv_trace.h", 115 "Utilities/misc/stm32_mem.h", 116 "Utilities/tim_serv/stm32_timer.h", 117 "Utilities/misc/stm32_tiny_vsnprintf.h", 118 ], 119} 120 121 122def os_cmd(cmd, cwd=None, shell=False): 123 """Execute a command with subprocess.check_call() 124 Args: 125 cmd: string command to execute. 126 cwd: directory where to run command 127 shell: boolean to enable command interpretation by the shell 128 129 Returns: 130 return the returncode of the command after execution. 131 """ 132 logging.debug("%s", f"{str(cmd)} cwd:{str(cwd)}") 133 134 return subprocess.check_call( 135 cmd, 136 shell=shell, 137 cwd=cwd, 138 stdout=subprocess.DEVNULL, 139 stderr=subprocess.DEVNULL, 140 ) 141 142 143def copy_ble_lib_files(src_repo_path, dest_lib_path, stm32_serie): 144 """Copy BLE lib related files from Cube Firmware to hal_stm32""" 145 if stm32_serie == "stm32wb": 146 # Remove existing *.c and *.h files 147 hci_path = Path(dest_lib_path / "hci") 148 if hci_path.exists(): 149 for item in os.listdir(hci_path): 150 if item.endswith(".c") or item.endswith(".h"): 151 os.remove(hci_path / item) 152 153 # Create hci folder if does not exist 154 if not hci_path.exists(): 155 hci_path.mkdir(parents=True) 156 157 # Copy files 158 for file in file_list_wb: 159 src_file_path = Path(src_repo_path / file) 160 file_name = src_file_path.name 161 if src_file_path.exists(): 162 # copy each file to destination 163 shutil.copy(src_file_path, Path(hci_path / file_name)) 164 else: 165 logging.error(f"File : {src_file_path} not found") 166 logging.error("Abort") 167 sys.exit() 168 169 elif stm32_serie == "stm32wba": 170 # Remove existing *.c and *.h files 171 for root, _, files in os.walk(dest_lib_path): 172 for file in files: 173 if file.endswith(".c") or file.endswith(".h"): 174 os.remove(os.path.join(root, file)) 175 176 for dir_name in file_list_wba: 177 for file in file_list_wba[dir_name]: 178 # Src file path to be copied 179 src_file_path = Path(src_repo_path / file) 180 if src_file_path.exists(): 181 # Extract the relevant part of the path from "dir_name" onwards 182 start_index = file.find(dir_name) 183 relative_path = file[start_index:] 184 # Create the full destination path 185 destination_path = os.path.join(dest_lib_path, relative_path) 186 # Create (if does not exist) all directories in the destination path 187 os.makedirs(os.path.dirname(destination_path), exist_ok=True) 188 # Copy the file to the destination path 189 shutil.copy(src_file_path, destination_path) 190 else: 191 # Raise all the errors but not aborting to allow a manual check 192 logging.error(f"File : {src_file_path} not found") 193 194 195def update_ble_lib_readme(lib_path, make_version, make_commit): 196 """Update README.rst file 197 198 Args: 199 dest_lib_path: library path 200 make_version: latest STM32Cube version. 201 make_commit: Commit corresponding to latest STM32Cube version. 202 """ 203 204 readme_path = Path(lib_path / "README.rst") 205 206 with readme_path.open(mode="r") as readme_prev: 207 lines = (x for x in readme_prev.read().splitlines()) 208 209 readme_path.unlink() 210 211 # Write README.rst from previous one if exists 212 with open(str(readme_path), "w") as readme_file: 213 for line_item in lines: 214 # change version nb 215 if "status" in line_item.lower(): 216 readme_file.write("Status:\n") 217 readme_file.write(f" version {make_version}\n") 218 next(lines) # skip next line 219 elif "commit" in line_item.lower(): 220 readme_file.write("Commit:\n") 221 readme_file.write(f" {make_commit}") 222 next(lines) # skip next line 223 # change patch list with a link to the release_note.html 224 elif "Patch List" in line_item: 225 readme_file.write("Patch List:\n") 226 readme_file.write( 227 "--> please check that the following list " 228 + "is still valid:\n" 229 ) 230 else: 231 readme_file.write(f"{line_item}\n") 232 233 readme_file.flush() 234 235 236def build_patch_from_current_zephyr_version( 237 src_repo_path, temp_source_path, zephyr_lib_path, version, stm32_serie 238): 239 """ Rebuild zephyr patch compare to cube files (current zephyr version) """ 240 241 temp_source_lib_path = Path(temp_source_path / "lib" / stm32_serie) 242 243 # Checkout the current Zephyr version of the STM32Cube repo 244 os_cmd( 245 ("git", "checkout", "-f", "--recurse-submodules", version), 246 cwd=src_repo_path, 247 ) 248 249 # create Cube reference from zephyr version 250 shutil.rmtree(temp_source_path, onerror=common_utils.remove_readonly) 251 temp_source_lib_path.mkdir(parents=True) 252 253 copy_ble_lib_files( 254 src_repo_path, 255 temp_source_lib_path, 256 stm32_serie, 257 ) 258 os_cmd(("git", "init"), cwd=temp_source_path) 259 os_cmd( 260 ("git", "commit", "--allow-empty", "-m", "'Trigger notification'"), 261 cwd=temp_source_path, 262 ) 263 os_cmd( 264 ("git", "add", "-A", Path(temp_source_lib_path / "*")), 265 cwd=temp_source_path, 266 ) 267 os_cmd( 268 ("git", "commit", "-am", "ble lib from zephyr version"), 269 cwd=temp_source_path, 270 ) 271 272 # Remove trailing whitespaces 273 os_cmd( 274 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 275 cwd=temp_source_path, 276 ) 277 278 # copy zephyr files 279 shutil.rmtree(temp_source_lib_path, onerror=common_utils.remove_readonly) 280 shutil.copytree(zephyr_lib_path, temp_source_lib_path) 281 282 # remove all files at root dir (like readme and cmakelist) 283 # so that it is not part of the patch 284 for file in temp_source_lib_path.glob("*"): 285 if file.is_file(): 286 file.unlink() 287 if Path(temp_source_lib_path / "README.rst").exists(): 288 Path(temp_source_lib_path / "README.rst").unlink() 289 290 # commit this current zephyr library file 291 os_cmd(("git", "add", "*"), cwd=temp_source_path) 292 os_cmd(("git", "commit", "-am", '"module"'), cwd=temp_source_path) 293 294 # Remove trailing space 295 os_cmd( 296 ("git", "rebase", "--whitespace=fix", "HEAD~1"), 297 cwd=temp_source_path, 298 ) 299 300 # For unclear reason, using tuple ("git", "diff", ...) is failing on Linux 301 # especially for this command. Keep a single string. 302 os_cmd( 303 ( 304 "git diff --ignore-space-at-eol HEAD~1 --output=" 305 + str(zephyr_lib_path) 306 + "/ble_zephyr.patch" 307 ), 308 shell=True, 309 cwd=temp_source_path, 310 ) 311 os_cmd(("dos2unix", "ble_zephyr.patch"), cwd=zephyr_lib_path) 312 313 314def update( 315 src_repo_path, 316 dest_lib_path, 317 temp_source_path, 318 current_version, 319 update_version, 320 commit, 321 stm32_serie 322): 323 """Update ble library""" 324 logging.info(" ... Updating ble library ...") 325 if not dest_lib_path.exists(): 326 dest_lib_path.mkdir(parents=True) 327 328 build_patch_from_current_zephyr_version( 329 src_repo_path, temp_source_path, dest_lib_path, current_version, 330 stm32_serie 331 ) 332 # Checkout the latest version of the STM32Cube repo 333 os_cmd( 334 ("git", "checkout", "-f", "--recurse-submodules", update_version), 335 cwd=src_repo_path, 336 ) 337 copy_ble_lib_files(src_repo_path, dest_lib_path, stm32_serie) 338 common_utils.apply_patch(dest_lib_path / "ble_zephyr.patch", dest_lib_path) 339 if Path(dest_lib_path / "README.rst").exists(): 340 update_ble_lib_readme(dest_lib_path, update_version, commit) 341 342 343if __name__ == "__main__": 344 print("This script is not intend to be called directly\n") 345 print("It is used through serie_update.py\n") 346 sys.exit() 347