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.comWe (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