lists.osmocom.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

gerrit-log

Thread Start a new thread
Download
Threads by month
  • ----- 2026 -----
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
gerrit-log@lists.osmocom.org

July 2023

  • 1 participants
  • 3051 discussions
[M] Change in pysim[master]: pySim/commands.py: Better type annotations
by laforge 12 Jul '23

12 Jul '23
Attention is currently required from: dexter. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/pysim/+/33658 ) Change subject: pySim/commands.py: Better type annotations ...................................................................... Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/c/pysim/+/33658 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Change-Id: I68081b5472188f80a964ca48d5ec1f03adc70c4a Gerrit-Change-Number: 33658 Gerrit-PatchSet: 4 Gerrit-Owner: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de> Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Attention: dexter <pmaier(a)sysmocom.de> Gerrit-Comment-Date: Wed, 12 Jul 2023 16:12:29 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
[M] Change in pysim[master]: pySim/transport: More type annotations
by laforge 12 Jul '23

12 Jul '23
Attention is currently required from: dexter. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/pysim/+/33657 ) Change subject: pySim/transport: More type annotations ...................................................................... Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/c/pysim/+/33657 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Change-Id: I62e081271e3a579851a588a4ed7282017e56f852 Gerrit-Change-Number: 33657 Gerrit-PatchSet: 4 Gerrit-Owner: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de> Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Attention: dexter <pmaier(a)sysmocom.de> Gerrit-Comment-Date: Wed, 12 Jul 2023 16:12:26 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
[S] Change in pysim[master]: pySim/utils: define 'Hexstr' using NewType
by laforge 12 Jul '23

12 Jul '23
Attention is currently required from: dexter. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/pysim/+/33656 ) Change subject: pySim/utils: define 'Hexstr' using NewType ...................................................................... Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/c/pysim/+/33656 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Change-Id: Ifb787670ed0e149ae6fcd0e6c0626ddc68880068 Gerrit-Change-Number: 33656 Gerrit-PatchSet: 4 Gerrit-Owner: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de> Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Attention: dexter <pmaier(a)sysmocom.de> Gerrit-Comment-Date: Wed, 12 Jul 2023 16:12:22 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
[L] Change in osmocom-bb[master]: trxcon/l1sched: do not craft artificial BFI frames on TCH
by fixeria 12 Jul '23

12 Jul '23
fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/33711 ) Change subject: trxcon/l1sched: do not craft artificial BFI frames on TCH ...................................................................... trxcon/l1sched: do not craft artificial BFI frames on TCH Whenever decoding fails or a FACCH setaling happens, simply send an empty DATA.ind to the upper layers. On the Uplink path, use a dummy LAPDm func=UI frame (with random padding) whenever possible. Crafting TCH frames with zeroes is not really needed and moreover makes it hard to distinguish between valid speech frames and BFIs. This also used to be the case for osmo-bts-trx, but not anymore (see the related patch). Change-Id: I20391b860fbc2ce8f0f03d7ba95ef7a098c0f9db Related: osmo-bts.git I8f9fb5b8c5b2cad4b92ac693c0040779f811981a --- M src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h M src/host/trxcon/include/osmocom/bb/l1sched/prim.h M src/host/trxcon/src/sched_lchan_common.c M src/host/trxcon/src/sched_lchan_tchf.c M src/host/trxcon/src/sched_lchan_tchh.c M src/host/trxcon/src/sched_lchan_xcch.c M src/host/trxcon/src/sched_prim.c 7 files changed, 72 insertions(+), 250 deletions(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve pespin: Looks good to me, but someone else must approve fixeria: Looks good to me, approved diff --git a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h index cee2660..5385c00 100644 --- a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h +++ b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h @@ -389,8 +389,6 @@ extern const uint8_t l1sched_nb_training_bits[8][26]; const char *l1sched_burst_mask2str(const uint8_t *mask, int bits); -size_t l1sched_bad_frame_ind(uint8_t *l2, struct l1sched_lchan_state *lchan); -bool l1sched_lchan_amr_prim_is_valid(struct l1sched_lchan_state *lchan, bool is_cmr); /* Interleaved TCH/H block TDMA frame mapping */ bool l1sched_tchh_block_map_fn(enum l1sched_lchan_type chan, diff --git a/src/host/trxcon/include/osmocom/bb/l1sched/prim.h b/src/host/trxcon/include/osmocom/bb/l1sched/prim.h index c0e6af6..af3ac3b 100644 --- a/src/host/trxcon/include/osmocom/bb/l1sched/prim.h +++ b/src/host/trxcon/include/osmocom/bb/l1sched/prim.h @@ -116,9 +116,10 @@ struct msgb *l1sched_prim_alloc(enum l1sched_prim_type type, enum osmo_prim_operation op); +bool l1sched_lchan_amr_prim_is_valid(struct l1sched_lchan_state *lchan, bool is_cmr); struct msgb *l1sched_lchan_prim_dequeue_sacch(struct l1sched_lchan_state *lchan); struct msgb *l1sched_lchan_prim_dequeue_tch(struct l1sched_lchan_state *lchan, bool facch); -struct msgb *l1sched_lchan_prim_dummy(struct l1sched_lchan_state *lchan); +struct msgb *l1sched_lchan_prim_dummy_lapdm(const struct l1sched_lchan_state *lchan); void l1sched_lchan_prim_drop(struct l1sched_lchan_state *lchan); int l1sched_lchan_emit_data_ind(struct l1sched_lchan_state *lchan, diff --git a/src/host/trxcon/src/sched_lchan_common.c b/src/host/trxcon/src/sched_lchan_common.c index ad42d9e..bf31831 100644 --- a/src/host/trxcon/src/sched_lchan_common.c +++ b/src/host/trxcon/src/sched_lchan_common.c @@ -93,55 +93,6 @@ return buf; } -/** - * Composes a bad frame indication message - * according to the current tch_mode. - * - * @param l2 Caller-allocated byte array - * @param lchan Logical channel to generate BFI for - * @return How much bytes were written - */ -size_t l1sched_bad_frame_ind(uint8_t *l2, struct l1sched_lchan_state *lchan) -{ - int rc; - - switch (lchan->tch_mode) { - case GSM48_CMODE_SPEECH_V1: - if (lchan->type == L1SCHED_TCHF) { /* Full Rate */ - memset(l2, 0x00, GSM_FR_BYTES); - l2[0] = 0xd0; - return GSM_FR_BYTES; - } else { /* Half Rate */ - memset(l2 + 1, 0x00, GSM_HR_BYTES); - l2[0] = 0x70; /* F = 0, FT = 111 */ - return GSM_HR_BYTES + 1; - } - case GSM48_CMODE_SPEECH_EFR: /* Enhanced Full Rate */ - memset(l2, 0x00, GSM_EFR_BYTES); - l2[0] = 0xc0; - return GSM_EFR_BYTES; - case GSM48_CMODE_SPEECH_AMR: /* Adaptive Multi Rate */ - rc = osmo_amr_rtp_enc(l2, - lchan->amr.codec[lchan->amr.dl_cmr], - lchan->amr.codec[lchan->amr.dl_ft], - AMR_BAD); - if (rc < 2) { - LOGP_LCHAND(lchan, LOGL_ERROR, - "Failed to encode AMR_BAD frame (rc=%d), " - "not sending BFI\n", rc); - return 0; - } - memset(l2 + 2, 0, rc - 2); - return rc; - case GSM48_CMODE_SIGN: - LOGP_LCHAND(lchan, LOGL_ERROR, "BFI is not allowed in signalling mode\n"); - return 0; - default: - LOGP_LCHAND(lchan, LOGL_ERROR, "Invalid TCH mode: %u\n", lchan->tch_mode); - return 0; - } -} - bool l1sched_lchan_amr_prim_is_valid(struct l1sched_lchan_state *lchan, bool is_cmr) { enum osmo_amr_type ft_codec; diff --git a/src/host/trxcon/src/sched_lchan_tchf.c b/src/host/trxcon/src/sched_lchan_tchf.c index a87efaf..cd53c46 100644 --- a/src/host/trxcon/src/sched_lchan_tchf.c +++ b/src/host/trxcon/src/sched_lchan_tchf.c @@ -167,16 +167,17 @@ "Received bad frame (rc=%d, ber=%d/%d) at fn=%u\n", rc, n_errors, n_bits_total, lchan->meas_avg.fn); - /* Send BFI */ - goto bfi; + /* Send BFI (DATA.ind without payload) */ + tch_data_len = 0; } else if (rc == GSM_MACBLOCK_LEN) { /* FACCH received, forward it to the higher layers */ l1sched_lchan_emit_data_ind(lchan, &tch_data[amr], GSM_MACBLOCK_LEN, n_errors, n_bits_total, false); - /* Send BFI substituting a stolen TCH frame */ - n_errors = -1; /* ensure fake measurements */ - goto bfi; + /* Send BFI (DATA.ind without payload) */ + if (lchan->tch_mode == GSM48_CMODE_SIGN) + return 0; + tch_data_len = 0; } else { /* A good TCH frame received */ tch_data_len = rc; @@ -185,32 +186,6 @@ /* Send a traffic frame to the higher layers */ return l1sched_lchan_emit_data_ind(lchan, &tch_data[0], tch_data_len, n_errors, n_bits_total, true); - -bfi: - /* Didn't try to decode, fake measurements */ - if (n_errors < 0) { - lchan->meas_avg = (struct l1sched_meas_set) { - .fn = lchan->meas_avg.fn, - .toa256 = 0, - .rssi = -110, - }; - - /* No bursts => no errors */ - n_errors = 0; - } - - /* BFI is not applicable in signalling mode */ - if (lchan->tch_mode == GSM48_CMODE_SIGN) { - return l1sched_lchan_emit_data_ind(lchan, NULL, 0, - n_errors, n_bits_total, false); - } - - /* Bad frame indication */ - tch_data_len = l1sched_bad_frame_ind(&tch_data[0], lchan); - - /* Send a BFI frame to the higher layers */ - return l1sched_lchan_emit_data_ind(lchan, &tch_data[0], tch_data_len, - n_errors, n_bits_total, true); } static struct msgb *prim_dequeue_tchf(struct l1sched_lchan_state *lchan) @@ -255,11 +230,9 @@ *mask = *mask << 4; lchan->prim = prim_dequeue_tchf(lchan); - if (lchan->prim == NULL) { - lchan->prim = l1sched_lchan_prim_dummy(lchan); - if (lchan->prim == NULL) - return -ENOENT; - } + if (lchan->prim == NULL) + lchan->prim = l1sched_lchan_prim_dummy_lapdm(lchan); + OSMO_ASSERT(lchan->prim != NULL); /* populate the buffer with bursts */ switch (lchan->tch_mode) { diff --git a/src/host/trxcon/src/sched_lchan_tchh.c b/src/host/trxcon/src/sched_lchan_tchh.c index 67e2132..3fa823b 100644 --- a/src/host/trxcon/src/sched_lchan_tchh.c +++ b/src/host/trxcon/src/sched_lchan_tchh.c @@ -180,60 +180,6 @@ return false; } -/** - * Calculates a frame number of the first burst - * using given frame number of the last burst. - * - * See GSM 05.02, clause 7, table 1 - * - * @param chan channel type (L1SCHED_TCHH_0 or L1SCHED_TCHH_1) - * @param last_fn frame number of the last burst - * @param facch FACCH/H or traffic? - * @return either frame number of the first burst, - * or fn=last_fn if calculation failed - */ -static uint32_t tchh_block_dl_first_fn(const struct l1sched_lchan_state *lchan, - uint32_t last_fn, bool facch) -{ - enum l1sched_lchan_type chan = lchan->type; - uint8_t fn_mf, fn_diff; - int i = 0; - - /* Just to be sure */ - OSMO_ASSERT(chan == L1SCHED_TCHH_0 || chan == L1SCHED_TCHH_1); - - /* Calculate a modulo */ - fn_mf = facch ? (last_fn % 26) : (last_fn % 13); - -#define BLOCK_FIRST_FN(map) \ - do { \ - if (map[i][ARRAY_SIZE(map[i]) - 1] == fn_mf) { \ - fn_diff = GSM_TDMA_FN_DIFF(fn_mf, map[i][0]); \ - return GSM_TDMA_FN_SUB(last_fn, fn_diff); \ - } \ - } while (++i < ARRAY_SIZE(map)) - - /* Choose a proper block map */ - if (facch) { - if (chan == L1SCHED_TCHH_0) - BLOCK_FIRST_FN(tch_h0_dl_facch_block_map); - else - BLOCK_FIRST_FN(tch_h1_dl_facch_block_map); - } else { - if (chan == L1SCHED_TCHH_0) - BLOCK_FIRST_FN(tch_h0_traffic_block_map); - else - BLOCK_FIRST_FN(tch_h1_traffic_block_map); - } - - LOGP_LCHAND(lchan, LOGL_ERROR, - "Failed to calculate TDMA frame number of the first burst of %s block, " - "using the current fn=%u\n", facch ? "FACCH/H" : "TCH/H", last_fn); - - /* Couldn't calculate the first fn, return the last */ - return last_fn; -} - int rx_tchh_fn(struct l1sched_lchan_state *lchan, const struct l1sched_burst_ind *bi) { @@ -290,21 +236,13 @@ if (bi->bid != 1) return 0; - /* Wait for complete set of bursts */ - if (lchan->tch_mode == GSM48_CMODE_SIGN) { - /* FACCH/H is interleaved over 6 bursts */ - if ((*mask & 0x3f) != 0x3f) - goto bfi; - } else { - /* Traffic is interleaved over 4 bursts */ - if ((*mask & 0x0f) != 0x0f) - goto bfi; - } - /* Skip decoding attempt in case of FACCH/H */ if (lchan->dl_ongoing_facch) { + /* Send BFI (DATA.ind without payload) for the 2nd stolen TCH frame */ + l1sched_lchan_meas_avg(lchan, 4); + l1sched_lchan_emit_data_ind(lchan, NULL, 0, 0, 0, true); lchan->dl_ongoing_facch = false; - goto bfi; /* 2/2 BFI */ + return 0; } switch (lchan->tch_mode) { @@ -350,15 +288,12 @@ /* Check decoding result */ if (rc < 4) { - /* Calculate AVG of the measurements (assuming 4 bursts) */ - l1sched_lchan_meas_avg(lchan, 4); - LOGP_LCHAND(lchan, LOGL_ERROR, "Received bad frame (rc=%d, ber=%d/%d) at fn=%u\n", rc, n_errors, n_bits_total, lchan->meas_avg.fn); - /* Send BFI */ - goto bfi; + /* Send BFI (DATA.ind without payload) */ + tch_data_len = 0; } else if (rc == GSM_MACBLOCK_LEN) { /* Skip decoding of the next 2 stolen bursts */ lchan->dl_ongoing_facch = true; @@ -370,46 +305,21 @@ l1sched_lchan_emit_data_ind(lchan, &tch_data[amr], GSM_MACBLOCK_LEN, n_errors, n_bits_total, false); - /* Send BFI substituting 1/2 stolen TCH frames */ - n_errors = -1; /* ensure fake measurements */ - goto bfi; + /* Send BFI (DATA.ind without payload) for the 1st stolen TCH frame */ + if (lchan->tch_mode == GSM48_CMODE_SIGN) + return 0; + tch_data_len = 0; } else { /* A good TCH frame received */ tch_data_len = rc; - - /* Calculate AVG of the measurements (traffic takes 4 bursts) */ - l1sched_lchan_meas_avg(lchan, 4); } + /* Calculate AVG of the measurements (traffic takes 4 bursts) */ + l1sched_lchan_meas_avg(lchan, 4); + /* Send a traffic frame to the higher layers */ return l1sched_lchan_emit_data_ind(lchan, &tch_data[0], tch_data_len, n_errors, n_bits_total, true); - -bfi: - /* Didn't try to decode, fake measurements */ - if (n_errors < 0) { - lchan->meas_avg = (struct l1sched_meas_set) { - .fn = tchh_block_dl_first_fn(lchan, bi->fn, false), - .toa256 = 0, - .rssi = -110, - }; - - /* No bursts => no errors */ - n_errors = 0; - } - - /* BFI is not applicable in signalling mode */ - if (lchan->tch_mode == GSM48_CMODE_SIGN) { - return l1sched_lchan_emit_data_ind(lchan, NULL, 0, - n_errors, n_bits_total, false); - } - - /* Bad frame indication */ - tch_data_len = l1sched_bad_frame_ind(&tch_data[0], lchan); - - /* Send a BFI frame to the higher layers */ - return l1sched_lchan_emit_data_ind(lchan, &tch_data[0], tch_data_len, - n_errors, n_bits_total, true); } static struct msgb *prim_dequeue_tchh(struct l1sched_lchan_state *lchan, uint32_t fn) @@ -473,7 +383,8 @@ lchan->prim = prim_dequeue_tchh(lchan, br->fn); if (lchan->prim == NULL) { - lchan->prim = l1sched_lchan_prim_dummy(lchan); + if (l1sched_tchh_facch_start(lchan->type, br->fn, 1)) + lchan->prim = l1sched_lchan_prim_dummy_lapdm(lchan); if (lchan->prim == NULL) return -ENOENT; } diff --git a/src/host/trxcon/src/sched_lchan_xcch.c b/src/host/trxcon/src/sched_lchan_xcch.c index 7f1dd11..e263836 100644 --- a/src/host/trxcon/src/sched_lchan_xcch.c +++ b/src/host/trxcon/src/sched_lchan_xcch.c @@ -141,7 +141,7 @@ lchan->prim = prim_dequeue_xcch(lchan); if (lchan->prim == NULL) - lchan->prim = l1sched_lchan_prim_dummy(lchan); + lchan->prim = l1sched_lchan_prim_dummy_lapdm(lchan); OSMO_ASSERT(lchan->prim != NULL); /* Encode payload */ diff --git a/src/host/trxcon/src/sched_prim.c b/src/host/trxcon/src/sched_prim.c index 3301df4..4675675 100644 --- a/src/host/trxcon/src/sched_prim.c +++ b/src/host/trxcon/src/sched_prim.c @@ -260,81 +260,50 @@ } /** - * Allocate a dummy DATA.req for the given logical channel. + * Allocate a DATA.req with dummy LAPDm func=UI frame for the given logical channel. * To be used when no suitable DATA.req is present in the Tx queue. * * @param lchan lchan to allocate a dummy primitive for * @return an msgb with DATA.req primitive, or NULL */ -struct msgb *l1sched_lchan_prim_dummy(struct l1sched_lchan_state *lchan) +struct msgb *l1sched_lchan_prim_dummy_lapdm(const struct l1sched_lchan_state *lchan) { - const struct l1sched_lchan_desc *lchan_desc; - enum l1sched_lchan_type chan = lchan->type; - uint8_t tch_mode = lchan->tch_mode; struct l1sched_prim *prim; struct msgb *msg; - uint8_t prim_buffer[40]; - size_t prim_len = 0; - int i; + uint8_t *ptr; - /** - * TS 144.006, section 8.4.2.3 "Fill frames" - * A fill frame is a UI command frame for SAPI 0, P=0 - * and with an information field of 0 octet length. - */ - static const uint8_t lapdm_fill_frame[] = { - 0x01, 0x03, 0x01, 0x2b, - /* Pending part is to be randomized */ - }; - - /* Not applicable for SACCH! */ + /* LAPDm func=UI is not applicable for SACCH */ OSMO_ASSERT(!L1SCHED_CHAN_IS_SACCH(lchan->type)); - lchan_desc = &l1sched_lchan_desc[lchan->type]; - - /** - * Determine what actually should be generated: - * TCH in GSM48_CMODE_SIGN: LAPDm fill frame; - * TCH in other modes: silence frame; - * other channels: LAPDm fill frame. - */ - if (L1SCHED_CHAN_IS_TCH(chan) && L1SCHED_TCH_MODE_IS_SPEECH(tch_mode)) { - /* Bad frame indication */ - prim_len = l1sched_bad_frame_ind(prim_buffer, lchan); - } else if (L1SCHED_CHAN_IS_TCH(chan) && L1SCHED_TCH_MODE_IS_DATA(tch_mode)) { - /* FIXME: should we do anything for CSD? */ - return NULL; - } else { - /* Copy LAPDm fill frame's header */ - memcpy(prim_buffer, lapdm_fill_frame, sizeof(lapdm_fill_frame)); - - /** - * TS 144.006, section 5.2 "Frame delimitation and fill bits" - * Except for the first octet containing fill bits which shall - * be set to the binary value "00101011", each fill bit should - * be set to a random value when sent by the network. - */ - for (i = sizeof(lapdm_fill_frame); i < GSM_MACBLOCK_LEN; i++) - prim_buffer[i] = (uint8_t) rand(); - - /* Define a prim length */ - prim_len = GSM_MACBLOCK_LEN; - } - - /* Nothing to allocate / assign */ - if (!prim_len) - return NULL; - msg = l1sched_prim_alloc(L1SCHED_PRIM_T_DATA, PRIM_OP_REQUEST); OSMO_ASSERT(msg != NULL); prim = l1sched_prim_from_msgb(msg); prim->data_req = (struct l1sched_prim_chdr) { - .chan_nr = lchan_desc->chan_nr | lchan->ts->index, - .link_id = lchan_desc->link_id, + .chan_nr = l1sched_lchan_desc[lchan->type].chan_nr | lchan->ts->index, + .link_id = l1sched_lchan_desc[lchan->type].link_id, }; - memcpy(msgb_put(msg, prim_len), &prim_buffer[0], prim_len); + ptr = msgb_put(msg, GSM_MACBLOCK_LEN); + + /** + * TS 144.006, section 8.4.2.3 "Fill frames" + * A fill frame is a UI command frame for SAPI 0, P=0 + * and with an information field of 0 octet length. + */ + *(ptr++) = 0x01; + *(ptr++) = 0x03; + *(ptr++) = 0x01; + + /** + * TS 144.006, section 5.2 "Frame delimitation and fill bits" + * Except for the first octet containing fill bits which shall + * be set to the binary value "00101011", each fill bit should + * be set to a random value when sent by the network. + */ + *(ptr++) = 0x2b; + while (ptr < msg->tail) + *(ptr++) = (uint8_t)rand(); return msg; } -- To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/33711 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Change-Id: I20391b860fbc2ce8f0f03d7ba95ef7a098c0f9db Gerrit-Change-Number: 33711 Gerrit-PatchSet: 1 Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in osmocom-bb[master]: trxcon/l1sched: peoperly prioritize FACCH/H over TCH
by fixeria 12 Jul '23

12 Jul '23
fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/33709 ) Change subject: trxcon/l1sched: peoperly prioritize FACCH/H over TCH ...................................................................... trxcon/l1sched: peoperly prioritize FACCH/H over TCH Unlike FACCH/F, which steals one TCH frame, FACCH/H steals two TCH frames. This is what prim_dequeue_tchh() aims to implement, but the current implementation is not 100% correct. The problem is that we're attempting to dequeue and drop two TCH frames in one go, whenever we get a FACCH/H frame. Most likely, there will be no 2nd TCH frame in the Tx queue at that time, so it will never be dropped and will clog the queue. Let's replicate what osmo-bts-trx does: * dequeue and drop the 1st TCH frame when sending 1st/6 burst of FACCH, * dequeue and drop the 2nd TCH frame when sending 3rd/6 burst of FACCH. Change-Id: I513d6805ddf97783c002be285fb3ca7893e42377 Related: OS#4396, OS#1572 --- M src/host/trxcon/src/sched_lchan_tchh.c 1 file changed, 41 insertions(+), 27 deletions(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve pespin: Looks good to me, but someone else must approve fixeria: Looks good to me, approved diff --git a/src/host/trxcon/src/sched_lchan_tchh.c b/src/host/trxcon/src/sched_lchan_tchh.c index 6affbc5..67e2132 100644 --- a/src/host/trxcon/src/sched_lchan_tchh.c +++ b/src/host/trxcon/src/sched_lchan_tchh.c @@ -414,36 +414,23 @@ static struct msgb *prim_dequeue_tchh(struct l1sched_lchan_state *lchan, uint32_t fn) { - struct msgb *facch; - struct msgb *tch; - bool facch_now; + struct msgb *msg_facch; + struct msgb *msg_tch; - /* Can we initiate an UL FACCH/H frame transmission at this Fn? */ - facch_now = l1sched_tchh_facch_start(lchan->type, fn, true); - if (!facch_now) - goto no_facch; + /* dequeue a pair of TCH and FACCH frames */ + msg_tch = l1sched_lchan_prim_dequeue_tch(lchan, false); + if (l1sched_tchh_facch_start(lchan->type, fn, true)) + msg_facch = l1sched_lchan_prim_dequeue_tch(lchan, true); + else + msg_facch = NULL; - /* If there are no FACCH/H prims in the queue */ - facch = l1sched_lchan_prim_dequeue_tch(lchan, true); - if (!facch) /* Just dequeue a TCH/H prim */ - goto no_facch; - - /* FACCH/H prim replaces two TCH/F prims */ - tch = l1sched_lchan_prim_dequeue_tch(lchan, false); - if (tch) { - /* At least one TCH/H prim is dropped */ - msgb_free(tch); - - /* Attempt to find another */ - tch = l1sched_lchan_prim_dequeue_tch(lchan, false); - if (tch) /* Drop the second TCH/H prim */ - msgb_free(tch); + /* prioritize FACCH over TCH */ + if (msg_facch != NULL) { + msgb_free(msg_tch); /* drop 1st TCH/HS block */ + return msg_facch; } - return facch; - -no_facch: - return l1sched_lchan_prim_dequeue_tch(lchan, false); + return msg_tch; } int tx_tchh_fn(struct l1sched_lchan_state *lchan, @@ -478,8 +465,11 @@ *mask = *mask << 2; /* If FACCH/H blocks are still pending */ - if (lchan->ul_facch_blocks > 2) + if (lchan->ul_facch_blocks > 2) { + struct msgb *msg = l1sched_lchan_prim_dequeue_tch(lchan, false); + msgb_free(msg); /* drop 2nd TCH/HS block */ goto send_burst; + } lchan->prim = prim_dequeue_tchh(lchan, br->fn); if (lchan->prim == NULL) { -- To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/33709 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Change-Id: I513d6805ddf97783c002be285fb3ca7893e42377 Gerrit-Change-Number: 33709 Gerrit-PatchSet: 1 Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[S] Change in osmocom-bb[master]: trxcon/l1sched: simplify and unify prim_dequeue_tchf()
by fixeria 12 Jul '23

12 Jul '23
fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/33710 ) Change subject: trxcon/l1sched: simplify and unify prim_dequeue_tchf() ...................................................................... trxcon/l1sched: simplify and unify prim_dequeue_tchf() Make it easier to read and more similar to prim_dequeue_tchh(). Change-Id: Ie79069e5cc8acd193a326ac9d334fe070552e320 --- M src/host/trxcon/src/sched_lchan_tchf.c 1 file changed, 22 insertions(+), 17 deletions(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved diff --git a/src/host/trxcon/src/sched_lchan_tchf.c b/src/host/trxcon/src/sched_lchan_tchf.c index 6d48fc7..a87efaf 100644 --- a/src/host/trxcon/src/sched_lchan_tchf.c +++ b/src/host/trxcon/src/sched_lchan_tchf.c @@ -215,26 +215,20 @@ static struct msgb *prim_dequeue_tchf(struct l1sched_lchan_state *lchan) { - struct msgb *facch; - struct msgb *tch; + struct msgb *msg_facch; + struct msgb *msg_tch; - /* Attempt to find a pair of FACCH/F and TCH/F frames */ - facch = l1sched_lchan_prim_dequeue_tch(lchan, true); - tch = l1sched_lchan_prim_dequeue_tch(lchan, false); + /* dequeue a pair of TCH and FACCH frames */ + msg_tch = l1sched_lchan_prim_dequeue_tch(lchan, false); + msg_facch = l1sched_lchan_prim_dequeue_tch(lchan, true); - /* Prioritize FACCH/F, if found */ - if (facch) { - /* One TCH/F prim is replaced */ - if (tch) - msgb_free(tch); - return facch; - } else if (tch) { - /* Only TCH/F prim was found */ - return tch; - } else { - /* Nothing was found */ - return NULL; + /* prioritize FACCH over TCH */ + if (msg_facch != NULL) { + msgb_free(msg_tch); /* drop one TCH/FS block */ + return msg_facch; } + + return msg_tch; } int tx_tchf_fn(struct l1sched_lchan_state *lchan, -- To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/33710 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Change-Id: Ie79069e5cc8acd193a326ac9d334fe070552e320 Gerrit-Change-Number: 33710 Gerrit-PatchSet: 1 Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in osmocom-bb[master]: trxcon/l1sched: transmit dummy speech blocks with inverted CRC3
by fixeria 12 Jul '23

12 Jul '23
fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/33712 ) Change subject: trxcon/l1sched: transmit dummy speech blocks with inverted CRC3 ...................................................................... trxcon/l1sched: transmit dummy speech blocks with inverted CRC3 In case when an Uplink TCH/[FH]S frame needs to be transmitted, but there is no frame available in the Tx queue, transmit an intentionally invalid block with inverted CRC3. This will induce a BFI condition in the BTS side receiver. See also the related osmo-bts-trx patch. Change-Id: I16ff09a220da13c2c76538bc43354afc4e688794 Depends: libosmocore.git Iade3310e16b906efb6892d28f474a0d15204e861 Related: osmo-bts.git I78106802a0aa4af39859c75d29fe0e77037899fe --- M src/host/trxcon/src/sched_lchan_tchf.c M src/host/trxcon/src/sched_lchan_tchh.c M src/host/trxcon/src/sched_prim.c 3 files changed, 55 insertions(+), 18 deletions(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved diff --git a/src/host/trxcon/src/sched_lchan_tchf.c b/src/host/trxcon/src/sched_lchan_tchf.c index cd53c46..0206b61 100644 --- a/src/host/trxcon/src/sched_lchan_tchf.c +++ b/src/host/trxcon/src/sched_lchan_tchf.c @@ -230,15 +230,20 @@ *mask = *mask << 4; lchan->prim = prim_dequeue_tchf(lchan); - if (lchan->prim == NULL) - lchan->prim = l1sched_lchan_prim_dummy_lapdm(lchan); - OSMO_ASSERT(lchan->prim != NULL); /* populate the buffer with bursts */ switch (lchan->tch_mode) { case GSM48_CMODE_SIGN: + if (lchan->prim == NULL) + lchan->prim = l1sched_lchan_prim_dummy_lapdm(lchan); + /* fall-through */ case GSM48_CMODE_SPEECH_V1: case GSM48_CMODE_SPEECH_EFR: + if (lchan->prim == NULL) { + /* transmit a dummy speech block with inverted CRC3 */ + gsm0503_tch_fr_encode(bursts_p, NULL, 0, 1); + goto send_burst; + } rc = gsm0503_tch_fr_encode(bursts_p, msgb_l2(lchan->prim), msgb_l2len(lchan->prim), 1); @@ -246,8 +251,14 @@ case GSM48_CMODE_SPEECH_AMR: { bool amr_fn_is_cmr = !sched_tchf_ul_amr_cmi_map[br->fn % 26]; - const uint8_t *data = msgb_l2(lchan->prim); - size_t data_len = msgb_l2len(lchan->prim); + const uint8_t *data = lchan->prim ? msgb_l2(lchan->prim) : NULL; + size_t data_len = lchan->prim ? msgb_l2len(lchan->prim) : 0; + + if (lchan->prim == NULL) { + /* TODO: It's not clear what to do for TCH/AFS. + * TODO: Send dummy FACCH maybe? */ + goto send_burst; /* send something */ + } if (data_len != GSM_MACBLOCK_LEN) { /* TCH/AFS: speech */ if (!l1sched_lchan_amr_prim_is_valid(lchan, amr_fn_is_cmr)) diff --git a/src/host/trxcon/src/sched_lchan_tchh.c b/src/host/trxcon/src/sched_lchan_tchh.c index 3fa823b..3b329cb 100644 --- a/src/host/trxcon/src/sched_lchan_tchh.c +++ b/src/host/trxcon/src/sched_lchan_tchh.c @@ -382,20 +382,21 @@ } lchan->prim = prim_dequeue_tchh(lchan, br->fn); - if (lchan->prim == NULL) { - if (l1sched_tchh_facch_start(lchan->type, br->fn, 1)) - lchan->prim = l1sched_lchan_prim_dummy_lapdm(lchan); - if (lchan->prim == NULL) - return -ENOENT; - } - - if (msgb_l2len(lchan->prim) == GSM_MACBLOCK_LEN) - lchan->ul_facch_blocks = 6; /* populate the buffer with bursts */ switch (lchan->tch_mode) { case GSM48_CMODE_SIGN: + if (!l1sched_tchh_facch_start(lchan->type, br->fn, 1)) + goto send_burst; /* XXX: should not happen */ + if (lchan->prim == NULL) + lchan->prim = l1sched_lchan_prim_dummy_lapdm(lchan); + /* fall-through */ case GSM48_CMODE_SPEECH_V1: + if (lchan->prim == NULL) { + /* transmit a dummy speech block with inverted CRC3 */ + gsm0503_tch_hr_encode(bursts_p, NULL, 0); + goto send_burst; + } rc = gsm0503_tch_hr_encode(bursts_p, msgb_l2(lchan->prim), msgb_l2len(lchan->prim)); @@ -403,8 +404,14 @@ case GSM48_CMODE_SPEECH_AMR: { bool amr_fn_is_cmr = !sched_tchh_ul_amr_cmi_map[br->fn % 26]; - const uint8_t *data = msgb_l2(lchan->prim); - size_t data_len = msgb_l2len(lchan->prim); + const uint8_t *data = lchan->prim ? msgb_l2(lchan->prim) : NULL; + size_t data_len = lchan->prim ? msgb_l2len(lchan->prim) : 0; + + if (lchan->prim == NULL) { + /* TODO: It's not clear what to do for TCH/AHS. + * TODO: Send dummy FACCH maybe? */ + goto send_burst; /* send garbage */ + } if (data_len != GSM_MACBLOCK_LEN) { /* TCH/AHS: speech */ if (!l1sched_lchan_amr_prim_is_valid(lchan, amr_fn_is_cmr)) @@ -438,6 +445,9 @@ return -EINVAL; } + if (msgb_l2len(lchan->prim) == GSM_MACBLOCK_LEN) + lchan->ul_facch_blocks = 6; + send_burst: /* Determine which burst should be sent */ burst = bursts_p + br->bid * 116; diff --git a/src/host/trxcon/src/sched_prim.c b/src/host/trxcon/src/sched_prim.c index 4675675..3211560 100644 --- a/src/host/trxcon/src/sched_prim.c +++ b/src/host/trxcon/src/sched_prim.c @@ -349,8 +349,8 @@ struct msgb *msg; /* take ownership of the prim */ - OSMO_ASSERT(lchan->prim != NULL); - msg = lchan->prim; + if ((msg = lchan->prim) == NULL) + return -ENODEV; lchan->prim = NULL; /* convert from DATA.req to DATA.cnf */ -- To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/33712 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Change-Id: I16ff09a220da13c2c76538bc43354afc4e688794 Gerrit-Change-Number: 33712 Gerrit-PatchSet: 1 Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in osmocom-bb[master]: trxcon/l1sched: fix handling of UL FACCH on TCH/A[FH]S
by fixeria 12 Jul '23

12 Jul '23
fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/33706 ) Change subject: trxcon/l1sched: fix handling of UL FACCH on TCH/A[FH]S ...................................................................... trxcon/l1sched: fix handling of UL FACCH on TCH/A[FH]S In ad8f7794 I changed both tx_tch[fh]_fn() to use a switch statement and introduced a regression by removing special treatment of FACCH: @@ -238,10 +237,16 @@ int tx_tchf_fn(struct l1sched_lchan_state *lchan, - if (msgb_l2len(lchan->prim) == GSM_MACBLOCK_LEN) { - /* Encode payload */ - rc = gsm0503_tch_fr_encode(buffer, msgb_l2(lchan->prim), GSM_MACBLOCK_LEN, 1); - } else if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) { @@ -459,10 +458,15 @@ int tx_tchh_fn(struct l1sched_lchan_state *lchan, - if (msgb_l2len(lchan->prim) == GSM_MACBLOCK_LEN) { - rc = gsm0503_tch_hr_encode(buffer, msgb_l2(lchan->prim), GSM_MACBLOCK_LEN); - lchan->ul_facch_blocks = 6; - } else if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) { Now if the channel mode is GSM48_CMODE_SPEECH_AMR, UL FACCH/[FH] frames will be fed to osmo_amr_rtp_dec(), which is definitely wrong. Fix this by doing all AMR specific checks in a separate function, which is called only for speech frames. Change-Id: Ie217bbb389b5abb95d241781ffe3f5c7b1c188c0 Fixes: ad8f7794 "trxcon/l1sched: remove redundant TCH/[FH] prim length checks" Related: OS#4396 --- M src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h M src/host/trxcon/src/sched_lchan_common.c M src/host/trxcon/src/sched_lchan_tchf.c M src/host/trxcon/src/sched_lchan_tchh.c 4 files changed, 98 insertions(+), 90 deletions(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve pespin: Looks good to me, but someone else must approve fixeria: Looks good to me, approved diff --git a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h index d3b079c..715b9a0 100644 --- a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h +++ b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h @@ -392,6 +392,7 @@ const char *l1sched_burst_mask2str(const uint8_t *mask, int bits); size_t l1sched_bad_frame_ind(uint8_t *l2, struct l1sched_lchan_state *lchan); +bool l1sched_lchan_amr_prim_is_valid(struct l1sched_lchan_state *lchan, bool is_cmr); /* Interleaved TCH/H block TDMA frame mapping */ bool l1sched_tchh_block_map_fn(enum l1sched_lchan_type chan, diff --git a/src/host/trxcon/src/sched_lchan_common.c b/src/host/trxcon/src/sched_lchan_common.c index cddc9e5..26d8f22 100644 --- a/src/host/trxcon/src/sched_lchan_common.c +++ b/src/host/trxcon/src/sched_lchan_common.c @@ -141,3 +141,48 @@ return 0; } } + +bool l1sched_lchan_amr_prim_is_valid(struct l1sched_lchan_state *lchan, bool is_cmr) +{ + enum osmo_amr_type ft_codec; + enum osmo_amr_quality bfi; + uint8_t cmr_codec; + int ft, cmr, len; + int8_t sti, cmi; + + len = osmo_amr_rtp_dec(msgb_l2(lchan->prim), msgb_l2len(lchan->prim), + &cmr_codec, &cmi, &ft_codec, &bfi, &sti); + if (len < 0) { + LOGP_LCHAND(lchan, LOGL_ERROR, "Cannot send invalid AMR payload (%u): %s\n", + msgb_l2len(lchan->prim), msgb_hexdump_l2(lchan->prim)); + return false; + } + ft = -1; + cmr = -1; + for (unsigned int i = 0; i < lchan->amr.codecs; i++) { + if (lchan->amr.codec[i] == ft_codec) + ft = i; + if (lchan->amr.codec[i] == cmr_codec) + cmr = i; + } + if (ft < 0) { + LOGP_LCHAND(lchan, LOGL_ERROR, + "Codec (FT = %d) of RTP frame not in list\n", ft_codec); + return false; + } + if (is_cmr && lchan->amr.ul_ft != ft) { + LOGP_LCHAND(lchan, LOGL_ERROR, + "Codec (FT = %d) of RTP cannot be changed now, but in next frame\n", + ft_codec); + return false; + } + lchan->amr.ul_ft = ft; + if (cmr < 0) { + LOGP_LCHAND(lchan, LOGL_ERROR, + "Codec (CMR = %d) of RTP frame not in list\n", cmr_codec); + } else { + lchan->amr.ul_cmr = cmr; + } + + return true; +} diff --git a/src/host/trxcon/src/sched_lchan_tchf.c b/src/host/trxcon/src/sched_lchan_tchf.c index a4aa80c..9e8256f 100644 --- a/src/host/trxcon/src/sched_lchan_tchf.c +++ b/src/host/trxcon/src/sched_lchan_tchf.c @@ -244,54 +244,20 @@ break; case GSM48_CMODE_SPEECH_AMR: { - int len; - uint8_t cmr_codec; - int ft, cmr, i; - enum osmo_amr_type ft_codec; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - bool amr_fn_is_cmr; - /* the first FN 0,8,17 defines that CMI is included in frame, - * the first FN 4,13,21 defines that CMR is included in frame. - */ - amr_fn_is_cmr = !sched_tchf_ul_amr_cmi_map[br->fn % 26]; + bool amr_fn_is_cmr = !sched_tchf_ul_amr_cmi_map[br->fn % 26]; + const uint8_t *data = msgb_l2(lchan->prim); + size_t data_len = msgb_l2len(lchan->prim); - len = osmo_amr_rtp_dec(msgb_l2(lchan->prim), msgb_l2len(lchan->prim), - &cmr_codec, &cmi, &ft_codec, &bfi, &sti); - if (len < 0) { - LOGP_LCHAND(lchan, LOGL_ERROR, "Cannot send invalid AMR payload (%u): %s\n", - msgb_l2len(lchan->prim), msgb_hexdump_l2(lchan->prim)); - goto free_bad_msg; + if (data_len != GSM_MACBLOCK_LEN) { /* TCH/AFS: speech */ + if (!l1sched_lchan_amr_prim_is_valid(lchan, amr_fn_is_cmr)) + goto free_bad_msg; + /* pull the AMR header - sizeof(struct amr_hdr) */ + data_len -= 2; + data += 2; } - ft = -1; - cmr = -1; - for (i = 0; i < lchan->amr.codecs; i++) { - if (lchan->amr.codec[i] == ft_codec) - ft = i; - if (lchan->amr.codec[i] == cmr_codec) - cmr = i; - } - if (ft < 0) { - LOGP_LCHAND(lchan, LOGL_ERROR, - "Codec (FT = %d) of RTP frame not in list\n", ft_codec); - goto free_bad_msg; - } - if (amr_fn_is_cmr && lchan->amr.ul_ft != ft) { - LOGP_LCHAND(lchan, LOGL_ERROR, - "Codec (FT = %d) of RTP cannot be changed now, but in next frame\n", - ft_codec); - goto free_bad_msg; - } - lchan->amr.ul_ft = ft; - if (cmr < 0) { - LOGP_LCHAND(lchan, LOGL_ERROR, - "Codec (CMR = %d) of RTP frame not in list\n", cmr_codec); - } else { - lchan->amr.ul_cmr = cmr; - } + rc = gsm0503_tch_afs_encode(bursts_p, - msgb_l2(lchan->prim) + 2, - msgb_l2len(lchan->prim) - 2, + data, data_len, amr_fn_is_cmr, lchan->amr.codec, lchan->amr.codecs, diff --git a/src/host/trxcon/src/sched_lchan_tchh.c b/src/host/trxcon/src/sched_lchan_tchh.c index 30d623b..6973f91 100644 --- a/src/host/trxcon/src/sched_lchan_tchh.c +++ b/src/host/trxcon/src/sched_lchan_tchh.c @@ -457,54 +457,20 @@ break; case GSM48_CMODE_SPEECH_AMR: { - int len; - uint8_t cmr_codec; - int ft, cmr, i; - enum osmo_amr_type ft_codec; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - bool amr_fn_is_cmr; - /* the first FN 0,8,17 defines that CMI is included in frame, - * the first FN 4,13,21 defines that CMR is included in frame. - */ - amr_fn_is_cmr = !sched_tchh_ul_amr_cmi_map[br->fn % 26]; + bool amr_fn_is_cmr = !sched_tchh_ul_amr_cmi_map[br->fn % 26]; + const uint8_t *data = msgb_l2(lchan->prim); + size_t data_len = msgb_l2len(lchan->prim); - len = osmo_amr_rtp_dec(msgb_l2(lchan->prim), msgb_l2len(lchan->prim), - &cmr_codec, &cmi, &ft_codec, &bfi, &sti); - if (len < 0) { - LOGP_LCHAND(lchan, LOGL_ERROR, "Cannot send invalid AMR payload (%u): %s\n", - msgb_l2len(lchan->prim), msgb_hexdump_l2(lchan->prim)); - goto free_bad_msg; + if (data_len != GSM_MACBLOCK_LEN) { /* TCH/AHS: speech */ + if (!l1sched_lchan_amr_prim_is_valid(lchan, amr_fn_is_cmr)) + goto free_bad_msg; + /* pull the AMR header - sizeof(struct amr_hdr) */ + data_len -= 2; + data += 2; } - ft = -1; - cmr = -1; - for (i = 0; i < lchan->amr.codecs; i++) { - if (lchan->amr.codec[i] == ft_codec) - ft = i; - if (lchan->amr.codec[i] == cmr_codec) - cmr = i; - } - if (ft < 0) { - LOGP_LCHAND(lchan, LOGL_ERROR, - "Codec (FT = %d) of RTP frame not in list\n", ft_codec); - goto free_bad_msg; - } - if (amr_fn_is_cmr && lchan->amr.ul_ft != ft) { - LOGP_LCHAND(lchan, LOGL_ERROR, - "Codec (FT = %d) of RTP cannot be changed now, but in next frame\n", - ft_codec); - goto free_bad_msg; - } - lchan->amr.ul_ft = ft; - if (cmr < 0) { - LOGP_LCHAND(lchan, LOGL_ERROR, - "Codec (CMR = %d) of RTP frame not in list\n", cmr_codec); - } else { - lchan->amr.ul_cmr = cmr; - } + rc = gsm0503_tch_ahs_encode(bursts_p, - msgb_l2(lchan->prim) + 2, - msgb_l2len(lchan->prim) - 2, + data, data_len, amr_fn_is_cmr, lchan->amr.codec, lchan->amr.codecs, -- To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/33706 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Change-Id: Ie217bbb389b5abb95d241781ffe3f5c7b1c188c0 Gerrit-Change-Number: 33706 Gerrit-PatchSet: 1 Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[S] Change in osmocom-bb[master]: trxcon/l1sched: remove unused vars in l1sched_lchan_amr_prim_is_valid()
by fixeria 12 Jul '23

12 Jul '23
fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/33707 ) Change subject: trxcon/l1sched: remove unused vars in l1sched_lchan_amr_prim_is_valid() ...................................................................... trxcon/l1sched: remove unused vars in l1sched_lchan_amr_prim_is_valid() Change-Id: I57e18866addc2245c017e354eab218f56583026c Related: OS#4396 --- M src/host/trxcon/src/sched_lchan_common.c 1 file changed, 11 insertions(+), 3 deletions(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved diff --git a/src/host/trxcon/src/sched_lchan_common.c b/src/host/trxcon/src/sched_lchan_common.c index 26d8f22..ad42d9e 100644 --- a/src/host/trxcon/src/sched_lchan_common.c +++ b/src/host/trxcon/src/sched_lchan_common.c @@ -145,13 +145,11 @@ bool l1sched_lchan_amr_prim_is_valid(struct l1sched_lchan_state *lchan, bool is_cmr) { enum osmo_amr_type ft_codec; - enum osmo_amr_quality bfi; uint8_t cmr_codec; int ft, cmr, len; - int8_t sti, cmi; len = osmo_amr_rtp_dec(msgb_l2(lchan->prim), msgb_l2len(lchan->prim), - &cmr_codec, &cmi, &ft_codec, &bfi, &sti); + &cmr_codec, NULL, &ft_codec, NULL, NULL); if (len < 0) { LOGP_LCHAND(lchan, LOGL_ERROR, "Cannot send invalid AMR payload (%u): %s\n", msgb_l2len(lchan->prim), msgb_hexdump_l2(lchan->prim)); -- To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/33707 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Change-Id: I57e18866addc2245c017e354eab218f56583026c Gerrit-Change-Number: 33707 Gerrit-PatchSet: 1 Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-MessageType: merged
1 0
0 0
[L] Change in osmocom-bb[master]: trxcon/l1sched: rework dequeueing of Tx prims
by fixeria 12 Jul '23

12 Jul '23
fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/33708 ) Change subject: trxcon/l1sched: rework dequeueing of Tx prims ...................................................................... trxcon/l1sched: rework dequeueing of Tx prims Centralized dequeueing of Tx prims in l1sched_pull_burst() is a working approach, but doing this in each logical channel handler individually is a lot more flexible. This is how it's done in osmo-bts-trx, and this allows implementing FACCH support for CSD channels. Change-Id: I3d6c2136ff1855ab0aa9062b20b2a64fd0e5fe28 Related: OS#4396, OS#1572 --- M src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h M src/host/trxcon/include/osmocom/bb/l1sched/prim.h M src/host/trxcon/src/sched_lchan_desc.c M src/host/trxcon/src/sched_lchan_pdtch.c M src/host/trxcon/src/sched_lchan_rach.c M src/host/trxcon/src/sched_lchan_tchf.c M src/host/trxcon/src/sched_lchan_tchh.c M src/host/trxcon/src/sched_lchan_xcch.c M src/host/trxcon/src/sched_prim.c M src/host/trxcon/src/sched_trx.c 10 files changed, 174 insertions(+), 227 deletions(-) Approvals: laforge: Looks good to me, but someone else must approve fixeria: Verified pespin: Looks good to me, approved diff --git a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h index 715b9a0..cee2660 100644 --- a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h +++ b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h @@ -30,8 +30,6 @@ #define L1SCHED_CH_FLAG_PDCH (1 << 0) /* Should a channel be activated automatically */ #define L1SCHED_CH_FLAG_AUTO (1 << 1) -/* Is continuous burst transmission assumed */ -#define L1SCHED_CH_FLAG_CBTX (1 << 2) #define MAX_A5_KEY_LEN (128 / 8) #define TRX_TS_COUNT 8 diff --git a/src/host/trxcon/include/osmocom/bb/l1sched/prim.h b/src/host/trxcon/include/osmocom/bb/l1sched/prim.h index 0575ad8..c0e6af6 100644 --- a/src/host/trxcon/include/osmocom/bb/l1sched/prim.h +++ b/src/host/trxcon/include/osmocom/bb/l1sched/prim.h @@ -116,8 +116,9 @@ struct msgb *l1sched_prim_alloc(enum l1sched_prim_type type, enum osmo_prim_operation op); -struct msgb *l1sched_lchan_prim_dequeue(struct l1sched_lchan_state *lchan, uint32_t fn); -void l1sched_lchan_prim_assign_dummy(struct l1sched_lchan_state *lchan); +struct msgb *l1sched_lchan_prim_dequeue_sacch(struct l1sched_lchan_state *lchan); +struct msgb *l1sched_lchan_prim_dequeue_tch(struct l1sched_lchan_state *lchan, bool facch); +struct msgb *l1sched_lchan_prim_dummy(struct l1sched_lchan_state *lchan); void l1sched_lchan_prim_drop(struct l1sched_lchan_state *lchan); int l1sched_lchan_emit_data_ind(struct l1sched_lchan_state *lchan, diff --git a/src/host/trxcon/src/sched_lchan_desc.c b/src/host/trxcon/src/sched_lchan_desc.c index 3b37c57..4943a71 100644 --- a/src/host/trxcon/src/sched_lchan_desc.c +++ b/src/host/trxcon/src/sched_lchan_desc.c @@ -131,7 +131,6 @@ * The MS shall continuously transmit bursts, even if there is nothing * to send, unless DTX (Discontinuous Transmission) is used. */ .burst_buf_size = 8 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_tchf_fn, .tx_fn = tx_tchf_fn, }, @@ -158,7 +157,6 @@ * The MS shall continuously transmit bursts, even if there is nothing * to send, unless DTX (Discontinuous Transmission) is used. */ .burst_buf_size = 6 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_tchh_fn, .tx_fn = tx_tchh_fn, }, @@ -170,7 +168,6 @@ /* Same as for L1SCHED_TCHH_0, see above. */ .burst_buf_size = 6 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_tchh_fn, .tx_fn = tx_tchh_fn, }, @@ -182,7 +179,6 @@ /* Same as for L1SCHED_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -194,7 +190,6 @@ /* Same as for L1SCHED_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -206,7 +201,6 @@ /* Same as for L1SCHED_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -218,7 +212,6 @@ /* Same as for L1SCHED_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -230,7 +223,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -242,7 +234,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -254,7 +245,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -266,7 +256,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -278,7 +267,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -290,7 +278,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -302,7 +289,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -314,7 +300,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -326,7 +311,6 @@ /* Same as for L1SCHED_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -338,7 +322,6 @@ /* Same as for L1SCHED_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -350,7 +333,6 @@ /* Same as for L1SCHED_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -362,7 +344,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -374,7 +355,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -386,7 +366,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -398,7 +377,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -410,7 +388,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -422,7 +399,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -434,7 +410,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -446,7 +421,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -458,7 +432,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -470,7 +443,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -482,7 +454,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, @@ -494,7 +465,6 @@ /* Same as for L1SCHED_BCCH and L1SCHED_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_NBITS_NB_GMSK_PAYLOAD, - .flags = L1SCHED_CH_FLAG_CBTX, .rx_fn = rx_data_fn, .tx_fn = tx_data_fn, }, diff --git a/src/host/trxcon/src/sched_lchan_pdtch.c b/src/host/trxcon/src/sched_lchan_pdtch.c index 4b5ffdf..03d43ce 100644 --- a/src/host/trxcon/src/sched_lchan_pdtch.c +++ b/src/host/trxcon/src/sched_lchan_pdtch.c @@ -101,6 +101,24 @@ return 0; } +static struct msgb *prim_dequeue_pdtch(struct l1sched_lchan_state *lchan, uint32_t fn) +{ + const struct l1sched_prim *prim; + struct msgb *msg; + + msg = msgb_dequeue(&lchan->tx_prims); + if (msg == NULL) + return NULL; + prim = l1sched_prim_from_msgb(msg); + + if (OSMO_LIKELY(prim->data_req.frame_nr == fn)) + return msg; + LOGP_LCHAND(lchan, LOGL_ERROR, + "%s(): dropping Tx primitive (current Fn=%u, prim Fn=%u)\n", + __func__, fn, prim->data_req.frame_nr); + msgb_free(msg); + return NULL; +} int tx_pdtch_fn(struct l1sched_lchan_state *lchan, struct l1sched_burst_req *br) @@ -114,8 +132,17 @@ mask = &lchan->tx_burst_mask; bursts_p = lchan->tx_bursts; - if (br->bid > 0) + if (br->bid > 0) { + if ((*mask & 0x01) != 0x01) + return -ENOENT; goto send_burst; + } + + *mask = *mask << 4; + + lchan->prim = prim_dequeue_pdtch(lchan, br->fn); + if (lchan->prim == NULL) + return -ENOENT; /* Encode payload */ rc = gsm0503_pdtch_encode(bursts_p, msgb_l2(lchan->prim), msgb_l2len(lchan->prim)); @@ -150,9 +177,6 @@ if ((*mask & 0x0f) == 0x0f) { /* Confirm data / traffic sending (pass ownership of the prim) */ l1sched_lchan_emit_data_cnf(lchan, br->fn); - - /* Reset mask */ - *mask = 0x00; } return 0; diff --git a/src/host/trxcon/src/sched_lchan_rach.c b/src/host/trxcon/src/sched_lchan_rach.c index 109d100..8df7fa2 100644 --- a/src/host/trxcon/src/sched_lchan_rach.c +++ b/src/host/trxcon/src/sched_lchan_rach.c @@ -78,6 +78,11 @@ uint8_t payload[36]; int i, rc; + if (lchan->prim == NULL) { + lchan->prim = msgb_dequeue(&lchan->tx_prims); + if (lchan->prim == NULL) + return 0; + } prim = l1sched_prim_from_msgb(lchan->prim); /* Delay sending according to offset value */ diff --git a/src/host/trxcon/src/sched_lchan_tchf.c b/src/host/trxcon/src/sched_lchan_tchf.c index 9e8256f..6d48fc7 100644 --- a/src/host/trxcon/src/sched_lchan_tchf.c +++ b/src/host/trxcon/src/sched_lchan_tchf.c @@ -213,6 +213,30 @@ n_errors, n_bits_total, true); } +static struct msgb *prim_dequeue_tchf(struct l1sched_lchan_state *lchan) +{ + struct msgb *facch; + struct msgb *tch; + + /* Attempt to find a pair of FACCH/F and TCH/F frames */ + facch = l1sched_lchan_prim_dequeue_tch(lchan, true); + tch = l1sched_lchan_prim_dequeue_tch(lchan, false); + + /* Prioritize FACCH/F, if found */ + if (facch) { + /* One TCH/F prim is replaced */ + if (tch) + msgb_free(tch); + return facch; + } else if (tch) { + /* Only TCH/F prim was found */ + return tch; + } else { + /* Nothing was found */ + return NULL; + } +} + int tx_tchf_fn(struct l1sched_lchan_state *lchan, struct l1sched_burst_req *br) { @@ -225,14 +249,24 @@ mask = &lchan->tx_burst_mask; bursts_p = lchan->tx_bursts; - if (br->bid > 0) + if (br->bid > 0) { + if ((*mask & 0x01) != 0x01) + return -ENOENT; goto send_burst; + } /* Shift the burst buffer by 4 bursts leftwards for interleaving */ memcpy(&bursts_p[0], &bursts_p[464], 464); memset(&bursts_p[464], 0, 464); *mask = *mask << 4; + lchan->prim = prim_dequeue_tchf(lchan); + if (lchan->prim == NULL) { + lchan->prim = l1sched_lchan_prim_dummy(lchan); + if (lchan->prim == NULL) + return -ENOENT; + } + /* populate the buffer with bursts */ switch (lchan->tch_mode) { case GSM48_CMODE_SIGN: diff --git a/src/host/trxcon/src/sched_lchan_tchh.c b/src/host/trxcon/src/sched_lchan_tchh.c index 6973f91..6affbc5 100644 --- a/src/host/trxcon/src/sched_lchan_tchh.c +++ b/src/host/trxcon/src/sched_lchan_tchh.c @@ -412,6 +412,40 @@ n_errors, n_bits_total, true); } +static struct msgb *prim_dequeue_tchh(struct l1sched_lchan_state *lchan, uint32_t fn) +{ + struct msgb *facch; + struct msgb *tch; + bool facch_now; + + /* Can we initiate an UL FACCH/H frame transmission at this Fn? */ + facch_now = l1sched_tchh_facch_start(lchan->type, fn, true); + if (!facch_now) + goto no_facch; + + /* If there are no FACCH/H prims in the queue */ + facch = l1sched_lchan_prim_dequeue_tch(lchan, true); + if (!facch) /* Just dequeue a TCH/H prim */ + goto no_facch; + + /* FACCH/H prim replaces two TCH/F prims */ + tch = l1sched_lchan_prim_dequeue_tch(lchan, false); + if (tch) { + /* At least one TCH/H prim is dropped */ + msgb_free(tch); + + /* Attempt to find another */ + tch = l1sched_lchan_prim_dequeue_tch(lchan, false); + if (tch) /* Drop the second TCH/H prim */ + msgb_free(tch); + } + + return facch; + +no_facch: + return l1sched_lchan_prim_dequeue_tch(lchan, false); +} + int tx_tchh_fn(struct l1sched_lchan_state *lchan, struct l1sched_burst_req *br) { @@ -424,8 +458,11 @@ mask = &lchan->tx_burst_mask; bursts_p = lchan->tx_bursts; - if (br->bid > 0) + if (br->bid > 0) { + if ((*mask & 0x01) != 0x01) + return -ENOENT; goto send_burst; + } if (*mask == 0x00) { /* Align transmission of the first FACCH/H frame */ @@ -444,6 +481,13 @@ if (lchan->ul_facch_blocks > 2) goto send_burst; + lchan->prim = prim_dequeue_tchh(lchan, br->fn); + if (lchan->prim == NULL) { + lchan->prim = l1sched_lchan_prim_dummy(lchan); + if (lchan->prim == NULL) + return -ENOENT; + } + if (msgb_l2len(lchan->prim) == GSM_MACBLOCK_LEN) lchan->ul_facch_blocks = 6; diff --git a/src/host/trxcon/src/sched_lchan_xcch.c b/src/host/trxcon/src/sched_lchan_xcch.c index f76d518..7f1dd11 100644 --- a/src/host/trxcon/src/sched_lchan_xcch.c +++ b/src/host/trxcon/src/sched_lchan_xcch.c @@ -98,6 +98,27 @@ n_errors, n_bits_total, false); } +static struct msgb *prim_dequeue_xcch(struct l1sched_lchan_state *lchan) +{ + struct msgb *msg; + + if (L1SCHED_CHAN_IS_SACCH(lchan->type)) + return l1sched_lchan_prim_dequeue_sacch(lchan); + if ((msg = msgb_dequeue(&lchan->tx_prims)) == NULL) + return NULL; + + /* Check the prim payload length */ + if (msgb_l2len(msg) != GSM_MACBLOCK_LEN) { + LOGP_LCHAND(lchan, LOGL_ERROR, + "Primitive has odd length %u (expected %u), so dropping...\n", + msgb_l2len(msg), GSM_MACBLOCK_LEN); + msgb_free(msg); + return NULL; + } + + return msg; +} + int tx_data_fn(struct l1sched_lchan_state *lchan, struct l1sched_burst_req *br) { @@ -110,18 +131,19 @@ mask = &lchan->tx_burst_mask; bursts_p = lchan->tx_bursts; - if (br->bid > 0) + if (br->bid > 0) { + if ((*mask & 0x01) != 0x01) + return -ENOENT; goto send_burst; - - /* Check the prim payload length */ - if (msgb_l2len(lchan->prim) != GSM_MACBLOCK_LEN) { - LOGP_LCHAND(lchan, LOGL_ERROR, - "Primitive has odd length %u (expected %u), so dropping...\n", - msgb_l2len(lchan->prim), GSM_MACBLOCK_LEN); - l1sched_lchan_prim_drop(lchan); - return -EINVAL; } + *mask = *mask << 4; + + lchan->prim = prim_dequeue_xcch(lchan); + if (lchan->prim == NULL) + lchan->prim = l1sched_lchan_prim_dummy(lchan); + OSMO_ASSERT(lchan->prim != NULL); + /* Encode payload */ rc = gsm0503_xcch_encode(bursts_p, msgb_l2(lchan->prim)); if (rc) { @@ -155,9 +177,6 @@ if ((*mask & 0x0f) == 0x0f) { /* Confirm data sending (pass ownership of the prim) */ l1sched_lchan_emit_data_cnf(lchan, br->fn); - - /* Reset mask */ - *mask = 0x00; } return 0; diff --git a/src/host/trxcon/src/sched_prim.c b/src/host/trxcon/src/sched_prim.c index 44cfd37..3301df4 100644 --- a/src/host/trxcon/src/sched_prim.c +++ b/src/host/trxcon/src/sched_prim.c @@ -151,7 +151,7 @@ * @param lchan lchan to assign a primitive * @return SACCH primitive to be transmitted */ -static struct msgb *prim_dequeue_sacch(struct l1sched_lchan_state *lchan) +struct msgb *l1sched_lchan_prim_dequeue_sacch(struct l1sched_lchan_state *lchan) { struct msgb *msg_nmr = NULL; struct msgb *msg_mr = NULL; @@ -228,7 +228,7 @@ * @return either a FACCH, or a TCH primitive if found, * otherwise NULL */ -static struct msgb *prim_dequeue_tch(struct l1sched_lchan_state *lchan, bool facch) +struct msgb *l1sched_lchan_prim_dequeue_tch(struct l1sched_lchan_state *lchan, bool facch) { struct msgb *msg; @@ -249,146 +249,6 @@ } /** - * Dequeues either a TCH/F, or a FACCH/F prim (preferred). - * If a FACCH/F prim is found, one TCH/F prim is being - * dropped (i.e. replaced). - * - * @param lchan logical channel state - * @return either a FACCH/F, or a TCH/F primitive, - * otherwise NULL - */ -static struct msgb *prim_dequeue_tch_f(struct l1sched_lchan_state *lchan) -{ - struct msgb *facch; - struct msgb *tch; - - /* Attempt to find a pair of both FACCH/F and TCH/F frames */ - facch = prim_dequeue_tch(lchan, true); - tch = prim_dequeue_tch(lchan, false); - - /* Prioritize FACCH/F, if found */ - if (facch) { - /* One TCH/F prim is replaced */ - if (tch) - msgb_free(tch); - return facch; - } else if (tch) { - /* Only TCH/F prim was found */ - return tch; - } else { - /* Nothing was found */ - return NULL; - } -} - -/** - * Dequeues either a TCH/H, or a FACCH/H prim (preferred). - * If a FACCH/H prim is found, two TCH/H prims are being - * dropped (i.e. replaced). - * - * According to GSM 05.02, the following blocks can be used - * to carry FACCH/H data (see clause 7, table 1 of 9): - * - * UL FACCH/H0: - * B0(0,2,4,6,8,10), B1(8,10,13,15,17,19), B2(17,19,21,23,0,2) - * - * UL FACCH/H1: - * B0(1,3,5,7,9,11), B1(9,11,14,16,18,20), B2(18,20,22,24,1,3) - * - * where the numbers within brackets are fn % 26. - * - * @param lchan logical channel state - * @param fn the current frame number - * @return either a FACCH/H, or a TCH/H primitive, - * otherwise NULL - */ -static struct msgb *prim_dequeue_tch_h(struct l1sched_lchan_state *lchan, uint32_t fn) -{ - struct msgb *facch; - struct msgb *tch; - bool facch_now; - - /* May we initiate an UL FACCH/H frame transmission now? */ - facch_now = l1sched_tchh_facch_start(lchan->type, fn, true); - if (!facch_now) /* Just dequeue a TCH/H prim */ - goto no_facch; - - /* If there are no FACCH/H prims in the queue */ - facch = prim_dequeue_tch(lchan, true); - if (!facch) /* Just dequeue a TCH/H prim */ - goto no_facch; - - /* FACCH/H prim replaces two TCH/F prims */ - tch = prim_dequeue_tch(lchan, false); - if (tch) { - /* At least one TCH/H prim is dropped */ - msgb_free(tch); - - /* Attempt to find another */ - tch = prim_dequeue_tch(lchan, false); - if (tch) /* Drop the second TCH/H prim */ - msgb_free(tch); - } - - return facch; - -no_facch: - return prim_dequeue_tch(lchan, false); -} - -/** - * Dequeues a primitive from the Tx queue of the given lchan. - * - * @param lchan logical channel state - * @param fn the current frame number (used for FACCH/H) - * @return a primitive or NULL if not found - */ -struct msgb *l1sched_lchan_prim_dequeue(struct l1sched_lchan_state *lchan, uint32_t fn) -{ - /* SACCH is unorthodox, see 3GPP TS 04.08, section 3.4.1 */ - if (L1SCHED_CHAN_IS_SACCH(lchan->type)) - return prim_dequeue_sacch(lchan); - - /* There is nothing to dequeue */ - if (llist_empty(&lchan->tx_prims)) - return NULL; - - switch (lchan->type) { - /* TCH/F requires FACCH/F prioritization */ - case L1SCHED_TCHF: - return prim_dequeue_tch_f(lchan); - - /* FACCH/H prioritization is a bit more complex */ - case L1SCHED_TCHH_0: - case L1SCHED_TCHH_1: - return prim_dequeue_tch_h(lchan, fn); - - /* PDCH is timing critical, we need to check TDMA Fn */ - case L1SCHED_PDTCH: - { - struct msgb *msg = msgb_dequeue(&lchan->tx_prims); - const struct l1sched_prim *prim; - - if (msg == NULL) - return NULL; - prim = l1sched_prim_from_msgb(msg); - - if (OSMO_LIKELY(prim->data_req.frame_nr == fn)) - return msg; - LOGP_LCHAND(lchan, LOGL_ERROR, - "%s(): dropping Tx primitive (current Fn=%u, prim Fn=%u)\n", - __func__, fn, prim->data_req.frame_nr); - msgb_free(msg); - return NULL; - } - - /* Other kinds of logical channels */ - default: - return msgb_dequeue(&lchan->tx_prims); - } -} - -/** * Drops the current primitive of specified logical channel * * @param lchan a logical channel to drop prim from @@ -400,14 +260,13 @@ } /** - * Assigns a dummy primitive to a lchan depending on its type. - * Could be used when there is nothing to transmit, but - * CBTX (Continuous Burst Transmission) is assumed. + * Allocate a dummy DATA.req for the given logical channel. + * To be used when no suitable DATA.req is present in the Tx queue. * - * @param lchan lchan to assign a primitive - * @return zero in case of success, otherwise a error code + * @param lchan lchan to allocate a dummy primitive for + * @return an msgb with DATA.req primitive, or NULL */ -void l1sched_lchan_prim_assign_dummy(struct l1sched_lchan_state *lchan) +struct msgb *l1sched_lchan_prim_dummy(struct l1sched_lchan_state *lchan) { const struct l1sched_lchan_desc *lchan_desc; enum l1sched_lchan_type chan = lchan->type; @@ -428,8 +287,6 @@ /* Pending part is to be randomized */ }; - /* Make sure that there is no existing primitive */ - OSMO_ASSERT(lchan->prim == NULL); /* Not applicable for SACCH! */ OSMO_ASSERT(!L1SCHED_CHAN_IS_SACCH(lchan->type)); @@ -446,7 +303,7 @@ prim_len = l1sched_bad_frame_ind(prim_buffer, lchan); } else if (L1SCHED_CHAN_IS_TCH(chan) && L1SCHED_TCH_MODE_IS_DATA(tch_mode)) { /* FIXME: should we do anything for CSD? */ - return; + return NULL; } else { /* Copy LAPDm fill frame's header */ memcpy(prim_buffer, lapdm_fill_frame, sizeof(lapdm_fill_frame)); @@ -466,7 +323,7 @@ /* Nothing to allocate / assign */ if (!prim_len) - return; + return NULL; msg = l1sched_prim_alloc(L1SCHED_PRIM_T_DATA, PRIM_OP_REQUEST); OSMO_ASSERT(msg != NULL); @@ -479,10 +336,7 @@ memcpy(msgb_put(msg, prim_len), &prim_buffer[0], prim_len); - /* Assign the current prim */ - lchan->prim = msg; - - LOGP_LCHAND(lchan, LOGL_DEBUG, "Transmitting a dummy / silence frame\n"); + return msg; } int l1sched_lchan_emit_data_ind(struct l1sched_lchan_state *lchan, diff --git a/src/host/trxcon/src/sched_trx.c b/src/host/trxcon/src/sched_trx.c index 3b452b1..cac3a21 100644 --- a/src/host/trxcon/src/sched_trx.c +++ b/src/host/trxcon/src/sched_trx.c @@ -121,27 +121,10 @@ if (lchan == NULL || !lchan->active) return; - /* If no primitive is being processed, try obtaining one from Tx queue */ - if (lchan->prim == NULL) { - /* Align to the first burst of a block */ - if (frame->ul_bid != 0) - return; - lchan->prim = l1sched_lchan_prim_dequeue(lchan, br->fn); - if (lchan->prim == NULL) { - /* If CBTX (Continuous Burst Transmission) is required */ - if (l1sched_lchan_desc[chan].flags & L1SCHED_CH_FLAG_CBTX) - l1sched_lchan_prim_assign_dummy(lchan); - if (lchan->prim == NULL) - return; - } - } - - /* TODO: report TX buffers health to the higher layers */ - /* Handover RACH needs to be handled regardless of the * current channel type and the associated handler. */ - if (l1sched_prim_type_from_msgb(lchan->prim) == L1SCHED_PRIM_T_RACH && - lchan->type != L1SCHED_RACH) + struct msgb *msg = llist_first_entry_or_null(&lchan->tx_prims, struct msgb, list); + if (msg && l1sched_prim_type_from_msgb(msg) == L1SCHED_PRIM_T_RACH) handler = l1sched_lchan_desc[L1SCHED_RACH].tx_fn; /* Poke lchan handler */ -- To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/33708 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Change-Id: I3d6c2136ff1855ab0aa9062b20b2a64fd0e5fe28 Gerrit-Change-Number: 33708 Gerrit-PatchSet: 1 Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • ...
  • 306
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.