Complete implementation of ChangeDUState

This commit is contained in:
Zaid Abdulla committed 2021-08-27 15:02:04 -07:00
1 parent 716f2c6df3
commit 84de431872
4 files changed
+145 -17

No files matched your search

+43
View File
@@ -361,6 +361,39 @@ async function transferComplete(sessionContext, rpc): Promise<void> {
return writeResponse(sessionContext, res); return writeResponse(sessionContext, res);
} }
async function duStateChangeComplete(sessionContext, rpc): Promise<void> {
const { acsResponse, operation, fault } = await session.duStateChangeComplete(
sessionContext,
rpc.cpeRequest
);
if (!operation) {
logger.accessWarn({
sessionContext: sessionContext,
message: "Unrecognized command key",
rpc: rpc,
});
}
if (fault) {
Object.assign(sessionContext.retries, operation.retries);
recordFault(
sessionContext,
fault,
operation.provisions,
operation.channels
);
}
const res = soap.response({
id: rpc.id,
acsResponse: acsResponse,
cwmpVersion: sessionContext.cwmpVersion,
});
return writeResponse(sessionContext, res);
}
// Append provisions and remove duplicates // Append provisions and remove duplicates
function appendProvisions(original, toAppend): boolean { function appendProvisions(original, toAppend): boolean {
let modified = false; let modified = false;
@@ -1239,6 +1272,16 @@ async function processRequest(
cwmpVersion: sessionContext.cwmpVersion, cwmpVersion: sessionContext.cwmpVersion,
}); });
return writeResponse(sessionContext, res); return writeResponse(sessionContext, res);
} else if (rpc.cpeRequest.name === "DUStateChangeComplete") {
if (sessionContext.state !== 1) return reportBadState(sessionContext);
logger.accessInfo({
sessionContext: sessionContext,
message: "CPE request",
rpc: rpc,
});
return duStateChangeComplete(sessionContext, rpc);
} else { } else {
if (sessionContext.state !== 1 || rpc.cpeRequest.name === "Inform") if (sessionContext.state !== 1 || rpc.cpeRequest.name === "Inform")
return void reportBadState(sessionContext); return void reportBadState(sessionContext);
+95 -10
View File
@@ -60,6 +60,7 @@ import {
ChangeDUStateOperation, ChangeDUStateOperation,
DownloadOperation, DownloadOperation,
DUStateChangeCompleteRequest, DUStateChangeCompleteRequest,
ChangeDUState,
} from "./types"; } from "./types";
import { getRequestOrigin } from "./forwarded"; import { getRequestOrigin } from "./forwarded";
import * as logger from "./logger"; import * as logger from "./logger";
@@ -452,8 +453,6 @@ export async function duStateChangeComplete(
sessionContext.deviceData.attributes.revision = revision; sessionContext.deviceData.attributes.revision = revision;
const commandKey = rpcReq.commandKey; const commandKey = rpcReq.commandKey;
const operation = sessionContext.operations[commandKey]; const operation = sessionContext.operations[commandKey];
if (operation.name !== "ChangeDUState")
throw new Error("Unexpected operation name");
if (!operation) { if (!operation) {
return { return {
@@ -463,6 +462,21 @@ export async function duStateChangeComplete(
}; };
} }
if (operation.name !== "ChangeDUState")
throw new Error("Unexpected operation name");
if (operation.args.operations.length !== rpcReq.results.length) {
return {
acsResponse: { name: "DUStateChangeCompleteResponse" },
operation: operation,
fault: {
code: "invalid_response",
message: "Unexpected number of results in DUStateChangeComplete",
timestamp: operation.timestamp,
},
};
}
delete sessionContext.operations[commandKey]; delete sessionContext.operations[commandKey];
if (!sessionContext.operationsTouched) sessionContext.operationsTouched = {}; if (!sessionContext.operationsTouched) sessionContext.operationsTouched = {};
sessionContext.operationsTouched[commandKey] = 1; sessionContext.operationsTouched[commandKey] = 1;
@@ -1577,7 +1591,7 @@ export async function rpcRequest(
if (index == null) { if (index == null) {
index = 0; index = 0;
for (const p of sessionContext.deviceData.paths.find( for (const p of sessionContext.deviceData.paths.find(
Path.parse("DUState.*"), Path.parse("DUStates.*"),
false, false,
true true
)) { )) {
@@ -1593,7 +1607,7 @@ export async function rpcRequest(
toClear = device.set( toClear = device.set(
sessionContext.deviceData, sessionContext.deviceData,
Path.parse("DUState"), Path.parse("DUStates"),
timestamp, timestamp,
{ object: [timestamp, 1], writable: [timestamp, 1] }, { object: [timestamp, 1], writable: [timestamp, 1] },
toClear toClear
@@ -1601,7 +1615,7 @@ export async function rpcRequest(
toClear = device.set( toClear = device.set(
sessionContext.deviceData, sessionContext.deviceData,
Path.parse(`DUState.${index}`), Path.parse(`DUStates.${index}`),
timestamp, timestamp,
{ object: [timestamp, 1], writable: [timestamp, 1] }, { object: [timestamp, 1], writable: [timestamp, 1] },
toClear toClear
@@ -1653,7 +1667,7 @@ export async function rpcRequest(
for (const [k, v] of Object.entries(params)) { for (const [k, v] of Object.entries(params)) {
toClear = device.set( toClear = device.set(
sessionContext.deviceData, sessionContext.deviceData,
Path.parse(`DUState.${index}.${k}`), Path.parse(`DUStates.${index}.${k}`),
timestamp, timestamp,
{ {
object: [timestamp, 0], object: [timestamp, 0],
@@ -1669,7 +1683,7 @@ export async function rpcRequest(
toClear = device.set( toClear = device.set(
sessionContext.deviceData, sessionContext.deviceData,
Path.parse(`DUState.${index}.*`), Path.parse(`DUStates.${index}.*`),
timestamp, timestamp,
null, null,
toClear toClear
@@ -2014,6 +2028,7 @@ function generateSetRpcRequest(
| FactoryReset | FactoryReset
| Reboot | Reboot
| Download | Download
| ChangeDUState
) & { next?: string } { ) & { next?: string } {
const syncState = sessionContext.syncState; const syncState = sessionContext.syncState;
if (!syncState) return null; if (!syncState) return null;
@@ -2192,6 +2207,76 @@ function generateSetRpcRequest(
} }
} }
// ChangeDUState
const duStateOps: ChangeDUState["operations"] = [];
for (const [p, t] of syncState.duStatesChangeDUState) {
const attrs = deviceData.attributes.get(p);
if (attrs && attrs.value && t <= attrs.value[1][0]) continue;
const urlAttrs = deviceData.attributes.get(
deviceData.paths.get(p.slice(0, -1).concat(Path.parse("URL")))
);
const operationTypeAttrs = deviceData.attributes.get(
deviceData.paths.get(p.slice(0, -1).concat(Path.parse("OperationType")))
);
const uuidAttrs = deviceData.attributes.get(
deviceData.paths.get(p.slice(0, -1).concat(Path.parse("UUID")))
);
const executionEnvRefAttrs = deviceData.attributes.get(
deviceData.paths.get(p.slice(0, -1).concat(Path.parse("ExecutionEnvRef")))
);
const versionAttrs = deviceData.attributes.get(
deviceData.paths.get(p.slice(0, -1).concat(Path.parse("Version")))
);
const usernameAttrs = deviceData.attributes.get(
deviceData.paths.get(p.slice(0, -1).concat(Path.parse("Username")))
);
const passwordAttrs = deviceData.attributes.get(
deviceData.paths.get(p.slice(0, -1).concat(Path.parse("Password")))
);
const operationType = operationTypeAttrs
? (operationTypeAttrs.value[1][0] as string)
: null;
const url = urlAttrs ? (urlAttrs.value[1][0] as string) : null;
const uuid = uuidAttrs ? (uuidAttrs.value[1][0] as string) : null;
const executionEnvRef = executionEnvRefAttrs
? (executionEnvRefAttrs.value[1][0] as string)
: null;
const version = versionAttrs ? (versionAttrs.value[1][0] as string) : null;
const username = usernameAttrs
? (usernameAttrs.value[1][0] as string)
: null;
const password = passwordAttrs
? (passwordAttrs.value[1][0] as string)
: null;
if (
operationType !== "install" &&
operationType !== "update" &&
operationType !== "uninstall"
)
continue;
duStateOps.push({
operationType: operationType,
instance: p.segments[1] as string,
url: url,
uuid: uuid,
executionEnvRef: executionEnvRef,
version: version,
username: username,
password: password,
});
}
if (duStateOps.length) {
return {
name: "ChangeDUState",
commandKey: generateRpcId(sessionContext),
operations: duStateOps,
};
}
// Reboot // Reboot
if (syncState.reboot) { if (syncState.reboot) {
const p = sessionContext.deviceData.paths.get(Path.parse("Reboot")); const p = sessionContext.deviceData.paths.get(Path.parse("Reboot"));
@@ -2473,7 +2558,7 @@ function processDeclarations(
} }
} }
break; break;
case "DUState": case "DUStates":
if ( if (
currentPath.length === 3 && currentPath.length === 3 &&
currentPath.wildcard === 0 && currentPath.wildcard === 0 &&
@@ -2955,7 +3040,7 @@ export async function rpcResponse(
"FactoryReset", "FactoryReset",
"VirtualParameters", "VirtualParameters",
"Downloads", "Downloads",
"DUState", "DUStates",
]) { ]) {
const p = sessionContext.deviceData.paths.get(Path.parse(n)); const p = sessionContext.deviceData.paths.get(Path.parse(n));
if (p && sessionContext.deviceData.attributes.has(p)) if (p && sessionContext.deviceData.attributes.has(p))
@@ -3186,7 +3271,7 @@ export async function rpcResponse(
for (const op of rpcReq.operations) { for (const op of rpcReq.operations) {
toClear = device.set( toClear = device.set(
sessionContext.deviceData, sessionContext.deviceData,
Path.parse(`DuStates.${op.instance}.ChangeDUState`), Path.parse(`DUStates.${op.instance}.ChangeDUState`),
timestamp + 1, timestamp + 1,
{ value: [timestamp + 1, [sessionContext.timestamp, "xsd:dateTime"]] }, { value: [timestamp + 1, [sessionContext.timestamp, "xsd:dateTime"]] },
toClear toClear
+3 -3
View File
@@ -788,10 +788,10 @@ function DUStateChangeComplete(xml: Element): DUStateChangeCompleteRequest {
res.executionUnitRefList = cc.text; res.executionUnitRefList = cc.text;
break; break;
case "StartTime": case "StartTime":
res.startTime = Date.parse(c.text); if (c.text) res.startTime = Date.parse(c.text);
break; break;
case "CompleteTime": case "CompleteTime":
res.completeTime = Date.parse(c.text); if (c.text) res.completeTime = Date.parse(c.text);
break; break;
case "Fault": case "Fault":
res.fault = { res.fault = {
@@ -803,8 +803,8 @@ function DUStateChangeComplete(xml: Element): DUStateChangeCompleteRequest {
}; };
break; break;
} }
results.push(res);
} }
results.push(res);
break; break;
} }
} }
+4 -4
View File
@@ -304,10 +304,10 @@ export interface ChangeDUState {
instance: string; instance: string;
url: string; url: string;
uuid: string; uuid: string;
version?: string; version: string;
executionEnvRef?: string; executionEnvRef: string;
username?: string; username: string;
password?: string; password: string;
}[]; }[];
} }