mirror of https://gerrit.osmocom.org/osmo-tetra
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
This commit is contained in:
parent
fde3a8c7da
commit
75c33d9d7e
|
@ -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
|
||||
|
|
|
@ -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 @@ 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("<<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 @@ 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;
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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];
|
||||
|
||||
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue