From 24e98d039d6f2d60a8db36a8cf034a299e2372f9 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 19 Oct 2013 18:15:44 +0200 Subject: [PATCH] pdch: Move paging dequeue into the PDCH object Rely on packet_paging_request returning NULL in case the queue is empty. We should move the write_packet_paging_request into a separate file/object as well. --- src/bts.cpp | 100 +++++++++++++++++++++++++++++++++++++- src/bts.h | 4 ++ src/gprs_rlcmac.cpp | 94 ----------------------------------- src/gprs_rlcmac.h | 6 --- src/gprs_rlcmac_sched.cpp | 3 +- 5 files changed, 104 insertions(+), 103 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index ca012883..7675ba36 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -23,13 +23,19 @@ #include #include +#include extern "C" { #include + #include } +#include + #include +extern void *tall_pcu_ctx; + static BTS s_bts; BTS* BTS::main_bts() @@ -87,7 +93,7 @@ void gprs_rlcmac_pdch::free_resources(uint8_t trx, uint8_t ts) gprs_rlcmac_tbf::free_all(this); /* flush all pending paging messages */ - while ((pag = gprs_rlcmac_dequeue_paging(this))) + while ((pag = dequeue_paging())) talloc_free(pag); llist_for_each_entry_safe(sba, sba2, &gprs_rlcmac_sbas, list) { @@ -97,3 +103,95 @@ void gprs_rlcmac_pdch::free_resources(uint8_t trx, uint8_t ts) } } } + +struct gprs_rlcmac_paging *gprs_rlcmac_pdch::dequeue_paging() +{ + struct gprs_rlcmac_paging *pag; + + if (llist_empty(&paging_list)) + return NULL; + pag = llist_entry(paging_list.next, struct gprs_rlcmac_paging, list); + llist_del(&pag->list); + + return pag; +} + +struct msgb *gprs_rlcmac_pdch::packet_paging_request() +{ + struct gprs_rlcmac_paging *pag; + struct msgb *msg; + unsigned wp = 0, len; + + /* no paging, no message */ + pag = dequeue_paging(); + if (!pag) + return NULL; + + LOGP(DRLCMAC, LOGL_DEBUG, "Scheduling paging\n"); + + /* alloc message */ + msg = msgb_alloc(23, "pag ctrl block"); + if (!msg) { + talloc_free(pag); + return NULL; + } + bitvec *pag_vec = bitvec_alloc(23); + if (!pag_vec) { + msgb_free(msg); + talloc_free(pag); + return NULL; + } + wp = write_packet_paging_request(pag_vec); + + /* loop until message is full */ + while (pag) { + /* try to add paging */ + if ((pag->identity_lv[1] & 0x07) == 4) { + /* TMSI */ + LOGP(DRLCMAC, LOGL_DEBUG, "- TMSI=0x%08x\n", + ntohl(*((uint32_t *)(pag->identity_lv + 1)))); + len = 1 + 1 + 1 + 32 + 2 + 1; + if (pag->identity_lv[0] != 5) { + LOGP(DRLCMAC, LOGL_ERROR, "TMSI paging with " + "MI != 5 octets!\n"); + goto continue_next; + } + } else { + /* MI */ + LOGP(DRLCMAC, LOGL_DEBUG, "- MI=%s\n", + osmo_hexdump(pag->identity_lv + 1, + pag->identity_lv[0])); + len = 1 + 1 + 1 + 4 + (pag->identity_lv[0]<<3) + 2 + 1; + if (pag->identity_lv[0] > 8) { + LOGP(DRLCMAC, LOGL_ERROR, "Paging with " + "MI > 8 octets!\n"); + goto continue_next; + } + } + if (wp + len > 184) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Does not fit, so schedule " + "next time\n"); + /* put back paging record, because does not fit */ + llist_add_tail(&pag->list, &paging_list); + break; + } + write_repeated_page_info(pag_vec, wp, pag->identity_lv[0], + pag->identity_lv + 1, pag->chan_needed); + +continue_next: + talloc_free(pag); + pag = dequeue_paging(); + } + + bitvec_pack(pag_vec, msgb_put(msg, 23)); + RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); + LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Paging Request +++++++++++++++++++++++++\n"); + decode_gsm_rlcmac_downlink(pag_vec, mac_control_block); + LOGPC(DCSN1, LOGL_NOTICE, "\n"); + LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- TX : Packet Paging Request -------------------------\n"); + bitvec_free(pag_vec); + talloc_free(mac_control_block); + + return msg; +} + diff --git a/src/bts.h b/src/bts.h index 8e88bc93..66043b19 100644 --- a/src/bts.h +++ b/src/bts.h @@ -40,6 +40,10 @@ struct BTS; */ struct gprs_rlcmac_pdch { #ifdef __cplusplus + struct gprs_rlcmac_paging *dequeue_paging(); + struct msgb *packet_paging_request(); + + /* TODO: the PDCH should know the trx/ts it belongs to */ void free_resources(uint8_t trx, uint8_t ts); diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index e83de21f..cb545066 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -358,100 +358,6 @@ int gprs_rlcmac_add_paging(struct gprs_rlcmac_bts *bts, return 0; } -struct gprs_rlcmac_paging *gprs_rlcmac_dequeue_paging( - struct gprs_rlcmac_pdch *pdch) -{ - struct gprs_rlcmac_paging *pag; - - if (llist_empty(&pdch->paging_list)) - return NULL; - pag = llist_entry(pdch->paging_list.next, - struct gprs_rlcmac_paging, list); - llist_del(&pag->list); - - return pag; -} - -struct msgb *gprs_rlcmac_send_packet_paging_request( - struct gprs_rlcmac_pdch *pdch) -{ - struct gprs_rlcmac_paging *pag; - struct msgb *msg; - unsigned wp = 0, len; - - /* no paging, no message */ - pag = gprs_rlcmac_dequeue_paging(pdch); - if (!pag) - return NULL; - - LOGP(DRLCMAC, LOGL_DEBUG, "Scheduling paging\n"); - - /* alloc message */ - msg = msgb_alloc(23, "pag ctrl block"); - if (!msg) { - talloc_free(pag); - return NULL; - } - bitvec *pag_vec = bitvec_alloc(23); - if (!pag_vec) { - msgb_free(msg); - talloc_free(pag); - return NULL; - } - wp = write_packet_paging_request(pag_vec); - - /* loop until message is full */ - while (pag) { - /* try to add paging */ - if ((pag->identity_lv[1] & 0x07) == 4) { - /* TMSI */ - LOGP(DRLCMAC, LOGL_DEBUG, "- TMSI=0x%08x\n", - ntohl(*((uint32_t *)(pag->identity_lv + 1)))); - len = 1 + 1 + 1 + 32 + 2 + 1; - if (pag->identity_lv[0] != 5) { - LOGP(DRLCMAC, LOGL_ERROR, "TMSI paging with " - "MI != 5 octets!\n"); - goto continue_next; - } - } else { - /* MI */ - LOGP(DRLCMAC, LOGL_DEBUG, "- MI=%s\n", - osmo_hexdump(pag->identity_lv + 1, - pag->identity_lv[0])); - len = 1 + 1 + 1 + 4 + (pag->identity_lv[0]<<3) + 2 + 1; - if (pag->identity_lv[0] > 8) { - LOGP(DRLCMAC, LOGL_ERROR, "Paging with " - "MI > 8 octets!\n"); - goto continue_next; - } - } - if (wp + len > 184) { - LOGP(DRLCMAC, LOGL_DEBUG, "- Does not fit, so schedule " - "next time\n"); - /* put back paging record, because does not fit */ - llist_add_tail(&pag->list, &pdch->paging_list); - break; - } - write_repeated_page_info(pag_vec, wp, pag->identity_lv[0], - pag->identity_lv + 1, pag->chan_needed); - -continue_next: - talloc_free(pag); - pag = gprs_rlcmac_dequeue_paging(pdch); - } - - bitvec_pack(pag_vec, msgb_put(msg, 23)); - RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); - LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Paging Request +++++++++++++++++++++++++\n"); - decode_gsm_rlcmac_downlink(pag_vec, mac_control_block); - LOGPC(DCSN1, LOGL_NOTICE, "\n"); - LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- TX : Packet Paging Request -------------------------\n"); - bitvec_free(pag_vec); - talloc_free(mac_control_block); - - return msg; -} - // GSM 04.08 9.1.18 Immediate assignment int write_immediate_assignment( struct gprs_rlcmac_bts *bts, diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 4b9119b0..79627c47 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -192,12 +192,6 @@ int gprs_rlcmac_imm_ass_cnf(uint8_t *data, uint32_t fn); int gprs_rlcmac_add_paging(struct gprs_rlcmac_bts *bts, uint8_t chan_needed, uint8_t *identity_lv); -struct gprs_rlcmac_paging *gprs_rlcmac_dequeue_paging( - struct gprs_rlcmac_pdch *pdch); - -struct msgb *gprs_rlcmac_send_packet_paging_request( - struct gprs_rlcmac_pdch *pdch); - int remember_timing_advance(uint32_t tlli, uint8_t ta); int recall_timing_advance(uint32_t tlli); diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index c0154fc5..be699e67 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -156,8 +156,7 @@ static struct msgb *sched_select_ctrl_msg(struct gprs_rlcmac_bts *bts, return msg; } /* schedule PACKET PAGING REQUEST */ - if (!llist_empty(&pdch->paging_list)) - msg = gprs_rlcmac_send_packet_paging_request(pdch); + msg = pdch->packet_paging_request(); if (msg) { LOGP(DRLCMACSCHED, LOGL_DEBUG, "Scheduling paging request " "message at RTS for (TRX=%d, TS=%d)\n", trx, ts);