Complete implementation of ChangeDUState
This commit is contained in:
1 parent
716f2c6df3
commit
84de431872
4 files changed
+145
-17
No files matched your search
+43
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user