pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/34005 )
Change subject: rlcmac: Initial selection of packet-access-procedure mode based on originating cause ......................................................................
rlcmac: Initial selection of packet-access-procedure mode based on originating cause
Change-Id: I930a1fcf23506f75562a6795f9a6e42b187d2974 --- M include/osmocom/gprs/rlcmac/llc_queue.h M src/rlcmac/gre.c M src/rlcmac/llc_queue.c 3 files changed, 43 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-gprs refs/changes/05/34005/1
diff --git a/include/osmocom/gprs/rlcmac/llc_queue.h b/include/osmocom/gprs/rlcmac/llc_queue.h index 7149f76..dd7528c 100644 --- a/include/osmocom/gprs/rlcmac/llc_queue.h +++ b/include/osmocom/gprs/rlcmac/llc_queue.h @@ -27,6 +27,7 @@
struct gprs_llc_prio_queue { enum gprs_rlcmac_radio_priority radio_prio; /* Radio prio of this queue, range (1..4) */ + enum osmo_gprs_rlcmac_llc_sapi sapi; /* LLC SAPI of this queue */ struct gprs_codel codel_state; struct llist_head queue; /* queued LLC DL data. See enum gprs_rlcmac_llc_queue_prio. */ }; @@ -50,6 +51,7 @@ 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); enum gprs_rlcmac_radio_priority gprs_rlcmac_llc_queue_highest_radio_prio_pending(struct gprs_rlcmac_llc_queue *q); +enum osmo_gprs_rlcmac_llc_sapi gprs_rlcmac_llc_queue_highest_llc_sapi_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 59cf0f5..0eb6a8c 100644 --- a/src/rlcmac/gre.c +++ b/src/rlcmac/gre.c @@ -198,6 +198,9 @@ /* Create a new UL TBF and start Packet access procedure to get an UL assignment if needed */ int gprs_rlcmac_entity_start_ul_tbf_pkt_acc_proc_if_needed(struct gprs_rlcmac_entity *gre) { + enum osmo_gprs_rlcmac_llc_sapi tx_sapi; + enum gprs_rlcmac_tbf_ul_ass_type ul_ass_type; + /* TS 44.060 5.3 "In packet idle mode, upper layers may require the * transfer of a upper layer PDU, which implicitly triggers the * establishment of a TBF and the transition to packet transfer mode." */ @@ -212,8 +215,27 @@ gre->ul_tbf = gprs_rlcmac_ul_tbf_alloc(gre); if (!gre->ul_tbf) return -ENOMEM; + + tx_sapi = gprs_rlcmac_llc_queue_highest_radio_prio_pending(gre->llc_queue); + /* 3GPP TS 44.018 3.5.2.1.2 "Initiation of the packet access procedure: channel request" */ + switch (tx_sapi) { + case OSMO_GPRS_RLCMAC_LLC_SAPI_GMM: + /* "If the purpose [...] is to send a Page Response, a Cell update (the mobile + * station was in GMM READY state before the cell reselection) or for any other + * GPRS Mobility Management or GPRS Session Management procedure, the mobile station + * shall request a one phase packet access" */ + ul_ass_type = GPRS_RLCMAC_TBF_UL_ASS_TYPE_1PHASE; + break; + default: + /* "If the purpose [...] is to send user data and the requested RLC mode is + * acknowledged mode, the mobile station shall request either a one phase packet + * access or a single block packet access." */ + /* TODO: We always use 1phase for now... ideally we should decide + * based on amount of Tx data and configured MultiSlot Class? */ + ul_ass_type = GPRS_RLCMAC_TBF_UL_ASS_TYPE_1PHASE; + } /* We always use 1phase for now... */ - return gprs_rlcmac_tbf_ul_ass_start(gre->ul_tbf, GPRS_RLCMAC_TBF_UL_ASS_TYPE_1PHASE); + return gprs_rlcmac_tbf_ul_ass_start(gre->ul_tbf, ul_ass_type); }
int gprs_rlcmac_entity_llc_enqueue(struct gprs_rlcmac_entity *gre, diff --git a/src/rlcmac/llc_queue.c b/src/rlcmac/llc_queue.c index 83c926e..d1f923a 100644 --- a/src/rlcmac/llc_queue.c +++ b/src/rlcmac/llc_queue.c @@ -47,6 +47,7 @@ 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; /* enum gprs_rlcmac_radio_priority, range (0..3) */ + q->pq[i][j].sapi = i + 1; /* osmo_gprs_rlcmac_llc_sapi, range (1..11) */ INIT_LLIST_HEAD(&q->pq[i][j].queue); gprs_codel_init(&q->pq[i][j].codel_state); } @@ -222,6 +223,14 @@ return prioq->radio_prio; }
+enum osmo_gprs_rlcmac_llc_sapi gprs_rlcmac_llc_queue_highest_llc_sapi_pending(struct gprs_rlcmac_llc_queue *q) +{ + struct gprs_llc_prio_queue *prioq = gprs_rlcmac_llc_queue_find_msg(q); + OSMO_ASSERT(prioq); + return prioq->sapi; +} + + /* Merge old_q messages into q, prepending them. old_q must be freed by the caller. */ void gprs_rlcmac_llc_queue_merge_prepend(struct gprs_rlcmac_llc_queue *q, struct gprs_rlcmac_llc_queue *old_q) {