- Main
- Tutorials
- Library
- Samples

- File List
- Globals

demo_node_operator.c
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright (C) 2019 Moxa Inc. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Demo Node Operator
6 *
7 * Date Author Comment
8 * 2019-06-05 Rich Liao Created it.
9 ******************************************************************************/
10
25 #include <unistd.h>
26 #include <string.h>
27
29 #include <mx_node_sdk/mx_node_interface_basic.h>
30 #include <mx_node_sdk/mx_node_interface_data_access.h>
31
32 #define NUM_DATA 12
33
35 typedef enum
36 {
37 OPERATOR_STATE_STOP,
38 OPERATOR_STATE_STOPPING,
39 OPERATOR_STATE_RUNNING,
40 } OPERATOR_STATE;
41
42 typedef struct _MY_DATA
43 {
44 MX_NODE_NODE_HANDLE node_handle;
45 MX_NODE_VARIANT data;
46 struct timeval timestamp;
47 } MY_DATA;
48
49 struct timeval now();
50 MX_NODE_RESULT add_my_nodes();
51 void rotate(char* str);
52
53 MX_NODE_NODE_OPERATOR_HANDLE g_operator_handle;
54 volatile OPERATOR_STATE g_state;
55 MY_DATA g_my_data[NUM_DATA];
56
59 const char* mx_node_operator_get_version()
60 {
61 return "1.0";
62 }
63
64 long long mx_node_operator_get_supported_interfaces()
65 {
66 return INTERFACE_MX_NODE_BASIC | INTERFACE_MX_NODE_DATA_ACCESS;
67 }
68
69 MX_NODE_RESULT mx_node_operator_initialize(MX_NODE_NODE_OPERATOR_HANDLE operator_handle)
70 {
71 g_operator_handle = operator_handle;
72 g_state = OPERATOR_STATE_STOP;
73
74 for (int i = 0; i < NUM_DATA; ++i)
75 {
76 g_my_data[i].data.type = i;
77 if (MX_NODE_VALUE_TYPE_STRING == g_my_data[i].data.type)
78 {
79 g_my_data[i].data.value.s = malloc(8);
80 strcpy(g_my_data[i].data.value.s, "abcdefg");
81 }
82 else
83 memset(&g_my_data[i].data.value, 0, sizeof(g_my_data[i].data.value));
84 }
85
86 return add_my_nodes();
87 }
88
89 void mx_node_operator_uninitialize()
90 {
91 for (int i = 0; i < NUM_DATA; ++i)
92 {
93 if (MX_NODE_VALUE_TYPE_STRING == g_my_data[i].data.type)
94 free(g_my_data[i].data.value.s);
95 }
96 }
97
98 void mx_node_operator_start()
99 {
100 g_state = OPERATOR_STATE_RUNNING;
101 while (g_state == OPERATOR_STATE_RUNNING)
102 {
103 for (int i = 0; i < NUM_DATA; ++i)
104 {
105 g_my_data[i].timestamp = now();
106 switch (g_my_data[i].data.type)
107 {
108 case MX_NODE_VALUE_TYPE_BOOLEAN:
109 g_my_data[i].data.value.b = !g_my_data[i].data.value.b;
110 break;
111 case MX_NODE_VALUE_TYPE_SBYTE:
112 g_my_data[i].data.value.i8++;
113 break;
114 case MX_NODE_VALUE_TYPE_INT16:
115 g_my_data[i].data.value.i16++;
116 break;
117 case MX_NODE_VALUE_TYPE_INT32:
118 g_my_data[i].data.value.i32++;
119 break;
120 case MX_NODE_VALUE_TYPE_INT64:
121 g_my_data[i].data.value.i64++;
122 break;
123 case MX_NODE_VALUE_TYPE_BYTE:
124 g_my_data[i].data.value.u8++;
125 break;
126 case MX_NODE_VALUE_TYPE_UINT16:
127 g_my_data[i].data.value.u16++;
128 break;
129 case MX_NODE_VALUE_TYPE_UINT32:
130 g_my_data[i].data.value.u32++;
131 break;
132 case MX_NODE_VALUE_TYPE_UINT64:
133 g_my_data[i].data.value.u64++;
134 break;
135 case MX_NODE_VALUE_TYPE_FLOAT:
136 g_my_data[i].data.value.f++;
137 break;
138 case MX_NODE_VALUE_TYPE_DOUBLE:
139 g_my_data[i].data.value.d++;
140 break;
141 case MX_NODE_VALUE_TYPE_STRING:
142 rotate(g_my_data[i].data.value.s);
143 break;
144 default:
145 continue;
146 }
147 mx_node_update_node(g_my_data[i].node_handle, &g_my_data[i].data, &g_my_data[i].timestamp);
148 }
149 sleep(3);
150 }
151 g_state = OPERATOR_STATE_STOP;
152 }
153
154 void mx_node_operator_stop()
155 {
156 if (g_state == OPERATOR_STATE_RUNNING)
157 {
158 g_state = OPERATOR_STATE_STOPPING;
159 while (g_state != OPERATOR_STATE_STOP);
160 }
161 }
163
165 MX_NODE_RESULT mx_node_operator_read_node(MX_NODE_NODE_HANDLE node_handle, MX_NODE_VARIANT* node_value, struct timeval* node_timestamp)
166 {
167 for (int i = 0; i < NUM_DATA; ++i)
168 {
169 if (node_handle == g_my_data[i].node_handle)
170 {
171 *node_value = g_my_data[i].data;
172 *node_timestamp = g_my_data[i].timestamp;
173 return MX_NODE_RESULT_GOOD;
174 }
175 }
176 return MX_NODE_RESULT_BAD;
177 }
178
179 MX_NODE_RESULT mx_node_operator_write_node(MX_NODE_NODE_HANDLE node_handle, const MX_NODE_VARIANT* node_value)
180 {
181 for (int i = 0; i < NUM_DATA; ++i)
182 {
183 if (node_handle == g_my_data[i].node_handle)
184 {
185 g_my_data[i].data = *node_value;
186 g_my_data[i].timestamp = now();
187 return MX_NODE_RESULT_GOOD;
188 }
189 }
190 return MX_NODE_RESULT_BAD;
191 }
194
195 MX_NODE_RESULT add_my_nodes()
196 {
197 // DemoFolder
198 // |--DemoObject
199 // |--DemoBoolean
200 // |--DemoTimeZone (property, value: 480)
201 // |--DemoInt8
202 // |--DemoTimeZone (property, value: 480)
203 // |--DemoInt16
204 // |--DemoTimeZone (property, value: 480)
205 // |--DemoInt32
206 // |--DemoTimeZone (property, value: 480)
207 // |--DemoInt64
208 // |--DemoTimeZone (property, value: 480)
209 // |--DemoUInt8
210 // |--DemoTimeZone (property, value: 480)
211 // |--DemoUInt16
212 // |--DemoTimeZone (property, value: 480)
213 // |--DemoUInt32
214 // |--DemoTimeZone (property, value: 480)
215 // |--DemoUInt64
216 // |--DemoTimeZone (property, value: 480)
217 // |--DemoFloat
218 // |--DemoTimeZone (property, value: 480)
219 // |--DemoDouble
220 // |--DemoTimeZone (property, value: 480)
221 // |--DemoString
222 // |--DemoTimeZone (property, value: 480)
223
224 MX_NODE_RESULT res;
225
226 // folder
227 MX_NODE_NODE folder;
228 {
229 strcpy(folder.node_name, "DemoFolder");
230 folder.node_type = MX_NODE_NODE_TYPE_FOLDER;
231 strcpy(folder.description, "DemoFolder's Description");
232 }
233 MX_NODE_NODE_HANDLE folder_handle;
234 res = mx_node_add_node(g_operator_handle, &folder, &folder_handle);
235 if (res != MX_NODE_RESULT_GOOD)
236 return res;
237
238 // object
239 MX_NODE_NODE object;
240 {
241 strcpy(object.node_name, "DemoObject");
242 object.node_type = MX_NODE_NODE_TYPE_OBJECT;
243 strcpy(object.description, "DemoObject's Description");
244 }
245 MX_NODE_NODE_HANDLE object_handle;
246 res = mx_node_add_node(g_operator_handle, &object, &object_handle);
247 if (res != MX_NODE_RESULT_GOOD)
248 return res;
249 res = mx_node_set_parent_node(object_handle, folder_handle);
250 if (res != MX_NODE_RESULT_GOOD)
251 return res;
252
253 // variable
254 char* node_name[NUM_DATA] = {
255 "DemoBoolean", "DemoInt8", "DemoInt16", "DemoInt32",
256 "DemoInt64", "DemoUInt8", "DemoUInt16", "DemoUInt32",
257 "DemoUInt64", "DemoFloat", "DemoDouble", "DemoString"
258 };
259
260 for (int i = 0; i < NUM_DATA; ++i)
261 {
262 MX_NODE_NODE variable;
263 {
264 strcpy(variable.node_name, node_name[i]);
265 variable.node_type = MX_NODE_NODE_TYPE_VARIABLE;
266 strcpy(variable.description, node_name[i]);
267 strcat(variable.description, "'s Description");
268 variable.variable.access_right = MX_NODE_ACCESS_RIGHT_READWRITE;
269 variable.variable.value = g_my_data[i].data;
270 }
271 res = mx_node_add_node(g_operator_handle, &variable, &g_my_data[i].node_handle);
272 if (res != MX_NODE_RESULT_GOOD)
273 return res;
274 res = mx_node_set_parent_node(g_my_data[i].node_handle, object_handle);
275 if (res != MX_NODE_RESULT_GOOD)
276 return res;
277 }
278
279 // property
280 MX_NODE_NODE property;
281 {
282 strcpy(property.node_name, "DemoTimeZone");
283 property.node_type = MX_NODE_NODE_TYPE_PROPERTY;
284 strcpy(property.description, "DemoTimeZone's Description");
285 property.property.access_right = MX_NODE_ACCESS_RIGHT_READONLY;
286 property.property.value.type = MX_NODE_VALUE_TYPE_INT32;
287 property.property.value.value.i32 = 480;
288 }
289 for (int i = 0; i < NUM_DATA; ++i)
290 {
291 MX_NODE_NODE_HANDLE property_handle;
292 res = mx_node_add_node(g_operator_handle, &property, &property_handle);
293 if (res != MX_NODE_RESULT_GOOD)
294 return res;
295 res = mx_node_set_parent_node(property_handle, g_my_data[i].node_handle);
296 if (res != MX_NODE_RESULT_GOOD)
297 return res;
298 }
299
300 return MX_NODE_RESULT_GOOD;
301 }
302
303 struct timeval now()
304 {
305 struct timeval t;
306 gettimeofday(&t, NULL);
307 return t;
308 }
309
310 void rotate(char* str)
311 {
312 if (str[0] != '\0')
313 {
314 char tmp = str[0];
315 int i = 0;
316 while (str[i + 1] != '\0')
317 {
318 str[i] = str[i + 1];
319 ++i;
320 }
321 str[i] = tmp;
322 }
323 }
_MX_NODE_VARIABLE::value
MX_NODE_VARIANT value
Definition: mx_node_node_def.h:123
_MX_NODE_VARIANT::u8
uint8_t u8
Definition: mx_node_node_def.h:107
mx_node_add_node
MX_NODE_RESULT mx_node_add_node(MX_NODE_NODE_OPERATOR_HANDLE operator_handle, MX_NODE_NODE *node, MX_NODE_NODE_HANDLE *node_handle)
Add a node to OPC UA server.
_MX_NODE_VARIANT::u16
uint16_t u16
Definition: mx_node_node_def.h:108
mx_node_operator_write_node
MX_NODE_RESULT mx_node_operator_write_node(MX_NODE_NODE_HANDLE node_handle, const MX_NODE_VARIANT *node_value)
Write data by handle index.
g_state
volatile OPERATOR_STATE g_state
Definition: demo_node_operator.c:54
_MX_NODE_VARIANT
A variant structure is used to store different type&#39;s data.
Definition: mx_node_node_def.h:97
mx_node_operator_start
void mx_node_operator_start()
A notify to inform node operator start with non-blocking.
MX_NODE_VALUE_TYPE_BOOLEAN
Definition: mx_node_node_def.h:68
OPERATOR_STATE_STOPPING
Definition: demo_node_operator.c:38
MX_NODE_NODE_HANDLE
size_t MX_NODE_NODE_HANDLE
Handle of a node.
Definition: mx_node_node.h:42
INTERFACE_MX_NODE_BASIC
#define INTERFACE_MX_NODE_BASIC
Interface basic&#39;s flag.
Definition: mx_node_interface_basic.h:42
MX_NODE_ACCESS_RIGHT_READWRITE
Definition: mx_node_node_def.h:90
MY_DATA
struct _MY_DATA MY_DATA
MX_NODE_NODE_TYPE_VARIABLE
Definition: mx_node_node_def.h:44
_MX_NODE_VARIANT::i16
int16_t i16
Definition: mx_node_node_def.h:104
_MX_NODE_NODE::variable
MX_NODE_VARIABLE variable
Definition: mx_node_node_def.h:148
MX_NODE_RESULT
enum _MX_NODE_RESULT MX_NODE_RESULT
A result enumeration represents success or not.
NUM_DATA
#define NUM_DATA
include interfaces
Definition: demo_node_operator.c:32
MX_NODE_ACCESS_RIGHT_READONLY
Definition: mx_node_node_def.h:88
MX_NODE_VALUE_TYPE_FLOAT
Definition: mx_node_node_def.h:77
_MY_DATA::data
MX_NODE_VARIANT data
Definition: demo_node_operator.c:45
mx_node_operator_stop
void mx_node_operator_stop()
A notify to inform node operator stopping.
_MX_NODE_NODE
A node&#39;s sturcture contain name, description, node type and attribute.
Definition: mx_node_node_def.h:139
g_my_data
MY_DATA g_my_data[NUM_DATA]
Definition: demo_node_operator.c:55
mx_node_set_parent_node
MX_NODE_RESULT mx_node_set_parent_node(MX_NODE_NODE_HANDLE node_handle, MX_NODE_NODE_HANDLE parent_node_handle)
Set a node&#39;s parent.
MX_NODE_VALUE_TYPE_BYTE
Definition: mx_node_node_def.h:73
INTERFACE_MX_NODE_DATA_ACCESS
#define INTERFACE_MX_NODE_DATA_ACCESS
Interface data access&#39;s flag.
Definition: mx_node_interface_basic.h:48
_MX_NODE_VARIANT::b
bool b
Definition: mx_node_node_def.h:102
mx_node_operator_get_version
const char * mx_node_operator_get_version()
Get node operator&#39;s version.
mx_node_operator_read_node
MX_NODE_RESULT mx_node_operator_read_node(MX_NODE_NODE_HANDLE node_handle, MX_NODE_VARIANT *node_value, struct timeval *node_timestamp)
Read a node&#39;s data and timestamp.
_MX_NODE_VARIANT::i32
int32_t i32
Definition: mx_node_node_def.h:105
MX_NODE_NODE_TYPE_PROPERTY
Definition: mx_node_node_def.h:45
mx_node_operator_get_supported_interfaces
long long mx_node_operator_get_supported_interfaces()
Get supported interfaces.
rotate
void rotate(char *str)
Definition: demo_node_operator.c:310
_MX_NODE_VARIANT::u32
uint32_t u32
Definition: mx_node_node_def.h:109
_MX_NODE_VARIABLE::access_right
MX_NODE_ACCESS_RIGHT access_right
Definition: mx_node_node_def.h:124
MX_NODE_VALUE_TYPE_UINT16
Definition: mx_node_node_def.h:74
MX_NODE_RESULT_GOOD
Definition: mx_node_node_def.h:158
MX_NODE_NODE_TYPE_OBJECT
Definition: mx_node_node_def.h:43
_MX_NODE_VARIANT::i64
int64_t i64
Definition: mx_node_node_def.h:106
_MX_NODE_VARIANT::u64
uint64_t u64
Definition: mx_node_node_def.h:110
OPERATOR_STATE_RUNNING
Definition: demo_node_operator.c:39
_MX_NODE_VARIANT::d
double d
Definition: mx_node_node_def.h:112
MX_NODE_VALUE_TYPE_INT32
Definition: mx_node_node_def.h:71
MX_NODE_VALUE_TYPE_SBYTE
Definition: mx_node_node_def.h:69
MX_NODE_VALUE_TYPE_INT16
Definition: mx_node_node_def.h:70
now
struct timeval now()
Definition: demo_node_operator.c:303
MX_NODE_VALUE_TYPE_INT64
Definition: mx_node_node_def.h:72
_MX_NODE_NODE::node_name
char node_name[MAX_NODE_NAME_LEN]
Definition: mx_node_node_def.h:141
MX_NODE_VALUE_TYPE_UINT32
Definition: mx_node_node_def.h:75
MX_NODE_VALUE_TYPE_DOUBLE
Definition: mx_node_node_def.h:78
_MX_NODE_NODE::description
char description[MAX_NODE_DESC_LEN]
Definition: mx_node_node_def.h:142
_MX_NODE_VARIANT::type
MX_NODE_VALUE_TYPE type
Definition: mx_node_node_def.h:99
mx_node_operator_uninitialize
void mx_node_operator_uninitialize()
Do node operator&#39;s uninitialize.
add_my_nodes
MX_NODE_RESULT add_my_nodes()
Definition: demo_node_operator.c:195
MX_NODE_NODE_TYPE_FOLDER
Definition: mx_node_node_def.h:42
MX_NODE_VALUE_TYPE_STRING
Definition: mx_node_node_def.h:79
_MX_NODE_VARIANT::i8
int8_t i8
Definition: mx_node_node_def.h:103
_MX_NODE_VARIANT::f
float f
Definition: mx_node_node_def.h:111
_MY_DATA::node_handle
MX_NODE_NODE_HANDLE node_handle
Definition: demo_node_operator.c:44
MX_NODE_RESULT_BAD
Definition: mx_node_node_def.h:159
_MX_NODE_VARIANT::s
char * s
Definition: mx_node_node_def.h:113
_MX_NODE_VARIANT::value
union _MX_NODE_VARIANT::@0 value
_MY_DATA::timestamp
struct timeval timestamp
Definition: demo_node_operator.c:46
MX_NODE_VALUE_TYPE_UINT64
Definition: mx_node_node_def.h:76
_MY_DATA
Definition: demo_node_operator.c:42
OPERATOR_STATE_STOP
Definition: demo_node_operator.c:37
_MX_NODE_NODE::node_type
MX_NODE_NODE_TYPE node_type
Definition: mx_node_node_def.h:143
mx_node_operator_initialize
MX_NODE_RESULT mx_node_operator_initialize(MX_NODE_NODE_OPERATOR_HANDLE operator_handle)
Do node operator&#39;s initialize, like create nodes.
mx_node_update_node
MX_NODE_RESULT mx_node_update_node(MX_NODE_NODE_HANDLE node_handle, MX_NODE_VARIANT *value, struct timeval *timestamp)
Update a node&#39;s data and timestamp.
g_operator_handle
MX_NODE_NODE_OPERATOR_HANDLE g_operator_handle
Definition: demo_node_operator.c:53
MX_NODE_NODE_OPERATOR_HANDLE
size_t MX_NODE_NODE_OPERATOR_HANDLE
Handle of a node operator.
Definition: mx_node_node.h:37
OPERATOR_STATE
OPERATOR_STATE
custom define
Definition: demo_node_operator.c:35