Skip to content

Commit

Permalink
better detect <1.03 nodesets
Browse files Browse the repository at this point in the history
  • Loading branch information
erossignon committed Jul 14, 2023
1 parent 4c82abc commit 2e9e962
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 9 deletions.
@@ -1,19 +1,58 @@
import { findLastKey } from "lodash";
import { AttributeIds, BrowseDirection, NodeClassMask } from "node-opcua-data-model";
import { coerceNodeId, resolveNodeId } from "node-opcua-nodeid";
import { AttributeIds, BrowseDirection, NodeClassMask, ResultMask } from "node-opcua-data-model";
import { resolveNodeId } from "node-opcua-nodeid";
import { IBasicSession, browseAll } from "node-opcua-pseudo-session";
import { DataTypeIds } from "node-opcua-constants";

import { StatusCodes } from "node-opcua-status-code";
import { DataTypeIds, ObjectIds, ObjectTypeIds, VariableTypeIds } from "node-opcua-constants";
import { DataType } from "node-opcua-variant";
import { ReferenceDescription } from "node-opcua-types";
import { makeBrowsePath } from "node-opcua-service-translate-browse-path";
//
import { ExtraDataTypeManager } from "./extra_data_type_manager";
import { populateDataTypeManager103 } from "./private/populate_data_type_manager_103";
import { populateDataTypeManager104 } from "./private/populate_data_type_manager_104";

async function serverImplementsDataTypeDefinition(session: IBasicSession): Promise<boolean> {
// check if server provides DataTypeDefinition => in this case this is the prefered route,
/**
* @private
*/
export async function serverImplementsDataTypeDefinition(session: IBasicSession): Promise<boolean> {
// One way to figure out is to check if the server provides DataTypeDefinition node
// ( see OPCUA 1.04 part 6 -)
// This is the preferred route, as we go along, more and more servers will implement this.
const browseResult1 = await browseAll(session, {
browseDirection: BrowseDirection.Forward,
includeSubtypes: true,
nodeClassMask: NodeClassMask.Variable,
nodeId: resolveNodeId(ObjectIds.OPCBinarySchema_TypeSystem),
resultMask: ResultMask.TypeDefinition
});

let count103DataType = 0;
for (const ref of browseResult1.references || []) {
const td = ref.typeDefinition;
if (!(td.namespace === 0 && td.value === VariableTypeIds.DataTypeDictionaryType)) continue;
// we have a type definition,
// let check if there is a deprecated property
const p = await session.translateBrowsePath(makeBrowsePath(ref.nodeId, "/Deprecated"));
if (!p.statusCode.isGood() || !p.targets || p.targets.length === 0) {
// the dataTypeDictionaryType is not exposing a Deprecated property
count103DataType++;
continue;
}
const deprecatedNodeId = p.targets[0].targetId;
// we have a deprecated property => this is a 1.03 server or 1.04
// => we need to check if the server provides DataTypeDefinition
const dataValue = await session.read({ nodeId: deprecatedNodeId, attributeId: AttributeIds.Value });
if (dataValue.statusCode.isGood() && dataValue.value.value === false) {
// this is a 1.03 server
count103DataType++;
continue;
}
}
if (count103DataType >= 1) {
// some namespace are old , we cannot assume that all namespace are 1.04
return false;
}

// check if server provides DataTypeDefinition => in this case this is the preferred route,
// as we go along, more and more servers will implement this.
const browseResult = await browseAll(session, {
browseDirection: BrowseDirection.Forward,
Expand Down
2 changes: 1 addition & 1 deletion packages/node-opcua-modeler/test/test_issue_889.ts
Expand Up @@ -143,7 +143,7 @@ describe("loading very large DataType Definitions ", function (this: any) {

// since 1.04 (september 2021) 1.04 datatype is in force
browseSpy.callCount.should.be.greaterThanOrEqual(1);
browseSpy.callCount.should.be.lessThanOrEqual(2421);
browseSpy.callCount.should.be.lessThanOrEqual(2422 );
browseNextSpy.callCount.should.eql(87);

interface DataTypeFactoryPriv {
Expand Down

0 comments on commit 2e9e962

Please sign in to comment.