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

November 2023

  • 1 participants
  • 1508 discussions
[M] Change in libosmocore[master]: coding: gsm0503_tch_{afs,ahs}_encode(): add ability to emit BFI
by laforge 27 Nov '23

27 Nov '23
Attention is currently required from: falconia, jolly. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmocore/+/35131?usp=email ) Change subject: coding: gsm0503_tch_{afs,ahs}_encode(): add ability to emit BFI ...................................................................... Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/35131?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I82ce2adf995a4b42d1f378c5819f88d773b9104a Gerrit-Change-Number: 35131 Gerrit-PatchSet: 2 Gerrit-Owner: jolly <andreas(a)eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: falconia <falcon(a)freecalypso.org> Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Attention: jolly <andreas(a)eversberg.eu> Gerrit-Attention: falconia <falcon(a)freecalypso.org> Gerrit-Comment-Date: Mon, 27 Nov 2023 16:27:30 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
[S] Change in osmo-bts[master]: LAPDm: Reject (release) establishment on DCCH, SAPI 0 without L3 payload
by laforge 27 Nov '23

27 Nov '23
Attention is currently required from: fixeria, jolly. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-bts/+/35082?usp=email ) Change subject: LAPDm: Reject (release) establishment on DCCH, SAPI 0 without L3 payload ...................................................................... Patch Set 4: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/35082?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Change-Id: I6819b51a876b8743c2d4a04165b7900723a1631c Gerrit-Change-Number: 35082 Gerrit-PatchSet: 4 Gerrit-Owner: jolly <andreas(a)eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Attention: jolly <andreas(a)eversberg.eu> Gerrit-Attention: fixeria <vyanitskiy(a)sysmocom.de> Gerrit-Comment-Date: Mon, 27 Nov 2023 16:26:42 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
[M] Change in libosmocore[master]: LAPDm: Add support for RTS based polling
by laforge 27 Nov '23

27 Nov '23
laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/34986?usp=email ) Change subject: LAPDm: Add support for RTS based polling ...................................................................... LAPDm: Add support for RTS based polling The lower layer must set the 'POLLING_ONLY' flag and provide frame number when polling a frame. If T200 is pending, it is started with a timeout frame number in advance to given frame number. The lower layer must call lapdm_t200_fn() after a frame has been received or if a frame has not been received. Also it must be called after a TCH frame has been received. LAPDm uses this to check the T200 timeout condition. A new function is used to set the frame number based timeout values. Related: OS#4074 Change-Id: I6ebe83f829d7751ea9de1d90eb478c7a628db64c --- M TODO-RELEASE M include/osmocom/gsm/lapdm.h M src/gsm/lapdm.c M src/gsm/libosmogsm.map 4 files changed, 178 insertions(+), 11 deletions(-) Approvals: Jenkins Builder: Verified daniel: Looks good to me, but someone else must approve laforge: Looks good to me, approved diff --git a/TODO-RELEASE b/TODO-RELEASE index 1d56d45..226450b 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -10,3 +10,4 @@ core ADD osmo_sock_multiaddr_{add,del}_local_addr() core ADD gsmtap_inst_fd2() core, DEPRECATE gsmtap_inst_fd() isdn ABI change add states and flags for external T200 handling +gsm ABI change add T200 timer states to lapdm_datalink diff --git a/include/osmocom/gsm/lapdm.h b/include/osmocom/gsm/lapdm.h index 1a39fca..db66680 100644 --- a/include/osmocom/gsm/lapdm.h +++ b/include/osmocom/gsm/lapdm.h @@ -33,6 +33,9 @@ struct lapdm_msg_ctx mctx; /*!< context of established connection */ struct lapdm_entity *entity; /*!< LAPDm entity we are part of */ + + uint32_t t200_fn; /*!< T200 timer in frames */ + uint32_t t200_timeout; /*!< T200 timeout frame number */ }; /*! LAPDm datalink SAPIs */ @@ -119,6 +122,11 @@ void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags); void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags); +void lapdm_entity_set_t200_fn(struct lapdm_entity *le, const uint32_t *t200_fn); +void lapdm_channel_set_t200_fn(struct lapdm_channel *lc, const uint32_t *t200_fn_dcch, const uint32_t *t200_fn_acch); + int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp); +int lapdm_phsap_dequeue_prim_fn(struct lapdm_entity *le, struct osmo_phsap_prim *pp, uint32_t fn); +void lapdm_t200_fn(struct lapdm_entity *le, uint32_t fn); /*! @} */ diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c index 43f5662..d609317 100644 --- a/src/gsm/lapdm.c +++ b/src/gsm/lapdm.c @@ -27,6 +27,7 @@ #include <stdio.h> #include <stdint.h> +#include <inttypes.h> #include <string.h> #include <errno.h> @@ -196,9 +197,9 @@ char name[256]; if (name_pfx) { snprintf(name, sizeof(name), "%s[%s]", name_pfx, i == 0 ? "0" : "3"); - lapdm_dl_init(&le->datalink[i], le, t200_ms[i], n200, name); + lapdm_dl_init(&le->datalink[i], le, (t200_ms) ? t200_ms[i] : 0, n200, name); } else - lapdm_dl_init(&le->datalink[i], le, t200_ms[i], n200, NULL); + lapdm_dl_init(&le->datalink[i], le, (t200_ms) ? t200_ms[i] : 0, n200, NULL); } lapdm_entity_set_mode(le, mode); @@ -358,6 +359,18 @@ /* if there is a pending message, queue it */ if (le->tx_pending || le->flags & LAPDM_ENT_F_POLLING_ONLY) { + struct msgb *old_msg; + + /* In 'Polling only' mode there can be only one message. */ + if (le->flags & LAPDM_ENT_F_POLLING_ONLY) { + /* Overwrite existing message by removing it first. */ + if ((old_msg = msgb_dequeue(&dl->dl.tx_queue))) { + msgb_free(old_msg); + /* Reset V(S) to V(A), because there is no outstanding message now. */ + dl->dl.v_send = dl->dl.v_ack; + } + } + *msgb_push(msg, 1) = pad; *msgb_push(msg, 1) = link_id; *msgb_push(msg, 1) = chan_nr; @@ -377,21 +390,55 @@ return le->l1_prim_cb(&pp.oph, le->l1_ctx); } +/* Get transmit frame from queue, if any. In polling mode, indicate RTS to LAPD and start T200, if pending. */ +static struct msgb *tx_dequeue_msgb(struct lapdm_datalink *dl, uint32_t fn) +{ + struct msgb *msg; + + /* Call RTS function of LAPD, to poll next frame. */ + if (dl->entity->flags & LAPDM_ENT_F_POLLING_ONLY) { + struct lapd_msg_ctx lctx; + int rc; + + /* Poll next frame. */ + lctx.dl = &dl->dl; + rc = lapd_ph_rts_ind(&lctx); + + /* If T200 has been started, calculate timeout FN. */ + if (rc == 1) { + /* Set T200 in advance. */ + dl->t200_timeout = fn; + ADD_MODULO(dl->t200_timeout, dl->t200_fn, GSM_MAX_FN); + + LOGDL(&dl->dl, LOGL_INFO, + "T200 running from FN %"PRIu32" to FN %"PRIu32" (%"PRIu32" frames).\n", + fn, dl->t200_timeout, dl->t200_fn); + } + } + + /* If there is no frame from LAPD, send UI frame, if any. */ + msg = msgb_dequeue(&dl->dl.tx_queue); + if (msg) + LOGDL(&dl->dl, LOGL_INFO, "Sending frame from TX queue. (FN %"PRIu32")\n", fn); + return msg; +} + /* Dequeue a Downlink message for DCCH (dedicated channel) */ -static struct msgb *tx_dequeue_dcch_msgb(struct lapdm_entity *le) +static struct msgb *tx_dequeue_dcch_msgb(struct lapdm_entity *le, uint32_t fn) { struct msgb *msg; /* SAPI=0 always has higher priority than SAPI=3 */ - msg = msgb_dequeue(&le->datalink[DL_SAPI0].dl.tx_queue); - if (msg == NULL) /* no SAPI=0 messages, dequeue SAPI=3 (if any) */ - msg = msgb_dequeue(&le->datalink[DL_SAPI3].dl.tx_queue); + msg = tx_dequeue_msgb(&le->datalink[DL_SAPI0], fn); + if (msg == NULL) { /* no SAPI=0 messages, dequeue SAPI=3 (if any) */ + msg = tx_dequeue_msgb(&le->datalink[DL_SAPI3], fn); + } return msg; } /* Dequeue a Downlink message for ACCH (associated channel) */ -static struct msgb *tx_dequeue_acch_msgb(struct lapdm_entity *le) +static struct msgb *tx_dequeue_acch_msgb(struct lapdm_entity *le, uint32_t fn) { struct lapdm_datalink *dl; int last = le->last_tx_dequeue; @@ -403,7 +450,7 @@ /* next */ i = (i + 1) % n; dl = &le->datalink[i]; - if ((msg = msgb_dequeue(&dl->dl.tx_queue))) + if ((msg = tx_dequeue_msgb(dl, fn))) break; } while (i != last); @@ -417,7 +464,7 @@ /*! dequeue a msg that's pending transmission via L1 and wrap it into * a osmo_phsap_prim */ -int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp) +int lapdm_phsap_dequeue_prim_fn(struct lapdm_entity *le, struct osmo_phsap_prim *pp, uint32_t fn) { struct msgb *msg; uint8_t pad; @@ -425,9 +472,9 @@ /* Dequeue depending on channel type: DCCH or ACCH. * See 3GPP TS 44.005, section 4.2.2 "Priority". */ if (le == &le->lapdm_ch->lapdm_dcch) - msg = tx_dequeue_dcch_msgb(le); + msg = tx_dequeue_dcch_msgb(le, fn); else - msg = tx_dequeue_acch_msgb(le); + msg = tx_dequeue_acch_msgb(le, fn); if (!msg) return -ENODEV; @@ -449,6 +496,57 @@ return 0; } +static void lapdm_t200_fn_dl(struct lapdm_datalink *dl, uint32_t fn) +{ + uint32_t diff; + + OSMO_ASSERT((dl->dl.lapd_flags & LAPD_F_RTS)); + + /* If T200 is running, check if it has fired. */ + if (dl->dl.t200_rts != LAPD_T200_RTS_RUNNING) + return; + + /* Calculate how many frames fn is behind t200_timeout. + * If it is negative (>= GSM_MAX_FN / 2), we have not reached t200_timeout yet. + * If it is 0 or positive, we reached it or we are a bit too late, which is not a problem. + */ + diff = fn; + ADD_MODULO(diff, GSM_MAX_FN - dl->t200_timeout, GSM_MAX_FN); + if (diff >= GSM_MAX_FN / 2) + return; + + LOGDL(&dl->dl, LOGL_INFO, "T200 timeout at FN %"PRIu32", detected at FN %"PRIu32".\n", dl->t200_timeout, fn); + + lapd_t200_timeout(&dl->dl); +} + +/*! Get receive frame number from L1. It is used to check the T200 timeout. + * This function is used if LAPD is in RTS mode only. (Applies if the LAPDM_ENT_F_POLLING_ONLY flag is set.) + * This function must be called for every valid or invalid data frame received. + * The frame number fn must be the frame number of the first burst of a data frame. + * This function must be called after the frame is delivered to layer 2. + * In case of TCH, this this function must be called for every speech frame received, meaning that there was no valid + * data frame. */ +void lapdm_t200_fn(struct lapdm_entity *le, uint32_t fn) +{ + unsigned int i; + + if (!(le->flags & LAPDM_ENT_F_POLLING_ONLY)) { + LOGP(DLLAPD, LOGL_ERROR, "Function call not allowed on timer based T200.\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(le->datalink); i++) + lapdm_t200_fn_dl(&le->datalink[i], fn); +} + +/*! dequeue a msg that's pending transmission via L1 and wrap it into + * a osmo_phsap_prim */ +int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp) +{ + return lapdm_phsap_dequeue_prim_fn(le, pp, 0); +} + /* get next frame from the tx queue. because the ms has multiple datalinks, * each datalink's queue is read round-robin. */ @@ -853,6 +951,7 @@ return -EINVAL; } /* send to LAPD */ + LOGDL(lctx.dl, LOGL_DEBUG, "Frame received at FN %"PRIu32".\n", fn); rc = lapd_ph_data_ind(msg, &lctx); break; case LAPDm_FMT_Bter: @@ -1494,7 +1593,20 @@ /*! Set the flags of a LAPDm entity */ void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags) { + unsigned int dl_flags = 0; + struct lapdm_datalink *dl; + int i; + le->flags = flags; + + /* Set flags at LAPD. */ + if (le->flags & LAPDM_ENT_F_POLLING_ONLY) + dl_flags |= LAPD_F_RTS; + + for (i = 0; i < ARRAY_SIZE(le->datalink); i++) { + dl = &le->datalink[i]; + lapd_dl_set_flags(&dl->dl, dl_flags); + } } /*! Set the flags of all LAPDm entities in a LAPDm channel */ @@ -1504,4 +1616,25 @@ lapdm_entity_set_flags(&lc->lapdm_acch, flags); } +/*! Set the T200 FN timer of a LAPDm entity + * \param[in] \ref lapdm_entity + * \param[in] t200_fn Array of T200 timeout in frame numbers for all SAPIs (0, 3) */ +void lapdm_entity_set_t200_fn(struct lapdm_entity *le, const uint32_t *t200_fn) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(le->datalink); i++) + le->datalink[i].t200_fn = t200_fn[i]; +} + +/*! Set the T200 FN timer of all LAPDm entities in a LAPDm channel + * \param[in] \ref lapdm_channel + * \param[in] t200_fn_dcch Array of T200 timeout in frame numbers for all SAPIs (0, 3) on SDCCH/FACCH + * \param[in] t200_fn_acch Array of T200 timeout in frame numbers for all SAPIs (0, 3) on SACCH */ +void lapdm_channel_set_t200_fn(struct lapdm_channel *lc, const uint32_t *t200_fn_dcch, const uint32_t *t200_fn_acch) +{ + lapdm_entity_set_t200_fn(&lc->lapdm_dcch, t200_fn_dcch); + lapdm_entity_set_t200_fn(&lc->lapdm_acch, t200_fn_acch); +} + /*! @} */ diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 056d320..6bb3b4b 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -587,7 +587,11 @@ lapdm_entity_reset; lapdm_entity_set_flags; lapdm_entity_set_mode; +lapdm_entity_set_t200_fn; +lapdm_channel_set_t200_fn; lapdm_phsap_dequeue_prim; +lapdm_phsap_dequeue_prim_fn; +lapdm_t200_fn; lapdm_phsap_up; lapdm_rslms_recvmsg; -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/34986?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I6ebe83f829d7751ea9de1d90eb478c7a628db64c Gerrit-Change-Number: 34986 Gerrit-PatchSet: 17 Gerrit-Owner: jolly <andreas(a)eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in libosmocore[master]: LAPDm: Add an extra queue for UI frames
by laforge 27 Nov '23

27 Nov '23
laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/34987?usp=email ) ( 14 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: LAPDm: Add an extra queue for UI frames ...................................................................... LAPDm: Add an extra queue for UI frames The extra queue is used to transmit the UI frame only when there is no frame in the regular TX queue. This allows to give LAPD frames prioity over UI frame. Related: OS#4074 Change-Id: I00c8ee73be8b7c564a4dee3fca3e893484f567da --- M TODO-RELEASE M include/osmocom/gsm/lapdm.h M src/gsm/lapdm.c 3 files changed, 52 insertions(+), 1 deletion(-) Approvals: Jenkins Builder: Verified daniel: Looks good to me, approved laforge: Looks good to me, but someone else must approve diff --git a/TODO-RELEASE b/TODO-RELEASE index 226450b..fa7bc57 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -11,3 +11,4 @@ core ADD gsmtap_inst_fd2() core, DEPRECATE gsmtap_inst_fd() isdn ABI change add states and flags for external T200 handling gsm ABI change add T200 timer states to lapdm_datalink +gsm ABI change add UI queue to struct lapdm_datalink diff --git a/include/osmocom/gsm/lapdm.h b/include/osmocom/gsm/lapdm.h index db66680..08b808c 100644 --- a/include/osmocom/gsm/lapdm.h +++ b/include/osmocom/gsm/lapdm.h @@ -34,6 +34,7 @@ struct lapdm_entity *entity; /*!< LAPDm entity we are part of */ + struct llist_head tx_ui_queue; /*!< UI frames to L1 */ uint32_t t200_fn; /*!< T200 timer in frames */ uint32_t t200_timeout; /*!< T200 timeout frame number */ }; diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c index d609317..28644c2 100644 --- a/src/gsm/lapdm.c +++ b/src/gsm/lapdm.c @@ -200,6 +200,7 @@ lapdm_dl_init(&le->datalink[i], le, (t200_ms) ? t200_ms[i] : 0, n200, name); } else lapdm_dl_init(&le->datalink[i], le, (t200_ms) ? t200_ms[i] : 0, n200, NULL); + INIT_LLIST_HEAD(&le->datalink[i].tx_ui_queue); } lapdm_entity_set_mode(le, mode); @@ -296,6 +297,7 @@ for (i = 0; i < ARRAY_SIZE(le->datalink); i++) { dl = &le->datalink[i]; lapd_dl_exit(&dl->dl); + msgb_queue_free(&dl->tx_ui_queue); } } @@ -390,6 +392,33 @@ return le->l1_prim_cb(&pp.oph, le->l1_ctx); } +static int tx_ph_data_enqueue_ui(struct lapdm_datalink *dl, struct msgb *msg, + uint8_t chan_nr, uint8_t link_id, uint8_t pad) +{ + struct lapdm_entity *le = dl->entity; + struct osmo_phsap_prim pp; + + /* if there is a pending message, queue it */ + if (le->tx_pending || le->flags & LAPDM_ENT_F_POLLING_ONLY) { + *msgb_push(msg, 1) = pad; + *msgb_push(msg, 1) = link_id; + *msgb_push(msg, 1) = chan_nr; + msgb_enqueue(&dl->tx_ui_queue, msg); + return 0; + } + + osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA, + PRIM_OP_REQUEST, msg); + pp.u.data.chan_nr = chan_nr; + pp.u.data.link_id = link_id; + + /* send the frame now */ + le->tx_pending = 0; /* disabled flow control */ + lapdm_pad_msgb(msg, pad); + + return le->l1_prim_cb(&pp.oph, le->l1_ctx); +} + /* Get transmit frame from queue, if any. In polling mode, indicate RTS to LAPD and start T200, if pending. */ static struct msgb *tx_dequeue_msgb(struct lapdm_datalink *dl, uint32_t fn) { @@ -420,6 +449,11 @@ msg = msgb_dequeue(&dl->dl.tx_queue); if (msg) LOGDL(&dl->dl, LOGL_INFO, "Sending frame from TX queue. (FN %"PRIu32")\n", fn); + else { + msg = msgb_dequeue(&dl->tx_ui_queue); + if (msg) + LOGDL(&dl->dl, LOGL_INFO, "Sending UI frame from TX queue. (FN %"PRIu32")\n", fn); + } return msg; } @@ -1183,7 +1217,7 @@ } /* Tramsmit */ - return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, 23); + return tx_ph_data_enqueue_ui(dl, msg, chan_nr, link_id, 23); } /* L3 requests transfer of acknowledged information */ @@ -1580,6 +1614,7 @@ for (i = 0; i < ARRAY_SIZE(le->datalink); i++) { dl = &le->datalink[i]; lapd_dl_reset(&dl->dl); + msgb_queue_free(&dl->tx_ui_queue); } } -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/34987?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I00c8ee73be8b7c564a4dee3fca3e893484f567da Gerrit-Change-Number: 34987 Gerrit-PatchSet: 17 Gerrit-Owner: jolly <andreas(a)eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-MessageType: merged
1 0
0 0
[M] Change in libosmocore[master]: LAPD: Add support for RTS based polling and T200
by laforge 27 Nov '23

27 Nov '23
laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/34985?usp=email ) Change subject: LAPD: Add support for RTS based polling and T200 ...................................................................... LAPD: Add support for RTS based polling and T200 The T200 timer is started when the current frame is polled at PH-READY-TO-SEND event. A flag is used to enable this feature. The user of LAPD core must track frame numbers to check the timeout condition. Then it must call the external timeout function. Related: OS#4074 Change-Id: Ib961b5a44911b99b0487641533301749c0286995 --- M TODO-RELEASE M include/osmocom/isdn/lapd_core.h M src/isdn/lapd_core.c M src/isdn/libosmoisdn.map 4 files changed, 135 insertions(+), 14 deletions(-) Approvals: laforge: Looks good to me, approved Jenkins Builder: Verified daniel: Looks good to me, but someone else must approve diff --git a/TODO-RELEASE b/TODO-RELEASE index b67161d..1d56d45 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -9,3 +9,4 @@ #library what description / commit summary line core ADD osmo_sock_multiaddr_{add,del}_local_addr() core ADD gsmtap_inst_fd2() core, DEPRECATE gsmtap_inst_fd() +isdn ABI change add states and flags for external T200 handling diff --git a/include/osmocom/isdn/lapd_core.h b/include/osmocom/isdn/lapd_core.h index e4e8b46..776d4f4 100644 --- a/include/osmocom/isdn/lapd_core.h +++ b/include/osmocom/isdn/lapd_core.h @@ -84,6 +84,16 @@ LAPD_STATE_TIMER_RECOV, }; +/*! lapd_flags */ +#define LAPD_F_RTS 0x0001 + +/*! LAPD T200 state in RTS mode */ +enum lapd_t200_rts { + LAPD_T200_RTS_OFF = 0, + LAPD_T200_RTS_PENDING, + LAPD_T200_RTS_RUNNING, +}; + /*! LAPD message format (I / S / U) */ enum lapd_format { LAPD_FORM_UKN = 0, @@ -133,6 +143,7 @@ struct lapd_cr_ent rem2loc; } cr; enum lapd_mode mode; /*!< current mode of link */ + unsigned int lapd_flags; /*!< \ref lapd_flags to change processing */ int use_sabme; /*!< use SABME instead of SABM */ int reestablish; /*!< enable reestablish support */ int n200, n200_est_rel; /*!< number of retranmissions */ @@ -149,6 +160,7 @@ uint8_t peer_busy; /*!< receiver busy on remote side */ int t200_sec, t200_usec; /*!< retry timer (default 1 sec) */ int t203_sec, t203_usec; /*!< retry timer (default 10 secs) */ + enum lapd_t200_rts t200_rts; /*!< state of T200 in RTS mode */ struct osmo_timer_list t200; /*!< T200 timer */ struct osmo_timer_list t203; /*!< T203 timer */ uint8_t retrans_ctr; /*!< re-transmission counter */ @@ -169,8 +181,11 @@ void lapd_dl_set_name(struct lapd_datalink *dl, const char *name); void lapd_dl_exit(struct lapd_datalink *dl); void lapd_dl_reset(struct lapd_datalink *dl); +int lapd_dl_set_flags(struct lapd_datalink *dl, unsigned int flags); int lapd_set_mode(struct lapd_datalink *dl, enum lapd_mode mode); int lapd_ph_data_ind(struct msgb *msg, struct lapd_msg_ctx *lctx); +int lapd_ph_rts_ind(struct lapd_msg_ctx *lctx); int lapd_recv_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx); +int lapd_t200_timeout(struct lapd_datalink *dl); /*! @} */ diff --git a/src/isdn/lapd_core.c b/src/isdn/lapd_core.c index 57a0225..34748a4 100644 --- a/src/isdn/lapd_core.c +++ b/src/isdn/lapd_core.c @@ -204,11 +204,35 @@ static void lapd_start_t200(struct lapd_datalink *dl) { - if (osmo_timer_pending(&dl->t200)) - return; - LOGDL(dl, LOGL_INFO, "start T200 (timeout=%d.%06ds)\n", - dl->t200_sec, dl->t200_usec); - osmo_timer_schedule(&dl->t200, dl->t200_sec, dl->t200_usec); + if ((dl->lapd_flags & LAPD_F_RTS)) { + if (dl->t200_rts != LAPD_T200_RTS_OFF) + return; + LOGDL(dl, LOGL_INFO, "Start T200. (pending until triggered by RTS)\n"); + dl->t200_rts = LAPD_T200_RTS_PENDING; + } else { + if (osmo_timer_pending(&dl->t200)) + return; + LOGDL(dl, LOGL_INFO, "Start T200 (timeout=%d.%06ds).\n", dl->t200_sec, dl->t200_usec); + osmo_timer_schedule(&dl->t200, dl->t200_sec, dl->t200_usec); + } +} + +/*! Handle timeout condition of T200 in RTS mode. + * The caller (LAPDm code) implements the T200 timer and must detect timeout condition. + * The function gets called by LAPDm code when it detects a timeout of T200. + * \param[in] dl caller-allocated datalink structure */ +int lapd_t200_timeout(struct lapd_datalink *dl) +{ + OSMO_ASSERT((dl->lapd_flags & LAPD_F_RTS)); + + if (dl->t200_rts != LAPD_T200_RTS_RUNNING) + return -EINVAL; + + dl->t200_rts = LAPD_T200_RTS_OFF; + + lapd_t200_cb(dl); + + return 0; } static void lapd_start_t203(struct lapd_datalink *dl) @@ -221,10 +245,24 @@ static void lapd_stop_t200(struct lapd_datalink *dl) { - if (!osmo_timer_pending(&dl->t200)) - return; + if ((dl->lapd_flags & LAPD_F_RTS)) { + if (dl->t200_rts == LAPD_T200_RTS_OFF) + return; + dl->t200_rts = LAPD_T200_RTS_OFF; + } else { + if (!osmo_timer_pending(&dl->t200)) + return; + osmo_timer_del(&dl->t200); + } LOGDL(dl, LOGL_INFO, "stop T200\n"); - osmo_timer_del(&dl->t200); +} + +static bool lapd_is_t200_started(struct lapd_datalink *dl) +{ + if ((dl->lapd_flags & LAPD_F_RTS)) + return (dl->t200_rts != LAPD_T200_RTS_OFF); + else + return osmo_timer_pending(&dl->t200); } static void lapd_stop_t203(struct lapd_datalink *dl) @@ -359,6 +397,21 @@ lapd_dl_newstate(dl, LAPD_STATE_IDLE); } +/*! Set lapd_flags to change behaviour + * \param[in] dl \ref lapd_datalink instance + * \param[in] flags \ref lapd_flags */ +int lapd_dl_set_flags(struct lapd_datalink *dl, unsigned int flags) +{ + if (lapd_is_t200_started(dl) && (flags & LAPD_F_RTS) != (dl->lapd_flags & LAPD_F_RTS)) { + LOGDL(dl, LOGL_ERROR, "Changing RTS flag not allowed while T200 is running.\n"); + return -EINVAL; + } + + dl->lapd_flags = flags; + + return 0; +} + /* reset and de-allocate history buffer */ void lapd_dl_exit(struct lapd_datalink *dl) { @@ -806,11 +859,8 @@ /* Stop T203, if running */ lapd_stop_t203(dl); /* Start T203, if T200 is not running in MF EST state, if enabled */ - if (!osmo_timer_pending(&dl->t200) - && (dl->t203_sec || dl->t203_usec) - && (dl->state == LAPD_STATE_MF_EST)) { + if (!lapd_is_t200_started(dl) && (dl->t203_sec || dl->t203_usec) && (dl->state == LAPD_STATE_MF_EST)) lapd_start_t203(dl); - } } /* L1 -> L2 */ @@ -1732,6 +1782,31 @@ return rc; } +/*! Enqueue next LAPD frame and run pending T200. (Must be called when frame is ready to send.) + * The caller (LAPDm code) calls this function before it sends the next frame. + * If there is no frame in the TX queue, LAPD will enqueue next I-frame, if possible. + * If the T200 is pending, it is changed to running state. + * \param[in] lctx LAPD context + * \param[out] rc set to 1, if timer T200 state changed to running, set to 0, if not. */ +int lapd_ph_rts_ind(struct lapd_msg_ctx *lctx) +{ + struct lapd_datalink *dl = lctx->dl; + + /* If there is no pending frame, try to enqueue next I frame. */ + if (llist_empty(&dl->tx_queue) && (dl->state == LAPD_STATE_MF_EST || dl->state == LAPD_STATE_TIMER_RECOV)) { + /* Send an I frame, if there are pending outgoing messages. */ + lapd_send_i(dl, __LINE__, true); + } + + /* Run T200 at RTS, if pending. Tell caller that is has been started. (rc = 1) */ + if (dl->t200_rts == LAPD_T200_RTS_PENDING) { + dl->t200_rts = LAPD_T200_RTS_RUNNING; + return 1; + } + + return 0; +} + /* L3 -> L2 */ /* send unit data */ @@ -1861,6 +1936,12 @@ if (!rts) LOGDL(dl, LOGL_INFO, "%s() called from line %d\n", __func__, line); + if ((dl->lapd_flags & LAPD_F_RTS) && !llist_empty(&dl->tx_queue)) { + if (!rts) + LOGDL(dl, LOGL_INFO, "There is a frame in the TX queue, not checking for sending I frame.\n"); + return rc; + } + next_frame: if (dl->peer_busy) { @@ -1978,7 +2059,7 @@ /* If timer T200 is not running at the time right before transmitting a * frame, when the PH-READY-TO-SEND primitive is received from the * physical layer., it shall be set. */ - if (!osmo_timer_pending(&dl->t200)) { + if (!lapd_is_t200_started(dl)) { /* stop Timer T203, if running */ lapd_stop_t203(dl); /* start Timer T200 */ @@ -1987,7 +2068,11 @@ dl->send_ph_data_req(&nctx, msg); - rc = 0; /* we sent something */ + /* When using RTS, we send only one frame. */ + if ((dl->lapd_flags & LAPD_F_RTS)) + return 0; + + rc = 0; /* We sent an I frame, so sending RR frame is not required. */ goto next_frame; } diff --git a/src/isdn/libosmoisdn.map b/src/isdn/libosmoisdn.map index 3269771..c29240b 100644 --- a/src/isdn/libosmoisdn.map +++ b/src/isdn/libosmoisdn.map @@ -7,11 +7,14 @@ lapd_dl_init2; lapd_dl_set_name; lapd_dl_reset; +lapd_dl_set_flags; lapd_msgb_alloc; lapd_ph_data_ind; +lapd_ph_rts_ind; lapd_recv_dlsap; lapd_set_mode; lapd_state_names; +lapd_t200_timeout; osmo_i460_demux_in; osmo_i460_mux_enqueue; -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/34985?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: Ib961b5a44911b99b0487641533301749c0286995 Gerrit-Change-Number: 34985 Gerrit-PatchSet: 10 Gerrit-Owner: jolly <andreas(a)eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[S] Change in libosmocore[master]: LAPDm: Add a flag to enable suppression of subsequent REJ frame
by laforge 27 Nov '23

27 Nov '23
laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/35015?usp=email ) ( 2 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: LAPDm: Add a flag to enable suppression of subsequent REJ frame ...................................................................... LAPDm: Add a flag to enable suppression of subsequent REJ frame This behaviour was default in earlier versions of LAPDm/LAPD. Because it is only required for osmocom-bb, a flag is added to enable it there. Related: OS#5969 Change-Id: I93994dbbd1fc2c9edb8f3015c6b18ecd0fce0565 --- M include/osmocom/gsm/lapdm.h M include/osmocom/isdn/lapd_core.h M src/gsm/lapdm.c M src/isdn/lapd_core.c 4 files changed, 19 insertions(+), 3 deletions(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved fixeria: Looks good to me, but someone else must approve diff --git a/include/osmocom/gsm/lapdm.h b/include/osmocom/gsm/lapdm.h index 08b808c..42ebbce 100644 --- a/include/osmocom/gsm/lapdm.h +++ b/include/osmocom/gsm/lapdm.h @@ -50,6 +50,7 @@ #define LAPDM_ENT_F_EMPTY_FRAME 0x0001 #define LAPDM_ENT_F_POLLING_ONLY 0x0002 +#define LAPDM_ENT_F_DROP_2ND_REJ 0x0004 /*! a LAPDm Entity */ struct lapdm_entity { diff --git a/include/osmocom/isdn/lapd_core.h b/include/osmocom/isdn/lapd_core.h index 776d4f4..1e010af 100644 --- a/include/osmocom/isdn/lapd_core.h +++ b/include/osmocom/isdn/lapd_core.h @@ -86,6 +86,7 @@ /*! lapd_flags */ #define LAPD_F_RTS 0x0001 +#define LAPD_F_DROP_2ND_REJ 0x0002 /*! LAPD T200 state in RTS mode */ enum lapd_t200_rts { diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c index 28644c2..fb892d2 100644 --- a/src/gsm/lapdm.c +++ b/src/gsm/lapdm.c @@ -1637,6 +1637,8 @@ /* Set flags at LAPD. */ if (le->flags & LAPDM_ENT_F_POLLING_ONLY) dl_flags |= LAPD_F_RTS; + if (le->flags & LAPDM_ENT_F_DROP_2ND_REJ) + dl_flags |= LAPD_F_DROP_2ND_REJ; for (i = 0; i < ARRAY_SIZE(le->datalink); i++) { dl = &le->datalink[i]; diff --git a/src/isdn/lapd_core.c b/src/isdn/lapd_core.c index 34748a4..d98edae 100644 --- a/src/isdn/lapd_core.c +++ b/src/isdn/lapd_core.c @@ -1633,9 +1633,8 @@ ns, dl->v_recv, lapd_state_name(dl->state)); /* discard data */ msgb_free(msg); - if (dl->seq_err_cond != 1) { - /* FIXME: help me understand what exactly todo here - */ + /* Send reject, but suppress second reject if LAPD_F_DROP_2ND_REJ flag is set. */ + if (dl->seq_err_cond != 1 || !(dl->lapd_flags & LAPD_F_DROP_2ND_REJ)) { dl->seq_err_cond = 1; lapd_send_rej(lctx, lctx->p_f); } else { -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/35015?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I93994dbbd1fc2c9edb8f3015c6b18ecd0fce0565 Gerrit-Change-Number: 35015 Gerrit-PatchSet: 9 Gerrit-Owner: jolly <andreas(a)eversberg.eu> 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
[S] Change in libosmocore[master]: LAPD: Indicate sequence error after indicating received data
by laforge 27 Nov '23

27 Nov '23
laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/35048?usp=email ) Change subject: LAPD: Indicate sequence error after indicating received data ...................................................................... LAPD: Indicate sequence error after indicating received data First indicated the received data in an I frame, if possible. Then indicate the sequence error using MDL-ERROR-INDICATION. This way the data is delivered before the error is handled by BSC. Also there is no reason to indicate sequence error on supervisory frames. See ยง8.7.4 of 3GPP TS 44.006. Related: OS#5968 Change-Id: I535c18018bf0df4124a5e9618238028fa31be289 --- M src/isdn/lapd_core.c 1 file changed, 34 insertions(+), 5 deletions(-) Approvals: laforge: Looks good to me, approved Jenkins Builder: Verified pespin: Looks good to me, but someone else must approve diff --git a/src/isdn/lapd_core.c b/src/isdn/lapd_core.c index d98edae..b32ed26 100644 --- a/src/isdn/lapd_core.c +++ b/src/isdn/lapd_core.c @@ -796,8 +796,9 @@ lapd_start_t200(dl); } -/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value */ -static void lapd_acknowledge(struct lapd_msg_ctx *lctx) +/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value + * In case of a sequence error, the cause is returned with negative sign. */ +static int lapd_acknowledge(struct lapd_msg_ctx *lctx) { struct lapd_datalink *dl = lctx->dl; uint8_t nr = lctx->n_recv; @@ -838,7 +839,7 @@ */ if (sub_mod(nr, dl->v_ack, dl->v_range) > sub_mod(dl->v_send, dl->v_ack, dl->v_range)) { LOGDL(dl, LOGL_NOTICE, "N(R) sequence error\n"); - mdl_error(MDL_CAUSE_SEQ_ERR, lctx); + return -MDL_CAUSE_SEQ_ERR; } } @@ -861,6 +862,8 @@ /* Start T203, if T200 is not running in MF EST state, if enabled */ if (!lapd_is_t200_started(dl) && (dl->t203_sec || dl->t203_usec) && (dl->state == LAPD_STATE_MF_EST)) lapd_start_t203(dl); + + return 0; } /* L1 -> L2 */ @@ -1576,6 +1579,7 @@ int length = lctx->length; int rc; bool i_frame_in_queue = false; + int mdl_cause = 0; LOGDL(dl, LOGL_INFO, "I received in state %s on SAPI(%u)\n", lapd_state_name(dl->state), lctx->sapi); @@ -1652,7 +1656,9 @@ } /* Even if N(s) sequence error, acknowledge to N(R)-1 */ /* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */ - lapd_acknowledge(lctx); /* V(A) is also set here */ + mdl_cause = lapd_acknowledge(lctx); /* V(A) is also set here */ + if (mdl_cause < 0) + mdl_error(-mdl_cause, lctx); /* Send message, if possible due to acknowledged data */ lapd_send_i(dl, __LINE__, false); @@ -1673,7 +1679,7 @@ } /* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */ - lapd_acknowledge(lctx); /* V(A) is also set here */ + mdl_cause = lapd_acknowledge(lctx); /* V(A) is also set here */ /* Only if we are not in own receiver busy condition */ if (!dl->own_busy) { @@ -1718,6 +1724,10 @@ } else LOGDL(dl, LOGL_INFO, "I frame ignored during own receiver busy condition\n"); + /* Indicate sequence error, if exists. */ + if (mdl_cause < 0) + mdl_error(-mdl_cause, lctx); + /* Check for P bit */ if (lctx->p_f) { /* 5.5.2.1 */ -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/35048?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I535c18018bf0df4124a5e9618238028fa31be289 Gerrit-Change-Number: 35048 Gerrit-PatchSet: 8 Gerrit-Owner: jolly <andreas(a)eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in libosmocore[master]: LAPD: Add support for RTS based polling and T200
by laforge 27 Nov '23

27 Nov '23
Attention is currently required from: jolly, neels. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmocore/+/34985?usp=email ) Change subject: LAPD: Add support for RTS based polling and T200 ...................................................................... Patch Set 9: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/34985?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: Ib961b5a44911b99b0487641533301749c0286995 Gerrit-Change-Number: 34985 Gerrit-PatchSet: 9 Gerrit-Owner: jolly <andreas(a)eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Attention: jolly <andreas(a)eversberg.eu> Gerrit-Attention: neels <nhofmeyr(a)sysmocom.de> Gerrit-Comment-Date: Mon, 27 Nov 2023 16:25:49 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
[S] Change in libosmocore[master]: LAPD: Indicate sequence error after indicating received data
by laforge 27 Nov '23

27 Nov '23
Attention is currently required from: jolly. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmocore/+/35048?usp=email ) Change subject: LAPD: Indicate sequence error after indicating received data ...................................................................... Patch Set 7: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/35048?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I535c18018bf0df4124a5e9618238028fa31be289 Gerrit-Change-Number: 35048 Gerrit-PatchSet: 7 Gerrit-Owner: jolly <andreas(a)eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-Attention: jolly <andreas(a)eversberg.eu> Gerrit-Comment-Date: Mon, 27 Nov 2023 16:25:32 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
[M] Change in libosmocore[master]: LAPDm: Add support for RTS based polling
by laforge 27 Nov '23

27 Nov '23
Attention is currently required from: jolly, neels. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmocore/+/34986?usp=email ) Change subject: LAPDm: Add support for RTS based polling ...................................................................... Patch Set 16: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/34986?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I6ebe83f829d7751ea9de1d90eb478c7a628db64c Gerrit-Change-Number: 34986 Gerrit-PatchSet: 16 Gerrit-Owner: jolly <andreas(a)eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de> Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Attention: jolly <andreas(a)eversberg.eu> Gerrit-Attention: neels <nhofmeyr(a)sysmocom.de> Gerrit-Comment-Date: Mon, 27 Nov 2023 16:25:26 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • ...
  • 151
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.