Commit f49805d2 authored by Joanne Hugé's avatar Joanne Hugé

WIP: One Way Delay Measure

parent d430eca0
...@@ -100,8 +100,10 @@ typedef struct { ...@@ -100,8 +100,10 @@ typedef struct {
int flow_id; int flow_id;
int start_receiving; int start_receiving;
int master; int master;
int generic_data_sync;
int trx_read_null; int trx_read_null;
int one_way_measure;
int one_way_period;
int tdd_frame_start;
} TRXEcpriState; } TRXEcpriState;
typedef struct { typedef struct {
...@@ -141,6 +143,10 @@ static ring_buffer_t tx_rbuf; // Packets to send ...@@ -141,6 +143,10 @@ static ring_buffer_t tx_rbuf; // Packets to send
static ring_buffer_t trxw_rbuf[4]; // Uncompressed IQ samples static ring_buffer_t trxw_rbuf[4]; // Uncompressed IQ samples
static ring_buffer_t trxw_group_rbuf; // Group of IQ samples static ring_buffer_t trxw_group_rbuf; // Group of IQ samples
static ring_buffer_t one_way_rbuf; // One way delay measurements
static volatile uint64_t one_way_timestamp;
// Counters // Counters
static volatile counter_stat_t recv_counter; // frames received from eRE static volatile counter_stat_t recv_counter; // frames received from eRE
static volatile counter_stat_t decode_counter; // decoded frames static volatile counter_stat_t decode_counter; // decoded frames
...@@ -704,17 +710,30 @@ static void *send_thread(void *p) { ...@@ -704,17 +710,30 @@ static void *send_thread(void *p) {
pthread_exit(EXIT_SUCCESS); pthread_exit(EXIT_SUCCESS);
} }
static void encode_empty_frames(int n, int tx_n_channel, int trx, int tdd_period) { static int one_way_delay_measure(uint8_t ** buf) {
struct timespec t;
clock_gettime(CLOCK_TAI, &t);
one_way_timestamp = ts_to_int(t);
*( (*buf - 7)) = 3; // eCPRI Type
*( (*buf - 4)) = 0; // Measurement ID
*( (*buf - 3)) = 0; // Action Type
*((uint64_t *)(*buf - 2)) = one_way_timestamp; // Timestamp
*((uint64_t *)(*buf + 7)) = 0; // Compensation
*buf += tx_rbuf.len;
return 1;
}
static void encode_empty_frames(int n, int trx, TRXEcpriState * s) {
uint8_t * buf = RBUF_WRITE0(tx_rbuf, uint8_t) + 8; uint8_t * buf = RBUF_WRITE0(tx_rbuf, uint8_t) + 8;
int n2 = n; int n2 = n;
for(int i = 0; i < n; i++) { for(int i = 0; i < n; i++) {
//if(trx && !((trx_encode_counter.counter + i) % tdd_period)) { // ONE WAY DELAY MEASURE
// *(buf - 7) = 3; if(s->one_way_measure && (encode_counter.counter + i) % s->one_way_period)
// *((uint16_t *)(buf - 2)) = htons(tx_seq_id++); n2 += one_way_delay_measure(&buf);
// buf += tx_rbuf.len; // TDD FRAME START
// n2++; if(s->tdd_frame_start)
//} *((uint8_t *)(buf + 60 * s->tx_n_channel)) = (trx && !((trx_encode_counter.counter + i) % s->tdd_period));
memset(buf, 0x00, 60 * tx_n_channel); memset(buf, 0x00, 60 * s->tx_n_channel);
*((uint16_t *)(buf - 2)) = htons(tx_seq_id++); *((uint16_t *)(buf - 2)) = htons(tx_seq_id++);
buf += tx_rbuf.len; buf += tx_rbuf.len;
} }
...@@ -722,27 +741,27 @@ static void encode_empty_frames(int n, int tx_n_channel, int trx, int tdd_period ...@@ -722,27 +741,27 @@ static void encode_empty_frames(int n, int tx_n_channel, int trx, int tdd_period
if(trx) if(trx)
trxw_rbuf[0].read_index = (trxw_rbuf[0].read_index + n) % trxw_rbuf[0].buf_len; trxw_rbuf[0].read_index = (trxw_rbuf[0].read_index + n) % trxw_rbuf[0].buf_len;
} }
static void encode_trx_frames(int n, int tx_n_channel, int tdd_period) { static void encode_trx_frames(int n, TRXEcpriState * s) {
int nc; int nc;
int nf = n; int nf = n;
while((nc = rbuf_contiguous_copy(&trxw_rbuf[0], &tx_rbuf, nf))) { while((nc = rbuf_contiguous_copy(&trxw_rbuf[0], &tx_rbuf, nf))) {
Complex * iq_samples[4]; Complex * iq_samples[4];
uint8_t * buf = RBUF_WRITE0(tx_rbuf, uint8_t) + 8; uint8_t * buf = RBUF_WRITE0(tx_rbuf, uint8_t) + 8;
int nc2 = nc; int nc2 = nc;
for(int j = 0; j < tx_n_channel; j++) for(int j = 0; j < s->tx_n_channel; j++)
iq_samples[j] = ((Complex *) trxw_rbuf[j].buffer) + (trxw_rbuf[0].read_index * trxw_rbuf[0].len); iq_samples[j] = ((Complex *) trxw_rbuf[j].buffer) + (trxw_rbuf[0].read_index * trxw_rbuf[0].len);
for(int i = 0; i < nc; i++) { for(int i = 0; i < nc; i++) {
//if(!((trx_encode_counter.counter + i) % tdd_period)) { // ONE WAY DELAY MEASURE
// *(buf - 7) = 3; if(s->one_way_measure && (encode_counter.counter + i) % s->one_way_period)
// *((uint16_t *)(buf - 2)) = htons(tx_seq_id++); nc2 += one_way_delay_measure(&buf);
// buf += tx_rbuf.len; // TDD FRAME START
// nc2++; if(s->tdd_frame_start)
//} *((uint8_t *)(buf + 60 * s->tx_n_channel)) = (trx && !((trx_encode_counter.counter + i) % s->tdd_period));
for(int i = 0; i < tx_n_channel ; i++) for(int i = 0; i < s->tx_n_channel ; i++)
encode_s64_b60_2(buf + i * 60, (float *) iq_samples[i]); encode_s64_b60_2(buf + i * 60, (float *) iq_samples[i]);
*((uint16_t *)(buf - 2)) = htons(tx_seq_id++); *((uint16_t *)(buf - 2)) = htons(tx_seq_id++);
for(int j = 0; j < tx_n_channel; j++) for(int j = 0; j < s->tx_n_channel; j++)
iq_samples[j] += trxw_rbuf[0].len; iq_samples[j] += trxw_rbuf[0].len;
buf += tx_rbuf.len; buf += tx_rbuf.len;
} }
...@@ -781,9 +800,9 @@ int read_trx(int n_max, TRXEcpriState * s) { ...@@ -781,9 +800,9 @@ int read_trx(int n_max, TRXEcpriState * s) {
} }
if(g->zeroes) if(g->zeroes)
encode_empty_frames(n_trx, s->tx_n_channel, 1, s->tdd_period); encode_empty_frames(n_trx, 1, s);
else else
encode_trx_frames(n_trx, s->tx_n_channel, s->tdd_period); encode_trx_frames(n_trx, s);
if(!g->count) { if(!g->count) {
rbuf_update_read_index(&trxw_group_rbuf); rbuf_update_read_index(&trxw_group_rbuf);
...@@ -830,7 +849,7 @@ static void *encode_thread(void *p) { ...@@ -830,7 +849,7 @@ static void *encode_thread(void *p) {
n = rbuf_write_amount(&tx_rbuf); n = rbuf_write_amount(&tx_rbuf);
n_min = s->encode_burst; n_min = s->encode_burst;
n_min += s->generic_data_sync ? (s->encode_burst / s->tdd_period) + 1 : 0; n_min += s->one_way_measure ? (s->encode_burst / s->one_way_period) + 1 : 0;
if(s->master && n < n_min) if(s->master && n < n_min)
log_exit("ENCODE_THREAD", "Not enough space in TX RBUF (%d < %d)\n", n, s->encode_burst); log_exit("ENCODE_THREAD", "Not enough space in TX RBUF (%d < %d)\n", n, s->encode_burst);
...@@ -841,7 +860,7 @@ static void *encode_thread(void *p) { ...@@ -841,7 +860,7 @@ static void *encode_thread(void *p) {
if(s->master) { if(s->master) {
struct timespec current; struct timespec current;
n_empty = s->encode_burst - n_trx; n_empty = s->encode_burst - n_trx;
encode_empty_frames(n_empty, s->tx_n_channel, 0, s->tdd_period); encode_empty_frames(n_empty, 0, s);
target_counter += s->encode_burst; target_counter += s->encode_burst;
next = int_to_ts(initial_ts + target_counter * NSEC_PER_SEC / s->frame_frequency); next = int_to_ts(initial_ts + target_counter * NSEC_PER_SEC / s->frame_frequency);
do { do {
...@@ -902,6 +921,7 @@ static void *decode_thread(void *p) { ...@@ -902,6 +921,7 @@ static void *decode_thread(void *p) {
while((nc = rbuf_contiguous_copy(&rx_rbuf, &trxr_rbuf[0], n))) { while((nc = rbuf_contiguous_copy(&rx_rbuf, &trxr_rbuf[0], n))) {
uint8_t * buf = ((uint8_t *) rx_rbuf.buffer) + (rx_rbuf.read_index * rx_rbuf.len) + 22; uint8_t * buf = ((uint8_t *) rx_rbuf.buffer) + (rx_rbuf.read_index * rx_rbuf.len) + 22;
int one_way_count = 0;
if(s->trace_rx) { if(s->trace_rx) {
if(received_pkts && ((decode_counter.counter + nc) >= (trxr_rbuf[0].buf_len + s->trace_offset))) { if(received_pkts && ((decode_counter.counter + nc) >= (trxr_rbuf[0].buf_len + s->trace_offset))) {
...@@ -918,6 +938,15 @@ static void *decode_thread(void *p) { ...@@ -918,6 +938,15 @@ static void *decode_thread(void *p) {
iq_samples[i] = (((Complex *) trxr_rbuf[i].buffer) + (trxr_rbuf[0].write_index * trxr_rbuf[0].len)); iq_samples[i] = (((Complex *) trxr_rbuf[i].buffer) + (trxr_rbuf[0].write_index * trxr_rbuf[0].len));
for(int i = 0; i < nc; i++) { for(int i = 0; i < nc; i++) {
// ONE WAY MEASURE
if(s->one_way_measure && *((buf + i * rx_rbuf.len) - 7) == 3) {
uint64_t timestamp = (uint64_t) *(buf + 7);
*(RBUF_WRITE0(one_way_rbuf, int64_t)) = ((int64_t) timestamp) - ((int64_t) one_way_timestamp);
rbuf_update_write_index(&one_way_rbuf);
continue;
}
for(int j = 0; j < s->rx_n_channel ; j++) { for(int j = 0; j < s->rx_n_channel ; j++) {
decode_s64_b60_2((float *) (iq_samples[j] + i * 32), buf + j * 60 + i * rx_rbuf.len); decode_s64_b60_2((float *) (iq_samples[j] + i * 32), buf + j * 60 + i * rx_rbuf.len);
} }
...@@ -1168,8 +1197,8 @@ int startdpdk(TRXEcpriState * s) { ...@@ -1168,8 +1197,8 @@ int startdpdk(TRXEcpriState * s) {
init_counter(&sent_counter); init_counter(&sent_counter);
init_counter(&empty_encode_counter); init_counter(&empty_encode_counter);
RBUF_INIT(rx_rbuf, "RX ring buffer", s->txrx_buf_size, RX_MAX_PACKET_SIZE, uint8_t); RBUF_INIT(rx_rbuf, "RX ring buffer", s->txrx_buf_size, RX_MAX_PACKET_SIZE + s->one_way_measure, uint8_t);
RBUF_INIT(tx_rbuf, "TX ring buffer", s->txrx_buf_size, TX_ECPRI_PACKET_SIZE, uint8_t); RBUF_INIT(tx_rbuf, "TX ring buffer", s->txrx_buf_size, TX_ECPRI_PACKET_SIZE + s->one_way_measure, uint8_t);
for(int i = 0; i < s->tx_n_channel; i++) { for(int i = 0; i < s->tx_n_channel; i++) {
char name[256]; char name[256];
sprintf(name, "TRXWrite Ring Buffer %d", i); sprintf(name, "TRXWrite Ring Buffer %d", i);
...@@ -1182,6 +1211,8 @@ int startdpdk(TRXEcpriState * s) { ...@@ -1182,6 +1211,8 @@ int startdpdk(TRXEcpriState * s) {
} }
RBUF_INIT(trxw_group_rbuf, "TRXGroupWrite ring buffer", TRX_MAX_GROUP, 1, sample_group_t); RBUF_INIT(trxw_group_rbuf, "TRXGroupWrite ring buffer", TRX_MAX_GROUP, 1, sample_group_t);
RBUF_INIT(one_way_rbuf, "One-way ring buffer", 1024, 1, int64_t);
memset((uint8_t *) ecpri_message, 0, TX_ECPRI_PACKET_SIZE); memset((uint8_t *) ecpri_message, 0, TX_ECPRI_PACKET_SIZE);
#ifdef DPDK #ifdef DPDK
...@@ -1587,8 +1618,12 @@ int trx_driver_init(TRXState *s1) ...@@ -1587,8 +1618,12 @@ int trx_driver_init(TRXState *s1)
s->tx_n_channel = (int) val; s->tx_n_channel = (int) val;
trx_get_param_double(s1, &val, "master"); trx_get_param_double(s1, &val, "master");
s->master = (int) val; s->master = (int) val;
trx_get_param_double(s1, &val, "generic_data_sync"); trx_get_param_double(s1, &val, "one_way_measure");
s->generic_data_sync = (int) val; s->one_way_measure = (int) val;
trx_get_param_double(s1, &val, "one_way_period");
s->one_way_period = (int) val;
trx_get_param_double(s1, &val, "tdd_frame_start");
s->tdd_frame_start = (int) val;
trx_get_param_double(s1, &val, "trx_read_null"); trx_get_param_double(s1, &val, "trx_read_null");
s->trx_read_null = (int) val; s->trx_read_null = (int) val;
trx_get_param_double(s1, &val, "tdd_period"); trx_get_param_double(s1, &val, "tdd_period");
......
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