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 libosmo-gprs[master]: rlcmac: Use enum gprs_rlcmac_radio_priority internally everywhere
by laforge 29 Jul '23

29 Jul '23
laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/33981 ) Change subject: rlcmac: Use enum gprs_rlcmac_radio_priority internally everywhere ...................................................................... rlcmac: Use enum gprs_rlcmac_radio_priority internally everywhere This simplifies the array handling in the LLC queue, and moves param checking to the rx rlcmac_prim path instead of deep in the llc_queue enqueuing code. This commit also fixes the RADIO_PRIORITY field in the Channel Request Description section of PKT DL ACK/NCK, since gprs_rlcmac_llc_queue_highest_radio_prio_pending() now returns the enum normalized 0..3 as expected by the field format (before it was returning 1..4). Change-Id: If2d1946522bc4a1c19d65acb23605f1a3f05ab45 --- M include/osmocom/gprs/rlcmac/gre.h M include/osmocom/gprs/rlcmac/llc_queue.h M src/rlcmac/gre.c M src/rlcmac/llc_queue.c M src/rlcmac/rlcmac_prim.c M tests/rlcmac/rlcmac_prim_test.c M tests/rlcmac/rlcmac_prim_test.err M tests/rlcmac/rlcmac_prim_test.ok 8 files changed, 78 insertions(+), 40 deletions(-) Approvals: Jenkins Builder: Verified osmith: Looks good to me, but someone else must approve laforge: Looks good to me, approved diff --git a/include/osmocom/gprs/rlcmac/gre.h b/include/osmocom/gprs/rlcmac/gre.h index befcf05..a7317cd 100644 --- a/include/osmocom/gprs/rlcmac/gre.h +++ b/include/osmocom/gprs/rlcmac/gre.h @@ -46,8 +46,10 @@ bool gprs_rlcmac_entity_have_tx_data_queued(const struct gprs_rlcmac_entity *gre); int gprs_rlcmac_entity_start_ul_tbf_pkt_acc_proc_if_needed(struct gprs_rlcmac_entity *gre); -int gprs_rlcmac_entity_llc_enqueue(struct gprs_rlcmac_entity *gre, uint8_t *ll_pdu, unsigned int ll_pdu_len, - enum osmo_gprs_rlcmac_llc_sapi sapi, uint8_t radio_prio); +int gprs_rlcmac_entity_llc_enqueue(struct gprs_rlcmac_entity *gre, + const uint8_t *ll_pdu, unsigned int ll_pdu_len, + enum osmo_gprs_rlcmac_llc_sapi sapi, + enum gprs_rlcmac_radio_priority radio_prio); struct msgb *gprs_rlcmac_gre_create_pkt_ctrl_ack(const struct gprs_rlcmac_entity *gre); diff --git a/include/osmocom/gprs/rlcmac/llc_queue.h b/include/osmocom/gprs/rlcmac/llc_queue.h index 331f33b..7149f76 100644 --- a/include/osmocom/gprs/rlcmac/llc_queue.h +++ b/include/osmocom/gprs/rlcmac/llc_queue.h @@ -9,17 +9,14 @@ #include <osmocom/gprs/rlcmac/codel.h> #include <osmocom/gprs/rlcmac/rlcmac_prim.h> -#include <osmocom/gprs/rlcmac/types.h> +#include <osmocom/gprs/rlcmac/types_private.h> #include <osmocom/gprs/rlcmac/rlcmac.h> struct gprs_rlcmac_entity; /* Highet/Lowest radio priority (biggest number) as per 3GPP TS 24.008 version 16.7.0 Release 16 section 10.5.7.2: * "All other values are interpreted as priority level 4 by this version of the protocol." */ -#define _GPRS_RLCMAC_RADIO_PRIO_HIGHEST 1 -#define _GPRS_RLCMAC_RADIO_PRIO_LOWEST 4 -/* Normalize 0..N-1 (to be used in arrays): */ -#define RADIO_PRIO_NORM(radio_prio) ((radio_prio) - _GPRS_RLCMAC_RADIO_PRIO_HIGHEST) +#define _GPRS_RLCMAC_RADIO_NUM_PRIO 4 enum gprs_rlcmac_llc_queue_sapi_prio { /* lowest value has highest prio */ GPRS_RLCMAC_LLC_QUEUE_SAPI_PRIO_GMM = 0, /* SAPI 1 */ @@ -29,7 +26,7 @@ }; struct gprs_llc_prio_queue { - uint8_t radio_prio; /* Radio prio of this queue, range (1..4) */ + enum gprs_rlcmac_radio_priority radio_prio; /* Radio prio of this queue, range (1..4) */ struct gprs_codel codel_state; struct llist_head queue; /* queued LLC DL data. See enum gprs_rlcmac_llc_queue_prio. */ }; @@ -40,7 +37,7 @@ size_t queue_size; size_t queue_octets; bool use_codel; - struct gprs_llc_prio_queue pq[RADIO_PRIO_NORM(_GPRS_RLCMAC_RADIO_PRIO_LOWEST) + 1][_GPRS_RLCMAC_LLC_QUEUE_SAPI_PRIO_SIZE]; /* queued LLC DL data. See enum gprs_rlcmac_llc_queue_prio. */ + struct gprs_llc_prio_queue pq[_GPRS_RLCMAC_RADIO_NUM_PRIO][_GPRS_RLCMAC_LLC_QUEUE_SAPI_PRIO_SIZE]; /* queued LLC DL data. See enum gprs_rlcmac_llc_queue_prio. */ }; struct gprs_rlcmac_llc_queue *gprs_rlcmac_llc_queue_alloc(struct gprs_rlcmac_entity *gre); @@ -49,10 +46,10 @@ void gprs_rlcmac_llc_queue_set_codel_params(struct gprs_rlcmac_llc_queue *q, bool use, unsigned int interval_msec); -int gprs_rlcmac_llc_queue_enqueue(struct gprs_rlcmac_llc_queue *q, uint8_t *ll_pdu, unsigned int ll_pdu_len, - enum osmo_gprs_rlcmac_llc_sapi sapi, uint8_t radio_prio); +int gprs_rlcmac_llc_queue_enqueue(struct gprs_rlcmac_llc_queue *q, const uint8_t *ll_pdu, unsigned int ll_pdu_len, + enum osmo_gprs_rlcmac_llc_sapi sapi, enum gprs_rlcmac_radio_priority radio_prio); struct msgb *gprs_rlcmac_llc_queue_dequeue(struct gprs_rlcmac_llc_queue *q, bool can_discard); -uint8_t gprs_rlcmac_llc_queue_highest_radio_prio_pending(struct gprs_rlcmac_llc_queue *q); +enum gprs_rlcmac_radio_priority gprs_rlcmac_llc_queue_highest_radio_prio_pending(struct gprs_rlcmac_llc_queue *q); void gprs_rlcmac_llc_queue_merge_prepend(struct gprs_rlcmac_llc_queue *q, struct gprs_rlcmac_llc_queue *old_q); diff --git a/src/rlcmac/gre.c b/src/rlcmac/gre.c index 500feed..59cf0f5 100644 --- a/src/rlcmac/gre.c +++ b/src/rlcmac/gre.c @@ -216,17 +216,19 @@ return gprs_rlcmac_tbf_ul_ass_start(gre->ul_tbf, GPRS_RLCMAC_TBF_UL_ASS_TYPE_1PHASE); } -int gprs_rlcmac_entity_llc_enqueue(struct gprs_rlcmac_entity *gre, uint8_t *ll_pdu, unsigned int ll_pdu_len, - enum osmo_gprs_rlcmac_llc_sapi sapi, uint8_t radio_prio) +int gprs_rlcmac_entity_llc_enqueue(struct gprs_rlcmac_entity *gre, + const uint8_t *ll_pdu, unsigned int ll_pdu_len, + enum osmo_gprs_rlcmac_llc_sapi sapi, + enum gprs_rlcmac_radio_priority radio_prio) { int rc; LOGGRE(gre, LOGL_DEBUG, "Enqueueing LLC-PDU len=%u SAPI=%s radio_prio=%u\n", - ll_pdu_len, get_value_string(osmo_gprs_rlcmac_llc_sapi_names, sapi), radio_prio); + ll_pdu_len, get_value_string(osmo_gprs_rlcmac_llc_sapi_names, sapi), radio_prio + 1); rc = gprs_rlcmac_llc_queue_enqueue(gre->llc_queue, ll_pdu, ll_pdu_len, sapi, radio_prio); if (rc < 0) { LOGGRE(gre, LOGL_NOTICE, "Enqueueing LLC-PDU len=%u SAPI=%s radio_prio=%u failed!\n", - ll_pdu_len, get_value_string(osmo_gprs_rlcmac_llc_sapi_names, sapi), radio_prio); + ll_pdu_len, get_value_string(osmo_gprs_rlcmac_llc_sapi_names, sapi), radio_prio + 1); return rc; } diff --git a/src/rlcmac/llc_queue.c b/src/rlcmac/llc_queue.c index 066df47..83c926e 100644 --- a/src/rlcmac/llc_queue.c +++ b/src/rlcmac/llc_queue.c @@ -46,7 +46,7 @@ q->avg_queue_delay = 0; for (i = 0; i < ARRAY_SIZE(q->pq); i++) { for (j = 0; j < ARRAY_SIZE(q->pq[i]); j++) { - q->pq[i][j].radio_prio = i + 1; /* range (1..4) */ + q->pq[i][j].radio_prio = i; /* enum gprs_rlcmac_radio_priority, range (0..3) */ INIT_LLIST_HEAD(&q->pq[i][j].queue); gprs_codel_init(&q->pq[i][j].codel_state); } @@ -89,19 +89,13 @@ } } -int gprs_rlcmac_llc_queue_enqueue(struct gprs_rlcmac_llc_queue *q, uint8_t *ll_pdu, unsigned int ll_pdu_len, - enum osmo_gprs_rlcmac_llc_sapi sapi, uint8_t radio_prio) +int gprs_rlcmac_llc_queue_enqueue(struct gprs_rlcmac_llc_queue *q, const uint8_t *ll_pdu, unsigned int ll_pdu_len, + enum osmo_gprs_rlcmac_llc_sapi sapi, enum gprs_rlcmac_radio_priority radio_prio) { struct llc_queue_entry_hdr *ehdr; enum gprs_rlcmac_llc_queue_sapi_prio sapi_prio; struct msgb *msg; - /* Trim to expected values 1..4, (3GPP TS 24.008) 10.5.7.2 */ - if (radio_prio < _GPRS_RLCMAC_RADIO_PRIO_HIGHEST) - radio_prio = _GPRS_RLCMAC_RADIO_PRIO_HIGHEST; - else if (radio_prio > _GPRS_RLCMAC_RADIO_PRIO_LOWEST) - radio_prio = _GPRS_RLCMAC_RADIO_PRIO_LOWEST; - sapi_prio = gprs_rlcmac_llc_sapi2prio(sapi); msg = msgb_alloc_headroom(sizeof(*ehdr) + ll_pdu_len, 0, "llc_queue_msg"); @@ -117,7 +111,7 @@ msg->l2h = NULL; } - msgb_enqueue(&q->pq[RADIO_PRIO_NORM(radio_prio)][sapi_prio].queue, msg); + msgb_enqueue(&q->pq[radio_prio][sapi_prio].queue, msg); q->queue_size += 1; q->queue_octets += ll_pdu_len; @@ -221,7 +215,7 @@ return msg; } -uint8_t gprs_rlcmac_llc_queue_highest_radio_prio_pending(struct gprs_rlcmac_llc_queue *q) +enum gprs_rlcmac_radio_priority gprs_rlcmac_llc_queue_highest_radio_prio_pending(struct gprs_rlcmac_llc_queue *q) { struct gprs_llc_prio_queue *prioq = gprs_rlcmac_llc_queue_find_msg(q); OSMO_ASSERT(prioq); diff --git a/src/rlcmac/rlcmac_prim.c b/src/rlcmac/rlcmac_prim.c index d3df15f..f13ac3d 100644 --- a/src/rlcmac/rlcmac_prim.c +++ b/src/rlcmac/rlcmac_prim.c @@ -375,6 +375,7 @@ static int rlcmac_prim_handle_grr_unitdata_req(struct osmo_gprs_rlcmac_prim *rlcmac_prim) { struct gprs_rlcmac_entity *gre; + enum gprs_rlcmac_radio_priority radio_prio; int rc; gre = gprs_rlcmac_find_entity_by_tlli(rlcmac_prim->grr.tlli); @@ -385,11 +386,24 @@ } OSMO_ASSERT(gre); + /* Expected values are integers 1..4, trim to known expected radio priorities (3GPP TS 24.008) 10.5.7.2 */ + if (OSMO_UNLIKELY(rlcmac_prim->grr.unitdata_req.radio_prio < 1)) { + LOGGRE(gre, LOGL_NOTICE, "Rx UNITDATA.req with unexpected radio_prio=%u not in range (1..4)\n", + rlcmac_prim->grr.unitdata_req.radio_prio); + radio_prio = GPRS_RLCMAC_RADIO_PRIORITY_1; + } else if (OSMO_UNLIKELY(rlcmac_prim->grr.unitdata_req.radio_prio > 4)) { + LOGGRE(gre, LOGL_NOTICE, "Rx UNITDATA.req with unexpected radio_prio=%u not in range (1..4)\n", + rlcmac_prim->grr.unitdata_req.radio_prio); + radio_prio = GPRS_RLCMAC_RADIO_PRIORITY_4; + } else { + radio_prio = (enum gprs_rlcmac_radio_priority)(rlcmac_prim->grr.unitdata_req.radio_prio - 1); + } + rc = gprs_rlcmac_entity_llc_enqueue(gre, rlcmac_prim->grr.ll_pdu, rlcmac_prim->grr.ll_pdu_len, rlcmac_prim->grr.unitdata_req.sapi, - rlcmac_prim->grr.unitdata_req.radio_prio); + radio_prio); msgb_free(rlcmac_prim->oph.msg); return rc; } diff --git a/tests/rlcmac/rlcmac_prim_test.c b/tests/rlcmac/rlcmac_prim_test.c index 10f148a..410b266 100644 --- a/tests/rlcmac/rlcmac_prim_test.c +++ b/tests/rlcmac/rlcmac_prim_test.c @@ -599,6 +599,7 @@ rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req, sizeof(pdu_llc_gmm_att_req)); rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM; + rlcmac_prim->grr.unitdata_req.radio_prio = 1; rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim); OSMO_ASSERT(sizeof(ccch_imm_ass_pkt_ul_tbf_normal) == GSM_MACBLOCK_LEN); @@ -662,6 +663,7 @@ rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req, 14); rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM; + rlcmac_prim->grr.unitdata_req.radio_prio = 1; rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim); OSMO_ASSERT(sizeof(ccch_imm_ass_pkt_ul_tbf_normal) == GSM_MACBLOCK_LEN); @@ -696,6 +698,7 @@ rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req, 14); rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM; + rlcmac_prim->grr.unitdata_req.radio_prio = 1; rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim); /* Trigger transmission of PKT RES REQ: */ @@ -721,6 +724,7 @@ rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req, sizeof(pdu_llc_gmm_att_req)); rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM; + rlcmac_prim->grr.unitdata_req.radio_prio = 1; rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim); OSMO_ASSERT(sizeof(ccch_imm_ass_pkt_ul_tbf_normal) == GSM_MACBLOCK_LEN); @@ -757,6 +761,7 @@ rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req, sizeof(pdu_llc_gmm_att_req)); rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM; + rlcmac_prim->grr.unitdata_req.radio_prio = 1; rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim); for (i = 0; i < 4; i++) { @@ -806,6 +811,7 @@ rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req, sizeof(pdu_llc_gmm_att_req)); rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM; + rlcmac_prim->grr.unitdata_req.radio_prio = 1; rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim); OSMO_ASSERT(rc == 0); } @@ -853,6 +859,7 @@ rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req, sizeof(pdu_llc_gmm_att_req)); rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM; + rlcmac_prim->grr.unitdata_req.radio_prio = 1; rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim); ccch_imm_ass_pkt_ul_tbf_normal[7] = last_rach_req_ra; /* Update RA to match */ @@ -910,6 +917,7 @@ rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req, sizeof(pdu_llc_gmm_att_req)); rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM; + rlcmac_prim->grr.unitdata_req.radio_prio = 1; rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim); ccch_imm_ass_pkt_ul_tbf_normal[7] = last_rach_req_ra; /* Update RA to match */ @@ -980,6 +988,7 @@ memset(msgb_data(llc_msg), 0xab, msgb_length(llc_msg)); rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, msgb_data(llc_msg), msgb_length(llc_msg)); rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_SNDCP3; + rlcmac_prim->grr.unitdata_req.radio_prio = 2; rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim); ccch_imm_ass_pkt_ul_tbf_normal[7] = last_rach_req_ra; /* Update RA to match */ @@ -1111,6 +1120,7 @@ /* Submit 14 bytes to fit in 1 RLCMAC block to shorten test and end up in FINISHED state quickly: */ rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req, 14); rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM; + rlcmac_prim->grr.unitdata_req.radio_prio = 1; rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim); OSMO_ASSERT(rc == 0); diff --git a/tests/rlcmac/rlcmac_prim_test.err b/tests/rlcmac/rlcmac_prim_test.err index 6b84f2c..913c9da 100644 --- a/tests/rlcmac/rlcmac_prim_test.err +++ b/tests/rlcmac/rlcmac_prim_test.err @@ -1,7 +1,7 @@ DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request DLGLOBAL INFO TLLI=0x00002342 not found, creating entity on the fly DLGLOBAL INFO DL_TBF_ASS{IDLE}: Allocated -DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=0 +DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=1 DLGLOBAL INFO UL_TBF{NEW}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START @@ -76,7 +76,7 @@ DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request DLGLOBAL INFO TLLI=0x00002342 not found, creating entity on the fly DLGLOBAL INFO DL_TBF_ASS{IDLE}: Allocated -DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=0 +DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=1 DLGLOBAL INFO UL_TBF{NEW}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START @@ -181,7 +181,7 @@ DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request DLGLOBAL INFO TLLI=0x00002342 not found, creating entity on the fly DLGLOBAL INFO DL_TBF_ASS{IDLE}: Allocated -DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=0 +DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=1 DLGLOBAL INFO UL_TBF{NEW}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START @@ -335,7 +335,7 @@ DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request DLGLOBAL INFO TLLI=0x00002342 not found, creating entity on the fly DLGLOBAL INFO DL_TBF_ASS{IDLE}: Allocated -DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=0 +DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=1 DLGLOBAL INFO UL_TBF{NEW}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START @@ -345,7 +345,7 @@ DLGLOBAL DEBUG Tx to lower layers: L1CTL-RACH.request DLGLOBAL INFO UL_TBF_ASS{IDLE}: state_chg to WAIT_CCCH_IMM_ASS DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request -DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=0 +DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=1 DLGLOBAL DEBUG Rx from lower layers: L1CTL-CCCH_DATA.indication DLGLOBAL DEBUG Tx to lower layers: L1CTL-PDCH_ESTABLISH.request DLGLOBAL INFO UL_TBF_ASS{WAIT_CCCH_IMM_ASS}: Received Event RX_CCCH_IMM_ASS @@ -511,7 +511,7 @@ DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request DLGLOBAL INFO TLLI=0x00002342 not found, creating entity on the fly DLGLOBAL INFO DL_TBF_ASS{IDLE}: Allocated -DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=0 +DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=1 DLGLOBAL INFO UL_TBF{NEW}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START @@ -579,7 +579,7 @@ DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request DLGLOBAL INFO TLLI=0x00002342 not found, creating entity on the fly DLGLOBAL INFO DL_TBF_ASS{IDLE}: Allocated -DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=0 +DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=33 SAPI=GMM radio_prio=1 DLGLOBAL INFO UL_TBF{NEW}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START @@ -693,7 +693,7 @@ DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request DLGLOBAL INFO TLLI=0x00002342 not found, creating entity on the fly DLGLOBAL INFO DL_TBF_ASS{IDLE}: Allocated -DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=200 SAPI=SNDCP3 radio_prio=0 +DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=200 SAPI=SNDCP3 radio_prio=2 DLGLOBAL INFO UL_TBF{NEW}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START @@ -803,7 +803,7 @@ DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request DLGLOBAL INFO TLLI=0x00002342 not found, creating entity on the fly DLGLOBAL INFO DL_TBF_ASS{IDLE}: Allocated -DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=14 SAPI=GMM radio_prio=0 +DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=14 SAPI=GMM radio_prio=1 DLGLOBAL INFO UL_TBF{NEW}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START @@ -854,7 +854,7 @@ DLGLOBAL INFO UL_TBF{FINISHED}: state_chg to RELEASING DLGLOBAL DEBUG Register POLL (TS=7 FN=17, reason=UL_ACK) DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request -DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=14 SAPI=GMM radio_prio=0 +DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=14 SAPI=GMM radio_prio=1 DLGLOBAL DEBUG Rx from lower layers: L1CTL-PDCH_RTS.indication DLGLOBAL DEBUG (ts=7,fn=17,usf=0) Tx Pkt Resource Request (UL ACK/NACK poll) DLGLOBAL INFO UL_TBF{NEW}: Allocated @@ -947,7 +947,7 @@ DLGLOBAL INFO DL_TBF{FLOW}: state_chg to FINISHED DLGLOBAL DEBUG Register POLL (TS=7 FN=21, reason=DL_ACK) DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request -DLGLOBAL DEBUG GRE(00000001) Enqueueing LLC-PDU len=14 SAPI=GMM radio_prio=0 +DLGLOBAL DEBUG GRE(00000001) Enqueueing LLC-PDU len=14 SAPI=GMM radio_prio=1 DLGLOBAL DEBUG Rx from lower layers: L1CTL-PDCH_RTS.indication DLGLOBAL DEBUG (ts=7,fn=21,usf=0) Tx DL ACK/NACK FinalAck=1 DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) - SSN 1, V(N): "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR" R=Received I=Invalid, FINAL_ACK=1 diff --git a/tests/rlcmac/rlcmac_prim_test.ok b/tests/rlcmac/rlcmac_prim_test.ok index daea0f2..d601794 100644 --- a/tests/rlcmac/rlcmac_prim_test.ok +++ b/tests/rlcmac/rlcmac_prim_test.ok @@ -201,7 +201,7 @@ test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_ESTABLISH.request test_rlcmac_prim_down_cb(): Rx L1CTL-CFG_DL_TBF.request dl_tbf_nr=0 dl_slotmask=0x80 dl_tfi=0 test_rlcmac_prim_up_cb(): Rx GRR-UNITDATA.indication TLLI=0x00000001 ll=[43 c0 01 2b 2b 2b ] -test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=21 ts=7 data_len=23 data=[40 08 10 20 00 00 00 00 00 00 00 30 40 00 00 00 00 03 2b 2b 2b 2b 2b ] +test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=21 ts=7 data_len=23 data=[40 08 10 20 00 00 00 00 00 00 00 30 00 00 00 00 00 03 2b 2b 2b 2b 2b ] test_rlcmac_prim_down_cb(): Rx L1CTL-CFG_UL_TBF.request ul_tbf_nr=0 ul_slotmask=0xc0 test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=43 ts=7 data_len=23 data=[40 04 00 00 00 04 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b ] test_rlcmac_prim_up_cb(): Rx GMMRR-LLC_TRANSMITTED.indication TLLI=0x00000001 -- To view, visit https://gerrit.osmocom.org/c/libosmo-gprs/+/33981 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-gprs Gerrit-Branch: master Gerrit-Change-Id: If2d1946522bc4a1c19d65acb23605f1a3f05ab45 Gerrit-Change-Number: 33981 Gerrit-PatchSet: 3 Gerrit-Owner: pespin <pespin(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[L] Change in libosmo-gprs[master]: sm: Introduce APIs to enc/dec QoS Profile
by laforge 29 Jul '23

29 Jul '23
laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/33970 ) Change subject: sm: Introduce APIs to enc/dec QoS Profile ...................................................................... sm: Introduce APIs to enc/dec QoS Profile Ported from open5gs.git/lib/gtp/v1/types.{c,h} 5764f7267d16a8ea6aeedc6c227552575915def5, for which I was the author too. The ARP extra byte field at the start of the IE val which is introduced in the GTP variant is dropped when porting to SM, since it's not present there (and offsets/sizes are adjusted). The QoS code is moved is moved into a common/ directory where a new libosmo-gprs-common.la private static library is created. This is done in order to be able to resuse the QoS dec/enc code in several libraries since it's actually planned to use it in SNDCP and SM layers. The most natural place to add the APIs is SM, and that's where the public API to accees the enc/dec is provided, since the user app will have to use them in the SM SAP. However, the SNDCP will also have to decode the QoS recived by SM through the SNSM SAP, and we don't really want libosmo-gprs-sndcp depend on libosmo-gprs-sm. This way libosmo-gprs-sndcp will be able to use the private APIs directly in a follow-up commit. Change-Id: I6c0676e55bb1f0f424f41d8d04d4f5e5bf376f4f --- M configure.ac M include/osmocom/gprs/sm/Makefile.am M include/osmocom/gprs/sm/sm.h A include/osmocom/gprs/sm/sm_qos.h M src/Makefile.am A src/common/Makefile.am A src/common/qos.c A src/common/qos.h M src/sm/Makefile.am A src/sm/sm_qos.c 10 files changed, 503 insertions(+), 4 deletions(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved diff --git a/configure.ac b/configure.ac index 52b9d14..91fb36a 100644 --- a/configure.ac +++ b/configure.ac @@ -90,6 +90,7 @@ include/osmocom/gprs/sndcp/Makefile include/osmocom/gprs/sm/Makefile src/Makefile + src/common/Makefile src/csn1/Makefile src/gmm/Makefile src/llc/Makefile diff --git a/include/osmocom/gprs/sm/Makefile.am b/include/osmocom/gprs/sm/Makefile.am index 46a30cb..f6bede4 100644 --- a/include/osmocom/gprs/sm/Makefile.am +++ b/include/osmocom/gprs/sm/Makefile.am @@ -8,6 +8,7 @@ sm_HEADERS = \ sm.h \ sm_prim.h \ + sm_qos.h \ $(NULL) smdir = $(includedir)/osmocom/gprs/sm diff --git a/include/osmocom/gprs/sm/sm.h b/include/osmocom/gprs/sm/sm.h index 37f86bc..089faa1 100644 --- a/include/osmocom/gprs/sm/sm.h +++ b/include/osmocom/gprs/sm/sm.h @@ -5,6 +5,8 @@ #include <stdint.h> #include <stddef.h> +#include <osmocom/gprs/sm/sm_qos.h> + /* 3GPP TS 24.008 10.5.6.1 */ #define OSMO_GPRS_SM_APN_MAXLEN 100 @@ -14,9 +16,6 @@ /* 3GPP TS 24.008 10.5.6.3 Protocol configuration options */ #define OSMO_GPRS_SM_PCO_MAXLEN 253 -/* 3GPP TS 24.008 10.5.6.5 Quality of service */ -#define OSMO_GPRS_SM_QOS_MAXLEN 22 - /* 3GPP TS 24.008 10.5.6.21 NBIFOM container (T=1,L=1,V=255 => 257) */ #define OSMO_GPRS_SM_MBIFORM_MAXLEN 255 diff --git a/include/osmocom/gprs/sm/sm_qos.h b/include/osmocom/gprs/sm/sm_qos.h new file mode 100644 index 0000000..a1ffe63 --- /dev/null +++ b/include/osmocom/gprs/sm/sm_qos.h @@ -0,0 +1,96 @@ +/* GPRS QoS definitions from 3GPP TS 24.008 sec 10.5.6.5 */ +#pragma once + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> +#include <osmocom/core/endian.h> + +/* 3GPP TS 24.008 10.5.6.5 Quality of service */ +#define OSMO_GPRS_SM_QOS_MAXLEN 22 + +/* TS 24.008 10.5.6.5 Quality of service */ +struct osmo_gprs_sm_qos_profile_data_extended_bit_rate { + uint8_t max_bit_rate_uplink; + uint8_t guaranteed_bit_rate_uplink; + uint8_t max_bit_rate_downlink; + uint8_t guaranteed_bit_rate_downlink; +} __attribute__ ((packed)); + +struct osmo_gprs_sm_qos_profile_data { +#if OSMO_IS_LITTLE_ENDIAN + uint8_t reliability_class:3, + delay_class:2, + spare1:3; + uint8_t precedence_class:3, + spare2:1, + peak_throughput:4; + uint8_t mean_throughput:5, + spare3:3; + uint8_t delivery_erroneous_sdu:3, + delivery_order:2, + traffic_class:3; + uint8_t max_sdu_size; + uint8_t max_bit_rate_uplink; + uint8_t max_bit_rate_downlink; + uint8_t sdu_error_ratio:4, + residual_ber:4; + uint8_t traffic_handling_priority:2, + transfer_delay:6; + uint8_t guaranteed_bit_rate_uplink; + uint8_t guaranteed_bit_rate_downlink; + uint8_t source_statistics_descriptor:4, + signalling_indication:1, + spare4:3; + struct osmo_gprs_sm_qos_profile_data_extended_bit_rate extended; + struct osmo_gprs_sm_qos_profile_data_extended_bit_rate extended2; +#elif OSMO_IS_BIG_ENDIAN +/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */ + uint8_t spare1:3, delay_class:2, reliability_class:3; + uint8_t peak_throughput:4, spare2:1, precedence_class:3; + uint8_t spare3:3, mean_throughput:5; + uint8_t traffic_class:3, delivery_order:2, delivery_erroneous_sdu:3; + uint8_t max_sdu_size; + uint8_t max_bit_rate_uplink; + uint8_t max_bit_rate_downlink; + uint8_t residual_ber:4, sdu_error_ratio:4; + uint8_t transfer_delay:6, traffic_handling_priority:2; + uint8_t guaranteed_bit_rate_uplink; + uint8_t guaranteed_bit_rate_downlink; + uint8_t spare4:3, signalling_indication:1, source_statistics_descriptor:4; + struct osmo_gprs_sm_qos_profile_data_extended_bit_rate extended; + struct osmo_gprs_sm_qos_profile_data_extended_bit_rate extended2; +#endif +} __attribute__ ((packed)); + +struct osmo_gprs_sm_qos_profile { + struct osmo_gprs_sm_qos_profile_data data; +} __attribute__ ((packed)); +struct osmo_gprs_sm_qos_profile_decoded { + struct osmo_gprs_sm_qos_profile qos_profile; + /* Filled in by the decoder function: */ + bool data_octet6_to_13_present; /* from traffic_class to guaranteed_bit_rate_downlink */ + bool data_octet14_present; /* byte containing signalling_indication */ + bool bit_rate_downlink_extended_present; + bool bit_rate_uplink_extended_present; + bool bit_rate_downlink_extended2_present; + bool bit_rate_uplink_extended2_present; + uint16_t dec_transfer_delay; + uint32_t dec_mbr_kbps_dl; /* decoded MBR in kbps */ + uint32_t dec_mbr_kbps_ul; /* decoded MBR in kbps */ + uint32_t dec_gbr_kbps_dl; /* decoded GBR in kbps */ + uint32_t dec_gbr_kbps_ul; /* decoded GBR in kbps */ +} __attribute__ ((packed)); + +#define OSMO_GPRS_SM_QOS_TRAFFIC_CLASS_SUBSCRIBED 0 +#define OSMO_GPRS_SM_QOS_TRAFFIC_CLASS_CONVERSATIONAL 1 +#define OSMO_GPRS_SM_QOS_TRAFFIC_CLASS_STREAMING 2 +#define OSMO_GPRS_SM_QOS_TRAFFIC_CLASS_INTERACTIVE 3 +#define OSMO_GPRS_SM_QOS_TRAFFIC_CLASS_BACKGROUND 4 + +#define OSMO_GPRS_SM_QOS_SRC_STATS_DESC_UNKNOWN 0 +#define OSMO_GPRS_SM_QOS_SRC_STATS_DESC_SPEECH 1 + +int16_t osmo_gprs_sm_qos_parse_qos_profile( + struct osmo_gprs_sm_qos_profile_decoded *decoded, const uint8_t *data, size_t data_len); +int16_t osmo_gprs_sm_qos_build_qos_profile(const struct osmo_gprs_sm_qos_profile_decoded *decoded, void *data, int data_len); diff --git a/src/Makefile.am b/src/Makefile.am index 69ce5a0..90d901f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,5 @@ SUBDIRS = \ + common \ csn1 \ llc \ rlcmac \ diff --git a/src/common/Makefile.am b/src/common/Makefile.am new file mode 100644 index 0000000..ae7c2bd --- /dev/null +++ b/src/common/Makefile.am @@ -0,0 +1,22 @@ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(NULL) + +noinst_LTLIBRARIES = \ + libosmo-gprs-common.la \ + $(NULL) + +libosmo_gprs_common_la_SOURCES = \ + qos.c \ + $(NULL) + +noinst_HEADERS = \ + qos.h \ + $(NULL) diff --git a/src/common/qos.c b/src/common/qos.c new file mode 100644 index 0000000..3de532f --- /dev/null +++ b/src/common/qos.c @@ -0,0 +1,303 @@ +/* GPRS QoS definitions from 3GPP TS 24.008 sec 10.5.6.5 */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <osmocom/core/utils.h> +#include <osmocom/core/logging.h> +#include "qos.h" + +#define GPRS_QOS_FALLTHROUGH __attribute__ ((fallthrough)) + +static uint32_t dec_mbr_kbps(uint8_t mbr_byte, const uint8_t *extended_mbr_byte, const uint8_t *extended2_mbr_byte) +{ + uint8_t mbr, embr1, embr2; + mbr = mbr_byte; + embr1 = extended_mbr_byte ? *extended_mbr_byte : 0; + embr2 = extended2_mbr_byte ? *extended2_mbr_byte : 0; + + if (mbr == 0) + return 0; + if (mbr == 0xff) + return UINT32_MAX; + if (mbr == 0xfe) { /* Check extended field */ + if (extended_mbr_byte == NULL || embr1 == 0) + return 8640; + if (embr1 == 0xfa) { /* Check extended2 field */ + if (extended2_mbr_byte == NULL || embr2 == 0) + return 256 * 1000; + if (embr2 == 0xf6) + return 10 * 1000 * 1000; /* TODO: check "extended quality of service" IE */ + if (embr2 >= 0xa2 && embr2 <= 0xf6) + return (1500 + (embr2 - (0xa2 - 1)) * 100) * 1000; + if (embr2 >= 0x3e && embr2 <= 0xa1) + return (500 + (embr2 - (0x3e - 1)) * 10) * 1000; + return (256 + embr2 * 4) * 1000; + } + if (embr1 >= 0xbb && embr1 <= 0xfa) + return (128 + (embr1 - (0xbb - 1)) * 2) * 1000; + if (embr1 >= 0x4b && embr1 <= 0xba) + return (16 + (embr1 - (0x4b - 1)) * 1) * 1000; + return 8600 + embr1 * 100; + } + if (mbr & 0x80) { + mbr &= ~0x80; + return 576 + mbr_byte * 64; + } + if (mbr & 0x40) { + mbr &= ~0x40; + return 64 + mbr * 8; + } + return mbr; +} + +static uint16_t dec_transfer_delay_ms(uint8_t transfer_delay_byte) +{ + transfer_delay_byte &= 0x3f; /* 6 bits */ + if (transfer_delay_byte <= 0x0f) + return transfer_delay_byte; + if (transfer_delay_byte <= 0x1f) + return 200 + (transfer_delay_byte - 0x10) * 50; + return 1000 + (transfer_delay_byte - 0x20) * 100; +} + +/* TS 29.060 7.7.34 Quality of Service (QoS) Profile */ +/* TS 24.008 10.5.6.5 Quality of service */ +int16_t gprs_qos_parse_qos_profile( + struct osmo_gprs_sm_qos_profile_decoded *decoded, const uint8_t *data, size_t data_len) +{ + struct osmo_gprs_sm_qos_profile *source = (struct osmo_gprs_sm_qos_profile *)data; + + OSMO_ASSERT(decoded); + OSMO_ASSERT(data); + + memset(decoded, 0, sizeof(struct osmo_gprs_sm_qos_profile_decoded)); + switch (data_len) { + case 20: /* octet 3 + octet 3-22 */ + decoded->bit_rate_uplink_extended2_present = true; + GPRS_QOS_FALLTHROUGH; + case 18: /* octet 3 + octet 3-20 */ + decoded->bit_rate_downlink_extended2_present = true; + GPRS_QOS_FALLTHROUGH; + case 16: /* octet 3 + octet 3-18 */ + decoded->bit_rate_uplink_extended_present = true; + GPRS_QOS_FALLTHROUGH; + case 14: /* octet 3 + octet 3-16 */ + decoded->bit_rate_downlink_extended_present = true; + GPRS_QOS_FALLTHROUGH; + case 12: /* octet 3-14 */ + decoded->data_octet14_present = true; + GPRS_QOS_FALLTHROUGH; + case 11: /* octet 3-13 */ + decoded->data_octet6_to_13_present = true; + GPRS_QOS_FALLTHROUGH; + case 3: /* octet 3 + octet 4 + octet 5 */ + break; + default: + LOGP(DLGLOBAL, LOGL_ERROR, "Qos Profile wrong length %zu\n", data_len); + return -1; + } + memcpy(&decoded->qos_profile, source, data_len); + + /* Calculate resulting MBRs in kbps: */ + if (decoded->data_octet6_to_13_present) { + decoded->dec_transfer_delay = dec_transfer_delay_ms(source->data.transfer_delay); + decoded->dec_mbr_kbps_dl = dec_mbr_kbps(source->data.max_bit_rate_downlink, + decoded->bit_rate_downlink_extended_present ? + &source->data.extended.max_bit_rate_downlink : NULL, + decoded->bit_rate_downlink_extended2_present ? + &source->data.extended2.max_bit_rate_downlink : NULL); + decoded->dec_mbr_kbps_ul = dec_mbr_kbps(source->data.max_bit_rate_uplink, + decoded->bit_rate_uplink_extended_present ? + &source->data.extended.max_bit_rate_uplink : NULL, + decoded->bit_rate_uplink_extended2_present ? + &source->data.extended2.max_bit_rate_uplink : NULL); + /* GBR is encoded the same way as MBR: */ + decoded->dec_gbr_kbps_dl = dec_mbr_kbps(source->data.guaranteed_bit_rate_downlink, + decoded->bit_rate_downlink_extended_present ? + &source->data.extended.guaranteed_bit_rate_downlink : NULL, + decoded->bit_rate_downlink_extended2_present ? + &source->data.extended2.guaranteed_bit_rate_downlink : NULL); + decoded->dec_gbr_kbps_ul = dec_mbr_kbps(source->data.guaranteed_bit_rate_uplink, + decoded->bit_rate_uplink_extended_present ? + &source->data.extended.guaranteed_bit_rate_uplink : NULL, + decoded->bit_rate_uplink_extended2_present ? + &source->data.extended2.guaranteed_bit_rate_uplink : NULL); + } + + return data_len; +} + +static uint8_t enc_transfer_delay_ms(uint16_t transfer_delay_ms) +{ + if (transfer_delay_ms >= 4000) + return 0x3e; + if (transfer_delay_ms >= 1000) { + transfer_delay_ms -= 1000; + return 0x20 + (transfer_delay_ms / 100); + } + if (transfer_delay_ms >= 200) { + transfer_delay_ms -= 200; + return 0x10 + (transfer_delay_ms / 50); + } + if (transfer_delay_ms > 150) + transfer_delay_ms = 150; + if (transfer_delay_ms >= 10) + return transfer_delay_ms / 10; + return 1; /* 0 is "Reserved" Network->MS */ +} + +#define CHECK_EXT1 0xfe +#define CHECK_EXT2 0xfa +static uint32_t enc_mbr_kbps(uint32_t mbr_kbps, uint8_t *mbr_byte, uint8_t *extended_mbr_byte, uint8_t *extended2_mbr_byte) +{ + /* up to EXT2 byte: */ + if (mbr_kbps > 10*1000*1000) { + *extended2_mbr_byte = 0xf6; /* TODO: need to set the real value somewhere else */ + goto ret_check_ext2; + } + if (mbr_kbps >= 1600*1000) { + mbr_kbps -= 1500*1000; + *extended2_mbr_byte = 0xa1 + mbr_kbps/(100*1000); + goto ret_check_ext2; + } + if (mbr_kbps >= 510*1000) { + mbr_kbps -= 500*1000; + *extended2_mbr_byte = 0x2d + mbr_kbps/(10*1000); + goto ret_check_ext2; + } + if (mbr_kbps >= 260*1000) { + mbr_kbps -= 256*1000; + *extended2_mbr_byte = 0x00 + mbr_kbps/(4*1000); + goto ret_check_ext2; + } + + /* up to EXT1 byte: */ + if (mbr_kbps >= 130*1000) { + mbr_kbps -= 128*1000; + *extended_mbr_byte = 0xba + mbr_kbps/(2*1000); + goto ret_check_ext1; + } + if (mbr_kbps >= 17*1000) { + mbr_kbps -= 16*1000; + *extended_mbr_byte = 0x4a + mbr_kbps/(1*1000); + goto ret_check_ext1; + } + if (mbr_kbps >= 8700) { + mbr_kbps -= 8600; + *extended_mbr_byte = 0x00 + mbr_kbps/(100); + goto ret_check_ext1; + } + + /* Only MBR byte: */ + if (mbr_kbps >= 576) { + mbr_kbps -= 576; + *mbr_byte = 0x80 + mbr_kbps/(64); + goto ret_mbr; + } + if (mbr_kbps >= 64) { + mbr_kbps -= 64; + *mbr_byte = 0x40 + mbr_kbps/(8); + goto ret_mbr; + } + if (mbr_kbps > 0) { + *mbr_byte = mbr_kbps; + goto ret_mbr; + } + /* if (mbr_kpbs == 0) */ + *mbr_byte = 0xff; + goto ret_mbr; + +ret_check_ext2: + *extended_mbr_byte = CHECK_EXT2; + *mbr_byte = CHECK_EXT1; + return 2; +ret_check_ext1: + *extended2_mbr_byte = 0; + *mbr_byte = CHECK_EXT1; + return 1; +ret_mbr: + *extended2_mbr_byte = 0; + *extended_mbr_byte = 0; + return 0; +} + +int16_t gprs_qos_build_qos_profile(const struct osmo_gprs_sm_qos_profile_decoded *decoded, void *data, int data_len) +{ + struct osmo_gprs_sm_qos_profile *target; + int mbr_extended_dl, mbr_extended_ul; + int gbr_extended_dl, gbr_extended_ul; + int extended_dl, extended_ul; + unsigned int enc_len = 0; + + OSMO_ASSERT(decoded); + OSMO_ASSERT(data); + OSMO_ASSERT((size_t)data_len >= sizeof(struct osmo_gprs_sm_qos_profile)); + + target = (struct osmo_gprs_sm_qos_profile *)data; + + /* First, copy the encoded buffer as it is: */ + memcpy(target, &decoded->qos_profile, sizeof(struct osmo_gprs_sm_qos_profile)); + + /* Avoid setting Traffic Handling to 0=Reserved even if ignored based on + * Interactive/Background Traffic Class: */ + if (target->data.traffic_handling_priority == 0) + target->data.traffic_handling_priority = 1; + + /* Then, encode in the target position the decoded-provided fields: */ + if (decoded->data_octet6_to_13_present) + target->data.transfer_delay = enc_transfer_delay_ms(decoded->dec_transfer_delay); + + mbr_extended_dl = enc_mbr_kbps(decoded->dec_mbr_kbps_dl, + &target->data.max_bit_rate_downlink, + &target->data.extended.max_bit_rate_downlink, + &target->data.extended2.max_bit_rate_downlink); + mbr_extended_ul = enc_mbr_kbps(decoded->dec_mbr_kbps_ul, + &target->data.max_bit_rate_uplink, + &target->data.extended.max_bit_rate_uplink, + &target->data.extended2.max_bit_rate_uplink); + /* GBR is encoded the same way as MBR: */ + gbr_extended_dl = enc_mbr_kbps(decoded->dec_gbr_kbps_dl, + &target->data.guaranteed_bit_rate_downlink, + &target->data.extended.guaranteed_bit_rate_downlink, + &target->data.extended2.guaranteed_bit_rate_downlink); + gbr_extended_ul = enc_mbr_kbps(decoded->dec_gbr_kbps_ul, + &target->data.guaranteed_bit_rate_uplink, + &target->data.extended.guaranteed_bit_rate_uplink, + &target->data.extended2.guaranteed_bit_rate_uplink); + extended_dl = OSMO_MAX(mbr_extended_dl, gbr_extended_dl); + extended_ul = OSMO_MAX(mbr_extended_ul, gbr_extended_ul); + + /* Finally, set len based on the required octets to encode the fields: */ + if (extended_ul == 2) + enc_len = 20; + else if (extended_dl == 2) + enc_len = 18; + else if (extended_ul == 1) + enc_len = 16; + else if (extended_dl == 1) + enc_len = 14; + else if (decoded->data_octet14_present) + enc_len = 12; + else if (decoded->data_octet6_to_13_present) + enc_len = 11; + else + enc_len = 5; + return enc_len; +} diff --git a/src/common/qos.h b/src/common/qos.h new file mode 100644 index 0000000..3ddbacc --- /dev/null +++ b/src/common/qos.h @@ -0,0 +1,12 @@ +/* GPRS QoS definitions from 3GPP TS 24.008 sec 10.5.6.5 */ +#pragma once + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> + +#include <osmocom/gprs/sm/sm_qos.h> + +int16_t gprs_qos_parse_qos_profile( + struct osmo_gprs_sm_qos_profile_decoded *decoded, const uint8_t *data, size_t data_len); +int16_t gprs_qos_build_qos_profile(const struct osmo_gprs_sm_qos_profile_decoded *decoded, void *data, int data_len); diff --git a/src/sm/Makefile.am b/src/sm/Makefile.am index ecd8ba3..83b19de 100644 --- a/src/sm/Makefile.am +++ b/src/sm/Makefile.am @@ -23,6 +23,7 @@ sm_ms_fsm.c \ sm_pdu.c \ sm_prim.c \ + sm_qos.c \ misc.c \ $(NULL) @@ -35,7 +36,8 @@ libosmo_gprs_sm_la_LIBADD = \ $(top_builddir)/src/gmm/libosmo-gprs-gmm.la \ $(top_builddir)/src/sndcp/libosmo-gprs-sndcp.la \ - $(LIBOSMOCORE_LIBS) \ + $(top_builddir)/src/common/libosmo-gprs-common.la \ $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCORE_LIBS) \ -lm \ $(NULL) diff --git a/src/sm/sm_qos.c b/src/sm/sm_qos.c new file mode 100644 index 0000000..504c2a2 --- /dev/null +++ b/src/sm/sm_qos.c @@ -0,0 +1,34 @@ +/* GPRS QoS definitions from 3GPP TS 24.008 sec 10.5.6.5 */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <osmocom/gprs/sm/sm_qos.h> +#include "../common/qos.h" + +int16_t osmo_gprs_sm_qos_parse_qos_profile( + struct osmo_gprs_sm_qos_profile_decoded *decoded, const uint8_t *data, size_t data_len) +{ + return gprs_qos_parse_qos_profile(decoded, data, data_len); +} + +int16_t osmo_gprs_sm_qos_build_qos_profile(const struct osmo_gprs_sm_qos_profile_decoded *decoded, void *data, int data_len) +{ + return gprs_qos_build_qos_profile(decoded, data, data_len); +} -- To view, visit https://gerrit.osmocom.org/c/libosmo-gprs/+/33970 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-gprs Gerrit-Branch: master Gerrit-Change-Id: I6c0676e55bb1f0f424f41d8d04d4f5e5bf376f4f Gerrit-Change-Number: 33970 Gerrit-PatchSet: 2 Gerrit-Owner: pespin <pespin(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in libosmo-gprs[master]: rlcmac: Use enum gprs_rlcmac_radio_priority internally everywhere
by laforge 29 Jul '23

29 Jul '23
Attention is currently required from: pespin. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/33981 ) Change subject: rlcmac: Use enum gprs_rlcmac_radio_priority internally everywhere ...................................................................... Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/c/libosmo-gprs/+/33981 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-gprs Gerrit-Branch: master Gerrit-Change-Id: If2d1946522bc4a1c19d65acb23605f1a3f05ab45 Gerrit-Change-Number: 33981 Gerrit-PatchSet: 3 Gerrit-Owner: pespin <pespin(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-Attention: pespin <pespin(a)sysmocom.de> Gerrit-Comment-Date: Sat, 29 Jul 2023 08:40:50 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
[M] Change in libosmo-gprs[master]: sndcp: Forward QoS params from SM to LLC
by laforge 29 Jul '23

29 Jul '23
Attention is currently required from: pespin. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/33971 ) Change subject: sndcp: Forward QoS params from SM to LLC ...................................................................... Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/c/libosmo-gprs/+/33971 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-gprs Gerrit-Branch: master Gerrit-Change-Id: I70e355ef27d24bdaf00e54f0e7126193f5bbf19f Gerrit-Change-Number: 33971 Gerrit-PatchSet: 2 Gerrit-Owner: pespin <pespin(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-Attention: pespin <pespin(a)sysmocom.de> Gerrit-Comment-Date: Sat, 29 Jul 2023 08:40:28 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
[L] Change in libosmo-gprs[master]: sm: Introduce APIs to enc/dec QoS Profile
by laforge 29 Jul '23

29 Jul '23
Attention is currently required from: osmith, pespin. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/33970 ) Change subject: sm: Introduce APIs to enc/dec QoS Profile ...................................................................... Patch Set 2: Code-Review+2 (1 comment) Patchset: PS1: > Regarding endianness, should we disable the check? it will keep on failing in all future patches if […] I think it's safe to disable the check and then subsequently at low priority submit patches to the various projects to remove the related generated code. -- To view, visit https://gerrit.osmocom.org/c/libosmo-gprs/+/33970 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-gprs Gerrit-Branch: master Gerrit-Change-Id: I6c0676e55bb1f0f424f41d8d04d4f5e5bf376f4f Gerrit-Change-Number: 33970 Gerrit-PatchSet: 2 Gerrit-Owner: pespin <pespin(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: osmith <osmith(a)sysmocom.de> Gerrit-Attention: osmith <osmith(a)sysmocom.de> Gerrit-Attention: pespin <pespin(a)sysmocom.de> Gerrit-Comment-Date: Sat, 29 Jul 2023 08:40:15 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Comment-In-Reply-To: osmith <osmith(a)sysmocom.de> Gerrit-MessageType: comment
1 0
0 0
[S] Change in osmo-pcu[master]: cosmetic: Document foce_two_phase feature based on specs
by laforge 29 Jul '23

29 Jul '23
laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-pcu/+/34006 ) Change subject: cosmetic: Document foce_two_phase feature based on specs ...................................................................... cosmetic: Document foce_two_phase feature based on specs Change-Id: I4f8e3d0dcb721d51838b50aba5b40d0551c8d0c5 --- M src/bts.cpp 1 file changed, 15 insertions(+), 0 deletions(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved diff --git a/src/bts.cpp b/src/bts.cpp index 177544a..fe48018 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -970,6 +970,12 @@ LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single TS uplink transmission " "(one phase packet access)\n"); if (bts->pcu->vty.force_two_phase) { + /* 3GPP TS 44.018 3.5.2.1.3.1: "If the establishment cause in the + * CHANNEL REQUEST message indicates a request for one phase packet access, + * the network may grant either a one phase packet access or a single block + * packet access for the mobile station. If a single block packet access is + * granted, it forces the mobile station to perform a two phase packet access." + */ LOGP(DRLCMAC, LOGL_DEBUG, "Forcing two phase access\n"); chan_req.single_block = true; } -- To view, visit https://gerrit.osmocom.org/c/osmo-pcu/+/34006 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Change-Id: I4f8e3d0dcb721d51838b50aba5b40d0551c8d0c5 Gerrit-Change-Number: 34006 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pespin(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-MessageType: merged
1 0
0 0
[S] Change in osmo-pcu[master]: cosmetic: Document foce_two_phase feature based on specs
by laforge 29 Jul '23

29 Jul '23
Attention is currently required from: pespin. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-pcu/+/34006 ) Change subject: cosmetic: Document foce_two_phase feature based on specs ...................................................................... Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/c/osmo-pcu/+/34006 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Change-Id: I4f8e3d0dcb721d51838b50aba5b40d0551c8d0c5 Gerrit-Change-Number: 34006 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pespin(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Attention: pespin <pespin(a)sysmocom.de> Gerrit-Comment-Date: Sat, 29 Jul 2023 08:38:40 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1 0
0 0
[S] Change in osmo-tetra[master]: Fixed makefile to also clean crypto subdirectory
by laforge 29 Jul '23

29 Jul '23
laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-tetra/+/33996 ) Change subject: Fixed makefile to also clean crypto subdirectory ...................................................................... Fixed makefile to also clean crypto subdirectory Change-Id: Ib2a404edece89d26d5369f4ff2ad7510611cac08 --- M src/Makefile 1 file changed, 10 insertions(+), 1 deletion(-) Approvals: Jenkins Builder: Verified pespin: Looks good to me, but someone else must approve laforge: Looks good to me, approved diff --git a/src/Makefile b/src/Makefile index 9b12484..b424ea4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -30,4 +30,4 @@ tunctl: tunctl.o clean: - @rm -f tunctl float_to_bits crc_test tetra-rx conv_enc_test *.o phy/*.o lower_mac/*.o *.a + @rm -f tunctl float_to_bits crc_test tetra-rx conv_enc_test *.o phy/*.o lower_mac/*.o crypto/*.o *.a -- To view, visit https://gerrit.osmocom.org/c/osmo-tetra/+/33996 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-tetra Gerrit-Branch: master Gerrit-Change-Id: Ib2a404edece89d26d5369f4ff2ad7510611cac08 Gerrit-Change-Number: 33996 Gerrit-PatchSet: 1 Gerrit-Owner: wbokslag <w.bokslag(a)midnightblue.nl> 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 osmo-tetra[master]: Added stub for decryption and full keystream application functions
by laforge 29 Jul '23

29 Jul '23
Attention is currently required from: wbokslag. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-tetra/+/34001 ) Change subject: Added stub for decryption and full keystream application functions ...................................................................... Patch Set 2: (2 comments) File src/crypto/tetra_crypto.c: https://gerrit.osmocom.org/c/osmo-tetra/+/34001/comment/87f12f9f_714dba42 PS2, Line 207: case KSG_TEA1: : tea1_stub(iv, eck, num_bytes, ks_bytes); : break; : case KSG_TEA2: : tea2_stub(iv, eck, num_bytes, ks_bytes); : break; : case KSG_TEA3: : tea3_stub(iv, eck, num_bytes, ks_bytes); : break; I think it's a bit weird to add the stub functions that don't do anything in a commit here. This leads to situations that if somebody calls the function now, it returns success (true) despite not having generated the keystream. I think it would be wise to not merge the stub functions at all, and have generate_keystream run into the default-clause below which gives a proper error message and return code instead of silent failure. https://gerrit.osmocom.org/c/osmo-tetra/+/34001/comment/cea1cccd_ff18f74c PS2, Line 305: / we typically prefer /* */ comments. Feels especially inconsistenc since this very same patch is adding multiple comments in different styles. -- To view, visit https://gerrit.osmocom.org/c/osmo-tetra/+/34001 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-tetra Gerrit-Branch: master Gerrit-Change-Id: I4e6147f206ad6046f32e08015ec9721b64382ca1 Gerrit-Change-Number: 34001 Gerrit-PatchSet: 2 Gerrit-Owner: wbokslag <w.bokslag(a)midnightblue.nl> Gerrit-Reviewer: Jenkins Builder Gerrit-CC: laforge <laforge(a)osmocom.org> Gerrit-Attention: wbokslag <w.bokslag(a)midnightblue.nl> Gerrit-Comment-Date: Sat, 29 Jul 2023 08:37:51 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Gerrit-MessageType: comment
1 0
0 0
[S] Change in osmo-tetra[master]: Fixups and clarifying comments for msgb tail modifications
by laforge 29 Jul '23

29 Jul '23
Attention is currently required from: wbokslag. laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-tetra/+/34000 ) Change subject: Fixups and clarifying comments for msgb tail modifications ...................................................................... Patch Set 2: (6 comments) File src/lower_mac/tetra_lower_mac.c: https://gerrit.osmocom.org/c/osmo-tetra/+/34000/comment/c28a8e8e_e37afbcb PS2, Line 347: msg->len = msg in general we don't ever manually manipulate msgb's this way in other osmocom software. We use the various msgb.[ch] functions as high-level operations on the buffer (like msgb_put/pull/push/get/trim/reserve/...), but don't consider manipulation of the individual fields as good code. I don't know the specific use case here (and have too many other tasks to review in detail) so I don't have a concrete suggestion, just sharing general thoughts. File src/tetra_llc.c: https://gerrit.osmocom.org/c/osmo-tetra/+/34000/comment/e33e4841_ee2edb49 PS2, Line 124: msg->tail = msg->l3h + lpp.tl_sdu_len; // Strips off FCS (if present) : msg->len = msg->tail - msg->head; this looks a bit like openn-coding a msgb_get(), or probably even more a msgb_l3trim() ? File src/tetra_upper_mac.c: https://gerrit.osmocom.org/c/osmo-tetra/+/34000/comment/68250cd6_9fecc52e PS2, Line 178: msg->len = m same here. msgb_trim? https://gerrit.osmocom.org/c/osmo-tetra/+/34000/comment/7b1ffe59_7871231b PS2, Line 185: msg->len = m same here. msgb_trim? https://gerrit.osmocom.org/c/osmo-tetra/+/34000/comment/edec0a07_0a8865b4 PS2, Line 306: msg->len = m yet another msgb_trim? Also, the entire get_num_fill_bits + following operations happens several times in the code, so it might make sense to create a function to cover the sequence of getting the number of fill-bits and then trimming the message to exclude those? https://gerrit.osmocom.org/c/osmo-tetra/+/34000/comment/46364861_fc916427 PS2, Line 359: msg->len = m again another fill-bits-stripping situation. -- To view, visit https://gerrit.osmocom.org/c/osmo-tetra/+/34000 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-tetra Gerrit-Branch: master Gerrit-Change-Id: Ia725edbeafe26bd2ea9b5a1810d0b26bc79d84db Gerrit-Change-Number: 34000 Gerrit-PatchSet: 2 Gerrit-Owner: wbokslag <w.bokslag(a)midnightblue.nl> Gerrit-Reviewer: Jenkins Builder Gerrit-CC: laforge <laforge(a)osmocom.org> Gerrit-Attention: wbokslag <w.bokslag(a)midnightblue.nl> Gerrit-Comment-Date: Sat, 29 Jul 2023 08:34:44 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Gerrit-MessageType: comment
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • ...
  • 306
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.