Expose all device params to config expressions
This commit is contained in:
1 parent
75ff56f3ae
commit
add4c84132
9 files changed
+254
-137
No files matched your search
+77
-54
@@ -31,57 +31,77 @@ import {
|
||||
udpConnectionRequest
|
||||
} from "./connection-request";
|
||||
import { Expression, Task } from "./types";
|
||||
import { flattenDevice } from "./mongodb-functions";
|
||||
import { evaluate } from "./common/expression";
|
||||
|
||||
export async function connectionRequest(deviceId): Promise<void> {
|
||||
const options = {
|
||||
projection: {
|
||||
_deviceId: 1,
|
||||
"Device.ManagementServer.ConnectionRequestURL._value": 1,
|
||||
"Device.ManagementServer.UDPConnectionRequestAddress._value": 1,
|
||||
"Device.ManagementServer.ConnectionRequestUsername._value": 1,
|
||||
"Device.ManagementServer.ConnectionRequestPassword._value": 1,
|
||||
"InternetGatewayDevice.ManagementServer.ConnectionRequestURL._value": 1,
|
||||
"InternetGatewayDevice.ManagementServer.UDPConnectionRequestAddress._value": 1,
|
||||
"InternetGatewayDevice.ManagementServer.ConnectionRequestUsername._value": 1,
|
||||
"InternetGatewayDevice.ManagementServer.ConnectionRequestPassword._value": 1
|
||||
export async function connectionRequest(
|
||||
deviceId: string,
|
||||
device?: {}
|
||||
): Promise<void> {
|
||||
if (!device) {
|
||||
const res = await db.devicesCollection.findOne({ _id: deviceId });
|
||||
if (!res) throw new Error("No such device");
|
||||
device = flattenDevice(res);
|
||||
}
|
||||
};
|
||||
|
||||
const device = await db.devicesCollection.findOne({ _id: deviceId }, options);
|
||||
if (!device) throw new Error("No such device");
|
||||
let connectionRequestUrl, udpConnectionRequestAddress, username, password;
|
||||
|
||||
let managementServer,
|
||||
connectionRequestUrl,
|
||||
udpConnectionRequestAddress,
|
||||
username,
|
||||
password;
|
||||
if (device.Device)
|
||||
// TR-181 data model
|
||||
managementServer = device.Device.ManagementServer;
|
||||
// TR-098 data model
|
||||
else managementServer = device.InternetGatewayDevice.ManagementServer;
|
||||
|
||||
if (managementServer.ConnectionRequestURL)
|
||||
connectionRequestUrl = managementServer.ConnectionRequestURL._value;
|
||||
if (managementServer.UDPConnectionRequestAddress) {
|
||||
udpConnectionRequestAddress =
|
||||
managementServer.UDPConnectionRequestAddress._value;
|
||||
if (device["InternetGatewayDevice.ManagementServer.ConnectionRequestURL"]) {
|
||||
connectionRequestUrl = (device[
|
||||
"InternetGatewayDevice.ManagementServer.ConnectionRequestURL"
|
||||
].value || [""])[0];
|
||||
udpConnectionRequestAddress = ((
|
||||
device[
|
||||
"InternetGatewayDevice.ManagementServer.UDPConnectionRequestAddress"
|
||||
] || {}
|
||||
).value || [""])[0];
|
||||
username = ((
|
||||
device[
|
||||
"InternetGatewayDevice.ManagementServer.ConnectionRequestUsername"
|
||||
] || {}
|
||||
).value || [""])[0];
|
||||
password = ((
|
||||
device[
|
||||
"InternetGatewayDevice.ManagementServer.ConnectionRequestPassword"
|
||||
] || {}
|
||||
).value || [""])[0];
|
||||
} else {
|
||||
connectionRequestUrl = (device[
|
||||
"Device.ManagementServer.ConnectionRequestURL"
|
||||
].value || [""])[0];
|
||||
udpConnectionRequestAddress = ((
|
||||
device["Device.ManagementServer.UDPConnectionRequestAddress"] || {}
|
||||
).value || [""])[0];
|
||||
udpConnectionRequestAddress = ((
|
||||
device["Device.ManagementServer.ConnectionRequestUsername"] || {}
|
||||
).value || [""])[0];
|
||||
password = ((
|
||||
device["Device.ManagementServer.ConnectionRequestPassword"] || {}
|
||||
).value || [""])[0];
|
||||
}
|
||||
if (managementServer.ConnectionRequestUsername)
|
||||
username = managementServer.ConnectionRequestUsername._value;
|
||||
if (managementServer.ConnectionRequestPassword)
|
||||
password = managementServer.ConnectionRequestPassword._value;
|
||||
|
||||
const context = {
|
||||
id: device["_id"],
|
||||
serialNumber: device["_deviceId"]["SerialNumber"],
|
||||
productClass: device["_deviceId"]["ProductClass"],
|
||||
oui: device["_deviceId"]["OUI"],
|
||||
remoteAddress: connectionRequestUrl
|
||||
? parse(connectionRequestUrl).host
|
||||
: null,
|
||||
username: username || "",
|
||||
password: password || ""
|
||||
const remoteAddress = parse(connectionRequestUrl).host;
|
||||
|
||||
const evalCallback = (exp): Expression => {
|
||||
if (!Array.isArray(exp)) return exp;
|
||||
if (exp[0] === "PARAM") {
|
||||
let name = exp[1];
|
||||
if (name === "id") name = "DeviceID.ID";
|
||||
else if (name === "serialNumber") name = "DeviceID.SerialNumber";
|
||||
else if (name === "productClass") name = "DeviceID.ProductClass";
|
||||
else if (name === "oui") name = "DeviceID.OUI";
|
||||
else if (name === "remoteAddress") return remoteAddress;
|
||||
else if (name === "username") return username;
|
||||
else if (name === "password") return password;
|
||||
|
||||
const p = device[name];
|
||||
if (p && p.value) return p.value[0];
|
||||
} else if (exp[0] === "FUNC") {
|
||||
if (exp[1] === "REMOTE_ADDRESS") return remoteAddress;
|
||||
else if (exp[1] === "USERNAME") return username;
|
||||
else if (exp[1] === "PASSWORD") return password;
|
||||
}
|
||||
return exp;
|
||||
};
|
||||
|
||||
const snapshot = await getCurrentSnapshot();
|
||||
@@ -89,20 +109,23 @@ export async function connectionRequest(deviceId): Promise<void> {
|
||||
const UDP_CONNECTION_REQUEST_PORT = +getConfig(
|
||||
snapshot,
|
||||
"cwmp.udpConnectionRequestPort",
|
||||
context,
|
||||
now
|
||||
{},
|
||||
now,
|
||||
evalCallback
|
||||
);
|
||||
const CONNECTION_REQUEST_TIMEOUT = +getConfig(
|
||||
snapshot,
|
||||
"cwmp.connectionRequestTimeout",
|
||||
context,
|
||||
now
|
||||
{},
|
||||
now,
|
||||
evalCallback
|
||||
);
|
||||
const CONNECTION_REQUEST_ALLOW_BASIC_AUTH = !!getConfig(
|
||||
snapshot,
|
||||
"cwmp.connectionRequestAllowBasicAuth",
|
||||
context,
|
||||
now
|
||||
{},
|
||||
now,
|
||||
evalCallback
|
||||
);
|
||||
let authExp: Expression = getConfigExpression(
|
||||
snapshot,
|
||||
@@ -118,14 +141,15 @@ export async function connectionRequest(deviceId): Promise<void> {
|
||||
] as Expression;
|
||||
}
|
||||
|
||||
const debug = !!getConfig(snapshot, "cwmp.debug", context, now);
|
||||
authExp = evaluate(authExp, {}, now, evalCallback);
|
||||
|
||||
const debug = !!getConfig(snapshot, "cwmp.debug", {}, now, evalCallback);
|
||||
|
||||
let udpProm;
|
||||
if (udpConnectionRequestAddress) {
|
||||
udpProm = udpConnectionRequest(
|
||||
udpConnectionRequestAddress,
|
||||
authExp,
|
||||
context,
|
||||
UDP_CONNECTION_REQUEST_PORT,
|
||||
debug,
|
||||
deviceId
|
||||
@@ -136,7 +160,6 @@ export async function connectionRequest(deviceId): Promise<void> {
|
||||
await httpConnectionRequest(
|
||||
connectionRequestUrl,
|
||||
authExp,
|
||||
context,
|
||||
CONNECTION_REQUEST_ALLOW_BASIC_AUTH,
|
||||
CONNECTION_REQUEST_TIMEOUT,
|
||||
debug,
|
||||
|
||||
+3
-1
@@ -26,8 +26,10 @@ function parseHeaderFeilds(str: string): {} {
|
||||
let part;
|
||||
while ((part = parts.shift()) != null) {
|
||||
const name = part.split("=", 1)[0];
|
||||
if (name.length === part.length)
|
||||
if (name.length === part.length) {
|
||||
if (!part.trim()) continue;
|
||||
throw new Error("Unable to parse auth header");
|
||||
}
|
||||
|
||||
let value = part.slice(name.length + 1);
|
||||
if (!/^\s*"/.test(value)) {
|
||||
|
||||
@@ -29,15 +29,13 @@ import * as debug from "./debug";
|
||||
|
||||
async function extractAuth(
|
||||
exp: Expression,
|
||||
context: {},
|
||||
now: number,
|
||||
dflt: any
|
||||
): Promise<[string, string, Expression]> {
|
||||
let username, password;
|
||||
const _exp = await evaluateAsync(
|
||||
exp,
|
||||
context,
|
||||
now,
|
||||
{},
|
||||
0,
|
||||
async (e: Expression): Promise<Expression> => {
|
||||
if (!username && Array.isArray(e) && e[0] === "FUNC") {
|
||||
if (e[1] === "EXT") {
|
||||
@@ -50,8 +48,8 @@ async function extractAuth(
|
||||
return fault ? null : value;
|
||||
} else if (e[1] === "AUTH") {
|
||||
if (!Array.isArray(e[2]) && !Array.isArray(e[3])) {
|
||||
username = e[2];
|
||||
password = e[3];
|
||||
username = e[2] || "";
|
||||
password = e[3] || "";
|
||||
}
|
||||
return dflt;
|
||||
}
|
||||
@@ -95,13 +93,11 @@ function httpGet(
|
||||
export async function httpConnectionRequest(
|
||||
address: string,
|
||||
authExp: Expression,
|
||||
context: {},
|
||||
allowBasicAuth: boolean,
|
||||
timeout: number,
|
||||
_debug: boolean,
|
||||
deviceId: string
|
||||
): Promise<void> {
|
||||
const now = Date.now();
|
||||
const options: http.RequestOptions = parse(address);
|
||||
if (options.protocol !== "http:")
|
||||
throw new Error("Invalid connection request URL or protocol");
|
||||
@@ -163,12 +159,7 @@ export async function httpConnectionRequest(
|
||||
authHeader = auth.parseWwwAuthenticateHeader(
|
||||
res.headers["www-authenticate"]
|
||||
);
|
||||
[username, password, authExp] = await extractAuth(
|
||||
authExp,
|
||||
context,
|
||||
now,
|
||||
false
|
||||
);
|
||||
[username, password, authExp] = await extractAuth(authExp, false);
|
||||
} else {
|
||||
throw new Error(
|
||||
`Unexpected response code from device: ${res.statusCode}`
|
||||
@@ -181,7 +172,6 @@ export async function httpConnectionRequest(
|
||||
export async function udpConnectionRequest(
|
||||
address: string,
|
||||
authExp: Expression,
|
||||
context: {},
|
||||
sourcePort: number = 0,
|
||||
_debug: boolean,
|
||||
deviceId: string
|
||||
@@ -202,12 +192,7 @@ export async function udpConnectionRequest(
|
||||
let username: string;
|
||||
let password: string;
|
||||
|
||||
[username, password, authExp] = await extractAuth(
|
||||
authExp,
|
||||
context,
|
||||
now,
|
||||
null
|
||||
);
|
||||
[username, password, authExp] = await extractAuth(authExp, null);
|
||||
|
||||
if (username == null) username = "";
|
||||
if (password == null) password = "";
|
||||
@@ -233,12 +218,7 @@ export async function udpConnectionRequest(
|
||||
});
|
||||
}
|
||||
|
||||
[username, password, authExp] = await extractAuth(
|
||||
authExp,
|
||||
context,
|
||||
now,
|
||||
null
|
||||
);
|
||||
[username, password, authExp] = await extractAuth(authExp, null);
|
||||
}
|
||||
client.close();
|
||||
}
|
||||
+64
-30
@@ -103,12 +103,12 @@ async function authenticate(
|
||||
authentication["body"] = body;
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
const res = await evaluateAsync(
|
||||
authExpression,
|
||||
sessionContext.configContext,
|
||||
now,
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
async (e: Expression): Promise<Expression> => {
|
||||
e = session.configContextCallback(sessionContext, e);
|
||||
if (Array.isArray(e) && e[0] === "FUNC") {
|
||||
if (e[1] === "EXT") {
|
||||
if (typeof e[2] !== "string" || typeof e[3] !== "string") return null;
|
||||
@@ -294,7 +294,9 @@ async function inform(sessionContext: SessionContext, rpc): Promise<void> {
|
||||
const cookiesPath = localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.cookiesPath",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => session.configContextCallback(sessionContext, e)
|
||||
);
|
||||
|
||||
if (cookiesPath) {
|
||||
@@ -384,7 +386,9 @@ async function applyPresets(sessionContext: SessionContext): Promise<void> {
|
||||
const RETRY_DELAY = +localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.retryDelay",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => session.configContextCallback(sessionContext, e)
|
||||
);
|
||||
|
||||
if (sessionContext.faults) {
|
||||
@@ -1263,9 +1267,19 @@ async function listenerAsync(
|
||||
debug.outgoingHttpResponse(httpResponse, sessionContext.deviceId, msg);
|
||||
} else {
|
||||
const cacheSnapshot = await localCache.getCurrentSnapshot();
|
||||
const d = !!localCache.getConfig(cacheSnapshot, "cwmp.debug", {
|
||||
const d = !!localCache.getConfig(
|
||||
cacheSnapshot,
|
||||
"cwmp.debug",
|
||||
{
|
||||
remoteAddress: httpResponse.connection.remoteAddress
|
||||
});
|
||||
},
|
||||
Date.now(),
|
||||
e => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
|
||||
return httpResponse.connection.remoteAddress;
|
||||
return e;
|
||||
}
|
||||
);
|
||||
if (d) debug.outgoingHttpResponse(httpResponse, null, msg);
|
||||
}
|
||||
httpResponse.end(msg);
|
||||
@@ -1314,9 +1328,19 @@ async function listenerAsync(
|
||||
}
|
||||
} else {
|
||||
const cacheSnapshot = await localCache.getCurrentSnapshot();
|
||||
const d = !!localCache.getConfig(cacheSnapshot, "cwmp.debug", {
|
||||
const d = !!localCache.getConfig(
|
||||
cacheSnapshot,
|
||||
"cwmp.debug",
|
||||
{
|
||||
remoteAddress: httpResponse.connection.remoteAddress
|
||||
});
|
||||
},
|
||||
Date.now(),
|
||||
e => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
|
||||
return httpResponse.connection.remoteAddress;
|
||||
return e;
|
||||
}
|
||||
);
|
||||
if (d) debug.outgoingHttpResponse(httpResponse, null, error.message);
|
||||
}
|
||||
httpResponse.end(error.message);
|
||||
@@ -1347,9 +1371,19 @@ async function listenerAsync(
|
||||
httpResponse.setHeader("Content-Length", Buffer.byteLength(_body));
|
||||
httpResponse.writeHead(400, { Connection: "close" });
|
||||
const cacheSnapshot = await localCache.getCurrentSnapshot();
|
||||
const d = !!localCache.getConfig(cacheSnapshot, "cwmp.debug", {
|
||||
const d = !!localCache.getConfig(
|
||||
cacheSnapshot,
|
||||
"cwmp.debug",
|
||||
{
|
||||
remoteAddress: httpResponse.connection.remoteAddress
|
||||
});
|
||||
},
|
||||
Date.now(),
|
||||
e => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
|
||||
return httpResponse.connection.remoteAddress;
|
||||
return e;
|
||||
}
|
||||
);
|
||||
if (d)
|
||||
debug.outgoingHttpResponse(httpResponse, sessionContext.deviceId, _body);
|
||||
httpResponse.end(_body);
|
||||
@@ -1361,31 +1395,13 @@ async function listenerAsync(
|
||||
|
||||
const cacheSnapshot = await localCache.getCurrentSnapshot();
|
||||
|
||||
const configContext = {
|
||||
id: deviceId,
|
||||
serialNumber: rpc.cpeRequest.deviceId["SerialNumber"],
|
||||
productClass: rpc.cpeRequest.deviceId["ProductClass"],
|
||||
oui: rpc.cpeRequest.deviceId["OUI"],
|
||||
remoteAddress: httpRequest.connection.remoteAddress
|
||||
};
|
||||
|
||||
const sessionTimeout =
|
||||
rpc.sessionTimeout ||
|
||||
localCache.getConfig(cacheSnapshot, "cwmp.sessionTimeout", configContext);
|
||||
|
||||
const _sessionContext = session.init(
|
||||
deviceId,
|
||||
rpc.cwmpVersion,
|
||||
sessionTimeout
|
||||
rpc.sessionTimeout
|
||||
);
|
||||
|
||||
_sessionContext.cacheSnapshot = cacheSnapshot;
|
||||
_sessionContext.configContext = configContext;
|
||||
_sessionContext.debug = !!localCache.getConfig(
|
||||
cacheSnapshot,
|
||||
"cwmp.debug",
|
||||
configContext
|
||||
);
|
||||
|
||||
_sessionContext.httpRequest = httpRequest;
|
||||
_sessionContext.httpResponse = httpResponse;
|
||||
@@ -1434,6 +1450,24 @@ async function listenerAsync(
|
||||
_sessionContext.new = true;
|
||||
}
|
||||
|
||||
if (!_sessionContext.timeout) {
|
||||
_sessionContext.timeout = +localCache.getConfig(
|
||||
cacheSnapshot,
|
||||
"cwmp.sessionTimeout",
|
||||
{},
|
||||
_sessionContext.timestamp,
|
||||
e => session.configContextCallback(_sessionContext, e)
|
||||
);
|
||||
}
|
||||
|
||||
_sessionContext.debug = !!localCache.getConfig(
|
||||
cacheSnapshot,
|
||||
"cwmp.debug",
|
||||
{},
|
||||
_sessionContext.timestamp,
|
||||
e => session.configContextCallback(_sessionContext, e)
|
||||
);
|
||||
|
||||
const authenticated = await authenticate(_sessionContext, bodyStr);
|
||||
if (!authenticated) return responseUnauthorized(_sessionContext);
|
||||
|
||||
|
||||
+19
-8
@@ -461,10 +461,11 @@ export function getFiles(
|
||||
}
|
||||
|
||||
export function getConfig(
|
||||
snapshotKey,
|
||||
key,
|
||||
context?,
|
||||
now?
|
||||
snapshotKey: string,
|
||||
key: string,
|
||||
context: {},
|
||||
now: number,
|
||||
cb?: (Expression) => Expression
|
||||
): string | number | boolean | null {
|
||||
const snapshot = snapshots.get(snapshotKey);
|
||||
if (!snapshot) throw new Error("Cache snapshot does not exist");
|
||||
@@ -488,11 +489,21 @@ export function getConfig(
|
||||
};
|
||||
|
||||
if (!(key in snapshot.config)) {
|
||||
if (key in oldOpts)
|
||||
return config.get(oldOpts[key], context ? context.id : null);
|
||||
else return null;
|
||||
if (key in oldOpts) {
|
||||
let id;
|
||||
if (context && context["id"]) {
|
||||
id = context["id"];
|
||||
} else if (cb) {
|
||||
id = cb(["PARAM", "DeviceID.ID"]);
|
||||
if (Array.isArray(id)) id = null;
|
||||
}
|
||||
return expression.evaluate(snapshot.config[key], context, now || Date.now());
|
||||
return config.get(oldOpts[key], id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const v = expression.evaluate(snapshot.config[key], context, now, cb);
|
||||
return Array.isArray(v) ? null : v;
|
||||
}
|
||||
|
||||
export function getConfigExpression(snapshotKey, key): Expression {
|
||||
|
||||
+57
-10
@@ -47,7 +47,8 @@ import {
|
||||
InformRequest,
|
||||
TransferCompleteRequest,
|
||||
Operation,
|
||||
ScriptResult
|
||||
ScriptResult,
|
||||
Expression
|
||||
} from "./types";
|
||||
|
||||
const VALID_PARAM_TYPES = new Set([
|
||||
@@ -105,6 +106,34 @@ function generateRpcId(sessionContext: SessionContext): string {
|
||||
);
|
||||
}
|
||||
|
||||
export function configContextCallback(
|
||||
sessionContext: SessionContext,
|
||||
exp: Expression
|
||||
): Expression {
|
||||
if (!Array.isArray(exp)) return exp;
|
||||
if (exp[0] === "PARAM") {
|
||||
let name = exp[1];
|
||||
if (name === "id") name = "DeviceID.ID";
|
||||
else if (name === "serialNumber") name = "DeviceID.SerialNumber";
|
||||
else if (name === "productClass") name = "DeviceID.ProductClass";
|
||||
else if (name === "oui") name = "DeviceID.OUI";
|
||||
else if (name === "remoteAddress")
|
||||
return sessionContext.httpRequest.connection.remoteAddress;
|
||||
|
||||
const deviceData = sessionContext.deviceData;
|
||||
const paths = deviceData.paths;
|
||||
const path = paths.get(Path.parse(name));
|
||||
if (path) {
|
||||
const attrs = deviceData.attributes.get(path, 1);
|
||||
if (attrs && attrs.value && attrs.value[1]) return attrs.value[1][0];
|
||||
}
|
||||
} else if (exp[0] === "FUNC") {
|
||||
if (exp[1] === "REMOTE_ADDRESS")
|
||||
return sessionContext.httpRequest.connection.remoteAddress;
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
export async function inform(
|
||||
sessionContext: SessionContext,
|
||||
rpcReq: InformRequest
|
||||
@@ -413,7 +442,9 @@ export async function timeoutOperations(
|
||||
+localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.downloadTimeout",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => configContextCallback(sessionContext, e)
|
||||
) * 1000;
|
||||
|
||||
if (sessionContext.timestamp > operation.timestamp + DOWNLOAD_TIMEOUT) {
|
||||
@@ -448,7 +479,9 @@ export function addProvisions(
|
||||
+localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.maxCommitIterations",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => configContextCallback(sessionContext, e)
|
||||
) * 2;
|
||||
|
||||
delete sessionContext.syncState;
|
||||
@@ -501,7 +534,9 @@ export function clearProvisions(sessionContext: SessionContext): void {
|
||||
+localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.maxCommitIterations",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => configContextCallback(sessionContext, e)
|
||||
) * 2;
|
||||
|
||||
if (sessionContext.revisions[sessionContext.revisions.length - 1] > 0) {
|
||||
@@ -1080,7 +1115,9 @@ export async function rpcRequest(
|
||||
+localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.maxCommitIterations",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => configContextCallback(sessionContext, e)
|
||||
) * 2;
|
||||
|
||||
if (sessionContext.iteration >= MAX_ITERATIONS * (sessionContext.cycle + 1)) {
|
||||
@@ -1523,7 +1560,9 @@ function generateGetRpcRequest(sessionContext: SessionContext): GetAcsRequest {
|
||||
const GPN_NEXT_LEVEL = localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.gpnNextLevel",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => configContextCallback(sessionContext, e)
|
||||
);
|
||||
|
||||
const paths = Array.from(syncState.gpn.keys()).sort(
|
||||
@@ -1582,7 +1621,9 @@ function generateGetRpcRequest(sessionContext: SessionContext): GetAcsRequest {
|
||||
const GPV_BATCH_SIZE = localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.gpvBatchSize",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => configContextCallback(sessionContext, e)
|
||||
);
|
||||
|
||||
const parameterNames: string[] = [];
|
||||
@@ -1643,19 +1684,25 @@ function generateSetRpcRequest(sessionContext: SessionContext): SetAcsRequest {
|
||||
const GPV_BATCH_SIZE = localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.gpvBatchSize",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => configContextCallback(sessionContext, e)
|
||||
);
|
||||
|
||||
const DATETIME_MILLISECONDS = !!localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.datetimeMilliseconds",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => configContextCallback(sessionContext, e)
|
||||
);
|
||||
|
||||
const BOOLEAN_LITERAL = !!localCache.getConfig(
|
||||
sessionContext.cacheSnapshot,
|
||||
"cwmp.booleanLiteral",
|
||||
sessionContext.configContext
|
||||
{},
|
||||
sessionContext.timestamp,
|
||||
e => configContextCallback(sessionContext, e)
|
||||
);
|
||||
|
||||
const parameterValues: [Path, string | number | boolean, string][] = [];
|
||||
|
||||
@@ -131,7 +131,6 @@ export interface SessionContext {
|
||||
faults?: { [channel: string]: SessionFault };
|
||||
retries?: { [channel: string]: number };
|
||||
cacheSnapshot?: string;
|
||||
configContext?: { [name: string]: any };
|
||||
httpResponse?: ServerResponse;
|
||||
httpRequest?: IncomingMessage;
|
||||
faultsTouched?: { [channel: string]: boolean };
|
||||
|
||||
@@ -88,7 +88,8 @@ export async function deleteResource(resource, id): Promise<void> {
|
||||
export async function postTasks(
|
||||
deviceId,
|
||||
tasks,
|
||||
timeout
|
||||
timeout,
|
||||
device
|
||||
): Promise<{ connectionRequest: string; tasks: any[] }> {
|
||||
for (const task of tasks) {
|
||||
delete task._id;
|
||||
@@ -103,7 +104,7 @@ export async function postTasks(
|
||||
await del(`${deviceId}_tasks_faults_operations`);
|
||||
|
||||
try {
|
||||
await connectionRequest(deviceId);
|
||||
await connectionRequest(deviceId, device);
|
||||
} catch (err) {
|
||||
return {
|
||||
connectionRequest: err.message,
|
||||
|
||||
+24
-4
@@ -30,6 +30,7 @@ import { generateSalt, hashPassword } from "../auth";
|
||||
import { del } from "../cache";
|
||||
import Authorizer from "../common/authorizer";
|
||||
import { ping } from "../ping";
|
||||
import * as url from "url";
|
||||
|
||||
const router = new Router();
|
||||
export default router;
|
||||
@@ -481,8 +482,9 @@ router.post("/devices/:id/tasks", async (ctx, next) => {
|
||||
}
|
||||
const devices = await db.query("devices", filter);
|
||||
if (!devices.length) return void next();
|
||||
const device = devices[0];
|
||||
|
||||
const validate = authorizer.getValidator("devices", devices[0]);
|
||||
const validate = authorizer.getValidator("devices", device);
|
||||
for (const t of ctx.request.body) {
|
||||
if (!validate("task", t)) {
|
||||
logUnauthorizedWarning(log);
|
||||
@@ -490,16 +492,34 @@ router.post("/devices/:id/tasks", async (ctx, next) => {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Pass context and timestamp
|
||||
const onlineThreshold = getConfig(
|
||||
ctx.state.configSnapshot,
|
||||
"cwmp.deviceOnlineThreshold"
|
||||
"cwmp.deviceOnlineThreshold",
|
||||
{},
|
||||
Date.now(),
|
||||
exp => {
|
||||
if (!Array.isArray(exp)) return exp;
|
||||
if (exp[0] === "PARAM") {
|
||||
const p = device[exp[1]];
|
||||
if (p && p.value) return p.value[0];
|
||||
} else if (exp[0] === "FUNC") {
|
||||
if (exp[1] === "REMOTE_ADDRESS") {
|
||||
for (const root of ["InternetGatewayDevice", "Device"]) {
|
||||
const p = device[`${root}.ManagementServer.ConnectionRequestURL`];
|
||||
if (p && p.value) return url.parse(p.value[0]).host;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
);
|
||||
|
||||
const res = await apiFunctions.postTasks(
|
||||
ctx.params.id,
|
||||
ctx.request.body,
|
||||
onlineThreshold
|
||||
onlineThreshold,
|
||||
device
|
||||
);
|
||||
|
||||
log.tasks = res.tasks.map(t => t._id).join(",");
|
||||
|
||||
Reference in new issue
Block a user