pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmocom-bb/+/34310?usp=email )
Change subject: l1gprs/l1ctl: Decouple RTS.ind from DL_BLOCK.ind
......................................................................
l1gprs/l1ctl: Decouple RTS.ind from DL_BLOCK.ind
Before this patch, the RTS:ind was crafted up in the stack when
receiving the DL_BLOCK.ind. This created some problems since the
internal low level state has to be updated in between signalling
DL_BLOCK.ind and RTS.ind, as there's a fn-advnace of one block between
those 2 signals (hence the timeslot allocation has to be applied at the
time when the fn-advance is applied).
This is actually not fixing the whole issue, since there's several
timeslots and hence the following events will have the internal timeslot updated
during the event in the middle, hence potentially causing problems in the
remaining TS:
DL_BLOCK.ind(FN=N, TS=1), RTS.ind(FN=N+4, TS=1), DL_BLOCK.ind(FN=N, TS=2)
In any case, this decoupling already improves the situation and is step
needed anyway towards fully fixing the problem (by, for instance,
maintaining a timeslot state duplicated both for DL and Ul directions,
since they drive based on differnet FN time (1 PDCH block).
Change-Id: I1494e0aac7555f6e01b4b435b77140afc42c098e
---
M include/l1ctl_proto.h
M include/l1gprs.h
M src/host/layer23/include/osmocom/bb/common/ms.h
M src/host/layer23/include/osmocom/bb/modem/grr.h
M src/host/layer23/src/common/l1ctl.c
M src/host/layer23/src/modem/grr.c
M src/host/layer23/src/modem/rlcmac.c
M src/host/trxcon/src/trxcon_fsm.c
M src/host/virt_phy/src/virt_prim_pdch.c
M src/shared/l1gprs.c
10 files changed, 154 insertions(+), 9 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/10/34310/1
diff --git a/include/l1ctl_proto.h b/include/l1ctl_proto.h
index f0bc56d..8bf44cf 100644
--- a/include/l1ctl_proto.h
+++ b/include/l1ctl_proto.h
@@ -59,6 +59,7 @@
L1CTL_GPRS_DL_BLOCK_IND = 0x23,
/* Extended (11-bit) RACH (see 3GPP TS 05.02, section 5.2.7) */
L1CTL_EXT_RACH_REQ = 0x24,
+ L1CTL_GPRS_RTS_IND = 0x25,
};
enum ccch_mode {
@@ -387,4 +388,11 @@
uint8_t data[0];
} __attribute__((packed));
+/* payload of L1CTL_GPRS_RTS_IND */
+struct l1ctl_gprs_rts_ind {
+ uint32_t fn;
+ uint8_t tn;
+ uint8_t usf;
+} __attribute__((packed));
+
#endif /* __L1CTL_PROTO_H__ */
diff --git a/include/l1gprs.h b/include/l1gprs.h
index eb15726..57380d3 100644
--- a/include/l1gprs.h
+++ b/include/l1gprs.h
@@ -112,4 +112,5 @@
struct l1gprs_prim_ul_block_req *req,
const struct msgb *msg);
struct msgb *l1gprs_handle_dl_block_ind(struct l1gprs_state *gprs,
- const struct l1gprs_prim_dl_block_ind *ind);
+ const struct l1gprs_prim_dl_block_ind *ind, uint8_t *usf);
+struct msgb *l1gprs_handle_rts_ind(struct l1gprs_state *gprs, uint32_t fn, uint8_t tn,
uint8_t usf);
diff --git a/src/host/layer23/include/osmocom/bb/common/ms.h
b/src/host/layer23/include/osmocom/bb/common/ms.h
index 8d1ffc4..f08e977 100644
--- a/src/host/layer23/include/osmocom/bb/common/ms.h
+++ b/src/host/layer23/include/osmocom/bb/common/ms.h
@@ -43,6 +43,7 @@
struct osmol1_entity {
int (*l1_traffic_ind)(struct osmocom_ms *ms, struct msgb *msg);
int (*l1_gprs_dl_block_ind)(struct osmocom_ms *ms, struct msgb *msg);
+ int (*l1_gprs_rts_ind)(struct osmocom_ms *ms, struct msgb *msg);
};
struct osmomncc_entity {
diff --git a/src/host/layer23/include/osmocom/bb/modem/grr.h
b/src/host/layer23/include/osmocom/bb/modem/grr.h
index 3472a10..8235d59 100644
--- a/src/host/layer23/include/osmocom/bb/modem/grr.h
+++ b/src/host/layer23/include/osmocom/bb/modem/grr.h
@@ -25,6 +25,7 @@
GRR_EV_PDCH_DL_TBF_CFG_REQ,
GRR_EV_PDCH_BLOCK_REQ,
GRR_EV_PDCH_BLOCK_IND,
+ GRR_EV_PDCH_RTS_IND,
};
extern struct osmo_fsm grr_fsm_def;
diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c
index 38510d8..d9e0dba 100644
--- a/src/host/layer23/src/common/l1ctl.c
+++ b/src/host/layer23/src/common/l1ctl.c
@@ -986,6 +986,35 @@
return 0;
}
+/* Receive L1CTL_GPRS_RTS_IND */
+static int rx_l1_gprs_rts_ind(struct osmocom_ms *ms, struct msgb *msg)
+{
+ const struct l1ctl_gprs_rts_ind *ind = (void *)msg->l1h;
+
+ if (msgb_l1len(msg) < sizeof(*ind)) {
+ LOGP(DL1C, LOGL_ERROR,
+ "Rx malformed GPRS RTS.ind (len=%u < %zu)\n",
+ msgb_l1len(msg), sizeof(*ind));
+ return -EINVAL;
+ }
+ if (OSMO_UNLIKELY(ind->tn >= 8)) {
+ LOGP(DL1C, LOGL_ERROR,
+ "Rx malformed GPRS RTS.ind (tn=%u)\n",
+ ind->tn);
+ return -EINVAL;
+ }
+
+ DEBUGP(DL1C, "Rx GPRS DL block (fn=%u, tn=%u)\n",
+ ntohl(ind->fn), ind->tn);
+
+ /* distribute or drop */
+ if (ms->l1_entity.l1_gprs_rts_ind)
+ return ms->l1_entity.l1_gprs_rts_ind(ms, msg);
+
+ msgb_free(msg);
+ return 0;
+}
+
/* Transmit L1CTL_GPRS_UL_BLOCK_REQ */
int l1ctl_tx_gprs_ul_block_req(struct osmocom_ms *ms, uint32_t fn, uint8_t tn,
const uint8_t *data, size_t data_len)
@@ -1132,6 +1161,9 @@
case L1CTL_GPRS_DL_BLOCK_IND:
rc = rx_l1_gprs_dl_block_ind(ms, msg);
break;
+ case L1CTL_GPRS_RTS_IND:
+ rc = rx_l1_gprs_rts_ind(ms, msg);
+ break;
default:
LOGP(DL1C, LOGL_ERROR, "Unknown MSG: %u\n", hdr->msg_type);
msgb_free(msg);
diff --git a/src/host/layer23/src/modem/grr.c b/src/host/layer23/src/modem/grr.c
index 7eec935..a4a270c 100644
--- a/src/host/layer23/src/modem/grr.c
+++ b/src/host/layer23/src/modem/grr.c
@@ -469,16 +469,19 @@
}
};
osmo_gprs_rlcmac_prim_lower_up(prim);
+}
+
+static void handle_pdch_rts_ind(struct osmocom_ms *ms, struct msgb *msg)
+{
+ const struct l1ctl_gprs_rts_ind *ind = (void *)msg->l1h;
+ const uint32_t fn = osmo_load32be(&ind->fn);
+ struct osmo_gprs_rlcmac_prim *prim;
/* Do not send RTS.ind if we got PTCCH/D */
if (fn % 104 == 12)
return;
- /* Every fn % 13 == 12 we have either a PTCCH or an IDLE slot, thus
- * every fn % 13 == 8 we add 5 frames, or 4 frames othrwise. The
- * resulting value is first fn of the next block. */
- const uint32_t rts_fn = GSM_TDMA_FN_SUM(fn, (fn % 13 == 8) ? 5 : 4);
- prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_rts_ind(ind->hdr.tn, rts_fn,
ind->usf);
+ prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_rts_ind(ind->tn, fn, ind->usf);
osmo_gprs_rlcmac_prim_lower_up(prim);
}
@@ -693,6 +696,9 @@
case GRR_EV_PDCH_BLOCK_IND:
handle_pdch_block_ind(ms, (struct msgb *)data);
break;
+ case GRR_EV_PDCH_RTS_IND:
+ handle_pdch_rts_ind(ms, (struct msgb *)data);
+ break;
case GRR_EV_PDCH_RELEASE_REQ:
modem_sync_to_cell(ms);
osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_NOT_READY, 0, 0);
@@ -729,6 +735,7 @@
| S(GRR_EV_PDCH_DL_TBF_CFG_REQ)
| S(GRR_EV_PDCH_BLOCK_REQ)
| S(GRR_EV_PDCH_BLOCK_IND)
+ | S(GRR_EV_PDCH_RTS_IND)
| S(GRR_EV_PDCH_RELEASE_REQ),
.action = &grr_st_packet_transfer_action,
.onenter = &grr_st_packet_transfer_onenter,
@@ -747,6 +754,7 @@
OSMO_VALUE_STRING(GRR_EV_PDCH_DL_TBF_CFG_REQ),
OSMO_VALUE_STRING(GRR_EV_PDCH_BLOCK_REQ),
OSMO_VALUE_STRING(GRR_EV_PDCH_BLOCK_IND),
+ OSMO_VALUE_STRING(GRR_EV_PDCH_RTS_IND),
{ 0, NULL }
};
diff --git a/src/host/layer23/src/modem/rlcmac.c b/src/host/layer23/src/modem/rlcmac.c
index 0f98e79..5037d99 100644
--- a/src/host/layer23/src/modem/rlcmac.c
+++ b/src/host/layer23/src/modem/rlcmac.c
@@ -167,6 +167,11 @@
return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_BLOCK_IND, msg);
}
+static int l1ctl_rts_cb(struct osmocom_ms *ms, struct msgb *msg)
+{
+ return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_RTS_IND, msg);
+}
+
int modem_rlcmac_init(struct osmocom_ms *ms)
{
int rc;
@@ -182,6 +187,7 @@
osmo_gprs_rlcmac_prim_set_down_cb(modem_rlcmac_prim_down_cb, ms);
ms->l1_entity.l1_gprs_dl_block_ind = &l1ctl_dl_block_cb;
+ ms->l1_entity.l1_gprs_rts_ind = &l1ctl_rts_cb;
return rc;
}
diff --git a/src/host/trxcon/src/trxcon_fsm.c b/src/host/trxcon/src/trxcon_fsm.c
index e7c60f2..023ed49 100644
--- a/src/host/trxcon/src/trxcon_fsm.c
+++ b/src/host/trxcon/src/trxcon_fsm.c
@@ -607,6 +607,7 @@
const struct trxcon_param_rx_data_ind *ind = data;
struct l1gprs_prim_dl_block_ind block_ind;
struct msgb *msg;
+ uint8_t usf = 0xff;
block_ind = (struct l1gprs_prim_dl_block_ind) {
.hdr = {
@@ -627,7 +628,14 @@
else
block_ind.meas.ber10k = 10000 * ind->n_errors / ind->n_bits_total;
- msg = l1gprs_handle_dl_block_ind(trxcon->gprs, &block_ind);
+ msg = l1gprs_handle_dl_block_ind(trxcon->gprs, &block_ind, &usf);
+ if (msg != NULL)
+ trxcon_l1ctl_send(trxcon, msg);
+ /* Every fn % 13 == 12 we have either a PTCCH or an IDLE slot, thus
+ * every fn % 13 == 8 we add 5 frames, or 4 frames othrwise. The
+ * resulting value is first fn of the next block. */
+ const uint32_t rts_fn = GSM_TDMA_FN_SUM(ind->frame_nr, (ind->frame_nr % 13 == 8)
? 5 : 4);
+ msg = l1gprs_handle_rts_ind(trxcon->gprs, rts_fn, ind->chan_nr & 0x07, usf);
if (msg != NULL)
trxcon_l1ctl_send(trxcon, msg);
break;
diff --git a/src/host/virt_phy/src/virt_prim_pdch.c
b/src/host/virt_phy/src/virt_prim_pdch.c
index 65551d3..d2992f7 100644
--- a/src/host/virt_phy/src/virt_prim_pdch.c
+++ b/src/host/virt_phy/src/virt_prim_pdch.c
@@ -22,6 +22,7 @@
#include <osmocom/core/utils.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_08_58.h>
+#include <osmocom/gsm/gsm0502.h>
#include <osmocom/bb/virtphy/l1ctl_sap.h>
#include <osmocom/bb/virtphy/virt_l1_sched.h>
@@ -75,6 +76,7 @@
{
struct l1gprs_prim_dl_block_ind ind;
struct msgb *nmsg;
+ uint8_t usf;
if (ms->gprs == NULL)
return;
@@ -93,7 +95,14 @@
.data_len = msgb_length(msg),
};
- nmsg = l1gprs_handle_dl_block_ind(ms->gprs, &ind);
+ nmsg = l1gprs_handle_dl_block_ind(ms->gprs, &ind, &usf);
if (nmsg != NULL)
l1ctl_sap_tx_to_l23_inst(ms, nmsg);
+ /* Every fn % 13 == 12 we have either a PTCCH or an IDLE slot, thus
+ * every fn % 13 == 8 we add 5 frames, or 4 frames othrwise. The
+ * resulting value is first fn of the next block. */
+ const uint32_t rts_fn = GSM_TDMA_FN_SUM(fn, (fn % 13 == 8) ? 5 : 4);
+ nmsg = l1gprs_handle_rts_ind(ms->gprs, rts_fn, tn, usf);
+ if (msg != NULL)
+ l1ctl_sap_tx_to_l23_inst(ms, nmsg);
}
diff --git a/src/shared/l1gprs.c b/src/shared/l1gprs.c
index 61b6eea..bfbda59 100644
--- a/src/shared/l1gprs.c
+++ b/src/shared/l1gprs.c
@@ -674,7 +674,8 @@
(((ind)->hdr.fn % 104) == 12)
struct msgb *l1gprs_handle_dl_block_ind(struct l1gprs_state *gprs,
- const struct l1gprs_prim_dl_block_ind *ind)
+ const struct l1gprs_prim_dl_block_ind *ind,
+ uint8_t *usf)
{
const struct l1gprs_pdch *pdch = NULL;
struct l1ctl_gprs_dl_block_ind *l1bi;
@@ -743,6 +744,7 @@
case OSMO_GPRS_CS3:
case OSMO_GPRS_CS4:
l1bi->usf = ind->data[0] & 0x07;
+ *usf = l1bi->usf;
/* Determine whether to include the payload or not */
if (l1gprs_pdch_filter_dl_block(pdch, ind->data))
memcpy(msgb_put(msg, ind->data_len), ind->data, ind->data_len);
@@ -758,3 +760,46 @@
return msg;
}
+
+struct msgb *l1gprs_handle_rts_ind(struct l1gprs_state *gprs, uint32_t fn, uint8_t tn,
uint8_t usf)
+{
+ const struct l1gprs_pdch *pdch = NULL;
+ struct l1ctl_gprs_rts_ind *l1bi;
+ struct msgb *msg;
+
+ pdch = &gprs->pdch[tn];
+
+ LOGP_PDCH(pdch, LOGL_DEBUG,
+ "Rx RTS.ind (%s, fn=%u, usf=%u)\n",
+ ((fn % 104) == 12) ? "PTCCH" : "PDTCH",
+ fn, usf);
+
+ l1gprs_check_pending_tbfs(gprs, fn);
+
+ if (pdch->ul_tbf_count + pdch->dl_tbf_count == 0) {
+ if (pdch->pending_ul_tbf_count + pdch->pending_dl_tbf_count > 0)
+ LOGP_PDCH(pdch, LOGL_DEBUG,
+ "Rx RTS.ind (fn=%u, usf=%u), but this PDCH has no active TBFs yet\n",
+ fn, usf);
+ else
+ LOGP_PDCH(pdch, LOGL_ERROR,
+ "Rx RTS.ind (fn=%u, usf=%u), but this PDCH has no configured TBFs\n",
+ fn, usf);
+ return NULL;
+ }
+
+ msg = l1gprs_l1ctl_msgb_alloc(L1CTL_GPRS_RTS_IND);
+ if (OSMO_UNLIKELY(msg == NULL)) {
+ LOGP_GPRS(gprs, LOGL_ERROR, "l1gprs_l1ctl_msgb_alloc() failed\n");
+ return NULL;
+ }
+
+ l1bi = (void *)msgb_put(msg, sizeof(*l1bi));
+ *l1bi = (struct l1ctl_gprs_rts_ind) {
+ .fn = htonl(fn),
+ .tn = tn,
+ .usf = usf,
+ };
+
+ return msg;
+}
--
To view, visit
https://gerrit.osmocom.org/c/osmocom-bb/+/34310?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: I1494e0aac7555f6e01b4b435b77140afc42c098e
Gerrit-Change-Number: 34310
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: newchange