[PATCH 2/3] layer23 smscb: reassemble blocks and pass them up to L3

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/baseband-devel@lists.osmocom.org/.

Alex Badea vamposdecampos at gmail.com
Sun Nov 28 14:07:28 UTC 2010


We (re)construct an equivalent RSL_MT_SMS_BC_CMD from
received frames.

Signed-off-by: Alex Badea <vamposdecampos at gmail.com>
---
 src/host/layer23/include/osmocom/bb/common/smscb.h |    5 +
 src/host/layer23/src/common/smscb.c                |  177 +++++++++++++++++++-
 2 files changed, 176 insertions(+), 6 deletions(-)

diff --git a/src/host/layer23/include/osmocom/bb/common/smscb.h b/src/host/layer23/include/osmocom/bb/common/smscb.h
index d689cd7..a475a78 100644
--- a/src/host/layer23/include/osmocom/bb/common/smscb.h
+++ b/src/host/layer23/include/osmocom/bb/common/smscb.h
@@ -7,7 +7,12 @@ struct osmocom_ms;
 struct msgb;
 struct l1ctl_info_dl;
 
+#define SMSCB_MAX_BLOCKS	4
+
 struct smscb_entity {
+	uint8_t seq_next;
+	uint8_t sched:1;
+	struct msgb *blocks[SMSCB_MAX_BLOCKS];
 	struct osmocom_ms *ms;
 };
 
diff --git a/src/host/layer23/src/common/smscb.c b/src/host/layer23/src/common/smscb.c
index 31a5752..f520f25 100644
--- a/src/host/layer23/src/common/smscb.c
+++ b/src/host/layer23/src/common/smscb.c
@@ -21,26 +21,191 @@
  */
 
 #include <osmocom/bb/common/smscb.h>
+#include <osmocom/bb/common/lapdm.h>
 #include <osmocom/bb/common/logging.h>
 #include <osmocore/msgb.h>
+#include <osmocore/rsl.h>
+#include <osmocore/tlv.h>
+#include <osmocore/gsm_utils.h>
+#include <osmocore/protocol/gsm_04_12.h>
+#include <osmocore/protocol/gsm_08_58.h>
+
+#include <errno.h>
+#include <string.h>
+#include <netinet/in.h>
+
+#define SMSCB_LPD	1
+
+#define SMSCB_ALLOC_SIZE	256
+#define SMSCB_ALLOC_HEADROOM	64
+
+static void smscb_reset(struct smscb_entity *se)
+{
+	int k;
+
+	for (k = 0; k < SMSCB_MAX_BLOCKS; k++) {
+		msgb_free(se->blocks[k]);
+		se->blocks[k] = NULL;
+	}
+	se->sched = 0;
+	se->seq_next = 0;
+}
 
 void smscb_init(struct smscb_entity *se, struct osmocom_ms *ms)
 {
+	memset(se, 0, sizeof(*se));
 	se->ms = ms;
 }
 
 void smscb_exit(struct smscb_entity *se)
 {
+	smscb_reset(se);
+}
+
+static int smscb_rx_msg(struct smscb_entity *se, const struct l1ctl_info_dl *l1i)
+{
+	struct msgb *msg;
+	struct abis_rsl_cchan_hdr *ch;
+	int k;
+	uint8_t msglen, *tlv;
+	struct gsm_time tm;
+	struct rsl_ie_cb_cmd_type cmd_type = {};
+
+	msg = msgb_alloc_headroom(
+		SMSCB_ALLOC_HEADROOM + SMSCB_ALLOC_SIZE,
+		SMSCB_ALLOC_HEADROOM, "smscb_data");
+	if (!msg)
+		return -ENOMEM;
+
+	msg->l2h = msgb_put(msg, sizeof(*ch));
+	ch = (struct abis_rsl_cchan_hdr *) msg->l2h;
+	rsl_init_cchan_hdr(ch, RSL_MT_SMS_BC_CMD);
+	ch->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
+	ch->chan_nr = l1i->chan_nr;
+
+	cmd_type.command =
+		se->sched ? RSL_CB_CMD_TYPE_SCHEDULE :
+		RSL_CB_CMD_TYPE_NORMAL;
+	cmd_type.last_block =
+		se->blocks[3] ? RSL_CB_CMD_LASTBLOCK_4 :
+		se->blocks[2] ? RSL_CB_CMD_LASTBLOCK_3 :
+		se->blocks[1] ? RSL_CB_CMD_LASTBLOCK_2 :
+		RSL_CB_CMD_LASTBLOCK_1;
+	msgb_tv_put(msg, RSL_IE_CB_CMD_TYPE, *((uint8_t *) &cmd_type));
+
+	for (k = 0, msglen = 0; se->blocks[k] && k < SMSCB_MAX_BLOCKS; k++)
+		msglen += se->blocks[k]->len;
+	tlv = msgb_put(msg, TLV_GROSS_LEN(msglen));
+	*tlv++ = RSL_IE_SMSCB_MSG;
+	*tlv++ = msglen;
+	for (k = 0; se->blocks[k] && k < SMSCB_MAX_BLOCKS; k++) {
+		memcpy(tlv, se->blocks[k]->data, se->blocks[k]->len);
+		tlv += se->blocks[k]->len;
+	}
+
+	/*
+	 * TS 05.02 chapter 6.5.4: basic vs. extended CBCH
+	 * is indicated by multiframe number
+	 */
+	gsm_fn2gsmtime(&tm, ntohl(l1i->frame_nr));
+	msgb_tv_put(msg, RSL_IE_SMSCB_CHAN_INDICATOR, !(tm.tc < 4));
+
+	return rslms_sendmsg(msg, se->ms);
+}
+
+static int smscb_rx_null_msg(struct smscb_entity *se, const struct l1ctl_info_dl *l1i)
+{
+	struct msgb *msg;
+	struct abis_rsl_cchan_hdr *ch;
+	struct gsm_time tm;
+	struct rsl_ie_cb_cmd_type cmd_type = {};
+
+	msg = msgb_alloc_headroom(
+		SMSCB_ALLOC_HEADROOM + SMSCB_ALLOC_SIZE,
+		SMSCB_ALLOC_HEADROOM, "smscb_data");
+	if (!msg)
+		return -ENOMEM;
+
+	msg->l2h = msgb_put(msg, sizeof(*ch));
+	ch = (struct abis_rsl_cchan_hdr *) msg->l2h;
+	rsl_init_cchan_hdr(ch, RSL_MT_SMS_BC_CMD);
+	ch->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
+	ch->chan_nr = l1i->chan_nr;
+
+	cmd_type.command = RSL_CB_CMD_TYPE_NULL;
+	msgb_tv_put(msg, RSL_IE_CB_CMD_TYPE, *((uint8_t *) &cmd_type));
+	msgb_tlv_put(msg, RSL_IE_SMSCB_MSG, 0, NULL);
+
+	gsm_fn2gsmtime(&tm, ntohl(l1i->frame_nr));
+	msgb_tv_put(msg, RSL_IE_SMSCB_CHAN_INDICATOR, !(tm.tc < 4));
+
+	return rslms_sendmsg(msg, se->ms);
 }
 
 int smscb_ph_data_ind(struct smscb_entity *se, struct msgb *msg, struct l1ctl_info_dl *l1i)
 {
-	uint8_t addr = msg->l2h[0];
-	uint8_t seq = addr & 0x0f;
+	struct gsm412_block_type *bt = (struct gsm412_block_type *) msg->l2h;
+	uint8_t seq;
+	uint8_t last;
+
+	LOGP(DLAPDM, LOGL_NOTICE, "SMSCB: received message: len=%d"
+		" seq=%d lb=%d lpd=%d spare=%d\n",
+		msg->len, bt->seq_nr, bt->lb, bt->lpd, bt->spare);
+
+	if (bt->lpd != SMSCB_LPD) {
+		msgb_free(msg);
+		return -EINVAL;
+	}
+
+	msgb_pull(msg, sizeof(*bt));
+
+	seq = bt->seq_nr & 3;
+	last = bt->lb;
+
+	if (bt->seq_nr == GSM412_SEQ_NULL_MSG) {
+		smscb_rx_null_msg(se, l1i);
+		smscb_reset(se);
+		msgb_free(msg);
+		return 0;
+	}
+
+	if (seq != se->seq_next) {
+		LOGP(DLAPDM, LOGL_ERROR, "SMSCB: got sequence %d (expected %d)\n",
+			bt->seq_nr, se->seq_next);
+		smscb_reset(se);
+		if (seq) {
+			msgb_free(msg);
+			return -EINVAL;
+		}
+	}
 
-	LOGP(DLAPDM, LOGL_NOTICE, "SMSCB: received message: seq=%d len=%d\n",
-		seq, msg->len);
+	switch (bt->seq_nr) {
+	case GSM412_SEQ_FST_SCHED_BLOCK:
+		se->sched = 1;
+		break;
+	case GSM412_SEQ_FTH_BLOCK:
+		last = 1;
+		break;
+	}
 
-	msgb_free(msg);
-	return 0;
+	switch (bt->seq_nr) {
+	case GSM412_SEQ_FST_SCHED_BLOCK:
+	case GSM412_SEQ_FST_BLOCK:
+	case GSM412_SEQ_SND_BLOCK:
+	case GSM412_SEQ_TRD_BLOCK:
+	case GSM412_SEQ_FTH_BLOCK:
+		msgb_free(se->blocks[seq]);
+		se->blocks[seq] = msg;
+		se->seq_next = seq + 1;
+		if (!last)
+			return 0;
+		smscb_rx_msg(se, l1i);
+		smscb_reset(se);
+		return 0;
+	default:
+		LOGP(DLAPDM, LOGL_ERROR, "SMSCB: unhandled sequence number %d\n",
+			bt->seq_nr);
+		msgb_free(msg);
+		return -EINVAL;
+	}
 }
-- 
1.7.0.4





More information about the baseband-devel mailing list