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