pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmocom-bb/+/33901 )


Change subject: [WIP] modem: implement GPRS-RR FSM
......................................................................

[WIP] modem: implement GPRS-RR FSM

Change-Id: I8a7d85df7b07d85ac86e0b7e340f6bbacc65e1bc
---
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/modem/app_modem.c
M src/host/layer23/src/modem/grr.c
M src/host/layer23/src/modem/rlcmac.c
M src/host/layer23/src/modem/vty.c
6 files changed, 350 insertions(+), 133 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/01/33901/1

diff --git a/src/host/layer23/include/osmocom/bb/common/ms.h 
b/src/host/layer23/include/osmocom/bb/common/ms.h
index bfbf879..8d1ffc4 100644
--- a/src/host/layer23/include/osmocom/bb/common/ms.h
+++ b/src/host/layer23/include/osmocom/bb/common/ms.h
@@ -100,6 +100,7 @@
        /* GPRS */
        struct gprs_settings gprs;
        struct osmobb_ms_gmm_layer gmmlayer;
+       struct osmo_fsm_inst *grr_fi;

        /* Audio I/O */
        struct gapk_io_state *gapk_io;
diff --git a/src/host/layer23/include/osmocom/bb/modem/grr.h 
b/src/host/layer23/include/osmocom/bb/modem/grr.h
index 1f2b08c..3472a10 100644
--- a/src/host/layer23/include/osmocom/bb/modem/grr.h
+++ b/src/host/layer23/include/osmocom/bb/modem/grr.h
@@ -6,7 +6,28 @@
 struct msgb;
 struct osmocom_ms;
 struct lapdm_entity;
+struct osmo_fsm;
+
+enum grr_fsm_state {
+       GRR_ST_PACKET_NOT_READY,
+       GRR_ST_PACKET_IDLE,
+       GRR_ST_PACKET_TRANSFER,
+};
+
+enum grr_fsm_event {
+       GRR_EV_BCCH_BLOCK_IND,
+       GRR_EV_PCH_AGCH_BLOCK_IND,
+       GRR_EV_RACH_REQ,
+       GRR_EV_RACH_CNF,
+       GRR_EV_PDCH_ESTABLISH_REQ,
+       GRR_EV_PDCH_RELEASE_REQ,
+       GRR_EV_PDCH_UL_TBF_CFG_REQ,
+       GRR_EV_PDCH_DL_TBF_CFG_REQ,
+       GRR_EV_PDCH_BLOCK_REQ,
+       GRR_EV_PDCH_BLOCK_IND,
+};
+
+extern struct osmo_fsm grr_fsm_def;

 int modem_grr_rslms_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx);
-int modem_grr_tx_chan_req(struct osmocom_ms *ms, uint8_t chan_req);
 uint8_t modem_grr_gen_chan_req(bool single_block);
diff --git a/src/host/layer23/src/modem/app_modem.c 
b/src/host/layer23/src/modem/app_modem.c
index fdb3821..6871384 100644
--- a/src/host/layer23/src/modem/app_modem.c
+++ b/src/host/layer23/src/modem/app_modem.c
@@ -62,34 +62,6 @@

 struct modem_app app_data;

-static bool modem_can_gprs_attach(const struct osmocom_ms *ms)
-{
-       const struct gsm_subscriber *subscr = &ms->subscr;
-       const struct gsm322_cellsel *cs = &ms->cellsel;
-       const struct gsm48_sysinfo *si = &cs->sel_si;
-
-       if (!subscr->sim_valid)
-               goto ret_false;
-
-       if (!si->si1 || !si->si3 || !si->si4 || !si->si13)
-               goto ret_false;
-
-       if (!si->gprs.supported)
-               goto ret_false;
-
-       return true;
-
-ret_false:
-       LOGP(DRLCMAC, LOGL_INFO, "Delaying GPRS attach, waiting 
for:%s%s%s%s%s%s\n",
-            subscr->sim_valid ? "" : " imsi",
-            si->si1 ? "" : " si1",
-            si->si3 ? "" : " si3",
-            si->si4 ? "" : " si4",
-            si->si13 ? "" : " si13",
-            si->gprs.supported ? "" : " GprsIndicator");
-       return false;
-}
-
 int modem_gprs_attach_if_needed(struct osmocom_ms *ms)
 {
        int rc;
@@ -97,7 +69,10 @@
        if (app_data.modem_state != MODEM_ST_IDLE)
                return 0;

-       if (!modem_can_gprs_attach(ms))
+       if (ms->grr_fi->state == GRR_ST_PACKET_NOT_READY)
+               return 0;
+
+       if (!ms->subscr.sim_valid)
                return 0;

        app_data.modem_state = MODEM_ST_ATTACHING;
@@ -201,6 +176,8 @@
        switch (signal) {
        case S_L1CTL_RESET:
                ms = signal_data;
+               if (ms->started)
+                       break;
                layer3_app_reset();
                app_data.ms = ms;

@@ -285,6 +262,12 @@
                return rc;
        }

+       /* TODO: move to a separate function */
+       app_data.ms->grr_fi = osmo_fsm_inst_alloc(&grr_fsm_def, NULL,
+                                                 app_data.ms, LOGL_DEBUG,
+                                                 app_data.ms->name);
+       OSMO_ASSERT(app_data.ms->grr_fi != NULL);
+
        osmo_signal_register_handler(SS_L1CTL, &global_signal_cb, NULL);
        osmo_signal_register_handler(SS_L23_SUBSCR, 
&modem_l23_subscr_signal_cb, NULL);
        lapdm_channel_set_l3(&app_data.ms->lapdm_channel, &modem_grr_rslms_cb, 
app_data.ms);
diff --git a/src/host/layer23/src/modem/grr.c b/src/host/layer23/src/modem/grr.c
index bd55f30..a7185fe 100644
--- a/src/host/layer23/src/modem/grr.c
+++ b/src/host/layer23/src/modem/grr.c
@@ -1,5 +1,8 @@
 /*
  * (C) 2022-2023 by sysmocom - s.f.m.c. GmbH <[email protected]>
+ * Author: Pau Espin Pedrol <[email protected]>
+ * Author: Vadim Yanitskiy <[email protected]>
+ *
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -23,6 +26,7 @@
 #include <string.h>
 #include <errno.h>

+#include <osmocom/core/fsm.h>
 #include <osmocom/core/msgb.h>
 #include <osmocom/core/utils.h>
 #include <osmocom/core/logging.h>
@@ -41,6 +45,7 @@
 #include <osmocom/bb/common/l1ctl.h>
 #include <osmocom/bb/common/ms.h>
 #include <osmocom/bb/modem/modem.h>
+#include <osmocom/bb/modem/grr.h>

 #include <osmocom/bb/mobile/gsm322.h>
 #include <osmocom/bb/mobile/gsm48_rr.h>
@@ -87,29 +92,6 @@
        return false;
 }

-int modem_grr_tx_chan_req(struct osmocom_ms *ms, uint8_t chan_req)
-{
-       struct gsm322_cellsel *cs = &ms->cellsel;
-       struct gsm48_rrlayer *rr = &ms->rrlayer;
-
-       OSMO_ASSERT(rr->state == GSM48_RR_ST_IDLE);
-
-       if (!cs->sel_si.si1 || !cs->sel_si.si13)
-               return -EAGAIN;
-       if (!cs->sel_si.gprs.supported)
-               return -ENOTSUP;
-
-       rr->cr_ra = chan_req;
-       memset(&rr->cr_hist[0], 0x00, sizeof(rr->cr_hist));
-
-       LOGP(DRR, LOGL_NOTICE, "Sending CHANNEL REQUEST (0x%02x)\n", rr->cr_ra);
-       l1ctl_tx_rach_req(ms, RSL_CHAN_RACH, 0x00, rr->cr_ra, 0,
-                         cs->ccch_mode == CCCH_MODE_COMBINED);
-
-       rr->state = GSM48_RR_ST_CONN_PEND;
-       return 0;
-}
-
 static int forward_to_rlcmac(struct osmocom_ms *ms, struct msgb *msg)
 {
        struct osmo_gprs_rlcmac_prim *rlcmac_prim;
@@ -135,7 +117,6 @@
                return rc;
        }

-       modem_gprs_attach_if_needed(ms);
        return 0;
 }

@@ -171,7 +152,6 @@
        LOGP(DRR, LOGL_NOTICE, "Found GPRS Indicator (RA Colour %u, SI13 on 
BCCH %s)\n",
             cs->sel_si.gprs.ra_colour, cs->sel_si.gprs.si13_pos ? "Ext" : 
"Norm");

-       modem_gprs_attach_if_needed(ms);
        return 0;
 }

@@ -199,7 +179,6 @@
        LOGP(DRR, LOGL_NOTICE, "Found GPRS Indicator (RA Colour %u, SI13 on 
BCCH %s)\n",
             cs->sel_si.gprs.ra_colour, cs->sel_si.gprs.si13_pos ? "Ext" : 
"Norm");

-       modem_gprs_attach_if_needed(ms);
        return 0;
 }

@@ -218,10 +197,7 @@
                return rc;

        /* Forward SI13 to RLC/MAC layer */
-       rc = forward_to_rlcmac(ms, msg);
-
-       modem_gprs_attach_if_needed(ms);
-       return rc;
+       return forward_to_rlcmac(ms, msg);
 }

 static int grr_rx_bcch(struct osmocom_ms *ms, struct msgb *msg)
@@ -299,6 +275,11 @@
                return -EINVAL;
        }

+       /* FIXME: this event should be triggered by the RLC/MAC layers itself */
+       rc = osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_ESTABLISH_REQ, 
NULL);
+       if (rc != 0)
+               return rc;
+
        if (!ia->chan_desc.h0.h) {
                /* Non-hopping */
                uint16_t arfcn;
@@ -349,7 +330,6 @@
        if (rc < 0)
                return rc;

-       rr->state = GSM48_RR_ST_DEDICATED;
        return 0;
 }

@@ -461,9 +441,9 @@

        switch (rllh->chan_nr) {
        case RSL_CHAN_PCH_AGCH:
-               return grr_rx_ccch(ms, msg);
+               return osmo_fsm_inst_dispatch(ms->grr_fi, 
GRR_EV_PCH_AGCH_BLOCK_IND, msg);
        case RSL_CHAN_BCCH:
-               return grr_rx_bcch(ms, msg);
+               return osmo_fsm_inst_dispatch(ms->grr_fi, 
GRR_EV_BCCH_BLOCK_IND, msg);
        default:
                return 0;
        }
@@ -486,25 +466,11 @@
 static int grr_rx_rslms_cchan(struct osmocom_ms *ms, struct msgb *msg)
 {
        const struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
-       struct gsm48_rrlayer *rr = &ms->rrlayer;

        switch (ch->c.msg_type) {
        case RSL_MT_CHAN_CONF: /* RACH.conf */
-               if (rr->state == GSM48_RR_ST_CONN_PEND) {
-                       const struct gsm48_req_ref *ref = (void *)&ch->data[1];
-                       LOGP(DRSL, LOGL_NOTICE,
-                            "Rx RACH.conf (RA=0x%02x, T1=%u, T3=%u, T2=%u, 
FN=%u)\n",
-                            rr->cr_ra, ref->t1, ref->t3_high << 3 | 
ref->t3_low, ref->t2,
-                            _gsm48_req_ref2fn(ref));
-                       /* shift the CHANNEL REQUEST history buffer */
-                       memmove(&rr->cr_hist[1], &rr->cr_hist[0], 
ARRAY_SIZE(rr->cr_hist) - 1);
-                       /* store the new entry */
-                       rr->cr_hist[0].ref = *ref;
-                       rr->cr_hist[0].ref.ra = rr->cr_ra;
-                       rr->cr_hist[0].valid = 1;
-                       return 0;
-               }
-               /* fall-through */
+               return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_RACH_CNF,
+                                             (void *)&ch->data[1]);
        default:
                LOGP(DRSL, LOGL_NOTICE, "Unhandled RSLms CCHAN message "
                     "(msg_type 0x%02x)\n", ch->c.msg_type);
@@ -534,3 +500,277 @@
        msgb_free(msg);
        return rc;
 }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define S(x)   (1 << (x))
+
+#include <osmocom/gsm/gsm0502.h> // XXX
+
+static void handle_pdch_block_ind(struct osmocom_ms *ms, struct msgb *msg)
+{
+       const struct l1ctl_gprs_dl_block_ind *ind = (void *)msg->l1h;
+       const uint32_t fn = osmo_load32be(&ind->hdr.fn);
+       struct osmo_gprs_rlcmac_prim *prim;
+
+       /* FIXME: sadly, rlcmac_prim_l1ctl_alloc() is not exposed */
+       prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_data_ind(0, 0, 0, 0, 0, 
NULL, 0);
+       prim->l1ctl = (struct osmo_gprs_rlcmac_l1ctl_prim) {
+               .pdch_data_ind = {
+                       .fn = fn,
+                       .ts_nr = ind->hdr.tn,
+                       .rx_lev = ind->meas.rx_lev,
+                       .ber10k = osmo_load16be(&ind->meas.ber10k),
+                       .ci_cb = osmo_load16be(&ind->meas.ci_cb),
+                       .data_len = msgb_l2len(msg),
+                       .data = msgb_l2(msg),
+               }
+       };
+       osmo_gprs_rlcmac_prim_lower_up(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);
+       osmo_gprs_rlcmac_prim_lower_up(prim);
+}
+
+static bool grr_cell_is_usable(const struct osmocom_ms *ms)
+{
+       const struct gsm322_cellsel *cs = &ms->cellsel;
+       const struct gsm48_sysinfo *si = &cs->sel_si;
+
+       if (!si->si1 || !si->si3 || !si->si4 || !si->si13)
+               return false;
+       if (!si->gprs.supported)
+               return false;
+
+       return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static void grr_st_packet_not_ready_action(struct osmo_fsm_inst *fi,
+                                          uint32_t event, void *data)
+{
+       struct osmocom_ms *ms = fi->priv;
+
+       switch (event) {
+       case GRR_EV_BCCH_BLOCK_IND:
+               grr_rx_bcch(ms, (struct msgb *)data);
+               if (grr_cell_is_usable(ms)) {
+                       LOGPFSML(fi, LOGL_NOTICE, "Cell is usable, GRR becomes 
ready\n");
+                       osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_IDLE, 0, 0);
+               }
+               break;
+       case GRR_EV_PCH_AGCH_BLOCK_IND:
+               grr_rx_ccch(ms, (struct msgb *)data);
+               break;
+       default:
+               OSMO_ASSERT(0);
+       }
+}
+
+static void grr_st_packet_idle_onenter(struct osmo_fsm_inst *fi, uint32_t 
prev_state)
+{
+       struct osmocom_ms *ms = fi->priv;
+
+       modem_gprs_attach_if_needed(ms);
+}
+
+static void grr_st_packet_idle_action(struct osmo_fsm_inst *fi,
+                                     uint32_t event, void *data)
+{
+       struct osmocom_ms *ms = fi->priv;
+
+       switch (event) {
+       case GRR_EV_BCCH_BLOCK_IND:
+               grr_rx_bcch(ms, (struct msgb *)data);
+               if (!grr_cell_is_usable(ms)) {
+                       LOGPFSML(fi, LOGL_NOTICE, "Cell is not usable, GRR 
becomes not ready\n");
+                       osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_NOT_READY, 0, 
0);
+               }
+               break;
+       case GRR_EV_PCH_AGCH_BLOCK_IND:
+               grr_rx_ccch(ms, (struct msgb *)data);
+               break;
+       case GRR_EV_RACH_REQ:
+       {
+               const struct osmo_gprs_rlcmac_l1ctl_prim *lp = data;
+               struct gsm48_rrlayer *rr = &ms->rrlayer;
+
+               if (lp->rach_req.is_11bit) { /* TODO: implement 11-bit RACH */
+                       LOGPFSML(fi, LOGL_ERROR, "11-bit RACH is not 
supported\n");
+                       return;
+               }
+
+               rr->cr_ra = lp->rach_req.ra;
+               memset(&rr->cr_hist[0], 0x00, sizeof(rr->cr_hist));
+
+               LOGPFSML(fi, LOGL_INFO, "Sending CHANNEL REQUEST (0x%02x)\n", 
rr->cr_ra);
+               l1ctl_tx_rach_req(ms, RSL_CHAN_RACH, 0x00, rr->cr_ra, 0,
+                                 ms->cellsel.ccch_mode == CCCH_MODE_COMBINED);
+
+               rr->state = GSM48_RR_ST_CONN_PEND;
+               break;
+       }
+       case GRR_EV_RACH_CNF:
+       {
+               struct gsm48_rrlayer *rr = &ms->rrlayer;
+               const struct gsm48_req_ref *ref = data;
+
+               LOGPFSML(fi, LOGL_NOTICE,
+                        "Rx RACH.conf (RA=0x%02x, T1=%u, T3=%u, T2=%u, 
FN=%u)\n",
+                        rr->cr_ra, ref->t1, ref->t3_high << 3 | ref->t3_low, 
ref->t2,
+                        _gsm48_req_ref2fn(ref));
+
+               if (ms->rrlayer.state != GSM48_RR_ST_CONN_PEND) {
+                       LOGPFSML(fi, LOGL_ERROR, "Rx unexpected RACH.conf\n");
+                       return;
+               }
+
+               /* shift the CHANNEL REQUEST history buffer */
+               memmove(&rr->cr_hist[1], &rr->cr_hist[0], 
ARRAY_SIZE(rr->cr_hist) - 1);
+               /* store the new entry */
+               rr->cr_hist[0].ref = *ref;
+               rr->cr_hist[0].ref.ra = rr->cr_ra;
+               rr->cr_hist[0].valid = 1;
+               break;
+       }
+       case GRR_EV_PDCH_ESTABLISH_REQ:
+               /* TODO: send L1CTL_DM_EST_REQ here */
+               osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_TRANSFER, 0, 0);
+               break;
+       default:
+               OSMO_ASSERT(0);
+       }
+}
+
+static void grr_st_packet_transfer_onenter(struct osmo_fsm_inst *fi, uint32_t 
prev_state)
+{
+       struct osmocom_ms *ms = fi->priv;
+
+       ms->rrlayer.state = GSM48_RR_ST_DEDICATED;
+}
+
+static void grr_st_packet_transfer_onleave(struct osmo_fsm_inst *fi, uint32_t 
next_state)
+{
+       struct osmocom_ms *ms = fi->priv;
+
+       ms->rrlayer.state = GSM48_RR_ST_IDLE;
+}
+
+static void grr_st_packet_transfer_action(struct osmo_fsm_inst *fi,
+                                         uint32_t event, void *data)
+{
+       struct osmocom_ms *ms = fi->priv;
+
+       switch (event) {
+       case GRR_EV_PDCH_UL_TBF_CFG_REQ:
+       {
+               const struct osmo_gprs_rlcmac_l1ctl_prim *lp = data;
+               l1ctl_tx_gprs_ul_tbf_cfg_req(ms,
+                                            lp->cfg_ul_tbf_req.ul_tbf_nr,
+                                            lp->cfg_ul_tbf_req.ul_slotmask);
+               break;
+       }
+       case GRR_EV_PDCH_DL_TBF_CFG_REQ:
+       {
+               const struct osmo_gprs_rlcmac_l1ctl_prim *lp = data;
+               l1ctl_tx_gprs_dl_tbf_cfg_req(ms,
+                                            lp->cfg_dl_tbf_req.dl_tbf_nr,
+                                            lp->cfg_dl_tbf_req.dl_slotmask,
+                                            lp->cfg_dl_tbf_req.dl_tfi);
+               break;
+       }
+       case GRR_EV_PDCH_BLOCK_REQ:
+       {
+               const struct osmo_gprs_rlcmac_l1ctl_prim *lp = data;
+               l1ctl_tx_gprs_ul_block_req(ms,
+                                          lp->pdch_data_req.fn,
+                                          lp->pdch_data_req.ts_nr,
+                                          lp->pdch_data_req.data,
+                                          lp->pdch_data_req.data_len);
+               break;
+       }
+       case GRR_EV_PDCH_BLOCK_IND:
+               handle_pdch_block_ind(ms, (struct msgb *)data);
+               break;
+       case GRR_EV_PDCH_RELEASE_REQ:
+               l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
+               l1ctl_tx_fbsb_req(ms, ms->test_arfcn,
+                                 L1CTL_FBSB_F_FB01SB, 100, 0,
+                                 ms->cellsel.ccch_mode, dbm2rxlev(-85));
+               osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_IDLE, 0, 0);
+               break;
+       default:
+               OSMO_ASSERT(0);
+       }
+}
+
+static const struct osmo_fsm_state grr_fsm_states[] = {
+       [GRR_ST_PACKET_NOT_READY] = {
+               .name = "PACKET_NOT_READY",
+               .out_state_mask = S(GRR_ST_PACKET_IDLE),
+               .in_event_mask  = S(GRR_EV_BCCH_BLOCK_IND)
+                               | S(GRR_EV_PCH_AGCH_BLOCK_IND),
+               .action = &grr_st_packet_not_ready_action,
+       },
+       [GRR_ST_PACKET_IDLE] = {
+               .name = "PACKET_IDLE",
+               .out_state_mask = S(GRR_ST_PACKET_NOT_READY)
+                               | S(GRR_ST_PACKET_TRANSFER),
+               .in_event_mask  = S(GRR_EV_BCCH_BLOCK_IND)
+                               | S(GRR_EV_PCH_AGCH_BLOCK_IND)
+                               | S(GRR_EV_RACH_REQ)
+                               | S(GRR_EV_RACH_CNF)
+                               | S(GRR_EV_PDCH_ESTABLISH_REQ),
+               .action = &grr_st_packet_idle_action,
+               .onenter = &grr_st_packet_idle_onenter,
+       },
+       [GRR_ST_PACKET_TRANSFER] = {
+               .name = "PACKET_TRANSFER",
+               .out_state_mask = S(GRR_ST_PACKET_NOT_READY)
+                               | S(GRR_ST_PACKET_IDLE),
+               .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_IND)
+                               | S(GRR_EV_PDCH_RELEASE_REQ),
+               .action = &grr_st_packet_transfer_action,
+               .onenter = &grr_st_packet_transfer_onenter,
+               .onleave = &grr_st_packet_transfer_onleave,
+       },
+};
+
+static const struct value_string grr_fsm_event_names[] = {
+       OSMO_VALUE_STRING(GRR_EV_BCCH_BLOCK_IND),
+       OSMO_VALUE_STRING(GRR_EV_PCH_AGCH_BLOCK_IND),
+       OSMO_VALUE_STRING(GRR_EV_RACH_REQ),
+       OSMO_VALUE_STRING(GRR_EV_RACH_CNF),
+       OSMO_VALUE_STRING(GRR_EV_PDCH_ESTABLISH_REQ),
+       OSMO_VALUE_STRING(GRR_EV_PDCH_RELEASE_REQ),
+       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_IND),
+       { 0, NULL }
+};
+
+struct osmo_fsm grr_fsm_def = {
+       .name = "GPRS-RR",
+       .log_subsys = DRR,
+       .states = grr_fsm_states,
+       .num_states = ARRAY_SIZE(grr_fsm_states),
+       .event_names = grr_fsm_event_names,
+};
+
+static __attribute__((constructor)) void on_dso_load(void)
+{
+       OSMO_ASSERT(osmo_fsm_register(&grr_fsm_def) == 0);
+}
diff --git a/src/host/layer23/src/modem/rlcmac.c 
b/src/host/layer23/src/modem/rlcmac.c
index fcd2b2e..d209ec4 100644
--- a/src/host/layer23/src/modem/rlcmac.c
+++ b/src/host/layer23/src/modem/rlcmac.c
@@ -22,6 +22,7 @@
 #include <stdint.h>
 #include <stdbool.h>

+#include <osmocom/core/fsm.h>
 #include <osmocom/core/msgb.h>
 #include <osmocom/core/bits.h>
 #include <osmocom/core/prim.h>
@@ -38,13 +39,10 @@
 #include <osmocom/gprs/gmm/gmm_prim.h>

 #include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/l1ctl.h>
 #include <osmocom/bb/common/ms.h>
 #include <osmocom/bb/modem/rlcmac.h>
 #include <osmocom/bb/modem/grr.h>

-#include <l1ctl_proto.h>
-
 static int modem_rlcmac_handle_grr(struct osmo_gprs_rlcmac_prim *rlcmac_prim)
 {
        int rc;
@@ -141,33 +139,19 @@

 static int modem_rlcmac_prim_down_cb(struct osmo_gprs_rlcmac_prim *prim, void 
*user_data)
 {
-       const struct osmo_gprs_rlcmac_l1ctl_prim *lp = &prim->l1ctl;
+       struct osmo_gprs_rlcmac_l1ctl_prim *lp = &prim->l1ctl;
        const char *pdu_name = osmo_gprs_rlcmac_prim_name(prim);
        struct osmocom_ms *ms = user_data;

        switch (OSMO_PRIM_HDR(&prim->oph)) {
        case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_RACH, PRIM_OP_REQUEST):
-               if (lp->rach_req.is_11bit) {
-                       LOGP(DRLCMAC, LOGL_NOTICE,
-                            "%s(): 11-bit RACH is not supported\n", __func__);
-                       return -ENOTSUP;
-               }
-               return modem_grr_tx_chan_req(ms, lp->rach_req.ra);
+               return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_RACH_REQ, lp);
        case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_PDCH_DATA, PRIM_OP_REQUEST):
-               return l1ctl_tx_gprs_ul_block_req(ms,
-                                                 lp->pdch_data_req.fn,
-                                                 lp->pdch_data_req.ts_nr,
-                                                 lp->pdch_data_req.data,
-                                                 lp->pdch_data_req.data_len);
+               return osmo_fsm_inst_dispatch(ms->grr_fi, 
GRR_EV_PDCH_BLOCK_REQ, lp);
        case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_CFG_UL_TBF, PRIM_OP_REQUEST):
-               return l1ctl_tx_gprs_ul_tbf_cfg_req(ms,
-                                                   
lp->cfg_ul_tbf_req.ul_tbf_nr,
-                                                   
lp->cfg_ul_tbf_req.ul_slotmask);
+               return osmo_fsm_inst_dispatch(ms->grr_fi, 
GRR_EV_PDCH_UL_TBF_CFG_REQ, lp);
        case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_CFG_DL_TBF, PRIM_OP_REQUEST):
-               return l1ctl_tx_gprs_dl_tbf_cfg_req(ms,
-                                                   
lp->cfg_dl_tbf_req.dl_tbf_nr,
-                                                   
lp->cfg_dl_tbf_req.dl_slotmask,
-                                                   lp->cfg_dl_tbf_req.dl_tfi);
+               return osmo_fsm_inst_dispatch(ms->grr_fi, 
GRR_EV_PDCH_DL_TBF_CFG_REQ, lp);
        default:
                LOGP(DRLCMAC, LOGL_DEBUG, "%s(): Unexpected Rx %s\n", __func__, 
pdu_name);
                OSMO_ASSERT(0);
@@ -176,37 +160,7 @@

 static int l1ctl_dl_block_cb(struct osmocom_ms *ms, struct msgb *msg)
 {
-       const struct l1ctl_gprs_dl_block_ind *ind = (void *)msg->l1h;
-       const uint32_t fn = osmo_load32be(&ind->hdr.fn);
-       struct osmo_gprs_rlcmac_prim *prim;
-
-       /* FIXME: sadly, rlcmac_prim_l1ctl_alloc() is not exposed */
-       prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_data_ind(0, 0, 0, 0, 0, 
NULL, 0);
-       prim->l1ctl = (struct osmo_gprs_rlcmac_l1ctl_prim) {
-               .pdch_data_ind = {
-                       .fn = fn,
-                       .ts_nr = ind->hdr.tn,
-                       .rx_lev = ind->meas.rx_lev,
-                       .ber10k = osmo_load16be(&ind->meas.ber10k),
-                       .ci_cb = osmo_load16be(&ind->meas.ci_cb),
-                       .data_len = msgb_l2len(msg),
-                       .data = msgb_l2(msg),
-               }
-       };
-       osmo_gprs_rlcmac_prim_lower_up(prim);
-
-       /* Do not send RTS.ind if we got PTCCH/D */
-       if (fn % 104 == 12)
-               return 0;
-
-       /* 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);
-       osmo_gprs_rlcmac_prim_lower_up(prim);
-
-       return 0;
+       return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_PDCH_BLOCK_IND, msg);
 }

 int modem_rlcmac_init(struct osmocom_ms *ms)
diff --git a/src/host/layer23/src/modem/vty.c b/src/host/layer23/src/modem/vty.c
index d827993..da29165 100644
--- a/src/host/layer23/src/modem/vty.c
+++ b/src/host/layer23/src/modem/vty.c
@@ -19,6 +19,7 @@
 #include <stdint.h>
 #include <stdbool.h>

+#include <osmocom/core/fsm.h>
 #include <osmocom/core/utils.h>
 #include <osmocom/core/talloc.h>
 #include <osmocom/core/linuxlist.h>
@@ -27,6 +28,7 @@
 #include <osmocom/gprs/llc/llc_prim.h>
 #include <osmocom/gprs/gmm/gmm_prim.h>
 #include <osmocom/gprs/sm/sm_prim.h>
+#include <osmocom/gprs/rlcmac/rlcmac_prim.h>


 #include <osmocom/vty/vty.h>
@@ -84,7 +86,14 @@
                return CMD_WARNING;

        chan_req = modem_grr_gen_chan_req(argv[1][0] == '2');
-       if (modem_grr_tx_chan_req(ms, chan_req) != 0) {
+       const struct osmo_gprs_rlcmac_l1ctl_prim lp = {
+               .rach_req = {
+                       .is_11bit = false,
+                       .ra = chan_req,
+               }
+       };
+
+       if (osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_RACH_REQ, (void *)&lp)) {
                vty_out(vty, "Failed to send a CHANNEL REQUEST%s", VTY_NEWLINE);
                return CMD_WARNING;
        }

--
To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/33901
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: I8a7d85df7b07d85ac86e0b7e340f6bbacc65e1bc
Gerrit-Change-Number: 33901
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-CC: fixeria <[email protected]>
Gerrit-MessageType: newchange

Reply via email to