Initial implementation for Get/SetParameterAttributes

This commit is contained in:
Zaid Abdulla committed 2019-11-06 10:37:18 -08:00
1 parent 765f0be7bc
commit 601690e3b5
5 files changed
+389 -26

No files matched your search

+173 -18
View File
@@ -729,9 +729,12 @@ function runDeclarations(
exist: new Set(),
object: new Set(),
writable: new Set(),
value: new Set()
value: new Set(),
notification: new Set(),
accessList: new Set()
},
spv: new Map(),
spa: new Map(),
gpn: new Set<Path>(),
gpnPatterns: new Map(),
tags: new Map(),
@@ -1463,6 +1466,8 @@ function generateGetRpcRequest(sessionContext: SessionContext): GetAcsRequest {
syncState.refreshAttributes.value.has(p) ||
syncState.refreshAttributes.object.has(p) ||
syncState.refreshAttributes.writable.has(p) ||
syncState.refreshAttributes.notification.has(p) ||
syncState.refreshAttributes.accessList.has(p) ||
syncState.gpn.has(p)
) {
found = true;
@@ -1491,7 +1496,9 @@ function generateGetRpcRequest(sessionContext: SessionContext): GetAcsRequest {
syncState.refreshAttributes.value.has(p) ||
(p.length > path.length &&
(syncState.refreshAttributes.object.has(p) ||
syncState.refreshAttributes.writable.has(p)))
syncState.refreshAttributes.writable.has(p) ||
syncState.refreshAttributes.notification.has(p) ||
syncState.refreshAttributes.accessList.has(p)))
) {
found = true;
break;
@@ -1599,9 +1606,57 @@ function generateGetRpcRequest(sessionContext: SessionContext): GetAcsRequest {
};
}
}
if (
syncState.refreshAttributes.notification.size ||
syncState.refreshAttributes.accessList.size
) {
const GPV_BATCH_SIZE = localCache.getConfig(
sessionContext.cacheSnapshot,
"cwmp.gpvBatchSize",
sessionContext.configContext
);
const parameterNames: string[] = [];
for (const path of syncState.refreshAttributes.notification) {
syncState.refreshAttributes.notification.delete(path);
syncState.refreshAttributes.accessList.delete(path);
// Need to check in case param is deleted
const attrs = sessionContext.deviceData.attributes.get(path);
if (attrs) {
parameterNames.push(path.toString());
if (parameterNames.length >= GPV_BATCH_SIZE) break;
}
}
if (parameterNames.length < GPV_BATCH_SIZE) {
for (const path of syncState.refreshAttributes.accessList) {
syncState.refreshAttributes.accessList.delete(path);
const attrs = sessionContext.deviceData.attributes.get(path);
if (attrs) {
parameterNames.push(path.toString());
if (parameterNames.length >= GPV_BATCH_SIZE) break;
}
}
}
if (parameterNames.length) {
return {
name: "GetParameterAttributes",
parameterNames: parameterNames
};
}
}
return null;
}
function compareAccessLists(list1: string[], list2: string[]): boolean {
if (list1.length !== list2.length) return false;
for (const [i, v] of list1.entries()) if (v !== list2[i]) return false;
return true;
}
function generateSetRpcRequest(sessionContext: SessionContext): SetAcsRequest {
const syncState = sessionContext.syncState;
if (!syncState) return null;
@@ -1654,7 +1709,7 @@ function generateSetRpcRequest(sessionContext: SessionContext): SetAcsRequest {
sessionContext.configContext
);
const parameterValues: [Path, string | number | boolean, string][] = [];
const parameterValues: [string, string | number | boolean, string][] = [];
for (const [k, v] of syncState.spv) {
syncState.spv.delete(k);
const attrs = sessionContext.deviceData.attributes.get(k);
@@ -1673,7 +1728,7 @@ function generateSetRpcRequest(sessionContext: SessionContext): SetAcsRequest {
val[0] -= val[0] % 1000;
if (val[0] !== curVal[0] || val[1] !== curVal[1])
parameterValues.push([k, val[0], val[1]]);
parameterValues.push([k.toString(), val[0], val[1]]);
if (parameterValues.length >= GPV_BATCH_SIZE) break;
}
@@ -1682,19 +1737,44 @@ function generateSetRpcRequest(sessionContext: SessionContext): SetAcsRequest {
if (parameterValues.length) {
return {
name: "SetParameterValues",
parameterList: parameterValues.map(
p =>
[p[0].toString(), p[1], p[2]] as [
string,
string | number | boolean,
string
]
),
parameterList: parameterValues,
DATETIME_MILLISECONDS: DATETIME_MILLISECONDS,
BOOLEAN_LITERAL: BOOLEAN_LITERAL
};
}
// Set attributes
const parameterAttributes: [string, number, string[]][] = [];
for (const [k, v] of syncState.spa) {
syncState.spa.delete(k);
const attrs = sessionContext.deviceData.attributes.get(k);
if (
v.notification != null &&
(!attrs.notification || v.notification === attrs.notification[1])
)
v.notification = null;
if (
v.accessList != null &&
(!attrs.accessList ||
compareAccessLists(v.accessList, attrs.accessList[1]))
)
v.accessList = null;
if (v.notification != null || v.accessList != null)
parameterAttributes.push([k.toString(), v.notification, v.accessList]);
if (parameterAttributes.length >= GPV_BATCH_SIZE) break;
}
if (parameterAttributes.length) {
return {
name: "SetParameterAttributes",
parameterList: parameterAttributes
};
}
// Downloads
for (const [p, t] of syncState.downloadsDownload) {
const attrs = deviceData.attributes.get(p);
@@ -2109,8 +2189,34 @@ function processDeclarations(
}
}
}
if (declareAttributeValues && declareAttributeValues.value != null)
syncState.spv.set(currentPath, declareAttributeValues.value);
if (declareAttributeValues) {
if (declareAttributeValues.value != null)
syncState.spv.set(currentPath, declareAttributeValues.value);
if (declareAttributeValues.notification != null) {
const spa = syncState.spa.get(currentPath);
if (spa) {
spa.notification = declareAttributeValues.notification;
} else {
syncState.spa.set(currentPath, {
notification: declareAttributeValues.notification,
accessList: null
});
}
}
if (declareAttributeValues.accessList != null) {
const spa = syncState.spa.get(currentPath);
if (spa) {
spa.accessList = declareAttributeValues.accessList;
} else {
syncState.spa.set(currentPath, {
notification: null,
accessList: declareAttributeValues.accessList
});
}
}
}
}
}
@@ -2243,7 +2349,7 @@ export async function rpcResponse(
if (p[1] !== rpcReq.instanceValues[p[0]]) {
const v = device.sanitizeParameterValue([
rpcReq.instanceValues[p[0]],
p[2]
p[2] as string
]);
parameterList.push([p[0], v[0], v[1]]);
}
@@ -2288,6 +2394,21 @@ export async function rpcResponse(
);
}
break;
case "GetParameterAttributesResponse":
if (rpcReq.name !== "GetParameterAttributes")
throw new Error("Response name does not match request name");
for (const p of rpcRes.parameterList) {
toClear = device.set(
sessionContext.deviceData,
Path.parse(p[0]),
timestamp,
{ notification: [timestamp, p[1]], accessList: [timestamp, p[2]] },
toClear
);
}
break;
case "GetParameterNamesResponse":
if (rpcReq.name !== "GetParameterNames")
@@ -2404,6 +2525,38 @@ export async function rpcResponse(
);
}
break;
case "SetParameterAttributesResponse":
if (rpcReq.name !== "SetParameterAttributes")
throw new Error("Response name does not match request name");
for (const p of rpcReq.parameterList) {
let attrs;
if (p[1] != null && p[2] != null) {
attrs = {
notification: [timestamp + 1, p[1]],
accessList: [timestamp + 1, p[2]]
};
} else if (p[1] != null) {
attrs = {
notification: [timestamp + 1, p[1]]
};
} else if (p[2] != null) {
attrs = {
accessList: [timestamp + 1, p[2]]
};
}
toClear = device.set(
sessionContext.deviceData,
Path.parse(p[0]),
timestamp + 1,
attrs,
toClear
);
}
break;
case "AddObjectResponse":
toClear = device.set(
@@ -2566,9 +2719,11 @@ export async function rpcFault(
p => [Path.parse(p.replace(/\.$/, "")), timestamp] as Clear
);
} else if (rpcReq.name === "SetParameterValues") {
toClear = rpcReq.parameterList.map(
p => [Path.parse(p[0].replace(/\.$/, "")), timestamp] as Clear
);
toClear = (rpcReq.parameterList as [
string,
string | number | boolean,
string
][]).map(p => [Path.parse(p[0].replace(/\.$/, "")), timestamp] as Clear);
} else if (rpcReq.name === "AddObject") {
toClear = [[Path.parse(rpcReq.objectName.replace(/\.$/, "")), timestamp]];
} else if (rpcReq.name === "DeleteObject") {