#ifndef TETRA_LLC_PDU_H #define TETRA_LLC_PDU_H #include #include /* Table 21.1 */ enum tetra_llc_pdu_t { TLLC_PDUT_BL_ADATA = 0, TLLC_PDUT_BL_DATA = 1, TLLC_PDUT_BL_UDATA = 2, TLLC_PDUT_BL_ACK = 3, TLLC_PDUT_BL_ADATA_FCS = 4, TLLC_PDUT_BL_DATA_FCS = 5, TLLC_PDUT_BL_UDATA_FCS = 6, TLLC_PDUT_BL_ACK_FCS = 7, TLLC_PDUT_AL_SETUP = 8, TLLC_PDUT_AL_DATA_FINAL = 9, TLLC_PDUT_AL_UDATA_UFINAL = 10, TLLC_PDUT_AL_ACK_RNR = 11, TLLC_PDUT_AL_RECONNECT = 12, TLLC_PDUT_SUPPL = 13, TLLC_PDUT_L2SIG = 14, TLLD_PDUT_AL_DISC = 15 }; const char *tetra_get_llc_pdut_name(uint8_t pdut); /* Table 21.2 */ enum tetra_llc_l2sig_pdu_t { TLLC_PDUT_L2_DATA_PRIO = 0, TLLC_PDUT_L2_SCHEDULE_SYNC = 1, TLLC_PDUT_L2_LINK_FB_CTRL = 2, TLLC_PDUT_L2_LINK_FB_INFO = 3, TLLC_PDUT_L2_LINK_FB_INFO_RD_PRIO = 4 }; /* Table 21.3 */ enum tetra_llc_suppl_pdu_t { TLLC_PDUT_SUPPL_ALX_DATA_FINAL = 0, TLLC_PDUT_SUPPL_ALX_UDATA_UFINAL = 1, TLLC_PDUT_SUPPL_ALX_ACK_RNR = 2 }; /* Decoded */ enum tllc_pdut_dec { TLLC_PDUT_DEC_UNKNOWN, TLLC_PDUT_DEC_BL_ADATA, TLLC_PDUT_DEC_BL_DATA, TLLC_PDUT_DEC_BL_UDATA, TLLC_PDUT_DEC_BL_ACK, TLLC_PDUT_DEC_AL_SETUP, TLLC_PDUT_DEC_AL_DATA, TLLC_PDUT_DEC_AL_FINAL, TLLC_PDUT_DEC_AL_UDATA, TLLC_PDUT_DEC_AL_UFINAL, TLLC_PDUT_DEC_AL_ACK, TLLC_PDUT_DEC_AL_RNR, TLLC_PDUT_DEC_AL_RECONNECT, TLLC_PDUT_DEC_AL_DISC, TLLC_PDUT_DEC_ALX_DATA, TLLC_PDUT_DEC_ALX_FINAL, TLLC_PDUT_DEC_ALX_UDATA, TLLC_PDUT_DEC_ALX_UFINAL, TLLC_PDUT_DEC_ALX_ACK, TLLC_PDUT_DEC_ALX_RNR, }; const char *tetra_get_llc_pdut_dec_name(enum tllc_pdut_dec pdut); /* decoded/parsed PDU with easier encoding */ struct tetra_llc_pdu { enum tllc_pdut_dec pdu_type; uint8_t nr; /* N(R) PDU number (receive) */ uint8_t ns; /* N(S) PDU number (sent) */ uint8_t ss; /* S(S) Segment (sent) */ bool have_fcs; /* 1 if LLC PDU defines FCS is present */ uint32_t fcs; /* FCS value extracted from pdu */ bool fcs_invalid; /* 1 if extracted FCS does not match computed FCS */ uint8_t *tl_sdu; /* pointer to bitbuf */ uint32_t tl_sdu_len; /* in bits */ }; /* parse a received LLC PDU and parse it into 'lpp' */ int tetra_llc_pdu_parse(struct tetra_llc_pdu *lpp, uint8_t *buf, int len); /* TETRA LLC state */ struct tllc_state { struct llist_head list; struct { struct llist_head defrag_list; } rx; }; /* entry in the defragmentation queue */ struct tllc_defrag_q_e { struct llist_head list; unsigned int ns; /* current de-fragmenting */ unsigned int last_ss; /* last received S(S) */ struct msgb *tl_sdu; }; #endif /* TETRA_LLC_PDU_H */