opcua 0.12 → 0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
}
|