opcua 0.12 → 0.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +71 -4
- data/cert/cert.h +52 -52
- data/cert/cert_key.h +101 -101
- data/example/array/Makefile +3 -0
- data/example/array/clienttest.c +168 -0
- data/example/array/open62541.h +27464 -0
- data/example/array/servertest.c +142 -0
- data/example/bug5.rb +22 -0
- data/example/client_method.rb +7 -3
- data/example/server.rb +3 -3
- data/ext/opcua/client/client.c +38 -13
- data/ext/opcua/client/client.h +2 -1
- data/ext/opcua/client/finders.c +1 -0
- data/ext/opcua/client/finders.h +1 -0
- data/ext/opcua/client/log_none.c +1 -0
- data/ext/opcua/client/log_none.h +1 -0
- data/ext/opcua/client/strnautocat.c +1 -0
- data/ext/opcua/client/strnautocat.h +1 -0
- data/ext/opcua/client/values.c +1 -0
- data/ext/opcua/client/values.h +1 -0
- data/ext/opcua/helpers/finders.c +142 -0
- data/ext/opcua/helpers/finders.h +13 -0
- data/ext/opcua/{log_none.h → helpers/log_none.c} +2 -0
- data/ext/opcua/helpers/log_none.h +12 -0
- data/ext/opcua/{strnautocat.h → helpers/strnautocat.c} +2 -0
- data/ext/opcua/helpers/strnautocat.h +8 -0
- data/ext/opcua/{values.h → helpers/values.c} +64 -25
- data/ext/opcua/helpers/values.h +12 -0
- data/ext/opcua/server/finders.c +1 -0
- data/ext/opcua/server/finders.h +1 -0
- data/ext/opcua/server/log_none.c +1 -0
- data/ext/opcua/server/log_none.h +1 -0
- data/ext/opcua/server/server.c +70 -57
- data/ext/opcua/server/server.h +4 -2
- data/ext/opcua/server/strnautocat.c +1 -0
- data/ext/opcua/server/strnautocat.h +1 -0
- data/ext/opcua/server/values.c +1 -0
- data/ext/opcua/server/values.h +1 -0
- data/opcua.gemspec +1 -1
- metadata +32 -6
@@ -0,0 +1,13 @@
|
|
1
|
+
#ifndef __OPCUA_SMART_FINDERS_H__
|
2
|
+
#define __OPCUA_SMART_FINDERS_H__
|
3
|
+
|
4
|
+
#include <open62541.h>
|
5
|
+
#include <ruby.h>
|
6
|
+
|
7
|
+
RUBY_EXTERN UA_BrowsePathResult node_browse_path(UA_Server *server, UA_NodeId relative, UA_NodeId ref, UA_QualifiedName mqn, bool inverse);
|
8
|
+
RUBY_EXTERN bool server_node_get_reference(UA_Server *server, UA_NodeId parent, UA_NodeId *result, bool inverse);
|
9
|
+
RUBY_EXTERN bool client_node_get_reference_by_name(UA_Client *client, UA_NodeId parent, UA_QualifiedName name, UA_NodeId *result, bool inverse);
|
10
|
+
RUBY_EXTERN bool client_node_get_reference_by_type(UA_Client *client, UA_NodeId parent, UA_NodeId type, UA_NodeId *result, bool inverse);
|
11
|
+
RUBY_EXTERN bool client_node_list_references(UA_Client *client, UA_NodeId parent, bool inverse);
|
12
|
+
|
13
|
+
#endif
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#ifndef __OPCUA_SMART_LOG_NONE_H__
|
2
|
+
#define __OPCUA_SMART_LOG_NONE_H__
|
3
|
+
|
4
|
+
#include <open62541.h>
|
5
|
+
#include <ruby.h>
|
6
|
+
|
7
|
+
RUBY_EXTERN void UA_Log_None_log(void *_, UA_LogLevel level, UA_LogCategory category, const char *msg, va_list args);
|
8
|
+
RUBY_EXTERN void UA_Log_None_clear(void *logContext);
|
9
|
+
RUBY_EXTERN const UA_Logger UA_Log_None_;
|
10
|
+
RUBY_EXTERN const UA_Logger *UA_Log_None;
|
11
|
+
|
12
|
+
#endif
|
@@ -1,12 +1,13 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#include "values.h"
|
2
|
+
|
3
|
+
VALUE mOPCUA;
|
3
4
|
|
4
5
|
/* -- */
|
5
|
-
static void variant_set_one_dimension(UA_Variant *variant,UA_UInt32 len) {
|
6
|
+
static void variant_set_one_dimension(UA_Variant *variant,UA_UInt32 len) { //{{{
|
6
7
|
variant->arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]);
|
7
8
|
variant->arrayDimensions[0] = len;
|
8
9
|
variant->arrayDimensionsSize = 1;
|
9
|
-
}
|
10
|
+
} //}}}
|
10
11
|
static bool value_to_array(VALUE value, UA_Variant *variant) {/*{{{*/
|
11
12
|
int done = false;
|
12
13
|
|
@@ -92,7 +93,8 @@ static bool value_to_array(VALUE value, UA_Variant *variant) {/*{{{*/
|
|
92
93
|
}
|
93
94
|
return done;
|
94
95
|
}/*}}}*/
|
95
|
-
|
96
|
+
|
97
|
+
bool value_to_variant(VALUE value, UA_Variant *variant, UA_UInt32 proposal) { //{{{
|
96
98
|
bool done = false;
|
97
99
|
if (rb_obj_is_kind_of(value,rb_cTime)) {
|
98
100
|
UA_DateTime tmp = UA_DateTime_fromUnixTime(rb_time_timeval(value).tv_sec);
|
@@ -115,13 +117,39 @@ static bool value_to_variant(VALUE value, UA_Variant *variant) { //{{{
|
|
115
117
|
break;
|
116
118
|
}
|
117
119
|
case T_FLOAT:
|
118
|
-
case T_FIXNUM:
|
119
120
|
{
|
120
121
|
UA_Double tmp = NUM2DBL(value);
|
121
122
|
UA_Variant_setScalarCopy(variant, &tmp, &UA_TYPES[UA_TYPES_DOUBLE]);
|
122
123
|
done = true;
|
123
124
|
break;
|
124
125
|
}
|
126
|
+
case T_FIXNUM:
|
127
|
+
{
|
128
|
+
if (proposal == UA_TYPES_SBYTE) {
|
129
|
+
UA_SByte tmp = (UA_SByte)NUM2CHR(value);
|
130
|
+
UA_Variant_setScalarCopy(variant, &tmp, &UA_TYPES[UA_TYPES_SBYTE]);
|
131
|
+
} else if (proposal == UA_TYPES_BYTE) {
|
132
|
+
UA_SByte tmp = (UA_Byte)NUM2CHR(value);
|
133
|
+
UA_Variant_setScalarCopy(variant, &tmp, &UA_TYPES[UA_TYPES_BYTE]);
|
134
|
+
} else if (proposal == UA_TYPES_INT16) {
|
135
|
+
UA_Int16 tmp = NUM2INT(value);
|
136
|
+
UA_Variant_setScalarCopy(variant, &tmp, &UA_TYPES[UA_TYPES_INT16]);
|
137
|
+
} else if (proposal == UA_TYPES_UINT16) {
|
138
|
+
UA_UInt16 tmp = NUM2INT(value);
|
139
|
+
UA_Variant_setScalarCopy(variant, &tmp, &UA_TYPES[UA_TYPES_UINT16]);
|
140
|
+
} else if (proposal == UA_TYPES_INT32) {
|
141
|
+
UA_Int32 tmp = NUM2LONG(value);
|
142
|
+
UA_Variant_setScalarCopy(variant, &tmp, &UA_TYPES[UA_TYPES_INT32]);
|
143
|
+
} else if (proposal == UA_TYPES_UINT32) {
|
144
|
+
UA_UInt32 tmp = NUM2ULONG(value);
|
145
|
+
UA_Variant_setScalarCopy(variant, &tmp, &UA_TYPES[UA_TYPES_UINT32]);
|
146
|
+
} else {
|
147
|
+
UA_Int32 tmp = NUM2LONG(value);
|
148
|
+
UA_Variant_setScalarCopy(variant, &tmp, &UA_TYPES[UA_TYPES_INT32]);
|
149
|
+
}
|
150
|
+
done = true;
|
151
|
+
break;
|
152
|
+
}
|
125
153
|
case T_STRING:
|
126
154
|
case T_SYMBOL:
|
127
155
|
{
|
@@ -142,9 +170,8 @@ static bool value_to_variant(VALUE value, UA_Variant *variant) { //{{{
|
|
142
170
|
}
|
143
171
|
return done;
|
144
172
|
} //}}}
|
145
|
-
/* ++ */
|
146
173
|
|
147
|
-
|
174
|
+
void Init_types() {/*{{{*/
|
148
175
|
mTYPES = rb_define_module_under(mOPCUA,"TYPES");
|
149
176
|
rb_define_const(mTYPES, "DATETIME", INT2NUM(UA_TYPES_DATETIME ));
|
150
177
|
rb_define_const(mTYPES, "BOOLEAN", INT2NUM(UA_TYPES_BOOLEAN ));
|
@@ -156,32 +183,38 @@ static void Init_types() {/*{{{*/
|
|
156
183
|
rb_define_const(mTYPES, "STRING", INT2NUM(UA_TYPES_STRING ));
|
157
184
|
}/*}}}*/
|
158
185
|
|
159
|
-
static VALUE UA_TYPES_DATETIME_to_value(UA_DateTime data) {
|
186
|
+
static VALUE UA_TYPES_DATETIME_to_value(UA_DateTime data) { //{{{
|
160
187
|
return rb_time_new(UA_DateTime_toUnixTime(data),0);
|
161
|
-
}
|
162
|
-
static VALUE UA_TYPES_BOOLEAN_to_value(UA_Boolean data) {
|
188
|
+
} //}}}
|
189
|
+
static VALUE UA_TYPES_BOOLEAN_to_value(UA_Boolean data) { //{{{
|
163
190
|
return data ? Qtrue : Qfalse;
|
164
|
-
}
|
165
|
-
static VALUE UA_TYPES_DOUBLE_to_value(UA_Double data) {
|
191
|
+
} //}}}
|
192
|
+
static VALUE UA_TYPES_DOUBLE_to_value(UA_Double data) { //{{{
|
166
193
|
return DBL2NUM(data);
|
167
|
-
}
|
168
|
-
static VALUE
|
194
|
+
} //}}}
|
195
|
+
static VALUE UA_TYPES_SBYTE_to_value(UA_SByte data) { //{{{
|
196
|
+
return CHR2FIX((signed char)data);
|
197
|
+
} //}}}
|
198
|
+
static VALUE UA_TYPES_INT32_to_value(UA_Int32 data) { //{{{
|
169
199
|
return INT2NUM(data);
|
170
|
-
}
|
171
|
-
static VALUE UA_TYPES_INT16_to_value(UA_Int16 data) {
|
200
|
+
} //}}}
|
201
|
+
static VALUE UA_TYPES_INT16_to_value(UA_Int16 data) { //{{{
|
172
202
|
return INT2NUM(data);
|
173
|
-
}
|
174
|
-
static VALUE
|
203
|
+
} //}}}
|
204
|
+
static VALUE UA_TYPES_BYTE_to_value(UA_Byte data) { //{{{
|
205
|
+
return CHR2FIX((unsigned char)data);
|
206
|
+
} //}}}
|
207
|
+
static VALUE UA_TYPES_UINT32_to_value(UA_UInt32 data) { //{{{
|
175
208
|
return UINT2NUM(data);
|
176
|
-
}
|
177
|
-
static VALUE UA_TYPES_UINT16_to_value(UA_UInt16 data) {
|
209
|
+
} //}}}
|
210
|
+
static VALUE UA_TYPES_UINT16_to_value(UA_UInt16 data) { //{{{
|
178
211
|
return UINT2NUM(data);
|
179
|
-
}
|
180
|
-
static VALUE UA_TYPES_STRING_to_value(UA_String data) {
|
212
|
+
} //}}}
|
213
|
+
static VALUE UA_TYPES_STRING_to_value(UA_String data) { //{{{
|
181
214
|
return rb_str_export_locale(rb_str_new((char *)(data.data),data.length));
|
182
|
-
}
|
215
|
+
} //}}}
|
183
216
|
|
184
|
-
|
217
|
+
VALUE extract_value(UA_Variant value) { //{{{
|
185
218
|
VALUE ret = rb_ary_new2(2);
|
186
219
|
rb_ary_store(ret,0,Qnil);
|
187
220
|
rb_ary_store(ret,1,Qnil);
|
@@ -210,6 +243,12 @@ static VALUE extract_value(UA_Variant value) { //{{{
|
|
210
243
|
} else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_UINT16])) {
|
211
244
|
rb_ary_store(ret,0,UA_TYPES_UINT16_to_value(*(UA_UInt16 *)value.data));
|
212
245
|
rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.UInt16")));
|
246
|
+
} else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_SBYTE])) {
|
247
|
+
rb_ary_store(ret,0,UA_TYPES_SBYTE_to_value(*(UA_SByte *)value.data));
|
248
|
+
rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.SByte")));
|
249
|
+
} else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_BYTE])) {
|
250
|
+
rb_ary_store(ret,0,UA_TYPES_BYTE_to_value(*(UA_Byte *)value.data));
|
251
|
+
rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Byte")));
|
213
252
|
} else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_STRING])) {
|
214
253
|
rb_ary_store(ret,0,UA_TYPES_STRING_to_value(*(UA_String *)value.data));
|
215
254
|
rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.String")));
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#ifndef __OPCUA_SMART_VALUES_H__
|
2
|
+
#define __OPCUA_SMART_VALUES_H__
|
3
|
+
|
4
|
+
#include <open62541.h>
|
5
|
+
#include <ruby.h>
|
6
|
+
|
7
|
+
VALUE mTYPES;
|
8
|
+
RUBY_EXTERN bool value_to_variant(VALUE value, UA_Variant *variant, UA_UInt32 proposal);
|
9
|
+
RUBY_EXTERN void Init_types();
|
10
|
+
RUBY_EXTERN VALUE extract_value(UA_Variant value);
|
11
|
+
|
12
|
+
#endif
|
@@ -0,0 +1 @@
|
|
1
|
+
../helpers/finders.c
|
@@ -0,0 +1 @@
|
|
1
|
+
../helpers/finders.h
|
@@ -0,0 +1 @@
|
|
1
|
+
../helpers/log_none.c
|
@@ -0,0 +1 @@
|
|
1
|
+
../helpers/log_none.h
|
data/ext/opcua/server/server.c
CHANGED
@@ -12,7 +12,7 @@ VALUE cReferenceNode = Qnil;
|
|
12
12
|
VALUE cVarNode = Qnil;
|
13
13
|
VALUE cMethodNode = Qnil;
|
14
14
|
|
15
|
-
#include "
|
15
|
+
#include "values.h"
|
16
16
|
|
17
17
|
int nodecounter = 2000;
|
18
18
|
|
@@ -24,7 +24,7 @@ static void node_free(node_struct *ns) { //{{{
|
|
24
24
|
}
|
25
25
|
free(ns);
|
26
26
|
}
|
27
|
-
} //}}}
|
27
|
+
} // }}}
|
28
28
|
static node_struct * node_alloc(server_struct *server, UA_NodeId nodeid) { //{{{
|
29
29
|
node_struct *ns;
|
30
30
|
ns = (node_struct *)malloc(sizeof(node_struct));
|
@@ -34,6 +34,7 @@ static node_struct * node_alloc(server_struct *server, UA_NodeId nodeid) { //{{{
|
|
34
34
|
ns->master = server;
|
35
35
|
ns->id = nodeid;
|
36
36
|
ns->method = Qnil;
|
37
|
+
ns->exists = true;
|
37
38
|
|
38
39
|
return ns;
|
39
40
|
} //}}}
|
@@ -45,12 +46,14 @@ static VALUE node_wrap(VALUE klass, node_struct *ns) { //{{{
|
|
45
46
|
static VALUE node_type_folder(VALUE self) { //{{{
|
46
47
|
node_struct *ns;
|
47
48
|
Data_Get_Struct(self, node_struct, ns);
|
49
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
48
50
|
return node_wrap(cTypeTopNode, node_alloc(ns->master, UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE)));
|
49
51
|
} //}}}
|
50
52
|
static VALUE node_add_object_type(VALUE self, VALUE name) { //{{{
|
51
53
|
node_struct *ns;
|
52
54
|
|
53
55
|
Data_Get_Struct(self, node_struct, ns);
|
56
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
54
57
|
|
55
58
|
VALUE str = rb_obj_as_string(name);
|
56
59
|
if (NIL_P(str) || TYPE(str) != T_STRING)
|
@@ -76,6 +79,7 @@ static VALUE node_add_reference_type(VALUE self, VALUE name, VALUE type) { //{{{
|
|
76
79
|
node_struct *ns;
|
77
80
|
|
78
81
|
Data_Get_Struct(self, node_struct, ns);
|
82
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
79
83
|
|
80
84
|
VALUE str = rb_obj_as_string(name);
|
81
85
|
if (NIL_P(str) || TYPE(str) != T_STRING)
|
@@ -104,6 +108,7 @@ static VALUE node_id(VALUE self) { //{{{
|
|
104
108
|
node_struct *ns;
|
105
109
|
|
106
110
|
Data_Get_Struct(self, node_struct, ns);
|
111
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
107
112
|
|
108
113
|
VALUE ret = rb_ary_new();
|
109
114
|
|
@@ -118,11 +123,23 @@ static VALUE node_id(VALUE self) { //{{{
|
|
118
123
|
}
|
119
124
|
return ret;
|
120
125
|
} //}}}
|
126
|
+
static VALUE node_name(VALUE self) { //{{{
|
127
|
+
node_struct *ns;
|
128
|
+
|
129
|
+
Data_Get_Struct(self, node_struct, ns);
|
130
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
131
|
+
|
132
|
+
UA_QualifiedName qn; UA_QualifiedName_init(&qn);
|
133
|
+
UA_Server_readBrowseName(ns->master->master, ns->id, &qn);
|
134
|
+
|
135
|
+
return rb_sprintf("%.*s", (int)qn.name.length, qn.name.data);
|
136
|
+
} //}}}
|
121
137
|
static VALUE node_to_s(VALUE self) { //{{{
|
122
138
|
node_struct *ns;
|
123
139
|
VALUE ret;
|
124
140
|
|
125
141
|
Data_Get_Struct(self, node_struct, ns);
|
142
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
126
143
|
|
127
144
|
if (ns->id.identifierType == UA_NODEIDTYPE_NUMERIC) {
|
128
145
|
ret = rb_sprintf("ns=%d;i=%d", ns->id.namespaceIndex, ns->id.identifier.numeric);
|
@@ -139,12 +156,15 @@ static VALUE node_add_reference(VALUE self, VALUE to, VALUE type) { //{{{
|
|
139
156
|
node_struct *tys;
|
140
157
|
|
141
158
|
Data_Get_Struct(self, node_struct, ns);
|
159
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
142
160
|
|
143
161
|
if (!(rb_obj_is_kind_of(type,cReferenceSubNode) || rb_obj_is_kind_of(to,cTypeSubNode))) {
|
144
162
|
rb_raise(rb_eArgError, "arguments have to be NodeIDs.");
|
145
163
|
}
|
146
164
|
Data_Get_Struct(to, node_struct, tos);
|
165
|
+
if (!tos->exists) rb_raise(rb_eRuntimeError, "To (arg 1) node does not exist anymore.");
|
147
166
|
Data_Get_Struct(type, node_struct, tys);
|
167
|
+
if (!tys->exists) rb_raise(rb_eRuntimeError, "Type (arg 2) node does not exist anymore.");
|
148
168
|
UA_NodeId n = UA_NODEID_NUMERIC(ns->master->default_ns, nodecounter++);
|
149
169
|
|
150
170
|
UA_ExpandedNodeId toNodeId;
|
@@ -269,6 +289,7 @@ static VALUE node_add_method(int argc, VALUE* argv, VALUE self) { //{{{
|
|
269
289
|
if (NIL_P(opts)) opts = rb_hash_new();
|
270
290
|
|
271
291
|
Data_Get_Struct(self, node_struct, parent);
|
292
|
+
if (!parent->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
272
293
|
|
273
294
|
VALUE str = rb_obj_as_string(name);
|
274
295
|
if (NIL_P(str) || TYPE(str) != T_STRING)
|
@@ -326,6 +347,7 @@ static VALUE node_add_variable_wrap(int argc, VALUE* argv, VALUE self, UA_Byte a
|
|
326
347
|
}
|
327
348
|
|
328
349
|
Data_Get_Struct(self, node_struct, parent);
|
350
|
+
if (!parent->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
329
351
|
|
330
352
|
VALUE str = rb_obj_as_string(argv[0]);
|
331
353
|
if (NIL_P(str) || TYPE(str) != T_STRING)
|
@@ -422,7 +444,9 @@ static VALUE node_add_object(int argc, VALUE* argv, VALUE self) { //{{{
|
|
422
444
|
}
|
423
445
|
|
424
446
|
Data_Get_Struct(self, node_struct, parent);
|
447
|
+
if (!parent->exists) rb_raise(rb_eRuntimeError, "Parent node does not exist anymore.");
|
425
448
|
Data_Get_Struct(argv[1], node_struct, datatype);
|
449
|
+
if (!datatype->exists) rb_raise(rb_eRuntimeError, "Datatype node does not exist anymore.");
|
426
450
|
|
427
451
|
VALUE str = rb_obj_as_string(argv[0]);
|
428
452
|
if (NIL_P(str) || TYPE(str) != T_STRING)
|
@@ -432,52 +456,6 @@ static VALUE node_add_object(int argc, VALUE* argv, VALUE self) { //{{{
|
|
432
456
|
return node_wrap(CLASS_OF(self),node_alloc(parent->master,node_add_object_ua_simple(type,nstr,parent,datatype,argv[2])));
|
433
457
|
} //}}}
|
434
458
|
|
435
|
-
static UA_BrowsePathResult node_browse_path(UA_Server *server, UA_NodeId relative, UA_NodeId ref, UA_QualifiedName mqn) { //{{{
|
436
|
-
UA_RelativePathElement rpe;
|
437
|
-
UA_RelativePathElement_init(&rpe);
|
438
|
-
rpe.referenceTypeId = ref;
|
439
|
-
rpe.isInverse = false;
|
440
|
-
rpe.includeSubtypes = false;
|
441
|
-
rpe.targetName = mqn;
|
442
|
-
|
443
|
-
UA_BrowsePath bp;
|
444
|
-
UA_BrowsePath_init(&bp);
|
445
|
-
bp.startingNode = relative;
|
446
|
-
bp.relativePath.elementsSize = 1;
|
447
|
-
bp.relativePath.elements = &rpe;
|
448
|
-
|
449
|
-
return UA_Server_translateBrowsePathToNodeIds(server, &bp);
|
450
|
-
} //}}}
|
451
|
-
|
452
|
-
static bool node_get_reference(UA_Server *server, UA_NodeId parent, UA_NodeId *result) { //{{{
|
453
|
-
UA_BrowseDescription bDes;
|
454
|
-
UA_BrowseDescription_init(&bDes);
|
455
|
-
bDes.nodeId = parent;
|
456
|
-
bDes.resultMask = UA_BROWSERESULTMASK_ALL;
|
457
|
-
UA_BrowseResult bRes = UA_Server_browse(server, 999, &bDes);
|
458
|
-
|
459
|
-
if (bRes.referencesSize > 0) {
|
460
|
-
UA_ReferenceDescription *ref = &(bRes.references[0]);
|
461
|
-
|
462
|
-
UA_NodeId_copy(&ref->nodeId.nodeId,result);
|
463
|
-
|
464
|
-
UA_QualifiedName qn; UA_QualifiedName_init(&qn);
|
465
|
-
UA_Server_readBrowseName(server, ref->nodeId.nodeId, &qn);
|
466
|
-
|
467
|
-
// printf("NS: %d ---> NodeId %u; %-16.*s\n",
|
468
|
-
// ref->nodeId.nodeId.namespaceIndex,
|
469
|
-
// ref->nodeId.nodeId.identifier.numeric,
|
470
|
-
// (int)qn.name.length,
|
471
|
-
// qn.name.data
|
472
|
-
// );
|
473
|
-
|
474
|
-
UA_BrowseResult_deleteMembers(&bRes);
|
475
|
-
UA_BrowseResult_clear(&bRes);
|
476
|
-
return true;
|
477
|
-
}
|
478
|
-
return false;
|
479
|
-
} //}}}
|
480
|
-
|
481
459
|
static UA_StatusCode node_manifest_iter(UA_NodeId child_id, UA_Boolean is_inverse, UA_NodeId reference_type_id, void *handle) { //{{{
|
482
460
|
if (is_inverse) return UA_STATUSCODE_GOOD;
|
483
461
|
|
@@ -516,8 +494,8 @@ static UA_StatusCode node_manifest_iter(UA_NodeId child_id, UA_Boolean is_invers
|
|
516
494
|
if (child_id.namespaceIndex == parent->master->default_ns) {
|
517
495
|
UA_QualifiedName mqn;UA_QualifiedName_init(&mqn);
|
518
496
|
UA_Server_readBrowseName(parent->master->master, UA_NODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORY), &mqn);
|
519
|
-
|
520
|
-
|
497
|
+
UA_BrowsePathResult mandatory = node_browse_path(parent->master->master, child_id, UA_NODEID_NUMERIC(0, UA_NS0ID_HASMODELLINGRULE), mqn, false);
|
498
|
+
UA_QualifiedName_clear(&mqn);
|
521
499
|
|
522
500
|
if (mandatory.statusCode == UA_STATUSCODE_GOOD && (nc == UA_NODECLASS_OBJECT || nc == UA_NODECLASS_VARIABLE || nc == UA_NODECLASS_METHOD)) {
|
523
501
|
char * buffer = strnautocat(NULL,"",0);
|
@@ -529,7 +507,7 @@ static UA_StatusCode node_manifest_iter(UA_NodeId child_id, UA_Boolean is_invers
|
|
529
507
|
buffer = strnautocat(buffer,(char *)qn.name.data,qn.name.length);
|
530
508
|
if(nc == UA_NODECLASS_OBJECT) {
|
531
509
|
UA_NodeId typeid;
|
532
|
-
|
510
|
+
server_node_get_reference(parent->master->master, child_id, &typeid, false);
|
533
511
|
|
534
512
|
node_struct *thetype = node_alloc(parent->master,typeid);
|
535
513
|
|
@@ -547,7 +525,8 @@ static UA_StatusCode node_manifest_iter(UA_NodeId child_id, UA_Boolean is_invers
|
|
547
525
|
if(nc == UA_NODECLASS_VARIABLE) {
|
548
526
|
UA_QualifiedName pqn;UA_QualifiedName_init(&pqn);
|
549
527
|
UA_Server_readBrowseName(parent->master->master, UA_NODEID_NUMERIC(0, UA_NS0ID_PROPERTYTYPE), &pqn);
|
550
|
-
UA_BrowsePathResult property = node_browse_path(parent->master->master, child_id, UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION), pqn);
|
528
|
+
UA_BrowsePathResult property = node_browse_path(parent->master->master, child_id, UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION), pqn, false);
|
529
|
+
UA_QualifiedName_clear(&pqn);
|
551
530
|
|
552
531
|
if (property.statusCode == UA_STATUSCODE_GOOD) {
|
553
532
|
node_add_variable_ua(UA_NS0ID_PROPERTYTYPE,UA_NODEID_STRING(parent->master->default_ns,buffer),dn,qn,newnode,al);
|
@@ -556,12 +535,11 @@ static UA_StatusCode node_manifest_iter(UA_NodeId child_id, UA_Boolean is_invers
|
|
556
535
|
}
|
557
536
|
|
558
537
|
UA_BrowsePathResult_clear(&property);
|
559
|
-
UA_QualifiedName_clear(&pqn);
|
560
538
|
}
|
561
539
|
if(nc == UA_NODECLASS_METHOD) {
|
562
540
|
UA_NodeId ttt;
|
563
541
|
VALUE blk = rb_hash_aref(parent->master->methods,INT2NUM(child_id.identifier.numeric));
|
564
|
-
if (
|
542
|
+
if (server_node_get_reference(parent->master->master, child_id, &ttt, false)) {
|
565
543
|
UA_Variant arv; UA_Variant_init(&arv);
|
566
544
|
UA_Server_readValue(parent->master->master, ttt, &arv);
|
567
545
|
|
@@ -573,7 +551,6 @@ static UA_StatusCode node_manifest_iter(UA_NodeId child_id, UA_Boolean is_invers
|
|
573
551
|
}
|
574
552
|
}
|
575
553
|
UA_BrowsePathResult_clear(&mandatory);
|
576
|
-
UA_QualifiedName_clear(&mqn);
|
577
554
|
}
|
578
555
|
|
579
556
|
UA_NodeClass_clear(&nc);
|
@@ -593,7 +570,9 @@ static VALUE node_manifest(VALUE self, VALUE name, VALUE parent) { //{{{
|
|
593
570
|
}
|
594
571
|
|
595
572
|
Data_Get_Struct(self, node_struct, ns);
|
573
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
596
574
|
Data_Get_Struct(parent, node_struct, ts);
|
575
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Target node does not exist anymore.");
|
597
576
|
|
598
577
|
VALUE str = rb_obj_as_string(name);
|
599
578
|
if (NIL_P(str) || TYPE(str) != T_STRING)
|
@@ -620,13 +599,14 @@ static VALUE node_find(VALUE self, VALUE qname) { //{{{
|
|
620
599
|
node_struct *ns;
|
621
600
|
|
622
601
|
Data_Get_Struct(self, node_struct, ns);
|
602
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
623
603
|
|
624
604
|
VALUE str = rb_obj_as_string(qname);
|
625
605
|
if (NIL_P(str) || TYPE(str) != T_STRING)
|
626
606
|
rb_raise(rb_eTypeError, "cannot convert obj to string");
|
627
607
|
char *nstr = (char *)StringValuePtr(str);
|
628
608
|
|
629
|
-
UA_BrowsePathResult bpr = node_browse_path(ns->master->master, ns->id, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(ns->master->default_ns, nstr));
|
609
|
+
UA_BrowsePathResult bpr = node_browse_path(ns->master->master, ns->id, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(ns->master->default_ns, nstr), false);
|
630
610
|
|
631
611
|
if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
|
632
612
|
return Qnil;
|
@@ -707,9 +687,10 @@ static VALUE server_get(int argc, VALUE* argv, VALUE self) { //{{{
|
|
707
687
|
static VALUE node_value_set(VALUE self, VALUE value) { //{{{
|
708
688
|
node_struct *ns;
|
709
689
|
Data_Get_Struct(self, node_struct, ns);
|
690
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
710
691
|
|
711
692
|
UA_Variant variant;
|
712
|
-
if (value_to_variant(value,&variant)) {
|
693
|
+
if (value_to_variant(value,&variant,-1)) {
|
713
694
|
// printf("-----------------------------------------%ld\n",variant.arrayDimensionsSize);
|
714
695
|
if (variant.arrayDimensionsSize > 0) {
|
715
696
|
UA_Server_writeValueRank(ns->master->master, ns->id, variant.arrayDimensionsSize);
|
@@ -726,6 +707,7 @@ static VALUE node_value(VALUE self) { //{{{
|
|
726
707
|
node_struct *ns;
|
727
708
|
|
728
709
|
Data_Get_Struct(self, node_struct, ns);
|
710
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
729
711
|
|
730
712
|
UA_Variant value;
|
731
713
|
UA_Variant_init(&value);
|
@@ -740,9 +722,34 @@ static VALUE node_value(VALUE self) { //{{{
|
|
740
722
|
UA_Variant_clear(&value);
|
741
723
|
return rb_ary_entry(ret,0);
|
742
724
|
} //}}}
|
725
|
+
static VALUE node_delete(VALUE self) { //{{{
|
726
|
+
node_struct *ns;
|
727
|
+
|
728
|
+
Data_Get_Struct(self, node_struct, ns);
|
729
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
730
|
+
|
731
|
+
UA_StatusCode retval = UA_Server_deleteNode(ns->master->master, ns->id, true);
|
732
|
+
|
733
|
+
if (retval == UA_STATUSCODE_GOOD) {
|
734
|
+
ns->exists = false;
|
735
|
+
return Qtrue;
|
736
|
+
}
|
737
|
+
|
738
|
+
return Qfalse;
|
739
|
+
} //}}}
|
740
|
+
static VALUE node_exists(VALUE self) { //{{{
|
741
|
+
node_struct *ns;
|
742
|
+
|
743
|
+
Data_Get_Struct(self, node_struct, ns);
|
744
|
+
if (ns->exists)
|
745
|
+
return Qtrue;
|
746
|
+
else
|
747
|
+
return Qfalse;
|
748
|
+
} //}}}
|
743
749
|
static VALUE node_description_set(VALUE self, VALUE value) { //{{{
|
744
750
|
node_struct *ns;
|
745
751
|
Data_Get_Struct(self, node_struct, ns);
|
752
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
746
753
|
|
747
754
|
VALUE str = rb_obj_as_string(value);
|
748
755
|
if (NIL_P(str) || TYPE(str) != T_STRING)
|
@@ -757,6 +764,7 @@ static VALUE node_description(VALUE self) { //{{{
|
|
757
764
|
node_struct *ns;
|
758
765
|
|
759
766
|
Data_Get_Struct(self, node_struct, ns);
|
767
|
+
if (!ns->exists) rb_raise(rb_eRuntimeError, "Node does not exist anymore.");
|
760
768
|
|
761
769
|
UA_LocalizedText value;
|
762
770
|
UA_LocalizedText_init(&value);
|
@@ -918,8 +926,10 @@ void Init_server(void) {
|
|
918
926
|
|
919
927
|
rb_define_method(cNode, "to_s", node_to_s, 0);
|
920
928
|
rb_define_method(cNode, "id", node_id, 0);
|
929
|
+
rb_define_method(cNode, "name", node_name, 0);
|
921
930
|
rb_define_method(cNode, "description", node_description, 0);
|
922
931
|
rb_define_method(cNode, "description=", node_description_set, 1);
|
932
|
+
rb_define_method(cNode, "exists?", node_exists, 0);
|
923
933
|
|
924
934
|
rb_define_method(cTypeTopNode, "add_object_type", node_add_object_type, 1);
|
925
935
|
rb_define_method(cTypeTopNode, "add_reference_type", node_add_reference_type, 1);
|
@@ -931,10 +941,13 @@ void Init_server(void) {
|
|
931
941
|
rb_define_method(cTypeSubNode, "add_object", node_add_object, -1);
|
932
942
|
rb_define_method(cTypeSubNode, "add_method", node_add_method, -1);
|
933
943
|
rb_define_method(cTypeSubNode, "add_reference", node_add_reference, 2);
|
944
|
+
rb_define_method(cTypeSubNode, "delete!", node_delete, 0);
|
934
945
|
|
935
946
|
rb_define_method(cObjectNode, "manifest", node_manifest, 2);
|
936
947
|
rb_define_method(cObjectNode, "find", node_find, 1);
|
948
|
+
rb_define_method(cObjectNode, "delete!", node_delete, 0);
|
937
949
|
|
938
950
|
rb_define_method(cVarNode, "value", node_value, 0);
|
939
951
|
rb_define_method(cVarNode, "value=", node_value_set, 1);
|
952
|
+
rb_define_method(cVarNode, "delete!", node_delete, 0);
|
940
953
|
}
|