const HParser* init_character_string() { static const HParser *cstr = NULL; if (cstr) return cstr; cstr = h_length_value(h_uint8(), h_uint8()); return cstr; }
void dnp3_p_init_transport(void) { H_RULE(bit, h_bits(1, false)); H_RULE(byte, h_uint8()); H_RULE(fir, bit); H_RULE(fin, bit); H_RULE(seqno, h_bits(6, false)); H_RULE(hdr, h_sequence(fin, fir, seqno, NULL)); // big-endian H_ARULE(segment, h_sequence(hdr, h_many(byte), NULL)); // XXX is there a minimum number of bytes in the transport payload? dnp3_p_transport_segment = segment; }
void dnp3_p_init_binoutcmd(void) { H_RULE (bit, h_bits(1, false)); H_RULE (cs, bit); H_RULE (status, h_bits(7, false)); H_ARULE(notime, h_sequence(status, cs, NULL)); H_ARULE(abstime, h_sequence(status, cs, dnp3_p_dnp3time, NULL)); H_RULE (tcc, h_int_range(h_bits(2, false), 0, 2)); H_ARULE(crob, h_sequence(h_bits(4, false), // op type bit, // queue flag (obsolete) bit, // clear flag tcc, h_uint8(), // count h_uint32(), // on-time [ms] h_uint32(), // off-time [ms] status, // 7 bits dnp3_p_reserved(1), NULL)); H_ARULE(packed, bit); // group 12 (binary output commands)... dnp3_p_g12v1_binoutcmd_crob_oblock = dnp3_p_oblock(G_V(BINOUTCMD, CROB), crob); dnp3_p_g12v2_binoutcmd_pcb_oblock = dnp3_p_single(G_V(BINOUTCMD, PCB), crob); dnp3_p_g12v3_binoutcmd_pcm_oblock = dnp3_p_oblock_packed(G_V(BINOUTCMD, PCM), packed); dnp3_p_g12v3_binoutcmd_pcm_rblock = dnp3_p_specific_rblock(G_V(BINOUTCMD, PCM)); dnp3_p_binoutcmd_rblock = dnp3_p_rblock(G(BINOUTCMD), V(BINOUTCMD, CROB), V(BINOUTCMD, PCB), V(BINOUTCMD, PCM), 0); // group 13 (binary output command events)... H_RULE(oblock_notime, dnp3_p_oblock(G_V(BINOUTCMDEV, NOTIME), notime)); H_RULE(oblock_abstime, dnp3_p_oblock(G_V(BINOUTCMDEV, ABSTIME), abstime)); dnp3_p_binoutcmdev_rblock = dnp3_p_rblock(G(BINOUTCMDEV), V(BINOUTCMDEV, NOTIME), V(BINOUTCMDEV, ABSTIME), 0); dnp3_p_binoutcmdev_oblock = h_choice(oblock_notime, oblock_abstime, NULL); }
const HParser* init_rdata(uint16_t type) { static const HParser *parsers[RDATA_TYPE_MAX+1]; static int inited = 0; if (type >= sizeof(parsers)) return NULL; if (inited) return parsers[type]; H_RULE (domain, init_domain()); H_ARULE(cstr, init_character_string()); H_RULE (a, h_uint32()); H_RULE (ns, domain); H_RULE (md, domain); H_RULE (mf, domain); H_RULE (cname, domain); H_ARULE(soa, h_sequence(domain, // MNAME domain, // RNAME h_uint32(), // SERIAL h_uint32(), // REFRESH h_uint32(), // RETRY h_uint32(), // EXPIRE h_uint32(), // MINIMUM NULL)); H_RULE (mb, domain); H_RULE (mg, domain); H_RULE (mr, domain); H_VRULE(null, h_many(h_uint8())); H_RULE (wks, h_sequence(h_uint32(), h_uint8(), h_many(h_uint8()), NULL)); H_RULE (ptr, domain); H_RULE (hinfo, h_sequence(cstr, cstr, NULL)); H_RULE (minfo, h_sequence(domain, domain, NULL)); H_RULE (mx, h_sequence(h_uint16(), domain, NULL)); H_ARULE(txt, h_many1(cstr)); parsers[ 0] = NULL; // there is no type 0 parsers[ 1] = a; parsers[ 2] = ns; parsers[ 3] = md; parsers[ 4] = mf; parsers[ 5] = cname; parsers[ 6] = soa; parsers[ 7] = mb; parsers[ 8] = mg; parsers[ 9] = mr; parsers[10] = null; parsers[11] = wks; parsers[12] = ptr; parsers[13] = hinfo; parsers[14] = minfo; parsers[15] = mx; parsers[16] = txt; // All parsers must consume their input exactly. for(uint16_t i; i<sizeof(parsers); i++) { if(parsers[i]) { parsers[i] = h_action(h_sequence(parsers[i], h_end_p(), NULL), act_index0); } } inited = 1; return parsers[type]; }