Commit a35865b7 authored by Cedric Roux's avatar Cedric Roux

Merge remote-tracking branch 'internal/mobipass-standalone' into develop_integration_w34

parents cdcc1d54 f38572b4
...@@ -532,6 +532,19 @@ set(TPLIB_ETHERNET_SOURCE ...@@ -532,6 +532,19 @@ set(TPLIB_ETHERNET_SOURCE
) )
add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} ) add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/mobipass/")
set(TPLIB_MOBIPASS_SOURCE
${OPENAIR_TARGETS}/ARCH/mobipass/interface.c
${OPENAIR_TARGETS}/ARCH/mobipass/mobipass.c
${OPENAIR_TARGETS}/ARCH/mobipass/queues.c
)
add_library(oai_mobipass MODULE ${TPLIB_MOBIPASS_SOURCE} )
# Hide all functions/variables in the mobipass library.
# Use __attribute__((__visibility__("default")))
# in the source code to unhide a function/variable.
get_target_property(mobipas_cflags oai_mobipass COMPILE_FLAGS)
set_target_properties(oai_mobipass PROPERTIES COMPILE_FLAGS "${mobipass_cflags} -fvisibility=hidden")
########################################################## ##########################################################
......
...@@ -181,63 +181,114 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe ...@@ -181,63 +181,114 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe
} }
} }
} else if (packet_type == IF5_MOBIPASS) { } else if (packet_type == IF5_MOBIPASS) {
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES; /* the only difference between mobipass standalone and the other one
* is the timestamp in trx_write_func, but let's duplicate anyway
__m128i *data_block=NULL, *data_block_head=NULL; * (plus we don't call malloc for the standalone case)
*/
if (eNB->node_timing == synch_to_mobipass_standalone) {
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
__m128i *txp128; __m128i *data_block=NULL, *data_block_head=NULL;
__m128i t0, t1; __m128i *txp128;
__m128i t0, t1;
// tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); unsigned char _tx_buffer[MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)];
tx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); tx_buffer=(int32_t *)_tx_buffer;
IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block_head = (__m128i *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t); IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block_head = (__m128i *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
header->flags = 0;
header->fifo_status = 0; header->flags = 0;
header->seqno = *seqno; header->fifo_status = 0;
header->ack = 0; header->seqno = *seqno;
header->word0 = 0; header->ack = 0;
header->word0 = 0;
txp[0] = (void*)&eNB->common_vars.txdata[0][0][subframe*eNB->frame_parms.samples_per_tti];
txp128 = (__m128i *) txp[0]; txp[0] = (void*)&eNB->common_vars.txdata[0][0][subframe*eNB->frame_parms.samples_per_tti];
txp128 = (__m128i *) txp[0];
for (packet_id=0; packet_id<fp->samples_per_tti/db_fulllength; packet_id++) {
header->time_stamp = htonl((uint32_t)(proc_timestamp + packet_id*db_fulllength)); for (packet_id=0; packet_id<fp->samples_per_tti/db_fulllength; packet_id++) {
data_block = data_block_head; header->time_stamp = htonl((uint32_t)(proc_timestamp + packet_id*db_fulllength));
data_block = data_block_head;
for (i=0; i<db_fulllength>>2; i+=2) {
t0 = _mm_srai_epi16(*txp128++, 4); for (i=0; i<db_fulllength>>2; i+=2) {
t1 = _mm_srai_epi16(*txp128++, 4); t0 = _mm_srai_epi16(*txp128++, 4);
// *data_block++ = _mm_packs_epi16(t0, t1); t1 = _mm_srai_epi16(*txp128++, 4);
_mm_storeu_si128(data_block++, _mm_packs_epi16(t0, t1)); _mm_storeu_si128(data_block++, _mm_packs_epi16(t0, t1));
}
// Write the packet to the fronthaul
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
proc_timestamp + packet_id*db_fulllength,
(void**)&tx_buffer,
db_fulllength,
1,
IF5_MOBIPASS)) < 0) {
perror("ETHERNET write for IF5_MOBIPASS\n");
}
header->seqno += 1;
} }
*seqno = header->seqno;
tx_buffer = NULL;
} else {
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
// Write the packet to the fronthaul __m128i *data_block=NULL, *data_block_head=NULL;
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
packet_id, __m128i *txp128;
(void**)&tx_buffer, __m128i t0, t1;
db_fulllength,
1, // tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
IF5_MOBIPASS)) < 0) { tx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
perror("ETHERNET write for IF5_MOBIPASS\n"); IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES);
} data_block_head = (__m128i *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
header->flags = 0;
header->fifo_status = 0;
header->seqno = *seqno;
header->ack = 0;
header->word0 = 0;
txp[0] = (void*)&eNB->common_vars.txdata[0][0][subframe*eNB->frame_parms.samples_per_tti];
txp128 = (__m128i *) txp[0];
for (packet_id=0; packet_id<fp->samples_per_tti/db_fulllength; packet_id++) {
header->time_stamp = htonl((uint32_t)(proc_timestamp + packet_id*db_fulllength));
data_block = data_block_head;
for (i=0; i<db_fulllength>>2; i+=2) {
t0 = _mm_srai_epi16(*txp128++, 4);
t1 = _mm_srai_epi16(*txp128++, 4);
// *data_block++ = _mm_packs_epi16(t0, t1);
_mm_storeu_si128(data_block++, _mm_packs_epi16(t0, t1));
}
// Write the packet to the fronthaul
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
packet_id,
(void**)&tx_buffer,
db_fulllength,
1,
IF5_MOBIPASS)) < 0) {
perror("ETHERNET write for IF5_MOBIPASS\n");
}
#ifdef DEBUG_DL_MOBIPASS #ifdef DEBUG_DL_MOBIPASS
if ((subframe==0)&&(dummy_cnt == 100)) { if ((subframe==0)&&(dummy_cnt == 100)) {
memcpy((void*)&dummy_buffer[packet_id*db_fulllength*2],(void*)data_block_head,db_fulllength*2); memcpy((void*)&dummy_buffer[packet_id*db_fulllength*2],(void*)data_block_head,db_fulllength*2);
} }
#endif #endif
header->seqno += 1; header->seqno += 1;
} }
*seqno = header->seqno; *seqno = header->seqno;
#ifdef DEBUG_DL_MOBIPASS #ifdef DEBUG_DL_MOBIPASS
uint8_t txe; uint8_t txe;
txe = dB_fixed(signal_energy(txp[0],fp->samples_per_tti)); txe = dB_fixed(signal_energy(txp[0],fp->samples_per_tti));
if (txe > 0){ if (txe > 0){
LOG_D(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, txe); LOG_D(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, txe);
} }
#endif #endif
}
} else { } else {
AssertFatal(1==0, "send_IF5 - Unknown packet_type %x", packet_type); AssertFatal(1==0, "send_IF5 - Unknown packet_type %x", packet_type);
} }
...@@ -391,131 +442,176 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram ...@@ -391,131 +442,176 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram
*proc_timestamp = timestamp[0]; *proc_timestamp = timestamp[0];
} else if (packet_type == IF5_MOBIPASS) { } else if (packet_type == IF5_MOBIPASS) {
if (eNB->node_timing == synch_to_mobipass_standalone) {
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES; uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength]; openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
int subframe_skip = 0;
int reset_flag = 0;
int32_t *rx_buffer=NULL;
__m128i *data_block=NULL, *data_block_head=NULL;
__m128i *rxp128;
__m128i r0;
unsigned char _rx_buffer[MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)];
rx_buffer = (int32_t *)_rx_buffer;
IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES);
data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti];
rxp128 = (__m128i *) (rxp[0]);
eNB_proc_t *proc = &eNB->proc;
packet_id=0;
while(packet_id<fp->samples_per_tti/db_fulllength) {
data_block = data_block_head;
eNB->ifdevice.trx_read_func(&eNB->ifdevice,
&timestamp_mobipass[packet_id],
(void**)&rx_buffer,
db_fulllength,
1
);
//store rxdata and increase packet_id
rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength];
rxp128 = (__m128i *) (rxp[0]);
for (i=0; i<db_fulllength>>2; i+=2) {
r0 = _mm_loadu_si128(data_block++);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
}
packet_id++;
}//end while
*proc_timestamp = ntohl(timestamp_mobipass[0]);
} else {
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
#ifdef DEBUG_UL_MOBIPASS #ifdef DEBUG_UL_MOBIPASS
int lower_offset = 0; int lower_offset = 0;
int upper_offset = 70000; int upper_offset = 70000;
#endif #endif
int subframe_skip = 0; int subframe_skip = 0;
int reset_flag = 0; int reset_flag = 0;
int32_t *rx_buffer=NULL; int32_t *rx_buffer=NULL;
__m128i *data_block=NULL, *data_block_head=NULL; __m128i *data_block=NULL, *data_block_head=NULL;
__m128i *rxp128; __m128i *rxp128;
__m128i r0; __m128i r0;
//rx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); //rx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
rx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); rx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES); IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES);
data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t); data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti]; rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti];
rxp128 = (__m128i *) (rxp[0]); rxp128 = (__m128i *) (rxp[0]);
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
/* /*
// while(packet_id<fp->samples_per_tti/db_fulllength) { // while(packet_id<fp->samples_per_tti/db_fulllength) {
data_block = data_block_head; data_block = data_block_head;
eNB->ifdevice.trx_read_func(&eNB->ifdevice,
&ts0,
(void**)&rx_buffer,
db_fulllength,
1
);
if ((header->seqno == 1)&&(first_packet==1)) {
first_packet = 0; //ignore the packets before synchnorization
packet_id = 0;
ts_offset = ntohl(ts0);
}
if (first_packet==0) {
packet_cnt++;
ts = ntohl(ts0);
packet_id = (ts-ts_offset)/db_fulllength;
packet_id = packet_id % (fp->samples_per_tti/db_fulllength);
printf("[IF5_tools]packet_id:%d\n", packet_id);
// if (ts_stored == 0) {
// ts_stored = 1;
*proc_timestamp = ntohl(ts - (packet_id*db_fulllength));
// }
rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength];
rxp128 = (__m128i *) (rxp[0]);
for (i=0; i<db_fulllength>>2; i+=2) { eNB->ifdevice.trx_read_func(&eNB->ifdevice,
r0 = _mm_loadu_si128(data_block++); &ts0,
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4); (void**)&rx_buffer,
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4); db_fulllength,
1
);
if ((header->seqno == 1)&&(first_packet==1)) {
first_packet = 0; //ignore the packets before synchnorization
packet_id = 0;
ts_offset = ntohl(ts0);
}
if (first_packet==0) {
packet_cnt++;
ts = ntohl(ts0);
packet_id = (ts-ts_offset)/db_fulllength;
packet_id = packet_id % (fp->samples_per_tti/db_fulllength);
printf("[IF5_tools]packet_id:%d\n", packet_id);
// if (ts_stored == 0) {
// ts_stored = 1;
*proc_timestamp = ntohl(ts - (packet_id*db_fulllength));
// }
rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength];
rxp128 = (__m128i *) (rxp[0]);
for (i=0; i<db_fulllength>>2; i+=2) {
r0 = _mm_loadu_si128(data_block++);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
}
} }
} // }//end while
// }//end while
*/ */
packet_id=0; packet_id=0;
while(packet_id<fp->samples_per_tti/db_fulllength) { while(packet_id<fp->samples_per_tti/db_fulllength) {
data_block = data_block_head; data_block = data_block_head;
eNB->ifdevice.trx_read_func(&eNB->ifdevice, eNB->ifdevice.trx_read_func(&eNB->ifdevice,
&timestamp_mobipass[packet_id], &timestamp_mobipass[packet_id],
(void**)&rx_buffer, (void**)&rx_buffer,
db_fulllength, db_fulllength,
1 1
); );
#ifdef DEBUG_UL_MOBIPASS #ifdef DEBUG_UL_MOBIPASS
if (((proc->timestamp_tx + lower_offset) > ntohl(timestamp_mobipass[packet_id])) || ((proc->timestamp_tx + upper_offset) < ntohl(timestamp_mobipass[packet_id]))) { if (((proc->timestamp_tx + lower_offset) > ntohl(timestamp_mobipass[packet_id])) || ((proc->timestamp_tx + upper_offset) < ntohl(timestamp_mobipass[packet_id]))) {
//ignore the packet //ignore the packet
subframe_skip_extra = (subframe_skip_extra + 1)%67; subframe_skip_extra = (subframe_skip_extra + 1)%67;
LOG_D("[Mobipass] ignored packet, id:[%d,%d], proc->timestamp_tx:%llu, proc->timestamp_rx:%llu, seqno:%d\n", packet_id,subframe_skip_extra, proc->timestamp_tx, ntohl(timestamp_mobipass[packet_id]), header->seqno); LOG_D("[Mobipass] ignored packet, id:[%d,%d], proc->timestamp_tx:%llu, proc->timestamp_rx:%llu, seqno:%d\n", packet_id,subframe_skip_extra, proc->timestamp_tx, ntohl(timestamp_mobipass[packet_id]), header->seqno);
} }
#endif #endif
//skip SUBFRAME_SKIP_NUM_MOBIPASS additional UL packets //skip SUBFRAME_SKIP_NUM_MOBIPASS additional UL packets
if ((start_flag == 1) && (subframe_skip < SUBFRAME_SKIP_NUM_MOBIPASS)){ if ((start_flag == 1) && (subframe_skip < SUBFRAME_SKIP_NUM_MOBIPASS)){
subframe_skip++; subframe_skip++;
offset_cnt = header->seqno; offset_cnt = header->seqno;
} else { } else {
if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){ if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){
#ifdef DEBUG_UL_MOBIPASS #ifdef DEBUG_UL_MOBIPASS
LOG_D(PHY,"[Mobipass] Reset sequence number, offset_cnt:%d, header->seqno:%d, packet_id:%d\n", offset_cnt, header->seqno, packet_id); LOG_D(PHY,"[Mobipass] Reset sequence number, offset_cnt:%d, header->seqno:%d, packet_id:%d\n", offset_cnt, header->seqno, packet_id);
#endif #endif
reset_flag=1; reset_flag=1;
} }
if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) { if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) {
packet_id = 1; packet_id = 1;
reset_flag = 0; reset_flag = 0;
}
start_flag = 0;
//store rxdata and increase packet_id
rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength];
rxp128 = (__m128i *) (rxp[0]);
for (i=0; i<db_fulllength>>2; i+=2) {
r0 = _mm_loadu_si128(data_block++);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
}
packet_id++;
offset_cnt = (header->seqno+1)&255;
} }
start_flag = 0; }//end while
//store rxdata and increase packet_id *proc_timestamp = ntohl(timestamp_mobipass[0]);
rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength];
rxp128 = (__m128i *) (rxp[0]);
for (i=0; i<db_fulllength>>2; i+=2) {
r0 = _mm_loadu_si128(data_block++);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
}
packet_id++;
offset_cnt = (header->seqno+1)&255;
}
}//end while
*proc_timestamp = ntohl(timestamp_mobipass[0]);
#ifdef DEBUG_UL_MOBIPASS #ifdef DEBUG_UL_MOBIPASS
LOG_I(PHY,"[Mobipass][Recv_MOBIPASS] timestamp: %llu\n ", *proc_timestamp); LOG_I(PHY,"[Mobipass][Recv_MOBIPASS] timestamp: %llu\n ", *proc_timestamp);
if (eNB->CC_id>0) { if (eNB->CC_id>0) {
rxe = dB_fixed(signal_energy(rxp[0],fp->samples_per_tti)); rxe = dB_fixed(signal_energy(rxp[0],fp->samples_per_tti));
if (rxe > 0){ if (rxe > 0){
LOG_I(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (*proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, rxe); LOG_I(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (*proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, rxe);
// write_output("rxsigmb.m","rxs",(void*)dummy_buffer_rx, fp->samples_per_tti,1, 5); // write_output("rxsigmb.m","rxs",(void*)dummy_buffer_rx, fp->samples_per_tti,1, 5);
// exit(-1); // exit(-1);
} }
} }
#endif #endif
}
} else { } else {
AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type); AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type);
} }
......
...@@ -165,8 +165,9 @@ typedef enum { ...@@ -165,8 +165,9 @@ typedef enum {
} eNB_func_t; } eNB_func_t;
typedef enum { typedef enum {
synch_to_ext_device=0, // synch to RF or Ethernet device synch_to_ext_device=0, // synch to RF or Ethernet device
synch_to_other // synch to another source (timer, other CC_id) synch_to_other, // synch to another source (timer, other CC_id)
synch_to_mobipass_standalone // special case for mobipass in standalone mode
} eNB_timing_t; } eNB_timing_t;
#endif #endif
......
...@@ -947,6 +947,8 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) ...@@ -947,6 +947,8 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
enb_properties.properties[enb_properties_index]->cc_node_timing[j] = synch_to_ext_device; enb_properties.properties[enb_properties_index]->cc_node_timing[j] = synch_to_ext_device;
} else if (strcmp(cc_node_timing, "synch_to_other") == 0) { } else if (strcmp(cc_node_timing, "synch_to_other") == 0) {
enb_properties.properties[enb_properties_index]->cc_node_timing[j] = synch_to_other; enb_properties.properties[enb_properties_index]->cc_node_timing[j] = synch_to_other;
} else if (strcmp(cc_node_timing, "synch_to_mobipass_standalone") == 0) {
enb_properties.properties[enb_properties_index]->cc_node_timing[j] = synch_to_mobipass_standalone;
} else { } else {
AssertError (0, parse_errors ++, AssertError (0, parse_errors ++,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for node_function choice: SYNCH_TO_DEVICE or SYNCH_TO_OTHER !\n", "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for node_function choice: SYNCH_TO_DEVICE or SYNCH_TO_OTHER !\n",
......
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <unistd.h>
#include <errno.h>
#include <linux/sysctl.h>
#include <sys/sysctl.h>
#include "common_lib.h"
#include "ethernet_lib.h"
#include "mobipass.h"
#include "queues.h"
struct mobipass_header {
uint16_t flags;
uint16_t fifo_status;
unsigned char seqno;
unsigned char ack;
uint32_t word0;
uint32_t timestamp;
} __attribute__((__packed__));
int mobipass_start(openair0_device *device) { init_mobipass(device->priv); return 0; }
int mobipass_request(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; }
int mobipass_reply(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; }
int mobipass_get_stats(openair0_device* device) { return 0; }
int mobipass_reset_stats(openair0_device* device) { return 0; }
void mobipass_end(openair0_device *device) {}
int mobipass_stop(openair0_device *device) { return 0; }
int mobipass_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { return 0; }
int mobipass_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) { return 0; }
int mobipass_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
mobipass_state_t *mobi = device->priv;
struct mobipass_header *mh = (struct mobipass_header *)(((char *)buff[0]) + 14);
mobi->mobipass_write_last_timestamp += 640;
mobi->mobipass_write_last_timestamp %= mobi->samples_per_1024_frames;
mh->timestamp = htonl(ntohl(mh->timestamp) % mobi->samples_per_1024_frames);
if (mobi->mobipass_write_last_timestamp != ntohl(mh->timestamp))
{ printf("mobipass: ERROR: bad timestamp wanted %d got %d\n", mobi->mobipass_write_last_timestamp, ntohl(mh->timestamp)); exit(1); }
//printf("__write nsamps %d timestamps %ld seqno %d (packet timestamp %d)\n", nsamps, timestamp, mh->seqno, ntohl(mh->timestamp));
if (nsamps != 640) abort();
enqueue_to_mobipass(mobi->qstate, buff[0]);
return nsamps;
}
int mobipass_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
mobipass_state_t *mobi = device->priv;
//printf("__read nsamps %d return timestamp %d\n", nsamps, ts);
*timestamp = htonl(mobi->mobipass_read_ts);
mobi->mobipass_read_ts += nsamps;
mobi->mobipass_read_ts %= mobi->samples_per_1024_frames;
if (nsamps != 640) { printf("mobipass: ERROR: bad nsamps %d, should be 640\n", nsamps); fflush(stdout); abort(); }
dequeue_from_mobipass(mobi->qstate, ntohl(*timestamp), buff[0]);
#if 1
struct mobipass_header *mh = (struct mobipass_header *)(((char *)buff[0]) + 14);
mh->flags = 0;
mh->fifo_status = 0;
mh->seqno = mobi->mobipass_read_seqno++;
mh->ack = 0;
mh->word0 = 0;
mh->timestamp = htonl(mobi->mobipass_read_ts);
#endif
return nsamps;
}
/* this is the only function in the library that is visible from outside
* because in CMakeLists.txt we use -fvisibility=hidden
*/
__attribute__((__visibility__("default")))
int transport_init(openair0_device *device, openair0_config_t *openair0_cfg,
eth_params_t * eth_params )
{
//init_mobipass();
mobipass_state_t *mobi = (mobipass_state_t*)malloc(sizeof(mobipass_state_t));
memset(mobi, 0, sizeof(mobipass_state_t));
if (eth_params->transp_preference != 4) goto err;
if (eth_params->if_compress != 0) goto err;
/* only 50 PRBs handled for the moment */
if (openair0_cfg[0].sample_rate != 15360000) {
printf("mobipass: ERROR: only 50 PRBs supported\n");
exit(1);
}
mobi->eth.flags = ETH_RAW_IF5_MOBIPASS;
mobi->eth.compression = NO_COMPRESS;
device->Mod_id = 0;//num_devices_eth++;
device->transp_type = ETHERNET_TP;
device->trx_start_func = mobipass_start;
device->trx_request_func = mobipass_request;
device->trx_reply_func = mobipass_reply;
device->trx_get_stats_func = mobipass_get_stats;
device->trx_reset_stats_func = mobipass_reset_stats;
device->trx_end_func = mobipass_end;
device->trx_stop_func = mobipass_stop;
device->trx_set_freq_func = mobipass_set_freq;
device->trx_set_gains_func = mobipass_set_gains;
device->trx_write_func = mobipass_write;
device->trx_read_func = mobipass_read;
device->priv = mobi;
mobi->eth.if_name = strdup(eth_params->local_if_name);
if (mobi->eth.if_name == NULL) abort();
if (sscanf(eth_params->my_addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&mobi->eth_local[0],
&mobi->eth_local[1],
&mobi->eth_local[2],
&mobi->eth_local[3],
&mobi->eth_local[4],
&mobi->eth_local[5]) != 6) {
printf("mobipass: ERROR: bad local ethernet address '%s', check configuration file\n",
eth_params->my_addr);
exit(1);
}
if (sscanf(eth_params->remote_addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&mobi->eth_remote[0],
&mobi->eth_remote[1],
&mobi->eth_remote[2],
&mobi->eth_remote[3],
&mobi->eth_remote[4],
&mobi->eth_remote[5]) != 6) {
printf("mobipass: ERROR: bad remote ethernet address '%s', check configuration file\n",
eth_params->remote_addr);
exit(1);
}
/* note: this only works for 50 PRBs */
mobi->samples_per_1024_frames = 7680*2*10*1024;
/* TX starts at subframe 4, let's pretend we are at the right position */
/* note: this only works for 50 PRBs */
mobi->mobipass_write_last_timestamp = 4*7680*2-640;
/* device specific */
openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
openair0_cfg[0].iq_txshift = eth_params->iq_txshift;// shift
openair0_cfg[0].tx_sample_advance = eth_params->tx_sample_advance;
/* this is useless, I think */
if (device->host_type == BBU_HOST) {
/*Note scheduling advance values valid only for case 7680000 */
switch ((int)openair0_cfg[0].sample_rate) {
case 30720000:
openair0_cfg[0].samples_per_packet = 3840;
break;
case 23040000:
openair0_cfg[0].samples_per_packet = 2880;
break;
case 15360000:
openair0_cfg[0].samples_per_packet = 1920;
break;
case 7680000:
openair0_cfg[0].samples_per_packet = 960;
break;
case 1920000:
openair0_cfg[0].samples_per_packet = 240;
break;
default:
printf("mobipass: ERROR: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
exit(-1);
break;
}
}
device->openair0_cfg=&openair0_cfg[0];
return 0;
err:
printf("mobipass: ERROR: bad configuration file?\n");
exit(1);
}