Skip to content

Commit

Permalink
implement basic read operation on server_engine
Browse files Browse the repository at this point in the history
  • Loading branch information
erossignon committed Feb 15, 2014
1 parent 467dd79 commit a4fbc65
Show file tree
Hide file tree
Showing 13 changed files with 275 additions and 56 deletions.
6 changes: 3 additions & 3 deletions lib/encode_decode.js
Expand Up @@ -177,6 +177,8 @@ exports.encodeDateTime = function(date, stream) {
assert(longValue>=0 && longValue <= MAX_INT64);
var lo = longValue % 0xFFFFFFFF;
var hi = Math.floor(longValue / 0xFFFFFFFF);

assert(longValue == hi * 0xFFFFFFFF + lo ," cross checking date " + date + " " + longValue + " " + (hi * 0xFFFFFFFF + lo) );
stream.writeUInt32(lo);
stream.writeUInt32(hi);
};
Expand Down Expand Up @@ -217,9 +219,7 @@ exports.encodeGUID = function (guid, stream) {

};

function toHex(i, nb) {
return ("000000000000000" + i.toString(16)).substr(-nb)
}
var toHex = require("./utils").toHex;

exports.decodeGUID = function (stream) {

Expand Down
7 changes: 4 additions & 3 deletions lib/factories.js
Expand Up @@ -387,6 +387,7 @@ function _install_initial_value(field,options) {

function ___install_single_initial_value(field,options) {

assert( (typeof(options) === "object") ," expection options for field " + util.inspect(field));
var value = null;

var typeDef = _defaultTypeMap[field.fieldType];
Expand All @@ -399,7 +400,7 @@ function ___install_single_initial_value(field,options) {
}

//xx console.log(options);
if (options && (field.name in options)) {
if ( field.name in options ) {
// the user has specified a value for this field
value = options[field.name ];
} else {
Expand Down Expand Up @@ -605,11 +606,11 @@ function BaseObject(schema,options) {
assert(this.__proto__._schema === schema);
assert(this._schema === schema);

options = options || {};

if (schema.construct_hook) {
schema.construct_hook.call(this);
options = schema.construct_hook.call(this,options);
}
options = options || {};

var data = {
options: options,
Expand Down
12 changes: 3 additions & 9 deletions lib/nodeid.js
@@ -1,7 +1,7 @@
var util = require("util");
var Enum = require("enum");
var assert = require("assert");

var toHex = require("./utils").toHex;
var is_guid = require("./guid").is_guid;

var NodeIdType = new Enum({
Expand All @@ -26,19 +26,13 @@ NodeId.prototype.toString = function() {
switch(this.identifierType) {
case NodeIdType.NUMERIC:
return "ns="+ this.namespace +";i="+this.value;
break;
case NodeIdType.STRING:
return "ns="+ this.namespace +";s="+this.value+"";
break;
case NodeIdType.GUID:
return "ns="+ this.namespace +";g="+this.value+"";
break;
case NodeIdType.BYTESTRING:
return "ns="+ this.namespace +";b="+toHex(this.value)+"";
break;
default:
assert(false,"invalid identifierType in NodeId : " + this.identifierType);
//xx return JSON.stringify(this).replace(re,"");
assert(this.identifierType == NodeIdType.BYTESTRING,"invalid identifierType in NodeId : " + this.identifierType);
return "ns="+ this.namespace +";b="+this.value.toString("hex")+"";
}
};

Expand Down
6 changes: 4 additions & 2 deletions lib/opcua-server.js
Expand Up @@ -227,10 +227,12 @@ OPCUAServerEndPoint.prototype._on_Browse = function(browseRequest,channel) {
assert(browseRequest._schema.name == "BrowseRequest");
assert(browseRequest.nodesToBrowse[0]._schema.name == "BrowseDescription");

var browseResult = engine.browse(browseRequest.nodesToBrowse);
var results = engine.browse(browseRequest.nodesToBrowse);
assert(results[0]._schema.name =="BrowseResult");

var response = new browse_service.BrowseResponse({
results: browseResult
results: results,
diagnosticInfos: null
});
channel.send_response("MSG", response);
};
Expand Down
2 changes: 1 addition & 1 deletion lib/read_service.js
Expand Up @@ -53,7 +53,7 @@ var AttributeIds = {
Executable:21,
UserExecutable:22
};

exports.AttributeIds = AttributeIds;

var ReadValueId_Schema = {
name: "ReadValueId",
Expand Down
83 changes: 80 additions & 3 deletions lib/server/server_engine.js
Expand Up @@ -7,6 +7,8 @@ var makeNodeId = require("../../lib/nodeid").makeNodeId;
var assert = require("assert");
var s = require("../../lib/structures");
var browse_service = require("../../lib/browse_service");
var read_service = require("../../lib/read_service");

var BrowseDirection = browse_service.BrowseDirection;
var util = require("util");

Expand Down Expand Up @@ -241,7 +243,8 @@ ServerEngine.prototype.addVariableInFolder = function (parentFolder, options) {


function makeStatusCode(statusCode, severity) {
return 0x80000000 + statusCode;
assert(isFinite(statusCode.value), "invalid status code provided " + util.inspect(statusCode));
return statusCode.value + 0x800000;
}
var StatusCodes = require("../../lib/opcua_status_code").StatusCodes;

Expand Down Expand Up @@ -278,10 +281,10 @@ ServerEngine.prototype._makeReferenceDescription = function(reference, isForward

ServerEngine.prototype.browseSingleNode = function (nodeId,browseDirection) {

// coerce nodeToBrowse to NodeId
nodeId = resolveNodeId(nodeId);
browseDirection = browseDirection || BrowseDirection.Both;

// coerce nodeToBrowse to NodeId
nodeId = resolveNodeId(nodeId);
assert(nodeId instanceof NodeId);
var obj = this.findObject(nodeId);

Expand Down Expand Up @@ -320,9 +323,83 @@ ServerEngine.prototype.browse = function (nodesToBrowse) {
var r = self.browseSingleNode(nodeId,browseDirection);
results.push(r);
});
//xx return new browse_service.BrowseResponse({
//xx results: results
//xx});
return results;
};

var DataValue = require("../datavalue").DataValue;
var Variant = require("../variant").Variant;
var DataType =require("../variant").DataType;
var AttributeIds = read_service.AttributeIds;
ServerEngine.prototype.readSingleNode = function (nodeId,attributeId) {

// coerce nodeToBrowse to NodeId
nodeId = resolveNodeId(nodeId);
assert(nodeId instanceof NodeId);
var obj = this.findObject(nodeId);
if (!obj) {
// Object Not Found
return null;

} else {
var options = {}
switch(attributeId) {
case AttributeIds.NodeId:
options.value = { dataType: DataType.NodeId, value: obj.nodeId }
break;
case AttributeIds.NodeClass:
assert(isFinite(obj.nodeClass));
options.value = { dataType: DataType.UInt32, value: obj.nodeClass }
break;
case AttributeIds.BrowseName:
// QualifiedName
options.value = { dataType: DataType.QualifiedName, value:
{ name: obj.browseName , namespaceIndex: 0 }
}
break;
case AttributeIds.DisplayName:
options.value = { dataType: DataType.LocalizedText, value: obj.displayName[0] }
break;
case AttributeIds.Value:
if (obj.hasOwnProperty("value")) {
assert(obj.value._schema.name == "Variant");
options.value = obj.value;
} else {

}
break;
default:
throw new Error(" Not implemented yet");
break;

}
return new DataValue(options);

}



};

ServerEngine.prototype.read = function (nodesToRead) {

var results = [];
var self = this;
nodesToRead.forEach(function(readValueId){
var nodeId = readValueId.nodeId;
var attributeId = readValueId.attributeId;
var indexRange = readValueId.indexRange;
var dataEncoding = readValueId.dataEncoding;
var r = self.readSingleNode(nodeId,attributeId);
results.push(r);
});
};




exports.ServerEngine = ServerEngine;
exports.Variable = Variable;
exports.Folder = Folder;
Expand Down
7 changes: 2 additions & 5 deletions lib/transport/tcp_transport.js
Expand Up @@ -31,15 +31,12 @@ function createClientSocket(endpoint_url) {
switch(ep.protocol) {
case "opc.tcp":
return net.connect({ host: hostname,port: port});
break;
case "fake":
default:
assert(ep.protocol=="fake"," Unsupported transport protocol");
process.nextTick(function(){
fakeSocket.emit("connect");
});
return fakeSocket;
break;
default:
throw new Error(" Unsupported transport protocol");
}
}

Expand Down
18 changes: 5 additions & 13 deletions lib/utils.js
Expand Up @@ -35,15 +35,6 @@ function getObjectClassName(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}

/**
* invoke a constructor without new
* @param constructor
* @returns {factory}
*/
function create(constructor) {
var factory = constructor.bind.apply(constructor, arguments);
return new factory();
}


function buffer_ellipsis(buffer,start,end) {
Expand All @@ -62,6 +53,9 @@ function chunk_ellipsis(messageChunk,bodyOffset){
buffer_ellipsis(messageChunk,bodyOffset,messageChunk.length).cyan;
}

function toHex(i, nb) {
return ("000000000000000" + i.toString(16)).substr(-nb)
}
function hexDump(buffer,width) {
if (!buffer) { return "<>" ;}
width = width || 32;
Expand Down Expand Up @@ -124,9 +118,7 @@ function redirectToFile(tmpfile,action_func,callback)

var msg = util.format.apply(null,arguments);
f.write(msg+ '\n');
if (process.env.DEBUG) {
old_console_log.call(this,msg);
}
if (process.env.DEBUG) { old_console_log.call(this,msg); }
};
// async version
action_func();
Expand Down Expand Up @@ -167,7 +159,6 @@ function display_trace_from_this_projet_only() {
}

exports.getObjectClassName = getObjectClassName;
exports.create = create;
exports.buffer_ellipsis = buffer_ellipsis;
exports.chunk_ellipsis = chunk_ellipsis;
exports.compare_buffers = compare_buffers;
Expand All @@ -176,5 +167,6 @@ exports.redirectToFile = redirectToFile;
exports.makebuffer = makeBuffer;
exports.replaceBufferWithHexDump = replaceBufferWithHexDump;
exports.hexDump = hexDump;
exports.toHex = toHex;
exports.display_trace_from_this_projet_only = display_trace_from_this_projet_only;

43 changes: 42 additions & 1 deletion lib/variant.js
Expand Up @@ -124,6 +124,34 @@ var Variant_ArrayDimensionsMask = 0x40;
var Variant_TypeMask = 0x3F;



function coerceVariantType(dataType, value)
{
switch(dataType) {
case DataType.Null:
value = null;
break;
case DataType.LocalizedText:
if (value._schema != s.LocalizedText.prototype._schema) {
value = new s.LocalizedText(value);
}
break;
case DataType.QualifiedName:
if (value._schema != s.QualifiedName.prototype._schema) {
value = new s.QualifiedName(value);
}
break;
case DataType.UInt32:
value = parseInt(value);
break;

default:
break;
}
return value;
}


var Variant_Schema = {
name: "Variant",
id: factories.next_available_id(),
Expand Down Expand Up @@ -174,8 +202,21 @@ var Variant_Schema = {
self.arrayType =VariantArrayType.Scalar ;
self.value = decoder(stream);
}
}
},

construct_hook: function( options) {
if (!options) return null;

if ( options.arrayType && options.arrayType != VariantArrayType.Scalar) {
if (options.arrayType == VariantArrayType.Array) {
options.value = options.value.map(function(e) { return coerceVariantType(options.dataType,e); });
} else { throw new Error("Not implemented Yet"); }
} else {
// scalar
options.value = coerceVariantType(options.dataType,options.value);
}
return options;
}
};


Expand Down

0 comments on commit a4fbc65

Please sign in to comment.