Review at  https://gerrit.osmocom.org/6774

host/trxcon/l1ctl.c: share primitive management code

This change introduces shared primitive management functions,
exposed from the l1ctl_rx_data_req() implementation:

  - sched_trx_init_prim() - allocates memory for a new primitive
    and its payload. Initializes primitive's header, setting
    the logical channel type and the payload length. After
    initialization, the talloc context of a primitive is
    a trx instance, which passed as the first argument.

  - sched_trx_push_prim() - decodes the timeslot index from
    chan_nr and pushes a primitive to its transimt queue.
    The talloc context of primitive is changed to the
    parent trx_ts instance after queuing.

Both functions will be used for handling both L1CTL_TRAFFIC_REQ
and L1CTL_RACH_REQ.

Change-Id: I8169a1ef4ef54d91b50f3e213e4842f54af8b499
---
M src/host/trxcon/l1ctl.c
M src/host/trxcon/sched_trx.c
M src/host/trxcon/sched_trx.h
3 files changed, 92 insertions(+), 46 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/74/6774/1

diff --git a/src/host/trxcon/l1ctl.c b/src/host/trxcon/l1ctl.c
index f193a7a..f125948 100644
--- a/src/host/trxcon/l1ctl.c
+++ b/src/host/trxcon/l1ctl.c
@@ -589,17 +589,13 @@
 
 static int l1ctl_rx_data_req(struct l1ctl_link *l1l, struct msgb *msg)
 {
-       struct trx_ts *ts;
-       struct trx_ts_prim *prim;
        struct l1ctl_info_ul *ul;
-       struct l1ctl_data_ind *data_ind;
-       enum trx_lchan_type lchan_type;
-       uint8_t chan_nr, link_id, tn;
-       size_t len;
-       int rc = 0;
+       struct trx_ts_prim *prim;
+       uint8_t chan_nr, link_id;
+       int rc;
 
+       /* Extract UL frame header */
        ul = (struct l1ctl_info_ul *) msg->l1h;
-       data_ind = (struct l1ctl_data_ind *) ul->payload;
 
        /* Obtain channel description */
        chan_nr = ul->chan_nr;
@@ -608,48 +604,21 @@
        LOGP(DL1D, LOGL_DEBUG, "Recv Data Req (chan_nr=0x%02x, "
                "link_id=0x%02x)\n", chan_nr, link_id);
 
-       /* Determine TS index */
-       tn = chan_nr & 0x7;
-       if (tn > 7) {
-               LOGP(DL1D, LOGL_ERROR, "Incorrect TS index %u\n", tn);
-               rc = -EINVAL;
+       /* Init a new primitive */
+       rc = sched_trx_init_prim(l1l->trx, &prim, 23,
+               chan_nr, link_id);
+       if (rc)
+               goto exit;
+
+       /* Push this primitive to transmit queue */
+       rc = sched_trx_push_prim(l1l->trx, prim, chan_nr);
+       if (rc) {
+               talloc_free(prim);
                goto exit;
        }
-
-       /* Determine lchan type */
-       lchan_type = sched_trx_chan_nr2lchan_type(chan_nr, link_id);
-       if (!lchan_type) {
-               LOGP(DL1D, LOGL_ERROR, "Couldn't determine lchan type "
-                       "for chan_nr=%02x and link_id=%02x\n", chan_nr, 
link_id);
-               rc = -EINVAL;
-               goto exit;
-       }
-
-       /* Check whether required timeslot is allocated and configured */
-       ts = l1l->trx->ts_list[tn];
-       if (ts == NULL || ts->mf_layout == NULL) {
-               LOGP(DL1D, LOGL_ERROR, "Timeslot %u isn't configured\n", tn);
-               rc = -EINVAL;
-               goto exit;
-       }
-
-       /* Allocate a new primitive */
-       len = sizeof(struct trx_ts_prim) + sizeof(struct l1ctl_info_ul) + 23;
-       prim = talloc_zero_size(ts, len);
-       if (prim == NULL) {
-               LOGP(DL1D, LOGL_ERROR, "Failed to allocate memory\n");
-               rc = -ENOMEM;
-               goto exit;
-       }
-
-       /* Set logical channel of primitive */
-       prim->chan = lchan_type;
 
        /* Fill in the payload */
-       memcpy(prim->payload, data_ind, 23);
-
-       /* Add to TS queue */
-       llist_add_tail(&prim->list, &ts->tx_prims);
+       memcpy(prim->payload, ul->payload, 23);
 
 exit:
        msgb_free(msg);
diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index 956c261..7f6729c 100644
--- a/src/host/trxcon/sched_trx.c
+++ b/src/host/trxcon/sched_trx.c
@@ -417,6 +417,75 @@
        }
 }
 
+int sched_trx_init_prim(struct trx_instance *trx,
+       struct trx_ts_prim **prim, size_t pl_len,
+       uint8_t chan_nr, uint8_t link_id)
+{
+       enum trx_lchan_type lchan_type;
+       struct trx_ts_prim *new_prim;
+       uint8_t len;
+
+       /* Determine lchan type */
+       lchan_type = sched_trx_chan_nr2lchan_type(chan_nr, link_id);
+       if (!lchan_type) {
+               LOGP(DSCH, LOGL_ERROR, "Couldn't determine lchan type "
+                       "for chan_nr=%02x and link_id=%02x\n", chan_nr, 
link_id);
+               return -EINVAL;
+       }
+
+       /* How much memory do we need? */
+       len  = sizeof(struct trx_ts_prim); /* Primitive header */
+       len += pl_len; /* Requested payload size */
+
+       /* Allocate a new primitive */
+       new_prim = talloc_zero_size(trx, len);
+       if (new_prim == NULL) {
+               LOGP(DSCH, LOGL_ERROR, "Failed to allocate memory\n");
+               return -ENOMEM;
+       }
+
+       /* Init primitive header */
+       new_prim->payload_len = pl_len;
+       new_prim->chan = lchan_type;
+
+       /* Set external pointer */
+       *prim = new_prim;
+
+       return 0;
+}
+
+int sched_trx_push_prim(struct trx_instance *trx,
+       struct trx_ts_prim *prim, uint8_t chan_nr)
+{
+       struct trx_ts *ts;
+       uint8_t tn;
+
+       /* Determine TS index */
+       tn = chan_nr & 0x7;
+       if (tn > 7) {
+               LOGP(DSCH, LOGL_ERROR, "Incorrect TS index %u\n", tn);
+               return -EINVAL;
+       }
+
+       /* Check whether required timeslot is allocated and configured */
+       ts = trx->ts_list[tn];
+       if (ts == NULL || ts->mf_layout == NULL) {
+               LOGP(DSCH, LOGL_ERROR, "Timeslot %u isn't configured\n", tn);
+               return -EINVAL;
+       }
+
+       /**
+        * Change talloc context of primitive
+        * from trx to the parent ts
+        */
+       talloc_steal(ts, prim);
+
+       /* Add primitive to TS transmit queue */
+       llist_add_tail(&prim->list, &ts->tx_prims);
+
+       return 0;
+}
+
 enum gsm_phys_chan_config sched_trx_chan_nr2pchan_config(uint8_t chan_nr)
 {
        uint8_t cbits = chan_nr >> 3;
diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h
index 1b74041..4209f53 100644
--- a/src/host/trxcon/sched_trx.h
+++ b/src/host/trxcon/sched_trx.h
@@ -235,6 +235,8 @@
        struct llist_head list;
        /*! \brief Logical channel type */
        enum trx_lchan_type chan;
+       /*! \brief Payload length */
+       size_t payload_len;
        /*! \brief Payload */
        uint8_t payload[0];
 };
@@ -267,5 +269,11 @@
 struct trx_lchan_state *sched_trx_find_lchan(struct trx_ts *ts,
        enum trx_lchan_type chan);
 
+/* Primitive management functions */
+int sched_trx_init_prim(struct trx_instance *trx, struct trx_ts_prim **prim,
+       size_t pl_len, uint8_t chan_nr, uint8_t link_id);
+int sched_trx_push_prim(struct trx_instance *trx,
+       struct trx_ts_prim *prim, uint8_t chan_nr);
+
 int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t tn,
        uint32_t burst_fn, sbit_t *bits, uint16_t nbits, int8_t rssi, float 
toa);

-- 
To view, visit https://gerrit.osmocom.org/6774
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8169a1ef4ef54d91b50f3e213e4842f54af8b499
Gerrit-PatchSet: 1
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>

Reply via email to