tutorial/opcua/node/README.md
Go to the documentation of this file.
1 
2 How to build node sample for Embedded OPC UA Server {#opcuaserver-sample}
3 ----
4 @brief Tutorial to add a node for Embedded OPC UA Server
5 
6 ## Moxa Embedded OPC UA Server Introduction
7 
8 MOXA Embedded OPC UA Server is constructed of multiple node operators. Each node operator has the capability to build the node hierarchy and the detail information of each node. e.g. the node name, the updated values etc....
9 
10 Besides the basic operation, OPC UA server supports the data access feature. When OPC UA client would like to write the value of the node immediately, the API in the interface of node operator is actively invoked by OPC UA server to support this feature and provide the operation result.
11 
12 ## Node Operator Introduction
13 
14 Node operator is builded as shared library and it can select which feature it supported. If it supports the specific feature, it should implement the specific interfaces and structures that OPC UA server defined like data access. OPC UA server actively invokes the API in specific interface of a node operator to achieve the corresponding behaviors.
15 
16 Besides implementing the interface desgined for the node operator, OPC UA server provides the node related API to add/update nodes.
17 To learn making a node operator by modifing sample node operator, the sample code is in ```sample/mx_node_sdk/c/example/sample_node_operator.c```.
18 
19 ## Add a node to OPC UA server
20 
21 Add a node as folder node's child.
22 ``` c
23 MX_NODE_RESULT mx_node_operator_initialize(MX_NODE_NODE_OPERATOR_HANDLE operator_handle)
24 {
25  ...
26 
27  MX_NODE_NODE_HANDLE double_handle;
28  MX_NODE_NODE var_double;
29 
30  // Fill in SampleDouble's information.
31  strcpy(var_double.node_name, "SampleDouble");
32  var_double.node_type = MX_NODE_NODE_TYPE_VARIABLE;
33  strcpy(var_double.description, "SampleDouble's Description");
34  var_double.variable.access_right = MX_NODE_ACCESS_RIGHT_READWRITE;
35  var_double.variable.value.type = MX_NODE_VALUE_TYPE_DOUBLE;
36  var_double.variable.value.value.d = 0.0;
37 
38  // Add SampleDouble to OPC UA server.
39  mx_node_add_node(operator_handle, &var_double, &double_handle);
40 
41  // Set SampleDouble's parent to SampleFolder.
42  mx_node_set_parent_node(double_handle, folder_handle);
43 
44  ...
45 
46  return MX_NODE_RESULT_GOOD;
47 }
48 ```
49 ![add_node][add_node]
50 
51 ## Update a node to OPC UA server
52 
53 Update the node SampleDouble.
54 ``` c
55 void mx_node_operator_start()
56 {
57  g_state = OPERATOR_STATE_RUNNING;
58  while (g_state == OPERATOR_STATE_RUNNING)
59  {
60  ...
61 
62  MX_NODE_VARIANT var_double;
63  var_double.type = MX_NODE_VALUE_TYPE_DOUBLE;
64  var_double.value.d = 5.5;
65  struct timeval timestamp = now();
66  mx_node_update_node(double_handle, &var_double, &timestamp);
67 
68  sleep(3);
69  }
70  g_state = OPERATOR_STATE_STOP;
71 }
72 ```
73 ![update_node][update_node]
74 
75 ## Handle data access requests from OPC UA client
76 
77 Handle a read request from OPC UA client.
78 ``` c
79 MX_NODE_RESULT mx_node_operator_read_node(MX_NODE_NODE_HANDLE node_handle, MX_NODE_VARIANT* node_value, struct timeval* node_timestamp)
80 {
81  if (node_handle == g_my_node.node_handle)
82  {
83  ...
84  }
85  else if (node_handle == double_handle)
86  {
87  node_value->type = MX_NODE_VALUE_TYPE_DOUBLE;
88  node_value->value.d = 9.3;
89  *node_timestamp = now();
90  return MX_NODE_RESULT_GOOD;
91  }
92  return MX_NODE_RESULT_BAD;
93 }
94 ```
95 ![read_node][read_node]
96 
97 ## Build node operator
98 
99 The example project path is ```~/sample/mx_node_sdk/c/example/```, there are 4 files, ```sample_node_operator.c```, ```CMakeLists.txt```, ```toolchain-native.cmake``` and ```toolchain-cross.cmake```.
100 Please execute follow commands to build node operator, the output file **liboperator.so** is in ```~/sample/mx_node_sdk/c/example```.
101 
102 ### Build native toolchain
103 
104 ```
105 moxa@Moxa:~/sample/mx_node_sdk/c/example$ cmake . -DCMAKE_TOOLCHAIN_FILE=toolchain-native.cmake
106 moxa@Moxa:~/sample/mx_node_sdk/c/example$ make
107 ```
108 
109 ### Build cross toolchain
110 
111 ```
112 moxa@Moxa:~/sample/mx_node_sdk/c/example$ cmake . -DCMAKE_TOOLCHAIN_FILE=toolchain-cross.cmake
113 moxa@Moxa:~/sample/mx_node_sdk/c/example$ make
114 ```
115 
116 ## Deploy node operator
117 
118 ```
119 moxa@Moxa:~/sample/mx_node_sdk/c/example$ mkdir /usr/local/bin/embeddedopcuaserver/OperatorLib/example
120 moxa@Moxa:~/sample/mx_node_sdk/c/example$ cp liboperator.so /usr/local/bin/embeddedopcuaserver/OperatorLib/example/
121 ```
122 
123 ## Location for OPC UA client certificate
124 
125 Put OPC UA client certificate to ```/usr/local/bin/embeddedopcuaserver/mxopcserver/certificationstores/trusted/certs/```
126 
127 ## Execute OPC UA server
128 
129 ```
130 moxa@Moxa:~$ sudo systemctl start embedded-opcua-server
131 moxa@Moxa:~$ sudo systemctl stop embedded-opcua-server
132 moxa@Moxa:~$ sudo systemctl restart embedded-opcua-server
133 moxa@Moxa:~$ sudo systemctl status embedded-opcua-server
134 moxa@Moxa:~$ sudo systemctl disable embedded-opcua-server
135 moxa@Moxa:~$ sudo systemctl enable embedded-opcua-server
136 ```
137 
138 ## Security policy for OPC UA server
139 
140 * None - None
141 * Basic128Rsa15 - Sign
142 * Basic128Rsa15 - Sign & Encrypt
143 * Basic256 - Sign
144 * Basic256 - Sign & Encrypt
145 * Basic256Sha256 - Sign
146 * Basic256Sha256 - Sign & Encrypt
147 
148 ## Add/Delete OPC UA server account
149 
150 ```
151 moxa@Moxa:~$ sudo opcuauser --add moxa
152 moxa@Moxa:~$ sudo opcuauser --del moxa
153 
154 moxa@Moxa:~$ sudo opcuauser --help
155 Usage: opcuauser [options] username
156 
157 Options:
158  -a, --add Add user account
159  -d, --del Delete user account
160  -c, --change Change user password
161  -v, --verion Show version
162  -h, --help Show help
163 
164 Example:
165  opcuauser Add user account
166  opcuauser username Change user password
167  opcuauser --help Show help
168 ```
169 
170 Please notice that embedded-opcua-server should be reboot to take effect of user account list.
171 Current user account list can be verify by checking ```/etc/opcuauser_passwd```.
172 
173 [comment]: # (Images)
174 [add_node]: images/add_node.png
175 [update_node]: images/update_node.png
176 [read_node]: images/read_node.png