From 26ffcbea6b15f80a83d2911431f58e18609fc5fa Mon Sep 17 00:00:00 2001 From: Kevin L'Hereec Date: Fri, 17 Jul 2026 16:29:29 +0200 Subject: [PATCH] fix: avoid GPN on root path Device. which returns the full parameter tree Two complementary fixes: - IdleState: skip root-level parent paths (Device., InternetGatewayDevice.) when building the GPN queue. Params like Device.RootDataModelVersion have Device. as parent but sending GPN on Device. with NextLevel=0 returns the entire TR-181 tree in one response (potentially several MB). These root-level params are classified via deeper subtree GPN or catalog. - task_queue: use NextLevel=1 for root paths (1 segment) as a safety net, NextLevel=0 for deeper paths to get all leaves of that subtree. --- app/services/cwmp/main_state_machine.ts | 13 ++++++++++--- app/services/cwmp/task_queue.ts | 7 ++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/services/cwmp/main_state_machine.ts b/app/services/cwmp/main_state_machine.ts index 0efb6c7..51276b9 100644 --- a/app/services/cwmp/main_state_machine.ts +++ b/app/services/cwmp/main_state_machine.ts @@ -77,12 +77,19 @@ class IdleState extends DeviceState { return { nextState: new CriticalReadsState(), response: '' } } - // Extract unique parent paths from the UNCLASSIFIED params only + // Extract unique parent paths from the UNCLASSIFIED params only. + // Skip root-level paths (e.g. "Device." or "InternetGatewayDevice.") that would + // produce a huge GPN response — root-level params like Device.RootDataModelVersion + // will be discovered when deeper subtrees are explored or classified via catalog. const parentPaths = new Set() for (const name of unclassified) { const lastDot = name.lastIndexOf('.') - if (lastDot > 0) { - parentPaths.add(name.substring(0, lastDot + 1)) + if (lastDot <= 0) continue + const parentPath = name.substring(0, lastDot + 1) + // Only add paths with at least 2 segments (e.g. "Device.DeviceInfo." not "Device.") + const segments = parentPath.replace(/\.$/, '').split('.') + if (segments.length >= 2) { + parentPaths.add(parentPath) } } diff --git a/app/services/cwmp/task_queue.ts b/app/services/cwmp/task_queue.ts index 6fbb8e9..df02cff 100644 --- a/app/services/cwmp/task_queue.ts +++ b/app/services/cwmp/task_queue.ts @@ -40,7 +40,12 @@ export enum TaskStatus { export class CWMPTaskQueue extends EventEmitter { static task_map: Record string> = { get_parameter_names: (parameterPath: string) => { - return CWMPMessageBuilder.getParameterNames(undefined, parameterPath, false) + // Use NextLevel=1 for root paths (e.g. "Device." or "InternetGatewayDevice.") + // to avoid fetching the entire parameter tree in a single response. + // For deeper paths (e.g. "Device.DeviceInfo.") use NextLevel=0 to get all leaves. + const segments = parameterPath.replace(/\.$/, '').split('.') + const nextLevel = segments.length <= 1 + return CWMPMessageBuilder.getParameterNames(undefined, parameterPath, nextLevel) }, get_parameter_attributes: (parameterNames: string[]) => { return CWMPMessageBuilder.getParameterAttributes(undefined, parameterNames)