fixeria has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmocom-bb/+/34514?usp=email )


Change subject: modem: grr: implement RACH.req retransmission
......................................................................

modem: grr: implement RACH.req retransmission

Sometimes sending one Access Burst is not enough, so we need to repeat
sending it a few more more times changing the 3 LSBs randomly.  This
is what we already do in the mobile app, but not in the modem app.

* Rename GRR_EV_RACH_{REQ,CNF} to GRR_EV_CHAN_ACCESS_{REQ,CNF}.
* Rename VTY command 'grr tx-chan-req' to 'grr start-chan-access'.
* Add an intermediate state GRR_ST_PACKET_ACCESS.
** The GRR_EV_CHAN_ACCESS_REQ transitions to this state.
** One RACH.req gets transmitted when entering this state.
** The GRR_EV_CHAN_ACCESS_CNF confirms transmission of a RACH.req.
** Upon the timeout (300 ms) expiry, a loop state transition happens.
** After 3 loop-transitions, transition to GRR_ST_PACKET_NOT_READY.

Change-Id: Iab6d9147f6e0aeb99239affacf318a3897fd6ffe
Related: libosmo-gprs.git If0de3ed86b1e2897d70183f3b0f4fbfd7d2bda80
Related: OS#5500, OS#6131
---
M src/host/layer23/include/osmocom/bb/modem/grr.h
M src/host/layer23/src/modem/grr.c
M src/host/layer23/src/modem/rlcmac.c
M src/host/layer23/src/modem/vty.c
4 files changed, 189 insertions(+), 78 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/14/34514/1

diff --git a/src/host/layer23/include/osmocom/bb/modem/grr.h 
b/src/host/layer23/include/osmocom/bb/modem/grr.h
index 8235d59..99800ad 100644
--- a/src/host/layer23/include/osmocom/bb/modem/grr.h
+++ b/src/host/layer23/include/osmocom/bb/modem/grr.h
@@ -11,14 +11,15 @@
 enum grr_fsm_state {
        GRR_ST_PACKET_NOT_READY,
        GRR_ST_PACKET_IDLE,
+       GRR_ST_PACKET_ACCESS,
        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_CHAN_ACCESS_REQ,
+       GRR_EV_CHAN_ACCESS_CNF,
        GRR_EV_PDCH_ESTABLISH_REQ,
        GRR_EV_PDCH_RELEASE_REQ,
        GRR_EV_PDCH_UL_TBF_CFG_REQ,
@@ -31,4 +32,3 @@
 extern struct osmo_fsm grr_fsm_def;

 int modem_grr_rslms_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx);
-uint8_t modem_grr_gen_chan_req(bool single_block);
diff --git a/src/host/layer23/src/modem/grr.c b/src/host/layer23/src/modem/grr.c
index af773a3..a029dd8 100644
--- a/src/host/layer23/src/modem/grr.c
+++ b/src/host/layer23/src/modem/grr.c
@@ -63,7 +63,7 @@
 }

 /* Generate an 8-bit CHANNEL REQUEST message as per 3GPP TS 44.018, 9.1.8 */
-uint8_t modem_grr_gen_chan_req(bool single_block)
+static uint8_t grr_gen_chan_req(bool single_block)
 {
        uint8_t rnd = (uint8_t)rand();

@@ -408,7 +408,7 @@

        switch (ch->c.msg_type) {
        case RSL_MT_CHAN_CONF: /* RACH.conf */
-               return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_RACH_CNF,
+               return osmo_fsm_inst_dispatch(ms->grr_fi, 
GRR_EV_CHAN_ACCESS_CNF,
                                              (void *)&ch->data[1]);
        default:
                LOGP(DRSL, LOGL_NOTICE, "Unhandled RSLms CCHAN message "
@@ -449,6 +449,78 @@

 #include <osmocom/gsm/gsm0502.h> // XXX

+/* RACH re-transmission delay value (in ms) */
+#define GRR_PACKET_ACCESS_DELAY_MS             300
+/* RACH max number of transmissions */
+#define GRR_PACKET_ACCESS_MAX_CHAN_REQ         3
+
+static void handle_chan_access_req(struct osmo_fsm_inst *fi,
+                                  const struct osmo_gprs_rlcmac_l1ctl_prim *lp)
+{
+       struct osmocom_ms *ms = fi->priv;
+       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;
+       }
+
+       memset(&rr->cr_hist[0], 0x00, sizeof(rr->cr_hist));
+       rr->chan_req_val = lp->rach_req.ra & ~0x07;
+       rr->n_chan_req = GRR_PACKET_ACCESS_MAX_CHAN_REQ;
+       rr->state = GSM48_RR_ST_CONN_PEND;
+
+       osmo_fsm_inst_state_chg_ms(fi, GRR_ST_PACKET_ACCESS,
+                                  GRR_PACKET_ACCESS_DELAY_MS, 0);
+}
+
+static void handle_pdch_establish_req(struct osmo_fsm_inst *fi,
+                                     const struct osmo_gprs_rlcmac_l1ctl_prim 
*lp)
+{
+       struct osmocom_ms *ms = fi->priv;
+
+       if (!lp->pdch_est_req.fh) {
+               LOGPFSML(fi, LOGL_INFO,
+                        "PDCH Establish.Req: TSC=%u, H0, ARFCN=%u\n",
+                        lp->pdch_est_req.tsc, lp->pdch_est_req.arfcn);
+               l1ctl_tx_dm_est_req_h0(ms, lp->pdch_est_req.arfcn,
+                                      RSL_CHAN_OSMO_PDCH | 
lp->pdch_est_req.ts_nr,
+                                      lp->pdch_est_req.tsc, GSM48_CMODE_SIGN, 
0);
+       } else {
+               /* Hopping */
+               uint8_t ma_len = 0;
+               uint16_t ma[64];
+
+               LOGPFSML(fi, LOGL_INFO,
+                        "PDCH Establish.Req: TSC=%u, H1, HSN=%u, MAIO=%u\n",
+                        lp->pdch_est_req.tsc,
+                        lp->pdch_est_req.fhp.hsn,
+                        lp->pdch_est_req.fhp.maio);
+
+               for (unsigned int i = 1, j = 0; i <= 1024; i++) {
+                       unsigned int arfcn = i & 1023;
+                       unsigned int k;
+
+                       if (~ms->cellsel.sel_si.freq[arfcn].mask & 0x01)
+                               continue;
+
+                       k = lp->pdch_est_req.fhp.ma_len - (j >> 3) - 1;
+                       if (lp->pdch_est_req.fhp.ma[k] & (1 << (j & 7)))
+                               ma[ma_len++] = arfcn;
+                       j++;
+               }
+
+               l1ctl_tx_dm_est_req_h1(ms,
+                                      lp->pdch_est_req.fhp.maio,
+                                      lp->pdch_est_req.fhp.hsn,
+                                      &ma[0], ma_len,
+                                      RSL_CHAN_OSMO_PDCH | 
lp->pdch_est_req.ts_nr,
+                                      lp->pdch_est_req.tsc, GSM48_CMODE_SIGN, 
0);
+       }
+
+       osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_TRANSFER, 0, 0);
+}
+
 static void handle_pdch_block_ind(struct osmocom_ms *ms, struct msgb *msg)
 {
        const struct l1ctl_gprs_dl_block_ind *ind = (void *)msg->l1h;
@@ -547,27 +619,60 @@
        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;
+       case GRR_EV_CHAN_ACCESS_REQ:
+               handle_chan_access_req(fi, data);
                break;
+       case GRR_EV_PDCH_ESTABLISH_REQ:
+               handle_pdch_establish_req(fi, data);
+               break;
+       default:
+               OSMO_ASSERT(0);
        }
-       case GRR_EV_RACH_CNF:
+}
+
+static void grr_st_packet_access_onenter(struct osmo_fsm_inst *fi, uint32_t 
prev_state)
+{
+       struct osmocom_ms *ms = fi->priv;
+       struct gsm48_rrlayer *rr = &ms->rrlayer;
+
+       if (rr->n_chan_req == 0) {
+               LOGPFSML(fi, LOGL_ERROR, "Packet access failed (no more 
attempts left)\n");
+               osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_NOT_READY, 0, 0);
+               return;
+       }
+
+       /* (re-)generate the RA value */
+       if ((rr->chan_req_val >> 3) == 0x0e) /* 01110xxx */
+               rr->cr_ra = grr_gen_chan_req(true);
+       else /* 011110xx or 01111x0x or 01111xx0 */
+               rr->cr_ra = grr_gen_chan_req(false);
+       rr->n_chan_req--;
+
+       LOGPFSML(fi, LOGL_INFO,
+                "Sending CHANNEL REQUEST (ra=0x%02x, num_attempts=%u)\n",
+                rr->cr_ra, rr->n_chan_req);
+
+       l1ctl_tx_rach_req(ms, RSL_CHAN_RACH, 0x00, rr->cr_ra, 0,
+                         ms->cellsel.ccch_mode == CCCH_MODE_COMBINED);
+}
+
+static void grr_st_packet_access_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_CHAN_ACCESS_CNF:
        {
                struct gsm48_rrlayer *rr = &ms->rrlayer;
                const struct gsm48_req_ref *ref = data;
@@ -591,50 +696,8 @@
                break;
        }
        case GRR_EV_PDCH_ESTABLISH_REQ:
-       {
-               const struct osmo_gprs_rlcmac_l1ctl_prim *lp = data;
-
-               if (!lp->pdch_est_req.fh) {
-                       LOGPFSML(fi, LOGL_INFO,
-                                "PDCH Establish.Req: TSC=%u, H0, ARFCN=%u\n",
-                                lp->pdch_est_req.tsc, lp->pdch_est_req.arfcn);
-                       l1ctl_tx_dm_est_req_h0(ms, lp->pdch_est_req.arfcn,
-                                              RSL_CHAN_OSMO_PDCH | 
lp->pdch_est_req.ts_nr,
-                                              lp->pdch_est_req.tsc, 
GSM48_CMODE_SIGN, 0);
-               } else {
-                       /* Hopping */
-                       uint8_t ma_len = 0;
-                       uint16_t ma[64];
-
-                       LOGPFSML(fi, LOGL_INFO,
-                                "PDCH Establish.Req: TSC=%u, H1, HSN=%u, 
MAIO=%u\n",
-                                lp->pdch_est_req.tsc,
-                                lp->pdch_est_req.fhp.hsn,
-                                lp->pdch_est_req.fhp.maio);
-
-                       for (unsigned int i = 1, j = 0; i <= 1024; i++) {
-                               unsigned int arfcn = i & 1023;
-                               unsigned int k;
-
-                               if (~ms->cellsel.sel_si.freq[arfcn].mask & 0x01)
-                                       continue;
-
-                               k = lp->pdch_est_req.fhp.ma_len - (j >> 3) - 1;
-                               if (lp->pdch_est_req.fhp.ma[k] & (1 << (j & 7)))
-                                       ma[ma_len++] = arfcn;
-                               j++;
-                       }
-
-                       l1ctl_tx_dm_est_req_h1(ms,
-                                              lp->pdch_est_req.fhp.maio,
-                                              lp->pdch_est_req.fhp.hsn,
-                                              &ma[0], ma_len,
-                                              RSL_CHAN_OSMO_PDCH | 
lp->pdch_est_req.ts_nr,
-                                              lp->pdch_est_req.tsc, 
GSM48_CMODE_SIGN, 0);
-               }
-               osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_TRANSFER, 0, 0);
+               handle_pdch_establish_req(fi, data);
                break;
-       }
        default:
                OSMO_ASSERT(0);
        }
@@ -704,6 +767,19 @@
        }
 }

+static int grr_fsm_timer_cb(struct osmo_fsm_inst *fi)
+{
+       switch (fi->state) {
+       case GRR_ST_PACKET_ACCESS:
+               /* perform a loop transaction, restarting the timer */
+               osmo_fsm_inst_state_chg_ms(fi, GRR_ST_PACKET_ACCESS,
+                                          GRR_PACKET_ACCESS_DELAY_MS, 0);
+               return 0;
+       default:
+               OSMO_ASSERT(0);
+       }
+}
+
 static const struct osmo_fsm_state grr_fsm_states[] = {
        [GRR_ST_PACKET_NOT_READY] = {
                .name = "PACKET_NOT_READY",
@@ -715,15 +791,26 @@
        [GRR_ST_PACKET_IDLE] = {
                .name = "PACKET_IDLE",
                .out_state_mask = S(GRR_ST_PACKET_NOT_READY)
+                               | S(GRR_ST_PACKET_ACCESS)
                                | 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),
+                               | S(GRR_EV_CHAN_ACCESS_REQ)
+                               | S(GRR_EV_PDCH_ESTABLISH_REQ), /* DL TBF ASS */
                .action = &grr_st_packet_idle_action,
                .onenter = &grr_st_packet_idle_onenter,
        },
+       [GRR_ST_PACKET_ACCESS] = {
+               .name = "PACKET_ACCESS",
+               .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_CHAN_ACCESS_CNF)
+                               | S(GRR_EV_PDCH_ESTABLISH_REQ), /* UL TBF ASS */
+               .onenter = &grr_st_packet_access_onenter,
+               .action = &grr_st_packet_access_action,
+       },
        [GRR_ST_PACKET_TRANSFER] = {
                .name = "PACKET_TRANSFER",
                .out_state_mask = S(GRR_ST_PACKET_NOT_READY),
@@ -742,8 +829,8 @@
 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_CHAN_ACCESS_REQ),
+       OSMO_VALUE_STRING(GRR_EV_CHAN_ACCESS_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),
@@ -760,6 +847,7 @@
        .states = grr_fsm_states,
        .num_states = ARRAY_SIZE(grr_fsm_states),
        .event_names = grr_fsm_event_names,
+       .timer_cb = &grr_fsm_timer_cb,
 };

 static __attribute__((constructor)) void on_dso_load(void)
diff --git a/src/host/layer23/src/modem/rlcmac.c 
b/src/host/layer23/src/modem/rlcmac.c
index 5037d99..a9588f7 100644
--- a/src/host/layer23/src/modem/rlcmac.c
+++ b/src/host/layer23/src/modem/rlcmac.c
@@ -145,7 +145,7 @@

        switch (OSMO_PRIM_HDR(&prim->oph)) {
        case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_RACH, PRIM_OP_REQUEST):
-               return osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_RACH_REQ, lp);
+               return osmo_fsm_inst_dispatch(ms->grr_fi, 
GRR_EV_CHAN_ACCESS_REQ, lp);
        case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_PDCH_DATA, PRIM_OP_REQUEST):
                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):
diff --git a/src/host/layer23/src/modem/vty.c b/src/host/layer23/src/modem/vty.c
index da29165..f487e38 100644
--- a/src/host/layer23/src/modem/vty.c
+++ b/src/host/layer23/src/modem/vty.c
@@ -73,27 +73,26 @@
 /* testing commands */
 DEFUN_HIDDEN(test_grr_tx_chan_req,
             test_grr_tx_chan_req_cmd,
-            "test MS_NAME grr tx-chan-req (1phase|2phase)",
+            "test MS_NAME grr start-chan-access (1phase|2phase)",
             TEST_CMD_DESC MS_NAME_DESC GRR_CMDG_DESC
             "Send a CHANNEL REQUEST (RACH) to the network\n"
             "One-phase packet access (011110xx or 01111x0x or 01111xx0)\n"
             "Two-phase (single block) packet access (01110xxx)\n")
 {
        struct osmocom_ms *ms;
-       uint8_t chan_req;

        if ((ms = l23_vty_get_ms(argv[0], vty)) == NULL)
                return CMD_WARNING;

-       chan_req = modem_grr_gen_chan_req(argv[1][0] == '2');
        const struct osmo_gprs_rlcmac_l1ctl_prim lp = {
                .rach_req = {
                        .is_11bit = false,
-                       .ra = chan_req,
+                       /* the 3 LSBs are randomized during (re)transmission */
+                       .ra = argv[1][0] == '1' ? 0x70 : 0x78,
                }
        };

-       if (osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_RACH_REQ, (void *)&lp)) {
+       if (osmo_fsm_inst_dispatch(ms->grr_fi, GRR_EV_CHAN_ACCESS_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/+/34514?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: Iab6d9147f6e0aeb99239affacf318a3897fd6ffe
Gerrit-Change-Number: 34514
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanits...@sysmocom.de>
Gerrit-MessageType: newchange

Reply via email to