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);
}
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
function appendProvisions(original, toAppend): boolean {
let modified = false;
@@ -1239,6 +1272,16 @@ async function processRequest(
cwmpVersion: sessionContext.cwmpVersion,
});
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 {
if (sessionContext.state !== 1 || rpc.cpeRequest.name === "Inform")
return void reportBadState(sessionContext);
+95 -10
View File
@@ -60,6 +60,7 @@ import {
ChangeDUStateOperation,
DownloadOperation,
DUStateChangeCompleteRequest,
ChangeDUState,
} from "./types";
import { getRequestOrigin } from "./forwarded";
import * as logger from "./logger";
@@ -452,8 +453,6 @@ export async function duStateChangeComplete(
sessionContext.deviceData.attributes.revision = revision;
const commandKey = rpcReq.commandKey;
const operation = sessionContext.operations[commandKey];
if (operation.name !== "ChangeDUState")
throw new Error("Unexpected operation name");
if (!operation) {
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];
if (!sessionContext.operationsTouched) sessionContext.operationsTouched = {};
sessionContext.operationsTouched[commandKey] = 1;
@@ -1577,7 +1591,7 @@ export async function rpcRequest(
if (index == null) {
index = 0;
for (const p of sessionContext.deviceData.paths.find(
Path.parse("DUState.*"),
Path.parse("DUStates.*"),
false,
true
)) {
@@ -1593,7 +1607,7 @@ export async function rpcRequest(
toClear = device.set(
sessionContext.deviceData,
Path.parse("DUState"),
Path.parse("DUStates"),
timestamp,
{ object: [timestamp, 1], writable: [timestamp, 1] },
toClear
@@ -1601,7 +1615,7 @@ export async function rpcRequest(
toClear = device.set(
sessionContext.deviceData,
Path.parse(`DUState.${index}`),
Path.parse(`DUStates.${index}`),
timestamp,
{ object: [timestamp, 1], writable: [timestamp, 1] },
toClear
@@ -1653,7 +1667,7 @@ export async function rpcRequest(
for (const [k, v] of Object.entries(params)) {
toClear = device.set(
sessionContext.deviceData,
Path.parse(`DUState.${index}.${k}`),
Path.parse(`DUStates.${index}.${k}`),
timestamp,
{
object: [timestamp, 0],
@@ -1669,7 +1683,7 @@ export async function rpcRequest(
toClear = device.set(
sessionContext.deviceData,
Path.parse(`DUState.${index}.*`),
Path.parse(`DUStates.${index}.*`),
timestamp,
null,
toClear
@@ -2014,6 +2028,7 @@ function generateSetRpcRequest(
| FactoryReset
| Reboot
| Download
| ChangeDUState
) & { next?: string } {
const syncState = sessionContext.syncState;
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
if (syncState.reboot) {
const p = sessionContext.deviceData.paths.get(Path.parse("Reboot"));
@@ -2473,7 +2558,7 @@ function processDeclarations(
}
}
break;
case "DUState":
case "DUStates":
if (
currentPath.length === 3 &&
currentPath.wildcard === 0 &&
@@ -2955,7 +3040,7 @@ export async function rpcResponse(
"FactoryReset",
"VirtualParameters",
"Downloads",
"DUState",
"DUStates",
]) {
const p = sessionContext.deviceData.paths.get(Path.parse(n));
if (p && sessionContext.deviceData.attributes.has(p))
@@ -3186,7 +3271,7 @@ export async function rpcResponse(
for (const op of rpcReq.operations) {
toClear = device.set(
sessionContext.deviceData,
Path.parse(`DuStates.${op.instance}.ChangeDUState`),
Path.parse(`DUStates.${op.instance}.ChangeDUState`),
timestamp + 1,
{ value: [timestamp + 1, [sessionContext.timestamp, "xsd:dateTime"]] },
toClear
+3 -3
View File
@@ -788,10 +788,10 @@ function DUStateChangeComplete(xml: Element): DUStateChangeCompleteRequest {
res.executionUnitRefList = cc.text;
break;
case "StartTime":
res.startTime = Date.parse(c.text);
if (c.text) res.startTime = Date.parse(c.text);
break;
case "CompleteTime":
res.completeTime = Date.parse(c.text);
if (c.text) res.completeTime = Date.parse(c.text);
break;
case "Fault":
res.fault = {
@@ -803,8 +803,8 @@ function DUStateChangeComplete(xml: Element): DUStateChangeCompleteRequest {
};
break;
}
results.push(res);
}
results.push(res);
break;
}
}
+4 -4
View File
@@ -304,10 +304,10 @@ export interface ChangeDUState {
instance: string;
url: string;
uuid: string;
version?: string;
executionEnvRef?: string;
username?: string;
password?: string;
version: string;
executionEnvRef: string;
username: string;
password: string;
}[];
}