[layer23] msgb_free() must in l1ctl.c must called after reading its header
[osmocom-bb.git] / src / host / layer23 / src / common / l1ctl.c
index 21ee996..ac8bac8 100644 (file)
@@ -160,7 +160,51 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg)
        meas->berr += dl->num_biterr;
        meas->rxlev += dl->rx_level;
 
-       if (dl->num_biterr) {
+       /* counting loss criteria */
+       if (!(dl->link_id & 0x40)) {
+               switch (chan_type) {
+               case RSL_CHAN_PCH_AGCH:
+                       if (!meas->ds_fail)
+                               break;
+                       if (dl->fire_crc >= 2)
+                               meas->dsc -= 4;
+                       else
+                               meas->dsc += 1;
+                       if (meas->dsc > meas->ds_fail)
+                               meas->dsc = meas->ds_fail;
+                       if (meas->dsc < meas->ds_fail)
+                               printf("LOSS counter for CCCH %d\n", meas->dsc);
+                       if (meas->dsc > 0)
+                               break;
+                       meas->ds_fail = 0;
+                       dispatch_signal(SS_L1CTL, S_L1CTL_LOSS_IND, ms);
+                       break;
+               }
+       } else {
+               switch (chan_type) {
+               case RSL_CHAN_Bm_ACCHs:
+               case RSL_CHAN_Lm_ACCHs:
+               case RSL_CHAN_SDCCH4_ACCH:
+               case RSL_CHAN_SDCCH8_ACCH:
+                       if (!meas->rl_fail)
+                               break;
+                       if (dl->fire_crc >= 2)
+                               meas->s -= 1;
+                       else
+                               meas->s += 2;
+                       if (meas->s > meas->rl_fail)
+                               meas->s = meas->rl_fail;
+                       if (meas->s < meas->rl_fail)
+                               printf("LOSS counter for ACCH %d\n", meas->s);
+                       if (meas->s > 0)
+                               break;
+                       meas->rl_fail = 0;
+                       dispatch_signal(SS_L1CTL, S_L1CTL_LOSS_IND, ms);
+                       break;
+               }
+       }
+
+       if (dl->fire_crc >= 2) {
 printf("Dropping frame with %u bit errors\n", dl->num_biterr);
                LOGP(DL1C, LOGL_NOTICE, "Dropping frame with %u bit errors\n",
                        dl->num_biterr);
@@ -266,13 +310,11 @@ int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn,
        if (!msg)
                return -1;
 
-       memset(&ms->meas, 0, sizeof(ms->meas));
-
        req = (struct l1ctl_fbsb_req *) msgb_put(msg, sizeof(*req));
        req->band_arfcn = htons(osmo_make_band_arfcn(ms, arfcn));
        req->timeout = htons(timeout);
        /* Threshold when to consider FB_MODE1: 4kHz - 1kHz */
-       req->freq_err_thresh1 = htons(4000 - 1000);
+       req->freq_err_thresh1 = htons(11000 - 1000);
        /* Threshold when to consider SCH: 1kHz - 200Hz */
        req->freq_err_thresh2 = htons(1000 - 200);
        /* not used yet! */
@@ -363,8 +405,8 @@ int l1ctl_tx_crypto_req(struct osmocom_ms *ms, uint8_t algo, uint8_t *key,
 }
 
 /* Transmit L1CTL_RACH_REQ */
-int l1ctl_tx_rach_req(struct osmocom_ms *ms, uint8_t ra, uint8_t fn51,
-       uint8_t mf_off)
+int l1ctl_tx_rach_req(struct osmocom_ms *ms, uint8_t ra, uint16_t offset,
+       uint8_t combined)
 {
        struct msgb *msg;
        struct l1ctl_info_ul *ul;
@@ -374,19 +416,19 @@ int l1ctl_tx_rach_req(struct osmocom_ms *ms, uint8_t ra, uint8_t fn51,
        if (!msg)
                return -1;
 
-       DEBUGP(DL1C, "RACH Req. fn51=%d, mf_off=%d\n", fn51, mf_off);
+       DEBUGP(DL1C, "RACH Req. offset=%d combined=%d\n", offset, combined);
        ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
        req = (struct l1ctl_rach_req *) msgb_put(msg, sizeof(*req));
        req->ra = ra;
-       req->fn51 = fn51;
-       req->mf_off = mf_off;
+       req->offset = htons(offset);
+       req->combined = combined;
 
        return osmo_send_l1(ms, msg);
 }
 
 /* Transmit L1CTL_DM_EST_REQ */
 int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
-                           uint8_t chan_nr, uint8_t tsc)
+                           uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode)
 {
        struct msgb *msg;
        struct l1ctl_info_ul *ul;
@@ -399,8 +441,6 @@ int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
        LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Est Req (arfcn=%u, "
                "chan_nr=0x%02x)\n", band_arfcn, chan_nr);
 
-       memset(&ms->meas, 0, sizeof(ms->meas));
-
        ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
        ul->chan_nr = chan_nr;
        ul->link_id = 0;
@@ -409,13 +449,14 @@ int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
        req->tsc = tsc;
        req->h = 0;
        req->h0.band_arfcn = htons(band_arfcn);
+       req->tch_mode = tch_mode;
 
        return osmo_send_l1(ms, msg);
 }
 
 int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn,
                            uint16_t *ma, uint8_t ma_len,
-                           uint8_t chan_nr, uint8_t tsc)
+                           uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode)
 {
        struct msgb *msg;
        struct l1ctl_info_ul *ul;
@@ -429,8 +470,6 @@ int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn,
        LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Est Req (maio=%u, hsn=%u, "
                "chan_nr=0x%02x)\n", maio, hsn, chan_nr);
 
-       memset(&ms->meas, 0, sizeof(ms->meas));
-
        ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
        ul->chan_nr = chan_nr;
        ul->link_id = 0;
@@ -443,6 +482,7 @@ int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn,
        req->h1.n = ma_len;
        for (i = 0; i < ma_len; i++)
                req->h1.ma[i] = htons(ma[i]);
+       req->tch_mode = tch_mode;
 
        return osmo_send_l1(ms, msg);
 }
@@ -520,8 +560,6 @@ int l1ctl_tx_dm_rel_req(struct osmocom_ms *ms)
 
        LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Rel Req\n");
 
-       memset(&ms->meas, 0, sizeof(ms->meas));
-
        ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
 
        return osmo_send_l1(ms, msg);
@@ -724,9 +762,9 @@ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
                break;
        case L1CTL_PM_CONF:
                rc = rx_l1_pm_conf(ms, msg);
-               msgb_free(msg);
                if (l1h->flags & L1CTL_F_DONE)
                        dispatch_signal(SS_L1CTL, S_L1CTL_PM_DONE, ms);
+               msgb_free(msg);
                break;
        case L1CTL_RACH_CONF:
                rc = rx_l1_rach_conf(ms, msg);