mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-pcu.git
				synced 2025-11-04 06:03:30 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							
								
								
									
										100
									
								
								src/bts.cpp
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								src/bts.cpp
									
									
									
									
									
								
							@@ -23,13 +23,19 @@
 | 
			
		||||
#include <tbf.h>
 | 
			
		||||
 | 
			
		||||
#include <gprs_rlcmac.h>
 | 
			
		||||
#include <gprs_debug.h>
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
	#include <osmocom/core/talloc.h>
 | 
			
		||||
	#include <osmocom/core/msgb.h>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user