Commit 6a23bcfb authored by Robert Schmidt's avatar Robert Schmidt Committed by Chieh-Chun Chen

Add PDCP stats

parent ec4df27a
...@@ -59,6 +59,9 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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( ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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) ...@@ -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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment