51#ifndef PROTOCORE_OPCUA_H
52#define PROTOCORE_OPCUA_H
72void pc_ua_w_u8(UaWriter *w, uint8_t v);
73void pc_ua_w_u16(UaWriter *w, uint16_t v);
74void pc_ua_w_u32(UaWriter *w, uint32_t v);
75void pc_ua_w_u64(UaWriter *w, uint64_t v);
76void pc_ua_w_i32(UaWriter *w, int32_t v);
77void pc_ua_w_f32(UaWriter *w,
float v);
78void pc_ua_w_f64(UaWriter *w,
double v);
79void pc_ua_w_bool(UaWriter *w,
bool v);
81void pc_ua_w_string(UaWriter *w,
const char *s, int32_t len);
91uint8_t pc_ua_r_u8(UaReader *r);
92uint16_t pc_ua_r_u16(UaReader *r);
93uint32_t pc_ua_r_u32(UaReader *r);
94uint64_t pc_ua_r_u64(UaReader *r);
95int32_t pc_ua_r_i32(UaReader *r);
96float pc_ua_r_f32(UaReader *r);
97double pc_ua_r_f64(UaReader *r);
98bool pc_ua_r_bool(UaReader *r);
104bool pc_ua_r_string(UaReader *r,
char *out,
size_t cap, int32_t *out_len);
119bool pc_opcua_parse_header(
const uint8_t *buf,
size_t len, UaMsgHeader *h);
128 uint32_t protocol_version;
129 uint32_t recv_buf_size;
130 uint32_t send_buf_size;
131 uint32_t max_msg_size;
132 uint32_t max_chunk_count;
136bool pc_opcua_parse_hello(
const uint8_t *msg,
size_t len, OpcUaHello *out);
143size_t pc_opcua_build_ack(
const OpcUaHello *hello, uint8_t *out,
size_t cap);
146#define PC_OPCUA_BAD_TCP_MESSAGE_TYPE_INVALID 0x807E0000u
147#define PC_OPCUA_BAD_TCP_MESSAGE_TOO_LARGE 0x80800000u
148#define PC_OPCUA_BAD_TCP_NOT_ENOUGH_RESOURCES 0x80810000u
149#define PC_OPCUA_BAD_TCP_INTERNAL_ERROR 0x80820000u
157size_t pc_opcua_build_error(uint32_t error_code,
const char *reason, uint8_t *out,
size_t cap);
172void pc_ua_w_nodeid_numeric(UaWriter *w, uint16_t ns, uint32_t
id);
178bool pc_ua_r_nodeid(UaReader *r, UaNodeId *out);
181int64_t pc_opcua_filetime_from_unix(int64_t unix_seconds);
184#define OPCUA_ID_OPEN_REQ 446
185#define OPCUA_ID_OPEN_RESP 449
188#define OPCUA_POLICY_NONE_URI "http://opcfoundation.org/UA/SecurityPolicy#None"
195struct OpcUaOpenChannel
197 uint32_t secure_channel_id;
198 uint32_t sequence_number;
200 uint32_t request_handle;
201 uint32_t client_protocol_version;
202 uint32_t security_token_request_type;
203 uint32_t message_security_mode;
204 uint32_t requested_lifetime;
208bool pc_opcua_parse_open(
const uint8_t *msg,
size_t len, OpcUaOpenChannel *out);
220size_t pc_opcua_build_open_response(
const OpcUaOpenChannel *req, uint32_t channel_id, uint32_t token_id,
221 uint32_t seq_number, int64_t now_ft, uint32_t lifetime, uint8_t *out,
size_t cap);
228#define OPCUA_ID_CREATE_SESSION_REQ 461
229#define OPCUA_ID_CREATE_SESSION_RESP 464
230#define OPCUA_ID_ACTIVATE_SESSION_REQ 467
231#define OPCUA_ID_ACTIVATE_SESSION_RESP 470
236 uint32_t secure_channel_id;
238 uint32_t sequence_number;
241 uint32_t request_handle;
249bool pc_opcua_parse_msg(
const uint8_t *msg,
size_t len, OpcUaMsg *out);
252struct OpcUaServerInfo
254 const char *endpoint_url;
255 const char *application_uri;
256 const char *application_name;
272size_t pc_opcua_build_create_session_response(
const OpcUaMsg *req, uint32_t session_id, uint32_t auth_token,
273 double revised_timeout,
const OpcUaServerInfo *info, uint32_t seq,
274 int64_t now_ft, uint8_t *out,
size_t cap);
281size_t pc_opcua_build_activate_session_response(
const OpcUaMsg *req, uint32_t seq, int64_t now_ft, uint8_t *out,
289#define OPCUA_ID_READ_REQ 631
290#define OPCUA_ID_READ_RESP 634
293#define OPCUA_ATTR_VALUE 13
296#define OPCUA_STATUS_GOOD 0x00000000u
297#define OPCUA_STATUS_BAD_NODE_ID_UNKNOWN 0x80340000u
300enum class OpcUaVariantType : uint8_t
305 OPCUA_VAR_UINT32 = 7,
307 OPCUA_VAR_UINT64 = 9,
308 OPCUA_VAR_FLOAT = 10,
309 OPCUA_VAR_DOUBLE = 11,
310 OPCUA_VAR_STRING = 12,
316 OpcUaVariantType type;
329void pc_ua_w_variant(UaWriter *w,
const OpcUaVariant *v);
332void pc_ua_w_datavalue(UaWriter *w,
const OpcUaVariant *v, uint32_t status);
338bool pc_ua_r_variant(UaReader *r, OpcUaVariant *out);
346bool pc_ua_r_datavalue(UaReader *r, OpcUaVariant *out_value, uint32_t *out_status);
358struct OpcUaReadRequest
363 OpcUaReadItem items[PC_OPCUA_READ_MAX];
367bool pc_opcua_parse_read(
const uint8_t *msg,
size_t len, OpcUaReadRequest *out);
375size_t pc_opcua_build_read_response(
const OpcUaReadRequest *req,
const OpcUaVariant *values,
const uint32_t *statuses,
376 uint32_t seq, int64_t now_ft, uint8_t *out,
size_t cap);
382typedef bool (*OpcUaReadHandler)(uint16_t ns, uint32_t id, uint32_t attribute, OpcUaVariant *out);
385void pc_opcua_set_read_handler(OpcUaReadHandler fn);
392#define OPCUA_ID_BROWSE_REQ 527
393#define OPCUA_ID_BROWSE_RESP 530
394#define OPCUA_ID_CLOSE_SESSION_REQ 473
395#define OPCUA_ID_CLOSE_SESSION_RESP 476
398#define OPCUA_NODECLASS_OBJECT 1
399#define OPCUA_NODECLASS_VARIABLE 2
400#define OPCUA_REFTYPE_ORGANIZES 35
401#define OPCUA_REFTYPE_HAS_COMPONENT 47
402#define OPCUA_TYPEDEF_BASE_OBJECT 58
403#define OPCUA_TYPEDEF_BASE_DATA_VARIABLE 63
406void pc_ua_w_qualifiedname(UaWriter *w, uint16_t ns,
const char *name);
409void pc_ua_w_localizedtext(UaWriter *w,
const char *locale,
const char *text);
414 uint32_t ref_type_id;
418 uint16_t browse_name_ns;
419 const char *browse_name;
420 const char *display_name;
422 uint32_t type_def_id;
426void pc_ua_w_reference(UaWriter *w,
const OpcUaReference *ref);
429struct OpcUaBrowseItem
437struct OpcUaBrowseRequest
442 OpcUaBrowseItem items[PC_OPCUA_BROWSE_MAX];
446bool pc_opcua_parse_browse(
const uint8_t *msg,
size_t len, OpcUaBrowseRequest *out);
453typedef int32_t (*OpcUaBrowseHandler)(uint16_t ns, uint32_t id, OpcUaReference *out, uint32_t max);
456void pc_opcua_set_browse_handler(OpcUaBrowseHandler fn);
463size_t pc_opcua_build_browse_response(
const OpcUaBrowseRequest *req, OpcUaBrowseHandler handler, uint32_t seq,
464 int64_t now_ft, uint8_t *out,
size_t cap);
467size_t pc_opcua_build_close_session_response(
const OpcUaMsg *req, uint32_t seq, int64_t now_ft, uint8_t *out,
475#define OPCUA_ID_GET_ENDPOINTS_REQ 428
476#define OPCUA_ID_GET_ENDPOINTS_RESP 431
477#define OPCUA_ID_SERVICE_FAULT 397
480#define OPCUA_STATUS_BAD_SERVICE_UNSUPPORTED 0x800B0000u
483void pc_ua_w_endpoint_description(UaWriter *w,
const OpcUaServerInfo *info);
486size_t pc_opcua_build_get_endpoints_response(
const OpcUaMsg *req,
const OpcUaServerInfo *info, uint32_t seq,
487 int64_t now_ft, uint8_t *out,
size_t cap);
493size_t pc_opcua_build_service_fault(
const OpcUaMsg *req, uint32_t service_result, uint32_t seq, int64_t now_ft,
494 uint8_t *out,
size_t cap);
497void pc_opcua_set_endpoint_url(
const char *url);
504#define OPCUA_ID_WRITE_REQ 673
505#define OPCUA_ID_WRITE_RESP 676
508#define OPCUA_STATUS_BAD_NOT_WRITABLE 0x803B0000u
521struct OpcUaWriteRequest
526 OpcUaWriteItem items[PC_OPCUA_WRITE_MAX];
530bool pc_opcua_parse_write(
const uint8_t *msg,
size_t len, OpcUaWriteRequest *out);
537size_t pc_opcua_build_write_response(
const OpcUaWriteRequest *req,
const uint32_t *results, uint32_t seq,
538 int64_t now_ft, uint8_t *out,
size_t cap);
545typedef uint32_t (*OpcUaWriteHandler)(uint16_t ns, uint32_t id, uint32_t attribute,
const OpcUaVariant *value);
548void pc_opcua_set_write_handler(OpcUaWriteHandler fn);
564void pc_opcua_rx(uint8_t slot);
User-facing configuration for ProtoCore.
Per-protocol connection event/poll callbacks (Layer 5 dispatch vtable).