blob: 6813b0262cef9d330dd705a31e59b4fed641299c [file]
############################################################################
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
"""Product core configuration handler."""
from typing import Any, Dict, Optional, Union
from ntfc.lib.elf.elf_parser import ElfParser
class CoreConfig:
"""Product core configuration."""
def __init__(self, cfg: Dict[str, Any]) -> None:
"""Initialzie product core configuration."""
self._config = cfg
self._kv_values: Dict[str, Any] = {}
self._elf: Optional[ElfParser] = None
conf_path = self._config.get("conf_path", None)
if conf_path:
# load config values
self._load_core_config()
elf_path = self._config.get("elf_path", None)
if elf_path:
# load ELF
self._elf = ElfParser(elf_path)
def _load_core_config(self) -> None:
"""Load core configuration."""
with open(self._config["conf_path"], "r", encoding="utf-8") as f:
for line in f:
line = line.rstrip("\n")
# ignore blank lines and commented lines
if not line or line.startswith("#"):
continue
name, sep, val = line.partition("=")
if not sep:
# no '=' found — skip malformed line
continue
# parse option value
val_parsed: Union[bool, str, int]
if val == "y":
val_parsed = True
elif val == "n":
val_parsed = False
elif "0x" in val:
val_parsed = int(val.rstrip(), 16)
elif val.isdigit():
val_parsed = int(val)
elif val.startswith('"') and val.endswith('"'):
val_parsed = val[1:-1]
else:
val_parsed = val
self._kv_values[name] = val_parsed
@property
def uptime(self) -> Any:
"""Return core uptime."""
return self._config.get("uptime", 3)
@property
def device(self) -> Any:
"""Return core device."""
return self._config.get("device", None)
@property
def name(self) -> Any:
"""Return core name."""
return self._config.get("name", "unknown_name")
def _load_prompt_from_config(self) -> Optional[str]:
"""Load the prompt string from the .config file."""
return self._kv_values.get("CONFIG_NSH_PROMPT_STRING", None)
@property
def prompt(self) -> Any:
"""Return core prompt.
First check YAML config, if not present, load from .config file.
"""
# First check if prompt is explicitly set in YAML config
yaml_prompt = self._config.get("prompt", None)
if yaml_prompt:
return yaml_prompt
# Otherwise, load from .config file
return self._load_prompt_from_config()
@property
def elf_path(self) -> Any:
"""Return core elf path."""
return self._config.get("elf_path", "")
@property
def exec_path(self) -> Any:
"""Return core exec path."""
return self._config.get("exec_path", "")
@property
def exec_args(self) -> Any:
"""Return core exec args."""
return self._config.get("exec_args", "")
@property
def reboot(self) -> Any:
"""Return core reboot command."""
return self._config.get("reboot", "")
@property
def poweroff(self) -> Any:
"""Return core poweroff command."""
return self._config.get("poweroff", "")
def kv_check(self, cfg: str) -> Any:
"""Check Kconfig option and return its value.
:param cfg: Kconfig option name (e.g., 'CONFIG_DEBUG')
:return: Config value if set (bool True, string value, etc),
False if not found
"""
if not self._kv_values:
# No config data loaded
return False
return self._kv_values.get(cfg, False)
def cmd_check(self, cmd: str, core: int = 0) -> bool:
"""Check if command is available in binary."""
if not self._elf:
raise AttributeError("no elf data")
symbol_name = f"{cmd}_main" if "cmocka" in cmd else cmd
return self._elf.has_symbol(symbol_name)