#!/usr/bin/env python3 """ Generate Beidou_B1C_codes.h/.cc from ICD Weil parameters in Beidou_B1C_prn.h. ----------------------------------------------------------------------------- GNSS-SDR is a Global Navigation Satellite System software-defined receiver. This file is part of GNSS-SDR. Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors) SPDX-License-Identifier: GPL-3.0-or-later Author: Wenhao Ou, 2026. ouwh(at)mail2.sysu.edu.cn ----------------------------------------------------------------------------- """ from __future__ import annotations import re from pathlib import Path ROOT = Path(__file__).resolve().parents[2] PRN_HEADER = ROOT / "src/core/system_parameters/Beidou_B1C_prn.h" OUT_HEADER = ROOT / "src/core/system_parameters/Beidou_B1C_codes.h" OUT_SOURCE = ROOT / "src/core/system_parameters/Beidou_B1C_codes.cc" def extract(name: str, text: str) -> list[int]: match = re.search(rf"{name}\[63\]\s*=\s*\{{([^}}]+)\}}", text, re.S) if not match: raise RuntimeError(f"Could not parse {name}") return [int(x.strip()) for x in match.group(1).split(",") if x.strip()] def legendre(n: int) -> list[int]: seq = [0] * n for x in range(1, n): seq[(x * x) % n] = 1 return seq def weil_code(L: list[int], weil_len: int, w: int, p: int, out_len: int) -> list[int]: W = [L[k] ^ L[(k + w) % weil_len] for k in range(weil_len)] return [W[(n + p - 1) % weil_len] for n in range(out_len)] def chips_to_hex(chips: list[int]) -> str: out = "" for i in range(0, len(chips), 4): chunk = chips[i : i + 4] value = 0 for bit in chunk: value = (value << 1) | bit while len(chunk) < 4: value <<= 1 chunk.append(0) out += format(value, "X") return out def chips_to_binstr(chips: list[int]) -> str: return "".join(str(c) for c in chips) # Keep generated source under the CI long-line limit (512 chars). # Match the historical 76-char fragment width used in Beidou_B1C_codes.h. _CODE_LINE_WIDTH = 76 def emit_array_decl(name: str, rows: list[str]) -> str: return f"extern const char {name}[63][{len(rows[0]) + 1}];" def emit_wrapped_string(row: str) -> list[str]: """Emit one array element as adjacent string literals, one chunk per line.""" chunks = [row[i : i + _CODE_LINE_WIDTH] for i in range(0, len(row), _CODE_LINE_WIDTH)] if not chunks: chunks = [""] out: list[str] = [] for idx, chunk in enumerate(chunks): suffix = "," if idx == len(chunks) - 1 else "" out.append(f' "{chunk}"{suffix}') return out def emit_array_def(name: str, rows: list[str]) -> str: lines = [f"const char {name}[63][{len(rows[0]) + 1}] = {{"] for row in rows: lines.extend(emit_wrapped_string(row)) lines.append("};") return "\n".join(lines) def main() -> None: text = PRN_HEADER.read_text(encoding="utf-8") data_w = extract("BEIDOU_B1C_DATA_PRN_W", text) data_p = extract("BEIDOU_B1C_DATA_PRN_P", text) pilot_w = extract("BEIDOU_B1C_PILOT_PRN_W", text) pilot_p = extract("BEIDOU_B1C_PILOT_PRN_P", text) sec_w = extract("BEIDOU_B1C_PILOT_SECONDARY_W", text) sec_p = extract("BEIDOU_B1C_PILOT_SECONDARY_P", text) L10243 = legendre(10243) L3607 = legendre(3607) data_hex = [ chips_to_hex(weil_code(L10243, 10243, data_w[i], data_p[i], 10230)) for i in range(63) ] pilot_hex = [ chips_to_hex(weil_code(L10243, 10243, pilot_w[i], pilot_p[i], 10230)) for i in range(63) ] sec_bin = [chips_to_binstr(weil_code(L3607, 3607, sec_w[i], sec_p[i], 1800)) for i in range(63)] expected = "101011111111011001001110" assert "".join(str(b) for b in weil_code(L10243, 10243, data_w[0], data_p[0], 10230)[:24]) == expected script_name = Path(__file__).name header = f"""/*! * \\file Beidou_B1C_codes.h * \\brief Precomputed BeiDou B1C primary and secondary codes (declarations) * \\author Wenhao Ou, 2026. ouwh(at)mail2.sysu.edu.cn * * Auto-generated by {script_name}. Do not edit manually. * Definitions live in Beidou_B1C_codes.cc. * * ----------------------------------------------------------------------------- * * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * This file is part of GNSS-SDR. * * Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- */ #ifndef GNSS_SDR_BEIDOU_B1C_CODES_H #define GNSS_SDR_BEIDOU_B1C_CODES_H #include constexpr size_t BEIDOU_B1C_PRIMARY_CODE_STR_LENGTH = 2558; constexpr size_t BEIDOU_B1C_PILOT_SECONDARY_CODE_STR_LENGTH = 1800; {emit_array_decl("BEIDOU_B1C_DATA_PRIMARY_CODE", data_hex)} {emit_array_decl("BEIDOU_B1C_PILOT_PRIMARY_CODE", pilot_hex)} {emit_array_decl("BEIDOU_B1C_PILOT_SECONDARY_CODE", sec_bin)} #endif """ source = f"""/*! * \\file Beidou_B1C_codes.cc * \\brief Precomputed BeiDou B1C primary and secondary codes * \\author Wenhao Ou, 2026. ouwh(at)mail2.sysu.edu.cn * * Auto-generated by {script_name}. Do not edit manually. * * ----------------------------------------------------------------------------- * * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * This file is part of GNSS-SDR. * * Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- */ #include "Beidou_B1C_codes.h" {emit_array_def("BEIDOU_B1C_DATA_PRIMARY_CODE", data_hex)} {emit_array_def("BEIDOU_B1C_PILOT_PRIMARY_CODE", pilot_hex)} {emit_array_def("BEIDOU_B1C_PILOT_SECONDARY_CODE", sec_bin)} """ OUT_HEADER.write_text(header, encoding="utf-8") OUT_SOURCE.write_text(source, encoding="utf-8") print(f"Wrote {OUT_HEADER} ({len(header)} bytes)") print(f"Wrote {OUT_SOURCE} ({len(source)} bytes)") if __name__ == "__main__": main()