Add PDCP stats
This commit is contained in:
committed by
Chieh-Chun Chen
parent
ec4df27a75
commit
6a23bcfb42
@@ -59,6 +59,9 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
|||||||
We need to investigate why this hack is neccessary. */
|
We need to investigate why this hack is neccessary. */
|
||||||
buffer[0] |= 128;
|
buffer[0] |= 128;
|
||||||
}
|
}
|
||||||
|
entity->stats.rxpdu_pkts++;
|
||||||
|
entity->stats.rxpdu_bytes += size;
|
||||||
|
|
||||||
|
|
||||||
if (entity->sn_size == 12) {
|
if (entity->sn_size == 12) {
|
||||||
rcvd_sn = ((buffer[0] & 0xf) << 8) |
|
rcvd_sn = ((buffer[0] & 0xf) << 8) |
|
||||||
@@ -70,6 +73,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
|||||||
buffer[2];
|
buffer[2];
|
||||||
header_size = 3;
|
header_size = 3;
|
||||||
}
|
}
|
||||||
|
entity->stats.rxpdu_sn = rcvd_sn;
|
||||||
|
|
||||||
/* SRBs always have MAC-I, even if integrity is not active */
|
/* SRBs always have MAC-I, even if integrity is not active */
|
||||||
if (entity->has_integrity || entity->type == NR_PDCP_SRB) {
|
if (entity->has_integrity || entity->type == NR_PDCP_SRB) {
|
||||||
@@ -80,6 +84,11 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
|||||||
|
|
||||||
if (size < header_size + integrity_size + 1) {
|
if (size < header_size + integrity_size + 1) {
|
||||||
LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
|
LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
|
||||||
|
|
||||||
|
entity->stats.rxpdu_dd_pkts++;
|
||||||
|
entity->stats.rxpdu_dd_bytes += size;
|
||||||
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,12 +118,20 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
|||||||
if (memcmp(integrity, buffer + size - integrity_size, 4) != 0) {
|
if (memcmp(integrity, buffer + size - integrity_size, 4) != 0) {
|
||||||
LOG_E(PDCP, "discard NR PDU, integrity failed\n");
|
LOG_E(PDCP, "discard NR PDU, integrity failed\n");
|
||||||
// return;
|
// return;
|
||||||
|
entity->stats.rxpdu_dd_pkts++;
|
||||||
|
entity->stats.rxpdu_dd_bytes += size;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcvd_count < entity->rx_deliv
|
if (rcvd_count < entity->rx_deliv
|
||||||
|| nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) {
|
|| nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) {
|
||||||
LOG_W(PDCP, "discard NR PDU rcvd_count=%d, entity->rx_deliv %d,sdu_in_list %d\n", rcvd_count,entity->rx_deliv,nr_pdcp_sdu_in_list(entity->rx_list,rcvd_count));
|
LOG_W(PDCP, "discard NR PDU rcvd_count=%d, entity->rx_deliv %d,sdu_in_list %d\n", rcvd_count,entity->rx_deliv,nr_pdcp_sdu_in_list(entity->rx_list,rcvd_count));
|
||||||
|
entity->stats.rxpdu_dd_pkts++;
|
||||||
|
entity->stats.rxpdu_dd_bytes += size;
|
||||||
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,6 +156,10 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
|||||||
cur->buffer, cur->size);
|
cur->buffer, cur->size);
|
||||||
entity->rx_list = cur->next;
|
entity->rx_list = cur->next;
|
||||||
entity->rx_size -= cur->size;
|
entity->rx_size -= cur->size;
|
||||||
|
entity->stats.txsdu_pkts++;
|
||||||
|
entity->stats.txsdu_bytes += cur->size;
|
||||||
|
|
||||||
|
|
||||||
nr_pdcp_free_sdu(cur);
|
nr_pdcp_free_sdu(cur);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -165,6 +186,9 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
|
|||||||
int integrity_size;
|
int integrity_size;
|
||||||
char buf[size + 3 + 4];
|
char buf[size + 3 + 4];
|
||||||
int dc_bit;
|
int dc_bit;
|
||||||
|
entity->stats.rxsdu_pkts++;
|
||||||
|
entity->stats.rxsdu_bytes += size;
|
||||||
|
|
||||||
|
|
||||||
count = entity->tx_next;
|
count = entity->tx_next;
|
||||||
sn = entity->tx_next & entity->sn_max;
|
sn = entity->tx_next & entity->sn_max;
|
||||||
@@ -215,6 +239,11 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
|
|||||||
|
|
||||||
entity->deliver_pdu(entity->deliver_pdu_data, entity, buf,
|
entity->deliver_pdu(entity->deliver_pdu_data, entity, buf,
|
||||||
header_size + size + integrity_size, sdu_id);
|
header_size + size + integrity_size, sdu_id);
|
||||||
|
entity->stats.txpdu_pkts++;
|
||||||
|
entity->stats.txpdu_bytes += header_size + size + integrity_size;
|
||||||
|
entity->stats.txpdu_sn = sn;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* may be called several times, take care to clean previous settings */
|
/* may be called several times, take care to clean previous settings */
|
||||||
@@ -346,6 +375,13 @@ void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
|
|||||||
free(entity);
|
free(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nr_pdcp_entity_get_stats(nr_pdcp_entity_t *entity,
|
||||||
|
nr_pdcp_statistics_t *out)
|
||||||
|
{
|
||||||
|
*out = entity->stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
nr_pdcp_entity_t *new_nr_pdcp_entity(
|
nr_pdcp_entity_t *new_nr_pdcp_entity(
|
||||||
nr_pdcp_entity_type_t type,
|
nr_pdcp_entity_type_t type,
|
||||||
int is_gnb, int rb_id, int pdusession_id,int has_sdap,
|
int is_gnb, int rb_id, int pdusession_id,int has_sdap,
|
||||||
@@ -381,6 +417,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
|
|||||||
|
|
||||||
ret->delete_entity = nr_pdcp_entity_delete;
|
ret->delete_entity = nr_pdcp_entity_delete;
|
||||||
|
|
||||||
|
ret->get_stats = nr_pdcp_entity_get_stats;
|
||||||
ret->deliver_sdu = deliver_sdu;
|
ret->deliver_sdu = deliver_sdu;
|
||||||
ret->deliver_sdu_data = deliver_sdu_data;
|
ret->deliver_sdu_data = deliver_sdu_data;
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,39 @@ typedef enum {
|
|||||||
NR_PDCP_SRB
|
NR_PDCP_SRB
|
||||||
} nr_pdcp_entity_type_t;
|
} nr_pdcp_entity_type_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
//nr_pdcp_entity_type_t mode;
|
||||||
|
/* PDU stats */
|
||||||
|
/* TX */
|
||||||
|
uint32_t txpdu_pkts; /* aggregated number of tx packets */
|
||||||
|
uint32_t txpdu_bytes; /* aggregated bytes of tx packets */
|
||||||
|
uint32_t txpdu_sn; /* current sequence number of last tx packet (or TX_NEXT) */
|
||||||
|
/* RX */
|
||||||
|
uint32_t rxpdu_pkts; /* aggregated number of rx packets */
|
||||||
|
uint32_t rxpdu_bytes; /* aggregated bytes of rx packets */
|
||||||
|
uint32_t rxpdu_sn; /* current sequence number of last rx packet (or RX_NEXT) */
|
||||||
|
/* TODO? */
|
||||||
|
uint32_t rxpdu_oo_pkts; /* aggregated number of out-of-order rx pkts (or RX_REORD) */
|
||||||
|
/* TODO? */
|
||||||
|
uint32_t rxpdu_oo_bytes; /* aggregated amount of out-of-order rx bytes */
|
||||||
|
uint32_t rxpdu_dd_pkts; /* aggregated number of duplicated discarded packets (or dropped packets because of other reasons such as integrity failure) (or RX_DELIV) */
|
||||||
|
uint32_t rxpdu_dd_bytes; /* aggregated amount of discarded packets' bytes */
|
||||||
|
/* TODO? */
|
||||||
|
uint32_t rxpdu_ro_count; /* this state variable indicates the COUNT value following the COUNT value associated with the PDCP Data PDU which triggered t-Reordering. (RX_REORD) */
|
||||||
|
|
||||||
|
/* SDU stats */
|
||||||
|
/* TX */
|
||||||
|
uint32_t txsdu_pkts; /* number of SDUs delivered */
|
||||||
|
uint32_t txsdu_bytes; /* number of bytes of SDUs delivered */
|
||||||
|
|
||||||
|
/* RX */
|
||||||
|
uint32_t rxsdu_pkts; /* number of SDUs received */
|
||||||
|
uint32_t rxsdu_bytes; /* number of bytes of SDUs received */
|
||||||
|
|
||||||
|
uint8_t mode; /* 0: PDCP AM, 1: PDCP UM, 2: PDCP TM */
|
||||||
|
} nr_pdcp_statistics_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct nr_pdcp_entity_t {
|
typedef struct nr_pdcp_entity_t {
|
||||||
nr_pdcp_entity_type_t type;
|
nr_pdcp_entity_type_t type;
|
||||||
|
|
||||||
@@ -40,6 +73,7 @@ typedef struct nr_pdcp_entity_t {
|
|||||||
void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
|
void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
|
||||||
int sdu_id);
|
int sdu_id);
|
||||||
void (*delete_entity)(struct nr_pdcp_entity_t *entity);
|
void (*delete_entity)(struct nr_pdcp_entity_t *entity);
|
||||||
|
void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out);
|
||||||
|
|
||||||
/* set_security: pass -1 to integrity_algorithm / ciphering_algorithm
|
/* set_security: pass -1 to integrity_algorithm / ciphering_algorithm
|
||||||
* to keep the current algorithm
|
* to keep the current algorithm
|
||||||
@@ -114,6 +148,7 @@ typedef struct nr_pdcp_entity_t {
|
|||||||
nr_pdcp_sdu_t *rx_list;
|
nr_pdcp_sdu_t *rx_list;
|
||||||
int rx_size;
|
int rx_size;
|
||||||
int rx_maxsize;
|
int rx_maxsize;
|
||||||
|
nr_pdcp_statistics_t stats;
|
||||||
} nr_pdcp_entity_t;
|
} nr_pdcp_entity_t;
|
||||||
|
|
||||||
nr_pdcp_entity_t *new_nr_pdcp_entity(
|
nr_pdcp_entity_t *new_nr_pdcp_entity(
|
||||||
|
|||||||
@@ -1441,6 +1441,44 @@ void nr_pdcp_tick(int frame, int subframe)
|
|||||||
/*
|
/*
|
||||||
* For the SDAP API
|
* For the SDAP API
|
||||||
*/
|
*/
|
||||||
nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager(){
|
nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager() {
|
||||||
return nr_pdcp_ue_manager;
|
return nr_pdcp_ue_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns 0 in case of error, 1 if everything ok */
|
||||||
|
int const nr_pdcp_get_statistics(
|
||||||
|
int rnti,
|
||||||
|
int srb_flag,
|
||||||
|
int rb_id,
|
||||||
|
nr_pdcp_statistics_t *out)
|
||||||
|
{
|
||||||
|
nr_pdcp_ue_t *ue;
|
||||||
|
nr_pdcp_entity_t *rb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
|
||||||
|
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
|
||||||
|
|
||||||
|
if (srb_flag == 1) {
|
||||||
|
if (rb_id < 1 || rb_id > 2)
|
||||||
|
rb = NULL;
|
||||||
|
else
|
||||||
|
rb = ue->srb[rb_id - 1];
|
||||||
|
} else {
|
||||||
|
if (rb_id < 1 || rb_id > 5)
|
||||||
|
rb = NULL;
|
||||||
|
else
|
||||||
|
rb = ue->drb[rb_id - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rb != NULL) {
|
||||||
|
rb->get_stats(rb, out);
|
||||||
|
ret = 1;
|
||||||
|
} else {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user