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


Change subject: modem: request an Uplink TBF, match Immediate Assignment
......................................................................

modem: request an Uplink TBF, match Immediate Assignment

Change-Id: Iec0dcc629d29dec270649cf7428f71af0dfd2dbb
Related: SYS#5500
---
M src/host/layer23/src/modem/app_modem.c
1 file changed, 99 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/48/30948/1

diff --git a/src/host/layer23/src/modem/app_modem.c 
b/src/host/layer23/src/modem/app_modem.c
index c135ff3..4ad02a3 100644
--- a/src/host/layer23/src/modem/app_modem.c
+++ b/src/host/layer23/src/modem/app_modem.c
@@ -45,8 +45,30 @@
 static struct {
        enum ccch_mode ccch_mode;
        struct gsm48_sysinfo si;
+
+       /* TODO: use mobile->rrlayer API instead */
+       struct {
+               bool ref_valid;
+               struct gsm48_req_ref ref;
+       } chan_req;
 } app_data;

+/* Generate a 8-bit CHANNEL REQUEST message as per 3GPP TS 44.018, 9.1.8 */
+static uint8_t gen_chan_req(bool single_block)
+{
+       uint8_t rnd = (uint8_t)rand();
+
+       if (single_block) {
+               /* 01110xxx */
+               return 0x70 | (rnd & 0x07);
+       } else {
+               /* 011110xx or 01111x0x or 01111xx0 */
+               if ((rnd & 0x07) == 0x07)
+                       return 0x78;
+               return 0x78 | (rnd & 0x07);
+       }
+}
+
 static int handle_si1(struct osmocom_ms *ms, struct msgb *msg)
 {
        int rc;
@@ -127,6 +149,7 @@

 static int handle_si13(struct osmocom_ms *ms, struct msgb *msg)
 {
+       struct gsm48_rrlayer *rr = &ms->rrlayer;
        int rc;

        if (msgb_l3len(msg) != GSM_MACBLOCK_LEN)
@@ -138,6 +161,22 @@
        if (rc != 0)
                return rc;

+#if 1
+       /* HACK: request an Uplink TBF here (one phase access) */
+       if (rr->state == GSM48_RR_ST_IDLE) {
+               if (!app_data.si.si1)
+                       return 0;
+               if (!app_data.si.gprs.supported)
+                       return 0;
+
+               rr->cr_ra = gen_chan_req(false);
+               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,
+                                 app_data.ccch_mode == CCCH_MODE_COMBINED);
+               rr->state = GSM48_RR_ST_CONN_PEND;
+       }
+#endif
+
        return 0;
 }

@@ -166,6 +205,7 @@
 static int modem_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
 {
        const struct gsm48_imm_ass *ia = msgb_l3(msg);
+       struct gsm48_rrlayer *rr = &ms->rrlayer;
        uint8_t ch_type, ch_subch, ch_ts;
        int rc;

@@ -173,6 +213,13 @@
        if ((ia->page_mode >> 4) == 0)
                return 0;

+       if (rr->state != GSM48_RR_ST_CONN_PEND)
+               return 0;
+       if (!app_data.chan_req.ref_valid)
+               return 0;
+       if (memcmp(&ia->req_ref, &app_data.chan_req.ref, sizeof(ia->req_ref)))
+               return 0;
+
        if (rsl_dec_chan_nr(ia->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts) 
!= 0) {
                LOGP(DRR, LOGL_ERROR,
                     "%s(): rsl_dec_chan_nr(chan_nr=0x%02x) failed\n",
@@ -190,9 +237,13 @@
                     "ARFCN=%u, TS=%u, SS=%u, TSC=%u)\n", ia->req_ref.ra,
                     ia->chan_desc.chan_nr, arfcn, ch_ts, ch_subch,
                     ia->chan_desc.h0.tsc);
+
+               l1ctl_tx_dm_est_req_h0(ms, arfcn, RSL_CHAN_OSMO_PDCH,
+                                      ia->chan_desc.h0.tsc, GSM48_CMODE_SIGN, 
0);
        } else {
                /* Hopping */
-               uint8_t maio, hsn;
+               uint8_t maio, hsn, ma_len;
+               uint16_t ma[64];

                hsn = ia->chan_desc.h1.hsn;
                maio = ia->chan_desc.h1.maio_low | (ia->chan_desc.h1.maio_high 
<< 2);
@@ -201,6 +252,22 @@
                     "HSN=%u, MAIO=%u, TS=%u, SS=%u, TSC=%u)\n", ia->req_ref.ra,
                     ia->chan_desc.chan_nr, hsn, maio, ch_ts, ch_subch,
                     ia->chan_desc.h1.tsc);
+
+               for (unsigned int i = 1, j = 0; i <= 1024; i++) {
+                       unsigned int arfcn = i & 1023;
+                       unsigned int k;
+
+                       if (~app_data.si.freq[arfcn].mask & 0x01)
+                               continue;
+
+                       k = ia->mob_alloc_len - (j >> 3) - 1;
+                       if (ia->mob_alloc[k] & (1 << (j & 7)))
+                               ma[ma_len++] = arfcn;
+                       j++;
+               }
+
+               l1ctl_tx_dm_est_req_h1(ms, maio, hsn, &ma[0], ma_len, 
RSL_CHAN_OSMO_PDCH,
+                                      ia->chan_desc.h1.tsc, GSM48_CMODE_SIGN, 
0);
        }

        const uint8_t *data = msgb_l3(msg) + sizeof(*ia) + ia->mob_alloc_len;
@@ -213,6 +280,9 @@
                return rc;
        }

+       /* TODO: deliver decoded params to the RLC/MAC layer */
+
+       rr->state = GSM48_RR_ST_DEDICATED;
        return 0;
 }

@@ -313,6 +383,31 @@
        }
 }

+static int modem_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)\n",
+                            rr->cr_ra, ref->t1, ref->t3_high << 3 | 
ref->t3_low, ref->t2);
+                       memcpy(&app_data.chan_req.ref, ref, sizeof(*ref));
+                       app_data.chan_req.ref.ra = rr->cr_ra;
+                       app_data.chan_req.ref_valid = true;
+                       return 0;
+               }
+               /* fall-through */
+       default:
+               LOGP(DRSL, LOGL_NOTICE, "Unhandled RSLms CCHAN message "
+                    "(msg_type 0x%02x)\n", ch->c.msg_type);
+               return -EINVAL;
+       }
+}
+
 static int modem_rslms_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx)
 {
        const struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
@@ -322,6 +417,9 @@
        case ABIS_RSL_MDISC_RLL:
                rc = modem_rx_rslms_rll((struct osmocom_ms *)ctx, msg);
                break;
+       case ABIS_RSL_MDISC_COM_CHAN:
+               rc = modem_rx_rslms_cchan((struct osmocom_ms *)ctx, msg);
+               break;
        default:
                LOGP(DRSL, LOGL_NOTICE, "Unhandled RSLms message "
                     "(msg_discr 0x%02x)\n", rslh->msg_discr);

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

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: Iec0dcc629d29dec270649cf7428f71af0dfd2dbb
Gerrit-Change-Number: 30948
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanits...@sysmocom.de>
Gerrit-MessageType: newchange

Reply via email to