Types refactoring

This commit is contained in:
Zaid Abdulla committed 2020-08-25 01:02:11 -07:00
1 parent cce525cb07
commit c9eb5d1327
4 files changed
+302 -159

No files matched your search

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