From: Andreas Eversberg <[email protected]>

This part moves PDTCH, PACCH and PTCCH message primitives from
osmo-bts-sysmo to common part.
---
 src/common/l1sap.c         |  90 +++++++++++++++++++++++++++
 src/common/pcu_sock.c      |   7 +--
 src/osmo-bts-sysmo/l1_if.c | 152 ++++++++++++++++++++++++---------------------
 3 files changed, 172 insertions(+), 77 deletions(-)

diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index 12be383..633a5a5 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -91,6 +91,19 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx,
        DEBUGP(DL1P, "Rx PH-RTS.ind %02u/%02u/%02u chan_nr=%d link_id=%d\n",
                g_time.t1, g_time.t2, g_time.t3, chan_nr, link_id);
 
+       if (trx->ts[tn].pchan == GSM_PCHAN_PDCH) {
+               if (L1SAP_IS_PTCCH(rts_ind->fn)) {
+                       pcu_tx_rts_req(&trx->ts[tn], 1, fn, 1 /* ARFCN */,
+                               L1SAP_FN2PTCCHBLOCK(fn));
+
+                       return 0;
+               }
+               pcu_tx_rts_req(&trx->ts[tn], 0, fn, 0 /* ARFCN */,
+                       L1SAP_FN2MACBLOCK(fn));
+
+               return 0;
+       }
+
        /* reuse PH-RTS.ind for PH-DATA.req */
        if (!msg) {
                LOGP(DL1P, LOGL_FATAL, "RTS without msg to be reused. Please "
@@ -155,6 +168,54 @@ static int l1sap_handover_rach(struct gsm_bts_trx *trx,
        return 0;
 }
 
+/* DATA received from bts model */
+static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
+        struct osmo_phsap_prim *l1sap, struct ph_data_param *data_ind)
+{
+       struct msgb *msg = l1sap->oph.msg;
+       struct gsm_time g_time;
+       uint8_t *data = msg->l2h;
+       int len = msgb_l2len(msg);
+       uint8_t chan_nr, link_id;
+       uint8_t tn, ss;
+       uint32_t fn;
+       int8_t rssi;
+
+       rssi = data_ind->rssi;
+       chan_nr = data_ind->chan_nr;
+       link_id = data_ind->link_id;
+       fn = data_ind->fn;
+       tn = L1SAP_CHAN2TS(chan_nr);
+       ss = l1sap_chan2ss(chan_nr);
+
+       gsm_fn2gsmtime(&g_time, fn);
+
+       DEBUGP(DL1P, "Rx PH-DATA.ind %02u/%02u/%02u chan_nr=%d link_id=%d\n",
+               g_time.t1, g_time.t2, g_time.t3, chan_nr, link_id);
+
+       if (trx->ts[tn].pchan == GSM_PCHAN_PDCH) {
+               if (len == 0)
+                       return -EINVAL;
+               if (L1SAP_IS_PTCCH(fn)) {
+                       pcu_tx_data_ind(&trx->ts[tn], 1, fn,
+                               0 /* ARFCN */, L1SAP_FN2PTCCHBLOCK(fn),
+                               data, len, rssi);
+
+                       return 0;
+               }
+               /* drop incomplete UL block */
+               if (data[0] != 7)
+                       return 0;
+               /* PDTCH / PACCH frame handling */
+               pcu_tx_data_ind(&trx->ts[tn], 0, fn, 0 /* ARFCN */,
+                       L1SAP_FN2MACBLOCK(fn), data + 1, len - 1, rssi);
+
+               return 0;
+       }
+
+       return 0;
+}
+
 /* RACH received from bts model */
 static int l1sap_ph_rach_ind(struct gsm_bts_trx *trx,
         struct osmo_phsap_prim *l1sap, struct ph_rach_ind_param *rach_ind)
@@ -204,6 +265,9 @@ int l1sap_up(struct gsm_bts_trx *trx, struct 
osmo_phsap_prim *l1sap)
        case OSMO_PRIM(PRIM_PH_RTS, PRIM_OP_INDICATION):
                rc = l1sap_ph_rts_ind(trx, l1sap, &l1sap->u.data);
                break;
+       case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_INDICATION):
+               rc = l1sap_ph_data_ind(trx, l1sap, &l1sap->u.data);
+               break;
        case OSMO_PRIM(PRIM_PH_RACH, PRIM_OP_INDICATION):
                rc = l1sap_ph_rach_ind(trx, l1sap, &l1sap->u.rach_ind);
                break;
@@ -226,3 +290,29 @@ static int l1sap_down(struct gsm_bts_trx *trx, struct 
osmo_phsap_prim *l1sap)
        return bts_model_l1sap_down(trx, l1sap);
 }
 
+/* pcu (socket interface) sends us a data request primitive */
+int l1sap_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn,
+       uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len)
+{
+       struct msgb *msg;
+       struct osmo_phsap_prim *l1sap;
+       struct gsm_time g_time;
+
+       gsm_fn2gsmtime(&g_time, fn);
+
+       DEBUGP(DL1P, "TX packet data %02u/%02u/%02u is_ptcch=%d trx=%d ts=%d "
+               "block_nr=%d, arfcn=%d, len=%d\n", g_time.t1, g_time.t2,
+               g_time.t3, is_ptcch, ts->trx->nr, ts->nr, block_nr, arfcn, len);
+
+       msg = l1sap_msgb_alloc(len);
+       l1sap = msgb_l1sap_prim(msg);
+       osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_DATA, PRIM_OP_REQUEST,
+               msg);
+       l1sap->u.data.chan_nr = 0x08 | ts->nr;
+       l1sap->u.data.link_id = 0x00;
+       l1sap->u.data.fn = fn;
+       msg->l2h = msgb_put(msg, len);
+       memcpy(msg->l2h, data, len);
+
+       return l1sap_down(ts->trx, l1sap);
+}
diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c
index a978e46..515993e 100644
--- a/src/common/pcu_sock.c
+++ b/src/common/pcu_sock.c
@@ -40,6 +40,7 @@
 #include <osmo-bts/rsl.h>
 #include <osmo-bts/signal.h>
 #include <osmo-bts/bts_model.h>
+#include <osmo-bts/l1sap.h>
 
 uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx);
 
@@ -57,10 +58,6 @@ static const char *sapi_string[] = {
        [PCU_IF_SAPI_PTCCH] =   "PTCCH",
 };
 
-/* FIXME: common l1if include ? */
-int l1if_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn,
-        uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len);
-
 static int pcu_sock_send(struct gsm_network *net, struct msgb *msg);
 /* FIXME: move this to libosmocore */
 int osmo_unixsock_listen(struct osmo_fd *bfd, int type, const char *path);
@@ -512,7 +509,7 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t 
msg_type,
                }
                ts = &trx->ts[data_req->ts_nr];
                is_ptcch = (data_req->sapi == PCU_IF_SAPI_PTCCH);
-               rc = l1if_pdch_req(ts, is_ptcch, data_req->fn, data_req->arfcn,
+               rc = l1sap_pdch_req(ts, is_ptcch, data_req->fn, data_req->arfcn,
                        data_req->block_nr, data_req->data, data_req->len);
                break;
        default:
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index a3fd64e..d4861e2 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -466,7 +466,17 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct 
msgb *msg,
        u32Fn = l1sap->u.data.fn;
        u8Tn = L1SAP_CHAN2TS(chan_nr);
        subCh = 0x1f;
-       if (L1SAP_IS_CHAN_BCCH(chan_nr)) {
+       if (L1SAP_IS_CHAN_TCHF(chan_nr)) {
+               if (trx->ts[u8Tn].pchan == GSM_PCHAN_PDCH) {
+                       if (L1SAP_IS_PTCCH(u32Fn)) {
+                               sapi = GsmL1_Sapi_Ptcch;
+                               u8BlockNbr = L1SAP_FN2PTCCHBLOCK(u32Fn);
+                       } else {
+                               sapi = GsmL1_Sapi_Pdtch;
+                               u8BlockNbr = L1SAP_FN2MACBLOCK(u32Fn);
+                       }
+               }
+       } else if (L1SAP_IS_CHAN_BCCH(chan_nr)) {
                sapi = GsmL1_Sapi_Bcch;
        } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) {
                /* The sapi depends on DSP configuration, not
@@ -556,6 +566,35 @@ static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config 
pchan,
        case GsmL1_Sapi_Pch:
                cbits = 0x12;
                break;
+       case GsmL1_Sapi_Pdtch:
+       case GsmL1_Sapi_Pacch:
+               switch(pchan) {
+               case GSM_PCHAN_PDCH:
+                       cbits = 0x01;
+                       break;
+               default:
+                       LOGP(DL1C, LOGL_ERROR, "PDTCH for pchan %d?\n",
+                               pchan);
+                       return 0;
+               }
+               break;
+       case GsmL1_Sapi_Ptcch:
+               if (!L1SAP_IS_PTCCH(u32Fn)) {
+                       LOGP(DL1C, LOGL_FATAL, "Not expecting PTCCH at frame "
+                               "number other than 12, got it at %u (%u). "
+                               "Please fix!\n", u32Fn % 52, u32Fn);
+                       abort();
+               }
+               switch(pchan) {
+               case GSM_PCHAN_PDCH:
+                       cbits = 0x01;
+                       break;
+               default:
+                       LOGP(DL1C, LOGL_ERROR, "PTCCH for pchan %d?\n",
+                               pchan);
+                       return 0;
+               }
+               break;
        default:
                return 0;
        }
@@ -648,13 +687,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl 
*fl1,
                /* actually transmit it */
                goto tx;
                break;
-       case GsmL1_Sapi_Pdtch:
-       case GsmL1_Sapi_Pacch:
-               return pcu_tx_rts_req(&trx->ts[rts_ind->u8Tn], 0,
-                       rts_ind->u32Fn, rts_ind->u16Arfcn, rts_ind->u8BlockNbr);
-       case GsmL1_Sapi_Ptcch:
-               return pcu_tx_rts_req(&trx->ts[rts_ind->u8Tn], 1,
-                       rts_ind->u32Fn, rts_ind->u16Arfcn, rts_ind->u8BlockNbr);
        default:
                break;
        }
@@ -886,6 +918,10 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, 
GsmL1_PhDataInd_t *data_i
        struct gsm_lchan *lchan;
        struct lapdm_entity *le;
        struct msgb *msg;
+       uint8_t chan_nr, link_id;
+       struct osmo_phsap_prim *l1sap;
+       uint32_t fn;
+       uint8_t *data, len;
        int rc = 0;
 
        ul_to_gsmtap(fl1, l1p_msg);
@@ -895,14 +931,22 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, 
GsmL1_PhDataInd_t *data_i
                LOGP(DL1C, LOGL_ERROR,
                        "unable to resolve lchan by hLayer2 for 0x%x\n",
                        data_ind->hLayer2);
+               msgb_free(l1p_msg);
                return -ENODEV;
        }
 
+       chan_nr = chan_nr_by_sapi(trx->ts[data_ind->u8Tn].pchan, data_ind->sapi,
+               data_ind->subCh, data_ind->u8Tn, data_ind->u32Fn);
+       fn = data_ind->u32Fn;
+       link_id =  (data_ind->sapi == GsmL1_Sapi_Sacch) ? 0x40 : 0x00;
+
        process_meas_res(lchan, &data_ind->measParam);
 
        if (data_ind->measParam.fLinkQuality < fl1->min_qual_norm
-        && data_ind->msgUnitParam.u8Size != 0)
+        && data_ind->msgUnitParam.u8Size != 0) {
+               msgb_free(l1p_msg);
                return 0;
+       }
 
        DEBUGP(DL1C, "Rx PH-DATA.ind %s (hL2 %08x): %s",
                get_value_string(femtobts_l1sapi_names, data_ind->sapi),
@@ -973,27 +1017,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, 
GsmL1_PhDataInd_t *data_i
                break;
        case GsmL1_Sapi_Pdtch:
        case GsmL1_Sapi_Pacch:
-               /* drop incomplete UL block */
-               if (!data_ind->msgUnitParam.u8Size
-                || data_ind->msgUnitParam.u8Buffer[0]
-                       != GsmL1_PdtchPlType_Full)
-                       break;
-               /* PDTCH / PACCH frame handling */
-               rc = pcu_tx_data_ind(&trx->ts[data_ind->u8Tn], 0,
-                       data_ind->u32Fn, data_ind->u16Arfcn,
-                       data_ind->u8BlockNbr,
-                       data_ind->msgUnitParam.u8Buffer + 1,
-                       data_ind->msgUnitParam.u8Size - 1,
-                       (int8_t) (data_ind->measParam.fRssi));
-               break;
        case GsmL1_Sapi_Ptcch:
-               /* PTCCH frame handling */
-               rc = pcu_tx_data_ind(&trx->ts[data_ind->u8Tn], 1,
-                       data_ind->u32Fn, data_ind->u16Arfcn,
-                       data_ind->u8BlockNbr,
-                       data_ind->msgUnitParam.u8Buffer,
-                       data_ind->msgUnitParam.u8Size,
-                       (int8_t) (data_ind->measParam.fRssi));
                break;
        case GsmL1_Sapi_Idle:
                /* nothing to send */
@@ -1004,7 +1028,32 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, 
GsmL1_PhDataInd_t *data_i
                break;
        }
 
-       return rc;
+       if (!chan_nr) {
+               msgb_free(l1p_msg);
+               return rc;
+       }
+
+       /* get data pointer and length */
+       data = data_ind->msgUnitParam.u8Buffer;
+       len = data_ind->msgUnitParam.u8Size;
+       /* pull lower header part before data */
+       msgb_pull(l1p_msg, data - l1p_msg->data);
+       /* trim remaining data to it's size, to get rid of upper header part */
+       rc = msgb_trim(l1p_msg, len);
+       if (rc < 0)
+               MSGB_ABORT(l1p_msg, "No room for primitive data\n");
+       l1p_msg->l2h = l1p_msg->data;
+       /* push new l1 header */
+       l1p_msg->l1h = msgb_push(l1p_msg, sizeof(*l1sap));
+       /* fill header */
+       l1sap = msgb_l1sap_prim(l1p_msg);
+       osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_DATA,
+               PRIM_OP_INDICATION, l1p_msg);
+       l1sap->u.data.link_id = link_id;
+       l1sap->u.data.chan_nr = chan_nr;
+       l1sap->u.data.fn = fn;
+
+       return l1sap_up(trx, l1sap);
 }
 
 static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind,
@@ -1084,8 +1133,7 @@ static int l1if_handle_ind(struct femtol1_hdl *fl1, 
struct msgb *msg)
                return handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd,
                                               msg);
        case GsmL1_PrimId_PhDataInd:
-               rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg);
-               break;
+               return handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg);
        case GsmL1_PrimId_PhRaInd:
                return handle_ph_ra_ind(fl1, &l1p->u.phRaInd, msg);
                break;
@@ -1538,46 +1586,6 @@ int l1if_set_trace_flags(struct femtol1_hdl *hdl, 
uint32_t flags)
        return osmo_wqueue_enqueue(&hdl->write_q[MQ_SYS_WRITE], msg);
 }
 
-/* send packet data request to L1 */
-int l1if_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn,
-       uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len)
-{
-       struct gsm_bts_trx *trx = ts->trx;
-       struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
-       struct msgb *msg;
-       GsmL1_Prim_t *l1p;
-       GsmL1_PhDataReq_t *data_req;
-       GsmL1_MsgUnitParam_t *msu_param;
-       struct gsm_time g_time;
-
-       gsm_fn2gsmtime(&g_time, fn);
-
-       DEBUGP(DL1P, "TX packet data %02u/%02u/%02u is_ptcch=%d trx=%d ts=%d "
-               "block_nr=%d, arfcn=%d, len=%d\n", g_time.t1, g_time.t2,
-               g_time.t3, is_ptcch, ts->trx->nr, ts->nr, block_nr, arfcn, len);
-
-       msg = l1p_msgb_alloc();
-       l1p = msgb_l1prim(msg);
-       l1p->id = GsmL1_PrimId_PhDataReq;
-       data_req = &l1p->u.phDataReq;
-       data_req->hLayer1 = fl1h->hLayer1;
-       data_req->sapi = (is_ptcch) ? GsmL1_Sapi_Ptcch : GsmL1_Sapi_Pdtch;
-       data_req->subCh = GsmL1_SubCh_NA;
-       data_req->u8BlockNbr = block_nr;
-       data_req->u8Tn = ts->nr;
-       data_req->u32Fn = fn;
-       msu_param = &data_req->msgUnitParam;
-       msu_param->u8Size = len;
-       memcpy(msu_param->u8Buffer, data, len);
-
-       tx_to_gsmtap(fl1h, msg);
-
-       /* transmit */
-       osmo_wqueue_enqueue(&fl1h->write_q[MQ_L1_WRITE], msg);
-
-       return 0;
-}
-
 /* get those femtol1_hdl.hw_info elements that sre in EEPROM */
 static int get_hwinfo_eeprom(struct femtol1_hdl *fl1h)
 {
-- 
2.1.0


Reply via email to