29#ifndef PROTOCORE_DNP3_H
30#define PROTOCORE_DNP3_H
39#define DNP3_START0 0x05
40#define DNP3_START1 0x64
41#define DNP3_MAX_USER_DATA 250
45#define DNP3_BLOCK_LEN 16
47#define DNP3_HEADER_LEN 8
48#define DNP3_HEADER_BLOCK_LEN 10
49#define DNP3_LEN_OVERHEAD 5
52uint16_t pc_dnp3_crc(
const uint8_t *data,
size_t len);
61size_t pc_dnp3_build_frame(uint8_t *buf,
size_t cap, uint8_t control, uint16_t dest, uint16_t src,
62 const uint8_t *user_data,
size_t user_data_len);
81bool pc_dnp3_parse_frame(
const uint8_t *buf,
size_t len, Dnp3Frame *out, uint8_t *out_user,
size_t out_cap,
82 size_t *out_user_len);
91#define DNP3_TR_FIN 0x80u
92#define DNP3_TR_FIR 0x40u
93#define DNP3_TR_SEQ_MASK 0x3Fu
94#define DNP3_TR_MAX_APP 249
97uint8_t pc_dnp3_transport_header(
bool fir,
bool fin, uint8_t seq);
103size_t pc_dnp3_build_transport_segment(uint8_t *out,
size_t cap,
bool fir,
bool fin, uint8_t seq,
104 const uint8_t *app_data,
size_t app_len);
107enum Dnp3TransportResult
116struct Dnp3TransportRx
127void pc_dnp3_transport_rx_init(Dnp3TransportRx *r, uint8_t *buf,
size_t cap);
133int pc_dnp3_transport_feed(Dnp3TransportRx *r,
const uint8_t *user,
size_t user_len);
143#define DNP3_AC_FIR 0x80u
144#define DNP3_AC_FIN 0x40u
145#define DNP3_AC_CON 0x20u
146#define DNP3_AC_UNS 0x10u
147#define DNP3_AC_SEQ_MASK 0x0Fu
150#define DNP3_FC_CONFIRM 0x00u
151#define DNP3_FC_READ 0x01u
152#define DNP3_FC_WRITE 0x02u
153#define DNP3_FC_SELECT 0x03u
154#define DNP3_FC_OPERATE 0x04u
155#define DNP3_FC_DIRECT_OPERATE 0x05u
156#define DNP3_FC_DIRECT_OPERATE_NR 0x06u
157#define DNP3_FC_COLD_RESTART 0x0Du
158#define DNP3_FC_WARM_RESTART 0x0Eu
159#define DNP3_FC_RESPONSE 0x81u
160#define DNP3_FC_UNSOLICITED_RESPONSE 0x82u
163#define DNP3_IIN_BROADCAST 0x0001u
164#define DNP3_IIN_CLASS1_EVENTS 0x0002u
165#define DNP3_IIN_CLASS2_EVENTS 0x0004u
166#define DNP3_IIN_CLASS3_EVENTS 0x0008u
167#define DNP3_IIN_NEED_TIME 0x0010u
168#define DNP3_IIN_LOCAL_CONTROL 0x0020u
169#define DNP3_IIN_DEVICE_TROUBLE 0x0040u
170#define DNP3_IIN_DEVICE_RESTART 0x0080u
171#define DNP3_IIN_FUNC_NOT_SUPPORTED 0x0100u
172#define DNP3_IIN_OBJECT_UNKNOWN 0x0200u
173#define DNP3_IIN_PARAM_ERROR 0x0400u
174#define DNP3_IIN_EVENT_OVERFLOW 0x0800u
175#define DNP3_IIN_ALREADY_EXECUTING 0x1000u
176#define DNP3_IIN_CONFIG_CORRUPT 0x2000u
190 const uint8_t *objects;
195uint8_t pc_dnp3_app_control(
bool fir,
bool fin,
bool con,
bool uns, uint8_t seq);
201size_t pc_dnp3_build_app_request(uint8_t *out,
size_t cap, uint8_t app_control, uint8_t fc,
const uint8_t *objects,
208size_t pc_dnp3_build_app_response(uint8_t *out,
size_t cap, uint8_t app_control, uint8_t fc, uint16_t iin,
209 const uint8_t *objects,
size_t obj_len);
215bool pc_dnp3_parse_app_header(
const uint8_t *frag,
size_t len, Dnp3AppHeader *out);
221#define DNP3_QUAL_PREFIX_MASK 0x70u
222#define DNP3_QUAL_PREFIX_SHIFT 4u
223#define DNP3_QUAL_RANGE_MASK 0x0Fu
226#define DNP3_RANGE_START_STOP_1 0x00u
227#define DNP3_RANGE_START_STOP_2 0x01u
228#define DNP3_RANGE_START_STOP_4 0x02u
229#define DNP3_RANGE_NO_RANGE 0x06u
230#define DNP3_RANGE_COUNT_1 0x07u
231#define DNP3_RANGE_COUNT_2 0x08u
232#define DNP3_RANGE_COUNT_4 0x09u
235struct Dnp3ObjectHeader
246 const uint8_t *objects;
255bool pc_dnp3_parse_object_header(
const uint8_t *buf,
size_t len, Dnp3ObjectHeader *out);
263size_t pc_dnp3_build_object_header_range(uint8_t *buf,
size_t cap, uint8_t group, uint8_t variation, uint32_t start,
270size_t pc_dnp3_build_object_header_all(uint8_t *buf,
size_t cap, uint8_t group, uint8_t variation);
275#define DNP3_CROB_LEN 11
278#define DNP3_CROB_OP_NUL 0x00u
279#define DNP3_CROB_OP_PULSE_ON 0x01u
280#define DNP3_CROB_OP_PULSE_OFF 0x02u
281#define DNP3_CROB_OP_LATCH_ON 0x03u
282#define DNP3_CROB_OP_LATCH_OFF 0x04u
285#define DNP3_CROB_TCC_NUL 0x00u
286#define DNP3_CROB_TCC_CLOSE 0x01u
287#define DNP3_CROB_TCC_TRIP 0x02u
296size_t pc_dnp3_build_crob(uint8_t *buf,
size_t cap, uint8_t op_type, uint8_t tcc,
bool clear, uint8_t count,
297 uint32_t on_time_ms, uint32_t off_time_ms);
303#define DNP3_AOB_LEN 5
311size_t pc_dnp3_build_aob32(uint8_t *buf,
size_t cap, int32_t value);
318size_t pc_dnp3_build_aob_float(uint8_t *buf,
size_t cap,
float value);
User-facing configuration for ProtoCore.