#!/usr/bin/python3 # Copyright (C) 2024-2025 iopsys Software Solutions AB # Author: Amin Ben Romdhane import sys import os import subprocess import shutil # Constants BBF_ERROR_CODE = 0 CURRENT_PATH = os.getcwd() DM_JSON_FILE = os.path.join(CURRENT_PATH, "tools", "datamodel.json") LIST_SUPPORTED_USP_DM = [] LIST_SUPPORTED_CWMP_DM = [] Array_Types = { "string": "DMT_STRING", "unsignedInt": "DMT_UNINT", "unsignedLong": "DMT_UNLONG", "int": "DMT_INT", "long": "DMT_LONG", "boolean": "DMT_BOOL", "dateTime": "DMT_TIME", "hexBinary": "DMT_HEXBIN", "base64": "DMT_BASE64", "command": "DMT_COMMAND", "event": "DMT_EVENT" } def remove_file(file_path): try: os.remove(file_path) except OSError: pass def create_folder(folder_path): try: os.makedirs(folder_path, exist_ok=True) except OSError: pass def remove_folder(folder_path): if os.path.isdir(folder_path): shutil.rmtree(folder_path) def obj_has_child(value): if isinstance(value, dict): for _obj, val in value.items(): if isinstance(val, dict): for obj1, val1 in val.items(): if obj1 == "type" and val1 == "object": return True return False def obj_has_param(value): if isinstance(value, dict): for _obj, val in value.items(): if isinstance(val, dict): for obj1, val1 in val.items(): if obj1 == "type" and val1 != "object": return True return False def get_option_value(value, option, default=None): if isinstance(value, dict): for obj, val in value.items(): if obj == option: return val return default def get_param_type(value): param_type = get_option_value(value, "type") return Array_Types.get(param_type, None) def get_description_from_json(value): description = get_option_value(value, "description", "") return description def get_range_from_json(value): range_value = get_option_value(value, "range", []) return range_value def get_list_from_json(value): list_value = get_option_value(value, "list", {}) return list_value def get_enum_from_json(value): enumerations = get_option_value(value, "enumerations", []) return enumerations def is_proto_exist(value, proto): protocols = get_option_value(value, "protocols", []) return proto in protocols def build_command(plugin, proto): service_name = get_option_value(plugin, "service_name") unified = get_option_value(plugin, "unified_daemon", False) daemon_name = get_option_value(plugin, "daemon_name", "") schema_option = get_option_value(plugin, "schema_option", "d") # default stays 'd' if not service_name: return None # skip this plugin # Start with base command if unified: base_cmd = f"{daemon_name}" else: base_cmd = f"dm-service -m {service_name}" # Append protocol-specific schema options if proto == "cwmp": base_cmd += f" -{schema_option}" elif proto == "usp": base_cmd += f" -{schema_option}{schema_option}" return base_cmd def fill_list_dm(command, dm_list): try: result = subprocess.run(command, shell=True, text=True, capture_output=True, check=True) output = result.stdout lines = output.strip().split('\n') for line in lines: parts = line.split() if len(parts) < 3: continue path, n_type, data = parts[0], parts[1], parts[2] permission = "readWrite" if data == "1" else "readOnly" p_type = n_type[4:] entry = { "param": path, "permission": permission, "type": p_type, } dm_list.append(entry) except subprocess.CalledProcessError as e: print(f"Error running command '{command}': {e}") sys.exit(1) def remove_duplicate_elements(input_list): unique_values = set() result_list = [] for item in input_list: item_value = item["param"] if item_value not in unique_values: unique_values.add(item_value) result_list.append(item) return result_list def fill_list_supported_dm(plugins): if plugins is None or not isinstance(plugins, list) or not plugins: print("No plugins provided.") return for proto, DB in [("usp", LIST_SUPPORTED_USP_DM), ("cwmp", LIST_SUPPORTED_CWMP_DM)]: for plugin in plugins: command = build_command(plugin, proto) if command: print(f"Running command for {proto}: {command}") fill_list_dm(command, DB) DB.sort(key=lambda x: x['param'], reverse=False) DB[:] = remove_duplicate_elements(DB) def generate_supported_dm(plugins=None): ''' Generates supported data models and performs necessary actions. Args: plugins (list, optional): List of plugin configurations. ''' # Fill the list supported data model fill_list_supported_dm(plugins)