diff --git a/src/Makefile b/src/Makefile index b21f846..41250a9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,7 +13,7 @@ debug: all libosmo-tetra-phy.a: phy/tetra_burst_sync.o phy/tetra_burst.o $(AR) r $@ $^ -libosmo-tetra-mac.a: lower_mac/tetra_conv_enc.o lower_mac/tch_reordering.o tetra_tdma.o lower_mac/tetra_scramb.o lower_mac/tetra_rm3014.o lower_mac/tetra_interleave.o lower_mac/crc_simple.o tetra_common.o lower_mac/viterbi.o lower_mac/viterbi_cch.o lower_mac/viterbi_tch.o lower_mac/tetra_lower_mac.o tetra_upper_mac.o tetra_mac_pdu.o tetra_llc_pdu.o tetra_llc.o tetra_mle_pdu.o tetra_mm_pdu.o tetra_cmce_pdu.o tetra_sndcp_pdu.o tetra_gsmtap.o tuntap.o +libosmo-tetra-mac.a: lower_mac/tetra_conv_enc.o lower_mac/tch_reordering.o tetra_tdma.o lower_mac/tetra_scramb.o lower_mac/tetra_rm3014.o lower_mac/tetra_interleave.o lower_mac/crc_simple.o tetra_common.o lower_mac/viterbi.o lower_mac/viterbi_cch.o lower_mac/viterbi_tch.o lower_mac/tetra_lower_mac.o tetra_upper_mac.o tetra_mac_pdu.o tetra_llc_pdu.o tetra_llc.o tetra_mle_pdu.o tetra_mle.o tetra_mm_pdu.o tetra_cmce_pdu.o tetra_sndcp_pdu.o tetra_gsmtap.o tuntap.o $(AR) r $@ $^ float_to_bits: float_to_bits.o diff --git a/src/tetra_llc.c b/src/tetra_llc.c index e0d5cab..b8a378d 100644 --- a/src/tetra_llc.c +++ b/src/tetra_llc.c @@ -28,6 +28,7 @@ #include #include "tetra_llc_pdu.h" +#include "tetra_mle.h" #include "tuntap.h" static int tun_fd = -1; @@ -36,8 +37,6 @@ static struct tllc_state g_llcs = { .rx.defrag_list = LLIST_HEAD_INIT(g_llcs.rx.defrag_list), }; -int rx_tl_sdu(struct msgb *msg, unsigned int len); - static struct tllc_defrag_q_e * get_dqe_for_ns(struct tllc_state *llcs, uint8_t ns, int alloc_if_missing) { @@ -79,8 +78,7 @@ static int tllc_defrag_in(struct tllc_state *llcs, return 0; } -static int tllc_defrag_out(struct tllc_state *llcs, - struct tetra_llc_pdu *lpp) +static int tllc_defrag_out(struct tetra_mac_state *tms, struct tllc_state *llcs, struct tetra_llc_pdu *lpp) { struct tllc_defrag_q_e *dqe; struct msgb *msg; @@ -90,7 +88,7 @@ static int tllc_defrag_out(struct tllc_state *llcs, printf("<> "); msg->l3h = msg->data; - rx_tl_sdu(msg, msgb_l3len(msg)); + rx_tl_sdu(tms, msg, msgb_l3len(msg)); if (tun_fd < 0) { tun_fd = tun_alloc("tun0"); @@ -110,16 +108,34 @@ static int tllc_defrag_out(struct tllc_state *llcs, /* Receive TM-SDU (MAC SDU == LLC PDU) */ /* this resembles TMA-UNITDATA.ind (TM-SDU / length) */ -int rx_tm_sdu(struct msgb *msg, unsigned int len) +int rx_tm_sdu(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len) { - struct tetra_llc_pdu lpp; + if (!len) { + return -1; + } else if (len < 4) { + printf("WARNING rx_tm_sdu: l2len too small: %d\n", len); + return -1; + } + struct tetra_llc_pdu lpp; memset(&lpp, 0, sizeof(lpp)); tetra_llc_pdu_parse(&lpp, msg->l2h, len); msg->l3h = lpp.tl_sdu; + msg->tail = msg->l3h + lpp.tl_sdu_len; // Strips off FCS (if present) - printf("TM-SDU(%s,%u,%u): ", - tetra_get_llc_pdut_dec_name(lpp.pdu_type), lpp.ns, lpp.ss); + printf("TM-SDU(%s)", tetra_get_llc_pdut_dec_name(lpp.pdu_type)); + if (lpp.have_fcs) { + printf(" fcs=%s ", (lpp.have_fcs && lpp.fcs_invalid ? "BAD" : "OK")); + } + printf(" l3len=%d", msgb_l3len(msg)); + if (msgb_l3len(msg)) { + printf(" %s", osmo_ubit_dump(msg->l3h, msgb_l3len(msg))); + } + printf("\n"); + + if (!lpp.tl_sdu_len) { + return len; + } switch (lpp.pdu_type) { case TLLC_PDUT_DEC_BL_ADATA: @@ -132,7 +148,7 @@ int rx_tm_sdu(struct msgb *msg, unsigned int len) case TLLC_PDUT_DEC_AL_RECONNECT: case TLLC_PDUT_DEC_AL_DISC: /* directly hand it to MLE */ - rx_tl_sdu(msg, lpp.tl_sdu_len); + rx_tl_sdu(tms, msg, lpp.tl_sdu_len); break; case TLLC_PDUT_DEC_AL_DATA: case TLLC_PDUT_DEC_AL_UDATA: @@ -148,7 +164,7 @@ int rx_tm_sdu(struct msgb *msg, unsigned int len) /* input into LLC defragmenter */ tllc_defrag_in(&g_llcs, &lpp, msg, len); /* check if the fragment is complete and hand it off*/ - tllc_defrag_out(&g_llcs, &lpp); + tllc_defrag_out(tms, &g_llcs, &lpp); break; case TLLC_PDUT_DEC_UNKNOWN: @@ -158,9 +174,5 @@ int rx_tm_sdu(struct msgb *msg, unsigned int len) break; } - if (lpp.tl_sdu && lpp.ss == 0) { - /* this resembles TMA-UNITDATA.ind */ - //rx_tl_sdu(msg, lpp.tl_sdu_len); - } return len; } diff --git a/src/tetra_llc.h b/src/tetra_llc.h new file mode 100644 index 0000000..134fdb5 --- /dev/null +++ b/src/tetra_llc.h @@ -0,0 +1,8 @@ +#ifndef TETRA_LLC_H +#define TETRA_LLC_H + +#include "tetra_common.h" + +int rx_tm_sdu(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len); + +#endif diff --git a/src/tetra_mle.c b/src/tetra_mle.c new file mode 100644 index 0000000..a957bc9 --- /dev/null +++ b/src/tetra_mle.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include "tetra_mle_pdu.h" +#include "tetra_mle.h" +#include "tetra_mm_pdu.h" +#include "tetra_cmce_pdu.h" +#include "tetra_sndcp_pdu.h" +#include "tetra_mle_pdu.h" + + + +/* Receive TL-SDU (LLC SDU == MLE PDU) */ +int rx_tl_sdu(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len) +{ + uint8_t *bits = msg->l3h; + uint8_t mle_pdisc = bits_to_uint(bits, 3); + + printf("TL-SDU(%s): %s ", tetra_get_mle_pdisc_name(mle_pdisc), + osmo_ubit_dump(bits, len)); + switch (mle_pdisc) { + case TMLE_PDISC_MM: + printf("%s\n", tetra_get_mm_pdut_name(bits_to_uint(bits+3, 4), 0)); + break; + case TMLE_PDISC_CMCE: + printf("%s\n", tetra_get_cmce_pdut_name(bits_to_uint(bits+3, 5), 0)); + break; + case TMLE_PDISC_SNDCP: + printf("%s ", tetra_get_sndcp_pdut_name(bits_to_uint(bits+3, 4), 0)); + printf(" NSAPI=%u PCOMP=%u, DCOMP=%u", + bits_to_uint(bits+3+4, 4), + bits_to_uint(bits+3+4+4, 4), + bits_to_uint(bits+3+4+4+4, 4)); + printf(" V%u, IHL=%u", + bits_to_uint(bits+3+4+4+4+4, 4), + 4*bits_to_uint(bits+3+4+4+4+4+4, 4)); + printf(" Proto=%u\n", + bits_to_uint(bits+3+4+4+4+4+4+4+64, 8)); + break; + case TMLE_PDISC_MLE: + printf("%s\n", tetra_get_mle_pdut_name(bits_to_uint(bits+3, 3), 0)); + break; + default: + break; + } + return len; +} diff --git a/src/tetra_mle.h b/src/tetra_mle.h new file mode 100644 index 0000000..1488eb4 --- /dev/null +++ b/src/tetra_mle.h @@ -0,0 +1,8 @@ +#ifndef TETRA_MLE_H +#define TETRA_MLE_H + +#include "tetra_common.h" + +int rx_tl_sdu(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len); + +#endif diff --git a/src/tetra_upper_mac.c b/src/tetra_upper_mac.c index 86c4439..ef5ce39 100644 --- a/src/tetra_upper_mac.c +++ b/src/tetra_upper_mac.c @@ -32,14 +32,9 @@ #include "tetra_upper_mac.h" #include "tetra_mac_pdu.h" #include "tetra_llc_pdu.h" -#include "tetra_mm_pdu.h" -#include "tetra_cmce_pdu.h" -#include "tetra_sndcp_pdu.h" -#include "tetra_mle_pdu.h" +#include "tetra_llc.h" #include "tetra_gsmtap.h" -static int rx_tm_sdu(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len); - /* FIXME move global fragslots to context variable */ struct fragslot fragslots[FRAGSLOT_NR_SLOTS] = {0}; @@ -144,64 +139,6 @@ const char *tetra_alloc_dump(const struct tetra_chan_alloc_decoded *cad, struct return buf; } -/* Receive TL-SDU (LLC SDU == MLE PDU) */ -static int rx_tl_sdu(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len) -{ - uint8_t *bits = msg->l3h; - uint8_t mle_pdisc = bits_to_uint(bits, 3); - - printf("TL-SDU(%s): %s", tetra_get_mle_pdisc_name(mle_pdisc), - osmo_ubit_dump(bits, len)); - switch (mle_pdisc) { - case TMLE_PDISC_MM: - printf(" %s", tetra_get_mm_pdut_name(bits_to_uint(bits+3, 4), 0)); - break; - case TMLE_PDISC_CMCE: - printf(" %s", tetra_get_cmce_pdut_name(bits_to_uint(bits+3, 5), 0)); - break; - case TMLE_PDISC_SNDCP: - printf(" %s", tetra_get_sndcp_pdut_name(bits_to_uint(bits+3, 4), 0)); - printf(" NSAPI=%u PCOMP=%u, DCOMP=%u", - bits_to_uint(bits+3+4, 4), - bits_to_uint(bits+3+4+4, 4), - bits_to_uint(bits+3+4+4+4, 4)); - printf(" V%u, IHL=%u", - bits_to_uint(bits+3+4+4+4+4, 4), - 4*bits_to_uint(bits+3+4+4+4+4+4, 4)); - printf(" Proto=%u", - bits_to_uint(bits+3+4+4+4+4+4+4+64, 8)); - break; - case TMLE_PDISC_MLE: - printf(" %s", tetra_get_mle_pdut_name(bits_to_uint(bits+3, 3), 0)); - break; - default: - break; - } - return len; -} - -static int rx_tm_sdu(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len) -{ - struct tetra_llc_pdu lpp; - uint8_t *bits = msg->l2h; - - memset(&lpp, 0, sizeof(lpp)); - tetra_llc_pdu_parse(&lpp, bits, len); - - printf("TM-SDU(%s,%u,%u)", - tetra_get_llc_pdut_dec_name(lpp.pdu_type), lpp.ns, lpp.ss); - if (lpp.have_fcs) { - printf("(FCS: %s)", lpp.fcs_invalid ? "BAD" : "OK"); - } - printf(": "); - - if (lpp.tl_sdu && lpp.ss == 0) { - msg->l3h = lpp.tl_sdu; - rx_tl_sdu(tms, msg, lpp.tl_sdu_len); - } - return len; -} - static int rx_resrc(struct tetra_tmvsap_prim *tmvp, struct tetra_mac_state *tms) { struct msgb *msg = tmvp->oph.msg; @@ -231,22 +168,26 @@ static int rx_resrc(struct tetra_tmvsap_prim *tmvp, struct tetra_mac_state *tms) /* We now have accurate length and start of TM-SDU, set LLC start in msg->l2h */ msg->l2h = msg->l1h + tmpdu_offset; - printf("RESOURCE Encr=%u, len=%d l1_len=%d l2_len %d Addr=%s ", + printf("RESOURCE Encr=%u len_field=%d l1_len=%d l2_len %d Addr=%s", rsd.encryption_mode, rsd.macpdu_length, msgb_l1len(msg), msgb_l2len(msg), tetra_addr_dump(&rsd.addr)); + if (rsd.chan_alloc_pres) + printf(" ChanAlloc=%s", tetra_alloc_dump(&rsd.cad, tms)); + + if (rsd.slot_granting.pres) + printf(" SlotGrant=%u/%u", rsd.slot_granting.nr_slots, + rsd.slot_granting.delay); + if (rsd.addr.type == ADDR_TYPE_NULL) { pdu_bits = -1; /* No more PDUs in slot */ goto out; } + if (msgb_l2len(msg) == 0) { + goto out; /* No l2 data */ + } - if (rsd.chan_alloc_pres) - printf("ChanAlloc=%s ", tetra_alloc_dump(&rsd.cad, tms)); - - if (rsd.slot_granting.pres) - printf("SlotGrant=%u/%u ", rsd.slot_granting.nr_slots, - rsd.slot_granting.delay); - + printf(": %s\n", osmo_ubit_dump(msg->l2h, msgb_l2len(msg))); if (rsd.macpdu_length != MACPDU_LEN_START_FRAG || !REASSEMBLE_FRAGMENTS) { /* Non-fragmented resource (or no reassembly desired) */ if (!rsd.is_encrypted) {