diff --git a/lib/cwmp.ts b/lib/cwmp.ts index e6b0de2..03d4568 100644 --- a/lib/cwmp.ts +++ b/lib/cwmp.ts @@ -36,7 +36,6 @@ import * as extensions from "./extensions"; import { SessionContext, AcsRequest, - SetAcsRequest, SessionFault, Operation, Fault, @@ -44,8 +43,8 @@ import { Task, SoapMessage, InformRequest, - AcsResponse, Preset, + GetRPCMethodsResponse, } from "./types"; import { IncomingMessage, ServerResponse } from "http"; import { Readable } from "stream"; @@ -806,9 +805,8 @@ async function sendAcsRequest( return writeResponse(sessionContext, soap.response(null), true); if (acsRequest.name === "Download") { - const downloadRequest = acsRequest as SetAcsRequest; - downloadRequest.fileSize = 0; - if (!downloadRequest.url) { + acsRequest.fileSize = 0; + if (!acsRequest.url) { let prefix = "" + config.get("FS_URL_PREFIX"); if (!prefix) { @@ -820,11 +818,11 @@ async function sendAcsRequest( prefix = (ssl ? "https" : "http") + `://${hostname}:${FS_PORT}/`; } - downloadRequest.url = prefix + encodeURI(downloadRequest.fileName); + acsRequest.url = prefix + encodeURI(acsRequest.fileName); const files = localCache.getFiles(sessionContext.cacheSnapshot); - if (files[downloadRequest.fileName]) - downloadRequest.fileSize = files[downloadRequest.fileName].length; + if (files[acsRequest.fileName]) + acsRequest.fileSize = files[acsRequest.fileName].length; } } @@ -1147,7 +1145,7 @@ async function processRequest( acsResponse: { name: "GetRPCMethodsResponse", methodList: ["Inform", "GetRPCMethods", "TransferComplete"], - } as AcsResponse, + } as GetRPCMethodsResponse, cwmpVersion: sessionContext.cwmpVersion, }); return writeResponse(sessionContext, res); diff --git a/lib/session.ts b/lib/session.ts index 948dfb7..26822ae 100644 --- a/lib/session.ts +++ b/lib/session.ts @@ -31,8 +31,6 @@ import { SessionContext, DeviceData, VirtualParameterDeclaration, - GetAcsRequest, - SetAcsRequest, AttributeTimestamps, AttributeValues, Fault, @@ -40,8 +38,6 @@ import { Clear, CpeResponse, CpeFault, - CpeSetResponse, - CpeGetResponse, AcsRequest, AcsResponse, InformRequest, @@ -49,6 +45,18 @@ import { Operation, ScriptResult, Expression, + GetParameterValues, + GetParameterAttributes, + GetParameterNames, + SetParameterValues, + SetParameterAttributes, + AddObject, + DeleteObject, + Download, + Reboot, + FactoryReset, + AddObjectResponse, + GetParameterValuesResponse, } from "./types"; import { getRequestOrigin } from "./forwarded"; @@ -1495,7 +1503,9 @@ export async function rpcRequest( return rpcRequest(sessionContext, null); } -function generateGetRpcRequest(sessionContext: SessionContext): GetAcsRequest { +function generateGetRpcRequest( + sessionContext: SessionContext +): GetParameterNames | GetParameterValues | GetParameterAttributes { const syncState = sessionContext.syncState; if (!syncState) return null; @@ -1590,7 +1600,7 @@ function generateGetRpcRequest(sessionContext: SessionContext): GetAcsRequest { } if (path) { - let nextLevel; + let nextLevel: boolean; let est = 0; if (path.length >= GPN_NEXT_LEVEL) { const patterns: [Path, number][] = [[path, 0]]; @@ -1708,7 +1718,17 @@ function compareAccessLists(list1: string[], list2: string[]): boolean { return true; } -function generateSetRpcRequest(sessionContext: SessionContext): SetAcsRequest { +function generateSetRpcRequest( + sessionContext: SessionContext +): ( + | SetParameterValues + | SetParameterAttributes + | AddObject + | DeleteObject + | FactoryReset + | Reboot + | Download +) & { next?: string } { const syncState = sessionContext.syncState; if (!syncState) return null; @@ -2379,15 +2399,16 @@ export async function rpcResponse( ++sessionContext.rpcCount; const rpcRes = _rpcRes; - const rpcReq = sessionContext.rpcRequest; + const rpcReq: typeof sessionContext.rpcRequest & { next?: string } = + sessionContext.rpcRequest; if (!rpcReq.next) { sessionContext.rpcRequest = null; } else if (rpcReq.next === "getInstanceKeys") { const parameterNames = []; - const instanceValues = {}; - const req = rpcReq as GetAcsRequest; - const res = rpcRes as CpeSetResponse; + const instanceValues: Record = {}; + const req = rpcReq as AddObject; + const res = rpcRes as AddObjectResponse; for (const [k, v] of Object.entries(req.instanceValues)) { const n = `${req.objectName}${res.instanceNumber}.${k}`; parameterNames.push(n); @@ -2397,7 +2418,10 @@ export async function rpcResponse( if (!parameterNames.length) { sessionContext.rpcRequest = null; } else { - const r: GetAcsRequest = { + const r: GetParameterValues & { + next: "setInstanceKeys"; + instanceValues: Record; + } = { name: "GetParameterValues", parameterNames: parameterNames, next: "setInstanceKeys", @@ -2406,8 +2430,10 @@ export async function rpcResponse( sessionContext.rpcRequest = r; } } else if (rpcReq.next === "setInstanceKeys") { - const req = rpcReq as GetAcsRequest; - const res = rpcRes as CpeGetResponse; + const req = rpcReq as GetParameterValues & { + instanceValues: Record; + }; + const res = rpcRes as GetParameterValuesResponse; const parameterList: [string, string | number | boolean, string][] = []; for (const p of res.parameterList) { if (p[1] !== req.instanceValues[p[0]]) { @@ -2438,7 +2464,7 @@ export async function rpcResponse( (e) => configContextCallback(sessionContext, e) ); - const r: SetAcsRequest = { + const r: SetParameterValues = { name: "SetParameterValues", parameterList: parameterList, DATETIME_MILLISECONDS: DATETIME_MILLISECONDS, @@ -2462,12 +2488,10 @@ export async function rpcResponse( wildcardPath: Path; if (rpcRes.name === "GetParameterValuesResponse") { - const req = rpcReq as GetAcsRequest; - const res = rpcRes as CpeGetResponse; - if (req.name !== "GetParameterValues") + if (rpcReq.name !== "GetParameterValues") throw new Error("Response name does not match request name"); - for (const p of res.parameterList) { + for (const p of rpcRes.parameterList) { toClear = device.set( sessionContext.deviceData, Path.parse(p[0]), @@ -2480,12 +2504,10 @@ export async function rpcResponse( ); } } else if (rpcRes.name === "GetParameterAttributesResponse") { - const req = rpcReq as GetAcsRequest; - const res = rpcRes as CpeGetResponse; - if (req.name !== "GetParameterAttributes") + if (rpcReq.name !== "GetParameterAttributes") throw new Error("Response name does not match request name"); - for (const p of res.parameterList) { + for (const p of rpcRes.parameterList) { toClear = device.set( sessionContext.deviceData, Path.parse(p[0]), @@ -2498,15 +2520,12 @@ export async function rpcResponse( ); } } else if (rpcRes.name === "GetParameterNamesResponse") { - const req = rpcReq as GetAcsRequest; - const res = rpcRes as CpeGetResponse; - - if (req.name !== "GetParameterNames") + if (rpcReq.name !== "GetParameterNames") throw new Error("Response name does not match request name"); - if (req.parameterPath.endsWith(".")) - root = Path.parse(req.parameterPath.slice(0, -1)); - else root = Path.parse(req.parameterPath); + if (rpcReq.parameterPath.endsWith(".")) + root = Path.parse(rpcReq.parameterPath.slice(0, -1)); + else root = Path.parse(rpcReq.parameterPath); wildcardPath = Path.parse("*"); params = [[root.concat(wildcardPath), timestamp]]; @@ -2514,15 +2533,16 @@ export async function rpcResponse( // Some clients don't report all ancestors explicitly missing = {}; - for (const p of res.parameterList) { + for (const p of rpcRes.parameterList) { let i = p[0].length - 1; - while ((i = p[0].lastIndexOf(".", i - 1)) > req.parameterPath.length) + while ((i = p[0].lastIndexOf(".", i - 1)) > rpcReq.parameterPath.length) missing[p[0].slice(0, i)] |= 0; if (p[0].endsWith(".")) { missing[p[0].slice(0, -1)] |= 1; const path = Path.parse(p[0].slice(0, -1)); - if (!req.nextLevel) params.push([path.concat(wildcardPath), timestamp]); + if (!rpcReq.nextLevel) + params.push([path.concat(wildcardPath), timestamp]); params.push([ path, @@ -2590,12 +2610,10 @@ export async function rpcResponse( ); } } else if (rpcRes.name === "SetParameterValuesResponse") { - const req = rpcReq as SetAcsRequest; - - if (req.name !== "SetParameterValues") + if (rpcReq.name !== "SetParameterValues") throw new Error("Response name does not match request name"); - for (const p of req.parameterList) { + for (const p of rpcReq.parameterList) { toClear = device.set( sessionContext.deviceData, Path.parse(p[0]), @@ -2612,11 +2630,10 @@ export async function rpcResponse( ); } } else if (rpcRes.name === "SetParameterAttributesResponse") { - const req = rpcReq as SetAcsRequest; - if (req.name !== "SetParameterAttributes") + if (rpcReq.name !== "SetParameterAttributes") throw new Error("Response name does not match request name"); - for (const p of req.parameterList) { + for (const p of rpcReq.parameterList) { let attrs; if (p[1] != null && p[2] != null) { @@ -2643,25 +2660,31 @@ export async function rpcResponse( ); } } else if (rpcRes.name === "AddObjectResponse") { - const req = rpcReq as SetAcsRequest; - const res = rpcRes as CpeSetResponse; + if (rpcReq.name !== "AddObject") + throw new Error("Response name does not match request name"); + toClear = device.set( sessionContext.deviceData, - Path.parse(req.objectName + res.instanceNumber), + Path.parse(rpcReq.objectName + rpcRes.instanceNumber), timestamp + 1, { object: [timestamp + 1, 1] }, toClear ); } else if (rpcRes.name === "DeleteObjectResponse") { - const req = rpcReq as SetAcsRequest; + if (rpcReq.name !== "DeleteObject") + throw new Error("Response name does not match request name"); + toClear = device.set( sessionContext.deviceData, - Path.parse(req.objectName.slice(0, -1)), + Path.parse(rpcReq.objectName.slice(0, -1)), timestamp + 1, null, toClear ); } else if (rpcRes.name === "RebootResponse") { + if (rpcReq.name !== "Reboot") + throw new Error("Response name does not match request name"); + toClear = device.set( sessionContext.deviceData, Path.parse("Reboot"), @@ -2670,6 +2693,9 @@ export async function rpcResponse( toClear ); } else if (rpcRes.name === "FactoryResetResponse") { + if (rpcReq.name !== "FactoryReset") + throw new Error("Response name does not match request name"); + toClear = device.set( sessionContext.deviceData, Path.parse("FactoryReset"), @@ -2678,20 +2704,21 @@ export async function rpcResponse( toClear ); } else if (rpcRes.name === "DownloadResponse") { - const req = rpcReq as SetAcsRequest; - const res = rpcRes as CpeSetResponse; + if (rpcReq.name !== "Download") + throw new Error("Response name does not match request name"); + toClear = device.set( sessionContext.deviceData, - Path.parse(`Downloads.${req.instance}.Download`), + Path.parse(`Downloads.${rpcReq.instance}.Download`), timestamp + 1, { value: [timestamp + 1, [sessionContext.timestamp, "xsd:dateTime"]] }, toClear ); - if (res.status === 0) { + if (rpcRes.status === 0) { toClear = device.set( sessionContext.deviceData, - Path.parse(`Downloads.${req.instance}.LastDownload`), + Path.parse(`Downloads.${rpcReq.instance}.LastDownload`), timestamp + 1, { value: [timestamp + 1, [sessionContext.timestamp, "xsd:dateTime"]], @@ -2701,41 +2728,41 @@ export async function rpcResponse( toClear = device.set( sessionContext.deviceData, - Path.parse(`Downloads.${req.instance}.LastFileType`), + Path.parse(`Downloads.${rpcReq.instance}.LastFileType`), timestamp + 1, - { value: [timestamp + 1, [req.fileType, "xsd:string"]] }, + { value: [timestamp + 1, [rpcReq.fileType, "xsd:string"]] }, toClear ); toClear = device.set( sessionContext.deviceData, - Path.parse(`Downloads.${req.instance}.LastFileName`), + Path.parse(`Downloads.${rpcReq.instance}.LastFileName`), timestamp + 1, - { value: [timestamp + 1, [req.fileType, "xsd:string"]] }, + { value: [timestamp + 1, [rpcReq.fileType, "xsd:string"]] }, toClear ); toClear = device.set( sessionContext.deviceData, - Path.parse(`Downloads.${req.instance}.LastTargetFileName`), + Path.parse(`Downloads.${rpcReq.instance}.LastTargetFileName`), timestamp + 1, - { value: [timestamp + 1, [req.fileType, "xsd:string"]] }, + { value: [timestamp + 1, [rpcReq.fileType, "xsd:string"]] }, toClear ); toClear = device.set( sessionContext.deviceData, - Path.parse(`Downloads.${req.instance}.StartTime`), + Path.parse(`Downloads.${rpcReq.instance}.StartTime`), timestamp + 1, - { value: [timestamp + 1, [+res.startTime, "xsd:dateTime"]] }, + { value: [timestamp + 1, [+rpcRes.startTime, "xsd:dateTime"]] }, toClear ); toClear = device.set( sessionContext.deviceData, - Path.parse(`Downloads.${req.instance}.CompleteTime`), + Path.parse(`Downloads.${rpcReq.instance}.CompleteTime`), timestamp + 1, - { value: [timestamp + 1, [+res.completeTime, "xsd:dateTime"]] }, + { value: [timestamp + 1, [+rpcRes.completeTime, "xsd:dateTime"]] }, toClear ); } else { @@ -2746,10 +2773,10 @@ export async function rpcResponse( channels: sessionContext.channels, retries: {}, args: { - instance: req.instance, - fileType: req.fileType, - fileName: req.fileName, - targetFileName: req.targetFileName, + instance: rpcReq.instance, + fileType: rpcReq.fileType, + fileName: rpcReq.fileName, + targetFileName: rpcReq.targetFileName, }, }; @@ -2758,10 +2785,10 @@ export async function rpcResponse( operation.retries[channel] = sessionContext.retries[channel]; } - sessionContext.operations[req.commandKey] = operation; + sessionContext.operations[rpcReq.commandKey] = operation; if (!sessionContext.operationsTouched) sessionContext.operationsTouched = {}; - sessionContext.operationsTouched[req.commandKey] = 1; + sessionContext.operationsTouched[rpcReq.commandKey] = 1; } } else { throw new Error("Response name not recognized"); @@ -2778,7 +2805,7 @@ export async function rpcFault( id: string, faultResponse: CpeFault ): Promise { - const rpcReq = sessionContext.rpcRequest as GetAcsRequest | SetAcsRequest; + const rpcReq = sessionContext.rpcRequest; delete sessionContext.syncState; delete sessionContext.rpcRequest; ++sessionContext.rpcCount; diff --git a/lib/soap.ts b/lib/soap.ts index 14907cc..dc8c522 100644 --- a/lib/soap.ts +++ b/lib/soap.ts @@ -27,17 +27,27 @@ import { import memoize from "./common/memoize"; import { version as VERSION } from "../package.json"; import { - CpeGetResponse, - CpeSetResponse, InformRequest, - AcsResponse, - CpeRequest, FaultStruct, SpvFault, CpeFault, SoapMessage, TransferCompleteRequest, AcsRequest, + GetParameterNamesResponse, + GetParameterValuesResponse, + GetParameterAttributesResponse, + SetParameterValuesResponse, + SetParameterAttributesResponse, + AddObjectResponse, + DeleteObject, + DeleteObjectResponse, + RebootResponse, + FactoryResetResponse, + DownloadResponse, + GetRPCMethodsRequest, + RequestDownloadRequest, + AcsResponse, } from "./types"; const SERVER_NAME = `GenieACS/${VERSION}`; @@ -118,7 +128,7 @@ function parameterInfoList(xml: Element): [string, boolean][] { let parsed: boolean = parseBool(value); - if (parsed === null) { + if (parsed == null) { warnings.push({ message: "Invalid writable attribute", parameter: param, @@ -160,7 +170,7 @@ function parameterValueList( let parsed: string | number | boolean = value; if (valueType === "xsd:boolean") { parsed = parseBool(value); - if (parsed === null) { + if (parsed == null) { warnings.push({ message: "Invalid value attribute", parameter: param, @@ -236,7 +246,7 @@ function GetParameterNames(methodRequest): string { }${+methodRequest.nextLevel}`; } -function GetParameterNamesResponse(xml): CpeGetResponse { +function GetParameterNamesResponse(xml): GetParameterNamesResponse { return { name: "GetParameterNamesResponse", parameterList: parameterInfoList( @@ -253,7 +263,7 @@ function GetParameterValues(methodRequest): string { .join("")}`; } -function GetParameterValuesResponse(xml: Element): CpeGetResponse { +function GetParameterValuesResponse(xml: Element): GetParameterValuesResponse { return { name: "GetParameterValuesResponse", parameterList: parameterValueList( @@ -270,7 +280,9 @@ function GetParameterAttributes(methodRequest): string { .join("")}`; } -function GetParameterAttributesResponse(xml: Element): CpeGetResponse { +function GetParameterAttributesResponse( + xml: Element +): GetParameterAttributesResponse { return { name: "GetParameterAttributesResponse", parameterList: parameterAttributeList( @@ -301,7 +313,7 @@ function SetParameterValues(methodRequest): string { }`; } -function SetParameterValuesResponse(xml: Element): CpeSetResponse { +function SetParameterValuesResponse(xml: Element): SetParameterValuesResponse { return { name: "SetParameterValuesResponse", status: parseInt(xml.children.find((n) => n.localName === "Status").text), @@ -332,7 +344,7 @@ function SetParameterAttributes(methodRequest): string { }]">${params.join("")}`; } -function SetParameterAttributesResponse(): CpeSetResponse { +function SetParameterAttributesResponse(): SetParameterAttributesResponse { return { name: "SetParameterAttributesResponse", }; @@ -346,7 +358,7 @@ function AddObject(methodRequest): string { }`; } -function AddObjectResponse(xml: Element): CpeSetResponse { +function AddObjectResponse(xml: Element): AddObjectResponse { let instanceNumber, status; for (const c of xml.children) { switch (c.localName) { @@ -374,7 +386,7 @@ function DeleteObject(methodRequest): string { }`; } -function DeleteObjectResponse(xml: Element): CpeSetResponse { +function DeleteObjectResponse(xml: Element): DeleteObjectResponse { return { name: "DeleteObjectResponse", status: parseInt(xml.children.find((n) => n.localName === "Status").text), @@ -387,7 +399,7 @@ function Reboot(methodRequest): string { }`; } -function RebootResponse(): CpeSetResponse { +function RebootResponse(): RebootResponse { return { name: "RebootResponse", }; @@ -397,7 +409,7 @@ function FactoryReset(): string { return ""; } -function FactoryResetResponse(): CpeSetResponse { +function FactoryResetResponse(): FactoryResetResponse { return { name: "FactoryResetResponse", }; @@ -425,7 +437,7 @@ function Download(methodRequest): string { )}`; } -function DownloadResponse(xml: Element): CpeSetResponse { +function DownloadResponse(xml: Element): DownloadResponse { let status, startTime, completeTime; for (const c of xml.children) { switch (c.localName) { @@ -491,7 +503,7 @@ function InformResponse(): string { return "1"; } -function GetRPCMethods(): AcsResponse { +function GetRPCMethods(): GetRPCMethodsRequest { return { name: "GetRPCMethods" }; } @@ -535,7 +547,7 @@ function TransferCompleteResponse(): string { return ""; } -function RequestDownload(xml: Element): CpeRequest { +function RequestDownload(xml: Element): RequestDownloadRequest { return { name: "RequestDownload", fileType: xml.children.find((n) => n.localName === "FileType").text, @@ -789,7 +801,11 @@ export function response(rpc: { body = RequestDownloadResponse(); break; default: - throw new Error(`Unknown method response type ${rpc.acsResponse.name}`); + throw new Error( + `Unknown method response type ${ + (rpc.acsResponse as AcsResponse).name + }` + ); } } else if (rpc.acsRequest) { switch (rpc.acsRequest.name) { @@ -824,7 +840,9 @@ export function response(rpc: { body = Download(rpc.acsRequest); break; default: - throw new Error(`Unknown method request ${rpc.acsRequest.name}`); + throw new Error( + `Unknown method request ${(rpc.acsRequest as AcsRequest).name}` + ); } } diff --git a/lib/types.ts b/lib/types.ts index 2305eb6..2369ff2 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -196,47 +196,84 @@ export interface Operation { }; } -export interface AcsRequest { - name: string; - next?: string; +export type AcsRequest = + | GetParameterNames + | GetParameterValues + | GetParameterAttributes + | SetParameterValues + | SetParameterAttributes + | AddObject + | DeleteObject + | FactoryReset + | Reboot + | Download; + +export interface GetParameterNames { + name: "GetParameterNames"; + parameterPath: string; + nextLevel: boolean; } -export interface GetAcsRequest extends AcsRequest { - name: "GetParameterNames" | "GetParameterValues" | "GetParameterAttributes"; - objectName?: string; - parameterNames?: string[]; - parameterPath?: string; - nextLevel?: boolean; - instanceValues?: { [name: string]: string }; +export interface GetParameterValues { + name: "GetParameterValues"; + parameterNames: string[]; } -export interface SetAcsRequest extends AcsRequest { - name: - | "SetParameterValues" - | "SetParameterAttributes" - | "AddObject" - | "DeleteObject" - | "FactoryReset" - | "Reboot" - | "Download"; - parameterList?: - | [string, string | number | boolean, string][] - | [string, number, string[]][]; - instanceValues?: { [param: string]: string | number | boolean }; - objectName?: string; +export interface GetParameterAttributes { + name: "GetParameterAttributes"; + parameterNames: string[]; +} + +export interface SetParameterValues { + name: "SetParameterValues"; + parameterList: [string, boolean | number | string, string][]; + parameterKey?: string; DATETIME_MILLISECONDS?: boolean; BOOLEAN_LITERAL?: boolean; - commandKey?: string; - instance?: string; - fileType?: string; - fileSize?: number; - url?: string; - fileName?: string; - targetFileName?: string; } -export interface CpeResponse { - name: string; +export interface SetParameterAttributes { + name: "SetParameterAttributes"; + parameterList: [string, number, string[]][]; +} + +export interface AddObject { + name: "AddObject"; + objectName: string; + parameterKey?: string; + instanceValues: Record; +} + +export interface DeleteObject { + name: "DeleteObject"; + objectName: string; + parameterKey?: string; +} + +export interface FactoryReset { + name: "FactoryReset"; + commandKey?: string; +} + +export interface Reboot { + name: "Reboot"; + commandKey?: string; +} + +export interface Download { + name: "Download"; + commandKey: string; + instance: string; + fileType: string; + fileName?: string; + url?: string; + username?: string; + password?: string; + fileSize?: number; + targetFileName?: string; + delaySecods?: number; + successUrl?: string; + failureUrl?: string; } export interface SpvFault { @@ -257,38 +294,75 @@ export interface CpeFault { detail?: FaultStruct; } -export interface CpeGetResponse extends CpeResponse { - name: - | "GetParameterNamesResponse" - | "GetParameterValuesResponse" - | "GetParameterAttributesResponse"; - parameterList?: - | [string, boolean][] - | [string, string | number | boolean, string][] - | [string, number, string[]][]; +export type CpeResponse = + | GetParameterNamesResponse + | GetParameterValuesResponse + | GetParameterAttributesResponse + | SetParameterValuesResponse + | SetParameterAttributesResponse + | AddObjectResponse + | DeleteObjectResponse + | RebootResponse + | FactoryResetResponse + | DownloadResponse; + +export interface GetParameterNamesResponse { + name: "GetParameterNamesResponse"; + parameterList: [string, boolean][]; } -export interface CpeSetResponse extends CpeResponse { - name: - | "SetParameterValuesResponse" - | "SetParameterAttributesResponse" - | "AddObjectResponse" - | "DeleteObjectResponse" - | "RebootResponse" - | "FactoryResetResponse" - | "DownloadResponse"; - status?: number; - instanceNumber?: string; +export interface GetParameterValuesResponse { + name: "GetParameterValuesResponse"; + parameterList: [string, string | number | boolean, string][]; +} + +export interface GetParameterAttributesResponse { + name: "GetParameterAttributesResponse"; + parameterList: [string, number, string[]][]; +} + +export interface SetParameterValuesResponse { + name: "SetParameterValuesResponse"; + status: number; +} + +export interface SetParameterAttributesResponse { + name: "SetParameterAttributesResponse"; +} + +export interface AddObjectResponse { + name: "AddObjectResponse"; + instanceNumber: string; + status: number; +} + +export interface DeleteObjectResponse { + name: "DeleteObjectResponse"; + status: number; +} + +export interface RebootResponse { + name: "RebootResponse"; +} + +export interface FactoryResetResponse { + name: "FactoryResetResponse"; +} + +export interface DownloadResponse { + name: "DownloadResponse"; + status: number; startTime?: number; completeTime?: number; } -export interface CpeRequest { - name: string; - fileType?: string; -} +export type CpeRequest = + | InformRequest + | TransferCompleteRequest + | GetRPCMethodsRequest + | RequestDownloadRequest; -export interface InformRequest extends CpeRequest { +export interface InformRequest { name: "Inform"; deviceId: { Manufacturer: string; @@ -301,7 +375,7 @@ export interface InformRequest extends CpeRequest { parameterList: [string, string | number | boolean, string][]; } -export interface TransferCompleteRequest extends CpeRequest { +export interface TransferCompleteRequest { name: "TransferComplete"; commandKey?: string; faultStruct?: FaultStruct; @@ -309,10 +383,36 @@ export interface TransferCompleteRequest extends CpeRequest { completeTime?: number; } -export interface AcsResponse { - name: string; - commandKey?: string; - faultStruct?: FaultStruct; +export interface GetRPCMethodsRequest { + name: "GetRPCMethods"; +} + +export interface RequestDownloadRequest { + name: "RequestDownload"; + fileType: string; +} + +export type AcsResponse = + | InformResponse + | GetRPCMethodsResponse + | TransferCompleteResponse + | RequestDownloadResponse; + +export interface InformResponse { + name: "InformResponse"; +} + +export interface GetRPCMethodsResponse { + name: "GetRPCMethodsResponse"; + methodList: string[]; +} + +export interface TransferCompleteResponse { + name: "TransferCompleteResponse"; +} + +export interface RequestDownloadResponse { + name: "RequestDownloadResponse"; } export interface QueryOptions {