laforge submitted this change.
added support for advanced link defragmentation
the rx_tm_sdu and rx_tl_sdu did not belong in tetra_upper_mac and are removed. Instead, we use rx_tm_sdu in tetra_llc.c, who in turn invokes rx_tl_sdu in tetra_mle.c. The llc can now also make use of the advanced link defragmentation code that was already there but unused.
Change-Id: I294c684e97c55876f1a207a7152a83dad4ebaa26
---
M src/Makefile
M src/tetra_llc.c
A src/tetra_llc.h
A src/tetra_mle.c
A src/tetra_mle.h
M src/tetra_upper_mac.c
6 files changed, 110 insertions(+), 88 deletions(-)
diff --git a/src/Makefile b/src/Makefile
index b21f846..41250a9 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -13,7 +13,7 @@
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 <osmocom/core/bits.h>
#include "tetra_llc_pdu.h"
+#include "tetra_mle.h"
#include "tuntap.h"
static int tun_fd = -1;
@@ -36,8 +37,6 @@
.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 @@
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 @@
printf("<<REMOVE>> ");
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 @@
/* 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 @@
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 @@
/* 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 @@
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 <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/bits.h>
+
+#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 @@
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 @@
/* 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) {
To view, visit change 29405. To unsubscribe, or for help writing mail filters, visit settings.