mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-19 07:30:31 +00:00
Compare commits
2 Commits
2017.w34
...
mobipass-h
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edb209f6e5 | ||
|
|
72e6e34f41 |
@@ -534,17 +534,12 @@ 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/main.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")
|
||||
|
||||
##########################################################
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -24;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -24;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -24;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -24;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -24;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -24;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -29;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -29;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -29;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -29;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -29;
|
||||
|
||||
@@ -47,7 +47,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -29;
|
||||
|
||||
@@ -555,7 +555,11 @@ check_install_oai_software() {
|
||||
|
||||
$SUDO update-alternatives --set liblapack.so /usr/lib/atlas-base/atlas/liblapack.so
|
||||
|
||||
#Remove old gnutls/nettle installation that was done from sources
|
||||
remove_nettle_from_source
|
||||
|
||||
$SUDO apt-get install -y nettle-dev nettle-bin
|
||||
remove_gnutls_from_source
|
||||
|
||||
$SUDO apt-get install -y libgnutls-dev
|
||||
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
|
||||
@@ -643,6 +647,56 @@ check_install_oai_software() {
|
||||
$SUDO git clone https://gist.github.com/2190472.git /opt/ssh
|
||||
}
|
||||
|
||||
### Remove Nettle installation which was done from sources (only done for Ubuntu Distro)
|
||||
remove_nettle_from_source() {
|
||||
nettle_uninstall_log=$OPENAIR_DIR/cmake_targets/log/nettle_uninstall_log.txt
|
||||
echo_info "\nUn-Installing Nettle from sources. The log file for nettle un-installation is here: $nettle_uninstall_log "
|
||||
(
|
||||
$SUDO apt-get remove -y nettle-dev nettle-bin
|
||||
cd /tmp
|
||||
echo "Downloading nettle archive"
|
||||
$SUDO rm -rf /tmp/nettle-2.5.tar.gz* /tmp/nettle-2.5
|
||||
wget https://ftp.gnu.org/gnu/nettle/nettle-2.5.tar.gz
|
||||
if [ $? -ne 0 ]; then
|
||||
wget ftp://ftp.lysator.liu.se/pub/security/lsh/nettle-2.5.tar.gz
|
||||
fi
|
||||
if [ ! -f nettle-2.5.tar.gz ]; then
|
||||
echo_error "Could not download nettle source files"
|
||||
cd -
|
||||
return
|
||||
fi
|
||||
tar -xzf nettle-2.5.tar.gz
|
||||
cd nettle-2.5/
|
||||
./configure --disable-openssl --enable-shared --prefix=/usr
|
||||
$SUDO make uninstall || true
|
||||
$SUDO ldconfig
|
||||
) >& $nettle_uninstall_log
|
||||
}
|
||||
|
||||
### Remove Gnutls from source (Only done for Ubuntu Distro)
|
||||
remove_gnutls_from_source(){
|
||||
gnutls_uninstall_log=$OPENAIR_DIR/cmake_targets/log/gnutls_uninstall_log.txt
|
||||
echo_info "\nUn-Installing Gnutls. The log file for Gnutls un-installation is here: $gnutls_uninstall_log "
|
||||
(
|
||||
$SUDO apt-get remove -y libgnutls-dev
|
||||
cd /tmp
|
||||
echo "Downloading gnutls archive"
|
||||
$SUDO rm -rf /tmp/gnutls-3.1.23.tar.xz* /tmp/gnutls-3.1.23
|
||||
wget http://mirrors.dotsrc.org/gcrypt/gnutls/v3.1/gnutls-3.1.23.tar.xz || \
|
||||
wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.1/gnutls-3.1.23.tar.xz
|
||||
if [ ! -f gnutls-3.1.23.tar.xz ]; then
|
||||
echo_error "Could not download gnutls source files"
|
||||
cd -
|
||||
return
|
||||
fi
|
||||
tar -xJf gnutls-3.1.23.tar.xz
|
||||
cd gnutls-3.1.23/
|
||||
./configure --prefix=/usr
|
||||
$SUDO make uninstall || true
|
||||
$SUDO ldconfig
|
||||
)>& $gnutls_uninstall_log
|
||||
}
|
||||
|
||||
install_asn1c_from_source(){
|
||||
asn1_install_log=$OPENAIR_DIR/cmake_targets/log/asn1c_install_log.txt
|
||||
echo_info "\nInstalling ASN1. The log file for ASN1 installation is here: $asn1_install_log "
|
||||
|
||||
@@ -29,10 +29,10 @@ typedef struct {
|
||||
#define T_SHM_FILENAME "/T_shm_segment"
|
||||
|
||||
/* number of VCD functions (to be kept up to date! see in T_messages.txt) */
|
||||
#define VCD_NUM_FUNCTIONS 172
|
||||
#define VCD_NUM_FUNCTIONS 142
|
||||
|
||||
/* number of VCD variables (to be kept up to date! see in T_messages.txt) */
|
||||
#define VCD_NUM_VARIABLES 118
|
||||
#define VCD_NUM_VARIABLES 107
|
||||
|
||||
/* first VCD function (to be kept up to date! see in T_messages.txt) */
|
||||
#define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP)
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
ID = MOBIPASS
|
||||
GROUP = ALL:GENERAL:ENB
|
||||
FORMAT = int,ts_high : int,ts_low
|
||||
ID = SUBFRAME
|
||||
GROUP = ALL:GENERAL:ENB
|
||||
FORMAT = int,frame : int,subframe : string,function
|
||||
|
||||
#general logs
|
||||
ID = ENB_MASTER_TICK
|
||||
DESC = eNodeB master tick - one tick per ms, to be used as "reference clock", mostly for ticktime view
|
||||
GROUP = ALL:GENERAL:ENB
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe
|
||||
|
||||
#PHY logs
|
||||
ID = ENB_PHY_UL_TICK
|
||||
DESC = eNodeB uplink tick - one tick per ms at start of uplink processing
|
||||
GROUP = ALL:PHY:GRAPHIC:ENB
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe
|
||||
ID = ENB_PHY_DL_TICK
|
||||
DESC = eNodeB downlink tick - one tick per ms at start of downlink processing
|
||||
GROUP = ALL:PHY:GRAPHIC:ENB
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe
|
||||
ID = ENB_PHY_DLSCH_UE_DCI
|
||||
DESC = eNodeB downlink UE specific DCI as sent by the PHY layer
|
||||
GROUP = ALL:PHY:GRAPHIC:ENB
|
||||
@@ -44,11 +51,7 @@ ID = ENB_PHY_ULSCH_UE_NACK
|
||||
ID = ENB_PHY_INPUT_SIGNAL
|
||||
DESC = eNodeB received signal in the time domain for a duration of 1ms
|
||||
GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,antenna : buffer,rxdata
|
||||
ID = ENB_PHY_OUTPUT_SIGNAL
|
||||
DESC = eNodeB sent signal in the time domain for a duration of 1ms
|
||||
GROUP = ALL:PHY:HEAVY:ENB
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe : int,antenna : buffer,txdata
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe : int,antenna : buffer,rxdata
|
||||
ID = ENB_PHY_UL_CHANNEL_ESTIMATE
|
||||
DESC = eNodeB channel estimation in the time domain
|
||||
GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
|
||||
@@ -115,10 +118,6 @@ ID = ENB_MAC_UE_DL_PDU_WITH_DATA
|
||||
DESC = MAC downlink PDU for an UE
|
||||
GROUP = ALL:MAC:ENB
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : buffer,data
|
||||
ID = ENB_MAC_SCHEDULING_REQUEST
|
||||
DESC = MAC scheduling request detected for an UE
|
||||
GROUP = ALL:MAC:ENB
|
||||
FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe : int,rnti
|
||||
|
||||
#RLC logs
|
||||
ID = ENB_RLC_DL
|
||||
@@ -1358,22 +1357,6 @@ ID = VCD_VARIABLE_UE0_SFN7
|
||||
DESC = VCD variable UE0_SFN7
|
||||
GROUP = ALL:VCD:ENB:VCD_VARIABLE
|
||||
FORMAT = ulong,value
|
||||
ID = VCD_VARIABLE_SEND_IF4_SYMBOL
|
||||
DESC = VCD variable SEND_IF4_SYMBOL
|
||||
GROUP = ALL:VCD:ENB:VCD_VARIABLE
|
||||
FORMAT = ulong,value
|
||||
ID = VCD_VARIABLE_RECV_IF4_SYMBOL
|
||||
DESC = VCD variable RECV_IF4_SYMBOL
|
||||
GROUP = ALL:VCD:ENB:VCD_VARIABLE
|
||||
FORMAT = ulong,value
|
||||
ID = VCD_VARIABLE_SEND_IF5_PKT_ID
|
||||
DESC = VCD variable SEND_IF5_PKT_ID
|
||||
GROUP = ALL:VCD:ENB:VCD_VARIABLE
|
||||
FORMAT = ulong,value
|
||||
ID = VCD_VARIABLE_RECV_IF5_PKT_ID
|
||||
DESC = VCD variable RECV_IF5_PKT_ID
|
||||
GROUP = ALL:VCD:ENB:VCD_VARIABLE
|
||||
FORMAT = ulong,value
|
||||
ID = VCD_VARIABLE_UE_PDCP_FLUSH_SIZE
|
||||
DESC = VCD variable UE_PDCP_FLUSH_SIZE
|
||||
GROUP = ALL:VCD:ENB:UE:VCD_VARIABLE
|
||||
@@ -2085,11 +2068,3 @@ ID = VCD_FUNCTION_RECV_IF5
|
||||
DESC = VCD function RECV_IF5
|
||||
GROUP = ALL:VCD:ENB:VCD_FUNCTION
|
||||
FORMAT = int,value
|
||||
ID = VCD_FUNCTION_TRX_COMPR_IF
|
||||
DESC = VCD function TRX_COMPR_IF
|
||||
GROUP = ALL:VCD:ENB:VCD_FUNCTION
|
||||
FORMAT = int,value
|
||||
ID = VCD_FUNCTION_TRX_DECOMPR_IF
|
||||
DESC = VCD function TRX_DECOMPR_IF
|
||||
GROUP = ALL:VCD:ENB:VCD_FUNCTION
|
||||
FORMAT = int,value
|
||||
|
||||
@@ -5,8 +5,7 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I.
|
||||
|
||||
LIBS=-lX11 -lm -lpng -lXft
|
||||
|
||||
all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
|
||||
extract_input_subframe
|
||||
all: record replay extract_config textlog enb ue vcd macpdu2wireshark
|
||||
|
||||
record: utils.o record.o database.o config.o
|
||||
$(CC) $(CFLAGS) -o record $^ $(LIBS)
|
||||
@@ -17,10 +16,6 @@ replay: utils.o replay.o
|
||||
extract_config: extract_config.o
|
||||
$(CC) $(CFLAGS) -o extract_config $^ $(LIBS)
|
||||
|
||||
extract_input_subframe: extract_input_subframe.o database.o event.o utils.o \
|
||||
config.o
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
textlog: utils.o textlog.o database.o event.o handler.o config.o \
|
||||
event_selector.o view/view.a gui/gui.a logger/logger.a \
|
||||
filter/filter.a
|
||||
@@ -64,7 +59,7 @@ filter/filter.a:
|
||||
|
||||
clean:
|
||||
rm -f *.o core tracer_remote textlog enb ue vcd record replay
|
||||
rm -f extract_config macpdu2wireshark extract_input_subframe
|
||||
rm -f extract_config macpdu2wireshark
|
||||
cd gui && make clean
|
||||
cd view && make clean
|
||||
cd logger && make clean
|
||||
|
||||
@@ -264,14 +264,14 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
|
||||
|
||||
input_signal_plot = new_xy_plot(g, 256, 55, "input signal", 20);
|
||||
widget_add_child(g, line, input_signal_plot, -1);
|
||||
xy_plot_set_range(g, input_signal_plot, 0, 7680*10, 20, 70);
|
||||
xy_plot_set_range(g, input_signal_plot, 0, 7680*10*2, 20, 70);
|
||||
input_signal_log = new_framelog(h, database,
|
||||
"ENB_PHY_INPUT_SIGNAL", "subframe", "rxdata");
|
||||
/* a skip value of 10 means to process 1 frame over 10, that is
|
||||
* more or less 10 frames per second
|
||||
*/
|
||||
framelog_set_skip(input_signal_log, 10);
|
||||
input_signal_view = new_view_xy(7680*10, 10,
|
||||
input_signal_view = new_view_xy(7680*10*2, 10,
|
||||
g, input_signal_plot, new_color(g, "#0c0c72"), XY_LOOP_MODE);
|
||||
logger_add_view(input_signal_log, input_signal_view);
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "database.h"
|
||||
#include "event.h"
|
||||
#include "config.h"
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf(
|
||||
"usage: [options] <file> <frame> <subframe>\n"
|
||||
"options:\n"
|
||||
" -d <database file> this option is mandatory\n"
|
||||
" -v verbose\n"
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int n, char **v)
|
||||
{
|
||||
char *database_filename = NULL;
|
||||
void *database;
|
||||
int i;
|
||||
int input_event_id;
|
||||
database_event_format f;
|
||||
char *file = NULL;
|
||||
int fd;
|
||||
int frame = -1, subframe = -1;
|
||||
int frame_arg, subframe_arg, buffer_arg;
|
||||
int verbose = 0;
|
||||
|
||||
for (i = 1; i < n; i++) {
|
||||
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
|
||||
if (!strcmp(v[i], "-d"))
|
||||
{ if (i > n-2) usage(); database_filename = v[++i]; continue; }
|
||||
if (!strcmp(v[i], "-v")) { verbose = 1; continue; }
|
||||
if (file == NULL) { file = v[i]; continue; }
|
||||
if (frame == -1) { frame = atoi(v[i]); continue; }
|
||||
if (subframe == -1) { subframe = atoi(v[i]); continue; }
|
||||
usage();
|
||||
}
|
||||
if (file == NULL || frame == -1 || subframe == -1) usage();
|
||||
|
||||
if (database_filename == NULL) {
|
||||
printf("ERROR: provide a database file (-d)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
database = parse_database(database_filename);
|
||||
|
||||
load_config_file(database_filename);
|
||||
|
||||
input_event_id = event_id_from_name(database, "ENB_PHY_INPUT_SIGNAL");
|
||||
f = get_format(database, input_event_id);
|
||||
|
||||
frame_arg = subframe_arg = buffer_arg = -1;
|
||||
for (i = 0; i < f.count; i++) {
|
||||
if (!strcmp(f.name[i], "frame")) {
|
||||
if (frame_arg != -1) goto err;
|
||||
if (strcmp(f.type[i], "int")) goto err;
|
||||
frame_arg = i;
|
||||
}
|
||||
if (!strcmp(f.name[i], "subframe")) {
|
||||
if (subframe_arg != -1) goto err;
|
||||
if (strcmp(f.type[i], "int")) goto err;
|
||||
subframe_arg = i;
|
||||
}
|
||||
if (!strcmp(f.name[i], "rxdata")) {
|
||||
if (buffer_arg != -1) goto err;
|
||||
if (strcmp(f.type[i], "buffer")) goto err;
|
||||
buffer_arg = i;
|
||||
}
|
||||
continue;
|
||||
err:
|
||||
printf("cannot deal with ENB_PHY_INPUT_SIGNAL from database file\n");
|
||||
exit(1);
|
||||
}
|
||||
if (frame_arg == -1 || subframe_arg == -1 || buffer_arg == -1) goto err;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd == -1) { perror(file); exit(1); }
|
||||
|
||||
/* get wanted frame/subframe */
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
e = get_event(fd, v, database);
|
||||
if (e.type == -1) break;
|
||||
if (e.type != input_event_id) continue;
|
||||
if (verbose)
|
||||
printf("input frame %d subframe %d size %d\n",
|
||||
e.e[frame_arg].i, e.e[subframe_arg].i, e.e[buffer_arg].bsize);
|
||||
if (!(frame == e.e[frame_arg].i && subframe == e.e[subframe_arg].i))
|
||||
continue;
|
||||
#if 0
|
||||
for (i = 0; i < e.e[buffer_arg].bsize/2; i++) {
|
||||
short *x = e.e[buffer_arg].b;
|
||||
x[i] *= 14;
|
||||
}
|
||||
#endif
|
||||
fwrite(e.e[buffer_arg].b, e.e[buffer_arg].bsize, 1, stdout);
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("frame %d subframe %d not found\n", frame, subframe);
|
||||
return 0;
|
||||
}
|
||||
@@ -2176,7 +2176,6 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,
|
||||
// printf("dci_alloc[%d].L = %d\n",i,dci_alloc[i].L);
|
||||
//}
|
||||
//exit(-1);
|
||||
exit(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -181,114 +181,63 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe
|
||||
}
|
||||
}
|
||||
} else if (packet_type == IF5_MOBIPASS) {
|
||||
/* the only difference between mobipass standalone and the other one
|
||||
* is the timestamp in trx_write_func, but let's duplicate anyway
|
||||
* (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 *data_block=NULL, *data_block_head=NULL;
|
||||
__m128i *txp128;
|
||||
__m128i t0, t1;
|
||||
|
||||
unsigned char _tx_buffer[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);
|
||||
|
||||
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);
|
||||
_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;
|
||||
|
||||
__m128i *data_block=NULL, *data_block_head=NULL;
|
||||
|
||||
__m128i *txp128;
|
||||
__m128i t0, t1;
|
||||
|
||||
// tx_buffer = memalign(16, 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));
|
||||
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);
|
||||
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
|
||||
|
||||
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);
|
||||
__m128i *data_block=NULL, *data_block_head=NULL;
|
||||
|
||||
__m128i *txp128;
|
||||
__m128i t0, t1;
|
||||
|
||||
// tx_buffer = memalign(16, 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));
|
||||
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");
|
||||
}
|
||||
_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");
|
||||
}
|
||||
#ifdef DEBUG_DL_MOBIPASS
|
||||
if ((subframe==0)&&(dummy_cnt == 100)) {
|
||||
memcpy((void*)&dummy_buffer[packet_id*db_fulllength*2],(void*)data_block_head,db_fulllength*2);
|
||||
}
|
||||
if ((subframe==0)&&(dummy_cnt == 100)) {
|
||||
memcpy((void*)&dummy_buffer[packet_id*db_fulllength*2],(void*)data_block_head,db_fulllength*2);
|
||||
}
|
||||
#endif
|
||||
header->seqno += 1;
|
||||
}
|
||||
*seqno = header->seqno;
|
||||
header->seqno += 1;
|
||||
}
|
||||
*seqno = header->seqno;
|
||||
|
||||
#ifdef DEBUG_DL_MOBIPASS
|
||||
uint8_t txe;
|
||||
txe = dB_fixed(signal_energy(txp[0],fp->samples_per_tti));
|
||||
if (txe > 0){
|
||||
LOG_D(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, txe);
|
||||
}
|
||||
#endif
|
||||
uint8_t txe;
|
||||
txe = dB_fixed(signal_energy(txp[0],fp->samples_per_tti));
|
||||
if (txe > 0){
|
||||
LOG_D(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, txe);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
AssertFatal(1==0, "send_IF5 - Unknown packet_type %x", packet_type);
|
||||
}
|
||||
@@ -442,171 +391,148 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram
|
||||
*proc_timestamp = timestamp[0];
|
||||
|
||||
} else if (packet_type == IF5_MOBIPASS) {
|
||||
if (eNB->node_timing == synch_to_mobipass_standalone) {
|
||||
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
|
||||
openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
|
||||
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;
|
||||
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]);
|
||||
|
||||
packet_id=0;
|
||||
while(packet_id<fp->samples_per_tti/db_fulllength) {
|
||||
data_block = data_block_head;
|
||||
|
||||
eNB->ifdevice.trx_read_func(&eNB->ifdevice,
|
||||
×tamp_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
|
||||
int lower_offset = 0;
|
||||
int upper_offset = 70000;
|
||||
#endif
|
||||
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;
|
||||
|
||||
//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));
|
||||
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;
|
||||
/*
|
||||
// while(packet_id<fp->samples_per_tti/db_fulllength) {
|
||||
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) {
|
||||
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
|
||||
*/
|
||||
|
||||
|
||||
packet_id=0;
|
||||
while(packet_id<fp->samples_per_tti/db_fulllength) {
|
||||
data_block = data_block_head;
|
||||
|
||||
eNB->ifdevice.trx_read_func(&eNB->ifdevice,
|
||||
×tamp_mobipass[packet_id],
|
||||
(void**)&rx_buffer,
|
||||
db_fulllength,
|
||||
1
|
||||
);
|
||||
#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]))) {
|
||||
//ignore the packet
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
//skip SUBFRAME_SKIP_NUM_MOBIPASS additional UL packets
|
||||
if ((start_flag == 1) && (subframe_skip < SUBFRAME_SKIP_NUM_MOBIPASS)){
|
||||
subframe_skip++;
|
||||
offset_cnt = header->seqno;
|
||||
} else {
|
||||
if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){
|
||||
#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);
|
||||
#endif
|
||||
reset_flag=1;
|
||||
}
|
||||
if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) {
|
||||
packet_id = 1;
|
||||
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;
|
||||
}
|
||||
}//end while
|
||||
|
||||
*proc_timestamp = ntohl(timestamp_mobipass[0]);
|
||||
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
|
||||
openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
|
||||
#ifdef DEBUG_UL_MOBIPASS
|
||||
LOG_I(PHY,"[Mobipass][Recv_MOBIPASS] timestamp: %llu\n ", *proc_timestamp);
|
||||
int lower_offset = 0;
|
||||
int upper_offset = 70000;
|
||||
#endif
|
||||
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;
|
||||
|
||||
//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));
|
||||
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;
|
||||
/*
|
||||
// while(packet_id<fp->samples_per_tti/db_fulllength) {
|
||||
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) {
|
||||
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
|
||||
*/
|
||||
|
||||
|
||||
packet_id=0;
|
||||
while(packet_id<fp->samples_per_tti/db_fulllength) {
|
||||
data_block = data_block_head;
|
||||
|
||||
eNB->ifdevice.trx_read_func(&eNB->ifdevice,
|
||||
×tamp_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++;
|
||||
#if 0
|
||||
uint64_t tt = htonl(timestamp_mobipass[packet_id]);
|
||||
static uint64_t oldts = 0;
|
||||
T(T_MOBIPASS, T_INT(tt-oldts), T_INT(tt));
|
||||
oldts = tt;
|
||||
if (offset_cnt != header->seqno) printf("ERROR offset_cnt %d header->seqno %d\n", offset_cnt, header->seqno);
|
||||
#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]))) {
|
||||
//ignore the packet
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
//skip SUBFRAME_SKIP_NUM_MOBIPASS additional UL packets
|
||||
if ((start_flag == 1) && (subframe_skip < SUBFRAME_SKIP_NUM_MOBIPASS)){
|
||||
subframe_skip++;
|
||||
offset_cnt = header->seqno;
|
||||
} else {
|
||||
if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){
|
||||
#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);
|
||||
#endif
|
||||
reset_flag=1;
|
||||
}
|
||||
if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) {
|
||||
packet_id = 1;
|
||||
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;
|
||||
}
|
||||
#endif /* #if 0 */
|
||||
}//end while
|
||||
|
||||
*proc_timestamp = ntohl(timestamp_mobipass[0]);
|
||||
#ifdef DEBUG_UL_MOBIPASS
|
||||
LOG_I(PHY,"[Mobipass][Recv_MOBIPASS] timestamp: %llu\n ", *proc_timestamp);
|
||||
if (eNB->CC_id>0) {
|
||||
rxe = dB_fixed(signal_energy(rxp[0],fp->samples_per_tti));
|
||||
if (rxe > 0){
|
||||
LOG_I(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (*proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, rxe);
|
||||
rxe = dB_fixed(signal_energy(rxp[0],fp->samples_per_tti));
|
||||
if (rxe > 0){
|
||||
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);
|
||||
// exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type);
|
||||
}
|
||||
|
||||
@@ -1899,6 +1899,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
|
||||
Nprime_div_deltaPUCCH_Shift = (n1_pucch < thres) ? Ncs1_div_deltaPUCCH_Shift : (12/deltaPUCCH_Shift);
|
||||
Nprime = Nprime_div_deltaPUCCH_Shift * deltaPUCCH_Shift;
|
||||
|
||||
LOG_I(PHY, "[eNB] PUCCH: cNcs1/deltaPUCCH_Shift %d, Nprime %d, n1_pucch %d\n",thres,Nprime,n1_pucch);
|
||||
#ifdef DEBUG_PUCCH_RX
|
||||
printf("[eNB] PUCCH: cNcs1/deltaPUCCH_Shift %d, Nprime %d, n1_pucch %d\n",thres,Nprime,n1_pucch);
|
||||
#endif
|
||||
@@ -2074,12 +2075,12 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
|
||||
rxptr = (int16_t *)&common_vars->rxdataF[0][aa][symbol_offset];
|
||||
|
||||
for (i=0; i<12; i++,j+=2,re_offset++) {
|
||||
if (re_offset==frame_parms->ofdm_symbol_size)
|
||||
re_offset = 0;
|
||||
|
||||
rxcomp[aa][j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[j])>>15) - ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[1+j])>>15);
|
||||
rxcomp[aa][1+j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[1+j])>>15) + ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[j])>>15);
|
||||
|
||||
if (re_offset==frame_parms->ofdm_symbol_size)
|
||||
re_offset = 0;
|
||||
|
||||
#ifdef DEBUG_PUCCH_RX
|
||||
printf("[eNB] PUCCH subframe %d (%d,%d,%d,%d,%d) => (%d,%d) x (%d,%d) : (%d,%d)\n",subframe,l,i,re_offset,m,j,
|
||||
rxptr[re_offset<<1],rxptr[1+(re_offset<<1)],
|
||||
@@ -2095,6 +2096,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
|
||||
// Do cfo correction and MRC across symbols
|
||||
|
||||
if (fmt == pucch_format1) {
|
||||
LOG_I(PHY, "Doing PUCCH detection for format 1\n");
|
||||
#ifdef DEBUG_PUCCH_RX
|
||||
printf("Doing PUCCH detection for format 1\n");
|
||||
#endif
|
||||
@@ -2153,13 +2155,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
|
||||
|
||||
} //phase
|
||||
|
||||
// stat_max *= nsymb; // normalize to energy per symbol
|
||||
// stat_max /= (frame_parms->N_RB_UL*12); //
|
||||
stat_max /= (nsymb*12);
|
||||
stat_max *= nsymb; // normalize to energy per symbol
|
||||
stat_max /= (frame_parms->N_RB_UL*12); //
|
||||
#ifdef DEBUG_PUCCH_RX
|
||||
printf("[eNB] PUCCH: stat %d, stat_max %d, phase_max %d\n", stat,stat_max,phase_max);
|
||||
#endif
|
||||
|
||||
LOG_I(PHY,"[eNB] PUCCH fmt1: stat_max : %d, sigma2_dB %d (%d, %d), phase_max : %d\n",dB_fixed(stat_max),sigma2_dB,eNB->measurements[0].n0_subband_power_tot_dBm[6],pucch1_thres,phase_max);
|
||||
#ifdef DEBUG_PUCCH_RX
|
||||
LOG_I(PHY,"[eNB] PUCCH fmt1: stat_max : %d, sigma2_dB %d (%d, %d), phase_max : %d\n",dB_fixed(stat_max),sigma2_dB,eNB->measurements[0].n0_subband_power_tot_dBm[6],pucch1_thres,phase_max);
|
||||
#endif
|
||||
@@ -2199,11 +2201,12 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
|
||||
}
|
||||
} else if ((fmt == pucch_format1a)||(fmt == pucch_format1b)) {
|
||||
stat_max = 0;
|
||||
LOG_I(PHY,"Doing PUCCH detection for format 1a/1b\n");
|
||||
#ifdef DEBUG_PUCCH_RX
|
||||
LOG_I(PHY,"Doing PUCCH detection for format 1a/1b\n");
|
||||
#endif
|
||||
|
||||
for (phase=0; phase<7; phase++) {
|
||||
for (phase=3;phase<4;phase++){ //phase=0; phase<7; phase++) {
|
||||
stat=0;
|
||||
|
||||
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
@@ -2267,6 +2270,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
|
||||
} //re
|
||||
} // aa
|
||||
|
||||
LOG_I(PHY,"Format 1A: phase %d : stat %d\n",phase,stat);
|
||||
#ifdef DEBUG_PUCCH_RX
|
||||
LOG_I(PHY,"Format 1A: phase %d : stat %d\n",phase,stat);
|
||||
#endif
|
||||
@@ -2340,8 +2344,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
|
||||
off=(re<<1) + (24*l);
|
||||
tmp_re = ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
|
||||
tmp_im = ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
|
||||
stat_re += (((tmp_re*chest_re)>>15) + ((tmp_im*chest_im)>>15))/4;
|
||||
stat_im += (((tmp_re*chest_im)>>15) - ((tmp_im*chest_re)>>15))/4;
|
||||
stat_re += (((tmp_re*chest_re)>>15) + ((tmp_im*chest_im)>>15)/4);
|
||||
stat_im += (((tmp_re*chest_im)>>15) - ((tmp_im*chest_re)>>15)/4);
|
||||
off+=2;
|
||||
#ifdef DEBUG_PUCCH_RX
|
||||
printf("[eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d)\n",subframe,l,re,
|
||||
@@ -2403,6 +2407,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
|
||||
} //re
|
||||
} // aa
|
||||
|
||||
LOG_I(PHY,"PUCCH 1a/b: subframe %d : stat %d,%d (pos %d)\n",subframe,stat_re,stat_im,
|
||||
(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe]));
|
||||
#ifdef DEBUG_PUCCH_RX
|
||||
LOG_I(PHY,"PUCCH 1a/b: subframe %d : stat %d,%d (pos %d)\n",subframe,stat_re,stat_im,
|
||||
(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe]));
|
||||
|
||||
@@ -165,9 +165,8 @@ typedef enum {
|
||||
} eNB_func_t;
|
||||
|
||||
typedef enum {
|
||||
synch_to_ext_device=0, // synch to RF or Ethernet device
|
||||
synch_to_other, // synch to another source (timer, other CC_id)
|
||||
synch_to_mobipass_standalone // special case for mobipass in standalone mode
|
||||
synch_to_ext_device=0, // synch to RF or Ethernet device
|
||||
synch_to_other // synch to another source (timer, other CC_id)
|
||||
} eNB_timing_t;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -290,30 +290,6 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16
|
||||
return(0);
|
||||
}
|
||||
|
||||
int get_ue_rbs(int Mod_id, int CC_id, int rnti, int frame, int subframe, int *start_rb, int *nb_rb)
|
||||
{
|
||||
LTE_eNB_ULSCH_t *ULSCH_ptr;
|
||||
uint8_t ulsch_subframe,ulsch_frame;
|
||||
int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
|
||||
int harq_pid;
|
||||
|
||||
if (UE_id==-1) {
|
||||
LOG_E(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
ULSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->ulsch[(uint32_t)UE_id];
|
||||
ulsch_subframe = pdcch_alloc2ul_subframe(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,subframe);
|
||||
ulsch_frame = pdcch_alloc2ul_frame(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,frame,subframe);
|
||||
harq_pid = subframe2harq_pid(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,
|
||||
ulsch_frame,
|
||||
ulsch_subframe);
|
||||
*nb_rb = ULSCH_ptr->harq_processes[harq_pid]->nb_rb;
|
||||
*start_rb = ULSCH_ptr->harq_processes[harq_pid]->first_rb;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
|
||||
{
|
||||
return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
|
||||
@@ -1203,7 +1179,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1);
|
||||
if (do_meas==1) start_meas(&eNB->phy_proc_tx);
|
||||
|
||||
T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe));
|
||||
T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(eNB->CC_id), T_INT(frame), T_INT(subframe));
|
||||
|
||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
// If we've dropped the UE, go back to PRACH mode for this UE
|
||||
@@ -2194,7 +2170,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
|
||||
frame,
|
||||
subframe,
|
||||
PUCCH1_THRES);
|
||||
LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR is %d (SR n1pucch is %d)\n",
|
||||
LOG_I(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR is %d (SR n1pucch is %d)\n",
|
||||
eNB->Mod_id,
|
||||
eNB->ulsch[UE_id]->rnti,
|
||||
frame,
|
||||
@@ -2221,7 +2197,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
|
||||
// if SR was detected, use the n1_pucch from SR, else use n1_pucch0
|
||||
// n1_pucch0 = (SR_payload==1) ? eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex:n1_pucch0;
|
||||
|
||||
LOG_D(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,SR_payload);
|
||||
LOG_I(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,SR_payload);
|
||||
|
||||
if (eNB->abstraction_flag == 0) {
|
||||
metric0 = rx_pucch(eNB,
|
||||
@@ -2277,6 +2253,11 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
|
||||
#endif
|
||||
}
|
||||
|
||||
LOG_I(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n",
|
||||
eNB->Mod_id,
|
||||
eNB->dlsch[UE_id][0]->rnti,
|
||||
frame,subframe,
|
||||
pucch_payload0[0],metric0);
|
||||
#ifdef DEBUG_PHY_PROC
|
||||
LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n",
|
||||
eNB->Mod_id,
|
||||
@@ -2307,6 +2288,10 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
|
||||
|
||||
// if SR was detected, use the n1_pucch from SR
|
||||
if (SR_payload==1) {
|
||||
LOG_I(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n",eNB->Mod_id,
|
||||
eNB->dlsch[UE_id][0]->rnti,
|
||||
frame,subframe,
|
||||
n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
|
||||
#ifdef DEBUG_PHY_PROC
|
||||
LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n",eNB->Mod_id,
|
||||
eNB->dlsch[UE_id][0]->rnti,
|
||||
@@ -2335,6 +2320,10 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
|
||||
#endif
|
||||
}
|
||||
} else { //using n1_pucch0/n1_pucch1 resources
|
||||
LOG_I(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d\n",eNB->Mod_id,
|
||||
eNB->dlsch[UE_id][0]->rnti,
|
||||
frame,subframe,
|
||||
n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
|
||||
#ifdef DEBUG_PHY_PROC
|
||||
LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d\n",eNB->Mod_id,
|
||||
eNB->dlsch[UE_id][0]->rnti,
|
||||
@@ -2412,6 +2401,10 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
|
||||
pucch_sel = 2; // indicate that this is a bundled ACK/NAK
|
||||
}
|
||||
|
||||
LOG_I(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",eNB->Mod_id,
|
||||
eNB->dlsch[UE_id][0]->rnti,
|
||||
frame,subframe,
|
||||
metric0,metric1,pucch_sel,pucch_payload[0],pucch_payload[1]);
|
||||
#ifdef DEBUG_PHY_PROC
|
||||
LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",eNB->Mod_id,
|
||||
eNB->dlsch[UE_id][0]->rnti,
|
||||
@@ -2427,6 +2420,8 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
|
||||
}
|
||||
|
||||
if (SR_payload == 1) {
|
||||
LOG_I(PHY,"[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n",eNB->Mod_id,
|
||||
eNB->ulsch[UE_id]->rnti,frame,subframe);
|
||||
LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n",eNB->Mod_id,
|
||||
eNB->ulsch[UE_id]->rnti,frame,subframe);
|
||||
eNB->UE_stats[UE_id].sr_received++;
|
||||
@@ -2435,6 +2430,9 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
|
||||
eNB->first_sr[UE_id] = 0;
|
||||
eNB->dlsch[UE_id][0]->harq_processes[0]->round=0;
|
||||
eNB->dlsch[UE_id][0]->harq_processes[0]->status=SCH_IDLE;
|
||||
LOG_I(PHY,"[eNB %d][SR %x] Frame %d subframe %d First SR\n",
|
||||
eNB->Mod_id,
|
||||
eNB->ulsch[UE_id]->rnti,frame,subframe);
|
||||
LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d First SR\n",
|
||||
eNB->Mod_id,
|
||||
eNB->ulsch[UE_id]->rnti,frame,subframe);
|
||||
@@ -2910,9 +2908,9 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
|
||||
uint16_t do_srs=0;
|
||||
uint16_t is_srs_pos=0;
|
||||
|
||||
T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe));
|
||||
T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(eNB->CC_id), T_INT(frame), T_INT(subframe));
|
||||
|
||||
T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0),
|
||||
T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(eNB->CC_id), T_INT(frame), T_INT(subframe), T_INT(0),
|
||||
T_BUFFER(&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti],
|
||||
eNB->frame_parms.samples_per_tti * 4));
|
||||
|
||||
|
||||
@@ -947,8 +947,6 @@ 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;
|
||||
} else if (strcmp(cc_node_timing, "synch_to_other") == 0) {
|
||||
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 {
|
||||
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",
|
||||
|
||||
@@ -1087,13 +1087,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
|
||||
|
||||
// Allocate CCEs for good after scheduling is done
|
||||
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++)
|
||||
if (allocate_CCEs(module_idP,CC_id,subframeP,0)) {
|
||||
LOG_D(MAC, "eNB %d CC_id %d frame %d subframe %d: CCE allocation failed\n",
|
||||
module_idP, CC_id, frameP, subframeP);
|
||||
printf("eNB %d CC_id %d frame %d subframe %d: CCE allocation failed\n",
|
||||
module_idP, CC_id, frameP, subframeP);
|
||||
abort();
|
||||
}
|
||||
allocate_CCEs(module_idP,CC_id,subframeP,0);
|
||||
|
||||
#if defined(FLEXRAN_AGENT_SB_IF)
|
||||
#ifndef DISABLE_CONT_STATS
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,8 +56,6 @@
|
||||
# include "intertask_interface.h"
|
||||
#endif
|
||||
|
||||
#include "T.h"
|
||||
|
||||
#define ENABLE_MAC_PAYLOAD_DEBUG
|
||||
#define DEBUG_eNB_SCHEDULER 1
|
||||
|
||||
@@ -1159,7 +1157,6 @@ boolean_t CCE_allocation_infeasible(int module_idP,
|
||||
|
||||
void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP)
|
||||
{
|
||||
T(T_ENB_MAC_SCHEDULING_REQUEST, T_INT(mod_idP), T_INT(cc_idP), T_INT(frameP), T_INT(subframeP), T_INT(rntiP));
|
||||
|
||||
int UE_id = find_UE_id(mod_idP, rntiP);
|
||||
UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
|
||||
|
||||
@@ -670,21 +670,6 @@ void schedule_ulsch(module_id_t module_idP,
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: this is a hack to disable scheduling in the PRACH.
|
||||
* We need to get the information from config/phy/wherever
|
||||
* as done in the commented code below.
|
||||
* For the moment, we hardcode for the config used by default.
|
||||
* Only deals with FDD, PRACH config 0.
|
||||
*/
|
||||
LTE_DL_FRAME_PARMS *frame_parms;
|
||||
frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);
|
||||
if (frame_parms->frame_type == FDD &&
|
||||
frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex == 0) {
|
||||
int frame_ul = (frameP + (subframeP >= 6)) & 1023;
|
||||
int subframe_ul = (subframeP + 4) % 10;
|
||||
if ((frame_ul & 1) == 0 && subframe_ul == 1) first_rb[CC_id] = 8;
|
||||
}
|
||||
|
||||
/*
|
||||
if (mac_xface->is_prach_subframe(&(mac_xface->lte_frame_parms),frameP,subframeP)) {
|
||||
first_rb[CC_id] = (mac_xface->get_prach_prb_offset(&(mac_xface->lte_frame_parms),
|
||||
@@ -692,65 +677,6 @@ void schedule_ulsch(module_id_t module_idP,
|
||||
|
||||
}
|
||||
|
||||
/* TODO: remove this hack which is to avoid scheduling new uplink where there is a
|
||||
* retransmission. It increases first_rb to move after the retransmission RBs,
|
||||
* which can skip a lot of free RBs (say the UE 2 has a retransmission
|
||||
* in RBs 45..47, we would skip RBs 1..47, but RBs 1..44 are free and
|
||||
* won't be used for scheduling)
|
||||
*/
|
||||
int UE_id;
|
||||
int rnti;
|
||||
UE_list_t *UE_list=&eNB->UE_list;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
int drop_ue=0;
|
||||
uint8_t harq_pid = 0;
|
||||
uint8_t round = 0;
|
||||
int n;
|
||||
// loop over all UEs
|
||||
for (UE_id=0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
|
||||
rnti = UE_RNTI(module_idP,UE_id);
|
||||
if (rnti==NOT_A_RNTI) continue;
|
||||
if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) continue;
|
||||
drop_ue = 0;
|
||||
for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
|
||||
CC_id = UE_list->ordered_ULCCids[n][UE_id];
|
||||
if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) {
|
||||
drop_ue = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (drop_ue == 1) continue;
|
||||
|
||||
for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
|
||||
// This is the actual CC_id in the list
|
||||
CC_id = UE_list->ordered_ULCCids[n][UE_id];
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
|
||||
|
||||
if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
|
||||
int start_rb;
|
||||
int nb_rb;
|
||||
|
||||
//DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
|
||||
//UE_template = &UE_list->UE_template[CC_id][UE_id];
|
||||
//UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
|
||||
if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL) == -1 ) continue;
|
||||
int get_ue_rbs(int module_idP, int CC_id, int rnti, int frameP, int subframeP, int *start_rb, int *nb_rb);
|
||||
if (get_ue_rbs(module_idP,CC_id,rnti,frameP,subframeP,&start_rb,&nb_rb) == -1 ) continue;
|
||||
|
||||
if (round > 0)
|
||||
{
|
||||
if (start_rb < first_rb[CC_id]) {
|
||||
LOG_E(MAC, "scheduled retransmission in forbidden RBs\n");
|
||||
// printf("scheduled retransmission in forbidden RBs\n");
|
||||
}
|
||||
if (first_rb[CC_id] < start_rb + nb_rb)
|
||||
first_rb[CC_id] = start_rb + nb_rb;
|
||||
}
|
||||
} // UE is in PUSCH
|
||||
} // loop over CC
|
||||
} // loop over UE
|
||||
|
||||
schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe,first_rb);
|
||||
|
||||
#ifdef CBA
|
||||
@@ -762,7 +688,548 @@ void schedule_ulsch(module_id_t module_idP,
|
||||
|
||||
}
|
||||
|
||||
//#define BASIC_SCHED_HACK
|
||||
|
||||
#ifdef BASIC_SCHED_HACK
|
||||
|
||||
/* basic scheduler:
|
||||
* - schedule only 1 UE per TTI
|
||||
* - priority based: once scheduled, go to end of list
|
||||
* - retransmission has absolute priority
|
||||
* potential issues:
|
||||
* - interactions with random access
|
||||
*/
|
||||
|
||||
static int list[16];
|
||||
static int list_size;
|
||||
|
||||
static void list_check(int rnti)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < list_size; i++)
|
||||
if (list[i] == rnti) { printf("rnti %d already in list\n", rnti); abort(); }
|
||||
}
|
||||
|
||||
static void list_insert_at_start(int rnti)
|
||||
{
|
||||
list_check(rnti);
|
||||
if (list_size == 16) { printf("list full\n"); abort(); }
|
||||
memmove(list+1, list, list_size * sizeof(int));
|
||||
list[0] = rnti;
|
||||
list_size++;
|
||||
}
|
||||
|
||||
static void list_insert_at_end(int rnti)
|
||||
{
|
||||
list_check(rnti);
|
||||
if (list_size == 16) { printf("list full\n"); abort(); }
|
||||
list[list_size] = rnti;
|
||||
list_size++;
|
||||
}
|
||||
|
||||
static void list_remove(int rnti)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < list_size; i++) if (list[i] == rnti) break;
|
||||
if (i == list_size) { printf("rnti %d not found\n", rnti); abort(); }
|
||||
list_size--;
|
||||
memmove(list+i, list+i+1, (list_size-i) * sizeof(int));
|
||||
}
|
||||
|
||||
static int in_list(int rnti)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < list_size; i++) if (list[i] == rnti) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int look_for_ue(int wanted_rnti)
|
||||
{
|
||||
eNB_MAC_INST *eNB = &eNB_mac_inst[0];
|
||||
UE_list_t *UE_list = &eNB->UE_list;
|
||||
int i;
|
||||
int rnti;
|
||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
if (UE_list->active[i] != TRUE) continue;
|
||||
rnti = UE_RNTI(0, i);
|
||||
if (rnti == wanted_rnti) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int get_ue_id(int wanted_rnti)
|
||||
{
|
||||
int ret = look_for_ue(wanted_rnti);
|
||||
if (ret == -1) abort();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ue_in_mac(int wanted_rnti)
|
||||
{
|
||||
int ret = look_for_ue(wanted_rnti);
|
||||
return ret != -1;
|
||||
}
|
||||
|
||||
static int is_rach_subframe(int frame, int subframe)
|
||||
{
|
||||
/* we suppose config 0 */
|
||||
frame = ((frame * 10 + subframe + 4) / 10) % 1024;
|
||||
subframe = (subframe + 4) % 10;
|
||||
return (frame & 1) == 0 && subframe == 1;
|
||||
}
|
||||
|
||||
static void basic_ul(int module_idP, int frameP, int subframeP, uint16_t *first_rb, int sched_subframe)
|
||||
{
|
||||
if (module_idP) abort();
|
||||
|
||||
if (is_rach_subframe(frameP, subframeP)) first_rb[0] = 8;
|
||||
/* TODO: careful - only for mobipass CC 1 */
|
||||
//if (is_rach_subframe(frameP, subframeP)) first_rb[1] = 8;
|
||||
|
||||
eNB_MAC_INST *eNB = &eNB_mac_inst[0];
|
||||
UE_list_t *UE_list = &eNB->UE_list;
|
||||
LTE_DL_FRAME_PARMS *frame_parms;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
int i;
|
||||
int rnti;
|
||||
int CC_id;
|
||||
uint8_t harq_pid = 0;
|
||||
uint8_t round = 0;
|
||||
uint8_t aggregation = 2;
|
||||
int UE_id;
|
||||
UE_TEMPLATE *UE_template;
|
||||
uint8_t status = 0;
|
||||
uint32_t cqi_req,cshift,ndi,mcs=0,rballoc,tpc;
|
||||
UE_sched_ctrl *UE_sched_ctrl;
|
||||
int32_t normalized_rx_power, target_rx_power=-90;
|
||||
static int32_t tpc_accumulated=0;
|
||||
uint8_t rb_table_index = -1;
|
||||
uint16_t TBS = 0;
|
||||
void *ULSCH_dci = NULL;
|
||||
DCI_PDU *DCI_pdu;
|
||||
|
||||
/* update list, put new UEs at head of list */
|
||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
if (UE_list->active[i] != TRUE) continue;
|
||||
rnti = UE_RNTI(0, i);
|
||||
if (rnti==NOT_A_RNTI) continue;
|
||||
if (!phy_stats_exist(0, rnti)) continue;
|
||||
if (!in_list(rnti))
|
||||
{
|
||||
printf("%d.%d: UL new rnti %d\n", frameP, subframeP, rnti);
|
||||
list_insert_at_start(rnti);
|
||||
}
|
||||
}
|
||||
|
||||
/* remove dead UEs */
|
||||
remove:
|
||||
for (i = 0; i < list_size; i++) {
|
||||
if (ue_in_mac(list[i]) && phy_stats_exist(0, list[i])) continue;
|
||||
printf("%d.%d: UL remove rnti %d (in_mac %d phy_stats_exist %d)\n", frameP, subframeP, list[i], ue_in_mac(list[i]), phy_stats_exist(0, list[i]));
|
||||
list_remove(list[i]);
|
||||
goto remove;
|
||||
}
|
||||
|
||||
/* look for retransmission */
|
||||
for (i = 0; i < list_size; i++) {
|
||||
rnti = list[i];
|
||||
UE_id = get_ue_id(rnti);
|
||||
// don't schedule if Msg4 is not received yet
|
||||
if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
|
||||
LOG_I(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n",
|
||||
module_idP,frameP,subframeP,UE_id);
|
||||
continue;
|
||||
}
|
||||
CC_id = 0;
|
||||
frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
|
||||
if (eNB_UE_stats->mode != PUSCH) continue;
|
||||
if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL) == -1 ) {
|
||||
LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
|
||||
module_idP,frameP,subframeP, UE_id, CC_id, rnti);
|
||||
abort();
|
||||
}
|
||||
if (round != 0) {
|
||||
T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
|
||||
T_INT(subframeP), T_INT(harq_pid), T_INT(round), T_INT(-1), T_INT(-1),
|
||||
T_INT(round));
|
||||
list_remove(rnti);
|
||||
list_insert_at_end(rnti);
|
||||
/* nothing more to do */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* first transmission */
|
||||
for (i = 0; i < list_size; i++) {
|
||||
rnti = list[i];
|
||||
UE_id = get_ue_id(rnti);
|
||||
//if (UE_id + 1 != subframeP) continue;
|
||||
// don't schedule if Msg4 is not received yet
|
||||
if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
|
||||
LOG_I(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n",
|
||||
module_idP,frameP,subframeP,UE_id);
|
||||
continue;
|
||||
}
|
||||
CC_id = 0;
|
||||
frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
|
||||
if (eNB_UE_stats->mode != PUSCH) continue;
|
||||
DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
|
||||
UE_template = &UE_list->UE_template[CC_id][UE_id];
|
||||
UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
|
||||
if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL) == -1 ) {
|
||||
LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
|
||||
module_idP,frameP,subframeP, UE_id, CC_id, rnti);
|
||||
abort();
|
||||
}
|
||||
if (round != 0) abort();
|
||||
|
||||
aggregation=get_aggregation(get_bw_index(module_idP,CC_id),
|
||||
eNB_UE_stats->DL_cqi[0],
|
||||
format0);
|
||||
|
||||
if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) {
|
||||
LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
|
||||
//abort();
|
||||
continue;
|
||||
}
|
||||
if (!(UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) continue;
|
||||
|
||||
list_remove(rnti);
|
||||
list_insert_at_end(rnti);
|
||||
|
||||
UE_list->head_ul = UE_id;
|
||||
UE_list->next_ul[UE_id] = -1;
|
||||
|
||||
/* copy/paste from old code, with adaptation (no pre_processor) */
|
||||
|
||||
UE_template->ul_SR = 0;
|
||||
status = mac_eNB_get_rrc_status(module_idP,rnti);
|
||||
if (status < RRC_CONNECTED)
|
||||
cqi_req = 0;
|
||||
else if (UE_sched_ctrl->cqi_req_timer>30) {
|
||||
cqi_req = 1;
|
||||
UE_sched_ctrl->cqi_req_timer=0;
|
||||
}
|
||||
else
|
||||
cqi_req = 0;
|
||||
|
||||
//power control
|
||||
//compute the expected ULSCH RX power (for the stats)
|
||||
|
||||
// this is the normalized RX power and this should be constant (regardless of mcs
|
||||
normalized_rx_power = eNB_UE_stats->UL_rssi[0];
|
||||
target_rx_power = mac_xface->get_target_pusch_rx_power(module_idP,CC_id);
|
||||
|
||||
// this assumes accumulated tpc
|
||||
// make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
|
||||
int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe;
|
||||
if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case
|
||||
((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around
|
||||
{
|
||||
UE_template->pusch_tpc_tx_frame=frameP;
|
||||
UE_template->pusch_tpc_tx_subframe=subframeP;
|
||||
if (normalized_rx_power>(target_rx_power+1)) {
|
||||
tpc = 0; //-1
|
||||
tpc_accumulated--;
|
||||
} else if (normalized_rx_power<(target_rx_power-1)) {
|
||||
tpc = 2; //+1
|
||||
tpc_accumulated++;
|
||||
} else {
|
||||
tpc = 1; //0
|
||||
}
|
||||
} else {
|
||||
tpc = 1; //0
|
||||
}
|
||||
|
||||
if (frameP == 1000)
|
||||
if (tpc!=1) {
|
||||
printf("[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
|
||||
module_idP,frameP,subframeP,harq_pid,tpc,
|
||||
tpc_accumulated,normalized_rx_power,target_rx_power);
|
||||
LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
|
||||
module_idP,frameP,subframeP,harq_pid,tpc,
|
||||
tpc_accumulated,normalized_rx_power,target_rx_power);
|
||||
}
|
||||
|
||||
ndi = 1-UE_template->oldNDI_UL[harq_pid];
|
||||
UE_template->oldNDI_UL[harq_pid]=ndi;
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power;
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power;
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul;
|
||||
mcs = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
|
||||
if (UE_template->pre_allocated_rb_table_index_ul >=0) {
|
||||
rb_table_index=UE_template->pre_allocated_rb_table_index_ul;
|
||||
} else {
|
||||
mcs=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs);
|
||||
rb_table_index=5; // for PHR
|
||||
}
|
||||
|
||||
mcs = 19;
|
||||
rb_table_index = 32;
|
||||
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs;
|
||||
// buffer_occupancy = UE_template->ul_total_buffer;
|
||||
|
||||
while (((rb_table[rb_table_index]>(frame_parms->N_RB_UL-1-first_rb[CC_id])) ||
|
||||
(rb_table[rb_table_index]>45)) &&
|
||||
(rb_table_index>0)) {
|
||||
rb_table_index--;
|
||||
}
|
||||
|
||||
TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]);
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index];
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=TBS;
|
||||
// buffer_occupancy -= TBS;
|
||||
rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL,
|
||||
first_rb[CC_id],
|
||||
rb_table[rb_table_index]);
|
||||
|
||||
T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
|
||||
T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
|
||||
T_INT(TBS), T_INT(ndi));
|
||||
|
||||
if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED)
|
||||
LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n",
|
||||
module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs,
|
||||
first_rb[CC_id],rb_table[rb_table_index],
|
||||
rb_table_index,TBS,harq_pid);
|
||||
|
||||
// bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
|
||||
// increment for next UE allocation
|
||||
first_rb[CC_id]+=rb_table[rb_table_index];
|
||||
//store for possible retransmission
|
||||
UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index];
|
||||
UE_sched_ctrl->ul_scheduled |= (1<<harq_pid);
|
||||
|
||||
// adjust total UL buffer status by TBS, wait for UL sdus to do final update
|
||||
LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,TBS);
|
||||
if (UE_template->ul_total_buffer > TBS)
|
||||
UE_template->ul_total_buffer -= TBS;
|
||||
else
|
||||
UE_template->ul_total_buffer = 0;
|
||||
LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer);
|
||||
// Cyclic shift for DM RS
|
||||
cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
|
||||
|
||||
if (frame_parms->frame_type == TDD) {
|
||||
switch (frame_parms->N_RB_UL) {
|
||||
case 6:
|
||||
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
|
||||
|
||||
((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0;
|
||||
((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0;
|
||||
((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc;
|
||||
((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs;
|
||||
((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi;
|
||||
((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc;
|
||||
((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift;
|
||||
((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0;
|
||||
((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe];
|
||||
((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req;
|
||||
|
||||
add_ue_spec_dci(DCI_pdu,
|
||||
ULSCH_dci,
|
||||
rnti,
|
||||
sizeof(DCI0_1_5MHz_TDD_1_6_t),
|
||||
aggregation,
|
||||
sizeof_DCI0_1_5MHz_TDD_1_6_t,
|
||||
format0,
|
||||
0);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 25:
|
||||
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
|
||||
|
||||
((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0;
|
||||
((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0;
|
||||
((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc;
|
||||
((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs;
|
||||
((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi;
|
||||
((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc;
|
||||
((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift;
|
||||
((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0;
|
||||
((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe];
|
||||
((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req;
|
||||
|
||||
add_ue_spec_dci(DCI_pdu,
|
||||
ULSCH_dci,
|
||||
rnti,
|
||||
sizeof(DCI0_5MHz_TDD_1_6_t),
|
||||
aggregation,
|
||||
sizeof_DCI0_5MHz_TDD_1_6_t,
|
||||
format0,
|
||||
0);
|
||||
break;
|
||||
|
||||
case 50:
|
||||
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
|
||||
|
||||
((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->type = 0;
|
||||
((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0;
|
||||
((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc;
|
||||
((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs;
|
||||
((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi;
|
||||
((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc;
|
||||
((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift;
|
||||
((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0;
|
||||
((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe];
|
||||
((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req;
|
||||
|
||||
add_ue_spec_dci(DCI_pdu,
|
||||
ULSCH_dci,
|
||||
rnti,
|
||||
sizeof(DCI0_10MHz_TDD_1_6_t),
|
||||
aggregation,
|
||||
sizeof_DCI0_10MHz_TDD_1_6_t,
|
||||
format0,
|
||||
0);
|
||||
break;
|
||||
|
||||
case 100:
|
||||
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
|
||||
|
||||
((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->type = 0;
|
||||
((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0;
|
||||
((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc;
|
||||
((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs;
|
||||
((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi;
|
||||
((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc;
|
||||
((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift;
|
||||
((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0;
|
||||
((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe];
|
||||
((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req;
|
||||
|
||||
add_ue_spec_dci(DCI_pdu,
|
||||
ULSCH_dci,
|
||||
rnti,
|
||||
sizeof(DCI0_20MHz_TDD_1_6_t),
|
||||
aggregation,
|
||||
sizeof_DCI0_20MHz_TDD_1_6_t,
|
||||
format0,
|
||||
0);
|
||||
break;
|
||||
}
|
||||
} // TDD
|
||||
else { //FDD
|
||||
switch (frame_parms->N_RB_UL) {
|
||||
case 25:
|
||||
default:
|
||||
|
||||
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
|
||||
|
||||
((DCI0_5MHz_FDD_t *)ULSCH_dci)->type = 0;
|
||||
((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping = 0;
|
||||
((DCI0_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc;
|
||||
((DCI0_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs;
|
||||
((DCI0_5MHz_FDD_t *)ULSCH_dci)->ndi = ndi;
|
||||
((DCI0_5MHz_FDD_t *)ULSCH_dci)->TPC = tpc;
|
||||
((DCI0_5MHz_FDD_t *)ULSCH_dci)->cshift = cshift;
|
||||
((DCI0_5MHz_FDD_t *)ULSCH_dci)->padding = 0;
|
||||
((DCI0_5MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req;
|
||||
|
||||
add_ue_spec_dci(DCI_pdu,
|
||||
ULSCH_dci,
|
||||
rnti,
|
||||
sizeof(DCI0_5MHz_FDD_t),
|
||||
aggregation,
|
||||
sizeof_DCI0_5MHz_FDD_t,
|
||||
format0,
|
||||
0);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
|
||||
|
||||
((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->type = 0;
|
||||
((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->hopping = 0;
|
||||
((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc;
|
||||
((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs;
|
||||
((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->ndi = ndi;
|
||||
((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->TPC = tpc;
|
||||
((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cshift = cshift;
|
||||
((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->padding = 0;
|
||||
((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req;
|
||||
|
||||
add_ue_spec_dci(DCI_pdu,
|
||||
ULSCH_dci,
|
||||
rnti,
|
||||
sizeof(DCI0_1_5MHz_FDD_t),
|
||||
aggregation,
|
||||
sizeof_DCI0_1_5MHz_FDD_t,
|
||||
format0,
|
||||
0);
|
||||
break;
|
||||
|
||||
case 50:
|
||||
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
|
||||
|
||||
((DCI0_10MHz_FDD_t *)ULSCH_dci)->type = 0;
|
||||
((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping = 0;
|
||||
((DCI0_10MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc;
|
||||
((DCI0_10MHz_FDD_t *)ULSCH_dci)->mcs = mcs;
|
||||
((DCI0_10MHz_FDD_t *)ULSCH_dci)->ndi = ndi;
|
||||
((DCI0_10MHz_FDD_t *)ULSCH_dci)->TPC = tpc;
|
||||
((DCI0_10MHz_FDD_t *)ULSCH_dci)->padding = 0;
|
||||
((DCI0_10MHz_FDD_t *)ULSCH_dci)->cshift = cshift;
|
||||
((DCI0_10MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req;
|
||||
|
||||
add_ue_spec_dci(DCI_pdu,
|
||||
ULSCH_dci,
|
||||
rnti,
|
||||
sizeof(DCI0_10MHz_FDD_t),
|
||||
aggregation,
|
||||
sizeof_DCI0_10MHz_FDD_t,
|
||||
format0,
|
||||
0);
|
||||
break;
|
||||
|
||||
case 100:
|
||||
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
|
||||
|
||||
((DCI0_20MHz_FDD_t *)ULSCH_dci)->type = 0;
|
||||
((DCI0_20MHz_FDD_t *)ULSCH_dci)->hopping = 0;
|
||||
((DCI0_20MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc;
|
||||
((DCI0_20MHz_FDD_t *)ULSCH_dci)->mcs = mcs;
|
||||
((DCI0_20MHz_FDD_t *)ULSCH_dci)->ndi = ndi;
|
||||
((DCI0_20MHz_FDD_t *)ULSCH_dci)->TPC = tpc;
|
||||
((DCI0_20MHz_FDD_t *)ULSCH_dci)->padding = 0;
|
||||
((DCI0_20MHz_FDD_t *)ULSCH_dci)->cshift = cshift;
|
||||
((DCI0_20MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req;
|
||||
|
||||
add_ue_spec_dci(DCI_pdu,
|
||||
ULSCH_dci,
|
||||
rnti,
|
||||
sizeof(DCI0_20MHz_FDD_t),
|
||||
aggregation,
|
||||
sizeof_DCI0_20MHz_FDD_t,
|
||||
format0,
|
||||
0);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
add_ue_ulsch_info(module_idP,
|
||||
CC_id,
|
||||
UE_id,
|
||||
subframeP,
|
||||
S_UL_SCHEDULED);
|
||||
|
||||
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id);
|
||||
#ifdef DEBUG
|
||||
dump_dci(frame_parms, &DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci-1]);
|
||||
#endif
|
||||
/* done, return */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BASIC_SCHED_HACK */
|
||||
|
||||
void schedule_ulsch_rnti(module_id_t module_idP,
|
||||
unsigned char cooperation_flag,
|
||||
@@ -771,6 +1238,9 @@ void schedule_ulsch_rnti(module_id_t module_idP,
|
||||
unsigned char sched_subframe,
|
||||
uint16_t *first_rb)
|
||||
{
|
||||
#ifdef BASIC_SCHED_HACK
|
||||
return basic_ul(module_idP, frameP, subframeP, first_rb, sched_subframe);
|
||||
#endif
|
||||
|
||||
int UE_id;
|
||||
uint8_t aggregation = 2;
|
||||
@@ -876,13 +1346,6 @@ abort();
|
||||
module_idP,frameP,subframeP,UE_id,rnti,CC_id, mode_string[eNB_UE_stats->mode], 1<<aggregation);
|
||||
}
|
||||
|
||||
/* be sure that there are some free RBs */
|
||||
if (first_rb[CC_id] >= frame_parms->N_RB_UL-1) {
|
||||
LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d mode %s: dropping, not enough RBs\n",
|
||||
module_idP,frameP,subframeP,UE_id,rnti,CC_id, mode_string[eNB_UE_stats->mode]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
|
||||
|
||||
@@ -972,11 +1435,9 @@ abort();
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs;
|
||||
// buffer_occupancy = UE_template->ul_total_buffer;
|
||||
|
||||
while (rb_table_index > 0 &&
|
||||
(rb_table[rb_table_index] > frame_parms->N_RB_UL-1-first_rb[CC_id] ||
|
||||
rb_table[rb_table_index]>45 ||
|
||||
(UE_template->pre_allocated_rb_table_index_ul >= 0 &&
|
||||
rb_table[rb_table_index] > UE_template->pre_allocated_nb_rb_ul))) {
|
||||
while (((rb_table[rb_table_index]>(frame_parms->N_RB_UL-1-first_rb[CC_id])) ||
|
||||
(rb_table[rb_table_index]>45)) &&
|
||||
(rb_table_index>0)) {
|
||||
rb_table_index--;
|
||||
}
|
||||
|
||||
|
||||
@@ -672,12 +672,9 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||
|
||||
for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
|
||||
CC_id = UE_list->ordered_CCids[ii][i];
|
||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[i];
|
||||
round = ue_sched_ctl->round[CC_id];
|
||||
|
||||
// control channel or retransmission
|
||||
/* TODO: do we have to check for retransmission? */
|
||||
if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED || round > 0) {
|
||||
// control channel
|
||||
if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED) {
|
||||
nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
|
||||
} else {
|
||||
nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);
|
||||
@@ -699,7 +696,6 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||
nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i];
|
||||
} else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
|
||||
nb_rbs_required_remaining[CC_id][i] = nb_rbs_required[CC_id][i]-nb_rbs_required_remaining_1[CC_id][i]+nb_rbs_required_remaining[CC_id][i];
|
||||
if (nb_rbs_required_remaining[CC_id][i]<0) abort();
|
||||
}
|
||||
|
||||
if (nb_rbs_required[CC_id][i]> 0 )
|
||||
@@ -905,7 +901,7 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort();
|
||||
}
|
||||
}
|
||||
|
||||
#define SF0_LIMIT 1
|
||||
#define SF05_LIMIT 1
|
||||
|
||||
void dlsch_scheduler_pre_processor_reset (int module_idP,
|
||||
int UE_id,
|
||||
@@ -924,10 +920,10 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,
|
||||
UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
rnti_t rnti = UE_RNTI(module_idP,UE_id);
|
||||
uint8_t *vrb_map = eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map;
|
||||
int RBGsize;
|
||||
int RBGsize_last;
|
||||
#ifdef SF0_LIMIT
|
||||
int sf0_upper=-1,sf0_lower=-1;
|
||||
int RBGsize = PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL/N_RBG;
|
||||
#ifdef SF05_LIMIT
|
||||
//int subframe05_limit=0;
|
||||
int sf05_upper=-1,sf05_lower=-1;
|
||||
#endif
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
|
||||
if (eNB_UE_stats == NULL) return;
|
||||
@@ -990,60 +986,44 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,
|
||||
ue_sched_ctl->dl_pow_off[CC_id] = 2;
|
||||
nb_rbs_required_remaining[CC_id][UE_id] = 0;
|
||||
|
||||
switch (PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL) {
|
||||
case 6: RBGsize = 1; RBGsize_last = 1; break;
|
||||
case 15: RBGsize = 2; RBGsize_last = 1; break;
|
||||
case 25: RBGsize = 2; RBGsize_last = 1; break;
|
||||
case 50: RBGsize = 3; RBGsize_last = 2; break;
|
||||
case 75: RBGsize = 4; RBGsize_last = 3; break;
|
||||
case 100: RBGsize = 4; RBGsize_last = 4; break;
|
||||
default: printf("unsupported RBs (%d)\n", PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL); fflush(stdout); abort();
|
||||
}
|
||||
|
||||
#ifdef SF0_LIMIT
|
||||
#ifdef SF05_LIMIT
|
||||
switch (N_RBG) {
|
||||
case 6:
|
||||
sf0_lower=0;
|
||||
sf0_upper=5;
|
||||
sf05_lower=0;
|
||||
sf05_upper=5;
|
||||
break;
|
||||
case 8:
|
||||
sf0_lower=2;
|
||||
sf0_upper=5;
|
||||
sf05_lower=2;
|
||||
sf05_upper=5;
|
||||
break;
|
||||
case 13:
|
||||
sf0_lower=4;
|
||||
sf0_upper=7;
|
||||
sf05_lower=4;
|
||||
sf05_upper=7;
|
||||
break;
|
||||
case 17:
|
||||
sf0_lower=7;
|
||||
sf0_upper=9;
|
||||
sf05_lower=7;
|
||||
sf05_upper=9;
|
||||
break;
|
||||
case 25:
|
||||
sf0_lower=11;
|
||||
sf0_upper=13;
|
||||
sf05_lower=11;
|
||||
sf05_upper=13;
|
||||
break;
|
||||
default: printf("unsupported RBs (%d)\n", PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL); fflush(stdout); abort();
|
||||
}
|
||||
#endif
|
||||
// Initialize Subbands according to VRB map
|
||||
for (i=0; i<N_RBG; i++) {
|
||||
int rb_size = i==N_RBG-1 ? RBGsize_last : RBGsize;
|
||||
|
||||
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
|
||||
rballoc_sub[CC_id][i] = 0;
|
||||
#ifdef SF0_LIMIT
|
||||
// for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors)
|
||||
/* TODO: make it proper - allocate those RBs, do not "protect" them, but
|
||||
* compute number of available REs and limit MCS according to the
|
||||
* TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor)
|
||||
*/
|
||||
if (subframeP==0 &&
|
||||
i >= sf0_lower && i <= sf0_upper)
|
||||
#ifdef SF05_LIMIT
|
||||
// for avoiding 6+ PRBs around DC in subframe 0-5 (avoid excessive errors)
|
||||
|
||||
if ((subframeP==0 || subframeP==5) &&
|
||||
(i>=sf05_lower && i<=sf05_upper))
|
||||
rballoc_sub[CC_id][i]=1;
|
||||
#endif
|
||||
// for SI-RNTI,RA-RNTI and P-RNTI allocations
|
||||
for (j = 0; j < rb_size; j++) {
|
||||
if (vrb_map[j+(i*RBGsize)] != 0) {
|
||||
for (j=0;j<RBGsize;j++) {
|
||||
if (vrb_map[j+(i*RBGsize)]!=0) {
|
||||
rballoc_sub[CC_id][i] = 1;
|
||||
LOG_D(MAC,"Frame %d, subframe %d : vrb %d allocated\n",frameP,subframeP,j+(i*RBGsize));
|
||||
break;
|
||||
@@ -1083,16 +1063,14 @@ void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id,
|
||||
if (ue_sched_ctl->dl_pow_off[CC_id] != 0 ) {
|
||||
|
||||
if ((i == N_RBG-1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
|
||||
if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit-1){
|
||||
rballoc_sub[CC_id][i] = 1;
|
||||
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
|
||||
MIMO_mode_indicator[CC_id][i] = 1;
|
||||
if (transmission_mode == 5 ) {
|
||||
ue_sched_ctl->dl_pow_off[CC_id] = 1;
|
||||
}
|
||||
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1;
|
||||
ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1;
|
||||
}
|
||||
rballoc_sub[CC_id][i] = 1;
|
||||
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
|
||||
MIMO_mode_indicator[CC_id][i] = 1;
|
||||
if (transmission_mode == 5 ) {
|
||||
ue_sched_ctl->dl_pow_off[CC_id] = 1;
|
||||
}
|
||||
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1;
|
||||
ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1;
|
||||
} else {
|
||||
if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit){
|
||||
rballoc_sub[CC_id][i] = 1;
|
||||
@@ -1108,6 +1086,7 @@ void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id,
|
||||
} // dl_pow_off[CC_id][UE_id] ! = 0
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1356,8 +1335,6 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra
|
||||
// if this UE has UL traffic
|
||||
if (UE_template->ul_total_buffer > 0 ) {
|
||||
|
||||
/* start with 3 RB => rb_table_index = 2 */
|
||||
rb_table_index = 2;
|
||||
tbs = mac_xface->get_TBS_UL(mcs,3); // 1 or 2 PRB with cqi enabled does not work well!
|
||||
// fixme: set use_srs flag
|
||||
tx_power= mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0);
|
||||
@@ -1401,15 +1378,8 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra
|
||||
UE_template->pre_allocated_nb_rb_ul,
|
||||
UE_template->phr_info,tx_power);
|
||||
} else {
|
||||
/* if UE has pending scheduling request then pre-allocate 3 RBs */
|
||||
//if (UE_template->ul_active == 1 && UE_template->ul_SR == 1) {
|
||||
if (UE_is_to_be_scheduled(module_idP, CC_id, i)) {
|
||||
UE_template->pre_allocated_rb_table_index_ul = 2;
|
||||
UE_template->pre_allocated_nb_rb_ul = 3;
|
||||
} else {
|
||||
UE_template->pre_allocated_rb_table_index_ul=-1;
|
||||
UE_template->pre_allocated_nb_rb_ul=0;
|
||||
}
|
||||
UE_template->pre_allocated_rb_table_index_ul=-1;
|
||||
UE_template->pre_allocated_nb_rb_ul=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1680,7 +1680,7 @@ do_RRCConnectionSetup(
|
||||
// SchedulingRequestConfig
|
||||
|
||||
physicalConfigDedicated2->schedulingRequestConfig->present = SchedulingRequestConfig_PR_setup;
|
||||
physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 71 - ue_context_pP->local_uid/10;//ue_context_pP->local_uid;
|
||||
physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 3;//ue_context_pP->local_uid;
|
||||
|
||||
if (frame_parms->frame_type == 0) { // FDD
|
||||
physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 5+(ue_context_pP->local_uid%10); // Isr = 5 (every 10 subframes, offset=2+UE_id mod3)
|
||||
|
||||
@@ -175,16 +175,16 @@ const char* eurecomVariablesNames[] = {
|
||||
"ue0_SFN5",
|
||||
"ue0_SFN6",
|
||||
"ue0_SFN7",
|
||||
"send_if4_symbol",
|
||||
"recv_if4_symbol",
|
||||
"send_if5_pkt_id",
|
||||
"recv_if5_pkt_id",
|
||||
"ue_pdcp_flush_size",
|
||||
"ue_pdcp_flush_err",
|
||||
"ue0_trx_read_ns",
|
||||
"ue0_trx_write_ns",
|
||||
"ue0_trx_read_ns_missing",
|
||||
"ue0_trx_write_ns_missing",
|
||||
"ue0_trx_write_ns_missing"
|
||||
"send_if4_symbol",
|
||||
"recv_if4_symbol",
|
||||
"send_if5_pkt_id",
|
||||
"recv_if5_pkt_id"
|
||||
};
|
||||
|
||||
const char* eurecomFunctionsNames[] = {
|
||||
@@ -382,10 +382,10 @@ const char* eurecomFunctionsNames[] = {
|
||||
"recv_if5",
|
||||
|
||||
"compress_if",
|
||||
"decompress_if",
|
||||
"decompress_if"
|
||||
};
|
||||
|
||||
struct vcd_module_s vcd_modules[] = {
|
||||
struct vcd_module_s vcd_modules[VCD_SIGNAL_DUMPER_MODULE_END] = {
|
||||
{ "variables", VCD_SIGNAL_DUMPER_VARIABLES_END, eurecomVariablesNames, VCD_WIRE, 64 },
|
||||
{ "functions", VCD_SIGNAL_DUMPER_FUNCTIONS_END, eurecomFunctionsNames, VCD_WIRE, 1 },
|
||||
// { "ue_procedures_functions", VCD_SIGNAL_DUMPER_UE_PROCEDURES_FUNCTIONS_END, eurecomUEFunctionsNames, VCD_WIRE, 1 },
|
||||
@@ -686,7 +686,7 @@ void vcd_signal_dumper_create_header(void)
|
||||
fprintf(vcd_fd, "$timescale 1 ns $end\n");
|
||||
|
||||
/* Initialize each module definition */
|
||||
for(i = 0; i < sizeof(vcd_modules) / sizeof(struct vcd_module_s); i++) {
|
||||
for(i = 0; i < VCD_SIGNAL_DUMPER_MODULE_END; i++) {
|
||||
struct vcd_module_s *module;
|
||||
module = &vcd_modules[i];
|
||||
fprintf(vcd_fd, "$scope module %s $end\n", module->name);
|
||||
@@ -711,7 +711,7 @@ void vcd_signal_dumper_create_header(void)
|
||||
/* Init variables and functions to 0 */
|
||||
fprintf(vcd_fd, "$dumpvars\n");
|
||||
|
||||
for(i = 0; i < sizeof(vcd_modules) / sizeof(struct vcd_module_s); i++) {
|
||||
for(i = 0; i < VCD_SIGNAL_DUMPER_MODULE_END; i++) {
|
||||
struct vcd_module_s *module;
|
||||
module = &vcd_modules[i];
|
||||
|
||||
|
||||
@@ -157,7 +157,8 @@ typedef enum {
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS_MISSING,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS_MISSING,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_END
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_LAST,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_END = VCD_SIGNAL_DUMPER_VARIABLES_LAST,
|
||||
} vcd_signal_dump_variables;
|
||||
|
||||
typedef enum {
|
||||
@@ -360,7 +361,8 @@ typedef enum {
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF,
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF,
|
||||
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_END
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_END = VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
|
||||
} vcd_signal_dump_functions;
|
||||
|
||||
typedef enum {
|
||||
@@ -369,6 +371,8 @@ typedef enum {
|
||||
VCD_SIGNAL_DUMPER_MODULE_VARIABLES,
|
||||
VCD_SIGNAL_DUMPER_MODULE_FUNCTIONS,
|
||||
// VCD_SIGNAL_DUMPER_MODULE_UE_PROCEDURES_FUNCTIONS,
|
||||
VCD_SIGNAL_DUMPER_MODULE_LAST,
|
||||
VCD_SIGNAL_DUMPER_MODULE_END = VCD_SIGNAL_DUMPER_MODULE_LAST,
|
||||
} vcd_signal_dumper_modules;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -140,9 +140,7 @@ typedef enum {
|
||||
//! This tells the underlying hardware to use the internal reference
|
||||
internal=0,
|
||||
//! This tells the underlying hardware to use the external reference
|
||||
external=1,
|
||||
//! This tells the underlying hardware to use the gpsdo reference
|
||||
gpsdo=2
|
||||
external=1
|
||||
} clock_source_t;
|
||||
|
||||
/*! \brief RF frontend parameters set by application */
|
||||
|
||||
@@ -52,8 +52,20 @@
|
||||
//int addr_len[MAX_INST];
|
||||
//struct ifreq if_index[MAX_INST];
|
||||
|
||||
static unsigned char frame[1024*10*7680*2*2];
|
||||
|
||||
int eth_socket_init_raw(openair0_device *device) {
|
||||
|
||||
do { static int first = 1;
|
||||
//if (first == 0) break;
|
||||
first = 0;
|
||||
printf("read file\n");
|
||||
FILE *f = fopen("/roux/FRAMES.raw", "r"); if (f==NULL) abort();
|
||||
if (fread(frame, 1024*10*7680*2*2, 1, f) != 1) abort();
|
||||
fclose(f);
|
||||
printf("ok\n");
|
||||
} while (0);
|
||||
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
const char *local_mac, *remote_mac;
|
||||
int sock_dom=0;
|
||||
@@ -219,6 +231,35 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam
|
||||
|
||||
eth->tx_nsamps = nblocks;
|
||||
|
||||
if (flags == IF5_MOBIPASS) do {
|
||||
if (nsamps != 640) { printf("bad nsamps %d\n", nsamps); break; }
|
||||
static FILE *f = NULL;
|
||||
static unsigned long ts = 0;
|
||||
if (f == NULL) { f = fopen("/tmp/test.raw", "w"); if (f == NULL) abort(); }
|
||||
unsigned char *x = buff[0];
|
||||
timestamp = ntohl(* (int32_t*)(x + 14+10));
|
||||
if (ts != timestamp) {
|
||||
printf("warning : bad ts (timestamp %ld ts %ld diff %ld)!!\n", timestamp, ts, timestamp-ts);
|
||||
ts = timestamp;
|
||||
// fclose(f);
|
||||
// f = fopen("/tmp/test.raw", "w"); if (f == NULL) abort();
|
||||
}
|
||||
ts += 640;
|
||||
x += MAC_HEADER_SIZE_BYTES+sizeof_IF5_mobipass_header_t;
|
||||
fwrite(x, 640*2, 1, f);
|
||||
} while(0);
|
||||
|
||||
if (0 && flags == IF5_MOBIPASS) {
|
||||
static int pos = 0;
|
||||
unsigned char *x = buff[0];
|
||||
x += MAC_HEADER_SIZE_BYTES+sizeof_IF5_mobipass_header_t;
|
||||
memcpy(x, frame+pos, nsamps*2);
|
||||
//int i; for (i = 0; i < 16; i++) printf("%2.2x ", x[i]); printf("\n");
|
||||
pos += nsamps * 2;
|
||||
if (pos == 1024*10*7680*2*2) pos = 0;
|
||||
if (pos > 1024*10*7680*2*2) { pos = 0; printf("WARN: bad nsamps somehow\n");}
|
||||
printf("psize %ld\n", packet_size-MAC_HEADER_SIZE_BYTES-sizeof_IF5_mobipass_header_t);
|
||||
}
|
||||
memcpy(buff[0], (void*)ð->eh, MAC_HEADER_SIZE_BYTES);
|
||||
|
||||
|
||||
@@ -424,6 +465,9 @@ int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *t
|
||||
ssize_t packet_size = 28; //MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t ;
|
||||
// ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t);
|
||||
|
||||
|
||||
int nloop = 0;
|
||||
loop:
|
||||
bytes_received = recv(eth->sockfd,
|
||||
buff[0],
|
||||
packet_size,
|
||||
@@ -432,6 +476,10 @@ int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *t
|
||||
if (bytes_received ==-1) {
|
||||
eth->num_rx_errors++;
|
||||
perror("[MOBIPASS]ETHERNET IF5 READ (header): ");
|
||||
nloop++;
|
||||
usleep(10*1000);
|
||||
if (nloop < 100)
|
||||
goto loop;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@@ -439,6 +487,7 @@ int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *t
|
||||
*timestamp = test_header->time_stamp;
|
||||
packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t);
|
||||
|
||||
nloop = 0;
|
||||
while(bytes_received < packet_size) {
|
||||
bytes_received = recv(eth->sockfd,
|
||||
buff[0],
|
||||
@@ -447,6 +496,9 @@ int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *t
|
||||
if (bytes_received ==-1) {
|
||||
eth->num_rx_errors++;
|
||||
perror("[MOBIPASS] ETHERNET IF5 READ (payload): ");
|
||||
nloop++;
|
||||
usleep(10*1000);
|
||||
if (nloop >= 100)
|
||||
exit(-1);
|
||||
} else {
|
||||
eth->rx_actual_nsamps = bytes_received>>1;
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
#include <uhd/version.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
#include <complex>
|
||||
#include <fstream>
|
||||
@@ -94,181 +92,12 @@ typedef struct {
|
||||
int num_seq_errors;
|
||||
int64_t tx_count;
|
||||
int64_t rx_count;
|
||||
int wait_for_first_pps;
|
||||
int use_gps;
|
||||
//! timestamp of RX packet
|
||||
openair0_timestamp rx_timestamp;
|
||||
|
||||
} usrp_state_t;
|
||||
|
||||
//void print_notes(void)
|
||||
//{
|
||||
// Helpful notes
|
||||
// std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n");
|
||||
// std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS signals are now from the GPSDO.\n");
|
||||
// std::cout << boost::format("If you would like to use the internal reference(TCXO) in other applications, you must configure that explicitly.\n");
|
||||
// std::cout << boost::format("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n");
|
||||
// std::cout << boost::format("****************************************************************************************************************\n");
|
||||
//}
|
||||
|
||||
static int sync_to_gps(openair0_device *device)
|
||||
{
|
||||
uhd::set_thread_priority_safe();
|
||||
|
||||
//std::string args;
|
||||
|
||||
//Set up program options
|
||||
//po::options_description desc("Allowed options");
|
||||
//desc.add_options()
|
||||
//("help", "help message")
|
||||
//("args", po::value<std::string>(&args)->default_value(""), "USRP device arguments")
|
||||
//;
|
||||
//po::variables_map vm;
|
||||
//po::store(po::parse_command_line(argc, argv, desc), vm);
|
||||
//po::notify(vm);
|
||||
|
||||
//Print the help message
|
||||
//if (vm.count("help"))
|
||||
//{
|
||||
// std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl;
|
||||
// return EXIT_FAILURE;
|
||||
//}
|
||||
|
||||
//Create a USRP device
|
||||
//std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args;
|
||||
//uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
|
||||
//std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string();
|
||||
|
||||
usrp_state_t *s = (usrp_state_t*)device->priv;
|
||||
|
||||
try
|
||||
{
|
||||
size_t num_mboards = s->usrp->get_num_mboards();
|
||||
size_t num_gps_locked = 0;
|
||||
for (size_t mboard = 0; mboard < num_mboards; mboard++)
|
||||
{
|
||||
std::cout << "Synchronizing mboard " << mboard << ": " << s->usrp->get_mboard_name(mboard) << std::endl;
|
||||
|
||||
//Set references to GPSDO
|
||||
s->usrp->set_clock_source("gpsdo", mboard);
|
||||
s->usrp->set_time_source("gpsdo", mboard);
|
||||
|
||||
//std::cout << std::endl;
|
||||
//print_notes();
|
||||
//std::cout << std::endl;
|
||||
|
||||
//Check for 10 MHz lock
|
||||
std::vector<std::string> sensor_names = s->usrp->get_mboard_sensor_names(mboard);
|
||||
if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end())
|
||||
{
|
||||
std::cout << "Waiting for reference lock..." << std::flush;
|
||||
bool ref_locked = false;
|
||||
for (int i = 0; i < 30 and not ref_locked; i++)
|
||||
{
|
||||
ref_locked = s->usrp->get_mboard_sensor("ref_locked", mboard).to_bool();
|
||||
if (not ref_locked)
|
||||
{
|
||||
std::cout << "." << std::flush;
|
||||
boost::this_thread::sleep(boost::posix_time::seconds(1));
|
||||
}
|
||||
}
|
||||
if(ref_locked)
|
||||
{
|
||||
std::cout << "LOCKED" << std::endl;
|
||||
} else {
|
||||
std::cout << "FAILED" << std::endl;
|
||||
std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << boost::format("ref_locked sensor not present on this board.\n");
|
||||
}
|
||||
|
||||
//Wait for GPS lock
|
||||
bool gps_locked = s->usrp->get_mboard_sensor("gps_locked", mboard).to_bool();
|
||||
if(gps_locked)
|
||||
{
|
||||
num_gps_locked++;
|
||||
std::cout << boost::format("GPS Locked\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "WARNING: GPS not locked - time will not be accurate until locked" << std::endl;
|
||||
}
|
||||
|
||||
//Set to GPS time
|
||||
uhd::time_spec_t gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int()));
|
||||
//s->usrp->set_time_next_pps(gps_time+1.0, mboard);
|
||||
s->usrp->set_time_next_pps(uhd::time_spec_t(0.0));
|
||||
|
||||
//Wait for it to apply
|
||||
//The wait is 2 seconds because N-Series has a known issue where
|
||||
//the time at the last PPS does not properly update at the PPS edge
|
||||
//when the time is actually set.
|
||||
boost::this_thread::sleep(boost::posix_time::seconds(2));
|
||||
|
||||
//Check times
|
||||
gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int()));
|
||||
uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(mboard);
|
||||
std::cout << "USRP time: " << (boost::format("%0.9f") % time_last_pps.get_real_secs()) << std::endl;
|
||||
std::cout << "GPSDO time: " << (boost::format("%0.9f") % gps_time.get_real_secs()) << std::endl;
|
||||
//if (gps_time.get_real_secs() == time_last_pps.get_real_secs())
|
||||
// std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time" << std::endl << std::endl;
|
||||
//else
|
||||
// std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
if (num_gps_locked == num_mboards and num_mboards > 1)
|
||||
{
|
||||
//Check to see if all USRP times are aligned
|
||||
//First, wait for PPS.
|
||||
uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps();
|
||||
while (time_last_pps == s->usrp->get_time_last_pps())
|
||||
{
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
|
||||
}
|
||||
|
||||
//Sleep a little to make sure all devices have seen a PPS edge
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
|
||||
|
||||
//Compare times across all mboards
|
||||
bool all_matched = true;
|
||||
uhd::time_spec_t mboard0_time = s->usrp->get_time_last_pps(0);
|
||||
for (size_t mboard = 1; mboard < num_mboards; mboard++)
|
||||
{
|
||||
uhd::time_spec_t mboard_time = s->usrp->get_time_last_pps(mboard);
|
||||
if (mboard_time != mboard0_time)
|
||||
{
|
||||
all_matched = false;
|
||||
std::cerr << (boost::format("ERROR: Times are not aligned: USRP 0=%0.9f, USRP %d=%0.9f")
|
||||
% mboard0_time.get_real_secs()
|
||||
% mboard
|
||||
% mboard_time.get_real_secs()) << std::endl;
|
||||
}
|
||||
}
|
||||
if (all_matched)
|
||||
{
|
||||
std::cout << "SUCCESS: USRP times aligned" << std::endl << std::endl;
|
||||
} else {
|
||||
std::cout << "ERROR: USRP times are not aligned" << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << boost::format("\nError: %s") % e.what();
|
||||
std::cout << boost::format("This could mean that you have not installed the GPSDO correctly.\n\n");
|
||||
std::cout << boost::format("Visit one of these pages if the problem persists:\n");
|
||||
std::cout << boost::format(" * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html");
|
||||
std::cout << boost::format(" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n");
|
||||
std::cout << boost::format(" * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error
|
||||
@param device pointer to the device structure specific to the RF hardware target
|
||||
@@ -277,31 +106,9 @@ static int trx_usrp_start(openair0_device *device) {
|
||||
|
||||
usrp_state_t *s = (usrp_state_t*)device->priv;
|
||||
|
||||
|
||||
// setup GPIO for TDD, GPIO(4) = ATR_RX
|
||||
//set data direction register (DDR) to output
|
||||
s->usrp->set_gpio_attr("FP0", "DDR", 0x1f, 0x1f);
|
||||
|
||||
//set control register to ATR
|
||||
s->usrp->set_gpio_attr("FP0", "CTRL", 0x1f,0x1f);
|
||||
|
||||
//set ATR register
|
||||
s->usrp->set_gpio_attr("FP0", "ATR_RX", 1<<4, 0x1f);
|
||||
|
||||
// init recv and send streaming
|
||||
uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
|
||||
LOG_I(PHY,"Time in secs now: %llu \n", s->usrp->get_time_now().to_ticks(s->sample_rate));
|
||||
LOG_I(PHY,"Time in secs last pps: %llu \n", s->usrp->get_time_last_pps().to_ticks(s->sample_rate));
|
||||
|
||||
if (s->use_gps == 1) {
|
||||
s->wait_for_first_pps = 1;
|
||||
cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0);
|
||||
}
|
||||
else {
|
||||
s->wait_for_first_pps = 0;
|
||||
cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05);
|
||||
}
|
||||
|
||||
cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05);
|
||||
cmd.stream_now = false; // start at constant delay
|
||||
s->rx_stream->issue_stream_cmd(cmd);
|
||||
|
||||
@@ -420,11 +227,9 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
|
||||
while (samples_received != nsamps) {
|
||||
samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received,
|
||||
nsamps-samples_received, s->rx_md);
|
||||
if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE))
|
||||
if (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)
|
||||
break;
|
||||
if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { printf("sleep...\n");} //usleep(100);
|
||||
}
|
||||
if (samples_received == nsamps) s->wait_for_first_pps=0;
|
||||
}
|
||||
// bring RX data into 12 LSBs for softmodem RX
|
||||
for (int i=0; i<cc; i++) {
|
||||
@@ -663,10 +468,6 @@ extern "C" {
|
||||
int device_init(openair0_device* device, openair0_config_t *openair0_cfg) {
|
||||
uhd::set_thread_priority_safe(1.0);
|
||||
usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1);
|
||||
|
||||
if (openair0_cfg[0].clock_source==gpsdo)
|
||||
s->use_gps =1;
|
||||
|
||||
// Initialize USRP device
|
||||
device->openair0_cfg = openair0_cfg;
|
||||
|
||||
@@ -760,13 +561,10 @@ extern "C" {
|
||||
// set master clock rate and sample rate for tx & rx for streaming
|
||||
|
||||
// lock mboard clocks
|
||||
if (openair0_cfg[0].clock_source == internal){
|
||||
s->usrp->set_clock_source("internal");
|
||||
}
|
||||
else{
|
||||
if (openair0_cfg[0].clock_source == internal)
|
||||
s->usrp->set_clock_source("internal");
|
||||
else
|
||||
s->usrp->set_clock_source("external");
|
||||
s->usrp->set_time_source("external");
|
||||
}
|
||||
|
||||
device->type = USRP_B200_DEV;
|
||||
if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) {
|
||||
@@ -885,6 +683,8 @@ extern "C" {
|
||||
for(int i=0; i<s->usrp->get_rx_num_channels() && i<openair0_cfg[0].rx_num_channels; i++)
|
||||
s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i);
|
||||
|
||||
s->usrp->set_time_now(uhd::time_spec_t(0.0));
|
||||
|
||||
for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) {
|
||||
LOG_I(PHY,"RX Channel %d\n",i);
|
||||
LOG_I(PHY," Actual RX sample rate: %fMSps...\n",s->usrp->get_rx_rate(i)/1e6);
|
||||
@@ -926,14 +726,6 @@ extern "C" {
|
||||
s->tx_forward_nsamps = 90;
|
||||
if(is_equal(s->sample_rate, (double)7.68e6))
|
||||
s->tx_forward_nsamps = 50;
|
||||
|
||||
if (s->use_gps == 1) {
|
||||
if (sync_to_gps(device)) {
|
||||
LOG_I(PHY,"USRP fails to sync with GPS...\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
146
targets/ARCH/mobipass/main.c
Normal file
146
targets/ARCH/mobipass/main.c
Normal file
@@ -0,0 +1,146 @@
|
||||
#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 trx_eth_start(openair0_device *device) { init_mobipass(); return 0;}
|
||||
int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0;}
|
||||
int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0;}
|
||||
int trx_eth_get_stats(openair0_device* device) { return(0); }
|
||||
int trx_eth_reset_stats(openair0_device* device) { return(0); }
|
||||
void trx_eth_end(openair0_device *device) {}
|
||||
int trx_eth_stop(openair0_device *device) { return(0); }
|
||||
int trx_eth_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { return(0); }
|
||||
int trx_eth_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) {
|
||||
struct mobipass_header *mh = (struct mobipass_header *)(((char *)buff[0]) + 14);
|
||||
static uint32_t last_timestamp = 4*7680*2-640;
|
||||
last_timestamp += 640;
|
||||
last_timestamp %= SAMPLES_PER_1024_FRAMES;
|
||||
mh->timestamp = htonl(ntohl(mh->timestamp) % SAMPLES_PER_1024_FRAMES);
|
||||
if (last_timestamp != ntohl(mh->timestamp)) { printf("bad timestamp wanted %d got %d\n", 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();
|
||||
mobipass_send(buff[0]);
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
int mobipass_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
|
||||
static uint32_t ts = 0;
|
||||
static unsigned char seqno = 0;
|
||||
//printf("__read nsamps %d return timestamp %d\n", nsamps, ts);
|
||||
*timestamp = htonl(ts);
|
||||
ts += nsamps;
|
||||
ts %= SAMPLES_PER_1024_FRAMES;
|
||||
if (nsamps != 640) { printf("bad nsamps %d, should be 640\n", nsamps); fflush(stdout); abort(); }
|
||||
|
||||
dequeue_from_mobipass(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 = seqno++;
|
||||
mh->ack = 0;
|
||||
mh->word0 = 0;
|
||||
mh->timestamp = htonl(ts);
|
||||
#endif
|
||||
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
int transport_init(openair0_device *device, openair0_config_t *openair0_cfg,
|
||||
eth_params_t * eth_params )
|
||||
{
|
||||
//init_mobipass();
|
||||
|
||||
eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
|
||||
memset(eth, 0, sizeof(eth_state_t));
|
||||
|
||||
if (eth_params->transp_preference != 4) goto err;
|
||||
if (eth_params->if_compress != 0) goto err;
|
||||
|
||||
eth->flags = ETH_RAW_IF5_MOBIPASS;
|
||||
eth->compression = NO_COMPRESS;
|
||||
device->Mod_id = 0;//num_devices_eth++;
|
||||
device->transp_type = ETHERNET_TP;
|
||||
|
||||
device->trx_start_func = trx_eth_start;
|
||||
device->trx_request_func = trx_eth_request;
|
||||
device->trx_reply_func = trx_eth_reply;
|
||||
device->trx_get_stats_func = trx_eth_get_stats;
|
||||
device->trx_reset_stats_func = trx_eth_reset_stats;
|
||||
device->trx_end_func = trx_eth_end;
|
||||
device->trx_stop_func = trx_eth_stop;
|
||||
device->trx_set_freq_func = trx_eth_set_freq;
|
||||
device->trx_set_gains_func = trx_eth_set_gains;
|
||||
device->trx_write_func = mobipass_write;
|
||||
device->trx_read_func = mobipass_read;
|
||||
|
||||
eth->if_name = eth_params->local_if_name;
|
||||
device->priv = eth;
|
||||
|
||||
/* 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("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: bad config file?\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -1,24 +1,3 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -40,21 +19,28 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
static void init_time(mobipass_state_t *mobi)
|
||||
#if 0
|
||||
struct timespec {
|
||||
time_t tv_sec; /* seconds */
|
||||
long tv_nsec; /* nanoseconds */
|
||||
};
|
||||
#endif
|
||||
|
||||
static uint64_t t0;
|
||||
|
||||
static void init_time(void)
|
||||
{
|
||||
struct timespec now;
|
||||
if (clock_gettime(CLOCK_MONOTONIC_RAW, &now)) abort();
|
||||
mobi->t0 = (uint64_t)now.tv_sec * (uint64_t)1000000000 + (uint64_t)now.tv_nsec;
|
||||
t0 = (uint64_t)now.tv_sec * (uint64_t)1000000000 + (uint64_t)now.tv_nsec;
|
||||
}
|
||||
|
||||
/* called before sending data to mobipass
|
||||
* waits if called too early with respect to system clock
|
||||
* does not wait more than 1ms in any case
|
||||
*/
|
||||
static void synch_time(mobipass_state_t *mobi, uint32_t ts)
|
||||
static void synch_time(uint32_t ts)
|
||||
{
|
||||
if (ts < mobi->synch_time_last_ts) mobi->synch_time_mega_ts++;
|
||||
mobi->synch_time_last_ts = ts;
|
||||
static uint32_t last_ts = 0;
|
||||
static uint64_t mega_ts = 0;
|
||||
if (ts < last_ts) mega_ts++;
|
||||
last_ts = ts;
|
||||
|
||||
struct timespec now;
|
||||
if (clock_gettime(CLOCK_MONOTONIC_RAW, &now)) abort();
|
||||
@@ -62,20 +48,21 @@ static void synch_time(mobipass_state_t *mobi, uint32_t ts)
|
||||
uint64_t tnow;
|
||||
tnow = (uint64_t)now.tv_sec * (uint64_t)1000000000 + (uint64_t)now.tv_nsec;
|
||||
|
||||
uint64_t cur = tnow - mobi->t0;
|
||||
uint64_t cur = tnow - t0;
|
||||
|
||||
/* 15360000 samples/second, in nanoseconds:
|
||||
* = 15360000 / 1000000000 = 1536 / 100000 = 48 / 3125*/
|
||||
|
||||
uint64_t ts_ns = ((uint64_t)ts + mobi->synch_time_mega_ts * (uint64_t)mobi->samples_per_1024_frames) * (uint64_t)3125 / (uint64_t)48;
|
||||
uint64_t ts_ns = ((uint64_t)ts + mega_ts * (uint64_t)SAMPLES_PER_1024_FRAMES) * (uint64_t)3125 / (uint64_t)48;
|
||||
|
||||
/* TODO: if cur is way higher than ts_ns, we are very late, log something? */
|
||||
//printf("tnow %lu t0 %lu ts %u cur %lu ts_ns %lu mega_ts %lu\n", tnow, t0, ts, cur, ts_ns, mega_ts);
|
||||
if (cur >= ts_ns) return;
|
||||
|
||||
uint64_t delta = ts_ns - cur;
|
||||
/* don't sleep more than 1 ms */
|
||||
if (delta > 1000*1000) delta = 1000*1000;
|
||||
delta = delta/1000;
|
||||
//printf("ts %u delta %lu\n", ts, delta);
|
||||
if (delta) usleep(delta);
|
||||
}
|
||||
|
||||
@@ -83,6 +70,10 @@ static void synch_time(mobipass_state_t *mobi, uint32_t ts)
|
||||
/* time end */
|
||||
/******************************************************************/
|
||||
|
||||
static unsigned char receive_packet[14 + 14 + 1280];
|
||||
static int sock;
|
||||
static unsigned char packet[14 + 14 + 1280];
|
||||
|
||||
struct ethernet_header {
|
||||
unsigned char dst[6];
|
||||
unsigned char src[6];
|
||||
@@ -98,37 +89,112 @@ struct mobipass_header {
|
||||
uint32_t timestamp;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
static void do_receive(mobipass_state_t *mobi, unsigned char *b)
|
||||
static void receive(int sock, unsigned char *b)
|
||||
{
|
||||
if (recv(mobi->sock, b, 14+14+1280, 0) != 14+14+1280) { perror("recv"); exit(1); }
|
||||
if (recv(sock, b, 14+14+1280, 0) != 14+14+1280) { perror("recv"); exit(1); }
|
||||
struct mobipass_header *mh = (struct mobipass_header *)(b+14);
|
||||
mh->timestamp = htonl((ntohl(mh->timestamp)-45378/*40120*/) % mobi->samples_per_1024_frames);
|
||||
mh->timestamp = htonl((ntohl(mh->timestamp)-45378/*40120*/) % SAMPLES_PER_1024_FRAMES);
|
||||
//printf("recv timestamp %u\n", ntohl(mh->timestamp));
|
||||
}
|
||||
|
||||
/* receiver thread */
|
||||
static void *receiver(void *_mobi)
|
||||
void mobipass_send(void *data)
|
||||
{
|
||||
mobipass_state_t *mobi = _mobi;
|
||||
unsigned char receive_packet[14 + 14 + 1280];
|
||||
//printf("SEND seqno %d ts %d\n", seqno, ts);
|
||||
struct ethernet_header *eh = (struct ethernet_header *)data;
|
||||
//struct mobipass_header *mh = (struct mobipass_header *)(data+14);
|
||||
//printf("SEND seqno %d ts %d\n", mh->seqno, ntohl(mh->timestamp));
|
||||
|
||||
eh->dst[0] = 0x00;
|
||||
eh->dst[1] = 0x21;
|
||||
eh->dst[2] = 0x5e;
|
||||
eh->dst[3] = 0x91;
|
||||
eh->dst[4] = 0x5c;
|
||||
eh->dst[5] = 0x7e;
|
||||
|
||||
eh->src[0] = 0xf0;
|
||||
eh->src[1] = 0x1f;
|
||||
eh->src[2] = 0xaf;
|
||||
eh->src[3] = 0xdb;
|
||||
eh->src[4] = 0xb9;
|
||||
eh->src[5] = 0xc8;
|
||||
|
||||
eh->packet_type = htons(0xbffe);
|
||||
|
||||
enqueue_to_mobipass(data);
|
||||
// if (send(sock, data, 14+14+1280, 0) != 14+14+1280) { perror("recv"); exit(1); }
|
||||
|
||||
//usleep(1000/24+1);
|
||||
|
||||
#if 0
|
||||
mh->flags = 0;
|
||||
mh->fifo_status = 0;
|
||||
mh->seqno = seqno;
|
||||
mh->ack = 0;
|
||||
mh->word0 = 0;
|
||||
mh->timestamp = ntohl(ts);
|
||||
|
||||
static int pos = 0;
|
||||
memcpy(packet+14+14, frame+pos, 640*2);
|
||||
pos += 640*2;
|
||||
if (pos >= 1024*10*7680*2*2) pos = 0;
|
||||
if (send(sock, packet, 14+14+1280, 0) != 14+14+1280) { perror("recv"); exit(1); }
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *receiver(void *_)
|
||||
{
|
||||
// unsigned char last_seqno = 0;
|
||||
while (1) {
|
||||
do_receive(mobi, receive_packet);
|
||||
enqueue_from_mobipass(mobi->qstate, receive_packet);
|
||||
//struct ethernet_header *eh;
|
||||
//struct mobipass_header *mh;
|
||||
receive(sock, receive_packet);
|
||||
enqueue_from_mobipass(receive_packet);
|
||||
#if 0
|
||||
eh = (struct ethernet_header *)receive_packet;
|
||||
printf("got dst %2.2x.%2.2x.%2.2x.%2.2x.%2.2x.%2.2x src %2.2x.%2.2x.%2.2x.%2.2x.%2.2x.%2.2x type %d\n",
|
||||
eh->dst[0], eh->dst[1], eh->dst[2],
|
||||
eh->dst[3], eh->dst[4], eh->dst[5],
|
||||
eh->src[0], eh->src[1], eh->src[2],
|
||||
eh->src[3], eh->src[4], eh->src[5],
|
||||
ntohs(eh->packet_type));
|
||||
eh = (struct ethernet_header *)receive_packet;
|
||||
mh = (struct mobipass_header *)(receive_packet+14);
|
||||
printf(" flag %d fifo %d seq %d ack %d w0 %d ts %d\n",
|
||||
ntohs(mh->flags),
|
||||
ntohs(mh->fifo_status),
|
||||
mh->seqno,
|
||||
mh->ack,
|
||||
ntohl(mh->word0),
|
||||
ntohl(mh->timestamp));
|
||||
last_seqno++;
|
||||
if (last_seqno != mh->seqno) printf("DISCONTINU\n");
|
||||
last_seqno = mh->seqno;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void do_send(mobipass_state_t *mobi, int seqno, uint32_t ts,
|
||||
unsigned char *packet)
|
||||
void dosend(int sock, int seqno, uint32_t ts)
|
||||
{
|
||||
struct ethernet_header *eh = (struct ethernet_header *)packet;
|
||||
struct mobipass_header *mh = (struct mobipass_header *)(packet+14);
|
||||
|
||||
ts %= mobi->samples_per_1024_frames;
|
||||
ts %= SAMPLES_PER_1024_FRAMES;
|
||||
//printf("SEND seqno %d ts %d\n", seqno, ts);
|
||||
|
||||
memcpy(eh->dst, mobi->eth_remote, 6);
|
||||
memcpy(eh->src, mobi->eth_local, 6);
|
||||
eh->dst[0] = 0x00;
|
||||
eh->dst[1] = 0x21;
|
||||
eh->dst[2] = 0x5e;
|
||||
eh->dst[3] = 0x91;
|
||||
eh->dst[4] = 0x5c;
|
||||
eh->dst[5] = 0x7e;
|
||||
|
||||
eh->src[0] = 0xf0;
|
||||
eh->src[1] = 0x1f;
|
||||
eh->src[2] = 0xaf;
|
||||
eh->src[3] = 0xdb;
|
||||
eh->src[4] = 0xb9;
|
||||
eh->src[5] = 0xc8;
|
||||
|
||||
eh->packet_type = htons(0xbffe);
|
||||
|
||||
@@ -139,26 +205,32 @@ static void do_send(mobipass_state_t *mobi, int seqno, uint32_t ts,
|
||||
mh->word0 = 0;
|
||||
mh->timestamp = htonl(ts);
|
||||
|
||||
synch_time(mobi, ts);
|
||||
#if 0
|
||||
static int pos = 0;
|
||||
memcpy(packet+14+14, frame+pos, 640*2);
|
||||
pos += 640*2;
|
||||
if (pos >= 1024*10*7680*2*2) pos = 0;
|
||||
#endif
|
||||
|
||||
if (send(mobi->sock, packet, 14+14+1280, 0) != 14+14+1280) { perror("send"); exit(1); }
|
||||
synch_time(ts);
|
||||
|
||||
if (send(sock, packet, 14+14+1280, 0) != 14+14+1280) { perror("recv"); exit(1); }
|
||||
//usleep(1000/500);
|
||||
//usleep(1);
|
||||
}
|
||||
|
||||
/* sender thread */
|
||||
static void *sender(void *_mobi)
|
||||
void *sender(void *_)
|
||||
{
|
||||
mobipass_state_t *mobi = _mobi;
|
||||
unsigned char packet[14 + 14 + 1280];
|
||||
uint32_t ts = 0;
|
||||
unsigned char seqno = 0;
|
||||
//int i;
|
||||
while (1) {
|
||||
dequeue_to_mobipass(mobi->qstate, ts, packet);
|
||||
do_send(mobi, seqno, ts, packet);
|
||||
dequeue_to_mobipass(ts, packet);
|
||||
dosend(sock, seqno, ts);
|
||||
seqno++;
|
||||
ts += 640;
|
||||
ts %= mobi->samples_per_1024_frames;
|
||||
ts %= SAMPLES_PER_1024_FRAMES;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void new_thread(void *(*f)(void *), void *data)
|
||||
@@ -178,15 +250,15 @@ static void new_thread(void *(*f)(void *), void *data)
|
||||
{ fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
|
||||
}
|
||||
|
||||
void init_mobipass(mobipass_state_t *mobi)
|
||||
void init_mobipass(void)
|
||||
{
|
||||
int i;
|
||||
unsigned char data[14+14+640];
|
||||
memset(data, 0, 14+14+640);
|
||||
|
||||
init_time(mobi);
|
||||
init_time();
|
||||
|
||||
mobi->qstate = init_queues(mobi->samples_per_1024_frames);
|
||||
init_queues();
|
||||
|
||||
for (i = 0; i < 24*4; i++) {
|
||||
uint32_t timestamp = i*640;
|
||||
@@ -194,17 +266,17 @@ void init_mobipass(mobipass_state_t *mobi)
|
||||
struct mobipass_header *mh = (struct mobipass_header *)(data+14);
|
||||
mh->seqno = seqno;
|
||||
mh->timestamp = htonl(timestamp);
|
||||
enqueue_to_mobipass(mobi->qstate, data);
|
||||
enqueue_to_mobipass(data);
|
||||
}
|
||||
|
||||
mobi->sock = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
|
||||
if (mobi->sock == -1) { perror("socket"); exit(1); }
|
||||
sock = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
|
||||
if (sock == -1) { perror("socket"); exit(1); }
|
||||
|
||||
/* get if index */
|
||||
struct ifreq if_index;
|
||||
memset(&if_index, 0, sizeof(struct ifreq));
|
||||
strcpy(if_index.ifr_name, mobi->eth.if_name);
|
||||
if (ioctl(mobi->sock, SIOCGIFINDEX, &if_index)<0) {perror("SIOCGIFINDEX");exit(1);}
|
||||
strcpy(if_index.ifr_name, "eth1.300");
|
||||
if (ioctl(sock, SIOCGIFINDEX, &if_index)<0) {perror("SIOCGIFINDEX");exit(1);}
|
||||
|
||||
struct sockaddr_ll local_addr;
|
||||
local_addr.sll_family = AF_PACKET;
|
||||
@@ -213,9 +285,34 @@ void init_mobipass(mobipass_state_t *mobi)
|
||||
local_addr.sll_halen = ETH_ALEN;
|
||||
local_addr.sll_pkttype = PACKET_OTHERHOST;
|
||||
|
||||
if (bind(mobi->sock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_ll))<0)
|
||||
if (bind(sock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_ll))<0)
|
||||
{ perror("bind"); exit(1); }
|
||||
|
||||
new_thread(receiver, mobi);
|
||||
new_thread(sender, mobi);
|
||||
new_thread(receiver, NULL);
|
||||
new_thread(sender, NULL);
|
||||
|
||||
#if 0
|
||||
|
||||
while (1) {
|
||||
struct ethernet_header *eh;
|
||||
struct mobipass_header *mh;
|
||||
receive(sock, receive_packet);
|
||||
eh = (struct ethernet_header *)receive_packet;
|
||||
printf("got dst %2.2x.%2.2x.%2.2x.%2.2x.%2.2x.%2.2x src %2.2x.%2.2x.%2.2x.%2.2x.%2.2x.%2.2x type %d\n",
|
||||
eh->dst[0], eh->dst[1], eh->dst[2],
|
||||
eh->dst[3], eh->dst[4], eh->dst[5],
|
||||
eh->src[0], eh->src[1], eh->src[2],
|
||||
eh->src[3], eh->src[4], eh->src[5],
|
||||
ntohs(eh->packet_type));
|
||||
eh = (struct ethernet_header *)receive_packet;
|
||||
mh = (struct mobipass_header *)(receive_packet+14);
|
||||
printf(" flag %d fifo %d seq %d ack %d w0 %d ts %d\n",
|
||||
ntohs(mh->flags),
|
||||
ntohs(mh->fifo_status),
|
||||
mh->seqno,
|
||||
mh->ack,
|
||||
ntohl(mh->word0),
|
||||
ntohl(mh->timestamp));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,59 +1,10 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _MOBIPASS_H_
|
||||
#define _MOBIPASS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ethernet_lib.h"
|
||||
void mobipass_send(void *data);
|
||||
void init_mobipass(void);
|
||||
|
||||
typedef struct {
|
||||
/* this has to come first */
|
||||
eth_state_t eth;
|
||||
|
||||
void *qstate;
|
||||
|
||||
uint8_t eth_local[6];
|
||||
uint8_t eth_remote[6];
|
||||
|
||||
int samples_per_1024_frames;
|
||||
|
||||
/* variables used by the function interface.c:mobipass_read */
|
||||
uint32_t mobipass_read_ts;
|
||||
unsigned char mobipass_read_seqno;
|
||||
|
||||
/* variables used by the function interface.c:mobipass_write */
|
||||
uint32_t mobipass_write_last_timestamp;
|
||||
|
||||
/* variables used by the function mobipass.c:[init_time|synch_time] */
|
||||
uint64_t t0;
|
||||
|
||||
/* variables used by the function mobipass.c:synch_time */
|
||||
uint32_t synch_time_last_ts;
|
||||
uint64_t synch_time_mega_ts;
|
||||
|
||||
/* sock is used in mobipass.c */
|
||||
int sock;
|
||||
} mobipass_state_t;
|
||||
|
||||
void init_mobipass(mobipass_state_t *mobi);
|
||||
/* TODO: following variable only works for 10MHz */
|
||||
#define SAMPLES_PER_1024_FRAMES (7680*2*10*1024)
|
||||
|
||||
#endif /* _MOBIPASS_H_ */
|
||||
|
||||
@@ -1,24 +1,3 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "queues.h"
|
||||
#include "mobipass.h"
|
||||
|
||||
@@ -43,6 +22,7 @@ struct mobipass_header {
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct queue {
|
||||
// uint32_t next_timestamp;
|
||||
unsigned char buf[QSIZE][14+14+640*2];
|
||||
volatile int start;
|
||||
volatile int len;
|
||||
@@ -50,25 +30,8 @@ struct queue {
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct queue to_mobipass;
|
||||
struct queue from_mobipass;
|
||||
int samples_per_1024_frames;
|
||||
|
||||
/* variables used by dequeue_from_mobipass */
|
||||
int dequeue_from_mobipass_seqno;
|
||||
|
||||
/* variables used to manage logging of "missing samples"
|
||||
* coming from mobipass. (Yes, this can happen, mostly
|
||||
* at startup.)
|
||||
* This idea is to print some logs, but not too much to
|
||||
* flood stdout. (This is already a bad idea to call
|
||||
* printf in a 'realtime' thread.)
|
||||
*/
|
||||
int no_sample_log_running;
|
||||
uint32_t no_sample_log_start_sample;
|
||||
uint32_t no_sample_log_next_sample;
|
||||
} queue_state_t;
|
||||
static struct queue to_mobipass;
|
||||
static struct queue from_mobipass;
|
||||
|
||||
static void enqueue(void *data, struct queue *q)
|
||||
{
|
||||
@@ -76,7 +39,7 @@ static void enqueue(void *data, struct queue *q)
|
||||
|
||||
if (pthread_mutex_lock(&q->mutex)) abort();
|
||||
if (q->len == QSIZE) {
|
||||
printf("mobipass: WARNING: enqueue: full\n");
|
||||
printf("enqueue: full\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -84,133 +47,93 @@ static void enqueue(void *data, struct queue *q)
|
||||
memcpy(q->buf[pos], data, 14+14+640*2);
|
||||
q->len++;
|
||||
|
||||
//if (q == &from_mobipass) {
|
||||
//struct mobipass_header *mh = (struct mobipass_header *)((char*)data+14);
|
||||
//printf("recv timestamp %u in pos %d\n", ntohl(mh->timestamp), pos);
|
||||
//}
|
||||
|
||||
done:
|
||||
if (pthread_cond_signal(&q->cond)) abort();
|
||||
if (pthread_mutex_unlock(&q->mutex)) abort();
|
||||
}
|
||||
|
||||
void enqueue_to_mobipass(void *_qstate, void *data)
|
||||
void enqueue_to_mobipass(void *data)
|
||||
{
|
||||
queue_state_t *qstate = _qstate;
|
||||
enqueue(data, &qstate->to_mobipass);
|
||||
enqueue(data, &to_mobipass);
|
||||
}
|
||||
|
||||
void dequeue_to_mobipass(void *_qstate, uint32_t timestamp, void *data)
|
||||
void dequeue_to_mobipass(uint32_t timestamp, void *data)
|
||||
{
|
||||
queue_state_t *qstate = _qstate;
|
||||
if (pthread_mutex_lock(&qstate->to_mobipass.mutex)) abort();
|
||||
while (qstate->to_mobipass.len == 0) {
|
||||
if (pthread_cond_wait(&qstate->to_mobipass.cond, &qstate->to_mobipass.mutex)) abort();
|
||||
if (pthread_mutex_lock(&to_mobipass.mutex)) abort();
|
||||
while (to_mobipass.len == 0) {
|
||||
if (pthread_cond_wait(&to_mobipass.cond, &to_mobipass.mutex)) abort();
|
||||
}
|
||||
|
||||
memcpy(data, qstate->to_mobipass.buf[qstate->to_mobipass.start], 14+14+640*2);
|
||||
qstate->to_mobipass.len--;
|
||||
qstate->to_mobipass.start = (qstate->to_mobipass.start + 1) % QSIZE;
|
||||
memcpy(data, to_mobipass.buf[to_mobipass.start], 14+14+640*2);
|
||||
to_mobipass.len--;
|
||||
to_mobipass.start = (to_mobipass.start + 1) % QSIZE;
|
||||
|
||||
if (pthread_mutex_unlock(&qstate->to_mobipass.mutex)) abort();
|
||||
if (pthread_mutex_unlock(&to_mobipass.mutex)) abort();
|
||||
}
|
||||
|
||||
void enqueue_from_mobipass(void *_qstate, void *data)
|
||||
void enqueue_from_mobipass(void *data)
|
||||
{
|
||||
queue_state_t *qstate = _qstate;
|
||||
struct mobipass_header *mh = (struct mobipass_header *)((char*)data+14);
|
||||
mh->timestamp = htonl(ntohl(mh->timestamp) % qstate->samples_per_1024_frames);
|
||||
//printf("from mobipass! timestamp %u seqno %d\n", ntohl(mh->timestamp), mh->seqno);
|
||||
enqueue(data, &qstate->from_mobipass);
|
||||
mh->timestamp = htonl(ntohl(mh->timestamp) % SAMPLES_PER_1024_FRAMES);
|
||||
//printf("from mobipass! timestamp %u seqno %d\n", ntohl(mh->timestamp), mh->seqno);
|
||||
enqueue(data, &from_mobipass);
|
||||
}
|
||||
|
||||
static int cmp_timestamps(uint32_t a, uint32_t b, int samples_per_1024_frames)
|
||||
static int cmp_timestamps(uint32_t a, uint32_t b)
|
||||
{
|
||||
if (a == b) return 0;
|
||||
if (a < b) {
|
||||
if (b-a > samples_per_1024_frames/2) return 1;
|
||||
if (b-a > SAMPLES_PER_1024_FRAMES/2) return 1;
|
||||
return -1;
|
||||
}
|
||||
if (a-b > samples_per_1024_frames/2) return -1;
|
||||
if (a-b > SAMPLES_PER_1024_FRAMES/2) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*************************************************/
|
||||
/* missing samples logging management begin */
|
||||
/*************************************************/
|
||||
|
||||
static void log_flush(queue_state_t *qstate)
|
||||
{
|
||||
/* print now if there is something to print */
|
||||
if (qstate->no_sample_log_running == 0)
|
||||
return;
|
||||
qstate->no_sample_log_running = 0;
|
||||
printf("mobipass: WARNING: missing samples [%u-%u]\n",
|
||||
qstate->no_sample_log_start_sample,
|
||||
(uint32_t)(qstate->no_sample_log_next_sample-1));
|
||||
}
|
||||
|
||||
static void log_missed_sample(queue_state_t *qstate, uint32_t timestamp)
|
||||
{
|
||||
/* collect data, print if there is a discontinuity */
|
||||
if (qstate->no_sample_log_running == 0 ||
|
||||
timestamp != qstate->no_sample_log_next_sample) {
|
||||
log_flush(qstate);
|
||||
qstate->no_sample_log_start_sample = timestamp;
|
||||
}
|
||||
|
||||
qstate->no_sample_log_next_sample = timestamp+1;
|
||||
qstate->no_sample_log_running = 1;
|
||||
}
|
||||
|
||||
static void log_flush_if_old(queue_state_t *qstate, uint32_t timestamp)
|
||||
{
|
||||
/* log every second (more or less), if we have to */
|
||||
/* note that if mobipass stopped, it may take much more
|
||||
* than one second to log, due to the sleeps done while
|
||||
* waiting for samples (that never come)
|
||||
*/
|
||||
if (qstate->no_sample_log_running == 1 &&
|
||||
labs(timestamp-qstate->no_sample_log_start_sample) > qstate->samples_per_1024_frames/10)
|
||||
log_flush(qstate);
|
||||
}
|
||||
|
||||
/*************************************************/
|
||||
/* missing samples logging management end */
|
||||
/*************************************************/
|
||||
|
||||
/* to be called with lock on */
|
||||
static void get_sample_from_mobipass(queue_state_t *qstate, char *I, char *Q, uint32_t timestamp)
|
||||
static void get_sample_from_mobipass(char *I, char *Q, uint32_t timestamp)
|
||||
{
|
||||
unsigned char *b = NULL;
|
||||
unsigned char *data = NULL;
|
||||
struct mobipass_header *mh = NULL;
|
||||
uint32_t packet_timestamp = 0;
|
||||
|
||||
#if 0
|
||||
uint32_t old_start = qstate->from_mobipass.start;
|
||||
uint32_t old_len = qstate->from_mobipass.len;
|
||||
b = qstate->from_mobipass.buf[qstate->from_mobipass.start];
|
||||
uint32_t old_start = from_mobipass.start;
|
||||
uint32_t old_len = from_mobipass.len;
|
||||
b = from_mobipass.buf[from_mobipass.start];
|
||||
mh = (struct mobipass_header *)(b+14);
|
||||
uint32_t old_pts = qstate->from_mobipass.len ? ntohl(mh->timestamp) : -1;
|
||||
uint32_t old_pts = from_mobipass.len ? ntohl(mh->timestamp) : -1;
|
||||
b=NULL;
|
||||
mh=NULL;
|
||||
#endif
|
||||
|
||||
while (qstate->from_mobipass.len) {
|
||||
b = qstate->from_mobipass.buf[qstate->from_mobipass.start];
|
||||
while (from_mobipass.len) {
|
||||
b = from_mobipass.buf[from_mobipass.start];
|
||||
mh = (struct mobipass_header *)(b+14);
|
||||
data = b + 14*2;
|
||||
packet_timestamp = ntohl(mh->timestamp);
|
||||
if (cmp_timestamps(timestamp, packet_timestamp, qstate->samples_per_1024_frames) < 0) goto nodata;
|
||||
if (cmp_timestamps(timestamp, (packet_timestamp+640) % qstate->samples_per_1024_frames, qstate->samples_per_1024_frames) < 0) break;
|
||||
qstate->from_mobipass.len--;
|
||||
qstate->from_mobipass.start = (qstate->from_mobipass.start+1) % QSIZE;
|
||||
//printf("cmp A %u pt %u start %d\n", timestamp, packet_timestamp, from_mobipass.start);
|
||||
if (cmp_timestamps(timestamp, packet_timestamp) < 0) goto nodata;
|
||||
//printf("cmp B %u pt %u\n", timestamp, packet_timestamp);
|
||||
if (cmp_timestamps(timestamp, (packet_timestamp+640) % SAMPLES_PER_1024_FRAMES) < 0) break;
|
||||
//printf("cmp C %u pt %u\n", timestamp, packet_timestamp);
|
||||
from_mobipass.len--;
|
||||
from_mobipass.start = (from_mobipass.start+1) % QSIZE;
|
||||
}
|
||||
|
||||
if (qstate->from_mobipass.len == 0) goto nodata;
|
||||
if (from_mobipass.len == 0) goto nodata;
|
||||
|
||||
if (timestamp == (packet_timestamp + 639) % qstate->samples_per_1024_frames) {
|
||||
qstate->from_mobipass.len--;
|
||||
qstate->from_mobipass.start = (qstate->from_mobipass.start+1) % QSIZE;
|
||||
if (timestamp == (packet_timestamp + 639) % SAMPLES_PER_1024_FRAMES) {
|
||||
from_mobipass.len--;
|
||||
from_mobipass.start = (from_mobipass.start+1) % QSIZE;
|
||||
}
|
||||
|
||||
if (timestamp < packet_timestamp) timestamp += qstate->samples_per_1024_frames;
|
||||
if (timestamp < packet_timestamp) timestamp += SAMPLES_PER_1024_FRAMES;
|
||||
|
||||
*I = data[(timestamp - packet_timestamp) * 2];
|
||||
*Q = data[(timestamp - packet_timestamp) * 2 + 1];
|
||||
@@ -220,12 +143,7 @@ mh=NULL;
|
||||
nodata:
|
||||
*I = 0;
|
||||
*Q = 0;
|
||||
|
||||
log_missed_sample(qstate, timestamp);
|
||||
|
||||
#if 0
|
||||
printf("no sample timestamp %u pt %u start %d old_start %d old_pt %u len %d old len %d\n", timestamp, packet_timestamp, qstate->from_mobipass.start, old_start, old_pts, qstate->from_mobipass.len, old_len);
|
||||
#endif
|
||||
printf("no sample timestamp %u pt %u start %d old_start %d old_pt %u len %d old len %d\n", timestamp, packet_timestamp, from_mobipass.start, old_start, old_pts, from_mobipass.len, old_len);
|
||||
}
|
||||
|
||||
/* doesn't work with delay more than 1s */
|
||||
@@ -238,65 +156,71 @@ static void wait_for_data(pthread_cond_t *cond, pthread_mutex_t *mutex, int dela
|
||||
target.tv_nsec = (now.tv_usec + delay_us) * 1000;
|
||||
if (target.tv_nsec >= 1000 * 1000 * 1000) { target.tv_nsec -= 1000 * 1000 * 1000; target.tv_sec++; }
|
||||
int err = pthread_cond_timedwait(cond, mutex, &target);
|
||||
if (err != 0 && err != ETIMEDOUT) { printf("mobipass: ERROR: pthread_cond_timedwait: err (%d) %s\n", err, strerror(err)); abort(); }
|
||||
if (err != 0 && err != ETIMEDOUT) { printf("pthread_cond_timedwait: err (%d) %s\n", err, strerror(err)); abort(); }
|
||||
}
|
||||
|
||||
/* don't block infinitely when waiting for data
|
||||
* if waiting for too long, just return some zeros
|
||||
*/
|
||||
void dequeue_from_mobipass(void *_qstate, uint32_t timestamp, void *data)
|
||||
void dequeue_from_mobipass(uint32_t timestamp, void *data)
|
||||
{
|
||||
queue_state_t *qstate = _qstate;
|
||||
int i;
|
||||
// int ts = timestamp;
|
||||
int waiting_allowed;
|
||||
|
||||
if (pthread_mutex_lock(&qstate->from_mobipass.mutex)) abort();
|
||||
if (pthread_mutex_lock(&from_mobipass.mutex)) abort();
|
||||
|
||||
if (qstate->from_mobipass.len == 0) {
|
||||
//printf("sleep 1\n");
|
||||
wait_for_data(&qstate->from_mobipass.cond, &qstate->from_mobipass.mutex, 2000); //1000/3);
|
||||
#if 0
|
||||
printf("want dequeue ts %u queue (start %d len %d): [", timestamp, from_mobipass.start, from_mobipass.len);
|
||||
for (i = 0; i < from_mobipass.len; i++) {
|
||||
unsigned char *b = NULL;
|
||||
struct mobipass_header *mh = NULL;
|
||||
b = from_mobipass.buf[(from_mobipass.start + i) %QSIZE];
|
||||
mh = (struct mobipass_header *)(b+14);
|
||||
uint32_t packet_timestamp = ntohl(mh->timestamp);
|
||||
printf(" %d", packet_timestamp);
|
||||
}
|
||||
printf("]\n");
|
||||
#endif
|
||||
|
||||
if (from_mobipass.len == 0) {
|
||||
//if (pthread_mutex_unlock(&from_mobipass.mutex)) abort();
|
||||
printf("sleep 1\n");
|
||||
//usleep(1000/3);
|
||||
//if (pthread_mutex_lock(&from_mobipass.mutex)) abort();
|
||||
wait_for_data(&from_mobipass.cond, &from_mobipass.mutex, 2000); //1000/3);
|
||||
}
|
||||
|
||||
waiting_allowed = qstate->from_mobipass.len != 0;
|
||||
waiting_allowed = from_mobipass.len != 0;
|
||||
|
||||
for (i = 0; i < 640*2; i+=2) {
|
||||
if (qstate->from_mobipass.len == 0 && waiting_allowed) {
|
||||
if (from_mobipass.len == 0 && waiting_allowed) {
|
||||
//if (pthread_mutex_unlock(&from_mobipass.mutex)) abort();
|
||||
//printf("sleep 2\n");
|
||||
wait_for_data(&qstate->from_mobipass.cond, &qstate->from_mobipass.mutex, 2000); //1000/3);
|
||||
waiting_allowed = qstate->from_mobipass.len != 0;
|
||||
//usleep(1000/3);
|
||||
//if (pthread_mutex_lock(&from_mobipass.mutex)) abort();
|
||||
wait_for_data(&from_mobipass.cond, &from_mobipass.mutex, 2000); //1000/3);
|
||||
waiting_allowed = from_mobipass.len != 0;
|
||||
}
|
||||
|
||||
get_sample_from_mobipass(qstate, (char*)data + 14*2 + i, (char*)data + 14*2 + i+1, timestamp % qstate->samples_per_1024_frames);
|
||||
get_sample_from_mobipass((char*)data + 14*2 + i, (char*)data + 14*2 + i+1, timestamp % SAMPLES_PER_1024_FRAMES);
|
||||
timestamp++;
|
||||
}
|
||||
|
||||
log_flush_if_old(qstate, timestamp);
|
||||
if (pthread_mutex_unlock(&from_mobipass.mutex)) abort();
|
||||
|
||||
if (pthread_mutex_unlock(&qstate->from_mobipass.mutex)) abort();
|
||||
static int seqno = 0;
|
||||
|
||||
struct mobipass_header *mh = (struct mobipass_header *)(((char *)data) + 14);
|
||||
mh->flags = 0;
|
||||
mh->fifo_status = 0;
|
||||
mh->seqno = qstate->dequeue_from_mobipass_seqno++;
|
||||
mh->seqno = seqno++;
|
||||
mh->ack = 0;
|
||||
mh->word0 = 0;
|
||||
mh->timestamp = htonl(timestamp);
|
||||
}
|
||||
|
||||
void *init_queues(int samples_per_1024_frames)
|
||||
void init_queues(void)
|
||||
{
|
||||
queue_state_t *q;
|
||||
q = malloc(sizeof(queue_state_t));
|
||||
if (q == NULL) abort();
|
||||
memset(q, 0, sizeof(queue_state_t));
|
||||
|
||||
if (pthread_mutex_init(&q->to_mobipass.mutex, NULL)) abort();
|
||||
if (pthread_mutex_init(&q->from_mobipass.mutex, NULL)) abort();
|
||||
if (pthread_cond_init(&q->to_mobipass.cond, NULL)) abort();
|
||||
if (pthread_cond_init(&q->from_mobipass.cond, NULL)) abort();
|
||||
|
||||
q->samples_per_1024_frames = samples_per_1024_frames;
|
||||
|
||||
return q;
|
||||
if (pthread_mutex_init(&to_mobipass.mutex, NULL)) abort();
|
||||
if (pthread_mutex_init(&from_mobipass.mutex, NULL)) abort();
|
||||
if (pthread_cond_init(&to_mobipass.cond, NULL)) abort();
|
||||
if (pthread_cond_init(&from_mobipass.cond, NULL)) abort();
|
||||
}
|
||||
|
||||
@@ -1,36 +1,14 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _QUEUES_H_
|
||||
#define _QUEUES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void enqueue_to_mobipass(void *qstate, void *data);
|
||||
void dequeue_to_mobipass(void *qstate, uint32_t timestamp, void *data);
|
||||
void enqueue_to_mobipass(void *data);
|
||||
void dequeue_to_mobipass(uint32_t timestamp, void *data);
|
||||
|
||||
void enqueue_from_mobipass(void *qstate, void *receive_packet);
|
||||
void dequeue_from_mobipass(void *qstate, uint32_t timestamp, void *data);
|
||||
void enqueue_from_mobipass(void *receive_packet);
|
||||
void dequeue_from_mobipass(uint32_t timestamp, void *data);
|
||||
|
||||
/* returns a queue state type, as opaque data structure */
|
||||
void *init_queues(int samples_per_1024_frames);
|
||||
void init_queues(void);
|
||||
|
||||
#endif /* _QUEUES_H_ */
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
Active_eNBs = ( "eNB_Eurecom_LTEBox");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
eNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
eNB_ID = 0xe00;
|
||||
|
||||
cell_type = "CELL_MACRO_ENB";
|
||||
|
||||
eNB_name = "eNB_Eurecom_LTEBox";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = "1";
|
||||
|
||||
mobile_country_code = "208";
|
||||
|
||||
mobile_network_code = "92";
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
component_carriers = (
|
||||
// second carrier-> for ERCOM
|
||||
{
|
||||
node_function = "eNodeB_3GPP_BBU" # should be verified
|
||||
//node_function = "NGFI_RCC_IF5" # should be verified
|
||||
node_timing = "synch_to_mobipass_standalone";
|
||||
//node_timing = "synch_to_ext_device";
|
||||
node_synch_ref = 0; #should
|
||||
frame_type = "FDD";
|
||||
tdd_config = 3;
|
||||
tdd_config_s = 0;
|
||||
prefix_type = "NORMAL";
|
||||
eutra_band = 7;
|
||||
downlink_frequency = 2660000000L;
|
||||
uplink_frequency_offset = -120000000;
|
||||
Nid_cell = 0;
|
||||
N_RB_DL = 50;
|
||||
Nid_cell_mbsfn = 0;
|
||||
nb_antenna_ports = 1;
|
||||
nb_antennas_tx = 1;
|
||||
nb_antennas_rx = 1;
|
||||
tx_gain = 90;
|
||||
rx_gain = 125;
|
||||
prach_root = 0;
|
||||
prach_config_index = 0;
|
||||
prach_high_speed = "DISABLE";
|
||||
prach_zero_correlation = 3;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -29;
|
||||
pdsch_p_b = 0;
|
||||
pusch_n_SB = 1;
|
||||
pusch_enable64QAM = "DISABLE";
|
||||
pusch_hoppingMode = "interSubFrame";
|
||||
pusch_hoppingOffset = 0;
|
||||
pusch_groupHoppingEnabled = "ENABLE";
|
||||
pusch_groupAssignment = 0;
|
||||
pusch_sequenceHoppingEnabled = "DISABLE";
|
||||
pusch_nDMRS1 = 1;
|
||||
phich_duration = "NORMAL";
|
||||
phich_resource = "ONESIXTH";
|
||||
srs_enable = "DISABLE";
|
||||
/* srs_BandwidthConfig =;
|
||||
srs_SubframeConfig =;
|
||||
srs_ackNackST =;
|
||||
srs_MaxUpPts =;*/
|
||||
|
||||
pusch_p0_Nominal = -96;
|
||||
pusch_alpha = "AL1";
|
||||
pucch_p0_Nominal = -100;
|
||||
msg3_delta_Preamble = 6;
|
||||
pucch_deltaF_Format1 = "deltaF2";
|
||||
pucch_deltaF_Format1b = "deltaF3";
|
||||
pucch_deltaF_Format2 = "deltaF0";
|
||||
pucch_deltaF_Format2a = "deltaF0";
|
||||
pucch_deltaF_Format2b = "deltaF0";
|
||||
|
||||
rach_numberOfRA_Preambles = 64;
|
||||
rach_preamblesGroupAConfig = "DISABLE";
|
||||
/*
|
||||
rach_sizeOfRA_PreamblesGroupA = ;
|
||||
rach_messageSizeGroupA = ;
|
||||
rach_messagePowerOffsetGroupB = ;
|
||||
*/
|
||||
rach_powerRampingStep = 4;
|
||||
rach_preambleInitialReceivedTargetPower = -108;
|
||||
rach_preambleTransMax = 10;
|
||||
rach_raResponseWindowSize = 10;
|
||||
rach_macContentionResolutionTimer = 48;
|
||||
rach_maxHARQ_Msg3Tx = 4;
|
||||
|
||||
pcch_default_PagingCycle = 128;
|
||||
pcch_nB = "oneT";
|
||||
bcch_modificationPeriodCoeff = 2;
|
||||
ue_TimersAndConstants_t300 = 1000;
|
||||
ue_TimersAndConstants_t301 = 1000;
|
||||
ue_TimersAndConstants_t310 = 1000;
|
||||
ue_TimersAndConstants_t311 = 10000;
|
||||
ue_TimersAndConstants_n310 = 20;
|
||||
ue_TimersAndConstants_n311 = 1;
|
||||
|
||||
ue_TransmissionMode = 1;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
srb1_parameters :
|
||||
{
|
||||
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
|
||||
timer_poll_retransmit = 80;
|
||||
|
||||
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
|
||||
timer_reordering = 35;
|
||||
|
||||
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
|
||||
timer_status_prohibit = 0;
|
||||
|
||||
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
|
||||
poll_pdu = 4;
|
||||
|
||||
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
|
||||
poll_byte = 99999;
|
||||
|
||||
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
|
||||
max_retx_threshold = 4;
|
||||
}
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// MME parameters:
|
||||
mme_ip_address = ( { ipv4 = "127.0.0.3";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
|
||||
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24";
|
||||
ENB_INTERFACE_NAME_FOR_S1U = "lo";
|
||||
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.4/24";
|
||||
ENB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
|
||||
|
||||
rrh_gw_config = (
|
||||
//second config for Ercom
|
||||
{
|
||||
local_if_name = "eth1.300";
|
||||
remote_address = "00:21:5e:91:5c:7e"; # should be updated with ERCOM's MAC
|
||||
local_address = "f0:1f:af:db:b9:c8";
|
||||
local_port = 50000; #for raw option local port must be the same to remote
|
||||
remote_port = 50000;
|
||||
rrh_gw_active = "yes";
|
||||
tr_preference = "raw_if5_mobipass";
|
||||
rf_preference = "usrp_b200";
|
||||
iq_txshift = 0;
|
||||
tx_sample_advance = 80;
|
||||
tx_scheduling_advance = 9;
|
||||
if_compression = "None"
|
||||
}
|
||||
);
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
global_log_verbosity ="medium";
|
||||
hw_log_level ="info";
|
||||
hw_log_verbosity ="medium";
|
||||
phy_log_level ="info";
|
||||
phy_log_verbosity ="medium";
|
||||
mac_log_level ="info";
|
||||
mac_log_verbosity ="high";
|
||||
rlc_log_level ="info";
|
||||
rlc_log_verbosity ="medium";
|
||||
pdcp_log_level ="info";
|
||||
pdcp_log_verbosity ="medium";
|
||||
rrc_log_level ="info";
|
||||
rrc_log_verbosity ="medium";
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ eNBs =
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nRB_CQI = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 32;
|
||||
pdsch_referenceSignalPower = -29;
|
||||
@@ -243,9 +243,9 @@ eNBs =
|
||||
|
||||
rrh_gw_config = (
|
||||
{
|
||||
local_if_name = "eth2";
|
||||
local_if_name = "eth6";
|
||||
remote_address = "00:13:95:1f:a0:af"; #Conga's MAC
|
||||
local_address = "90:e2:ba:c5:fc:04";
|
||||
local_address = "a0:36:9f:df:96:6a";
|
||||
local_port = 50000; #for raw option local port must be the same to remote
|
||||
remote_port = 50000;
|
||||
rrh_gw_active = "yes";
|
||||
@@ -254,7 +254,7 @@ eNBs =
|
||||
iq_txshift = 4;
|
||||
tx_sample_advance = 80;
|
||||
tx_scheduling_advance = 9;
|
||||
if_compression = "alaw";
|
||||
if_compression = "alaw"; #alaw
|
||||
},
|
||||
//second config for Ercom
|
||||
{
|
||||
@@ -269,6 +269,7 @@ eNBs =
|
||||
iq_txshift = 0;
|
||||
tx_sample_advance = 80;
|
||||
tx_scheduling_advance = 9;
|
||||
if_compression = "None"
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -433,14 +433,6 @@ void tx_fh_if5_mobipass(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
|
||||
send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_MOBIPASS);
|
||||
}
|
||||
|
||||
void tx_fh_if5_mobipass_standalone(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx&0xffffffff );
|
||||
if ((eNB->frame_parms.frame_type==FDD) ||
|
||||
((eNB->frame_parms.frame_type==TDD) &&
|
||||
(subframe_select(&eNB->frame_parms,proc->subframe_tx) != SF_UL)))
|
||||
send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_MOBIPASS);
|
||||
}
|
||||
|
||||
void tx_fh_if4p5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
|
||||
if ((eNB->frame_parms.frame_type==FDD) ||
|
||||
((eNB->frame_parms.frame_type==TDD) &&
|
||||
@@ -499,10 +491,6 @@ void proc_tx_full(PHY_VARS_eNB *eNB,
|
||||
proc_tx_high0(eNB,proc,r_type,rn);
|
||||
// do OFDM modulation
|
||||
do_OFDM_mod_rt(proc->subframe_tx,eNB);
|
||||
|
||||
T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(proc->frame_tx), T_INT(proc->subframe_tx),
|
||||
T_INT(0), T_BUFFER(&eNB->common_vars.txdata[0][0][proc->subframe_tx * eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti * 4));
|
||||
|
||||
// if TX fronthaul go ahead
|
||||
if (eNB->tx_fh) eNB->tx_fh(eNB,proc);
|
||||
|
||||
@@ -693,6 +681,7 @@ void fh_if5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
|
||||
pthread_mutex_lock(&proc->mutex_asynch_rxtx);
|
||||
proc->subframe_rx = ((proc->timestamp_rx-offset_mobipass)/fp->samples_per_tti)%10;
|
||||
proc->frame_rx = ((proc->timestamp_rx-offset_mobipass)/(fp->samples_per_tti*10))&1023;
|
||||
T(T_SUBFRAME, T_INT(proc->frame_rx), T_INT(proc->subframe_rx), T_STRING(__FUNCTION__));
|
||||
|
||||
if (proc->first_rx == 1) {
|
||||
proc->first_rx =2;
|
||||
@@ -884,6 +873,9 @@ static void* eNB_thread_asynch_rxtx( void* param ) {
|
||||
eNB_proc_t *proc = (eNB_proc_t*)param;
|
||||
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
|
||||
|
||||
PHY_VARS_eNB fake_eNB;
|
||||
memcpy(&fake_eNB, eNB, sizeof(PHY_VARS_eNB));
|
||||
memcpy(&fake_eNB.proc, proc, sizeof(eNB_proc_t));
|
||||
|
||||
|
||||
int subframe=0, frame=0;
|
||||
@@ -914,7 +906,8 @@ static void* eNB_thread_asynch_rxtx( void* param ) {
|
||||
subframe++;
|
||||
}
|
||||
|
||||
if (eNB->fh_asynch) eNB->fh_asynch(eNB,&frame,&subframe);
|
||||
//if (eNB->fh_asynch) eNB->fh_asynch(eNB,&frame,&subframe);
|
||||
if (eNB->fh_asynch) eNB->fh_asynch(&fake_eNB,&frame,&subframe);
|
||||
else AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function);
|
||||
|
||||
}
|
||||
@@ -957,7 +950,7 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
|
||||
int siglen=fp->samples_per_tti,flags=1;
|
||||
|
||||
if (SF_type == SF_S) {
|
||||
siglen = (fp->dl_symbols_in_S_subframe+1)*(fp->ofdm_symbol_size+fp->nb_prefix_samples0);
|
||||
siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0);
|
||||
flags=3; // end of burst
|
||||
}
|
||||
if ((fp->frame_type == TDD) &&
|
||||
@@ -1040,6 +1033,7 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
|
||||
}
|
||||
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
|
||||
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
|
||||
T(T_SUBFRAME, T_INT(proc->frame_rx), T_INT(proc->subframe_rx), T_STRING(__FUNCTION__));
|
||||
proc->frame_rx = (proc->frame_rx+proc->frame_offset)&1023;
|
||||
proc->frame_tx = proc->frame_rx;
|
||||
if (proc->subframe_rx > 5) proc->frame_tx=(proc->frame_tx+1)&1023;
|
||||
@@ -1084,6 +1078,7 @@ void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) {
|
||||
|
||||
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
|
||||
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
|
||||
T(T_SUBFRAME, T_INT(proc->frame_rx), T_INT(proc->subframe_rx), T_STRING(__FUNCTION__));
|
||||
|
||||
if (proc->first_rx == 0) {
|
||||
if (proc->subframe_rx != *subframe){
|
||||
@@ -1109,24 +1104,24 @@ void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) {
|
||||
|
||||
}
|
||||
|
||||
void rx_fh_if5_mobipass_standalone(PHY_VARS_eNB *eNB,int *frame, int *subframe)
|
||||
{
|
||||
void rx_fh_if5_mobipass(PHY_VARS_eNB *eNB,int *frame, int *subframe) {
|
||||
|
||||
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
|
||||
eNB_proc_t *proc = &eNB->proc;
|
||||
|
||||
recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_MOBIPASS);
|
||||
recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_MOBIPASS);
|
||||
//printf("in rx_fh_if5_mobipass timestamp from recv_IF5 %ld\n", proc->timestamp_rx);
|
||||
|
||||
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
|
||||
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
|
||||
// T(T_SUBFRAME, T_INT(proc->frame_rx), T_INT(proc->subframe_rx), T_STRING(__FUNCTION__));
|
||||
|
||||
T(T_SUBFRAME, T_INT(proc->frame_rx), T_INT(proc->subframe_rx), T_STRING(__FUNCTION__));
|
||||
|
||||
if (proc->first_rx == 0) {
|
||||
if (proc->subframe_rx != *subframe){
|
||||
LOG_E(PHY,"rx_fh_if5: Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe);
|
||||
exit_fun("Exiting");
|
||||
}
|
||||
|
||||
|
||||
if (proc->frame_rx != *frame) {
|
||||
LOG_E(PHY,"rx_fh_if5: Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,*frame);
|
||||
exit_fun("Exiting");
|
||||
@@ -1134,14 +1129,18 @@ void rx_fh_if5_mobipass_standalone(PHY_VARS_eNB *eNB,int *frame, int *subframe)
|
||||
} else {
|
||||
proc->first_rx--;
|
||||
*frame = proc->frame_rx;
|
||||
*subframe = proc->subframe_rx;
|
||||
}
|
||||
*subframe = proc->subframe_rx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
|
||||
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
|
||||
|
||||
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
|
||||
@@ -1185,6 +1184,7 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
|
||||
|
||||
proc->subframe_rx = sf;
|
||||
proc->frame_rx = f;
|
||||
T(T_SUBFRAME, T_INT(proc->frame_rx), T_INT(proc->subframe_rx), T_STRING(__FUNCTION__));
|
||||
|
||||
proc->symbol_mask[*subframe] = 0;
|
||||
proc->symbol_mask[(9+*subframe)%10]= 0; // to handle a resynchronization event
|
||||
@@ -1274,6 +1274,7 @@ int wakeup_rxtx(eNB_proc_t *proc,eNB_rxtx_proc_t *proc_rxtx,LTE_DL_FRAME_PARMS *
|
||||
proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
|
||||
proc_rxtx->frame_rx = proc->frame_rx;
|
||||
proc_rxtx->subframe_rx = proc->subframe_rx;
|
||||
T(T_SUBFRAME, T_INT(proc->frame_rx), T_INT(proc->subframe_rx), T_STRING(__FUNCTION__));
|
||||
proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
|
||||
proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10;
|
||||
|
||||
@@ -1317,6 +1318,7 @@ void wakeup_slaves(eNB_proc_t *proc) {
|
||||
int cnt_slave = ++slave_proc->instance_cnt_FH;
|
||||
slave_proc->frame_rx = proc->frame_rx;
|
||||
slave_proc->subframe_rx = proc->subframe_rx;
|
||||
T(T_SUBFRAME, T_INT(proc->frame_rx), T_INT(proc->subframe_rx), T_STRING(__FUNCTION__));
|
||||
//slave_proc->timestamp_rx = proc->timestamp_rx;
|
||||
slave_proc->timestamp_tx = proc->timestamp_tx;
|
||||
|
||||
@@ -1512,7 +1514,7 @@ static void* eNB_thread_FH( void* param ) {
|
||||
if (eNB->rx_fh) eNB->rx_fh(eNB,&frame,&subframe);
|
||||
else AssertFatal(1==0, "No fronthaul interface : eNB->node_function %d",eNB->node_function);
|
||||
|
||||
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
|
||||
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(eNB->CC_id), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
|
||||
|
||||
// At this point, all information for subframe has been received on FH interface
|
||||
// If this proc is to provide synchronization, do so
|
||||
@@ -1713,10 +1715,11 @@ static void* eNB_thread_single( void* param ) {
|
||||
if (eNB->rx_fh) eNB->rx_fh(eNB,&frame,&subframe);
|
||||
else AssertFatal(1==0, "No fronthaul interface : eNB->node_function %d",eNB->node_function);
|
||||
|
||||
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
|
||||
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(eNB->CC_id), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
|
||||
|
||||
proc_rxtx->subframe_rx = proc->subframe_rx;
|
||||
proc_rxtx->frame_rx = proc->frame_rx;
|
||||
T(T_SUBFRAME, T_INT(proc->frame_rx), T_INT(proc->subframe_rx), T_STRING(__FUNCTION__));
|
||||
proc_rxtx->subframe_tx = (proc->subframe_rx+4)%10;
|
||||
proc_rxtx->frame_tx = (proc->subframe_rx>5) ? (1+proc->frame_rx)&1023 : proc->frame_rx;
|
||||
proc->frame_tx = proc_rxtx->frame_tx;
|
||||
@@ -1829,7 +1832,7 @@ void init_eNB_proc(int inst) {
|
||||
(eNB->node_function == NGFI_RRU_IF4p5))
|
||||
|
||||
|
||||
pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, eNB_thread_asynch_rxtx, &eNB->proc );
|
||||
;// pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, eNB_thread_asynch_rxtx, &eNB->proc );
|
||||
|
||||
char name[16];
|
||||
if (eNB->single_thread_flag == 0) {
|
||||
@@ -2172,15 +2175,10 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
|
||||
eNB->proc_tx = proc_tx_full;
|
||||
if (eNB->node_timing == synch_to_other) {
|
||||
eNB->tx_fh = tx_fh_if5_mobipass;
|
||||
eNB->rx_fh = rx_fh_slave;
|
||||
eNB->fh_asynch = fh_if5_asynch_UL;
|
||||
eNB->rx_fh = rx_fh_if5_mobipass; //rx_fh_slave;
|
||||
eNB->fh_asynch = NULL; //fh_if5_asynch_UL;
|
||||
|
||||
}
|
||||
else if (eNB->node_timing == synch_to_mobipass_standalone) {
|
||||
eNB->tx_fh = tx_fh_if5_mobipass_standalone;
|
||||
eNB->rx_fh = rx_fh_if5_mobipass_standalone;
|
||||
eNB->fh_asynch = NULL;
|
||||
}
|
||||
else {
|
||||
eNB->tx_fh = tx_fh_if5;
|
||||
eNB->rx_fh = rx_fh_if5;
|
||||
|
||||
@@ -608,6 +608,9 @@ static void get_options (int argc, char **argv) {
|
||||
// char line[1000];
|
||||
// int l;
|
||||
int k,i;//,j,k;
|
||||
#if defined(OAI_USRP) || defined(CPRIGW)
|
||||
int clock_src;
|
||||
#endif
|
||||
int CC_id;
|
||||
|
||||
|
||||
@@ -636,7 +639,6 @@ static void get_options (int argc, char **argv) {
|
||||
LONG_OPTION_USIMTEST,
|
||||
LONG_OPTION_MMAPPED_DMA,
|
||||
LONG_OPTION_EXTERNAL_CLOCK,
|
||||
LONG_OPTION_GPSDO_CLOCK,
|
||||
LONG_OPTION_WAIT_FOR_SYNC,
|
||||
LONG_OPTION_SINGLE_THREAD_DISABLE,
|
||||
LONG_OPTION_THREADIQ,
|
||||
@@ -679,7 +681,6 @@ static void get_options (int argc, char **argv) {
|
||||
{"usim-test", no_argument, NULL, LONG_OPTION_USIMTEST},
|
||||
{"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
|
||||
{"external-clock", no_argument, NULL, LONG_OPTION_EXTERNAL_CLOCK},
|
||||
{"gpsdo-clock", no_argument, NULL, LONG_OPTION_GPSDO_CLOCK},
|
||||
{"wait-for-sync", no_argument, NULL, LONG_OPTION_WAIT_FOR_SYNC},
|
||||
{"single-thread-disable", no_argument, NULL, LONG_OPTION_SINGLE_THREAD_DISABLE},
|
||||
{"threadIQ", required_argument, NULL, LONG_OPTION_THREADIQ},
|
||||
@@ -809,10 +810,6 @@ static void get_options (int argc, char **argv) {
|
||||
clock_source = external;
|
||||
break;
|
||||
|
||||
case LONG_OPTION_GPSDO_CLOCK:
|
||||
clock_source = gpsdo;
|
||||
break;
|
||||
|
||||
case LONG_OPTION_WAIT_FOR_SYNC:
|
||||
wait_for_sync = 1;
|
||||
break;
|
||||
@@ -1005,6 +1002,24 @@ static void get_options (int argc, char **argv) {
|
||||
|
||||
break;
|
||||
|
||||
case 's':
|
||||
#if defined(OAI_USRP) || defined(CPRIGW)
|
||||
|
||||
clock_src = atoi(optarg);
|
||||
|
||||
if (clock_src == 0) {
|
||||
// char ref[128] = "internal";
|
||||
//strncpy(uhd_ref, ref, strlen(ref)+1);
|
||||
} else if (clock_src == 1) {
|
||||
//char ref[128] = "external";
|
||||
//strncpy(uhd_ref, ref, strlen(ref)+1);
|
||||
}
|
||||
|
||||
#else
|
||||
printf("Note: -s not defined for ExpressMIMO2\n");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
exit_missed_slots=0;
|
||||
printf("Skip exit for missed slots\n");
|
||||
|
||||
Reference in New Issue
Block a user