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

Add RLC stats

parent bcbf2b38
...@@ -29,6 +29,14 @@ ...@@ -29,6 +29,14 @@
#include "LOG/log.h" #include "LOG/log.h"
static void nr_rlc_entity_get_stats(
nr_rlc_entity_t *entity,
nr_rlc_statistics_t *out)
{
// printf("Stats from the RLC entity asked\n");
*out = entity->stats;
}
nr_rlc_entity_t *new_nr_rlc_entity_am( nr_rlc_entity_t *new_nr_rlc_entity_am(
int rx_maxsize, int rx_maxsize,
int tx_maxsize, int tx_maxsize,
...@@ -86,6 +94,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_am( ...@@ -86,6 +94,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_am(
ret->common.reestablishment = nr_rlc_entity_am_reestablishment; ret->common.reestablishment = nr_rlc_entity_am_reestablishment;
ret->common.delete = nr_rlc_entity_am_delete; ret->common.delete = nr_rlc_entity_am_delete;
ret->common.available_tx_space = nr_rlc_entity_am_available_tx_space; ret->common.available_tx_space = nr_rlc_entity_am_available_tx_space;
ret->common.get_stats = nr_rlc_entity_get_stats;
ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu = deliver_sdu;
ret->common.deliver_sdu_data = deliver_sdu_data; ret->common.deliver_sdu_data = deliver_sdu_data;
...@@ -94,6 +103,8 @@ nr_rlc_entity_t *new_nr_rlc_entity_am( ...@@ -94,6 +103,8 @@ nr_rlc_entity_t *new_nr_rlc_entity_am(
ret->common.max_retx_reached = max_retx_reached; ret->common.max_retx_reached = max_retx_reached;
ret->common.max_retx_reached_data = max_retx_reached_data; ret->common.max_retx_reached_data = max_retx_reached_data;
ret->common.stats.mode = 0; /* 0 for AM */
return (nr_rlc_entity_t *)ret; return (nr_rlc_entity_t *)ret;
} }
...@@ -137,10 +148,13 @@ nr_rlc_entity_t *new_nr_rlc_entity_um( ...@@ -137,10 +148,13 @@ nr_rlc_entity_t *new_nr_rlc_entity_um(
ret->common.reestablishment = nr_rlc_entity_um_reestablishment; ret->common.reestablishment = nr_rlc_entity_um_reestablishment;
ret->common.delete = nr_rlc_entity_um_delete; ret->common.delete = nr_rlc_entity_um_delete;
ret->common.available_tx_space = nr_rlc_entity_um_available_tx_space; ret->common.available_tx_space = nr_rlc_entity_um_available_tx_space;
ret->common.get_stats = nr_rlc_entity_get_stats;
ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu = deliver_sdu;
ret->common.deliver_sdu_data = deliver_sdu_data; ret->common.deliver_sdu_data = deliver_sdu_data;
ret->common.stats.mode = 1; /* 1 for UM */
return (nr_rlc_entity_t *)ret; return (nr_rlc_entity_t *)ret;
} }
...@@ -169,9 +183,12 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm( ...@@ -169,9 +183,12 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm(
ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; ret->common.reestablishment = nr_rlc_entity_tm_reestablishment;
ret->common.delete = nr_rlc_entity_tm_delete; ret->common.delete = nr_rlc_entity_tm_delete;
ret->common.available_tx_space = nr_rlc_entity_tm_available_tx_space; ret->common.available_tx_space = nr_rlc_entity_tm_available_tx_space;
ret->common.get_stats = nr_rlc_entity_get_stats;
ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu = deliver_sdu;
ret->common.deliver_sdu_data = deliver_sdu_data; ret->common.deliver_sdu_data = deliver_sdu_data;
ret->common.stats.mode = 2; /* 2 for TM */
return (nr_rlc_entity_t *)ret; return (nr_rlc_entity_t *)ret;
} }
...@@ -26,6 +26,59 @@ ...@@ -26,6 +26,59 @@
#define NR_SDU_MAX 16000 /* max NR PDCP SDU size is 9000, let's take more */ #define NR_SDU_MAX 16000 /* max NR PDCP SDU size is 9000, let's take more */
typedef struct {
uint32_t mode; /* 0: RLC AM, 1: RLC UM, 2: RLC TM */
/* PDU stats */
/* TX */
uint32_t txpdu_pkts; /* aggregated number of transmitted RLC PDUs */
uint32_t txpdu_bytes; /* aggregated amount of transmitted bytes in RLC PDUs */
/* TODO? */
uint32_t txpdu_wt_ms; /* aggregated head-of-line tx packet waiting time to be transmitted (i.e. send to the MAC layer) */
uint32_t txpdu_dd_pkts; /* aggregated number of dropped or discarded tx packets by RLC */
uint32_t txpdu_dd_bytes; /* aggregated amount of bytes dropped or discarded tx packets by RLC */
uint32_t txpdu_retx_pkts; /* aggregated number of tx pdus/pkts to be re-transmitted (only applicable to RLC AM) */
uint32_t txpdu_retx_bytes; /* aggregated amount of bytes to be re-transmitted (only applicable to RLC AM) */
uint32_t txpdu_segmented; /* aggregated number of segmentations */
uint32_t txpdu_status_pkts; /* aggregated number of tx status pdus/pkts (only applicable to RLC AM) */
uint32_t txpdu_status_bytes; /* aggregated amount of tx status bytes (only applicable to RLC AM) */
/* TODO? */
uint32_t txbuf_occ_bytes; /* current tx buffer occupancy in terms of amount of bytes (average: NOT IMPLEMENTED) */
/* TODO? */
uint32_t txbuf_occ_pkts; /* current tx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */
/* txbuf_wd_ms: the time window for which the txbuf occupancy value is obtained - NOT IMPLEMENTED */
/* RX */
uint32_t rxpdu_pkts; /* aggregated number of received RLC PDUs */
uint32_t rxpdu_bytes; /* amount of bytes received by the RLC */
uint32_t rxpdu_dup_pkts; /* aggregated number of duplicate packets */
uint32_t rxpdu_dup_bytes; /* aggregated amount of duplicated bytes */
uint32_t rxpdu_dd_pkts; /* aggregated number of rx packets dropped or discarded by RLC */
uint32_t rxpdu_dd_bytes; /* aggregated amount of rx bytes dropped or discarded by RLC */
uint32_t rxpdu_ow_pkts; /* aggregated number of out of window received RLC pdu */
uint32_t rxpdu_ow_bytes; /* aggregated number of out of window bytes received RLC pdu */
uint32_t rxpdu_status_pkts; /* aggregated number of rx status pdus/pkts (only applicable to RLC AM) */
uint32_t rxpdu_status_bytes; /* aggregated amount of rx status bytes (only applicable to RLC AM) */
/* rxpdu_rotout_ms: flag indicating rx reordering timeout in ms - NOT IMPLEMENTED */
/* rxpdu_potout_ms: flag indicating the poll retransmit time out in ms - NOT IMPLEMENTED */
/* rxpdu_sptout_ms: flag indicating status prohibit timeout in ms - NOT IMPLEMENTED */
/* TODO? */
uint32_t rxbuf_occ_bytes; /* current rx buffer occupancy in terms of amount of bytes (average: NOT IMPLEMENTED) */
/* TODO? */
uint32_t rxbuf_occ_pkts; /* current rx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */
/* 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 */
uint32_t rxsdu_dd_pkts; /* number of dropped or discarded SDUs */
uint32_t rxsdu_dd_bytes; /* number of bytes of SDUs dropped or discarded */
} nr_rlc_statistics_t;
typedef struct { typedef struct {
int status_size; int status_size;
int tx_size; int tx_size;
...@@ -52,6 +105,8 @@ typedef struct nr_rlc_entity_t { ...@@ -52,6 +105,8 @@ typedef struct nr_rlc_entity_t {
int (*available_tx_space)(struct nr_rlc_entity_t *entity); int (*available_tx_space)(struct nr_rlc_entity_t *entity);
void (*get_stats)(struct nr_rlc_entity_t *entity, nr_rlc_statistics_t *out);
/* callbacks provided to the RLC module */ /* callbacks provided to the RLC module */
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
char *buf, int size); char *buf, int size);
...@@ -67,6 +122,8 @@ typedef struct nr_rlc_entity_t { ...@@ -67,6 +122,8 @@ typedef struct nr_rlc_entity_t {
void *max_retx_reached_data; void *max_retx_reached_data;
/* buffer status computation */ /* buffer status computation */
nr_rlc_entity_buffer_status_t bstatus; nr_rlc_entity_buffer_status_t bstatus;
nr_rlc_statistics_t stats;
} nr_rlc_entity_t; } nr_rlc_entity_t;
nr_rlc_entity_t *new_nr_rlc_entity_am( nr_rlc_entity_t *new_nr_rlc_entity_am(
......
...@@ -221,6 +221,9 @@ static void reassemble_and_deliver(nr_rlc_entity_am_t *entity, int sn) ...@@ -221,6 +221,9 @@ static void reassemble_and_deliver(nr_rlc_entity_am_t *entity, int sn)
entity->common.deliver_sdu(entity->common.deliver_sdu_data, entity->common.deliver_sdu(entity->common.deliver_sdu_data,
(nr_rlc_entity_t *)entity, (nr_rlc_entity_t *)entity,
sdu, so); sdu, so);
entity->common.stats.txsdu_pkts++;
entity->common.stats.txsdu_bytes += so;
} }
static void reception_actions(nr_rlc_entity_am_t *entity, nr_rlc_pdu_t *pdu) static void reception_actions(nr_rlc_entity_am_t *entity, nr_rlc_pdu_t *pdu)
...@@ -684,6 +687,9 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity, ...@@ -684,6 +687,9 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
int is_first; int is_first;
int is_last; int is_last;
entity->common.stats.rxpdu_pkts++;
entity->common.stats.rxpdu_bytes += size;
nr_rlc_pdu_decoder_init(&decoder, buffer, size); nr_rlc_pdu_decoder_init(&decoder, buffer, size);
dc = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); dc = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
...@@ -733,6 +739,10 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity, ...@@ -733,6 +739,10 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, sn out of window (sn %d rx_next %d)\n", LOG_D(RLC, "%s:%d:%s: warning: discard PDU, sn out of window (sn %d rx_next %d)\n",
__FILE__, __LINE__, __FUNCTION__, __FILE__, __LINE__, __FUNCTION__,
sn, entity->rx_next); sn, entity->rx_next);
entity->common.stats.rxpdu_ow_pkts++;
entity->common.stats.rxpdu_ow_bytes += size;
goto discard; goto discard;
} }
...@@ -740,6 +750,10 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity, ...@@ -740,6 +750,10 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
if (segment_already_received(entity, sn, so, data_size)) { if (segment_already_received(entity, sn, so, data_size)) {
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, already received\n", LOG_D(RLC, "%s:%d:%s: warning: discard PDU, already received\n",
__FILE__, __LINE__, __FUNCTION__); __FILE__, __LINE__, __FUNCTION__);
entity->common.stats.rxpdu_dup_pkts++;
entity->common.stats.rxpdu_dup_bytes += size;
goto discard; goto discard;
} }
...@@ -779,6 +793,9 @@ discard: ...@@ -779,6 +793,9 @@ discard:
if (p) if (p)
entity->status_triggered = 1; entity->status_triggered = 1;
entity->common.stats.rxpdu_dd_pkts++;
entity->common.stats.rxpdu_dd_bytes += size;
#undef R #undef R
} }
...@@ -1309,6 +1326,11 @@ static int generate_status(nr_rlc_entity_am_t *entity, char *buffer, int size) ...@@ -1309,6 +1326,11 @@ static int generate_status(nr_rlc_entity_am_t *entity, char *buffer, int size)
/* start t_status_prohibit */ /* start t_status_prohibit */
entity->t_status_prohibit_start = entity->t_current; entity->t_status_prohibit_start = entity->t_current;
entity->common.stats.txpdu_pkts++;
entity->common.stats.txpdu_bytes += encoder.byte;
entity->common.stats.txpdu_status_pkts++;
entity->common.stats.txpdu_status_bytes += encoder.byte;
return encoder.byte; return encoder.byte;
} }
...@@ -1473,6 +1495,8 @@ static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer, ...@@ -1473,6 +1495,8 @@ static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer,
/* update buffer status */ /* update buffer status */
entity->common.bstatus.retx_size += compute_pdu_header_size(entity, next_sdu) entity->common.bstatus.retx_size += compute_pdu_header_size(entity, next_sdu)
+ next_sdu->size; + next_sdu->size;
entity->common.stats.txpdu_segmented++;
} }
/* put SDU/SDU segment in the wait list */ /* put SDU/SDU segment in the wait list */
...@@ -1496,7 +1520,14 @@ static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer, ...@@ -1496,7 +1520,14 @@ static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer,
entity->force_poll = 0; entity->force_poll = 0;
} }
return serialize_sdu(entity, sdu, buffer, size, p); int ret_size = serialize_sdu(entity, sdu, buffer, size, p);
entity->common.stats.txpdu_pkts++;
entity->common.stats.txpdu_bytes += ret_size;
entity->common.stats.txpdu_retx_pkts++;
entity->common.stats.txpdu_retx_bytes += ret_size;
return ret_size;
// return serialize_sdu(entity, sdu, buffer, size, p);
} }
static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size) static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
...@@ -1544,6 +1575,8 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size) ...@@ -1544,6 +1575,8 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
entity->tx_list = next_sdu; entity->tx_list = next_sdu;
if (entity->tx_end == NULL) if (entity->tx_end == NULL)
entity->tx_end = entity->tx_list; entity->tx_end = entity->tx_list;
entity->common.stats.txpdu_segmented++;
/* update buffer status */ /* update buffer status */
entity->common.bstatus.tx_size += compute_pdu_header_size(entity, next_sdu) entity->common.bstatus.tx_size += compute_pdu_header_size(entity, next_sdu)
+ next_sdu->size; + next_sdu->size;
...@@ -1582,8 +1615,13 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size) ...@@ -1582,8 +1615,13 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
p = 1; p = 1;
entity->force_poll = 0; entity->force_poll = 0;
} }
int ret_size = serialize_sdu(entity, sdu, buffer, size, p);
entity->common.stats.txpdu_pkts++;
entity->common.stats.txpdu_bytes += ret_size;
return serialize_sdu(entity, sdu, buffer, size, p); return ret_size;
// return serialize_sdu(entity, sdu, buffer, size, p);
} }
nr_rlc_entity_buffer_status_t nr_rlc_entity_am_buffer_status( nr_rlc_entity_buffer_status_t nr_rlc_entity_am_buffer_status(
...@@ -1635,6 +1673,9 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity, ...@@ -1635,6 +1673,9 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity,
nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity;
nr_rlc_sdu_segment_t *sdu; nr_rlc_sdu_segment_t *sdu;
entity->common.stats.rxsdu_pkts++;
entity->common.stats.rxsdu_bytes += size;
if (size > NR_SDU_MAX) { if (size > NR_SDU_MAX) {
LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n", LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n",
__FILE__, __LINE__, __FUNCTION__, size); __FILE__, __LINE__, __FUNCTION__, size);
......
...@@ -36,9 +36,16 @@ void nr_rlc_entity_tm_recv_pdu(nr_rlc_entity_t *_entity, ...@@ -36,9 +36,16 @@ void nr_rlc_entity_tm_recv_pdu(nr_rlc_entity_t *_entity,
char *buffer, int size) char *buffer, int size)
{ {
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
entity->common.stats.rxpdu_pkts++;
entity->common.stats.rxpdu_bytes += size;
entity->common.deliver_sdu(entity->common.deliver_sdu_data, entity->common.deliver_sdu(entity->common.deliver_sdu_data,
(nr_rlc_entity_t *)entity, (nr_rlc_entity_t *)entity,
buffer, size); buffer, size);
entity->common.stats.txsdu_pkts++;
entity->common.stats.txsdu_bytes += size;
} }
/*************************************************************************/ /*************************************************************************/
...@@ -68,6 +75,9 @@ static int generate_tx_pdu(nr_rlc_entity_tm_t *entity, char *buffer, int size) ...@@ -68,6 +75,9 @@ static int generate_tx_pdu(nr_rlc_entity_tm_t *entity, char *buffer, int size)
memcpy(buffer, sdu->sdu->data, sdu->size); memcpy(buffer, sdu->sdu->data, sdu->size);
entity->tx_size -= sdu->size; entity->tx_size -= sdu->size;
entity->common.stats.txpdu_pkts++;
entity->common.stats.txpdu_bytes += size;
/* update buffer status */ /* update buffer status */
entity->common.bstatus.tx_size -= sdu->size; entity->common.bstatus.tx_size -= sdu->size;
...@@ -109,6 +119,9 @@ void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *_entity, ...@@ -109,6 +119,9 @@ void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *_entity,
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
nr_rlc_sdu_segment_t *sdu; nr_rlc_sdu_segment_t *sdu;
entity->common.stats.rxsdu_pkts++;
entity->common.stats.rxsdu_bytes += size;
if (size > NR_SDU_MAX) { if (size > NR_SDU_MAX) {
LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n", LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n",
__FILE__, __LINE__, __FUNCTION__, size); __FILE__, __LINE__, __FUNCTION__, size);
...@@ -118,6 +131,10 @@ void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *_entity, ...@@ -118,6 +131,10 @@ void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *_entity,
if (entity->tx_size + size > entity->tx_maxsize) { if (entity->tx_size + size > entity->tx_maxsize) {
LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n", LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
__FILE__, __LINE__, __FUNCTION__); __FILE__, __LINE__, __FUNCTION__);
entity->common.stats.rxsdu_dd_pkts++;
entity->common.stats.rxsdu_dd_bytes += size;
return; return;
} }
......
...@@ -179,6 +179,9 @@ static void reassemble_and_deliver(nr_rlc_entity_um_t *entity, int sn) ...@@ -179,6 +179,9 @@ static void reassemble_and_deliver(nr_rlc_entity_um_t *entity, int sn)
entity->common.deliver_sdu(entity->common.deliver_sdu_data, entity->common.deliver_sdu(entity->common.deliver_sdu_data,
(nr_rlc_entity_t *)entity, (nr_rlc_entity_t *)entity,
sdu, so); sdu, so);
entity->common.stats.txsdu_pkts++;
entity->common.stats.txsdu_bytes += so;
} }
static void reception_actions(nr_rlc_entity_um_t *entity, nr_rlc_pdu_t *pdu) static void reception_actions(nr_rlc_entity_um_t *entity, nr_rlc_pdu_t *pdu)
...@@ -208,6 +211,15 @@ static void reception_actions(nr_rlc_entity_um_t *entity, nr_rlc_pdu_t *pdu) ...@@ -208,6 +211,15 @@ static void reception_actions(nr_rlc_entity_um_t *entity, nr_rlc_pdu_t *pdu)
nr_rlc_pdu_t *p = entity->rx_list; nr_rlc_pdu_t *p = entity->rx_list;
entity->rx_size -= p->size; entity->rx_size -= p->size;
entity->rx_list = p->next; entity->rx_list = p->next;
entity->common.stats.rxpdu_dd_pkts++;
/* we don't count PDU header bytes here, so be it */
entity->common.stats.rxpdu_dd_bytes += p->size;
entity->common.stats.rxpdu_ow_pkts++;
/* we don't count PDU header bytes here, so be it */
entity->common.stats.rxpdu_ow_bytes += p->size;
nr_rlc_free_pdu(p); nr_rlc_free_pdu(p);
} }
...@@ -272,6 +284,9 @@ void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *_entity, ...@@ -272,6 +284,9 @@ void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *_entity,
int is_first; int is_first;
int is_last; int is_last;
entity->common.stats.rxpdu_pkts++;
entity->common.stats.rxpdu_bytes += size;
nr_rlc_pdu_decoder_init(&decoder, buffer, size); nr_rlc_pdu_decoder_init(&decoder, buffer, size);
si = nr_rlc_pdu_decoder_get_bits(&decoder, 2); R(decoder); si = nr_rlc_pdu_decoder_get_bits(&decoder, 2); R(decoder);
...@@ -290,6 +305,10 @@ void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *_entity, ...@@ -290,6 +305,10 @@ void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *_entity,
entity->common.deliver_sdu(entity->common.deliver_sdu_data, entity->common.deliver_sdu(entity->common.deliver_sdu_data,
(nr_rlc_entity_t *)entity, (nr_rlc_entity_t *)entity,
buffer + 1, size - 1); buffer + 1, size - 1);
entity->common.stats.txsdu_pkts++;
entity->common.stats.txsdu_bytes += size - 1;
return; return;
} }
...@@ -350,6 +369,9 @@ err: ...@@ -350,6 +369,9 @@ err:
goto discard; goto discard;
discard: discard:
entity->common.stats.rxpdu_dd_pkts++;
entity->common.stats.rxpdu_dd_bytes += size;
return; return;
#undef R #undef R
...@@ -434,6 +456,8 @@ static nr_rlc_sdu_segment_t *resegment(nr_rlc_sdu_segment_t *sdu, ...@@ -434,6 +456,8 @@ static nr_rlc_sdu_segment_t *resegment(nr_rlc_sdu_segment_t *sdu,
next->so = sdu->so + sdu->size; next->so = sdu->so + sdu->size;
next->is_first = 0; next->is_first = 0;
entity->common.stats.txpdu_segmented++;
return next; return next;
} }
...@@ -478,6 +502,8 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size) ...@@ -478,6 +502,8 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size)
entity->tx_list = next_sdu; entity->tx_list = next_sdu;
if (entity->tx_end == NULL) if (entity->tx_end == NULL)
entity->tx_end = entity->tx_list; entity->tx_end = entity->tx_list;
entity->common.stats.txpdu_segmented++;
/* update buffer status */ /* update buffer status */
entity->common.bstatus.tx_size += compute_pdu_header_size(entity, next_sdu) entity->common.bstatus.tx_size += compute_pdu_header_size(entity, next_sdu)
+ next_sdu->size; + next_sdu->size;
...@@ -492,6 +518,11 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size) ...@@ -492,6 +518,11 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size)
entity->tx_size -= sdu->size; entity->tx_size -= sdu->size;
nr_rlc_free_sdu_segment(sdu); nr_rlc_free_sdu_segment(sdu);
entity->common.stats.txpdu_pkts++;
entity->common.stats.txpdu_bytes += size;
return ret; return ret;
} }
...@@ -527,6 +558,9 @@ void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity, ...@@ -527,6 +558,9 @@ void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity,
nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity;
nr_rlc_sdu_segment_t *sdu; nr_rlc_sdu_segment_t *sdu;
entity->common.stats.rxsdu_pkts++;
entity->common.stats.rxsdu_bytes += size;
if (size > NR_SDU_MAX) { if (size > NR_SDU_MAX) {
LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n", LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n",
__FILE__, __LINE__, __FUNCTION__, size); __FILE__, __LINE__, __FUNCTION__, size);
...@@ -536,6 +570,10 @@ void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity, ...@@ -536,6 +570,10 @@ void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity,
if (entity->tx_size + size > entity->tx_maxsize) { if (entity->tx_size + size > entity->tx_maxsize) {
LOG_W(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n", LOG_W(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
__FILE__, __LINE__, __FUNCTION__); __FILE__, __LINE__, __FUNCTION__);
entity->common.stats.rxsdu_dd_pkts++;
entity->common.stats.rxsdu_dd_bytes += size;
return; return;
} }
...@@ -584,6 +622,11 @@ static void check_t_reassembly(nr_rlc_entity_um_t *entity) ...@@ -584,6 +622,11 @@ static void check_t_reassembly(nr_rlc_entity_um_t *entity)
nr_rlc_pdu_t *p = cur; nr_rlc_pdu_t *p = cur;
cur = cur->next; cur = cur->next;
entity->rx_list = cur; entity->rx_list = cur;
entity->common.stats.rxpdu_dd_pkts++;
/* we don't count PDU header bytes here, so be it */
entity->common.stats.rxpdu_dd_bytes += p->size;
nr_rlc_free_pdu(p); nr_rlc_free_pdu(p);
} }
......
...@@ -1110,3 +1110,39 @@ void rlc_tick(int a, int b) ...@@ -1110,3 +1110,39 @@ void rlc_tick(int a, int b)
__FILE__, __LINE__, __FUNCTION__); __FILE__, __LINE__, __FUNCTION__);
exit(1); exit(1);
} }
/* returns 0 in case of error, 1 if everything ok */
int const nr_rlc_get_statistics(
int rnti,
int srb_flag,
int rb_id,
nr_rlc_statistics_t *out)
{
nr_rlc_ue_t *ue;
nr_rlc_entity_t *rb;
int ret;
nr_rlc_manager_lock(nr_rlc_ue_manager);
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
rb = NULL;
if (srb_flag) {
if (rb_id >= 1 && rb_id <= 2)
rb = ue->srb[rb_id - 1];
} else {
if (rb_id >= 1 && rb_id <= 5)
rb = ue->drb[rb_id - 1];
}
if (rb != NULL) {
rb->get_stats(rb, out);
ret = 1;
} else {
ret = 0;
}
nr_rlc_manager_unlock(nr_rlc_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