layer23/modem: handle and forward L1CTL UL BLOCK.cnf

Change-Id: I9255ac17529b5ac260f9a0f141f3af6b3b72a802
Depends: libosmo-gprs.git I145b9586f83ae0235b4648916bd44996e8dc57f0
This commit is contained in:
Vadim Yanitskiy 2024-02-02 05:57:02 +07:00
parent 841e1eecc7
commit 6c38a00444
5 changed files with 62 additions and 4 deletions

View File

@ -42,6 +42,7 @@ struct osmosap_entity {
struct osmol1_entity {
int (*l1_traffic_ind)(struct osmocom_ms *ms, struct msgb *msg);
int (*l1_gprs_ul_block_cnf)(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);
};

View File

@ -25,6 +25,7 @@ enum grr_fsm_event {
GRR_EV_PDCH_UL_TBF_CFG_REQ,
GRR_EV_PDCH_DL_TBF_CFG_REQ,
GRR_EV_PDCH_BLOCK_REQ,
GRR_EV_PDCH_BLOCK_CNF,
GRR_EV_PDCH_BLOCK_IND,
GRR_EV_PDCH_RTS_IND,
};

View File

@ -949,6 +949,36 @@ static int rx_l1_neigh_pm_ind(struct osmocom_ms *ms, struct msgb *msg)
return 0;
}
/* Receive L1CTL_GPRS_UL_BLOCK_CNF */
static int rx_l1_gprs_ul_block_cnf(struct osmocom_ms *ms, struct msgb *msg)
{
const struct l1ctl_gprs_ul_block_cnf *cnf = (void *)msg->l1h;
if (msgb_l1len(msg) < sizeof(*cnf)) {
LOGP(DL1C, LOGL_ERROR,
"Rx malformed GPRS UL BLOCK.cnf (len=%u < %zu)\n",
msgb_l1len(msg), sizeof(*cnf));
return -EINVAL;
}
if (OSMO_UNLIKELY(cnf->tn >= 8)) {
LOGP(DL1C, LOGL_ERROR,
"Rx malformed GPRS UL BLOCK.cnf (tn=%u)\n", cnf->tn);
return -EINVAL;
}
msg->l2h = (void *)&cnf->data[0];
DEBUGP(DL1C, "Rx GPRS UL BLOCK.cnf (fn=%u, tn=%u, len=%u): %s\n",
ntohl(cnf->fn), cnf->tn, msgb_l2len(msg), msgb_hexdump_l2(msg));
/* distribute or drop */
if (ms->l1_entity.l1_gprs_ul_block_cnf)
return ms->l1_entity.l1_gprs_ul_block_cnf(ms, msg);
msgb_free(msg);
return 0;
}
/* Receive L1CTL_GPRS_DL_BLOCK_IND */
static int rx_l1_gprs_dl_block_ind(struct osmocom_ms *ms, struct msgb *msg)
{
@ -1171,6 +1201,9 @@ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
case L1CTL_TRAFFIC_CONF:
msgb_free(msg);
break;
case L1CTL_GPRS_UL_BLOCK_CNF:
rc = rx_l1_gprs_ul_block_cnf(ms, msg);
break;
case L1CTL_GPRS_DL_BLOCK_IND:
rc = rx_l1_gprs_dl_block_ind(ms, msg);
break;

View File

@ -521,6 +521,18 @@ static void handle_pdch_establish_req(struct osmo_fsm_inst *fi,
osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_TRANSFER, 0, 0);
}
static void handle_pdch_block_cnf(struct osmocom_ms *ms, struct msgb *msg)
{
const struct l1ctl_gprs_ul_block_cnf *cnf = (void *)msg->l1h;
const uint32_t fn = osmo_load32be(&cnf->fn);
struct osmo_gprs_rlcmac_prim *prim;
prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_data_cnf(cnf->tn, fn,
msgb_l2(msg),
msgb_l2len(msg));
osmo_gprs_rlcmac_prim_lower_up(prim);
}
static void handle_pdch_block_ind(struct osmocom_ms *ms, struct msgb *msg)
{
const struct l1ctl_gprs_dl_block_ind *ind = (void *)msg->l1h;
@ -753,6 +765,9 @@ static void grr_st_packet_transfer_action(struct osmo_fsm_inst *fi,
lp->pdch_data_req.data_len);
break;
}
case GRR_EV_PDCH_BLOCK_CNF:
handle_pdch_block_cnf(ms, (struct msgb *)data);
break;
case GRR_EV_PDCH_BLOCK_IND:
handle_pdch_block_ind(ms, (struct msgb *)data);
break;
@ -819,6 +834,7 @@ static const struct osmo_fsm_state grr_fsm_states[] = {
.in_event_mask = S(GRR_EV_PDCH_UL_TBF_CFG_REQ)
| S(GRR_EV_PDCH_DL_TBF_CFG_REQ)
| S(GRR_EV_PDCH_BLOCK_REQ)
| S(GRR_EV_PDCH_BLOCK_CNF)
| S(GRR_EV_PDCH_BLOCK_IND)
| S(GRR_EV_PDCH_RTS_IND)
| S(GRR_EV_PDCH_RELEASE_REQ),
@ -838,6 +854,7 @@ static const struct value_string grr_fsm_event_names[] = {
OSMO_VALUE_STRING(GRR_EV_PDCH_UL_TBF_CFG_REQ),
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_CNF),
OSMO_VALUE_STRING(GRR_EV_PDCH_BLOCK_IND),
OSMO_VALUE_STRING(GRR_EV_PDCH_RTS_IND),
{ 0, NULL }

View File

@ -162,12 +162,17 @@ static int modem_rlcmac_prim_down_cb(struct osmo_gprs_rlcmac_prim *prim, void *u
}
}
static int l1ctl_dl_block_cb(struct osmocom_ms *ms, struct msgb *msg)
static int l1ctl_ul_block_cnf_cb(struct osmocom_ms *ms, struct msgb *msg)
{
return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_BLOCK_CNF, msg);
}
static int l1ctl_dl_block_ind_cb(struct osmocom_ms *ms, struct msgb *msg)
{
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)
static int l1ctl_rts_ind_cb(struct osmocom_ms *ms, struct msgb *msg)
{
return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_RTS_IND, msg);
}
@ -186,8 +191,9 @@ int modem_rlcmac_init(struct osmocom_ms *ms)
osmo_gprs_rlcmac_prim_set_up_cb(modem_rlcmac_prim_up_cb, ms);
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;
ms->l1_entity.l1_gprs_ul_block_cnf = &l1ctl_ul_block_cnf_cb;
ms->l1_entity.l1_gprs_dl_block_ind = &l1ctl_dl_block_ind_cb;
ms->l1_entity.l1_gprs_rts_ind = &l1ctl_rts_ind_cb;
return rc;
}