From: Andreas Eversberg <[email protected]>

This part moves control channel message primitives from osmo-bts-sysmo to
common part.

In order to control ciphering fo BTS model, CIPHER (MPH_INFO) messages are
used.
---
 src/common/l1sap.c         | 181 ++++++++++++++++++++++++++++++++++++-
 src/osmo-bts-sysmo/l1_if.c | 219 ++++++++++++++++++---------------------------
 2 files changed, 265 insertions(+), 135 deletions(-)

diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index 9068bb8..14dbde9 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -69,6 +69,54 @@ struct msgb *l1sap_msgb_alloc(unsigned int l2_len)
        return msg;
 }
 
+static int l1sap_tx_ciph_req(struct gsm_bts_trx *trx, uint8_t chan_nr,
+       uint8_t downlink, uint8_t uplink)
+{
+       struct osmo_phsap_prim l1sap_ciph;
+
+       osmo_prim_init(&l1sap_ciph.oph, SAP_GSM_PH, PRIM_MPH_INFO,
+               PRIM_OP_REQUEST, NULL);
+       l1sap_ciph.u.info.type = PRIM_INFO_ACT_CIPH;
+       l1sap_ciph.u.info.u.ciph_req.chan_nr = chan_nr;
+       l1sap_ciph.u.info.u.ciph_req.downlink = downlink;
+       l1sap_ciph.u.info.u.ciph_req.uplink = uplink;
+
+       return l1sap_down(trx, &l1sap_ciph);
+}
+
+
+/* check if the message is a GSM48_MT_RR_CIPH_M_CMD, and if yes, enable
+ * uni-directional de-cryption on the uplink. We need this ugly layering
+ * violation as we have no way of passing down L3 metadata (RSL CIPHERING CMD)
+ * to this point in L1 */
+static int check_for_ciph_cmd(struct msgb *msg, struct gsm_lchan *lchan,
+       uint8_t chan_nr)
+{
+
+       /* only do this if we are in the right state */
+       switch (lchan->ciph_state) {
+       case LCHAN_CIPH_NONE:
+       case LCHAN_CIPH_RX_REQ:
+               break;
+       default:
+               return 0;
+       }
+
+       /* First byte (Address Field) of LAPDm header) */
+       if (msg->data[0] != 0x03)
+               return 0;
+       /* First byte (protocol discriminator) of RR */
+       if ((msg->data[3] & 0xF) != GSM48_PDISC_RR)
+               return 0;
+       /* 2nd byte (msg type) of RR */
+       if ((msg->data[4] & 0x3F) != GSM48_MT_RR_CIPH_M_CMD)
+               return 0;
+
+       l1sap_tx_ciph_req(lchan->ts->trx, chan_nr, 0, 1);
+
+       return 1;
+}
+
 /* time information received from bts model */
 static int l1sap_info_time_ind(struct gsm_bts_trx *trx,
        struct osmo_phsap_prim *l1sap,
@@ -193,10 +241,13 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx,
 {
        struct msgb *msg = l1sap->oph.msg;
        struct gsm_time g_time;
+       struct gsm_lchan *lchan;
        uint8_t chan_nr, link_id;
-       uint8_t tn;
+       uint8_t tn, ss;
        uint32_t fn;
        uint8_t *p, *si;
+       struct lapdm_entity *le;
+       struct osmo_phsap_prim pp;
        int rc;
 
        chan_nr = rts_ind->chan_nr;
@@ -241,6 +292,52 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx,
                        memcpy(p, si, GSM_MACBLOCK_LEN);
                else
                        memcpy(p, fill_frame, GSM_MACBLOCK_LEN);
+       } else if (!(chan_nr & 0x80)) { /* only TCH/F, TCH/H, SDCCH/4 and 
SDCCH/8 have C5 bit cleared */
+               if (L1SAP_IS_CHAN_TCHH(chan_nr))
+                       ss = L1SAP_CHAN2SS_TCHH(chan_nr); /* TCH/H */
+               else if (L1SAP_IS_CHAN_SDCCH4(chan_nr))
+                       ss = L1SAP_CHAN2SS_SDCCH4(chan_nr); /* SDCCH/4 */
+               else if (L1SAP_IS_CHAN_SDCCH8(chan_nr))
+                       ss = L1SAP_CHAN2SS_SDCCH8(chan_nr); /* SDCCH/8 */
+               else
+                       ss = 0; /* TCH/F */
+               lchan = &trx->ts[tn].lchan[ss];
+               if (L1SAP_IS_LINK_SACCH(link_id)) {
+                       p = msgb_put(msg, GSM_MACBLOCK_LEN);
+                       /* L1-header, if not set/modified by layer 1 */
+                       p[0] = lchan->ms_power;
+                       p[1] = lchan->rqd_ta;
+                       le = &lchan->lapdm_ch.lapdm_acch;
+               } else
+                       le = &lchan->lapdm_ch.lapdm_dcch;
+               rc = lapdm_phsap_dequeue_prim(le, &pp);
+               if (rc < 0) {
+                       if (L1SAP_IS_LINK_SACCH(link_id)) {
+                               /* No SACCH data from LAPDM pending, send SACCH 
filling */
+                               uint8_t *si = lchan_sacch_get(lchan);
+                               if (si) {
+                                       /* The +2 is empty space where the DSP 
inserts the L1 hdr */
+                                       memcpy(p + 2, si, GSM_MACBLOCK_LEN - 2);
+                               } else
+                                       memcpy(p + 2, fill_frame, 
GSM_MACBLOCK_LEN - 2);
+                       } else if ((!L1SAP_IS_CHAN_TCHF(chan_nr) && 
!L1SAP_IS_CHAN_TCHH(chan_nr))
+                               || lchan->rsl_cmode == RSL_CMOD_SPD_SIGN) {
+                               /* send fill frame only, if not TCH/x != 
Signalling, otherwise send empty frame */
+                               p = msgb_put(msg, GSM_MACBLOCK_LEN);
+                               memcpy(p, fill_frame, GSM_MACBLOCK_LEN);
+                       } /* else the message remains empty, so TCH frames are 
sent */
+               } else {
+                       /* The +2 is empty space where the DSP inserts the L1 
hdr */
+                       if (L1SAP_IS_LINK_SACCH(link_id))
+                               memcpy(p + 2, pp.oph.msg->data + 2, 
GSM_MACBLOCK_LEN - 2);
+                       else {
+                               p = msgb_put(msg, GSM_MACBLOCK_LEN);
+                               memcpy(p, pp.oph.msg->data, GSM_MACBLOCK_LEN);
+                               /* check if it is a RR CIPH MODE CMD. if yes, 
enable RX ciphering */
+                               check_for_ciph_cmd(pp.oph.msg, lchan, chan_nr);
+                       }
+                       msgb_free(pp.oph.msg);
+               }
        } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) {
                p = msgb_put(msg, GSM_MACBLOCK_LEN);
 #warning "TODO: Yet another assumption that BS_AG_BLKS_RES=1"
@@ -352,12 +449,46 @@ static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx,
        return 0;
 }
 
+/* process radio link timeout counter S */
+static void radio_link_timeout(struct gsm_lchan *lchan, int bad_frame)
+{
+       struct gsm_bts_role_bts *btsb = lchan->ts->trx->bts->role;
+
+       /* if link loss criterion already reached */
+       if (lchan->s == 0) {
+               DEBUGP(DMEAS, "%s radio link counter S already 0.\n",
+                       gsm_lchan_name(lchan));
+               return;
+       }
+
+       if (bad_frame) {
+               /* count down radio link counter S */
+               lchan->s--;
+               DEBUGP(DMEAS, "%s counting down radio link counter S=%d\n",
+                       gsm_lchan_name(lchan), lchan->s);
+               if (lchan->s == 0)
+                       rsl_tx_conn_fail(lchan, RSL_ERR_RADIO_LINK_FAIL);
+               return;
+       }
+
+       if (lchan->s < btsb->radio_link_timeout) {
+               /* count up radio link counter S */
+               lchan->s += 2;
+               if (lchan->s > btsb->radio_link_timeout)
+                       lchan->s = btsb->radio_link_timeout;
+               DEBUGP(DMEAS, "%s counting up radio link counter S=%d\n",
+                       gsm_lchan_name(lchan), lchan->s);
+       }
+}
+
 /* 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;
+       struct gsm_lchan *lchan;
+       struct lapdm_entity *le;
        uint8_t *data = msg->l2h;
        int len = msgb_l2len(msg);
        uint8_t chan_nr, link_id;
@@ -397,7 +528,53 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
                return 0;
        }
 
-       return 0;
+       lchan = &trx->ts[tn].lchan[ss];
+
+       /* bad frame */
+       if (len == 0) {
+               if (L1SAP_IS_LINK_SACCH(link_id))
+                       radio_link_timeout(lchan, 1);
+               return -EINVAL;
+       }
+
+       if (L1SAP_IS_LINK_SACCH(link_id)) {
+               radio_link_timeout(lchan, 0);
+               le = &lchan->lapdm_ch.lapdm_acch;
+               /* save the SACCH L1 header in the lchan struct for RSL MEAS 
RES */
+               if (len < 2) {
+                       LOGP(DL1P, LOGL_NOTICE, "SACCH with size %u<2 !?!\n",
+                               len);
+                       return -EINVAL;
+               }
+               /* Some brilliant engineer decided that the ordering of
+                * fields on the Um interface is different from the
+                * order of fields in RLS. See TS 04.04 (Chapter 7.2)
+                * vs. TS 08.58 (Chapter 9.3.10). */
+               lchan->meas.l1_info[0] = data[0] << 3;
+               lchan->meas.l1_info[0] |= ((data[0] >> 5) & 1) << 2;
+               lchan->meas.l1_info[1] = data[1];
+               lchan->meas.flags |= LC_UL_M_F_L1_VALID;
+       } else
+               le = &lchan->lapdm_ch.lapdm_dcch;
+
+       /* if this is the first valid message after enabling Rx
+        * decryption, we have to enable Tx encryption */
+       if (lchan->ciph_state == LCHAN_CIPH_RX_CONF) {
+               /* HACK: check if it's an I frame, in order to
+                * ignore some still buffered/queued UI frames received
+                * before decryption was enabled */
+               if (data[0] == 0x01 && (data[1] & 0x01) == 0) {
+                       l1sap_tx_ciph_req(trx, chan_nr, 1, 0);
+               }
+       }
+
+       /* SDCCH, SACCH and FACCH all go to LAPDm */
+       msgb_pull(msg, (msg->l2h - msg->data));
+       msg->l1h = NULL;
+       lapdm_phsap_up(&l1sap->oph, le);
+
+       /* don't free, because we forwarded data */
+       return 1;
 }
 
 /* TCH received from bts model */
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index f17972b..6a6437e 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -464,7 +464,11 @@ 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_TCHF(chan_nr)) {
+       if (L1SAP_IS_LINK_SACCH(link_id)) {
+               sapi = GsmL1_Sapi_Sacch;
+               if (!L1SAP_IS_CHAN_TCHF(chan_nr))
+                       subCh = l1sap_chan2ss(chan_nr);
+       } else if (L1SAP_IS_CHAN_TCHF(chan_nr)) {
                if (trx->ts[u8Tn].pchan == GSM_PCHAN_PDCH) {
                        if (L1SAP_IS_PTCCH(u32Fn)) {
                                sapi = GsmL1_Sapi_Ptcch;
@@ -473,7 +477,20 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct 
msgb *msg,
                                sapi = GsmL1_Sapi_Pdtch;
                                u8BlockNbr = L1SAP_FN2MACBLOCK(u32Fn);
                        }
+               } else {
+                       sapi = GsmL1_Sapi_FacchF;
+                       u8BlockNbr = (u32Fn % 13) >> 2;
                }
+       } else if (L1SAP_IS_CHAN_TCHH(chan_nr)) {
+               subCh = L1SAP_CHAN2SS_TCHH(chan_nr);
+               sapi = GsmL1_Sapi_FacchH;
+               u8BlockNbr = (u32Fn % 26) >> 3;
+       } else if (L1SAP_IS_CHAN_SDCCH4(chan_nr)) {
+               subCh = L1SAP_CHAN2SS_SDCCH4(chan_nr);
+               sapi = GsmL1_Sapi_Sdcch;
+       } else if (L1SAP_IS_CHAN_SDCCH8(chan_nr)) {
+               subCh = L1SAP_CHAN2SS_SDCCH8(chan_nr);
+               sapi = GsmL1_Sapi_Sdcch;
        } else if (L1SAP_IS_CHAN_BCCH(chan_nr)) {
                sapi = GsmL1_Sapi_Bcch;
        } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) {
@@ -603,12 +620,27 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct 
msgb *msg,
 static int mph_info_req(struct gsm_bts_trx *trx, struct msgb *msg,
                        struct osmo_phsap_prim *l1sap)
 {
+       struct femtol1_hdl *fl1 = trx_femtol1_hdl(trx);
        uint8_t u8Tn, ss;
        uint8_t chan_nr;
        struct gsm_lchan *lchan;
        int rc = 0;
 
        switch (l1sap->u.info.type) {
+       case PRIM_INFO_ACT_CIPH:
+               chan_nr = l1sap->u.info.u.ciph_req.chan_nr;
+               u8Tn = L1SAP_CHAN2TS(chan_nr);
+               ss = l1sap_chan2ss(chan_nr);
+               lchan = &trx->ts[u8Tn].lchan[ss];
+               if (l1sap->u.info.u.ciph_req.uplink) {
+                       l1if_set_ciphering(fl1, lchan, 0);
+                       lchan->ciph_state = LCHAN_CIPH_RX_REQ;
+               }
+               if (l1sap->u.info.u.ciph_req.downlink) {
+                       l1if_set_ciphering(fl1, lchan, 1);
+                       lchan->ciph_state = LCHAN_CIPH_TXRX_REQ;
+               }
+               break;
        case PRIM_INFO_ACTIVATE:
        case PRIM_INFO_DEACTIVATE:
        case PRIM_INFO_MODIFY:
@@ -701,6 +733,40 @@ static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config 
pchan,
        case GsmL1_Sapi_Bcch:
                cbits = 0x10;
                break;
+       case GsmL1_Sapi_Sacch:
+               switch(pchan) {
+               case GSM_PCHAN_TCH_F:
+                       cbits = 0x01;
+                       break;
+               case GSM_PCHAN_TCH_H:
+                       cbits = 0x02 + subCh;
+                       break;
+               case GSM_PCHAN_CCCH_SDCCH4:
+                       cbits = 0x04 + subCh;
+                       break;
+               case GSM_PCHAN_SDCCH8_SACCH8C:
+                       cbits = 0x08 + subCh;
+                       break;
+               default:
+                       LOGP(DL1C, LOGL_ERROR, "SACCH for pchan %d?\n",
+                               pchan);
+                       return 0;
+               }
+               break;
+       case GsmL1_Sapi_Sdcch:
+               switch(pchan) {
+               case GSM_PCHAN_CCCH_SDCCH4:
+                       cbits = 0x04 + subCh;
+                       break;
+               case GSM_PCHAN_SDCCH8_SACCH8C:
+                       cbits = 0x08 + subCh;
+                       break;
+               default:
+                       LOGP(DL1C, LOGL_ERROR, "SDCCH for pchan %d?\n",
+                               pchan);
+                       return 0;
+               }
+               break;
        case GsmL1_Sapi_Agch:
        case GsmL1_Sapi_Pch:
                cbits = 0x12;
@@ -723,6 +789,12 @@ static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config 
pchan,
        case GsmL1_Sapi_TchH:
                cbits = 0x02 + subCh;
                break;
+       case GsmL1_Sapi_FacchF:
+               cbits = 0x01;
+               break;
+       case GsmL1_Sapi_FacchH:
+               cbits = 0x02 + subCh;
+               break;
        case GsmL1_Sapi_Ptcch:
                if (!L1SAP_IS_PTCCH(u32Fn)) {
                        LOGP(DL1C, LOGL_FATAL, "Not expecting PTCCH at frame "
@@ -757,11 +829,8 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl 
*fl1,
        struct msgb *resp_msg;
        GsmL1_PhDataReq_t *data_req;
        GsmL1_MsgUnitParam_t *msu_param;
-       struct lapdm_entity *le;
-       struct gsm_lchan *lchan;
        struct gsm_time g_time;
        uint32_t t3p;
-       struct osmo_phsap_prim pp;
        int rc;
        struct osmo_phsap_prim *l1sap;
        uint8_t chan_nr, link_id;
@@ -772,7 +841,10 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl 
*fl1,
                rts_ind->subCh, rts_ind->u8Tn, rts_ind->u32Fn);
        if (chan_nr) {
                fn = rts_ind->u32Fn;
-               link_id = 0;
+               if (rts_ind->sapi == GsmL1_Sapi_Sacch)
+                       link_id = 0x40;
+               else
+                       link_id = 0;
                rc = msgb_trim(l1p_msg, sizeof(*l1sap));
                if (rc < 0)
                        MSGB_ABORT(l1p_msg, "No room for primitive\n");
@@ -899,27 +971,6 @@ empty_frame:
        goto tx;
 }
 
-/* determine LAPDm entity inside LAPDm channel for given L1 sapi */
-static struct lapdm_entity *le_by_l1_sapi(struct lapdm_channel *lc, 
GsmL1_Sapi_t sapi)
-{
-       switch (sapi) {
-       case GsmL1_Sapi_Sacch:
-               return &lc->lapdm_acch;
-       default:
-               return &lc->lapdm_dcch;
-       }
-}
-
-static uint8_t gen_link_id(GsmL1_Sapi_t l1_sapi, uint8_t lapdm_sapi)
-{
-       uint8_t c_bits = 0;
-
-       if (l1_sapi == GsmL1_Sapi_Sacch)
-               c_bits = 0x40;
-
-       return c_bits | (lapdm_sapi & 7);
-}
-
 static void dump_meas_res(int ll, GsmL1_MeasParam_t *m)
 {
        LOGPC(DL1C, ll, ", Meas: RSSI %-3.2f dBm,  Qual %-3.2f dB,  "
@@ -943,46 +994,11 @@ static int process_meas_res(struct gsm_lchan *lchan, 
GsmL1_MeasParam_t *m)
        return lchan_new_ul_meas(lchan, &ulm);
 }
 
-/* process radio link timeout counter S */
-static void radio_link_timeout(struct gsm_lchan *lchan, int bad_frame)
-{
-       struct gsm_bts_role_bts *btsb = lchan->ts->trx->bts->role;
-
-       /* if link loss criterion already reached */
-       if (lchan->s == 0) {
-               DEBUGP(DMEAS, "%s radio link counter S already 0.\n",
-                       gsm_lchan_name(lchan));
-               return;
-       }
-
-       if (bad_frame) {
-               /* count down radio link counter S */
-               lchan->s--;
-               DEBUGP(DMEAS, "%s counting down radio link counter S=%d\n",
-                       gsm_lchan_name(lchan), lchan->s);
-               if (lchan->s == 0)
-                       rsl_tx_conn_fail(lchan, RSL_ERR_RADIO_LINK_FAIL);
-               return;
-       }
-
-       if (lchan->s < btsb->radio_link_timeout) {
-               /* count up radio link counter S */
-               lchan->s += 2;
-               if (lchan->s > btsb->radio_link_timeout)
-                       lchan->s = btsb->radio_link_timeout;
-               DEBUGP(DMEAS, "%s counting up radio link counter S=%d\n",
-                       gsm_lchan_name(lchan), lchan->s);
-       }
-}
-
 static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t 
*data_ind,
                              struct msgb *l1p_msg)
 {
        struct gsm_bts_trx *trx = fl1->priv;
-       struct osmo_phsap_prim pp;
        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;
@@ -1002,6 +1018,12 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, 
GsmL1_PhDataInd_t *data_i
 
        chan_nr = chan_nr_by_sapi(trx->ts[data_ind->u8Tn].pchan, data_ind->sapi,
                data_ind->subCh, data_ind->u8Tn, data_ind->u32Fn);
+       if (!chan_nr) {
+               LOGP(DL1C, LOGL_ERROR, "PH-DATA-INDICATION for unknown sapi "
+                       "%d\n", data_ind->sapi);
+               msgb_free(l1p_msg);
+               return ENOTSUP;
+       }
        fn = data_ind->u32Fn;
        link_id =  (data_ind->sapi == GsmL1_Sapi_Sacch) ? 0x40 : 0x00;
 
@@ -1023,84 +1045,15 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, 
GsmL1_PhDataInd_t *data_i
        if (lchan->ho.active == HANDOVER_WAIT_FRAME)
                handover_frame(lchan);
 
-       switch (data_ind->sapi) {
-       case GsmL1_Sapi_Sacch:
-               radio_link_timeout(lchan, (data_ind->msgUnitParam.u8Size == 0));
-               if (data_ind->msgUnitParam.u8Size == 0)
-                       break;
-               /* save the SACCH L1 header in the lchan struct for RSL MEAS 
RES */
-               if (data_ind->msgUnitParam.u8Size < 2) {
-                       LOGP(DL1C, LOGL_NOTICE, "SACCH with size %u<2 !?!\n",
-                               data_ind->msgUnitParam.u8Size);
-                       break;
-               }
-               /* Some brilliant engineer decided that the ordering of
-                * fields on the Um interface is different from the
-                * order of fields in RLS. See TS 04.04 (Chapter 7.2)
-                * vs. TS 08.58 (Chapter 9.3.10). */
-               lchan->meas.l1_info[0] = data_ind->msgUnitParam.u8Buffer[0] << 
3;
-               lchan->meas.l1_info[0] |= ((data_ind->msgUnitParam.u8Buffer[0] 
>> 5) & 1) << 2;
-               lchan->meas.l1_info[1] = data_ind->msgUnitParam.u8Buffer[1];
-               lchan->meas.flags |= LC_UL_M_F_L1_VALID;
-               /* fall-through */
-       case GsmL1_Sapi_Sdcch:
-       case GsmL1_Sapi_FacchF:
-       case GsmL1_Sapi_FacchH:
-               /* Check and Re-check for the SACCH */
-               if (data_ind->msgUnitParam.u8Size == 0) {
-                       LOGP(DL1C, LOGL_NOTICE, "%s %s data is null.\n",
-                               gsm_lchan_name(lchan),
-                               get_value_string(femtobts_l1sapi_names, 
data_ind->sapi));
-                       break;
-               }
-
-               check_for_first_ciphrd(fl1, &data_ind->msgUnitParam, lchan);
-
-               /* SDCCH, SACCH and FACCH all go to LAPDm */
-               le = le_by_l1_sapi(&lchan->lapdm_ch, data_ind->sapi);
-               /* allocate and fill LAPDm primitive */
-               msg = msgb_alloc_headroom(128, 64, "PH-DATA.ind");
-               osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA,
-                               PRIM_OP_INDICATION, msg);
-
-               /* copy over actual MAC block */
-               msg->l2h = msgb_put(msg, data_ind->msgUnitParam.u8Size);
-               memcpy(msg->l2h, data_ind->msgUnitParam.u8Buffer,
-                       data_ind->msgUnitParam.u8Size);
-
-               /* LAPDm requires those... */
-               pp.u.data.chan_nr = gsm_lchan2chan_nr(lchan);
-               pp.u.data.link_id = gen_link_id(data_ind->sapi, 0);
-
-               /* feed into the LAPDm code of libosmogsm */
-               rc = lapdm_phsap_up(&pp.oph, le);
-               break;
-       case GsmL1_Sapi_TchF:
-       case GsmL1_Sapi_TchH:
+       /* check for TCH */
+       if (data_ind->sapi == GsmL1_Sapi_TchF
+        || data_ind->sapi == GsmL1_Sapi_TchH) {
                /* TCH speech frame handling */
                rc = l1if_tch_rx(trx, chan_nr, l1p_msg);
-               break;
-       case GsmL1_Sapi_Pdtch:
-       case GsmL1_Sapi_Pacch:
-       case GsmL1_Sapi_Ptcch:
-               break;
-       case GsmL1_Sapi_Idle:
-               /* nothing to send */
-               break;
-       default:
-               LOGP(DL1C, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI 
%s\n",
-                       get_value_string(femtobts_l1sapi_names, 
data_ind->sapi));
-               break;
-       }
-
-       if (!chan_nr) {
-               /* message was handled by old code, not by L1SAP */
                msgb_free(l1p_msg);
                return rc;
        }
 
-       /* if we proceed to this point, the message has to be handled via L1SAP 
*/
-
        /* get data pointer and length */
        data = data_ind->msgUnitParam.u8Buffer;
        len = data_ind->msgUnitParam.u8Size;
-- 
2.1.0


Reply via email to