diff --git a/.gitignore b/.gitignore
index 8f8ff1f454..ff947966a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,9 @@ targets/bin/
# vscode
.vscode
+
+# Tags for vim/global
+GPATH
+GRTAGS
+GTAGS
+tags
diff --git a/ci-scripts/args_parse.py b/ci-scripts/args_parse.py
index 1249f52172..84b3a84514 100644
--- a/ci-scripts/args_parse.py
+++ b/ci-scripts/args_parse.py
@@ -34,7 +34,7 @@
import sys # arg
import re # reg
import yaml
-
+import constants as CONST
#-----------------------------------------------------------
# Parsing Command Line Arguements
diff --git a/ci-scripts/cls_cots_ue.py b/ci-scripts/cls_cots_ue.py
index 6954aa3927..59c2713b47 100644
--- a/ci-scripts/cls_cots_ue.py
+++ b/ci-scripts/cls_cots_ue.py
@@ -27,61 +27,111 @@
# pexpect
#---------------------------------------------------------------------
+#to use isfile
+import os
+import sys
#to use logging.info()
import logging
#to create a SSH object locally in the methods
import sshconnection
#time.sleep
import time
+#to load cots_ue dictionary
+import yaml
class CotsUe:
- def __init__(self,model,UEIPAddr,UEUserName,UEPassWord):
- self.model = model
- self.UEIPAddr = UEIPAddr
- self.UEUserName = UEUserName
- self.UEPassWord = UEPassWord
- self.runargs = '' #on of off to toggle airplane mode on/off
+ def __init__(self,ADBIPAddr,ADBUserName,ADBPassWord):
+ self.cots_id = '' #cots id from yaml oppo, s10 etc...
+ self.ADBIPAddr = ADBIPAddr
+ self.ADBUserName = ADBUserName
+ self.ADBPassWord = ADBPassWord
+ self.cots_run_mode = '' #on of off to toggle airplane mode on/off
+ self.__cots_cde_dict_file = 'cots_ue_ctl.yaml'
self.__SetAirplaneRetry = 3
+
#-----------------$
#PUBLIC Methods$
#-----------------$
def Check_Airplane(self):
mySSH = sshconnection.SSHConnection()
- mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord)
- status=mySSH.cde_check_value('sudo adb shell settings get global airplane_mode_on ', ['0','1'],5)
+ mySSH.open(self.ADBIPAddr, self.ADBUserName, self.ADBPassWord)
+ status=mySSH.cde_check_value('adb shell settings get global airplane_mode_on ', ['0','1'],5)
mySSH.close()
return status
-
- def Set_Airplane(self,target_state_str):
- mySSH = sshconnection.SSHConnection()
- mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord)
- mySSH.command('sudo adb start-server','$',5)
- logging.info("Toggling COTS UE Airplane mode to : "+target_state_str)
- current_state = self.Check_Airplane()
- if target_state_str.lower()=="on":
- target_state=1
+ #simply check if the device id exists in the dictionary
+ #returns true if it exists, false otherwise
+ def Check_Exists(self,target_id):
+ #load cots commands dictionary
+ if (os.path.isfile(self.__cots_cde_dict_file)):
+ yaml_file=self.__cots_cde_dict_file
+ elif (os.path.isfile('ci-scripts/'+self.__cots_cde_dict_file)):
+ yaml_file='ci-scripts/'+self.__cots_cde_dict_file
else:
- target_state=0
- if current_state != target_state:
- #toggle state
- retry = 0
- while (current_state!=target_state) and (retry < self.__SetAirplaneRetry):
- mySSH.command('sudo adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS', '\$', 5)
- mySSH.command('sudo adb shell input keyevent 20', '\$', 5)
- mySSH.command('sudo adb shell input tap 968 324', '\$', 5)
- time.sleep(1)
- current_state = self.Check_Airplane()
- retry+=1
+ logging.error("COTS UE dictionary yaml file cannot be found")
+ sys.exit("COTS UE dictionary yaml file cannot be found")
+
+ #load cots commands dictionary
+ with open(yaml_file,'r') as file:
+ cots_ue_ctl = yaml.load(file,Loader=yaml.FullLoader)
+ #check if ue id is in the dictionary
+ if target_id in cots_ue_ctl:
+ return True
+ else:
+ return False
+
+ def Set_Airplane(self, target_id, target_state_str):
+ #loading cots commands dictionary
+
+ if (os.path.isfile(self.__cots_cde_dict_file)):
+ yaml_file=self.__cots_cde_dict_file
+ elif (os.path.isfile('ci-scripts/'+self.__cots_cde_dict_file)):
+ yaml_file='ci-scripts/'+self.__cots_cde_dict_file
+ else:
+ logging.error("COTS UE dictionary yaml file cannot be found")
+ sys.exit("COTS UE dictionary yaml file cannot be found")
+
+ #load cots commands dictionary
+ with open(yaml_file,'r') as file:
+ cots_ue_ctl = yaml.load(file,Loader=yaml.FullLoader)
+ #check if ue id is in the dictionary
+ if target_id in cots_ue_ctl:
+ mySSH = sshconnection.SSHConnection()
+ mySSH.open(self.ADBIPAddr, self.ADBUserName, self.ADBPassWord)
+ logging.info(str(self.ADBIPAddr)+' '+str(self.ADBUserName)+' '+str(self.ADBPassWord))
+ mySSH.command('adb start-server','\$',5)
+ mySSH.command('adb devices','\$',5)
+ logging.info("Toggling COTS UE Airplane mode to : "+target_state_str)
+ #get current state
+ current_state = self.Check_Airplane()
+ if target_state_str.lower()=="on":
+ target_state=1
+ else:
+ target_state=0
if current_state != target_state:
- logging.error("ATTENTION : Could not toggle to : "+target_state_str)
- logging.error("Current state is : "+ str(current_state))
+ #toggle state
+ retry = 0
+ while (current_state!=target_state) and (retry < self.__SetAirplaneRetry):
+ #loop over the command list from dictionary for the selected ue, to switch to required state
+ for i in range (0,len(cots_ue_ctl[target_id])):
+ mySSH.command(cots_ue_ctl[target_id][i], '\$', 5)
+ time.sleep(1)
+ current_state = self.Check_Airplane()
+ retry+=1
+ #could not toggle despite the retry
+ if current_state != target_state:
+ logging.error("ATTENTION : Could not toggle to : "+target_state_str)
+ logging.error("Current state is : "+ str(current_state))
+ else:
+ logging.info("Airplane mode is already "+ target_state_str)
+ mySSH.command('adb kill-server','\$',5)
+ mySSH.close()
+ #ue id is NOT in the dictionary
else:
- print("Airplane mode is already "+ target_state_str)
- mySSH.command('sudo adb kill-server','$',5)
- mySSH.close()
+ logging.error("COTS UE Id from XML could not be found in UE YAML dictionary " + self.__cots_cde_dict_file)
+ sys.exit("COTS UE Id from XML could not be found in UE YAML dictionary " + self.__cots_cde_dict_file)
diff --git a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf
index db1c5eae2a..d834b23e30 100644
--- a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf
@@ -105,6 +105,7 @@ eNBs =
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
+ mbms_dedicated_serving_cell = "DISABLE"
//Parameters for SIB18
rxPool_sc_CP_Len = "normal";
diff --git a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf
index de58950df4..a9ccb9f783 100644
--- a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf
@@ -105,6 +105,8 @@ eNBs =
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
+ mbms_dedicated_serving_cell = "DISABLE"
+
//Parameters for SIB18
rxPool_sc_CP_Len = "normal";
@@ -247,7 +249,6 @@ MCEs = (
);
-
NETWORK_INTERFACES :
{
MCE_INTERFACE_NAME_FOR_M2_ENB = "lo";
@@ -271,12 +272,12 @@ MCEs = (
mcch_update_time = 10;
mbms_area_config_list = (
{
- common_sf_allocation_period = 2; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6)
+ common_sf_allocation_period = 1; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6)
mbms_area_id = 0;
pmch_config_list = (
{
- allocated_sf_end=64;
- data_mcs=10;
+ allocated_sf_end=40;
+ data_mcs=20;
mch_scheduling_period = 0; #rf8(0)
mbms_session_list = (
{
@@ -288,7 +289,7 @@ MCEs = (
mnc_length = 2;
}
service_id=0;
- lcid=5; #this must be properly defined lcid:8+service:0 -> rab_id:5
+ lcid=5; #this must be properly defined lcid:8+service:0 -> rab_id:5 //with new RLC set lcid either 4 or 5
}
);
}
@@ -296,10 +297,10 @@ MCEs = (
mbms_sf_config_list = (
{
- radioframe_allocation_period=1; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5)
+ radioframe_allocation_period=0; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5)
radioframe_alloocation_offset=0;
num_frame="oneFrame";
- subframe_allocation=57; #xx100000
+ subframe_allocation=59; #xx111011 #57; #xx111001
//num_frame="fourFrame";
//subframe_allocation=14548987; #
}
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
index d92804ae44..36e93ba14e 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -71,6 +71,12 @@ gNBs =
initialDLBWPmappingType_2 = 0;
#this is SS=1,L=12
initialDLBWPstartSymbolAndLength_2 = 54;
+
+ initialDLBWPk0_3 = 0;
+ initialDLBWPmappingType_3 = 0;
+ #this is SS=1,L=4
+ initialDLBWPstartSymbolAndLength_3 = 57;
+
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
@@ -105,8 +111,8 @@ gNBs =
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
-#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
- ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
@@ -114,8 +120,8 @@ gNBs =
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
-#0 = 839, 1 = 139
- prach_RootSequenceIndex_PR = 1;
+#1 = 839, 2 = 139
+ prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
@@ -135,7 +141,11 @@ gNBs =
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
-
+ initialULBWPk2_2 = 7;
+ initialULBWPmappingType_2 = 1;
+ # this is SS=10 L=4
+ initialULBWPstartSymbolAndLength_2 = 52;
+
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
@@ -235,8 +245,10 @@ RUs = (
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
- max_rxgain = 114;
+ max_rxgain = 75;
eNB_instances = [0];
+ #beamforming 1x4 matrix:
+ bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
clock_src = "external";
}
diff --git a/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf
new file mode 100644
index 0000000000..e3adedbf4a
--- /dev/null
+++ b/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf
@@ -0,0 +1,426 @@
+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;
+ plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
+
+ tr_s_preference = "local_mac"
+
+ ////////// Physical parameters:
+
+ component_carriers = (
+ {
+ node_function = "3GPP_eNODEB";
+ node_timing = "synch_to_ext_device";
+ node_synch_ref = 0;
+ frame_type = "FDD";
+ tdd_config = 3;
+ tdd_config_s = 0;
+ prefix_type = "NORMAL";
+ eutra_band = 7;
+ downlink_frequency = 2680000000L;
+ uplink_frequency_offset = -120000000;
+ Nid_cell = 0;
+ N_RB_DL = 25;
+ Nid_cell_mbsfn = 0;
+ nb_antenna_ports = 1;
+ nb_antennas_tx = 1;
+ nb_antennas_rx = 1;
+ tx_gain = 90;
+ rx_gain = 125;
+ pbch_repetition = "FALSE";
+ prach_root = 0;
+ prach_config_index = 0;
+ prach_high_speed = "DISABLE";
+ prach_zero_correlation = 1;
+ prach_freq_offset = 2;
+ pucch_delta_shift = 1;
+ pucch_nRB_CQI = 0;
+ pucch_nCS_AN = 0;
+ pucch_n1_AN = 0;
+ pdsch_referenceSignalPower = -27;
+ 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 = -104;
+ 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;
+ mbms_dedicated_serving_cell = "ENABLE"
+
+ //Parameters for SIB18
+ rxPool_sc_CP_Len = "normal";
+ rxPool_sc_Period = "sf40";
+ rxPool_data_CP_Len = "normal";
+ rxPool_ResourceConfig_prb_Num = 20;
+ rxPool_ResourceConfig_prb_Start = 5;
+ rxPool_ResourceConfig_prb_End = 44;
+ rxPool_ResourceConfig_offsetIndicator_present = "prSmall";
+ rxPool_ResourceConfig_offsetIndicator_choice = 0;
+ rxPool_ResourceConfig_subframeBitmap_present = "prBs40";
+ rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000";
+ rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
+ rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
+/* rxPool_dataHoppingConfig_hoppingParameter = 0;
+ rxPool_dataHoppingConfig_numSubbands = "ns1";
+ rxPool_dataHoppingConfig_rbOffset = 0;
+ rxPool_commTxResourceUC-ReqAllowed = "TRUE";
+*/
+ // Parameters for SIB19
+ discRxPool_cp_Len = "normal"
+ discRxPool_discPeriod = "rf32"
+ discRxPool_numRetx = 1;
+ discRxPool_numRepetition = 2;
+ discRxPool_ResourceConfig_prb_Num = 5;
+ discRxPool_ResourceConfig_prb_Start = 3;
+ discRxPool_ResourceConfig_prb_End = 21;
+ discRxPool_ResourceConfig_offsetIndicator_present = "prSmall";
+ discRxPool_ResourceConfig_offsetIndicator_choice = 0;
+ discRxPool_ResourceConfig_subframeBitmap_present = "prBs40";
+ discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
+ discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
+ discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
+
+ }
+ );
+
+
+ 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 = "CI_MME_IP_ADDR";
+ ipv6 = "192:168:30::17";
+ active = "yes";
+ preference = "ipv4";
+ }
+ );
+
+ enable_measurement_reports = "no";
+
+ ///X2
+ enable_x2 = "no";
+ t_reloc_prep = 1000; /* unit: millisecond */
+ tx2_reloc_overall = 2000; /* unit: millisecond */
+
+ ////////// MCE parameters:
+ target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7";
+ ipv6 = "192:168:30::17";
+ active = "yes";
+ preference = "ipv4";
+ }
+ );
+
+ ///M2
+ enable_enb_m2 = "yes";
+
+
+ mbms_configuration_data_list = (
+ {
+ mbsfn_sync_area = 0x0001;
+ mbms_service_area_list=(
+ {
+ mbms_service_area=0x0001;
+ }
+ );
+ }
+
+ );
+
+
+
+ NETWORK_INTERFACES :
+ {
+
+ ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
+ ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
+ ENB_INTERFACE_NAME_FOR_S1U = "eth0";
+ ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR";
+ ENB_PORT_FOR_S1U = 2152; # Spec 2152
+ ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
+ ENB_PORT_FOR_X2C = 36422; # Spec 36422
+
+ ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24";
+ ENB_PORT_FOR_M2C = 36443; # Spec 36443
+ };
+ }
+);
+
+MACRLCs = (
+ {
+ num_cc = 1;
+ tr_s_preference = "local_L1";
+ tr_n_preference = "local_RRC";
+ phy_test_mode = 0;
+ puSch10xSnr = 200;
+ puCch10xSnr = 200;
+ }
+);
+
+L1s = (
+ {
+ num_cc = 1;
+ tr_n_preference = "local_mac";
+ }
+);
+
+MCEs = (
+ {
+ MCE_ID = 0xe00;
+
+ MCE_name = "MCE-Vicomtech-LTEBox";
+
+ //M2
+ enable_mce_m2 = "yes";
+
+ //M3
+ enable_mce_m3 = "yes";
+
+ target_mme_m3_ip_address = ( { ipv4 = "127.0.0.18";
+ ipv6 = "192:168:30::17";
+ active = "yes";
+ preference = "ipv4";
+ }
+ );
+
+
+
+ NETWORK_INTERFACES :
+ {
+ MCE_INTERFACE_NAME_FOR_M2_ENB = "lo";
+ MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24";
+ MCE_PORT_FOR_M2C = 36443; # Spec 36443
+
+ MCE_INTERFACE_NAME_FOR_M3_MME = "lo";
+ MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24";
+ MCE_PORT_FOR_M3C = 36444; # Spec 36444
+ };
+
+ plnm:
+ {
+ mcc = 208;
+ mnc = 93;
+ mnc_length = 2;
+ };
+
+ mbms_sched_info :
+ {
+ mcch_update_time = 10;
+ mbms_area_config_list = (
+ {
+ common_sf_allocation_period = 1; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6)
+ mbms_area_id = 0;
+ pmch_config_list = (
+ {
+ allocated_sf_end=512;
+ data_mcs=15;
+ mch_scheduling_period = 0; #rf8(0) rf16(1) rf32(2) rf64(3) rf128(4) rf256(5) rf512(6) rf1024(7)
+ mbms_session_list = (
+ {
+ #plnm + service_id ->tmgi
+ plnm:
+ {
+ mcc = 208;
+ mnc = 93;
+ mnc_length = 2;
+ }
+ service_id=0; #keep this allways as 0 (workaround for TUN if)
+ lcid=5; #this must be properly defined lcid:6+service:0 -> rab_id:5 //with new RLC set lcid either 4 or 5
+ }
+ );
+ }
+ );
+
+ mbms_sf_config_list = (
+ {
+ radioframe_allocation_period=0; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5)
+ radioframe_alloocation_offset=0;
+ num_frame="oneFrame";
+ subframe_allocation=57; #xx111001
+ //num_frame="fourFrame";
+ //subframe_allocation=14548987; #
+ }
+ );
+
+ }
+ );
+ };
+
+
+ mcch_config_per_mbsfn_area = (
+ {
+ mbsfn_area = 0;
+ pdcch_length = 1; #s1(0), s2(1)
+ repetition_period = 0; #rf32(0), rf64(1), rf128(2), rf256(3)
+ offset = 0;
+ modification_period = 0; #rf512(0; rf1024(1)
+ subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100000
+ mcs = 0; #n2(0), n7(1), n13(2), n19(3)
+ }
+ );
+
+ #); #end mbms_scheduling_info
+
+ }
+);
+
+MMEs = (
+ {
+ MME_ID = 0xe00;
+
+ MME_name = "MME-MBMS-Vicomtech-LTEBox";
+
+ //M3
+ enable_mme_m3 = "yes";
+ NETWORK_INTERFACES :
+ {
+ MME_INTERFACE_NAME_FOR_M3_MCE = "lo";
+ MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.18/24";
+ MME_PORT_FOR_M3C = 36444; # Spec 36444
+
+ };
+ }
+);
+
+
+RUs = (
+ {
+ local_rf = "yes"
+ nb_tx = 1
+ nb_rx = 1
+ att_tx = 0
+ att_rx = 0;
+ bands = [7];
+ max_pdschReferenceSignalPower = -27;
+ max_rxgain = 125;
+ eNB_instances = [0];
+
+ }
+);
+
+THREAD_STRUCT = (
+ {
+ #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+ parallel_config = "PARALLEL_SINGLE_THREAD";
+ #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+ worker_config = "WORKER_ENABLE";
+ }
+);
+
+NETWORK_CONTROLLER :
+{
+ FLEXRAN_ENABLED = "no";
+ FLEXRAN_INTERFACE_NAME = "ens3";
+ FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR";
+ FLEXRAN_PORT = 2210;
+ FLEXRAN_CACHE = "/mnt/oai_agent_cache";
+ FLEXRAN_AWAIT_RECONF = "no";
+};
+
+ 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";
+ };
+
+//rfsimulator :
+//{
+ //options = ("chanmod");
+ //modelname = "AWGN";
+//};
+
diff --git a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf
index 53261ec32d..3d5a859156 100644
--- a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf
+++ b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf
@@ -102,6 +102,7 @@ eNBs =
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
+ mbms_dedicated_serving_cell = "DISABLE"
//Parameters for SIB18
rxPool_sc_CP_Len = "normal";
@@ -295,8 +296,8 @@ MCEs = (
pmch_config_list = (
{
allocated_sf_end=32;
- data_mcs=14;
- mch_scheduling_period = 0; #rf8(0)
+ data_mcs=15;
+ mch_scheduling_period = 0; #rf8(0) rf16(1) rf32(2) rf64(3) rf128(4) rf256(5) rf512(6) rf1024(7)
mbms_session_list = (
{
#plnm + service_id ->tmgi
@@ -337,7 +338,7 @@ MCEs = (
offset = 0;
modification_period = 0; #rf512(0; rf1024(1)
subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100000
- mcs = 1; #n2(0), n7(1), n13(2), n19(3)
+ mcs = 0; #n2(0), n7(1), n13(2), n19(3)
}
);
@@ -416,3 +417,10 @@ NETWORK_CONTROLLER :
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
+
+//rfsimulator :
+//{
+ //options = ("chanmod");
+ //modelname = "AWGN";
+//};
+
diff --git a/ci-scripts/cots_ue_ctl.yaml b/ci-scripts/cots_ue_ctl.yaml
new file mode 100644
index 0000000000..c22fca246b
--- /dev/null
+++ b/ci-scripts/cots_ue_ctl.yaml
@@ -0,0 +1,20 @@
+9d690a12: #oppo
+ - adb shell input keyevent KEYCODE_POWER
+ - adb shell input swipe 300 700 300 0
+ - adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS
+ - adb shell input keyevent 20
+ - adb shell input tap 968 324
+002: #s10
+ - adb shell input keyevent KEYCODE_POWER
+ - adb shell input swipe 200 900 200 300
+ - adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS
+ - adb shell input tap 968 324
+003: #s20
+ - adb shell input keyevent KEYCODE_POWER
+ - adb shell input swipe 200 900 200 300
+ - adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS
+ - adb shell input tap 968 324
+004: #xperia
+ - tbd
+ - tbd
+ - tbd
diff --git a/ci-scripts/cppcheck_suppressions.list b/ci-scripts/cppcheck_suppressions.list
index 727fd22e74..4b9fb97427 100644
--- a/ci-scripts/cppcheck_suppressions.list
+++ b/ci-scripts/cppcheck_suppressions.list
@@ -83,6 +83,10 @@ nullPointer:common/utils/T/tracer/multi.c:265
// the tests
arrayIndexOutOfBounds:openair2/LAYER2/rlc_v2/tests/test.c:401
//
+//-----------------------------------------------------------------------------
+// cppcheck does not understand the different lengths of arrays
+arrayIndexOutOfBounds:openair1/SIMULATION/TOOLS/random_channel.c:705
+arrayIndexOutOfBounds:openair1/SIMULATION/TOOLS/random_channel.c:706
//*****************************************************************************
//
// True problems we don't know how to fix, Suppression is commented out,
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index d37f205f4e..86fd9d84df 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -285,21 +285,29 @@ class OaiCiTest():
SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
SSH.close()
return
- # enable data service
- SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60)
- # The following commands are deprecated since we no longer work on Android 7+
- # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10)
- # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60)
- # a dedicated script has to be installed inside the UE
- # airplane mode on means call /data/local/tmp/off
- if device_id == '84B7N16418004022':
- SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+ #RH quick add-on to integrate cots control defined by yaml
+ #if device_id exists in yaml dictionary, we execute the new procedure defined in cots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode ON (ie Radio OFF)
+ COTS_UE.Set_Airplane(device_id, 'ON')
else:
- SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
- #airplane mode off means call /data/local/tmp/on
- logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m')
- SSH.close()
+ # enable data service
+ SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60)
+
+ # The following commands are deprecated since we no longer work on Android 7+
+ # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10)
+ # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60)
+ # a dedicated script has to be installed inside the UE
+ # airplane mode on means call /data/local/tmp/off
+ if device_id == '84B7N16418004022':
+ SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+ else:
+ SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
+ #airplane mode off means call /data/local/tmp/on
+ logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m')
+ SSH.close()
except:
os.kill(os.getppid(),signal.SIGUSR1)
@@ -790,7 +798,13 @@ class OaiCiTest():
try:
SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
if self.ADBCentralized:
- if device_id == '84B7N16418004022':
+ #RH quick add on to integrate cots control defined by yaml
+ #if device Id exists in yaml dictionary, we execute the new procedure defined in cots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode OFF (ie Radio ON)
+ COTS_UE.Set_Airplane(device_id, 'OFF')
+ elif device_id == '84B7N16418004022':
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60)
else:
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
@@ -827,7 +841,13 @@ class OaiCiTest():
if count == 15 or count == 30:
logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m')
if self.ADBCentralized:
- if device_id == '84B7N16418004022':
+ #RH quick add on to intgrate cots control defined by yaml
+ #if device id exists in yaml dictionary, we execute the new procedure defined in cots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode ON (ie Radio OFF)
+ COTS_UE.Set_Airplane(device_id, 'ON')
+ elif device_id == '84B7N16418004022':
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
else:
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
@@ -835,7 +855,13 @@ class OaiCiTest():
SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
time.sleep(0.5)
if self.ADBCentralized:
- if device_id == '84B7N16418004022':
+ #RH quick add on to integrate cots control defined by yaml
+ #if device id exists in yaml dictionary, we execute the new procedre defined incots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode OFF (ie Radio ON)
+ COTS_UE.Set_Airplane(device_id, 'OFF')
+ elif device_id == '84B7N16418004022':
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60)
else:
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
@@ -918,7 +944,13 @@ class OaiCiTest():
try:
SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
if self.ADBCentralized:
- if device_id == '84B7N16418004022':
+ #RH quick add on to integrate cots control defined by yaml
+ #if device id exists in yaml dictionary, we execute the new procedure defined in cots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode ON (ie Radio OFF)
+ COTS_UE.Set_Airplane(device_id,'ON')
+ elif device_id == '84B7N16418004022':
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
else:
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
@@ -2697,7 +2729,13 @@ class OaiCiTest():
SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
# back in airplane mode on (ie radio off)
if self.ADBCentralized:
- if device_id == '84B7N16418004022':
+ #RH quick add on to intgrate cots control defined by yaml
+ #if device Id exists in yaml dictionary, we execute the new procedure defined in cots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode ON (ie Radio OFF)
+ COTS_UE.Set_Airplane(device_id, 'ON')
+ elif device_id == '84B7N16418004022':
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
else:
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
@@ -3133,7 +3171,7 @@ def GetParametersFromXML(action):
else:
RAN.backgroundBuild=False
- if action == 'WaitEndBuild_eNB':
+ elif action == 'WaitEndBuild_eNB':
RAN.Build_eNB_args=test.findtext('Build_eNB_args')
eNB_instance=test.findtext('eNB_instance')
if (eNB_instance is None):
@@ -3144,7 +3182,7 @@ def GetParametersFromXML(action):
if (RAN.eNB_serverId is None):
RAN.eNB_serverId='0'
- if action == 'Initialize_eNB':
+ elif action == 'Initialize_eNB':
RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args')
eNB_instance=test.findtext('eNB_instance')
if (eNB_instance is None):
@@ -3164,7 +3202,7 @@ def GetParametersFromXML(action):
else :
RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
- if action == 'Terminate_eNB':
+ elif action == 'Terminate_eNB':
eNB_instance=test.findtext('eNB_instance')
if (eNB_instance is None):
RAN.eNB_instance=0
@@ -3183,21 +3221,21 @@ def GetParametersFromXML(action):
else :
RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
- if action == 'Attach_UE':
+ elif action == 'Attach_UE':
nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
if (nbMaxUEtoAttach is None):
CiTestObj.nbMaxUEtoAttach = -1
else:
CiTestObj.nbMaxUEtoAttach = int(nbMaxUEtoAttach)
- if action == 'CheckStatusUE':
+ elif action == 'CheckStatusUE':
expectedNBUE = test.findtext('expectedNbOfConnectedUEs')
if (expectedNBUE is None):
CiTestObj.expectedNbOfConnectedUEs = -1
else:
CiTestObj.expectedNbOfConnectedUEs = int(expectedNBUE)
- if action == 'Build_OAI_UE':
+ elif action == 'Build_OAI_UE':
CiTestObj.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args')
CiTestObj.clean_repository = test.findtext('clean_repository')
if (CiTestObj.clean_repository == 'false'):
@@ -3205,7 +3243,7 @@ def GetParametersFromXML(action):
else:
CiTestObj.clean_repository = True
- if action == 'Initialize_OAI_UE':
+ elif action == 'Initialize_OAI_UE':
CiTestObj.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args')
UE_instance = test.findtext('UE_instance')
if (UE_instance is None):
@@ -3223,7 +3261,7 @@ def GetParametersFromXML(action):
#CiTestObj.air_interface = 'ocp-enb'
logging.error('OCP UE -- NOT SUPPORTED')
- if action == 'Terminate_OAI_UE':
+ elif action == 'Terminate_OAI_UE':
UE_instance=test.findtext('UE_instance')
if (UE_instance is None):
CiTestObj.UE_instance = '0'
@@ -3240,11 +3278,11 @@ def GetParametersFromXML(action):
#CiTestObj.air_interface = 'ocp-enb'
logging.error('OCP UE -- NOT SUPPORTED')
- if action == 'Ping' or action == 'Ping_CatM_module':
+ elif (action == 'Ping') or (action == 'Ping_CatM_module'):
CiTestObj.ping_args = test.findtext('ping_args')
CiTestObj.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
- if action == 'Iperf':
+ elif action == 'Iperf':
CiTestObj.iperf_args = test.findtext('iperf_args')
CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold')
CiTestObj.iperf_profile = test.findtext('iperf_profile')
@@ -3262,14 +3300,14 @@ def GetParametersFromXML(action):
logging.debug('ERROR: test-case has wrong option ' + CiTestObj.iperf_options)
CiTestObj.iperf_options = 'check'
- if action == 'IdleSleep':
+ elif action == 'IdleSleep':
string_field = test.findtext('idle_sleep_time_in_sec')
if (string_field is None):
CiTestObj.idle_sleep_time = 5
else:
CiTestObj.idle_sleep_time = int(string_field)
- if action == 'Perform_X2_Handover':
+ elif action == 'Perform_X2_Handover':
string_field = test.findtext('x2_ho_options')
if (string_field is None):
CiTestObj.x2_ho_options = 'network'
@@ -3280,7 +3318,7 @@ def GetParametersFromXML(action):
else:
CiTestObj.x2_ho_options = string_field
- if action == 'Build_PhySim':
+ elif action == 'Build_PhySim':
ldpc.buildargs = test.findtext('physim_build_args')
forced_workspace_cleanup = test.findtext('forced_workspace_cleanup')
if (forced_workspace_cleanup is None):
@@ -3291,11 +3329,9 @@ def GetParametersFromXML(action):
else:
ldpc.forced_workspace_cleanup=False
- if action == 'Run_PhySim':
+ else: # ie action == 'Run_PhySim':
ldpc.runargs = test.findtext('physim_run_args')
- if action == 'COTS_UE_Airplane':
- COTS_UE.runargs = test.findtext('cots_ue_airplane_args')
#check if given test is in list
#it is in list if one of the strings in 'list' is at the beginning of 'test'
@@ -3320,15 +3356,21 @@ def receive_signal(signum, frame):
#loading xml action list from yaml
import yaml
-xml_class_list_file=''
-if (os.path.isfile('xml_class_list.yml')):
- xml_class_list_file='xml_class_list.yml'
-if (os.path.isfile('ci-scripts/xml_class_list.yml')):
- xml_class_list_file='ci-scripts/xml_class_list.yml'
-with open(xml_class_list_file,'r') as file:
- # The FullLoader parameter handles the conversion from YAML
- # scalar values to Python the dictionary format
- xml_class_list = yaml.load(file,Loader=yaml.FullLoader)
+xml_class_list_file='xml_class_list.yml'
+if (os.path.isfile(xml_class_list_file)):
+ yaml_file=xml_class_list_file
+elif (os.path.isfile('ci-scripts/'+xml_class_list_file)):
+ yaml_file='ci-scripts/'+xml_class_list_file
+else:
+ logging.error("XML action list yaml file cannot be found")
+ sys.exit("XML action list yaml file cannot be found")
+
+with open(yaml_file,'r') as f:
+ # The FullLoader parameter handles the conversion-$
+ #from YAML scalar values to Python dictionary format$
+ xml_class_list = yaml.load(f,Loader=yaml.FullLoader)
+
+
mode = ''
@@ -3375,8 +3417,9 @@ if py_param_file_present == True:
#-----------------------------------------------------------
# COTS UE instanciation
#-----------------------------------------------------------
-#COTS_UE instanciation can only be done here for the moment, due to code architecture
-COTS_UE=cls_cots_ue.CotsUe('oppo', CiTestObj.UEIPAddress, CiTestObj.UEUserName,CiTestObj.UEPassword)
+#COTS_UE instanciation and ADB server init
+#ue id and ue mode are retrieved from xml
+COTS_UE=cls_cots_ue.CotsUe(CiTestObj.ADBIPAddress, CiTestObj.ADBUserName,CiTestObj.ADBPassword)
#-----------------------------------------------------------
@@ -3613,7 +3656,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
GetParametersFromXML(action)
if action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Ping' or action == 'Iperf' or action == 'Reboot_UE' or action == 'DataDisable_UE' or action == 'DataEnable_UE' or action == 'CheckStatusUE':
if (CiTestObj.ADBIPAddress != 'none'):
- terminate_ue_flag = False
+ #in these cases, having no devices is critical, GetAllUEDevices function has to manage it as a critical error, reason why terminate_ue_flag is set to True
+ terminate_ue_flag = True
CiTestObj.GetAllUEDevices(terminate_ue_flag)
if action == 'Build_eNB':
RAN.BuildeNB()
@@ -3688,8 +3732,6 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
if ldpc.exitStatus==1:sys.exit()
elif action == 'Run_PhySim':
HTML=ldpc.Run_PhySim(HTML,CONST,id)
- elif action == 'COTS_UE_Airplane':
- COTS_UE.Set_Airplane(COTS_UE.runargs)
else:
sys.exit('Invalid class (action) from xml')
CiTestObj.FailReportCnt += 1
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 96f28e21fe..d5906e9567 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -90,6 +90,7 @@ class RANManagement():
self.epcPcapFile = ''
self.htmlObj = None
self.epcObj = None
+ self.runtime_stats= ''
@@ -614,7 +615,7 @@ class RANManagement():
logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m')
logStatus = self.AnalyzeLogFile_eNB(extracted_log_file)
if self.htmlObj is not None:
- self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+ self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
self.eNBLogFiles[int(self.eNB_instance)] = ''
else:
analyzeFile = False
@@ -643,10 +644,10 @@ class RANManagement():
return
else:
if self.htmlObj is not None:
- self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+ self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
else:
if self.htmlObj is not None:
- self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+ self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
self.eNBmbmsEnables[int(self.eNB_instance)] = False
self.eNBstatuses[int(self.eNB_instance)] = -1
@@ -712,16 +713,20 @@ class RANManagement():
if runTime != '':
result = re.search('Time executing user inst', str(line))
if result is not None:
- userTime = 'to be decoded - 1'
+ fields=line.split(':')
+ userTime = 'userTime : ' + fields[1].replace('\n','')
result = re.search('Time executing system inst', str(line))
if result is not None:
- systemTime = 'to be decoded - 2'
+ fields=line.split(':')
+ systemTime = 'systemTime : ' + fields[1].replace('\n','')
result = re.search('Max. Phy. memory usage:', str(line))
if result is not None:
- maxPhyMemUsage = 'to be decoded - 3'
+ fields=line.split(':')
+ maxPhyMemUsage = 'maxPhyMemUsage : ' + fields[1].replace('\n','')
result = re.search('Number of context switch.*process origin', str(line))
if result is not None:
- nbContextSwitches = 'to be decoded - 4'
+ fields=line.split(':')
+ nbContextSwitches = 'nbContextSwitches : ' + fields[1].replace('\n','')
if X2HO_state == CONST.X2_HO_REQ_STATE__IDLE:
result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line))
if result is not None:
@@ -978,11 +983,12 @@ class RANManagement():
global_status = CONST.ENB_PROCESS_REALTIME_ISSUE
if self.htmlObj is not None:
self.htmlObj.htmleNBFailureMsg=htmleNBFailureMsg
- # Runtime statistics
+ # Runtime statistics for console output and HTML
if runTime != '':
logging.debug(runTime)
- logging.debug('Time executing user inst : ' + userTime)
- logging.debug('Time executing system inst : ' + systemTime)
- logging.debug('Max Physical Memory Usage : ' + maxPhyMemUsage)
- logging.debug('Nb Context Switches : ' + nbContextSwitches)
+ logging.debug(userTime)
+ logging.debug(systemTime)
+ logging.debug(maxPhyMemUsage)
+ logging.debug(nbContextSwitches)
+ self.runtime_stats='
'+runTime + '\n'+ userTime + '\n' + systemTime + '\n' + maxPhyMemUsage + '\n' + nbContextSwitches+'
'
return global_status
diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh
index 897f9285e9..b05ccf39db 100755
--- a/ci-scripts/reportTestLocally.sh
+++ b/ci-scripts/reportTestLocally.sh
@@ -620,6 +620,101 @@ function report_test {
#IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_ul*client*txt | grep -v mbms 2> /dev/null`
#analyzeIperfFiles
done
+
+ # FeMBMS Case
+ CN_CONFIG="noS1"
+ TMODE="fdd"
+ BW_CASES=(05)
+ for BW in ${BW_CASES[@]}
+ do
+ echo " " >> ./test_simulator_results.html
+ echo " | Test FeMBMS without EPC (aka noS1): ${TMODE} -- ${BW}MHz | " >> ./test_simulator_results.html
+ echo "
" >> ./test_simulator_results.html
+ ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_enb_fembms.log
+ UE_LOG=`echo $ENB_LOG | sed -e "s#enb#ue#"`
+ if [ -f $ENB_LOG ] && [ -f $UE_LOG ]
+ then
+ NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"`
+ NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"`
+ echo " " >> ./test_simulator_results.html
+ echo " | $NAME_ENB --- $NAME_UE | " >> ./test_simulator_results.html
+ echo " N/A | " >> ./test_simulator_results.html
+ #NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG`
+ NB_ENB_TUNNEL_UP=`egrep -c "Interface oaitun_enb1 successfully configured" $ENB_LOG`
+ NB_ENB_MTUNNEL_UP=`egrep -c "Interface oaitun_enm1 successfully configured" $ENB_LOG`
+ #NB_UE_GOT_SYNC=`egrep -c "rfsimulator: Success" $UE_LOG`
+ #NB_ENB_SYNCED_WITH_UE=`egrep -c "Generating RRCConnectionReconfigurationComplete" $UE_LOG`
+ NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfully configured" $UE_LOG`
+ NB_UE_MTUNNEL_UP=`egrep -c "Interface oaitun_uem1 successfully configured" $UE_LOG`
+ NB_UE_MBMS_PUSH_MSG=`egrep -c "TRIED TO PUSH MBMS DATA TO" $UE_LOG`
+ #if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 0 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] && [ $NB_UE_MBMS_PUSH_MSG -gt 0 ]
+ if [ $NB_UE_MBMS_PUSH_MSG -gt 0 ]
+ then
+ echo " OK | " >> ./test_simulator_results.html
+ else
+ echo " KO | " >> ./test_simulator_results.html
+ fi
+ echo " " >> ./test_simulator_results.html
+ #if [ $NB_ENB_GOT_SYNC -gt 0 ]
+ #then
+ # echo "- eNB --> got sync" >> ./test_simulator_results.html
+ #else
+ # echo "- eNB NEVER got sync" >> ./test_simulator_results.html
+ #fi
+ if [ $NB_ENB_TUNNEL_UP -gt 0 ]
+ then
+ echo "- eNB mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+ else
+ echo "- eNB NEVER mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+ fi
+ if [ $NB_ENB_MTUNNEL_UP -gt 0 ]
+ then
+ echo "- eNB mounted oaitun_enm1 interface" >> ./test_simulator_results.html
+ else
+ echo "- eNB NEVER mounted oaitun_enm1 interface" >> ./test_simulator_results.html
+ fi
+ #if [ $NB_UE_GOT_SYNC -gt 0 ]
+ #then
+ # echo "- LTE UE --> got sync" >> ./test_simulator_results.html
+ #else
+ # echo "- LTE UE NEVER got sync" >> ./test_simulator_results.html
+ #fi
+ #if [ $NB_ENB_SYNCED_WITH_UE -gt 0 ]
+ #then
+ # echo "- LTE UE attached to eNB" >> ./test_simulator_results.html
+ #else
+ # echo "- LTE UE NEVER attached to eNB" >> ./test_simulator_results.html
+ #fi
+ if [ $NB_UE_TUNNEL_UP -gt 0 ]
+ then
+ echo "- LTE UE mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+ else
+ echo "- LTE UE NEVER mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+ fi
+ if [ $NB_UE_MTUNNEL_UP -gt 0 ]
+ then
+ echo "- LTE UE mounted oaitun_uem1 interface" >> ./test_simulator_results.html
+ else
+ echo "- LTE UE NEVER mounted oaitun_uem1 interface" >> ./test_simulator_results.html
+ fi
+ if [ $NB_UE_MBMS_PUSH_MSG -gt 0 ]
+ then
+ echo "- LTE UE tried to push ${NB_UE_MBMS_PUSH_MSG} MBMS DATA" >> ./test_simulator_results.html
+ else
+ echo "- LTE UE NEVER pushed MBMS DATA" >> ./test_simulator_results.html
+ fi
+ echo " | " >> ./test_simulator_results.html
+ echo "
" >> ./test_simulator_results.html
+ fi
+ #PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_ping*.log 2> /dev/null`
+ #analyzePingFiles
+
+ #IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_dl*client*txt | grep -v mbms 2> /dev/null`
+ #analyzeIperfFiles
+
+ #IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_ul*client*txt | grep -v mbms 2> /dev/null`
+ #analyzeIperfFiles
+ done
echo " " >> ./test_simulator_results.html
echo " " >> ./test_simulator_results.html
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 0db2264c76..b9b9a2bafa 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -2050,6 +2050,95 @@ function run_test_on_vm {
echo "LTE RFSIM seems to FAIL"
echo "LTE: TEST_KO" > $ARCHIVES_LOC/test_final_status.log
fi
+
+ ####################
+ ## FeMBMS CASE noS1 ##
+ ####################
+ CONF_FILE=lte-fdd-fembms-basic-sim.conf
+ CN_CONFIG="noS1"
+ S1_NOS1_CFG=0
+ LTEBOX=0
+ TMODE="fdd"
+ FREQUENCY=2680
+ BW_CASES=(05)
+ FeMBMS_STATUS=0
+
+ for BW in ${BW_CASES[@]}
+ do
+ if [[ $BW =~ .*05.* ]]; then PRB=25; fi
+ if [[ $BW =~ .*10.* ]]; then PRB=50; fi
+ if [[ $BW =~ .*20.* ]]; then PRB=100; fi
+
+ echo "############################################################"
+ echo "${CN_CONFIG} : Starting the eNB with MSMS in ${TMODE}-${BW}MHz mode"
+ echo "############################################################"
+ CURRENT_ENB_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_enb_fembms.log
+ start_rf_sim_enb $ENB_VM_CMDS "$ENB_VM_IP_ADDR" "$EPC_VM_IP_ADDR" $CURRENT_ENB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG
+
+ echo "############################################################"
+ echo "${CN_CONFIG} : Starting the UE"
+ echo "############################################################"
+ CURRENT_UE_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_ue_fembms.log
+ start_rf_sim_ue $UE_VM_CMDS $UE_VM_IP_ADDR $ENB_VM_IP_ADDR $CURRENT_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 1
+ if [ $UE_SYNC -eq 0 ]
+ then
+ echo "Problem w/ eNB and UE not syncing"
+ terminate_enb_ue_basic_sim $ENB_VM_CMDS $ENB_VM_IP_ADDR 1
+ terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2
+ scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
+ scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
+ STATUS=-1
+ break
+ fi
+
+ echo "############################################################"
+ echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client"
+ echo "############################################################"
+ get_enb_mbms_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR
+ IPERF_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_dl_fembms
+ get_ue_mbms_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1
+ THROUGHPUT=2
+ generic_iperf $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $ENB_VM_CMDS $ENB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE 1 0
+ scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC
+ scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC
+ #check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT
+
+ echo "############################################################"
+ echo "${CN_CONFIG} : Terminate enb/ue simulators"
+ echo "############################################################"
+ terminate_enb_ue_basic_sim $ENB_VM_CMDS $ENB_VM_IP_ADDR 1
+ terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2
+ scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
+ scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
+ NB_UE_FeMBMS_MESSAGES=`egrep -c "TRIED TO PUSH MBMS DATA TO" $ARCHIVES_LOC/$CURRENT_UE_LOG_FILE`
+ if [ $NB_UE_FeMBMS_MESSAGES -eq 0 ]; then FeMBMS_STATUS=-1; fi
+
+ done
+
+ full_l2_sim_destroy
+
+ echo "############################################################"
+ echo "Checking run status"
+ echo "############################################################"
+
+ if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi
+ if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi
+ if [ $FeMBMS_STATUS -eq 0 ]
+ then
+ echo "LTE FeMBMS RFSIM seems OK"
+ else
+ echo "LTE FeMBMS RFSIM seems to FAIL"
+ STATUS=-1
+ fi
+ if [ $STATUS -eq 0 ]
+ then
+ echo "LTE RFSIM seems OK"
+ echo "LTE: TEST_OK" > $ARCHIVES_LOC/test_final_status.log
+ else
+ echo "LTE RFSIM seems to FAIL"
+ echo "LTE: TEST_KO" > $ARCHIVES_LOC/test_final_status.log
+ fi
+
fi
if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]]
diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml
index e80063a120..2c20988851 100755
--- a/ci-scripts/xml_class_list.yml
+++ b/ci-scripts/xml_class_list.yml
@@ -1,4 +1,3 @@
- - COTS_UE_Airplane
- Build_PhySim
- Run_PhySim
- Build_eNB
diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml
new file mode 100644
index 0000000000..775ef2e023
--- /dev/null
+++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml
@@ -0,0 +1,82 @@
+
+
+ test-05-tm1-fembms-nos1-tunnel
+ Test-05MHz-FEMBMS-TM1-noS1-tunnel
+ tasks
+ 2
+
+ 030201 090109
+ 030104 000001 090104 000002 040605 000001 090109 030201
+
+
+
+
+ IdleSleep
+ Sleep
+ 10
+
+
+
+ IdleSleep
+ Sleep
+ 15
+
+
+
+ IdleSleep
+ Sleep
+ 60
+
+
+
+ Initialize_eNB
+ Initialize eNB (FDD/Band7/5MHz/MBMS)
+ -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 --eNBs.[0].component_carriers.[0].mbms_dedicated_serving_cell ENABLE --MCEs.[0].mbms_sched_info.mbms_area_config_list.[0].pmch_config_list.[0].allocated_sf_end 512
+
+
+
+ Terminate_eNB
+ Terminate eNB
+
+
+
+ Initialize_OAI_UE
+ Initialize OAI UE (FDD/Band7/5MHz/MBMS)
+ -C 2680000000 -r 25 --ue-rxgain 120 --ue-txgain 0 --ue-max-power 0 --ue-scan-carrier --nokrnmod 1 --noS1
+
+
+
+ Terminate_OAI_UE
+ Terminate OAI UE
+
+
+
+ Iperf
+ iperf (5MHz - DL/1.5Mbps/UDP/MBMS-sink)(20 sec)
+ -c 10.0.2.2 -u -b 1.5M -t 20 -i 1 -fm -B 10.0.2.1
+ 50
+ sink
+
+
+
diff --git a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml b/ci-scripts/xml_files/fr1_epc_closure.xml
similarity index 72%
rename from ci-scripts/xml_files/fr1_toggle_cots_ue.xml
rename to ci-scripts/xml_files/fr1_epc_closure.xml
index b2267efc77..2fd8031936 100644
--- a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml
+++ b/ci-scripts/xml_files/fr1_epc_closure.xml
@@ -21,19 +21,27 @@
-->
- test-airplane-mode
- AirplaneToggle
- tasks
+ epc-closure
+ EPC-Closure
+ log-out
- 010000
+060000 060001 060002
-
- COTS_UE_Airplane
- Toggle COTS Airplane mode ON
- ON
+
+ Terminate_HSS
+ Terminate HSS
+
+ Terminate_MME
+ Terminate MME
+
+
+
+ Terminate_SPGW
+ Terminate SPGW
+
diff --git a/ci-scripts/xml_files/fr1_multi_node_terminate.xml b/ci-scripts/xml_files/fr1_epc_start.xml
similarity index 70%
rename from ci-scripts/xml_files/fr1_multi_node_terminate.xml
rename to ci-scripts/xml_files/fr1_epc_start.xml
index cbaaf8ba99..5cef2b5a6a 100644
--- a/ci-scripts/xml_files/fr1_multi_node_terminate.xml
+++ b/ci-scripts/xml_files/fr1_epc_start.xml
@@ -21,30 +21,28 @@
-->
- test-fr1-tm1
- Test-FR1-TM1
- tasks
- 1
+ epc-start-tab
+ EPC-Start
+ log-in
- 070001
- 070000
+ 000100 000101 000102
-
- Terminate_eNB
- Terminate eNB
- 0
- 0
+
+ Initialize_HSS
+ Initialize HSS
-
- Terminate_eNB
- Terminate gNB
- 1
- 1
+
+ Initialize_MME
+ Initialize MME
+
+
+
+ Initialize_SPGW
+ Initialize SPGW
-
diff --git a/ci-scripts/xml_files/fr1_ran_ue_proc.xml b/ci-scripts/xml_files/fr1_ran_ue_proc.xml
new file mode 100644
index 0000000000..e86a36d2db
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_ran_ue_proc.xml
@@ -0,0 +1,117 @@
+
+
+ TEST-FR1-TM1
+ FR1
+ tasks
+
+ 010000
+ 030000
+ 040000
+ 010001
+ 000001
+ 050000
+ 050001
+ 070001
+ 070000
+ 010002
+ 010003
+
+
+
+
+ Initialize_UE
+ Initialize UE
+
+
+
+ Terminate_UE
+ Terminate UE
+
+
+
+ Attach_UE
+ Attach UE
+
+
+
+ Detach_UE
+ Detach UE
+
+
+
+
+ Initialize_eNB
+ Initialize eNB
+ -O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf
+ 0
+ 0
+ lte
+
+
+
+
+ Initialize_eNB
+ Initialize gNB
+ -O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E
+ 1
+ 1
+ nr
+
+
+
+ IdleSleep
+ Sleep
+ 20
+
+
+
+ Ping
+ Ping: 20pings in 20sec
+ -c 20
+ 0
+
+
+
+ Ping
+ Ping: 5pings in 1sec
+ -c 5 -i 0.2
+ 0
+
+
+
+ Terminate_eNB
+ Terminate eNB
+ 0
+ 0
+
+
+
+ Terminate_eNB
+ Terminate gNB
+ 1
+ 1
+
+
+
+
diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
index c51093c178..a344cb6a7f 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
@@ -52,7 +52,7 @@
Initialize_OAI_UE
Initialize NR UE USRP
- --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path .
+ --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --threadoffset 16 --rrc_config_path .
NR
diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml
index b4290ae6a3..9e5e0a2bac 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml
@@ -52,7 +52,7 @@
Initialize_OAI_UE
Initialize NR UE USRP
- --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path .
+ --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --threadoffset 16 --rrc_config_path .
NR
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 050d50f9f5..0977f6c0d9 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -763,6 +763,42 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE
add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} )
set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
+# Benetel 4G library
+######################################################################
+
+set(HWLIB_BENETEL_4G_SOURCE
+ ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/benetel.c
+ ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/shared_buffers.c
+ ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/low.c
+ ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/low_dpdk.c
+ ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/dpdk_driver.c
+ )
+add_library(benetel_4g MODULE ${HWLIB_BENETEL_4G_SOURCE} )
+
+set_target_properties(benetel_4g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native -I$ENV{RTE_SDK}/$ENV{RTE_TARGET}/include")
+
+SET(DPDK_LIBS "-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive -L$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -ldpdk -Wl,--no-whole-archive")
+TARGET_LINK_LIBRARIES(benetel_4g ${DPDK_LIBS})
+TARGET_LINK_LIBRARIES(benetel_4g pthread dl rt m numa)
+
+# Benetel 5G library
+######################################################################
+
+set(HWLIB_BENETEL_5G_SOURCE
+ ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/benetel.c
+ ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/shared_buffers.c
+ ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/low.c
+ ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/low_dpdk.c
+ ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/dpdk_driver.c
+ )
+add_library(benetel_5g MODULE ${HWLIB_BENETEL_5G_SOURCE} )
+
+set_target_properties(benetel_5g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native -I$ENV{RTE_SDK}/$ENV{RTE_TARGET}/include")
+
+SET(DPDK_LIBS "-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive -L$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -ldpdk -Wl,--no-whole-archive")
+TARGET_LINK_LIBRARIES(benetel_5g ${DPDK_LIBS})
+TARGET_LINK_LIBRARIES(benetel_5g pthread dl rt m numa)
+
##########################################################
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
@@ -1547,6 +1583,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c
+ ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c
@@ -1599,6 +1636,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
+ ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
@@ -1744,9 +1782,15 @@ set(NR_RLC_SRC
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_sdu.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c
)
+
+set(NR_PDCP_SRC
+ ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+ ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
+ ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c
+ ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
+ )
set(L2_SRC
- ${OPENAIR2_DIR}/LAYER2/openair2_proc.c
${PDCP_DIR}/pdcp.c
${PDCP_DIR}/pdcp_fifo.c
${PDCP_DIR}/pdcp_sequence_manager.c
@@ -1754,6 +1798,7 @@ set(L2_SRC
${PDCP_DIR}/pdcp_util.c
${PDCP_DIR}/pdcp_security.c
${PDCP_DIR}/pdcp_netlink.c
+ ${OPENAIR2_DIR}/LAYER2/openair2_proc.c
# ${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_eNB.c
${RRC_DIR}/rrc_eNB_endc.c
@@ -1765,6 +1810,20 @@ set(L2_SRC
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
+
+set(L2_RRC_SRC
+ ${OPENAIR2_DIR}/LAYER2/openair2_proc.c
+ # ${RRC_DIR}/rrc_UE.c
+ ${RRC_DIR}/rrc_eNB.c
+ ${RRC_DIR}/rrc_eNB_endc.c
+ ${RRC_DIR}/rrc_eNB_S1AP.c
+ ${RRC_DIR}/rrc_eNB_M2AP.c
+ ${RRC_DIR}/rrc_eNB_UE_context.c
+ ${RRC_DIR}/rrc_common.c
+ ${RRC_DIR}/L2_interface.c
+ ${RRC_DIR}/L2_interface_common.c
+ ${RRC_DIR}/L2_interface_ue.c
+ )
set(L2_LTE_SRC
${RLC_V2}
@@ -1772,6 +1831,7 @@ set(L2_LTE_SRC
set(L2_NR_SRC
${NR_RLC_SRC}
+ ${NR_PDCP_SRC}
${NR_RRC_DIR}/rrc_gNB.c
${NR_RRC_DIR}/nr_rrc_common.c
${NR_RRC_DIR}/L2_nr_interface.c
@@ -1796,19 +1856,16 @@ set(L2_SRC_UE
${RRC_DIR}/L2_interface_ue.c
)
-set(LTE_NR_L2_SRC_UE
- ${PDCP_DIR}/pdcp.c
- ${PDCP_DIR}/pdcp_fifo.c
- ${PDCP_DIR}/pdcp_sequence_manager.c
- ${PDCP_DIR}/pdcp_primitives.c
- ${PDCP_DIR}/pdcp_util.c
- ${PDCP_DIR}/pdcp_security.c
- ${PDCP_DIR}/pdcp_netlink.c
- ${RLC_V2}
- )
-
+set(L2_RRC_SRC_UE
+ ${RRC_DIR}/rrc_UE.c
+ ${RRC_DIR}/rrc_common.c
+ ${RRC_DIR}/L2_interface_common.c
+ ${RRC_DIR}/L2_interface_ue.c
+ )
+
set(NR_L2_SRC_UE
${NR_RLC_SRC}
+ ${NR_PDCP_SRC}
${NR_UE_RRC_DIR}/L2_interface_ue.c
${NR_UE_RRC_DIR}/main_ue.c
${NR_UE_RRC_DIR}/rrc_UE.c
@@ -1918,6 +1975,14 @@ add_library(L2_NR
${MAC_NR_SRC}
${GNB_APP_SRC}
)
+
+add_library(L2_LTE_NR
+ ${L2_RRC_SRC}
+ ${MAC_SRC}
+ ${ENB_APP_SRC}
+ ${MCE_APP_SRC}
+)
+
add_dependencies(L2_NR rrc_flag nr_rrc_flag s1ap_flag x2_flag)
add_library(L2_UE
@@ -1925,6 +1990,11 @@ add_library(L2_UE
${MAC_SRC_UE}
)
+add_library(L2_UE_LTE_NR
+ ${L2_RRC_SRC_UE}
+ ${MAC_SRC_UE}
+)
+
if (NOT ${NOS1})
target_compile_definitions(L2_UE PUBLIC -DPDCP_USE_NETLINK)
endif()
@@ -2307,6 +2377,7 @@ add_library(LFDS7
add_library(SIMU_COMMON
${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c
+ ${OPENAIR1_DIR}/SIMULATION/TOOLS/phase_noise.c
)
# Simulation library
@@ -2745,7 +2816,7 @@ target_link_libraries (nr-softmodem
-Wl,--start-group
UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
- S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
+ S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB}
-Wl,--end-group z dl)
@@ -2787,7 +2858,7 @@ add_executable(nr-uesoftmodem
target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
- PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
+ PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
NFAPI_USER_LIB S1AP_LIB S1AP_ENB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
@@ -2906,6 +2977,7 @@ add_executable(nr_dlschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
+ ${OPENAIR_DIR}/common/utils/utils.c
${UTIL_SRC}
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
@@ -2919,6 +2991,7 @@ add_executable(nr_pbchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
+ ${OPENAIR_DIR}/common/utils/utils.c
${UTIL_SRC}
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
@@ -2934,6 +3007,7 @@ add_executable(nr_pucchsim
${OPENAIR_DIR}/common/utils/backtrace.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_DIR}/common/utils/utils.c
${UTIL_SRC}
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
@@ -2945,6 +3019,7 @@ target_link_libraries(nr_pucchsim
add_executable(nr_dlsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c
+ ${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/executables/softmodem-common.c
@@ -2960,6 +3035,7 @@ target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR)
add_executable(nr_prachsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c
+ ${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
@@ -2971,6 +3047,7 @@ target_link_libraries(nr_prachsim
add_executable(nr_ulschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
+ ${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${UTIL_SRC}
@@ -3005,6 +3082,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
${OPENAIR_DIR}/common/utils/backtrace.c
${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_DIR}/common/utils/utils.c
${XFORMS_SOURCE}
${T_SOURCE}
${CONFIG_SOURCES}
@@ -3091,7 +3169,7 @@ if (${T_TRACER})
SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
- L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR
+ L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR
CN_UTILS GTPV1U NR_GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB
ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts)
if (TARGET ${i})
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 786002e982..7e43a9d01c 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1276,7 +1276,10 @@
(Test2: MCS 16 50 PRBs),
(Test3: MCS 28 50 PRBs),
(Test4: MCS 9 217 PRBs),
- (Test5: MCS 9 273 PRBs)
+ (Test5: MCS 9 273 PRBs),
+ (Test6: DMRS Type A, 3 DMRS, 4 PTRS, 5 Interpolated Symbols),
+ (Test7: DMRS Type B, 3 DMRS, 2 PTRS, 7 Interpolated Symbols),
+ (Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1287,8 +1290,11 @@
-n100 -m16 -s10
-n100 -m28 -s20
-n100 -m9 -R217 -r217 -s5
- -n100 -m9 -R273 -r273 -s5
- nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5
+ -n100 -m9 -R273 -r273 -s5
+ -n100 -s5 -T 2 1 2 -U 2 0 2
+ -n100 -s5 -T 2 2 2 -U 2 1 2
+ -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3
+ nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8
PUSCH test OK
segmentation fault|assertion|exiting|fatal
3
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 36af9eaee4..f301908495 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -211,7 +211,7 @@ function main() {
GDB=0
CMAKE_BUILD_TYPE="RelWithDebInfo"
echo_info "Will Compile with gdb symbols"
- CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=RelWithDebInfo"
+ CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_EXPORT_COMPILE_COMMANDS=1"
shift
;;
"MinSizeRel")
diff --git a/doc/BUILD.md b/doc/BUILD.md
index 97f9047596..ba5db55cab 100644
--- a/doc/BUILD.md
+++ b/doc/BUILD.md
@@ -16,6 +16,7 @@ This page is valid on tags starting from **`2019.w09`**.
# Soft Modem Build Script
+The OAI EPC is developed in a distinct project with it's own [documentation](https://github.com/OPENAIRINTERFACE/openair-epc-fed/wiki) , it is not described here.
OAI softmodem sources, which aim to implement 3GPP compliant UEs, eNodeB and gNodeB can be downloaded from the Eurecom [gitlab repository](./GET_SOURCES.md).
@@ -33,7 +34,7 @@ The main oai binaries, which are tested by the Continuous Integration process ar
Running the [build_oai](../cmake_targets/build_oai) script also generates some utilities required to build and/or run the oai softmodem binaries:
-- `con2uedata`: a binary used to build the UE data from a configuration file. The created file emulates the sim card of a 3GPP compliant phone.
+- `conf2uedata`: a binary used to build the UE data from a configuration file. The created file emulates the sim card of a 3GPP compliant phone.
- `nvram`: a binary used to build UE (IMEI...) and EMM (IMSI, registered PLMN) non volatile data.
- `rb_tool`: radio bearer utility
- `genids` T Tracer utility, used at build time to generate T_IDs.h include file. This binary is located in the [T Tracer source file directory](../common/utils/T) .
diff --git a/doc/GET_SOURCES.md b/doc/GET_SOURCES.md
index e27e9dbb74..854ff3b504 100644
--- a/doc/GET_SOURCES.md
+++ b/doc/GET_SOURCES.md
@@ -33,12 +33,8 @@ holds the source code for (eNB RAN + UE RAN).
For legal issues (licenses), the core network (EPC) source code is now moved away from
the above openairinterface5g git repository.
-* A very old version of the EPC is located under the same GitLab Eurecom server (splitted into 2 Git repos):
- * [openair-cn](https://gitlab.eurecom.fr/oai/openair-cn.git) with apache license
- * [xtables-addons-oai](https://gitlab.eurecom.fr/oai/xtables-addons-oai.git) with GPL license
- * **These repositories are no more maintained.**
* A more recent version is available under our GitHub domain:
- * [OAI GitHub openair-cn](https://github.com/OPENAIRINTERFACE/openair-cn)
+ * [OAI GitHub openair-cn domain](https://github.com/OPENAIRINTERFACE)
* Check its wiki pages for more details
Configure git with your name/email address (only important if you are developer and want to contribute/push code to Git Repository):
@@ -80,8 +76,6 @@ you do not have account on gitlab.eurecom.fr, please register yourself to gitlab
* `git clone git@gitlab.eurecom.fr:oai/openairinterface5g.git`
* Clone with user name/password prompt:
* `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/openairinterface5g.git`
- * `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/openair-cn.git`
- * `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/xtables-addons-oai.git` (optional, openair-cn build script can do it for you)
# Which branch to checkout?
diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md
new file mode 100644
index 0000000000..7365bc0f4c
--- /dev/null
+++ b/doc/TESTBenches.md
@@ -0,0 +1,45 @@
+## Table of Contents ##
+
+1. [Legacy 1 Bench](#legacy-1-bench)
+2. [Legacy 2 Bench](#legacy-2-bench)
+3. [Next Bench for DEV](#next-bench-for-dev)
+4. [Next Bench for CI](#next-bench-for-ci)
+5. [Indoor Live Network Bench](#indoor-live-network-bench)
+6. [Outdoor Live Network Bench](#outdoor-live-network-bench)
+
+
+## Legacy 1 Bench
+
+**Purpose** : FDD Band 7 and Band 13, LTE-M
+**Note** : Legacy1 and Legacy2 are duplicated so that they can run in parallel, thus avoiding a CI bottleneck
+**Note** : Faraday Cages 1 and 2 are physically the same cage
+
+
+
+## Legacy 2 Bench
+
+**Purpose** : TDD Band 40, TM2 2xTX 2xRX
+**Note** : CN can run in a container, could also run on Massive
+
+
+
+## Next Bench for DEV
+
+**Note** : Benetel CI can also run on this bench at night
+
+
+
+
+## Next Bench for CI
+
+**Note** : The current test running on Caracal could run on this bench with a N300/N300 setup
+
+
+
+## Indoor Live Network Bench
+
+
+
+## Outdoor Live Network Bench
+
+
diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md
index a16b4dbe13..198f6bb115 100644
--- a/doc/TESTING_GNB_W_COTS_UE.md
+++ b/doc/TESTING_GNB_W_COTS_UE.md
@@ -1,4 +1,4 @@
-STATUS 2020/07/30 : under continuous improvement ; updated the configuration files links with CI approved reference files
+STATUS 2020/09/10 : updated the status of interop (end to end UL/DL traffic)
## Table of Contents ##
@@ -194,7 +194,7 @@ The order to run the different components is important:
1- first, CN
2- then, eNB
3- then, gNB
-4- finally, switch UE from airplane mode OFF to ON
+4- finally, switch UE from airplane mode ON to OFF (ie Radio from OFF to ON)
It is recommended to redirect the run commands to the same log file (fur further analysis and debug), using ```| tee **YOUR_LOG_FILE**``` especially for eNB and gNB.
It is not very useful for the CN.
@@ -220,17 +220,16 @@ Execute:
- **gNB** (on the gNB host)
+**ATTENTION** : for the gNB execution,
+The **-E** option is required to enable the tri-quarter sampling rate when using a B2xx serie USRP
+The **-E** option is **NOT supported** when using a a N300 USRP
+
Execute:
```
~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O **YOUR_GNB_CONF_FILE** -E | tee **YOUR_LOG_FILE**
```
-**ATTENTION** : for the gNB execution,
-The -E option is required to enable the tri-quarter sampling rate when using a B2xx serie USRP
-The -E opton is not needed when using a a N300 USRP
-
-
## Test Case
@@ -377,13 +376,11 @@ The following parts have been validated with FR1 COTS UE:
PDCCH DCI format 1_1 and correponding PDSCH are decoded correctlyby the phone
ACK/NACK (PUCCH format 0) are successfully received at gNB
-- On going:
- validation of HARQ procedures
- Integration with higher layers to replace dummy data with real traffic
+- **End-to end UL / DL traffic with HARQ procedures validated (ping, iperf)**
-- Known limitations as of May 2020:
- only dummy DL traffic
- no UL traffic
- no end-to-end traffic possible
+- Known limitations as of September 2020:
+ DL traffic : 3Mbps
+ UL traffic : 1Mbps
+ some packet losses might still occur even in ideal channel conditions
diff --git a/doc/testbenches_doc_resources/benches.vsdx b/doc/testbenches_doc_resources/benches.vsdx
new file mode 100755
index 0000000000..6ad3a5b576
Binary files /dev/null and b/doc/testbenches_doc_resources/benches.vsdx differ
diff --git a/doc/testbenches_doc_resources/indoor_live.jpg b/doc/testbenches_doc_resources/indoor_live.jpg
new file mode 100755
index 0000000000..ce8b9cda48
Binary files /dev/null and b/doc/testbenches_doc_resources/indoor_live.jpg differ
diff --git a/doc/testbenches_doc_resources/legacy1.jpg b/doc/testbenches_doc_resources/legacy1.jpg
new file mode 100755
index 0000000000..c3579df3e4
Binary files /dev/null and b/doc/testbenches_doc_resources/legacy1.jpg differ
diff --git a/doc/testbenches_doc_resources/legacy2.jpg b/doc/testbenches_doc_resources/legacy2.jpg
new file mode 100755
index 0000000000..f40d167a2d
Binary files /dev/null and b/doc/testbenches_doc_resources/legacy2.jpg differ
diff --git a/doc/testbenches_doc_resources/next_ci.jpg b/doc/testbenches_doc_resources/next_ci.jpg
new file mode 100755
index 0000000000..2d4111510c
Binary files /dev/null and b/doc/testbenches_doc_resources/next_ci.jpg differ
diff --git a/doc/testbenches_doc_resources/next_dev.jpg b/doc/testbenches_doc_resources/next_dev.jpg
new file mode 100755
index 0000000000..72e9f63bf9
Binary files /dev/null and b/doc/testbenches_doc_resources/next_dev.jpg differ
diff --git a/doc/testbenches_doc_resources/outdoor_live.jpg b/doc/testbenches_doc_resources/outdoor_live.jpg
new file mode 100755
index 0000000000..eba44a3c00
Binary files /dev/null and b/doc/testbenches_doc_resources/outdoor_live.jpg differ
diff --git a/docker/Dockerfile.enb.rhel7.oc4-4 b/docker/Dockerfile.enb.rhel7.oc4-4
new file mode 100644
index 0000000000..12d9a19640
--- /dev/null
+++ b/docker/Dockerfile.enb.rhel7.oc4-4
@@ -0,0 +1,92 @@
+#/*
+# * 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.1 (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
+# */
+#---------------------------------------------------------------------
+#
+# Dockerfile for the Open-Air-Interface eNB service
+# Valid for RHEL7 in the OpenShift context (v4.4)
+#
+#---------------------------------------------------------------------
+
+
+ARG REGISTRY=localhost
+FROM $REGISTRY/oai-build-base:latest.el7 AS builder
+
+ARG GIT_TAG=v1.1.1
+
+WORKDIR /root
+
+RUN if [ "$EURECOM_PROXY" == true ]; then git config --global http.proxy http://:@proxy.eurecom.fr:8080; fi
+
+RUN git clone --depth=1 --branch=$GIT_TAG https://gitlab.eurecom.fr/oai/openairinterface5g.git
+COPY patches patches/
+RUN patch -p1 -d openairinterface5g < patches/disable_building_nasmesh_and_rbtool.patch \
+ && patch -p1 -d openairinterface5g < patches/disable_sched_fifo_fail_exits.patch
+RUN cd openairinterface5g/cmake_targets \
+ && ln -sf /usr/local/bin/asn1c_oai /usr/local/bin/asn1c \
+ && ln -sf /usr/local/share/asn1c_oai /usr/local/share/asn1c \
+ && ./build_oai -c --eNB -w USRP --verbose-compile
+
+
+FROM registry.redhat.io/ubi7/ubi
+LABEL name="oai-enb" \
+ version="$GIT_TAG" \
+ maintainer="Frank A. Zdarsky " \
+ io.k8s.description="openairinterface5g eNB $GIT_TAG." \
+ io.openshift.tags="oai,enb" \
+ io.openshift.non-scalable="true"
+
+RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \
+ && REPOLIST="rhel-7-server-optional-rpms" \
+ && PKGLIST="boost libconfig lksctp-tools protobuf-c iproute iputils procps-ng bind-utils xforms nettle libyaml libusb" \
+ # && yum -y upgrade-minimal --setopt=tsflags=nodocs --security --sec-severity=Critical --sec-severity=Important && \
+ && yum -y install --enablerepo ${REPOLIST} --setopt=tsflag=nodocs ${PKGLIST} \
+ && yum -y clean all \
+ && rm -rf /var/cache/yum
+
+ENV APP_ROOT=/opt/oai-enb
+ENV PATH=${APP_ROOT}:${PATH} HOME=${APP_ROOT}
+COPY --from=builder /root/openairinterface5g/cmake_targets/lte_build_oai/build/lte-softmodem ${APP_ROOT}/bin/
+COPY --from=builder /root/openairinterface5g/cmake_targets/lte_build_oai/build/*.so* /lib64
+COPY --from=builder /usr/local/lib64 /lib64
+COPY --from=builder /usr/local/bin/uhd_* /usr/local/bin
+COPY --from=builder /usr/local/share/uhd /usr/local/share/uhd
+RUN cd /lib64 \
+ && ln -sf liboai_eth_transpro.so liboai_transpro.so \
+ && ln -sf liboai_usrpdevif.so liboai_device.so \
+ && ln -sf libuhd.so.3.13 libuhd.so.3 \
+ && ln -sf libuhd.so.3 libuhd.so
+COPY scripts ${APP_ROOT}/bin/
+COPY configs ${APP_ROOT}/etc/
+RUN chmod -R u+x ${APP_ROOT} && \
+ chgrp -R 0 ${APP_ROOT} && \
+ chmod -R g=u ${APP_ROOT} /etc/passwd
+USER 10001
+WORKDIR ${APP_ROOT}
+
+EXPOSE 2152/udp # S1U, GTP/UDP
+EXPOSE 22100/tcp # ?
+EXPOSE 36412/udp # S1C, SCTP/UDP
+EXPOSE 36422/udp # X2C, SCTP/UDP
+EXPOSE 50000/udp # IF5 / ORI (control)
+EXPOSE 50001/udp # IF5 / ECPRI (data)
+
+CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"]
+ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"]
diff --git a/executables/main-fs6.c b/executables/main-fs6.c
index d2d64d0959..c4a0d85b34 100644
--- a/executables/main-fs6.c
+++ b/executables/main-fs6.c
@@ -917,7 +917,7 @@ void phy_procedures_eNB_TX_fromsplit(uint8_t *bufferZone, int nbBlocks, PHY_VARS
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
if (is_pmch_subframe(frame,subframe,fp)) {
- pmch_procedures(eNB,proc);
+ pmch_procedures(eNB,proc,0);
} else {
// this is not a pmch subframe, so generate PSS/SSS/PBCH
common_signal_procedures(eNB,frame, subframe);
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index c2b5b80d31..46f2ff7b2e 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -180,6 +180,17 @@ int attach_rru(RU_t *ru)
((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]);
AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),
"RU %d failed send configuration to remote radio\n",ru->idx);
+
+ if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice,
+ &rru_config_msg,
+ msg_len))<0) {
+ LOG_I(PHY,"Waiting for RRU %d\n",ru->idx);
+ } else if (rru_config_msg.type == RRU_config_ok) {
+ LOG_I(PHY, "RRU_config_ok received\n");
+ } else {
+ LOG_E(PHY,"Received incorrect message %d from RRU %d\n",rru_config_msg.type,ru->idx);
+ }
+
return 0;
}
@@ -1442,6 +1453,8 @@ void *ru_thread( void *param ) {
LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
+ memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
+
if(emulate_rf) {
fill_rf_config(ru,ru->rf_config_file);
nr_init_frame_parms(&ru->config, fp);
@@ -1464,8 +1477,6 @@ void *ru_thread( void *param ) {
AssertFatal(ret==0,"Cannot connect to remote radio\n");
}
- memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
-
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
nr_init_frame_parms(&ru->config, fp);
nr_dump_frame_parms(fp);
@@ -1571,7 +1582,8 @@ void *ru_thread( void *param ) {
if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
//if (proc->tti_rx==8) {
- if (ru->feprx) ru->feprx(ru,proc->tti_rx);
+ if (ru->feprx) {
+ ru->feprx(ru,proc->tti_rx);
//LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1);
LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx);
@@ -1591,6 +1603,7 @@ void *ru_thread( void *param ) {
proc->frame_rx,proc->tti_rx);
free_nr_ru_prach_entry(ru,prach_id);
}
+ }
}
// At this point, all information for subframe has been received on FH interface
@@ -2131,26 +2144,29 @@ void set_function_spec_param(RU_t *ru) {
ru->fh_north_out = NULL; // no outgoing fronthaul to north
ru->nr_start_if = NULL; // no if interface
ru->rfdevice.host_type = RAU_HOST;
+
+ // FK this here looks messed up. The following lines should be part of the if (ru->function == gNodeB_3GPP), shouldn't they?
+
+ ru->fh_south_in = rx_rf; // local synchronous RF RX
+ ru->fh_south_out = tx_rf; // local synchronous RF TX
+ ru->start_rf = start_rf; // need to start the local RF interface
+ ru->stop_rf = stop_rf;
+ ru->start_write_thread = start_write_thread; // starting RF TX in different thread
+ printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf);
}
- ru->fh_south_in = rx_rf; // local synchronous RF RX
- ru->fh_south_out = tx_rf; // local synchronous RF TX
- ru->start_rf = start_rf; // need to start the local RF interface
- ru->stop_rf = stop_rf;
- ru->start_write_thread = start_write_thread; // starting RF TX in different thread
- printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf);
/*
- if (ru->function == gNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise
- fill_rf_config(ru,rf_config_file);
- init_frame_parms(&ru->frame_parms,1);
- nr_phy_init_RU(ru);
- }
+ printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf);
+ fill_rf_config(ru,rf_config_file);
+ init_frame_parms(&ru->frame_parms,1);
+ nr_phy_init_RU(ru);
- ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
- if (setup_RU_buffers(ru)!=0) {
- printf("Exiting, cannot initialize RU Buffers\n");
- exit(-1);
- }*/
+ ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
+ if (setup_RU_buffers(ru)!=0) {
+ printf("Exiting, cannot initialize RU Buffers\n");
+ exit(-1);
+ }
+ */
break;
case REMOTE_IF5: // the remote unit is IF5 RRU
@@ -2203,6 +2219,15 @@ void set_function_spec_param(RU_t *ru) {
exit(-1);
}
+ if (ru->ifdevice.get_internal_parameter != NULL) {
+ void *t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_in");
+ if (t != NULL)
+ ru->fh_south_in = t;
+ t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_out");
+ if (t != NULL)
+ ru->fh_south_out = t;
+ }
+
malloc_IF4p5_buffer(ru);
break;
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index ab10313c1a..a3d0b325d6 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -84,9 +84,6 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "NB_IoT_interface.h"
#include "x2ap_eNB.h"
-short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655};
-
-
pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index aee4c5b144..508c45cebf 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -121,7 +121,7 @@ extern double cpuf;
#ifndef NO_RAT_NR
#define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */
#else
- #define DURATION_RX_TO_TX (4) /* For LTE, this duration is fixed to 4 and it is linked to LTE standard for both modes FDD/TDD */
+ #define DURATION_RX_TO_TX (6) /* For LTE, this duration is fixed to 4 and it is linked to LTE standard for both modes FDD/TDD */
#endif
#define FRAME_PERIOD 100000000ULL
@@ -371,8 +371,6 @@ static void UE_synch(void *arg) {
}
void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
-
-
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_tti_tx);
uint8_t gNB_id = 0;
@@ -480,21 +478,22 @@ void UE_processing(void *arg) {
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
- uint8_t gNB_id = 0;
-
- // params for UL time alignment procedure
- NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id];
- uint8_t numerology = UE->frame_parms.numerology_index;
- uint16_t bwp_ul_NB_RB = UE->frame_parms.N_RB_UL;
- int slot_tx = proc->nr_tti_tx;
- int frame_tx = proc->frame_tx;
+ processSlotRX(UE, proc);
+ processSlotTX(UE, proc);
/* UL time alignment
// If the current tx frame and slot match the TA configuration in ul_time_alignment
// then timing advance is processed and set to be applied in the next UL transmission */
if (UE->mac_enabled == 1) {
+ uint8_t gNB_id = 0;
+ NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id];
+ int slot_tx = proc->nr_tti_tx;
+ int frame_tx = proc->frame_tx;
if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) {
+ uint8_t numerology = UE->frame_parms.numerology_index;
+ uint16_t bwp_ul_NB_RB = UE->frame_parms.N_RB_UL;
+
LOG_D(PHY,"Applying timing advance -- frame %d -- slot %d\n", frame_tx, slot_tx);
//if (nfapi_mode!=3){
@@ -504,9 +503,6 @@ void UE_processing(void *arg) {
//}
}
}
-
- processSlotRX(UE, proc);
- processSlotTX(UE, proc);
}
void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
@@ -631,6 +627,7 @@ void *UE_thread(void *arg) {
notifiedFIFO_t freeBlocks;
initNotifiedFIFO_nothreadSafe(&freeBlocks);
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+ int timing_advance = UE->timing_advance;
for (int i=0; iframe_parms.nb_antennas_tx; i++)
txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp(
- ((curMsg->proc.nr_tti_rx + DURATION_RX_TO_TX)%nb_slot_frame),&UE->frame_parms,0)];
+ ((slot_nr + DURATION_RX_TO_TX - RX_NB_TH)%nb_slot_frame),&UE->frame_parms,0)];
int readBlockSize, writeBlockSize;
if (slot_nr<(nb_slot_frame - 1)) {
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms);
- writeBlockSize=UE->frame_parms.get_samples_per_slot(curMsg->proc.nr_tti_tx,&UE->frame_parms);
+ writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms);
} else {
UE->rx_offset_diff = computeSamplesShift(UE);
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) -
UE->rx_offset_diff;
- writeBlockSize=UE->frame_parms.get_samples_per_slot(curMsg->proc.nr_tti_tx,&UE->frame_parms) -
+ writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms)-
UE->rx_offset_diff;
}
+ if (UE->timing_advance != timing_advance) {
+ writeBlockSize -= UE->timing_advance - timing_advance;
+ timing_advance = UE->timing_advance;
+ }
+
AssertFatal(readBlockSize ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
×tamp,
@@ -757,29 +759,19 @@ void *UE_thread(void *arg) {
readBlockSize,
UE->frame_parms.nb_antennas_rx),"");
- AssertFatal( writeBlockSize ==
- UE->rfdevice.trx_write_func(&UE->rfdevice,
- timestamp+
- UE->frame_parms.get_samples_slot_timestamp(slot_nr,
- &UE->frame_parms,DURATION_RX_TO_TX) - firstSymSamp -
- openair0_cfg[0].tx_sample_advance,
- txp,
- writeBlockSize,
- UE->frame_parms.nb_antennas_tx,
- 1),"");
-
if( slot_nr==(nb_slot_frame-1)) {
// read in first symbol of next frame and adjust for timing drift
int first_symbols=UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0; // first symbol of every frames
- if ( first_symbols > 0 )
+ if ( first_symbols > 0 ) {
+ openair0_timestamp ignore_timestamp;
AssertFatal(first_symbols ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
- ×tamp,
+ &ignore_timestamp,
(void **)UE->common_vars.rxdata,
first_symbols,
UE->frame_parms.nb_antennas_rx),"");
- else
+ } else
LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
}
@@ -790,18 +782,15 @@ void *UE_thread(void *arg) {
notifiedFIFO_elt_t *res;
while (nbSlotProcessing >= RX_NB_TH) {
- if ( (res=tryPullTpool(&nf, Tpool)) != NULL ) {
- nbSlotProcessing--;
- processingData_t *tmp=(processingData_t *)res->msgData;
+ res=pullTpool(&nf, Tpool);
+ nbSlotProcessing--;
+ processingData_t *tmp=(processingData_t *)res->msgData;
- if (tmp->proc.decoded_frame_rx != -1)
- decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
- //decoded_frame_rx=tmp->proc.decoded_frame_rx;
+ if (tmp->proc.decoded_frame_rx != -1)
+ decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
+ //decoded_frame_rx=tmp->proc.decoded_frame_rx;
- pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
- }
-
- usleep(200);
+ pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
}
if ( (decoded_frame_rx != curMsg->proc.frame_rx) &&
@@ -810,6 +799,20 @@ void *UE_thread(void *arg) {
LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
decoded_frame_rx, curMsg->proc.frame_rx );
+ AssertFatal( writeBlockSize ==
+ UE->rfdevice.trx_write_func(&UE->rfdevice,
+ timestamp+
+ UE->frame_parms.get_samples_slot_timestamp(slot_nr,
+ &UE->frame_parms,DURATION_RX_TO_TX - RX_NB_TH) - firstSymSamp -
+ openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - UE->timing_advance,
+ txp,
+ writeBlockSize,
+ UE->frame_parms.nb_antennas_tx,
+ 1),"");
+
+ for (int i=0; iframe_parms.nb_antennas_tx; i++)
+ memset(txp[i], 0, writeBlockSize);
+
nbSlotProcessing++;
msgToPush->key=slot_nr;
pushTpool(Tpool, msgToPush);
@@ -828,6 +831,7 @@ void *UE_thread(void *arg) {
pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
}
+
} // while !oai_exit
return NULL;
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 897ea540c9..3105f06901 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -38,13 +38,12 @@
#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
-
+#include "openair1/PHY/MODULATION/nr_modulation.h"
#include "PHY/phy_vars_nr_ue.h"
#include "PHY/LTE_TRANSPORT/transport_vars.h"
#include "SCHED/sched_common_vars.h"
#include "PHY/MODULATION/modulation_vars.h"
//#include "../../SIMU/USER/init_lte.h"
-#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "LAYER2/MAC/mac_vars.h"
#include "RRC/LTE/rrc_vars.h"
@@ -585,7 +584,7 @@ void init_pdcp(void) {
LOG_I(RLC, "Problem at RLC initiation \n");
}
pdcp_layer_init();
- nr_ip_over_LTE_DRB_preconfiguration();*/
+ nr_DRB_preconfiguration();*/
pdcp_module_init(pdcp_initmask);
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
@@ -752,6 +751,7 @@ int main( int argc, char **argv ) {
if (frame_parms[CC_id]->frame_type == TDD)
frame_parms[CC_id]->ul_CarrierFreq = downlink_frequency[0][0];
}
+ init_symbol_rotation(frame_parms[CC_id],frame_parms[CC_id]->dl_CarrierFreq);
}
// printf("tx_max_power = %d -> amp %d\n",tx_max_power[0],get_tx_amp(tx_max_poHwer,tx_max_power));
init_openair0();
@@ -769,13 +769,7 @@ int main( int argc, char **argv ) {
for(int CC_id=0; CC_idrf_map.card=0;
PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
-#if defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706)
- PHY_vars_UE_g[0][CC_id]->hw_timing_advance = timing_advance;
PHY_vars_UE_g[0][CC_id]->timing_advance = timing_advance;
-#else
- PHY_vars_UE_g[0][CC_id]->hw_timing_advance = 160;
-#endif
-
}
init_NR_UE_threads(1);
diff --git a/executables/split_headers.h b/executables/split_headers.h
index 985b1b7dae..dc451773c5 100644
--- a/executables/split_headers.h
+++ b/executables/split_headers.h
@@ -280,7 +280,7 @@ int init_rf(RU_t *ru);
void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
void tx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe);
-void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
+void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, int fembms_flag);
bool dlsch_procedures(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
int harq_pid,
diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
index 345122ca1d..b42ac6e4c8 100644
--- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c
+++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
@@ -396,17 +396,17 @@ int test_ldpc(short No_iteration,
decParams.numMaxIter=No_iteration;
decParams.outMode = nrLDPC_outMode_BIT;
//decParams.outMode =nrLDPC_outMode_LLRINT8;
-
-
- for(j=0;j 1280, 2401 -> 2560
diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/bgs/BG1_compact_in_C.h b/openair1/PHY/CODING/nrLDPC_decoder_LYC/bgs/BG1_compact_in_C.h
new file mode 100644
index 0000000000..9a6086998e
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_decoder_LYC/bgs/BG1_compact_in_C.h
@@ -0,0 +1,478 @@
+
+h_element host_h_compact1_I0 [46*19] =
+{{0 ,0,250},{1 ,0,2},{2 ,0,106},{3 ,0,121},{4 ,0,157},{5 ,0,205},{6 ,0,183},{7 ,0,220},{8 ,0,112},{9 ,0,103},{10 ,1,98},{11 ,0,77},{12 ,0,160},{13 ,0,177},{14 ,0,206},{15 ,0,40},{16 ,1,64},{17 ,0,7},{18 ,1,42},{19 ,0,60},{20 ,0,151},{21 ,1,249},{22 ,0,64},{23 ,1,156},{24 ,0,112},{25 ,1,23},{26 ,0,195},{27 ,1,25},{28 ,0,128},{29 ,1,86},{30 ,0,216},{31 ,1,95},{32 ,0,221},{33 ,1,2},{34 ,0,127},{35 ,1,161},{36 ,0,37},{37 ,1,198},{38 ,0,167},{39 ,1,173},{40 ,0,157},{41 ,1,167},{42 ,0,149},{43 ,1,151},{44 ,0,139},{45 ,1,149},
+{0 ,1,69},{1 ,2,239},{2 ,1,111},{3 ,1,89},{4 ,1,102},{5 ,1,236},{6 ,6,22},{7 ,1,44},{8 ,1,4},{9 ,1,182},{10 ,2,149},{11 ,1,41},{12 ,1,42},{13 ,3,248},{14 ,12,55},{15 ,1,96},{16 ,3,49},{17 ,14,164},{18 ,12,233},{19 ,1,73},{20 ,3,186},{21 ,5,121},{22 ,12,142},{23 ,2,147},{24 ,3,86},{25 ,6,136},{26 ,2,243},{27 ,6,104},{28 ,4,165},{29 ,14,236},{30 ,10,73},{31 ,7,177},{32 ,12,112},{33 ,2,187},{34 ,7,167},{35 ,6,197},{36 ,14,105},{37 ,13,220},{38 ,9,151},{39 ,3,139},{40 ,8,137},{41 ,3,173},{42 ,4,157},{43 ,16,163},{44 ,7,157},{45 ,6,151},
+{0 ,2,226},{1 ,3,117},{2 ,2,185},{3 ,3,84},{4 ,26,0},{5 ,3,194},{6 ,10,28},{7 ,4,159},{8 ,3,7},{9 ,10,109},{10 ,4,167},{11 ,12,83},{12 ,10,21},{13 ,7,151},{14 ,15,206},{15 ,10,65},{16 ,11,49},{17 ,16,59},{18 ,13,8},{19 ,7,72},{20 ,9,217},{21 ,16,109},{22 ,13,188},{23 ,10,170},{24 ,4,236},{25 ,7,116},{26 ,4,215},{27 ,8,194},{28 ,19,181},{29 ,18,84},{30 ,13,120},{31 ,22,172},{32 ,14,199},{33 ,11,41},{34 ,15,164},{35 ,12,207},{36 ,15,51},{37 ,23,122},{38 ,10,157},{39 ,7,149},{40 ,17,149},{41 ,9,139},{42 ,24,137},{43 ,18,173},{44 ,9,163},{45 ,10,167},
+{0 ,3,159},{1 ,4,124},{2 ,4,63},{3 ,4,20},{0 ,0,-1},{5 ,12,231},{6 ,11,67},{7 ,7,31},{8 ,12,211},{9 ,11,21},{10 ,7,160},{11 ,16,182},{12 ,11,32},{13 ,20,185},{14 ,16,127},{15 ,13,63},{16 ,20,51},{17 ,17,1},{18 ,18,155},{19 ,8,127},{20 ,11,47},{21 ,20,131},{22 ,17,158},{23 ,18,152},{24 ,11,116},{25 ,14,182},{26 ,15,61},{27 ,49,0},{28 ,21,63},{29 ,25,6},{30 ,24,9},{31 ,25,61},{32 ,24,121},{33 ,21,211},{34 ,17,159},{35 ,22,103},{36 ,18,120},{37 ,59,0},{38 ,12,163},{39 ,19,0},{40 ,62,0},{41 ,18,151},{42 ,64,0},{43 ,25,139},{44 ,22,173},{45 ,67,0},
+{0 ,5,100},{1 ,5,71},{2 ,5,117},{3 ,6,150},{0 ,0,-1},{5 ,16,28},{6 ,13,244},{7 ,8,167},{8 ,16,102},{9 ,13,142},{10 ,8,49},{11 ,21,78},{12 ,13,234},{13 ,23,62},{14 ,17,16},{15 ,18,75},{16 ,22,154},{17 ,21,144},{18 ,19,147},{19 ,10,224},{20 ,22,160},{21 ,21,171},{22 ,44,0},{23 ,45,0},{24 ,22,222},{25 ,47,0},{26 ,48,0},{0 ,0,-1},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{0 ,0,-1},{38 ,60,0},{39 ,61,0},{0 ,0,-1},{41 ,63,0},{0 ,0,-1},{43 ,65,0},{44 ,66,0},{0 ,0,-1},
+{0 ,6,10},{1 ,7,222},{2 ,6,93},{3 ,7,131},{0 ,0,-1},{5 ,21,123},{6 ,17,11},{7 ,14,104},{8 ,19,164},{9 ,17,14},{10 ,14,58},{11 ,22,252},{12 ,18,7},{13 ,35,0},{14 ,21,229},{15 ,25,179},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{0 ,0,-1},{0 ,0,-1},{24 ,46,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,9,59},{1 ,8,104},{2 ,7,229},{3 ,8,243},{0 ,0,-1},{5 ,22,115},{6 ,18,157},{7 ,29,0},{8 ,21,109},{9 ,18,61},{10 ,32,0},{11 ,23,22},{12 ,34,0},{0 ,0,-1},{14 ,36,0},{15 ,37,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,10,229},{1 ,9,173},{2 ,8,177},{3 ,10,136},{0 ,0,-1},{5 ,27,0},{6 ,20,211},{0 ,0,-1},{8 ,22,241},{9 ,20,216},{0 ,0,-1},{11 ,33,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,11,110},{1 ,11,220},{2 ,9,95},{3 ,11,86},{0 ,0,-1},{0 ,0,-1},{6 ,28,0},{0 ,0,-1},{8 ,24,90},{9 ,31,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,12,191},{1 ,12,102},{2 ,10,39},{3 ,12,246},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{8 ,30,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,13,9},{1 ,14,109},{2 ,13,142},{3 ,13,219},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,15,195},{1 ,15,132},{2 ,14,225},{3 ,14,211},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,16,23},{1 ,16,142},{2 ,15,225},{3 ,16,240},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,18,190},{1 ,17,155},{2 ,17,245},{3 ,17,76},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,19,35},{1 ,19,255},{2 ,18,205},{3 ,18,244},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,20,239},{1 ,21,28},{2 ,19,251},{3 ,20,144},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,21,31},{1 ,22,0},{2 ,20,117},{3 ,21,12},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,22,1},{1 ,23,0},{2 ,24,0},{3 ,22,1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,23,0},{1 ,24,0},{2 ,25,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+};
+
+
+h_element host_h_compact2_I0 [68*30] =
+{{0 ,0,250},{0 ,1,69},{0 ,2,226},{0 ,3,159},{1 ,4,124},{0 ,5,100},{0 ,6,10},{1 ,7,222},{1 ,8,104},{0 ,9,59},{0 ,10,229},{0 ,11,110},{0 ,12,191},{0 ,13,9},{1 ,14,109},{0 ,15,195},{0 ,16,23},{1 ,17,155},{0 ,18,190},{0 ,19,35},{0 ,20,239},{0 ,21,31},{0 ,22,1},{0 ,23,0},{1 ,24,0},{2 ,25,0},{4 ,26,0},{5 ,27,0},{6 ,28,0},{7 ,29,0},{8 ,30,0},{9 ,31,0},{10 ,32,0},{11 ,33,0},{12 ,34,0},{13 ,35,0},{14 ,36,0},{15 ,37,0},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{22 ,44,0},{23 ,45,0},{24 ,46,0},{25 ,47,0},{26 ,48,0},{27 ,49,0},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{37 ,59,0},{38 ,60,0},{39 ,61,0},{40 ,62,0},{41 ,63,0},{42 ,64,0},{43 ,65,0},{44 ,66,0},{45 ,67,0},
+{1 ,0,2},{2 ,1,111},{1 ,2,239},{1 ,3,117},{2 ,4,63},{1 ,5,71},{2 ,6,93},{2 ,7,229},{2 ,8,177},{1 ,9,173},{2 ,10,39},{1 ,11,220},{1 ,12,102},{2 ,13,142},{2 ,14,225},{1 ,15,132},{1 ,16,142},{2 ,17,245},{2 ,18,205},{1 ,19,255},{2 ,20,117},{1 ,21,28},{1 ,22,0},{1 ,23,0},{2 ,24,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{2 ,0,106},{3 ,1,89},{2 ,2,185},{3 ,3,84},{3 ,4,20},{2 ,5,117},{3 ,6,150},{3 ,7,131},{3 ,8,243},{2 ,9,95},{3 ,10,136},{3 ,11,86},{3 ,12,246},{3 ,13,219},{3 ,14,211},{2 ,15,225},{3 ,16,240},{3 ,17,76},{3 ,18,244},{2 ,19,251},{3 ,20,144},{3 ,21,12},{3 ,22,1},{11 ,23,22},{8 ,24,90},{15 ,25,179},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{3 ,0,121},{4 ,1,102},{10 ,2,149},{5 ,3,194},{7 ,4,159},{21 ,5,121},{6 ,6,22},{7 ,7,31},{7 ,8,167},{20 ,9,217},{6 ,10,28},{6 ,11,67},{5 ,12,231},{6 ,13,244},{7 ,14,104},{14 ,15,206},{5 ,16,28},{6 ,17,11},{6 ,18,157},{8 ,19,164},{6 ,20,211},{5 ,21,123},{5 ,22,115},{13 ,23,62},{30 ,24,9},{29 ,25,6},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{4 ,0,157},{5 ,1,236},{23 ,2,147},{8 ,3,7},{10 ,4,167},{0 ,0,-1},{25 ,6,136},{10 ,7,160},{10 ,8,49},{38 ,9,151},{9 ,10,109},{9 ,11,21},{8 ,12,211},{9 ,13,142},{10 ,14,58},{26 ,15,61},{8 ,16,102},{9 ,17,14},{9 ,18,61},{18 ,19,147},{9 ,20,216},{8 ,21,109},{8 ,22,241},{37 ,23,122},{32 ,24,121},{31 ,25,61},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{5 ,0,205},{7 ,1,44},{26 ,2,243},{13 ,3,248},{24 ,4,236},{0 ,0,-1},{27 ,6,104},{13 ,7,151},{19 ,8,127},{41 ,9,139},{12 ,10,21},{12 ,11,32},{11 ,12,83},{12 ,13,234},{17 ,14,164},{34 ,15,164},{11 ,16,182},{14 ,17,16},{12 ,18,7},{28 ,19,181},{13 ,20,185},{11 ,21,78},{11 ,22,252},{0 ,0,-1},{42 ,24,137},{43 ,25,139},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{6 ,0,183},{8 ,1,4},{33 ,2,187},{16 ,3,49},{26 ,4,215},{0 ,0,-1},{35 ,6,197},{19 ,7,72},{27 ,8,194},{44 ,9,163},{15 ,10,65},{16 ,11,49},{14 ,12,55},{15 ,13,63},{25 ,14,182},{36 ,15,51},{14 ,16,127},{17 ,17,1},{15 ,18,75},{39 ,19,0},{16 ,20,51},{14 ,21,229},{16 ,22,154},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{7 ,0,220},{9 ,1,182},{0 ,0,-1},{20 ,3,186},{28 ,4,165},{0 ,0,-1},{45 ,6,151},{25 ,7,116},{40 ,8,137},{0 ,0,-1},{19 ,10,224},{20 ,11,47},{18 ,12,233},{18 ,13,8},{29 ,14,236},{0 ,0,-1},{17 ,16,59},{22 ,17,158},{18 ,18,155},{0 ,0,-1},{21 ,20,131},{17 ,21,144},{20 ,22,160},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{8 ,0,112},{10 ,1,98},{0 ,0,-1},{24 ,3,86},{42 ,4,157},{0 ,0,-1},{0 ,0,-1},{31 ,7,177},{0 ,0,-1},{0 ,0,-1},{23 ,10,170},{24 ,11,116},{22 ,12,142},{22 ,13,188},{32 ,14,199},{0 ,0,-1},{21 ,16,109},{34 ,17,159},{23 ,18,152},{0 ,0,-1},{0 ,0,-1},{21 ,21,171},{24 ,22,222},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{9 ,0,103},{11 ,1,41},{0 ,0,-1},{39 ,3,139},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{34 ,7,167},{0 ,0,-1},{0 ,0,-1},{30 ,10,73},{33 ,11,41},{32 ,12,112},{30 ,13,120},{36 ,14,105},{0 ,0,-1},{43 ,16,163},{40 ,17,149},{29 ,18,84},{0 ,0,-1},{0 ,0,-1},{28 ,21,63},{31 ,22,172},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{11 ,0,77},{12 ,1,42},{0 ,0,-1},{41 ,3,173},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{39 ,7,149},{0 ,0,-1},{0 ,0,-1},{38 ,10,157},{0 ,0,-1},{35 ,12,207},{37 ,13,220},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{36 ,18,120},{0 ,0,-1},{0 ,0,-1},{33 ,21,211},{35 ,22,103},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{12 ,0,160},{15 ,1,96},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,7,157},{0 ,0,-1},{0 ,0,-1},{45 ,10,167},{0 ,0,-1},{38 ,12,163},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{41 ,18,151},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,22,173},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{13 ,0,177},{16 ,1,64},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{43 ,18,173},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{14 ,0,206},{18 ,1,42},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{15 ,0,40},{19 ,1,73},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{17 ,0,7},{21 ,1,249},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{19 ,0,60},{23 ,1,156},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{20 ,0,151},{25 ,1,23},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{22 ,0,64},{27 ,1,25},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{24 ,0,112},{29 ,1,86},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{26 ,0,195},{31 ,1,95},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{28 ,0,128},{33 ,1,2},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{30 ,0,216},{35 ,1,161},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{32 ,0,221},{37 ,1,198},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{34 ,0,127},{39 ,1,173},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{36 ,0,37},{41 ,1,167},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{38 ,0,167},{43 ,1,151},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{40 ,0,157},{45 ,1,149},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{42 ,0,149},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{44 ,0,139},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1}
+};
+
+//--------------------------------------------------BG1_I0-----------------------------------------------------------------
+
+
+//--------------------------------------------------BG1_I1-----------------------------------------------------------------
+
+h_element host_h_compact1_I1 [46*19] =
+{{0 ,0,307},{1 ,0,76},{2 ,0,205},{3 ,0,276},{4 ,0,332},{5 ,0,195},{6 ,0,278},{7 ,0,9},{8 ,0,307},{9 ,0,366},{10 ,1,101},{11 ,0,48},{12 ,0,77},{13 ,0,313},{14 ,0,142},{15 ,0,241},{16 ,1,13},{17 ,0,260},{18 ,1,130},{19 ,0,145},{20 ,0,187},{21 ,1,205},{22 ,0,30},{23 ,1,24},{24 ,0,298},{25 ,1,72},{26 ,0,71},{27 ,1,194},{28 ,0,222},{29 ,1,252},{30 ,0,159},{31 ,1,100},{32 ,0,102},{33 ,1,323},{34 ,0,230},{35 ,1,320},{36 ,0,210},{37 ,1,269},{38 ,0,185},{39 ,1,258},{40 ,0,175},{41 ,1,52},{42 ,0,113},{43 ,1,113},{44 ,0,80},{45 ,1,135},
+{0 ,1,19},{1 ,2,76},{2 ,1,250},{3 ,1,87},{4 ,1,181},{5 ,1,14},{6 ,6,257},{7 ,1,62},{8 ,1,179},{9 ,1,232},{10 ,2,339},{11 ,1,102},{12 ,1,186},{13 ,3,177},{14 ,12,248},{15 ,1,2},{16 ,3,338},{17 ,14,303},{18 ,12,163},{19 ,1,213},{20 ,3,206},{21 ,5,102},{22 ,12,11},{23 ,2,89},{24 ,3,158},{25 ,6,17},{26 ,2,81},{27 ,6,194},{28 ,4,19},{29 ,14,5},{30 ,10,229},{31 ,7,215},{32 ,12,201},{33 ,2,8},{34 ,7,148},{35 ,6,335},{36 ,14,313},{37 ,13,82},{38 ,9,177},{39 ,3,93},{40 ,8,37},{41 ,3,314},{42 ,4,14},{43 ,16,132},{44 ,7,78},{45 ,6,149},
+{0 ,2,50},{1 ,3,73},{2 ,2,328},{3 ,3,0},{4 ,26,0},{5 ,3,115},{6 ,10,1},{7 ,4,316},{8 ,3,165},{9 ,10,321},{10 ,4,274},{11 ,12,8},{12 ,10,174},{13 ,7,266},{14 ,15,137},{15 ,10,210},{16 ,11,57},{17 ,16,81},{18 ,13,280},{19 ,7,344},{20 ,9,264},{21 ,16,328},{22 ,13,233},{23 ,10,61},{24 ,4,235},{25 ,7,383},{26 ,4,76},{27 ,8,101},{28 ,19,244},{29 ,18,147},{30 ,13,260},{31 ,22,258},{32 ,14,175},{33 ,11,361},{34 ,15,202},{35 ,12,2},{36 ,15,297},{37 ,23,115},{38 ,10,289},{39 ,7,346},{40 ,17,312},{41 ,9,139},{42 ,24,218},{43 ,18,114},{44 ,9,163},{45 ,10,15},
+{0 ,3,369},{1 ,4,288},{2 ,4,332},{3 ,4,275},{0 ,0,-1},{5 ,12,166},{6 ,11,351},{7 ,7,333},{8 ,12,18},{9 ,11,133},{10 ,7,111},{11 ,16,47},{12 ,11,232},{13 ,20,115},{14 ,16,89},{15 ,13,318},{16 ,20,289},{17 ,17,358},{18 ,18,132},{19 ,8,242},{20 ,11,341},{21 ,20,213},{22 ,17,22},{23 ,18,27},{24 ,11,339},{25 ,14,312},{26 ,15,136},{27 ,49,0},{28 ,21,274},{29 ,25,78},{30 ,24,90},{31 ,25,256},{32 ,24,287},{33 ,21,105},{34 ,17,312},{35 ,22,266},{36 ,18,21},{37 ,59,0},{38 ,12,214},{39 ,19,297},{40 ,62,0},{41 ,18,288},{42 ,64,0},{43 ,25,168},{44 ,22,274},{45 ,67,0},
+{0 ,5,181},{1 ,5,144},{2 ,5,256},{3 ,6,199},{0 ,0,-1},{5 ,16,241},{6 ,13,92},{7 ,8,290},{8 ,16,39},{9 ,13,57},{10 ,8,383},{11 ,21,188},{12 ,13,50},{13 ,23,370},{14 ,17,347},{15 ,18,55},{16 ,22,57},{17 ,21,375},{18 ,19,4},{19 ,10,197},{20 ,22,59},{21 ,21,97},{22 ,44,0},{23 ,45,0},{24 ,22,234},{25 ,47,0},{26 ,48,0},{0 ,0,-1},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{0 ,0,-1},{38 ,60,0},{39 ,61,0},{0 ,0,-1},{41 ,63,0},{0 ,0,-1},{43 ,65,0},{44 ,66,0},{0 ,0,-1},
+{0 ,6,216},{1 ,7,331},{2 ,6,161},{3 ,7,153},{0 ,0,-1},{5 ,21,51},{6 ,17,253},{7 ,14,114},{8 ,19,224},{9 ,17,303},{10 ,14,354},{11 ,22,334},{12 ,18,74},{13 ,35,0},{14 ,21,12},{15 ,25,269},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{0 ,0,-1},{0 ,0,-1},{24 ,46,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,9,317},{1 ,8,331},{2 ,7,267},{3 ,8,56},{0 ,0,-1},{5 ,22,157},{6 ,18,18},{7 ,29,0},{8 ,21,368},{9 ,18,63},{10 ,32,0},{11 ,23,115},{12 ,34,0},{0 ,0,-1},{14 ,36,0},{15 ,37,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,10,288},{1 ,9,178},{2 ,8,160},{3 ,10,132},{0 ,0,-1},{5 ,27,0},{6 ,20,225},{0 ,0,-1},{8 ,22,67},{9 ,20,82},{0 ,0,-1},{11 ,33,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,11,109},{1 ,11,295},{2 ,9,63},{3 ,11,305},{0 ,0,-1},{0 ,0,-1},{6 ,28,0},{0 ,0,-1},{8 ,24,170},{9 ,31,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,12,17},{1 ,12,342},{2 ,10,129},{3 ,12,231},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{8 ,30,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,13,357},{1 ,14,217},{2 ,13,200},{3 ,13,341},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,15,215},{1 ,15,99},{2 ,14,88},{3 ,14,212},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,16,106},{1 ,16,354},{2 ,15,53},{3 ,16,304},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,18,242},{1 ,17,114},{2 ,17,131},{3 ,17,300},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,19,180},{1 ,19,331},{2 ,18,240},{3 ,18,271},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,20,330},{1 ,21,112},{2 ,19,205},{3 ,20,39},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,21,346},{1 ,22,0},{2 ,20,13},{3 ,21,357},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,22,1},{1 ,23,0},{2 ,24,0},{3 ,22,1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,23,0},{1 ,24,0},{2 ,25,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1}
+};
+
+
+h_element host_h_compact2_I1 [68*30] =
+{{0 ,0,307},{0 ,1,19},{0 ,2,50},{0 ,3,369},{1 ,4,288},{0 ,5,181},{0 ,6,216},{1 ,7,331},{1 ,8,331},{0 ,9,317},{0 ,10,288},{0 ,11,109},{0 ,12,17},{0 ,13,357},{1 ,14,217},{0 ,15,215},{0 ,16,106},{1 ,17,114},{0 ,18,242},{0 ,19,180},{0 ,20,330},{0 ,21,346},{0 ,22,1},{0 ,23,0},{1 ,24,0},{2 ,25,0},{4 ,26,0},{5 ,27,0},{6 ,28,0},{7 ,29,0},{8 ,30,0},{9 ,31,0},{10 ,32,0},{11 ,33,0},{12 ,34,0},{13 ,35,0},{14 ,36,0},{15 ,37,0},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{22 ,44,0},{23 ,45,0},{24 ,46,0},{25 ,47,0},{26 ,48,0},{27 ,49,0},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{37 ,59,0},{38 ,60,0},{39 ,61,0},{40 ,62,0},{41 ,63,0},{42 ,64,0},{43 ,65,0},{44 ,66,0},{45 ,67,0},
+{1 ,0,76},{2 ,1,250},{1 ,2,76},{1 ,3,73},{2 ,4,332},{1 ,5,144},{2 ,6,161},{2 ,7,267},{2 ,8,160},{1 ,9,178},{2 ,10,129},{1 ,11,295},{1 ,12,342},{2 ,13,200},{2 ,14,88},{1 ,15,99},{1 ,16,354},{2 ,17,131},{2 ,18,240},{1 ,19,331},{2 ,20,13},{1 ,21,112},{1 ,22,0},{1 ,23,0},{2 ,24,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{2 ,0,205},{3 ,1,87},{2 ,2,328},{3 ,3,0},{3 ,4,275},{2 ,5,256},{3 ,6,199},{3 ,7,153},{3 ,8,56},{2 ,9,63},{3 ,10,132},{3 ,11,305},{3 ,12,231},{3 ,13,341},{3 ,14,212},{2 ,15,53},{3 ,16,304},{3 ,17,300},{3 ,18,271},{2 ,19,205},{3 ,20,39},{3 ,21,357},{3 ,22,1},{11 ,23,115},{8 ,24,170},{15 ,25,269},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{3 ,0,276},{4 ,1,181},{10 ,2,339},{5 ,3,115},{7 ,4,316},{21 ,5,102},{6 ,6,257},{7 ,7,333},{7 ,8,290},{20 ,9,264},{6 ,10,1},{6 ,11,351},{5 ,12,166},{6 ,13,92},{7 ,14,114},{14 ,15,137},{5 ,16,241},{6 ,17,253},{6 ,18,18},{8 ,19,224},{6 ,20,225},{5 ,21,51},{5 ,22,157},{13 ,23,370},{30 ,24,90},{29 ,25,78},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{4 ,0,332},{5 ,1,14},{23 ,2,89},{8 ,3,165},{10 ,4,274},{0 ,0,-1},{25 ,6,17},{10 ,7,111},{10 ,8,383},{38 ,9,177},{9 ,10,321},{9 ,11,133},{8 ,12,18},{9 ,13,57},{10 ,14,354},{26 ,15,136},{8 ,16,39},{9 ,17,303},{9 ,18,63},{18 ,19,4},{9 ,20,82},{8 ,21,368},{8 ,22,67},{37 ,23,115},{32 ,24,287},{31 ,25,256},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{5 ,0,195},{7 ,1,62},{26 ,2,81},{13 ,3,177},{24 ,4,235},{0 ,0,-1},{27 ,6,194},{13 ,7,266},{19 ,8,242},{41 ,9,139},{12 ,10,174},{12 ,11,232},{11 ,12,8},{12 ,13,50},{17 ,14,303},{34 ,15,202},{11 ,16,47},{14 ,17,347},{12 ,18,74},{28 ,19,244},{13 ,20,115},{11 ,21,188},{11 ,22,334},{0 ,0,-1},{42 ,24,218},{43 ,25,168},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{6 ,0,278},{8 ,1,179},{33 ,2,8},{16 ,3,338},{26 ,4,76},{0 ,0,-1},{35 ,6,335},{19 ,7,344},{27 ,8,101},{44 ,9,163},{15 ,10,210},{16 ,11,57},{14 ,12,248},{15 ,13,318},{25 ,14,312},{36 ,15,297},{14 ,16,89},{17 ,17,358},{15 ,18,55},{39 ,19,297},{16 ,20,289},{14 ,21,12},{16 ,22,57},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{7 ,0,9},{9 ,1,232},{0 ,0,-1},{20 ,3,206},{28 ,4,19},{0 ,0,-1},{45 ,6,149},{25 ,7,383},{40 ,8,37},{0 ,0,-1},{19 ,10,197},{20 ,11,341},{18 ,12,163},{18 ,13,280},{29 ,14,5},{0 ,0,-1},{17 ,16,81},{22 ,17,22},{18 ,18,132},{0 ,0,-1},{21 ,20,213},{17 ,21,375},{20 ,22,59},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{8 ,0,307},{10 ,1,101},{0 ,0,-1},{24 ,3,158},{42 ,4,14},{0 ,0,-1},{0 ,0,-1},{31 ,7,215},{0 ,0,-1},{0 ,0,-1},{23 ,10,61},{24 ,11,339},{22 ,12,11},{22 ,13,233},{32 ,14,175},{0 ,0,-1},{21 ,16,328},{34 ,17,312},{23 ,18,27},{0 ,0,-1},{0 ,0,-1},{21 ,21,97},{24 ,22,234},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{9 ,0,366},{11 ,1,102},{0 ,0,-1},{39 ,3,93},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{34 ,7,148},{0 ,0,-1},{0 ,0,-1},{30 ,10,229},{33 ,11,361},{32 ,12,201},{30 ,13,260},{36 ,14,313},{0 ,0,-1},{43 ,16,132},{40 ,17,312},{29 ,18,147},{0 ,0,-1},{0 ,0,-1},{28 ,21,274},{31 ,22,258},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{11 ,0,48},{12 ,1,186},{0 ,0,-1},{41 ,3,314},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{39 ,7,346},{0 ,0,-1},{0 ,0,-1},{38 ,10,289},{0 ,0,-1},{35 ,12,2},{37 ,13,82},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{36 ,18,21},{0 ,0,-1},{0 ,0,-1},{33 ,21,105},{35 ,22,266},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{12 ,0,77},{15 ,1,2},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,7,78},{0 ,0,-1},{0 ,0,-1},{45 ,10,15},{0 ,0,-1},{38 ,12,214},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{41 ,18,288},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,22,274},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{13 ,0,313},{16 ,1,13},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{43 ,18,114},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{14 ,0,142},{18 ,1,130},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{15 ,0,241},{19 ,1,213},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{17 ,0,260},{21 ,1,205},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{19 ,0,145},{23 ,1,24},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{20 ,0,187},{25 ,1,72},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{22 ,0,30},{27 ,1,194},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{24 ,0,298},{29 ,1,252},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{26 ,0,71},{31 ,1,100},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{28 ,0,222},{33 ,1,323},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{30 ,0,159},{35 ,1,320},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{32 ,0,102},{37 ,1,269},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{34 ,0,230},{39 ,1,258},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{36 ,0,210},{41 ,1,52},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{38 ,0,185},{43 ,1,113},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{40 ,0,175},{45 ,1,135},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{42 ,0,113},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{44 ,0,80},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1}
+};
+
+//--------------------------------------------------BG1_I1-----------------------------------------------------------------
+
+//--------------------------------------------------BG1_I2-----------------------------------------------------------------
+
+h_element host_h_compact1_I2 [46*19] =
+{{0 ,0,73},{1 ,0,303},{2 ,0,68},{3 ,0,220},{4 ,0,233},{5 ,0,83},{6 ,0,289},{7 ,0,12},{8 ,0,295},{9 ,0,189},{10 ,1,14},{11 ,0,16},{12 ,0,229},{13 ,0,39},{14 ,0,78},{15 ,0,229},{16 ,1,69},{17 ,0,257},{18 ,1,260},{19 ,0,64},{20 ,0,301},{21 ,1,79},{22 ,0,177},{23 ,1,249},{24 ,0,289},{25 ,1,172},{26 ,0,270},{27 ,1,210},{28 ,0,11},{29 ,1,27},{30 ,0,91},{31 ,1,222},{32 ,0,210},{33 ,1,170},{34 ,0,187},{35 ,1,207},{36 ,0,259},{37 ,1,298},{38 ,0,151},{39 ,1,102},{40 ,0,32},{41 ,1,154},{42 ,0,226},{43 ,1,228},{44 ,0,234},{45 ,1,101},
+{0 ,1,15},{1 ,2,294},{2 ,1,7},{3 ,1,208},{4 ,1,205},{5 ,1,292},{6 ,6,21},{7 ,1,88},{8 ,1,133},{9 ,1,244},{10 ,2,80},{11 ,1,147},{12 ,1,235},{13 ,3,302},{14 ,12,299},{15 ,1,290},{16 ,3,140},{17 ,14,147},{18 ,12,294},{19 ,1,181},{20 ,3,162},{21 ,5,175},{22 ,12,20},{23 ,2,50},{24 ,3,280},{25 ,6,295},{26 ,2,110},{27 ,6,29},{28 ,4,293},{29 ,14,308},{30 ,10,23},{31 ,7,308},{32 ,12,22},{33 ,2,20},{34 ,7,296},{35 ,6,158},{36 ,14,179},{37 ,13,15},{38 ,9,179},{39 ,3,77},{40 ,8,80},{41 ,3,47},{42 ,4,65},{43 ,16,69},{44 ,7,227},{45 ,6,228},
+{0 ,2,103},{1 ,3,27},{2 ,2,80},{3 ,3,30},{4 ,26,0},{5 ,3,50},{6 ,10,293},{7 ,4,207},{8 ,3,130},{9 ,10,36},{10 ,4,211},{11 ,12,290},{12 ,10,169},{13 ,7,303},{14 ,15,54},{15 ,10,60},{16 ,11,45},{17 ,16,128},{18 ,13,291},{19 ,7,101},{20 ,9,40},{21 ,16,132},{22 ,13,55},{23 ,10,133},{24 ,4,110},{25 ,7,96},{26 ,4,318},{27 ,8,304},{28 ,19,50},{29 ,18,117},{30 ,13,105},{31 ,22,66},{32 ,14,271},{33 ,11,140},{34 ,15,5},{35 ,12,55},{36 ,15,178},{37 ,23,115},{38 ,10,64},{39 ,7,192},{40 ,17,197},{41 ,9,124},{42 ,24,126},{43 ,18,176},{44 ,9,259},{45 ,10,126},
+{0 ,3,49},{1 ,4,261},{2 ,4,280},{3 ,4,197},{0 ,0,-1},{5 ,12,318},{6 ,11,13},{7 ,7,50},{8 ,12,231},{9 ,11,286},{10 ,7,75},{11 ,16,289},{12 ,11,48},{13 ,20,160},{14 ,16,61},{15 ,13,130},{16 ,20,115},{17 ,17,51},{18 ,18,141},{19 ,8,270},{20 ,11,130},{21 ,20,283},{22 ,17,316},{23 ,18,105},{24 ,11,187},{25 ,14,46},{26 ,15,67},{27 ,49,0},{28 ,21,234},{29 ,25,29},{30 ,24,135},{31 ,25,162},{32 ,24,217},{33 ,21,33},{34 ,17,44},{35 ,22,285},{36 ,18,160},{37 ,59,0},{38 ,12,181},{39 ,19,208},{40 ,62,0},{41 ,18,207},{42 ,64,0},{43 ,25,102},{44 ,22,260},{45 ,67,0},
+{0 ,5,240},{1 ,5,161},{2 ,5,38},{3 ,6,61},{0 ,0,-1},{5 ,16,201},{6 ,13,232},{7 ,8,25},{8 ,16,296},{9 ,13,151},{10 ,8,161},{11 ,21,177},{12 ,13,105},{13 ,23,37},{14 ,17,179},{15 ,18,184},{16 ,22,300},{17 ,21,228},{18 ,19,295},{19 ,10,41},{20 ,22,10},{21 ,21,103},{22 ,44,0},{23 ,45,0},{24 ,22,281},{25 ,47,0},{26 ,48,0},{0 ,0,-1},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{0 ,0,-1},{38 ,60,0},{39 ,61,0},{0 ,0,-1},{41 ,63,0},{0 ,0,-1},{43 ,65,0},{44 ,66,0},{0 ,0,-1},
+{0 ,6,39},{1 ,7,133},{2 ,6,227},{3 ,7,175},{0 ,0,-1},{5 ,21,267},{6 ,17,302},{7 ,14,76},{8 ,19,110},{9 ,17,267},{10 ,14,311},{11 ,22,43},{12 ,18,52},{13 ,35,0},{14 ,21,258},{15 ,25,51},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{0 ,0,-1},{0 ,0,-1},{24 ,46,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,9,15},{1 ,8,4},{2 ,7,202},{3 ,8,79},{0 ,0,-1},{5 ,22,279},{6 ,18,138},{7 ,29,0},{8 ,21,269},{9 ,18,135},{10 ,32,0},{11 ,23,280},{12 ,34,0},{0 ,0,-1},{14 ,36,0},{15 ,37,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,10,162},{1 ,9,80},{2 ,8,200},{3 ,10,281},{0 ,0,-1},{5 ,27,0},{6 ,20,235},{0 ,0,-1},{8 ,22,245},{9 ,20,209},{0 ,0,-1},{11 ,33,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,11,215},{1 ,11,129},{2 ,9,71},{3 ,11,303},{0 ,0,-1},{0 ,0,-1},{6 ,28,0},{0 ,0,-1},{8 ,24,154},{9 ,31,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,12,164},{1 ,12,300},{2 ,10,106},{3 ,12,253},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{8 ,30,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,13,133},{1 ,14,76},{2 ,13,295},{3 ,13,164},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,15,298},{1 ,15,266},{2 ,14,283},{3 ,14,53},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,16,110},{1 ,16,72},{2 ,15,301},{3 ,16,44},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,18,113},{1 ,17,83},{2 ,17,184},{3 ,17,28},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,19,16},{1 ,19,260},{2 ,18,246},{3 ,18,77},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,20,189},{1 ,21,301},{2 ,19,230},{3 ,20,319},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,21,32},{1 ,22,0},{2 ,20,276},{3 ,21,68},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,22,1},{1 ,23,0},{2 ,24,0},{3 ,22,1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,23,0},{1 ,24,0},{2 ,25,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1}
+};
+
+
+h_element host_h_compact2_I2 [68*30] =
+{{0 ,0,73},{0 ,1,15},{0 ,2,103},{0 ,3,49},{1 ,4,261},{0 ,5,240},{0 ,6,39},{1 ,7,133},{1 ,8,4},{0 ,9,15},{0 ,10,162},{0 ,11,215},{0 ,12,164},{0 ,13,133},{1 ,14,76},{0 ,15,298},{0 ,16,110},{1 ,17,83},{0 ,18,113},{0 ,19,16},{0 ,20,189},{0 ,21,32},{0 ,22,1},{0 ,23,0},{1 ,24,0},{2 ,25,0},{4 ,26,0},{5 ,27,0},{6 ,28,0},{7 ,29,0},{8 ,30,0},{9 ,31,0},{10 ,32,0},{11 ,33,0},{12 ,34,0},{13 ,35,0},{14 ,36,0},{15 ,37,0},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{22 ,44,0},{23 ,45,0},{24 ,46,0},{25 ,47,0},{26 ,48,0},{27 ,49,0},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{37 ,59,0},{38 ,60,0},{39 ,61,0},{40 ,62,0},{41 ,63,0},{42 ,64,0},{43 ,65,0},{44 ,66,0},{45 ,67,0},
+{1 ,0,303},{2 ,1,7},{1 ,2,294},{1 ,3,27},{2 ,4,280},{1 ,5,161},{2 ,6,227},{2 ,7,202},{2 ,8,200},{1 ,9,80},{2 ,10,106},{1 ,11,129},{1 ,12,300},{2 ,13,295},{2 ,14,283},{1 ,15,266},{1 ,16,72},{2 ,17,184},{2 ,18,246},{1 ,19,260},{2 ,20,276},{1 ,21,301},{1 ,22,0},{1 ,23,0},{2 ,24,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{2 ,0,68},{3 ,1,208},{2 ,2,80},{3 ,3,30},{3 ,4,197},{2 ,5,38},{3 ,6,61},{3 ,7,175},{3 ,8,79},{2 ,9,71},{3 ,10,281},{3 ,11,303},{3 ,12,253},{3 ,13,164},{3 ,14,53},{2 ,15,301},{3 ,16,44},{3 ,17,28},{3 ,18,77},{2 ,19,230},{3 ,20,319},{3 ,21,68},{3 ,22,1},{11 ,23,280},{8 ,24,154},{15 ,25,51},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{3 ,0,220},{4 ,1,205},{10 ,2,80},{5 ,3,50},{7 ,4,207},{21 ,5,175},{6 ,6,21},{7 ,7,50},{7 ,8,25},{20 ,9,40},{6 ,10,293},{6 ,11,13},{5 ,12,318},{6 ,13,232},{7 ,14,76},{14 ,15,54},{5 ,16,201},{6 ,17,302},{6 ,18,138},{8 ,19,110},{6 ,20,235},{5 ,21,267},{5 ,22,279},{13 ,23,37},{30 ,24,135},{29 ,25,29},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{4 ,0,233},{5 ,1,292},{23 ,2,50},{8 ,3,130},{10 ,4,211},{0 ,0,-1},{25 ,6,295},{10 ,7,75},{10 ,8,161},{38 ,9,179},{9 ,10,36},{9 ,11,286},{8 ,12,231},{9 ,13,151},{10 ,14,311},{26 ,15,67},{8 ,16,296},{9 ,17,267},{9 ,18,135},{18 ,19,295},{9 ,20,209},{8 ,21,269},{8 ,22,245},{37 ,23,115},{32 ,24,217},{31 ,25,162},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{5 ,0,83},{7 ,1,88},{26 ,2,110},{13 ,3,302},{24 ,4,110},{0 ,0,-1},{27 ,6,29},{13 ,7,303},{19 ,8,270},{41 ,9,124},{12 ,10,169},{12 ,11,48},{11 ,12,290},{12 ,13,105},{17 ,14,147},{34 ,15,5},{11 ,16,289},{14 ,17,179},{12 ,18,52},{28 ,19,50},{13 ,20,160},{11 ,21,177},{11 ,22,43},{0 ,0,-1},{42 ,24,126},{43 ,25,102},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{6 ,0,289},{8 ,1,133},{33 ,2,20},{16 ,3,140},{26 ,4,318},{0 ,0,-1},{35 ,6,158},{19 ,7,101},{27 ,8,304},{44 ,9,259},{15 ,10,60},{16 ,11,45},{14 ,12,299},{15 ,13,130},{25 ,14,46},{36 ,15,178},{14 ,16,61},{17 ,17,51},{15 ,18,184},{39 ,19,208},{16 ,20,115},{14 ,21,258},{16 ,22,300},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{7 ,0,12},{9 ,1,244},{0 ,0,-1},{20 ,3,162},{28 ,4,293},{0 ,0,-1},{45 ,6,228},{25 ,7,96},{40 ,8,80},{0 ,0,-1},{19 ,10,41},{20 ,11,130},{18 ,12,294},{18 ,13,291},{29 ,14,308},{0 ,0,-1},{17 ,16,128},{22 ,17,316},{18 ,18,141},{0 ,0,-1},{21 ,20,283},{17 ,21,228},{20 ,22,10},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{8 ,0,295},{10 ,1,14},{0 ,0,-1},{24 ,3,280},{42 ,4,65},{0 ,0,-1},{0 ,0,-1},{31 ,7,308},{0 ,0,-1},{0 ,0,-1},{23 ,10,133},{24 ,11,187},{22 ,12,20},{22 ,13,55},{32 ,14,271},{0 ,0,-1},{21 ,16,132},{34 ,17,44},{23 ,18,105},{0 ,0,-1},{0 ,0,-1},{21 ,21,103},{24 ,22,281},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{9 ,0,189},{11 ,1,147},{0 ,0,-1},{39 ,3,77},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{34 ,7,296},{0 ,0,-1},{0 ,0,-1},{30 ,10,23},{33 ,11,140},{32 ,12,22},{30 ,13,105},{36 ,14,179},{0 ,0,-1},{43 ,16,69},{40 ,17,197},{29 ,18,117},{0 ,0,-1},{0 ,0,-1},{28 ,21,234},{31 ,22,66},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{11 ,0,16},{12 ,1,235},{0 ,0,-1},{41 ,3,47},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{39 ,7,192},{0 ,0,-1},{0 ,0,-1},{38 ,10,64},{0 ,0,-1},{35 ,12,55},{37 ,13,15},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{36 ,18,160},{0 ,0,-1},{0 ,0,-1},{33 ,21,33},{35 ,22,285},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{12 ,0,229},{15 ,1,290},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,7,227},{0 ,0,-1},{0 ,0,-1},{45 ,10,126},{0 ,0,-1},{38 ,12,181},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{41 ,18,207},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,22,260},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{13 ,0,39},{16 ,1,69},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{43 ,18,176},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{14 ,0,78},{18 ,1,260},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{15 ,0,229},{19 ,1,181},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{17 ,0,257},{21 ,1,79},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{19 ,0,64},{23 ,1,249},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{20 ,0,301},{25 ,1,172},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{22 ,0,177},{27 ,1,210},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{24 ,0,289},{29 ,1,27},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{26 ,0,270},{31 ,1,222},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{28 ,0,11},{33 ,1,170},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{30 ,0,91},{35 ,1,207},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{32 ,0,210},{37 ,1,298},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{34 ,0,187},{39 ,1,102},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{36 ,0,259},{41 ,1,154},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{38 ,0,151},{43 ,1,228},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{40 ,0,32},{45 ,1,101},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{42 ,0,226},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{44 ,0,234},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1}
+};
+
+//--------------------------------------------------BG1_I2-----------------------------------------------------------------
+
+
+//--------------------------------------------------BG1_I3-----------------------------------------------------------------
+
+h_element host_h_compact1_I3 [46*19] =
+{{0 ,0,223},{1 ,0,141},{2 ,0,207},{3 ,0,201},{4 ,0,170},{5 ,0,164},{6 ,0,158},{7 ,0,17},{8 ,0,33},{9 ,0,9},{10 ,1,82},{11 ,0,52},{12 ,0,142},{13 ,0,81},{14 ,0,14},{15 ,0,90},{16 ,1,154},{17 ,0,56},{18 ,1,199},{19 ,0,8},{20 ,0,105},{21 ,1,192},{22 ,0,53},{23 ,1,88},{24 ,0,49},{25 ,1,1},{26 ,0,107},{27 ,1,208},{28 ,0,146},{29 ,1,150},{30 ,0,34},{31 ,1,175},{32 ,0,192},{33 ,1,114},{34 ,0,82},{35 ,1,192},{36 ,0,222},{37 ,1,81},{38 ,0,123},{39 ,1,12},{40 ,0,67},{41 ,1,23},{42 ,0,114},{43 ,1,206},{44 ,0,84},{45 ,1,184},
+{0 ,1,16},{1 ,2,45},{2 ,1,203},{3 ,1,18},{4 ,1,10},{5 ,1,59},{6 ,6,119},{7 ,1,76},{8 ,1,95},{9 ,1,37},{10 ,2,165},{11 ,1,11},{12 ,1,175},{13 ,3,56},{14 ,12,175},{15 ,1,120},{16 ,3,164},{17 ,14,110},{18 ,12,110},{19 ,1,6},{20 ,3,210},{21 ,5,131},{22 ,12,0},{23 ,2,203},{24 ,3,157},{25 ,6,166},{26 ,2,176},{27 ,6,141},{28 ,4,153},{29 ,14,11},{30 ,10,130},{31 ,7,49},{32 ,12,209},{33 ,2,49},{34 ,7,186},{35 ,6,173},{36 ,14,157},{37 ,13,195},{38 ,9,90},{39 ,3,77},{40 ,8,45},{41 ,3,215},{42 ,4,91},{43 ,16,22},{44 ,7,4},{45 ,6,121},
+{0 ,2,94},{1 ,3,151},{2 ,2,31},{3 ,3,165},{4 ,26,0},{5 ,3,86},{6 ,10,113},{7 ,4,104},{8 ,3,4},{9 ,10,213},{10 ,4,174},{11 ,12,2},{12 ,10,136},{13 ,7,72},{14 ,15,211},{15 ,10,131},{16 ,11,43},{17 ,16,200},{18 ,13,200},{19 ,7,103},{20 ,9,121},{21 ,16,220},{22 ,13,3},{23 ,10,168},{24 ,4,64},{25 ,7,65},{26 ,4,212},{27 ,8,174},{28 ,19,217},{29 ,18,53},{30 ,13,210},{31 ,22,177},{32 ,14,58},{33 ,11,161},{34 ,15,68},{35 ,12,26},{36 ,15,0},{37 ,23,138},{38 ,10,73},{39 ,7,49},{40 ,17,96},{41 ,9,60},{42 ,24,78},{43 ,18,134},{44 ,9,9},{45 ,10,29},
+{0 ,3,91},{1 ,4,46},{2 ,4,176},{3 ,4,5},{0 ,0,-1},{5 ,12,80},{6 ,11,21},{7 ,7,100},{8 ,12,217},{9 ,11,105},{10 ,7,19},{11 ,16,35},{12 ,11,3},{13 ,20,217},{14 ,16,191},{15 ,13,209},{16 ,20,189},{17 ,17,63},{18 ,18,143},{19 ,8,198},{20 ,11,214},{21 ,20,50},{22 ,17,148},{23 ,18,122},{24 ,11,193},{25 ,14,81},{26 ,15,127},{27 ,49,0},{28 ,21,114},{29 ,25,68},{30 ,24,123},{31 ,25,128},{32 ,24,30},{33 ,21,137},{34 ,17,150},{35 ,22,187},{36 ,18,6},{37 ,59,0},{38 ,12,10},{39 ,19,114},{40 ,62,0},{41 ,18,167},{42 ,64,0},{43 ,25,161},{44 ,22,12},{45 ,67,0},
+{0 ,5,74},{1 ,5,119},{2 ,5,180},{3 ,6,45},{0 ,0,-1},{5 ,16,182},{6 ,13,63},{7 ,8,150},{8 ,16,204},{9 ,13,89},{10 ,8,194},{11 ,21,32},{12 ,13,28},{13 ,23,78},{14 ,17,51},{15 ,18,209},{16 ,22,101},{17 ,21,4},{18 ,19,186},{19 ,10,8},{20 ,22,183},{21 ,21,106},{22 ,44,0},{23 ,45,0},{24 ,22,124},{25 ,47,0},{26 ,48,0},{0 ,0,-1},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{0 ,0,-1},{38 ,60,0},{39 ,61,0},{0 ,0,-1},{41 ,63,0},{0 ,0,-1},{43 ,65,0},{44 ,66,0},{0 ,0,-1},
+{0 ,6,10},{1 ,7,157},{2 ,6,186},{3 ,7,142},{0 ,0,-1},{5 ,21,130},{6 ,17,51},{7 ,14,158},{8 ,19,39},{9 ,17,185},{10 ,14,103},{11 ,22,84},{12 ,18,182},{13 ,35,0},{14 ,21,43},{15 ,25,81},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{0 ,0,-1},{0 ,0,-1},{24 ,46,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,9,0},{1 ,8,133},{2 ,7,95},{3 ,8,16},{0 ,0,-1},{5 ,22,153},{6 ,18,136},{7 ,29,0},{8 ,21,58},{9 ,18,109},{10 ,32,0},{11 ,23,201},{12 ,34,0},{0 ,0,-1},{14 ,36,0},{15 ,37,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,10,205},{1 ,9,87},{2 ,8,153},{3 ,10,34},{0 ,0,-1},{5 ,27,0},{6 ,20,116},{0 ,0,-1},{8 ,22,44},{9 ,20,218},{0 ,0,-1},{11 ,33,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,11,216},{1 ,11,206},{2 ,9,177},{3 ,11,155},{0 ,0,-1},{0 ,0,-1},{6 ,28,0},{0 ,0,-1},{8 ,24,201},{9 ,31,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,12,21},{1 ,12,93},{2 ,10,70},{3 ,12,213},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{8 ,30,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,13,215},{1 ,14,79},{2 ,13,77},{3 ,13,147},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,15,14},{1 ,15,9},{2 ,14,214},{3 ,14,69},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,16,70},{1 ,16,118},{2 ,15,77},{3 ,16,96},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,18,141},{1 ,17,194},{2 ,17,198},{3 ,17,74},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,19,198},{1 ,19,31},{2 ,18,117},{3 ,18,99},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,20,104},{1 ,21,187},{2 ,19,223},{3 ,20,30},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,21,81},{1 ,22,0},{2 ,20,90},{3 ,21,158},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,22,1},{1 ,23,0},{2 ,24,0},{3 ,22,1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,23,0},{1 ,24,0},{2 ,25,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+};
+
+h_element host_h_compact2_I3 [68*30] =
+{{0 ,0,223},{0 ,1,16},{0 ,2,94},{0 ,3,91},{1 ,4,46},{0 ,5,74},{0 ,6,10},{1 ,7,157},{1 ,8,133},{0 ,9,0},{0 ,10,205},{0 ,11,216},{0 ,12,21},{0 ,13,215},{1 ,14,79},{0 ,15,14},{0 ,16,70},{1 ,17,194},{0 ,18,141},{0 ,19,198},{0 ,20,104},{0 ,21,81},{0 ,22,1},{0 ,23,0},{1 ,24,0},{2 ,25,0},{4 ,26,0},{5 ,27,0},{6 ,28,0},{7 ,29,0},{8 ,30,0},{9 ,31,0},{10 ,32,0},{11 ,33,0},{12 ,34,0},{13 ,35,0},{14 ,36,0},{15 ,37,0},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{22 ,44,0},{23 ,45,0},{24 ,46,0},{25 ,47,0},{26 ,48,0},{27 ,49,0},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{37 ,59,0},{38 ,60,0},{39 ,61,0},{40 ,62,0},{41 ,63,0},{42 ,64,0},{43 ,65,0},{44 ,66,0},{45 ,67,0},
+{1 ,0,141},{2 ,1,203},{1 ,2,45},{1 ,3,151},{2 ,4,176},{1 ,5,119},{2 ,6,186},{2 ,7,95},{2 ,8,153},{1 ,9,87},{2 ,10,70},{1 ,11,206},{1 ,12,93},{2 ,13,77},{2 ,14,214},{1 ,15,9},{1 ,16,118},{2 ,17,198},{2 ,18,117},{1 ,19,31},{2 ,20,90},{1 ,21,187},{1 ,22,0},{1 ,23,0},{2 ,24,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{2 ,0,207},{3 ,1,18},{2 ,2,31},{3 ,3,165},{3 ,4,5},{2 ,5,180},{3 ,6,45},{3 ,7,142},{3 ,8,16},{2 ,9,177},{3 ,10,34},{3 ,11,155},{3 ,12,213},{3 ,13,147},{3 ,14,69},{2 ,15,77},{3 ,16,96},{3 ,17,74},{3 ,18,99},{2 ,19,223},{3 ,20,30},{3 ,21,158},{3 ,22,1},{11 ,23,201},{8 ,24,201},{15 ,25,81},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{3 ,0,201},{4 ,1,10},{10 ,2,165},{5 ,3,86},{7 ,4,104},{21 ,5,131},{6 ,6,119},{7 ,7,100},{7 ,8,150},{20 ,9,121},{6 ,10,113},{6 ,11,21},{5 ,12,80},{6 ,13,63},{7 ,14,158},{14 ,15,211},{5 ,16,182},{6 ,17,51},{6 ,18,136},{8 ,19,39},{6 ,20,116},{5 ,21,130},{5 ,22,153},{13 ,23,78},{30 ,24,123},{29 ,25,68},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{4 ,0,170},{5 ,1,59},{23 ,2,203},{8 ,3,4},{10 ,4,174},{0 ,0,-1},{25 ,6,166},{10 ,7,19},{10 ,8,194},{38 ,9,90},{9 ,10,213},{9 ,11,105},{8 ,12,217},{9 ,13,89},{10 ,14,103},{26 ,15,127},{8 ,16,204},{9 ,17,185},{9 ,18,109},{18 ,19,186},{9 ,20,218},{8 ,21,58},{8 ,22,44},{37 ,23,138},{32 ,24,30},{31 ,25,128},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{5 ,0,164},{7 ,1,76},{26 ,2,176},{13 ,3,56},{24 ,4,64},{0 ,0,-1},{27 ,6,141},{13 ,7,72},{19 ,8,198},{41 ,9,60},{12 ,10,136},{12 ,11,3},{11 ,12,2},{12 ,13,28},{17 ,14,110},{34 ,15,68},{11 ,16,35},{14 ,17,51},{12 ,18,182},{28 ,19,217},{13 ,20,217},{11 ,21,32},{11 ,22,84},{0 ,0,-1},{42 ,24,78},{43 ,25,161},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{6 ,0,158},{8 ,1,95},{33 ,2,49},{16 ,3,164},{26 ,4,212},{0 ,0,-1},{35 ,6,173},{19 ,7,103},{27 ,8,174},{44 ,9,9},{15 ,10,131},{16 ,11,43},{14 ,12,175},{15 ,13,209},{25 ,14,81},{36 ,15,0},{14 ,16,191},{17 ,17,63},{15 ,18,209},{39 ,19,114},{16 ,20,189},{14 ,21,43},{16 ,22,101},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{7 ,0,17},{9 ,1,37},{0 ,0,-1},{20 ,3,210},{28 ,4,153},{0 ,0,-1},{45 ,6,121},{25 ,7,65},{40 ,8,45},{0 ,0,-1},{19 ,10,8},{20 ,11,214},{18 ,12,110},{18 ,13,200},{29 ,14,11},{0 ,0,-1},{17 ,16,200},{22 ,17,148},{18 ,18,143},{0 ,0,-1},{21 ,20,50},{17 ,21,4},{20 ,22,183},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{8 ,0,33},{10 ,1,82},{0 ,0,-1},{24 ,3,157},{42 ,4,91},{0 ,0,-1},{0 ,0,-1},{31 ,7,49},{0 ,0,-1},{0 ,0,-1},{23 ,10,168},{24 ,11,193},{22 ,12,0},{22 ,13,3},{32 ,14,58},{0 ,0,-1},{21 ,16,220},{34 ,17,150},{23 ,18,122},{0 ,0,-1},{0 ,0,-1},{21 ,21,106},{24 ,22,124},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{9 ,0,9},{11 ,1,11},{0 ,0,-1},{39 ,3,77},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{34 ,7,186},{0 ,0,-1},{0 ,0,-1},{30 ,10,130},{33 ,11,161},{32 ,12,209},{30 ,13,210},{36 ,14,157},{0 ,0,-1},{43 ,16,22},{40 ,17,96},{29 ,18,53},{0 ,0,-1},{0 ,0,-1},{28 ,21,114},{31 ,22,177},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{11 ,0,52},{12 ,1,175},{0 ,0,-1},{41 ,3,215},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{39 ,7,49},{0 ,0,-1},{0 ,0,-1},{38 ,10,73},{0 ,0,-1},{35 ,12,26},{37 ,13,195},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{36 ,18,6},{0 ,0,-1},{0 ,0,-1},{33 ,21,137},{35 ,22,187},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{12 ,0,142},{15 ,1,120},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,7,4},{0 ,0,-1},{0 ,0,-1},{45 ,10,29},{0 ,0,-1},{38 ,12,10},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{41 ,18,167},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,22,12},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{13 ,0,81},{16 ,1,154},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{43 ,18,134},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{14 ,0,14},{18 ,1,199},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{15 ,0,90},{19 ,1,6},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{17 ,0,56},{21 ,1,192},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{19 ,0,8},{23 ,1,88},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{20 ,0,105},{25 ,1,1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{22 ,0,53},{27 ,1,208},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{24 ,0,49},{29 ,1,150},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{26 ,0,107},{31 ,1,175},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{28 ,0,146},{33 ,1,114},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{30 ,0,34},{35 ,1,192},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{32 ,0,192},{37 ,1,81},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{34 ,0,82},{39 ,1,12},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{36 ,0,222},{41 ,1,23},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{38 ,0,123},{43 ,1,206},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{40 ,0,67},{45 ,1,184},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{42 ,0,114},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{44 ,0,84},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1}
+};
+
+
+//--------------------------------------------------BG1_I3-----------------------------------------------------------------
+
+
+//--------------------------------------------------BG1_I4-----------------------------------------------------------------
+h_element host_h_compact1_I4 [46*19] =
+{{0 ,0,211},{1 ,0,179},{2 ,0,258},{3 ,0,187},{4 ,0,246},{5 ,0,261},{6 ,0,80},{7 ,0,169},{8 ,0,54},{9 ,0,162},{10 ,1,178},{11 ,0,55},{12 ,0,225},{13 ,0,231},{14 ,0,0},{15 ,0,170},{16 ,1,270},{17 ,0,153},{18 ,1,161},{19 ,0,0},{20 ,0,265},{21 ,1,64},{22 ,0,72},{23 ,1,180},{24 ,0,236},{25 ,1,205},{26 ,0,0},{27 ,1,45},{28 ,0,275},{29 ,1,0},{30 ,0,0},{31 ,1,144},{32 ,0,0},{33 ,1,0},{34 ,0,197},{35 ,1,199},{36 ,0,216},{37 ,1,72},{38 ,0,190},{39 ,1,153},{40 ,0,216},{41 ,1,0},{42 ,0,27},{43 ,1,52},{44 ,0,18},{45 ,1,168},
+{0 ,1,198},{1 ,2,162},{2 ,1,167},{3 ,1,145},{4 ,1,235},{5 ,1,181},{6 ,6,144},{7 ,1,189},{8 ,1,0},{9 ,1,159},{10 ,2,1},{11 ,1,23},{12 ,1,162},{13 ,3,0},{14 ,12,186},{15 ,1,0},{16 ,3,13},{17 ,14,137},{18 ,12,151},{19 ,1,0},{20 ,3,81},{21 ,5,46},{22 ,12,189},{23 ,2,0},{24 ,3,199},{25 ,6,0},{26 ,2,0},{27 ,6,36},{28 ,4,0},{29 ,14,180},{30 ,10,90},{31 ,7,144},{32 ,12,211},{33 ,2,0},{34 ,7,0},{35 ,6,278},{36 ,14,16},{37 ,13,144},{38 ,9,0},{39 ,3,0},{40 ,8,144},{41 ,3,0},{42 ,4,0},{43 ,16,243},{44 ,7,0},{45 ,6,0},
+{0 ,2,188},{1 ,3,223},{2 ,2,220},{3 ,3,166},{4 ,26,0},{5 ,3,72},{6 ,10,169},{7 ,4,154},{8 ,3,252},{9 ,10,93},{10 ,4,28},{11 ,12,274},{12 ,10,244},{13 ,7,216},{14 ,15,253},{15 ,10,183},{16 ,11,99},{17 ,16,0},{18 ,13,0},{19 ,7,118},{20 ,9,90},{21 ,16,266},{22 ,13,72},{23 ,10,0},{24 ,4,0},{25 ,7,0},{26 ,4,0},{27 ,8,72},{28 ,19,155},{29 ,18,0},{30 ,13,252},{31 ,22,166},{32 ,14,36},{33 ,11,76},{34 ,15,108},{35 ,12,0},{36 ,15,0},{37 ,23,0},{38 ,10,0},{39 ,7,165},{40 ,17,2},{41 ,9,0},{42 ,24,35},{43 ,18,0},{44 ,9,0},{45 ,10,144},
+{0 ,3,186},{1 ,4,256},{2 ,4,133},{3 ,4,108},{0 ,0,-1},{5 ,12,283},{6 ,11,90},{7 ,7,184},{8 ,12,41},{9 ,11,134},{10 ,7,267},{11 ,16,181},{12 ,11,151},{13 ,20,47},{14 ,16,16},{15 ,13,108},{16 ,20,54},{17 ,17,0},{18 ,18,241},{19 ,8,144},{20 ,11,144},{21 ,20,9},{22 ,17,257},{23 ,18,165},{24 ,11,266},{25 ,14,183},{26 ,15,277},{27 ,49,0},{28 ,21,62},{29 ,25,42},{30 ,24,173},{31 ,25,19},{32 ,24,162},{33 ,21,18},{34 ,17,0},{35 ,22,205},{36 ,18,0},{37 ,59,0},{38 ,12,0},{39 ,19,117},{40 ,62,0},{41 ,18,183},{42 ,64,0},{43 ,25,270},{44 ,22,57},{45 ,67,0},
+{0 ,5,219},{1 ,5,160},{2 ,5,243},{3 ,6,82},{0 ,0,-1},{5 ,16,254},{6 ,13,59},{7 ,8,104},{8 ,16,98},{9 ,13,45},{10 ,8,234},{11 ,21,273},{12 ,13,238},{13 ,23,36},{14 ,17,0},{15 ,18,68},{16 ,22,0},{17 ,21,162},{18 ,19,144},{19 ,10,0},{20 ,22,228},{21 ,21,18},{22 ,44,0},{23 ,45,0},{24 ,22,0},{25 ,47,0},{26 ,48,0},{0 ,0,-1},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{0 ,0,-1},{38 ,60,0},{39 ,61,0},{0 ,0,-1},{41 ,63,0},{0 ,0,-1},{43 ,65,0},{44 ,66,0},{0 ,0,-1},
+{0 ,6,4},{1 ,7,76},{2 ,6,202},{3 ,7,132},{0 ,0,-1},{5 ,21,79},{6 ,17,177},{7 ,14,164},{8 ,19,46},{9 ,17,132},{10 ,14,201},{11 ,22,39},{12 ,18,243},{13 ,35,0},{14 ,21,79},{15 ,25,64},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{0 ,0,-1},{0 ,0,-1},{24 ,46,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,9,29},{1 ,8,202},{2 ,7,218},{3 ,8,197},{0 ,0,-1},{5 ,22,144},{6 ,18,151},{7 ,29,0},{8 ,21,15},{9 ,18,76},{10 ,32,0},{11 ,23,26},{12 ,34,0},{0 ,0,-1},{14 ,36,0},{15 ,37,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,10,144},{1 ,9,117},{2 ,8,63},{3 ,10,41},{0 ,0,-1},{5 ,27,0},{6 ,20,108},{0 ,0,-1},{8 ,22,230},{9 ,20,209},{0 ,0,-1},{11 ,33,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,11,116},{1 ,11,109},{2 ,9,0},{3 ,11,162},{0 ,0,-1},{0 ,0,-1},{6 ,28,0},{0 ,0,-1},{8 ,24,54},{9 ,31,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,12,216},{1 ,12,15},{2 ,10,3},{3 ,12,57},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{8 ,30,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,13,115},{1 ,14,72},{2 ,13,74},{3 ,13,36},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,15,233},{1 ,15,152},{2 ,14,229},{3 ,14,115},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,16,144},{1 ,16,158},{2 ,15,0},{3 ,16,242},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,18,95},{1 ,17,147},{2 ,17,216},{3 ,17,165},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,19,216},{1 ,19,156},{2 ,18,269},{3 ,18,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,20,73},{1 ,21,119},{2 ,19,200},{3 ,20,113},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,21,261},{1 ,22,0},{2 ,20,234},{3 ,21,108},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,22,1},{1 ,23,0},{2 ,24,0},{3 ,22,1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,23,0},{1 ,24,0},{2 ,25,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+};
+
+
+h_element host_h_compact2_I4 [68*30] =
+{{0 ,0,211},{0 ,1,198},{0 ,2,188},{0 ,3,186},{1 ,4,256},{0 ,5,219},{0 ,6,4},{1 ,7,76},{1 ,8,202},{0 ,9,29},{0 ,10,144},{0 ,11,116},{0 ,12,216},{0 ,13,115},{1 ,14,72},{0 ,15,233},{0 ,16,144},{1 ,17,147},{0 ,18,95},{0 ,19,216},{0 ,20,73},{0 ,21,261},{0 ,22,1},{0 ,23,0},{1 ,24,0},{2 ,25,0},{4 ,26,0},{5 ,27,0},{6 ,28,0},{7 ,29,0},{8 ,30,0},{9 ,31,0},{10 ,32,0},{11 ,33,0},{12 ,34,0},{13 ,35,0},{14 ,36,0},{15 ,37,0},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{22 ,44,0},{23 ,45,0},{24 ,46,0},{25 ,47,0},{26 ,48,0},{27 ,49,0},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{37 ,59,0},{38 ,60,0},{39 ,61,0},{40 ,62,0},{41 ,63,0},{42 ,64,0},{43 ,65,0},{44 ,66,0},{45 ,67,0},
+{1 ,0,179},{2 ,1,167},{1 ,2,162},{1 ,3,223},{2 ,4,133},{1 ,5,160},{2 ,6,202},{2 ,7,218},{2 ,8,63},{1 ,9,117},{2 ,10,3},{1 ,11,109},{1 ,12,15},{2 ,13,74},{2 ,14,229},{1 ,15,152},{1 ,16,158},{2 ,17,216},{2 ,18,269},{1 ,19,156},{2 ,20,234},{1 ,21,119},{1 ,22,0},{1 ,23,0},{2 ,24,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{2 ,0,258},{3 ,1,145},{2 ,2,220},{3 ,3,166},{3 ,4,108},{2 ,5,243},{3 ,6,82},{3 ,7,132},{3 ,8,197},{2 ,9,0},{3 ,10,41},{3 ,11,162},{3 ,12,57},{3 ,13,36},{3 ,14,115},{2 ,15,0},{3 ,16,242},{3 ,17,165},{3 ,18,0},{2 ,19,200},{3 ,20,113},{3 ,21,108},{3 ,22,1},{11 ,23,26},{8 ,24,54},{15 ,25,64},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{3 ,0,187},{4 ,1,235},{10 ,2,1},{5 ,3,72},{7 ,4,154},{21 ,5,46},{6 ,6,144},{7 ,7,184},{7 ,8,104},{20 ,9,90},{6 ,10,169},{6 ,11,90},{5 ,12,283},{6 ,13,59},{7 ,14,164},{14 ,15,253},{5 ,16,254},{6 ,17,177},{6 ,18,151},{8 ,19,46},{6 ,20,108},{5 ,21,79},{5 ,22,144},{13 ,23,36},{30 ,24,173},{29 ,25,42},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{4 ,0,246},{5 ,1,181},{23 ,2,0},{8 ,3,252},{10 ,4,28},{0 ,0,-1},{25 ,6,0},{10 ,7,267},{10 ,8,234},{38 ,9,0},{9 ,10,93},{9 ,11,134},{8 ,12,41},{9 ,13,45},{10 ,14,201},{26 ,15,277},{8 ,16,98},{9 ,17,132},{9 ,18,76},{18 ,19,144},{9 ,20,209},{8 ,21,15},{8 ,22,230},{37 ,23,0},{32 ,24,162},{31 ,25,19},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{5 ,0,261},{7 ,1,189},{26 ,2,0},{13 ,3,0},{24 ,4,0},{0 ,0,-1},{27 ,6,36},{13 ,7,216},{19 ,8,144},{41 ,9,0},{12 ,10,244},{12 ,11,151},{11 ,12,274},{12 ,13,238},{17 ,14,137},{34 ,15,108},{11 ,16,181},{14 ,17,0},{12 ,18,243},{28 ,19,155},{13 ,20,47},{11 ,21,273},{11 ,22,39},{0 ,0,-1},{42 ,24,35},{43 ,25,270},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{6 ,0,80},{8 ,1,0},{33 ,2,0},{16 ,3,13},{26 ,4,0},{0 ,0,-1},{35 ,6,278},{19 ,7,118},{27 ,8,72},{44 ,9,0},{15 ,10,183},{16 ,11,99},{14 ,12,186},{15 ,13,108},{25 ,14,183},{36 ,15,0},{14 ,16,16},{17 ,17,0},{15 ,18,68},{39 ,19,117},{16 ,20,54},{14 ,21,79},{16 ,22,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{7 ,0,169},{9 ,1,159},{0 ,0,-1},{20 ,3,81},{28 ,4,0},{0 ,0,-1},{45 ,6,0},{25 ,7,0},{40 ,8,144},{0 ,0,-1},{19 ,10,0},{20 ,11,144},{18 ,12,151},{18 ,13,0},{29 ,14,180},{0 ,0,-1},{17 ,16,0},{22 ,17,257},{18 ,18,241},{0 ,0,-1},{21 ,20,9},{17 ,21,162},{20 ,22,228},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{8 ,0,54},{10 ,1,178},{0 ,0,-1},{24 ,3,199},{42 ,4,0},{0 ,0,-1},{0 ,0,-1},{31 ,7,144},{0 ,0,-1},{0 ,0,-1},{23 ,10,0},{24 ,11,266},{22 ,12,189},{22 ,13,72},{32 ,14,36},{0 ,0,-1},{21 ,16,266},{34 ,17,0},{23 ,18,165},{0 ,0,-1},{0 ,0,-1},{21 ,21,18},{24 ,22,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{9 ,0,162},{11 ,1,23},{0 ,0,-1},{39 ,3,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{34 ,7,0},{0 ,0,-1},{0 ,0,-1},{30 ,10,90},{33 ,11,76},{32 ,12,211},{30 ,13,252},{36 ,14,16},{0 ,0,-1},{43 ,16,243},{40 ,17,2},{29 ,18,0},{0 ,0,-1},{0 ,0,-1},{28 ,21,62},{31 ,22,166},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{11 ,0,55},{12 ,1,162},{0 ,0,-1},{41 ,3,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{39 ,7,165},{0 ,0,-1},{0 ,0,-1},{38 ,10,0},{0 ,0,-1},{35 ,12,0},{37 ,13,144},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{36 ,18,0},{0 ,0,-1},{0 ,0,-1},{33 ,21,18},{35 ,22,205},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{12 ,0,225},{15 ,1,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,7,0},{0 ,0,-1},{0 ,0,-1},{45 ,10,144},{0 ,0,-1},{38 ,12,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{41 ,18,183},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,22,57},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{13 ,0,231},{16 ,1,270},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{43 ,18,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{14 ,0,0},{18 ,1,161},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{15 ,0,170},{19 ,1,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{17 ,0,153},{21 ,1,64},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{19 ,0,0},{23 ,1,180},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{20 ,0,265},{25 ,1,205},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{22 ,0,72},{27 ,1,45},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{24 ,0,236},{29 ,1,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{26 ,0,0},{31 ,1,144},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{28 ,0,275},{33 ,1,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{30 ,0,0},{35 ,1,199},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{32 ,0,0},{37 ,1,72},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{34 ,0,197},{39 ,1,153},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{36 ,0,216},{41 ,1,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{38 ,0,190},{43 ,1,52},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{40 ,0,216},{45 ,1,168},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{42 ,0,27},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{44 ,0,18},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1}
+};
+
+
+//--------------------------------------------------BG1_I4-----------------------------------------------------------------
+
+
+//--------------------------------------------------BG1_I5-----------------------------------------------------------------
+h_element host_h_compact1_I5 [46*19] =
+{{0 ,0,294},{1 ,0,77},{2 ,0,226},{3 ,0,97},{4 ,0,42},{5 ,0,219},{6 ,0,294},{7 ,0,3},{8 ,0,348},{9 ,0,156},{10 ,1,175},{11 ,0,25},{12 ,0,123},{13 ,0,311},{14 ,0,22},{15 ,0,176},{16 ,1,190},{17 ,0,110},{18 ,1,47},{19 ,0,87},{20 ,0,89},{21 ,1,162},{22 ,0,280},{23 ,1,18},{24 ,0,38},{25 ,1,279},{26 ,0,325},{27 ,1,91},{28 ,0,102},{29 ,1,273},{30 ,0,171},{31 ,1,101},{32 ,0,351},{33 ,1,56},{34 ,0,60},{35 ,1,100},{36 ,0,135},{37 ,1,319},{38 ,0,164},{39 ,1,236},{40 ,0,304},{41 ,1,123},{42 ,0,288},{43 ,1,210},{44 ,0,79},{45 ,1,82},
+{0 ,1,118},{1 ,2,225},{2 ,1,35},{3 ,1,94},{4 ,1,256},{5 ,1,130},{6 ,6,73},{7 ,1,103},{8 ,1,75},{9 ,1,88},{10 ,2,253},{11 ,1,322},{12 ,1,217},{13 ,3,251},{14 ,12,322},{15 ,1,348},{16 ,3,293},{17 ,14,228},{18 ,12,286},{19 ,1,110},{20 ,3,65},{21 ,5,264},{22 ,12,157},{23 ,2,6},{24 ,3,170},{25 ,6,255},{26 ,2,326},{27 ,6,326},{28 ,4,1},{29 ,14,104},{30 ,10,16},{31 ,7,297},{32 ,12,265},{33 ,2,304},{34 ,7,320},{35 ,6,210},{36 ,14,15},{37 ,13,236},{38 ,9,196},{39 ,3,264},{40 ,8,237},{41 ,3,77},{42 ,4,83},{43 ,16,3},{44 ,7,244},{45 ,6,67},
+{0 ,2,167},{1 ,3,96},{2 ,2,213},{3 ,3,49},{4 ,26,0},{5 ,3,251},{6 ,10,330},{7 ,4,224},{8 ,3,22},{9 ,10,293},{10 ,4,27},{11 ,12,200},{12 ,10,142},{13 ,7,265},{14 ,15,277},{15 ,10,15},{16 ,11,332},{17 ,16,247},{18 ,13,246},{19 ,7,147},{20 ,9,155},{21 ,16,346},{22 ,13,236},{23 ,10,181},{24 ,4,249},{25 ,7,111},{26 ,4,226},{27 ,8,268},{28 ,19,40},{29 ,18,243},{30 ,13,95},{31 ,22,279},{32 ,14,338},{33 ,11,141},{34 ,15,112},{35 ,12,195},{36 ,15,35},{37 ,23,85},{38 ,10,209},{39 ,7,37},{40 ,17,135},{41 ,9,25},{42 ,24,17},{43 ,18,53},{44 ,9,293},{45 ,10,235},
+{0 ,3,330},{1 ,4,338},{2 ,4,302},{3 ,4,279},{0 ,0,-1},{5 ,12,322},{6 ,11,99},{7 ,7,297},{8 ,12,312},{9 ,11,111},{10 ,7,231},{11 ,16,351},{12 ,11,110},{13 ,20,94},{14 ,16,156},{15 ,13,81},{16 ,20,331},{17 ,17,116},{18 ,18,181},{19 ,8,258},{20 ,11,244},{21 ,20,143},{22 ,17,113},{23 ,18,304},{24 ,11,288},{25 ,14,54},{26 ,15,99},{27 ,49,0},{28 ,21,167},{29 ,25,107},{30 ,24,212},{31 ,25,222},{32 ,24,83},{33 ,21,101},{34 ,17,54},{35 ,22,268},{36 ,18,188},{37 ,59,0},{38 ,12,246},{39 ,19,272},{40 ,62,0},{41 ,18,272},{42 ,64,0},{43 ,25,167},{44 ,22,272},{45 ,67,0},
+{0 ,5,207},{1 ,5,268},{2 ,5,111},{3 ,6,139},{0 ,0,-1},{5 ,16,295},{6 ,13,172},{7 ,8,215},{8 ,16,224},{9 ,13,92},{10 ,8,49},{11 ,21,166},{12 ,13,176},{13 ,23,81},{14 ,17,66},{15 ,18,176},{16 ,22,114},{17 ,21,190},{18 ,19,73},{19 ,10,204},{20 ,22,30},{21 ,21,109},{22 ,44,0},{23 ,45,0},{24 ,22,194},{25 ,47,0},{26 ,48,0},{0 ,0,-1},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{0 ,0,-1},{38 ,60,0},{39 ,61,0},{0 ,0,-1},{41 ,63,0},{0 ,0,-1},{43 ,65,0},{44 ,66,0},{0 ,0,-1},
+{0 ,6,165},{1 ,7,112},{2 ,6,265},{3 ,7,166},{0 ,0,-1},{5 ,21,258},{6 ,17,150},{7 ,14,39},{8 ,19,17},{9 ,17,152},{10 ,14,267},{11 ,22,338},{12 ,18,76},{13 ,35,0},{14 ,21,78},{15 ,25,113},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{0 ,0,-1},{0 ,0,-1},{24 ,46,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,9,243},{1 ,8,302},{2 ,7,128},{3 ,8,91},{0 ,0,-1},{5 ,22,283},{6 ,18,284},{7 ,29,0},{8 ,21,59},{9 ,18,23},{10 ,32,0},{11 ,23,192},{12 ,34,0},{0 ,0,-1},{14 ,36,0},{15 ,37,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,10,250},{1 ,9,50},{2 ,8,237},{3 ,10,106},{0 ,0,-1},{5 ,27,0},{6 ,20,305},{0 ,0,-1},{8 ,22,314},{9 ,20,337},{0 ,0,-1},{11 ,33,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,11,1},{1 ,11,167},{2 ,9,294},{3 ,11,246},{0 ,0,-1},{0 ,0,-1},{6 ,28,0},{0 ,0,-1},{8 ,24,244},{9 ,31,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,12,339},{1 ,12,253},{2 ,10,127},{3 ,12,345},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{8 ,30,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,13,201},{1 ,14,334},{2 ,13,110},{3 ,13,269},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,15,53},{1 ,15,242},{2 ,14,286},{3 ,14,185},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,16,347},{1 ,16,257},{2 ,15,125},{3 ,16,249},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,18,304},{1 ,17,133},{2 ,17,131},{3 ,17,215},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,19,167},{1 ,19,9},{2 ,18,163},{3 ,18,143},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,20,47},{1 ,21,302},{2 ,19,210},{3 ,20,121},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,21,188},{1 ,22,0},{2 ,20,7},{3 ,21,121},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,22,1},{1 ,23,0},{2 ,24,0},{3 ,22,1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,23,0},{1 ,24,0},{2 ,25,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+};
+
+
+h_element host_h_compact2_I5 [68*30] =
+{{0 ,0,294},{0 ,1,118},{0 ,2,167},{0 ,3,330},{1 ,4,338},{0 ,5,207},{0 ,6,165},{1 ,7,112},{1 ,8,302},{0 ,9,243},{0 ,10,250},{0 ,11,1},{0 ,12,339},{0 ,13,201},{1 ,14,334},{0 ,15,53},{0 ,16,347},{1 ,17,133},{0 ,18,304},{0 ,19,167},{0 ,20,47},{0 ,21,188},{0 ,22,1},{0 ,23,0},{1 ,24,0},{2 ,25,0},{4 ,26,0},{5 ,27,0},{6 ,28,0},{7 ,29,0},{8 ,30,0},{9 ,31,0},{10 ,32,0},{11 ,33,0},{12 ,34,0},{13 ,35,0},{14 ,36,0},{15 ,37,0},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{22 ,44,0},{23 ,45,0},{24 ,46,0},{25 ,47,0},{26 ,48,0},{27 ,49,0},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{37 ,59,0},{38 ,60,0},{39 ,61,0},{40 ,62,0},{41 ,63,0},{42 ,64,0},{43 ,65,0},{44 ,66,0},{45 ,67,0},
+{1 ,0,77},{2 ,1,35},{1 ,2,225},{1 ,3,96},{2 ,4,302},{1 ,5,268},{2 ,6,265},{2 ,7,128},{2 ,8,237},{1 ,9,50},{2 ,10,127},{1 ,11,167},{1 ,12,253},{2 ,13,110},{2 ,14,286},{1 ,15,242},{1 ,16,257},{2 ,17,131},{2 ,18,163},{1 ,19,9},{2 ,20,7},{1 ,21,302},{1 ,22,0},{1 ,23,0},{2 ,24,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{2 ,0,226},{3 ,1,94},{2 ,2,213},{3 ,3,49},{3 ,4,279},{2 ,5,111},{3 ,6,139},{3 ,7,166},{3 ,8,91},{2 ,9,294},{3 ,10,106},{3 ,11,246},{3 ,12,345},{3 ,13,269},{3 ,14,185},{2 ,15,125},{3 ,16,249},{3 ,17,215},{3 ,18,143},{2 ,19,210},{3 ,20,121},{3 ,21,121},{3 ,22,1},{11 ,23,192},{8 ,24,244},{15 ,25,113},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{3 ,0,97},{4 ,1,256},{10 ,2,253},{5 ,3,251},{7 ,4,224},{21 ,5,264},{6 ,6,73},{7 ,7,297},{7 ,8,215},{20 ,9,155},{6 ,10,330},{6 ,11,99},{5 ,12,322},{6 ,13,172},{7 ,14,39},{14 ,15,277},{5 ,16,295},{6 ,17,150},{6 ,18,284},{8 ,19,17},{6 ,20,305},{5 ,21,258},{5 ,22,283},{13 ,23,81},{30 ,24,212},{29 ,25,107},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{4 ,0,42},{5 ,1,130},{23 ,2,6},{8 ,3,22},{10 ,4,27},{0 ,0,-1},{25 ,6,255},{10 ,7,231},{10 ,8,49},{38 ,9,196},{9 ,10,293},{9 ,11,111},{8 ,12,312},{9 ,13,92},{10 ,14,267},{26 ,15,99},{8 ,16,224},{9 ,17,152},{9 ,18,23},{18 ,19,73},{9 ,20,337},{8 ,21,59},{8 ,22,314},{37 ,23,85},{32 ,24,83},{31 ,25,222},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{5 ,0,219},{7 ,1,103},{26 ,2,326},{13 ,3,251},{24 ,4,249},{0 ,0,-1},{27 ,6,326},{13 ,7,265},{19 ,8,258},{41 ,9,25},{12 ,10,142},{12 ,11,110},{11 ,12,200},{12 ,13,176},{17 ,14,228},{34 ,15,112},{11 ,16,351},{14 ,17,66},{12 ,18,76},{28 ,19,40},{13 ,20,94},{11 ,21,166},{11 ,22,338},{0 ,0,-1},{42 ,24,17},{43 ,25,167},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{6 ,0,294},{8 ,1,75},{33 ,2,304},{16 ,3,293},{26 ,4,226},{0 ,0,-1},{35 ,6,210},{19 ,7,147},{27 ,8,268},{44 ,9,293},{15 ,10,15},{16 ,11,332},{14 ,12,322},{15 ,13,81},{25 ,14,54},{36 ,15,35},{14 ,16,156},{17 ,17,116},{15 ,18,176},{39 ,19,272},{16 ,20,331},{14 ,21,78},{16 ,22,114},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{7 ,0,3},{9 ,1,88},{0 ,0,-1},{20 ,3,65},{28 ,4,1},{0 ,0,-1},{45 ,6,67},{25 ,7,111},{40 ,8,237},{0 ,0,-1},{19 ,10,204},{20 ,11,244},{18 ,12,286},{18 ,13,246},{29 ,14,104},{0 ,0,-1},{17 ,16,247},{22 ,17,113},{18 ,18,181},{0 ,0,-1},{21 ,20,143},{17 ,21,190},{20 ,22,30},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{8 ,0,348},{10 ,1,175},{0 ,0,-1},{24 ,3,170},{42 ,4,83},{0 ,0,-1},{0 ,0,-1},{31 ,7,297},{0 ,0,-1},{0 ,0,-1},{23 ,10,181},{24 ,11,288},{22 ,12,157},{22 ,13,236},{32 ,14,338},{0 ,0,-1},{21 ,16,346},{34 ,17,54},{23 ,18,304},{0 ,0,-1},{0 ,0,-1},{21 ,21,109},{24 ,22,194},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{9 ,0,156},{11 ,1,322},{0 ,0,-1},{39 ,3,264},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{34 ,7,320},{0 ,0,-1},{0 ,0,-1},{30 ,10,16},{33 ,11,141},{32 ,12,265},{30 ,13,95},{36 ,14,15},{0 ,0,-1},{43 ,16,3},{40 ,17,135},{29 ,18,243},{0 ,0,-1},{0 ,0,-1},{28 ,21,167},{31 ,22,279},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{11 ,0,25},{12 ,1,217},{0 ,0,-1},{41 ,3,77},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{39 ,7,37},{0 ,0,-1},{0 ,0,-1},{38 ,10,209},{0 ,0,-1},{35 ,12,195},{37 ,13,236},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{36 ,18,188},{0 ,0,-1},{0 ,0,-1},{33 ,21,101},{35 ,22,268},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{12 ,0,123},{15 ,1,348},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,7,244},{0 ,0,-1},{0 ,0,-1},{45 ,10,235},{0 ,0,-1},{38 ,12,246},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{41 ,18,272},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,22,272},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{13 ,0,311},{16 ,1,190},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{43 ,18,53},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{14 ,0,22},{18 ,1,47},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{15 ,0,176},{19 ,1,110},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{17 ,0,110},{21 ,1,162},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{19 ,0,87},{23 ,1,18},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{20 ,0,89},{25 ,1,279},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{22 ,0,280},{27 ,1,91},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{24 ,0,38},{29 ,1,273},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{26 ,0,325},{31 ,1,101},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{28 ,0,102},{33 ,1,56},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{30 ,0,171},{35 ,1,100},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{32 ,0,351},{37 ,1,319},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{34 ,0,60},{39 ,1,236},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{36 ,0,135},{41 ,1,123},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{38 ,0,164},{43 ,1,210},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{40 ,0,304},{45 ,1,82},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{42 ,0,288},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{44 ,0,79},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1}
+};
+//--------------------------------------------------BG1_I5-----------------------------------------------------------------
+
+
+//--------------------------------------------------BG1_I6-----------------------------------------------------------------
+h_element host_h_compact1_I6 [46*19] =
+{{0 ,0,0},{1 ,0,22},{2 ,0,132},{3 ,0,4},{4 ,0,24},{5 ,0,185},{6 ,0,6},{7 ,0,145},{8 ,0,172},{9 ,0,6},{10 ,1,126},{11 ,0,184},{12 ,0,6},{13 ,0,52},{14 ,0,1},{15 ,0,173},{16 ,1,88},{17 ,0,91},{18 ,1,1},{19 ,0,12},{20 ,0,6},{21 ,1,6},{22 ,0,44},{23 ,1,45},{24 ,0,9},{25 ,1,4},{26 ,0,21},{27 ,1,98},{28 ,0,4},{29 ,1,92},{30 ,0,2},{31 ,1,4},{32 ,0,6},{33 ,1,10},{34 ,0,4},{35 ,1,4},{36 ,0,6},{37 ,1,82},{38 ,0,91},{39 ,1,4},{40 ,0,10},{41 ,1,2},{42 ,0,163},{43 ,1,1},{44 ,0,4},{45 ,1,181},
+{0 ,1,0},{1 ,2,11},{2 ,1,37},{3 ,1,6},{4 ,1,204},{5 ,1,100},{6 ,6,27},{7 ,1,88},{8 ,1,2},{9 ,1,10},{10 ,2,77},{11 ,1,194},{12 ,1,20},{13 ,3,147},{14 ,12,202},{15 ,1,6},{16 ,3,198},{17 ,14,184},{18 ,12,41},{19 ,1,6},{20 ,3,12},{21 ,5,86},{22 ,12,58},{23 ,2,18},{24 ,3,125},{25 ,6,74},{26 ,2,142},{27 ,6,140},{28 ,4,1},{29 ,14,136},{30 ,10,88},{31 ,7,49},{32 ,12,126},{33 ,2,30},{34 ,7,153},{35 ,6,45},{36 ,14,200},{37 ,13,2},{38 ,9,64},{39 ,3,28},{40 ,8,84},{41 ,3,75},{42 ,4,10},{43 ,16,163},{44 ,7,6},{45 ,6,45},
+{0 ,2,0},{1 ,3,124},{2 ,2,21},{3 ,3,33},{4 ,26,0},{5 ,3,24},{6 ,10,163},{7 ,4,112},{8 ,3,131},{9 ,10,145},{10 ,4,156},{11 ,12,123},{12 ,10,203},{13 ,7,1},{14 ,15,118},{15 ,10,81},{16 ,11,160},{17 ,16,30},{18 ,13,167},{19 ,7,166},{20 ,9,15},{21 ,16,96},{22 ,13,130},{23 ,10,132},{24 ,4,191},{25 ,7,16},{26 ,4,192},{27 ,8,22},{28 ,19,40},{29 ,18,106},{30 ,13,112},{31 ,22,125},{32 ,14,63},{33 ,11,6},{34 ,15,197},{35 ,12,168},{36 ,15,177},{37 ,23,135},{38 ,10,198},{39 ,7,109},{40 ,17,12},{41 ,9,142},{42 ,24,162},{43 ,18,99},{44 ,9,142},{45 ,10,153},
+{0 ,3,0},{1 ,4,0},{2 ,4,180},{3 ,4,113},{0 ,0,-1},{5 ,12,65},{6 ,11,50},{7 ,7,153},{8 ,12,141},{9 ,11,53},{10 ,7,16},{11 ,16,16},{12 ,11,153},{13 ,20,16},{14 ,16,130},{15 ,13,182},{16 ,20,122},{17 ,17,3},{18 ,18,68},{19 ,8,184},{20 ,11,5},{21 ,20,42},{22 ,17,131},{23 ,18,100},{24 ,11,28},{25 ,14,28},{26 ,15,197},{27 ,49,0},{28 ,21,93},{29 ,25,6},{30 ,24,20},{31 ,25,194},{32 ,24,20},{33 ,21,92},{34 ,17,155},{35 ,22,185},{36 ,18,43},{37 ,59,0},{38 ,12,100},{39 ,19,188},{40 ,62,0},{41 ,18,128},{42 ,64,0},{43 ,25,98},{44 ,22,3},{45 ,67,0},
+{0 ,5,0},{1 ,5,10},{2 ,5,4},{3 ,6,49},{0 ,0,-1},{5 ,16,207},{6 ,13,48},{7 ,8,159},{8 ,16,96},{9 ,13,201},{10 ,8,12},{11 ,21,104},{12 ,13,104},{13 ,23,46},{14 ,17,1},{15 ,18,53},{16 ,22,182},{17 ,21,155},{18 ,19,148},{19 ,10,191},{20 ,22,30},{21 ,21,199},{22 ,44,0},{23 ,45,0},{24 ,22,6},{25 ,47,0},{26 ,48,0},{0 ,0,-1},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{0 ,0,-1},{38 ,60,0},{39 ,61,0},{0 ,0,-1},{41 ,63,0},{0 ,0,-1},{43 ,65,0},{44 ,66,0},{0 ,0,-1},
+{0 ,6,0},{1 ,7,0},{2 ,6,149},{3 ,7,21},{0 ,0,-1},{5 ,21,161},{6 ,17,24},{7 ,14,76},{8 ,19,99},{9 ,17,4},{10 ,14,70},{11 ,22,109},{12 ,18,207},{13 ,35,0},{14 ,21,2},{15 ,25,46},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{0 ,0,-1},{0 ,0,-1},{24 ,46,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,9,0},{1 ,8,0},{2 ,7,48},{3 ,8,6},{0 ,0,-1},{5 ,22,72},{6 ,18,38},{7 ,29,0},{8 ,21,101},{9 ,18,164},{10 ,32,0},{11 ,23,124},{12 ,34,0},{0 ,0,-1},{14 ,36,0},{15 ,37,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,10,0},{1 ,9,2},{2 ,8,38},{3 ,10,151},{0 ,0,-1},{5 ,27,0},{6 ,20,91},{0 ,0,-1},{8 ,22,35},{9 ,20,173},{0 ,0,-1},{11 ,33,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,11,0},{1 ,11,16},{2 ,9,122},{3 ,11,83},{0 ,0,-1},{0 ,0,-1},{6 ,28,0},{0 ,0,-1},{8 ,24,116},{9 ,31,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,12,0},{1 ,12,60},{2 ,10,195},{3 ,12,154},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{8 ,30,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,13,0},{1 ,14,0},{2 ,13,155},{3 ,13,87},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,15,0},{1 ,15,6},{2 ,14,28},{3 ,14,5},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,16,0},{1 ,16,30},{2 ,15,85},{3 ,16,92},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,18,0},{1 ,17,0},{2 ,17,47},{3 ,17,173},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,19,0},{1 ,19,168},{2 ,18,179},{3 ,18,120},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,20,0},{1 ,21,31},{2 ,19,42},{3 ,20,2},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,21,0},{1 ,22,105},{2 ,20,66},{3 ,21,142},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,22,0},{1 ,23,0},{2 ,24,0},{3 ,22,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,23,0},{1 ,24,0},{2 ,25,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+};
+
+
+h_element host_h_compact2_I6 [68*30] =
+{{0 ,0,0},{0 ,1,0},{0 ,2,0},{0 ,3,0},{1 ,4,0},{0 ,5,0},{0 ,6,0},{1 ,7,0},{1 ,8,0},{0 ,9,0},{0 ,10,0},{0 ,11,0},{0 ,12,0},{0 ,13,0},{1 ,14,0},{0 ,15,0},{0 ,16,0},{1 ,17,0},{0 ,18,0},{0 ,19,0},{0 ,20,0},{0 ,21,0},{0 ,22,0},{0 ,23,0},{1 ,24,0},{2 ,25,0},{4 ,26,0},{5 ,27,0},{6 ,28,0},{7 ,29,0},{8 ,30,0},{9 ,31,0},{10 ,32,0},{11 ,33,0},{12 ,34,0},{13 ,35,0},{14 ,36,0},{15 ,37,0},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{22 ,44,0},{23 ,45,0},{24 ,46,0},{25 ,47,0},{26 ,48,0},{27 ,49,0},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{37 ,59,0},{38 ,60,0},{39 ,61,0},{40 ,62,0},{41 ,63,0},{42 ,64,0},{43 ,65,0},{44 ,66,0},{45 ,67,0},
+{1 ,0,22},{2 ,1,37},{1 ,2,11},{1 ,3,124},{2 ,4,180},{1 ,5,10},{2 ,6,149},{2 ,7,48},{2 ,8,38},{1 ,9,2},{2 ,10,195},{1 ,11,16},{1 ,12,60},{2 ,13,155},{2 ,14,28},{1 ,15,6},{1 ,16,30},{2 ,17,47},{2 ,18,179},{1 ,19,168},{2 ,20,66},{1 ,21,31},{1 ,22,105},{1 ,23,0},{2 ,24,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{2 ,0,132},{3 ,1,6},{2 ,2,21},{3 ,3,33},{3 ,4,113},{2 ,5,4},{3 ,6,49},{3 ,7,21},{3 ,8,6},{2 ,9,122},{3 ,10,151},{3 ,11,83},{3 ,12,154},{3 ,13,87},{3 ,14,5},{2 ,15,85},{3 ,16,92},{3 ,17,173},{3 ,18,120},{2 ,19,42},{3 ,20,2},{3 ,21,142},{3 ,22,0},{11 ,23,124},{8 ,24,116},{15 ,25,46},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{3 ,0,4},{4 ,1,204},{10 ,2,77},{5 ,3,24},{7 ,4,112},{21 ,5,86},{6 ,6,27},{7 ,7,153},{7 ,8,159},{20 ,9,15},{6 ,10,163},{6 ,11,50},{5 ,12,65},{6 ,13,48},{7 ,14,76},{14 ,15,118},{5 ,16,207},{6 ,17,24},{6 ,18,38},{8 ,19,99},{6 ,20,91},{5 ,21,161},{5 ,22,72},{13 ,23,46},{30 ,24,20},{29 ,25,6},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{4 ,0,24},{5 ,1,100},{23 ,2,18},{8 ,3,131},{10 ,4,156},{0 ,0,-1},{25 ,6,74},{10 ,7,16},{10 ,8,12},{38 ,9,64},{9 ,10,145},{9 ,11,53},{8 ,12,141},{9 ,13,201},{10 ,14,70},{26 ,15,197},{8 ,16,96},{9 ,17,4},{9 ,18,164},{18 ,19,148},{9 ,20,173},{8 ,21,101},{8 ,22,35},{37 ,23,135},{32 ,24,20},{31 ,25,194},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{5 ,0,185},{7 ,1,88},{26 ,2,142},{13 ,3,147},{24 ,4,191},{0 ,0,-1},{27 ,6,140},{13 ,7,1},{19 ,8,184},{41 ,9,142},{12 ,10,203},{12 ,11,153},{11 ,12,123},{12 ,13,104},{17 ,14,184},{34 ,15,197},{11 ,16,16},{14 ,17,1},{12 ,18,207},{28 ,19,40},{13 ,20,16},{11 ,21,104},{11 ,22,109},{0 ,0,-1},{42 ,24,162},{43 ,25,98},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{6 ,0,6},{8 ,1,2},{33 ,2,30},{16 ,3,198},{26 ,4,192},{0 ,0,-1},{35 ,6,45},{19 ,7,166},{27 ,8,22},{44 ,9,142},{15 ,10,81},{16 ,11,160},{14 ,12,202},{15 ,13,182},{25 ,14,28},{36 ,15,177},{14 ,16,130},{17 ,17,3},{15 ,18,53},{39 ,19,188},{16 ,20,122},{14 ,21,2},{16 ,22,182},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{7 ,0,145},{9 ,1,10},{0 ,0,-1},{20 ,3,12},{28 ,4,1},{0 ,0,-1},{45 ,6,45},{25 ,7,16},{40 ,8,84},{0 ,0,-1},{19 ,10,191},{20 ,11,5},{18 ,12,41},{18 ,13,167},{29 ,14,136},{0 ,0,-1},{17 ,16,30},{22 ,17,131},{18 ,18,68},{0 ,0,-1},{21 ,20,42},{17 ,21,155},{20 ,22,30},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{8 ,0,172},{10 ,1,126},{0 ,0,-1},{24 ,3,125},{42 ,4,10},{0 ,0,-1},{0 ,0,-1},{31 ,7,49},{0 ,0,-1},{0 ,0,-1},{23 ,10,132},{24 ,11,28},{22 ,12,58},{22 ,13,130},{32 ,14,63},{0 ,0,-1},{21 ,16,96},{34 ,17,155},{23 ,18,100},{0 ,0,-1},{0 ,0,-1},{21 ,21,199},{24 ,22,6},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{9 ,0,6},{11 ,1,194},{0 ,0,-1},{39 ,3,28},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{34 ,7,153},{0 ,0,-1},{0 ,0,-1},{30 ,10,88},{33 ,11,6},{32 ,12,126},{30 ,13,112},{36 ,14,200},{0 ,0,-1},{43 ,16,163},{40 ,17,12},{29 ,18,106},{0 ,0,-1},{0 ,0,-1},{28 ,21,93},{31 ,22,125},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{11 ,0,184},{12 ,1,20},{0 ,0,-1},{41 ,3,75},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{39 ,7,109},{0 ,0,-1},{0 ,0,-1},{38 ,10,198},{0 ,0,-1},{35 ,12,168},{37 ,13,2},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{36 ,18,43},{0 ,0,-1},{0 ,0,-1},{33 ,21,92},{35 ,22,185},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{12 ,0,6},{15 ,1,6},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,7,6},{0 ,0,-1},{0 ,0,-1},{45 ,10,153},{0 ,0,-1},{38 ,12,100},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{41 ,18,128},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,22,3},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{13 ,0,52},{16 ,1,88},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{43 ,18,99},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{14 ,0,1},{18 ,1,1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{15 ,0,173},{19 ,1,6},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{17 ,0,91},{21 ,1,6},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{19 ,0,12},{23 ,1,45},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{20 ,0,6},{25 ,1,4},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{22 ,0,44},{27 ,1,98},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{24 ,0,9},{29 ,1,92},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{26 ,0,21},{31 ,1,4},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{28 ,0,4},{33 ,1,10},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{30 ,0,2},{35 ,1,4},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{32 ,0,6},{37 ,1,82},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{34 ,0,4},{39 ,1,4},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{36 ,0,6},{41 ,1,2},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{38 ,0,91},{43 ,1,1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{40 ,0,10},{45 ,1,181},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{42 ,0,163},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{44 ,0,4},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1}
+};
+
+//--------------------------------------------------BG1_I6-----------------------------------------------------------------
+
+
+//--------------------------------------------------BG1_I7-----------------------------------------------------------------
+h_element host_h_compact1_I7 [46*19] =
+{{0 ,0,135},{1 ,0,96},{2 ,0,189},{3 ,0,128},{4 ,0,64},{5 ,0,2},{6 ,0,199},{7 ,0,77},{8 ,0,181},{9 ,0,169},{10 ,1,116},{11 ,0,45},{12 ,0,186},{13 ,0,220},{14 ,0,124},{15 ,0,39},{16 ,1,78},{17 ,0,183},{18 ,1,183},{19 ,0,179},{20 ,0,77},{21 ,1,197},{22 ,0,25},{23 ,1,185},{24 ,0,32},{25 ,1,27},{26 ,0,163},{27 ,1,165},{28 ,0,32},{29 ,1,232},{30 ,0,170},{31 ,1,73},{32 ,0,103},{33 ,1,199},{34 ,0,161},{35 ,1,231},{36 ,0,11},{37 ,1,59},{38 ,0,121},{39 ,1,115},{40 ,0,4},{41 ,1,53},{42 ,0,222},{43 ,1,22},{44 ,0,191},{45 ,1,177},
+{0 ,1,227},{1 ,2,236},{2 ,1,4},{3 ,1,23},{4 ,1,211},{5 ,1,171},{6 ,6,22},{7 ,1,146},{8 ,1,105},{9 ,1,12},{10 ,2,151},{11 ,1,115},{12 ,1,215},{13 ,3,185},{14 ,12,144},{15 ,1,138},{16 ,3,152},{17 ,14,112},{18 ,12,215},{19 ,1,108},{20 ,3,187},{21 ,5,122},{22 ,12,47},{23 ,2,127},{24 ,3,178},{25 ,6,141},{26 ,2,131},{27 ,6,232},{28 ,4,43},{29 ,14,32},{30 ,10,199},{31 ,7,149},{32 ,12,110},{33 ,2,132},{34 ,7,237},{35 ,6,174},{36 ,14,207},{37 ,13,204},{38 ,9,90},{39 ,3,188},{40 ,8,103},{41 ,3,189},{42 ,4,170},{43 ,16,127},{44 ,7,211},{45 ,6,114},
+{0 ,2,126},{1 ,3,136},{2 ,2,225},{3 ,3,162},{4 ,26,0},{5 ,3,47},{6 ,10,23},{7 ,4,209},{8 ,3,141},{9 ,10,206},{10 ,4,70},{11 ,12,134},{12 ,10,124},{13 ,7,154},{14 ,15,182},{15 ,10,220},{16 ,11,84},{17 ,16,106},{18 ,13,180},{19 ,7,159},{20 ,9,203},{21 ,16,215},{22 ,13,126},{23 ,10,117},{24 ,4,2},{25 ,7,11},{26 ,4,169},{27 ,8,9},{28 ,19,200},{29 ,18,118},{30 ,13,26},{31 ,22,175},{32 ,14,151},{33 ,11,172},{34 ,15,142},{35 ,12,145},{36 ,15,42},{37 ,23,161},{38 ,10,26},{39 ,7,168},{40 ,17,30},{41 ,9,215},{42 ,24,71},{43 ,18,49},{44 ,9,187},{45 ,10,93},
+{0 ,3,134},{1 ,4,221},{2 ,4,151},{3 ,4,220},{0 ,0,-1},{5 ,12,143},{6 ,11,100},{7 ,7,32},{8 ,12,223},{9 ,11,221},{10 ,7,230},{11 ,16,1},{12 ,11,180},{13 ,20,178},{14 ,16,95},{15 ,13,173},{16 ,20,5},{17 ,17,219},{18 ,18,143},{19 ,8,138},{20 ,11,167},{21 ,20,65},{22 ,17,178},{23 ,18,199},{24 ,11,156},{25 ,14,181},{26 ,15,98},{27 ,49,0},{28 ,21,205},{29 ,25,103},{30 ,24,105},{31 ,25,108},{32 ,24,211},{33 ,21,65},{34 ,17,180},{35 ,22,100},{36 ,18,100},{37 ,59,0},{38 ,12,140},{39 ,19,52},{40 ,62,0},{41 ,18,24},{42 ,64,0},{43 ,25,125},{44 ,22,148},{45 ,67,0},
+{0 ,5,84},{1 ,5,128},{2 ,5,236},{3 ,6,43},{0 ,0,-1},{5 ,16,210},{6 ,13,92},{7 ,8,166},{8 ,16,177},{9 ,13,17},{10 ,8,115},{11 ,21,152},{12 ,13,98},{13 ,23,150},{14 ,17,72},{15 ,18,142},{16 ,22,205},{17 ,21,129},{18 ,19,14},{19 ,10,196},{20 ,22,130},{21 ,21,216},{22 ,44,0},{23 ,45,0},{24 ,22,58},{25 ,47,0},{26 ,48,0},{0 ,0,-1},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{0 ,0,-1},{38 ,60,0},{39 ,61,0},{0 ,0,-1},{41 ,63,0},{0 ,0,-1},{43 ,65,0},{44 ,66,0},{0 ,0,-1},
+{0 ,6,83},{1 ,7,92},{2 ,6,117},{3 ,7,186},{0 ,0,-1},{5 ,21,180},{6 ,17,207},{7 ,14,18},{8 ,19,145},{9 ,17,212},{10 ,14,84},{11 ,22,165},{12 ,18,80},{13 ,35,0},{14 ,21,76},{15 ,25,49},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{0 ,0,-1},{0 ,0,-1},{24 ,46,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,9,53},{1 ,8,172},{2 ,7,179},{3 ,8,96},{0 ,0,-1},{5 ,22,180},{6 ,18,52},{7 ,29,0},{8 ,21,199},{9 ,18,92},{10 ,32,0},{11 ,23,107},{12 ,34,0},{0 ,0,-1},{14 ,36,0},{15 ,37,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,10,225},{1 ,9,56},{2 ,8,92},{3 ,10,1},{0 ,0,-1},{5 ,27,0},{6 ,20,13},{0 ,0,-1},{8 ,22,153},{9 ,20,205},{0 ,0,-1},{11 ,33,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,11,205},{1 ,11,11},{2 ,9,24},{3 ,11,216},{0 ,0,-1},{0 ,0,-1},{6 ,28,0},{0 ,0,-1},{8 ,24,38},{9 ,31,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,12,128},{1 ,12,189},{2 ,10,68},{3 ,12,22},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{8 ,30,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,13,75},{1 ,14,95},{2 ,13,6},{3 ,13,24},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,15,135},{1 ,15,85},{2 ,14,101},{3 ,14,167},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,16,217},{1 ,16,153},{2 ,15,33},{3 ,16,200},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,18,220},{1 ,17,87},{2 ,17,96},{3 ,17,32},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,19,90},{1 ,19,163},{2 ,18,125},{3 ,18,235},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,20,105},{1 ,21,216},{2 ,19,67},{3 ,20,172},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,21,137},{1 ,22,0},{2 ,20,230},{3 ,21,219},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,22,1},{1 ,23,0},{2 ,24,0},{3 ,22,1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{0 ,23,0},{1 ,24,0},{2 ,25,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+};
+
+
+h_element host_h_compact2_I7 [68*30] =
+{{0 ,0,135},{0 ,1,227},{0 ,2,126},{0 ,3,134},{1 ,4,221},{0 ,5,84},{0 ,6,83},{1 ,7,92},{1 ,8,172},{0 ,9,53},{0 ,10,225},{0 ,11,205},{0 ,12,128},{0 ,13,75},{1 ,14,95},{0 ,15,135},{0 ,16,217},{1 ,17,87},{0 ,18,220},{0 ,19,90},{0 ,20,105},{0 ,21,137},{0 ,22,1},{0 ,23,0},{1 ,24,0},{2 ,25,0},{4 ,26,0},{5 ,27,0},{6 ,28,0},{7 ,29,0},{8 ,30,0},{9 ,31,0},{10 ,32,0},{11 ,33,0},{12 ,34,0},{13 ,35,0},{14 ,36,0},{15 ,37,0},{16 ,38,0},{17 ,39,0},{18 ,40,0},{19 ,41,0},{20 ,42,0},{21 ,43,0},{22 ,44,0},{23 ,45,0},{24 ,46,0},{25 ,47,0},{26 ,48,0},{27 ,49,0},{28 ,50,0},{29 ,51,0},{30 ,52,0},{31 ,53,0},{32 ,54,0},{33 ,55,0},{34 ,56,0},{35 ,57,0},{36 ,58,0},{37 ,59,0},{38 ,60,0},{39 ,61,0},{40 ,62,0},{41 ,63,0},{42 ,64,0},{43 ,65,0},{44 ,66,0},{45 ,67,0},
+{1 ,0,96},{2 ,1,4},{1 ,2,236},{1 ,3,136},{2 ,4,151},{1 ,5,128},{2 ,6,117},{2 ,7,179},{2 ,8,92},{1 ,9,56},{2 ,10,68},{1 ,11,11},{1 ,12,189},{2 ,13,6},{2 ,14,101},{1 ,15,85},{1 ,16,153},{2 ,17,96},{2 ,18,125},{1 ,19,163},{2 ,20,230},{1 ,21,216},{1 ,22,0},{1 ,23,0},{2 ,24,0},{3 ,25,0},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{2 ,0,189},{3 ,1,23},{2 ,2,225},{3 ,3,162},{3 ,4,220},{2 ,5,236},{3 ,6,43},{3 ,7,186},{3 ,8,96},{2 ,9,24},{3 ,10,1},{3 ,11,216},{3 ,12,22},{3 ,13,24},{3 ,14,167},{2 ,15,33},{3 ,16,200},{3 ,17,32},{3 ,18,235},{2 ,19,67},{3 ,20,172},{3 ,21,219},{3 ,22,1},{11 ,23,107},{8 ,24,38},{15 ,25,49},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{3 ,0,128},{4 ,1,211},{10 ,2,151},{5 ,3,47},{7 ,4,209},{21 ,5,122},{6 ,6,22},{7 ,7,32},{7 ,8,166},{20 ,9,203},{6 ,10,23},{6 ,11,100},{5 ,12,143},{6 ,13,92},{7 ,14,18},{14 ,15,182},{5 ,16,210},{6 ,17,207},{6 ,18,52},{8 ,19,145},{6 ,20,13},{5 ,21,180},{5 ,22,180},{13 ,23,150},{30 ,24,105},{29 ,25,103},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{4 ,0,64},{5 ,1,171},{23 ,2,127},{8 ,3,141},{10 ,4,70},{0 ,0,-1},{25 ,6,141},{10 ,7,230},{10 ,8,115},{38 ,9,90},{9 ,10,206},{9 ,11,221},{8 ,12,223},{9 ,13,17},{10 ,14,84},{26 ,15,98},{8 ,16,177},{9 ,17,212},{9 ,18,92},{18 ,19,14},{9 ,20,205},{8 ,21,199},{8 ,22,153},{37 ,23,161},{32 ,24,211},{31 ,25,108},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{5 ,0,2},{7 ,1,146},{26 ,2,131},{13 ,3,185},{24 ,4,2},{0 ,0,-1},{27 ,6,232},{13 ,7,154},{19 ,8,138},{41 ,9,215},{12 ,10,124},{12 ,11,180},{11 ,12,134},{12 ,13,98},{17 ,14,112},{34 ,15,142},{11 ,16,1},{14 ,17,72},{12 ,18,80},{28 ,19,200},{13 ,20,178},{11 ,21,152},{11 ,22,165},{0 ,0,-1},{42 ,24,71},{43 ,25,125},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{6 ,0,199},{8 ,1,105},{33 ,2,132},{16 ,3,152},{26 ,4,169},{0 ,0,-1},{35 ,6,174},{19 ,7,159},{27 ,8,9},{44 ,9,187},{15 ,10,220},{16 ,11,84},{14 ,12,144},{15 ,13,173},{25 ,14,181},{36 ,15,42},{14 ,16,95},{17 ,17,219},{15 ,18,142},{39 ,19,52},{16 ,20,5},{14 ,21,76},{16 ,22,205},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{7 ,0,77},{9 ,1,12},{0 ,0,-1},{20 ,3,187},{28 ,4,43},{0 ,0,-1},{45 ,6,114},{25 ,7,11},{40 ,8,103},{0 ,0,-1},{19 ,10,196},{20 ,11,167},{18 ,12,215},{18 ,13,180},{29 ,14,32},{0 ,0,-1},{17 ,16,106},{22 ,17,178},{18 ,18,143},{0 ,0,-1},{21 ,20,65},{17 ,21,129},{20 ,22,130},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{8 ,0,181},{10 ,1,116},{0 ,0,-1},{24 ,3,178},{42 ,4,170},{0 ,0,-1},{0 ,0,-1},{31 ,7,149},{0 ,0,-1},{0 ,0,-1},{23 ,10,117},{24 ,11,156},{22 ,12,47},{22 ,13,126},{32 ,14,151},{0 ,0,-1},{21 ,16,215},{34 ,17,180},{23 ,18,199},{0 ,0,-1},{0 ,0,-1},{21 ,21,216},{24 ,22,58},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{9 ,0,169},{11 ,1,115},{0 ,0,-1},{39 ,3,188},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{34 ,7,237},{0 ,0,-1},{0 ,0,-1},{30 ,10,199},{33 ,11,172},{32 ,12,110},{30 ,13,26},{36 ,14,207},{0 ,0,-1},{43 ,16,127},{40 ,17,30},{29 ,18,118},{0 ,0,-1},{0 ,0,-1},{28 ,21,205},{31 ,22,175},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{11 ,0,45},{12 ,1,215},{0 ,0,-1},{41 ,3,189},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{39 ,7,168},{0 ,0,-1},{0 ,0,-1},{38 ,10,26},{0 ,0,-1},{35 ,12,145},{37 ,13,204},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{36 ,18,100},{0 ,0,-1},{0 ,0,-1},{33 ,21,65},{35 ,22,100},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{12 ,0,186},{15 ,1,138},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,7,211},{0 ,0,-1},{0 ,0,-1},{45 ,10,93},{0 ,0,-1},{38 ,12,140},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{41 ,18,24},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{44 ,22,148},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{13 ,0,220},{16 ,1,78},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{43 ,18,49},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{14 ,0,124},{18 ,1,183},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{15 ,0,39},{19 ,1,108},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{17 ,0,183},{21 ,1,197},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{19 ,0,179},{23 ,1,185},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{20 ,0,77},{25 ,1,27},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{22 ,0,25},{27 ,1,165},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{24 ,0,32},{29 ,1,232},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{26 ,0,163},{31 ,1,73},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{28 ,0,32},{33 ,1,199},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{30 ,0,170},{35 ,1,231},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{32 ,0,103},{37 ,1,59},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{34 ,0,161},{39 ,1,115},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{36 ,0,11},{41 ,1,53},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{38 ,0,121},{43 ,1,22},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{40 ,0,4},{45 ,1,177},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{42 ,0,222},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},
+{44 ,0,191},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1},{0 ,0,-1}
+};
\ No newline at end of file
diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
index 161b3624d3..931d500338 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
+++ b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
@@ -32,7 +32,7 @@
#include "bgs/BG2_I6"
#include "bgs/BG2_I7"
-#define MAX_ITERATION 5
+#define MAX_ITERATION 2
#define MC 1
#define cudaCheck(ans) { cudaAssert((ans), __FILE__, __LINE__); }
@@ -49,13 +49,21 @@ typedef struct{
char y;
short value;
} h_element;
+#include "bgs/BG1_compact_in_C.h"
+__device__ char dev_const_llr[68*384];
+__device__ char dev_dt [46*68*384];
+__device__ char dev_llr[68*384];
+__device__ unsigned char dev_tmp[68*384];
h_element h_compact1 [46*19] = {};
h_element h_compact2 [68*30] = {};
-__device__ __constant__ h_element dev_h_compact1[46*19]; // used in kernel 1
-__device__ __constant__ h_element dev_h_compact2[68*30]; // used in kernel 2
+__device__ h_element dev_h_compact1[46*19]; // used in kernel 1
+__device__ h_element dev_h_compact2[68*30]; // used in kernel 2
+
+// __device__ __constant__ h_element dev_h_compact1[46*19]; // used in kernel 1
+// __device__ __constant__ h_element dev_h_compact2[68*30]; // used in kernel 2
// row and col element count
__device__ __constant__ char h_ele_row_bg1_count[46] = {
@@ -92,9 +100,93 @@ __global__ void warmup()
// warm up gpu for time measurement
}
+extern "C"
+void warmup_for_GPU(){
+
+ warmup<<<20,1024 >>>();
+
+}
+
+extern "C"
+void set_compact_BG(int Zc,short BG){
+
+ int row,col;
+ if(BG == 1){
+ row = 46;
+ col = 68;
+ }
+ else{
+ row = 42;
+ col = 52;
+ }
+ int compact_row = 30;
+ int compact_col = 19;
+ if(BG==2){compact_row = 10, compact_col = 23;}
+ int memorySize_h_compact1 = row * compact_col * sizeof(h_element);
+ int memorySize_h_compact2 = compact_row * col * sizeof(h_element);
+ int lift_index = 0;
+ short lift_set[][9] = {
+ {2,4,8,16,32,64,128,256},
+ {3,6,12,24,48,96,192,384},
+ {5,10,20,40,80,160,320},
+ {7,14,28,56,112,224},
+ {9,18,36,72,144,288},
+ {11,22,44,88,176,352},
+ {13,26,52,104,208},
+ {15,30,60,120,240},
+ {0}
+ };
+
+ for(int i = 0; lift_set[i][0] != 0; i++){
+ for(int j = 0; lift_set[i][j] != 0; j++){
+ if(Zc == lift_set[i][j]){
+ lift_index = i;
+ break;
+ }
+ }
+ }
+ printf("\nZc = %d BG = %d\n",Zc,BG);
+ switch(lift_index){
+ case 0:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I0, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I0, memorySize_h_compact2) );
+ break;
+ case 1:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I1, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I1, memorySize_h_compact2) );
+ break;
+ case 2:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I2, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I2, memorySize_h_compact2) );
+ break;
+ case 3:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I3, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I3, memorySize_h_compact2) );
+ break;
+ case 4:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I4, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I4, memorySize_h_compact2) );
+ break;
+ case 5:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I5, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I5, memorySize_h_compact2) );
+ break;
+ case 6:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I6, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I6, memorySize_h_compact2) );
+ break;
+ case 7:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I7, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I7, memorySize_h_compact2) );
+ break;
+ }
+
+ // return 0;
+}
+
// Kernel 1
-__global__ void ldpc_cnp_kernel_1st_iter(char * dev_llr, char * dev_dt, int BG, int row, int col, int Zc)
+__global__ void ldpc_cnp_kernel_1st_iter(/*char * dev_llr,*/ int BG, int row, int col, int Zc)
{
// if(blockIdx.x == 0 && threadIdx.x == 1) printf("cnp %d\n", threadIdx.x);
int iMCW = blockIdx.y; // codeword id
@@ -153,7 +245,7 @@ __global__ void ldpc_cnp_kernel_1st_iter(char * dev_llr, char * dev_dt, int BG,
for(int i = 0; i < s; i++){
// v0: Best performance so far. 0.75f is the value of alpha.
sq = 1 - 2 * ((Q_sign >> i) & 0x01);
- R_temp = 0.8 * sign * sq * (i != idx_min ? rmin1 : rmin2);
+ R_temp = 0.75f * sign * sq * (i != idx_min ? rmin1 : rmin2);
// write results to global memory
h_element_t = dev_h_compact1[i*row+iBlkRow];
int addr_temp = offsetR + h_element_t.y * row * Zc;
@@ -163,7 +255,7 @@ __global__ void ldpc_cnp_kernel_1st_iter(char * dev_llr, char * dev_dt, int BG,
}
// Kernel_1
-__global__ void ldpc_cnp_kernel(char * dev_llr, char * dev_dt, int BG, int row, int col, int Zc)
+__global__ void ldpc_cnp_kernel(/*char * dev_llr, char * dev_dt,*/ int BG, int row, int col, int Zc)
{
// if(blockIdx.x == 0 && threadIdx.x == 1) printf("cnp\n");
int iMCW = blockIdx.y;
@@ -223,7 +315,7 @@ __global__ void ldpc_cnp_kernel(char * dev_llr, char * dev_dt, int BG, int row,
// The 2nd recursion
for(int i = 0; i < s; i ++){
sq = 1 - 2 * ((Q_sign >> i) & 0x01);
- R_temp = 0.8 * sign * sq * (i != idx_min ? rmin1 : rmin2);
+ R_temp = 0.75f * sign * sq * (i != idx_min ? rmin1 : rmin2);
// write results to global memory
@@ -236,7 +328,7 @@ __global__ void ldpc_cnp_kernel(char * dev_llr, char * dev_dt, int BG, int row,
// Kernel 2: VNP processing
__global__ void
-ldpc_vnp_kernel_normal(char * dev_llr, char * dev_dt, char * dev_const_llr, int BG, int row, int col, int Zc)
+ldpc_vnp_kernel_normal(/*char * dev_llr, char * dev_dt, char * dev_const_llr,*/ int BG, int row, int col, int Zc)
{
int iMCW = blockIdx.y;
int iBlkCol = blockIdx.x;
@@ -276,7 +368,7 @@ ldpc_vnp_kernel_normal(char * dev_llr, char * dev_dt, char * dev_const_llr, int
}
-__global__ void pack_decoded_bit(char *dev, unsigned char *host, int col, int Zc)
+__global__ void pack_decoded_bit(/*char *dev, unsigned char *host,*/ int col, int Zc)
{
__shared__ unsigned char tmp[128];
int iMCW = blockIdx.y;
@@ -284,15 +376,15 @@ __global__ void pack_decoded_bit(char *dev, unsigned char *host, int col, int Zc
int btid = threadIdx.x;
tmp[btid] = 0;
- if(dev[tid] < 0){
+ if(dev_llr[tid] < 0){
tmp[btid] = 1 << (7-(btid&7));
}
__syncthreads();
if(threadIdx.x < 16){
- host[iMCW * col*Zc + blockIdx.x*16+threadIdx.x] = 0;
+ dev_tmp[iMCW * col*Zc + blockIdx.x*16+threadIdx.x] = 0;
for(int i = 0; i < 8; i++){
- host[iMCW * col*Zc + blockIdx.x*16+threadIdx.x] += tmp[threadIdx.x*8+i];
+ dev_tmp[iMCW * col*Zc + blockIdx.x*16+threadIdx.x] += tmp[threadIdx.x*8+i];
}
}
}
@@ -369,18 +461,11 @@ void read_BG(int BG, int *h, int row, int col)
*/
}
-
extern "C"
-int32_t nrLDPC_decoder_LYC(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length, time_stats_t *time_decoder)
-{
- // alloc mem
- //unsigned char *decision = (unsigned char*)p_out;
-
- uint16_t Zc = p_decParams->Z;
- uint8_t BG = p_decParams->BG;
- uint8_t numMaxIter = p_decParams->numMaxIter;
- e_nrLDPC_outMode outMode = p_decParams->outMode;
+void init_LLR_DMA_for_CUDA(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length){
+ uint16_t Zc = p_decParams->Z;
+ uint8_t BG = p_decParams->BG;
uint8_t row,col;
if(BG == 1){
row = 46;
@@ -390,96 +475,41 @@ int32_t nrLDPC_decoder_LYC(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8
row = 42;
col = 52;
}
- int compact_row = 30, compact_col = 19, lift_index=0;;
- if(BG==2){compact_row = 10, compact_col = 23;}
+ unsigned char *hard_decision = (unsigned char*)p_out;
+ int memorySize_llr_cuda = col * Zc * sizeof(char) * MC;
+ cudaCheck( cudaMemcpyToSymbol(dev_const_llr, p_llr, memorySize_llr_cuda) );
+ cudaCheck( cudaMemcpyToSymbol(dev_llr, p_llr, memorySize_llr_cuda) );
+ cudaDeviceSynchronize();
- short lift_set[][9] = {
- {2,4,8,16,32,64,128,256},
- {3,6,12,24,48,96,192,384},
- {5,10,20,40,80,160,320},
- {7,14,28,56,112,224},
- {9,18,36,72,144,288},
- {11,22,44,88,176,352},
- {13,26,52,104,208},
- {15,30,60,120,240},
- {0}
- };
-
- for(int i = 0; lift_set[i][0] != 0; i++){
- for(int j = 0; lift_set[i][j] != 0; j++){
- if(Zc == lift_set[i][j]){
- lift_index = i;
- break;
- }
- }
+}
+
+extern "C"
+int32_t nrLDPC_decoder_LYC(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length, time_stats_t *time_decoder)
+{
+
+
+ uint16_t Zc = p_decParams->Z;
+ uint8_t BG = p_decParams->BG;
+ uint8_t numMaxIter = p_decParams->numMaxIter;
+ e_nrLDPC_outMode outMode = p_decParams->outMode;
+ cudaError_t cudaStatus;
+ uint8_t row,col;
+ if(BG == 1){
+ row = 46;
+ col = 68;
}
-
- int *h = NULL;
- switch(lift_index){
- case 0:
- h = (BG == 1)? h_base_0:h_base_8;
- break;
- case 1:
- h = (BG == 1)? h_base_1:h_base_9;
- break;
- case 2:
- h = (BG == 1)? h_base_2:h_base_10;
- break;
- case 3:
- h = (BG == 1)? h_base_3:h_base_11;
- break;
- case 4:
- h = (BG == 1)? h_base_4:h_base_12;
- break;
- case 5:
- h = (BG == 1)? h_base_5:h_base_13;
- break;
- case 6:
- h = (BG == 1)? h_base_6:h_base_14;
- break;
- case 7:
- h = (BG == 1)? h_base_7:h_base_15;
- break;
+ else{
+ row = 42;
+ col = 52;
}
- /* pack BG in compact graph */
- read_BG(BG, h, row, col);
-
-
- int memorySize_h_compact1 = row * compact_col * sizeof(h_element);
- int memorySize_h_compact2 = compact_row * col * sizeof(h_element);
-// cpu
- int memorySize_hard_decision = col * Zc * sizeof(unsigned char) * MC;
-
-
// alloc memory
unsigned char *hard_decision = (unsigned char*)p_out;
-
// gpu
int memorySize_llr_cuda = col * Zc * sizeof(char) * MC;
- int memorySize_dt_cuda = row * Zc * col * sizeof(char) * MC;
-
-
-// alloc memory
- char *dev_llr;
- char *dev_dt;
- char *dev_const_llr;
- unsigned char *dev_tmp;
+ cudaCheck( cudaMemcpyToSymbol(dev_const_llr, p_llr, memorySize_llr_cuda) );
+ cudaCheck( cudaMemcpyToSymbol(dev_llr, p_llr, memorySize_llr_cuda) );
- cudaCheck( cudaMalloc((void **)&dev_tmp, memorySize_hard_decision) );
- cudaCheck( cudaMalloc((void **)&dev_llr, memorySize_llr_cuda) );
- cudaCheck( cudaMalloc((void **)&dev_const_llr, memorySize_llr_cuda) );
- cudaCheck( cudaMalloc((void **)&dev_dt, memorySize_dt_cuda) );
-
-// memcpy host to device
-
- cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, h_compact1, memorySize_h_compact1) );
- cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, h_compact2, memorySize_h_compact2) );
- cudaCheck( cudaMemcpy((void*)dev_const_llr, p_llr, memorySize_llr_cuda, cudaMemcpyHostToDevice) );
-start_meas(time_decoder);
- cudaCheck( cudaMemcpy((void*)dev_llr, p_llr, memorySize_llr_cuda, cudaMemcpyHostToDevice) );
-
-
// Define CUDA kernel dimension
int blockSizeX = Zc;
dim3 dimGridKernel1(row, MC, 1); // dim of the thread blocks
@@ -488,61 +518,35 @@ start_meas(time_decoder);
dim3 dimGridKernel2(col, MC, 1);
dim3 dimBlockKernel2(blockSizeX, 1, 1);
cudaDeviceSynchronize();
-
- cudaEvent_t start, end;
- float time;
- warmup<<>>();
- warmup<<>>();
-
-
- cudaEventCreate(&start);
- cudaEventCreate(&end);
- cudaEventRecord(start, 0);
-
-// cudaProfilerStart();
-
// lauch kernel
+
for(int ii = 0; ii < MAX_ITERATION; ii++){
// first kernel
if(ii == 0){
ldpc_cnp_kernel_1st_iter
<<>>
- (dev_llr, dev_dt, BG, row, col, Zc);
+ (/*dev_llr,*/ BG, row, col, Zc);
}else{
ldpc_cnp_kernel
<<>>
- (dev_llr, dev_dt, BG, row, col, Zc);
+ (/*dev_llr,*/ BG, row, col, Zc);
}
-
// second kernel
-
- ldpc_vnp_kernel_normal
- <<>>
- (dev_llr, dev_dt, dev_const_llr, BG, row, col, Zc);
-
+ ldpc_vnp_kernel_normal
+ <<>>
+ // (dev_llr, dev_const_llr,BG, row, col, Zc);
+ (BG, row, col, Zc);
}
+
int pack = (block_length/128)+1;
dim3 pack_block(pack, MC, 1);
- pack_decoded_bit<<>>(dev_llr, dev_tmp, col, Zc);
-
-
- cudaEventRecord(end, 0);
- cudaEventSynchronize(end);
- cudaEventElapsedTime(&time, start, end);
+ pack_decoded_bit<<>>(/*dev_llr,*/ /*dev_tmp,*/ col, Zc);
-
- //cudaCheck( cudaMemcpy((*)hard_decision, (const void*)dev_tmp, memorySize_hard_decision, cudaMemcpyDeviceToHost) );
- cudaCheck( cudaMemcpy((void*)hard_decision, (const void*)dev_tmp, (block_length/8)*sizeof(unsigned char), cudaMemcpyDeviceToHost) );
+ cudaCheck( cudaMemcpyFromSymbol((void*)hard_decision, (const void*)dev_tmp, (block_length/8)*sizeof(unsigned char)) );
cudaDeviceSynchronize();
-stop_meas(time_decoder);
- cudaCheck( cudaFree(dev_llr) );
- cudaCheck( cudaFree(dev_dt) );
- cudaCheck( cudaFree(dev_const_llr) );
- cudaCheck( cudaFree(dev_tmp) );
-
- //free(hard_decision);
+
return MAX_ITERATION;
}
diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h
index 0e78f988ba..c290cedf7d 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h
@@ -23,4 +23,12 @@
int32_t nrLDPC_decoder_LYC(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length, time_stats_t *time_decoder);
+
+void init_LLR_DMA_for_CUDA(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length);
+
+void warmup_for_GPU(void);
+
+void set_compact_BG(int Zc, short BG);
+
+
#endif
diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c
index f315365127..a16a8d100f 100644
--- a/openair1/PHY/CODING/nr_rate_matching.c
+++ b/openair1/PHY/CODING/nr_rate_matching.c
@@ -236,13 +236,12 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f)
}
*/
- int j2=0;
fp=f;
switch (Qm) {
case 2:
e0=e;
e1=e0+EQm;
- for (int j = 0; j< EQm; j++,j2+=2){
+ for (int j = 0, j2 = 0; j< EQm; j++,j2+=2){
fp=&f[j2];
fp[0] = e0[j];
fp[1] = e1[j];
@@ -253,7 +252,7 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f)
e1=e0+EQm;
e2=e1+EQm;
e3=e2+EQm;
- for (int j = 0; j< EQm; j++,j2+=4){
+ for (int j = 0, j2 = 0; j< EQm; j++,j2+=4){
fp=&f[j2];
fp[0] = e0[j];
fp[1] = e1[j];
@@ -287,7 +286,7 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f)
e5=e4+EQm;
e6=e5+EQm;
e7=e6+EQm;
- for (int j = 0; j< EQm; j++,j2+=8){
+ for (int j = 0, j2 = 0; j< EQm; j++,j2+=8){
fp=&f[j2];
fp[0] = e0[j];
fp[1] = e1[j];
@@ -310,7 +309,6 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f)
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f)
{
- int j2;
int16_t *e1,*e2,*e3,*e4,*e5,*e6,*e7;
switch(Qm) {
case 2:
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 2d65521ab3..2c7e3e88eb 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -275,6 +275,7 @@ void phy_config_request(PHY_Config_t *phy_config) {
fp->soundingrs_ul_config_common.srs_MaxUpPts = cfg->srs_config.max_up_pts.value;
fp->num_MBSFN_config = 0;
fp->NonMBSFN_config_flag =cfg->fembms_config.non_mbsfn_config_flag.value;
+ fp->FeMBMS_active = fp->NonMBSFN_config_flag;
fp->NonMBSFN_config.non_mbsfn_SubframeConfig = cfg->fembms_config.non_mbsfn_subframeconfig.value;
fp->NonMBSFN_config.radioframeAllocationPeriod = cfg->fembms_config.radioframe_allocation_period.value;
fp->NonMBSFN_config.radioframeAllocationOffset = cfg->fembms_config.radioframe_allocation_offset.value;
diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c
index 082db61da9..64a5992a64 100644
--- a/openair1/PHY/INIT/lte_init_ue.c
+++ b/openair1/PHY/INIT/lte_init_ue.c
@@ -137,7 +137,7 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id,
if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
fp->MBSFN_config[i].fourFrames_flag = 0;
fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
- LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %d\n", i,
+ LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] oneFrame pattern is %d\n", i,
fp->MBSFN_config[i].mbsfn_SubframeConfig);
} else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
fp->MBSFN_config[i].fourFrames_flag = 1;
@@ -145,7 +145,7 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id,
mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]|
(mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
(mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
- LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %x\n", i,
+ LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] fourFrame pattern is %x\n", i,
fp->MBSFN_config[i].mbsfn_SubframeConfig);
}
}
@@ -212,7 +212,7 @@ void phy_config_sib1_fembms_ue(module_id_t Mod_id,int CC_id,
LTE_DL_FRAME_PARMS *fp = &ue->frame_parms;
if (nonMBSFN_SubframeConfig != NULL) {
- fp->NonMBSFN_config_flag = 0;
+ fp->NonMBSFN_config_flag = 1;
fp->NonMBSFN_config.radioframeAllocationPeriod=nonMBSFN_SubframeConfig->radioFrameAllocationPeriod_r14;
fp->NonMBSFN_config.radioframeAllocationOffset=nonMBSFN_SubframeConfig->radioFrameAllocationOffset_r14;
fp->NonMBSFN_config.non_mbsfn_SubframeConfig=(nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]>>7);
diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c
index 12a5646df6..f5b7a6c7e8 100644
--- a/openair1/PHY/INIT/lte_parms.c
+++ b/openair1/PHY/INIT/lte_parms.c
@@ -93,6 +93,11 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,
frame_parms->N_RBGS = 4;
frame_parms->N_RBG = 25;
+ frame_parms->ofdm_symbol_size_khz_1dot25 = 2*2*6144*osf;
+ frame_parms->first_carrier_offset_khz_1dot25 = frame_parms->ofdm_symbol_size_khz_1dot25 - 1800*2*2;
+ frame_parms->nb_prefix_samples_khz_1dot25>>=(2-log2_osf);
+ frame_parms->nb_prefix_samples0_khz_1dot25>>=(2-log2_osf);
+
break;
case 75:
@@ -104,6 +109,12 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,
frame_parms->nb_prefix_samples0=(frame_parms->nb_prefix_samples0*3)>>2;
frame_parms->N_RBGS = 4;
frame_parms->N_RBG = 25;
+
+ frame_parms->ofdm_symbol_size_khz_1dot25 = 2*6144*osf;
+ frame_parms->first_carrier_offset_khz_1dot25 = frame_parms->ofdm_symbol_size_khz_1dot25 - 1800*2;
+ frame_parms->nb_prefix_samples_khz_1dot25>>=(2-log2_osf);
+ frame_parms->nb_prefix_samples0_khz_1dot25>>=(2-log2_osf);
+
break;
case 50:
@@ -115,6 +126,10 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,
frame_parms->nb_prefix_samples0>>=(1-log2_osf);
frame_parms->N_RBGS = 3;
frame_parms->N_RBG = 17;
+ frame_parms->ofdm_symbol_size_khz_1dot25 = 2*6144*osf;
+ frame_parms->first_carrier_offset_khz_1dot25 = frame_parms->ofdm_symbol_size_khz_1dot25 - 1800*2;
+ frame_parms->nb_prefix_samples_khz_1dot25>>=(2-log2_osf);
+ frame_parms->nb_prefix_samples0_khz_1dot25>>=(2-log2_osf);
break;
case 25:
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 0cfda8481e..057d259baa 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -27,6 +27,7 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
+#include "openair1/PHY/MODULATION/nr_modulation.h"
/*#include "RadioResourceConfigCommonSIB.h"
#include "RadioResourceConfigDedicated.h"
#include "TDD-Config.h"
@@ -132,6 +133,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
}
}
+ nr_generate_modulation_table();
nr_init_pdcch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
//PDSCH DMRS init
@@ -249,10 +251,11 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
pusch_vars[ULSCH_id]->ul_ch_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ptrs_phase_per_slot = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->ul_ch_estimates_time = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->rxdataF_comp = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
- pusch_vars[ULSCH_id]->ul_ch_mag0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
- pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_mag0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->rho = (int32_t **)malloc16_clear(Prx*sizeof(int32_t*) );
@@ -266,16 +269,18 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
pusch_vars[ULSCH_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot );
+ pusch_vars[ULSCH_id]->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot); // symbols per slot
pusch_vars[ULSCH_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
- pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
- pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
+ pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
+ pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
pusch_vars[ULSCH_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
}
printf("ULSCH_id %d (before llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
- printf("ULSCH_id %d (after llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
+ printf("ULSCH_id %d (after llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
+ pusch_vars[ULSCH_id]->ul_valid_re_per_slot = (int16_t *)malloc16_clear( sizeof(int16_t)*fp->symbols_per_slot);
} //ulsch_id
/*
for (ulsch_id=0; ulsch_idul_ch_estimates_time[i]);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i]);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ptrs_phase_per_slot[i]);
free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp[i]);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0[i]);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0[i]);
@@ -351,6 +357,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time);
+ free_and_zero(pusch_vars[ULSCH_id]->ptrs_phase_per_slot);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_valid_re_per_slot);
free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0);
@@ -495,6 +503,9 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
compute_nr_prach_seq(short_sequence, num_sequences, rootSequenceIndex, RC.gNB[Mod_id]->X_u);
RC.gNB[Mod_id]->configured = 1;
+
+ init_symbol_rotation(fp,fp->dl_CarrierFreq);
+
LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 1729ac0d9e..39e99e6ec3 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -39,6 +39,7 @@
#include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
+#include "PHY/NR_REFSIG/nr_refsig.h"
//uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10};
@@ -642,10 +643,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
// create shortcuts
NR_DL_FRAME_PARMS *const fp = &ue->frame_parms;
NR_UE_COMMON *const common_vars = &ue->common_vars;
- NR_UE_PDSCH **const pdsch_vars_SI = ue->pdsch_vars_SI;
- NR_UE_PDSCH **const pdsch_vars_ra = ue->pdsch_vars_ra;
- NR_UE_PDSCH **const pdsch_vars_p = ue->pdsch_vars_p;
- NR_UE_PDSCH **const pdsch_vars_mch = ue->pdsch_vars_MCH;
NR_UE_PBCH **const pbch_vars = ue->pbch_vars;
NR_UE_PRACH **const prach_vars = ue->prach_vars;
int i,j,k,l,slot,symb,q;
@@ -681,6 +678,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->bitrate[eNB_id] = 0;
ue->total_received_bits[eNB_id] = 0;
}
+ // init NR modulation lookup tables
+ nr_generate_modulation_table();
/////////////////////////PUSCH init/////////////////////////
///////////
@@ -796,10 +795,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->pdcch_vars[th_id][eNB_id] = (NR_UE_PDCCH *)malloc16_clear(sizeof(NR_UE_PDCCH));
}
- pdsch_vars_SI[eNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH));
- pdsch_vars_ra[eNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH));
- pdsch_vars_p[eNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH));
- pdsch_vars_mch[eNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH));
prach_vars[eNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH));
pbch_vars[eNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH));
@@ -861,11 +856,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
}
}
- phy_init_nr_ue__PDSCH( pdsch_vars_SI[eNB_id], fp );
- phy_init_nr_ue__PDSCH( pdsch_vars_ra[eNB_id], fp );
- phy_init_nr_ue__PDSCH( pdsch_vars_p[eNB_id], fp );
- phy_init_nr_ue__PDSCH( pdsch_vars_mch[eNB_id], fp );
-
// 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
for (th_id=0; th_idpdcch_vars[th_id][eNB_id]->llr = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
@@ -929,10 +919,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->pdsch_vars[th_id][eNB_id] = (NR_UE_PDSCH *)malloc16_clear( sizeof(NR_UE_PDSCH) );
}
- pdsch_vars_SI[eNB_id] = (NR_UE_PDSCH *)malloc16_clear( sizeof(NR_UE_PDSCH) );
- pdsch_vars_ra[eNB_id] = (NR_UE_PDSCH *)malloc16_clear( sizeof(NR_UE_PDSCH) );
- pdsch_vars_p[eNB_id] = (NR_UE_PDSCH *)malloc16_clear( sizeof(NR_UE_PDSCH) );
-
if (abstraction_flag == 0) {
for (th_id=0; th_idpdsch_vars[th_id][eNB_id], fp );
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
index 333a6f0866..4ad050ccea 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
@@ -22,7 +22,7 @@
/*! \file config_ue.c
* \brief This includes FeMBMS UE Channel Estimation Procedures for FeMBMS 1.25KHz Carrier Spacing
* \author Javier Morgade
- * \date 2019
+ * \date 2020
* \version 0.1
* \email: javier.morgade@ieee.org
* @ingroup _phy
@@ -768,8 +768,8 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue,
module_id_t eNB_id,
uint8_t eNB_offset,
int subframe) {
- int pilot_khz_1dot25[600] __attribute__((aligned(16)));
- unsigned char aarx/*,aa*/;
+ int pilot_khz_1dot25[2*2*600] __attribute__((aligned(16)));
+ unsigned char aarx,aa;
//unsigned int rb;
int16_t ch[2];
short *pil,*rxF,*dl_ch/*,*ch0,*ch1,*ch11,*chp,*ch_prev*/;
@@ -783,7 +783,7 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue,
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
ch_offset = 0;//(l*(ue->frame_parms.ofdm_symbol_size));
symbol_offset = 0;//ch_offset;//phy_vars_ue->lte_frame_parms.ofdm_symbol_size*l;
- AssertFatal( ue->frame_parms.N_RB_DL==25,"OFDM symbol size %d not yet supported for FeMBMS\n",ue->frame_parms.N_RB_DL);
+ //AssertFatal( ue->frame_parms.N_RB_DL==25,"OFDM symbol size %d not yet supported for FeMBMS\n",ue->frame_parms.N_RB_DL);
if( (subframe&0x1) == 0) {
f=filt24_0_khz_1dot25;
@@ -823,7 +823,7 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue,
k=3;
}
- if(ue->frame_parms.N_RB_DL==25) {
+ if(1/*ue->frame_parms.N_RB_DL==25*/) {
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(fl,
@@ -843,7 +843,7 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue,
rxF+=12;
dl_ch+=16;
- for(pilot_cnt=2; pilot_cnt<299; pilot_cnt+=2) {
+ for(pilot_cnt=2; pilot_cntframe_parms.N_RB_DL*12-1/*299*/; pilot_cnt+=2) {
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(f,
@@ -866,7 +866,7 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue,
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))]; //Skip DC offset
- for(pilot_cnt=0; pilot_cnt<297; pilot_cnt+=2) {
+ for(pilot_cnt=0; pilot_cntframe_parms.N_RB_DL*12-3/*297*/; pilot_cnt+=2) {
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(f,
@@ -905,6 +905,32 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue,
}
}
+ // do ifft of channel estimate
+ for (aa=0; aaframe_parms.nb_antennas_rx*ue->frame_parms.nb_antennas_tx; aa++) {
+ if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0][aa]) {
+ switch (ue->frame_parms.N_RB_DL) {
+ case 25:
+ idft(IDFT_6144,(int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0][aa][8],
+ (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[0][aa],
+ 1);
+ break;
+ case 50:
+ idft(IDFT_12288,(int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0][aa][8],
+ (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[0][aa],
+ 1);
+ break;
+ case 100:
+ idft(IDFT_24576,(int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0][aa][8],
+ (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[0][aa],
+ 1);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+
return(0);
}
diff --git a/openair1/PHY/LTE_REFSIG/lte_refsig.h b/openair1/PHY/LTE_REFSIG/lte_refsig.h
index 45402436f7..84a2676082 100644
--- a/openair1/PHY/LTE_REFSIG/lte_refsig.h
+++ b/openair1/PHY/LTE_REFSIG/lte_refsig.h
@@ -106,6 +106,16 @@ int lte_dl_mbsfn(PHY_VARS_eNB *phy_vars_eNB, int32_t *output,
short amp,
int subframe,
unsigned char l);
+/*! \brief This function generates the 1.25KHz MBSFN reference signal sequence (36-211, Sec 6.10.1.2)
+@param phy_vars_eNB Pointer to eNB variables
+@param output Output vector for OFDM symbol (Frequency Domain)
+@param amp Q15 amplitude
+*/
+
+int lte_dl_mbsfn_khz_1dot25(PHY_VARS_eNB *phy_vars_eNB, int32_t *output,
+ short amp,
+ int subframe);
+
/*!\brief This function generates the cell-specific reference signal sequence (36-211, Sec 6.10.1.1) for channel estimation upon reception
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index 14036ad43a..3eb44d98fa 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -20,12 +20,12 @@
*/
/*! \file PHY/LTE_TRANSPORT/dlsch_coding.c
- * \brief Top-level routines for implementing Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03
- * \author R. Knopp
+ * \brief Top-level routines for implementing Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03, V14.1 2017 (includes FeMBMS support)
+ * \author R. Knopp, J. Morgade
* \date 2011
* \version 0.1
* \company Eurecom
- * \email: knopp@eurecom.fr
+ * \email: knopp@eurecom.fr, jaiver.morgade@ieee.org
* \note
* \warning
*/
@@ -425,3 +425,108 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0);
}
+
+int dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB,
+ L1_rxtx_proc_t *proc,
+ unsigned char *a,
+ uint8_t num_pdcch_symbols,
+ LTE_eNB_DLSCH_t *dlsch,
+ int frame,
+ uint8_t subframe,
+ time_stats_t *rm_stats,
+ time_stats_t *te_stats,
+ time_stats_t *i_stats) {
+ LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
+ unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe];
+ if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) {
+ LOG_E(PHY,"dlsch_encoding illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
+ return(-1);
+ }
+
+ LTE_DL_eNB_HARQ_t *hadlsch=dlsch->harq_processes[harq_pid];
+ uint8_t beamforming_mode=0;
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
+
+ if(hadlsch->mimo_mode == TM7)
+ beamforming_mode = 7;
+ else if(hadlsch->mimo_mode == TM8)
+ beamforming_mode = 8;
+ else if(hadlsch->mimo_mode == TM9_10)
+ beamforming_mode = 9;
+
+ unsigned int G = get_G_khz_1dot25(frame_parms,hadlsch->nb_rb,
+ hadlsch->rb_alloc,
+ hadlsch->Qm, // mod order
+ hadlsch->Nl,
+ num_pdcch_symbols,
+ frame,subframe,beamforming_mode);
+
+ proc->nbEncode=0;
+
+ // if (hadlsch->Ndi == 1) { // this is a new packet
+ if (hadlsch->round == 0) { // this is a new packet
+ // Add 24-bit crc (polynomial A) to payload
+ unsigned int A=hadlsch->TBS; //6228;
+ unsigned int crc = crc24a(a,
+ A)>>8;
+ a[A>>3] = ((uint8_t *)&crc)[2];
+ a[1+(A>>3)] = ((uint8_t *)&crc)[1];
+ a[2+(A>>3)] = ((uint8_t *)&crc)[0];
+ // printf("CRC %x (A %d)\n",crc,A);
+ hadlsch->B = A+24;
+ // hadlsch->b = a;
+ memcpy(hadlsch->b,a,(A/8)+4);
+
+ if (lte_segmentation(hadlsch->b,
+ hadlsch->c,
+ hadlsch->B,
+ &hadlsch->C,
+ &hadlsch->Cplus,
+ &hadlsch->Cminus,
+ &hadlsch->Kplus,
+ &hadlsch->Kminus,
+ &hadlsch->F)<0)
+ return(-1);
+ }
+
+ for (int r=0, r_offset=0; rC; r++) {
+
+ union turboReqUnion id= {.s={dlsch->rnti,frame,subframe,r,0}};
+ notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, proc->respEncode, TPencode);
+ turboEncode_t * rdata=(turboEncode_t *) NotifiedFifoData(req);
+ rdata->input=hadlsch->c[r];
+ rdata->Kr_bytes= ( rCminus ? hadlsch->Kminus : hadlsch->Kplus) >>3;
+ rdata->filler=(r==0) ? hadlsch->F : 0;
+ rdata->r=r;
+ rdata->harq_pid=harq_pid;
+ rdata->dlsch=dlsch;
+ rdata->rm_stats=rm_stats;
+ rdata->te_stats=te_stats;
+ rdata->i_stats=i_stats;
+ rdata->round=hadlsch->round;
+ rdata->r_offset=r_offset;
+ rdata->G=G;
+
+ if ( proc->threadPool->activated ) {
+ pushTpool(proc->threadPool,req);
+ proc->nbEncode++;
+ } else {
+ TPencode(rdata);
+ delNotifiedFIFO_elt(req);
+ }
+
+ int Qm=hadlsch->Qm;
+ int C=hadlsch->C;
+ int Nl=hadlsch->Nl;
+ int Gp = G/Nl/Qm;
+ int GpmodC = Gp%C;
+ if (r < (C-(GpmodC)))
+ r_offset += Nl*Qm * (Gp/C);
+ else
+ r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
+ }
+
+ return(0);
+}
+
+
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
index 475c8bd521..8c07421b7e 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
@@ -20,12 +20,12 @@
*/
/*! \file PHY/LTE_TRANSPORT/dlsch_modulation.c
- * \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03
- * \author R. Knopp, F. Kaltenberger
+ * \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03, V14.1 2017 (FeMBMS)
+ * \author R. Knopp, F. Kaltenberger, J. Morgade
* \date 2011
* \version 0.1
* \company Eurecom
- * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
+ * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, javier.morgade@ieee.irg
* \note
* \warning
*/
@@ -2910,3 +2910,260 @@ int mch_modulation(int32_t **txdataF,
return (re_allocated);
}
+
+int allocate_REs_in_RB_MCH_khz_1dot25(int32_t **txdataF,
+ uint32_t *jj,
+ uint16_t re_offset,
+ uint32_t symbol_offset,
+ uint8_t *x0,
+ uint8_t subframe,
+ uint8_t mod_order,
+ int16_t amp,
+ int16_t *qam_table_s,
+ uint32_t *re_allocated,
+ uint8_t skip_dc,
+ LTE_DL_FRAME_PARMS *frame_parms)
+{
+ uint32_t tti_offset;
+ uint8_t re,offset;
+ uint8_t qam64_table_offset_re = 0;
+ uint8_t qam64_table_offset_im = 0;
+ uint8_t qam16_table_offset_re = 0;
+ uint8_t qam16_table_offset_im = 0;
+ int16_t gain_lin_QPSK;//,gain_lin_16QAM1,gain_lin_16QAM2;
+ int16_t re_off=re_offset;
+ gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
+ uint8_t first_re,last_re;
+ int inc;
+#ifdef DEBUG_DLSCH_MODULATION
+ LOG_I(PHY,"allocate_re_MCH khz_1dot25 (mod %d): symbol_offset %d re_offset %d (%d), jj %d -> %d,%d, gain_lin_QPSK %d,txdataF %p\n",mod_order,symbol_offset,re_offset,skip_dc,*jj, x0[*jj], x0[1+*jj],gain_lin_QPSK,&txdataF[0][symbol_offset]);
+#endif
+
+ /*last_re=12;
+ first_re=0;
+ inc=1;
+
+ if ((l==2)||(l==10)) {
+ inc=2;
+ first_re=1;
+ } else if (l==6) {
+ inc=2;
+ }*/
+ last_re=144; //12*12
+ if ((subframe&0x1)==0){ // n_sf mod 2 == 0: even
+ first_re=1;
+ offset=0;
+ }else{
+ first_re=0;
+ offset=3;
+ }
+ inc=1;
+
+ for (re=first_re; reofdm_symbol_size_khz_1dot25+1;
+ }
+
+ tti_offset = symbol_offset + re_off + re;
+
+ //LOG_I(PHY,"re %d (jj %d)\n",re,*jj);
+ *re_allocated = *re_allocated + 1;
+
+
+ switch (mod_order) {
+
+ case 2: //QPSK
+
+ LOG_D(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+ ((int16_t*)&txdataF[0][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
+
+ *jj = *jj + 1;
+
+ ((int16_t*)&txdataF[0][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
+
+ *jj = *jj + 1;
+
+ LOG_D(PHY,"subframe%d alloc[%d][%d][%d](%d,%d)\n",subframe,tti_offset,symbol_offset,tti_offset-symbol_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+ break;
+
+
+ case 4: //16QAM
+
+ qam16_table_offset_re = 0;
+ qam16_table_offset_im = 0;
+
+ if (x0[*jj] == 1)
+ qam16_table_offset_re+=2;
+
+ *jj=*jj+1;
+
+ if (x0[*jj] == 1)
+ qam16_table_offset_im+=2;
+
+ *jj=*jj+1;
+
+
+ if (x0[*jj] == 1)
+ qam16_table_offset_re+=1;
+
+ *jj=*jj+1;
+
+ if (x0[*jj] == 1)
+ qam16_table_offset_im+=1;
+
+ *jj=*jj+1;
+
+
+ ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+ ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+
+ break;
+
+ case 6: //64QAM
+
+ qam64_table_offset_re = 0;
+ qam64_table_offset_im = 0;
+
+ if (x0[*jj] == 1)
+ qam64_table_offset_re+=4;
+
+ *jj=*jj+1;
+
+ if (x0[*jj] == 1)
+ qam64_table_offset_im+=4;
+
+ *jj=*jj+1;
+
+ if (x0[*jj] == 1)
+ qam64_table_offset_re+=2;
+
+ *jj=*jj+1;
+
+ if (x0[*jj] == 1)
+ qam64_table_offset_im+=2;
+
+ *jj=*jj+1;
+
+ if (x0[*jj] == 1)
+ qam64_table_offset_re+=1;
+
+ *jj=*jj+1;
+
+ if (x0[*jj] == 1)
+ qam64_table_offset_im+=1;
+
+ *jj=*jj+1;
+
+ ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+ ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+
+ break;
+
+ }
+ }
+ return(0);
+}
+
+int mch_modulation_khz_1dot25(int32_t **txdataF,
+ int16_t amp,
+ uint32_t subframe_offset,
+ LTE_DL_FRAME_PARMS *frame_parms,
+ LTE_eNB_DLSCH_t *dlsch)
+{
+ uint8_t nsymb,nsymb_pmch;
+ uint32_t i,jj,re_allocated,symbol_offset;
+ uint16_t l,rb,re_offset;
+ uint8_t skip_dc=0;
+ uint8_t mod_order = dlsch->harq_processes[0]->Qm;
+ int16_t qam16_table_a[4],qam64_table_a[8];//,qam16_table_b[4],qam64_table_b[8];
+ int16_t *qam_table_s;
+
+ nsymb_pmch = 1;
+ nsymb = (frame_parms->Ncp == NORMAL) ? 14 : 12;
+
+ if (mod_order == 4)
+ for (i=0; i<4; i++) {
+ qam16_table_a[i] = (int16_t)(((int32_t)qam16_table[i]*amp)>>15);
+ }
+ else if (mod_order == 6)
+ for (i=0; i<8; i++) {
+ qam64_table_a[i] = (int16_t)(((int32_t)qam64_table[i]*amp)>>15);
+ }
+
+ jj=0;
+ re_allocated=0;
+
+
+
+
+
+ // LOG_I(PHY,"num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb);
+ for (l=0; lfirst_carrier_offset_khz_1dot25;
+ symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb));
+
+ for (rb=0; rbN_RB_DL; rb++) {
+
+
+ if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL
+
+ if (rb==(frame_parms->N_RB_DL>>1))
+ skip_dc = 1;
+ else
+ skip_dc = 0;
+
+ }
+
+ if (mod_order == 4)
+ qam_table_s = qam16_table_a;
+ else if (mod_order == 6)
+ qam_table_s = qam64_table_a;
+ else
+ qam_table_s = NULL;
+
+ //LOG_I(PHY,"Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp);
+ allocate_REs_in_RB_MCH_khz_1dot25(txdataF,
+ &jj,
+ re_offset,
+ symbol_offset,
+ dlsch->harq_processes[0]->eDL,
+ subframe_offset,
+ mod_order,
+ amp,
+ qam_table_s,
+ &re_allocated,
+ skip_dc,
+ frame_parms);
+
+ re_offset+=144; // go to next RB 12*12
+
+ // check if we crossed the symbol boundary and skip DC
+ if (re_offset >= frame_parms->ofdm_symbol_size_khz_1dot25) {
+ if (skip_dc == 0) //even number of RBs (doesn't straddle DC)
+ re_offset=1;
+ else
+ re_offset=73; // odd number of RBs
+ }
+ }
+ }
+
+#ifdef DEBUG_DLSCH_MODULATION
+ LOG_I(PHY,"generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset,1/*transmission mode*/));
+ LOG_I(PHY,"generate_dlsch(MCH) : jj = %d,re_allocated = %d\n",jj,re_allocated);
+#endif
+
+ return (re_allocated);
+}
+
diff --git a/openair1/PHY/LTE_TRANSPORT/pbch.c b/openair1/PHY/LTE_TRANSPORT/pbch.c
index 37997c94b4..dfa990269e 100644
--- a/openair1/PHY/LTE_TRANSPORT/pbch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pbch.c
@@ -20,12 +20,12 @@
*/
/*! \file PHY/LTE_TRANSPORT/pbch.c
-* \brief Top-level routines for generating and decoding the PBCH/BCH physical/transport channel V8.6 2009-03
-* \author R. Knopp, F. Kaltenberger
+* \brief Top-level routines for generating and decoding the PBCH/BCH physical/transport channel V8.6 2009-03, V14.1 (FeMBMS)
+* \author R. Knopp, F. Kaltenberger, J. Morgade
* \date 2011
* \version 0.1
* \company Eurecom
-* \email: knopp@eurecom.fr,florian.kaltenberger.fr
+* \email: knopp@eurecom.fr,florian.kaltenberger.fr, javier.morgade@ieee.org
* \note
* \warning
*/
@@ -139,6 +139,285 @@ int allocate_pbch_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
return(0);
}
+void pbch_scrambling_fembms(LTE_DL_FRAME_PARMS *frame_parms,
+ uint8_t *pbch_e,
+ uint32_t length)
+{
+ int i;
+ uint8_t reset;
+ uint32_t x1, x2, s=0;
+
+ reset = 1;
+ // x1 is set in lte_gold_generic
+ x2 = frame_parms->Nid_cell + (1<<9); //this is c_init for FeMBMS in 36.211 Sec 6.6.1
+ // msg("pbch_scrambling: Nid_cell = %d\n",x2);
+
+ for (i=0; i>(i&0x1f))&1);
+
+ }
+}
+
+int generate_pbch_fembms(LTE_eNB_PBCH *eNB_pbch,
+ int32_t **txdataF,
+ int amp,
+ LTE_DL_FRAME_PARMS *frame_parms,
+ uint8_t *pbch_pdu,
+ uint8_t frame_mod4)
+{
+
+ int i, l;
+
+ uint32_t pbch_D,pbch_E;//,pbch_coded_bytes;
+ uint8_t pbch_a[PBCH_A>>3];
+ uint8_t RCC;
+
+ uint32_t nsymb = (frame_parms->Ncp==NORMAL) ? 14:12;
+ uint32_t pilots;
+#ifdef INTERFERENCE_MITIGATION
+ uint32_t pilots_2;
+#endif
+ uint32_t second_pilot = (frame_parms->Ncp==NORMAL) ? 4 : 3;
+ uint32_t jj=0;
+ uint32_t re_allocated=0;
+ uint32_t rb, re_offset, symbol_offset;
+ uint16_t amask=0;
+
+ pbch_D = 16+PBCH_A;
+
+ pbch_E = (frame_parms->Ncp==NORMAL) ? 1920 : 1728; //RE/RB * #RB * bits/RB (QPSK)
+ // pbch_E_bytes = pbch_coded_bits>>3;
+
+ LOG_D(PHY,"%s(eNB_pbch:%p txdataF:%p amp:%d frame_parms:%p pbch_pdu:%p frame_mod4:%d)\n", __FUNCTION__, eNB_pbch, txdataF, amp, frame_parms, pbch_pdu, frame_mod4==0);
+
+ if (frame_mod4==0) {
+ bzero(pbch_a,PBCH_A>>3);
+ bzero(eNB_pbch->pbch_e,pbch_E);
+ memset(eNB_pbch->pbch_d,LTE_NULL,96);
+ // Encode data
+
+ // CRC attachment
+ // crc = (uint16_t) (crc16(pbch_pdu, pbch_crc_bits-16) >> 16);
+
+ /*
+ // scramble crc with PBCH CRC mask (Table 5.3.1.1-1 of 3GPP 36.212-860)
+ switch (frame_parms->nb_antenna_ports_eNB) {
+ case 1:
+ crc = crc ^ (uint16_t) 0;
+ break;
+ case 2:
+ crc = crc ^ (uint16_t) 0xFFFF;
+ break;
+ case 4:
+ crc = crc ^ (uint16_t) 0xAAAA;
+ break;
+ default:
+ msg("[PBCH] Unknown number of TX antennas!\n");
+ break;
+ }
+ */
+
+ // Fix byte endian of PBCH (bit 23 goes in first)
+ for (i=0; i<(PBCH_A>>3); i++)
+ pbch_a[(PBCH_A>>3)-i-1] = pbch_pdu[i];
+
+ // pbch_data[i] = ((char*) &crc)[0];
+ // pbch_data[i+1] = ((char*) &crc)[1];
+ //#ifdef DEBUG_PBCH
+
+ for (i=0; i<(PBCH_A>>3); i++)
+ LOG_D(PHY,"[PBCH] pbch_data[%d] = %x\n",i,pbch_a[i]);
+
+ //#endif
+
+ if (frame_parms->nb_antenna_ports_eNB == 1)
+ amask = 0x0000;
+ else {
+ switch (frame_parms->nb_antenna_ports_eNB) {
+ case 1:
+ amask = 0x0000;
+ break;
+
+ case 2:
+ amask = 0xffff;
+ break;
+
+ case 4:
+ amask = 0x5555;
+ }
+ }
+
+ ccodelte_encode(PBCH_A,2,pbch_a,eNB_pbch->pbch_d+96,amask);
+
+
+#ifdef DEBUG_PBCH_ENCODING
+
+ for (i=0; i<16+PBCH_A; i++)
+ LOG_D(PHY,"%d : (%d,%d,%d)\n",i,*(eNB_pbch->pbch_d+96+(3*i)),*(eNB_pbch->pbch_d+97+(3*i)),*(eNB_pbch->pbch_d+98+(3*i)));
+
+#endif //DEBUG_PBCH_ENCODING
+
+ // Bit collection
+ /*
+ j2=0;
+ for (j=0;j 0) { // bit is to be transmitted
+ pbch_coded_data2[j2++] = pbch_coded_data[j]&1;
+ //Bit is repeated
+ if ((pbch_coded_data[j]&0x40)>0)
+ pbch_coded_data2[j2++] = pbch_coded_data[j]&1;
+ }
+ }
+
+ #ifdef DEBUG_PBCH
+ msg("[PBCH] rate matched bits=%d, pbch_coded_bits=%d, pbch_crc_bits=%d\n",j2,pbch_coded_bits,pbch_crc_bits);
+ #endif
+
+ #ifdef DEBUG_PBCH
+ LOG_M"pbch_encoded_output2.m","pbch_encoded_out2",
+ pbch_coded_data2,
+ pbch_coded_bits,
+ 1,
+ 4);
+ #endif //DEBUG_PBCH
+ */
+#ifdef DEBUG_PBCH_ENCODING
+ LOG_D(PHY,"Doing PBCH interleaving for %d coded bits, e %p\n",pbch_D,eNB_pbch->pbch_e);
+#endif
+ RCC = sub_block_interleaving_cc(pbch_D,eNB_pbch->pbch_d+96,eNB_pbch->pbch_w);
+
+ lte_rate_matching_cc(RCC,pbch_E,eNB_pbch->pbch_w,eNB_pbch->pbch_e);
+
+#ifdef DEBUG_PBCH_ENCODING
+ LOG_D(PHY,"PBCH_e:\n");
+
+ for (i=0; ipbch_e+i));
+
+ LOG_D(PHY,"\n");
+#endif
+
+
+
+#ifdef DEBUG_PBCH
+ if (frame_mod4==0) {
+ LOG_M("pbch_e.m","pbch_e",
+ eNB_pbch->pbch_e,
+ pbch_E,
+ 1,
+ 4);
+
+ for (i=0; i<16; i++)
+ printf("e[%d] %d\n",i,eNB_pbch->pbch_e[i]);
+ }
+#endif //DEBUG_PBCH
+ // scrambling
+
+ pbch_scrambling_fembms(frame_parms,
+ eNB_pbch->pbch_e,
+ pbch_E);
+#ifdef DEBUG_PBCH
+ if (frame_mod4==0) {
+ LOG_M("pbch_e_s.m","pbch_e_s",
+ eNB_pbch->pbch_e,
+ pbch_E,
+ 1,
+ 4);
+
+ for (i=0; i<16; i++)
+ printf("e_s[%d] %d\n",i,eNB_pbch->pbch_e[i]);
+ }
+#endif //DEBUG_PBCH
+ } // frame_mod4==0
+
+ // modulation and mapping (slot 1, symbols 0..3)
+ for (l=(nsymb>>1); l<(nsymb>>1)+4; l++) {
+
+ pilots=0;
+#ifdef INTERFERENCE_MITIGATION
+ pilots_2 = 0;
+#endif
+
+ if ((l==0) || (l==(nsymb>>1))) {
+ pilots=1;
+#ifdef INTERFERENCE_MITIGATION
+ pilots_2=1;
+#endif
+ }
+
+ if ((l==1) || (l==(nsymb>>1)+1)) {
+ pilots=1;
+ }
+
+ if ((l==second_pilot)||(l==(second_pilot+(nsymb>>1)))) {
+ pilots=1;
+ }
+
+#ifdef DEBUG_PBCH
+ LOG_D(PHY,"[PBCH] l=%d, pilots=%d\n",l,pilots);
+#endif
+
+
+ re_offset = frame_parms->ofdm_symbol_size-3*12;
+ symbol_offset = frame_parms->ofdm_symbol_size*l;
+
+ for (rb=0; rb<6; rb++) {
+
+#ifdef DEBUG_PBCH
+ LOG_D(PHY,"RB %d, jj %d, re_offset %d, symbol_offset %d, pilots %d, nushift %d\n",rb,jj,re_offset, symbol_offset, pilots,frame_parms->nushift);
+#endif
+ allocate_pbch_REs_in_RB(frame_parms,
+ txdataF,
+ &jj,
+ re_offset,
+ symbol_offset,
+ &eNB_pbch->pbch_e[frame_mod4*(pbch_E>>2)],
+ pilots,
+#ifdef INTERFERENCE_MITIGATION
+ (pilots_2==1)?(amp/3):amp,
+#else
+ amp,
+#endif
+ &re_allocated);
+
+ re_offset+=12; // go to next RB
+
+ // check if we crossed the symbol boundary and skip DC
+
+ if (re_offset >= frame_parms->ofdm_symbol_size)
+ re_offset=1;
+ }
+
+ // }
+ }
+
+#ifdef DEBUG_PBCH
+ printf("[PBCH] txdataF=\n");
+
+ for (i=0; iofdm_symbol_size; i++) {
+ printf("%d=>(%d,%d)",i,((short*)&txdataF[0][frame_parms->ofdm_symbol_size*(nsymb>>1)+i])[0],
+ ((short*)&txdataF[0][frame_parms->ofdm_symbol_size*(nsymb>>1)+i])[1]);
+
+ if (frame_parms->nb_antenna_ports_eNB!=1) {
+ printf("(%d,%d)\n",((short*)&txdataF[1][frame_parms->ofdm_symbol_size*(nsymb>>1)+i])[0],
+ ((short*)&txdataF[1][frame_parms->ofdm_symbol_size*(nsymb>>1)+i])[1]);
+ } else {
+ printf("\n");
+ }
+ }
+
+#endif
+
+
+ return(0);
+}
+
void pbch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t *pbch_e,
uint32_t length)
diff --git a/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c b/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c
index 475102b57c..47ef6428cb 100644
--- a/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c
+++ b/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c
@@ -20,12 +20,12 @@
*/
/*! \file PHY/LTE_TRANSPORT/pilots_mbsfn.c
-* \brief Top-level routines for generating DL mbsfn reference signals
-* \authors S. Paranche, R. Knopp
+* \brief Top-level routines for generating DL mbsfn reference signals / DL mbsfn reference signals for FeMBMS
+* \authors S. Paranche, R. Knopp, J. Morgade
* \date 2012
* \version 0.1
* \company Eurecom
-* \email: knopp@eurecom.fr
+* \email: knopp@eurecom.fr, javier.morgade@ieee.org
* \note
* \warning
*/
@@ -85,3 +85,31 @@ int generate_mbsfn_pilot(PHY_VARS_eNB *eNB,
}
+int generate_mbsfn_pilot_khz_1dot25(PHY_VARS_eNB *eNB,
+ L1_rxtx_proc_t *proc,
+ int32_t **txdataF,
+ int16_t amp)
+
+{
+
+ LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
+ uint32_t subframe_offset,Nsymb;
+ int subframe = proc->subframe_tx;
+
+
+ if (subframe<0 || subframe>= 10) {
+ LOG_E(PHY,"generate_mbsfn_pilots_subframe: subframe not in range (%d)\n",subframe);
+ return(-1);
+ }
+
+ Nsymb = (frame_parms->Ncp==NORMAL) ? 7 : 6;
+
+ subframe_offset = subframe*frame_parms->ofdm_symbol_size*Nsymb<<1;
+
+ lte_dl_mbsfn_khz_1dot25(eNB,
+ &txdataF[0][subframe_offset+0],
+ amp,subframe);
+
+ return(0);
+}
+
diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c
index 90e2836b1e..7b508239a9 100644
--- a/openair1/PHY/LTE_TRANSPORT/pmch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pmch.c
@@ -128,3 +128,53 @@ void generate_mch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a)
}
+void generate_mch_khz_1dot25(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a)
+{
+
+ int G;
+ int subframe = proc->subframe_tx;
+ int frame = proc->frame_tx;
+ //int bits;
+
+ G = get_G_khz_1dot25(&eNB->frame_parms,
+ eNB->frame_parms.N_RB_DL,
+ eNB->dlsch_MCH->harq_processes[0]->rb_alloc,
+ get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs),1,
+ 2,proc->frame_tx,subframe,0);
+
+ //FeMBMS
+ eNB->dlsch_MCH->harq_processes[0]->Qm = get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs);
+
+
+ generate_mbsfn_pilot_khz_1dot25(eNB,proc,
+ eNB->common_vars.txdataF,
+ AMP);
+
+
+ AssertFatal(dlsch_encoding_fembms_pmch(eNB,
+ proc,
+ // a,
+ eNB->dlsch_MCH->harq_processes[0]->pdu,
+ 1,
+ eNB->dlsch_MCH,
+ proc->frame_tx,
+ subframe,
+ &eNB->dlsch_rate_matching_stats,
+ &eNB->dlsch_turbo_encoding_stats,
+ &eNB->dlsch_interleaving_stats)==0,
+ "problem in dlsch_encoding");
+
+
+ /*for(bits=0;bitsdlsch_MCH->harq_processes[0]->e[bits]);
+ printf("\n");*/
+
+ dlsch_scrambling(&eNB->frame_parms,1,eNB->dlsch_MCH,0,G,0,frame,subframe<<1);
+
+ mch_modulation_khz_1dot25(eNB->common_vars.txdataF,
+ AMP,
+ subframe,
+ &eNB->frame_parms,
+ eNB->dlsch_MCH);
+}
+
diff --git a/openair1/PHY/LTE_TRANSPORT/pmch_common.c b/openair1/PHY/LTE_TRANSPORT/pmch_common.c
index 03bf5a378b..8d65dd2744 100644
--- a/openair1/PHY/LTE_TRANSPORT/pmch_common.c
+++ b/openair1/PHY/LTE_TRANSPORT/pmch_common.c
@@ -37,23 +37,84 @@
int is_fembms_cas_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) {
- uint32_t period;
+ //uint32_t period;
- if(frame_parms->NonMBSFN_config_flag ) {
- period = 4<NonMBSFN_config.radioframeAllocationPeriod;
+ //if(frame_parms->NonMBSFN_config_flag ) {
+ // period = 4<NonMBSFN_config.radioframeAllocationPeriod;
- if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) {
+ // if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) {
+ // switch (subframe) {
+ // case 0:
+ // return(1); //This should be CAS
+ // break;
+ // }
+ // }
+ //}
+ if(frame_parms->NonMBSFN_config_flag || frame_parms->FeMBMS_active){
+ if ((frame&3)==0) {
switch (subframe) {
case 0:
- return(1); //This should be CAS
- break;
+ return(1); //This should be CAS
+ break;
}
- }
+ }
+
}
return (0);
}
+int is_fembms_nonMBSFN_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms){
+ uint32_t period;
+ if(frame_parms->NonMBSFN_config_flag ) {
+ period = 4<NonMBSFN_config.radioframeAllocationPeriod;
+ if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) {
+ switch (subframe) {
+ case 0:
+ return(1); //This should be CAS
+ break;
+ case 1:
+ if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x100) > 0)
+ return(1);
+ break;
+ case 2:
+ if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x80) > 0)
+ return(1);
+ break;
+ case 3:
+ if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x40) > 0)
+ return(1);
+ break;
+ case 4:
+ if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x20) > 0)
+ return(1);
+ break;
+ case 5:
+ if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x10) > 0)
+ return(1);
+ break;
+ case 6:
+ if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x8) > 0)
+ return(1);
+ break;
+ case 7:
+ if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x4) > 0)
+ return(1);
+ break;
+ case 8:
+ if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x2) > 0)
+ return(1);
+ break;
+ case 9:
+ if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x1) > 0)
+ return(1);
+ break;
+ }
+ }
+ }
+ return (0);
+}
+
int is_fembms_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) {
uint32_t period;
@@ -62,63 +123,67 @@ int is_fembms_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *fr
if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) {
switch (subframe) {
+ case 0:
+ return(0);
+ break;
case 1:
if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x100) > 0)
- return(1);
+ return(0);
break;
case 2:
if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x80) > 0)
- return(1);
+ return(0);
break;
case 3:
if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x40) > 0)
- return(1);
+ return(0);
break;
case 4:
if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x20) > 0)
- return(1);
+ return(0);
break;
case 5:
if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x10) > 0)
- return(1);
+ return(0);
break;
case 6:
if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x8) > 0)
- return(1);
+ return(0);
break;
case 7:
if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x4) > 0)
- return(1);
+ return(0);
break;
case 8:
if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x2) > 0)
- return(1);
+ return(0);
break;
case 9:
if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x1) > 0)
- return(1);
+ return(0);
break;
}
- } else { //Then regular MBSFN FeMBMS subframe
+ } else if((frame_parms->FeMBMS_active == 1 || frame_parms->NonMBSFN_config_flag == 1 ) && !is_fembms_cas_subframe(frame,subframe,frame_parms) ) { //Then regular MBSFN FeMBMS subframe
return(1);
}
+ return(1);
}
return(0);
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common.h b/openair1/PHY/LTE_TRANSPORT/transport_common.h
index 321789d54b..ab2921c2b9 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_common.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_common.h
@@ -67,6 +67,7 @@
#if !defined(SI_RNTI)
#define SI_RNTI (rnti_t)0xffff
+ #define SI_RNTI_MBMS (rnti_t)0xfff9
#endif
#if !defined(M_RNTI)
#define M_RNTI (rnti_t)0xfffd
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
index e4f5d9a17f..1944f06fab 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
@@ -270,6 +270,9 @@ int is_pmch_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parm
*/
int is_fembms_cas_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms);
+int is_fembms_nonMBSFN_subframe (frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms);
+
+
/*!
\brief Return the status of MBSFN in this frame/subframe
@param frame Frame index
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h
index 3988923bb9..4ce113f78e 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h
@@ -123,6 +123,42 @@ int32_t dlsch_encoding(PHY_VARS_eNB *eNB,
time_stats_t *te_stats,
time_stats_t *i_stats);
+/** \fn dlsch_encoding(PHY_VARS_eNB *eNB,
+ uint8_t *input_buffer,
+ LTE_DL_FRAME_PARMS *frame_parms,
+ uint8_t num_pdcch_symbols,
+ LTE_eNB_DLSCH_t *dlsch,
+ int frame,
+ uint8_t subframe)
+ \brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). The implemented functions are:
+ - CRC computation and addition
+ - Code block segmentation and sub-block CRC addition
+ - Channel coding (Turbo coding)
+ - Rate matching (sub-block interleaving, bit collection, selection and transmission
+ - Code block concatenation
+ @param eNB Pointer to eNB PHY context
+ @param input_buffer Pointer to input buffer for sub-frame
+ @param frame_parms Pointer to frame descriptor structure
+ @param num_pdcch_symbols Number of PDCCH symbols in this subframe
+ @param dlsch Pointer to dlsch to be encoded
+ @param frame Frame number
+ @param subframe Subframe number
+ @param rm_stats Time statistics for rate-matching
+ @param te_stats Time statistics for turbo-encoding
+ @param i_stats Time statistics for interleaving
+ @returns status
+*/
+int32_t dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB,
+ L1_rxtx_proc_t *proc,
+ uint8_t *a,
+ uint8_t num_pdcch_symbols,
+ LTE_eNB_DLSCH_t *dlsch,
+ int frame,
+ uint8_t subframe,
+ time_stats_t *rm_stats,
+ time_stats_t *te_stats,
+ time_stats_t *i_stats);
+
@@ -269,6 +305,30 @@ int mch_modulation(int32_t **txdataF,
LTE_DL_FRAME_PARMS *frame_parms,
LTE_eNB_DLSCH_t *dlsch);
+/*
+ \brief This function is the top-level routine for generation of the sub-frame signal (frequency-domain) for MCH.
+ @param txdataF Table of pointers for frequency-domain TX signals
+ @param amp Amplitude of signal
+ @param subframe_offset Offset of this subframe in units of subframes (usually 0)
+ @param frame_parms Pointer to frame descriptor
+ @param dlsch Pointer to DLSCH descriptor for this allocation
+*/
+int mch_modulation_khz_1dot25(int32_t **txdataF,
+ int16_t amp,
+ uint32_t subframe_offset,
+ LTE_DL_FRAME_PARMS *frame_parms,
+ LTE_eNB_DLSCH_t *dlsch);
+
+
+/** \brief Top-level generation function for eNB TX of MBSFN
+ @param phy_vars_eNB Pointer to eNB variables
+ @param a Pointer to transport block
+ @param abstraction_flag
+
+*/
+void generate_mch_khz_1dot25(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc,uint8_t *a);
+
+
/** \brief Top-level generation function for eNB TX of MBSFN
@param phy_vars_eNB Pointer to eNB variables
@param a Pointer to transport block
@@ -318,6 +378,12 @@ int32_t generate_pilots_slot(PHY_VARS_eNB *phy_vars_eNB,
uint16_t slot,
int first_pilot_only);
+int32_t generate_mbsfn_pilot_khz_1dot25(PHY_VARS_eNB *phy_vars_eNB,
+ L1_rxtx_proc_t *proc,
+ int32_t **txdataF,
+ int16_t amp);
+
+
int32_t generate_mbsfn_pilot(PHY_VARS_eNB *phy_vars_eNB,
L1_rxtx_proc_t *proc,
int32_t **txdataF,
@@ -350,6 +416,13 @@ int32_t generate_pbch(LTE_eNB_PBCH *eNB_pbch,
uint8_t *pbch_pdu,
uint8_t frame_mod4);
+int32_t generate_pbch_fembms(LTE_eNB_PBCH *eNB_pbch,
+ int32_t **txdataF,
+ int32_t amp,
+ LTE_DL_FRAME_PARMS *frame_parms,
+ uint8_t *pbch_pdu,
+ uint8_t frame_mod16);
+
diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c
index dbfe93adee..652421f77c 100644
--- a/openair1/PHY/MODULATION/nr_modulation.c
+++ b/openair1/PHY/MODULATION/nr_modulation.c
@@ -20,36 +20,138 @@
*/
#include "nr_modulation.h"
-
-extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
+#include "PHY/NR_REFSIG/nr_mod_table.h"
void nr_modulation(uint32_t *in,
uint32_t length,
uint16_t mod_order,
int16_t *out)
{
- uint16_t offset;
- uint8_t idx, b_idx;
-
- offset = (mod_order==2)? NR_MOD_TABLE_QPSK_OFFSET : (mod_order==4)? NR_MOD_TABLE_QAM16_OFFSET : \
- (mod_order==6)? NR_MOD_TABLE_QAM64_OFFSET: (mod_order==8)? NR_MOD_TABLE_QAM256_OFFSET : 0;
+ uint16_t mask = ((1<>b_idx)&1)<<(mod_order-j-1);
- }
+ switch (mod_order) {
- out[i<<1] = nr_mod_table[(offset+idx)<<1];
- out[(i<<1)+1] = nr_mod_table[((offset+idx)<<1)+1];
+#if defined(__SSE2__)
+ case 2:
+ nr_mod_table128 = (__m128i*) nr_qpsk_byte_mod_table;
+ out128 = (__m128i*) out;
+ for (i=0; i>((i*2)&0x7)) & mask);
+ out32[i] = nr_mod_table32[idx];
+ i++;
+ }
+ return;
+#else
+ case 2:
+ nr_mod_table32 = (int32_t*) nr_qpsk_mod_table;
+ for (i=0; i>((i*2)&0x1f)) & mask);
+ out32[i] = nr_mod_table32[idx];
+ }
+ return;
+#endif
+
+ case 4:
+ out64 = (int64_t*) out;
+ for (i=0; i>((i*4)&0x7)) & mask);
+ out32[i] = nr_16qam_mod_table[idx];
+ i++;
+ }
+ return;
+
+ case 6:
+ j = 0;
+ for (i=0; i>12)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x>>24)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x>>36)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x>>48)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x2 = (x>>60);
+ x = in64[i*3+1];
+ x2 |= x<<4;
+ x1 = x2&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x2>>12)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x2>>24)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x2>>36)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x2>>48)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x2 = ((x>>56)&0xf0) | (x2>>60);
+ x = in64[i*3+2];
+ x2 |= x<<8;
+ x1 = x2&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x2>>12)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x2>>24)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x2>>36)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x2>>48)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x2 = ((x>>52)&0xff0) | (x2>>60);
+ out64[j++] = nr_64qam_mod_table[x2];
+ }
+ i *= 24;
+ bit_cnt = i * 8;
+ while (bit_cnt < length) {
+ x = *((uint32_t*)(in_bytes+i));
+ x1 = x&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ x1 = (x>>12)&4095;
+ out64[j++] = nr_64qam_mod_table[x1];
+ i += 3;
+ bit_cnt += 24;
+ }
+ return;
+
+ case 8:
+ nr_mod_table32 = (int32_t*) nr_256qam_mod_table;
+ for (i=0; isymbols_per_slot * fp->slots_per_frame/10;
+ const double Tc=(1/480e3/4096);
+ const double Nu=2048*64*.5;
+ const double f0= (double)CarrierFreq;
+ const double Ncp0=16*64 + (144*64*.5);
+ const double Ncp1=(144*64*.5);
+ double tl=0,poff,exp_re,exp_im;
+ double Ncp,Ncpm1=Ncp0;
+
+ poff = 2*M_PI*((Ncp0*Tc))*f0;
+ exp_re = cos(poff);
+ exp_im = sin(-poff);
+ fp->symbol_rotation[0]=(int16_t)floor(exp_re*32767);
+ fp->symbol_rotation[1]=(int16_t)floor(exp_im*32767);
+ LOG_I(PHY,"Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n",f0,nsymb);
+ LOG_I(PHY,"Symbol rotation %d/%d => (%d,%d)\n",0,nsymb,fp->symbol_rotation[0],fp->symbol_rotation[1]);
+ for (int l=1;lnumerology_index))) Ncp=Ncp0;
+ else Ncp=Ncp1;
+ tl += (Nu+Ncpm1)*Tc;
+ poff = 2*M_PI*(tl + (Ncp*Tc))*f0;
+ exp_re = cos(poff);
+ exp_im = sin(-poff);
+ fp->symbol_rotation[l<<1]=(int16_t)floor(exp_re*32767);
+ fp->symbol_rotation[1+(l<<1)]=(int16_t)floor(exp_im*32767);
+ LOG_I(PHY,"Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",l,nsymb,tl,fp->symbol_rotation[l<<1],fp->symbol_rotation[1+(l<<1)],
+ (poff/2/M_PI)-floor(poff/2/M_PI));
+ Ncpm1=Ncp;
+ }
+}
diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h
index 706b4dc113..31d8754768 100644
--- a/openair1/PHY/MODULATION/nr_modulation.h
+++ b/openair1/PHY/MODULATION/nr_modulation.h
@@ -103,4 +103,13 @@ int nr_beam_precoding(int32_t **txdataF,
int nb_antenna_ports
);
+void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
+ int16_t* txdata,
+ int slot,
+ int first_symbol,
+ int nsymb,
+ int length);
+
+void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq);
+
#endif
diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c
index 20eebe3baa..92aea419af 100644
--- a/openair1/PHY/MODULATION/ofdm_mod.c
+++ b/openair1/PHY/MODULATION/ofdm_mod.c
@@ -90,7 +90,7 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
if(nb_symbols == 0) return;
- short temp[4096*4] __attribute__((aligned(32)));
+ short temp[2*2*6144*4] __attribute__((aligned(32)));
unsigned short i,j;
short k;
@@ -127,9 +127,23 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
case 3072:
idftsize = IDFT_3072;
break;
+
case 4096:
idftsize = IDFT_4096;
break;
+
+ case 6144:
+ idftsize= IDFT_6144;
+ break;
+
+ case 12288:
+ idftsize= IDFT_12288;
+ break;
+
+ case 24576:
+ idftsize= IDFT_24576;
+ break;
+
default:
idftsize = IDFT_512;
break;
@@ -294,60 +308,23 @@ void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t ne
}
-/*
-// OFDM modulation for each symbol
-void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, RU_COMMON *common, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms,int do_precoding)
-{
+void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
+ int16_t* trxdata,
+ int slot,
+ int first_symbol,
+ int nsymb,
+ int length) {
+ int symb_offset = (slot%fp->slots_per_subframe)*fp->symbols_per_slot;
- int aa, l, slot_offset, slot_offsetF;
- int32_t **txdataF = eNB_common_vars->txdataF;
- int32_t **txdataF_BF = common->txdataF_BF;
- int32_t **txdata = common->txdata;
-
- slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
- slot_offsetF = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==EXTENDED) ? 6 : 7);
- //printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
- for (l=0; lsymbols_per_tti>>1; l++) {
-
- for (aa=0; aanb_antennas_tx; aa++) {
-
- //printf("do_OFDM_mod_l, slot=%d, l=%d, NUMBER_OF_OFDM_CARRIERS=%d,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES=%d\n",next_slot, l,NUMBER_OF_OFDM_CARRIERS,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,1);
- if (do_precoding==1) beam_precoding(txdataF,txdataF_BF,frame_parms,eNB_common_vars->beam_weights,next_slot,l,aa);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,0);
-
- //PMCH case not implemented...
-
- if (frame_parms->Ncp == EXTENDED)
- PHY_ofdm_mod((do_precoding == 1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size], // input
- &txdata[aa][slot_offset+l*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES], // output
- frame_parms->ofdm_symbol_size,
- 1, // number of symbols
- frame_parms->nb_prefix_samples, // number of prefix samples
- CYCLIC_PREFIX);
- else {
- if (l==0) {
- PHY_ofdm_mod((do_precoding==1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size], // input
- &txdata[aa][slot_offset], // output
- frame_parms->ofdm_symbol_size,
- 1, // number of symbols
- frame_parms->nb_prefix_samples0, // number of prefix samples
- CYCLIC_PREFIX);
-
- } else {
- PHY_ofdm_mod((do_precoding==1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size], // input
- &txdata[aa][slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES], // output
- frame_parms->ofdm_symbol_size,
- 1, // number of symbols
- frame_parms->nb_prefix_samples, // number of prefix samples
- CYCLIC_PREFIX);
-
- //printf("txdata[%d][%d]=%d\n",aa,slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES,txdata[aa][slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES]);
-
- }
- }
- }
+ for (int sidx=0;sidxsymbol_rotation[2*(sidx+first_symbol+symb_offset)],fp->symbol_rotation[1+2*(sidx+first_symbol+symb_offset)]);
+ rotate_cpx_vector(trxdata+(sidx*length*2),
+ &fp->symbol_rotation[2*(sidx+first_symbol+symb_offset)],
+ trxdata+(sidx*length*2),
+ length,
+ 15);
}
-
}
-*/
+
diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index 28983e0bc3..8ad12105f8 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -133,8 +133,8 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
#ifdef DEBUG_FEP
// if (ue->frame <100)
- /*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
- ue->proc.proc_rxtx[(Ns)&1].frame_rx, Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
+ /*LOG_I(PHY,*/printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
+ Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
#endif
abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
@@ -198,12 +198,22 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
}
- #ifdef DEBUG_FEP
- // if (ue->frame <100)
- printf("slot_fep: frame %d: symbol %d rx_offset %u\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx, symbol, rx_offset);
- #endif
+#ifdef DEBUG_FEP
+ // if (ue->frame <100)
+ printf("slot_fep: symbol %d rx_offset %u\n", symbol, rx_offset);
+#endif
+
+ int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
+ int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
+ ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
+ rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
+ (int16_t*)&rot2,
+ (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
+ frame_parms->ofdm_symbol_size,
+ 15);
+
}
-
+
#ifdef DEBUG_FEP
printf("slot_fep: done\n");
@@ -308,8 +318,8 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
#ifdef DEBUG_FEP
// if (ue->frame <100)
- /*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
- ue->proc.proc_rxtx[(Ns)&1].frame_rx, Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
+ /*LOG_I(PHY,*/printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
+ Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
#endif
abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
@@ -373,10 +383,22 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
}
- #ifdef DEBUG_FEP
- // if (ue->frame <100)
- printf("slot_fep: frame %d: symbol %d rx_offset %u\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx, symbol, rx_offset);
- #endif
+ int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
+ int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
+ ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
+
+#ifdef DEBUG_FEP
+ // if (ue->frame <100)
+ printf("slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset,
+ symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
+#endif
+
+ rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
+ (int16_t*)&rot2,
+ (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
+ frame_parms->ofdm_symbol_size,
+ 15);
+
}
@@ -450,11 +472,11 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET;
if(sample_offset>rxdata_offset) {
- memcpy((void *)tmp_dft_in,
+ memcpy1((void *)tmp_dft_in,
(void *) &rxdata[frame_parms->samples_per_frame-sample_offset+rxdata_offset],
(sample_offset-rxdata_offset)*sizeof(int));
- memcpy((void *)&tmp_dft_in[sample_offset-rxdata_offset],
+ memcpy1((void *)&tmp_dft_in[sample_offset-rxdata_offset],
(void *) &rxdata[0],
(frame_parms->ofdm_symbol_size-sample_offset+rxdata_offset)*sizeof(int));
@@ -474,5 +496,14 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
// clear DC carrier from OFDM symbols
rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0;
+ int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
+ uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
+ ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
+ LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",Ns,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
+ rotate_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
+ (int16_t*)&rot2,
+ (int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
+ frame_parms->ofdm_symbol_size,
+ 15);
return(0);
}
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index 9a6f47b01d..b6388fb903 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -25,11 +25,15 @@
#include "nr_ul_estimation.h"
#include "PHY/sse_intrin.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
+#include "PHY/NR_REFSIG/ptrs_nr.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
//#define DEBUG_CH
//#define DEBUG_PUSCH
+#define dBc(x,y) (dB_fixed(((int32_t)(x))*(x) + ((int32_t)(y))*(y)))
+
int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
unsigned char Ns,
unsigned short p,
@@ -123,7 +127,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type);
//------------------------------------------------//
-
+#ifdef DEBUG_PUSCH
+ for (int i=0;i<(6*nb_rb_pusch);i++)
+ printf("%d+j*(%d)\n",((int16_t*)pilot)[2*i],((int16_t*)pilot)[1+(2*i)]);
+#endif
for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
pil = (int16_t *)&pilot[0];
@@ -135,7 +142,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#ifdef DEBUG_PUSCH
printf("symbol_offset %d, nushift %d\n",symbol_offset,nushift);
printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL);
- printf("bwp_start_subcarrier %d, k %d, first_carrier %d\n",bwp_start_subcarrier,k,gNB->frame_parms.first_carrier_offset);
+ printf("bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n",bwp_start_subcarrier,k,gNB->frame_parms.first_carrier_offset,nb_rb_pusch);
printf("rxF addr %p p %d\n", rxF,p);
printf("ul_ch addr %p nushift %d\n",ul_ch,nushift);
#endif
@@ -149,8 +156,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#ifdef DEBUG_PUSCH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
- printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
- printf("data 0 : rxF - > (%d,%d)\n",rxF[2],rxF[3]);
+ printf("pilot 0 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
+ printf("data 0 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
#endif
multadd_real_vector_complex_scalar(fl,
@@ -167,8 +174,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
- printf("data 1 : rxF - > (%d,%d)\n",rxF[2],rxF[3]);
+ printf("pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
+ printf("data 1 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
#endif
multadd_real_vector_complex_scalar(fml,
ch,
@@ -183,8 +190,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
- printf("data 2 : rxF - > (%d,%d)\n",rxF[2],rxF[3]);
+ printf("pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
+ printf("data 2 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
#endif
multadd_real_vector_complex_scalar(fmm,
ch,
@@ -205,8 +212,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
- printf("data %u : rxF - > (%d,%d)\n",pilot_cnt,rxF[2],rxF[3]);
+ printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
+ printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt,rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
#endif
multadd_real_vector_complex_scalar(fml,
ch,
@@ -221,8 +228,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
- printf("data %u : rxF - > (%d,%d)\n",pilot_cnt+1,rxF[2],rxF[3]);
+ printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
+ printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt+1,rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
#endif
multadd_real_vector_complex_scalar(fmm,
ch,
@@ -243,8 +250,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
- printf("data %u : rxF - > (%d,%d)\n",pilot_cnt,rxF[2],rxF[3]);
+ printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
+ printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt,rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
#endif
multadd_real_vector_complex_scalar(fm,
ch,
@@ -262,8 +269,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
- printf("pilot %u: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
- printf("data %u : rxF - > (%d,%d)\n",pilot_cnt+1,rxF[2],rxF[3]);
+ printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
+ printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt+1,rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
#endif
multadd_real_vector_complex_scalar(fmr,
ch,
@@ -278,8 +285,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("pilot %u: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
- printf("data %u : rxF - > (%d,%d)\n",pilot_cnt+2,rxF[2],rxF[3]);
+ printf("pilot %u: rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
+ printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt+2,rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
#endif
multadd_real_vector_complex_scalar(fr,
ch,
@@ -502,3 +509,408 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
return(0);
}
+
+
+/*******************************************************************
+ *
+ * NAME : nr_pusch_ptrs_processing
+ *
+ * PARAMETERS : gNB : gNB data structure
+ * rel15_ul : UL parameters
+ * UE_id : UE ID
+ * nr_tti_rx : slot rx TTI
+ * dmrs_symbol_flag: DMRS Symbol Flag
+ * symbol : OFDM Symbol
+ * nb_re_pusch : PUSCH RE's
+ * nb_re_pusch : PUSCH RE's
+ *
+ * RETURN : nothing
+ *
+ * DESCRIPTION :
+ * If ptrs is enabled process the symbol accordingly
+ * 1) Estimate phase noise per PTRS symbol
+ * 2) Interpolate PTRS estimated value in TD after all PTRS symbols
+ * 3) Compensated DMRS based estimated signal with PTRS estimation for slot
+ *********************************************************************/
+void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
+ nfapi_nr_pusch_pdu_t *rel15_ul,
+ uint8_t ulsch_id,
+ uint8_t nr_tti_rx,
+ uint8_t dmrs_symbol_flag,
+ unsigned char symbol,
+ uint32_t nb_re_pusch)
+{
+ NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
+ int16_t *phase_per_symbol;
+
+ uint8_t L_ptrs = 0;
+ uint8_t right_side_ref = 0;
+ uint8_t left_side_ref = 0;
+ uint8_t nb_dmrs_in_slot = 0;
+
+ //#define DEBUG_UL_PTRS 1
+ /* First symbol calculate PTRS symbol index for slot & set the variables */
+ if(symbol == rel15_ul->start_symbol_index)
+ {
+ gNB->pusch_vars[ulsch_id]->ptrs_symbols = 0;
+ L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
+ set_ptrs_symb_idx(&gNB->pusch_vars[ulsch_id]->ptrs_symbols,
+ rel15_ul->nr_of_symbols,
+ rel15_ul->start_symbol_index,
+ L_ptrs,
+ rel15_ul->ul_dmrs_symb_pos);
+ }/* First symbol check */
+
+ /* loop over antennas */
+ for (int aarx=0; aarx< frame_parms->nb_antennas_rx; aarx++)
+ {
+ phase_per_symbol = (int16_t*)gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx];
+ /* set the previous estimations to zero at first symbol */
+ if(symbol == rel15_ul->start_symbol_index)
+ {
+ memset(phase_per_symbol,0,sizeof(int32_t)*frame_parms->symbols_per_slot);
+ }
+ /* if not PTRS symbol set current ptrs symbol index to zero*/
+ gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = 0;
+ gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol = 0;
+ /* Check if current symbol contains PTRS */
+ if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols))
+ {
+ gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = symbol;
+ /*------------------------------------------------------------------------------------------------------- */
+ /* 1) Estimate phase noise per PTRS symbol */
+ /*------------------------------------------------------------------------------------------------------- */
+ nr_pusch_phase_estimation(frame_parms,
+ rel15_ul,
+ (int16_t *)&gNB->pusch_vars[ulsch_id]->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch],
+ nr_tti_rx,
+ symbol,
+ (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)],
+ gNB->nr_gold_pusch_dmrs[rel15_ul->scid],
+ &phase_per_symbol[2* symbol],
+ &gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol);
+ }
+ /* DMRS Symbol channel estimates extraction */
+ else if(dmrs_symbol_flag)
+ {
+ phase_per_symbol[2* symbol]= (int16_t)((1<<15)-1); // 32767
+ phase_per_symbol[2* symbol +1]= 0;// no angle
+ }
+ /* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/
+ if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1))
+ {
+ nb_dmrs_in_slot = get_dmrs_symbols_in_slot(rel15_ul->ul_dmrs_symb_pos,(rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
+ for(uint8_t dmrs_sym = 0; dmrs_sym < nb_dmrs_in_slot; dmrs_sym ++)
+ {
+ if(dmrs_sym == 0)
+ {
+ /* get first DMRS position */
+ left_side_ref = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, rel15_ul->start_symbol_index, (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
+ /* get first DMRS position is not at start symbol position then we need to extrapolate left side */
+ if(left_side_ref > rel15_ul->start_symbol_index)
+ {
+ left_side_ref = rel15_ul->start_symbol_index;
+ }
+ }
+ /* get the next symbol from left_side_ref value */
+ right_side_ref = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, left_side_ref+1, (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
+ /* if no symbol found then interpolate till end of slot*/
+ if(right_side_ref == 0)
+ {
+ right_side_ref = (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);
+ }
+ /*------------------------------------------------------------------------------------------------------- */
+ /* 2) Interpolate PTRS estimated value in TD */
+ /*------------------------------------------------------------------------------------------------------- */
+ nr_pusch_phase_interpolation(phase_per_symbol,left_side_ref,right_side_ref);
+ /* set left to last dmrs */
+ left_side_ref = right_side_ref;
+ } /*loop over dmrs positions */
+
+#ifdef DEBUG_UL_PTRS
+ LOG_M("ptrsEst.m","est",gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
+ LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp",
+ &gNB->pusch_vars[0]->rxdataF_comp[aarx][rel15_ul->start_symbol_index * NR_NB_SC_PER_RB * rel15_ul->rb_size],
+ rel15_ul->nr_of_symbols * NR_NB_SC_PER_RB * rel15_ul->rb_size,1,1);
+#endif
+
+ /*------------------------------------------------------------------------------------------------------- */
+ /* 3) Compensated DMRS based estimated signal with PTRS estimation */
+ /*--------------------------------------------------------------------------------------------------------*/
+ for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++)
+ {
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]);
+#endif
+ rotate_cpx_vector((int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
+ &phase_per_symbol[2* i],
+ (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
+ (rel15_ul->rb_size * NR_NB_SC_PER_RB),
+ 15);
+ }// symbol loop
+ }//interpolation and compensation
+ }// Antenna loop
+}
+
+/*******************************************************************
+ *
+ * NAME : nr_pusch_phase_estimation
+ *
+ * PARAMETERS : frame_parms : UL frame parameters
+ * rel15_ul : UL PDU Structure
+ * Ns :
+ * Symbol : OFDM symbol index
+ * rxF : Channel compensated signal
+ * ptrs_gold_seq: Gold sequence for PTRS regeneration
+ * error_est : Estimated error output vector [Re Im]
+ * RETURN : nothing
+ *
+ * DESCRIPTION :
+ * perform phase estimation from regenerated PTRS SC and channel compensated
+ * signal
+ *********************************************************************/
+void nr_pusch_phase_estimation(NR_DL_FRAME_PARMS *frame_parms,
+ nfapi_nr_pusch_pdu_t *rel15_ul,
+ int16_t *ptrs_ch_p,
+ unsigned char Ns,
+ unsigned char symbol,
+ int16_t *rxF_comp,
+ uint32_t ***ptrs_gold_seq,
+ int16_t *error_est,
+ uint16_t *ptrs_sc)
+{
+ uint8_t is_ptrs_re = 0;
+ uint16_t re_cnt = 0;
+ uint16_t cnt = 0;
+ unsigned short nb_re_pusch = NR_NB_SC_PER_RB * rel15_ul->rb_size;
+ uint8_t K_ptrs = rel15_ul->pusch_ptrs.ptrs_freq_density;
+ uint16_t sc_per_symbol = (rel15_ul->rb_size + K_ptrs - 1)/K_ptrs;
+ int16_t *ptrs_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol));
+ int16_t *dmrs_comp_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol));
+ double abs = 0.0;
+ double real = 0.0;
+ double imag = 0.0;
+#ifdef DEBUG_UL_PTRS
+ double alpha = 0;
+#endif
+ /* generate PTRS RE for the symbol */
+ nr_gen_ref_conj_symbols(ptrs_gold_seq[Ns][symbol],sc_per_symbol*2,ptrs_p, NR_MOD_TABLE_QPSK_OFFSET,2);// 2 for QPSK
+
+ /* loop over all sub carriers to get compensated RE on ptrs symbols*/
+ for (int re = 0; re < nb_re_pusch; re++)
+ {
+ is_ptrs_re = is_ptrs_subcarrier(re,
+ rel15_ul->rnti,
+ 0,
+ rel15_ul->dmrs_config_type,
+ K_ptrs,
+ rel15_ul->rb_size,
+ rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
+ 0,// start_re is 0 here
+ frame_parms->ofdm_symbol_size);
+ if(is_ptrs_re)
+ {
+ dmrs_comp_p[re_cnt*2] = rxF_comp[re *2];
+ dmrs_comp_p[(re_cnt*2)+1] = rxF_comp[(re *2)+1];
+ re_cnt++;
+ }
+ else
+ {
+ /* Skip PTRS symbols and keep data in a continuous vector */
+ rxF_comp[cnt *2]= rxF_comp[re *2];
+ rxF_comp[(cnt *2)+1]= rxF_comp[(re *2)+1];
+ cnt++;
+ }
+ }/* RE loop */
+ /* update the total ptrs RE in a symbol */
+ *ptrs_sc = re_cnt;
+
+ /*Multiple compensated data with conj of PTRS */
+ mult_cpx_vector(dmrs_comp_p, ptrs_p, ptrs_ch_p,(1 + sc_per_symbol/4)*4,15); // 2^15 shifted
+
+ /* loop over all ptrs sub carriers in a symbol */
+ /* sum the error vector */
+ for(int i = 0;i < sc_per_symbol; i++)
+ {
+ real+= ptrs_ch_p[(2*i)];
+ imag+= ptrs_ch_p[(2*i)+1];
+ }
+#ifdef DEBUG_UL_PTRS
+ alpha = atan(imag/real);
+ printf("PTRS: Symbol %d atan(Im,real):= %f \n",symbol, alpha );
+#endif
+ /* mean */
+ real /= sc_per_symbol;
+ imag /= sc_per_symbol;
+ /* absolute calculation */
+ abs = sqrt(((real * real) + (imag * imag)));
+ /* normalized error estimation */
+ error_est[0]= (real / abs)*(1<<15);
+ /* compensation in given by conjugate of estimated phase (e^-j*2*pi*fd*t)*/
+ error_est[1]= (-1)*(imag / abs)*(1<<15);
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: Estimated Symbol %d -> %d + j* %d \n",symbol, error_est[0], error_est[1] );
+#endif
+ /* free vectors */
+ free(ptrs_p);
+ free(dmrs_comp_p);
+}
+
+
+/*******************************************************************
+ *
+ * NAME : nr_pusch_phase_interpolation
+ *
+ * PARAMETERS : *error_est : Data Pointer [Re Im Re Im ...]
+ * start_symbol : Start Symbol
+ * end_symbol : End Symbol
+ * RETURN : nothing
+ *
+ * DESCRIPTION :
+ * Perform Interpolation, extrapolation based upon the estimation
+ * location between the data Pointer Array.
+ *
+ *********************************************************************/
+void nr_pusch_phase_interpolation(int16_t *error_est,
+ uint8_t start_symbol,
+ uint8_t end_symbol
+ )
+{
+
+ int next = 0, prev = 0, candidates= 0, distance=0, leftEdge= 0, rightEdge = 0, getDiff =0 ;
+ double weight = 0.0;
+ double scale = 0.125 ; // to avoid saturation due to fixed point multiplication
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: INT: Left limit %d, Right limit %d, Loop over %d Symbols \n",
+ start_symbol,end_symbol-1, (end_symbol -start_symbol)-1);
+#endif
+ for(int i =start_symbol; i< end_symbol;i++)
+ {
+ /* Only update when an estimation is found */
+ if( error_est[i*2] != 0 )
+ {
+ /* if found a symbol then set next symbol also */
+ next = nr_ptrs_find_next_estimate(error_est, i, end_symbol);
+ /* left extrapolation, if first estimate value is zero */
+ if( error_est[i*2] == 0 )
+ {
+ leftEdge = 1;
+ }
+ /* right extrapolation, if next is 0 before end symbol */
+ if((next == 0) && (end_symbol > i))
+ {
+ rightEdge = 1;
+ /* special case as no right extrapolation possible with DMRS on left */
+ /* In this case take mean of most recent 2 estimated points */
+ if(prev ==0)
+ {
+ prev = start_symbol -1;
+ next = start_symbol -2;
+ getDiff =1;
+ }else
+ {
+ /* for right edge previous is second last from right side */
+ next = prev;
+ /* Set the current as recent estimation reference */
+ prev = i;
+ }
+ }
+ /* update current symbol as prev for next symbol */
+ if (rightEdge==0)
+ /* Set the current as recent estimation reference */
+ prev = i;
+ }
+ /*extrapolation left side*/
+ if(leftEdge)
+ {
+ distance = next - prev;
+ weight = 1.0/distance;
+ candidates = i;
+ for(int j = 1; j <= candidates; j++)
+ {
+ error_est[(i-j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance + j) * weight) -
+ ((double)(error_est[next*2]) * scale * j * weight));
+ error_est[((i-j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale* (distance + j) * weight) -
+ ((double)(error_est[((next*2)+1)]) * scale * j * weight));
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: INT: Left Edge i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
+ (i-j),weight, error_est[(i-j)*2],error_est[((i-j)*2)+1], prev,next);
+#endif
+ }
+ leftEdge = 0;
+ }
+ /* extrapolation at right side */
+ else if (rightEdge )
+ {
+ if(getDiff)
+ {
+ error_est[(i+1)*2] = ((1<<15) +(error_est[prev*2]) - error_est[next*2]);
+ error_est[((i+1)*2)+1]= error_est[(prev*2)+1] - error_est[(next*2)+1];
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: INT: Right Edge Special Case i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
+ (i+1),weight, error_est[(i+1)*2],error_est[((i+1)*2)+1], prev,next);
+#endif
+ i++;
+ }
+ else
+ {
+ distance = prev - next;
+ candidates = (end_symbol -1) - i;
+ weight = 1.0/distance;
+ for(int j = 1; j <= candidates; j++)
+ {
+ error_est[(i+j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance + j) * weight) -
+ ((double)(error_est[next*2]) * scale * j * weight));
+ error_est[((i+j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale * (distance + j) * weight) -
+ ((double)(error_est[((next*2)+1)]) * scale *j * weight));
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: INT: Right Edge i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
+ (i+j),weight, error_est[(i+j)*2],error_est[((i+j)*2)+1], prev,next);
+#endif
+ }
+ if(candidates > 1)
+ {
+ i+=candidates;
+ }
+ }
+ }
+ /* Interpolation between 2 estimated points */
+ else if(next != 0 && ( error_est[2*i] == 0 ))
+ {
+ distance = next - prev;
+ weight = 1.0/distance;
+ candidates = next - i ;
+ for(int j = 0; j < candidates; j++)
+ {
+
+ error_est[(i+j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance - (j+1)) * weight) +
+ ((double)(error_est[next*2]) * scale * (j+1) * weight));
+ error_est[((i+j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale *(distance - (j+1)) * weight) +
+ ((double)(error_est[((next*2)+1)]) * scale *(j+1) * weight));
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: INT: Interpolation i= %d weight= %f %d + j*%d, Prev %d Next %d\n",
+ (i+j),weight, error_est[(i+j)*2],error_est[((i+j)*2)+1],prev,next);
+#endif
+ }
+ if(candidates > 1)
+ {
+ i+=candidates-1;
+ }
+ }// interpolation
+ }// symbol loop
+}
+
+/* Find the next non zero Real value in a complex vector */
+int nr_ptrs_find_next_estimate(int16_t *error_est,
+ uint8_t counter,
+ uint8_t end_symbol)
+{
+ for (int i = counter +1 ; i< end_symbol; i++)
+ {
+ if( error_est[2*i] != 0)
+ {
+ return i;
+ }
+ }
+ return 0;
+}
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
index 17d8c998c9..0f71487e36 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
@@ -51,4 +51,30 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB);
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
+
+void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
+ nfapi_nr_pusch_pdu_t *rel15_ul,
+ uint8_t ulsch_id,
+ uint8_t nr_tti_rx,
+ uint8_t dmrs_symbol_flag,
+ unsigned char symbol,
+ uint32_t nb_re_pusch);
+
+void nr_pusch_phase_estimation(NR_DL_FRAME_PARMS *frame_parms,
+ nfapi_nr_pusch_pdu_t *rel15_ul,
+ int16_t *ptrs_ch_p,
+ unsigned char Ns,
+ unsigned char symbol,
+ int16_t *rxF_comp,
+ uint32_t ***ptrs_gold_seq,
+ int16_t *error_est,
+ uint16_t *ptrs_sc);
+
+void nr_pusch_phase_interpolation(int16_t *error_est,
+ uint8_t start_symbol,
+ uint8_t end_symbol);
+
+int nr_ptrs_find_next_estimate(int16_t *error_est,
+ uint8_t counter,
+ uint8_t end_symbol);
#endif
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c
index 7042c152fd..415e6adfa2 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c
@@ -362,4 +362,25 @@ void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_H
free(dmrs_sequence);
#endif
}
+/* return the position of next dmrs symbol in a slot */
+int get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol)
+{
+ for(uint8_t symbol = counter; symbol < end_symbol; symbol++)
+ if((ul_dmrs_symb_pos >>symbol)&0x01 )
+ {
+ return symbol;
+ }
+ return 0;
+}
+
+/* return the total number of dmrs symbol in a slot */
+uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb)
+{
+ uint8_t tmp = 0;
+ for (int i = 0; i < nb_symb; i++)
+ {
+ tmp += (l_prime_mask >> i) & 0x01;
+ }
+ return tmp;
+}
diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
index 4eeb8a6e96..3e758c4fa5 100644
--- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
+++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -223,3 +223,27 @@ int nr_pbch_dmrs_rx(int symbol,
return(0);
}
+
+/*!
+ \brief This function generate gold ptrs sequence for each OFDM symbol
+ \param *in gold sequence for ptrs per OFDM symbol
+ \param length is number of RE in a OFDM symbol
+ \param *output pointer to all ptrs RE in a OFDM symbol
+*/
+void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order)
+{
+ uint8_t idx, b_idx;
+ for (int i=0; i>b_idx)&1)<<(mod_order-j-1);
+ }
+ output[i<<1] = nr_rx_mod_table[(offset+idx)<<1];
+ output[(i<<1)+1] = nr_rx_mod_table[((offset+idx)<<1)+1];
+ }
+}
diff --git a/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c b/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c
new file mode 100644
index 0000000000..b0f9e6d03c
--- /dev/null
+++ b/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c
@@ -0,0 +1,87 @@
+/*
+ * 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.1 (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 "nr_refsig.h"
+#include "nr_mod_table.h"
+
+void nr_generate_modulation_table() {
+ float sqrt2 = 0.70711;
+ float sqrt10 = 0.31623;
+ float sqrt42 = 0.15430;
+ float sqrt170 = 0.076696;
+ float val = 32768.0;
+ uint32_t i,j;
+ short* table;
+
+ // QPSK
+ for (i=0; i<4; i++) {
+ nr_qpsk_mod_table[i*2] = (short)(1-2*(i&1))*val*sqrt2*sqrt2;
+ nr_qpsk_mod_table[i*2+1] = (short)(1-2*((i>>1)&1))*val*sqrt2*sqrt2;
+ //printf("%d j%d\n",nr_qpsk_mod_table[i*2],nr_qpsk_mod_table[i*2+1]);
+ }
+
+#if defined(__SSE2__)
+ //QPSK m128
+ table = (short*) nr_qpsk_byte_mod_table;
+ for (i=0; i<256; i++) {
+ for (j=0; j<4; j++) {
+ table[i*8+(j*2)] = (short)(1-2*((i>>(j*2))&1))*val*sqrt2*sqrt2;
+ table[i*8+(j*2)+1] = (short)(1-2*((i>>(j*2+1))&1))*val*sqrt2*sqrt2;
+ //printf("%d j%d\n",nr_qpsk_byte_mod_table[i*8+(j*2)],nr_qpsk_byte_mod_table[i*8+(j*2)+1]);
+ }
+ }
+#endif
+
+ //16QAM
+ table = (short*) nr_16qam_byte_mod_table;
+ for (i=0; i<256; i++) {
+ for (j=0; j<2; j++) {
+ table[i*4+(j*2)] = (short)((1-2*((i>>(j*4))&1))*(2-(1-2*((i>>(j*4+2))&1))))*val*sqrt10*sqrt2;
+ table[i*4+(j*2)+1] = (short)((1-2*((i>>(j*4+1))&1))*(2-(1-2*((i>>(j*4+3))&1))))*val*sqrt10*sqrt2;
+ //printf("%d j%d\n",nr_16qam_byte_mod_table[i*4+(j*2)],nr_16qam_byte_mod_table[i*4+(j*2)+1]);
+ }
+ }
+
+ table = (short*) nr_16qam_mod_table;
+ for (i=0; i<16; i++) {
+ table[i*2] = (short)((1-2*(i&1))*(2-(1-2*((i>>2)&1))))*val*sqrt10*sqrt2;
+ table[i*2+1] = (short)((1-2*((i>>1)&1))*(2-(1-2*((i>>3)&1))))*val*sqrt10*sqrt2;
+ //printf("%d j%d\n",table[i*2],table[i*2+1]);
+ }
+
+ //64QAM
+ table = (short*) nr_64qam_mod_table;
+ for (i=0; i<4096; i++) {
+ for (j=0; j<2; j++) {
+ table[i*4+(j*2)] = (short)((1-2*((i>>(j*6))&1))*(4-(1-2*((i>>(j*6+2))&1))*(2-(1-2*((i>>(j*6+4))&1)))))*val*sqrt42*sqrt2;
+ table[i*4+(j*2)+1] = (short)((1-2*((i>>(j*6+1))&1))*(4-(1-2*((i>>(j*6+3))&1))*(2-(1-2*((i>>(j*6+5))&1)))))*val*sqrt42*sqrt2;
+ //printf("%d j%d\n",table[i*4+(j*2)],table[i*4+(j*2)+1]);
+ }
+ }
+
+ //256QAM
+ table = (short*) nr_256qam_mod_table;
+ for (i=0; i<256; i++) {
+ table[i*2] = (short)((1-2*(i&1))*(8-(1-2*((i>>2)&1))*(4-(1-2*((i>>4)&1))*(2-(1-2*((i>>6)&1))))))*val*sqrt170*sqrt2;
+ table[i*2+1] = (short)((1-2*((i>>1)&1))*(8-(1-2*((i>>3)&1))*(4-(1-2*((i>>5)&1))*(2-(1-2*((i>>7)&1))))))*val*sqrt170*sqrt2;
+ }
+}
+
diff --git a/openair1/PHY/NR_REFSIG/nr_gen_mod_table.m b/openair1/PHY/NR_REFSIG/nr_gen_mod_table.m
index 13a8d4ad09..6e1415bf28 100644
--- a/openair1/PHY/NR_REFSIG/nr_gen_mod_table.m
+++ b/openair1/PHY/NR_REFSIG/nr_gen_mod_table.m
@@ -45,7 +45,7 @@ for r=0:1 %0 -- 1 LS
for j=0:1 %0 -- 1 MS
%% Formula is dispalayed
-qpsk_table(2*r+j+1) = ((1-r*2)*QPSK + 1j*(1-2*j)*QPSK);
+qpsk_table(2*j+r+1) = ((1-r*2)*QPSK + 1j*(1-2*j)*QPSK);
end
end
@@ -61,7 +61,7 @@ for b0=0:1
for b1=0:1
for b2=0:1
for b3=0:1
-qam16_table2(b0*8+b1*4+b2*2+b3*1+1) = qam16_table(b0*2+b2*1+1) + 1j*qam16_table(b1*2+b3*1+1);
+qam16_table2(b3*8+b2*4+b1*2+b0*1+1) = qam16_table(b0*2+b2*1+1) + 1j*qam16_table(b1*2+b3*1+1);
end
end
end
@@ -84,7 +84,7 @@ for b2=0:1
for b3=0:1
for b4=0:1
for b5=0:1
-qam64_table2(b0*32+b1*16+b2*8+b3*4+b4*2+b5*1+1) = qam64_table(b0*4+b2*2+b4*1+1) + 1j*qam64_table(b1*4+b3*2+b5*1+1);
+qam64_table2(b5*32+b4*16+b3*8+b2*4+b1*2+b0*1+1) = qam64_table(b0*4+b2*2+b4*1+1) + 1j*qam64_table(b1*4+b3*2+b5*1+1);
end
end
end
@@ -116,7 +116,50 @@ for b6=0:1
for b7=0:1
%%qam64_table2(b0*32+b1*16+b2*8+b3*4+b4*2+b5*1+1) = qam64_table(b0*4+b2*2+b4*1+1) + 1j*qam64_table(b1*4+b3*2+b5*1+1);
-qam256_table2(b0*128+b1*64+b2*32+b3*16+b4*8+b5*4+b6*2+b7*1+1) = qam256_table(b0*8+b2*4+b4*2+b6*1+1) + 1j*qam256_table(b1*8+b3*4+b5*2+b7*1+1);
+qam256_table2(b7*128+b6*64+b5*32+b4*16+b3*8+b2*4+b1*2+b0*1+1) = qam256_table(b0*8+b2*4+b4*2+b6*1+1) + 1j*qam256_table(b1*8+b3*4+b5*2+b7*1+1);
+end
+end
+end
+end
+end
+end
+end
+end
+
+%%QPSK byte
+for b0=0:1
+for b1=0:1
+for b2=0:1
+for b3=0:1
+for b4=0:1
+for b5=0:1
+for b6=0:1
+for b7=0:1
+qpsk_byte_table2(b7*128+b6*64+b5*32+b4*16+b3*8+b2*4+b1*2+b0*1+1,:)=[(1-b0*2)*QPSK (1-2*b1)*QPSK (1-b2*2)*QPSK (1-2*b3)*QPSK ...
+ (1-b4*2)*QPSK (1-2*b5)*QPSK (1-b6*2)*QPSK (1-2*b7)*QPSK];
+
+end
+end
+end
+end
+end
+end
+end
+end
+
+%%16QAM byte
+qam16_byte_table2=[];
+for b0=0:1
+for b1=0:1
+for b2=0:1
+for b3=0:1
+for b4=0:1
+for b5=0:1
+for b6=0:1
+for b7=0:1
+qam16_byte_table2(b7*128+b6*64+b5*32+b4*16+b3*8+b2*4+b1*2+b0*1+1,:)=[qam16_table(b0*2+b2*1+1) qam16_table(b1*2+b3*1+1) ...
+ qam16_table(b4*2+b6*1+1) qam16_table(b5*2+b7*1+1) ];
+
end
end
end
@@ -133,6 +176,8 @@ save mod_table.mat table
table2 = zeros(1,length(table)*2);
table2(1:2:end) = real(table);
table2(2:2:end) = imag(table);
+qpsk_byte_table2=round(K * qpsk_byte_table2'(:));
+qam16_byte_table2=round(K * qam16_byte_table2'(:));
fd = fopen("nr_mod_table.h","w");
fprintf(fd,"#define NR_MOD_TABLE_SIZE_SHORT %d\n", length(table)*2);
@@ -144,4 +189,10 @@ fprintf(fd,"#define NR_MOD_TABLE_QAM256_OFFSET %d\n", 87);
fprintf(fd,"short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {");
fprintf(fd,"%d,",table2(1:end-1));
fprintf(fd,"%d};\n",table2(end));
+fprintf(fd,"short nr_qpsk_mod_table[2048] = {");
+fprintf(fd,"%d,",qpsk_byte_table2(1:end-1));
+fprintf(fd,"%d};\n",qpsk_byte_table2(end));
+fprintf(fd,"short nr_qam16_mod_table[1024] = {");
+fprintf(fd,"%d,",qam16_byte_table2(1:end-1));
+fprintf(fd,"%d};\n",qam16_byte_table2(end));
fclose(fd);
diff --git a/openair1/PHY/NR_REFSIG/nr_mod_table.h b/openair1/PHY/NR_REFSIG/nr_mod_table.h
index c34dadb663..aa8b99f584 100644
--- a/openair1/PHY/NR_REFSIG/nr_mod_table.h
+++ b/openair1/PHY/NR_REFSIG/nr_mod_table.h
@@ -28,6 +28,17 @@
#define NR_MOD_TABLE_QAM16_OFFSET 7
#define NR_MOD_TABLE_QAM64_OFFSET 23
#define NR_MOD_TABLE_QAM256_OFFSET 87
-short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655};
+short nr_qpsk_mod_table[8];
+
+int32_t nr_16qam_mod_table[16];
+#if defined(__SSE2__)
+__m128i nr_qpsk_byte_mod_table[2048];
+#endif
+
+int64_t nr_16qam_byte_mod_table[1024];
+
+int64_t nr_64qam_mod_table[4096];
+
+int32_t nr_256qam_mod_table[512];
#endif
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index d6f0a96763..ced7f9eb66 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -52,6 +52,11 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
uint8_t dmrs_type);
void init_scrambling_luts(void);
+void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order);
+uint8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol);
+uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb);
+
+void nr_generate_modulation_table(void);
extern __m64 byte2m64_re[256];
extern __m64 byte2m64_im[256];
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index 96796712b6..ebcf4116d2 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -163,7 +163,7 @@ uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB,
int16_t amp,
NR_DL_FRAME_PARMS frame_parms) {
- int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration
+ int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1] __attribute__((aligned(16))); // 3 for the max coreset duration
uint16_t cset_start_sc;
uint8_t cset_start_symb, cset_nsymb;
int k,l,k_prime,dci_idx, dmrs_idx;
@@ -264,7 +264,7 @@ uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB,
scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] );
#endif
/// QPSK modulation
- int16_t mod_dci[NR_MAX_DCI_SIZE>>1];
+ int16_t mod_dci[NR_MAX_DCI_SIZE>>1] __attribute__((aligned(16)));
nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, mod_dci); //Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_DCI
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index 23466132d6..4461edb33b 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -109,220 +109,255 @@ void nr_pdsch_codeword_scrambling_optim(uint8_t *in,
}
-uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
- uint32_t ***pdsch_dmrs,
- int32_t** txdataF,
- int16_t amp,
- int frame,
- uint8_t slot,
- NR_DL_FRAME_PARMS *frame_parms,
- int xOverhead,
- time_stats_t *dlsch_encoding_stats,
- time_stats_t *dlsch_scrambling_stats,
- time_stats_t *dlsch_modulation_stats,
- time_stats_t *tinput,
- time_stats_t *tprep,
- time_stats_t *tparity,
- time_stats_t *toutput,
- time_stats_t *dlsch_rate_matching_stats,
- time_stats_t *dlsch_interleaving_stats,
- time_stats_t *dlsch_segmentation_stats) {
+uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
+ int frame,
+ int slot) {
- int harq_pid = dlsch->harq_ids[frame%2][slot];
- NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid];
- nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
- uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
- int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
- int16_t **tx_layers = (int16_t**)dlsch->txdataF;
- int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
- uint8_t dmrs_Type = rel15->dmrsConfigType;
- int nb_re_dmrs;
- uint16_t n_dmrs;
- if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) {
- nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData;
- n_dmrs = ((rel15->rbSize+rel15->rbStart)*6)<<1;
- }
- else {
- nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
- n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1;
- }
- uint16_t nb_re;
- nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords;
- uint8_t Qm = rel15->qamModOrder[0];
- uint32_t encoded_length = nb_re*Qm;
- int16_t mod_dmrs[n_dmrs<<1];
+ NR_gNB_DLSCH_t *dlsch;
+ uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot];
+ int32_t** txdataF = gNB->common_vars.txdataF;
+ int16_t amp = AMP;
+ NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
+ int xOverhead = 0;
+ time_stats_t *dlsch_encoding_stats=&gNB->dlsch_encoding_stats;
+ time_stats_t *dlsch_scrambling_stats=&gNB->dlsch_scrambling_stats;
+ time_stats_t *dlsch_modulation_stats=&gNB->dlsch_modulation_stats;
+ time_stats_t *tinput=&gNB->tinput;
+ time_stats_t *tprep=&gNB->tprep;
+ time_stats_t *tparity=&gNB->tparity;
+ time_stats_t *toutput=&gNB->toutput;
+ time_stats_t *dlsch_rate_matching_stats=&gNB->dlsch_rate_matching_stats;
+ time_stats_t *dlsch_interleaving_stats=&gNB->dlsch_interleaving_stats;
+ time_stats_t *dlsch_segmentation_stats=&gNB->dlsch_segmentation_stats;
- /// CRC, coding, interleaving and rate matching
- AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
- start_meas(dlsch_encoding_stats);
- nr_dlsch_encoding(harq->pdu, frame, slot, dlsch, frame_parms,tinput,tprep,tparity,toutput,
- dlsch_rate_matching_stats,
- dlsch_interleaving_stats,
- dlsch_segmentation_stats);
- stop_meas(dlsch_encoding_stats);
+ for (int dlsch_id=0;dlsch_iddlsch[dlsch_id][0];
+ if (dlsch->slot_tx[slot] == 0) continue;
+
+ int harq_pid = dlsch->harq_ids[frame%2][slot];
+ NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid];
+ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
+ uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
+ int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
+ int16_t **tx_layers = (int16_t**)dlsch->txdataF;
+ int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
+ uint8_t dmrs_Type = rel15->dmrsConfigType;
+ int nb_re_dmrs;
+ uint16_t n_dmrs;
+ if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) {
+ nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData;
+ n_dmrs = ((rel15->rbSize+rel15->rbStart)*6)<<1;
+ }
+ else {
+ nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
+ n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1;
+ }
+ uint16_t nb_re;
+ nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords;
+ uint8_t Qm = rel15->qamModOrder[0];
+ uint32_t encoded_length = nb_re*Qm;
+ int16_t mod_dmrs[n_dmrs<<1] __attribute__ ((aligned(16)));
+
+
+ /// CRC, coding, interleaving and rate matching
+ AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
+ start_meas(dlsch_encoding_stats);
+ nr_dlsch_encoding(gNB,
+ harq->pdu, frame, slot, dlsch, frame_parms,tinput,tprep,tparity,toutput,
+ dlsch_rate_matching_stats,
+ dlsch_interleaving_stats,
+ dlsch_segmentation_stats);
+ stop_meas(dlsch_encoding_stats);
#ifdef DEBUG_DLSCH
- printf("PDSCH encoding:\nPayload:\n");
- for (int i=0; iB>>7; i++) {
- for (int j=0; j<16; j++)
- printf("0x%02x\t", harq->pdu[(i<<4)+j]);
- printf("\n");
- }
- printf("\nEncoded payload:\n");
- for (int i=0; i>3; i++) {
- for (int j=0; j<8; j++)
- printf("%d", harq->f[(i<<3)+j]);
- printf("\t");
- }
- printf("\n");
-#endif
-
-
-
- /// scrambling
- start_meas(dlsch_scrambling_stats);
- for (int q=0; qNrOfCodewords; q++)
- memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t));
- for (int q=0; qNrOfCodewords; q++)
- nr_pdsch_codeword_scrambling_optim(harq->f,
- encoded_length,
- q,
- rel15->dlDmrsScramblingId,
- rel15->rnti,
- scrambled_output[q]);
-
- stop_meas(dlsch_scrambling_stats);
-#ifdef DEBUG_DLSCH
- printf("PDSCH scrambling:\n");
- for (int i=0; i>8; i++) {
- for (int j=0; j<8; j++)
- printf("0x%08x\t", scrambled_output[0][(i<<3)+j]);
- printf("\n");
- }
-#endif
-
- /// Modulation
- start_meas(dlsch_modulation_stats);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 1);
- for (int q=0; qNrOfCodewords; q++)
- nr_modulation(scrambled_output[q],
- encoded_length,
- Qm,
- mod_symbs[q]);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 0);
- stop_meas(dlsch_modulation_stats);
-#ifdef DEBUG_DLSCH
- printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re);
- for (int i=0; i>3; i++) {
- for (int j=0; j<8; j++) {
- printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]);
+ printf("PDSCH encoding:\nPayload:\n");
+ for (int i=0; iB>>7; i++) {
+ for (int j=0; j<16; j++)
+ printf("0x%02x\t", harq->pdu[(i<<4)+j]);
+ printf("\n");
+ }
+ printf("\nEncoded payload:\n");
+ for (int i=0; i>3; i++) {
+ for (int j=0; j<8; j++)
+ printf("%d", harq->f[(i<<3)+j]);
+ printf("\t");
}
printf("\n");
- }
#endif
-
-
- /// Layer mapping
- nr_layer_mapping(mod_symbs,
- rel15->nrOfLayers,
- nb_re,
- tx_layers);
+
+
+
+ /// scrambling
+ start_meas(dlsch_scrambling_stats);
+ for (int q=0; qNrOfCodewords; q++)
+ memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t));
+ for (int q=0; qNrOfCodewords; q++)
+ nr_pdsch_codeword_scrambling_optim(harq->f,
+ encoded_length,
+ q,
+ rel15->dlDmrsScramblingId,
+ rel15->rnti,
+ scrambled_output[q]);
+
+ stop_meas(dlsch_scrambling_stats);
#ifdef DEBUG_DLSCH
- printf("Layer mapping (%d layers):\n", rel15->nrOfLayers);
- for (int l=0; lnrOfLayers; l++)
- for (int i=0; i<(nb_re/rel15->nrOfLayers)>>3; i++) {
- printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7);
+ printf("PDSCH scrambling:\n");
+ for (int i=0; i>8; i++) {
+ for (int j=0; j<8; j++)
+ printf("0x%08x\t", scrambled_output[0][(i<<3)+j]);
+ printf("\n");
+ }
+#endif
+
+ /// Modulation
+ start_meas(dlsch_modulation_stats);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 1);
+ for (int q=0; qNrOfCodewords; q++)
+ nr_modulation(scrambled_output[q],
+ encoded_length,
+ Qm,
+ mod_symbs[q]);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 0);
+ stop_meas(dlsch_modulation_stats);
+#ifdef DEBUG_DLSCH
+ printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re);
+ for (int i=0; i>3; i++) {
for (int j=0; j<8; j++) {
- printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]);
+ printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]);
}
printf("\n");
}
#endif
-
- /// Antenna port mapping
- //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007
-
- /// DMRS QPSK modulation
-
-
- l0 = get_l0(rel15->dlDmrsSymbPos);
- nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
-
+
+
+ /// Layer mapping
+ nr_layer_mapping(mod_symbs,
+ rel15->nrOfLayers,
+ nb_re,
+ tx_layers);
#ifdef DEBUG_DLSCH
- printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_Type);
- for (int i=0; i>4; i++) {
- for (int j=0; j<8; j++) {
- printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]);
+ printf("Layer mapping (%d layers):\n", rel15->nrOfLayers);
+ for (int l=0; lnrOfLayers; l++)
+ for (int i=0; i<(nb_re/rel15->nrOfLayers)>>3; i++) {
+ printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7);
+ for (int j=0; j<8; j++) {
+ printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]);
+ }
+ printf("\n");
+ }
+#endif
+
+ /// Antenna port mapping
+ //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007
+
+ /// DMRS QPSK modulation
+
+
+ l0 = get_l0(rel15->dlDmrsSymbPos);
+ nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
+
+#ifdef DEBUG_DLSCH
+ printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_Type);
+ for (int i=0; i>4; i++) {
+ for (int j=0; j<8; j++) {
+ printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]);
+ }
+ printf("\n");
}
- printf("\n");
- }
#endif
-
-
- /// Resource mapping
-
- // Non interleaved VRB to PRB mapping
- uint16_t start_sc = frame_parms->first_carrier_offset + rel15->rbStart*NR_NB_SC_PER_RB;
- if (start_sc >= frame_parms->ofdm_symbol_size)
- start_sc -= frame_parms->ofdm_symbol_size;
-
+
+
+ /// Resource mapping
+
+ // Non interleaved VRB to PRB mapping
+ uint16_t start_sc = frame_parms->first_carrier_offset + rel15->rbStart*NR_NB_SC_PER_RB;
+ if (start_sc >= frame_parms->ofdm_symbol_size)
+ start_sc -= frame_parms->ofdm_symbol_size;
+
#ifdef DEBUG_DLSCH_MAPPING
- printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
- start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
+ printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
+ start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
#endif
- for (int ap=0; apnrOfLayers; ap++) {
-
- // DMRS params for this ap
- get_Wt(Wt, ap, dmrs_Type);
- get_Wf(Wf, ap, dmrs_Type);
- delta = get_delta(ap, dmrs_Type);
- l_prime[0] = 0; // single symbol ap 0
- uint8_t dmrs_symbol = l0+l_prime[0];
+ for (int ap=0; apnrOfLayers; ap++) {
+
+ // DMRS params for this ap
+ get_Wt(Wt, ap, dmrs_Type);
+ get_Wf(Wf, ap, dmrs_Type);
+ delta = get_delta(ap, dmrs_Type);
+ l_prime[0] = 0; // single symbol ap 0
+ uint8_t dmrs_symbol = l0+l_prime[0];
#ifdef DEBUG_DLSCH_MAPPING
- printf("DMRS Type %d params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n",
- 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol);
+ printf("DMRS Type %d params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n",
+ 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol);
#endif
- uint8_t k_prime=0;
- uint16_t m=0, n=0, dmrs_idx=0, k=0;
-
- int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP;
- if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k)
- dmrs_idx = rel15->rbStart*6;
- else
- dmrs_idx = rel15->rbStart*4;
-
- for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) {
- k = start_sc;
- for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) {
- if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
+ uint8_t k_prime=0;
+ uint16_t m=0, n=0, dmrs_idx=0, k=0;
+
+ int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP;
+ if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k)
+ dmrs_idx = rel15->rbStart*6;
+ else
+ dmrs_idx = rel15->rbStart*4;
+
+ for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) {
+ k = start_sc;
+ for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) {
+ if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
- printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
- dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
-#endif
- dmrs_idx++;
- k_prime++;
- k_prime&=1;
- n+=(k_prime)?0:1;
- }
-
- else {
- if( (l != dmrs_symbol) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
-#ifdef DEBUG_DLSCH_MAPPING
- printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
- m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
+ printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
+ dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif
- m++;
- }
- }
- if (++k >= frame_parms->ofdm_symbol_size)
- k -= frame_parms->ofdm_symbol_size;
- }
- }
- }
+ dmrs_idx++;
+ k_prime++;
+ k_prime&=1;
+ n+=(k_prime)?0:1;
+ }
+
+ else {
+ if( (l != dmrs_symbol) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
+#ifdef DEBUG_DLSCH_MAPPING
+ printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
+ m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
+#endif
+ m++;
+ }
+ }
+ if (++k >= frame_parms->ofdm_symbol_size)
+ k -= frame_parms->ofdm_symbol_size;
+ } //RE loop
+ } // symbol loop
+ }// layer loop
+ dlsch->slot_tx[slot]=0;
+ }// dlsch loop
return 0;
}
+
+void dump_pdsch_stats(PHY_VARS_gNB *gNB) {
+
+ for (int i=0;idlsch_stats[i].rnti > 0)
+ LOG_I(PHY,"DLSCH RNTI %x: round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, current_Qm %d, current_RI %d, total_bytes TX %d\n",
+ gNB->dlsch_stats[i].rnti,
+ gNB->dlsch_stats[i].round_trials[0],
+ (double)gNB->dlsch_stats[i].round_trials[1]/gNB->dlsch_stats[i].round_trials[0],
+ gNB->dlsch_stats[i].round_trials[1],
+ (double)gNB->dlsch_stats[i].round_trials[2]/gNB->dlsch_stats[i].round_trials[0],
+ gNB->dlsch_stats[i].round_trials[2],
+ (double)gNB->dlsch_stats[i].round_trials[3]/gNB->dlsch_stats[i].round_trials[0],
+ gNB->dlsch_stats[i].round_trials[3],
+ gNB->dlsch_stats[i].current_Qm,
+ gNB->dlsch_stats[i].current_RI,
+ gNB->dlsch_stats[i].total_bytes_tx);
+
+}
+
+void clear_pdsch_stats(PHY_VARS_gNB *gNB) {
+
+ for (int i=0;idlsch_stats[i],0,sizeof(gNB->dlsch_stats[i]));
+}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
index 3a6851ee8f..23ec756531 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
@@ -69,27 +69,9 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
unsigned char *sdu);
-uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
- uint32_t ***pdsch_dmrs,
- int32_t** txdataF,
- int16_t amp,
- int frame,
- uint8_t slot,
- NR_DL_FRAME_PARMS *frame_parms,
- int xOverhead,
- time_stats_t *dlsch_encoding_stats,
- time_stats_t *dlsch_scrambling_stats,
- time_stats_t *dlsch_modulation_stats,
- time_stats_t *tinput,
- time_stats_t *tprep,
- time_stats_t *tparity,
- time_stats_t *toutput,
- time_stats_t *dlsch_rate_matching_stats,
- time_stats_t *dlsch_interleaving_stats,
- time_stats_t *dlsch_segmentation_stats);
-
-
-
+uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
+ int frame,
+ int slot);
void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB);
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
@@ -98,7 +80,10 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
-int nr_dlsch_encoding(unsigned char *a,int frame,
+NR_gNB_SCH_STATS_t *find_nr_dlsch_stats(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
+
+int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
+ unsigned char *a,int frame,
uint8_t slot,
NR_gNB_DLSCH_t *dlsch,
NR_DL_FRAME_PARMS* frame_parms,
@@ -113,4 +98,8 @@ int nr_dlsch_encoding(unsigned char *a,int frame,
void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size);
+void dump_pdsch_stats(PHY_VARS_gNB *gNB);
+
+void clear_pdsch_stats(PHY_VARS_gNB *gNB);
+
#endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index de5e9415b1..e5841d3262 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -309,7 +309,8 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
}
}
-int nr_dlsch_encoding(unsigned char *a,
+int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
+ unsigned char *a,
int frame,
uint8_t slot,
NR_gNB_DLSCH_t *dlsch,
@@ -354,6 +355,28 @@ int nr_dlsch_encoding(unsigned char *a,
A = rel15->TBSize[0]<<3;
+ NR_gNB_SCH_STATS_t *stats=NULL;
+ int first_free=-1;
+ for (int i=0;idlsch_stats[i].rnti == 0 && first_free == -1) {
+ first_free = i;
+ stats=&gNB->dlsch_stats[i];
+ }
+ if (gNB->dlsch_stats[i].rnti == dlsch->rnti) {
+ stats=&gNB->dlsch_stats[i];
+ break;
+ }
+ }
+
+ if (stats) {
+ stats->round_trials[dlsch->harq_processes[harq_pid]->round]++;
+ stats->rnti = dlsch->rnti;
+ if (dlsch->harq_processes[harq_pid]->round == 0){
+ stats->total_bytes_tx += rel15->TBSize[0];
+ stats->current_RI = rel15->nrOfLayers;
+ stats->current_Qm = rel15->qamModOrder[0];
+ }
+ }
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers);
LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
index ba0bf6b4bf..5ce2c45a7d 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
@@ -255,27 +255,28 @@ void nr_emulate_dlsch_payload(uint8_t* pdu, uint16_t size) {
}
int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
-
- uint16_t i;
- int16_t first_free_index=-1;
-
- AssertFatal(gNB!=NULL,"gNB is null\n");
- for (i=0; idlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i);
- AssertFatal(gNB->dlsch[i][0]!=NULL,"gNB->dlsch[%d][0] is null\n",i);
- LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index);
- if ((gNB->dlsch[i][0]->harq_mask >0) &&
- (gNB->dlsch[i][0]->rnti==rnti)) return i;
- else if ((gNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
- }
- if (type == SEARCH_EXIST) return -1;
- if (first_free_index != -1)
- gNB->dlsch[first_free_index][0]->rnti = 0;
- return first_free_index;
+
+ uint16_t i;
+ int16_t first_free_index=-1;
+
+ AssertFatal(gNB!=NULL,"gNB is null\n");
+ for (i=0; idlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i);
+ AssertFatal(gNB->dlsch[i][0]!=NULL,"gNB->dlsch[%d][0] is null\n",i);
+ LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,
+ gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index);
+ if ((gNB->dlsch[i][0]->harq_mask >0) &&
+ (gNB->dlsch[i][0]->rnti==rnti)) return i;
+ else if ((gNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
+ }
+ if (type == SEARCH_EXIST) return -1;
+ if (first_free_index != -1)
+ gNB->dlsch[first_free_index][0]->rnti = 0;
+ return first_free_index;
+
}
-
void nr_fill_dlsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
index bc33d93811..bd1278b2eb 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
@@ -40,7 +40,7 @@
//#define DEBUG_PBCH_ENCODING
//#define DEBUG_PBCH_DMRS
-extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
+extern short nr_qpsk_mod_table[8];
uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31
@@ -61,9 +61,9 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
/// QPSK modulation
for (int m=0; m>5])>>((m<<1)&0x1f))&1)<<1) ^ (((gold_pbch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1);
- mod_dmrs[m<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
- mod_dmrs[(m<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
+ idx = (((gold_pbch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&3);
+ mod_dmrs[m<<1] = nr_qpsk_mod_table[idx<<1];
+ mod_dmrs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1];
#ifdef DEBUG_PBCH_DMRS
printf("m %d idx %d gold seq %d b0-b1 %d-%d mod_dmrs %d %d\n", m, idx, gold_pbch_dmrs[(m<<1)>>5], (((gold_pbch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&1),
(((gold_pbch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), mod_dmrs[(m<<1)], mod_dmrs[(m<<1)+1]);
@@ -323,9 +323,9 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
/// QPSK modulation
for (int i=0; i>1; i++) {
- idx = (((pbch->pbch_e[(i<<1)>>5]>>((i<<1)&0x1f))&1)<<1) ^ ((pbch->pbch_e[((i<<1)+1)>>5]>>(((i<<1)+1)&0x1f))&1);
- mod_pbch_e[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
- mod_pbch_e[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1)+1];
+ idx = ((pbch->pbch_e[(i<<1)>>5]>>((i<<1)&0x1f))&3);
+ mod_pbch_e[i<<1] = nr_qpsk_mod_table[idx<<1];
+ mod_pbch_e[(i<<1)+1] = nr_qpsk_mod_table[(idx<<1)+1];
#ifdef DEBUG_PBCH
printf("i %d idx %d mod_pbch %d %d\n", i, idx, mod_pbch_e[2*i], mod_pbch_e[2*i+1]);
#endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index b8025a828b..8cb7ad45e7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -157,7 +157,6 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
uint8_t is_dmrs_symbol,
- uint8_t is_ptrs_symbol,
nfapi_nr_pusch_pdu_t *pusch_pdu,
NR_DL_FRAME_PARMS *frame_parms);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
index 9928f3f604..0040f01544 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
@@ -111,7 +111,6 @@ void nr_ulsch_unscrambling_optim(int16_t* llr,
uint32_t n_RNTI) {
#if defined(__x86_64__) || defined(__i386__)
- uint8_t reset;
uint32_t x1, x2, s=0;
x2 = (n_RNTI<<15) + Nid;
@@ -137,3 +136,29 @@ void nr_ulsch_unscrambling_optim(int16_t* llr,
n_RNTI);
#endif
}
+
+void dump_pusch_stats(PHY_VARS_gNB *gNB) {
+
+ for (int i=0;iulsch_stats[i].rnti>0)
+ LOG_I(PHY,"ULSCH RNTI %x: round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, current_Qm %d, current_RI %d, total_bytes RX/SCHED %d/%d\n",
+ gNB->ulsch_stats[i].rnti,
+ gNB->ulsch_stats[i].round_trials[0],
+ (double)gNB->ulsch_stats[i].round_trials[1]/gNB->ulsch_stats[i].round_trials[0],
+ gNB->ulsch_stats[i].round_trials[1],
+ (double)gNB->ulsch_stats[i].round_trials[2]/gNB->ulsch_stats[i].round_trials[0],
+ gNB->ulsch_stats[i].round_trials[2],
+ (double)gNB->ulsch_stats[i].round_trials[3]/gNB->ulsch_stats[i].round_trials[0],
+ gNB->ulsch_stats[i].round_trials[3],
+ gNB->ulsch_stats[i].current_Qm,
+ gNB->ulsch_stats[i].current_RI,
+ gNB->ulsch_stats[i].total_bytes_rx,
+ gNB->ulsch_stats[i].total_bytes_tx);
+
+}
+
+void clear_pusch_stats(PHY_VARS_gNB *gNB) {
+
+ for (int i=0;iulsch_stats[i],0,sizeof(gNB->ulsch_stats[i]));
+}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
index f4f977ff74..a9845b6bbb 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
@@ -87,3 +87,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
int UE_id,
uint8_t harq_pid);
int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
+
+void dump_pusch_stats(PHY_VARS_gNB *gNB);
+
+void clear_pusch_stats(PHY_VARS_gNB *gNB);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index a31b4acb1e..7980206eb4 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -208,8 +208,6 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
ulsch->Mlimit = 0;
ulsch->max_ldpc_iterations = 0;
ulsch->last_iteration_cnt = 0;
- ulsch->num_active_cba_groups = 0;
- for (i=0;icba_rnti[i] = 0;
for (i=0;iharq_process_id[i] = 0;
for (i=0; iharq_processes[i]->rar_alloc=0;
ulsch->harq_processes[i]->status=NR_SCH_IDLE;
ulsch->harq_processes[i]->subframe_scheduling_flag=0;
- ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0;
ulsch->harq_processes[i]->phich_active=0;
ulsch->harq_processes[i]->phich_ACK=0;
ulsch->harq_processes[i]->previous_first_rb=0;
@@ -289,7 +286,7 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
static uint32_t prnt_crc_cnt = 0;
#endif
-uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
+uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
uint8_t UE_id,
short *ulsch_llr,
NR_DL_FRAME_PARMS *frame_parms,
@@ -311,7 +308,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#endif
- NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0];
+ NR_gNB_ULSCH_t *ulsch = gNB->ulsch[UE_id][0];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
t_nrLDPC_dec_params decParams;
@@ -366,15 +363,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers);
-
- if (R<1024)
- Coderate = (float) R /(float) 1024;
- else
- Coderate = (float) R /(float) 2048;
-
- if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
- p_decParams->BG = 2;
- if (Coderate < 0.3333) {
+ if (R<1024)
+ Coderate = (float) R /(float) 1024;
+ else
+ Coderate = (float) R /(float) 2048;
+
+ if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
+ p_decParams->BG = 2;
+ if (Coderate < 0.3333) {
p_decParams->R = 15;
kc = 52;
}
@@ -401,8 +397,29 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
kc = 27;
}
}
-
+
+ NR_gNB_SCH_STATS_t *stats=NULL;
+ int first_free=-1;
+ for (int i=0;iulsch_stats[i].rnti == 0 && first_free == -1) {
+ first_free = i;
+ stats=&gNB->ulsch_stats[i];
+ }
+ if (gNB->ulsch_stats[i].rnti == ulsch->rnti) {
+ stats=&gNB->ulsch_stats[i];
+ break;
+ }
+ }
+ if (stats) {
+ stats->rnti = ulsch->rnti;
+ stats->round_trials[harq_process->round]++;
+ }
if (harq_process->round == 0) {
+ if (stats) {
+ stats->current_Qm = Qm;
+ stats->current_RI = n_layers;
+ stats->total_bytes_tx += harq_process->TBS;
+ }
// This is a new packet, so compute quantities regarding segmentation
if (A > 3824)
harq_process->B = A+24;
@@ -460,7 +477,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
- start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
+ start_meas(&gNB->ulsch_deinterleaving_stats);
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
@@ -476,10 +493,10 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
//for (int i =0; i<16; i++)
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
- stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
+ stop_meas(&gNB->ulsch_deinterleaving_stats);
- LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
+ LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rvidx %d, round %d)...\n",
harq_pid,r, G,
Kr*3,
harq_process->TBS,
@@ -497,7 +514,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
- start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
+ start_meas(&gNB->ulsch_rate_unmatching_stats);
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers,harq_process->C);
@@ -514,12 +531,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
harq_process->F,
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
- stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
+ stop_meas(&gNB->ulsch_rate_unmatching_stats);
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
return (ulsch->max_ldpc_iterations + 1);
} else {
- stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
+ stop_meas(&gNB->ulsch_rate_unmatching_stats);
}
r_offset += E;
@@ -557,7 +574,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
if (err_flag == 0) {
- start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
+ start_meas(&gNB->ulsch_ldpc_decoding_stats);
//LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A);
@@ -625,7 +642,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
//write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
#endif
- stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
+ stop_meas(&gNB->ulsch_ldpc_decoding_stats);
}
if ((err_flag == 0) && (ret >= (ulsch->max_ldpc_iterations + 1))) {
@@ -648,7 +665,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#ifdef gNB_DEBUG_TRACE
LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) Kr %d r %d\n",
- phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,Kr,r);
+ gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,Kr,r);
#endif
// harq_process->harq_ack.ack = 0;
@@ -665,7 +682,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
// LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
- // phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
+ // gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
harq_process->handled = 1;
ret = ulsch->max_ldpc_iterations + 1;
@@ -674,7 +691,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#ifdef gNB_DEBUG_TRACE
LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n",
- phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS);
+ gNB->Mod_id,nr_tti_rx,harq_process->TBS);
#endif
harq_process->status = SCH_IDLE;
@@ -685,7 +702,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
// harq_process->harq_ack.harq_id = harq_pid;
// harq_process->harq_ack.send_harq_status = 1;
- // LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
+ // LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
// Reassembly of Transport block here
@@ -708,14 +725,15 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#endif
}
+ if (stats) stats->total_bytes_rx += harq_process->TBS;
}
#ifdef DEBUG_ULSCH_DECODING
- LOG_I(PHY, "Decoder output (payload): \n");
- for (i = 0; i < harq_process->TBS ; i++) {
+ LOG_I(PHY, "Decoder output (payload) at SFN/SF: %d/%d TBS: %d\n", frame, nr_tti_rx,harq_process->TBS);
+ for (i = 0; i < harq_process->TBS; i++) {
//harq_process_ul_ue->a[i] = (unsigned char) rand();
//printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
- printf("%02x",harq_process->b[i]);
+ printf("%02x ",harq_process->b[i]);
}
#endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 03bb1e11dc..3fd7966ce7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -226,25 +226,19 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
uint8_t is_dmrs_symbol,
- uint8_t is_ptrs_symbol,
nfapi_nr_pusch_pdu_t *pusch_pdu,
NR_DL_FRAME_PARMS *frame_parms)
{
unsigned short start_re, re, nb_re_pusch;
unsigned char aarx;
- uint8_t K_ptrs = 0;
uint32_t rxF_ext_index = 0;
uint32_t ul_ch0_ext_index = 0;
uint32_t ul_ch0_index = 0;
- uint32_t ul_ch0_ptrs_ext_index = 0;
- uint32_t ul_ch0_ptrs_index = 0;
uint8_t k_prime;
- uint16_t n=0, num_ptrs_symbols;
+ uint16_t n;
int16_t *rxF,*rxF_ext;
int *ul_ch0,*ul_ch0_ext;
- int *ul_ch0_ptrs,*ul_ch0_ptrs_ext;
- uint16_t n_rnti = pusch_pdu->rnti;
uint8_t delta = 0;
#ifdef DEBUG_RB_EXT
@@ -253,8 +247,8 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size);
#endif
-
- uint8_t is_dmrs_re=0,is_ptrs_re=0;
+
+ uint8_t is_dmrs_re;
start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
#ifdef __AVX2__
@@ -263,10 +257,8 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
int nb_re_pusch2 = nb_re_pusch;
#endif
- num_ptrs_symbols = 0;
-
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
-
+
rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6
@@ -274,20 +266,17 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aarx][symbol*nb_re_pusch2];
- ul_ch0_ptrs = &pusch_vars->ul_ch_ptrs_estimates[aarx][pusch_vars->ptrs_symbol_index*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available
-
- ul_ch0_ptrs_ext = &pusch_vars->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch];
-
n = 0;
k_prime = 0;
- if (is_dmrs_symbol == 0 && is_ptrs_symbol == 0) {
+ if (is_dmrs_symbol == 0) {
//
//rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
- if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) memcpy1((void*)rxF_ext,
- (void*)&rxF[start_re*2],
- nb_re_pusch*sizeof(int32_t));
- else {
+ if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) {
+ memcpy1((void*)rxF_ext,
+ (void*)&rxF[start_re*2],
+ nb_re_pusch*sizeof(int32_t));
+ } else {
int neg_length = frame_parms->ofdm_symbol_size-start_re;
int pos_length = nb_re_pusch-neg_length;
@@ -298,56 +287,36 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
}
else {
for (re = 0; re < nb_re_pusch; re++) {
-
- if (is_dmrs_symbol) is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type));
-
- if (is_ptrs_symbol) {
- K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
- is_ptrs_re = is_ptrs_subcarrier((start_re + re) % frame_parms->ofdm_symbol_size,
- n_rnti,
- aarx,
- pusch_pdu->dmrs_config_type,
- K_ptrs,
- pusch_pdu->rb_size,
- pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
- start_re,
- frame_parms->ofdm_symbol_size);
-
- num_ptrs_symbols+=is_ptrs_re;
-
- }
-
+
+ is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type));
+
#ifdef DEBUG_RB_EXT
- printf("re = %d, ptrs_symbol_flag = %d, symbol = %d\n", re, ptrs_symbol_flag, symbol);
+ printf("re = %d, kprime %d, n %d, is_dmrs_symbol = %d, symbol = %d\n", re, k_prime, n, is_dmrs_symbol, symbol);
#endif
- if ( is_dmrs_re == 0 && is_ptrs_re == 0) {
-
- rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
- rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
- ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
- ul_ch0_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index];
-
+ /* save only data and respective channel estimates */
+ if (is_dmrs_re == 0) {
+ rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
+ rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
+ ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
+
#ifdef DEBUG_RB_EXT
- printf("rxF_ext[%d] = (%d,%d)\n", rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1]);
+ printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n",
+ is_dmrs_symbol,rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1],
+ ul_ch0_ext_index, ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[0], ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[1]);
#endif
- ul_ch0_ext_index++;
- ul_ch0_ptrs_ext_index++;
- rxF_ext_index +=2;
- } else {
- k_prime++;
- k_prime&=1;
- n+=(k_prime)?0:1;
- }
- ul_ch0_index++;
- ul_ch0_ptrs_index++;
+ ul_ch0_ext_index++;
+ rxF_ext_index +=2;
+ } else {
+ n += k_prime;
+ k_prime ^= 1;
+ }
+ ul_ch0_index++;
}
- } // is_dmrs_symbol ==0 && is_ptrs_symbol == 0
- }
- pusch_vars->ptrs_sc_per_ofdm_symbol = num_ptrs_symbols;
-
+ }
+ }
}
-
+
void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms,
NR_gNB_ULSCH_t **ulsch_gNB,
@@ -1044,6 +1013,67 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
}
+void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **ul_ch_mag,
+ int32_t **ul_ch_magb,
+ uint8_t symbol,
+ uint16_t nb_rb) {
+ int n_rx = frame_parms->nb_antennas_rx;
+#if defined(__x86_64__) || defined(__i386__)
+ __m128i *rxdataF_comp128[1+n_rx],*ul_ch_mag128[1+n_rx],*ul_ch_mag128b[1+n_rx];
+#elif defined(__arm__)
+ int16x8_t *rxdataF_comp128_0,*ul_ch_mag128_0,*ul_ch_mag128_0b;
+ int16x8_t *rxdataF_comp128_1,*ul_ch_mag128_1,*ul_ch_mag128_1b;
+#endif
+ int32_t i;
+
+#ifdef __AVX2__
+ int off = ((nb_rb&1) == 1)? 4:0;
+#else
+ int off = 0;
+#endif
+
+ if (frame_parms->nb_antennas_rx>1) {
+#if defined(__x86_64__) || defined(__i386__)
+ int nb_re = nb_rb*12;
+ for (int aa=0;aanb_antennas_rx;aa++) {
+ rxdataF_comp128[aa] = (__m128i *)&rxdataF_comp[aa][(symbol*(nb_re + off))];
+ ul_ch_mag128[aa] = (__m128i *)&ul_ch_mag[aa][(symbol*(nb_re + off))];
+ ul_ch_mag128b[aa] = (__m128i *)&ul_ch_magb[aa][(symbol*(nb_re + off))];
+
+ // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
+ for (i=0; iN_RB_DL*12];
+ rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12];
+ ul_ch_mag128_0 = (int16x8_t *)&ul_ch_mag[0][symbol*frame_parms->N_RB_DL*12];
+ ul_ch_mag128_1 = (int16x8_t *)&ul_ch_mag[1][symbol*frame_parms->N_RB_DL*12];
+ ul_ch_mag128_0b = (int16x8_t *)&ul_ch_magb[0][symbol*frame_parms->N_RB_DL*12];
+ ul_ch_mag128_1b = (int16x8_t *)&ul_ch_magb[1][symbol*frame_parms->N_RB_DL*12];
+
+ // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
+ for (i=0; iframe_parms;
nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu;
dmrs_symbol_flag = 0;
- ptrs_symbol_flag = 0;
-
- gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol = 0;
if(symbol == rel15_ul->start_symbol_index){
- gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset = 0;
gNB->pusch_vars[ulsch_id]->dmrs_symbol = 0;
gNB->pusch_vars[ulsch_id]->cl_done = 0;
- gNB->pusch_vars[ulsch_id]->ptrs_symbols = 0;
-
- if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { // if there is ptrs pdu
- L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
-
- set_ptrs_symb_idx(&gNB->pusch_vars[ulsch_id]->ptrs_symbols,
- rel15_ul->nr_of_symbols,
- rel15_ul->start_symbol_index,
- L_ptrs,
- rel15_ul->ul_dmrs_symb_pos);
- }
}
@@ -1088,6 +1101,9 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
dmrs_symbol_flag = ((rel15_ul->ul_dmrs_symb_pos)>>symbol)&0x01;
+ LOG_D(PHY,"symbol %d bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n",symbol,bwp_start_subcarrier,rel15_ul->rb_start,frame_parms->first_carrier_offset);
+ LOG_D(PHY,"ul_dmrs_symb_pos %x\n",rel15_ul->ul_dmrs_symb_pos);
+
if (dmrs_symbol_flag == 1){
if (((rel15_ul->ul_dmrs_symb_pos)>>((symbol+1)%frame_parms->symbols_per_slot))&0x01)
AssertFatal(1==0,"Double DMRS configuration is not yet supported\n");
@@ -1100,18 +1116,12 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
else {
nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*4));
}
+ LOG_D(PHY,"dmrs_symbol: nb_re_pusch %d\n",nb_re_pusch);
gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol;
} else {
nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
}
- if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { // if there is ptrs pdu
- if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols)) {
- gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = symbol;
- ptrs_symbol_flag = 1;
- }
- }
-
//----------------------------------------------------------
//--------------------- Channel estimation ---------------------
//----------------------------------------------------------
@@ -1139,16 +1149,21 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
if (nb_re_pusch > 0) {
+ gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] = nb_re_pusch;
+
start_meas(&gNB->ulsch_rbs_extraction_stats);
nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
gNB->pusch_vars[ulsch_id],
symbol,
dmrs_symbol_flag,
- ptrs_symbol_flag,
rel15_ul,
frame_parms);
stop_meas(&gNB->ulsch_rbs_extraction_stats);
+ //----------------------------------------------------------
+ //--------------------- Channel Scaling --------------------
+ //----------------------------------------------------------
+
nr_ulsch_scale_channel(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
frame_parms,
gNB->ulsch[ulsch_id],
@@ -1177,6 +1192,10 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
gNB->pusch_vars[ulsch_id]->cl_done = 1;
}
+ //----------------------------------------------------------
+ //--------------------- Channel Compensation ---------------
+ //----------------------------------------------------------
+
start_meas(&gNB->ulsch_channel_compensation_stats);
nr_ulsch_channel_compensation(gNB->pusch_vars[ulsch_id]->rxdataF_ext,
gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
@@ -1192,34 +1211,66 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
gNB->pusch_vars[ulsch_id]->log2_maxh);
stop_meas(&gNB->ulsch_channel_compensation_stats);
-
+ start_meas(&gNB->ulsch_mrc_stats);
+ nr_ulsch_detection_mrc(frame_parms,
+ gNB->pusch_vars[ulsch_id]->rxdataF_comp,
+ gNB->pusch_vars[ulsch_id]->ul_ch_mag,
+ gNB->pusch_vars[ulsch_id]->ul_ch_magb,
+ symbol,
+ rel15_ul->rb_size);
+ stop_meas(&gNB->ulsch_mrc_stats);
#ifdef NR_SC_FDMA
nr_idft(&((uint32_t*)gNB->pusch_vars[ulsch_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
#endif
- //----------------------------------------------------------
- //-------------------- LLRs computation --------------------
- //----------------------------------------------------------
- start_meas(&gNB->ulsch_llr_stats);
- AssertFatal(gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order+nb_re_pusch*rel15_ul->qam_mod_order < (8*((3*8*6144)+12)) , "Mysterious llr buffer size check");
+
+ //----------------------------------------------------------
+ //--------------------- PTRS Processing --------------------
+ //----------------------------------------------------------
+
+ /* In case PTRS is enabled then LLR will be calculated after PTRS symbols are processed *
+ * otherwise LLR are calculated for each symbol based upon DMRS channel estimates only. */
+ if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS)
+ {
+ start_meas(&gNB->ulsch_ptrs_processing_stats);
+ nr_pusch_ptrs_processing(gNB,
+ rel15_ul,
+ ulsch_id,
+ nr_tti_rx,
+ dmrs_symbol_flag,
+ symbol,
+ nb_re_pusch);
+ stop_meas(&gNB->ulsch_ptrs_processing_stats);
+
+ /* Subtract total PTRS RE's in the symbol from PUSCH RE's */
+ gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol;
+ }
+
+ /*---------------------------------------------------------------------------------------------------- */
+ /*-------------------- LLRs computation -------------------------------------------------------------*/
+ /*-----------------------------------------------------------------------------------------------------*/
+ if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1))
+ {
#ifdef __AVX2__
- int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
+ int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
#else
- int off = 0;
+ int off = 0;
#endif
- nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * (off+(rel15_ul->rb_size * NR_NB_SC_PER_RB))],
- gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
- gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
- &gNB->pusch_vars[ulsch_id]->llr[gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order],
- rel15_ul->rb_size,
- nb_re_pusch,
- symbol,
- rel15_ul->qam_mod_order);
- stop_meas(&gNB->ulsch_llr_stats);
-
+ uint32_t rxdataF_ext_offset = 0;
+ for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) {
+ start_meas(&gNB->ulsch_llr_stats);
+ nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][i * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)],
+ gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
+ gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
+ &gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order],
+ rel15_ul->rb_size,
+ gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i],
+ i,
+ rel15_ul->qam_mod_order);
+ stop_meas(&gNB->ulsch_llr_stats);
+ rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i];
+ }// symbol loop
+ }// last symbol check
}
-
- gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset = gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset + nb_re_pusch;
return (0);
-
}
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index 6f551fcce8..71132b64c5 100644
--- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c
+++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
@@ -340,6 +340,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
}
}
int32_t corr_re,corr_im,temp,no_corr=0;
+ int32_t av_corr=0;
int seq_index;
for(i=0;i%f\n",mcs[i],seq_index,corr_re,corr_im,10*log10(corr_re*corr_re + corr_im*corr_im));
#endif
temp=corr_re*corr_re + corr_im*corr_im;
- no_corr+=temp;
+ av_corr+=temp;
if (temp>xrtmag) {
xrtmag=temp;
maxpos=i;
}
}
- no_corr-=xrtmag;
- if (nr_sequences>1)
- no_corr/=(nr_sequences-1);
+ if(nr_sequences>1)
+ no_corr=(av_corr-xrtmag)/(nr_sequences-1);
+ av_corr/=nr_sequences;
uint8_t xrtmag_dB = dB_fixed(xrtmag);
@@ -386,17 +387,21 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
else if (SNRtimes10 > 635) cqi=255;
else cqi=(640+SNRtimes10)/5;
+ bool no_conf=false;
+ if (nr_sequences>1) {
+ if ((xrtmag_dB<(11+dB_fixed(no_corr))) || (dB_fixed(av_corr)<(13+gNB->measurements.n0_power_tot_dB))) //TODO these are temporary threshold based on measurments with the phone
+ no_conf=true;
+ }
// first bit of bitmap for sr presence and second bit for acknack presence
uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
uci_pdu->pucch_format = 0; // format 0
uci_pdu->ul_cqi = cqi; // currently not valid
uci_pdu->timing_advance = 0xffff; // currently not valid
- uci_pdu->rssi = 0xffff; // currently not valid
-
+ uci_pdu->rssi = 1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(signal_energy(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12)));
if (pucch_pdu->bit_len_harq==0) {
uci_pdu->harq = NULL;
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
- uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+gNB->measurements.n0_power_tot_dB)) ? 1 : 0;
+ uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(13+gNB->measurements.n0_power_tot_dB)) ? 1 : 0;
if (xrtmag_dB>(gNB->measurements.n0_power_tot_dB)) {
uci_pdu->sr->sr_indication = 1;
} else {
@@ -406,7 +411,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
else if (pucch_pdu->bit_len_harq==1) {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 1;
- uci_pdu->harq->harq_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
+ uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0;
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
uci_pdu->harq->harq_list[0].harq_value = index&0x01;
LOG_I(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n",
@@ -414,13 +419,13 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>1) ? 1 : 0;
- uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
+ uci_pdu->sr->sr_confidence_level = (no_conf) ? 1 : 0;
}
}
else {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 2;
- uci_pdu->harq->harq_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
+ uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0;
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
uci_pdu->harq->harq_list[1].harq_value = index&0x01;
uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01;
@@ -429,7 +434,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
- uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
+ uci_pdu->sr->sr_confidence_level = (no_conf) ? 1 : 0;
}
}
}
@@ -1435,56 +1440,60 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
}
printf("\n");
#endif
- // do complex correlation
- for (int aa=0;aa (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",aa,
- ((int16_t*)&prod_re[aa])[0],((int16_t*)&prod_re[aa])[1],((int16_t*)&prod_re[aa])[2],((int16_t*)&prod_re[aa])[3],
- ((int16_t*)&prod_re[aa])[4],((int16_t*)&prod_re[aa])[5],((int16_t*)&prod_re[aa])[6],((int16_t*)&prod_re[aa])[7],
- ((int16_t*)&prod_re[aa])[8],((int16_t*)&prod_re[aa])[9],((int16_t*)&prod_re[aa])[10],((int16_t*)&prod_re[aa])[11],
- ((int16_t*)&prod_re[aa])[12],((int16_t*)&prod_re[aa])[13],((int16_t*)&prod_re[aa])[14],((int16_t*)&prod_re[aa])[15]);
- printf("prod_im[%d] => (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",aa,
- ((int16_t*)&prod_im[aa])[0],((int16_t*)&prod_im[aa])[1],((int16_t*)&prod_im[aa])[2],((int16_t*)&prod_im[aa])[3],
- ((int16_t*)&prod_im[aa])[4],((int16_t*)&prod_im[aa])[5],((int16_t*)&prod_im[aa])[6],((int16_t*)&prod_im[aa])[7],
- ((int16_t*)&prod_im[aa])[8],((int16_t*)&prod_im[aa])[9],((int16_t*)&prod_im[aa])[10],((int16_t*)&prod_im[aa])[11],
- ((int16_t*)&prod_im[aa])[12],((int16_t*)&prod_im[aa])[13],((int16_t*)&prod_im[aa])[14],((int16_t*)&prod_im[aa])[15]);
-
-#endif
- prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1
- prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
- prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3
- prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
- prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7
- prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
- prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15
- prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
- }
- int64_t corr_re=0,corr_im=0;
-
int64_t corr_tmp = 0;
- for (int aa=0;aa (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",aa,
+ ((int16_t*)&prod_re[aa])[0],((int16_t*)&prod_re[aa])[1],((int16_t*)&prod_re[aa])[2],((int16_t*)&prod_re[aa])[3],
+ ((int16_t*)&prod_re[aa])[4],((int16_t*)&prod_re[aa])[5],((int16_t*)&prod_re[aa])[6],((int16_t*)&prod_re[aa])[7],
+ ((int16_t*)&prod_re[aa])[8],((int16_t*)&prod_re[aa])[9],((int16_t*)&prod_re[aa])[10],((int16_t*)&prod_re[aa])[11],
+ ((int16_t*)&prod_re[aa])[12],((int16_t*)&prod_re[aa])[13],((int16_t*)&prod_re[aa])[14],((int16_t*)&prod_re[aa])[15]);
+ printf("prod_im[%d] => (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",aa,
+ ((int16_t*)&prod_im[aa])[0],((int16_t*)&prod_im[aa])[1],((int16_t*)&prod_im[aa])[2],((int16_t*)&prod_im[aa])[3],
+ ((int16_t*)&prod_im[aa])[4],((int16_t*)&prod_im[aa])[5],((int16_t*)&prod_im[aa])[6],((int16_t*)&prod_im[aa])[7],
+ ((int16_t*)&prod_im[aa])[8],((int16_t*)&prod_im[aa])[9],((int16_t*)&prod_im[aa])[10],((int16_t*)&prod_im[aa])[11],
+ ((int16_t*)&prod_im[aa])[12],((int16_t*)&prod_im[aa])[13],((int16_t*)&prod_im[aa])[14],((int16_t*)&prod_im[aa])[15]);
+
+#endif
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ }
+ int64_t corr_re=0,corr_im=0;
+
+
+ for (int aa=0;aa corr) {
corr = corr_tmp;
cw_ML=cw;
}
- }
+ } // cw loop
corr_dB = dB_fixed64((uint64_t)corr);
LOG_D(PHY,"cw_ML %d, metric %d dB\n",cw_ML,corr_dB);
decodedPayload[0]=(uint64_t)cw_ML;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 7006b54c29..36bcb2f379 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -590,6 +590,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
// Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
+ if (r==0)
+ for (int i=0;i<10;i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t*)llrProcBuf)[i]);
+
//Temporary hack
no_iteration_ldpc = dlsch->max_ldpc_iterations;
ret = no_iteration_ldpc;
@@ -663,9 +666,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->harq_ack.harq_id = harq_pid;
harq_process->harq_ack.send_harq_status = 1;
harq_process->errors[harq_process->round]++;
- harq_process->round++; // [hna] uncomment this line when HARQ is implemented
- // printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
+ // printf("Rate: [UE %d] DLSCH: Setting NACK for slot %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round);
if (harq_process->round >= dlsch->Mlimit) {
harq_process->status = SCH_IDLE;
harq_process->round = 0;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index f792e1f4c6..7aa0e357aa 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -159,20 +159,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
switch (type) {
case SI_PDSCH:
- pdsch_vars = ue->pdsch_vars_SI;
+ pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]];
dlsch = &ue->dlsch_SI[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
break;
case RA_PDSCH:
- pdsch_vars = ue->pdsch_vars_ra;
+ pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]];
dlsch = &ue->dlsch_ra[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- // WIP TBR Hotfix
- memcpy((void*)&pdsch_vars[eNB_id]->dl_ch_estimates[0][ue->frame_parms.ofdm_symbol_size*2], (void*)&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_estimates[0][ue->frame_parms.ofdm_symbol_size*2], ue->frame_parms.ofdm_symbol_size*sizeof(int32_t));
-
break;
case PDSCH:
@@ -189,7 +186,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
break;
}
- if (dlsch1_harq){
+ if (dlsch0_harq && dlsch1_harq){
//printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_tti_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status);
@@ -230,19 +227,18 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
return(-1);
}
} else if (dlsch0_harq) {
- if (dlsch0_harq->status == ACTIVE)
+ if (dlsch0_harq->status == ACTIVE) {
codeword_TB0 = dlsch0_harq->codeword;
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
#ifdef DEBUG_HARQ
printf("[DEMOD] I am assuming only TB0 is active\n");
#endif
+ } else {
+ LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx);
+ return (-1);
+ }
} else {
- LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx);
- return (-1);
- }
-
- if (dlsch0_harq == NULL) {
LOG_E(PHY, "Done\n");
return -1;
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
index ce1c0df156..e0b24a033a 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
@@ -786,16 +786,16 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
//----------------------------------------------------------------------------------------------
void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int16_t *dlsch_llr,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint32_t len,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint32_t llr_offset,
- uint8_t beamforming_mode)
+ int32_t **rxdataF_comp,
+ int16_t *dlsch_llr,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ uint8_t symbol,
+ uint32_t len,
+ uint8_t first_symbol_flag,
+ uint16_t nb_rb,
+ uint32_t llr_offset,
+ uint8_t beamforming_mode)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)];
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
index e4cab0b9a6..29841c3186 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
@@ -71,7 +71,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
int16_t prach_tmp[98304*2*4] __attribute__((aligned(32)));
int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu;
- int32_t Xu_re, Xu_im, samp_count;
+ int32_t Xu_re, Xu_im;
int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k;
//int restricted_Type;
@@ -103,22 +103,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
ue->X_u);
- if (mu == 0)
- samp_count = fp->samples_per_subframe;
- else
- samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0;
-
- #ifdef OAI_USRP
- prach_start = (ue->rx_offset + slot*samp_count - ue->hw_timing_advance - ue->N_TA_offset);
- #else //normal case (simulation)
- prach_start = slot*samp_count - ue->N_TA_offset;
- #endif
-
- if (prach_start<0)
- prach_start += (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME);
-
- if (prach_start >= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME))
- prach_start -= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME);
+ prach_start = fp->get_samples_slot_timestamp(slot, fp, 0);
// First compute physical root sequence
/************************************************************************
@@ -796,40 +781,16 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
}
#ifdef NR_PRACH_DEBUG
- LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", Mod_id,
+ LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d\n", Mod_id,
fp->N_RB_UL,
prach_start,
- prach_len,
- ue->rx_offset,
- ue->hw_timing_advance,
- ue->N_TA_offset);
+ prach_len);
#endif
- #if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
- int j, overflow = prach_start + prach_len - NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe;
-
- #ifdef NR_PRACH_DEBUG
- LOG_I( PHY, "PRACH [UE %d] overflow = %d\n", Mod_id, overflow);
- #endif
-
- // prach_start=414.730, overflow=-39470 prach_len=6600 fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME 460.800 prach_start+prach_len 421.330 fp->samples_per_subframe 46080
-
- // from prach_start=414.730 to prach_start+prach_len 421.330
- for (i = prach_start, j = 0; i < min(fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME, prach_start + prach_len); i++, j++) {
- ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j];
- ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
- }
-
- for (i = 0; i < overflow; i++,j++) {
- ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j];
- ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
- }
- #else // simulators
- for (i=0; icommon_vars.txdata[0][prach_start]))[2*i] = prach[2*i];
- ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1];
- }
- #endif
+ for (i=0; icommon_vars.txdata[0][prach_start]))[2*i] = prach[2*i];
+ ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1];
+ }
//printf("----------------------\n");
//for(int ii = prach_start; ii<2*(prach_start + prach_len); ii++){
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
index 65ed57057f..845eace8b6 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -1064,7 +1064,7 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
unsigned char harq_pid,
- uint8_t frame,
+ uint32_t frame,
uint8_t slot,
uint8_t thread_id,
int gNB_id);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index 6ffb6f21a3..d1dd0f785b 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -177,7 +177,7 @@ typedef struct {
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
uint8_t b_tilde[MAX_NUM_NR_CHANNEL_BITS];
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
- uint32_t d_mod[MAX_NUM_NR_RE];
+ uint32_t d_mod[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
/// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4)
uint32_t y[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
/*
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index c02228bc9f..6f5fba7812 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -424,19 +424,15 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
}
}
-#ifdef DEBUG_DLSCH_CODING
- printf("Rate Matching, Code segment %d (coded bits (G) %u, unpunctured/repeated bits per code segment %d, mod_order %d, nb_rb %d)...\n",
- r,
- G,
- Kr*3,
- mod_order,nb_rb);
-#endif
+
+ LOG_D(PHY,"Rate Matching, Code segment %d (coded bits (G) %u, unpunctured/repeated bits per code segment %d, mod_order %d, nb_rb %d, rvidx %d)...\n",
+ r,
+ G,
+ Kr*3,
+ mod_order,nb_rb,
+ harq_process->pusch_pdu.pusch_data.rv_index);
//start_meas(rm_stats);
-#ifdef DEBUG_DLSCH_CODING
- printf("rvidx in encoding = %d\n", harq_process->pusch_pdu.pusch_data.rv_index);
-#endif
-
///////////////////////// d---->| Rate matching bit selection |---->e /////////////////////////
///////////
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index b1c549530d..c85a7691f6 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -93,7 +93,7 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
unsigned char harq_pid,
- uint8_t frame,
+ uint32_t frame,
uint8_t slot,
uint8_t thread_id,
int gNB_id) {
@@ -218,7 +218,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
///////////
pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
n_dmrs = (nb_rb*((dmrs_type == pusch_dmrs_type1) ? 6:4)*number_dmrs_symbols);
- int16_t mod_dmrs[n_dmrs<<1];
+ int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16)));
///////////
////////////////////////////////////////////////////////////////////////
@@ -226,12 +226,12 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/////////////////////////PTRS parameters' initialization/////////////////////////
///////////
- int16_t mod_ptrs[(nb_rb/2)*(NR_SYMBOLS_PER_SLOT-1)*2]; // assume maximum number of PTRS per pusch allocation
+ int16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation
K_ptrs = 0; // just to avoid a warning
if (harq_process_ul_ue->pusch_pdu.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
- K_ptrs = (harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density)?4:2;
+ K_ptrs = harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density;
L_ptrs = 1<pusch_pdu.pusch_ptrs.ptrs_time_density;
beta_ptrs = 1; // temp value until power control is implemented
@@ -322,7 +322,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint16_t m=0, n=0, dmrs_idx=0, ptrs_idx = 0;
for (l=start_symbol; ltiming_advance;
-#else
- timing_advance = 0;
-#endif
-
- tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0) - timing_advance;
-
- if (tx_offset < 0)
- tx_offset += frame_parms->samples_per_frame;
+ tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
// clear the transmit data array for the current subframe
/*for (int aa=0; aaframe_parms.nb_antennas_tx; aa++) {
@@ -458,49 +448,32 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
txdata = UE->common_vars.txdata;
txdataF = UE->common_vars.txdataF;
- if(UE->N_TA_offset > tx_offset) {
- int32_t *tmp_idft_out = (int32_t*)malloc16(frame_parms->get_samples_per_slot(slot, frame_parms) * sizeof(int32_t));
-
- for(ap = 0; ap < Nl; ap++) {
- if (frame_parms->Ncp == 1) { // extended cyclic prefix
- PHY_ofdm_mod(txdataF[ap],
- tmp_idft_out,
- frame_parms->ofdm_symbol_size,
- 12,
- frame_parms->nb_prefix_samples,
- CYCLIC_PREFIX);
- } else { // normal cyclic prefix
- nr_normal_prefix_mod(txdataF[ap],
- tmp_idft_out,
- 14,
- frame_parms);
- }
-
- memcpy((void *) &txdata[ap][frame_parms->samples_per_frame - UE->N_TA_offset + tx_offset],
- (void *) tmp_idft_out,
- (UE->N_TA_offset - tx_offset) * sizeof(int32_t));
-
- memcpy((void *) &txdata[ap][0],
- (void *) &tmp_idft_out[UE->N_TA_offset - tx_offset],
- (frame_parms->get_samples_per_slot(slot, frame_parms) - UE->N_TA_offset + tx_offset) * sizeof(int32_t));
+ int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
+ for(ap = 0; ap < Nl; ap++) {
+ for (int s=0;s (%d.%d)\n",
+ s,s+symb_offset,frame_parms->symbol_rotation[2*(s+symb_offset)],frame_parms->symbol_rotation[1+(2*(s+symb_offset))]);
+ rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s],
+ &frame_parms->symbol_rotation[2*(s+symb_offset)],
+ (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s],
+ frame_parms->ofdm_symbol_size,
+ 15);
}
+ }
- free(tmp_idft_out);
- } else { // UE->N_TA_offset <= tx_offset
- for (ap = 0; ap < Nl; ap++) {
- if (frame_parms->Ncp == 1) { // extended cyclic prefix
- PHY_ofdm_mod(txdataF[ap],
- &txdata[ap][tx_offset-UE->N_TA_offset],
- frame_parms->ofdm_symbol_size,
- 12,
- frame_parms->nb_prefix_samples,
- CYCLIC_PREFIX);
- } else { // normal cyclic prefix
- nr_normal_prefix_mod(txdataF[ap],
- &txdata[ap][tx_offset-UE->N_TA_offset],
- 14,
- frame_parms);
- }
+ for (ap = 0; ap < Nl; ap++) {
+ if (frame_parms->Ncp == 1) { // extended cyclic prefix
+ PHY_ofdm_mod(txdataF[ap],
+ &txdata[ap][tx_offset],
+ frame_parms->ofdm_symbol_size,
+ 12,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
+ } else { // normal cyclic prefix
+ nr_normal_prefix_mod(txdataF[ap],
+ &txdata[ap][tx_offset],
+ 14,
+ frame_parms);
}
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index c977118df3..cf0fc716f9 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -270,7 +270,6 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
if (k>= fp->ofdm_symbol_size) k-=fp->ofdm_symbol_size;
-
for (int i=0; i < LENGTH_PSS_NR; i++) {
synchroF_tmp[2*k] = primary_synchro[2*i];
synchroF_tmp[2*k+1] = primary_synchro[2*i+1];
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
index 5b7a39da31..0b8111fc32 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
@@ -928,7 +928,17 @@ void nr_uci_encoding(uint64_t payload,
if (A<=11) {
// procedure in subclause 6.3.1.2.2 (UCI encoded by channel coding of small block lengths -> subclause 6.3.1.3.2)
// CRC bits are not attached, and coding small block lengths (subclause 5.3.3)
- b[0] = encodeSmallBlock((uint16_t*)&payload,A);
+ uint64_t b0= encodeSmallBlock((uint16_t*)&payload,A);
+ // repetition for rate-matching up to 16 PRB
+ b[0] = b0 | (b0<<32);
+ b[1] = b[0];
+ b[2] = b[0];
+ b[3] = b[0];
+ b[4] = b[0];
+ b[5] = b[0];
+ b[6] = b[0];
+ b[7] = b[0];
+ AssertFatal(nrofPRB<=16,"Number of PRB >16\n");
} else if (A>=12) {
AssertFatal(A<65,"Polar encoding not supported yet for UCI with more than 64 bits\n");
t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_UCI_PUCCH_MESSAGE_TYPE,
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index 44d7b93ae2..78e34036a3 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -525,32 +525,25 @@ static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr)
return;
- NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
- uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
- uint8_t nb_antennas_tx = frame_parms->nb_antennas_tx;
- scopeSample_t **chest_f = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
- int ind = 0;
- float chest_f_abs[frame_parms->ofdm_symbol_size];
- float freq[frame_parms->ofdm_symbol_size];
+ int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
+ int Qm = 2;
+ int coded_bits_per_codeword = num_re*Qm;
+ localBuff(llr,coded_bits_per_codeword*RX_NB_TH_MAX);
+ localBuff(bit,coded_bits_per_codeword*RX_NB_TH_MAX);
+ int base=0;
- for (int atx=0; atxofdm_symbol_size; k++) {
- freq[ind] = (float)ind;
- chest_f_abs[ind] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][6144+k]));
- ind++;
- }
- }
+ for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
+ int16_t *pdcch_llr = (int16_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->llr;
+
+ for (int i=0; ichest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
- //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
- // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
- //fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
- oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10);
+ oai_xygraph(graph,bit,llr,base,0,10);
}
static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h
index 9163fc13b6..e17b752e7b 100644
--- a/openair1/PHY/defs_UE.h
+++ b/openair1/PHY/defs_UE.h
@@ -452,55 +452,6 @@ typedef struct {
uint32_t llr_length[14];
} LTE_UE_PDSCH;
-typedef struct {
- /// \brief Received frequency-domain signal after extraction.
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- int32_t **rxdataF_ext;
- /// \brief Received frequency-domain signal after extraction and channel compensation.
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- double **rxdataF_comp;
- /// \brief Downlink channel estimates extracted in PRBS.
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- int32_t **dl_ch_estimates_ext;
- /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS.
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- double **dl_ch_rho_ext;
- /// \brief Downlink PMIs extracted in PRBS and grouped in subbands.
- /// - first index: ressource block [0..N_RB_DL[
- uint8_t *pmi_ext;
- /// \brief Magnitude of Downlink Channel (16QAM level/First 64QAM level).
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- double **dl_ch_mag;
- /// \brief Magnitude of Downlink Channel (2nd 64QAM level).
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- double **dl_ch_magb;
- /// \brief Cross-correlation of two eNB signals.
- /// - first index: rx antenna [0..nb_antennas_rx[
- /// - second index: ? [0..]
- double **rho;
- /// never used... always send dl_ch_rho_ext instead...
- double **rho_i;
- /// \brief Pointers to llr vectors (2 TBs).
- /// - first index: ? [0..1] (hard coded)
- /// - second index: ? [0..1179743] (hard coded)
- int16_t *llr[2];
- /// \f$\log_2(\max|H_i|^2)\f$
- uint8_t log2_maxh;
- /// \brief Pointers to llr vectors (128-bit alignment).
- /// - first index: ? [0..0] (hard coded)
- /// - second index: ? [0..]
- int16_t **llr128;
- //uint32_t *rb_alloc;
- //uint8_t Qm[2];
- //MIMO_mode_t mimo_mode;
-} LTE_UE_PDSCH_FLP;
-
typedef struct {
/// \brief Pointers to extracted PDCCH symbols in frequency-domain.
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
@@ -667,7 +618,6 @@ typedef struct {
uint8_t current_thread_id[10];
LTE_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads
- LTE_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1];
LTE_UE_PDSCH *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1];
LTE_UE_PDSCH *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1];
LTE_UE_PDSCH *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1];
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 5605a85287..179ca0331f 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -124,6 +124,15 @@ typedef struct {
nfapi_nr_ul_dci_request_pdus_t pdcch_pdu;
} NR_gNB_UL_PDCCH_t;
+typedef struct {
+ uint16_t rnti;
+ int round_trials[8];
+ int total_bytes_tx;
+ int total_bytes_rx;
+ int current_Qm;
+ int current_RI;
+} NR_gNB_SCH_STATS_t;
+
typedef struct {
/// Pointers to 16 HARQ processes for the DLSCH
NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES];
@@ -169,6 +178,8 @@ typedef struct {
int16_t sqrt_rho_b;
} NR_gNB_DLSCH_t;
+
+
typedef struct {
int frame;
int slot;
@@ -345,10 +356,6 @@ typedef struct {
uint8_t max_ldpc_iterations;
/// number of iterations used in last LDPC decoding
uint8_t last_iteration_cnt;
- /// num active cba group
- uint8_t num_active_cba_groups;
- /// num active cba group
- uint16_t cba_rnti[NUM_MAX_CBA_GROUP];
} NR_gNB_ULSCH_t;
typedef struct {
@@ -390,8 +397,6 @@ typedef struct {
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **rxdataF_ext2;
- /// \brief Offset for calculating the index of rxdataF_ext for the current symbol
- uint32_t rxdataF_ext_offset;
/// \brief Hold the channel estimates in time domain based on DRS.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..4*ofdm_symbol_size[
@@ -459,6 +464,13 @@ typedef struct {
uint16_t ptrs_symbols;
// PTRS subcarriers per OFDM symbol
uint16_t ptrs_sc_per_ofdm_symbol;
+ /// \brief Estimated phase error based upon PTRS on each symbol .
+ /// - first index: ? [0..7] Number of Antenna
+ /// - second index: ? [0...14] smybol per slot
+ int32_t **ptrs_phase_per_slot;
+ /// \brief Total RE count after DMRS/PTRS RE's are extracted from respective symbol.
+ /// - first index: ? [0...14] smybol per slot
+ int16_t *ul_valid_re_per_slot;
/// flag to verify if channel level computation is done
uint8_t cl_done;
} NR_gNB_PUSCH;
@@ -704,6 +716,11 @@ typedef struct PHY_VARS_gNB_s {
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX][2]; // [Nusers times][2 codewords]
NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
NR_gNB_DLSCH_t *dlsch_PCH;
+ /// statistics for DLSCH measurement collection
+ NR_gNB_SCH_STATS_t dlsch_stats[NUMBER_OF_NR_SCH_STATS_MAX];
+ /// statistics for ULSCH measurement collection
+ NR_gNB_SCH_STATS_t ulsch_stats[NUMBER_OF_NR_SCH_STATS_MAX];
+
t_nrPolar_params *uci_polarParams;
uint8_t pbch_configured;
@@ -795,9 +812,12 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t ulsch_deinterleaving_stats;
time_stats_t ulsch_unscrambling_stats;
time_stats_t ulsch_channel_estimation_stats;
+ time_stats_t ulsch_ptrs_processing_stats;
time_stats_t ulsch_channel_compensation_stats;
time_stats_t ulsch_rbs_extraction_stats;
+ time_stats_t ulsch_mrc_stats;
time_stats_t ulsch_llr_stats;
+
/*
time_stats_t rx_dft_stats;
time_stats_t ulsch_freq_offset_estimation_stats;
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 9bdf892ceb..62ffeaaea8 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -416,55 +416,6 @@ typedef struct {
uint32_t llr_length[14];
} NR_UE_PDSCH;
-typedef struct {
- /// \brief Received frequency-domain signal after extraction.
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- int32_t **rxdataF_ext;
- /// \brief Received frequency-domain signal after extraction and channel compensation.
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- double **rxdataF_comp;
- /// \brief Downlink channel estimates extracted in PRBS.
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- int32_t **dl_ch_estimates_ext;
- /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS.
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- double **dl_ch_rho_ext;
- /// \brief Downlink PMIs extracted in PRBS and grouped in subbands.
- /// - first index: ressource block [0..N_RB_DL[
- uint8_t *pmi_ext;
- /// \brief Magnitude of Downlink Channel (16QAM level/First 64QAM level).
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- double **dl_ch_mag;
- /// \brief Magnitude of Downlink Channel (2nd 64QAM level).
- /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - second index: ? [0..]
- double **dl_ch_magb;
- /// \brief Cross-correlation of two eNB signals.
- /// - first index: rx antenna [0..nb_antennas_rx[
- /// - second index: ? [0..]
- double **rho;
- /// never used... always send dl_ch_rho_ext instead...
- double **rho_i;
- /// \brief Pointers to llr vectors (2 TBs).
- /// - first index: ? [0..1] (hard coded)
- /// - second index: ? [0..1179743] (hard coded)
- int16_t *llr[2];
- /// \f$\log_2(\max|H_i|^2)\f$
- uint8_t log2_maxh;
- /// \brief Pointers to llr vectors (128-bit alignment).
- /// - first index: ? [0..0] (hard coded)
- /// - second index: ? [0..]
- int16_t **llr128;
- //uint32_t *rb_alloc;
- //uint8_t Qm[2];
- //MIMO_mode_t mimo_mode;
-} NR_UE_PDSCH_FLP;
-
#define NR_PDCCH_DEFS_NR_UE
#define NR_NBR_CORESET_ACT_BWP 3 // The number of CoreSets per BWP is limited to 3 (including initial CORESET: ControlResourceId 0)
#define NR_NBR_SEARCHSPACE_ACT_BWP 10 // The number of SearchSpaces per BWP is limited to 10 (including initial SEARCHSPACE: SearchSpaceId 0)
@@ -902,11 +853,6 @@ typedef struct {
t_nrPolar_params *polarList;
NR_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads
- NR_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1];
- NR_UE_PDSCH *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1];
- NR_UE_PDSCH *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1];
- NR_UE_PDSCH *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1];
- NR_UE_PDSCH *pdsch_vars_MCH[NUMBER_OF_CONNECTED_eNB_MAX];
NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX];
NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX];
NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX];
@@ -1022,7 +968,6 @@ typedef struct {
/// Timing Advance updates variables
/// Timing advance update computed from the TA command signalled from gNB
int timing_advance;
- int hw_timing_advance;
int N_TA_offset; ///timing offset used in TDD
NR_UL_TIME_ALIGNMENT_t ul_time_alignment[NUMBER_OF_CONNECTED_gNB_MAX];
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index 80e6c08117..a21af3fa03 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -322,6 +322,8 @@ struct NR_DL_FRAME_PARMS {
uint8_t nb_antenna_ports_gNB;
/// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP)
lte_prefix_type_t Ncp;
+ /// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211
+ int16_t symbol_rotation[224*2];
/// shift of pilot position in one RB
uint8_t nushift;
/// SRS configuration from TS 38.331 RRC
diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h
index a4607d3106..6c3d97838d 100644
--- a/openair1/PHY/impl_defs_top.h
+++ b/openair1/PHY/impl_defs_top.h
@@ -265,7 +265,7 @@
#define NB_NUMEROLOGIES_NR (5)
#define TDD_CONFIG_NB_FRAMES (2)
#define NR_MAX_SLOTS_PER_FRAME (160) /* number of slots per frame */
-#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (4) /* FFS_NR_TODO it defines ue capability which is the number of slots */
+#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (6) /* FFS_NR_TODO it defines ue capability which is the number of slots */
/* - between reception of pdsch and tarnsmission of its acknowlegment */
/* - between reception of un uplink grant and its related transmission */
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 558fa8d4eb..b3e3ab8c4e 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -20,12 +20,12 @@
*/
/*! \file phy_procedures_lte_eNB.c
- * \brief Implementation of eNB procedures from 36.213 LTE specifications
- * \author R. Knopp, F. Kaltenberger, N. Nikaein, X. Foukas
+ * \brief Implementation of eNB procedures from 36.213 LTE specifications / FeMBMS 36.231 LTE procedures v14.2
+ * \author R. Knopp, F. Kaltenberger, N. Nikaein, X. Foukas, J. Morgade
* \date 2011
* \version 0.1
* \company Eurecom
- * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr, x.foukas@sms.ed.ac.uk
+ * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr, x.foukas@sms.ed.ac.uk, javier.morgade@ieee.org
* \note
* \warning
*/
@@ -122,12 +122,32 @@ lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subfr
}
#ifdef MBMS_NFAPI_SCHEDULER
-void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
+void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, int fembms_flag) {
int subframe = proc->subframe_tx;
// This is DL-Cell spec pilots in Control region
- generate_pilots_slot (eNB, eNB->common_vars.txdataF, AMP, subframe << 1, 1);
- if(eNB->dlsch_MCH->active==1)
- generate_mch (eNB, proc,NULL/*, eNB->dlsch_MCH->harq_processes[0]->pdu*/);
+ if(!fembms_flag){
+ generate_pilots_slot (eNB, eNB->common_vars.txdataF, AMP, subframe << 1, 1);
+ generate_mbsfn_pilot(eNB,proc,
+ eNB->common_vars.txdataF,
+ AMP);
+ }else
+ generate_mbsfn_pilot_khz_1dot25(eNB,proc,
+ eNB->common_vars.txdataF,
+ AMP);
+
+ if(eNB->dlsch_MCH->active==1){
+ if(!fembms_flag){
+ generate_mch (eNB, proc,NULL/*, eNB->dlsch_MCH->harq_processes[0]->pdu*/);
+ }
+ else{
+ generate_mch_khz_1dot25 (eNB, proc,NULL/*, eNB->dlsch_MCH->harq_processes[0]->pdu*/);
+ }
+
+ LOG_D(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (TBS %d) fembms %d \n",
+ eNB->Mod_id,proc->frame_tx,subframe,
+ eNB->dlsch_MCH->harq_processes[0]->TBS>>3,fembms_flag);
+
+ }
eNB->dlsch_MCH->active = 0;
}
#else
@@ -171,6 +191,80 @@ void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
}
#endif
+void common_signal_procedures_fembms (PHY_VARS_eNB *eNB,int frame, int subframe) {
+ LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
+ int **txdataF = eNB->common_vars.txdataF;
+ uint8_t *pbch_pdu=&eNB->pbch_pdu[0];
+
+ if((frame&3)!=0 /*&& subframe != 0*/)
+ return;
+
+ LOG_I(PHY,"common_signal_procedures: frame %d, subframe %d fdd:%s dir:%s index:%d\n",frame,subframe,fp->frame_type == FDD?"FDD":"TDD", subframe_select(fp,subframe) == SF_DL?"DL":"UL?",(frame&15)/4);
+ // generate Cell-Specific Reference Signals for both slots
+ //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1);
+
+
+ if(subframe_select(fp,subframe) == SF_S)
+ generate_pilots_slot(eNB,
+ txdataF,
+ AMP,
+ subframe<<1,1);
+ else
+ generate_pilots_slot(eNB,
+ txdataF,
+ AMP,
+ subframe<<1,0);
+
+ // check that 2nd slot is for DL
+ if (subframe_select (fp, subframe) == SF_DL)
+ generate_pilots_slot (eNB, txdataF, AMP, (subframe << 1) + 1, 0);
+
+ //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX, 0);
+
+ // First half of PSS/SSS (FDD, slot 0)
+ if (subframe == 0) {
+ //if (fp->frame_type == FDD) {
+ generate_pss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 6 : 5, 0);
+ generate_sss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 5 : 4, 0);
+ //}
+
+ /// First half of SSS (TDD, slot 1)
+
+ //if (fp->frame_type == TDD) {
+ generate_sss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 6 : 5, 1);
+ //}
+
+ // generate PBCH (Physical Broadcast CHannel) info
+
+ /// generate PBCH
+ if ((frame&15)==0) {
+ //AssertFatal(eNB->pbch_configured==1,"PBCH was not configured by MAC\n");
+ if (eNB->pbch_configured!=1) return;
+
+ eNB->pbch_configured=0;
+ }
+
+ T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
+ T_BUFFER(pbch_pdu, 3));
+ generate_pbch_fembms (&eNB->pbch, txdataF, AMP, fp, pbch_pdu, (frame & 15)/4);
+ } //else if ((subframe == 1) && (fp->frame_type == TDD)) {
+ //generate_pss (txdataF, AMP, fp, 2, 2);
+ // }
+ // Second half of PSS/SSS (FDD, slot 10)
+ else if ((subframe == 5) && (fp->frame_type == FDD) && is_fembms_nonMBSFN_subframe(frame,subframe,fp)) {
+ generate_pss (txdataF, AMP, &eNB->frame_parms, (fp->Ncp == NORMAL) ? 6 : 5, 10);
+ generate_sss (txdataF, AMP, &eNB->frame_parms, (fp->Ncp == NORMAL) ? 5 : 4, 10);
+ }
+ // Second-half of SSS (TDD, slot 11)
+ // else if ((subframe == 5) && (fp->frame_type == TDD)) {
+ // generate_sss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 6 : 5, 11);
+ // }
+ // Second half of PSS (TDD, slot 12)
+ // else if ((subframe == 6) && (fp->frame_type == TDD)) {
+ // generate_pss (txdataF, AMP, fp, 2, 12);
+ // }
+}
+
void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
int **txdataF = eNB->common_vars.txdataF;
@@ -417,12 +511,30 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
}
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
+ if (is_fembms_pmch_subframe(frame,subframe,fp)) {
+#ifdef MBMS_NFAPI_SCHEDULER
+ pmch_procedures(eNB,proc,1);
+ LOG_D(MAC,"frame %d, subframe %d -> PMCH\n",frame,subframe);
+ return;
+#endif
+ }else if(is_fembms_cas_subframe(frame,subframe,fp) || is_fembms_nonMBSFN_subframe(frame,subframe,fp)){
+ LOG_D(MAC,"frame %d, subframe %d -> CAS\n",frame,subframe);
+ common_signal_procedures_fembms(eNB,proc->frame_tx, proc->subframe_tx);
+ //return;
+ }
+
+ if((!is_fembms_cas_subframe(frame,subframe,fp)) && (!is_fembms_nonMBSFN_subframe(frame,subframe,fp))){
if (is_pmch_subframe(frame,subframe,fp)) {
+#ifdef MBMS_NFAPI_SCHEDULER
+ pmch_procedures(eNB,proc,0);
+#else
pmch_procedures(eNB,proc);
+#endif
} else {
// this is not a pmch subframe, so generate PSS/SSS/PBCH
common_signal_procedures(eNB,proc->frame_tx, proc->subframe_tx);
}
+ }
}
// clear existing ulsch dci allocations before applying info from MAC (this is table
@@ -508,6 +620,18 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
if (do_meas==1) start_meas(&eNB->dlsch_ue_specific);
+ if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
+ if (is_fembms_pmch_subframe(frame,subframe,fp)) {
+#ifdef MBMS_NFAPI_SCHEDULER
+ pmch_procedures(eNB,proc,1);
+ return;
+#endif
+ }else if(is_fembms_cas_subframe(frame,subframe,fp)){
+ common_signal_procedures_fembms(eNB,proc->frame_tx, proc->subframe_tx);
+ }
+ }
+
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
// Now scan UE specific DLSCH
diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c
index cb03821388..e472d64db4 100644
--- a/openair1/SCHED/ru_procedures.c
+++ b/openair1/SCHED/ru_procedures.c
@@ -41,6 +41,17 @@
* \warning
*/
+/*! \function feptx0
+ * \brief Implementation of ofdm encoding for FeMBMS profile in one eNB
+ * \author J. Morgade
+ * \date 2020
+ * \version 0.1
+ * \email: javier.morgade@ieee.org
+ * \note
+ * \warning
+ */
+
+
#include "PHY/defs_eNB.h"
#include "PHY/phy_extern.h"
@@ -76,7 +87,7 @@ void feptx0(RU_t *ru,
int slot_sizeF = (fp->ofdm_symbol_size) * ((fp->Ncp==1) ? 6 : 7);
int subframe = ru->proc.tti_tx;
- //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 1 );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(slot&1) , 1 );
slot_offset = slot*(fp->samples_per_tti>>1); //slot_offset = subframe*fp->samples_per_tti + (slot*(fp->samples_per_tti>>1));
@@ -91,7 +102,17 @@ void feptx0(RU_t *ru,
fp->nb_prefix_samples,
CYCLIC_PREFIX);
} else {
- if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)){
+ if(is_fembms_pmch_subframe(ru->proc.frame_tx,subframe,fp)){
+ if((slot&1)==0){//just use one slot chance
+ PHY_ofdm_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF],
+ (int*)&ru->common.txdata[aa][slot_offset],
+ fp->ofdm_symbol_size_khz_1dot25,
+ 1,
+ fp->ofdm_symbol_size_khz_1dot25>>2,
+ CYCLIC_PREFIX);
+ LOG_D(HW,"Generating PMCH FeMBMS TX subframe %d %d\n",subframe,fp->ofdm_symbol_size_khz_1dot25);
+ }
+ } else if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)){
if ((slot&1) == 0) {//just use one slot chance
normal_prefix_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF],
(int*)&ru->common.txdata[aa][slot_offset],
diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c
index 974441e5db..84490bfad4 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.c
+++ b/openair1/SCHED_NR/fapi_nr_l1.c
@@ -218,7 +218,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
- nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
+ if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
break;
}
}
diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c
index 560f47059a..9723b2f99e 100644
--- a/openair1/SCHED_NR/nr_ru_procedures.c
+++ b/openair1/SCHED_NR/nr_ru_procedures.c
@@ -87,14 +87,29 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
CYCLIC_PREFIX);
else {
if (fp->numerology_index != 0) {
+
+ if (!(slot%(fp->slots_per_subframe/2))&&(first_symbol==0)) { // case where first symbol in slot has longer prefix
+ apply_nr_rotation(fp,
+ (int16_t*)&ru->common.txdataF_BF[aa][slot_offsetF],
+ slot,
+ 0,
+ 1,
+ fp->ofdm_symbol_size);
- if (!(slot%(fp->slots_per_subframe/2))&&(first_symbol==0)) {
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
(int*)&ru->common.txdata[aa][slot_offset],
fp->ofdm_symbol_size,
1,
fp->nb_prefix_samples0,
CYCLIC_PREFIX);
+
+ apply_nr_rotation(fp,
+ (int16_t*)&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size],
+ slot,
+ 1,
+ num_symbols-1,
+ fp->ofdm_symbol_size);
+
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size],
(int*)&ru->common.txdata[aa][slot_offset+fp->nb_prefix_samples0+fp->ofdm_symbol_size],
fp->ofdm_symbol_size,
@@ -102,7 +117,13 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
fp->nb_prefix_samples,
CYCLIC_PREFIX);
}
- else {
+ else { // all symbols in slot have shorter prefix
+ apply_nr_rotation(fp,
+ (int16_t*)&ru->common.txdataF_BF[aa][slot_offsetF],
+ slot,
+ first_symbol,
+ num_symbols,
+ fp->ofdm_symbol_size);
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
(int*)&ru->common.txdata[aa][slot_offset],
fp->ofdm_symbol_size,
@@ -110,9 +131,8 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
fp->nb_prefix_samples,
CYCLIC_PREFIX);
}
- }
-
- else {
+ } // numerology_index!=0
+ else { //numerology_index == 0
for (uint16_t idx_sym=abs_first_symbol; idx_symcommon.txdataF_BF[aa][slot_offsetF],
@@ -121,6 +141,12 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
1,
fp->nb_prefix_samples,
CYCLIC_PREFIX);
+ apply_nr_rotation(fp,
+ (int16_t*)&ru->common.txdata[aa][slot_offset],
+ slot,
+ idx_sym,
+ 1,
+ fp->ofdm_symbol_size+fp->nb_prefix_samples);
slot_offset += fp->nb_prefix_samples+fp->ofdm_symbol_size;
}
else {
@@ -130,6 +156,12 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
1,
fp->nb_prefix_samples0,
CYCLIC_PREFIX);
+ apply_nr_rotation(fp,
+ (int16_t*)&ru->common.txdata[aa][slot_offset],
+ slot,
+ 0,
+ 1,
+ fp->ofdm_symbol_size+fp->nb_prefix_samples0);
slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size;
}
}
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 65e3209d57..618fa8a11e 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -194,20 +194,8 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
for (int i=0; inum_pdsch_rnti[slot]; i++) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", gNB->num_pdsch_rnti[slot],frame,slot);
- nr_generate_pdsch(gNB->dlsch[i][0],
- gNB->nr_gold_pdsch_dmrs[slot],
- gNB->common_vars.txdataF,
- AMP, frame, slot, fp, 0,
- &gNB->dlsch_encoding_stats,
- &gNB->dlsch_scrambling_stats,
- &gNB->dlsch_modulation_stats,
- &gNB->tinput,
- &gNB->tprep,
- &gNB->tparity,
- &gNB->toutput,
- &gNB->dlsch_rate_matching_stats,
- &gNB->dlsch_interleaving_stats,
- &gNB->dlsch_segmentation_stats);
+ nr_generate_pdsch(gNB,frame, slot);
+ if ((frame&127) == 0) dump_pdsch_stats(gNB);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
}
@@ -252,7 +240,21 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
pusch_pdu->qam_mod_order,
pusch_pdu->nrOfLayers);
-
+
+ AssertFatal(G>0,"G is 0 : rb_size %u, number_symbols %d, nb_re_dmrs %d, number_dmrs_symbols %d, qam_mod_order %u, nrOfLayer %u\n",
+ pusch_pdu->rb_size,
+ number_symbols,
+ nb_re_dmrs,
+ number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
+ pusch_pdu->qam_mod_order,
+ pusch_pdu->nrOfLayers);
+ LOG_D(PHY,"rb_size %d, number_symbols %d, nb_re_dmrs %d, number_dmrs_symbols %d, qam_mod_order %d, nrOfLayer %d\n",
+ pusch_pdu->rb_size,
+ number_symbols,
+ nb_re_dmrs,
+ number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
+ pusch_pdu->qam_mod_order,
+ pusch_pdu->nrOfLayers);
//----------------------------------------------------------
//------------------- ULSCH unscrambling -------------------
//----------------------------------------------------------
@@ -279,13 +281,12 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
G);
stop_meas(&gNB->ulsch_decoding_stats);
-
if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations){
- LOG_I(PHY, "ULSCH %d in error\n",ULSCH_id);
+ LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id);
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
}
else if(gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->b!=NULL){
- LOG_I(PHY, "ULSCH received ok \n");
+ LOG_D(PHY, "ULSCH received ok \n");
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 0);
}
}
@@ -324,12 +325,12 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
if (timing_advance_update < 0) timing_advance_update = 0;
if (timing_advance_update > 63) timing_advance_update = 63;
- LOG_I(PHY, "Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", sync_pos,timing_advance_update);
+ LOG_D(PHY, "Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", sync_pos,timing_advance_update);
// estimate UL_CQI for MAC (from antenna port 0 only)
int SNRtimes10 = dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0]) - (10*gNB->measurements.n0_power_dB[0]);
- LOG_I(PHY, "Estimated SNR for PUSCH is = %d dB\n", SNRtimes10/10);
+ LOG_D(PHY, "Estimated SNR for PUSCH is = %d dB\n", SNRtimes10/10);
if (SNRtimes10 < -640) cqi=0;
else if (SNRtimes10 > 635) cqi=255;
@@ -348,7 +349,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
gNB->crc_pdu_list[num_crc].num_cb = pusch_pdu->pusch_data.num_cb;
gNB->crc_pdu_list[num_crc].ul_cqi = cqi;
gNB->crc_pdu_list[num_crc].timing_advance = timing_advance_update;
- gNB->crc_pdu_list[num_crc].rssi = 0xffff; // invalid value as this is not yet computed
+ // in terms of dBFS range -128 to 0 with 0.1 step
+ gNB->crc_pdu_list[num_crc].rssi = 1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0]));
gNB->UL_INFO.crc_ind.number_crcs++;
@@ -362,7 +364,7 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
gNB->rx_pdu_list[num_rx].harq_id = harq_pid;
gNB->rx_pdu_list[num_rx].ul_cqi = cqi;
gNB->rx_pdu_list[num_rx].timing_advance = timing_advance_update;
- gNB->rx_pdu_list[num_rx].rssi = 0xffff; // invalid value as this is not yet computed
+ gNB->rx_pdu_list[num_rx].rssi = 1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0]));
if (crc_flag)
gNB->rx_pdu_list[num_rx].pdu_length = 0;
else {
@@ -522,7 +524,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
(ulsch_harq->slot == slot_rx) &&
(ulsch_harq->handled == 0)){
- LOG_I(PHY, "PUSCH generation started in frame %d slot %d\n",
+ LOG_D(PHY, "PUSCH detection started in frame %d slot %d\n",
frame_rx,slot_rx);
#ifdef DEBUG_RXDATA
@@ -573,5 +575,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
}
}
}
+ // figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS
+ if ((frame_rx&127) == 0 && slot_rx==19) dump_pusch_stats(gNB);
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
}
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index ea73f2fecc..55c7cd0baf 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -117,6 +117,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type);
dlsch0_harq->harq_ack.vDAI_DL = dlsch_config_pdu->dai;
LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs);
+
}
}
}
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 85e66abe6e..e00b166a8e 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -1101,169 +1101,6 @@ uint16_t nr_get_n1_pucch(PHY_VARS_NR_UE *ue,
return(-1);
}
-
-
-void ulsch_common_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t empty_subframe) {
-
- int aa;
- NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
-
- int nsymb;
- int nr_tti_tx = proc->nr_tti_tx;
- int frame_tx = proc->frame_tx;
- int ulsch_start;
- int overflow=0;
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
- int k,l;
- int dummy_tx_buffer[frame_parms->samples_per_subframe] __attribute__((aligned(16)));
-#endif
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN);
-#if UE_TIMING_TRACE
- start_meas(&ue->ofdm_mod_stats);
-#endif
- nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
-
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)//this is the EXPRESS MIMO case
- ulsch_start = (ue->rx_offset+nr_tti_tx*frame_parms->samples_per_subframe-
- ue->hw_timing_advance-
- ue->timing_advance-
- ue->N_TA_offset+5);
- //LOG_E(PHY,"ul-signal [nr_tti_rx: %d, ulsch_start %d]\n",nr_tti_tx, ulsch_start);
-
- if(ulsch_start < 0)
- ulsch_start = ulsch_start + (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe);
-
- if (ulsch_start > (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe))
- ulsch_start = ulsch_start % (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe);
-
- //LOG_E(PHY,"ul-signal [nr_tti_rx: %d, ulsch_start %d]\n",nr_tti_tx, ulsch_start);
-#else //this is the normal case
- ulsch_start = (frame_parms->samples_per_subframe*nr_tti_tx)-ue->N_TA_offset; //-ue->timing_advance;
-#endif //else EXMIMO
-
- //#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
- if (empty_subframe)
- {
- //#if 1
- overflow = ulsch_start - 9*frame_parms->samples_per_subframe;
- for (aa=0; aanb_antennas_tx; aa++) {
-
- if (overflow > 0)
- {
- memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_subframe-overflow));
- memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
- }
- else
- {
- memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_subframe);
- }
- }
- /*#else
- overflow = ulsch_start - 9*frame_parms->samples_per_subframe;
- for (aa=0; aanb_antennas_tx; aa++) {
- for (k=ulsch_start; ksamples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_subframe); k++) {
- ((short*)ue->common_vars.txdata[aa])[2*k] = 0;
- ((short*)ue->common_vars.txdata[aa])[2*k+1] = 0;
- }
-
- for (k=0; kcommon_vars.txdata[aa])[2*k] = 0;
- ((short*)ue->common_vars.txdata[aa])[2*k+1] = 0;
- }
- }
- endif*/
- return;
- }
-
-
- if ((frame_tx%100) == 0)
- LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n",
- ue->Mod_id,frame_tx,nr_tti_tx,
- ulsch_start,
- ue->rx_offset,
- ue->hw_timing_advance,
- ue->timing_advance,
- ue->N_TA_offset);
-
-
- for (aa=0; aanb_antennas_tx; aa++) {
- if (frame_parms->Ncp == 1)
- PHY_ofdm_mod(&ue->common_vars.txdataF[aa][nr_tti_tx*nsymb*frame_parms->ofdm_symbol_size],
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
- dummy_tx_buffer,
-#else
- &ue->common_vars.txdata[aa][ulsch_start],
-#endif
- frame_parms->ofdm_symbol_size,
- nsymb,
- frame_parms->nb_prefix_samples,
- CYCLIC_PREFIX);
- else
- normal_prefix_mod(&ue->common_vars.txdataF[aa][nr_tti_tx*nsymb*frame_parms->ofdm_symbol_size],
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
- dummy_tx_buffer,
-#else
- &ue->common_vars.txdata[aa][ulsch_start],
-#endif
- nsymb,
- &ue->frame_parms);
-
-
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
- apply_7_5_kHz(ue,dummy_tx_buffer,0);
- apply_7_5_kHz(ue,dummy_tx_buffer,1);
-#else
- apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],0);
- apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],1);
-#endif
-
-
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
- overflow = ulsch_start - 9*frame_parms->samples_per_subframe;
-
-
- for (k=ulsch_start,l=0; ksamples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_subframe); k++,l++) {
- ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
- ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
- }
-
- for (k=0; kcommon_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
- ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
- }
-#if defined(EXMIMO)
- // handle switch before 1st TX nr_tti_rx, guarantee that the slot prior to transmission is switch on
- for (k=ulsch_start - (frame_parms->samples_per_subframe>>1) ; kcommon_vars.txdata[aa][k+frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
- else if (k>(frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
- ue->common_vars.txdata[aa][k-frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
- else
- ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE;
- }
-#endif
-#endif
- /*
- only for debug
- LOG_I(PHY,"ul-signal [nr_tti_rx: %d, ulsch_start %d, TA: %d, rxOffset: %d, timing_advance: %d, hw_timing_advance: %d]\n",nr_tti_tx, ulsch_start, ue->N_TA_offset, ue->rx_offset, ue->timing_advance, ue->hw_timing_advance);
- if( (crash == 1) && (nr_tti_tx == 0) )
- {
- LOG_E(PHY,"***** DUMP TX Signal [ulsch_start %d] *****\n",ulsch_start);
- write_output("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_subframe,1,1);
- }
- */
-
- } //nb_antennas_tx
-
-#if UE_TIMING_TRACE
- stop_meas(&ue->ofdm_mod_stats);
-#endif
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT);
-
-}
-
#endif
UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){
@@ -1426,7 +1263,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue,
}
if (isBad) {
- LOG_I(PHY,"Skip PUSCH generation!\n");
+ LOG_D(PHY,"Skip PUSCH generation!\n");
ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
}
}
@@ -2231,7 +2068,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
memset(ue->common_vars.txdataF[0], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size);
- LOG_I(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
+ LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
#if UE_TIMING_TRACE
start_meas(&ue->phy_proc_tx);
@@ -2252,14 +2089,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
*/
if (get_softmodem_params()->usim_test==0) {
- LOG_I(PHY, "Generating PUCCH\n");
+ LOG_D(PHY, "Generating PUCCH\n");
pucch_procedures_ue_nr(ue,
gNB_id,
proc,
FALSE);
}
- LOG_I(PHY, "Sending Uplink data \n");
+ LOG_D(PHY, "Sending Uplink data \n");
nr_ue_pusch_common_procedures(ue,
slot_tx,
&ue->frame_parms,1);
@@ -2273,7 +2110,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
nr_ue_prach_procedures(ue, proc, gNB_id, mode);
}
}
- LOG_I(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
+ LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
#if UE_TIMING_TRACE
@@ -3036,7 +2873,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t
memcpy(harq_ack_dest, current_harq_ack, sizeof(nr_harq_status_t));
}*/
-void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) {
+int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) {
int nr_tti_rx = proc->nr_tti_rx;
int m;
@@ -3044,9 +2881,9 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
int first_symbol_flag=0;
if (!dlsch0)
- return;
+ return 0;
if (dlsch0->active == 0)
- return;
+ return 0;
if (!dlsch1) {
int harq_pid = dlsch0->current_harq_pid;
@@ -3057,7 +2894,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol;
uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols;
- LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
+ LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
// do channel estimation for first DMRS only
for (m = s0; m < 3; m++) {
@@ -3091,8 +2928,8 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
#endif
// process DLSCH received in first slot
// skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed
- if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) == 0)
- nr_rx_pdsch(ue,
+ if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) == 0) {
+ if (nr_rx_pdsch(ue,
pdsch,
eNB_id,
eNB_id_i,
@@ -3102,20 +2939,25 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
first_symbol_flag,
dual_stream_UE,
i_mod,
- dlsch0->current_harq_pid);
+ dlsch0->current_harq_pid) < 0)
+ return -1;
+ }
else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS)
- if (pdsch == RA_PDSCH) ue->pdsch_vars_ra[eNB_id]->llr_offset[m]=ue->pdsch_vars_ra[eNB_id]->llr_offset[m-1];
- else if (pdsch == PDSCH) nr_rx_pdsch(ue,
- pdsch,
- eNB_id,
- eNB_id_i,
- proc->frame_rx,
- nr_tti_rx, // nr_tti_rx,
- m,
- first_symbol_flag,
- dual_stream_UE,
- i_mod,
- dlsch0->current_harq_pid);
+ if (pdsch == RA_PDSCH) ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]=ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m-1];
+ else if (pdsch == PDSCH) {
+ if (nr_rx_pdsch(ue,
+ pdsch,
+ eNB_id,
+ eNB_id_i,
+ proc->frame_rx,
+ nr_tti_rx, // nr_tti_rx,
+ m,
+ first_symbol_flag,
+ dual_stream_UE,
+ i_mod,
+ dlsch0->current_harq_pid) < 0)
+ return -1;
+ }
else AssertFatal(1==0,"not RA_PDSCH or PDSCH\n");
}
if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]);
@@ -3134,6 +2976,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
}
} // CRNTI active
}
+ return 0;
}
// WIP fix:
@@ -3351,14 +3194,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
if (1) {
switch (pdsch) {
case SI_PDSCH:
- pdsch_vars = ue->pdsch_vars_SI[eNB_id];
- break;
case RA_PDSCH:
- pdsch_vars = ue->pdsch_vars_ra[eNB_id];
- break;
case P_PDSCH:
- pdsch_vars = ue->pdsch_vars_p[eNB_id];
- break;
case PDSCH:
pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id];
break;
@@ -3739,7 +3576,7 @@ void *UE_thread_slot1_dl_processing(void *arg) {
int frame_rx;
uint8_t nr_tti_rx;
- uint8_t pilot0;
+ uint8_t pilot0;
uint8_t pilot1;
uint8_t slot1;
@@ -4119,6 +3956,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
int coreset_nb_rb=0;
int coreset_start_rb=0;
+
if (pdcch_vars->nb_search_space > 0)
get_coreset_rballoc(pdcch_vars->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
@@ -4129,7 +3967,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if ((ue->decode_MIB == 1) && slot_pbch)
{
LOG_I(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
-
for (int i=1; i<4; i++) {
nr_slot_fep(ue,
@@ -4210,27 +4047,29 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
} else if (ue->dlsch_ra[0]->active == 1){
dlsch = ue->dlsch_ra[0];
}
- AssertFatal(dlsch != NULL, "Unsupported mode\n");
- uint8_t harq_pid = dlsch->current_harq_pid;
- NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid];
- uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
- uint16_t start_symb_sch = dlsch0_harq->start_symbol;
- int symb_dmrs = -1;
- LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
- //to update from pdsch config
+ if (dlsch) {
+ uint8_t harq_pid = dlsch->current_harq_pid;
+ NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid];
+ uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
+ uint16_t start_symb_sch = dlsch0_harq->start_symbol;
+ int symb_dmrs = -1;
- for (int i=0;i<4;i++) if (((1<dlDmrsSymbPos) > 0) {symb_dmrs=i;break;}
- AssertFatal(symb_dmrs>=0,"no dmrs in 0..3\n");
- LOG_D(PHY,"Initializing dmrs for symb %d DMRS mask %x\n",symb_dmrs,dlsch0_harq->dlDmrsSymbPos);
- nr_gold_pdsch(ue,symb_dmrs,0, 1);
+ LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
+ //to update from pdsch config
+
+ for (int i=0;i<4;i++) if (((1<dlDmrsSymbPos) > 0) {symb_dmrs=i;break;}
+ AssertFatal(symb_dmrs>=0,"no dmrs in 0..3\n");
+ LOG_D(PHY,"Initializing dmrs for symb %d DMRS mask %x\n",symb_dmrs,dlsch0_harq->dlDmrsSymbPos);
+ nr_gold_pdsch(ue,symb_dmrs,0, 1);
- for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
- nr_slot_fep(ue,
+ for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
+ nr_slot_fep(ue,
m, //to be updated from higher layer
nr_tti_rx,
0,
0);
+ }
}
} else {
LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_tti_rx);
@@ -4242,9 +4081,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
start_meas(&ue->generic_stat);
#endif
// do procedures for C-RNTI
+ int ret_pdsch = 0;
if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
- nr_ue_pdsch_procedures(ue,
+ ret_pdsch = nr_ue_pdsch_procedures(ue,
proc,
eNB_id,
PDSCH,
@@ -4339,7 +4179,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
#endif
- nr_ue_dlsch_procedures(ue,
+ if (ret_pdsch >= 0)
+ nr_ue_dlsch_procedures(ue,
proc,
eNB_id,
PDSCH,
diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c
index e0ea4ef2b2..3215718f8e 100644
--- a/openair1/SCHED_UE/phy_procedures_lte_ue.c
+++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c
@@ -2383,10 +2383,12 @@ void ue_pbch_procedures(uint8_t eNB_id,
if (pbch_phase>=4)
pbch_phase=0;
+if((ue->frame_parms.FeMBMS_active == 0)|| is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms) || first_run) {
+
for (pbch_trials=0; pbch_trials<4; pbch_trials++) {
//for (pbch_phase=0;pbch_phase<4;pbch_phase++) {
//LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id);
- if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms)) {
+ if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms) || ue->frame_parms.FeMBMS_active) {
pbch_tx_ant = rx_pbch_fembms(&ue->common_vars,
ue->pbch_vars[eNB_id],
&ue->frame_parms,
@@ -2431,9 +2433,10 @@ void ue_pbch_procedures(uint8_t eNB_id,
ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0;
- if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms)) {
+ if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms) || ue->frame_parms.FeMBMS_active) {
frame_tx = (int)((ue->pbch_vars[eNB_id]->decoded_output[2]&31)<<1);
frame_tx += ue->pbch_vars[eNB_id]->decoded_output[1]>>7;
+ frame_tx = frame_tx<<4;
frame_tx +=4*pbch_phase;
} else {
frame_tx = (((int)(ue->pbch_vars[eNB_id]->decoded_output[2]&0x03))<<8);
@@ -2490,7 +2493,7 @@ void ue_pbch_procedures(uint8_t eNB_id,
}
if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) {
- LOG_UI(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): nb_antenna_ports_eNB %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
+ LOG_D(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): nb_antenna_ports_eNB %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
ue->Mod_id,
frame_rx,
subframe_rx,
@@ -2501,6 +2504,17 @@ void ue_pbch_procedures(uint8_t eNB_id,
ue->frame_parms.phich_config_common.phich_duration,
ue->frame_parms.phich_config_common.phich_resource);
}
+ LOG_D(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): nb_antenna_ports_eNB %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
+ ue->Mod_id,
+ frame_rx,
+ subframe_rx,
+ ue->frame_parms.nb_antenna_ports_eNB,
+ pbch_tx_ant,
+ frame_tx,
+ ue->frame_parms.N_RB_DL,
+ ue->frame_parms.phich_config_common.phich_duration,
+ ue->frame_parms.phich_config_common.phich_resource);
+
} else {
if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) {
LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n",
@@ -2533,6 +2547,8 @@ void ue_pbch_procedures(uint8_t eNB_id,
ue->pbch_vars[eNB_id]->pdu_errors_conseq);
}
+} //if((ue->frame_parms.FeMBMS_active == 0)|| is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms) || first_run)
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
}
@@ -2877,10 +2893,19 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
int l;
int ret=0;
- if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) {
+ if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) || fembms_flag) {
// LOG_D(PHY,"ue calling pmch subframe ..\n ");
LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n",
ue->Mod_id,frame_rx,subframe_rx);
+ if(fembms_flag)
+ pmch_mcs = ue_query_mch_fembms(ue->Mod_id,
+ CC_id,
+ frame_rx,
+ subframe_rx,
+ eNB_id,
+ &sync_area,
+ &mcch_active);
+ else
pmch_mcs = ue_query_mch(ue->Mod_id,
CC_id,
frame_rx,
@@ -2960,6 +2985,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
LOG_D(PHY,"start turbo decode for MCH %d.%d --> Nl %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Nl);
LOG_D(PHY,"start turbo decode for MCH %d.%d --> G %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->G);
LOG_D(PHY,"start turbo decode for MCH %d.%d --> Kmimo %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->Kmimo);
+
ret = dlsch_decoding(ue,
ue->pdsch_vars_MCH[ue->current_thread_id[subframe_rx]][0]->llr[0],
&ue->frame_parms,
@@ -3007,14 +3033,14 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
// if (subframe_rx==9)
// mac_xface->macphy_exit("Why are we exiting here?");
} else { // decoding successful
- LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH OK (%d,%d), passing to L2 (TBS %d, iter %d,G %d)\n",
+ LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH OK (%d,%d), passing to L2 (TBS %d, iter %d,G %d) ret %d\n",
ue->Mod_id,
frame_rx,subframe_rx,
ue->dlsch_mcch_errors[sync_area][0],
ue->dlsch_mtch_errors[sync_area][0],
ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
ue->dlsch_MCH[0]->max_turbo_iterations,
- ue->dlsch_MCH[0]->harq_processes[0]->G);
+ ue->dlsch_MCH[0]->harq_processes[0]->G,ret);
ue_send_mch_sdu(ue->Mod_id,
CC_id,
frame_rx,
@@ -3022,6 +3048,8 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
eNB_id,// not relevant in eMBMS context
sync_area);
+ //dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
+ //exit_fun("nothing to add");
if (mcch_active == 1)
ue->dlsch_mcch_received[sync_area][0]++;
@@ -4429,6 +4457,15 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,
ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag,1);
return 0;
} else { // this gets closed at end
+ if (is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms) || is_fembms_nonMBSFN_subframe(frame_rx,subframe_rx,&ue->frame_parms) ) {
+ l=0;
+ slot_fep(ue,
+ l,
+ subframe_rx<<1,
+ 0,
+ 0,
+ 0);
+ }
pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;
if (do_pdcch_flag) {
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index f65e1f9633..94214ab3b3 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -78,6 +78,8 @@ double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */
int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
+double DS_TDL = .03;
+
int emulate_rf = 0;
int split73=0;
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
@@ -161,7 +163,7 @@ void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR,
// Multipath channel
if (awgn_flag == 0) {
multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im,
- 2*UE->frame_parms.samples_per_tti,hold_channel);
+ 2*UE->frame_parms.samples_per_tti,hold_channel,0);
// printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset);
if(abstx==1 && num_rounds>1)
@@ -1172,6 +1174,7 @@ int main(int argc, char **argv) {
channel_model,
N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
+ DS_TDL,
forgetting_factor,
rx_sample_offset,
0);
@@ -1185,6 +1188,7 @@ int main(int argc, char **argv) {
channel_model,
N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
+ DS_TDL,
forgetting_factor,
rx_sample_offset,
0);
diff --git a/openair1/SIMULATION/LTE_PHY/dummy_functions.c b/openair1/SIMULATION/LTE_PHY/dummy_functions.c
index 5ec0f6e696..120e4845d9 100644
--- a/openair1/SIMULATION/LTE_PHY/dummy_functions.c
+++ b/openair1/SIMULATION/LTE_PHY/dummy_functions.c
@@ -67,6 +67,11 @@ int ue_query_mch(module_id_t Mod_id, uint8_t CC_id, uint32_t frame,
sub_frame_t subframe, uint8_t eNB_index,
uint8_t * sync_area, uint8_t * mcch_active){ return(0);}
+
+int ue_query_mch_fembms(module_id_t Mod_id, uint8_t CC_id, uint32_t frame,
+ sub_frame_t subframe, uint8_t eNB_index,
+ uint8_t * sync_area, uint8_t * mcch_active){ return(0);}
+
void dl_phy_sync_success(module_id_t module_idP,
frame_t frameP,
unsigned char eNB_index, uint8_t first_sync){}
diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c
index 65415e7c68..5073be24f5 100644
--- a/openair1/SIMULATION/LTE_PHY/mbmssim.c
+++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c
@@ -19,204 +19,1048 @@
* contact@openairinterface.org
*/
+/*! \file mbmssim.c
+ \brief Top-level MBMS DL simulator
+ \authors R. Knopp, J. Morgade
+ \date 2011 - 2014 (Knopp) / 2020 (Morgade)
+ \version 0.1
+ \company Eurecom
+ \email: knopp@eurecom.fr, javier.morgade@ieee.org
+ \note
+ \warning
+*/
+
#include
#include
#include
-#include
-#include
-#include
+#include
+#include
-#include "SIMULATION/TOOLS/defs.h"
-#include "SIMULATION/RF/defs.h"
+#include "SIMULATION/TOOLS/sim.h"
#include "PHY/types.h"
-#include "PHY/defs.h"
-#include "PHY/vars.h"
-#include "SCHED/defs.h"
-#include "SCHED/vars.h"
-#include "LAYER2/MAC/vars.h"
-
-#ifdef XFORMS
- #include "PHY/TOOLS/lte_phy_scope.h"
-#endif //XFORMS
+#include "PHY/defs_eNB.h"
+#include "PHY/defs_UE.h"
+#include "PHY/phy_vars.h"
+#include "SCHED/sched_eNB.h"
+#include "SCHED/sched_common_vars.h"
+#include "LAYER2/MAC/mac_vars.h"
#include "OCG_vars.h"
+#include "common/utils/LOG/log.h"
+#include "UTIL/LISTS/list.h"
+
#include "unitary_defs.h"
-PHY_VARS_eNB *eNB;
-PHY_VARS_UE *UE;
+#include "PHY/TOOLS/lte_phy_scope.h"
+
+#include "dummy_functions.c"
+
+#include "PHY/MODULATION/modulation_common.h"
+#include "PHY/MODULATION/modulation_eNB.h"
+#include "PHY/MODULATION/modulation_UE.h"
+#include "PHY/LTE_TRANSPORT/transport_proto.h"
+#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
+#include "SCHED/sched_eNB.h"
+#include "SCHED_UE/sched_UE.h"
+#include "common/config/config_load_configmodule.h"
+#include "PHY/INIT/phy_init.h"
+#include "nfapi/oai_integration/vendor_ext.h"
+
+#define ENABLE_MBMS_SIM
+
+int enable_fembms=1;
+
+void feptx_ofdm(RU_t *ru);
+void feptx_prec(RU_t *ru);
double cpuf;
+#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
+//#define MCS_COUNT 23//added for PHY abstraction
+#include
+
+int otg_enabled=0;
+/*the following parameters are used to control the processing times calculations*/
+double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */
+double t_rx_max = -1000000000; /*!< \brief initial max process time for rx */
+double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */
+double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */
+int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
+int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
+
+THREAD_STRUCT thread_struct;
+
+int emulate_rf = 0;
+
+void handler(int sig) {
+ void *array[10];
+ size_t size;
+ // get void*'s for all entries on the stack
+ size = backtrace(array, 10);
+ // print out all the frames to stderr
+ fprintf(stderr, "Error: signal %d:\n", sig);
+ backtrace_symbols_fd(array, size, 2);
+ exit(1);
+}
+
+
+
+//DCI2_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_2A[2];
DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_1E[2];
+uint64_t DLSCH_alloc_pdu_1[2];
+
#define UL_RB_ALLOC 0x1ff;
#define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2)
+//#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13
+//#define DLSCH_RB_ALLOC 0x0001
+void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms) {
+ int aa, slot_offset, slot_offset_F;
+ slot_offset_F = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7);
+ slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
+
+ for (aa=0; aanb_antennas_tx; aa++) {
+ // printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
+ if (frame_parms->Ncp == 1)
+ PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input
+ &txdata[aa][slot_offset], // output
+ frame_parms->ofdm_symbol_size,
+ 6, // number of symbols
+ frame_parms->nb_prefix_samples, // number of prefix samples
+ CYCLIC_PREFIX);
+ else {
+ normal_prefix_mod(&txdataF[aa][slot_offset_F],
+ &txdata[aa][slot_offset],
+ 7,
+ frame_parms);
+ }
+ }
+}
+
+void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4],
+ double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) {
+ int i,u;
+ int aa,aarx,aatx;
+ double channelx,channely;
+ double sigma2_dB,sigma2;
+ double iqim=0.0;
+
+ // printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,eNB->frame_parms.nb_antennas_tx,awgn_flag);
+ for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) {
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
+ if (awgn_flag == 0) {
+ s_re[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]);
+ s_im[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+ } else {
+ for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
+ if (aa==0) {
+ r_re[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
+ r_im[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+ } else {
+ r_re[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
+ r_im[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+ }
+ }
+ }
+ }
+ }
+
+ // Multipath channel
+ if (awgn_flag == 0) {
+ multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im,
+ 2*UE->frame_parms.samples_per_tti,hold_channel);
+
+ // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset);
+ if(abstx==1 && num_rounds>1)
+ if(round==0 && hold_channel==0) {
+ random_channel(eNB2UE[1],0);
+ random_channel(eNB2UE[2],0);
+ random_channel(eNB2UE[3],0);
+ }
+
+ if (UE->perfect_ce==1) {
+ // fill in perfect channel estimates
+ freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1);
+ /*
+ LOG_M("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8);
+ LOG_M("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL + 1,1,8);
+ */
+ }
+ }
+
+ if(abstx) {
+ if (trials==0 && round==0) {
+ // calculate freq domain representation to compute SINR
+ freq_channel(eNB2UE[0], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1);
+ // snr=pow(10.0,.1*SNR);
+ fprintf(csv_fd,"%f,",SNR);
+
+ for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) {
+ for (aarx=0; aarxnb_rx; aarx++) {
+ for (aatx=0; aatxnb_tx; aatx++) {
+ channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x;
+ channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y;
+ fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+ }
+ }
+ }
+
+ if(num_rounds>1) {
+ freq_channel(eNB2UE[1], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1);
+
+ for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) {
+ for (aarx=0; aarxnb_rx; aarx++) {
+ for (aatx=0; aatxnb_tx; aatx++) {
+ channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x;
+ channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y;
+ fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+ }
+ }
+ }
+
+ freq_channel(eNB2UE[2], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1);
+
+ for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) {
+ for (aarx=0; aarxnb_rx; aarx++) {
+ for (aatx=0; aatxnb_tx; aatx++) {
+ channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x;
+ channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y;
+ fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+ }
+ }
+ }
+
+ freq_channel(eNB2UE[3], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1);
+
+ for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) {
+ for (aarx=0; aarxnb_rx; aarx++) {
+ for (aatx=0; aatxnb_tx; aatx++) {
+ channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x;
+ channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y;
+ fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //AWGN
+ // tx_lev is the average energy over the whole subframe
+ // but SNR should be better defined wrt the energy in the reference symbols
+ sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)ru->frame_parms.ofdm_symbol_size/(double)(ru->frame_parms.N_RB_DL*12)) - SNR;
+ sigma2 = pow(10,sigma2_dB/10);
+
+ for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) {
+ for (aa=0; aaframe_parms.nb_antennas_rx; aa++) {
+ //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
+ ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] =
+ (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+ ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] =
+ (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+ }
+ }
+}
+
+uint16_t
+fill_tx_req(nfapi_tx_request_body_t *tx_req_body,
+ uint16_t absSF,
+ uint16_t pdu_length,
+ uint16_t pdu_index,
+ uint8_t *pdu) {
+ nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus];
+ LOG_D(MAC, "Filling TX_req %d for pdu length %d\n",
+ tx_req_body->number_of_pdus, pdu_length);
+ TX_req->pdu_length = pdu_length;
+ TX_req->pdu_index = pdu_index;
+ TX_req->num_segments = 1;
+ TX_req->segments[0].segment_length = pdu_length;
+ TX_req->segments[0].segment_data = pdu;
+ tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
+ tx_req_body->number_of_pdus++;
+ return (((absSF / 10) << 4) + (absSF % 10));
+}
+
+void
+fill_mch_config(nfapi_dl_config_request_body_t *dl_req,
+ uint16_t length,
+ uint16_t pdu_index,
+ uint16_t rnti,
+ uint8_t resource_allocation_type,
+ uint16_t resource_block_coding,
+ uint8_t modulation,
+ uint16_t transmission_power,
+ uint8_t mbsfn_area_id){
+ nfapi_dl_config_request_pdu_t *dl_config_pdu =
+ &dl_req->dl_config_pdu_list[dl_req->number_pdu];
+ memset((void *) dl_config_pdu, 0,
+ sizeof(nfapi_dl_config_request_pdu_t));
+ dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MCH_PDU_TYPE;
+ dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mch_pdu));
+ dl_config_pdu->mch_pdu.mch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG;
+ dl_config_pdu->mch_pdu.mch_pdu_rel8.length = length;
+ dl_config_pdu->mch_pdu.mch_pdu_rel8.pdu_index = pdu_index;
+ dl_config_pdu->mch_pdu.mch_pdu_rel8.rnti = rnti;
+ dl_config_pdu->mch_pdu.mch_pdu_rel8.resource_allocation_type = resource_allocation_type;
+ dl_config_pdu->mch_pdu.mch_pdu_rel8.resource_block_coding = resource_block_coding;
+ dl_config_pdu->mch_pdu.mch_pdu_rel8.modulation = modulation;
+ dl_config_pdu->mch_pdu.mch_pdu_rel8.transmission_power = transmission_power;
+ dl_config_pdu->mch_pdu.mch_pdu_rel8.mbsfn_area_id = mbsfn_area_id;
+ dl_req->number_pdu++;
+}
+
+void
+fill_dlsch_config(nfapi_dl_config_request_body_t *dl_req,
+ uint16_t length,
+ uint16_t pdu_index,
+ uint16_t rnti,
+ uint8_t resource_allocation_type,
+ uint8_t virtual_resource_block_assignment_flag,
+ uint16_t resource_block_coding,
+ uint8_t modulation,
+ uint8_t redundancy_version,
+ uint8_t transport_blocks,
+ uint8_t transport_block_to_codeword_swap_flag,
+ uint8_t transmission_scheme,
+ uint8_t number_of_layers,
+ uint8_t number_of_subbands,
+ // uint8_t codebook_index,
+ uint8_t ue_category_capacity,
+ uint8_t pa,
+ uint8_t delta_power_offset_index,
+ uint8_t ngap,
+ uint8_t nprb,
+ uint8_t transmission_mode,
+ uint8_t num_bf_prb_per_subband,
+ uint8_t num_bf_vector) {
+ nfapi_dl_config_request_pdu_t *dl_config_pdu =
+ &dl_req->dl_config_pdu_list[dl_req->number_pdu];
+ memset((void *) dl_config_pdu, 0,
+ sizeof(nfapi_dl_config_request_pdu_t));
+ dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
+ dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu));
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = resource_allocation_type;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = virtual_resource_block_assignment_flag;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = resource_block_coding;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = modulation;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = redundancy_version;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = transport_blocks;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = transport_block_to_codeword_swap_flag;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = transmission_scheme;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = number_of_layers;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = number_of_subbands;
+ // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = ue_category_capacity;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = delta_power_offset_index;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = ngap;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = nprb;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = transmission_mode;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = num_bf_prb_per_subband;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector;
+ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF;
+ dl_req->number_pdu++;
+}
+
+void fill_MCH(PHY_VARS_eNB *eNB,
+ int frame,
+ int subframe,
+ Sched_Rsp_t *sched_resp,
+ uint8_t input_buffer[NUMBER_OF_UE_MAX][20000],
+ int n_rnti,
+ int common_flag,
+ int NB_RB,
+ int TPC,
+ int mcs1){
+
+ nfapi_dl_config_request_body_t *dl_req=&sched_resp->DL_req->dl_config_request_body;
+ nfapi_dl_config_request_pdu_t *dl_config_pdu;
+ nfapi_tx_request_body_t *TX_req=&sched_resp->TX_req->tx_request_body;
+ int NB_RB4TBS = common_flag == 0 ? NB_RB : (2+TPC);
+ dl_req->number_dci=0;
+ dl_req->number_pdu=0;
+ TX_req->number_of_pdus=0;
+ dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+ fill_mch_config(
+ dl_req,
+ get_TBS_DL(mcs1,NB_RB4TBS),
+ 0,
+ 0xfffd,
+ 0,
+ get_Qm(mcs1),
+ mcs1,
+ 6000, //equal to RS power
+ 0 //mbsfn_area_id
+ );
+
+ fill_tx_req(TX_req,
+ (frame * 10) + subframe,
+ get_TBS_DL(mcs1,NB_RB4TBS),
+ 0,
+ input_buffer[0]);
+}
+
+void fill_DCI(PHY_VARS_eNB *eNB,
+ int frame,
+ int subframe,
+ Sched_Rsp_t *sched_resp,
+ uint8_t input_buffer[NUMBER_OF_UE_MAX][20000],
+ int n_rnti,
+ int n_users,
+ int transmission_mode,
+ int retrans,
+ int common_flag,
+ int NB_RB,
+ int DLSCH_RB_ALLOC,
+ int TPC,
+ int mcs1,
+ int mcs2,
+ int ndi,
+ int rv,
+ int pa,
+ int *num_common_dci,
+ int *num_ue_spec_dci,
+ int *num_dci) {
+ int k;
+ nfapi_dl_config_request_body_t *dl_req=&sched_resp->DL_req->dl_config_request_body;
+ nfapi_dl_config_request_pdu_t *dl_config_pdu;
+ nfapi_tx_request_body_t *TX_req=&sched_resp->TX_req->tx_request_body;
+ int NB_RB4TBS = common_flag == 0 ? NB_RB : (2+TPC);
+ dl_req->number_dci=0;
+ dl_req->number_pdu=0;
+ TX_req->number_of_pdus=0;
+
+ for(k=0; kdl_config_pdu_list[dl_req->number_pdu];
+ memset((void *) dl_config_pdu, 0,
+ sizeof(nfapi_dl_config_request_pdu_t));
+ dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
+ dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = (common_flag == 0) ? NFAPI_DL_DCI_FORMAT_1 : NFAPI_DL_DCI_FORMAT_1A;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = (common_flag == 0) ? n_rnti+k : SI_RNTI;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (common_flag ==0 ) ? 1: 2; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = TPC; // dont adjust power when retransmitting
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = (common_flag == 0) ? ndi : 0;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs1;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = (common_flag == 0) ? DLSCH_RB_ALLOC : computeRIV(eNB->frame_parms.N_RB_DL,0,NB_RB);
+ //deactivate second codeword
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = 0;
+ dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = 0;
+ dl_req->number_dci++;
+ dl_req->number_pdu++;
+ dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+ AssertFatal(TPC>=0 && TPC<2, "TPC should be 0 or 1\n");
+ if(1){
+ fill_mch_config(
+ dl_req,
+ get_TBS_DL(mcs1,NB_RB4TBS),
+ 0,
+ 0xfffd,
+ 0,
+ get_Qm(mcs1),
+ mcs1,
+ 6000, //equal to RS power
+ 0 //mbsfn_area_id
+ );
+
+ fill_tx_req(TX_req,
+ (frame * 10) + subframe,
+ get_TBS_DL(mcs1,NB_RB4TBS),
+ 0,
+ input_buffer[0]);
+
+ }else{
+ fill_dlsch_config(dl_req,
+ get_TBS_DL(mcs1,NB_RB4TBS),
+ (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */
+ (common_flag == 0) ? n_rnti : SI_RNTI,
+ 0, // type 0 allocation from 7.1.6 in 36.213
+ 0, // virtual_resource_block_assignment_flag, unused here
+ DLSCH_RB_ALLOC, // resource_block_coding,
+ get_Qm(mcs1),
+ rv, // redundancy version
+ 1, // transport blocks
+ 0, // transport block to codeword swap flag
+ transmission_mode == 1 ? 0 : 1, // transmission_scheme
+ 1, // number of layers
+ 1, // number of subbands
+ // uint8_t codebook_index,
+ 4, // UE category capacity
+ pa, // pa
+ 0, // delta_power_offset for TM5
+ 0, // ngap
+ 0, // nprb
+ transmission_mode,
+ 0, //number of PRBs treated as one subband, not used here
+ 0 // number of beamforming vectors, not used here
+ );
+ fill_tx_req(TX_req,
+ (frame * 10) + subframe,
+ get_TBS_DL(mcs1,NB_RB4TBS),
+ 0,
+ input_buffer[k]);
+ }
+ break;
+
+ case 3:
+ if (common_flag == 0) {
+ if (eNB->frame_parms.nb_antennas_tx == 2) {
+ if (eNB->frame_parms.frame_type == TDD) {
+ } else {
+ }
+ }
+ }
+
+ break;
+
+ case 4:
+ if (common_flag == 0) {
+ if (eNB->frame_parms.nb_antennas_tx == 2) {
+ if (eNB->frame_parms.frame_type == TDD) {
+ } else {
+ }
+ } else if (eNB->frame_parms.nb_antennas_tx == 4) {
+ }
+ } else {
+ }
+
+ break;
+
+ case 5:
+ case 6:
+ break;
+
+ default:
+ printf("Unsupported Transmission Mode %d!!!\n",transmission_mode);
+ exit(-1);
+ break;
+ }
+ }
+
+ *num_dci = dl_req->number_dci;
+ *num_ue_spec_dci = dl_req->number_dci;
+ *num_common_dci = 0;
+}
+
+int n_users = 1;
+int subframe=7;
+int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1;
+uint16_t n_rnti=0x1234;
+
+int abstx=0;
+int Nid_cell=0;
+int N_RB_DL=25;
+int tdd_config=3;
+int dci_flag=0;
+int threequarter_fs=0;
+double snr_step=1,input_snr_step=1, snr_int=30;
+double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
+int test_perf=0;
+int n_frames;
+int n_ch_rlz = 1;
+int rx_sample_offset = 0;
+int xforms=0;
+int dump_table=0;
+int loglvl=OAILOG_WARNING;
+int mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0;
+int two_thread_flag=0;
+int num_rounds = 4;//,fix_rounds=0;
+int perfect_ce = 0;
+int extended_prefix_flag=0;
+int verbose=0, help=0;
+double SNR,snr0=-2.0,snr1,rate = 0;
+int print_perf=0;
+
int main(int argc, char **argv) {
- char c;
- int i,l,l2,aa,aarx,k;
- double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1=0.0;
- uint8_t snr1set=0;
- double snr_step=1,input_snr_step=1;
- int **txdata;
- double s_re0[2*30720],s_im0[2*30720],s_re1[2*30720],s_im1[2*30720];
- double r_re0[2*30720],r_im0[2*30720],r_re1[2*30720],r_im1[2*30720];
- double *s_re[2]= {s_re0,s_re1},*s_im[2]= {s_im0,s_im1},*r_re[2]= {r_re0,r_re1},*r_im[2]= {r_im0,r_im1};
- double iqim = 0.0;
- int subframe=1;
- char fname[40];//, vname[40];
- uint8_t transmission_mode = 1,n_tx=1,n_rx=2;
- uint16_t Nid_cell=0;
- FILE *fd;
- int eNB_id = 0;
- unsigned char mcs=0,awgn_flag=0,round;
- int n_frames=1;
- channel_desc_t *eNB2UE;
- uint32_t nsymb,tx_lev,tx_lev_dB;
- uint8_t extended_prefix_flag=1;
+ int k,i,j,aa;
+ int re;
+ int s,Kr,Kr_bytes;
LTE_DL_FRAME_PARMS *frame_parms;
+ double s_re0[30720*2],s_im0[30720*2],r_re0[30720*2],r_im0[30720*2];
+ double s_re1[30720*2],s_im1[30720*2],r_re1[30720*2],r_im1[30720*2];
+ double *s_re[2]= {s_re0,s_re1};
+ double *s_im[2]= {s_im0,s_im1};
+ double *r_re[2]= {r_re0,r_re1};
+ double *r_im[2]= {r_im0,r_im1};
+ uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2;
+ int eNB_id = 0;
+ unsigned char round;
+ unsigned char i_mod = 2;
+ int NB_RB;
+ SCM_t channel_model=Rayleigh1;
+ // unsigned char *input_data,*decoded_output;
+ DCI_ALLOC_t da;
+ DCI_ALLOC_t *dci_alloc = &da;
+ unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0;
+ unsigned int tx_lev=0,tx_lev_dB=0,trials;
+ unsigned int errs[4],errs2[4],round_trials[4],dci_errors[4];//,num_layers;
+ memset(errs,0,4*sizeof(unsigned int));
+ memset(errs2,0,4*sizeof(unsigned int));
+ memset(round_trials,0,4*sizeof(unsigned int));
+ memset(dci_errors,0,4*sizeof(unsigned int));
+ //int re_allocated;
+ char fname[32],vname[32];
+ FILE *bler_fd;
+ char bler_fname[256];
+ FILE *time_meas_fd;
+ char time_meas_fname[256];
+ // FILE *tikz_fd;
+ // char tikz_fname[256];
+ FILE *input_trch_fd=NULL;
+ unsigned char input_trch_file=0;
+ FILE *input_fd=NULL;
+ unsigned char input_file=0;
+ channel_desc_t *eNB2UE[4];
+ //uint8_t num_pdcch_symbols_2=0;
+ //char stats_buffer[4096];
+ //int len;
+ //int u;
+ int n=0;
+ //int iii;
+ int ch_realization;
+ //int pmi_feedback=0;
int hold_channel=0;
- uint16_t NB_RB=25;
- int tdd_config=3;
- SCM_t channel_model=MBSFN;
- unsigned char *input_buffer;
- unsigned short input_buffer_length;
- unsigned int ret;
- unsigned int trials,errs[4]= {0,0,0,0}; //,round_trials[4]={0,0,0,0};
- uint8_t N_RB_DL=25,osf=1;
- uint32_t perfect_ce = 0;
- lte_frame_type_t frame_type = FDD;
- uint32_t Nsoft = 1827072;
- /*
- #ifdef XFORMS
- FD_lte_phy_scope_ue *form_ue;
+ // void *data;
+ // int ii;
+ // int bler;
+ double blerr[4];
+ short *uncoded_ber_bit=NULL;
+ int osf=1;
+ frame_t frame_type = FDD;
+ FD_lte_phy_scope_ue *form_ue = NULL;
char title[255];
+ int numCCE=0;
+ //int dci_length_bytes=0,dci_length=0;
+ //double channel_bandwidth = 5.0, sampling_rate=7.68;
+ int common_flag=0,TPC=0;
+ double cpu_freq_GHz;
+ // time_stats_t ts;//,sts,usts;
+ int avg_iter,iter_trials;
+ int rballocset=0;
+ int test_passed=0;
+ double effective_rate=0.0;
+ char channel_model_input[10]="I";
+ int TB0_active = 1;
+ // LTE_DL_UE_HARQ_t *dlsch0_ue_harq;
+ // LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq;
+ uint8_t Kmimo;
+ uint8_t ue_category=4;
+ uint32_t Nsoft;
+ int sf;
+ int CCE_table[800];
+ opp_enabled=1; // to enable the time meas
+ FILE *csv_fd=NULL;
+ char csv_fname[FILENAME_MAX];
+ int DLSCH_RB_ALLOC = 0;
+ int dci_received;
+ PHY_VARS_eNB *eNB;
+ RU_t *ru;
+ PHY_VARS_UE *UE=NULL;
+ nfapi_dl_config_request_t DL_req;
+ nfapi_ul_config_request_t UL_req;
+ nfapi_hi_dci0_request_t HI_DCI0_req;
+ nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_DL_PDU];
+ nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU];
+ nfapi_tx_request_t TX_req;
+ Sched_Rsp_t sched_resp;
+ int pa=dB0;
+#if defined(__arm__)
+ FILE *proc_fd = NULL;
+ char buf[64];
+ memset(buf,0,sizeof(buf));
+ proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r");
- fl_initialize (&argc, argv, NULL, 0, 0);
- form_ue = create_lte_phy_scope_ue();
- sprintf (title, "LTE DL SCOPE UE");
- fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
- #endif
- */
- cpuf = get_cpu_freq_GHz();
- logInit();
- number_of_cards = 1;
+ if(!proc_fd)
+ printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq");
+ else {
+ while(fgets(buf, 63, proc_fd))
+ printf("%s", buf);
+ }
- while ((c = getopt (argc, argv, "ahA:Cp:n:s:S:t:x:y:z:N:F:R:O:dm:i:Y")) != -1) {
- switch (c) {
+ fclose(proc_fd);
+ cpu_freq_GHz = ((double)atof(buf))/1e6;
+#else
+ cpu_freq_GHz = get_cpu_freq_GHz();
+#endif
+ printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);
+ memset((void *)&sched_resp,0,sizeof(sched_resp));
+ sched_resp.DL_req = &DL_req;
+ sched_resp.UL_req = &UL_req;
+ sched_resp.HI_DCI0_req = &HI_DCI0_req;
+ sched_resp.TX_req = &TX_req;
+ memset((void *)&DL_req,0,sizeof(DL_req));
+ memset((void *)&UL_req,0,sizeof(UL_req));
+ memset((void *)&HI_DCI0_req,0,sizeof(HI_DCI0_req));
+ memset((void *)&TX_req,0,sizeof(TX_req));
+ DL_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdu_list;
+ TX_req.tx_request_body.tx_pdu_list = tx_pdu_list;
+ set_parallel_conf("PARALLEL_SINGLE_THREAD");
+ cpuf = cpu_freq_GHz;
+ //signal(SIGSEGV, handler);
+ //signal(SIGABRT, handler);
+ // default parameters
+ n_frames = 1000;
+ snr0 = 0;
+ // num_layers = 1;
+ perfect_ce = 0;
+ static paramdef_t options[] = {
+ { "awgn", "Use AWGN channel and not multipath", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL },
+ { "Abstx", "Turns on calibration mode for abstraction.", PARAMFLAG_BOOL, iptr:&abstx, defintval:0, TYPE_INT, 0 },
+ { "bTDD", "Set the tdd configuration mode",0, iptr:&tdd_config, defintval:3, TYPE_INT, 0 },
+ { "BnbRBs", "The LTE bandwith in RBs (100 is 20MHz)",0, iptr:&N_RB_DL, defintval:25, TYPE_INT, 0 },
+ { "cPdcch", "Number of PDCCH symbols",0, iptr:&num_pdcch_symbols, defintval:1, TYPE_INT, 0 },
+ { "CnidCell", "The cell id ",0, iptr:&Nid_cell, defintval:0, TYPE_INT, 0 },
+ { "dciFlag", "Transmit the DCI and compute its error statistics", PARAMFLAG_BOOL, iptr:&dci_flag, defintval:0, TYPE_INT, 0 },
+ { "Dtdd", "Enable tdd", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL },
+ { "eRounds", "Number of rounds",0, iptr:NULL, defintval:25, TYPE_INT, 0 },
+ { "EsubSampling","three quarters sub-sampling",PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0 },
+ { "f_snr_step", "step size of SNR, default value is 1.",0, dblptr:&input_snr_step, defdblval:1, TYPE_DOUBLE, 0 },
+ { "Forgetting", "forgetting factor (0 new channel every trial, 1 channel constant)",0, dblptr:&forgetting_factor, defdblval:0.0, TYPE_DOUBLE, 0 },
+ { "input_file", "input IQ data file",0, iptr:NULL, defintval:0, TYPE_INT, 0 },
+ { "Input_file_trch", " Input filename for TrCH data (binary)",0, iptr:NULL, defintval:0, TYPE_INT, 0 },
+ { "WtwoThreads", "two_thread_flag", PARAMFLAG_BOOL, iptr:&two_thread_flag, defintval:0, TYPE_INT, 0 },
+ { "lMuMimo", "offset_mumimo_llr_drange_fix",0, u8ptr:&offset_mumimo_llr_drange_fix, defintval:0, TYPE_UINT8, 0 },
+ { "mcs1", "The MCS for TB 1", 0, iptr:&mcs1, defintval:0, TYPE_INT, 0 },
+ { "Mcs2", "The MCS for TB 2", 0, iptr:&mcs2, defintval:0, TYPE_INT, 0 },
+ { "Operf", "Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100)",0, iptr:&test_perf, defintval:0, TYPE_INT, 0 },
+ { "tmcs_i", "MCS of interfering UE",0, iptr:NULL, defintval:0, TYPE_INT, 0 },
+ { "nb_frame", "number of frame in a test",0, iptr:&n_frames, defintval:1, TYPE_INT, 0 },
+ { "offsetRxSample", "Sample offset for receiver", 0, iptr:&rx_sample_offset, defintval:0, TYPE_INT, 0 },
+ { "rballocset", "ressource block allocation (see section 7.1.6.3 in 36.213)",0, iptr:NULL, defintval:0, TYPE_INT, 0 },
+ { "snr", "Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated", dblptr:&snr0, defdblval:-2.0, TYPE_DOUBLE, 0 },
+ { "wsnrInterrupt", "snr int ?", 0, dblptr:&snr_int, defdblval:30, TYPE_DOUBLE, 0 },
+ { "N_ch_rlzN0", "Determines the number of Channel Realizations in Abstraction mode. Default value is 1",0, iptr:&n_ch_rlz, defintval:1, TYPE_INT, 0 },
+ { "prefix_extended","Enable extended prefix", PARAMFLAG_BOOL, iptr:&extended_prefix_flag, defintval:0, TYPE_INT, 0 },
+ { "RNumRound", "Number of HARQ rounds (fixed)",0, iptr:&num_rounds, defintval:4, TYPE_INT, 0 },
+ { "Subframe", "subframe ",0, iptr:&subframe, defintval:7, TYPE_INT, 0 },
+ { "Trnti", "rnti",0, u16ptr:&n_rnti, defuintval:0x1234, TYPE_UINT16, 0 },
+ { "vi_mod", "i_mod",0, iptr:NULL, defintval:0, TYPE_INT, 0 },
+ { "Qparallel", "Enable parallel execution",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 },
+ { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL, iptr:&print_perf, defintval:0, TYPE_INT, 0 },
+ { "q_tx_port", "Number of TX antennas ports used in eNB",0, iptr:NULL, defintval:0, TYPE_INT, 0 },
+ { "uEdual", "Enables the Interference Aware Receiver for TM5 (default is normal receiver)",0, iptr:NULL, defintval:0, TYPE_INT, 0 },
+ { "xTransmission","Transmission mode (1,2,6,7 for the moment)",0, iptr:NULL, defintval:25, TYPE_INT, 0 },
+ { "yn_tx_phy","Number of TX antennas used in eNB",0, iptr:NULL, defintval:25, TYPE_INT, 0 },
+ { "XForms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 },
+ { "Yperfect_ce","Perfect CE", PARAMFLAG_BOOL, iptr:&perfect_ce, defintval:0, TYPE_INT, 0 },
+ { "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 },
+ { "Loglvl", "log level",0, iptr:&loglvl, defintval:OAILOG_DEBUG, TYPE_INT, 0 },
+ { "zn_rx", "Number of RX antennas used in UE",0, iptr:NULL, defintval:2, TYPE_INT, 0 },
+ { "gchannel", "[A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 },
+ { "verbose", "display debug text", PARAMFLAG_BOOL, iptr:&verbose, defintval:0, TYPE_INT, 0 },
+ { "mmse", "Use MMSE whitening", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL },
+ { "help", "display help and exit", PARAMFLAG_BOOL, iptr:&help, defintval:0, TYPE_INT, 0 },
+ { "", "",0, iptr:NULL, defintval:0, TYPE_INT, 0 },
+ };
+ struct option *long_options = parse_oai_options(options);
+ int option_index;
+ int res;
+
+ while ((res=getopt_long_only(argc, argv, "", long_options, &option_index)) == 0) {
+ if (options[option_index].voidptr != NULL ) {
+ if (long_options[option_index].has_arg==no_argument)
+ *(bool *)options[option_index].iptr=1;
+ else switch (options[option_index].type) {
+ case TYPE_INT:
+ *(int *)options[option_index].iptr=atoi(optarg);
+ break;
+
+ case TYPE_DOUBLE:
+ *(double *)options[option_index].dblptr=atof(optarg);
+ break;
+
+ case TYPE_UINT8:
+ *(uint8_t *)options[option_index].dblptr=atoi(optarg);
+ break;
+
+ case TYPE_UINT16:
+ *(uint16_t *)options[option_index].dblptr=atoi(optarg);
+ break;
+
+ default:
+ printf("not decoded type.\n");
+ exit(1);
+ }
+
+ continue;
+ }
+
+ switch (long_options[option_index].name[0]) {
case 'a':
- awgn_flag=1;
+ awgn_flag = 1;
+ channel_model = AWGN;
break;
- case 'd':
- frame_type = 0;
+ case 'D':
+ frame_type=TDD;
break;
- case 'n':
- n_frames = atoi(optarg);
- break;
-
- case 'm':
- mcs=atoi(optarg);
- break;
-
- case 's':
- snr0 = atof(optarg);
- msg("Setting SNR0 to %f\n",snr0);
+ case 'e':
+ num_rounds=1;
+ common_flag = 1;
+ TPC = atoi(optarg);
break;
case 'i':
- input_snr_step = atof(optarg);
+ input_fd = fopen(optarg,"r");
+ input_file=1;
+ dci_flag = 1;
break;
- case 'S':
- snr1 = atof(optarg);
- snr1set=1;
- msg("Setting SNR1 to %f\n",snr1);
+ case 'I':
+ input_trch_fd = fopen(optarg,"r");
+ input_trch_file=1;
break;
- case 'p': // subframe no;
- subframe=atoi(optarg);
+ case 't':
+ mcs_i = atoi(optarg);
+ i_mod = get_Qm(mcs_i);
+ break;
+
+ case 'r':
+ DLSCH_RB_ALLOC = atoi(optarg);
+ rballocset = 1;
+ break;
+
+ case 'g':
+ strncpy(channel_model_input,optarg,9);
+ struct tmp {
+ char opt;
+ int m;
+ int M;
+ }
+ tmp[]= {
+ {'A',SCM_A,2},
+ {'B',SCM_B,3},
+ {'C',SCM_C,4},
+ {'D',SCM_D,5},
+ {'E',EPA,6},
+ {'F',EVA,6},
+ {'G',ETU,8},
+ {'H',Rayleigh8,9},
+ {'I',Rayleigh1,10},
+ {'J',Rayleigh1_corr,11},
+ {'K',Rayleigh1_anticorr,12},
+ {'L',Rice8,13},
+ {'M',Rice1,14},
+ {'N',AWGN,1},
+ {0,0,0}
+ };
+ struct tmp *ptr;
+
+ for (ptr=tmp; ptr->opt!=0; ptr++)
+ if ( ptr->opt == optarg[0] ) {
+ channel_model=ptr->m;
+ break;
+ }
+
+ AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg );
+ break;
+
+ case 'u':
+ dual_stream_UE=1;
+
+ if (UE != NULL)
+ UE->use_ia_receiver = 1;
+ else {
+ printf("UE is NULL\n");
+ exit(-1);
+ }
+
+ if ((n_tx_port!=2) || (transmission_mode!=5)) {
+ printf("IA receiver only supported for TM5!");
+ exit(-1);
+ }
+
+ break;
+
+ case 'v':
+ i_mod = atoi(optarg);
+
+ if (i_mod!=2 && i_mod!=4 && i_mod!=6) {
+ printf("Wrong i_mod %d, should be 2,4 or 6\n",i_mod);
+ exit(-1);
+ }
+
+ break;
+
+ case 'q':
+ n_tx_port=atoi(optarg);
+
+ if ((n_tx_port==0) || ((n_tx_port>2))) {
+ printf("Unsupported number of cell specific antennas ports %d\n",n_tx_port);
+ exit(-1);
+ }
+
+ break;
+
+ case 'x':
+ transmission_mode=atoi(optarg);
+
+ if ((transmission_mode!=1) &&
+ (transmission_mode!=2) &&
+ (transmission_mode!=3) &&
+ (transmission_mode!=4) &&
+ (transmission_mode!=5) &&
+ (transmission_mode!=6) &&
+ (transmission_mode!=7)) {
+ printf("Unsupported transmission mode %d\n",transmission_mode);
+ exit(-1);
+ }
+
+ if (transmission_mode>1 && transmission_mode<7) {
+ n_tx_port = 2;
+ }
+
+ break;
+
+ case 'y':
+ n_tx_phy=atoi(optarg);
+
+ if (n_tx_phy < n_tx_port) {
+ printf("n_tx_phy mush not be smaller than n_tx_port");
+ exit(-1);
+ }
+
+ if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) {
+ printf("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode);
+ exit(-1);
+ }
+
+ if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) {
+ printf("Physical number of antennas not supported for TM7.\n");
+ exit(-1);
+ }
+
break;
case 'z':
n_rx=atoi(optarg);
if ((n_rx==0) || (n_rx>2)) {
- msg("Unsupported number of rx antennas %d\n",n_rx);
+ printf("Unsupported number of rx antennas %d\n",n_rx);
exit(-1);
}
break;
- case 'N':
- Nid_cell = atoi(optarg);
- break;
-
- case 'R':
- N_RB_DL = atoi(optarg);
-
- if ((N_RB_DL!=6) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=100)) {
- printf("Unsupported Bandwidth %d\n",N_RB_DL);
- exit(-1);
- }
-
- break;
-
- case 'O':
- osf = atoi(optarg);
- break;
-
- case 'Y':
- perfect_ce = 1;
+ case 'Q':
+ set_parallel_conf(optarg);
break;
default:
- case 'h':
- printf("%s -h(elp) -p(subframe) -N cell_id -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -i snr increment -z RXant \n",argv[0]);
- printf("-h This message\n");
- printf("-a Use AWGN Channel\n");
- printf("-p Use extended prefix mode\n");
- printf("-d Use TDD\n");
- printf("-n Number of frames to simulate\n");
- printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n");
- printf("-S Ending SNR, runs from SNR0 to SNR1\n");
- printf("-t Delay spread for multipath channel\n");
- printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
- printf("-x Transmission mode (1,2,6 for the moment)\n");
- printf("-y Number of TX antennas used in eNB\n");
- printf("-z Number of RX antennas used in UE\n");
- printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
- printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
- printf("-N Nid_cell\n");
- printf("-R N_RB_DL\n");
- printf("-O oversampling factor (1,2,4,8,16)\n");
- printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
- printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
- printf("-f Output filename (.txt format) for Pe/SNR results\n");
- printf("-F Input filename (.txt format) for RX conformance testing\n");
- exit (-1);
+ printf("Wrong option: %s\n",long_options[option_index].name);
+ exit(1);
break;
}
}
- if (awgn_flag == 1)
- channel_model = AWGN;
-
- // check that subframe is legal for eMBMS
-
- if ((subframe == 0) || (subframe == 5) || // TDD and FDD SFn 0,5;
- ((frame_type == FDD) && ((subframe == 4) || (subframe == 9))) || // FDD SFn 4,9;
- ((frame_type == TDD ) && ((subframe<3) || (subframe==6)))) { // TDD SFn 1,2,6;
- printf("Illegal subframe %d for eMBMS transmission (frame_type %d)\n",subframe,frame_type);
- exit(-1);
+ if ( res != -1 ) {
+ printf("A wrong option has been found\n");
+ exit(1);
}
- if (transmission_mode==2)
- n_tx=2;
+ if (help || verbose )
+ display_options_values(options, true);
- lte_param_init(n_tx,
- n_tx,
+ if (help)
+ exit(0);
+ if (thread_struct.parallel_conf != PARALLEL_SINGLE_THREAD)
+ set_worker_conf("WORKER_ENABLE");
+
+ if (transmission_mode>1) pa=dBm3;
+
+ printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa);
+ AssertFatal(load_configmodule(argc,argv, CONFIG_ENABLECMDLINEONLY) != NULL,
+ "cannot load configuration module, exiting\n");
+ logInit();
+ set_glog_onlinelog(true);
+ // enable these lines if you need debug info
+ set_glog(loglvl);
+ SET_LOG_DEBUG(UE_TIMING);
+ // moreover you need to init itti with the following line
+ // however itti will catch all signals, so ctrl-c won't work anymore
+ // alternatively you can disable ITTI completely in CMakeLists.txt
+ //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
+
+ if (common_flag == 0) {
+ switch (N_RB_DL) {
+ case 6:
+ if (rballocset==0) DLSCH_RB_ALLOC = 0x3f;
+
+ num_pdcch_symbols = 3;
+ break;
+
+ case 25:
+ if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff;
+
+ break;
+
+ case 50:
+ if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff;
+
+ break;
+
+ case 100:
+ if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff;
+
+ break;
+ }
+
+ NB_RB = conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
+ } else {
+ if (rballocset==0) NB_RB = 8;
+ else NB_RB = DLSCH_RB_ALLOC;
+
+ AssertFatal(NB_RB <= N_RB_DL,"illegal NB_RB %d\n",NB_RB);
+ }
+
+ if (xforms==1) {
+ fl_initialize (&argc, argv, NULL, 0, 0);
+ form_ue = create_lte_phy_scope_ue();
+ sprintf (title, "LTE PHY SCOPE eNB");
+ fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
+
+ if (!dual_stream_UE==0) {
+ if (UE) {
+ UE->use_ia_receiver = 1;
+ fl_set_button(form_ue->button_0,1);
+ fl_set_object_label(form_ue->button_0, "IA Receiver ON");
+ fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN);
+ } else {
+ printf("UE is NULL\n");
+ exit(-1);
+ }
+ }
+ }
+
+ if (transmission_mode==5) {
+ n_users = 2;
+ printf("dual_stream_UE=%d\n", dual_stream_UE);
+ }
+
+ RC.nb_L1_inst = 1;
+ RC.nb_RU = 1;
+ lte_param_init(&eNB,&UE,&ru,
+ n_tx_port,
+ n_tx_phy,
+ 1,
n_rx,
transmission_mode,
extended_prefix_flag,
@@ -224,281 +1068,1251 @@ int main(int argc, char **argv) {
Nid_cell,
tdd_config,
N_RB_DL,
- 0,
+ pa,
+ threequarter_fs,
osf,
perfect_ce);
+ RC.eNB = (PHY_VARS_eNB ** *)malloc(sizeof(PHY_VARS_eNB **));
+ RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *));
+ RC.ru = (RU_t **)malloc(sizeof(RC.ru));
+ RC.eNB[0][0] = eNB;
+ RC.ru[0] = ru;
+ printf("lte_param_init done\n");
- if (snr1set==0) {
- if (n_frames==1)
- snr1 = snr0+.1;
- else
- snr1 = snr0+5.0;
+ if ((transmission_mode==1) || (transmission_mode==7)) {
+ for (aa=0; aanb_tx; aa++)
+ for (re=0; reframe_parms.ofdm_symbol_size; re++)
+ ru->beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx;
}
+ if (transmission_mode<7)
+ ru->do_precoding=0;
+ else
+ ru->do_precoding=1;
+
+ eNB->mac_enabled=1;
+
+
+#ifdef ENABLE_MBMS_SIM
+ //eNB->pbch_configured=1;
+ eNB_MAC_INST ** mac;
+ mac = malloc16(1 * sizeof(eNB_MAC_INST *));
+ for (int ii = 0;ii < 1; ii++) {
+ mac[ii] = malloc16(sizeof(eNB_MAC_INST));
+ bzero(mac[ii], sizeof(eNB_MAC_INST));
+ }
+ RC.mac = mac;
+ COMMON_channels_t *cc = &RC.mac[0]->common_channels[0];
+ cc->MCH_pdu.mcs = 9;
+ cc->MCH_pdu.Pdu_size = get_TBS_DL(cc->MCH_pdu.mcs,N_RB_DL);
+ printf("MCH_pdu.Pdu_size %d\n",cc->MCH_pdu.Pdu_size);
+ cc->MCH_pdu.sync_area =0;
+ for(int ii=0; ii < cc->MCH_pdu.Pdu_size; ii++)
+ cc->MCH_pdu.payload[ii] = (char)(taus() & 0xff);
+ eNB->frame_parms.Nid_cell_mbsfn=0;
+#endif
+
+
+ if(get_thread_worker_conf() == WORKER_ENABLE) {
+ extern void init_td_thread(PHY_VARS_eNB *);
+ extern void init_te_thread(PHY_VARS_eNB *);
+ init_td_thread(eNB);
+ init_te_thread(eNB);
+ }
+
+ // callback functions required for phy_procedures_tx
+ // eNB_id_i = UE->n_connected_eNB;
+ printf("Setting mcs1 = %d\n",mcs1);
+ printf("Setting mcs2 = %d\n",mcs2);
+ printf("NPRB = %d\n",NB_RB);
+ printf("n_frames = %d\n",n_frames);
+ printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag);
+ snr1 = snr0+snr_int;
printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
+ uint8_t input_buffer[NUMBER_OF_UE_MAX][20000];
+
+ for (i=0; iframe_parms;
+ nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12;
+ printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model);
+ printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d\n",
+ SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8);
- if (awgn_flag == 0)
- sprintf(fname,"embms_%d_%d.m",mcs,N_RB_DL);
+ if(transmission_mode==5)
+ sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,channel_model,n_rx,mcs1,mcs_i,dual_stream_UE,i_mod);
else
- sprintf(fname,"embms_awgn_%d_%d.m",mcs,N_RB_DL);
+ sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d.csv",transmission_mode,channel_model,n_rx,mcs1);
- if (!(fd = fopen(fname,"w"))) {
- printf("Cannot open %s, check permissions\n",fname);
+ bler_fd = fopen(bler_fname,"w");
+
+ if (bler_fd==NULL) {
+ fprintf(stderr,"Cannot create file %s!\n",bler_fname);
exit(-1);
}
- if (awgn_flag==0)
- fprintf(fd,"SNR_%d_%d=[];errs_mch_%d_%d=[];mch_trials_%d_%d=[];\n",
- mcs,N_RB_DL,
- mcs,N_RB_DL,
- mcs,N_RB_DL);
- else
- fprintf(fd,"SNR_awgn_%d_%d=[];errs_mch_awgn_%d_%d=[];mch_trials_awgn_%d_%d=[];\n",
- mcs,N_RB_DL,
- mcs,N_RB_DL,
- mcs,N_RB_DL);
+ fprintf(bler_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n");
- fflush(fd);
- txdata = eNB->common_vars.txdata[0];
- nsymb = 12;
- printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d, AWGN %d\n",NUMBER_OF_OFDM_CARRIERS,
- frame_parms->Ncp,frame_parms->samples_per_tti,nsymb,awgn_flag);
- eNB2UE = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
- UE->frame_parms.nb_antennas_rx,
- channel_model,
- N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
- N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
- 0,
- 0,
- 0);
- // Create transport channel structures for 2 transport blocks (MIMO)
- eNB->dlsch_MCH = new_eNB_dlsch(1,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
+ if (test_perf != 0) {
+ char hostname[1024];
+ hostname[1023] = '\0';
+ gethostname(hostname, 1023);
+ printf("Hostname: %s\n", hostname);
+ //char dirname[FILENAME_MAX];
+ //sprintf(dirname, "%s/SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname );
+ sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_anttx%d_antrx%d_pdcch%d_channel%s_tx%d.csv",
+ N_RB_DL,mcs1,n_tx_phy,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode);
+ //mkdir(dirname,0777);
+ time_meas_fd = fopen(time_meas_fname,"w");
- if (!eNB->dlsch_MCH) {
- printf("Can't get eNB dlsch structures\n");
- exit(-1);
+ if (time_meas_fd==NULL) {
+ fprintf(stderr,"Cannot create file %s!\n",time_meas_fname);
+ exit(-1);
+ }
}
- UE->dlsch_MCH[0] = new_ue_dlsch(1,8,Nsoft,MAX_TURBO_ITERATIONS_MBSFN,N_RB_DL,0);
- eNB->frame_parms.num_MBSFN_config = 1;
- eNB->frame_parms.MBSFN_config[0].radioframeAllocationPeriod = 0;
- eNB->frame_parms.MBSFN_config[0].radioframeAllocationOffset = 0;
- eNB->frame_parms.MBSFN_config[0].fourFrames_flag = 0;
- eNB->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xff; // activate all possible subframes
- UE->frame_parms.num_MBSFN_config = 1;
- UE->frame_parms.MBSFN_config[0].radioframeAllocationPeriod = 0;
- UE->frame_parms.MBSFN_config[0].radioframeAllocationOffset = 0;
- UE->frame_parms.MBSFN_config[0].fourFrames_flag = 0;
- UE->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xff; // activate all possible subframes
- fill_eNB_dlsch_MCH(eNB,mcs,1,0);
- fill_UE_dlsch_MCH(UE,mcs,1,0,0);
+ if(abstx) {
+ // CSV file
+ sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d.m",transmission_mode,dual_stream_UE,mcs1,channel_model,n_frames,num_rounds);
+ csv_fd = fopen(csv_fname,"w");
- if (is_pmch_subframe(0,subframe,&eNB->frame_parms)==0) {
- printf("eNB is not configured for MBSFN in subframe %d\n",subframe);
- exit(-1);
- } else if (is_pmch_subframe(0,subframe,&UE->frame_parms)==0) {
- printf("UE is not configured for MBSFN in subframe %d\n",subframe);
- exit(-1);
- }
-
- input_buffer_length = eNB->dlsch_MCH->harq_processes[0]->TBS/8;
- input_buffer = (unsigned char *)malloc(input_buffer_length+4);
- memset(input_buffer,0,input_buffer_length+4);
-
- for (i=0; iproc.proc_rxtx[0].frame_tx=0;
- eNB->proc.proc_rxtx[0].frame_tx=0;
- eNB->proc.proc_rxtx[0].subframe_tx=subframe;
- errs[0]=0;
- errs[1]=0;
- errs[2]=0;
- errs[3]=0;
- /*
- round_trials[0] = 0;
- round_trials[1] = 0;
- round_trials[2] = 0;
- round_trials[3] = 0;*/
- printf("********************** SNR %f (step %f)\n",SNR,snr_step);
-
- for (trials = 0; trialsfirst_run = 1;
- eNB2UE->first_run = 1;
- memset(&eNB->common_vars.txdataF[0][0][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
- generate_mch(eNB,&eNB->proc.proc_rxtx[0],input_buffer);
- PHY_ofdm_mod(eNB->common_vars.txdataF[0][0], // input,
- txdata[0], // output
- frame_parms->ofdm_symbol_size,
- LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*nsymb, // number of symbols
- frame_parms->nb_prefix_samples, // number of prefix samples
- CYCLIC_PREFIX);
-
- if (n_frames==1) {
- LOG_M("txsigF0.m","txsF0", &eNB->common_vars.txdataF[0][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],
- nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
- //if (eNB->frame_parms.nb_antennas_tx>1)
- //LOG_M("txsigF1.m","txsF1", &eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
- }
-
- tx_lev = 0;
-
- for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
- tx_lev += signal_energy(&eNB->common_vars.txdata[eNB_id][aa]
- [subframe*eNB->frame_parms.samples_per_tti],
- eNB->frame_parms.samples_per_tti);
- }
-
- tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
-
- if (n_frames==1) {
- printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB);
- // LOG_M("txsig0.m","txs0", &eNB->common_vars.txdata[0][0][subframe* eNB->frame_parms.samples_per_tti],
- // eNB->frame_parms.samples_per_tti,1,1);
- }
-
- for (i=0; i<2*frame_parms->samples_per_tti; i++) {
- for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
- s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]);
- s_im[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
- }
- }
-
- //Multipath channel
- multipath_channel(eNB2UE,s_re,s_im,r_re,r_im,
- 2*frame_parms->samples_per_tti,hold_channel);
- //AWGN
- sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(NB_RB*12)) - SNR;
- sigma2 = pow(10,sigma2_dB/10);
-
- if (n_frames==1)
- printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB);
-
- for (i=0; i<2*frame_parms->samples_per_tti; i++) {
- for (aa=0; aaframe_parms.nb_antennas_rx; aa++) {
- //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
- ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] =
- (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
- ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] =
- (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
- }
- }
-
- for (l=2; l<12; l++) {
- slot_fep_mbsfn(UE,
- l,
- subframe%10,
- 0,
- 0);
-
- if (UE->perfect_ce==1) {
- // fill in perfect channel estimates
- freq_channel(eNB2UE,UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1);
-
- for(k=0; knb_antennas_tx; aa++) {
- for (aarx=0; aarxnb_antennas_rx; aarx++) {
- for (i=0; iN_RB_DL*12; i++) {
- ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+
- (aa*frame_parms->nb_antennas_rx)][i].x*AMP);
- ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+
- (aa*frame_parms->nb_antennas_rx)][i].y*AMP);
- }
- }
- }
- }
- }
-
- if (l==6)
- for (l2=2; l2<7; l2++)
- rx_pmch(UE,
- 0,
- subframe%10,
- l2);
-
- if (l==6)
- for (l2=2; l2<7; l2++)
- rx_pmch(UE,
- 0,
- subframe%10,
- l2);
-
- if (l==11)
- for (l2=7; l2<12; l2++)
- rx_pmch(UE,
- 0,
- subframe%10,
- l2);
- }
-
- UE->dlsch_MCH[0]->harq_processes[0]->G = get_G(&UE->frame_parms,
- UE->dlsch_MCH[0]->harq_processes[0]->nb_rb,
- UE->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
- get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs),
- 1,2,
- UE->proc.proc_rxtx[0].frame_tx,subframe,0);
- UE->dlsch_MCH[0]->harq_processes[0]->Qm = get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs);
- dlsch_unscrambling(&UE->frame_parms,1,UE->dlsch_MCH[0],
- UE->dlsch_MCH[0]->harq_processes[0]->G,
- UE->pdsch_vars_MCH[0]->llr[0],0,subframe<<1);
- ret = dlsch_decoding(UE,
- UE->pdsch_vars_MCH[0]->llr[0],
- &UE->frame_parms,
- UE->dlsch_MCH[0],
- UE->dlsch_MCH[0]->harq_processes[0],
- trials,
- subframe,
- 0,0,0);
-
- if (n_frames==1)
- printf("MCH decoding returns %u\n",ret);
-
- if (ret == (1+UE->dlsch_MCH[0]->max_turbo_iterations))
- errs[0]++;
-
- UE->proc.proc_rxtx[0].frame_tx++;
- eNB->proc.proc_rxtx[0].frame_tx++;
+ if (csv_fd==NULL) {
+ fprintf(stderr,"Cannot create file %s!\n",csv_fname);
+ exit(-1);
}
- printf("errors %u/%u (Pe %e)\n",errs[round],trials,(double)errs[round]/trials);
+ fprintf(csv_fd,"data_all%d=[",mcs1);
+ }
- if (awgn_flag==0)
- fprintf(fd,"SNR_%d_%d = [SNR_%d_%d %f]; errs_mch_%d_%d =[errs_mch_%d_%d %u]; mch_trials_%d_%d =[mch_trials_%d_%d %u];\n",
- mcs,N_RB_DL,mcs,N_RB_DL,SNR,
- mcs,N_RB_DL,mcs,N_RB_DL,errs[0],
- mcs,N_RB_DL,mcs,N_RB_DL,trials);
- else
- fprintf(fd,"SNR_awgn_%d = [SNR_awgn_%d %f]; errs_mch_awgn_%d =[errs_mch_awgn_%d %u]; mch_trials_awgn_%d =[mch_trials_awgn_%d %u];\n",
- N_RB_DL,N_RB_DL,SNR,
- N_RB_DL,N_RB_DL,errs[0],
- N_RB_DL,N_RB_DL,trials);
+ /*
+ //sprintf(tikz_fname, "second_bler_tx%d_u2=%d_mcs%d_chan%d_nsimus%d.tex",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames);
+ sprintf(tikz_fname, "second_bler_tx%d_u2%d_mcs%d_chan%d_nsimus%d",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames);
+ tikz_fd = fopen(tikz_fname,"w");
+ //fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {");
+ switch (mcs)
+ {
+ case 0:
+ fprintf(tikz_fd,"\\addplot[color=blue, mark=star] plot coordinates {");
+ break;
+ case 1:
+ fprintf(tikz_fd,"\\addplot[color=red, mark=star] plot coordinates {");
+ break;
+ case 2:
+ fprintf(tikz_fd,"\\addplot[color=green, mark=star] plot coordinates {");
+ break;
+ case 3:
+ fprintf(tikz_fd,"\\addplot[color=yellow, mark=star] plot coordinates {");
+ break;
+ case 4:
+ fprintf(tikz_fd,"\\addplot[color=black, mark=star] plot coordinates {");
+ break;
+ case 5:
+ fprintf(tikz_fd,"\\addplot[color=blue, mark=o] plot coordinates {");
+ break;
+ case 6:
+ fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {");
+ break;
+ case 7:
+ fprintf(tikz_fd,"\\addplot[color=green, mark=o] plot coordinates {");
+ break;
+ case 8:
+ fprintf(tikz_fd,"\\addplot[color=yellow, mark=o] plot coordinates {");
+ break;
+ case 9:
+ fprintf(tikz_fd,"\\addplot[color=black, mark=o] plot coordinates {");
+ break;
+ case 10:
+ fprintf(tikz_fd,"\\addplot[color=blue, mark=square] plot coordinates {");
+ break;
+ case 11:
+ fprintf(tikz_fd,"\\addplot[color=red, mark=square] plot coordinates {");
+ break;
+ case 12:
+ fprintf(tikz_fd,"\\addplot[color=green, mark=square] plot coordinates {");
+ break;
+ case 13:
+ fprintf(tikz_fd,"\\addplot[color=yellow, mark=square] plot coordinates {");
+ break;
+ case 14:
+ fprintf(tikz_fd,"\\addplot[color=black, mark=square] plot coordinates {");
+ break;
+ case 15:
+ fprintf(tikz_fd,"\\addplot[color=blue, mark=diamond] plot coordinates {");
+ break;
+ case 16:
+ fprintf(tikz_fd,"\\addplot[color=red, mark=diamond] plot coordinates {");
+ break;
+ case 17:
+ fprintf(tikz_fd,"\\addplot[color=green, mark=diamond] plot coordinates {");
+ break;
+ case 18:
+ fprintf(tikz_fd,"\\addplot[color=yellow, mark=diamond] plot coordinates {");
+ break;
+ case 19:
+ fprintf(tikz_fd,"\\addplot[color=black, mark=diamond] plot coordinates {");
+ break;
+ case 20:
+ fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {");
+ break;
+ case 21:
+ fprintf(tikz_fd,"\\addplot[color=red, mark=x] plot coordinates {");
+ break;
+ case 22:
+ fprintf(tikz_fd,"\\addplot[color=green, mark=x] plot coordinates {");
+ break;
+ case 23:
+ fprintf(tikz_fd,"\\addplot[color=yellow, mark=x] plot coordinates {");
+ break;
+ case 24:
+ fprintf(tikz_fd,"\\addplot[color=black, mark=x] plot coordinates {");
+ break;
+ case 25:
+ fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {");
+ break;
+ case 26:
+ fprintf(tikz_fd,"\\addplot[color=red, mark=+] plot coordinates {");
+ break;
+ case 27:
+ fprintf(tikz_fd,"\\addplot[color=green, mark=+] plot coordinates {");
+ break;
+ case 28:
+ fprintf(tikz_fd,"\\addplot[color=yellow, mark=+] plot coordinates {");
+ break;
+ }
+ */
+ UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti;
+ UE->n_connected_eNB = 1;
+ printf("Allocating %dx%d eNB->UE channel descriptor\n",eNB->frame_parms.nb_antennas_tx,UE->frame_parms.nb_antennas_rx);
+ eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
+ UE->frame_parms.nb_antennas_rx,
+ channel_model,
+ N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
+ N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
+ forgetting_factor,
+ rx_sample_offset,
+ 0);
+ reset_meas(&eNB2UE[0]->random_channel);
+ reset_meas(&eNB2UE[0]->interp_time);
- fflush(fd);
+ if(num_rounds>1) {
+ for(n=1; n<4; n++) {
+ eNB2UE[n] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
+ UE->frame_parms.nb_antennas_rx,
+ channel_model,
+ N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
+ N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
+ forgetting_factor,
+ rx_sample_offset,
+ 0);
+ reset_meas(&eNB2UE[n]->random_channel);
+ reset_meas(&eNB2UE[n]->interp_time);
+ }
+ }
- if (errs[0] == 0)
+ if (eNB2UE[0]==NULL) {
+ printf("Problem generating channel model. Exiting.\n");
+ exit(-1);
+ }
+
+ if ((transmission_mode == 3) || (transmission_mode==4))
+ Kmimo=2;
+ else
+ Kmimo=1;
+
+ switch (ue_category) {
+ case 1:
+ Nsoft = 250368;
+ break;
+
+ case 2:
+ case 3:
+ Nsoft = 1237248;
+ break;
+
+ case 4:
+ Nsoft = 1827072;
+ break;
+
+ default:
+ printf("Unsupported UE category %d\n",ue_category);
+ exit(-1);
break;
}
- if (n_frames==1) {
- printf("Dumping PMCH files ( G %d)\n",UE->dlsch_MCH[0]->harq_processes[0]->G);
- dump_mch(UE,0,
- UE->dlsch_MCH[0]->harq_processes[0]->G,
- subframe);
+ for (k=0; kdlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
+
+ if (!eNB->dlsch[k][i]) {
+ printf("Can't get eNB dlsch structures\n");
+ exit(-1);
+ }
+
+ eNB->dlsch[k][i]->rnti = n_rnti+k;
+ }
}
- printf("Freeing dlsch structures\n");
- free_eNB_dlsch(eNB->dlsch_MCH);
- free_ue_dlsch(UE->dlsch_MCH[0]);
- fclose(fd);
- return(0);
-}
+#ifdef ENABLE_MBMS_SIM
+ eNB->dlsch_MCH = new_eNB_dlsch(1,8,Nsoft,N_RB_DL, 0, &eNB->frame_parms);
+#endif
+
+ /* allocate memory for both subframes (only one is really used
+ * but there is now "copy_harq_proc_struct" which needs both
+ * to be valid)
+ * TODO: refine this somehow (necessary?)
+ */
+ for (sf = 0; sf < 2; sf++) {
+ for (i=0; i<2; i++) {
+ UE->dlsch[sf][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+
+ if (!UE->dlsch[sf][0][i]) {
+ printf("Can't get ue dlsch structures\n");
+ exit(-1);
+ }
+
+ UE->dlsch[sf][0][i]->rnti = n_rnti;
+ }
+ }
+
+#ifdef ENABLE_MBMS_SIM
+ UE->dlsch_MCH[0] = new_ue_dlsch(1,8,Nsoft,MAX_TURBO_ITERATIONS_MBSFN,N_RB_DL,0);
+ UE->dlsch_MCH[0]->active = 1;
+ UE->dlsch_MCH[0]->harq_processes[0]->mcs = mcs1;
+#endif
+
+ UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+ UE->dlsch_ra[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+ UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0);
+ // structure for SIC at UE
+ UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
+
+ if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
+ eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff);
+
+ if (n_users>1)
+ eNB->UE_stats[1].DL_pmi_single = (eNB->UE_stats[0].DL_pmi_single ^ 0x1555); //opposite PMI
+ } else {
+ eNB->UE_stats[0].DL_pmi_single = 0;
+
+ if (n_users>1)
+ eNB->UE_stats[1].DL_pmi_single = 0;
+ }
+
+ L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc;
+
+ if (input_fd==NULL) {
+ DL_req.dl_config_request_body.number_pdcch_ofdm_symbols = num_pdcch_symbols;
+ DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
+ TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
+ // UE specific DCI
+ fill_DCI(eNB,
+ proc_eNB->frame_tx,subframe,
+ &sched_resp,
+ input_buffer,
+ n_rnti,
+ n_users,
+ transmission_mode,
+ 0,
+ common_flag,
+ NB_RB,
+ DLSCH_RB_ALLOC,
+ TPC,
+ mcs1,
+ mcs2,
+ 1,
+ 0,
+ pa,
+ &num_common_dci,
+ &num_ue_spec_dci,
+ &num_dci);
+ numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe));
+
+ if (n_frames==1) printf("num_pdcch_symbols %d, numCCE %d, num_dci %d/%d/%d\n",num_pdcch_symbols,numCCE, num_dci,num_ue_spec_dci,num_common_dci);
+ }
+
+ eNB->frame_parms.Nid_cell_mbsfn=0;
+ if(enable_fembms){
+ lte_gold_mbsfn_khz_1dot25 (&eNB->frame_parms, eNB->lte_gold_mbsfn_khz_1dot25_table, eNB->frame_parms.Nid_cell_mbsfn);
+ eNB->frame_parms.NonMBSFN_config_flag=1;
+ }else{
+ lte_gold_mbsfn (&eNB->frame_parms, eNB->lte_gold_mbsfn_table, eNB->frame_parms.Nid_cell_mbsfn);
+ eNB->frame_parms.num_MBSFN_config=1;
+ eNB->frame_parms.MBSFN_config[0].radioframeAllocationPeriod=0;
+ eNB->frame_parms.MBSFN_config[0].fourFrames_flag=0;
+ eNB->frame_parms.MBSFN_config[0].radioframeAllocationOffset=0;
+ //eNB->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xC0;
+ eNB->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xFC;
+ }
+
+
+
+ snr_step = input_snr_step;
+ UE->high_speed_flag = 1;
+ UE->ch_est_alpha=0;
+
+ for (ch_realization=0; ch_realizationproc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx=0;
+ errs[0]=0;
+ errs[1]=0;
+ errs[2]=0;
+ errs[3]=0;
+ errs2[0]=0;
+ errs2[1]=0;
+ errs2[2]=0;
+ errs2[3]=0;
+ round_trials[0] = 0;
+ round_trials[1] = 0;
+ round_trials[2] = 0;
+ round_trials[3] = 0;
+ dci_errors[0]=0;
+ dci_errors[1]=0;
+ dci_errors[2]=0;
+ dci_errors[3]=0;
+ // avg_ber = 0;
+ round=0;
+ avg_iter = 0;
+ iter_trials=0;
+ reset_meas(&eNB->phy_proc_tx); // total eNB tx
+ reset_meas(&eNB->dlsch_scrambling_stats);
+ reset_meas(&UE->dlsch_unscrambling_stats);
+ reset_meas(&eNB->ofdm_mod_stats);
+ reset_meas(&eNB->dlsch_modulation_stats);
+ reset_meas(&eNB->dlsch_encoding_stats);
+ reset_meas(&eNB->dlsch_interleaving_stats);
+ reset_meas(&eNB->dlsch_rate_matching_stats);
+ reset_meas(&eNB->dlsch_turbo_encoding_stats);
+ reset_meas(&eNB->dlsch_common_and_dci);
+ reset_meas(&eNB->dlsch_ue_specific);
+
+ for (int i=0; iphy_proc_rx[i]); // total UE rx
+ reset_meas(&UE->ue_front_end_stat[i]);
+ reset_meas(&UE->pdsch_procedures_stat[i]);
+ reset_meas(&UE->dlsch_procedures_stat[i]);
+ reset_meas(&UE->dlsch_decoding_stats[i]);
+ reset_meas(&UE->dlsch_llr_stats_parallelization[i][0]);
+ reset_meas(&UE->dlsch_llr_stats_parallelization[i][1]);
+ }
+
+ reset_meas(&UE->ofdm_demod_stats);
+ reset_meas(&UE->crnti_procedures_stats);
+ reset_meas(&UE->dlsch_channel_estimation_stats);
+ reset_meas(&UE->dlsch_freq_offset_estimation_stats);
+ reset_meas(&UE->rx_dft_stats);
+ reset_meas(&UE->dlsch_decoding_stats[0]);
+ reset_meas(&UE->dlsch_decoding_stats[1]);
+ reset_meas(&UE->dlsch_turbo_decoding_stats);
+ reset_meas(&UE->dlsch_deinterleaving_stats);
+ reset_meas(&UE->dlsch_rate_unmatching_stats);
+ reset_meas(&UE->dlsch_tc_init_stats);
+ reset_meas(&UE->dlsch_tc_alpha_stats);
+ reset_meas(&UE->dlsch_tc_beta_stats);
+ reset_meas(&UE->dlsch_tc_gamma_stats);
+ reset_meas(&UE->dlsch_tc_ext_stats);
+ reset_meas(&UE->dlsch_tc_intl1_stats);
+ reset_meas(&UE->dlsch_tc_intl2_stats);
+ // initialization
+ // initialization
+ varArray_t *table_tx=initVarArray(1000,sizeof(double));
+ varArray_t *table_tx_ifft=initVarArray(1000,sizeof(double));
+ varArray_t *table_tx_mod=initVarArray(1000,sizeof(double));
+ varArray_t *table_tx_enc=initVarArray(1000,sizeof(double));
+ varArray_t *table_rx=initVarArray(1000,sizeof(double));
+ time_stats_t phy_proc_rx_tot;
+ time_stats_t pdsch_procedures_tot;
+ time_stats_t dlsch_procedures_tot;
+ time_stats_t dlsch_decoding_tot;
+ time_stats_t dlsch_llr_tot;
+ time_stats_t ue_front_end_tot;
+ varArray_t *table_rx_fft=initVarArray(1000,sizeof(double));
+ varArray_t *table_rx_demod=initVarArray(1000,sizeof(double));
+ varArray_t *table_rx_dec=initVarArray(1000,sizeof(double));
+
+ for (trials = 0; trialsfirst_run = 1;
+ UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack = 0;
+ UE->dlsch[UE->current_thread_id[subframe]][eNB_id][1]->harq_ack[subframe].ack = 0;
+
+ while ((round < num_rounds) && (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 0)) {
+ // printf("Trial %d, round %d\n",trials,round);
+ round_trials[round]++;
+
+ //if(transmission_mode>=5)
+ // pmi_feedback=1;
+ //else
+ // pmi_feedback=0;
+
+ if (abstx) {
+ if (trials==0 && round==0 && SNR==snr0) //generate a new channel
+ hold_channel = 0;
+ else
+ hold_channel = 1;
+ } else
+ hold_channel = 0;//(round==0) ? 0 : 1;
+
+ //PMI_FEEDBACK:
+
+ // printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback);
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
+ memset(&eNB->common_vars.txdataF[aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
+ }
+
+ if (input_fd==NULL) {
+ // Simulate HARQ procedures!!!
+ memset(CCE_table,0,800*sizeof(int));
+
+ if (/*common_flag == 0*/ 1) {
+ num_dci=0;
+ num_common_dci=0;
+ num_ue_spec_dci=0;
+
+ if (round == 0) { // First round
+ TB0_active = 1;
+ eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
+ DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
+ TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
+ fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,0,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC,
+ mcs1,mcs2,!(trials&1),round&3,pa,&num_common_dci,&num_ue_spec_dci,&num_dci);
+ } else {
+ DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
+ TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
+ fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,1,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC,
+ (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,pa,&num_common_dci,&num_ue_spec_dci,&num_dci);
+ }
+ }
+
+//#ifdef ENABLE_MBMS_SIM
+// eNB->frame_parms.Nid_cell_mbsfn=0;
+// lte_gold_mbsfn (&eNB->frame_parms, eNB->lte_gold_mbsfn_table, eNB->frame_parms.Nid_cell_mbsfn);
+//#endif
+
+ UE->measurements.n0_power_tot_dB = 10*log10((double)tx_lev) +10*log10((double)ru->frame_parms.ofdm_symbol_size/(double)(ru->frame_parms.N_RB_DL*12)) - SNR;
+ UE->measurements.n0_power_tot = pow(10,( 10*log10((double)tx_lev) +10*log10((double)ru->frame_parms.ofdm_symbol_size/(double)(ru->frame_parms.N_RB_DL*12)) - SNR)/10);
+
+ proc_eNB->subframe_tx = subframe;
+ sched_resp.subframe=subframe;
+ sched_resp.frame=proc_eNB->frame_tx;
+ eNB->abstraction_flag=0;
+ schedule_response(&sched_resp);
+ phy_procedures_eNB_TX(eNB,proc_eNB,1);
+
+ if (uncoded_ber_bit == NULL) {
+ // this is for user 0 only
+ printf("nb_rb %d, rb_alloc %x, mcs %d\n",
+ eNB->dlsch[0][0]->harq_processes[0]->nb_rb,
+ eNB->dlsch[0][0]->harq_processes[0]->rb_alloc[0],
+ eNB->dlsch[0][0]->harq_processes[0]->mcs);
+ coded_bits_per_codeword = get_G(&eNB->frame_parms,
+ eNB->dlsch[0][0]->harq_processes[0]->nb_rb,
+ eNB->dlsch[0][0]->harq_processes[0]->rb_alloc,
+ get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
+ eNB->dlsch[0][0]->harq_processes[0]->Nl,
+ num_pdcch_symbols,
+ 0,
+ subframe,
+ transmission_mode>=7?transmission_mode:0);
+ uncoded_ber_bit = (short *) malloc(sizeof(short)*coded_bits_per_codeword);
+ printf("uncoded_ber_bit=%p\n",uncoded_ber_bit);
+ }
+
+
+
+ start_meas(&eNB->ofdm_mod_stats);
+ ru->proc.subframe_tx=subframe;
+ LOG_W(PHY,"eNB %d\n",eNB->frame_parms.num_MBSFN_config);
+ LOG_W(PHY,"eNB %d\n",eNB->frame_parms.NonMBSFN_config_flag);
+ memcpy((void *)&ru->frame_parms,(void *)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS));
+ LOG_W(PHY,"RU %d\n",ru->frame_parms.num_MBSFN_config);
+ LOG_W(PHY,"RU %d\n",ru->frame_parms.NonMBSFN_config_flag);
+ feptx_prec(ru);
+ feptx_ofdm(ru);
+ stop_meas(&eNB->ofdm_mod_stats);
+ // generate next subframe for channel estimation
+ DL_req.dl_config_request_body.number_dci=0;
+ DL_req.dl_config_request_body.number_pdu=0;
+ TX_req.tx_request_body.number_of_pdus=0;
+ proc_eNB->subframe_tx = subframe+1;
+ sched_resp.subframe=subframe+1;
+ schedule_response(&sched_resp);
+
+ phy_procedures_eNB_TX(eNB,proc_eNB,0);
+ ru->proc.subframe_tx=(subframe+1)%10;
+ feptx_prec(ru);
+ feptx_ofdm(ru);
+ proc_eNB->frame_tx++;
+ tx_lev = 0;
+
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
+ tx_lev += signal_energy(&ru->common.txdata[aa]
+ [subframe*eNB->frame_parms.samples_per_tti],
+ eNB->frame_parms.samples_per_tti);
+ }
+
+ tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
+
+ if (n_frames==1) {
+ printf("tx_lev = %u (%u dB)\n",tx_lev,tx_lev_dB);
+ LOG_M("txsig0.m","txs0", &ru->common.txdata[0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1);
+
+ if (transmission_mode<7) {
+ LOG_M("txsigF0.m","txsF0x", &ru->common.txdataF_BF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
+ } else if (transmission_mode == 7) {
+ LOG_M("txsigF0.m","txsF0", &ru->common.txdataF_BF[5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
+ LOG_M("txsigF0_BF.m","txsF0_BF", &ru->common.txdataF_BF[0][0],eNB->frame_parms.ofdm_symbol_size,1,1);
+ }
+ }
+ }
+
+ DL_channel(ru,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd);
+ UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]];
+ proc->subframe_rx = subframe;
+ UE->UE_mode[0] = PUSCH;
+ // first symbol has to be done separately in one-shot mode
+ slot_fep(UE,
+ 0,
+ (proc->subframe_rx<<1),
+ UE->rx_offset,
+ 0,
+ 0);
+
+ if (n_frames==1) printf("Running phy_procedures_UE_RX\n");
+
+ if (dci_flag==0) {
+ memcpy(dci_alloc,eNB->pdcch_vars[subframe&1].dci_alloc,num_dci*sizeof(DCI_ALLOC_t));
+ UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols;
+
+ if (n_frames==1)
+ printf("bypassing PDCCH/DCI detection\n");
+
+ if (generate_ue_dlsch_params_from_dci(proc->frame_rx,
+ proc->subframe_rx,
+ (void *)&dci_alloc[0].dci_pdu,
+ common_flag == 0 ? n_rnti : SI_RNTI,
+ dci_alloc[0].format,
+ UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
+ UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
+ UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0],
+ &UE->frame_parms,
+ UE->pdsch_config_dedicated,
+ SI_RNTI,
+ 0,
+ P_RNTI,
+ UE->transmission_mode[eNB_id]<7?0:UE->transmission_mode[eNB_id],
+ 0)==0) {
+ dump_dci(&UE->frame_parms, &dci_alloc[0]);
+ //UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][0]->active = 1;
+ //UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][1]->active = 1;
+ UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols;
+ UE->dlsch_received[eNB_id]++;
+ } else {
+ LOG_E(PHY,"Problem in DCI!\n");
+ }
+ }
+
+
+ UE->frame_parms.Nid_cell_mbsfn=0;
+ if(enable_fembms){
+ lte_gold_mbsfn_khz_1dot25 (&UE->frame_parms, UE->lte_gold_mbsfn_khz_1dot25_table, UE->frame_parms.Nid_cell_mbsfn);
+ UE->frame_parms.NonMBSFN_config_flag=1;
+ }else{
+ lte_gold_mbsfn (&UE->frame_parms, UE->lte_gold_mbsfn_table, UE->frame_parms.Nid_cell_mbsfn);
+ UE->frame_parms.num_MBSFN_config=1;
+ UE->frame_parms.MBSFN_config[0].radioframeAllocationPeriod=0;
+ UE->frame_parms.MBSFN_config[0].fourFrames_flag=0;
+ UE->frame_parms.MBSFN_config[0].radioframeAllocationOffset=0;
+ UE->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xC0;
+ }
+
+
+
+
+ dci_received = UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;
+ phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx);
+ dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;
+
+ if (dci_flag && (dci_received == 0)) {
+ printf("DCI not received\n");
+ dci_errors[round]++;
+ LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
+ LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
+ LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1);
+ LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4);
+ LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
+ LOG_M("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+ exit(-1);
+ }
+
+ int bit_errors=0;
+
+ if ((test_perf ==0 ) && (n_frames==1)) {
+ dlsch_unscrambling(&eNB->frame_parms,
+ 0,
+ UE->dlsch[UE->current_thread_id[subframe]][0][0],
+ coded_bits_per_codeword,
+ UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0],
+ 0,
+ subframe<<1);
+
+ for (i=0; idlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)||
+ (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) {
+ uncoded_ber_bit[bit_errors++] = 1;
+ printf("error in pos %d : %d => %d\n",i,
+ eNB->dlsch[0][0]->harq_processes[0]->e[i],
+ UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]);
+ } else {
+ /*
+ printf("no error in pos %d : %d => %d\n",i,
+ eNB->dlsch[0][0]->harq_processes[0]->e[i],
+ UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]);
+ */
+ }
+
+ LOG_M("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
+ LOG_M("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8);
+
+ if (eNB->frame_parms.nb_antennas_tx>1)
+ LOG_M("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8);
+
+ //common vars
+ LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
+ LOG_M("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+ if (UE->frame_parms.nb_antennas_rx>1) {
+ LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
+ LOG_M("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+ }
+
+ LOG_M("dlsch00_r0.m","dl00_r0",
+ &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+ if (UE->frame_parms.nb_antennas_rx>1)
+ LOG_M("dlsch01_r0.m","dl01_r0",
+ &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+ if (eNB->frame_parms.nb_antennas_tx>1)
+ LOG_M("dlsch10_r0.m","dl10_r0",
+ &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+ if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1))
+ LOG_M("dlsch11_r0.m","dl11_r0",
+ &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
+
+ //pdsch_vars
+ printf("coded_bits_per_codeword %u\n",coded_bits_per_codeword);
+ dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
+ LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
+ //pdcch_vars
+ LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
+ LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
+ LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1);
+ LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4);
+ }
+
+ if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 1) {
+ avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt;
+ iter_trials++;
+
+ if (n_frames==1)
+ printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword);
+
+ UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS;
+ TB0_active = 0;
+ } // DLSCH received ok
+ else {
+ errs[round]++;
+ avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt-1;
+ iter_trials++;
+
+ if (n_frames==1) {
+ //if ((n_frames==1) || (SNR>=30)) {
+ printf("DLSCH errors found (round %d), uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword);
+
+ for (s=0; sdlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) {
+ if (sdlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus)
+ Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus;
+ else
+ Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus;
+
+ Kr_bytes = Kr>>3;
+ printf("Decoded_output (Segment %d):\n",s);
+
+ for (i=0; idlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i],
+ UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
+ }
+
+ sprintf(fname,"rxsig0_r%d.m",round);
+ sprintf(vname,"rxs0_r%d",round);
+ LOG_M(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
+ sprintf(fname,"rxsigF0_r%d.m",round);
+ sprintf(vname,"rxs0F_r%d",round);
+ LOG_M(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+ if (UE->frame_parms.nb_antennas_rx>1) {
+ sprintf(fname,"rxsig1_r%d.m",round);
+ sprintf(vname,"rxs1_r%d.m",round);
+ LOG_M(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
+ sprintf(fname,"rxsigF1_r%d.m",round);
+ sprintf(vname,"rxs1F_r%d.m",round);
+ LOG_M(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+ }
+
+ sprintf(fname,"dlsch00_r%d.m",round);
+ sprintf(vname,"dl00_r%d",round);
+ LOG_M(fname,vname,
+ &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+ if (UE->frame_parms.nb_antennas_rx>1) {
+ sprintf(fname,"dlsch01_r%d.m",round);
+ sprintf(vname,"dl01_r%d",round);
+ LOG_M(fname,vname,
+ &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
+ }
+
+ if (eNB->frame_parms.nb_antennas_tx>1) {
+ sprintf(fname,"dlsch10_r%d.m",round);
+ sprintf(vname,"dl10_r%d",round);
+ LOG_M(fname,vname,
+ &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
+ }
+
+ if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) {
+ sprintf(fname,"dlsch11_r%d.m",round);
+ sprintf(vname,"dl11_r%d",round);
+ LOG_M(fname,vname,
+ &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
+ }
+
+ //pdsch_vars
+ dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
+ //LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
+ //LOG_M("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
+ //LOG_M("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
+ //LOG_M("dlsch_w.m","w",UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
+ //pdcch_vars
+ LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
+ LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
+ LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1);
+ LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4);
+
+ if (round == 3) exit(-1);
+ }
+
+ // printf("round %d errors %d/%d\n",round,errs[round],trials);
+ round++;
+ // UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++;
+ }
+
+ if (xforms==1) {
+ phy_scope_UE(form_ue,
+ UE,
+ eNB_id,
+ 0,// UE_id
+ subframe);
+ }
+
+ UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++;
+ } //round
+
+ // printf("\n");
+
+ if ((errs[0]>=n_frames/10) && (trials>(n_frames/2)))
+ break;
+
+ //len = chbch_stats_read(stats_buffer,NULL,0,4096);
+ //printf("%s\n\n",stats_buffer);
+
+ if (UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx % 10 == 0) {
+ UE->bitrate[eNB_id] = (UE->total_TBS[eNB_id] - UE->total_TBS_last[eNB_id])*10;
+ LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",UE->Mod_id,UE->total_TBS[eNB_id],UE->total_TBS_last[eNB_id],
+ UE->bitrate[eNB_id]/1000);
+ UE->total_TBS_last[eNB_id] = UE->total_TBS[eNB_id];
+ }
+
+ /* calculate the total processing time for each packet,
+ * get the max, min, and number of packets that exceed t>2000us
+ */
+ double t_tx = inMicroS(eNB->phy_proc_tx.p_time);
+ double t_tx_ifft = inMicroS(eNB->ofdm_mod_stats.p_time);
+ double t_rx = inMicroS(UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time);
+ sumUpStats(&phy_proc_rx_tot, UE->phy_proc_rx, UE->current_thread_id[subframe]);
+ sumUpStats(&ue_front_end_tot, UE->ue_front_end_stat, UE->current_thread_id[subframe]);
+ sumUpStats(&pdsch_procedures_tot, UE->pdsch_procedures_stat, UE->current_thread_id[subframe]);
+ sumUpStats(&dlsch_procedures_tot, UE->dlsch_procedures_stat, UE->current_thread_id[subframe]);
+ sumUpStats(&dlsch_decoding_tot, UE->dlsch_decoding_stats, UE->current_thread_id[subframe]);
+ sumUpStatsSlot(&dlsch_llr_tot, UE->dlsch_llr_stats_parallelization, UE->current_thread_id[subframe]);
+ double t_rx_fft = inMicroS(UE->ofdm_demod_stats.p_time);
+ double t_rx_demod = inMicroS(UE->dlsch_rx_pdcch_stats.p_time);
+ double t_rx_dec = inMicroS(UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time);
+
+ if (t_tx > 2000 )// 2ms is too much time for a subframe
+ n_tx_dropped++;
+
+ if (t_rx > 2000 )
+ n_rx_dropped++;
+
+ appendVarArray(table_tx, &t_tx);
+ appendVarArray(table_tx_ifft, &t_tx_ifft);
+ appendVarArray(table_rx, &t_rx );
+ appendVarArray(table_rx_fft, &t_rx_fft );
+ appendVarArray(table_rx_demod, &t_rx_demod );
+ appendVarArray(table_rx_dec, &t_rx_dec );
+ } //trials
+
+ // round_trials[0]: number of code word : goodput the protocol
+ // sort table
+ qsort (dataArray(table_tx), table_tx->size, table_tx->atomSize, &cmpdouble);
+ qsort (dataArray(table_tx_ifft), table_tx_ifft->size, table_tx_ifft->atomSize, &cmpdouble);
+ qsort (dataArray(table_tx_mod), table_tx_mod->size, table_tx_mod->atomSize, &cmpdouble);
+ qsort (dataArray(table_tx_enc), table_tx_enc->size, table_tx_enc->atomSize, &cmpdouble);
+ qsort (dataArray(table_rx), table_rx->size, table_rx->atomSize, &cmpdouble);
+ qsort (dataArray(table_rx_fft), table_rx_fft->size, table_rx_fft->atomSize, &cmpdouble);
+ qsort (dataArray(table_rx_demod), table_rx_demod->size, table_rx_demod->atomSize, &cmpdouble);
+ qsort (dataArray(table_rx_dec), table_rx_dec->size, table_rx_dec->atomSize, &cmpdouble);
+
+ if (dump_table == 1 ) {
+ set_component_filelog(SIM); // file located in /tmp/usim.txt
+ LOG_UDUMPMSG(SIM,table_tx,table_tx->size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n");
+ LOG_UDUMPMSG(SIM,table_rx,table_rx->size,LOG_DUMP_DOUBLE,"Thereceiver raw data: \n");
+ }
+
+ effective_rate = 1.0-((double)(errs[0]+errs[1]+errs[2]+errs[3])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3]));
+ printf("\n**********************SNR = %f dB (tx_lev %f)**************************\n",
+ SNR,
+ (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12)));
+ printf("Errors (%u(%u)/%u %u/%u %u/%u %u/%u), Pe = (%e,%e,%e,%e), dci_errors %u/%u, Pe = %e => effective rate %f, normalized delay %f (%f)\n",
+ errs[0],
+ errs2[0],
+ round_trials[0],
+ errs[1],
+ round_trials[1],
+ errs[2],
+ round_trials[2],
+ errs[3],
+ round_trials[3],
+ (double)errs[0]/(round_trials[0]),
+ (double)errs[1]/(round_trials[1]),
+ (double)errs[2]/(round_trials[2]),
+ (double)errs[3]/(round_trials[3]),
+ dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3],
+ round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3],
+ (double)(dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3])/(round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]),
+ //rate*effective_rate,
+ 100*effective_rate,
+ //rate,
+ //rate*get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
+ (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
+ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
+ double timeBase=1/(1000*cpu_freq_GHz);
+
+ if (print_perf==1) {
+ printf("\neNB TX function statistics (per 1ms subframe)\n");
+ printDistribution(&eNB->phy_proc_tx,table_tx,"PHY proc tx");
+ printStatIndent(&eNB->dlsch_common_and_dci,"DL common channels and dci time");
+ printStatIndent(&eNB->dlsch_ue_specific,"DL per ue part time");
+ printStatIndent2(&eNB->dlsch_encoding_stats,"DLSCH encoding time");
+ printStatIndent3(&eNB->dlsch_rate_matching_stats,"DLSCH rate matching time");
+ printStatIndent3(&eNB->dlsch_turbo_encoding_stats,"DLSCH turbo encoding time");
+ printStatIndent3(&eNB->dlsch_interleaving_stats,"DLSCH interleaving time");
+ printStatIndent2(&eNB->dlsch_scrambling_stats, "DLSCH scrambling time");
+ printStatIndent2(&eNB->dlsch_modulation_stats, "DLSCH modulation time");
+ printDistribution(&eNB->ofdm_mod_stats,table_tx_ifft,"OFDM_mod (idft) time");
+ printf("\nUE RX function statistics (per 1ms subframe)\n");
+ printDistribution(&phy_proc_rx_tot, table_rx,"Total PHY proc rx");
+ printStatIndent(&ue_front_end_tot,"Front end processing");
+ printStatIndent(&dlsch_llr_tot,"rx_pdsch processing");
+ printStatIndent2(&pdsch_procedures_tot,"pdsch processing");
+ printStatIndent2(&dlsch_procedures_tot,"dlsch processing");
+ printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing");
+ printStatIndent(&UE->ofdm_demod_stats,"ofdm demodulation");
+ printStatIndent(&UE->dlsch_channel_estimation_stats,"DLSCH channel estimation time");
+ printStatIndent(&UE->dlsch_freq_offset_estimation_stats,"DLSCH frequency offset estimation time");
+ printStatIndent(&dlsch_decoding_tot, "DLSCH Decoding time ");
+ printStatIndent(&UE->dlsch_unscrambling_stats,"DLSCH unscrambling time");
+ printStatIndent(&UE->dlsch_rate_unmatching_stats,"DLSCH Rate Unmatching");
+ printf("|__ DLSCH Turbo Decoding(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n",
+ UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ?
+ UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus :
+ UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus,
+ UE->dlsch_tc_intl1_stats.trials/(double)UE->dlsch_tc_init_stats.trials,
+ (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials*timeBase,
+ (int)((double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials),
+ UE->dlsch_turbo_decoding_stats.trials);
+ printStatIndent2(&UE->dlsch_tc_init_stats,"init");
+ printStatIndent2(&UE->dlsch_tc_alpha_stats,"alpha");
+ printStatIndent2(&UE->dlsch_tc_beta_stats,"beta");
+ printStatIndent2(&UE->dlsch_tc_gamma_stats,"gamma");
+ printStatIndent2(&UE->dlsch_tc_ext_stats,"ext");
+ printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver");
+ printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC");
+ }
+
+ if ((transmission_mode != 3) && (transmission_mode != 4)) {
+ fprintf(bler_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u\n",
+ SNR,
+ mcs1,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ rate,
+ errs[0],
+ round_trials[0],
+ errs[1],
+ round_trials[1],
+ errs[2],
+ round_trials[2],
+ errs[3],
+ round_trials[3],
+ dci_errors[0]);
+ } else {
+ fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u\n",
+ SNR,
+ mcs1,mcs2,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ eNB->dlsch[0][1]->harq_processes[0]->TBS,
+ rate,
+ errs[0],
+ round_trials[0],
+ errs[1],
+ round_trials[1],
+ errs[2],
+ round_trials[2],
+ errs[3],
+ round_trials[3],
+ dci_errors[0]);
+ }
+
+ if(abstx) { //ABSTRACTION
+ blerr[0] = (double)errs[0]/(round_trials[0]);
+
+ if(num_rounds>1) {
+ blerr[1] = (double)errs[1]/(round_trials[1]);
+ blerr[2] = (double)errs[2]/(round_trials[2]);
+ blerr[3] = (double)errs[3]/(round_trials[3]);
+ fprintf(csv_fd,"%e,%e,%e,%e;\n",blerr[0],blerr[1],blerr[2],blerr[3]);
+ } else {
+ fprintf(csv_fd,"%e;\n",blerr[0]);
+ }
+ } //ABStraction
+
+ if ( (test_perf != 0) && (100 * effective_rate > test_perf )) {
+ //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n");
+ if ((transmission_mode != 3) && (transmission_mode != 4)) {
+ fprintf(time_meas_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u;",
+ SNR,
+ mcs1,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ rate,
+ errs[0],
+ round_trials[0],
+ errs[1],
+ round_trials[1],
+ errs[2],
+ round_trials[2],
+ errs[3],
+ round_trials[3],
+ dci_errors[0]);
+ //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n");
+ fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%u;%u;%e;%f;%f;",
+ SNR,
+ mcs1,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ rate*effective_rate,
+ 100*effective_rate,
+ rate,
+ (double)avg_iter/iter_trials,
+ errs[0],
+ round_trials[0],
+ errs[1],
+ round_trials[1],
+ errs[2],
+ round_trials[2],
+ errs[3],
+ round_trials[3],
+ (double)errs[0]/(round_trials[0]),
+ (double)errs[1]/(round_trials[0]),
+ (double)errs[2]/(round_trials[0]),
+ (double)errs[3]/(round_trials[0]),
+ dci_errors[0],
+ round_trials[0],
+ (double)dci_errors[0]/(round_trials[0]),
+ (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
+ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
+ } else {
+ fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u;",
+ SNR,
+ mcs1,mcs2,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ eNB->dlsch[0][1]->harq_processes[0]->TBS,
+ rate,
+ errs[0],
+ round_trials[0],
+ errs[1],
+ round_trials[1],
+ errs[2],
+ round_trials[2],
+ errs[3],
+ round_trials[3],
+ dci_errors[0]);
+ //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n");
+ fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%u;%u;%e;%f;%f;",
+ SNR,
+ mcs1,mcs2,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ eNB->dlsch[0][1]->harq_processes[0]->TBS,
+ rate*effective_rate,
+ 100*effective_rate,
+ rate,
+ (double)avg_iter/iter_trials,
+ errs[0],
+ round_trials[0],
+ errs[1],
+ round_trials[1],
+ errs[2],
+ round_trials[2],
+ errs[3],
+ round_trials[3],
+ (double)errs[0]/(round_trials[0]),
+ (double)errs[1]/(round_trials[0]),
+ (double)errs[2]/(round_trials[0]),
+ (double)errs[3]/(round_trials[0]),
+ dci_errors[0],
+ round_trials[0],
+ (double)dci_errors[0]/(round_trials[0]),
+ (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
+ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
+ }
+
+ //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n",
+ fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;",
+ eNB->phy_proc_tx.trials,
+ eNB->ofdm_mod_stats.trials,
+ eNB->dlsch_modulation_stats.trials,
+ eNB->dlsch_scrambling_stats.trials,
+ eNB->dlsch_encoding_stats.trials,
+ phy_proc_rx_tot.trials,
+ UE->ofdm_demod_stats.trials,
+ UE->dlsch_rx_pdcch_stats.trials,
+ UE->dlsch_llr_stats.trials,
+ UE->dlsch_unscrambling_stats.trials,
+ UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials
+ );
+ fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;",
+ get_time_meas_us(&eNB->phy_proc_tx),
+ get_time_meas_us(&eNB->ofdm_mod_stats),
+ get_time_meas_us(&eNB->dlsch_modulation_stats),
+ get_time_meas_us(&eNB->dlsch_scrambling_stats),
+ get_time_meas_us(&eNB->dlsch_encoding_stats),
+ get_time_meas_us(&phy_proc_rx_tot),
+ nsymb*get_time_meas_us(&UE->ofdm_demod_stats),
+ get_time_meas_us(&UE->dlsch_rx_pdcch_stats),
+ 3*get_time_meas_us(&UE->dlsch_llr_stats),
+ get_time_meas_us(&UE->dlsch_unscrambling_stats),
+ get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]])
+ );
+ //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;",squareRoot(&UE->phy_proc_tx), t_tx_max, t_tx_min, median(table_tx), q1(table_tx), q3(table_tx), n_tx_dropped);
+ //fprintf(time_meas_fd,"IFFT;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;",
+ squareRoot(&eNB->ofdm_mod_stats),
+ median(table_tx_ifft),q1(table_tx_ifft),q3(table_tx_ifft));
+ //fprintf(time_meas_fd,"MOD;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;",
+ squareRoot(&eNB->dlsch_modulation_stats),
+ median(table_tx_mod), q1(table_tx_mod), q3(table_tx_mod));
+ //fprintf(time_meas_fd,"ENC;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;",
+ squareRoot(&eNB->dlsch_encoding_stats),
+ median(table_tx_enc),q1(table_tx_enc),q3(table_tx_enc));
+ //fprintf(time_meas_fd,"eNB_PROC_RX_STD;eNB_PROC_RX_MAX;eNB_PROC_RX_MIN;eNB_PROC_RX_MED;eNB_PROC_RX_Q1;eNB_PROC_RX_Q3;eNB_PROC_RX_DROPPED;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;",
+ squareRoot(&phy_proc_rx_tot), t_rx_max, t_rx_min,
+ median(table_rx), q1(table_rx), q3(table_rx), n_rx_dropped);
+ //fprintf(time_meas_fd,"FFT;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;",
+ squareRoot(&UE->ofdm_demod_stats),
+ median(table_rx_fft), q1(table_rx_fft), q3(table_rx_fft));
+ //fprintf(time_meas_fd,"DEMOD;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;",
+ squareRoot(&UE->dlsch_demodulation_stats),
+ median(table_rx_demod), q1(table_rx_demod), q3(table_rx_demod));
+ //fprintf(time_meas_fd,"DEC;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f\n",
+ squareRoot(&UE->dlsch_decoding_stats[subframe]),
+ median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec));
+ printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
+ test_passed = 1;
+ break;
+ } else if (test_perf !=0 ) {
+ printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate);
+ test_passed = 0;
+ }
+
+ if (((double)errs[0]/(round_trials[0]))<(10.0/n_frames))
+ break;
+ }// SNR
+ } //ch_realization
+
+ fclose(bler_fd);
+
+ if (test_perf !=0)
+ fclose (time_meas_fd);
+
+ //fprintf(tikz_fd,"};\n");
+ //fclose(tikz_fd);
+
+ if (input_trch_file==1)
+ fclose(input_trch_fd);
+
+ if (input_file==1)
+ fclose(input_fd);
+
+ if(abstx) { // ABSTRACTION
+ fprintf(csv_fd,"];");
+ fclose(csv_fd);
+ }
+
+ if (uncoded_ber_bit)
+ free(uncoded_ber_bit);
+
+ uncoded_ber_bit = NULL;
+ printf("Freeing dlsch structures\n");
+
+ for (i=0; i<2; i++) {
+ printf("eNB %d\n",i);
+ free_eNB_dlsch(eNB->dlsch[0][i]);
+ printf("UE %d\n",i);
+ free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
+ }
+
+ if (test_perf && !test_passed)
+ return(-1);
+ else
+ return(0);
+}
+/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
+uint64_t get_softmodem_optmask(void) {
+ return 0;
+}
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index 42518c6438..37ce3a65d6 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -1087,7 +1087,7 @@ int main(int argc, char **argv) {
if (awgn_flag == 0) {
if (UE2eNB->max_Doppler == 0) {
multipath_channel(UE2eNB,s_re,s_im,r_re,r_im,
- eNB->frame_parms.samples_per_tti,hold_channel);
+ eNB->frame_parms.samples_per_tti,hold_channel,0);
} else {
multipath_tv_channel(UE2eNB,s_re,s_im,r_re,r_im,
2*eNB->frame_parms.samples_per_tti,hold_channel);
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index b4069237b8..957495181a 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -37,7 +37,6 @@
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
-#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
@@ -59,7 +58,8 @@ double cpuf;
uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
-
+uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
+uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
// needed for some functions
PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
@@ -114,7 +114,7 @@ int main(int argc, char **argv)
uint16_t nb_rb = 50;
uint8_t Imcs = 9;
uint8_t mcs_table = 0;
-
+ double DS_TDL = .03;
cpuf = get_cpu_freq_GHz();
if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) {
@@ -337,6 +337,7 @@ int main(int argc, char **argv)
gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model,
61.44e6, //N_RB2sampling_rate(N_RB_DL),
40e6, //N_RB2channel_bandwidth(N_RB_DL),
+ DS_TDL,
0, 0, 0);
if (gNB2UE == NULL) {
@@ -500,7 +501,7 @@ int main(int argc, char **argv)
//printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32));
// generate signal
if (input_fd == NULL) {
- nr_dlsch_encoding(test_input, frame, slot, dlsch, frame_parms,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+ nr_dlsch_encoding(gNB, test_input, frame, slot, dlsch, frame_parms,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
}
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index dedab0ad2b..38400cab51 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -38,9 +38,10 @@
#include "PHY/types.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_eNB.h"
+#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/MODULATION/modulation_UE.h"
-#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
+#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "SCHED_NR/fapi_nr_l1.h"
@@ -123,7 +124,7 @@ int generate_dlsch_header(unsigned char *mac_header,
unsigned char *ue_cont_res_id,
unsigned char short_padding,
unsigned short post_padding){return 0;}
-void nr_ip_over_LTE_DRB_preconfiguration(void){}
+void nr_DRB_preconfiguration(void){}
// needed for some functions
openair0_config_t openair0_cfg[MAX_CARDS];
@@ -181,7 +182,7 @@ int main(int argc, char **argv)
//unsigned char frame_type = 0;
- int frame=0,slot=1;
+ int frame=1,slot=1;
int frame_length_complex_samples;
int frame_length_complex_samples_no_prefix;
NR_DL_FRAME_PARMS *frame_parms;
@@ -573,6 +574,7 @@ int main(int argc, char **argv)
channel_model,
fs,
bw,
+ 30e-9,
0,
0,
0);
@@ -715,12 +717,16 @@ int main(int argc, char **argv)
reset_meas(&gNB->tparity);
reset_meas(&gNB->toutput);
+ clear_pdsch_stats(gNB);
+
n_errors = 0;
effRate = 0;
//n_errors2 = 0;
//n_alamouti = 0;
errors_scrambling=0;
n_false_positive = 0;
+ if (n_trials== 1) num_rounds = 1;
+
for (trial = 0; trial < n_trials; trial++) {
errors_bit = 0;
@@ -755,6 +761,7 @@ int main(int argc, char **argv)
UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
+
UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
UE_list->UE_sched_ctrl[0].current_harq_pid = harq_pid;
gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round;
@@ -779,12 +786,12 @@ int main(int argc, char **argv)
int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP;
if (n_trials==1) {
- LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
+ LOG_M("txsigF0.m","txsF0", &gNB->common_vars.txdataF[0][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
if (gNB->frame_parms.nb_antennas_tx>1)
- LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
+ LOG_M("txsigF1.m","txsF1", &gNB->common_vars.txdataF[1][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
}
int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
- if (n_trials==1) printf("samples_per_slot_wCP = %d\n", frame_parms->samples_per_slot_wCP);
+ if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset);
//TODO: loop over slots
for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
@@ -796,24 +803,51 @@ int main(int argc, char **argv)
12,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
- } else {
+ } else {/*
nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
&txdata[aa][tx_offset],
14,
frame_parms);
+ */
+ PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
+ (int*)&txdata[aa][tx_offset],
+ frame_parms->ofdm_symbol_size,
+ 1,
+ frame_parms->nb_prefix_samples0,
+ CYCLIC_PREFIX);
+
+ apply_nr_rotation(frame_parms,
+ (int16_t*)&txdata[aa][tx_offset],
+ slot,
+ 0,
+ 1,
+ frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
+ PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset+frame_parms->ofdm_symbol_size],
+ (int*)&txdata[aa][tx_offset+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
+ frame_parms->ofdm_symbol_size,
+ 13,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
+ apply_nr_rotation(frame_parms,
+ (int16_t*)&txdata[aa][tx_offset+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
+ slot,
+ 1,
+ 13,
+ frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
+
}
}
if (n_trials==1) {
- LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1);
+ LOG_M("txsig0.m","txs0", &txdata[0][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
if (gNB->frame_parms.nb_antennas_tx>1)
- LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1);
+ LOG_M("txsig1.m","txs1", &txdata[1][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
}
if (output_fd) {
printf("writing txdata to binary file\n");
fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd);
}
-
+
int txlev = signal_energy(&txdata[0][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
// if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev));
@@ -925,25 +959,10 @@ int main(int argc, char **argv)
(float) n_errors / (float) n_trials);
printf("*****************************************\n");
printf("\n");
+ dump_pdsch_stats(gNB);
printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %d bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS);
printf("\n");
- if (n_trials == 1) {
-
- LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1);
- if (UE->frame_parms.nb_antennas_rx>1)
- LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1);
- LOG_M("chestF0.m","chF0",UE->pdsch_vars[0][0]->dl_ch_estimates_ext,N_RB_DL*12*14,1,1);
- write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1);
- break;
- }
-
- //if ((float)n_errors/(float)n_trials <= target_error_rate) {
- if (effRate >= (eff_tp_check*TBS)) {
- printf("PDSCH test OK\n");
- break;
- }
-
if (print_perf==1) {
printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, TBS %d, Kr %d (Zc %d))\n",
1000>>*scc->ssbSubcarrierSpacing,dlsch_config.rbSize,dlsch_config.mcsIndex[0],
@@ -994,6 +1013,24 @@ int main(int argc, char **argv)
printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC");
*/
}
+
+ if (n_trials == 1) {
+
+ LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1);
+ if (UE->frame_parms.nb_antennas_rx>1)
+ LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1);
+ LOG_M("chestF0.m","chF0",UE->pdsch_vars[0][0]->dl_ch_estimates_ext,N_RB_DL*12*14,1,1);
+ write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1);
+ LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]][0]->llr[0],available_bits,1,0);
+ break;
+ }
+
+ //if ((float)n_errors/(float)n_trials <= target_error_rate) {
+ if (effRate >= (eff_tp_check*TBS)) {
+ printf("PDSCH test OK\n");
+ break;
+ }
+
snrRun++;
} // NSR
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 2144652f86..833b81f853 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -33,7 +33,6 @@
#include "PHY/defs_nr_UE.h"
#include "PHY/defs_gNB.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
-#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
@@ -60,6 +59,10 @@ uint16_t NB_UE_INST = 1;
// needed for some functions
openair0_config_t openair0_cfg[MAX_CARDS];
+
+uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
+uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
+
uint64_t get_softmodem_optmask(void) {return 0;}
void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
@@ -105,6 +108,9 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band);
nr_init_frame_parms(gNB_config, fp);
+
+ init_symbol_rotation(fp,fp->dl_CarrierFreq);
+
gNB->configured = 1;
LOG_I(PHY,"gNB configured\n");
}
@@ -468,6 +474,7 @@ int main(int argc, char **argv)
channel_model,
fs,
bw,
+ 300e-9,
0,
0,
0);
@@ -548,10 +555,35 @@ int main(int argc, char **argv)
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
} else {
- nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
+ /* nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
14,
- frame_parms);
+ frame_parms);*/
+ PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
+ (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+ frame_parms->ofdm_symbol_size,
+ 1,
+ frame_parms->nb_prefix_samples0,
+ CYCLIC_PREFIX);
+
+ apply_nr_rotation(frame_parms,
+ (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+ slot,
+ 0,
+ 1,
+ frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
+ PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
+ (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
+ frame_parms->ofdm_symbol_size,
+ 13,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
+ apply_nr_rotation(frame_parms,
+ (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
+ slot,
+ 1,
+ 13,
+ frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
}
}
}
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index 2db5bc905c..7d96e70809 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -37,7 +37,6 @@
#include "SCHED_NR_UE/phy_frame_config_nr.h"
#include "PHY/phy_vars_nr_ue.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
-#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
@@ -76,7 +75,7 @@ boolean_t pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
const sdu_size_t sdu_buffer_sizeP,
mem_block_t *const sdu_buffer_pP) {return(false);}
-void nr_ip_over_LTE_DRB_preconfiguration(void){}
+void nr_DRB_preconfiguration(void){}
void pdcp_layer_init(void) {}
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
@@ -93,6 +92,7 @@ int main(int argc, char **argv){
uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1;
uint32_t tx_lev = 10000, prach_errors = 0, samp_count; //,tx_lev_dB;
uint64_t SSB_positions = 0x01, absoluteFrequencyPointA = 640000;
+ double DS_TDL = .03;
// int8_t interf1=-19,interf2=-19;
// uint8_t abstraction_flag=0,calibration_flag=0;
@@ -558,6 +558,7 @@ int main(int argc, char **argv){
channel_model,
fs,
bw,
+ DS_TDL,
0.0,
delay,
0);
@@ -603,7 +604,7 @@ int main(int argc, char **argv){
/* tx_lev_dB not used later, no need to set */
//tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
- prach_start = subframe*frame_parms->samples_per_subframe-UE->N_TA_offset;
+ prach_start = subframe*frame_parms->samples_per_subframe;
#ifdef NR_PRACH_DEBUG
LOG_M("txsig0.m", "txs0", &txdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index 38743d91bd..c14a3d7198 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -33,7 +33,6 @@
#include "PHY/defs_nr_UE.h"
#include "PHY/defs_gNB.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
-#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
@@ -480,14 +479,17 @@ int main(int argc, char **argv)
uint32_t dmrs_scrambling_id = 0, data_scrambling_id=0;
//t_nrPolar_params *currentPtr;
+ int shift = 0;
+
if(format==0){
- // for now we are not considering SR just HARQ-ACK
+ if (sr_flag)
+ shift = 1< 11) gNB->uci_polarParams = nr_polar_params(2, nr_bit, nrofPRB, 1, NULL);
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index b0557ef1b4..f6d33c1d4b 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -34,7 +34,6 @@
#include "PHY/defs_gNB.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
-#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
@@ -56,6 +55,9 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
+uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
+uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
+
double cpuf;
uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
@@ -97,6 +99,8 @@ int main(int argc, char **argv)
uint16_t nb_rb = 50;
uint8_t Imcs = 9;
+ double DS_TDL = .03;
+
cpuf = get_cpu_freq_GHz();
if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) {
@@ -316,13 +320,12 @@ int main(int argc, char **argv)
snr1 = snr0 + 10;
gNB2UE = new_channel_desc_scm(n_tx,
- n_rx,
- channel_model,
+ n_rx,
+ channel_model,
61.44e6, //N_RB2sampling_rate(N_RB_DL),
40e6, //N_RB2channel_bandwidth(N_RB_DL),
- 0,
- 0,
- 0);
+ DS_TDL,
+ 0,0,0);
if (gNB2UE == NULL) {
printf("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 0ecb8f2c36..9dd6d61557 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -37,7 +37,6 @@
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/NR_REFSIG/dmrs_nr.h"
-#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
@@ -56,7 +55,6 @@
//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
-
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
#include "SIMULATION/LTE_PHY/common_sim.h"
@@ -97,7 +95,7 @@ boolean_t pdcp_data_ind(
) { return(false);}
void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
-void nr_ip_over_LTE_DRB_preconfiguration(void){}
+void nr_DRB_preconfiguration(void){}
int rrc_init_nr_global_param(void){return(0);}
@@ -120,7 +118,7 @@ int main(int argc, char **argv)
double sigma, sigma_dB;
double snr_step = .2;
uint8_t snr1set = 0;
- int slot = 8, frame = 0;
+ int slot = 8, frame = 1;
FILE *output_fd = NULL;
double *s_re[2]= {s_re0,s_re1};
double *s_im[2]= {s_im0,s_im1};
@@ -143,12 +141,12 @@ int main(int argc, char **argv)
//unsigned char frame_type = 0;
NR_DL_FRAME_PARMS *frame_parms;
- int loglvl = OAILOG_WARNING;
+ int loglvl = OAILOG_INFO;
//uint64_t SSB_positions=0x01;
uint16_t nb_symb_sch = 12;
int start_symbol = 0;
uint16_t nb_rb = 50;
- uint8_t Imcs = 9;
+ int Imcs = 9;
uint8_t precod_nbr_layers = 1;
int gNB_id = 0;
int ap;
@@ -161,14 +159,22 @@ int main(int argc, char **argv)
int print_perf = 0;
cpuf = get_cpu_freq_GHz();
int msg3_flag = 0;
- uint8_t rv_index = 0;
+ int rv_index = 0;
float roundStats[50];
float effRate;
- float eff_tp_check = 0.7;
+ //float eff_tp_check = 0.7;
uint8_t snrRun;
+ int enable_ptrs = 0;
+ int modify_dmrs = 0;
+ /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
+ int ptrs_arg[2] = {-1,-1};// Invalid values
+ /* DMRS TYPE = dmrs_arg[0], Add Pos = dmrs_arg[1] */
+ int dmrs_arg[2] = {-1,-1};// Invalid values
+
UE_nr_rxtx_proc_t UE_proc;
FILE *scg_fd=NULL;
+ int file_offset = 0;
double DS_TDL = .03;
int pusch_tgt_snrx10 = 200;
@@ -182,7 +188,7 @@ int main(int argc, char **argv)
//logInit();
randominit(0);
- while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:M:N:PR:S:L:")) != -1) {
+ while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:")) != -1) {
printf("handling optarg %c\n",c);
switch (c) {
@@ -311,10 +317,12 @@ int main(int argc, char **argv)
snr0 = atof(optarg);
printf("Setting SNR0 to %f\n", snr0);
break;
-
+
+/*
case 't':
eff_tp_check = (float)atoi(optarg)/100;
break;
+*/
/*
case 'r':
ricean_factor = pow(10,-.1*atof(optarg));
@@ -358,7 +366,15 @@ int main(int argc, char **argv)
}
break;
-
+
+ case 'G':
+ file_offset = atoi(optarg);
+ break;
+
+ case 'H':
+ slot = atoi(optarg);
+ break;
+
case 'M':
// SSB_positions = atoi(optarg);
break;
@@ -386,7 +402,21 @@ int main(int argc, char **argv)
case 'L':
loglvl = atoi(optarg);
break;
-
+
+ case 'T':
+ enable_ptrs=1;
+ for(i=0; i < atoi(optarg); i++){
+ ptrs_arg[i] = atoi(argv[optind++]);
+ }
+ break;
+
+ case 'U':
+ modify_dmrs = 1;
+ for(i=0; i < atoi(optarg); i++){
+ dmrs_arg[i] = atoi(argv[optind++]);
+ }
+ break;
+
default:
case 'h':
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]);
@@ -416,6 +446,8 @@ int main(int argc, char **argv)
printf("-t Acceptable effective throughput (in percentage)\n");
printf("-S Ending SNR, runs from SNR0 to SNR1\n");
printf("-P Print ULSCH performances\n");
+ printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
+ printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
exit(-1);
break;
@@ -452,14 +484,15 @@ int main(int argc, char **argv)
DS_TDL,
0, 0, 0);
- UE2gNB->max_Doppler = maxDoppler;
if (UE2gNB == NULL) {
printf("Problem generating channel model. Exiting.\n");
exit(-1);
}
+ UE2gNB->max_Doppler = maxDoppler;
+
RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
- RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB));
+ RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
gNB = RC.gNB[0];
//gNB_config = &gNB->gNB_config;
@@ -503,7 +536,7 @@ int main(int argc, char **argv)
0);
fix_scc(scc,ssb_bitmap);
- xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
+ // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
@@ -597,13 +630,9 @@ int main(int argc, char **argv)
nr_scheduled_response_t scheduled_response;
fapi_nr_ul_config_request_t ul_config;
+ fapi_nr_tx_request_t tx_req;
+ fapi_nr_tx_request_body_t tx_req_body;
- unsigned int TBS;
- uint16_t number_dmrs_symbols = 0;
- unsigned int available_bits;
- uint8_t nb_re_dmrs;
- unsigned char mod_order;
- uint16_t code_rate;
uint8_t ptrs_mcs1 = 2;
uint8_t ptrs_mcs2 = 4;
uint8_t ptrs_mcs3 = 10;
@@ -614,28 +643,119 @@ int main(int argc, char **argv)
uint8_t max_rounds = 4;
uint8_t crc_status = 0;
- uint8_t length_dmrs = pusch_len1; // [hna] remove dmrs struct
- uint16_t l_prime_mask = get_l_prime(nb_symb_sch, typeB, pusch_dmrs_pos0, length_dmrs); // [hna] remove dmrs struct
+ unsigned char mod_order = nr_get_Qm_ul(Imcs, 0);
+ uint16_t code_rate = nr_get_code_rate_ul(Imcs, 0);
+
+ uint8_t mapping_type = typeB; // Default Values
+ pusch_dmrs_type_t dmrs_config_type = pusch_dmrs_type1; // Default Values
+ pusch_dmrs_AdditionalPosition_t add_pos = pusch_dmrs_pos0; // Default Values
+
+ /* validate parameters othwerwise default values are used */
+ /* -U flag can be used to set DMRS parameters*/
+ if(modify_dmrs)
+ {
+ if(dmrs_arg[0] == 0)
+ {
+ mapping_type = typeA;
+ }
+ else if (dmrs_arg[0] == 1)
+ {
+ mapping_type = typeB;
+ }
+ /* Additional DMRS positions */
+ if(dmrs_arg[1] >= 0 && dmrs_arg[1] <=3 )
+ {
+ add_pos = dmrs_arg[1];
+ }
+ printf("NOTE: DMRS config is modified with Mapping Type %d , Additional Position %d \n", mapping_type, add_pos );
+ }
+
+ uint8_t length_dmrs = pusch_len1;
+ uint16_t l_prime_mask = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs);
+ uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch);
+ uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4;
+ unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
+ unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
+
+ uint8_t ulsch_input_buffer[TBS/8];
+
+ ulsch_input_buffer[0] = 0x31;
+ for (i = 1; i < TBS/8; i++) {
+ ulsch_input_buffer[i] = (unsigned char) rand();
+ }
+
uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table);
uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, nb_rb);
+ int ptrs_symbols = 0; // to calculate total PTRS RE's in a slot
+
+ double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);
+
+ /* -T option enable PTRS */
+ if(enable_ptrs)
+ {
+ /* validate parameters othwerwise default values are used */
+ if(ptrs_arg[0] == 0 || ptrs_arg[0] == 1 || ptrs_arg[0] == 2 )
+ {
+ ptrs_time_density = ptrs_arg[0];
+ }
+ if(ptrs_arg[1] == 2 || ptrs_arg[1] == 4 )
+ {
+ ptrs_freq_density = ptrs_arg[1];
+ }
+ pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
+ printf("NOTE: PTRS Enabled with L %d, K %d \n", ptrs_time_density, ptrs_freq_density );
+ }
if (input_fd != NULL) max_rounds=1;
if(1<= nb_symb_sch)
pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
- for (i = 0; i < nb_symb_sch; i++) {
- number_dmrs_symbols += (l_prime_mask >> i) & 0x01;
- }
-
- mod_order = nr_get_Qm_ul(Imcs, 0);
- code_rate = nr_get_code_rate_ul(Imcs, 0);
-
printf("\n");
//for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
snrRun = 0;
- int n_errs;
+ int n_errs = 0;
+
+ int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
+ int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
+
+ if (input_fd != NULL) {
+ AssertFatal(frame_parms->nb_antennas_rx == 1, "nb_ant != 1\n");
+ // 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
+ AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing);
+
+ fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET);
+ fread((void*)&n_rnti,sizeof(int16_t),1,input_fd);
+ printf("rnti %x\n",n_rnti);
+ fread((void*)&nb_rb,sizeof(int16_t),1,input_fd);
+ printf("nb_rb %d\n",nb_rb);
+ int16_t dummy;
+ fread((void*)&start_rb,sizeof(int16_t),1,input_fd);
+ //fread((void*)&dummy,sizeof(int16_t),1,input_fd);
+ printf("rb_start %d\n",start_rb);
+ fread((void*)&nb_symb_sch,sizeof(int16_t),1,input_fd);
+ //fread((void*)&dummy,sizeof(int16_t),1,input_fd);
+ printf("nb_symb_sch %d\n",nb_symb_sch);
+ fread((void*)&start_symbol,sizeof(int16_t),1,input_fd);
+ printf("start_symbol %d\n",start_symbol);
+ fread((void*)&Imcs,sizeof(int16_t),1,input_fd);
+ printf("mcs %d\n",Imcs);
+ fread((void*)&rv_index,sizeof(int16_t),1,input_fd);
+ printf("rv_index %d\n",rv_index);
+ // fread((void*)&harq_pid,sizeof(int16_t),1,input_fd);
+ fread((void*)&dummy,sizeof(int16_t),1,input_fd);
+ printf("harq_pid %d\n",harq_pid);
+ fread((void*)&gNB->common_vars.rxdata[0][slot_offset-delay],
+ sizeof(int16_t),
+ slot_length<<1,
+ input_fd);
+ for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
+ slot_offset,
+ ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
+ ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
+ }
+
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
varArray_t *table_rx=initVarArray(1000,sizeof(double));
int error_flag = 0;
@@ -645,11 +765,13 @@ int main(int argc, char **argv)
int round_trials[4]={0,0,0,0};
uint32_t errors_scrambling[4] = {0,0,0,0};
+ clear_pusch_stats(gNB);
for (trial = 0; trial < n_trials; trial++) {
uint8_t round = 0;
crc_status = 1;
errors_decoding = 0;
+ memset((void*)roundStats,0,50*sizeof(roundStats[0]));
while (roundharq_processes[harq_pid]->round = round;
@@ -663,30 +785,15 @@ int main(int argc, char **argv)
reset_meas(&gNB->ulsch_ldpc_decoding_stats);
reset_meas(&gNB->ulsch_unscrambling_stats);
reset_meas(&gNB->ulsch_channel_estimation_stats);
+ reset_meas(&gNB->ulsch_ptrs_processing_stats);
reset_meas(&gNB->ulsch_llr_stats);
+ reset_meas(&gNB->ulsch_mrc_stats);
reset_meas(&gNB->ulsch_channel_compensation_stats);
reset_meas(&gNB->ulsch_rbs_extraction_stats);
UE_proc.nr_tti_tx = slot;
UE_proc.frame_tx = frame;
- // --------- setting parameters for gNB --------
- /*
- rel15_ul->rnti = n_rnti;
- rel15_ul->ulsch_pdu_rel15.start_rb = start_rb;
- rel15_ul->ulsch_pdu_rel15.number_rbs = nb_rb;
- rel15_ul->ulsch_pdu_rel15.start_symbol = start_symbol;
- rel15_ul->ulsch_pdu_rel15.number_symbols = nb_symb_sch;
- rel15_ul->ulsch_pdu_rel15.length_dmrs = length_dmrs;
- rel15_ul->ulsch_pdu_rel15.Qm = mod_order;
- rel15_ul->ulsch_pdu_rel15.mcs = Imcs;
- rel15_ul->ulsch_pdu_rel15.rv = 0;
- rel15_ul->ulsch_pdu_rel15.ndi = 0;
- rel15_ul->ulsch_pdu_rel15.n_layers = precod_nbr_layers;
- rel15_ul->ulsch_pdu_rel15.R = code_rate;
- ///////////////////////////////////////////////////
- */
-
UL_tti_req->SFN = frame;
UL_tti_req->Slot = slot;
UL_tti_req->n_pdus = 1;
@@ -704,7 +811,7 @@ int main(int argc, char **argv)
else
pusch_pdu->bwp_start = ibwp_start;
pusch_pdu->bwp_size = ibwp_size;
- start_rb += (ibwp_start - abwp_start);
+ start_rb = (ibwp_start - abwp_start);
printf("msg3: ibwp_size %d, abwp_size %d, ibwp_start %d, abwp_start %d\n",
ibwp_size,abwp_size,ibwp_start,abwp_start);
}
@@ -713,6 +820,7 @@ int main(int argc, char **argv)
pusch_pdu->bwp_size = abwp_size;
}
+ pusch_pdu->pusch_data.tb_size = TBS/8;
pusch_pdu->pdu_bit_map = pdu_bit_map;
pusch_pdu->rnti = n_rnti;
pusch_pdu->mcs_index = Imcs;
@@ -723,11 +831,11 @@ int main(int argc, char **argv)
pusch_pdu->data_scrambling_id = *scc->physCellId;
pusch_pdu->nrOfLayers = 1;
pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol;
- pusch_pdu->dmrs_config_type = 0;
+ pusch_pdu->dmrs_config_type = dmrs_config_type;
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
pusch_pdu->scid = 0;
pusch_pdu->dmrs_ports = 1;
- pusch_pdu->num_dmrs_cdm_grps_no_data = 1;
+ pusch_pdu->num_dmrs_cdm_grps_no_data = msg3_flag == 0 ? 1 : 2;
pusch_pdu->resource_alloc = 1;
pusch_pdu->rb_start = start_rb;
pusch_pdu->rb_size = nb_rb;
@@ -756,8 +864,17 @@ int main(int argc, char **argv)
scheduled_response.slot = slot;
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &ul_config;
- scheduled_response.tx_request = (fapi_nr_tx_request_t *) malloc(sizeof(fapi_nr_tx_request_t));
- scheduled_response.tx_request->tx_request_body = (fapi_nr_tx_request_body_t *) malloc(sizeof(fapi_nr_tx_request_body_t));
+ scheduled_response.tx_request = &tx_req;
+ scheduled_response.tx_request->tx_request_body = &tx_req_body;
+
+ // Config UL TX PDU
+ tx_req.slot = slot;
+ tx_req.sfn = frame;
+ // tx_req->tx_config // TbD
+ tx_req.number_of_pdus = 1;
+ tx_req_body.pdu_length = TBS/8;
+ tx_req_body.pdu_index = 0;
+ tx_req_body.pdu = &ulsch_input_buffer[0];
ul_config.slot = slot;
ul_config.number_pdus = 1;
@@ -769,31 +886,24 @@ int main(int argc, char **argv)
ul_config.ul_config_list[0].pusch_config_pdu.nr_of_symbols = nb_symb_sch;
ul_config.ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol;
ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol;
- ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = 0;
+ ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
- ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
+ ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = msg3_flag == 0 ? 1 : 2;
+ ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
+ ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
+
+ ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = trial & 0x1;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
- ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
+
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
- //there are plenty of other parameters that we don't seem to be using for now. e.g.
- ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
-
- nb_re_dmrs = ((ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type == pusch_dmrs_type1) ? 6 : 4);
-
- available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
- TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
- pusch_pdu->pusch_data.tb_size = TBS>>3;
- ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS;
nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
- int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);// - (int)(800*factor);
- int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
for (int i=0;i<(TBS>>3);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
double scale = 1;
@@ -854,30 +964,16 @@ int main(int argc, char **argv)
for (ap=0; apnb_antennas_rx; ap++) {
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((tx_gain*r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((tx_gain*r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
+ /* Add phase noise if enabled */
+ if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+ phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)],
+ &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1]);
+ }
}
}
-
- }
- else {
- AssertFatal(frame_parms->nb_antennas_rx == 1, "nb_ant != 1\n");
- // 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
- AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing);
- double factor = 1;
- if (openair0_cfg[0].threequarter_fs== 1) factor =.75;
- int ta_offset=1600;
- if (N_RB_DL <217) ta_offset=800;
- else if (N_RB_DL < 106) ta_offset = 400;
- fseek(input_fd,(slot_length<<2)+2000,SEEK_SET);
- fread((void*)&gNB->common_vars.rxdata[0][slot_offset],
- sizeof(int16_t),
- slot_length<<1,
- input_fd);
- for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
- slot_offset,
- ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
- ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
- fclose(input_fd);
- }
+
+ }
+
////////////////////////////////////////////////////////////
//----------------------------------------------------------
@@ -889,22 +985,32 @@ int main(int argc, char **argv)
start_meas(&gNB->phy_proc_rx);
phy_procedures_gNB_common_RX(gNB, frame, slot);
+ phy_procedures_gNB_uespec_RX(gNB, frame, slot);
+
if (n_trials==1 && round==0) {
- LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][0],frame_parms->samples_per_subframe*10,1,1);
+ LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][slot_offset],slot_length,1,1);
LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0]+start_symbol*frame_parms->ofdm_symbol_size,nb_symb_sch*frame_parms->ofdm_symbol_size,1,1);
}
- phy_procedures_gNB_uespec_RX(gNB, frame, slot);
+
+
if (n_trials == 1 && round==0) {
+#ifdef __AVX2__
+ int off = ((nb_rb&1) == 1)? 4:0;
+#else
+ int off = 0;
+#endif
+
LOG_M("rxsigF0_ext.m","rxsF0_ext",
- &gNB->pusch_vars[0]->rxdataF_ext[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1);
+ &gNB->pusch_vars[0]->rxdataF_ext[0][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
LOG_M("chestF0.m","chF0",
&gNB->pusch_vars[0]->ul_ch_estimates[0][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
LOG_M("chestF0_ext.m","chF0_ext",
- &gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1);
+ &gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
+ (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
LOG_M("rxsigF0_comp.m","rxsF0_comp",
- &gNB->pusch_vars[0]->rxdataF_comp[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1);
+ &gNB->pusch_vars[0]->rxdataF_comp[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
LOG_M("rxsigF0_llr.m","rxsF0_llr",
&gNB->pusch_vars[0]->llr[0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
}
@@ -921,6 +1027,20 @@ int main(int argc, char **argv)
}
if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);
+ //----------------------------------------------------------
+ //----------------- count and print errors -----------------
+ //----------------------------------------------------------
+
+ if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) {
+ ptrs_symbols = 0;
+ for (int i = pusch_pdu->start_symbol_index; i < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; i++){
+ ptrs_symbols += ((gNB->pusch_vars[UE_id]->ptrs_symbols) >> i) & 1;
+ }
+ /* 2*5*(50/2), for RB = 50,K = 2 for 5 OFDM PTRS symbols */
+ available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density);
+ printf("After PTRS subtraction available_bits are : %u \n", available_bits);
+ }
+
for (i = 0; i < available_bits; i++) {
if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
@@ -935,14 +1055,8 @@ int main(int argc, char **argv)
} // round
- //----------------------------------------------------------
- //----------------- count and print errors -----------------
- //----------------------------------------------------------
-
-
-
if (n_trials == 1 && errors_scrambling[0] > 0) {
- printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling);
+ printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling[0]);
}
for (i = 0; i < TBS; i++) {
@@ -981,7 +1095,8 @@ int main(int argc, char **argv)
printf("*****************************************\n");
printf("SNR %f: n_errors (%d/%d,%d/%d,%d/%d,%d/%d) (negative CRC), false_positive %d/%d, errors_scrambling (%u/%u,%u/%u,%u/%u,%u/%u\n", SNR, n_errors[0], round_trials[0],n_errors[1], round_trials[1],n_errors[2], round_trials[2],n_errors[3], round_trials[3], n_false_positive, n_trials, errors_scrambling[0],available_bits*n_trials,errors_scrambling[1],available_bits*n_trials,errors_scrambling[2],available_bits*n_trials,errors_scrambling[3],available_bits*n_trials);
printf("\n");
- printf("SNR %f: Channel BLER (%e,%e,%e,%e), Channel BER (%e,%e,%e,%e) Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %d bits/slot\n", SNR,
+ printf("SNR %f: Channel BLER (%e,%e,%e,%e), Channel BER (%e,%e,%e,%e) Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n",
+ SNR,
(double)n_errors[0]/round_trials[0],
(double)n_errors[1]/round_trials[0],
(double)n_errors[2]/round_trials[0],
@@ -991,6 +1106,9 @@ int main(int argc, char **argv)
(double)errors_scrambling[2]/available_bits/round_trials[0],
(double)errors_scrambling[3]/available_bits/round_trials[0],
roundStats[snrRun],effRate,effRate/TBS*100,TBS);
+
+ dump_pusch_stats(gNB);
+
printf("*****************************************\n");
printf("\n");
@@ -998,8 +1116,10 @@ int main(int argc, char **argv)
printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
printStatIndent2(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
+ printStatIndent2(&gNB->ulsch_ptrs_processing_stats,"ULSCH PTRS Processing time");
printStatIndent2(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
printStatIndent2(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
+ printStatIndent2(&gNB->ulsch_mrc_stats,"ULSCH mrc computation");
printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
@@ -1008,17 +1128,17 @@ int main(int argc, char **argv)
printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
printf("\n");
}
-
+
if(n_trials==1)
break;
-
+
if ((float)n_errors[0]/(float)n_trials <= target_error_rate) {
printf("*************\n");
printf("PUSCH test OK\n");
printf("*************\n");
break;
}
-
+
snrRun++;
n_errs = n_errors[0];
} // SNR loop
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c
index a93f0d48f3..cc8c62a36d 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c
@@ -115,6 +115,11 @@ int ue_query_mch(module_id_t Mod_id, uint8_t CC_id, uint32_t frame,
sub_frame_t subframe, uint8_t eNB_index,
uint8_t * sync_area, uint8_t * mcch_active){ return(0);}
+
+int ue_query_mch_fembms(module_id_t Mod_id, uint8_t CC_id, uint32_t frame,
+ sub_frame_t subframe, uint8_t eNB_index,
+ uint8_t * sync_area, uint8_t * mcch_active){ return(0);}
+
void dl_phy_sync_success(module_id_t module_idP,
frame_t frameP,
unsigned char eNB_index, uint8_t first_sync){}
diff --git a/openair1/SIMULATION/TOOLS/phase_noise.c b/openair1/SIMULATION/TOOLS/phase_noise.c
new file mode 100644
index 0000000000..f243a09c59
--- /dev/null
+++ b/openair1/SIMULATION/TOOLS/phase_noise.c
@@ -0,0 +1,42 @@
+/*
+ * 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.1 (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
+#include
+#include
+#include
+#include "sim.h"
+
+
+/* linear phase noise model */
+void phase_noise(double ts, int16_t * InRe, int16_t * InIm)
+{
+ double fd = 300;//0.01*30000
+ static double i=0;
+ double real, imag,x ,y;
+ i++;
+ real = cos(fd * 2 * M_PI * i * ts);
+ imag = sin (fd * 2 * M_PI * i * ts);
+ x = ((real * (double)InRe[0]) - (imag * (double)InIm[0])) ;
+ y= ((real * (double)InIm[0]) + (imag * (double)InRe[0])) ;
+ InRe[0]= (int16_t)(x);
+ InIm[0]= (int16_t)(y);
+}
diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h
index 2f5ab99b41..d2684b15c1 100644
--- a/openair1/SIMULATION/TOOLS/sim.h
+++ b/openair1/SIMULATION/TOOLS/sim.h
@@ -460,6 +460,14 @@ void init_channelmod(void) ;
double N_RB2sampling_rate(uint16_t N_RB);
double N_RB2channel_bandwidth(uint16_t N_RB);
+/* Linear phase noise model */
+/*!
+ \brief This function produce phase noise and add to input signal
+ \param ts Sampling time
+ \param *Re *Im Real and Imag part of the signal
+*/
+void phase_noise(double ts, int16_t * InRe, int16_t * InIm);
+
#include "targets/RT/USER/rfsim.h"
void do_DL_sig(sim_t *sim,
diff --git a/openair2/COMMON/m2ap_messages_def.h b/openair2/COMMON/m2ap_messages_def.h
index adad70c9cc..743ca126fb 100644
--- a/openair2/COMMON/m2ap_messages_def.h
+++ b/openair2/COMMON/m2ap_messages_def.h
@@ -50,6 +50,7 @@ MESSAGE_DEF(M2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, m2ap_der
/* M2AP -> SCTP */
MESSAGE_DEF(M2AP_MCE_SCTP_REQ , MESSAGE_PRIORITY_MED, m2ap_mce_sctp_req_t , m2ap_mce_sctp_req)
+MESSAGE_DEF(M2AP_ENB_SCTP_REQ , MESSAGE_PRIORITY_MED, m2ap_enb_sctp_req_t , m2ap_enb_sctp_req)
//MESSAGE_DEF(M2AP_ENB_SCTP_REQ , MESSAGE_PRIORITY_MED, m2ap_enb_setup_req_t , f1ap_enb_setup_req)
/* eNB_DU application layer -> M2AP messages or CU M2AP -> RRC*/
diff --git a/openair2/COMMON/m2ap_messages_types.h b/openair2/COMMON/m2ap_messages_types.h
index 501414f296..c70c50fc64 100644
--- a/openair2/COMMON/m2ap_messages_types.h
+++ b/openair2/COMMON/m2ap_messages_types.h
@@ -480,7 +480,7 @@ typedef struct m2ap_mbms_scheduling_information_s {
uint8_t common_sf_allocation_period;
uint8_t mbms_area_id;
struct{
- uint8_t allocated_sf_end;
+ uint16_t allocated_sf_end;
uint8_t data_mcs;
uint8_t mch_scheduling_period;
struct{
@@ -533,6 +533,15 @@ typedef struct m2ap_mce_sctp_req_s {
uint32_t mce_port_for_M2C;
}m2ap_mce_sctp_req_t;
+typedef struct m2ap_enb_sctp_req_s {
+ /* The local MCE IP address to bind */
+ net_ip_address_t enb_m2_ip_address;
+
+ /* eNB port for M2C*/
+ uint32_t enb_port_for_M2C;
+}m2ap_enb_sctp_req_t;
+
+
typedef struct m2ap_mbms_scheduling_information_resp_s {
} m2ap_mbms_scheduling_information_resp_t;
typedef struct m2ap_session_start_req_s {
diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h
index 4ed928416b..af364437b8 100644
--- a/openair2/COMMON/platform_constants.h
+++ b/openair2/COMMON/platform_constants.h
@@ -101,6 +101,7 @@
#define NUMBER_OF_NR_DLSCH_MAX 2//16
#define NUMBER_OF_NR_ULSCH_MAX 2//16
+#define NUMBER_OF_NR_SCH_STATS_MAX 16
#define NUMBER_OF_NR_PUCCH_MAX 16
#define NUMBER_OF_NR_SR_MAX 16
#define NUMBER_OF_NR_PDCCH_MAX 16
diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c
index 7c91e57813..1d001022d2 100644
--- a/openair2/ENB_APP/enb_app.c
+++ b/openair2/ENB_APP/enb_app.c
@@ -214,7 +214,7 @@ void *eNB_app_task(void *args_p) {
long x2_enb_register_retry_timer_id;
uint32_t m2_register_enb_pending = 0;
uint32_t m2_registered_enb = 0;
- long m2_enb_register_retry_timer_id;
+ //long m2_enb_register_retry_timer_id;
MessageDef *msg_p = NULL;
instance_t instance;
int result;
@@ -236,16 +236,11 @@ void *eNB_app_task(void *args_p) {
/* Try to register each eNB with MCE each other */
if (is_m2ap_eNB_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) {
//eNB_app_register_MBMS_STA(RC.rrc[0]->node_type, enb_id_start, enb_id_end);
- //m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end);
+ m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end);
- if (timer_setup (5, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
- NULL, &m2_enb_register_retry_timer_id) < 0) {
- //LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n");
- //sleep(ENB_REGISTER_RETRY_DELAY);
- /* Restart the registration process */
- //registered_enb = 0;
- //register_enb_pending = eNB_app_register (RC.rrc[0]->node_type,enb_id_start, enb_id_end);
- }
+ //if (timer_setup (5, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
+ // NULL, &m2_enb_register_retry_timer_id) < 0) {
+ //}
}
@@ -376,11 +371,11 @@ void *eNB_app_task(void *args_p) {
}
} /* if (EPC_MODE_ENABLED) */
- if(TIMER_HAS_EXPIRED (msg_p).timer_id == m2_enb_register_retry_timer_id) {
-
- LOG_I(ENB_APP, " Received %s: timer_id %ld M2 register\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id);
- m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end);
- }
+// if(TIMER_HAS_EXPIRED (msg_p).timer_id == m2_enb_register_retry_timer_id) {
+//
+// LOG_I(ENB_APP, " Received %s: timer_id %ld M2 register\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id);
+// m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end);
+// }
break;
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 1d189832b4..4c6a7885c3 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -3052,7 +3052,8 @@ void configure_du_mac(int inst) {
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
}
diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
index fb9450728b..6953588818 100644
--- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
@@ -306,7 +306,8 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
break;
} // case
@@ -480,7 +481,8 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
}
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 49949bd771..781347abaa 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -660,7 +660,7 @@ config_sib2_mbsfn_part( int Mod_idP,
if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 0;
phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
- LOG_I (MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]);
+ LOG_I (MAC, "[CONFIG] MBSFN_SubframeConfig[%d] oneFrame pattern is %d\n", i, phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]);
} else if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 1;
phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] =
@@ -668,7 +668,7 @@ config_sib2_mbsfn_part( int Mod_idP,
(mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
(mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
- LOG_I(MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i,
+ LOG_I(MAC, "[CONFIG] MBSFN_SubframeConfig[%d] fourFrame pattern is %x\n", i,
phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]);
}
}
@@ -777,7 +777,8 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
LTE_SchedulingInfo_MBMS_r14_t *schedulingInfo_fembms,
struct LTE_NonMBSFN_SubframeConfig_r14 *nonMBSFN_SubframeConfig,
LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_mbms_r14_fembms,
- LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList_fembms
+ LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList_fembms,
+ LTE_MBSFNAreaConfiguration_r9_t*mbms_AreaConfig
) {
int i;
int UE_id = -1;
@@ -989,6 +990,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
cfg->num_tlv++;
//We need to reuse current MCH scheduler
//TOCHECK whether we can simply reuse current mbsfn_SubframeConfig stuff
+ RC.mac[Mod_idP]->common_channels[0].FeMBMS_flag = FeMBMS_Flag;
}
if (mbsfn_AreaInfoList != NULL) {
@@ -1005,6 +1007,21 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
}
}
+ if(mbms_AreaConfig != NULL) {
+ RC.mac[Mod_idP]->common_channels[0].commonSF_AllocPeriod_r9 = mbms_AreaConfig->commonSF_AllocPeriod_r9;
+ LOG_I(MAC, "[eNB %d][CONFIG] LTE_MBSFNAreaConfiguration_r9_t(%p) commonSF_AllocPeriod_r9(%d)\n",Mod_idP,mbms_AreaConfig, RC.mac[Mod_idP]->common_channels[0].commonSF_AllocPeriod_r9);
+ for(i=0; i < mbms_AreaConfig->commonSF_Alloc_r9.list.count; i++){
+ RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = mbms_AreaConfig->commonSF_Alloc_r9.list.array[i];
+ LOG_I(RRC,"[eNB %d][CONFIG] MBSFNArea[%d] commonSF_Alloc_r9: radioframeAllocationPeriod(%ldn),radioframeAllocationOffset(%ld), subframeAllocation(%x,%x,%x)\n"
+ ,Mod_idP,i
+ ,RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationPeriod
+ ,RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationOffset
+ ,RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]
+ ,RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]
+ ,RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[2]);
+ }
+ }
+
if (pmch_InfoList != NULL) {
// LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9));
LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n",
diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c
index 897afbf62b..1c5e706218 100644
--- a/openair2/LAYER2/MAC/config_ue.c
+++ b/openair2/LAYER2/MAC/config_ue.c
@@ -530,6 +530,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
LOG_I(MAC, "[UE %d] Configuring LTE_NonMBSFN \n",
Mod_idP);
phy_config_sib1_fembms_ue(Mod_idP, CC_idP, 0, nonMBSFN_SubframeConfig);
+ UE_mac_inst[Mod_idP].non_mbsfn_SubframeConfig = nonMBSFN_SubframeConfig;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index d184c7e439..8f5aab99a7 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -921,6 +921,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
#endif
+ int do_fembms_si=0;
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
if (cc[CC_id].MBMS_flag > 0) {
start_meas(&RC.mac[module_idP]->schedule_mch);
@@ -931,6 +932,10 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
stop_meas(&RC.mac[module_idP]->schedule_mch);
}
+ if (cc[CC_id].FeMBMS_flag > 0) {
+ do_fembms_si = 1;
+ }
+
}
static int debug_flag = 0;
@@ -952,12 +957,22 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
/* This schedules MIB */
- if ((subframeP == 0) && (frameP & 3) == 0)
- schedule_mib(module_idP, frameP, subframeP);
+ if(!do_fembms_si/*get_softmodem_params()->fembms*/){
+ if ((subframeP == 0) && (frameP & 3) == 0)
+ schedule_mib(module_idP, frameP, subframeP);
+ }else{
+ if ((subframeP == 0) && (frameP & 15) == 0 ){
+ schedule_fembms_mib(module_idP, frameP, subframeP);
+ //schedule_SI_MBMS(module_idP, frameP, subframeP);
+ }
+ }
if (get_softmodem_params()->phy_test == 0) {
/* This schedules SI for legacy LTE and eMTC starting in subframeP */
- schedule_SI(module_idP, frameP, subframeP);
+ if(!do_fembms_si/*get_softmodem_params()->fembms*/)
+ schedule_SI(module_idP, frameP, subframeP);
+ else
+ schedule_SI_MBMS(module_idP, frameP, subframeP);
/* This schedules Paging in subframeP */
schedule_PCH(module_idP,frameP,subframeP);
/* This schedules Random-Access for legacy LTE and eMTC starting in subframeP */
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
index 5b99578d57..e4b9a7a65b 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
@@ -731,6 +731,7 @@ schedule_SI_MBMS(module_id_t module_idP, frame_t frameP,
if (subframeP == 0) {
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
cc = &eNB->common_channels[CC_id];
+ //printf("*cc->sib1_MBMS->si_WindowLength_r14 %d \n", *cc->sib1_MBMS->si_WindowLength_r14);
vrb_map = (void *) &cc->vrb_map;
N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
dl_config_request = &eNB->DL_req[CC_id];
@@ -911,6 +912,64 @@ schedule_SI_MBMS(module_id_t module_idP, frame_t frameP,
stop_meas(&eNB->schedule_si_mbms);
}
+void
+schedule_fembms_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
+ eNB_MAC_INST *eNB = RC.mac[module_idP];
+ COMMON_channels_t *cc;
+ nfapi_dl_config_request_pdu_t *dl_config_pdu;
+ nfapi_tx_request_pdu_t *TX_req;
+ int mib_sdu_length;
+ int CC_id;
+ nfapi_dl_config_request_t *dl_config_request;
+ nfapi_dl_config_request_body_t *dl_req;
+ uint16_t sfn_sf = frameP << 4 | subframeP;
+ AssertFatal(subframeP == 0, "Subframe must be 0\n");
+ AssertFatal((frameP & 15) == 0, "Frame must be a multiple of 16\n");
+
+ for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+ dl_config_request = &eNB->DL_req[CC_id];
+ dl_req = &dl_config_request->dl_config_request_body;
+ cc = &eNB->common_channels[CC_id];
+ mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH_MBMS, 0xFFFF, 1, &cc->MIB_pdu.payload[0], 0); // not used in this case
+ LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n", frameP, subframeP, mib_sdu_length);
+
+ if (mib_sdu_length > 0) {
+ LOG_D(MAC, "Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP, subframeP, dl_req->number_pdu, mib_sdu_length);
+
+ if ((frameP & 1023) < 40)
+ LOG_D(MAC,
+ "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n",
+ module_idP, frameP, CC_id, mib_sdu_length,
+ (int) cc->mib->message.schedulingInfoSIB1_BR_r13);
+
+ dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
+ memset((void *) dl_config_pdu, 0,
+ sizeof(nfapi_dl_config_request_pdu_t));
+ dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size =
+ 2 + sizeof(nfapi_dl_config_bch_pdu);
+ dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG;
+ dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length;
+ dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id];
+ dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000;
+ dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+ dl_req->number_pdu++;
+ dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST;
+ dl_config_request->sfn_sf = sfn_sf;
+ LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n", dl_req->number_pdu, &dl_req->number_pdu);
+ // DL request
+ TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus];
+ TX_req->pdu_length = 3;
+ TX_req->pdu_index = eNB->pdu_index[CC_id]++;
+ TX_req->num_segments = 1;
+ TX_req->segments[0].segment_length = 3;
+ TX_req->segments[0].segment_data = cc[CC_id].MIB_pdu.payload;
+ eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
+ eNB->TX_req[CC_id].sfn_sf = sfn_sf;
+ eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
+ eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
+ }
+ }
+}
void
schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
index eb5d78fd3f..0c686a6475 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
@@ -66,7 +66,11 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id,
"[eNB %d] CC_id %d MBSFN synchronization area %d out of range\n ",
module_idP, CC_id, mbsfn_sync_area);
return -1;
- } else if (RC.mac[module_idP]->
+ }else if (RC.mac[module_idP]->
+ common_channels[CC_id].non_mbsfn_SubframeConfig
+ != NULL) {
+ return mbsfn_sync_area;
+ }else if (RC.mac[module_idP]->
common_channels[CC_id].mbsfn_SubframeConfig[mbsfn_sync_area]
!= NULL) {
return mbsfn_sync_area;
@@ -80,14 +84,30 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id,
static uint32_t bytes_in_buffer=0;
static uint32_t msi_pmch_stop=0;
-//static uint8_t msi_active=0;
-//static uint8_t msi_pmch_stop2=0;
-uint16_t mbms_rab_id = 2047;
+uint16_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047};
static uint32_t msi_sfs=0;
//MSI_ELEMENT * ptr =NULL;
+static int check_CAS_sf(frame_t frameP,sub_frame_t subframeP){
+ if( ((frameP&3)==0) && (subframeP == 0))
+ return 1;
+ else
+ return 0;
+}
+static int check_nonMBSFN_sf(frame_t frameP,COMMON_channels_t *cc,int sf){
+ uint32_t non_mbsfn_SubframeConfig = (cc->non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | cc->non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]>>7);
+ if( frameP % (4<non_mbsfn_SubframeConfig->radioFrameAllocationPeriod_r14) == cc->non_mbsfn_SubframeConfig->radioFrameAllocationOffset_r14 ){
+ return (non_mbsfn_SubframeConfig & (0x200>>(sf)))==(0x200 >> (sf));
+ }
+ return 0;
+}
+
+
+static int x=0;
+static int mbms_mch_i=0;
+
int
schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
sub_frame_t subframeP)
@@ -99,29 +119,28 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
int mcch_flag = 0, mtch_flag = 0, msi_flag = 0;
int mbsfn_period = 0; // 1<<(RC.mac[module_idP]->mbsfn_SubframeConfig[0]->radioframeAllocationPeriod);
int mcch_period = 0; //32<<(RC.mac[module_idP]->mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
+ //TOCHECK mtch index here
if(RC.mac[module_idP]->common_channels[CC_id].
pmch_Config[0] == NULL )
-
return 0;
-
-
-
+ //TOCHECK mtch index here
int mch_scheduling_period =
8 << (RC.mac[module_idP]->common_channels[CC_id].
pmch_Config[0]->mch_SchedulingPeriod_r9);
+
unsigned char mcch_sdu_length;
unsigned char header_len_mcch = 0, header_len_msi =
0, header_len_mtch = 0, header_len_mtch_temp =
0, header_len_mcch_temp = 0, header_len_msi_temp = 0;
- int ii = 0, msi_pos = 0;
+ int ii = 0, msi_pos = -1;
int mcch_mcs = -1;
+ int shifted_sf = 0;
uint16_t TBS, j = -1, padding = 0, post_padding = 0;
mac_rlc_status_resp_t rlc_status;
- //mac_rlc_status_resp_t rlc_status2;
- int num_mtch;
+ int num_mtch=0;
int msi_length=0, i, k;
- //uint8_t l =0;
+
unsigned char sdu_lcids[11], num_sdus = 0, offset = 0;
uint16_t sdu_lengths[11], sdu_length_total = 0;
unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only
@@ -136,358 +155,535 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
return 0;
}
- mbsfn_period =
- 1 << (cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod);
- mcch_period =
- 32 << (cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_RepetitionPeriod_r9);
- msi_pos = 0;
- ii = 0;
- LOG_D(MAC,
- "[eNB %d] CC_id %d Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n",
- module_idP, CC_id, frameP, subframeP, i,
- cc->num_active_mbsfn_area, j, cc->num_sf_allocation_pattern,
- mbsfn_period, mcch_period);
+ if(cc->non_mbsfn_SubframeConfig){
+ int alloc_offset=0;
+ uint32_t period;
+ uint32_t non_mbsfn_SubframeConfig = (cc->non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | cc->non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]>>7);
+ long mcch_offset = cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9;
- switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) {
- case 0:
- mcch_mcs = 2;
- break;
+ period = 4<non_mbsfn_SubframeConfig->radioFrameAllocationPeriod_r14;
+ alloc_offset = cc->non_mbsfn_SubframeConfig->radioFrameAllocationOffset_r14;
+ mcch_period = 32 << cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9;
+
+ // get the real MCS value
+ switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) {
+ case 0:
+ mcch_mcs = 2;
+ break;
- case 1:
- mcch_mcs = 7;
- break;
+ case 1:
+ mcch_mcs = 7;
+ break;
- case 2:
- mcch_mcs = 13;
- break;
+ case 2:
+ mcch_mcs = 13;
+ break;
- case 3:
- mcch_mcs = 19;
- break;
- }
+ case 3:
+ mcch_mcs = 19;
+ break;
+ }
+
+ if (cc->pmch_Config[0]) {
+ mch_scheduling_period = 8 << cc->pmch_Config[0]->mch_SchedulingPeriod_r9;
+ }
- // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist)
- if (frameP % mbsfn_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP
- if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format
-
- // Find the first subframeP in this MCH to transmit MSI
- if (frameP % mch_scheduling_period ==
- cc->mbsfn_SubframeConfig[j]->
- radioframeAllocationOffset) {
- while (ii == 0) {
- ii = cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & (0x80 >> msi_pos);
+ LOG_D(MAC,"frameP %d subframe %d period %d alloc_offset %d mcch_mcs %d mcch_period %d mcch_offset %ld buf %x mch_scheduling_period %d\n",frameP, subframeP, period, alloc_offset,mcch_mcs, mcch_period, mcch_offset,(cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0]),mch_scheduling_period);
+ //if( (frameP % (4 << cc->commonSF_AllocPeriod_r9) ) == 0 ){
+ // if((subframeP==0)){
+ // x=0;
+ // mbms_mch_i=0;
+ // }
+ //}
+ //if (frameP % (4 << cc->commonSF_AllocPeriod_r9 ) == 0) {
+ // if((subframeP==0)){
+ // x=0;
+ // mbms_mch_i=0;
+ // }
+ //}
+ if (cc->pmch_Config[0]) {
+ // Find the first subframe in this MCH to transmit MSI
+ if (frameP % 1 == 0) {
+ if (frameP % mch_scheduling_period == 0) {
+ msi_pos=0;
+ if((frameP&3)==0)
msi_pos++;
- }
+ while((non_mbsfn_SubframeConfig & (0x100 >> msi_pos)) == (0x100>>msi_pos))
+ msi_pos++;
+ mbms_mch_i=0;
- LOG_D(MAC,
- "[eNB %d] CC_id %d Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n",
- module_idP, CC_id, frameP, subframeP, i, j,
- cc->mbsfn_SubframeConfig[j]->
- subframeAllocation.choice.oneFrame.buf[0],
- msi_pos);
+ if((subframeP==0)){
+ x=0;
+ mbms_mch_i=0;
+ }
+
}
- // Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
- switch (subframeP) {
- case 1:
- if (cc->tdd_Config == NULL) {
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_FDD_SF1) ==
- MBSFN_FDD_SF1) {
- if (msi_pos == 1) {
- msi_flag = 1;
- }
+ }
+ }
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_FDD_SF1) ==
- MBSFN_FDD_SF1)) {
- mcch_flag = 1;
- }
+ if(cc->pmch_Config[mbms_mch_i+1]!=NULL){
+ if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9+shifted_sf){
- mtch_flag = 1;
- }
- }
-
- break;
-
- case 2:
- if (cc->tdd_Config == NULL) {
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_FDD_SF2) ==
- MBSFN_FDD_SF2) {
- if (msi_pos == 2) {
- msi_flag = 1;
- }
-
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_FDD_SF2) ==
- MBSFN_FDD_SF2)) {
- mcch_flag = 1;
- }
-
- mtch_flag = 1;
- }
- }
-
- break;
-
- case 3:
- if (cc->tdd_Config != NULL) { // TDD
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_TDD_SF3) ==
- MBSFN_TDD_SF3) {
- if (msi_pos == 1) {
- msi_flag = 1;
- }
-
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_TDD_SF3) ==
- MBSFN_TDD_SF3)) {
- mcch_flag = 1;
- }
-
- mtch_flag = 1;
- }
- } else { // FDD
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_FDD_SF3) ==
- MBSFN_FDD_SF3) {
- if (msi_pos == 3) {
- msi_flag = 1;
- }
-
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_FDD_SF3) ==
- MBSFN_FDD_SF3)) {
- mcch_flag = 1;
- }
-
- mtch_flag = 1;
- }
- }
-
- break;
-
- case 4:
- if (cc->tdd_Config != NULL) {
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_TDD_SF4) ==
- MBSFN_TDD_SF4) {
- if (msi_pos == 2) {
- msi_flag = 1;
- }
-
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_TDD_SF4) ==
- MBSFN_TDD_SF4)) {
- mcch_flag = 1;
- }
-
- mtch_flag = 1;
- }
- }
-
- break;
-
- case 6:
- if (cc->tdd_Config == NULL) {
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_FDD_SF6) ==
- MBSFN_FDD_SF6) {
- if (msi_pos == 4) {
- msi_flag = 1;
- }
-
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_FDD_SF6) ==
- MBSFN_FDD_SF6)) {
- mcch_flag = 1;
- }
-
- mtch_flag = 1;
- }
- }
-
- break;
-
- case 7:
- if (cc->tdd_Config != NULL) { // TDD
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_TDD_SF7) ==
- MBSFN_TDD_SF7) {
- if (msi_pos == 3) {
- msi_flag = 1;
- }
-
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_TDD_SF7) ==
- MBSFN_TDD_SF7)) {
- mcch_flag = 1;
- }
-
- mtch_flag = 1;
- }
- } else { // FDD
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_FDD_SF7) ==
- MBSFN_FDD_SF7) {
- if (msi_pos == 5) {
- msi_flag = 1;
- }
-
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_FDD_SF7) ==
- MBSFN_FDD_SF7)) {
- mcch_flag = 1;
- }
-
- mtch_flag = 1;
- }
- }
-
- break;
-
- case 8:
- if (cc->tdd_Config != NULL) { //TDD
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_TDD_SF8) ==
- MBSFN_TDD_SF8) {
- if (msi_pos == 4) {
- msi_flag = 1;
- }
-
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_TDD_SF8) ==
- MBSFN_TDD_SF8)) {
- mcch_flag = 1;
- }
-
- mtch_flag = 1;
- }
- } else { // FDD
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_FDD_SF8) ==
- MBSFN_FDD_SF8) {
- if (msi_pos == 6) {
- msi_flag = 1;
- }
-
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_FDD_SF8) ==
- MBSFN_FDD_SF8)) {
- mcch_flag = 1;
- }
-
- mtch_flag = 1;
- }
- }
-
- break;
-
- case 9:
- if (cc->tdd_Config != NULL) {
- if ((cc->
- mbsfn_SubframeConfig[j]->subframeAllocation.
- choice.oneFrame.buf[0] & MBSFN_TDD_SF9) ==
- MBSFN_TDD_SF9) {
- if (msi_pos == 5) {
- msi_flag = 1;
- }
-
- if ((frameP % mcch_period ==
- cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.mcch_Offset_r9)
- &&
- ((cc->mbsfn_AreaInfo[i]->
- mcch_Config_r9.sf_AllocInfo_r9.
- buf[0] & MBSFN_TDD_SF9) ==
- MBSFN_TDD_SF9)) {
- mcch_flag = 1;
- }
-
- mtch_flag = 1;
- }
- }
-
- break;
- } // end switch
-
- // sf allocation is non-overlapping
- if ((msi_flag == 1) || (mcch_flag == 1)
- || (mtch_flag == 1)) {
- LOG_D(MAC,
- "[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
- module_idP, CC_id, frameP, subframeP, i, j,
- msi_flag, mcch_flag, mtch_flag);
- break;
+ shifted_sf = check_nonMBSFN_sf(frameP,cc,subframeP)+check_CAS_sf(frameP,subframeP);
+ msi_pos=subframeP+shifted_sf;
+ if(shifted_sf==0)
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d shifted_sf %d\n",frameP, subframeP, msi_pos,mbms_mch_i,shifted_sf);
}
- } else { // four-frameP format
}
- }
- } // end of for loop
+
+ // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
+ switch (subframeP) {
+ case 0:
+ if (msi_pos == 0) {
+ msi_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+ case 1:
+ if (msi_pos == 1) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+
+ case 2:
+ if (msi_pos == 2) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+
+ break;
+
+ case 3:
+ if (msi_pos == 3) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+
+ case 4:
+ if (msi_pos == 4) {
+ msi_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+
+ case 5:
+ if (msi_pos == 5) {
+ msi_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+
+ case 6:
+ if (msi_pos == 6) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+
+ case 7:
+ if (msi_pos == 7) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+
+ case 8:
+ if (msi_pos == 8) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+
+ case 9:
+ if (msi_pos == 9) {
+ msi_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+ }// end switch
+
+ if ((msi_flag == 1) || (mcch_flag == 1) || (mtch_flag == 1)) {
+ LOG_D(MAC,
+ "[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
+ module_idP, CC_id, frameP, subframeP, i, j,
+ msi_flag, mcch_flag, mtch_flag);
+ }
+
+ //TODO quitar la subframe 0 del otro switch ... está mal interpretado ?
+ // if((frameP&3) == 0){
+ // mtch_flag=0;mcch_flag=0;msi_flag=0;
+ // }
+
+ if((frameP % period ) == alloc_offset){
+ LOG_D(MAC,"non_mbsfn_SubframeConfig %x\n",non_mbsfn_SubframeConfig);
+ switch(subframeP){
+ case 0:{
+ mtch_flag=0;mcch_flag=0;msi_flag=0;
+ }
+ break;
+ case 1:{
+ if ((non_mbsfn_SubframeConfig & 0x100) > 0)
+ {mtch_flag=0;mcch_flag=0;msi_flag=0;}
+ }
+ break;
+ case 2:{
+ if ((non_mbsfn_SubframeConfig & 0x80) > 0)
+ {mtch_flag=0;mcch_flag=0;msi_flag=0;}
+ }
+ break;
+ case 3:{
+ if ((non_mbsfn_SubframeConfig & 0x40) > 0)
+ {mtch_flag=0;mcch_flag=0;msi_flag=0;}
+ }
+ break;
+ case 4:{
+ if ((non_mbsfn_SubframeConfig & 0x20) > 0)
+ {mtch_flag=0;mcch_flag=0;msi_flag=0;}
+ }
+ break;
+ case 5:{
+ if ((non_mbsfn_SubframeConfig & 0x10) > 0)
+ {mtch_flag=0;mcch_flag=0;msi_flag=0;}
+ }
+ break;
+ case 6:{
+ if ((non_mbsfn_SubframeConfig & 0x8) > 0)
+ {mtch_flag=0;mcch_flag=0;msi_flag=0;}
+ }
+ break;
+ case 7:{
+ if ((non_mbsfn_SubframeConfig & 0x4) > 0)
+ {mtch_flag=0;mcch_flag=0;msi_flag=0;}
+ }
+ break;
+ case 8:{
+ if ((non_mbsfn_SubframeConfig & 0x2) > 0)
+ {mtch_flag=0;mcch_flag=0;msi_flag=0;}
+ }
+ break;
+ case 9:{
+ if ((non_mbsfn_SubframeConfig & 0x1) > 0)
+ {mtch_flag=0;mcch_flag=0;msi_flag=0;}
+ }
+ break;
+ }
+ }
+ // sf allocation is non-overlapping
+ if ((msi_flag == 1) || (mcch_flag == 1) || (mtch_flag == 1)) {
+ x++;
+ //if( (msi_flag!=1 && mcch_flag!=1) || (msi_flag!=1 && mcch_flag!=1 && mtch_flag!=1) ){
+ //x++;
+ //}
+
+ if(msi_flag==1){
+ if ( (/*AJ*/ (/*V*/ ( /*U*/ (frameP %( 4 << cc->commonSF_AllocPeriod_r9)) ) / 8 ) % ((8 << cc->pmch_Config[mbms_mch_i]->mch_SchedulingPeriod_r9) / 8 ) ) != 0 ){
+ msi_flag=0;
+ LOG_D(MAC,"frameP %d subframeP %d reset(%d)\n",frameP, subframeP, mbms_mch_i);
+ }
+
+ }
+
+ LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d, x %d\n",
+ module_idP, CC_id, frameP, subframeP, i, j,
+ msi_flag, mcch_flag, mtch_flag,x);
+ break;
+ }
+
+
+ }else if(cc->mbsfn_SubframeConfig[j]){
+
+ mbsfn_period =
+ 1 << (cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod);
+ mcch_period =
+ 32 << (cc->mbsfn_AreaInfo[i]->
+ mcch_Config_r9.mcch_RepetitionPeriod_r9);
+ msi_pos = 0;
+ ii = 0;
+ LOG_D(MAC, "[eNB %d] CC_id %d Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n",
+ module_idP, CC_id, frameP, subframeP, i,
+ cc->num_active_mbsfn_area, j, cc->num_sf_allocation_pattern,
+ mbsfn_period, mcch_period);
+
+ switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) {
+ case 0:
+ mcch_mcs = 2;
+ break;
+
+ case 1:
+ mcch_mcs = 7;
+ break;
+
+ case 2:
+ mcch_mcs = 13;
+ break;
+
+ case 3:
+ mcch_mcs = 19;
+ break;
+ }
+
+ // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist)
+ if (frameP % mbsfn_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP
+ if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format
+ // Find the first subframeP in this MCH to transmit MSI
+ if (frameP % mch_scheduling_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) {
+ while (ii == 0) {
+ ii = cc->
+ mbsfn_SubframeConfig[j]->subframeAllocation.
+ choice.oneFrame.buf[0] & (0x80 >> msi_pos);
+ msi_pos++;
+ }
+ LOG_D(MAC, "[eNB %d] CC_id %d Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n",
+ module_idP, CC_id, frameP, subframeP, i, j,
+ cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0],
+ msi_pos);
+ if((subframeP==1)){
+ x=0;
+ mbms_mch_i=0;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i);
+ }
+ }
+
+ // Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
+ switch (subframeP) {
+ case 1:
+ if (cc->tdd_Config == NULL) {
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
+ if(cc->pmch_Config[mbms_mch_i+1]!=NULL){
+ if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=1;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i);
+ }
+ }
+ if (msi_pos == 1) {
+ msi_flag = 1;
+ }
+ if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ && ( (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ }
+ break;
+ case 2:
+ if (cc->tdd_Config == NULL) {
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
+ if(cc->pmch_Config[mbms_mch_i+1]!=NULL){
+ if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=2;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i);
+ }
+ }
+
+ if (msi_pos == 2) {
+ msi_flag = 1;
+ }
+ if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ }
+ break;
+ case 3:
+ if (cc->tdd_Config != NULL) {
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) {
+ if (msi_pos == 1) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ } else { // FDD
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) {
+ if(cc->pmch_Config[mbms_mch_i+1]!=NULL){
+ if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=3;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i);
+ }
+ }
+ if (msi_pos == 3) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ }
+ break;
+ case 4:
+ if (cc->tdd_Config != NULL) {
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) {
+ if (msi_pos == 2) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ }
+ break;
+ case 6:
+ if (cc->tdd_Config == NULL) {
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) {
+ if(cc->pmch_Config[mbms_mch_i+1]!=NULL){
+ if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=4;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i);
+ }
+ }
+ if (msi_pos == 4) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ }
+ break;
+ case 7:
+ if (cc->tdd_Config != NULL) { // TDD
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) {
+ if (msi_pos == 3) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ } else { // FDD
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) {
+ if(cc->pmch_Config[mbms_mch_i+1]!=NULL){
+ if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=5;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i);
+ }
+ }
+
+ if (msi_pos == 5) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ }
+ break;
+ case 8:
+ if (cc->tdd_Config != NULL) { //TDD
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) {
+ if (msi_pos == 4) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ } else { // FDD
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) {
+ if(cc->pmch_Config[mbms_mch_i+1]!=NULL){
+ if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=6;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i);
+ }
+ }
+ if (msi_pos == 6) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ }
+ break;
+ case 9:
+ if (cc->tdd_Config != NULL) {
+ if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) {
+ if (msi_pos == 5) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9)
+ &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9)) {
+ mcch_flag = 1;
+ }
+ mtch_flag = 1;
+ }
+ }
+ break;
+ } // end switch
+ // sf allocation is non-overlapping
+ if ((msi_flag == 1) || (mcch_flag == 1) || (mtch_flag == 1)) {
+ x++;
+ //if( (msi_flag!=1 && mcch_flag!=1) || (msi_flag!=1 && mcch_flag!=1 && mtch_flag!=1) ){
+ //x++;
+ //}
+ if(msi_flag==1){
+ if ( (/*AJ*/ (/*V*/ ( /*U*/ (frameP %( 4 << cc->commonSF_AllocPeriod_r9)) ) / 8 ) % ((8 << cc->pmch_Config[mbms_mch_i]->mch_SchedulingPeriod_r9) / 8 ) ) != 0 ){
+ msi_flag=0;
+ LOG_D(MAC,"frameP %d subframeP %d reset(%d)\n",frameP, subframeP, mbms_mch_i);
+ }
+
+ }
+
+ LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d x %d\n",
+ module_idP, CC_id, frameP, subframeP, i, j,
+ msi_flag, mcch_flag, mtch_flag,x);
+ break;
+ }
+ } else {// four-frameP format
+ printf("Hola\n");
+ AssertFatal(1==0,"four-frameP format: not implemented yet\n");
+ }
+ }
+ } // MBMS format
+ }// end of for loop
cc->msi_active = 0;
cc->mcch_active = 0;
@@ -497,7 +693,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
if ((msi_flag == 1) || (mcch_flag == 1)) {
cc->MCH_pdu.mcs = mcch_mcs;
} else if (mtch_flag == 1) { // only MTCH in this subframeP
- cc->MCH_pdu.mcs = cc->pmch_Config[0]->dataMCS_r9;
+ cc->MCH_pdu.mcs = cc->pmch_Config[mbms_mch_i]->dataMCS_r9;
}
@@ -510,26 +706,14 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
// there is MSI (MCH Scheduling Info)
uint16_t msi_control_element[29], *msi_ptr;
+ // MSI buffer pointer
char *buffer_pointer=NULL;
if (msi_flag == 1) {
// Create MSI here
- //uint16_t msi_control_element[29], *msi_ptr;
-
msi_ptr = &msi_control_element[0];
- //((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH
-
- //if (mcch_flag == 1) {
- // ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0;
- // ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0;
- //} else { // no mcch for this MSP
- // ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // stop value is 2047
- // ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff;
- //}
-
- //msi_ptr += sizeof(MSI_ELEMENT);
//Header for MTCHs
- num_mtch = cc->mbms_SessionList[0]->list.count;
+ num_mtch = cc->mbms_SessionList[mbms_mch_i]->list.count;
TBS =
get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth));
@@ -537,7 +721,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment
- ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid;
+ ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[mbms_mch_i]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid;
if( msi_sfs != 0 )
msi_pmch_stop = msi_sfs-1;
@@ -546,22 +730,15 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
msi_pmch_stop = msi_sfs;
- //if( msi_pmch_stop > cc->pmch_Config[0]->sf_AllocEnd_r9)
- //LOG_W(MAC,"e-MBMS Buffer Overflow\n");
-
if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) {
- ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) & stop_sf limited to 256
- //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = msi_pmch_stop;
- ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9);
- msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9);
+ ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = (((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) >> 8) & 0x7f);
+ ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = ((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) & 0xff);
+ msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9);
}else{
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now)
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF;
msi_pmch_stop=0;
}
-
-
-
msi_ptr += sizeof(MSI_ELEMENT);
}
@@ -573,15 +750,11 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
header_len_msi = 3;
}
- LOG_D(MAC,
- "[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes TBS %d, bytes in buffer %d stop_sf_LSB %d msi_sfs %d cc->pmch_Config[0]->sf_AllocEnd_r9 %ld\n",
- module_idP, CC_id, frameP, msi_length,TBS, bytes_in_buffer,msi_pmch_stop,msi_sfs,cc->pmch_Config[0]->sf_AllocEnd_r9);
+ LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes TBS %d, bytes in buffer %d stop_sf_LSB %d msi_sfs %d cc->pmch_Config[0]->sf_AllocEnd_r9 %ld\n",
+ module_idP, CC_id, frameP, msi_length,TBS, bytes_in_buffer,msi_pmch_stop,msi_sfs,cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9);
msi_sfs = 0;
- //LOG_D(MAC,"Scheduler: MSI is transmitted in this subframeP \n" );
-
- // LOG_D(MAC,"Scheduler: MSI length is %d bytes\n",msi_length);
// Store MSI data to mch_buffer[0]
memcpy((char *) &mch_buffer[sdu_length_total],
msi_control_element, msi_length);
@@ -598,75 +771,93 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
}
// there is MCCH
if (mcch_flag == 1) {
+ //MCCH scheduling if !FeMBMS
+ if(!cc->non_mbsfn_SubframeConfig){
+ mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH_COUNTING, 0xFFFC, 1, &cc->MCCH_pdu.payload[0],
+ i); // this is the mbsfn sync area index
+ if(mcch_sdu_length>0)
+ LOG_I(MAC, "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE COUNTING (area %d, sfAlloc %d)\n",
+ module_idP, CC_id, frameP, subframeP, i, j);
- //LOG_E(MAC,
- //"[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE COUNTING (mod %d)\n",module_idP, CC_id, frameP, subframeP,frameP%2==0);
- if(1/*frameP%2==0*/){
- LOG_D(MAC,
- "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n",
- module_idP, CC_id, frameP, subframeP, i, j);
+ if (mcch_sdu_length > 0) {
+ mcch_sdu_length+=1; //RLC ?
+ LOG_D(MAC, "[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n",
+ module_idP, CC_id, frameP, subframeP, mcch_sdu_length);
- mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 0xFFFC, 1, &cc->MCCH_pdu.payload[0],
- i); // this is the mbsfn sync area index
- }
- else{
- LOG_E(MAC,
- "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE COUNTING (area %d, sfAlloc %d)\n",
- module_idP, CC_id, frameP, subframeP, i, j);
+ header_len_mcch = 2;
-//
-// mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH_COUNTING, 0xFFFC, 1, &cc->MCCH_pdu.payload[0],
-// i); // this is the mbsfn sync area index
+ if (cc->tdd_Config != NULL) {
+ LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n",
+ module_idP, CC_id, frameP, subframeP,
+ mcch_sdu_length, mcch_mcs);
+ } else {
+ LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n",
+ module_idP, CC_id, frameP, subframeP,
+ mcch_sdu_length, mcch_mcs);
+ }
+
+ cc->mcch_active = 1;
+
+ memcpy((char *) &mch_buffer[sdu_length_total]+1,
+ &cc->MCCH_pdu.payload[0], mcch_sdu_length);
+ sdu_lcids[num_sdus] = MCCH_LCHANID;
+ sdu_lengths[num_sdus] = mcch_sdu_length;
+
+ if (sdu_lengths[num_sdus] > 128) {
+ header_len_mcch = 3;
+ }
+
+ sdu_length_total += sdu_lengths[num_sdus];
+ LOG_D(MAC,
+ "[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n",
+ module_idP, CC_id, sdu_lengths[num_sdus]);
+ num_sdus++;
+ }
}
- mcch_sdu_length+=1; //RLC ?
+ //MCCH scheduling ... do it anyway
+ {
+ LOG_I(MAC, "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n",
+ module_idP, CC_id, frameP, subframeP, i, j);
- if (mcch_sdu_length > 0) {
- LOG_D(MAC,
- "[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n",
- module_idP, CC_id, frameP, subframeP, mcch_sdu_length);
+ mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 0xFFFC, 1, &cc->MCCH_pdu.payload[0],
+ i); // this is the mbsfn sync area index
- header_len_mcch = 2;
+ if (mcch_sdu_length > 0) {
+ mcch_sdu_length+=1; //RLC ?
+ LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n",
+ module_idP, CC_id, frameP, subframeP, mcch_sdu_length);
- if (cc->tdd_Config != NULL) {
- LOG_D(MAC,
- "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n",
- module_idP, CC_id, frameP, subframeP,
- mcch_sdu_length, mcch_mcs);
- } else {
- LOG_D(MAC,
- "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n",
- module_idP, CC_id, frameP, subframeP,
- mcch_sdu_length, mcch_mcs);
+ header_len_mcch = 2;
+
+ if (cc->tdd_Config != NULL) {
+ LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n",
+ module_idP, CC_id, frameP, subframeP,
+ mcch_sdu_length, mcch_mcs);
+ } else {
+ LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n",
+ module_idP, CC_id, frameP, subframeP,
+ mcch_sdu_length, mcch_mcs);
+ }
+
+ cc->mcch_active = 1;
+
+ memcpy((char *) &mch_buffer[sdu_length_total]+1,
+ &cc->MCCH_pdu.payload[0], mcch_sdu_length);
+ sdu_lcids[num_sdus] = MCCH_LCHANID;
+ sdu_lengths[num_sdus] = mcch_sdu_length;
+
+ if (sdu_lengths[num_sdus] > 128) {
+ header_len_mcch = 3;
+ }
+
+ sdu_length_total += sdu_lengths[num_sdus];
+ LOG_D(MAC,"[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n",
+ module_idP, CC_id, sdu_lengths[num_sdus]);
+ num_sdus++;
}
-
- cc->mcch_active = 1;
-
- memcpy((char *) &mch_buffer[sdu_length_total]+1,
- &cc->MCCH_pdu.payload[0], mcch_sdu_length);
- sdu_lcids[num_sdus] = MCCH_LCHANID;
- sdu_lengths[num_sdus] = mcch_sdu_length;
-
- // LOG_W(MAC,"MCCH RLC %x:",(unsigned char)mch_buffer[sdu_length_total]);
- // for (int kk = 7; kk >= 0; kk--)
- // {
- // printf("%d",(((unsigned char)mch_buffer[sdu_length_total]) >> kk) & 1 ? '1' : '0');
- // }
- // printf("\n");
- //mch_buffer[sdu_length_total] = (unsigned char)0;
-
-
- if (sdu_lengths[num_sdus] > 128) {
- header_len_mcch = 3;
- }
-
- sdu_length_total += sdu_lengths[num_sdus];
- LOG_D(MAC,
- "[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n",
- module_idP, CC_id, sdu_lengths[num_sdus]);
- num_sdus++;
}
- }
+ }// mcch_flag
TBS =
@@ -678,154 +869,108 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
// there is MTCHs, loop if there are more than 1
if (mtch_flag == 1 ) {
// Calculate TBS
- /* if ((msi_flag==1) || (mcch_flag==1)) {
- TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->frame_parms->N_RB_DL);
- }
- else { // only MTCH in this subframeP
- TBS = mac_xface->get_TBS(RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9, mac_xface->frame_parms->N_RB_DL);
- }
-
- // get MTCH data from RLC (like for DTCH)
- LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframe %d: Schedule MTCH (area %d, sfAlloc %d)\n",Mod_id,CC_id,frame,subframe,i,j);
-
- header_len_mtch = 3;
- LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
- Mod_id,CC_id,frame,MTCH,TBS,
- TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
-
- rlc_status = mac_rlc_status_ind(Mod_id,frame,1,RLC_MBMS_YES,MTCH+ (maxDRB + 3) * MAX_MOBILES_PER_RG,
- TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
- printf("frame %d, subframe %d, rlc_status.bytes_in_buffer is %d\n",frame,subframe, rlc_status.bytes_in_buffer);
-
- */
-
// get MTCH data from RLC (like for DTCH)
- LOG_D(MAC,
- "[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n",
+ LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n",
module_idP, CC_id, frameP, subframeP, i, j);
header_len_mtch = 3;
- LOG_D(MAC,
- "[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
+ LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
module_idP, CC_id, frameP, MTCH, TBS,
TBS - header_len_mcch - header_len_msi - sdu_length_total -
header_len_mtch);
- mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9;
+ //TODO
+ mbms_rab_id = cc->mbms_SessionList[0/*mbms_mch_i*/]->list.array[0]->logicalChannelIdentity_r9;
rlc_status =
mac_rlc_status_ind(module_idP, 0xfffd, frameP, subframeP,
module_idP, ENB_FLAG_YES, MBMS_FLAG_YES,
- cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
+ cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9,
//MTCH,
0, 0
);
+
bytes_in_buffer = rlc_status.bytes_in_buffer;
-
+ //TOCHECK is this really neede?
if( !(mcch_flag==1 || msi_flag==1) )
msi_sfs = rlc_status.bytes_in_buffer/(TBS- header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)+(rlc_status.bytes_in_buffer%(TBS- header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)?1:0);
- //uint16_t msi_control_element[29], *msi_ptr;
- //
- //
- uint16_t TBS_MTCH =
- get_TBS_DL(cc->pmch_Config[0]->dataMCS_r9, to_prb(cc->mib->message.dl_Bandwidth));
+
+ uint16_t TBS_MTCH =
+ get_TBS_DL(cc->pmch_Config[mbms_mch_i]->dataMCS_r9, to_prb(cc->mib->message.dl_Bandwidth));
+
if(msi_flag==1 && buffer_pointer!=NULL){
- msi_ptr = &msi_control_element[0];
+ // msi_ptr = &msi_control_element[0];
- //memcpy(buffer_pointer,
- // msi_control_element, msi_length);
-
- // msi_pmch_stop = rlc_status.bytes_in_buffer/TBS+(rlc_status.bytes_in_buffer%TBS?1:0);
msi_pmch_stop = (rlc_status.bytes_in_buffer - header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)/(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)+((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0);
- if( msi_pmch_stop > cc->pmch_Config[0]->sf_AllocEnd_r9)
- LOG_E(MAC,"e-MBMS Buffer Overflow\n");
- if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) {
- ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) & stop_sf limited to 256
- //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = msi_pmch_stop;
- ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9);
- msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9);
- }else{
- ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now)
- ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF;
- msi_pmch_stop=0;
- }
- LOG_I(MAC,"frameP %d, subframeP %d rlc_status.bytes_in_buffer %d stop_sf_LSB %d\n",frameP,subframeP,rlc_status.bytes_in_buffer,((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB);
- //LOG_W(MAC,"frameP %d, subframeP %d rlc_status.bytes_in_buffer %d stop_sf_LSB %d msi_calc:%d remainder %d\n",frameP,subframeP,rlc_status.bytes_in_buffer,((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB,rlc_status.bytes_in_buffer/(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)+((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0),((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0));
+ for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment
+ msi_ptr = &msi_control_element[k];
- memcpy(buffer_pointer,
+ ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[mbms_mch_i]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid;
+
+ if( msi_pmch_stop > cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9)
+ LOG_E(MAC,"e-MBMS Buffer Overflow\n");
+
+ if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) {
+ ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = (((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) >> 8) & 0x7f);
+ ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = ((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) & 0xff);
+ msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9);
+ }else{
+ ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now)
+ ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF;
+ msi_pmch_stop=0;
+ }
+ LOG_I(MAC,"frameP %d, subframeP %d LCID %d rlc_status.bytes_in_buffer %d stop_sf_LSB %d stop_sf_MSB %d msi_pmch_stop %d sf_AllocEnd_r9 %ld, msi_length %d\n",frameP,subframeP,((MSI_ELEMENT *) msi_ptr)->lcid,rlc_status.bytes_in_buffer,((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB,((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB, msi_pmch_stop,cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9, msi_length);
+ }
+
+ memcpy((char*)buffer_pointer,
msi_control_element, msi_length);
-
}
- LOG_D(MAC,
- "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d TBS_MTCH %d pmch_stop %d msi_sfs %d\n",
+ LOG_D(MAC, "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d TBS_MTCH %d pmch_stop %d msi_sfs %d\n",
MTCH, frameP, subframeP, rlc_status.bytes_in_buffer,TBS_MTCH,msi_pmch_stop,msi_sfs);
- if ((rlc_status.bytes_in_buffer > 0 && msi_pmch_stop > 0) && ((msi_flag!=1 || mcch_flag!=1)) /*|| (rlc_status.bytes_in_buffer > 0 && (msi_flag==1 || mcch_flag==1))*//*|| msi_sfs > cc->pmch_Config[0]->sf_AllocEnd_r9 */ /*msi_pmch_stop>=num_sf_alloc*/ ) {
- //if(rlc_status.bytes_in_buffer > 0){
- LOG_D(MAC,
- "[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d) rlc_status.bytes_in_buffer %d\n",
- module_idP, CC_id, frameP,
+ //TODO not sure whether msi and mch MCH should be precluded ... keep in mind this konditions just in case if ((rlc_status.bytes_in_buffer > 0 && msi_pmch_stop > 0) && ((msi_flag!=1 || mcch_flag!=1))
+ if ((rlc_status.bytes_in_buffer > 0 && msi_pmch_stop > 0) /*&& ((msi_flag!=1 || mcch_flag!=1))*/ /*|| (rlc_status.bytes_in_buffer > 0 && (msi_flag==1 || mcch_flag==1))*//*|| msi_sfs > cc->pmch_Config[0]->sf_AllocEnd_r9 */ /*msi_pmch_stop>=num_sf_alloc*/ ) {
+ LOG_I(MAC,"[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, Subframe %d MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d) rlc_status.bytes_in_buffer %d, LCID %ld\n",
+ module_idP, CC_id, frameP, subframeP,
TBS - header_len_mcch - header_len_msi -
- sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer);
+ sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer,cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9);
- sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0xfffd, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
+ sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0xfffd, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9,
TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch,
(char *)
&mch_buffer[sdu_length_total]
,0,
0
);
-
- // LOG_I(MAC,"RLC %x:",(unsigned char)mch_buffer[sdu_length_total]);
- // for (int kk = 7; kk >= 0; kk--)
- // {
- // printf("%d",(((unsigned char)mch_buffer[sdu_length_total]) >> kk) & 1 ? '1' : '0');
- // }
- // printf("\n");
-
- //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(MAX_MOBILES_PER_ENB+1)), (char*)&mch_buffer[sdu_length_total]);
- LOG_D(MAC,
- "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d msi_pmch_stop %d msi_sfs %d sdu_lengths[num_sdus] %d\n",
+ LOG_D(MAC,"[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d msi_pmch_stop %d msi_sfs %d sdu_lengths[num_sdus] %d\n",
module_idP, CC_id, sdu_lengths[num_sdus], MTCH,msi_pmch_stop,msi_sfs, sdu_lengths[num_sdus]);
+
cc->mtch_active = 1;
- sdu_lcids[num_sdus] = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9/*MTCH*/;
+
+ sdu_lcids[num_sdus] = cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9/*MTCH*/;
sdu_length_total += sdu_lengths[num_sdus];
if (msi_pmch_stop != 0 && msi_flag !=1)
msi_pmch_stop--;
-
if (sdu_lengths[num_sdus] < 128) {
header_len_mtch = 2;
}
num_sdus++;
- //}
}
else {
- // LOG_E(MAC,
- // "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d msi_pmch_stop %d msi_buffer %d msi_sfs %ld msi_buffer_act %ld sdu_lengths[num_sdus] %d\n",
- // module_idP, CC_id, sdu_lengths[num_sdus], MTCH,msi_pmch_stop,msi_sfs,msi_buffer_act, sdu_lengths[num_sdus]);
-
header_len_mtch = 0;
}
}
- // }
// FINAL STEP: Prepare and multiplexe MSI, MCCH and MTCHs
- if ((sdu_length_total + header_len_msi + header_len_mcch +
- header_len_mtch) > 0) {
+ if ((sdu_length_total + header_len_msi + header_len_mcch + header_len_mtch) > 0) {
+
// Adjust the last subheader
- /* if ((msi_flag==1) || (mcch_flag==1)) {
- RC.mac[module_idP]->MCH_pdu.mcs = mcch_mcs;
- }
- else if (mtch_flag == 1) { // only MTCH in this subframeP
- RC.mac[module_idP]->MCH_pdu.mcs = RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9;
- }
- */
header_len_mtch_temp = header_len_mtch;
header_len_mcch_temp = header_len_mcch;
header_len_msi_temp = header_len_msi;
@@ -881,12 +1026,10 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
cc->MCH_pdu.msi_active = cc->msi_active;
cc->MCH_pdu.mcch_active = cc->mcch_active;
cc->MCH_pdu.mtch_active = cc->mtch_active;
- LOG_D(MAC,
- " MCS for this sf is %d (mcch active %d, mtch active %d)\n",
+ LOG_D(MAC, " MCS for this sf is %d (mcch active %d, mtch active %d)\n",
cc->MCH_pdu.mcs, cc->MCH_pdu.mcch_active,
cc->MCH_pdu.mtch_active);
- LOG_D(MAC,
- "[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n",
+ LOG_D(MAC, "[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n",
module_idP, CC_id, sdu_length_total, num_sdus,
sdu_lengths[0], sdu_lcids[0], offset, padding, post_padding,
cc->MCH_pdu.mcs, TBS, header_len_mtch, header_len_mcch,
@@ -902,20 +1045,15 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
/* Tracing of PDU is done on UE side */
//if (opt_enabled == 1) {
- trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xfffd, // M_RNTI = 6 in wirehsark
- RC.mac[module_idP]->frame,
- RC.mac[module_idP]->subframe, 0, 0);
- LOG_D(OPT,
- "[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n",
+ trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xfffd, // M_RNTI = 6 in wirehsark
+ RC.mac[module_idP]->frame,
+ RC.mac[module_idP]->subframe, 0, 0);
+ LOG_D(OPT, "[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n",
module_idP, CC_id, frameP, TBS);
//}
eNB_MAC_INST *eNB = RC.mac[module_idP];
dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
- // dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
- // memset((void *) dl_config_pdu,
- // 0,
- // sizeof(nfapi_dl_config_request_pdu_t));
dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
fill_nfapi_mch_config(
dl_req,
@@ -934,12 +1072,6 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
TBS,
eNB->pdu_index[CC_id],
(uint8_t*)cc->MCH_pdu.payload);
-
-
- /*
- for (j=0;jMCH_pdu.payload[j+offset]);
- printf(" \n"); */
return 1;
} else {
cc->MCH_pdu.Pdu_size = 0;
@@ -947,21 +1079,8 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
cc->MCH_pdu.msi_active = 0;
cc->MCH_pdu.mcch_active = 0;
cc->MCH_pdu.mtch_active = 0;
- // for testing purpose, fill with random data
- //for (j=0;j<(TBS-sdu_length_total-offset);j++)
- // RC.mac[module_idP]->MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff);
return 0;
}
-
- //this is for testing
- /*
- if (mtch_flag == 1) {
- // LOG_D(MAC,"DUY: mch_buffer length so far is : %ld\n", &mch_buffer[sdu_length_total]-&mch_buffer[0]);
- return 1;
- }
- else
- return 0;
- */
}
int
schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index faefc481f6..7eccc6222d 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -56,6 +56,7 @@
#include "LTE_MobilityControlInfo.h"
#include "LTE_MBSFN-AreaInfoList-r9.h"
#include "LTE_MBSFN-SubframeConfigList.h"
+#include "LTE_MBSFNAreaConfiguration-r9.h"
#include "LTE_PMCH-InfoList-r9.h"
#include "LTE_SCellToAddMod-r10.h"
#include "LTE_SystemInformationBlockType1-v1310-IEs.h"
@@ -409,9 +410,11 @@ typedef struct {
/*!\brief Values of BCCH SIB_BR logical channel (fake) */
#define BCCH_SI_BR 7 // SI-BR
/*!\brief Values of BCCH SIB1_MBMS logical channel (fake) */
-#define BCCH_SIB1_MBMS 60 // SIB1_MBMS //TODO better armonize index
+#define MIBCH_MBMS 10 // SIB1_MBMS //TODO better armonize index
+#define BCCH_SIB1_MBMS 12 // SIB1_MBMS //TODO better armonize index
/*!\brief Values of BCCH SI_MBMS logical channel (fake) */
-#define BCCH_SI_MBMS 61 // SIB_MBMS //TODO better armonize index
+#define BCCH_SI_MBMS 13 // SIB_MBMS //TODO better armonize index
+#define MCCH_COUNTING 14
/*!\brief Value of CCCH / SRB0 logical channel */
#define CCCH 0 // srb0
/*!\brief DCCH / SRB1 logical channel */
@@ -1286,6 +1289,8 @@ typedef struct {
/// MBSFN SubframeConfig
struct LTE_MBSFN_SubframeConfig *mbsfn_SubframeConfig[8];
struct LTE_NonMBSFN_SubframeConfig_r14 *non_mbsfn_SubframeConfig;
+ struct LTE_MBSFN_SubframeConfig *commonSF_Alloc_r9_mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA?
+ uint8_t commonSF_AllocPeriod_r9;
/// number of subframe allocation pattern available for MBSFN sync area
uint8_t num_sf_allocation_pattern;
/// MBMS Flag
diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h
index 9d49fdffd5..b92ce85608 100644
--- a/openair2/LAYER2/MAC/mac_proto.h
+++ b/openair2/LAYER2/MAC/mac_proto.h
@@ -33,6 +33,16 @@
#include "PHY/defs_common.h" // for PRACH_RESOURCES_t and lte_subframe_t
#include "openair2/COMMON/mac_messages_types.h"
+/** \fn void schedule_fembms_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe);
+\brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1.
+@param Mod_id Instance ID of eNB
+@param frame Frame index
+@param subframe Subframe number on which to act
+
+*/
+
+void schedule_fembms_mib(module_id_t module_idP,
+ frame_t frameP, sub_frame_t subframeP);
/** \addtogroup _mac
* @{
@@ -532,6 +542,10 @@ int ue_query_mch(module_id_t Mod_id, uint8_t CC_id, uint32_t frame,
sub_frame_t subframe, uint8_t eNB_index,
uint8_t *sync_area, uint8_t *mcch_active);
+int ue_query_mch_fembms(module_id_t Mod_id, uint8_t CC_id, uint32_t frame,
+ sub_frame_t subframe, uint8_t eNB_index,
+ uint8_t * sync_area, uint8_t * mcch_active);
+
/* \brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header. CRNTI element is not supported yet. It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU.
@param Mod_id Instance id of UE in machine
@@ -899,6 +913,7 @@ int generate_dlsch_header(unsigned char *mac_header,
@param non_MBSFN_SubframeConfig pointer to FeMBMS Non MBSFN Subframe Config
@param sib1_mbms_r14_fembms pointer SI Scheduling infomration for SI-MBMS
@param mbsfn_AreaInfoList_fembms pointer to FeMBMS MBSFN Area Info list from SIB1-MBMS
+@param mbms_AreaConfiguration pointer to eMBMS MBSFN Area Configuration
*/
int rrc_mac_config_req_eNB(module_id_t module_idP,
@@ -935,7 +950,8 @@ int rrc_mac_config_req_eNB(module_id_t module_idP,
LTE_SchedulingInfo_MBMS_r14_t *schedulingInfo_fembms,
struct LTE_NonMBSFN_SubframeConfig_r14 *nonMBSFN_SubframeConfig,
LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_mbms_r14_fembms,
- LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList_fembms
+ LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList_fembms,
+ LTE_MBSFNAreaConfiguration_r9_t * mbms_AreaConfiguration
);
/** \brief RRC eNB Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages.
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index 24630c0fe2..e97f1bebdd 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -72,7 +72,10 @@ extern UL_IND_t *UL_INFO;
extern int next_ra_frame;
extern module_id_t next_Mod_id;
-int mbms_rab_id = 2047;
+int mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047};
+static int mbms_mch_i=0;
+//static int num_msi_per_CSA[28];
+
/*
*
@@ -753,8 +756,9 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
LOG_E(MAC,"MCH Scheduling Information MAC Control Element should have an even size\n");
}
- LOG_D(MAC,"MCH Scheduling Information, len(%d)\n",rx_lengths[i]);
+ LOG_D(MAC,"MCH Scheduling Information, len(%d)\n",rx_lengths[i]);
+
for (j=0; j> 3;
@@ -768,7 +772,7 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
UE_mac_inst[module_idP].msi_status_v[j] = 0;
if (UE_mac_inst[module_idP].mcch_status==1) {
- LOG_D(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes), i(%d)\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], UE_mac_inst[module_idP].pmch_stop_mtch[j]);
+ LOG_D(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes), LCID(%d)(%d)\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], UE_mac_inst[module_idP].pmch_lcids[j] , UE_mac_inst[module_idP].pmch_stop_mtch[j]);
if (UE_mac_inst[module_idP].pmch_stop_mtch[j] < 2043) {
UE_mac_inst[module_idP].pmch_stop_mtch[j] += UE_mac_inst[module_idP].msi_current_alloc;
@@ -794,7 +798,7 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
}
if (j<28 && UE_mac_inst[module_idP].msi_status_v[j]==1) {
- LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j);
+ LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d lcid %d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j,rx_lcids[i]);
//This sucks I know ... workaround !
mbms_rab_id = rx_lcids[i];
//end sucks :-(
@@ -951,7 +955,9 @@ int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subfra
}
} else { //more that one MCH ?? check better this condition
//msi and mtch are mutally excluded then the break is safe
+ //TODO
if ((num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[i-1]->sf_AllocEnd_r9 + 1) && (sf_AllocEnd_r9 >= (num_sf_alloc+1))) {
+ //if ((num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[i-1]->sf_AllocEnd_r9) && (sf_AllocEnd_r9 >= (num_sf_alloc))) {
//msi should be just after
msi_flag = 1;
LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9,
@@ -986,6 +992,458 @@ int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subfra
return mtch_mcs;
}
+//static int common_num_sf_alloc=0;
+//static int x=0;
+int ue_query_mch_fembms(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) {
+ int i = 0, j = 0,/* ii = 0,*/ msi_pos = -1, mcch_mcs = -1, mtch_mcs = -1, l=0/*,ii=0*/;
+ int mcch_flag = 0, mtch_flag = 0, msi_flag = 0;
+ int alloc_offset=0;
+ uint32_t period;
+ //uint16_t num_non_mbsfn_SubframeConfig=0;
+ long mch_scheduling_period = -1;
+ uint8_t mch_lcid = 0;
+ //int first_pos=0;
+
+ if(UE_mac_inst[module_idP].non_mbsfn_SubframeConfig == NULL )
+ return -1;
+
+ int non_mbsfn_SubframeConfig = (UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]>>7);
+
+ period = 4<radioFrameAllocationPeriod_r14;
+ alloc_offset = UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->radioFrameAllocationOffset_r14;
+
+ long mcch_period = 32 << UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9;
+ long mcch_offset = UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9;
+
+ if (UE_mac_inst[module_idP].pmch_Config[0]) {
+ mch_scheduling_period = 8 << UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9;
+ }
+
+
+// for(l=0;l<8;l++){
+// if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]!=NULL){
+// if(frameP%(4<> msi_pos)) == (0x100>>msi_pos))
+// first_pos++;
+// if(first_pos == subframe){
+// ii=0;
+// while(UE_mac_inst[module_idP].pmch_Config[ii]!=NULL){
+// num_msi_per_CSA[ii]= ( ( 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9) / (8 << UE_mac_inst[module_idP].pmch_Config[ii]->mch_SchedulingPeriod_r9) );
+// ii++;
+// LOG_D(MAC,"frameP %d subframe %d num_msi_per_CSA[%d] %d\n",frameP,subframe,ii,num_msi_per_CSA[ii]);
+// }
+// }
+//
+// }
+// }
+// }
+//
+
+ // get the real MCS value
+ switch (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) {
+ case 0:
+ mcch_mcs = 2;
+ break;
+
+ case 1:
+ mcch_mcs = 7;
+ break;
+
+ case 2:
+ mcch_mcs = 13;
+ break;
+
+ case 3:
+ mcch_mcs = 19;
+ break;
+ }
+ LOG_D(MAC,"frameP %d subframe %d period %d alloc_offset %d mcch_mcs %d mcch_period %ld mcch_offset %ld buf %x mch_scheduling_period %ld\n",frameP, subframe, period, alloc_offset,mcch_mcs, mcch_period, mcch_offset,(UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0]),mch_scheduling_period);
+
+ if((frameP % period ) == alloc_offset){
+ switch(subframe){
+ case 0:
+ return (-1);
+ break;
+ case 1:
+ if ((non_mbsfn_SubframeConfig & 0x100) > 0)
+ return (-1);
+ break;
+ case 2:
+ if ((non_mbsfn_SubframeConfig & 0x80) > 0)
+ return (-1);
+ break;
+ case 3:
+ if ((non_mbsfn_SubframeConfig & 0x40) > 0)
+ return (-1);
+ break;
+ case 4:
+ if ((non_mbsfn_SubframeConfig & 0x20) > 0)
+ return (-1);
+ break;
+ case 5:
+ if ((non_mbsfn_SubframeConfig & 0x10) > 0)
+ return (-1);
+ break;
+ case 6:
+ if ((non_mbsfn_SubframeConfig & 0x8) > 0)
+ return (-1);
+ break;
+ case 7:
+ if ((non_mbsfn_SubframeConfig & 0x4) > 0)
+ return (-1);
+ break;
+ case 8:
+ if ((non_mbsfn_SubframeConfig & 0x2) > 0)
+ return (-1);
+ break;
+ case 9:
+ if ((non_mbsfn_SubframeConfig & 0x1) > 0)
+ return (-1);
+ break;
+ }
+ }
+
+ if (UE_mac_inst[module_idP].pmch_Config[0]) {
+ // Find the first subframe in this MCH to transmit MSI
+ if (frameP % 1 == 0) {
+ if (frameP % mch_scheduling_period == 0) {
+ msi_pos=0;
+ if((frameP&3)==0)
+ msi_pos++;
+ while((non_mbsfn_SubframeConfig & (0x100 >> msi_pos)) == (0x100>>msi_pos))
+ msi_pos++;
+ if(msi_pos == subframe){
+ UE_mac_inst[module_idP].common_num_sf_alloc=0;
+ mbms_mch_i=0;
+ //LOG_W(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i);
+ }
+ }
+ }
+ }
+
+ if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){
+ if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=subframe;
+ mbms_mch_i++;
+ // LOG_W(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i);
+ }
+ }
+
+
+ // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
+ switch (subframe) {
+ case 0:
+ if (msi_pos == 0) {
+ msi_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+ case 1:
+ if (msi_pos == 1) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) &&
+ ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1)) {
+ mcch_flag = 1;
+ }
+
+ mtch_flag = 1;
+ break;
+
+ case 2:
+ if (msi_pos == 2) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) &&
+ ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) {
+ mcch_flag = 1;
+ }
+
+ mtch_flag = 1;
+
+ break;
+
+ case 3:
+ if (msi_pos == 3) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) &&
+ ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) {
+ mcch_flag = 1;
+ }
+
+ mtch_flag = 1;
+
+ break;
+ case 4:
+ if (msi_pos == 4) {
+ msi_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+ case 5:
+ if (msi_pos == 5) {
+ msi_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+
+ case 6:
+ if (msi_pos == 6) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) &&
+ ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) {
+ mcch_flag = 1;
+ }
+
+ mtch_flag = 1;
+
+ break;
+
+ case 7:
+ if (msi_pos == 7) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) &&
+ ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) {
+ mcch_flag = 1;
+ }
+
+ mtch_flag = 1;
+
+ break;
+
+ case 8:
+ if (msi_pos == 8) {
+ msi_flag = 1;
+ }
+ if ((frameP % mcch_period == mcch_offset) &&
+ ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) {
+ mcch_flag = 1;
+ }
+
+ mtch_flag = 1;
+ break;
+
+ case 9:
+ if (msi_pos == 9) {
+ msi_flag = 1;
+ }
+ mtch_flag = 1;
+ break;
+ }// end switch
+
+ if( (msi_flag == 1) || (mcch_flag == 1) || (mtch_flag == 1) ){
+ UE_mac_inst[module_idP].common_num_sf_alloc++;
+ //if( (msi_flag!=1 && mcch_flag!=1) || (msi_flag!=1 && mcch_flag!=1 && mtch_flag!=1) ){
+ //UE_mac_inst[module_idP].common_num_sf_alloc++;
+ //if(msi_flag == 1)
+ // if((num_msi_per_CSA[mbms_mch_i]--)==0){
+ // LOG_E(MAC,"Both MSI and MTCH Should be reset?\n");
+ // msi_flag=0;
+ //}
+ //}
+
+ }
+
+
+
+
+#ifdef OLD
+ // Acount for sf_allocable in CSA
+ int num_sf_alloc = 0;
+
+ for (l = 0; l < 8; l++) {
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL)
+ continue;
+
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame)
+ continue;
+
+ uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.choice.oneFrame.buf[0];
+
+
+ for (j = 0; j < 6; j++)
+ num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j));
+ //num_sf_alloc=1;
+ }
+
+ num_sf_alloc = 10;
+
+ num_non_mbsfn_SubframeConfig = (UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]>>7);
+ int ones=0;
+ for(j=0; j < 16; j++){
+ if(num_non_mbsfn_SubframeConfig & 1)
+ ones++;
+ num_non_mbsfn_SubframeConfig>>=1;
+ }
+
+ for (l = 0; l < 28; l++) {
+ if (UE_mac_inst[module_idP].pmch_stop_mtch[l] >= 1/*num_sf_alloc*/) {
+ if (UE_mac_inst[module_idP].pmch_stop_mtch[l] != 2047) {
+ if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL){
+ mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9;
+ //int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]->radioframeAllocationOffset;
+ long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]->radioframeAllocationPeriod;
+ long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9;
+ if(UE_mac_inst[module_idP].common_num_sf_alloc >= UE_mac_inst[module_idP].pmch_stop_mtch[l]){
+ //LOG_E(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc);
+
+ mtch_mcs = -1;
+ }/*else
+ OG_W(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc);*/
+ LOG_D(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d num_sf_alloc %d commonSF_AllocPeriod %ld, common_mbsfn_period %ld num_non_mbsfn_SubframeConfig %x ones %d\n",UE_mac_inst[module_idP].common_num_sf_alloc,num_sf_alloc, commonSF_AllocPeriod,common_mbsfn_period,num_non_mbsfn_SubframeConfig,ones);
+ UE_mac_inst[module_idP].common_num_sf_alloc++;
+ UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period-(1+ones)*(commonSF_AllocPeriod/4)); //TODO
+ }
+ else
+ mtch_mcs = -1;
+
+ mch_lcid = (uint8_t)l;
+ break;
+ }
+ }
+ }
+#endif
+
+{
+ // Acount for sf_allocable in Common SF Allocation
+ int num_sf_alloc = 0;
+
+ for (l = 0; l < 8; l++) {
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL)
+ continue;
+
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame)
+ continue;
+
+ //int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationOffset;
+ long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationPeriod;
+ long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9;
+
+
+ num_sf_alloc =10*commonSF_AllocPeriod/common_mbsfn_period;
+ num_sf_alloc -=1*((commonSF_AllocPeriod/common_mbsfn_period)/4); //CAS sfs
+ uint32_t num_non_mbsfn_SubframeConfig2 = (UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]>>7);
+ for (j = 0; j < 10; j++)
+ num_sf_alloc -= ((num_non_mbsfn_SubframeConfig2 & (0x200 >> j)) == (0x200 >> j))*((commonSF_AllocPeriod/common_mbsfn_period)/period);
+
+ }
+
+ for (l = 0; l < 8; l++) {
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL)
+ continue;
+
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame)
+ continue;
+
+ //int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationOffset;
+ long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationPeriod;
+ //long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9;
+
+
+ if(msi_flag==1 && UE_mac_inst[module_idP].pmch_Config[mbms_mch_i] != NULL){
+ LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%ld),common_num_sf_alloc(%d)\n",mbms_mch_i,frameP,subframe,num_sf_alloc,UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9,
+ UE_mac_inst[module_idP].common_num_sf_alloc);
+ UE_mac_inst[module_idP].msi_current_alloc = UE_mac_inst[module_idP].common_num_sf_alloc;//num_sf_alloc;
+ UE_mac_inst[module_idP].msi_pmch = mbms_mch_i;
+ }else if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i] != NULL){
+ if (UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i] >= UE_mac_inst[module_idP].common_num_sf_alloc/*num_sf_alloc*/) {
+ if (UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i] != 2047) {
+ mtch_flag = 1;
+ if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL)
+ mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9;
+ else
+ mtch_mcs = -1;
+ mch_lcid = (uint8_t)mbms_mch_i;
+ LOG_D(MAC,"mtch should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),mtch_mcs(%d),pmch_stop_mtch(%d),lcid(%d),msi_pmch(%d)\n",frameP,subframe,num_sf_alloc,mtch_mcs,
+ UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i],UE_mac_inst[module_idP].pmch_lcids[mbms_mch_i],UE_mac_inst[module_idP].msi_pmch);
+ }
+ }
+ }
+ UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % ((num_sf_alloc-mbms_mch_i) /** commonSF_AllocPeriod *// common_mbsfn_period);//48;
+
+ if(mtch_flag)
+ break;
+ }
+ if(msi_flag==1){
+ for (l = 0; l < 8; l++) {
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL)
+ continue;
+
+ if ( (/*AJ*/ (/*V*/ ( /*U*/ (frameP %(4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9)) ) / 8 ) % ((8 <mch_SchedulingPeriod_r9) / 8 ) ) != 0 ){
+ msi_flag=0;
+ LOG_D(MAC,"frameP %d subframeP %d reset(%d)\n",frameP, subframe, mbms_mch_i);
+ }
+ }
+ }
+}
+
+ // sf allocation is non-overlapping
+ if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) {
+ LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
+ module_idP, frameP, subframe,l,j,msi_flag,mcch_flag,mtch_flag);
+ *sync_area=i;
+ }
+
+ //if(msi_flag == 1)
+ // if((num_msi_per_CSA[mbms_mch_i]--)==0){
+ // LOG_E(MAC,"Both MSI and MTCH Should be reset?\n");
+ // msi_flag=mtch_flag=0;
+ //}
+
+
+ if ((mcch_flag == 1)) { // || (msi_flag==1))
+ *mcch_active = 1;
+ }
+
+ if ( (mcch_flag==1) || ((msi_flag==1) && (UE_mac_inst[module_idP].mcch_status==1)) ) {
+ if (msi_flag!=1) {
+ for (i=0; i<8; i++)
+ UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = NULL;
+
+ for (i=0; i<15; i++)
+ UE_mac_inst[module_idP].pmch_Config[i] = NULL;
+
+ for (i=0; i<28 ; i++) {
+ UE_mac_inst[module_idP].pmch_lcids[i] = -1;
+ UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047;
+ UE_mac_inst[module_idP].msi_status_v[i] = 0;
+ }
+ } else {
+ for (i=0; i<28; i++) {
+ UE_mac_inst[module_idP].pmch_lcids[i] = -1;
+ UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047;
+ UE_mac_inst[module_idP].msi_status_v[i] = 0;
+ }
+ }
+
+ return mcch_mcs;
+ } else if ((mtch_flag==1) && (UE_mac_inst[module_idP].msi_status_v[(mch_lcid > 27) ? 27 : mch_lcid] == 1)) {
+ return mtch_mcs;
+ } else {
+ return -1;
+ }
+
+
+
+ // if(mcch_flag == 1 || msi_flag == 1 ){
+ // *mcch_active = 1;
+ // return (mcch_mcs);
+ // }else if(mtch_flag == 1){
+ // mtch_mcs=-1;
+ // return (mtch_mcs);
+ // }
+
+ // return -1;
+
+}
+
+
int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int *mtch_active, int *msi_active, uint8_t *mch_lcid) {
int i, j, mtch_mcs = -1;
int mtch_flag = 0;
@@ -1100,6 +1558,7 @@ int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, i
return mtch_mcs;
}
+
int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) {
int i = 0, j = 0, ii = 0, jj = 0, msi_pos = 0, mcch_mcs = -1, mtch_mcs = -1;
int l =0;
@@ -1162,6 +1621,11 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
ii = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80 >> msi_pos);
msi_pos++;
}
+ if(msi_pos == subframe){
+ UE_mac_inst[module_idP].common_num_sf_alloc=0;
+ mbms_mch_i=0;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i);
+ }
}
}
@@ -1170,6 +1634,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
case 1:
if (UE_mac_inst[module_idP].tdd_Config == NULL) {
if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
+ if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){
+ if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=1;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i);
+ }
+ }
+
if (msi_pos == 1) {
msi_flag = 1;
}
@@ -1188,6 +1660,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
case 2:
if (UE_mac_inst[module_idP].tdd_Config == NULL) {
if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
+ if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){
+ if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=2;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i);
+ }
+ }
+
if (msi_pos == 2) {
msi_flag = 1;
}
@@ -1219,6 +1699,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
}
} else { // FDD
if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) {
+ if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){
+ if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=3;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i);
+ }
+ }
+
if (msi_pos == 3) {
msi_flag = 1;
}
@@ -1255,6 +1743,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
case 6:
if (UE_mac_inst[module_idP].tdd_Config == NULL) {
if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) {
+ if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){
+ if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=6;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i);
+ }
+ }
+
if (msi_pos == 4) {
msi_flag = 1;
}
@@ -1286,6 +1782,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
}
} else { // FDD
if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) {
+ if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){
+ if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=5;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i);
+ }
+ }
+
if (msi_pos == 5) {
msi_flag = 1;
}
@@ -1317,6 +1821,13 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
}
} else { // FDD
if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) {
+ if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){
+ if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){
+ msi_pos=6;
+ mbms_mch_i++;
+ LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i);
+ }
+ }
if (msi_pos == 6) {
msi_flag = 1;
}
@@ -1351,6 +1862,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
break;
}// end switch
+ if( (msi_flag == 1) || (mcch_flag == 1) || (mtch_flag == 1) ){
+ UE_mac_inst[module_idP].common_num_sf_alloc++;
+ //if( (msi_flag!=1 && mcch_flag!=1) || (msi_flag!=1 && mcch_flag!=1 && mtch_flag!=1) ){
+ //UE_mac_inst[module_idP].common_num_sf_alloc++;
+ //}
+ }
+
+#ifdef OLD
// Acount for sf_allocable in CSA
int num_sf_alloc = 0;
@@ -1392,11 +1911,86 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
}
}
}
+#endif
+
+{
+ // Acount for sf_allocable in Common SF Allocation
+ int num_sf_alloc = 0;
+
+ for (l = 0; l < 8; l++) {
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL)
+ continue;
+
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame)
+ continue;
+
+ //int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationOffset;
+ //long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationPeriod;
+ //long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9;
+
+ uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.choice.oneFrame.buf[0];
+
+ for (j = 0; j < 6; j++)
+ num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j));
+ }
+
+
+ for (l = 0; l < 8; l++) {
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL)
+ continue;
+
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame)
+ continue;
+
+ //int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationOffset;
+ long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationPeriod;
+ long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9;
+
+
+ if(msi_flag==1 && UE_mac_inst[module_idP].pmch_Config[mbms_mch_i] != NULL){
+ LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%ld),common_num_sf_alloc(%d)\n",mbms_mch_i,frameP,subframe,num_sf_alloc,UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9,
+ UE_mac_inst[module_idP].common_num_sf_alloc);
+ UE_mac_inst[module_idP].msi_current_alloc = UE_mac_inst[module_idP].common_num_sf_alloc;//num_sf_alloc;
+ UE_mac_inst[module_idP].msi_pmch = mbms_mch_i;
+ }else if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i] != NULL){
+ if (UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i] >= UE_mac_inst[module_idP].common_num_sf_alloc/*num_sf_alloc*/) {
+ if (UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i] != 2047) {
+ mtch_flag = 1;
+ if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL)
+ mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9;
+ else
+ mtch_mcs = -1;
+ mch_lcid = (uint8_t)mbms_mch_i;
+ LOG_D(MAC,"mtch should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),mtch_mcs(%d),pmch_stop_mtch(%d),lcid(%d),msi_pmch(%d)\n",frameP,subframe,num_sf_alloc,mtch_mcs,
+ UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i],UE_mac_inst[module_idP].pmch_lcids[mbms_mch_i],UE_mac_inst[module_idP].msi_pmch);
+ }
+ }
+ }
+ //LOG_D(MAC,"UE_mac_inst[module_idP].common_num_sf_alloc: %d num_sf_alloc %d mbms_mch_i %d commonSF_AllocPeriod %d common_mbsfn_period %d\n",UE_mac_inst[module_idP].common_num_sf_alloc,num_sf_alloc,mbms_mch_i,commonSF_AllocPeriod,common_mbsfn_period);
+ UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % ((num_sf_alloc* commonSF_AllocPeriod-mbms_mch_i) / common_mbsfn_period);//48;
+
+
+ if(mtch_flag)
+ break;
+ }
+ if(msi_flag==1){
+ for (l = 0; l < 8; l++) {
+ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL)
+ continue;
+
+ if ( (/*AJ*/ (/*V*/ ( /*U*/ (frameP %(4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9)) ) / 8 ) % ((8 <mch_SchedulingPeriod_r9) / 8 ) ) != 0 ){
+ msi_flag=0;
+ LOG_D(MAC,"frameP %d subframeP %d reset(%d)\n",frameP, subframe, mbms_mch_i);
+ }
+ }
+ }
+
+}
// sf allocation is non-overlapping
if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) {
- LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
- module_idP, frameP, subframe,l,j,msi_flag,mcch_flag,mtch_flag);
+ LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d x %d\n",
+ module_idP, frameP, subframe,l,j,msi_flag,mcch_flag,mtch_flag,UE_mac_inst[module_idP].common_num_sf_alloc);
*sync_area=i;
break;
}
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 810b0dcdaa..865abcc994 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -1151,7 +1151,7 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
if (NCS == 0) return nb_preambles;
else {
r = L_ra/NCS;
- found_sequences = (nb_preambles/r) + (nb_preambles%r!=0); //ceil(nb_preambles/r)
+ found_sequences = (nb_preambles/r) + (nb_preambles%r!=0); //ceil(nb_preambles/r)
printf(" found_sequences %u\n", found_sequences);
return (found_sequences);
}
@@ -1631,92 +1631,156 @@ uint16_t Table_61412[28][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120}
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 0:
+ if (Imcs > 28) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
+ Imcs = 28;
+ }
return (Table_51311[Imcs][0]);
break;
case 1:
+ if (Imcs > 27) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
+ Imcs = 27;
+ }
return (Table_51312[Imcs][0]);
break;
case 2:
+ if (Imcs > 28) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
+ Imcs = 28;
+ }
return (Table_51313[Imcs][0]);
break;
default:
- AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
+ AssertFatal(0, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx);
}
}
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 0:
+ if (Imcs > 28) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
+ Imcs = 28;
+ }
return (Table_51311[Imcs][1]);
break;
case 1:
+ if (Imcs > 27) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
+ Imcs = 27;
+ }
return (Table_51312[Imcs][1]);
break;
case 2:
+ if (Imcs > 28) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
+ Imcs = 28;
+ }
return (Table_51313[Imcs][1]);
break;
default:
- AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
+ AssertFatal(0, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx);
}
}
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 0:
+ if (Imcs > 28) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
+ Imcs = 28;
+ }
return (Table_51311[Imcs][0]);
break;
case 1:
+ if (Imcs > 27) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
+ Imcs = 27;
+ }
return (Table_51312[Imcs][0]);
break;
case 2:
+ if (Imcs > 28) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
+ Imcs = 28;
+ }
return (Table_51313[Imcs][0]);
break;
case 3:
+ if (Imcs > 27) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs);
+ Imcs = 27;
+ }
return (Table_61411[Imcs][0]);
break;
case 4:
+ if (Imcs > 27) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs);
+ Imcs = 27;
+ }
return (Table_61412[Imcs][0]);
break;
default:
- AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx);
+ AssertFatal(0, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx);
}
}
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 0:
+ if (Imcs > 28) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
+ Imcs = 28;
+ }
return (Table_51311[Imcs][1]);
break;
case 1:
+ if (Imcs > 27) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
+ Imcs = 27;
+ }
return (Table_51312[Imcs][1]);
break;
case 2:
+ if (Imcs > 28) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
+ Imcs = 28;
+ }
return (Table_51313[Imcs][1]);
break;
case 3:
+ if (Imcs > 27) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs);
+ Imcs = 27;
+ }
return (Table_61411[Imcs][1]);
break;
case 4:
+ if (Imcs > 27) {
+ LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs);
+ Imcs = 27;
+ }
return (Table_61412[Imcs][1]);
break;
default:
- AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx);
+ AssertFatal(0, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx);
}
}
@@ -1891,9 +1955,9 @@ uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) {
LOG_I(PHY,"PUSH PT-RS is not present.\n");
return -1;
} else if (N_RB >= nrb0 && N_RB < nrb1)
- return 0;
+ return 2;
else
- return 1;
+ return 4;
}
uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc,
diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
index af9822a5df..bae8e0d3c0 100644
--- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
+++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
@@ -39,6 +39,7 @@
#include "PHY/defs_UE.h"
#include "openair2/LAYER2/RLC/rlc.h"
#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h"
+#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
#include "executables/softmodem-common.h"
static NR_UE_MAC_INST_t *nr_ue_mac_inst;
@@ -59,7 +60,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst)
LOG_I(RLC, "Problem at RLC initiation \n");
}
pdcp_layer_init();
- nr_ip_over_LTE_DRB_preconfiguration();
+ nr_DRB_preconfiguration();
}
}
else LOG_I(MAC,"Running without RRC instance\n");
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 60f331a086..ab533af941 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -2342,7 +2342,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu_0_0,NULL,n_RB_ULBWP,0,dci->frequency_domain_assignment.val);
/* TIME_DOM_RESOURCE_ASSIGNMENT */
if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_0,NULL,dci->time_domain_assignment.val) < 0)
- break;
+ return -1;
/* FREQ_HOPPING_FLAG */
if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) &&
(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0))
@@ -2416,7 +2416,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu_0_1,NULL,n_RB_ULBWP,0,dci->frequency_domain_assignment.val);
/* TIME_DOM_RESOURCE_ASSIGNMENT */
if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_1,NULL,dci->time_domain_assignment.val) < 0)
- break;
+ return -1;
/* FREQ_HOPPING_FLAG */
if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) &&
(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0))
@@ -2747,7 +2747,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_0,0,n_RB_DLBWP,dci->frequency_domain_assignment.val);
/* TIME_DOM_RESOURCE_ASSIGNMENT */
if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val) < 0)
- break;
+ return -1;
/* dmrs symbol positions*/
dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
mac->scc->dmrs_TypeA_Position,
@@ -2872,7 +2872,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_1,0,n_RB_DLBWP,dci->frequency_domain_assignment.val);
/* TIME_DOM_RESOURCE_ASSIGNMENT */
if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val) < 0)
- break;
+ return -1;
/* dmrs symbol positions*/
dlsch_config_pdu_1_1->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
mac->scc->dmrs_TypeA_Position,
@@ -3582,19 +3582,18 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
// L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field;
// F: lenght of L is 0:8 or 1:16 bits wide
// R: Reserved bit, set to zero.
-
while (!done && pdu_len > 0){
mac_ce_len = 0x0000;
mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct
mac_sdu_len = 0x0000;
rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID;
+ //#ifdef DEBUG_HEADER_PARSING
+ LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len);
+ //#endif
switch(rx_lcid){
// MAC CE
- /*#ifdef DEBUG_HEADER_PARSING
- LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len);
- #endif*/
case DL_SCH_LCID_CCCH:
// MSG4 RRC Connection Setup 38.331
// varialbe length
@@ -3802,7 +3801,8 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
}
pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
- AssertFatal(pdu_len >= 0, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length < 0!\n");
+ if (pdu_len < 0)
+ LOG_E(MAC, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", pdu_len);
}
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 20e0e3e3cc..b474601dc7 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -298,30 +298,6 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
else LOG_I(PHY,"TDD has been properly configurated\n");
}
-/*
- // PDCCH-ConfigCommon
- cfg->pdcch_config.controlResourceSetZero.value = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero;
- cfg->pdcch_config.searchSpaceZero.value = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero;
-
- // PDSCH-ConfigCommon
- cfg->pdsch_config.num_PDSCHTimeDomainResourceAllocations.value = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;
- cfg->pdsch_config.dmrs_TypeA_Position.value = scc->dmrs_TypeA_Position;
- AssertFatal(cfg->pdsch_config.num_PDSCHTimeDomainResourceAllocations.value<=NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS,"illegal TimeDomainAllocation count %d\n",cfg->pdsch_config.num_PDSCHTimeDomainResourceAllocations.value);
- for (int i=0;ipdsch_config.num_PDSCHTimeDomainResourceAllocations.value;i++) {
- cfg->pdsch_config.PDSCHTimeDomainResourceAllocation_k0[i].value=*scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0;
- cfg->pdsch_config.PDSCHTimeDomainResourceAllocation_mappingType[i].value=scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType;
- cfg->pdsch_config.PDSCHTimeDomainResourceAllocation_startSymbolAndLength[i].value=scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
- }
-
- // PUSCH-ConfigCommon
- cfg->pusch_config.num_PUSCHTimeDomainResourceAllocations.value = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count;
- cfg->pusch_config.dmrs_TypeA_Position.value = scc->dmrs_TypeA_Position+2;
- AssertFatal(cfg->pusch_config.num_PUSCHTimeDomainResourceAllocations.value<=NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS,"illegal TimeDomainAllocation count %d\n",cfg->pusch_config.num_PUSCHTimeDomainResourceAllocations.value);
- for (int i=0;ipusch_config.num_PUSCHTimeDomainResourceAllocations.value;i++) {
- cfg->pusch_config.PUSCHTimeDomainResourceAllocation_k2[i].value=*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2;
- }*/
-
-
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index dfd3635019..c0f5778a72 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -62,6 +62,32 @@
const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
+void clear_mac_stats(gNB_MAC_INST *gNB) {
+ memset((void*)gNB->UE_list.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
+}
+
+void dump_mac_stats(gNB_MAC_INST *gNB) {
+
+ NR_UE_list_t *UE_list = &gNB->UE_list;
+ NR_mac_stats_t *stats;
+ int lc_id;
+
+ for (int UE_id=0;UE_idactive[UE_id] == TRUE) {
+ LOG_I(MAC,"UE %x\n",UE_list->rnti[UE_id]);
+ stats = &UE_list->mac_stats[UE_id];
+ LOG_I(MAC,"dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",stats->dlsch_rounds[0],stats->dlsch_rounds[1],stats->dlsch_rounds[2],stats->dlsch_rounds[3],stats->dlsch_errors);
+ LOG_I(MAC,"dlsch_total_bytes %d\n",stats->dlsch_total_bytes);
+ LOG_I(MAC,"ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",stats->ulsch_rounds[0],stats->ulsch_rounds[1],stats->ulsch_rounds[2],stats->ulsch_rounds[3],stats->ulsch_errors);
+ LOG_I(MAC,"ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",stats->ulsch_total_bytes_scheduled,stats->ulsch_total_bytes_rx);
+ for (lc_id=0;lc_id<63;lc_id++) {
+ if (stats->lc_bytes_tx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes TX\n",lc_id,stats->lc_bytes_tx[lc_id]);
+ if (stats->lc_bytes_rx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes RX\n",lc_id,stats->lc_bytes_rx[lc_id]);
+ }
+ }
+ }
+}
+
void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
int CC_idP,
frame_t frameP,
@@ -290,12 +316,15 @@ void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
void nr_schedule_pusch(int Mod_idP,
int UE_id,
+ int num_slots_per_tdd,
+ int ul_slots,
frame_t frameP,
sub_frame_t slotP) {
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
- NR_sched_pusch *pusch = UE_list->UE_sched_ctrl[UE_id].sched_pusch;
+ int k = slotP + ul_slots - num_slots_per_tdd;
+ NR_sched_pusch *pusch = &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k];
if ((pusch->active == true) && (frameP == pusch->frame) && (slotP == pusch->slot)) {
UL_tti_req->SFN = pusch->frame;
UL_tti_req->Slot = pusch->slot;
@@ -303,13 +332,15 @@ void nr_schedule_pusch(int Mod_idP,
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu = pusch->pusch_pdu;
UL_tti_req->n_pdus+=1;
- memset((void *) UE_list->UE_sched_ctrl[UE_id].sched_pusch,
+ memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k],
0, sizeof(NR_sched_pusch));
}
}
+
void nr_schedule_pucch(int Mod_idP,
int UE_id,
+ int nr_ulmix_slots,
frame_t frameP,
sub_frame_t slotP) {
@@ -326,15 +357,12 @@ void nr_schedule_pucch(int Mod_idP,
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
NR_sched_pucch *curr_pucch;
- int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
- if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0)
- nr_ulmix_slots++;
for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k];
if ((curr_pucch->dai_c > 0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) {
- UL_tti_req->SFN = frameP;
- UL_tti_req->Slot = slotP;
+ UL_tti_req->SFN = curr_pucch->frame;
+ UL_tti_req->Slot = curr_pucch->ul_slot;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu;
@@ -343,7 +371,7 @@ void nr_schedule_pucch(int Mod_idP,
O_ack = curr_pucch->dai_c;
O_uci = O_ack; // for now we are just sending acknacks in pucch
- LOG_I(MAC, "Scheduling pucch reception for frame %d slot %d\n", frameP, slotP);
+ LOG_D(MAC, "Scheduling pucch reception for frame %d slot %d\n", frameP, slotP);
nr_configure_pucch(pucch_pdu,
scc,
@@ -353,11 +381,15 @@ void nr_schedule_pucch(int Mod_idP,
O_ack,
SR_flag);
- curr_pucch->dai_c = 0;
+ memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k],
+ 0,
+ sizeof(NR_sched_pucch));
}
}
}
+
+
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot){
if((bitmap>>slot)&0x01)
@@ -367,15 +399,12 @@ bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot){
}
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
- frame_t frame_rxP,
- sub_frame_t slot_rxP,
- frame_t frame_txP,
- sub_frame_t slot_txP){
+ frame_t frame,
+ sub_frame_t slot){
- //printf("gNB_dlsch_ulsch_scheduler frameRX %d slotRX %d frameTX %d slotTX %d\n",frame_rxP,slot_rxP,frame_txP,slot_txP);
protocol_ctxt_t ctxt;
- PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame_txP, slot_txP,module_idP);
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
int CC_id;
int UE_id;
@@ -436,11 +465,14 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0)
nr_ulmix_slots++;
- if (slot_txP== 0 && (UE_list->fiveG_connected[UE_id] || get_softmodem_params()->phy_test)) {
+ if (slot== 0 && (UE_list->fiveG_connected[UE_id] || get_softmodem_params()->phy_test)) {
for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k],
0,
sizeof(NR_sched_pucch));
+ memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k],
+ 0,
+ sizeof(NR_sched_pusch));
}
}
@@ -450,29 +482,21 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
pdcp_run(&ctxt);
//rrc_rx_tx(&ctxt, CC_id);
- RC.nrmac[module_idP]->frame = frame_rxP;
- RC.nrmac[module_idP]->slot = slot_rxP;
-
dlsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch
ulsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch
// hardcoding dlsch to be in slot 1
- if (!(slot_txP%num_slots_per_tdd)) {
- if(slot_txP==0)
+ if (!(slot%num_slots_per_tdd)) {
+ if(slot==0) {
*dlsch_in_slot_bitmap = 0x02;
- else
- *dlsch_in_slot_bitmap = 0x00;
- }
-
- // hardcoding ulsch to be in slot 8
- if (!(slot_rxP%num_slots_per_tdd)) {
- if(slot_rxP==0)
*ulsch_in_slot_bitmap = 0x100;
- else
+ }
+ else {
+ *dlsch_in_slot_bitmap = 0x00;
*ulsch_in_slot_bitmap = 0x00;
+ }
}
-
memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
@@ -482,7 +506,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
memset(cc[CC_id].vrb_map, 0, 100);
memset(cc[CC_id].vrb_map_UL, 0, 100);
- clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP);
+ clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot);
}
// refresh UE list based on UEs dropped by PHY in previous subframe
@@ -499,14 +523,16 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
} //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
*/
+ if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]);
+
// This schedules MIB
- if((slot_txP == 0) && (frame_txP & 7) == 0){
- schedule_nr_mib(module_idP, frame_txP, slot_txP);
+ if((slot == 0) && (frame & 7) == 0){
+ schedule_nr_mib(module_idP, frame, slot);
}
// This schedule PRACH if we are not in phy_test mode
if (get_softmodem_params()->phy_test == 0)
- schedule_nr_prach(module_idP, (frame_rxP+1)&1023, slot_rxP);
+ schedule_nr_prach(module_idP, frame, slot);
// This schedule SR
// TODO
@@ -517,10 +543,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
// This schedule RA procedure if not in phy_test mode
// Otherwise already consider 5G already connected
if (get_softmodem_params()->phy_test == 0) {
- nr_schedule_RA(module_idP, frame_txP, slot_txP);
- nr_schedule_reception_msg3(module_idP, 0, frame_rxP, slot_rxP);
- }
- else
+ nr_schedule_RA(module_idP, frame, slot);
+ nr_schedule_reception_msg3(module_idP, 0, frame, slot);
+ } else
UE_list->fiveG_connected[UE_id] = true;
if (get_softmodem_params()->phy_test) {
@@ -543,20 +568,20 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
// This schedules the DCI for Uplink and subsequently PUSCH
if (UE_list->fiveG_connected[UE_id]) {
int tda = 1; // time domain assignment hardcoded for now
- schedule_fapi_ul_pdu(module_idP, frame_txP, slot_txP, num_slots_per_tdd, tda);
- nr_schedule_pusch(module_idP, UE_id, frame_rxP, slot_rxP);
+ schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda);
+ nr_schedule_pusch(module_idP, UE_id, num_slots_per_tdd, nr_ulmix_slots, frame, slot);
}
- if (UE_list->fiveG_connected[UE_id] && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot_txP%num_slots_per_tdd))) {
- ue_sched_ctl->current_harq_pid = slot_txP % num_slots_per_tdd;
- nr_update_pucch_scheduling(module_idP, UE_id, frame_txP, slot_txP, num_slots_per_tdd,&pucch_sched);
- nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
+ if (UE_list->fiveG_connected[UE_id] && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot%num_slots_per_tdd))) {
+ ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd;
+ nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched);
+ nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
// resetting ta flag
gNB->ta_len = 0;
}
if (UE_list->fiveG_connected[UE_id])
- nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP);
+ nr_schedule_pucch(module_idP, UE_id, nr_ulmix_slots, frame, slot);
/*
// Allocate CCEs for good after scheduling is done
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 705e1e2815..4c17ee3a0f 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -437,7 +437,10 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
NR_UE_list_t *UE_list = &mac->UE_list;
int UE_id = 0;
- AssertFatal(ra->state != RA_IDLE, "RA is not active for RA %X\n", ra->rnti);
+ if (ra->state == RA_IDLE) {
+ LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti);
+ return;
+ }
LOG_D(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
@@ -540,7 +543,7 @@ void nr_generate_Msg2(module_id_t module_idP,
sub_frame_t slotP){
int UE_id = 0, dci_formats[2], rnti_types[2], mcsIndex;
- int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment;
+ int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0;
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[0];
NR_RA_t *ra = &cc->ra[0];
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index cf2323f571..495095ce9e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -38,6 +38,7 @@
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
/*NFAPI*/
#include "nfapi_nr_interface.h"
@@ -76,6 +77,8 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
//NR_CellGroupConfig_t *config = UE_list->secondaryCellGroup[UE_id];
ue_sched_ctl = &(UE_list->UE_sched_ctrl[UE_id]);
+ NR_mac_stats_t *mac_stats = &(UE_list->mac_stats[UE_id]);
+
// 1) Compute MAC CE and related subheaders
// DRX command subheader (MAC CE size 0)
@@ -112,6 +115,8 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
ce_ptr += mac_ce_size;
mac_pdu_ptr += (unsigned char) mac_ce_size;
+
+
}
// Contention resolution fixed subheader and MAC CE
@@ -324,6 +329,8 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]);
dlsch_buffer_ptr += sdu_lengths[i];
mac_pdu_ptr += sdu_lengths[i];
+
+ mac_stats->lc_bytes_tx[sdu_lcids[i]] += sdu_lengths[i];
}
// 4) Compute final offset for padding
@@ -341,6 +348,70 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
return offset;
}
+void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10) {
+ // TODO
+ int max_harq_rounds = 4; // TODO define macro
+ int num_ucis = UL_info->uci_ind.num_ucis;
+ nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list;
+
+ for (int i = 0; i < num_ucis; i++) {
+ switch (uci_list[i].pdu_type) {
+ case NFAPI_NR_UCI_PDCCH_PDU_TYPE: break;
+
+ case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
+ //if (get_softmodem_params()->phy_test == 0) {
+ nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
+ // handle harq
+ int harq_idx_s = 0;
+ // tpc (power control)
+ sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
+ // iterate over received harq bits
+ for (int harq_bit = 0; harq_bit < uci_pdu->harq->num_harq; harq_bit++) {
+ // search for the right harq process
+ for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES; harq_idx++) {
+ // if the gNB received ack with a good confidence
+ if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
+ if ((uci_pdu->harq->harq_list[harq_bit].harq_value == 1) &&
+ (uci_pdu->harq->harq_confidence_level == 0)) {
+ // toggle NDI and reset round
+ sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
+ sched_ctrl->harq_processes[harq_idx].round = 0;
+ }
+ else
+ sched_ctrl->harq_processes[harq_idx].round++;
+ sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
+ harq_idx_s = harq_idx + 1;
+ // if the max harq rounds was reached
+ if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
+ sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
+ sched_ctrl->harq_processes[harq_idx].round = 0;
+ stats->dlsch_errors++;
+ }
+ break;
+ }
+ // if feedback slot processing is aborted
+ else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) &&
+ (sched_ctrl->harq_processes[harq_idx].is_waiting)) {
+ sched_ctrl->harq_processes[harq_idx].round++;
+ if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
+ sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
+ sched_ctrl->harq_processes[harq_idx].round = 0;
+ }
+ sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
+ }
+ }
+ }
+ //}
+ break;
+ }
+
+ case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: break;
+ }
+ }
+
+ UL_info->uci_ind.num_ucis = 0;
+}
+
/* functionalities of this function have been moved to nr_schedule_uss_dlsch_phytest */
void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 3e1c0e754e..3880240779 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -260,8 +260,6 @@ int configure_fapi_dl_pdu(int Mod_idP,
uint16_t *rbSize,
uint16_t *rbStart) {
-
-
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -322,7 +320,7 @@ int configure_fapi_dl_pdu(int Mod_idP,
pdsch_pdu_rel15->nrOfLayers = 1;
pdsch_pdu_rel15->transmissionScheme = 0;
pdsch_pdu_rel15->refPoint = 0; // Point A
-
+ UE_list->mac_stats[UE_id].dlsch_rounds[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++;
pdsch_pdu_rel15->dmrsConfigType = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
pdsch_pdu_rel15->SCID = 0;
@@ -457,6 +455,9 @@ int configure_fapi_dl_pdu(int Mod_idP,
// Hardcode it for now
TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0];
+ if (UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0)
+ UE_list->mac_stats[UE_id].dlsch_total_bytes += TBS;
+
LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d startSymbolAndLength %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n",
pdsch_pdu_rel15->rbStart,
pdsch_pdu_rel15->rbSize,
@@ -596,7 +597,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest frame %d slot %d\n",frameP,slotP);
int post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0;
- int lcid, offset, i, header_length_last, TBS_bytes;
+ int lcid, offset, i, header_length_last, TBS_bytes = 0;
int UE_id = 0, CC_id = 0;
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
@@ -630,70 +631,62 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
if (TBS_bytes == 0)
return;
-
- //The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving
- //through the LTE stack
- if (IS_SOFTMODEM_NOS1){
- for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
+ lcid = DL_SCH_LCID_DTCH;
- // TODO: check if the lcid is active
+ //for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
- LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n",
- module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3);
+ // TODO: check if the lcid is active
- if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) {
- rlc_status = mac_rlc_status_ind(module_idP,
- rnti,
- module_idP,
- frameP,
- slotP,
- ENB_FLAG_YES,
- MBMS_FLAG_NO,
- lcid,
- 0,
- 0);
+ LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n",
+ module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3);
- if (rlc_status.bytes_in_buffer > 0) {
+ //if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) {
+ rlc_status = mac_rlc_status_ind(module_idP,
+ rnti,
+ module_idP,
+ frameP,
+ slotP,
+ ENB_FLAG_YES,
+ MBMS_FLAG_NO,
+ lcid,
+ 0,
+ 0);
- LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n",
- module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
- lcid, header_length_total, TBS_bytes);
+ if (rlc_status.bytes_in_buffer > 0) {
- sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
- rnti,
- module_idP,
- frameP,
- ENB_FLAG_YES,
- MBMS_FLAG_NO,
- lcid,
- TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
- (char *)&mac_sdus[sdu_length_total],
- 0,
- 0);
+ LOG_I(MAC, "configure fapi due to data availability \n");
- LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid);
+ LOG_I(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n",
+ module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
+ lcid, header_length_total, TBS_bytes);
- sdu_lcids[num_sdus] = lcid;
- sdu_length_total += sdu_lengths[num_sdus];
- header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
- header_length_total += header_length_last;
+ sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
+ rnti,
+ module_idP,
+ frameP,
+ ENB_FLAG_YES,
+ MBMS_FLAG_NO,
+ lcid,
+ TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
+ (char *)&mac_sdus[sdu_length_total],
+ 0,
+ 0);
- num_sdus++;
+ LOG_W(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid);
- //ue_sched_ctl->uplane_inactivity_timer = 0;
- }
- } else { // no TBS_bytes left
- break;
- }
- }
+ sdu_lcids[num_sdus] = lcid;
+ sdu_length_total += sdu_lengths[num_sdus];
+ header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
+ header_length_total += header_length_last;
+
+ num_sdus++;
+
+ //ue_sched_ctl->uplane_inactivity_timer = 0;
+ }
- } //if (IS_SOFTMODEM_NOS1)
else {
- //When the --NOS1 option is not enabled, DLSCH transmissions with random data
- //occur every time that the current function is called (dlsch phytest mode)
-
LOG_D(MAC,"Configuring DL_TX in %d.%d\n", frameP, slotP);
// fill dlsch_buffer with random data
@@ -718,7 +711,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
}
#endif
- } // else IS_SOFTMODEM_NOS1
+ }
// there is at least one SDU or TA command
// if (num_sdus > 0 ){
@@ -761,14 +754,14 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
}
#endif
} else {
- #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
+#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
if (frameP%100 == 0){
LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes);
for(int i = 0; i < 10; i++) {
- LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]);
+ LOG_I(MAC, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]);
}
}
- #endif
+#endif
}
}
else { // There is no data from RLC or MAC header, so don't schedule
@@ -810,6 +803,7 @@ void schedule_fapi_ul_pdu(int Mod_idP,
frame_t frameP,
sub_frame_t slotP,
int num_slots_per_tdd,
+ int ul_slots,
int time_domain_assignment) {
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
@@ -857,7 +851,8 @@ void schedule_fapi_ul_pdu(int Mod_idP,
uint16_t rnti = UE_list->rnti[UE_id];
- NR_sched_pusch *pusch_sched = UE_list->UE_sched_ctrl[UE_id].sched_pusch;
+ int first_ul_slot = num_slots_per_tdd - ul_slots;
+ NR_sched_pusch *pusch_sched = &UE_list->UE_sched_ctrl[UE_id].sched_pusch[slotP+K2-first_ul_slot];
pusch_sched->frame = frameP;
pusch_sched->slot = slotP + K2;
pusch_sched->active = true;
@@ -1039,6 +1034,8 @@ void schedule_fapi_ul_pdu(int Mod_idP,
0,
pusch_pdu->nrOfLayers)>>3;
+ UE_list->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
+ if (cur_harq->round == 0) UE_list->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size;
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
//pusch_pdu->pusch_data.cb_present_and_position;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index d899669035..f4ec142da1 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -1465,8 +1465,17 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
memset((void *) &UE_list->UE_sched_ctrl[UE_id],
0,
sizeof(NR_UE_sched_ctrl_t));
+ UE_list->UE_sched_ctrl[UE_id].ul_rssi = 0;
UE_list->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch));
- UE_list->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(sizeof(NR_sched_pusch));
+ UE_list->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch));
+ for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k],
+ 0,
+ sizeof(NR_sched_pucch));
+ memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k],
+ 0,
+ sizeof(NR_sched_pusch));
+ }
LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n",
mod_idP,
UE_id,
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 7fe0d63efa..bb0dad7064 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -36,6 +36,7 @@
void nr_process_mac_pdu(
module_id_t module_idP,
+ rnti_t rnti,
uint8_t CC_id,
frame_t frameP,
uint8_t *pduP,
@@ -210,7 +211,8 @@ void nr_process_mac_pdu(
}
LOG_D(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len);
-
+ int UE_id = find_nr_UE_id(module_idP, rnti);
+ RC.nrmac[module_idP]->UE_list.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
@@ -219,25 +221,33 @@ void nr_process_mac_pdu(
LOG_T(MAC, "\n");
#endif
-
- if (IS_SOFTMODEM_NOS1){
- if (rx_lcid < NB_RB_MAX && rx_lcid >= UL_SCH_LCID_DTCH) {
-
- mac_rlc_data_ind(module_idP,
- 0x1234,
- module_idP,
- frameP,
- ENB_FLAG_YES,
- MBMS_FLAG_NO,
- rx_lcid,
- (char *) (pdu_ptr + mac_subheader_len),
- mac_sdu_len,
- 1,
- NULL);
- } else {
- LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, module_idP);
- }
+ if(IS_SOFTMODEM_NOS1){
+ mac_rlc_data_ind(module_idP,
+ 0x1234,
+ module_idP,
+ frameP,
+ ENB_FLAG_YES,
+ MBMS_FLAG_NO,
+ rx_lcid,
+ (char *) (pdu_ptr + mac_subheader_len),
+ mac_sdu_len,
+ 1,
+ NULL);
}
+ else{
+ mac_rlc_data_ind(module_idP,
+ rnti,
+ module_idP,
+ frameP,
+ ENB_FLAG_YES,
+ MBMS_FLAG_NO,
+ rx_lcid,
+ (char *) (pdu_ptr + mac_subheader_len),
+ mac_sdu_len,
+ 1,
+ NULL);
+ }
+
break;
@@ -255,6 +265,39 @@ void nr_process_mac_pdu(
}
}
+void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu) {
+
+ int max_harq_rounds = 4; // TODO define macro
+ uint8_t hrq_id = crc_pdu.harq_id;
+ NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id];
+ if (cur_harq->state==ACTIVE_SCHED) {
+ if (!crc_pdu.tb_crc_status) {
+ cur_harq->ndi ^= 1;
+ cur_harq->round = 0;
+ cur_harq->state = INACTIVE; // passed -> make inactive. can be used by scheduder for next grant
+#ifdef UL_HARQ_PRINT
+ printf("[HARQ HANDLER] Ulharq id %d crc passed, freeing it for scheduler\n",hrq_id);
+#endif
+ } else {
+ cur_harq->round++;
+ cur_harq->state = ACTIVE_NOT_SCHED;
+#ifdef UL_HARQ_PRINT
+ printf("[HARQ HANDLER] Ulharq id %d crc failed, requesting retransmission\n",hrq_id);
+#endif
+ }
+
+ if (!(cur_harq->roundndi ^= 1;
+ cur_harq->state = INACTIVE; // failed after 4 rounds -> make inactive
+ cur_harq->round = 0;
+ LOG_D(MAC,"[HARQ HANDLER] RNTI %x: Ulharq id %d crc failed in all round, freeing it for scheduler\n",crc_pdu.rnti,hrq_id);
+ stats->ulsch_errors++;
+ }
+ return;
+ } else
+ LOG_E(MAC,"Incorrect ULSCH HARQ process %d or invalid state %d\n",hrq_id,cur_harq->state);
+}
+
/*
* When data are received on PHY and transmitted to MAC
*/
@@ -266,7 +309,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
uint8_t *sduP,
const uint16_t sdu_lenP,
const uint16_t timing_advance,
- const uint8_t ul_cqi){
+ const uint8_t ul_cqi,
+ const uint16_t rssi){
int current_rnti = 0, UE_id = -1, harq_pid = 0;
gNB_MAC_INST *gNB_mac = NULL;
NR_UE_list_t *UE_list = NULL;
@@ -281,6 +325,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
if (UE_id != -1) {
UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
+ UE_list->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
gnb_mod_idP,
harq_pid,
@@ -291,6 +336,17 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
UE_id,
ul_cqi);
+ // if not missed detection (10dB threshold for now)
+ if (UE_scheduling_control->ul_rssi < (100+rssi)) {
+ UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
+ UE_scheduling_control->ta_update = timing_advance;
+ UE_scheduling_control->ul_rssi = rssi;
+ LOG_D(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
+ }
+ else{
+ UE_scheduling_control->tpc0 = 1;
+ }
+
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n");
for (int i = 0; i < sdu_lenP ; i++) {
@@ -302,11 +358,11 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
#endif
if (sduP != NULL){
- UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
- UE_scheduling_control->ta_update = timing_advance;
- LOG_I(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
LOG_D(MAC, "Received PDU at MAC gNB \n");
- nr_process_mac_pdu(gnb_mod_idP, CC_idP, frameP, sduP, sdu_lenP);
+ nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP);
+ }
+ else {
+
}
}
else {
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 7dd956927b..7caf1baed5 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -64,7 +64,6 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
sub_frame_t subframeP);
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
- frame_t frame_txP, sub_frame_t slot_txP,
frame_t frame_rxP, sub_frame_t slot_rxP);
int nr_generate_dlsch_pdu(module_id_t Mod_idP,
@@ -158,9 +157,17 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
void nr_schedule_pusch(int Mod_idP,
int UE_id,
+ int num_slots_per_tdd,
+ int ul_slots,
frame_t frameP,
sub_frame_t slotP);
+void nr_schedule_pucch(int Mod_idP,
+ int UE_id,
+ int nr_ulmix_slots,
+ frame_t frameP,
+ sub_frame_t slotP);
+
void nr_update_pucch_scheduling(int Mod_idP,
int UE_id,
frame_t frameP,
@@ -297,10 +304,12 @@ void schedule_fapi_ul_pdu(int Mod_idP,
frame_t frameP,
sub_frame_t slotP,
int num_slots_per_tdd,
+ int ul_slots,
int time_domain_assignment);
void nr_process_mac_pdu(
module_id_t module_idP,
+ rnti_t rnti,
uint8_t CC_id,
frame_t frameP,
uint8_t *pduP,
@@ -327,6 +336,11 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
const rnti_t rntiP,
uint8_t * sduP,
const uint16_t sdu_lenP,
- const uint16_t timing_advance, const uint8_t ul_cqi);
+ const uint16_t timing_advance,
+ const uint8_t ul_cqi,
+ const uint16_t rssi);
+void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu);
+
+void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index 873deddbe7..bd0be8c409 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -35,6 +35,7 @@
#include "assertions.h"
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
+#include "LAYER2/nr_pdcp/nr_pdcp_entity.h"
#include "RRC/NR/nr_rrc_defs.h"
#include "common/utils/LOG/log.h"
//#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
@@ -89,7 +90,7 @@ void mac_top_init_gNB(void)
pdcp_layer_init();
if(IS_SOFTMODEM_NOS1)
- nr_ip_over_LTE_DRB_preconfiguration();
+ nr_DRB_preconfiguration();
rrc_init_nr_global_param();
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 7d59deb9ae..bd8f0208c6 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -251,6 +251,7 @@ typedef struct NR_sched_pucch {
uint8_t dai_c;
uint8_t timing_indicator;
uint8_t resource_indicator;
+ bool active;
} NR_sched_pucch;
typedef struct NR_sched_pusch {
@@ -290,6 +291,7 @@ typedef struct {
int16_t ta_update;
uint8_t tpc0;
uint8_t tpc1;
+ uint16_t ul_rssi;
uint8_t current_harq_pid;
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
NR_UE_ul_harq_t ul_harq_processes[NR_MAX_NB_HARQ_PROCESSES];
@@ -302,11 +304,25 @@ typedef struct NR_preamble_ue {
uint8_t *preamble_list;
} NR_preamble_ue;
+typedef struct {
+
+ int lc_bytes_tx[64];
+ int lc_bytes_rx[64];
+ int dlsch_rounds[8];
+ int dlsch_errors;
+ int dlsch_total_bytes;
+ int ulsch_rounds[8];
+ int ulsch_errors;
+ int ulsch_total_bytes_scheduled;
+ int ulsch_total_bytes_rx;
+} NR_mac_stats_t;
+
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
typedef struct {
DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB];
/// scheduling control info
NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
+ NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB];
int next[MAX_MOBILES_PER_GNB];
int head;
int next_ul[MAX_MOBILES_PER_GNB];
@@ -329,10 +345,6 @@ typedef struct gNB_MAC_INST_s {
eth_params_t eth_params_s;
/// Module
module_id_t Mod_id;
- /// frame counter
- frame_t frame;
- /// slot counter
- int slot;
/// timing advance group
NR_TAG_t *tag;
/// Pointer to IF module instance for PHY
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index 3667af2698..33f268f07f 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -2353,101 +2353,6 @@ void pdcp_module_cleanup (void)
{
}
-void nr_ip_over_LTE_DRB_preconfiguration(void){
-
- // Addition for the use-case of 4G stack on top of 5G-NR.
- // We need to configure pdcp and rlc instances without having an actual
- // UE RRC Connection. In order to be able to test the NR PHY with some injected traffic
- // on top of the LTE stack.
- protocol_ctxt_t ctxt;
- LTE_DRB_ToAddModList_t* DRB_configList=NULL;
- DRB_configList = CALLOC(1, sizeof(LTE_DRB_ToAddModList_t));
- struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL;
- struct LTE_RLC_Config *DRB_rlc_config = NULL;
- struct LTE_PDCP_Config *DRB_pdcp_config = NULL;
- struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL;
-
- struct LTE_DRB_ToAddMod *DRB_config = NULL;
- struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL;
- long *logicalchannelgroup_drb;
-
-
- //Static preconfiguration of DRB
- DRB_config = CALLOC(1, sizeof(*DRB_config));
-
- DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
- // allowed value 5..15, value : x+4
- *(DRB_config->eps_BearerIdentity) = 1; //ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation
- // DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
- // 1 + drb_identiy_index;
- DRB_config->drb_Identity = 1;
- DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
- *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 3; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
-
- DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
- DRB_config->rlc_Config = DRB_rlc_config;
-
- DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
- DRB_config->pdcp_Config = DRB_pdcp_config;
- DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
- *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
- DRB_pdcp_config->rlc_AM = NULL;
- DRB_pdcp_config->rlc_UM = NULL;
-
- DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
- DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
- DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
- DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35;
- // PDCP
- PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
- DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
- PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
-
- DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
-
- DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config));
- DRB_config->logicalChannelConfig = DRB_lchan_config;
- DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
- DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;
-
- DRB_ul_SpecificParameters->priority= 4;
-
- DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
- //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
- DRB_ul_SpecificParameters->bucketSizeDuration =
- LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
-
- logicalchannelgroup_drb = CALLOC(1, sizeof(long));
- *logicalchannelgroup_drb = 1;//(i+1) % 3;
- DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
-
- ASN_SEQUENCE_ADD(&DRB_configList->list,DRB_config);
-
- if (ENB_NAS_USE_TUN){
- PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0);
- }
- else{
- PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0);
- }
-
- rrc_pdcp_config_asn1_req(&ctxt,
- (LTE_SRB_ToAddModList_t *) NULL,
- DRB_configList,
- (LTE_DRB_ToReleaseList_t *) NULL,
- 0xff, NULL, NULL, NULL
- , (LTE_PMCH_InfoList_r9_t *) NULL,
- &DRB_config->drb_Identity);
-
- rrc_rlc_config_asn1_req(&ctxt,
- (LTE_SRB_ToAddModList_t*)NULL,
- DRB_configList,
- (LTE_DRB_ToReleaseList_t*)NULL
- //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
- ,(LTE_PMCH_InfoList_r9_t *)NULL
- , 0, 0
- //#endif
- );
-}
//-----------------------------------------------------------------------------
void pdcp_layer_init(void)
//-----------------------------------------------------------------------------
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 6c6bd30070..c9a62d573b 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -310,7 +310,7 @@ int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_p
ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
if (h_rc == HASH_TABLE_OK) {
- LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %ld \n",
+ LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %ld \n",
ctxt.frame, ctxt.instance, len, rab_id);
LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %ld]\n",
ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c
index 2fb844f05a..98c8c3e252 100644
--- a/openair2/LAYER2/RLC/rlc.c
+++ b/openair2/LAYER2/RLC/rlc.c
@@ -519,7 +519,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP,
// LOG_I(RLC,"DUY rlc_data_req: mbms_rb_id in RLC instant is: %d\n", mbms_rb_id);
if (sdu_pP != NULL) {
if (sdu_sizeP > 0) {
- LOG_I(RLC,"received a packet with size %d for MBMS \n", sdu_sizeP);
+ LOG_D(RLC,"received a packet with size %d for MBMS \n", sdu_sizeP);
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__);
if (new_sdu_p != NULL) {
diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c
index 85ee4e0571..4313f379fe 100644
--- a/openair2/LAYER2/RLC/rlc_rrc.c
+++ b/openair2/LAYER2/RLC/rlc_rrc.c
@@ -640,7 +640,8 @@ rlc_union_t *rrc_rlc_add_rlc (
} else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) {
rlc_union_p = calloc(1, sizeof(rlc_union_t));
h_rc = hashtable_insert(rlc_coll_p, key, rlc_union_p);
- h_lcid_rc = hashtable_insert(rlc_coll_p, key_lcid, rlc_union_p);
+ if(MBMS_flagP != TRUE)
+ h_lcid_rc = hashtable_insert(rlc_coll_p, key_lcid, rlc_union_p);
if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) {
if (MBMS_flagP == TRUE) {
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
new file mode 100644
index 0000000000..e25201c22c
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
@@ -0,0 +1,74 @@
+/*
+ * 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.1 (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 "nr_pdcp_entity.h"
+
+#include "nr_pdcp_entity_drb_am.h"
+
+#include "LOG/log.h"
+
+nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
+ int rb_id,
+ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
+ char *buf, int size),
+ void *deliver_sdu_data,
+ void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
+ char *buf, int size, int sdu_id),
+ void *deliver_pdu_data)
+{
+ abort();
+}
+
+nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
+ int rb_id,
+ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
+ char *buf, int size),
+ void *deliver_sdu_data,
+ void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
+ char *buf, int size, int sdu_id),
+ void *deliver_pdu_data)
+{
+ nr_pdcp_entity_drb_am_t *ret;
+
+ ret = calloc(1, sizeof(nr_pdcp_entity_drb_am_t));
+ if (ret == NULL) {
+ LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ ret->common.recv_pdu = nr_pdcp_entity_drb_am_recv_pdu;
+ ret->common.recv_sdu = nr_pdcp_entity_drb_am_recv_sdu;
+ ret->common.set_integrity_key = nr_pdcp_entity_drb_am_set_integrity_key;
+
+ ret->common.delete = nr_pdcp_entity_drb_am_delete;
+
+ ret->common.deliver_sdu = deliver_sdu;
+ ret->common.deliver_sdu_data = deliver_sdu_data;
+
+ ret->common.deliver_pdu = deliver_pdu;
+ ret->common.deliver_pdu_data = deliver_pdu_data;
+
+ ret->rb_id = rb_id;
+
+ ret->common.maximum_nr_pdcp_sn = 4095;
+
+ return (nr_pdcp_entity_t *)ret;
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
new file mode 100644
index 0000000000..45555ad6af
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
@@ -0,0 +1,65 @@
+/*
+ * 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.1 (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 _NR_PDCP_ENTITY_H_
+#define _NR_PDCP_ENTITY_H_
+
+typedef struct nr_pdcp_entity_t {
+ /* functions provided by the PDCP module */
+ void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
+ void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
+ int sdu_id);
+ void (*delete)(struct nr_pdcp_entity_t *entity);
+ void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key);
+
+ /* callbacks provided to the PDCP module */
+ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
+ char *buf, int size);
+ void *deliver_sdu_data;
+ void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
+ char *buf, int size, int sdu_id);
+ void *deliver_pdu_data;
+ int tx_hfn;
+ int next_nr_pdcp_tx_sn;
+ int maximum_nr_pdcp_sn;
+} nr_pdcp_entity_t;
+
+nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
+ int rb_id,
+ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
+ char *buf, int size),
+ void *deliver_sdu_data,
+ void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
+ char *buf, int size, int sdu_id),
+ void *deliver_pdu_data);
+
+nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
+ int rb_id,
+ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
+ char *buf, int size),
+ void *deliver_sdu_data,
+ void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
+ char *buf, int size, int sdu_id),
+ void *deliver_pdu_data);
+
+void nr_DRB_preconfiguration(void);
+
+#endif /* _NR_PDCP_ENTITY_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
new file mode 100644
index 0000000000..85f638d66d
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
@@ -0,0 +1,71 @@
+/*
+ * 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.1 (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 "nr_pdcp_entity_drb_am.h"
+
+#include
+#include
+#include
+
+void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size)
+{
+ nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
+
+ if (size < 3) abort();
+ if (!(buffer[0] & 0x80)) { printf("%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); }
+ entity->common.deliver_sdu(entity->common.deliver_sdu_data,
+ (nr_pdcp_entity_t *)entity, buffer+3, size-3);
+}
+
+void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size,
+ int sdu_id)
+{
+ nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
+ int sn;
+ char buf[size+2];
+
+ sn = entity->common.next_nr_pdcp_tx_sn;
+
+ entity->common.next_nr_pdcp_tx_sn++;
+ if (entity->common.next_nr_pdcp_tx_sn > entity->common.maximum_nr_pdcp_sn) {
+ entity->common.next_nr_pdcp_tx_sn = 0;
+ entity->common.tx_hfn++;
+ }
+
+ buf[0] = 0x80 | ((sn >> 16) & 0x3);
+ buf[1] = (sn >> 8) & 0xff;
+ buf[2] = sn & 0xff;
+ memcpy(buf+3, buffer, size);
+
+ entity->common.deliver_pdu(entity->common.deliver_pdu_data,
+ (nr_pdcp_entity_t *)entity, buf, size+3, sdu_id);
+}
+
+void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *key)
+{
+ /* nothing to do */
+}
+
+void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity)
+{
+ nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
+ free(entity);
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h
new file mode 100644
index 0000000000..faa8226e93
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h
@@ -0,0 +1,38 @@
+/*
+ * 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.1 (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 _NR_PDCP_ENTITY_DRB_AM_H_
+#define _NR_PDCP_ENTITY_DRB_AM_H_
+
+#include "nr_pdcp_entity.h"
+
+typedef struct {
+ nr_pdcp_entity_t common;
+ int rb_id;
+} nr_pdcp_entity_drb_am_t;
+
+void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size);
+void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *entity, char *buffer, int size,
+ int sdu_id);
+void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *entity, char *key);
+void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *entity);
+
+#endif /* _NR_PDCP_ENTITY_DRB_AM_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
new file mode 100644
index 0000000000..c8b385bbfc
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -0,0 +1,946 @@
+/*
+ * 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.1 (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 "nr_pdcp_ue_manager.h"
+#include "NR_RadioBearerConfig.h"
+#include "NR_RLC-BearerConfig.h"
+#include "NR_CellGroupConfig.h"
+#include "openair2/RRC/NR/nr_rrc_proto.h"
+
+/* from OAI */
+#include "pdcp.h"
+
+#define TODO do { \
+ printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \
+ exit(1); \
+ } while (0)
+
+static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
+
+/* necessary globals for OAI, not used internally */
+hash_table_t *pdcp_coll_p;
+static uint64_t pdcp_optmask;
+
+/****************************************************************************/
+/* rlc_data_req queue - begin */
+/****************************************************************************/
+
+#include
+
+/* NR PDCP and RLC both use "big locks". In some cases a thread may do
+ * lock(rlc) followed by lock(pdcp) (typically when running 'rx_sdu').
+ * Another thread may first do lock(pdcp) and then lock(rlc) (typically
+ * the GTP module calls 'pdcp_data_req' that, in a previous implementation
+ * was indirectly calling 'rlc_data_req' which does lock(rlc)).
+ * To avoid the resulting deadlock it is enough to ensure that a call
+ * to lock(pdcp) will never be followed by a call to lock(rlc). So,
+ * here we chose to have a separate thread that deals with rlc_data_req,
+ * out of the PDCP lock. Other solutions may be possible.
+ * So instead of calling 'rlc_data_req' directly we have a queue and a
+ * separate thread emptying it.
+ */
+
+typedef struct {
+ protocol_ctxt_t ctxt_pP;
+ srb_flag_t srb_flagP;
+ MBMS_flag_t MBMS_flagP;
+ rb_id_t rb_idP;
+ mui_t muiP;
+ confirm_t confirmP;
+ sdu_size_t sdu_sizeP;
+ mem_block_t *sdu_pP;
+} rlc_data_req_queue_item;
+
+#define RLC_DATA_REQ_QUEUE_SIZE 10000
+
+typedef struct {
+ rlc_data_req_queue_item q[RLC_DATA_REQ_QUEUE_SIZE];
+ volatile int start;
+ volatile int length;
+ pthread_mutex_t m;
+ pthread_cond_t c;
+} rlc_data_req_queue;
+
+static rlc_data_req_queue q;
+
+extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
+ const NR_SRB_ToAddModList_t * const srb2add_listP,
+ const NR_DRB_ToAddModList_t * const drb2add_listP,
+ const NR_DRB_ToReleaseList_t * const drb2release_listP,
+ const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
+ struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
+
+static void *rlc_data_req_thread(void *_)
+{
+ int i;
+
+ while (1) {
+ if (pthread_mutex_lock(&q.m) != 0) abort();
+ while (q.length == 0)
+ if (pthread_cond_wait(&q.c, &q.m) != 0) abort();
+ i = q.start;
+ if (pthread_mutex_unlock(&q.m) != 0) abort();
+
+ rlc_data_req(&q.q[i].ctxt_pP,
+ q.q[i].srb_flagP,
+ q.q[i].MBMS_flagP,
+ q.q[i].rb_idP,
+ q.q[i].muiP,
+ q.q[i].confirmP,
+ q.q[i].sdu_sizeP,
+ q.q[i].sdu_pP,
+ NULL,
+ NULL);
+
+ if (pthread_mutex_lock(&q.m) != 0) abort();
+
+ q.length--;
+ q.start = (q.start + 1) % RLC_DATA_REQ_QUEUE_SIZE;
+
+ if (pthread_cond_signal(&q.c) != 0) abort();
+ if (pthread_mutex_unlock(&q.m) != 0) abort();
+ }
+}
+
+static void init_nr_rlc_data_req_queue(void)
+{
+ pthread_t t;
+
+ pthread_mutex_init(&q.m, NULL);
+ pthread_cond_init(&q.c, NULL);
+
+ if (pthread_create(&t, NULL, rlc_data_req_thread, NULL) != 0) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+}
+
+static void enqueue_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
+ const srb_flag_t srb_flagP,
+ const MBMS_flag_t MBMS_flagP,
+ const rb_id_t rb_idP,
+ const mui_t muiP,
+ confirm_t confirmP,
+ sdu_size_t sdu_sizeP,
+ mem_block_t *sdu_pP,
+ void *_unused1, void *_unused2)
+{
+ int i;
+ int logged = 0;
+
+ if (pthread_mutex_lock(&q.m) != 0) abort();
+ while (q.length == RLC_DATA_REQ_QUEUE_SIZE) {
+ if (!logged) {
+ logged = 1;
+ LOG_W(PDCP, "%s: rlc_data_req queue is full\n", __FUNCTION__);
+ }
+ if (pthread_cond_wait(&q.c, &q.m) != 0) abort();
+ }
+
+ i = (q.start + q.length) % RLC_DATA_REQ_QUEUE_SIZE;
+ q.length++;
+
+ q.q[i].ctxt_pP = *ctxt_pP;
+ q.q[i].srb_flagP = srb_flagP;
+ q.q[i].MBMS_flagP = MBMS_flagP;
+ q.q[i].rb_idP = rb_idP;
+ q.q[i].muiP = muiP;
+ q.q[i].confirmP = confirmP;
+ q.q[i].sdu_sizeP = sdu_sizeP;
+ q.q[i].sdu_pP = sdu_pP;
+
+ if (pthread_cond_signal(&q.c) != 0) abort();
+ if (pthread_mutex_unlock(&q.m) != 0) abort();
+}
+
+/****************************************************************************/
+/* rlc_data_req queue - end */
+/****************************************************************************/
+
+/****************************************************************************/
+/* hacks to be cleaned up at some point - begin */
+/****************************************************************************/
+
+#include "LAYER2/MAC/mac_extern.h"
+
+static void reblock_tun_socket(void)
+{
+ extern int nas_sock_fd[];
+ int f;
+
+ f = fcntl(nas_sock_fd[0], F_GETFL, 0);
+ f &= ~(O_NONBLOCK);
+ if (fcntl(nas_sock_fd[0], F_SETFL, f) == -1) {
+ LOG_E(PDCP, "reblock_tun_socket failed\n");
+ exit(1);
+ }
+}
+
+static void *enb_tun_read_thread(void *_)
+{
+ extern int nas_sock_fd[];
+ char rx_buf[NL_MAX_PAYLOAD];
+ int len;
+ int rnti;
+ protocol_ctxt_t ctxt;
+
+ int rb_id = 1;
+
+ while (1) {
+ len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD);
+ if (len == -1) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+printf("\n\n\n########## nas_sock_fd read returns len %d\n", len);
+
+ nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+ rnti = nr_pdcp_get_first_rnti(nr_pdcp_ue_manager);
+ nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+
+ if (rnti == -1) continue;
+
+ ctxt.module_id = 0;
+ ctxt.enb_flag = 1;
+ ctxt.instance = 0;
+ ctxt.frame = 0;
+ ctxt.subframe = 0;
+ ctxt.eNB_index = 0;
+ ctxt.configured = 1;
+ ctxt.brOption = 0;
+
+ ctxt.rnti = rnti;
+
+ pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
+ RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf,
+ PDCP_TRANSMISSION_MODE_DATA, NULL, NULL);
+ }
+
+ return NULL;
+}
+
+static void *ue_tun_read_thread(void *_)
+{
+ extern int nas_sock_fd[];
+ char rx_buf[NL_MAX_PAYLOAD];
+ int len;
+ int rnti;
+ protocol_ctxt_t ctxt;
+
+ int rb_id = 1;
+
+ while (1) {
+ len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD);
+ if (len == -1) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+printf("\n\n\n########## nas_sock_fd read returns len %d\n", len);
+
+ nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+ rnti = nr_pdcp_get_first_rnti(nr_pdcp_ue_manager);
+ nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+
+ if (rnti == -1) continue;
+
+ ctxt.module_id = 0;
+ ctxt.enb_flag = 0;
+ ctxt.instance = 0;
+ ctxt.frame = 0;
+ ctxt.subframe = 0;
+ ctxt.eNB_index = 0;
+ ctxt.configured = 1;
+ ctxt.brOption = 0;
+
+ ctxt.rnti = rnti;
+
+ pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
+ RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf,
+ PDCP_TRANSMISSION_MODE_DATA, NULL, NULL);
+ }
+
+ return NULL;
+}
+
+static void start_pdcp_tun_enb(void)
+{
+ pthread_t t;
+
+ reblock_tun_socket();
+
+ if (pthread_create(&t, NULL, enb_tun_read_thread, NULL) != 0) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+}
+
+static void start_pdcp_tun_ue(void)
+{
+ pthread_t t;
+
+ reblock_tun_socket();
+
+ if (pthread_create(&t, NULL, ue_tun_read_thread, NULL) != 0) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+}
+
+/****************************************************************************/
+/* hacks to be cleaned up at some point - end */
+/****************************************************************************/
+
+int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP)
+{
+ return 0;
+}
+
+void pdcp_layer_init(void)
+{
+ /* hack: be sure to initialize only once */
+ static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+ static int initialized = 0;
+ if (pthread_mutex_lock(&m) != 0) abort();
+ if (initialized) {
+ if (pthread_mutex_unlock(&m) != 0) abort();
+ return;
+ }
+ initialized = 1;
+ if (pthread_mutex_unlock(&m) != 0) abort();
+
+ nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
+ init_nr_rlc_data_req_queue();
+}
+
+#include "nfapi/oai_integration/vendor_ext.h"
+#include "targets/RT/USER/lte-softmodem.h"
+#include "openair2/RRC/NAS/nas_config.h"
+
+uint64_t pdcp_module_init(uint64_t _pdcp_optmask)
+{
+ /* hack: be sure to initialize only once */
+ static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+ static int initialized = 0;
+ if (pthread_mutex_lock(&m) != 0) abort();
+ if (initialized) {
+ abort();
+ }
+ initialized = 1;
+ if (pthread_mutex_unlock(&m) != 0) abort();
+
+#if 0
+ pdcp_optmask = _pdcp_optmask;
+ return pdcp_optmask;
+#endif
+ /* temporary enforce netlink when UE_NAS_USE_TUN is set,
+ this is while switching from noS1 as build option
+ to noS1 as config option */
+ if ( _pdcp_optmask & UE_NAS_USE_TUN_BIT) {
+ pdcp_optmask = pdcp_optmask | PDCP_USE_NETLINK_BIT ;
+ }
+
+ pdcp_optmask = pdcp_optmask | _pdcp_optmask ;
+ LOG_I(PDCP, "pdcp init,%s %s\n",
+ ((LINK_ENB_PDCP_TO_GTPV1U)?"usegtp":""),
+ ((PDCP_USE_NETLINK)?"usenetlink":""));
+
+ if (PDCP_USE_NETLINK) {
+ nas_getparams();
+
+ if(UE_NAS_USE_TUN) {
+ int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1;
+ netlink_init_tun("ue",num_if);
+ //Add --nr-ip-over-lte option check for next line
+ if (IS_SOFTMODEM_NOS1)
+ nas_config(1, 1, 2, "ue");
+ LOG_I(PDCP, "UE pdcp will use tun interface\n");
+ start_pdcp_tun_ue();
+ } else if(ENB_NAS_USE_TUN) {
+ netlink_init_tun("enb",1);
+ nas_config(1, 1, 1, "enb");
+ LOG_I(PDCP, "ENB pdcp will use tun interface\n");
+ start_pdcp_tun_enb();
+ } else {
+ LOG_I(PDCP, "pdcp will use kernel modules\n");
+ abort();
+ netlink_init();
+ }
+ }
+ return pdcp_optmask ;
+}
+
+static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
+ char *buf, int size)
+{
+ extern int nas_sock_fd[];
+ int len;
+ nr_pdcp_ue_t *ue = _ue;
+ MessageDef *message_p;
+ uint8_t *gtpu_buffer_p;
+ int rb_id;
+ int i;
+
+ if(IS_SOFTMODEM_NOS1){
+ len = write(nas_sock_fd[0], buf, size);
+ if (len != size) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+ }
+ else{
+ for (i = 0; i < 5; i++) {
+ if (entity == ue->drb[i]) {
+ rb_id = i+1;
+ goto rb_found;
+ }
+ }
+
+ LOG_E(PDCP, "%s:%d:%s: fatal, no RB found for ue %d\n",
+ __FILE__, __LINE__, __FUNCTION__, ue->rnti);
+ exit(1);
+
+ rb_found:
+ gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U,
+ size + GTPU_HEADER_OVERHEAD_MAX);
+ AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
+ memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf, size);
+ message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_ENB_TUNNEL_DATA_REQ);
+ AssertFatal(message_p != NULL, "OUT OF MEMORY");
+ GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p;
+ GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length = size;
+ GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
+ GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti;
+ GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4;
+ printf("!!!!!!! deliver_sdu_drb (drb %d) sending message to gtp size %d: ", rb_id, size);
+ //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]);
+ printf("\n");
+ itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
+
+ }
+}
+
+static void deliver_pdu_drb(void *_ue, nr_pdcp_entity_t *entity,
+ char *buf, int size, int sdu_id)
+{
+ nr_pdcp_ue_t *ue = _ue;
+ int rb_id;
+ protocol_ctxt_t ctxt;
+ int i;
+ mem_block_t *memblock;
+
+ for (i = 0; i < 5; i++) {
+ if (entity == ue->drb[i]) {
+ rb_id = i+1;
+ goto rb_found;
+ }
+ }
+
+ LOG_E(PDCP, "%s:%d:%s: fatal, no RB found for ue %d\n",
+ __FILE__, __LINE__, __FUNCTION__, ue->rnti);
+ exit(1);
+
+rb_found:
+ ctxt.module_id = 0;
+ ctxt.enb_flag = 1;
+ ctxt.instance = 0;
+ ctxt.frame = 0;
+ ctxt.subframe = 0;
+ ctxt.eNB_index = 0;
+ ctxt.configured = 1;
+ ctxt.brOption = 0;
+
+ ctxt.rnti = ue->rnti;
+
+ memblock = get_free_mem_block(size, __FUNCTION__);
+ memcpy(memblock->data, buf, size);
+
+printf("!!!!!!! deliver_pdu_drb (srb %d) calling rlc_data_req size %d: ", rb_id, size);
+//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
+printf("\n");
+ enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock, NULL, NULL);
+}
+
+boolean_t pdcp_data_ind(
+ const protocol_ctxt_t *const ctxt_pP,
+ const srb_flag_t srb_flagP,
+ const MBMS_flag_t MBMS_flagP,
+ const rb_id_t rb_id,
+ const sdu_size_t sdu_buffer_size,
+ mem_block_t *const sdu_buffer)
+{
+ nr_pdcp_ue_t *ue;
+ nr_pdcp_entity_t *rb;
+ int rnti = ctxt_pP->rnti;
+
+ if (ctxt_pP->module_id != 0 ||
+ //ctxt_pP->enb_flag != 1 ||
+ ctxt_pP->instance != 0 ||
+ ctxt_pP->eNB_index != 0 ||
+ ctxt_pP->configured != 1 ||
+ ctxt_pP->brOption != 0) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ if (ctxt_pP->enb_flag)
+ T(T_ENB_PDCP_UL, T_INT(ctxt_pP->module_id), T_INT(rnti),
+ T_INT(rb_id), T_INT(sdu_buffer_size));
+
+ nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+ ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
+
+ if (srb_flagP == 1) {
+ if (rb_id < 1 || rb_id > 2)
+ rb = NULL;
+ else
+ rb = ue->srb[rb_id - 1];
+ } else {
+ if (rb_id < 1 || rb_id > 5)
+ rb = NULL;
+ else
+ rb = ue->drb[rb_id - 1];
+ }
+
+ if (rb != NULL) {
+ rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size);
+ } else {
+ LOG_E(PDCP, "%s:%d:%s: fatal: no RB found (rb_id %ld, srb_flag %d)\n",
+ __FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP);
+ exit(1);
+ }
+
+ nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+
+ free_mem_block(sdu_buffer, __FUNCTION__);
+
+ return 1;
+}
+
+void pdcp_run(const protocol_ctxt_t *const ctxt_pP)
+{
+ MessageDef *msg_p;
+ int result;
+ protocol_ctxt_t ctxt;
+
+ while (1) {
+ itti_poll_msg(ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, &msg_p);
+ if (msg_p == NULL)
+ break;
+ switch (ITTI_MSG_ID(msg_p)) {
+ case RRC_DCCH_DATA_REQ:
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(
+ &ctxt,
+ RRC_DCCH_DATA_REQ(msg_p).module_id,
+ RRC_DCCH_DATA_REQ(msg_p).enb_flag,
+ RRC_DCCH_DATA_REQ(msg_p).rnti,
+ RRC_DCCH_DATA_REQ(msg_p).frame,
+ 0,
+ RRC_DCCH_DATA_REQ(msg_p).eNB_index);
+ result = pdcp_data_req(&ctxt,
+ SRB_FLAG_YES,
+ RRC_DCCH_DATA_REQ(msg_p).rb_id,
+ RRC_DCCH_DATA_REQ(msg_p).muip,
+ RRC_DCCH_DATA_REQ(msg_p).confirmp,
+ RRC_DCCH_DATA_REQ(msg_p).sdu_size,
+ RRC_DCCH_DATA_REQ(msg_p).sdu_p,
+ RRC_DCCH_DATA_REQ(msg_p).mode,
+ NULL, NULL);
+
+ if (result != TRUE)
+ LOG_E(PDCP, "PDCP data request failed!\n");
+ result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ(msg_p).sdu_p);
+ AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+ break;
+ default:
+ LOG_E(PDCP, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p));
+ break;
+ }
+ }
+}
+
+static void add_srb(int rnti, struct NR_SRB_ToAddMod *s)
+{
+ TODO;
+}
+
+static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
+{
+ nr_pdcp_entity_t *pdcp_drb;
+ nr_pdcp_ue_t *ue;
+
+ int drb_id = s->drb_Identity;
+
+printf("\n\n################# rnti %d add drb %d\n\n\n", rnti, drb_id);
+
+ if (drb_id != 1) {
+ LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id %d\n",
+ __FILE__, __LINE__, __FUNCTION__, drb_id);
+ exit(1);
+ }
+
+ nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+ ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
+ if (ue->drb[drb_id-1] != NULL) {
+ LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
+ __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
+ } else {
+ pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue);
+ nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
+
+ LOG_D(PDCP, "%s:%d:%s: added drb %d to ue %d\n",
+ __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
+ }
+ nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+}
+
+static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config)
+{
+ switch (rlc_Config->present) {
+ case NR_RLC_Config_PR_am:
+ add_drb_am(rnti, s);
+ break;
+ case NR_RLC_Config_PR_um_Bi_Directional:
+ //add_drb_um(rnti, s);
+ /* hack */
+ add_drb_am(rnti, s);
+ break;
+ default:
+ LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n",
+ __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+}
+
+boolean_t nr_rrc_pdcp_config_asn1_req(
+ const protocol_ctxt_t *const ctxt_pP,
+ NR_SRB_ToAddModList_t *const srb2add_list,
+ NR_DRB_ToAddModList_t *const drb2add_list,
+ NR_DRB_ToReleaseList_t *const drb2release_list,
+ const uint8_t security_modeP,
+ uint8_t *const kRRCenc,
+ uint8_t *const kRRCint,
+ uint8_t *const kUPenc
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+ ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
+#endif
+ ,rb_id_t *const defaultDRB,
+ struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list)
+ //struct NR_RLC_Config *rlc_Config)
+{
+ int rnti = ctxt_pP->rnti;
+ int i;
+
+ if (//ctxt_pP->enb_flag != 1 ||
+ ctxt_pP->module_id != 0 ||
+ ctxt_pP->instance != 0 ||
+ ctxt_pP->eNB_index != 0 ||
+ //ctxt_pP->configured != 2 ||
+ //srb2add_list == NULL ||
+ //drb2add_list != NULL ||
+ drb2release_list != NULL ||
+ security_modeP != 255 ||
+ //kRRCenc != NULL ||
+ //kRRCint != NULL ||
+ //kUPenc != NULL ||
+ pmch_InfoList_r9 != NULL /*||
+ defaultDRB != NULL */) {
+ TODO;
+ }
+
+ if (srb2add_list != NULL) {
+ for (i = 0; i < srb2add_list->list.count; i++) {
+ add_srb(rnti, srb2add_list->list.array[i]);
+ }
+ }
+
+ if (drb2add_list != NULL) {
+ for (i = 0; i < drb2add_list->list.count; i++) {
+ LOG_I(PDCP, "Before calling add_drb \n");
+ add_drb(rnti, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config);
+ }
+ }
+
+ /* update security */
+ if (kRRCint != NULL) {
+ /* todo */
+ }
+
+ free(kRRCenc);
+ free(kRRCint);
+ free(kUPenc);
+
+ return 0;
+}
+
+/* Dummy function due to dependency from LTE libraries */
+boolean_t rrc_pdcp_config_asn1_req(
+ const protocol_ctxt_t *const ctxt_pP,
+ LTE_SRB_ToAddModList_t *const srb2add_list,
+ LTE_DRB_ToAddModList_t *const drb2add_list,
+ LTE_DRB_ToReleaseList_t *const drb2release_list,
+ const uint8_t security_modeP,
+ uint8_t *const kRRCenc,
+ uint8_t *const kRRCint,
+ uint8_t *const kUPenc
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+ ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
+#endif
+ ,rb_id_t *const defaultDRB)
+{
+ return 0;
+}
+
+void nr_DRB_preconfiguration(void)
+{
+
+ NR_RadioBearerConfig_t *rbconfig = NULL;
+ struct NR_CellGroupConfig__rlc_BearerToAddModList *Rlc_Bearer_ToAdd_list = NULL;
+ protocol_ctxt_t ctxt;
+ //fill_default_rbconfig(rb_config, 5, 1);
+ rbconfig = calloc(1, sizeof(*rbconfig));
+
+ rbconfig->srb_ToAddModList = NULL;
+ rbconfig->srb3_ToRelease = NULL;
+ rbconfig->drb_ToAddModList = calloc(1,sizeof(*rbconfig->drb_ToAddModList));
+ NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
+ drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
+ drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
+ drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5;
+ drb_ToAddMod->drb_Identity = 1;
+ drb_ToAddMod->reestablishPDCP = NULL;
+ drb_ToAddMod->recoverPDCP = NULL;
+ drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
+ drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb));
+ drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer));
+ *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_ms30;
+ drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL));
+ *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len12bits;
+ drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL));
+ *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len12bits;
+ drb_ToAddMod->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
+ drb_ToAddMod->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
+
+ drb_ToAddMod->pdcp_Config->drb->integrityProtection=NULL;
+ drb_ToAddMod->pdcp_Config->drb->statusReportRequired=NULL;
+ drb_ToAddMod->pdcp_Config->drb->outOfOrderDelivery=NULL;
+ drb_ToAddMod->pdcp_Config->moreThanOneRLC = NULL;
+
+ drb_ToAddMod->pdcp_Config->t_Reordering = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->t_Reordering));
+ *drb_ToAddMod->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
+ drb_ToAddMod->pdcp_Config->ext1 = NULL;
+
+ ASN_SEQUENCE_ADD(&rbconfig->drb_ToAddModList->list,drb_ToAddMod);
+
+ rbconfig->drb_ToReleaseList = NULL;
+
+ rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig));
+ rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig));
+ rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
+ rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL;
+ rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
+ *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
+
+ xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
+
+
+ NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig));
+
+ RLC_BearerConfig->logicalChannelIdentity = 4;
+ RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(*RLC_BearerConfig->servedRadioBearer));
+ RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity;
+
+ RLC_BearerConfig->servedRadioBearer->choice.drb_Identity=1;
+ RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC));
+ *RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true;
+ RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config));
+
+ // RLC UM Bi-directional Bearer configuration
+ RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_um_Bi_Directional;
+ RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional));
+ RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength));
+ *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
+
+ RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength));
+ *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
+ RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15;
+
+ // RLC AM Bearer configuration
+ /*RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am;
+ RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am));
+ RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength));
+ *RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18;
+ RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45;
+ RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_p64;
+ RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_kB500;
+ RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t32;
+
+ RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength));
+ *RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18;
+ RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15;
+ RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15;*/
+
+ RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig));
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters));
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority = 1;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedServingCells = NULL;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedSCS_List = NULL;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->maxPUSCH_Duration = NULL;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->configuredGrantType1Allowed = NULL;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup));
+ *RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = 1;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = NULL;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = false;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false;
+ RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer = NULL;
+
+ Rlc_Bearer_ToAdd_list = calloc(1,sizeof(*Rlc_Bearer_ToAdd_list));
+ ASN_SEQUENCE_ADD(&Rlc_Bearer_ToAdd_list->list, RLC_BearerConfig);
+
+ if (ENB_NAS_USE_TUN){
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0);
+ }
+ else{
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0);
+ }
+
+ nr_rrc_pdcp_config_asn1_req(
+ &ctxt,
+ (NR_SRB_ToAddModList_t *) NULL,
+ rbconfig->drb_ToAddModList ,
+ rbconfig->drb_ToReleaseList,
+ 0xff,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ Rlc_Bearer_ToAdd_list);
+
+ nr_rrc_rlc_config_asn1_req (&ctxt,
+ (NR_SRB_ToAddModList_t *) NULL,
+ rbconfig->drb_ToAddModList,
+ rbconfig->drb_ToReleaseList,
+ (LTE_PMCH_InfoList_r9_t *) NULL,
+ Rlc_Bearer_ToAdd_list);
+}
+
+uint64_t get_pdcp_optmask(void)
+{
+ return pdcp_optmask;
+}
+
+boolean_t pdcp_remove_UE(
+ const protocol_ctxt_t *const ctxt_pP)
+{
+ TODO;
+ return 1;
+}
+
+void pdcp_config_set_security(const protocol_ctxt_t* const ctxt_pP, pdcp_t *pdcp_pP, rb_id_t rb_id,
+ uint16_t lc_idP, uint8_t security_modeP, uint8_t *kRRCenc_pP, uint8_t *kRRCint_pP, uint8_t *kUPenc_pP)
+{
+ TODO;
+}
+
+static boolean_t pdcp_data_req_drb(
+ protocol_ctxt_t *ctxt_pP,
+ const rb_id_t rb_id,
+ const mui_t muiP,
+ const confirm_t confirmP,
+ const sdu_size_t sdu_buffer_size,
+ unsigned char *const sdu_buffer)
+{
+printf("pdcp_data_req called size %d\n", sdu_buffer_size);
+ nr_pdcp_ue_t *ue;
+ nr_pdcp_entity_t *rb;
+ int rnti = ctxt_pP->rnti;
+
+ if (ctxt_pP->module_id != 0 ||
+ //ctxt_pP->enb_flag != 1 ||
+ ctxt_pP->instance != 0 ||
+ ctxt_pP->eNB_index != 0 /*||
+ ctxt_pP->configured != 1 ||
+ ctxt_pP->brOption != 0*/) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+
+ ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
+
+ if (rb_id < 1 || rb_id > 5)
+ rb = NULL;
+ else
+ rb = ue->drb[rb_id - 1];
+
+ if (rb == NULL) {
+ LOG_E(PDCP, "%s:%d:%s: fatal: no DRB found (rnti %d, rb_id %ld)\n",
+ __FILE__, __LINE__, __FUNCTION__, rnti, rb_id);
+ exit(1);
+ }
+
+ rb->recv_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP);
+
+ nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+
+ return 1;
+}
+
+boolean_t pdcp_data_req(
+ protocol_ctxt_t *ctxt_pP,
+ const srb_flag_t srb_flagP,
+ const rb_id_t rb_id,
+ const mui_t muiP,
+ const confirm_t confirmP,
+ const sdu_size_t sdu_buffer_size,
+ unsigned char *const sdu_buffer,
+ const pdcp_transmission_mode_t mode
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+ ,const uint32_t *const sourceL2Id
+ ,const uint32_t *const destinationL2Id
+#endif
+ )
+{
+ if (srb_flagP) { TODO; }
+ return pdcp_data_req_drb(ctxt_pP, rb_id, muiP, confirmP, sdu_buffer_size,
+ sdu_buffer);
+}
+
+void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind)
+{
+ /* nothing to do */
+}
+
+void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req)
+{
+ /* nothing to do */
+}
+
+//Dummy function needed due to LTE dependencies
+void
+pdcp_mbms_run ( const protocol_ctxt_t *const ctxt_pP){
+ /* nothing to do */
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
new file mode 100644
index 0000000000..ca51da3d5f
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
@@ -0,0 +1,198 @@
+/*
+ * 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.1 (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 "nr_pdcp_ue_manager.h"
+
+#include
+#include
+#include
+
+#include "LOG/log.h"
+
+typedef struct {
+ pthread_mutex_t lock;
+ nr_pdcp_ue_t **ue_list;
+ int ue_count;
+ int enb_flag;
+} nr_pdcp_ue_manager_internal_t;
+
+nr_pdcp_ue_manager_t *new_nr_pdcp_ue_manager(int enb_flag)
+{
+ nr_pdcp_ue_manager_internal_t *ret;
+
+ ret = calloc(1, sizeof(nr_pdcp_ue_manager_internal_t));
+ if (ret == NULL) {
+ LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ if (pthread_mutex_init(&ret->lock, NULL)) abort();
+ ret->enb_flag = enb_flag;
+
+ return ret;
+}
+
+int nr_pdcp_manager_get_enb_flag(nr_pdcp_ue_manager_t *_m)
+{
+ nr_pdcp_ue_manager_internal_t *m = _m;
+ return m->enb_flag;
+}
+
+void nr_pdcp_manager_lock(nr_pdcp_ue_manager_t *_m)
+{
+ nr_pdcp_ue_manager_internal_t *m = _m;
+ if (pthread_mutex_lock(&m->lock)) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+}
+
+void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *_m)
+{
+ nr_pdcp_ue_manager_internal_t *m = _m;
+ if (pthread_mutex_unlock(&m->lock)) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+}
+
+/* must be called with lock acquired */
+nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *_m, int rnti)
+{
+ /* TODO: optimze */
+ nr_pdcp_ue_manager_internal_t *m = _m;
+ int i;
+
+ for (i = 0; i < m->ue_count; i++)
+ if (m->ue_list[i]->rnti == rnti)
+ return m->ue_list[i];
+
+ LOG_D(PDCP, "%s:%d:%s: new UE %d\n", __FILE__, __LINE__, __FUNCTION__, rnti);
+
+ m->ue_count++;
+ m->ue_list = realloc(m->ue_list, sizeof(nr_pdcp_ue_t *) * m->ue_count);
+ if (m->ue_list == NULL) {
+ LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+ m->ue_list[m->ue_count-1] = calloc(1, sizeof(nr_pdcp_ue_t));
+ if (m->ue_list[m->ue_count-1] == NULL) {
+ LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ m->ue_list[m->ue_count-1]->rnti = rnti;
+
+ return m->ue_list[m->ue_count-1];
+}
+
+/* must be called with lock acquired */
+void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *_m, int rnti)
+{
+ nr_pdcp_ue_manager_internal_t *m = _m;
+ nr_pdcp_ue_t *ue;
+ int i;
+ int j;
+
+ for (i = 0; i < m->ue_count; i++)
+ if (m->ue_list[i]->rnti == rnti)
+ break;
+
+ if (i == m->ue_count) {
+ LOG_D(PDCP, "%s:%d:%s: warning: ue %d not found\n",
+ __FILE__, __LINE__, __FUNCTION__,
+ rnti);
+ return;
+ }
+
+ ue = m->ue_list[i];
+
+ for (j = 0; j < 2; j++)
+ if (ue->srb[j] != NULL)
+ ue->srb[j]->delete(ue->srb[j]);
+
+ for (j = 0; j < 5; j++)
+ if (ue->drb[j] != NULL)
+ ue->drb[j]->delete(ue->drb[j]);
+
+ free(ue);
+
+ m->ue_count--;
+ if (m->ue_count == 0) {
+ free(m->ue_list);
+ m->ue_list = NULL;
+ return;
+ }
+
+ memmove(&m->ue_list[i], &m->ue_list[i+1],
+ (m->ue_count - i) * sizeof(nr_pdcp_ue_t *));
+ m->ue_list = realloc(m->ue_list, m->ue_count * sizeof(nr_pdcp_ue_t *));
+ if (m->ue_list == NULL) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+}
+
+/* must be called with lock acquired */
+void nr_pdcp_ue_add_srb_pdcp_entity(nr_pdcp_ue_t *ue, int srb_id, nr_pdcp_entity_t *entity)
+{
+ if (srb_id < 1 || srb_id > 2) {
+ LOG_E(PDCP, "%s:%d:%s: fatal, bad srb id\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ srb_id--;
+
+ if (ue->srb[srb_id] != NULL) {
+ LOG_E(PDCP, "%s:%d:%s: fatal, srb already present\n",
+ __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ ue->srb[srb_id] = entity;
+}
+
+/* must be called with lock acquired */
+void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id, nr_pdcp_entity_t *entity)
+{
+ if (drb_id < 1 || drb_id > 5) {
+ LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ drb_id--;
+
+ if (ue->drb[drb_id] != NULL) {
+ LOG_E(PDCP, "%s:%d:%s: fatal, drb already present\n",
+ __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ ue->drb[drb_id] = entity;
+}
+
+int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *_m)
+{
+ nr_pdcp_ue_manager_internal_t *m = _m;
+ if (m->ue_count == 0)
+ return -1;
+ return m->ue_list[0]->rnti;
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
new file mode 100644
index 0000000000..0de2f024b3
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
@@ -0,0 +1,65 @@
+/*
+ * 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.1 (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 _NR_PDCP_UE_MANAGER_H_
+#define _NR_PDCP_UE_MANAGER_H_
+
+#include "nr_pdcp_entity.h"
+
+typedef void nr_pdcp_ue_manager_t;
+
+typedef struct nr_pdcp_ue_t {
+ int rnti;
+ nr_pdcp_entity_t *srb[2];
+ nr_pdcp_entity_t *drb[5];
+} nr_pdcp_ue_t;
+
+/***********************************************************************/
+/* manager functions */
+/***********************************************************************/
+
+nr_pdcp_ue_manager_t *new_nr_pdcp_ue_manager(int enb_flag);
+
+int nr_pdcp_manager_get_enb_flag(nr_pdcp_ue_manager_t *m);
+
+void nr_pdcp_manager_lock(nr_pdcp_ue_manager_t *m);
+void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *m);
+
+nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *m, int rnti);
+void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *m, int rnti);
+
+/***********************************************************************/
+/* ue functions */
+/***********************************************************************/
+
+void nr_pdcp_ue_add_srb_pdcp_entity(nr_pdcp_ue_t *ue, int srb_id,
+ nr_pdcp_entity_t *entity);
+void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id,
+ nr_pdcp_entity_t *entity);
+
+/***********************************************************************/
+/* hacks */
+/***********************************************************************/
+
+/* returns -1 if no UE */
+int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *m);
+
+#endif /* _NR_PDCP_UE_MANAGER_H_ */
diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.c b/openair2/LAYER2/nr_rlc/asn1_utils.c
index 46f7d90da5..43d55af1ac 100644
--- a/openair2/LAYER2/nr_rlc/asn1_utils.c
+++ b/openair2/LAYER2/nr_rlc/asn1_utils.c
@@ -21,14 +21,14 @@
#include "rlc.h"
-int decode_t_reordering(int v)
+int decode_t_reassembly(int v)
{
- static int tab[32] = {
- 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85,
- 90, 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 1600
+ static int tab[31] = {
+ 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90,
+ 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200
};
- if (v < 0 || v > 31) {
+ if (v < 0 || v > 30) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
@@ -72,11 +72,13 @@ int decode_t_poll_retransmit(int v)
int decode_poll_pdu(int v)
{
- static int tab[8] = {
- 4, 8, 16, 32, 64, 128, 256, -1 /* -1 means infinity */
+ static int tab[24] = {
+ 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 6144, 8192, 12288,
+ 16384, 20480, 24576, 28672, 32768, 40960, 49152, 57344, 65536
+ -1 /* -1 means infinity */
};
- if (v < 0 || v > 7) {
+ if (v < 0 || v > 23) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
@@ -86,12 +88,23 @@ int decode_poll_pdu(int v)
int decode_poll_byte(int v)
{
- static int tab[15] = {
- 25, 50, 75, 100, 125, 250, 375, 500, 750, 1000, 1250, 1500, 2000, 3000,
+ static int tab[44] = {
+ /* KB */
+ 1024 * 1, 1024 * 2, 1024 * 5, 1024 * 8, 1024 * 10,
+ 1024 * 15, 1024 * 25, 1024 * 50, 1024 * 75, 1024 * 100,
+ 1024 * 125, 1024 * 250, 1024 * 375, 1024 * 500, 1024 * 750,
+ 1024 * 1000, 1024 * 1250, 1024 * 1500, 1024 * 2000, 1024 * 3000,
+ 1024 * 4000, 1024 * 4500, 1024 * 5000, 1024 * 5500, 1024 * 6000,
+ 1024 * 6500, 1024 * 7000, 1024 * 7500,
+ /* MB */
+ 1024 * 1024 * 8, 1024 * 1024 * 9, 1024 * 1024 * 10, 1024 * 1024 * 11,
+ 1024 * 1024 * 12, 1024 * 1024 * 13, 1024 * 1024 * 14, 1024 * 1024 * 15,
+ 1024 * 1024 * 16, 1024 * 1024 * 17, 1024 * 1024 * 18, 1024 * 1024 * 20,
+ 1024 * 1024 * 25, 1024 * 1024 * 30, 1024 * 1024 * 40,
-1 /* -1 means infinity */
};
- if (v < 0 || v > 14) {
+ if (v < 0 || v > 43) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
@@ -114,10 +127,24 @@ int decode_max_retx_threshold(int v)
return tab[v];
}
-int decode_sn_field_length(int v)
+int decode_sn_field_length_um(int v)
{
static int tab[2] = {
- 5, 10
+ 6, 12
+ };
+
+ if (v < 0 || v > 1) {
+ LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ return tab[v];
+}
+
+int decode_sn_field_length_am(int v)
+{
+ static int tab[2] = {
+ 12, 18
};
if (v < 0 || v > 1) {
diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.h b/openair2/LAYER2/nr_rlc/asn1_utils.h
index 61394c9c69..6f010b02da 100644
--- a/openair2/LAYER2/nr_rlc/asn1_utils.h
+++ b/openair2/LAYER2/nr_rlc/asn1_utils.h
@@ -19,15 +19,16 @@
* contact@openairinterface.org
*/
-#ifndef _ASN1_UTILS_H_
-#define _ASN1_UTILS_H_
+#ifndef _OPENAIR2_LAYER2_NR_RLC_ASN1_UTILS_H_
+#define _OPENAIR2_LAYER2_NR_RLC_ASN1_UTILS_H_
-int decode_t_reordering(int v);
+int decode_t_reassembly(int v);
int decode_t_status_prohibit(int v);
int decode_t_poll_retransmit(int v);
int decode_poll_pdu(int v);
int decode_poll_byte(int v);
int decode_max_retx_threshold(int v);
-int decode_sn_field_length(int v);
+int decode_sn_field_length_um(int v);
+int decode_sn_field_length_am(int v);
-#endif /* _ASN1_UTILS_H_ */
+#endif /* _OPENAIR2_LAYER2_NR_RLC_ASN1_UTILS_H_ */
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
index 8f3d49d8c2..78a49e4604 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
@@ -109,7 +109,8 @@ static void consider_retransmission(nr_rlc_entity_am_t *entity,
* upper layers should deal with this condition, internally it's better
* for the RLC code to keep going with this segment (we only remove
* a segment that was ACKed)
- */
+ */
+ LOG_D(RLC, "RLC segment to be added at the ReTx list \n");
nr_rlc_sdu_segment_list_append(&entity->retransmit_list,
&entity->retransmit_end,
cur);
@@ -1588,6 +1589,8 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity,
sdu = nr_rlc_new_sdu(buffer, size, sdu_id);
+ LOG_D(RLC, "Created new RLC SDU and append it to the RLC list \n");
+
nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu);
}
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index bbc4acbd56..919cf1a46a 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -27,19 +27,23 @@
#include "asn1_utils.h"
#include "nr_rlc_ue_manager.h"
#include "nr_rlc_entity.h"
+#include "NR_RLC-BearerConfig.h"
+#include "NR_DRB-ToAddMod.h"
+#include "NR_DRB-ToAddModList.h"
+#include "NR_SRB-ToAddModList.h"
+#include "NR_DRB-ToReleaseList.h"
+#include "NR_CellGroupConfig.h"
+#include "NR_RLC-Config.h"
#include
static nr_rlc_ue_manager_t *nr_rlc_ue_manager;
/* TODO: handle time a bit more properly */
-//#if 0
static uint64_t nr_rlc_current_time;
static int nr_rlc_current_time_last_frame;
static int nr_rlc_current_time_last_subframe;
-//#endif
-//#if 0
void mac_rlc_data_ind (
const module_id_t module_idP,
const rnti_t rntiP,
@@ -195,7 +199,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
ret.head_sdu_is_segmented = 0;
return ret;
}
-//#endif
rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
const module_id_t module_idP,
@@ -254,7 +257,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
int oai_emulation;
-//#if 0
rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
@@ -306,9 +308,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP,
return RLC_OP_STATUS_OK;
}
-//#endif
-//#if 0
int rlc_module_init(int enb_flag)
{
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
@@ -329,13 +329,10 @@ int rlc_module_init(int enb_flag)
return 0;
}
-//#endif
-//#if 0
void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP)
{
}
-//#endif
static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
{
@@ -522,7 +519,7 @@ rb_found:
#endif
}
-__attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s)
+static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s)
{
nr_rlc_entity_t *nr_rlc_am;
nr_rlc_ue_t *ue;
@@ -532,7 +529,6 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *
int srb_id = s->srb_Identity;
int logical_channel_group;
- //int t_reordering;
int t_status_prohibit;
int t_poll_retransmit;
int poll_pdu;
@@ -575,7 +571,6 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *
exit(1);
}
am = &r->choice.explicitValue.choice.am;
- //t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering);
t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit);
t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit);
poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU);
@@ -585,7 +580,6 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *
}
case LTE_SRB_ToAddMod__rlc_Config_PR_defaultValue:
/* default values from 36.331 9.2.1 */
- //t_reordering = 35;
t_status_prohibit = 0;
t_poll_retransmit = 45;
poll_pdu = -1;
@@ -628,18 +622,17 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
-static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s)
+static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_t *rlc_BearerConfig)
{
nr_rlc_entity_t *nr_rlc_am;
nr_rlc_ue_t *ue;
- struct LTE_RLC_Config *r = s->rlc_Config;
- struct LTE_LogicalChannelConfig *l = s->logicalChannelConfig;
+ struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
+ struct NR_LogicalChannelConfig *l = rlc_BearerConfig->mac_LogicalChannelConfig;
int drb_id = s->drb_Identity;
- int channel_id = *s->logicalChannelIdentity;
+ int channel_id = rlc_BearerConfig->logicalChannelIdentity;
int logical_channel_group;
- //int t_reordering;
int t_status_prohibit;
int t_poll_retransmit;
int poll_pdu;
@@ -669,15 +662,20 @@ static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s)
}
switch (r->present) {
- case LTE_RLC_Config_PR_am: {
- struct LTE_RLC_Config__am *am;
- am = &r->choice.am;
- //t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering);
+ case NR_RLC_Config_PR_am: {
+ struct NR_RLC_Config__am *am;
+ am = r->choice.am;
+ t_reassembly = decode_t_reassembly(am->dl_AM_RLC.t_Reassembly);
t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit);
t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit);
poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU);
poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte);
max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold);
+ if (*am->dl_AM_RLC.sn_FieldLength != *am->ul_AM_RLC.sn_FieldLength) {
+ LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+ sn_field_length = decode_sn_field_length_am(*am->dl_AM_RLC.sn_FieldLength);
break;
}
default:
@@ -691,14 +689,6 @@ static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s)
LOG_D(RLC, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
} else {
- /* hack: hardcode values for NR */
- t_poll_retransmit = 45;
- t_reassembly = 35;
- t_status_prohibit = 0;
- poll_pdu = -1;
- poll_byte = -1;
- max_retx_threshold = 8;
- sn_field_length = 12;
nr_rlc_am = new_nr_rlc_entity_am(100000,
100000,
deliver_sdu, ue,
@@ -716,18 +706,17 @@ static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s)
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
-static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s)
+static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_t *rlc_BearerConfig)
{
nr_rlc_entity_t *nr_rlc_um;
nr_rlc_ue_t *ue;
- struct LTE_RLC_Config *r = s->rlc_Config;
- struct LTE_LogicalChannelConfig *l = s->logicalChannelConfig;
+ struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
+ struct NR_LogicalChannelConfig *l = rlc_BearerConfig->mac_LogicalChannelConfig;
int drb_id = s->drb_Identity;
- int channel_id = *s->logicalChannelIdentity;
+ int channel_id = rlc_BearerConfig->logicalChannelIdentity;
int logical_channel_group;
- //int t_reordering;
int sn_field_length;
int t_reassembly;
@@ -752,15 +741,15 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s)
}
switch (r->present) {
- case LTE_RLC_Config_PR_um_Bi_Directional: {
- struct LTE_RLC_Config__um_Bi_Directional *um;
- um = &r->choice.um_Bi_Directional;
- //t_reordering = decode_t_reordering(um->dl_UM_RLC.t_Reordering);
- if (um->dl_UM_RLC.sn_FieldLength != um->ul_UM_RLC.sn_FieldLength) {
+ case NR_RLC_Config_PR_um_Bi_Directional: {
+ struct NR_RLC_Config__um_Bi_Directional *um;
+ um = r->choice.um_Bi_Directional;
+ t_reassembly = decode_t_reassembly(um->dl_UM_RLC.t_Reassembly);
+ if (*um->dl_UM_RLC.sn_FieldLength != *um->ul_UM_RLC.sn_FieldLength) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
- sn_field_length = decode_sn_field_length(um->dl_UM_RLC.sn_FieldLength);
+ sn_field_length = decode_sn_field_length_um(*um->dl_UM_RLC.sn_FieldLength);
break;
}
default:
@@ -774,9 +763,6 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s)
LOG_D(RLC, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
} else {
- /* hack: hardcode values for NR */
- t_reassembly = 35;
- sn_field_length = 6;
nr_rlc_um = new_nr_rlc_entity_um(1000000,
1000000,
deliver_sdu, ue,
@@ -790,14 +776,14 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s)
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
-__attribute__ ((unused)) static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s)
+static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, struct NR_RLC_BearerConfig *rlc_BearerConfig)
{
- switch (s->rlc_Config->present) {
- case LTE_RLC_Config_PR_am:
- add_drb_am(rnti, s);
+ switch (rlc_BearerConfig->rlc_Config->present) {
+ case NR_RLC_Config_PR_am:
+ add_drb_am(rnti, s, rlc_BearerConfig);
break;
- case LTE_RLC_Config_PR_um_Bi_Directional:
- add_drb_um(rnti, s);
+ case NR_RLC_Config_PR_um_Bi_Directional:
+ add_drb_um(rnti, s, rlc_BearerConfig);
break;
default:
LOG_E(RLC, "%s:%d:%s: fatal: unhandled DRB type\n",
@@ -806,7 +792,7 @@ __attribute__ ((unused)) static void add_drb(int rnti, struct LTE_DRB_ToAddMod *
}
}
-//#if 0
+/* Dummy function due to dependency from LTE libraries */
rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
const LTE_SRB_ToAddModList_t * const srb2add_listP,
const LTE_DRB_ToAddModList_t * const drb2add_listP,
@@ -814,6 +800,16 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP
const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
const uint32_t sourceL2Id,
const uint32_t destinationL2Id)
+{
+ return 0;
+}
+
+rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
+ const LTE_SRB_ToAddModList_t * const srb2add_listP,
+ const NR_DRB_ToAddModList_t * const drb2add_listP,
+ const NR_DRB_ToReleaseList_t * const drb2release_listP,
+ const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
+ struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list)
{
int rnti = ctxt_pP->rnti;
int i;
@@ -845,15 +841,13 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP
if (drb2add_listP != NULL) {
for (i = 0; i < drb2add_listP->list.count; i++) {
- add_drb(rnti, drb2add_listP->list.array[i]);
+ add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[i]);
}
}
return RLC_OP_STATUS_OK;
}
-//#endif
-//#if 0
rlc_op_status_t rrc_rlc_config_req (
const protocol_ctxt_t* const ctxt_pP,
const srb_flag_t srb_flagP,
@@ -912,16 +906,12 @@ rlc_op_status_t rrc_rlc_config_req (
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return RLC_OP_STATUS_OK;
}
-//#endif
-//#if 0
void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_data_conf_cb_t rrc_data_confP)
{
/* nothing to do */
}
-//#endif
-//#if 0
rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x)
{
LOG_D(RLC, "%s:%d:%s: remove UE %d\n", __FILE__, __LINE__, __FUNCTION__, x->rnti);
@@ -931,4 +921,3 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x)
return RLC_OP_STATUS_OK;
}
-//#endif
diff --git a/openair2/LAYER2/rlc_v2/asn1_utils.h b/openair2/LAYER2/rlc_v2/asn1_utils.h
index 61394c9c69..fadaf16f0a 100644
--- a/openair2/LAYER2/rlc_v2/asn1_utils.h
+++ b/openair2/LAYER2/rlc_v2/asn1_utils.h
@@ -19,8 +19,8 @@
* contact@openairinterface.org
*/
-#ifndef _ASN1_UTILS_H_
-#define _ASN1_UTILS_H_
+#ifndef _OPENAIR2_LAYER2_RLC_V2_ASN1_UTILS_H_
+#define _OPENAIR2_LAYER2_RLC_V2_ASN1_UTILS_H_
int decode_t_reordering(int v);
int decode_t_status_prohibit(int v);
@@ -30,4 +30,4 @@ int decode_poll_byte(int v);
int decode_max_retx_threshold(int v);
int decode_sn_field_length(int v);
-#endif /* _ASN1_UTILS_H_ */
+#endif /* _OPENAIR2_LAYER2_RLC_V2_ASN1_UTILS_H_ */
diff --git a/openair2/M2AP/m2ap_MCE_interface_management.c b/openair2/M2AP/m2ap_MCE_interface_management.c
index 1bef834179..e162c9a5de 100644
--- a/openair2/M2AP/m2ap_MCE_interface_management.c
+++ b/openair2/M2AP/m2ap_MCE_interface_management.c
@@ -521,6 +521,7 @@ int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance, /*uint32_t assoc_i
mbsfn_subframe_configuration->radioframeAllocationPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period;
mbsfn_subframe_configuration->radioframeAllocationOffset = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset;
if(m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf){
+ LOG_I(M2AP,"is_four_sf\n");
mbsfn_subframe_configuration->subframeAllocation.present = M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_fourFrames;
mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf = MALLOC(3);
mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation) & 0xFF);
@@ -530,6 +531,7 @@ int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance, /*uint32_t assoc_i
mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.bits_unused = 0;
}else{
+ LOG_I(M2AP,"is_one_sf\n");
mbsfn_subframe_configuration->subframeAllocation.present = M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_oneFrame;
mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf = MALLOC(1);
mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.size = 1;
@@ -1357,11 +1359,10 @@ int MCE_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance,
-int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,
- uint32_t assoc_id,
- uint32_t stream,
- M2AP_M2AP_PDU_t *pdu){
+int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,module_id_t du_mod_idP){
+
AssertFatal(1==0,"Not implemented yet\n");
+
}
/*
@@ -1378,16 +1379,138 @@ int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu){
- AssertFatal(1==0,"Not implemented yet\n");
+ //int i;
+ //AssertFatal(1==0,"Not implemented yet\n");
+ LOG_D(M2AP, "MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE\n");
+
+ AssertFatal(pdu->present == M2AP_M2AP_PDU_PR_successfulOutcome,
+ "pdu->present != M2AP_M2AP_PDU_PR_successfulOutcome\n");
+ AssertFatal(pdu->choice.successfulOutcome.procedureCode == M2AP_ProcedureCode_id_mbmsServiceCounting,
+ "pdu->choice.successfulOutcome->procedureCode != M2AP_ProcedureCode_id_mbmsServiceCounting\n");
+ AssertFatal(pdu->choice.successfulOutcome.criticality == M2AP_Criticality_reject,
+ "pdu->choice.successfulOutcome->criticality != M2AP_Criticality_reject\n");
+ AssertFatal(pdu->choice.successfulOutcome.value.present == M2AP_SuccessfulOutcome__value_PR_MbmsServiceCountingResponse,
+ "pdu->choice.successfulOutcome.value.present != M2AP_SuccessfulOutcome__value_PR_MbmsServiceCountingResponse\n");
+
+
+ M2AP_MbmsServiceCountingResponse_t *in = &pdu->choice.successfulOutcome.value.choice.MbmsServiceCountingResponse;
+ //M2AP_MbmsServiceCountingResponse_Ies_t *ie;
+ //int MCE_MBMS_M2AP_ID=-1;
+ //int ENB_MBMS_M2AP_ID=-1;
+
+
+ MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SERVICE_COUNTING_RESP); //TODO
+
+ LOG_D(M2AP, "M2AP: MbmsServiceCounting-Resp: protocolIEs.list.count %d\n",
+ in->protocolIEs.list.count);
+ for (int i=0;i < in->protocolIEs.list.count; i++) {
+ //ie = in->protocolIEs.list.array[i];
+ // switch (ie->id) {
+ // case M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID:
+ // AssertFatal(ie->criticality == M2AP_Criticality_reject,
+ // "ie->criticality != M2AP_Criticality_reject\n");
+ // AssertFatal(ie->value.present == M2AP_SessionStartResponse_Ies__value_PR_MCE_MBMS_M2AP_ID,
+ // "ie->value.present != M2AP_sessionStartResponse_IEs__value_PR_MCE_MBMS_M2AP_ID\n");
+ // MCE_MBMS_M2AP_ID=ie->value.choice.MCE_MBMS_M2AP_ID;
+ // LOG_D(M2AP, "M2AP: SessionStart-Resp: MCE_MBMS_M2AP_ID %d\n",
+ // MCE_MBMS_M2AP_ID);
+ // break;
+ // case M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID:
+ // AssertFatal(ie->criticality == M2AP_Criticality_reject,
+ // "ie->criticality != M2AP_Criticality_reject\n");
+ // AssertFatal(ie->value.present == M2AP_SessionStartResponse_Ies__value_PR_ENB_MBMS_M2AP_ID,
+ // "ie->value.present != M2AP_sessionStartResponse_Ies__value_PR_ENB_MBMS_M2AP_ID\n");
+ // ENB_MBMS_M2AP_ID=ie->value.choice.ENB_MBMS_M2AP_ID;
+ // LOG_D(M2AP, "M2AP: SessionStart-Resp: ENB_MBMS_M2AP_ID %d\n",
+ // ENB_MBMS_M2AP_ID);
+ // break;
+ // }
+ }
+
+ //AssertFatal(MCE_MBMS_M2AP_ID!=-1,"MCE_MBMS_M2AP_ID was not sent\n");
+ //AssertFatal(ENB_MBMS_M2AP_ID!=-1,"ENB_MBMS_M2AP_ID was not sent\n");
+ //M2AP_SESSION_START_RESP(msg_p).
+// MSC_LOG_RX_MESSAGE(
+// MSC_M2AP_MCE,
+// MSC_M2AP_ENB,
+ //return 0;
+// 0,
+// 0,
+// MSC_AS_TIME_FMT" MCE_handle_M2_SESSION_START_RESPONSE successfulOutcome assoc_id %d",
+// 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+// assoc_id);
+//
+ //LOG_D(M2AP, "Sending ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+ //assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id));
+
+ itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_g);
+ return 0;
+
}
-int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance,
- uint32_t assoc_id,
- uint32_t stream,
- M2AP_M2AP_PDU_t *pdu){
- AssertFatal(1==0,"Not implemented yet\n");
+int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance, module_id_t du_mod_idP){
+
+ M2AP_M2AP_PDU_t pdu;
+ M2AP_MbmsServiceCountingRequest_t *out;
+ M2AP_MbmsServiceCountingRequest_Ies_t *ie;
+
+ uint8_t *buffer;
+ uint32_t len;
+ //int i=0;
+ //int j=0;
+
+ /* Create */
+ /* 0. pdu Type */
+ memset(&pdu, 0, sizeof(pdu));
+ pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+ //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
+ pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_mbmsServiceCounting;
+ pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
+ pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_MbmsServiceCountingRequest;
+ out = &pdu.choice.initiatingMessage.value.choice.MbmsServiceCountingRequest;
+
+ /* mandatory */
+ /* c1. MCCH_Update_Time */ //long
+ ie=(M2AP_MbmsServiceCountingRequest_Ies_t *)calloc(1,sizeof(M2AP_MbmsSchedulingInformation_Ies_t));
+ ie->id = M2AP_ProtocolIE_ID_id_MCCH_Update_Time;
+ ie->criticality = M2AP_Criticality_reject;
+ ie->value.present = M2AP_MbmsServiceCountingRequest_Ies__value_PR_MCCH_Update_Time;
+ //ie->value.choice.MCCH_Update_Time = ;
+ //ie->value.choice.MCCH_Update_Time = m2ap_mbms_scheduling_information->mcch_update_time;
+
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+ /* mandatory */
+ /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+ ie = (M2AP_MbmsServiceCountingRequest_Ies_t *)calloc(1, sizeof(M2AP_MbmsServiceCountingRequest_Ies_t));
+ ie->id = M2AP_ProtocolIE_ID_id_MBSFN_Area_ID;
+ ie->criticality = M2AP_Criticality_reject;
+ ie->value.present = M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBSFN_Area_ID;
+ //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ /* mandatory */
+ /* c2. TMGI (integrer value) */
+ ie = (M2AP_MbmsServiceCountingRequest_Ies_t *)calloc(1, sizeof(M2AP_MbmsServiceCountingRequest_Ies_t ));
+ ie->id = M2AP_ProtocolIE_ID_id_MBMS_Counting_Request_Session;
+ ie->criticality = M2AP_Criticality_reject;
+ ie->value.present = M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBMS_Counting_Request_Session;
+
+ //M2AP_MBMS_Counting_Request_Session_t * m2ap_mbms_counting_request_session = &ie->value.choice.MBMS_Counting_Request_Session;
+
+ //&ie->choice.TMGI.pLMN_Identity);
+ //INT16_TO_OCTET_STRING(0,&ie->choice.TMGI.serviceId);
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+ LOG_E(M2AP, "Failed to encode MBMS Service Counting Results Report\n");
+ return -1;
+ }
+
+ return 0;
}
diff --git a/openair2/M2AP/m2ap_MCE_interface_management.h b/openair2/M2AP/m2ap_MCE_interface_management.h
index 6b899e9ea2..2b1d5824af 100644
--- a/openair2/M2AP/m2ap_MCE_interface_management.h
+++ b/openair2/M2AP/m2ap_MCE_interface_management.h
@@ -150,10 +150,7 @@ int MCE_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
-int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,
- uint32_t assoc_id,
- uint32_t stream,
- M2AP_M2AP_PDU_t *pdu);
+int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,module_id_t du_mod_idP);
/*
* Service Counting Request
@@ -165,10 +162,7 @@ int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
-int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance,
- uint32_t assoc_id,
- uint32_t stream,
- M2AP_M2AP_PDU_t *pdu);
+int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance, module_id_t du_mod_idP);
/*
* Service Counting Results Report
*/
diff --git a/openair2/M2AP/m2ap_eNB.c b/openair2/M2AP/m2ap_eNB.c
index 206b7cf8ca..39c769a43d 100644
--- a/openair2/M2AP/m2ap_eNB.c
+++ b/openair2/M2AP/m2ap_eNB.c
@@ -142,6 +142,22 @@ void m2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
sctp_new_association_resp->ulp_cnx_id);
//m2ap_handle_m2_setup_message(instance_p, m2ap_enb_data_p,
// sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
+
+ sleep(4);
+ int index;
+ /* Trying to connect to the provided list of eNB ip address */
+ for (index = 0; index < instance_p->nb_m2; index++) {
+ //M2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n",
+ // instance_id, instance->eNB_id);
+ m2ap_eNB_register_eNB(instance_p,
+ &instance_p->target_mce_m2_ip_address[index],
+ &instance_p->enb_m2_ip_address,
+ instance_p->sctp_in_streams,
+ instance_p->sctp_out_streams,
+ instance_p->enb_port_for_M2C,
+ instance_p->multi_sd);
+ }
+
return;
}
@@ -304,6 +320,8 @@ void m2ap_eNB_handle_register_eNB(instance_t instance,
DevCheck(new_instance->mcc == m2ap_register_eNB->mcc, new_instance->mcc, m2ap_register_eNB->mcc, 0);
DevCheck(new_instance->mnc == m2ap_register_eNB->mnc, new_instance->mnc, m2ap_register_eNB->mnc, 0);
M2AP_WARN("eNB[%d] already registered\n", instance);
+
+
} else {
new_instance = calloc(1, sizeof(m2ap_eNB_instance_t));
DevAssert(new_instance != NULL);
diff --git a/openair2/M2AP/m2ap_eNB_interface_management.c b/openair2/M2AP/m2ap_eNB_interface_management.c
index 95b8372025..9649d919c3 100644
--- a/openair2/M2AP/m2ap_eNB_interface_management.c
+++ b/openair2/M2AP/m2ap_eNB_interface_management.c
@@ -163,8 +163,12 @@ int eNB_handle_MBMS_SCHEDULING_INFORMATION(instance_t instance,
M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period = m2ap_mbsfn_sf_configuration->radioframeAllocationPeriod;
M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset = m2ap_mbsfn_sf_configuration->radioframeAllocationOffset;
if( m2ap_mbsfn_sf_configuration->subframeAllocation.present == M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_fourFrames ) {
+ LOG_I(RRC,"is_four_sf\n");
+ M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf = 1;
M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation = m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0] | (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[1]<<8) | (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0]<<16);
}else{
+ LOG_I(RRC,"is_one_sf\n");
+ M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf = 0;
M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation = (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0] >> 2) & 0x3F;
}
}
@@ -1262,46 +1266,226 @@ int eNB_handle_MBMS_SERVICE_COUNTING_REQ(instance_t instance,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu)
{
- LOG_D(M2AP, "eNB_handle_MBMS_SERVICE_COUNTING_REQUEST assoc_id %d\n",assoc_id);
- MessageDef *message_p;
+ LOG_D(M2AP, "eNB_handle_MBMS_SERVICE_COUNTING_REQUEST assoc_id %d\n",assoc_id);
+
+ //MessageDef *message_p;
//M2AP_MbmsServiceCountingRequest_t *container;
//M2AP_MbmsServiceCountingRequest_Ies_t *ie;
+ M2AP_MbmsServiceCountingRequest_t *in;
+ M2AP_MbmsServiceCountingRequest_Ies_t *ie;
//int i = 0;
+ int j;
DevAssert(pdu != NULL);
// container = &pdu->choice.initiatingMessage.value.choice.MbmsServiceCountingRequest;
+ in = &pdu->choice.initiatingMessage.value.choice.MbmsServiceCountingRequest;
/* M2 Setup Request == Non UE-related procedure -> stream 0 */
if (stream != 0) {
- LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n",
+ LOG_D(M2AP, "[SCTP %d] Received MMBS service Counting Request on stream != 0 (%d)\n",
assoc_id, stream);
}
- message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SERVICE_COUNTING_REQ);
+ for (j=0;j < in->protocolIEs.list.count; j++) {
+ ie = in->protocolIEs.list.array[j];
+ switch (ie->id) {
+ case M2AP_ProtocolIE_ID_id_MCCH_Update_Time:
+ AssertFatal(ie->criticality == M2AP_Criticality_reject,
+ "ie->criticality != M2AP_Criticality_reject\n");
+ AssertFatal(ie->value.present == M2AP_MbmsServiceCountingRequest_Ies__value_PR_MCCH_Update_Time,
+ "ie->value.present != M2AP_MbmsServiceCountingRequest_Ies__value_PR_MCCH_Update_Time\n");
+ LOG_D(M2AP, "M2AP: : MCCH_Update_Time \n");
+ break;
+ case M2AP_ProtocolIE_ID_id_MBSFN_Area_ID:
+ AssertFatal(ie->criticality == M2AP_Criticality_reject,
+ "ie->criticality != M2AP_Criticality_reject\n");
+ AssertFatal(ie->value.present == M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBSFN_Area_ID,
+ "ie->value.present != M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBSFN_Area_ID\n");
+ LOG_D(M2AP, "M2AP: : MBSFN_Area_ID \n");
+ break;
+ case M2AP_ProtocolIE_ID_id_MBMS_Counting_Request_Session:
+ AssertFatal(ie->criticality == M2AP_Criticality_reject,
+ "ie->criticality != M2AP_Criticality_reject\n");
+ AssertFatal(ie->value.present == M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBMS_Counting_Request_Session,
+ "ie->value.present != M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBMS_Counting_Request_Session\n");
+ LOG_D(M2AP, "M2AP: : MBMS_Counting_Request_Session \n");
+
+ //ie->value.choice.MBMS_Counting_Request_Session.list.count;
+
+ break;
+
+ }
+ }
- itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
-
+ //message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SERVICE_COUNTING_REQ);
return 0;
}
int eNB_send_MBMS_SERVICE_COUNTING_REPORT(instance_t instance, m2ap_mbms_service_counting_report_t * m2ap_mbms_service_counting_report)
{
- AssertFatal(1==0,"Not implemented yet\n");
+ M2AP_M2AP_PDU_t pdu;
+ M2AP_MbmsServiceCountingResultsReport_t *out;
+ M2AP_MbmsServiceCountingResultsReport_Ies_t *ie;
+
+ uint8_t *buffer;
+ uint32_t len;
+ //int i = 0;
+ //
+ // memset(&pdu, 0, sizeof(pdu));
+ pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+ //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
+ pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_mbmsServiceCountingResultsReport;
+ pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
+ pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_MbmsServiceCountingResultsReport;
+ out = &pdu.choice.initiatingMessage.value.choice.MbmsServiceCountingResultsReport;
+
+
+ /* Create */
+ /* 0. Message Type */
+ memset(&pdu, 0, sizeof(pdu));
+ pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
+ //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t));
+ pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_mbmsServiceCountingResultsReport;
+ pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
+ pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_MbmsServiceCountingResultsReport;
+ out = &pdu.choice.initiatingMessage.value.choice.MbmsServiceCountingResultsReport;
+
+ /* mandatory */
+ /* c1. MBSFN_Area_ID (integer value) */ //long
+ ie = (M2AP_MbmsServiceCountingResultsReport_Ies_t *)calloc(1, sizeof(M2AP_MbmsServiceCountingResultsReport_Ies_t));
+ ie->id = M2AP_ProtocolIE_ID_id_MBSFN_Area_ID;
+ ie->criticality = M2AP_Criticality_reject;
+ ie->value.present = M2AP_MbmsServiceCountingResultsReport_Ies__value_PR_MBSFN_Area_ID;
+ //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ /* mandatory */
+ /* c1. MBSFN_Area_ID (integer value) */ //long
+ ie = (M2AP_MbmsServiceCountingResultsReport_Ies_t *)calloc(1, sizeof(M2AP_MbmsServiceCountingResultsReport_Ies_t));
+ ie->id = M2AP_ProtocolIE_ID_id_MBMS_Counting_Result_List;
+ ie->criticality = M2AP_Criticality_reject;
+ ie->value.present = M2AP_MbmsServiceCountingResultsReport_Ies__value_PR_MBMS_Counting_Result_List;
+ //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+ M2AP_MBMS_Counting_Result_List_t * m2ap_mbms_counting_result_list = &ie->value.choice.MBMS_Counting_Result_List;
+
+ M2AP_MBMS_Counting_Result_Item_t * m2ap_mbms_counting_result_item = (M2AP_MBMS_Counting_Result_Item_t*)calloc(1,sizeof(M2AP_MBMS_Counting_Result_Item_t));
+ m2ap_mbms_counting_result_item->id = M2AP_ProtocolIE_ID_id_MBMS_Counting_Result_Item;
+ m2ap_mbms_counting_result_item->criticality = M2AP_Criticality_reject;
+ m2ap_mbms_counting_result_item->value.present = M2AP_MBMS_Counting_Result_Item__value_PR_MBMS_Counting_Result;
+ M2AP_MBMS_Counting_Result_t * m2ap_mbms_counting_result = &m2ap_mbms_counting_result_item->value.choice.MBMS_Counting_Result;
+
+ M2AP_TMGI_t * tmgi = &m2ap_mbms_counting_result->tmgi;
+ MCC_MNC_TO_PLMNID(0,0,3,&tmgi->pLMNidentity);/*instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,*/
+ uint8_t TMGI[5] = {4,3,2,1,0};
+ OCTET_STRING_fromBuf(&tmgi->serviceID,(const char*)&TMGI[2],3);
+
+ //M2AP_CountingResult_t * m2ap_counting_result = &m2ap_mbms_counting_result->countingResult;
+
+ ASN_SEQUENCE_ADD(&m2ap_mbms_counting_result_list->list,m2ap_mbms_counting_result_item);
+
+
+
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+ LOG_E(M2AP, "Failed to encode MBMS Service Counting Results Report\n");
+ return -1;
+ }
return 0;
}
+
int eNB_send_MBMS_SERVICE_COUNTING_RESP(instance_t instance, m2ap_mbms_service_counting_resp_t * m2ap_mbms_service_counting_resp)
{
AssertFatal(1==0,"Not implemented yet\n");
+ M2AP_M2AP_PDU_t pdu;
+ M2AP_MbmsServiceCountingResponse_t *out;
+ M2AP_MbmsServiceCountingResponse_Ies_t *ie;
+
+ uint8_t *buffer;
+ uint32_t len;
+ //int i = 0;
+
+ /* Create */
+ /* 0. Message Type */
+ memset(&pdu, 0, sizeof(pdu));
+ pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
+ //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t));
+ pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_mbmsServiceCounting;
+ pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
+ pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_MbmsServiceCountingResponse;
+ out = &pdu.choice.successfulOutcome.value.choice.MbmsServiceCountingResponse;
+
+
+ /* mandatory */
+ /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+ ie = (M2AP_MbmsServiceCountingResponse_Ies_t*)calloc(1, sizeof(M2AP_MbmsServiceCountingResponse_Ies_t));
+ ie->id = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID;
+ ie->criticality = M2AP_Criticality_reject;
+ ie->value.present = M2AP_MbmsServiceCountingResponse_Ies__value_PR_CriticalityDiagnostics;
+ //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+ LOG_E(M2AP, "Failed to encode MBMS Service Counting Results Report\n");
+ return -1;
+ }
+
+ return 0;
return 0;
}
+
int eNB_send_MBMS_SERVICE_COUNTING_FAILURE(instance_t instance, m2ap_mbms_service_counting_failure_t * m2ap_mbms_service_counting_failure)
{
- AssertFatal(1==0,"Not implemented yet\n");
+ M2AP_M2AP_PDU_t pdu;
+ M2AP_MbmsServiceCountingFailure_t *out;
+ M2AP_MbmsServiceCountingFailure_Ies_t *ie;
+
+ uint8_t *buffer;
+ uint32_t len;
+ //int i = 0;
+
+ /* Create */
+ /* 0. Message Type */
+ memset(&pdu, 0, sizeof(pdu));
+ pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome;
+ //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t));
+ pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_mbmsServiceCounting;
+ pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject;
+ pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_MbmsServiceCountingFailure;
+ out = &pdu.choice.unsuccessfulOutcome.value.choice.MbmsServiceCountingFailure;
+
+
+ /* mandatory */
+ /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long
+ ie = (M2AP_MbmsServiceCountingFailure_Ies_t*)calloc(1, sizeof(M2AP_MbmsServiceCountingFailure_Ies_t));
+ ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID;
+ ie->criticality = M2AP_Criticality_reject;
+ ie->value.present = M2AP_MbmsServiceCountingFailure_Ies__value_PR_CriticalityDiagnostics;
+ //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //?
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ /* mandatory */
+ /* c2. Cause */
+ ie = (M2AP_MbmsServiceCountingFailure_Ies_t *)calloc(1, sizeof(M2AP_MbmsServiceCountingFailure_Ies_t));
+ ie->id = M2AP_ProtocolIE_ID_id_Cause;
+ ie->criticality = M2AP_Criticality_ignore;
+ ie->value.present = M2AP_MbmsServiceCountingFailure_Ies__value_PR_Cause;
+ ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
+ ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_unspecified;
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+ if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+ LOG_E(M2AP, "Failed to encode MBMS Service Counting Results Report\n");
+ return -1;
+ }
+
+
return 0;
}
diff --git a/openair2/MCE_APP/mce_app.c b/openair2/MCE_APP/mce_app.c
index 6f7454c321..817c863f7b 100644
--- a/openair2/MCE_APP/mce_app.c
+++ b/openair2/MCE_APP/mce_app.c
@@ -372,7 +372,8 @@ void *MCE_app_task(void *args_p) {
// /* Try to register each MCE with MCE each other */
if (is_m3ap_MCE_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) {
- ///*m3_register_mce_pending =*/ MCE_app_register_m3 (mce_id_start, mce_id_end);
+ ///*m3_register_mce_pending =*/
+ MCE_app_register_m3 (mce_id_start, mce_id_end);
}
do {
@@ -627,7 +628,7 @@ void *MCE_app_task(void *args_p) {
//}
- /*m3_register_mce_pending =*/ MCE_app_register_m3 (mce_id_start, mce_id_end);
+ /*m3_register_mce_pending =*/ //MCE_app_register_m3 (mce_id_start, mce_id_end);
//MCE_app_send_m2ap_session_start_req(0);
break;
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index 5a89ffb5e7..c5b90cf028 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -78,102 +78,8 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
}
-void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, int target_snrx10) {
- // TODO
- int max_harq_rounds = 4; // TODO define macro
- int num_ucis = UL_info->uci_ind.num_ucis;
- nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list;
+void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) {
- for (int i = 0; i < num_ucis; i++) {
- switch (uci_list[i].pdu_type) {
- case NFAPI_NR_UCI_PDCCH_PDU_TYPE: break;
-
- case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
- //if (get_softmodem_params()->phy_test == 0) {
- nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
- // handle harq
- int harq_idx_s = 0;
- // tpc (power control)
- sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
- // iterate over received harq bits
- for (int harq_bit = 0; harq_bit < uci_pdu->harq->num_harq; harq_bit++) {
- // search for the right harq process
- for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) {
- // if the gNB received ack with a good confidence or if the max harq rounds was reached
- if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
- if (((uci_pdu->harq->harq_list[harq_bit].harq_value == 1) &&
- (uci_pdu->harq->harq_confidence_level == 0)) ||
- (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds)) {
- // toggle NDI and reset round
- sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
- sched_ctrl->harq_processes[harq_idx].round = 0;
- }
- else
- sched_ctrl->harq_processes[harq_idx].round++;
- sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
- harq_idx_s = harq_idx + 1;
- break;
- }
- // if gNB fails to receive a ACK/NACK
- else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) &&
- (sched_ctrl->harq_processes[harq_idx].is_waiting)) {
- sched_ctrl->harq_processes[harq_idx].round++;
- if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
- sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
- sched_ctrl->harq_processes[harq_idx].round = 0;
- }
- sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
- }
- }
- }
- //}
- break;
- }
-
- case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: break;
- }
- }
-
- UL_info->uci_ind.num_ucis = 0;
-}
-
-void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, uint8_t crc_status) {
-
- int max_harq_rounds = 4; // TODO define macro
- for (uint8_t hrq_id = 0; hrq_id < NR_MAX_NB_HARQ_PROCESSES; hrq_id++) {
- NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id];
- if ((cur_harq->last_tx_slot == slot-1) && cur_harq->state==ACTIVE_SCHED) {
- if (!crc_status) {
- cur_harq->ndi ^= 1;
- cur_harq->round = 0;
- cur_harq->state = INACTIVE; // passed -> make inactive. can be used by scheduder for next grant
-#ifdef UL_HARQ_PRINT
- printf("[HARQ HANDLER] Ulharq id %d crc passed, freeing it for scheduler\n",hrq_id);
-#endif
- } else {
- cur_harq->round++;
- cur_harq->state = ACTIVE_NOT_SCHED;
-#ifdef UL_HARQ_PRINT
- printf("[HARQ HANDLER] Ulharq id %d crc failed, requesting retransmission\n",hrq_id);
-#endif
- }
-
- if (!(cur_harq->roundndi ^= 1;
- cur_harq->state = INACTIVE; // failed after 4 rounds -> make inactive
- cur_harq->round = 0;
-#ifdef UL_HARQ_PRINT
- printf("[HARQ HANDLER] Ulharq id %d crc failed in all round, freeing it for scheduler\n",hrq_id);
-#endif
- }
- return;
- }
- }
-
-}
-
-
-void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
if(nfapi_mode == 1) {
if (UL_info->crc_ind.number_crcs>0) {
//LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf));
@@ -200,7 +106,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
UL_info->rx_ind.pdu_list[i].rnti) {
LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_list[j].tb_crc_status);
- handle_nr_ul_harq(UL_info->slot, sched_ctrl, UL_info->crc_ind.crc_list[j].tb_crc_status);
+ handle_nr_ul_harq(UL_info->slot, sched_ctrl, stats, UL_info->crc_ind.crc_list[j]);
if (UL_info->crc_ind.crc_list[j].tb_crc_status == 1) { // CRC error indication
LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot);
@@ -213,7 +119,8 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
(uint8_t *)NULL,
UL_info->rx_ind.pdu_list[i].pdu_length,
UL_info->rx_ind.pdu_list[i].timing_advance,
- UL_info->rx_ind.pdu_list[i].ul_cqi);
+ UL_info->rx_ind.pdu_list[i].ul_cqi,
+ UL_info->rx_ind.pdu_list[i].rssi);
} else {
LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot);
nr_rx_sdu(UL_info->module_id,
@@ -224,7 +131,8 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
UL_info->rx_ind.pdu_list[i].pdu,
UL_info->rx_ind.pdu_list[i].pdu_length,
UL_info->rx_ind.pdu_list[i].timing_advance,
- UL_info->rx_ind.pdu_list[i].ul_cqi);
+ UL_info->rx_ind.pdu_list[i].ul_cqi,
+ UL_info->rx_ind.pdu_list[i].rssi);
}
break;
}
@@ -252,7 +160,6 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
NR_Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id];
NR_IF_Module_t *ifi = if_inst[module_id];
gNB_MAC_INST *mac = RC.nrmac[module_id];
-
LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rach_pdus:%d rx_ind:%d crcs:%d]\n",
UL_info->frame,UL_info->slot,
module_id,CC_id, UL_info->rach_ind.number_of_pdus,
@@ -273,10 +180,11 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
// clear DL/UL info for new scheduling round
clear_nr_nfapi_information(mac,CC_id,UL_info->frame,UL_info->slot);
handle_nr_rach(UL_info);
- handle_nr_uci(UL_info,&mac->UE_list.UE_sched_ctrl[0],mac->pucch_target_snrx10);
+
+ handle_nr_uci(UL_info,&mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0],mac->pucch_target_snrx10);
// clear HI prior to handling ULSCH
mac->UL_dci_req[CC_id].numPdus = 0;
- handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0]);
+ handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0]);
if (nfapi_mode != 1) {
if (ifi->CC_mask == ((1<config[CC_id];
int spf = get_spf(cfg);
gNB_dlsch_ulsch_scheduler(module_id,
- UL_info->frame,
- UL_info->slot,
(UL_info->frame+((UL_info->slot>(spf-1-sl_ahead))?1:0)) % 1024,
(UL_info->slot+sl_ahead)%spf);
@@ -301,13 +207,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
sched_info->DL_req = &mac->DL_req[CC_id];
sched_info->UL_dci_req = &mac->UL_dci_req[CC_id];
- if ((mac->common_channels[CC_id].ServingCellConfigCommon->tdd_UL_DL_ConfigurationCommon==NULL) ||
- (is_nr_UL_slot(mac->common_channels[CC_id].ServingCellConfigCommon,UL_info->slot)>0)) {
- //printf("NR_UL_indication: this is an UL slot. UL_info: frame %d, slot %d. UL_tti_req: frame %d, slot %d\n",UL_info->frame,UL_info->slot,mac->UL_tti_req[CC_id].SFN,mac->UL_tti_req[CC_id].Slot);
- sched_info->UL_tti_req = &mac->UL_tti_req[CC_id];
- }
- else
- sched_info->UL_tti_req = NULL;
+ sched_info->UL_tti_req = &mac->UL_tti_req[CC_id];
sched_info->TX_req = &mac->TX_req[CC_id];
#ifdef DUMP_FAPI
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index e63f93b028..91cc965473 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -167,13 +167,16 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
for(i=0; idci_ind->number_of_dcis; ++i){
LOG_D(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
- ret_mask |= (handle_dci(dl_info->module_id,
+ int8_t ret = handle_dci(dl_info->module_id,
dl_info->cc_id,
dl_info->gNB_index,
- dl_info->dci_ind->dci_list+i)<< FAPI_NR_DCI_IND);
+ dl_info->dci_ind->dci_list+i);
- AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is void!\n" );
- nr_ue_if_module_inst[module_id]->scheduled_response(&mac->scheduled_response);
+ ret_mask |= (ret << FAPI_NR_DCI_IND);
+ if (ret >= 0) {
+ AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is void!\n" );
+ nr_ue_if_module_inst[module_id]->scheduled_response(&mac->scheduled_response);
+ }
}
}
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 41fb3ddc3a..de42d67624 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -800,7 +800,37 @@ void dl_config_req_UE_MAC_dci(int sfn,
UE_mac_inst[ue_id].first_ULSCH_Tx = 1;
}
}
- } else {
+ }
+ //else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) {
+ // // BCH case: Last parameter is 1 if first time synchronization and zero
+ // // otherwise. Not sure which value to put for our case.
+ // if (UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED){
+ // dl_phy_sync_success(Mod_id, sfn, 0, 1);
+ // LOG_E(MAC,
+ // "%s(): Received MIB: UE_mode: %d, sfn/sf: %d.%d\n",
+ // __func__,
+ // UE_mac_inst[Mod_id].UE_mode[0],
+ // sfn,
+ // sf);
+ // UE_mac_inst[Mod_id].UE_mode[0] = PRACH;
+ // } else {
+ // dl_phy_sync_success(Mod_id, sfn, 0, 0);
+ // }
+ //} else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_MCH_PDU_TYPE){
+ // if (UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED) {
+ // /* this check is in the code before refactoring, but I don't know
+ // * why. Leave it in here for the moment */
+ // continue;
+ // }
+ // nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp = &dl_config_pdu_list[i];
+ // const int pdu_index = dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index;
+ // ue_send_mch_sdu(Mod_id, 0, sfn,
+ // tx_request_pdu_list[pdu_index].segments[0].segment_data,
+ // tx_request_pdu_list[pdu_index].segments[0].segment_length,
+ // 0,0);
+
+ //}
+ else {
LOG_W(MAC, "can not handle special RNTI %x\n", rnti);
}
}
diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c
index 68017be85b..d9682b466f 100644
--- a/openair2/RRC/LTE/L2_interface.c
+++ b/openair2/RRC/LTE/L2_interface.c
@@ -28,6 +28,15 @@
* \email: raymond.knopp@eurecom.fr
*/
+/*! \file l2_interface.c
+ * \brief layer 2 interface, added support for FeMBMS RRC sublayer
+ * \author Javier Morgade
+ * \date 2020
+ * \version 1.0
+ * \email: javier.morgade@ieee.org
+ */
+
+
#include "platform_types.h"
#include "rrc_defs.h"
#include "rrc_extern.h"
@@ -65,6 +74,9 @@ mac_rrc_data_req(
uint8_t Sdu_size = 0;
uint8_t sfn = (uint8_t)((frameP>>2)&0xff);
+ uint8_t sfn_fembms = (uint8_t)((frameP>>4)&0xff);
+ sfn_fembms = sfn_fembms<<2;
+
if (LOG_DEBUGFLAG(DEBUG_RRC)) {
LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id);
}
@@ -72,12 +84,14 @@ mac_rrc_data_req(
eNB_RRC_INST *rrc;
rrc_eNB_carrier_data_t *carrier;
LTE_BCCH_BCH_Message_t *mib;
+ LTE_BCCH_BCH_Message_MBMS_t *mib_fembms;
rrc = RC.rrc[Mod_idP];
carrier = &rrc->carrier[0];
mib = &carrier->mib;
+ mib_fembms = &carrier->mib_fembms;
if((Srb_id & RAB_OFFSET) == BCCH_SI_MBMS){
- if (frameP%4 == 0) {
+ if (frameP%8 == 0) {
memcpy(&buffer_pP[0],
RC.rrc[Mod_idP]->carrier[CC_id].SIB1_MBMS,
RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_MBMS);
@@ -159,6 +173,22 @@ mac_rrc_data_req(
return(3);
}
+ if( (Srb_id & RAB_OFFSET ) == MIBCH_MBMS) {
+ mib_fembms->message.systemFrameNumber_r14.buf = &sfn_fembms;
+ enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message_MBMS,
+ NULL,
+ (void *)mib_fembms,
+ carrier->MIB_FeMBMS,
+ 24);
+ LOG_I(RRC,"Encoded MIB MBMS for frame %d (%p), bits %lu %x,%x,%x %x bits_unused %d\n",sfn_fembms>>2,carrier->MIB_FeMBMS,enc_rval.encoded,carrier->MIB_FeMBMS[0],carrier->MIB_FeMBMS[1],carrier->MIB_FeMBMS[2],mib_fembms->message.systemFrameNumber_r14.buf[0],mib_fembms->message.systemFrameNumber_r14.bits_unused);
+ buffer_pP[0]=carrier->MIB_FeMBMS[0];
+ buffer_pP[1]=carrier->MIB_FeMBMS[1];
+ buffer_pP[2]=carrier->MIB_FeMBMS[2];
+ AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
+ enc_rval.failed_type->name, enc_rval.encoded);
+ return(3);
+ }
+
if( (Srb_id & RAB_OFFSET ) == CCCH) {
struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti);
@@ -203,8 +233,10 @@ mac_rrc_data_req(
RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area],
RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]);
+ LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP);
+
if (LOG_DEBUGFLAG(DEBUG_RRC)) {
- LOG_W(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP);
+ LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP);
for (int i=0; icarrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]; i++) {
LOG_T(RRC,"%x.",buffer_pP[i]);
@@ -216,6 +248,29 @@ mac_rrc_data_req(
return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]);
}
+ if((Srb_id & RAB_OFFSET) == MCCH_COUNTING) {
+ if(RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESS_COUNTING[mbsfn_sync_area].Active==0) {
+ return 0; // this parameter is set in function init_mcch in rrc_eNB.c
+ }
+
+ memcpy(&buffer_pP[0],
+ RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE_COUNTING[mbsfn_sync_area],
+ RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE_COUNTING[mbsfn_sync_area]);
+
+ if (LOG_DEBUGFLAG(DEBUG_RRC)) {
+ LOG_W(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE_COUNTING \n",Mod_idP,frameP);
+
+ for (int i=0; icarrier[CC_id].sizeof_MCCH_MESSAGE_COUNTING[mbsfn_sync_area]; i++) {
+ LOG_T(RRC,"%x.",buffer_pP[i]);
+ }
+
+ LOG_T(RRC,"\n");
+ } /* LOG_DEBUGFLAG(DEBUG_RRC) */
+
+ return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE_COUNTING[mbsfn_sync_area]);
+ }
+
+
if ((Srb_id & RAB_OFFSET) == BCCH_SIB1_BR) {
memcpy(&buffer_pP[0],
RC.rrc[Mod_idP]->carrier[CC_id].SIB1_BR,
diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c
index 61ab63955d..8c55dbaeb5 100644
--- a/openair2/RRC/LTE/L2_interface_ue.c
+++ b/openair2/RRC/LTE/L2_interface_ue.c
@@ -19,7 +19,7 @@
* contact@openairinterface.org
*/
-/*! \file l2_interface.c
+/*! \file l2_interface_ue.c
* \brief layer 2 interface, used to support different RRC sublayer
* \author Raymond Knopp and Navid Nikaein
* \date 2010-2014
@@ -28,6 +28,16 @@
* \email: raymond.knopp@eurecom.fr
*/
+
+/*! \file l2_interface_ue.c
+ * \brief layer 2 interface, added support for FeMBMS RRC sublayer
+ * \author J. Morgade
+ * \date 2020
+ * \version 1.0
+ * \email: javier.morgade@ieee.org
+ */
+
+
#include "platform_types.h"
#include "rrc_defs.h"
#include "rrc_extern.h"
@@ -219,6 +229,7 @@ mac_rrc_data_ind_ue(
if ((srb_idP & RAB_OFFSET) == MCCH) {
LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %ld from eNB %d\n",
module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP);
+
{
MessageDef *message_p;
int msg_sdu_size = sizeof(RRC_MAC_MCCH_DATA_IND (message_p).sdu);
diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
index c537c536b2..09e6245fec 100644
--- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
@@ -28,6 +28,14 @@
* \email: raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr
*/
+/*! \file asn1_msg.c
+ * \brief added primitives to build the asn1 messages for FeMBMS
+ * \author Javier Morgade
+ * \date 2019-2020
+ * \version 1.0
+ * \email: javier.morgade@ieee.org
+ */
+
#include
#include
#include /* for atoi(3) */
@@ -185,7 +193,8 @@ uint8_t get_adjacent_cell_mod_id(uint16_t phyCellId) {
uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t additionalNonMBSFN, uint32_t frame) {
asn_enc_rval_t enc_rval;
LTE_BCCH_BCH_Message_MBMS_t *mib_fembms=&carrier->mib_fembms;
- uint8_t sfn = (uint8_t)((frame>>2)&0xff);
+ frame=198;
+ uint8_t sfn = (uint8_t)((frame>>4)&0xff);
uint16_t *spare = calloc(1,sizeof(uint16_t));
if( spare == NULL ) abort();
@@ -223,15 +232,16 @@ uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_
(uint32_t)mib_fembms->message.dl_Bandwidth_MBMS_r14,
(uint32_t)additionalNonMBSFN,
(uint32_t)sfn);
+ sfn = sfn<<2;
mib_fembms->message.systemFrameNumber_r14.buf = &sfn;
mib_fembms->message.systemFrameNumber_r14.size = 1;
- mib_fembms->message.systemFrameNumber_r14.bits_unused=0;
+ mib_fembms->message.systemFrameNumber_r14.bits_unused=2;
mib_fembms->message.spare.buf = (uint8_t *)spare;
mib_fembms->message.spare.size = 2;
- mib_fembms->message.spare.bits_unused = 6; // This makes a spare of 10 bits
+ mib_fembms->message.spare.bits_unused = 3; // This makes a spare of 10 bits
//TODO additionalNonBMSFNSubframes-r14 INTEGER (0..3) ?
//if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
- //xer_fprint(stdout, &asn_DEF_LTE_BCCH_BCH_Message_MBMS, (void *)mib_fembms);
+ xer_fprint(stdout, &asn_DEF_LTE_BCCH_BCH_Message_MBMS, (void *)mib_fembms);
//}
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message_MBMS,
NULL,
@@ -387,7 +397,11 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier,
// SystemInformation_t systemInformation;
int num_plmn = configuration->num_plmn;
- LTE_PLMN_IdentityInfo_t *PLMN_identity_info;
+ //LTE_PLMN_IdentityInfo_t *PLMN_identity_info;
+ LTE_PLMN_IdentityInfo_t * PLMN_identity_info = &carrier->PLMN_identity_info_MBMS[0];
+ //LTE_MCC_MNC_Digit_t dummy_mcc[num_plmn][3], dummy_mnc[num_plmn][3];
+ //LTE_MCC_MNC_Digit_t *dummy_mcc = &carrier->dummy_mcc_MBMS[0][0];
+ //LTE_MCC_MNC_Digit_t *dummy_mnc = &carrier->dummy_mnc_MBMS[0][0];
LTE_MCC_MNC_Digit_t *dummy_mcc_0;
LTE_MCC_MNC_Digit_t *dummy_mcc_1;
LTE_MCC_MNC_Digit_t *dummy_mcc_2;
@@ -395,7 +409,9 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier,
LTE_MCC_MNC_Digit_t *dummy_mnc_1;
LTE_MCC_MNC_Digit_t *dummy_mnc_2;
asn_enc_rval_t enc_rval;
- LTE_SchedulingInfo_MBMS_r14_t *schedulingInfo;
+ //LTE_SchedulingInfo_MBMS_r14_t *schedulingInfo;
+ //LTE_SchedulingInfo_MBMS_r14_t schedulingInfo;
+ LTE_SchedulingInfo_MBMS_r14_t *schedulingInfo = &carrier->schedulingInfo_MBMS;
LTE_SIB_Type_t *sib_type;
uint8_t *buffer = carrier->SIB1_MBMS;
LTE_BCCH_DL_SCH_Message_MBMS_t *bcch_message = &carrier->siblock1_MBMS;
@@ -408,6 +424,8 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier,
// memcpy(&bcch_message.message.choice.c1.choice.systemInformationBlockType1,sib1,sizeof(SystemInformationBlockType1_t));
*sib1_MBMS = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_MBMS_r14;
PLMN_identity_info = CALLOC(1, sizeof(LTE_PLMN_IdentityInfo_t) * num_plmn);
+ //memset(&schedulingInfo,0,sizeof(LTE_SchedulingInfo_MBMS_r14_t));
+ memset(schedulingInfo,0,sizeof(LTE_SchedulingInfo_MBMS_r14_t));
if (PLMN_identity_info == NULL)
exit(1);
@@ -528,7 +546,7 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier,
MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1;
MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=0x20<<2; // FDD: SF1
MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2;
- MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n7;
+ MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n2;
(MBSFN_Area1)->ext1 = CALLOC (1, sizeof(*(MBSFN_Area1)->ext1));
memset((MBSFN_Area1)->ext1,0,sizeof(*(MBSFN_Area1)->ext1));
MBSFN_Area1->ext1->subcarrierSpacingMBMS_r14 = CALLOC(1,sizeof(*( MBSFN_Area1->ext1)->subcarrierSpacingMBMS_r14));
@@ -541,18 +559,18 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier,
if(1) {
(*sib1_MBMS)->nonMBSFN_SubframeConfig_r14 = CALLOC(1,sizeof(struct LTE_NonMBSFN_SubframeConfig_r14));
memset((*sib1_MBMS)->nonMBSFN_SubframeConfig_r14,0,sizeof(struct LTE_NonMBSFN_SubframeConfig_r14));
- (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->radioFrameAllocationPeriod_r14 = LTE_NonMBSFN_SubframeConfig_r14__radioFrameAllocationPeriod_r14_rf8;
+ (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->radioFrameAllocationPeriod_r14 = LTE_NonMBSFN_SubframeConfig_r14__radioFrameAllocationPeriod_r14_rf4;
(*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->radioFrameAllocationOffset_r14 = 0;
(*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf = MALLOC(2);
//100000001 byte(0)=10000000 byte(1)=xxxxxxx1
- (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[0] = 0x80<<0;
- (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[1] = 0x1<<7;
+ (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[0] = 0x8<<0;
+ (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[1] = 0;
(*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.size = 2;
(*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.bits_unused = 7;
}
//if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
- //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, (void *)bcch_message);
+ xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, (void *)bcch_message);
//}
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS,
NULL,
diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c
index bdf992c76a..c5aa2bc0f8 100644
--- a/openair2/RRC/LTE/rrc_UE.c
+++ b/openair2/RRC/LTE/rrc_UE.c
@@ -155,14 +155,19 @@ static uint8_t check_trigger_meas_event(
LTE_Q_OffsetRange_t ofs, LTE_Q_OffsetRange_t ocs, long a3_offset, LTE_TimeToTrigger_t ttt);
static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area);
+static void decode_MBMSCountingRequest(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area);
+
uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq,
SL_TRIGGER_t mode);
-
-
-
-
-
+void
+rrc_ue_process_MBMSCountingRequest(
+ const protocol_ctxt_t *const ctxt_pP,
+ LTE_MBMSCountingRequest_r10_t *MBMSCountingRequest,
+ uint8_t eNB_index
+ );
+
+protocol_ctxt_t ctxt_pP_local;
/*------------------------------------------------------------------------------*/
@@ -520,6 +525,7 @@ static void rrc_ue_generate_RRCConnectionSetupComplete(
LOG_D(RLC,
"[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
ctxt_pP->frame, ctxt_pP->module_id+NB_eNB_INST, size, eNB_index, rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH);
+ ctxt_pP_local.rnti = ctxt_pP->rnti;
rrc_data_req_ue (
ctxt_pP,
DCCH,
@@ -1572,6 +1578,65 @@ rrc_ue_process_securityModeCommand(
securityModeCommand->criticalExtensions.present);
}
+void
+rrc_ue_process_MBMSCountingRequest(
+ const protocol_ctxt_t *const ctxt_pP,
+ LTE_MBMSCountingRequest_r10_t *MBMSCountingRequest,
+ uint8_t eNB_index
+)
+{
+ asn_enc_rval_t enc_rval;
+ LTE_UL_DCCH_Message_t ul_dcch_msg;
+ struct LTE_CountingResponseInfo_r10 CountingResponse;
+ uint8_t buffer[200];
+ //int i;
+ LOG_I(RRC,"[UE %d] Frame %d: Receiving from (MCCH), Processing MBMSCoutingRequest (eNB %d)\n",
+ ctxt_pP->module_id,
+ ctxt_pP->frame,
+ eNB_index);
+ memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t));
+ memset((void *)&CountingResponse,0,sizeof(struct LTE_CountingResponseInfo_r10));
+
+
+ ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1;
+ ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10;
+ LTE_MBMSCountingResponse_r10_t *MBMSCountingResponse = &ul_dcch_msg.message.choice.c1.choice.mbmsCountingResponse_r10;
+
+ MBMSCountingResponse->criticalExtensions.present = LTE_MBMSCountingResponse_r10__criticalExtensions_PR_c1;
+ MBMSCountingResponse->criticalExtensions.choice.c1.present = LTE_MBMSCountingResponse_r10__criticalExtensions__c1_PR_countingResponse_r10;
+ LTE_MBMSCountingResponse_r10_IEs_t *MBMSCountingResponse_r10_IEs = &MBMSCountingResponse->criticalExtensions.choice.c1.choice.countingResponse_r10;
+
+ MBMSCountingResponse_r10_IEs->mbsfn_AreaIndex_r10 = calloc(1,sizeof(long));
+ // MBMSCountingResponse_r10_IEs->countingResponseList_r10 = calloc(1,sizeof(struct LTE_CountingResponseList_r10));
+//
+// ASN_SEQUENCE_ADD(
+// &MBMSCountingResponse->criticalExtensions.choice.c1.choice.countingResponse_r10.countingResponseList_r10.list,
+// &CountingResponse);
+//
+
+ enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 100);
+ AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
+ enc_rval.failed_type->name, enc_rval.encoded);
+
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+ xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg);
+ }
+ xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg);
+
+
+ LOG_I(RRC,"MBMSCountingResponse Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
+ rrc_data_req_ue (
+ &ctxt_pP_local,
+ DCCH,
+ rrc_mui++,
+ SDU_CONFIRM_NO,
+ (enc_rval.encoded + 7) / 8,
+ buffer,
+ PDCP_TRANSMISSION_MODE_CONTROL);
+
+}
+
+
//-----------------------------------------------------------------------------
void
rrc_ue_process_ueCapabilityEnquiry(
@@ -2189,8 +2254,8 @@ rrc_ue_decode_dcch(
#endif
}
-const char siWindowLength[8][5] = {"1ms","2ms","5ms","10ms","15ms","20ms","40ms","ERR"};
-const char siWindowLength_int[7] = {1,2,5,10,15,20,40};
+const char siWindowLength[9][5] = {"1ms","2ms","5ms","10ms","15ms","20ms","40ms","80ms","ERR"};
+const char siWindowLength_int[8] = {1,2,5,10,15,20,40,80};
const char SIBType[12][6] = {"SIB3","SIB4","SIB5","SIB6","SIB7","SIB8","SIB9","SIB10","SIB11","SIB12","SIB13","Spare"};
const char SIBPeriod[8][6]= {"rf8","rf16","rf32","rf64","rf128","rf256","rf512","ERR"};
@@ -2700,7 +2765,7 @@ int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_in
//LOG_I( RRC, "TDD subframeAssignment : %ld\n", sib1_MBMS->tdd_Config->subframeAssignment );
//LOG_I( RRC, "TDD specialSubframePatterns : %ld\n", sib1_MBMS->tdd_Config->specialSubframePatterns );
//}
- LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1_MBMS->si_WindowLength_r14,7)] );
+ LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1_MBMS->si_WindowLength_r14,8)] );
LOG_I( RRC, "systemInfoValueTag : %ld\n", sib1_MBMS->systemInfoValueTag_r14 );
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod_MBMS = siPeriod_int[sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[0]->si_Periodicity_r14];
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize_MBMS = siWindowLength_int[sib1_MBMS->si_WindowLength_r14];
@@ -2898,7 +2963,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,
LOG_I( RRC, "TDD specialSubframePatterns : %ld\n", sib1->tdd_Config->specialSubframePatterns );
}
- LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1->si_WindowLength,7)] );
+ LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1->si_WindowLength,8)] );
LOG_I( RRC, "systemInfoValueTag : %ld\n", sib1->systemInfoValueTag );
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod = siPeriod_int[sib1->schedulingInfoList.list.array[0]->si_Periodicity];
UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize = siWindowLength_int[sib1->si_WindowLength];
@@ -4225,7 +4290,7 @@ int decode_MCCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB
ctxt_pP->frame,
mbsfn_sync_area);
return 0; // avoid decoding to prevent memory bloating
- } else if(UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State >= RRC_CONNECTED /*|| UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_RECONFIGURED*/){
+ } else if(1/*UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State >= RRC_CONNECTED*/ /*|| UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_RECONFIGURED*/){
dec_rval = uper_decode_complete(NULL,
&asn_DEF_LTE_MCCH_Message,
(void **)&mcch,
@@ -4244,6 +4309,7 @@ int decode_MCCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_LTE_MCCH_Message, (void *)mcch);
}
+ xer_fprint(stdout, &asn_DEF_LTE_MCCH_Message, (void *)mcch);
if (mcch->message.present == LTE_MCCH_MessageType_PR_c1) {
LOG_D(RRC,"[UE %d] Found mcch message \n",
@@ -4265,7 +4331,29 @@ int decode_MCCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB
ctxt_pP->frame,
mbsfn_sync_area);
}
+ }else if(mcch->message.present == LTE_MCCH_MessageType_PR_later){
+ LOG_D(RRC,"[UE %d] Found mcch message \n",
+ ctxt_pP->module_id);
+ if(mcch->message.choice.later.present == LTE_MCCH_MessageType__later_PR_c2){
+ if(mcch->message.choice.later.choice.c2.present == LTE_MCCH_MessageType__later__c2_PR_mbmsCountingRequest_r10){
+ LOG_I(RRC,"[UE %d] Frame %d : Found MBMSCountingRequest from eNB %d %p\n",
+ ctxt_pP->module_id,
+ ctxt_pP->frame,
+ eNB_index,&mcch->message.choice.later.choice.c2.choice.mbmsCountingRequest_r10);
+
+ rrc_ue_process_MBMSCountingRequest(ctxt_pP,&mcch->message.choice.later.choice.c2.choice.mbmsCountingRequest_r10,eNB_index);
+
+ decode_MBMSCountingRequest(
+ ctxt_pP->module_id,
+ eNB_index,
+ ctxt_pP->frame,
+ mbsfn_sync_area);
+
+
+ }
+ }
}
+
}
return 0;
@@ -4323,7 +4411,7 @@ void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, f
(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL,
(LTE_MBSFN_AreaInfoList_r9_t *)NULL
);
- if(UE_rrc_inst[ue_mod_idP].Info[eNB_index].State >= RRC_CONNECTED /*|| UE_rrc_inst[ue_mod_idP].Info[eNB_index].State == RRC_RECONFIGURED*/)
+ if(1/*UE_rrc_inst[ue_mod_idP].Info[eNB_index].State >= RRC_CONNECTED*/ /*|| UE_rrc_inst[ue_mod_idP].Info[eNB_index].State == RRC_RECONFIGURED*/)
UE_rrc_inst[ue_mod_idP].Info[eNB_index].MCCHStatus[mbsfn_sync_area] = 1;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, UE_rrc_inst[ue_mod_idP].Info[eNB_index].rnti, frameP, 0,eNB_index);
// Config Radio Bearer for MBMS user data (similar way to configure for eNB side in init_MBMS function)
@@ -4347,6 +4435,13 @@ void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, f
// */
}
+void decode_MBMSCountingRequest( module_id_t ue_mod_idP, uint8_t eNB_index, frame_t frameP, uint8_t mbsfn_sync_area ) {
+ //uint8_t i;
+ //protocol_ctxt_t ctxt;
+
+
+
+}
//-----------------------------------------------------------------------------
void *rrc_ue_task( void *args_p ) {
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index 3c02c45bc1..c498e3c6fe 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -716,6 +716,9 @@ typedef struct {
LTE_BCCH_BCH_Message_MBMS_t mib_fembms;
LTE_BCCH_DL_SCH_Message_MBMS_t siblock1_MBMS;
LTE_BCCH_DL_SCH_Message_MBMS_t systemInformation_MBMS;
+ LTE_SchedulingInfo_MBMS_r14_t schedulingInfo_MBMS;
+ LTE_PLMN_IdentityInfo_t PLMN_identity_info_MBMS[6];
+ LTE_MCC_MNC_Digit_t dummy_mcc_MBMS[6][3], dummy_mnc_MBMS[6][3];
LTE_SystemInformationBlockType1_t *sib1;
LTE_SystemInformationBlockType2_t *sib2;
LTE_SystemInformationBlockType3_t *sib3;
@@ -732,6 +735,12 @@ typedef struct {
LTE_MCCH_Message_t mcch;
LTE_MBSFNAreaConfiguration_r9_t *mcch_message;
SRB_INFO MCCH_MESS[8];// MAX_MBSFN_AREA
+ uint8_t **MCCH_MESSAGE_COUNTING; // MAX_MBSFN_AREA
+ uint8_t sizeof_MCCH_MESSAGE_COUNTING[8];// MAX_MBSFN_AREA
+ LTE_MCCH_Message_t mcch_counting;
+ LTE_MBMSCountingRequest_r10_t *mcch_message_counting;
+ SRB_INFO MCCH_MESS_COUNTING[8];// MAX_MBSFN_AREA
+
//TTN - SIB 18,19,21 for D2D
LTE_SystemInformationBlockType18_r12_t *sib18;
LTE_SystemInformationBlockType19_r12_t *sib19;
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 933fefe94f..108fea426d 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -155,6 +155,7 @@ init_SI(
LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__);
if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE) {
+
LOG_I(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n",
(int)configuration->N_RB_DL[CC_id]);
RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4);
@@ -231,6 +232,7 @@ init_SI(
RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf);
}
+ RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag=1;
//AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255");
}
@@ -496,12 +498,15 @@ init_SI(
(LTE_PMCH_InfoList_r9_t *) NULL,
sib1_v13ext,
RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag,
- (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
+ (carrier->sib1_MBMS==NULL?(LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL:(LTE_BCCH_DL_SCH_Message_MBMS_t *)carrier->sib1_MBMS),//(LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
- (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
- (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
- );
+ (carrier->sib1_MBMS==NULL?(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL:(struct LTE_NonMBSFN_SubframeConfig_r14 *)carrier->sib1_MBMS->nonMBSFN_SubframeConfig_r14),//(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
+ (carrier->sib1_MBMS==NULL?(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL:(LTE_SystemInformationBlockType1_MBMS_r14_t *)carrier->sib1_MBMS->systemInformationBlockType13_r14),//(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
+ (carrier->sib1_MBMS==NULL?(LTE_MBSFN_AreaInfoList_r9_t *) NULL:(LTE_MBSFN_AreaInfoList_r9_t *)&carrier->sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9)//(LTE_MBSFN_AreaInfoList_r9_t *) NULL
+
+ ,(LTE_MBSFNAreaConfiguration_r9_t*) NULL
+
+ );
}
/* set flag to indicate that cell information is configured. This is required
@@ -584,7 +589,8 @@ init_MCCH(
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
}
@@ -1481,7 +1487,8 @@ rrc_eNB_generate_RRCConnectionReestablishment(
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
break;
}
@@ -5782,7 +5789,8 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
// Configure target eNB SRB2
/// SRB2
@@ -6462,7 +6470,8 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
}
@@ -6678,7 +6687,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
}
} else { // remove LCHAN from MAC/PHY
@@ -6737,7 +6747,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
}
} // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0)
@@ -6899,7 +6910,8 @@ rrc_eNB_generate_RRCConnectionSetup(
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
break;
}
@@ -8372,6 +8384,8 @@ rrc_eNB_decode_dcch(
case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10:
T(T_ENB_RRC_MBMS_COUNTING_RESPONSE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
+ LOG_E(RRC, "THINH [LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10]\n");
+
break;
case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10:
@@ -9076,47 +9090,53 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP,
return;
}
- protocol_ctxt_t ctxt;
- rrc_eNB_ue_context_t *ue_context;
- unsigned char buffer[8192];
- int size;
- ue_context = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], m->rnti);
- ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded;
- int j=0;
+ protocol_ctxt_t ctxt;
+ rrc_eNB_ue_context_t *ue_context;
+ unsigned char buffer[8192];
+ int size;
- while(j < m->nb_e_rabs_admitted_tobeadded) {
- for (int e_rab_idx=0; e_rab_idxue_context.setup_e_rabs; e_rab_idx++) {
- //Update ue_context information with gNB's address and new GTP tunnel ID
- if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id) {
- memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer,
- m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer,
- m->e_rabs_admitted_tobeadded[j].gnb_addr.length);
- ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length;
- ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid;
- ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY;
- break;
+ ue_context = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], m->rnti);
+ if (ue_context) {
+ ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded;
+
+ int j=0;
+ while(j < m->nb_e_rabs_admitted_tobeadded){
+ for (int e_rab_idx=0; e_rab_idxue_context.setup_e_rabs; e_rab_idx++){
+ //Update ue_context information with gNB's address and new GTP tunnel ID
+ if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id){
+ memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer,
+ m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer,
+ m->e_rabs_admitted_tobeadded[j].gnb_addr.length);
+ ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length;
+ ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid;
+ ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY;
+ break;
+ }
+ }
+ j++;
}
+
+ PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
+ 0,
+ ENB_FLAG_YES,
+ m->rnti,
+ 0, 0);
+
+ size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, scg_CellGroupConfig, nr1_conf);
+
+ rrc_data_req(&ctxt,
+ DCCH,
+ rrc_eNB_mui++,
+ SDU_CONFIRM_NO,
+ size,
+ buffer,
+ PDCP_TRANSMISSION_MODE_CONTROL);
+ } else {
+ LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", m->rnti);
}
- j++;
- }
-
- PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
- 0,
- ENB_FLAG_YES,
- m->rnti,
- 0, 0);
- size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, scg_CellGroupConfig, nr1_conf);
- rrc_data_req(&ctxt,
- DCCH,
- rrc_eNB_mui++,
- SDU_CONFIRM_NO,
- size,
- buffer,
- PDCP_TRANSMISSION_MODE_CONTROL);
}
-
//-----------------------------------------------------------------------------
void *rrc_enb_process_itti_msg(void *notUsed) {
MessageDef *msg_p;
diff --git a/openair2/RRC/LTE/rrc_eNB_M2AP.c b/openair2/RRC/LTE/rrc_eNB_M2AP.c
index bd586dfc71..98a72895a0 100644
--- a/openair2/RRC/LTE/rrc_eNB_M2AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_M2AP.c
@@ -63,6 +63,71 @@ rrc_M2AP_openair_rrc_top_init_MBMS(int eMBMS_active){
}
+static uint8_t rrc_M2AP_do_MBSFNCountingRequest(
+ uint8_t Mod_id,
+ uint8_t sync_area,
+ uint8_t *buffer,
+ LTE_MCCH_Message_t *mcch_message,
+ LTE_MBMSCountingRequest_r10_t **mbsfnCoutingRequest,
+ const m2ap_mbms_service_counting_req_t *const m2ap_mbms_service_counting_req
+) {
+ //int i,j,k;
+
+ asn_enc_rval_t enc_rval;
+ //LTE_MBSFN_SubframeConfig_t *mbsfn_SubframeConfig1;
+ //LTE_PMCH_Info_r9_t *pmch_Info_1;
+ //LTE_MBMS_SessionInfo_r9_t *mbms_Session_1;
+ // MBMS_SessionInfo_r9_t *mbms_Session_2;
+ //eNB_RRC_INST *rrc = RC.rrc[Mod_id];
+ //rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0];
+ memset(mcch_message,0,sizeof(LTE_MCCH_Message_t));
+ //mcch_message->message.present = LTE_MCCH_MessageType_PR_c1;
+ mcch_message->message.present = LTE_MCCH_MessageType_PR_later;
+ //mcch_message->message.choice.c1.present = LTE_MCCH_MessageType__c1_PR_mbsfnAreaConfiguration_r9;
+ mcch_message->message.choice.later.present = LTE_MCCH_MessageType__later_PR_c2;
+ mcch_message->message.choice.later.choice.c2.present = LTE_MCCH_MessageType__later__c2_PR_mbmsCountingRequest_r10;
+ *mbsfnCoutingRequest = &mcch_message->message.choice.later.choice.c2.choice.mbmsCountingRequest_r10;
+
+
+ //LTE_CountingRequestList_r10_t countingRequestList_r10; // A_SEQUENCE_OF(struct LTE_CountingRequestInfo_r10) list;
+ struct LTE_CountingRequestInfo_r10 *lte_counting_request_info; //LTE_TMGI_r9_t tmgi_r10;
+ lte_counting_request_info = CALLOC(1,sizeof(struct LTE_CountingRequestInfo_r10));
+ uint8_t TMGI[5] = {4,3,2,1,0};
+ lte_counting_request_info->tmgi_r10.plmn_Id_r9.present = LTE_TMGI_r9__plmn_Id_r9_PR_plmn_Index_r9;
+ lte_counting_request_info->tmgi_r10.plmn_Id_r9.choice.plmn_Index_r9= 1;
+ memset(<e_counting_request_info->tmgi_r10.serviceId_r9,0,sizeof(OCTET_STRING_t));
+ OCTET_STRING_fromBuf(<e_counting_request_info->tmgi_r10.serviceId_r9,(const char*)&TMGI[2],3);
+ ASN_SEQUENCE_ADD(&(*mbsfnCoutingRequest)->countingRequestList_r10.list,lte_counting_request_info);
+
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+ xer_fprint(stdout,&asn_DEF_LTE_MCCH_Message,(void *)mcch_message);
+ }
+
+ xer_fprint(stdout,&asn_DEF_LTE_MCCH_Message,(void *)mcch_message);
+
+ enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_MCCH_Message,
+ NULL,
+ (void *)mcch_message,
+ buffer,
+ 100);
+
+ if(enc_rval.encoded == -1) {
+ LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+ enc_rval.failed_type->name, enc_rval.encoded);
+ return -1;
+ }
+
+ LOG_I(RRC,"[eNB] MCCH Message Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
+
+ if (enc_rval.encoded==-1) {
+ msg("[RRC] ASN1 : MCCH encoding failed for MBSFNAreaConfiguration\n");
+ return(-1);
+ }
+
+ return((enc_rval.encoded+7)/8);
+
+}
+
static uint8_t rrc_M2AP_do_MBSFNAreaConfig(
uint8_t Mod_id,
@@ -96,6 +161,7 @@ static uint8_t rrc_M2AP_do_MBSFNAreaConfig(
mbsfn_SubframeConfig1->radioframeAllocationPeriod= m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period;//LTE_MBSFN_SubframeConfig__radioframeAllocationPeriod_n4;
mbsfn_SubframeConfig1->radioframeAllocationOffset= m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset;
if(m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf){
+ LOG_I(RRC,"is_four_sf\n");
mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames;
mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3);
mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation) & 0xFF);
@@ -106,6 +172,7 @@ static uint8_t rrc_M2AP_do_MBSFNAreaConfig(
}else {
+ LOG_I(RRC,"is_one_sf\n");
mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame;
mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1);
mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1;
@@ -128,7 +195,8 @@ static uint8_t rrc_M2AP_do_MBSFNAreaConfig(
*/
pmch_Info_1->pmch_Config_r9.sf_AllocEnd_r9= m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].allocated_sf_end;
pmch_Info_1->pmch_Config_r9.dataMCS_r9= m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].data_mcs;
- pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9= LTE_PMCH_Config_r9__mch_SchedulingPeriod_r9_rf16;
+ //pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9= LTE_PMCH_Config_r9__mch_SchedulingPeriod_r9_rf16;
+ pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9 = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mch_scheduling_period;
// MBMSs-SessionInfoList-r9
for(k=0; k < m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].num_mbms_session_list; k++){
// pmch_Info_1->mbms_SessionInfoList_r9 = CALLOC(1,sizeof(struct MBMS_SessionInfoList_r9));
@@ -240,6 +308,9 @@ static void rrc_M2AP_init_MCCH(
RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE =
malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t *));
+
+ RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE_COUNTING =
+ malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t *));
for (sync_area = 0; sync_area < RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area; sync_area++) {
RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] = 0;
@@ -253,6 +324,20 @@ static void rrc_M2AP_init_MCCH(
&RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message,
m2ap_mbms_scheduling_information
);
+
+ RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE_COUNTING[sync_area] = 0;
+ RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE_COUNTING[sync_area] = (uint8_t *) malloc16(32);
+ AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE_COUNTING[sync_area] != NULL,
+ "[eNB %d]init_MCCH: FATAL, no memory for MCCH MESSAGE allocated \n", enb_mod_idP);
+
+ RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE_COUNTING[sync_area] = rrc_M2AP_do_MBSFNCountingRequest(enb_mod_idP,
+ sync_area,
+ (uint8_t *)RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE_COUNTING[sync_area],
+ &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_counting,
+ &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message_counting,
+ NULL//m2ap_mbms_scheduling_information
+ );
+
LOG_I(RRC, "mcch message pointer %p for sync area %d \n",
RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area],
sync_area);
@@ -269,6 +354,8 @@ static void rrc_M2AP_init_MCCH(
AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] != 255,
"RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] == 255");
RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESS[sync_area].Active = 1;
+
+ RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESS_COUNTING[sync_area].Active = 1;
}
@@ -297,17 +384,348 @@ static void rrc_M2AP_init_MCCH(
(LTE_MBSFN_AreaInfoList_r9_t *) NULL,
(LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9),
(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL,
- 0,
- (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
- (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
- (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
- (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ 0,
+ (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
+ (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
+ (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
+ (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*)(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message)
);
}
return;
}
+
+
+static uint8_t rrc_M2AP_do_SIB1_MBMS_SIB13(
+ const protocol_ctxt_t *const ctxt_pP,
+ uint8_t Mod_id,
+ int CC_id,
+ const m2ap_setup_resp_t *const m2ap_setup_resp,
+ const m2ap_mbms_scheduling_information_t *const m2ap_mbms_scheduling_information
+){
+
+ int i,j,l;
+
+ eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id];
+ rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id];
+
+
+ struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part=NULL;
+ LTE_MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList/*,*MBSFNSubframeConfigList_copy*/;
+
+ asn_enc_rval_t enc_rval;
+
+ LTE_BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation;
+ LTE_BCCH_DL_SCH_Message_MBMS_t *bcch_message_fembms = &RC.rrc[Mod_id]->carrier[CC_id].siblock1_MBMS;
+ uint8_t *buffer;
+ uint8_t *buffer_fembms;
+ LTE_SystemInformationBlockType2_t **sib2;
+
+
+ LTE_MBSFN_AreaInfoList_r9_t *MBSFNArea_list/*,*MBSFNArea_list_copy*/;
+ LTE_SystemInformationBlockType13_r9_t **sib13 = &RC.rrc[Mod_id]->carrier[CC_id].sib13;
+ struct LTE_MBSFN_AreaInfo_r9 *MBSFN_Area1;
+
+ LTE_SystemInformationBlockType1_MBMS_r14_t **sib1_MBMS = &RC.rrc[Mod_id]->carrier[CC_id].sib1_MBMS;
+
+
+
+ if(ctxt_pP->brOption){
+ buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23_BR;
+ sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2_BR;
+ LOG_I(RRC,"Running SIB2/3 Encoding for eMTC\n");
+
+
+ }else
+ {
+ buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23;
+ sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2;
+ }
+
+ buffer_fembms = RC.rrc[Mod_id]->carrier[CC_id].SIB1_MBMS;
+
+
+ if (bcch_message) {
+ //memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_t));
+ } else {
+ LOG_E(RRC,"[eNB %d] BCCH_MESSAGE is null, exiting\n", Mod_id);
+ exit(-1);
+ }
+
+ if (!sib2) {
+ LOG_E(RRC,"[eNB %d] sib2 is null, exiting\n", Mod_id);
+ exit(-1);
+ }
+
+ if(!sib13){
+ LOG_I(RRC,"[eNB %d] sib13 is null, it should get created\n",Mod_id);
+ }
+
+
+ if(!sib1_MBMS){
+ LOG_I(RRC,"[eNB %d] sib1_MBMS is null, it should get created\n",Mod_id);
+ }
+
+ //if (!sib3) {
+ // LOG_E(RRC,"[eNB %d] sib3 is null, exiting\n", Mod_id);
+ // exit(-1);
+ //}
+
+ for (i=0; i < bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) {
+ struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo;
+ typeandinfo = bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i];
+ switch(typeandinfo->present) {
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_NOTHING:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920:
+ *sib13=&typeandinfo->choice.sib13_v920;
+ (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9=LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2;
+ (*sib13)->notificationConfig_r9.notificationOffset_r9=0;
+ (*sib13)->notificationConfig_r9.notificationSF_Index_r9=1;
+ // MBSFN-AreaInfoList
+ MBSFNArea_list= &(*sib13)->mbsfn_AreaInfoList_r9;//CALLOC(1,sizeof(*MBSFNArea_list));
+ memset(MBSFNArea_list,0,sizeof(*MBSFNArea_list));
+
+ for( j=0; j < m2ap_setup_resp->num_mcch_config_per_mbsfn; j++){
+ // MBSFN Area 1
+ MBSFN_Area1= CALLOC(1, sizeof(*MBSFN_Area1));
+ MBSFN_Area1->mbsfn_AreaId_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].mbsfn_area;
+ MBSFN_Area1->non_MBSFNregionLength= m2ap_setup_resp->mcch_config_per_mbsfn[j].pdcch_length;
+ MBSFN_Area1->notificationIndicator_r9= 0;
+ MBSFN_Area1->mcch_Config_r9.mcch_RepetitionPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].repetition_period;//LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32;
+ MBSFN_Area1->mcch_Config_r9.mcch_Offset_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].offset; // in accordance with mbsfn subframe configuration in sib2
+ MBSFN_Area1->mcch_Config_r9.mcch_ModificationPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].modification_period;
+
+ // Subframe Allocation Info
+ MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1);
+ MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1;
+ MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=m2ap_setup_resp->mcch_config_per_mbsfn[j].subframe_allocation_info<<2; // FDD: SF1
+ MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2;
+ MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].mcs;
+ ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1);
+ }
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib14_v1130:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib15_v1130:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib16_v1130:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib17_v1250:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib20_v1310:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib24_v1530:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib25_v1530:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib26_v1530:
+ break;
+ case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2:
+
+ LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2, %p %p\n",&typeandinfo->choice.sib2,*sib2);
+
+ for(j=0; j < m2ap_mbms_scheduling_information->num_mbms_area_config_list ; j++) {
+
+ (&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList = CALLOC(1,sizeof(struct LTE_MBSFN_SubframeConfigList));
+ MBSFNSubframeConfigList = (&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList;
+
+ for(l=0; l < m2ap_mbms_scheduling_information->mbms_area_config_list[j].num_mbms_sf_config_list; l++){
+ LTE_MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig1;
+ sib2_mbsfn_SubframeConfig1= CALLOC(1,sizeof(*sib2_mbsfn_SubframeConfig1));
+ memset((void *)sib2_mbsfn_SubframeConfig1,0,sizeof(*sib2_mbsfn_SubframeConfig1));
+
+ sib2_mbsfn_SubframeConfig1->radioframeAllocationPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].radioframe_allocation_period;
+ sib2_mbsfn_SubframeConfig1->radioframeAllocationOffset = m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].radioframe_allocation_offset;
+
+
+ if(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].is_four_sf){
+ LOG_I(RRC,"is_four_sf\n");
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames;
+
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3);
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 3;
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 0;
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation) & 0xFF);
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>8) & 0xFF);
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>16) & 0xFF);
+
+ }else{
+ LOG_I(RRC,"is_one_sf\n");
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame;
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1);
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1;
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2;
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation<<2);
+
+
+ }
+
+ ASN_SEQUENCE_ADD(&MBSFNSubframeConfigList->list,sib2_mbsfn_SubframeConfig1);
+ }
+ }
+
+ break;
+
+ }
+ }
+
+
+ if(*sib13==NULL){
+ sib13_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member));
+ memset(sib13_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member));
+ sib13_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920;
+
+ *sib13 = &sib13_part->choice.sib13_v920;
+
+ (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9=LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2;
+ (*sib13)->notificationConfig_r9.notificationOffset_r9=0;
+ (*sib13)->notificationConfig_r9.notificationSF_Index_r9=1;
+
+ // MBSFN-AreaInfoList
+ MBSFNArea_list= &(*sib13)->mbsfn_AreaInfoList_r9;//CALLOC(1,sizeof(*MBSFNArea_list));
+ memset(MBSFNArea_list,0,sizeof(*MBSFNArea_list));
+
+ for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++){
+ // MBSFN Area 1
+ MBSFN_Area1= CALLOC(1, sizeof(*MBSFN_Area1));
+ MBSFN_Area1->mbsfn_AreaId_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].mbsfn_area;
+ MBSFN_Area1->non_MBSFNregionLength= m2ap_setup_resp->mcch_config_per_mbsfn[i].pdcch_length;
+ MBSFN_Area1->notificationIndicator_r9= 0;
+ MBSFN_Area1->mcch_Config_r9.mcch_RepetitionPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].repetition_period;//LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32;
+ MBSFN_Area1->mcch_Config_r9.mcch_Offset_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].offset; // in accordance with mbsfn subframe configuration in sib2
+ MBSFN_Area1->mcch_Config_r9.mcch_ModificationPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].modification_period;
+
+ // Subframe Allocation Info
+ MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1);
+ MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1;
+ MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=m2ap_setup_resp->mcch_config_per_mbsfn[i].subframe_allocation_info<<2; // FDD: SF1
+ MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2;
+ MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].mcs;
+ ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1);
+ }
+
+ ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib13_part);
+
+ }
+
+ *sib1_MBMS = &bcch_message_fembms->message.choice.c1.choice.systemInformationBlockType1_MBMS_r14;
+
+
+ if((*sib1_MBMS)->systemInformationBlockType13_r14==NULL){
+ (*sib1_MBMS)->systemInformationBlockType13_r14 = CALLOC(1,sizeof(struct LTE_SystemInformationBlockType13_r9));
+ memset((*sib1_MBMS)->systemInformationBlockType13_r14,0,sizeof(struct LTE_SystemInformationBlockType13_r9));
+ }
+
+
+ memcpy((*sib1_MBMS)->systemInformationBlockType13_r14,*sib13,sizeof(struct LTE_SystemInformationBlockType13_r9));
+
+ enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS,
+ NULL,
+ (void *)bcch_message_fembms,
+ buffer_fembms,
+ 100);
+ AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
+ enc_rval.failed_type->name, enc_rval.encoded);
+
+ LOG_I(RRC,"[eNB] MBMS SIB1_MBMS SystemInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
+
+ if (enc_rval.encoded==-1) {
+ msg("[RRC] ASN1 : SI encoding failed for SIB23\n");
+ return(-1);
+ }
+
+
+
+ //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message);
+
+ enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message,
+ NULL,
+ (void *)bcch_message,
+ buffer,
+ 900);
+ AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
+ enc_rval.failed_type->name, enc_rval.encoded);
+
+ LOG_I(RRC,"[eNB] MBMS SIB2 SystemInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
+
+ if (enc_rval.encoded==-1) {
+ msg("[RRC] ASN1 : SI encoding failed for SIB23\n");
+ return(-1);
+ }
+
+ carrier->MBMS_flag =1;
+
+ if (NODE_IS_MONOLITHIC(rrc->node_type)) {
+ rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id,
+ 0,0,0,0,0,
+ 0,
+ 0xfffd,//rnti
+ (LTE_BCCH_BCH_Message_t *)NULL,
+ (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+ (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+ (struct LTE_PhysicalConfigDedicated *)NULL,
+ (LTE_SCellToAddMod_r10_t *)NULL,
+ //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
+ (LTE_MeasObjectToAddMod_t **) NULL,
+ (LTE_MAC_MainConfig_t *) NULL,
+ 0,
+ (struct LTE_LogicalChannelConfig *)NULL,
+ (LTE_MeasGapConfig_t *) NULL,
+ (LTE_TDD_Config_t *) NULL,
+ (LTE_MobilityControlInfo_t *)NULL,
+ (LTE_SchedulingInfoList_t *) NULL,
+ 0, NULL,
+ (LTE_AdditionalSpectrumEmission_t *)NULL,
+ (LTE_MBSFN_SubframeConfigList_t *) carrier->sib2->mbsfn_SubframeConfigList,
+ carrier->MBMS_flag,
+ (LTE_MBSFN_AreaInfoList_r9_t *) & carrier->sib13->mbsfn_AreaInfoList_r9,
+ (LTE_PMCH_InfoList_r9_t *) NULL
+ ,
+ (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
+ ,
+ carrier->FeMBMS_flag,
+ (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
+ (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
+ (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
+ (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
+ );
+ }
+
+ RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = ((enc_rval.encoded+7)/8);
+
+ return 0;
+}
//static uint8_t rrc_M2AP_do_SIB1(
// const protocol_ctxt_t *const ctxt_pP,
// uint8_t Mod_id,
@@ -501,21 +919,23 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2(
if(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].is_four_sf){
+ LOG_I(RRC,"is_four_sf\n");
sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames;
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3);
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 3;
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 0;
- sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation) & 0xFF);
- sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation>>8) & 0xFF);
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation) & 0xFF);
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>8) & 0xFF);
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>16) & 0xFF);
}else{
+ LOG_I(RRC,"is_one_sf\n");
sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame;
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1);
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1;
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2;
- sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation<<2);
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation<<2);
}
@@ -580,7 +1000,8 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2(
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
}
@@ -752,7 +1173,8 @@ for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++){
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
}
@@ -917,20 +1339,22 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13(
if(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].is_four_sf){
sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames;
+ LOG_I(RRC,"rrc_M2AP_do_SIB23_SIB2_SIB13 is_four_sf\n");
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3);
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 3;
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 0;
- sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation) & 0xFF);
- sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation>>8) & 0xFF);
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation) & 0xFF);
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>8) & 0xFF);
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>16) & 0xFF);
}else{
+ LOG_I(RRC,"rrc_M2AP_do_SIB23_SIB2_SIB13 rs_one_sf\n");
sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame;
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1);
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1;
sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2;
- sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation<<2);
+ sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation<<2);
}
@@ -1030,7 +1454,8 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13(
(LTE_SchedulingInfo_MBMS_r14_t *) NULL,
(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
- (LTE_MBSFN_AreaInfoList_r9_t *) NULL
+ (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+ (LTE_MBSFNAreaConfiguration_r9_t*) NULL
);
}
@@ -1122,7 +1547,11 @@ rrc_eNB_process_M2AP_MBMS_SESSION_START_REQ(
rrc_M2AP_do_SIB23_SIB2(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_mbms_scheduling_information_g);
rrc_M2AP_do_SIB23_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g);
}else{
- rrc_M2AP_do_SIB23_SIB2_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g,m2ap_mbms_scheduling_information_g);
+ if(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag){
+ rrc_M2AP_do_SIB1_MBMS_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g,m2ap_mbms_scheduling_information_g);
+ }else{
+ rrc_M2AP_do_SIB23_SIB2_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g,m2ap_mbms_scheduling_information_g);
+ }
}
rrc_M2AP_init_MCCH(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_mbms_scheduling_information_g);
rrc_M2AP_init_MBMS(ctxt_pP->module_id, CC_id, 0);
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index 865bf32b34..78f39c16d7 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -36,11 +36,34 @@
//#include "NR_UE-CapabilityRAT-ContainerList.h"
#include "LTE_UE-CapabilityRAT-ContainerList.h"
#include "NR_CG-Config.h"
+//#include "NR_SRB-ToAddModList.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
#include "executables/softmodem-common.h"
#include
+extern boolean_t nr_rrc_pdcp_config_asn1_req(
+ const protocol_ctxt_t *const ctxt_pP,
+ NR_SRB_ToAddModList_t *const srb2add_list,
+ NR_DRB_ToAddModList_t *const drb2add_list,
+ NR_DRB_ToReleaseList_t *const drb2release_list,
+ const uint8_t security_modeP,
+ uint8_t *const kRRCenc,
+ uint8_t *const kRRCint,
+ uint8_t *const kUPenc
+ #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+ ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
+ #endif
+ ,rb_id_t *const defaultDRB,
+ struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
+
+extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
+ const NR_SRB_ToAddModList_t * const srb2add_listP,
+ const NR_DRB_ToAddModList_t * const drb2add_listP,
+ const NR_DRB_ToReleaseList_t * const drb2release_listP,
+ const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
+ struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
+
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t *cg_config_info) {
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
@@ -244,6 +267,27 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
1, // add_ue flag
ue_context_p->ue_id_rnti,
ue_context_p->ue_context.secondaryCellGroup);
+
+ nr_rrc_pdcp_config_asn1_req(
+ &ctxt,
+ (NR_SRB_ToAddModList_t *) NULL,
+ ue_context_p->ue_context.rb_config->drb_ToAddModList ,
+ ue_context_p->ue_context.rb_config->drb_ToReleaseList,
+ 0xff,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
+
+ nr_rrc_rlc_config_asn1_req (&ctxt,
+ (NR_SRB_ToAddModList_t *) NULL,
+ ue_context_p->ue_context.rb_config->drb_ToAddModList,
+ ue_context_p->ue_context.rb_config->drb_ToReleaseList,
+ (LTE_PMCH_InfoList_r9_t *) NULL,
+ ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
+
}
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index 6ea6f3b3b3..b8962051d8 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -66,6 +66,22 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC));
*RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true;
RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config));
+
+#if 0
+
+ // RLC UM Bi-directional Bearer configuration
+ RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_um_Bi_Directional;
+ RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional));
+ RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength));
+ *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
+
+ RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength));
+ *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
+ RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15;
+
+#else
+
+ // RLC AM Bearer configuration
RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am;
RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am));
RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength));
@@ -78,6 +94,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18;
RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15;
RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15;
+
+#endif
+
RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig));
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters));
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority = 1;
@@ -150,9 +169,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions));
memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric,
&servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t));
- //secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long));
- //*secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one;
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= NULL;
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long));
+ *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb));
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0;
@@ -2047,7 +2065,7 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
- drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity=5;
+ drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5;
drb_ToAddMod->drb_Identity = 1;
drb_ToAddMod->reestablishPDCP = NULL;
drb_ToAddMod->recoverPDCP = NULL;
diff --git a/openair3/M3AP/m3ap_MCE.c b/openair3/M3AP/m3ap_MCE.c
index 232b0c0ece..dec9b96897 100644
--- a/openair3/M3AP/m3ap_MCE.c
+++ b/openair3/M3AP/m3ap_MCE.c
@@ -142,6 +142,20 @@ void m3ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_associa
sctp_new_association_resp->ulp_cnx_id);
//m3ap_handle_m3_setup_message(instance_p, m3ap_enb_data_p,
//sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
+ sleep(4);
+ int index;
+ /* Trying to connect to the provided list of eNB ip address */
+ for (index = 0; index < instance_p->nb_m3; index++) {
+ //M2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n",
+ // instance_id, instance->eNB_id);
+ m3ap_MCE_register_MCE(instance_p,
+ &instance_p->target_mme_m3_ip_address[index],
+ &instance_p->mme_m3_ip_address,
+ instance_p->sctp_in_streams,
+ instance_p->sctp_out_streams,
+ instance_p->mce_port_for_M3C,
+ instance_p->multi_sd);
+ }
return;
}
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index d086c0e13a..778c8165eb 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -90,6 +90,8 @@ typedef enum {
USRP_B200_DEV,
/*!\brief device is USRP X300/X310*/
USRP_X300_DEV,
+ /*!\brief device is USRP N300/N310*/
+ USRP_N300_DEV,
/*!\brief device is BLADE RF*/
BLADERF_DEV,
/*!\brief device is LMSSDR (SoDeRa)*/
@@ -104,7 +106,7 @@ typedef enum {
UEDv2_DEV,
MAX_RF_DEV_TYPE
} dev_type_t;
-#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2"}
+#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2"}
/*!\brief transport protocol types
*/
typedef enum {
@@ -434,6 +436,11 @@ struct openair0_device_t {
* \param arg pointer to capabilities or configuration
*/
int (*trx_write_init)(openair0_device *device);
+ /* \brief Get internal parameter
+ * \param id parameter to get
+ * \return a pointer to the parameter
+ */
+ void *(*get_internal_parameter)(char *id);
};
/* type of device init function, implemented in shared lib */
diff --git a/targets/ARCH/ETHERNET/benetel/4g/benetel.c b/targets/ARCH/ETHERNET/benetel/4g/benetel.c
new file mode 100644
index 0000000000..37f55c689f
--- /dev/null
+++ b/targets/ARCH/ETHERNET/benetel/4g/benetel.c
@@ -0,0 +1,386 @@
+/*
+ * 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.1 (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
+
+#include "common_lib.h"
+#include "ethernet_lib.h"
+#include "shared_buffers.h"
+#include "low.h"
+#include "common/utils/LOG/log.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
+
+typedef struct {
+ eth_state_t e;
+ shared_buffers buffers;
+ rru_config_msg_type_t last_msg;
+ int capabilities_sent;
+ void *benetel_priv;
+ char *dpdk_main_command_line;
+} benetel_eth_state_t;
+
+int trx_benetel_start(openair0_device *device)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return 0;
+}
+
+
+void trx_benetel_end(openair0_device *device)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+}
+
+
+int trx_benetel_stop(openair0_device *device)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return(0);
+}
+
+
+int trx_benetel_set_freq(openair0_device* device,
+ openair0_config_t *openair0_cfg,
+ int exmimo_dump_config)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return(0);
+}
+
+
+int trx_benetel_set_gains(openair0_device* device,
+ openair0_config_t *openair0_cfg)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return(0);
+}
+
+
+int trx_benetel_get_stats(openair0_device* device)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return(0);
+}
+
+
+int trx_benetel_reset_stats(openair0_device* device)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return(0);
+}
+
+
+int ethernet_tune(openair0_device *device,
+ unsigned int option,
+ int value)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return 0;
+}
+
+int trx_benetel_write_raw(openair0_device *device,
+ openair0_timestamp timestamp,
+ void **buff, int nsamps, int cc, int flags)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return nsamps*4;
+}
+
+int trx_benetel_read_raw(openair0_device *device,
+ openair0_timestamp *timestamp,
+ void **buff, int nsamps, int cc)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return nsamps*4;
+}
+
+char *msg_type(int t)
+{
+ static char *s[12] = {
+ "RAU_tick",
+ "RRU_capabilities",
+ "RRU_config",
+ "RRU_config_ok",
+ "RRU_start",
+ "RRU_stop",
+ "RRU_sync_ok",
+ "RRU_frame_resynch",
+ "RRU_MSG_max_num",
+ "RRU_check_sync",
+ "RRU_config_update",
+ "RRU_config_update_ok",
+ };
+
+ if (t < 0 || t > 11) return "UNKNOWN";
+ return s[t];
+}
+
+int trx_benetel_ctlsend(openair0_device *device, void *msg, ssize_t msg_len)
+{
+ RRU_CONFIG_msg_t *rru_config_msg = msg;
+ benetel_eth_state_t *s = device->priv;
+
+ printf("BENETEL: %s\n", __FUNCTION__);
+
+ printf(" rru_config_msg->type %d [%s]\n", rru_config_msg->type,
+ msg_type(rru_config_msg->type));
+
+ s->last_msg = rru_config_msg->type;
+
+ return msg_len;
+}
+
+int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len)
+{
+ RRU_CONFIG_msg_t *rru_config_msg = msg;
+ benetel_eth_state_t *s = device->priv;
+
+ printf("BENETEL: %s\n", __FUNCTION__);
+
+ if (s->last_msg == RAU_tick && s->capabilities_sent == 0) {
+ RRU_capabilities_t *cap;
+ rru_config_msg->type = RRU_capabilities;
+ rru_config_msg->len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t);
+ cap = (RRU_capabilities_t*)&rru_config_msg->msg[0];
+ cap->FH_fmt = OAI_IF4p5_only;
+ cap->num_bands = 1;
+ cap->band_list[0] = 7;
+ cap->nb_rx[0] = 1;
+ cap->nb_tx[0] = 1;
+ cap->max_pdschReferenceSignalPower[0] = -27;
+ cap->max_rxgain[0] = 90;
+
+ s->capabilities_sent = 1;
+
+ return rru_config_msg->len;
+ }
+ if (s->last_msg == RRU_config) {
+ rru_config_msg->type = RRU_config_ok;
+ return 0;
+ }
+ if (s->last_msg == RRU_start) {
+ s->benetel_priv = benetel_start(s->e.if_name, &s->buffers, s->dpdk_main_command_line);
+ }
+ /* correct? */
+ while (1) pause();
+
+ return 0;
+}
+
+void benetel_fh_if4p5_south_in(RU_t *ru,
+ int *frame,
+ int *subframe)
+{
+ benetel_eth_state_t *s = ru->ifdevice.priv;
+ PHY_VARS_eNB **eNB_list = ru->eNB_list, *eNB;
+ LTE_DL_FRAME_PARMS *fp;
+ int symbol;
+ int32_t *rxdata;
+ int antenna = 0;
+
+ lock_ul_buffer(&s->buffers, *subframe);
+next:
+ while (!(s->buffers.ul_busy[*subframe] == 0x3fff ||
+ s->buffers.prach_busy[*subframe] == 1))
+ wait_ul_buffer(&s->buffers, *subframe);
+ if (s->buffers.prach_busy[*subframe] == 1) {
+ int i;
+ int antenna = 0;
+ uint16_t *in;
+ uint16_t *out;
+ in = (uint16_t *)s->buffers.prach[*subframe];
+ out = (uint16_t *)ru->prach_rxsigF[antenna];
+ for (i = 0; i < 840*2; i++)
+ out[i] = ntohs(in[i]);
+ s->buffers.prach_busy[*subframe] = 0;
+ ru->wakeup_prach_eNB(ru->eNB_list[0], ru, *frame, *subframe);
+ goto next;
+ }
+
+ eNB = eNB_list[0];
+ fp = &eNB->frame_parms;
+ for (symbol = 0; symbol < 14; symbol++) {
+ int i;
+ uint16_t *p = (uint16_t *)(&s->buffers.ul[*subframe][symbol*1200*4]);
+ for (i = 0; i < 1200*2; i++) {
+ p[i] = htons(p[i]);
+ }
+ rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size];
+#if 1
+ memcpy(rxdata + 2048 - 600,
+ &s->buffers.ul[*subframe][symbol*1200*4],
+ 600 * 4);
+ memcpy(rxdata,
+ &s->buffers.ul[*subframe][symbol*1200*4] + 600*4,
+ 600 * 4);
+#endif
+ }
+
+ s->buffers.ul_busy[*subframe] = 0;
+ signal_ul_buffer(&s->buffers, *subframe);
+ unlock_ul_buffer(&s->buffers, *subframe);
+
+ //printf("BENETEL: %s (f.sf %d.%d)\n", __FUNCTION__, *frame, *subframe);
+
+ RU_proc_t *proc = &ru->proc;
+ extern uint16_t sf_ahead;
+ int f = *frame;
+ int sf = *subframe;
+
+ //calculate timestamp_rx, timestamp_tx based on frame and subframe
+ proc->tti_rx = sf;
+ proc->frame_rx = f;
+ proc->timestamp_rx = ((proc->frame_rx * 10) + proc->tti_rx ) * fp->samples_per_tti ;
+
+ if (get_nprocs()<=4) {
+ proc->tti_tx = (sf+sf_ahead)%10;
+ proc->frame_tx = (sf>(9-sf_ahead)) ? (f+1)&1023 : f;
+ }
+
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_IN_RU+ru->idx,f);
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_IN_RU+ru->idx,sf);
+ proc->symbol_mask[sf] = 0;
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff);
+
+}
+
+void benetel_fh_if4p5_south_out(RU_t *ru,
+ int frame,
+ int subframe,
+ uint64_t timestamp)
+{
+ benetel_eth_state_t *s = ru->ifdevice.priv;
+ PHY_VARS_eNB **eNB_list = ru->eNB_list, *eNB;
+ LTE_DL_FRAME_PARMS *fp;
+ int symbol;
+ int32_t *txdata;
+ int aa = 0;
+
+ //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp);
+
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
+
+ lock_dl_buffer(&s->buffers, subframe);
+ if (s->buffers.dl_busy[subframe]) {
+ printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, subframe);
+ unlock_dl_buffer(&s->buffers, subframe);
+ return;
+ }
+ eNB = eNB_list[0];
+ fp = &eNB->frame_parms;
+ if (ru->num_eNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 ||
+ fp->Ncp != NORMAL || fp->symbols_per_tti != 14) {
+ printf("%s:%d:%s: unsupported configuration\n",
+ __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ for (symbol = 0; symbol < 14; symbol++) {
+ txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size];
+#if 1
+ memcpy(&s->buffers.dl[subframe][symbol*1200*4],
+ txdata + 2048 - 600,
+ 600 * 4);
+ memcpy(&s->buffers.dl[subframe][symbol*1200*4] + 600*4,
+ txdata + 1,
+ 600 * 4);
+#endif
+ int i;
+ uint16_t *p = (uint16_t *)(&s->buffers.dl[subframe][symbol*1200*4]);
+ for (i = 0; i < 1200*2; i++) {
+ p[i] = htons(p[i]);
+ }
+ }
+
+ s->buffers.dl_busy[subframe] = 0x3fff;
+ unlock_dl_buffer(&s->buffers, subframe);
+
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx);
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.tti_tx);
+
+}
+
+void *get_internal_parameter(char *name)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+
+ if (!strcmp(name, "fh_if4p5_south_in"))
+ return benetel_fh_if4p5_south_in;
+ if (!strcmp(name, "fh_if4p5_south_out"))
+ return benetel_fh_if4p5_south_out;
+
+ return NULL;
+}
+
+__attribute__((__visibility__("default")))
+int transport_init(openair0_device *device,
+ openair0_config_t *openair0_cfg,
+ eth_params_t * eth_params )
+{
+ benetel_eth_state_t *eth;
+
+ printf("BENETEL: %s\n", __FUNCTION__);
+
+ device->Mod_id = 0;
+ device->transp_type = ETHERNET_TP;
+ device->trx_start_func = trx_benetel_start;
+ device->trx_get_stats_func = trx_benetel_get_stats;
+ device->trx_reset_stats_func = trx_benetel_reset_stats;
+ device->trx_end_func = trx_benetel_end;
+ device->trx_stop_func = trx_benetel_stop;
+ device->trx_set_freq_func = trx_benetel_set_freq;
+ device->trx_set_gains_func = trx_benetel_set_gains;
+
+ device->trx_write_func = trx_benetel_write_raw;
+ device->trx_read_func = trx_benetel_read_raw;
+
+ device->trx_ctlsend_func = trx_benetel_ctlsend;
+ device->trx_ctlrecv_func = trx_benetel_ctlrecv;
+
+ device->get_internal_parameter = get_internal_parameter;
+
+ eth = calloc(1, sizeof(benetel_eth_state_t));
+ if (eth == NULL) {
+ AssertFatal(0==1, "out of memory\n");
+ }
+
+ eth->e.flags = ETH_RAW_IF4p5_MODE;
+ eth->e.compression = NO_COMPRESS;
+ eth->e.if_name = eth_params->local_if_name;
+ device->priv = eth;
+ device->openair0_cfg=&openair0_cfg[0];
+
+ if (openair0_cfg->sdr_addrs == NULL) {
+ printf("benetel: fatal: sdr_addrs not set in configuration file\n");
+ exit(1);
+ }
+
+ eth->dpdk_main_command_line = strdup(openair0_cfg->sdr_addrs);
+ if (eth->dpdk_main_command_line == NULL) {
+ AssertFatal(0==1, "out of memory\n");
+ }
+
+ eth->last_msg = -1;
+
+ init_buffers(ð->buffers);
+
+ return 0;
+}
diff --git a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c
new file mode 100644
index 0000000000..9b64f01d44
--- /dev/null
+++ b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c
@@ -0,0 +1,787 @@
+/* license: to be defined */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "low.h"
+
+// HEADER DEFINITION
+#define ANT_NUM buf[23]
+#define PAYLOAD_1 buf[20]
+#define PAYLOAD_2 buf[21]
+#define ETH_TYPE buf[17]
+#define SYMBOL buf[29]
+#define SUBFRAME buf[28]
+#define FRAME buf[27]
+
+static volatile bool force_quit;
+
+unsigned short iq[33600];
+unsigned char iq_swap[67200];
+
+unsigned short *iq_ptr[14];
+unsigned int dl_start = 0;
+
+/* MAC updating enabled by default */
+static int mac_updating = 1;
+#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
+#define MAX_PKT_BURST 32
+#define BURST_TX_DRAIN_US 5 /* TX drain every ~100us */
+#define MEMPOOL_CACHE_SIZE 256
+/*
+ * Configurable number of RX/TX ring descriptors
+ */
+#define RTE_TEST_RX_DESC_DEFAULT 1024
+#define RTE_TEST_TX_DESC_DEFAULT 1024
+static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
+static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
+/* ethernet addresses of ports */
+static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS];
+/* mask of enabled ports */
+static uint32_t l2fwd_enabled_port_mask = 0;
+/* list of enabled ports */
+static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS];
+static unsigned int l2fwd_rx_queue_per_lcore = 1;
+#define MAX_RX_QUEUE_PER_LCORE 16
+#define MAX_TX_QUEUE_PER_PORT 16
+struct lcore_queue_conf {
+ unsigned n_rx_port;
+ unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE];
+} __rte_cache_aligned;
+struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE];
+static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
+static struct rte_eth_conf port_conf = {
+ .rxmode = {
+ .split_hdr_size = 0,
+ .offloads = DEV_RX_OFFLOAD_CRC_STRIP,
+ .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME,
+ .split_hdr_size = 0,
+ .max_rx_pkt_len = 9500,
+ },
+ .txmode = {
+ .mq_mode = ETH_MQ_TX_NONE,
+ },
+};
+struct rte_mempool * l2fwd_pktmbuf_pool = NULL;
+/* Per-port statistics struct */
+struct l2fwd_port_statistics {
+ uint64_t tx;
+ uint64_t rx;
+ uint64_t dropped;
+} __rte_cache_aligned;
+struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS];
+#define MAX_TIMER_PERIOD 86400 /* 1 day max */
+/* A tsc-based timer responsible for triggering statistics printout */
+static uint64_t timer_period = 10; /* default period is 10 seconds */
+/* Print out statistics on packets dropped */
+static void
+print_stats(void)
+{
+ uint64_t total_packets_dropped, total_packets_tx, total_packets_rx;
+ unsigned portid;
+ total_packets_dropped = 0;
+ total_packets_tx = 0;
+ total_packets_rx = 0;
+ const char clr[] = { 27, '[', '2', 'J', '\0' };
+ const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' };
+ /* Clear screen and move to top left */
+ printf("%s%s", clr, topLeft);
+ printf("\nPort statistics ====================================");
+ for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {
+ /* skip disabled ports */
+ if ((l2fwd_enabled_port_mask & (1 << portid)) == 0)
+ continue;
+ printf("\nStatistics for port %u ------------------------------"
+ "\nPackets sent: %24"PRIu64
+ "\nPackets received: %20"PRIu64
+ "\nPackets dropped: %21"PRIu64,
+ portid,
+ port_statistics[portid].tx,
+ port_statistics[portid].rx,
+ port_statistics[portid].dropped);
+ total_packets_dropped += port_statistics[portid].dropped;
+ total_packets_tx += port_statistics[portid].tx;
+ total_packets_rx += port_statistics[portid].rx;
+ }
+ printf("\nAggregate statistics ==============================="
+ "\nTotal packets sent: %18"PRIu64
+ "\nTotal packets received: %14"PRIu64
+ "\nTotal packets dropped: %15"PRIu64,
+ total_packets_tx,
+ total_packets_rx,
+ total_packets_dropped);
+ printf("\n====================================================\n");
+}
+static void
+l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs)
+{
+ unsigned char *buf, *buf_tx;
+ unsigned int len;
+ struct ether_hdr *eth;
+
+ unsigned dst_port;
+ int sent, prach_ctrl = 0;
+ struct rte_eth_dev_tx_buffer *buffer;
+
+ unsigned char * IQ_ptr;
+
+ ul_packet_t p;
+
+ buf = rte_pktmbuf_mtod(m, unsigned char *);
+ //rte_memdump(stdout, "Rx Packet",buf ,34);
+ eth = rte_pktmbuf_mtod(m, struct ether_hdr *);
+ len = rte_pktmbuf_data_len(m);
+
+ IQ_ptr = &buf[34];
+
+ //destination mac address (RRU MAC)
+ eth->d_addr.addr_bytes[0] = 0x02;
+ eth->d_addr.addr_bytes[1] = 0x00;
+ eth->d_addr.addr_bytes[2] = 0x5e;
+ eth->d_addr.addr_bytes[3] = 0x01;
+ eth->d_addr.addr_bytes[4] = 0x01;
+ eth->d_addr.addr_bytes[5] = 0x01;
+
+ //source mac address (DU MAC)
+ eth->s_addr.addr_bytes[0] = 0xdd;
+ eth->s_addr.addr_bytes[1] = 0xdd;
+ eth->s_addr.addr_bytes[2] = 0xdd;
+ eth->s_addr.addr_bytes[3] = 0xdd;
+ eth->s_addr.addr_bytes[4] = 0xdd;
+ eth->s_addr.addr_bytes[5] = 0xdd;
+
+ dst_port = l2fwd_dst_ports[portid];
+ #if 1
+
+ if (buf[18] == 0xAA) //msg1 check
+ {
+ printf("\nHandshake MSG 1 Received\n");
+ printf("\n====================================================\n");
+
+ buf[18] = 0xBB;//change to msg2 after receive msg1
+
+ printf("Handshake MSG 2 Sent\n");
+ printf("\n====================================================\n");
+ }
+
+ #else
+ // Handshake Condition
+ if (buf[18] == 0x01 || buf[18] == 0x03) // ORAN handshake msgs.
+ {
+ if (buf[18] == 0x01) //msg1 check
+ {
+ printf("\nHandshake MSG 1 Received\n");
+ printf("\n====================================================\n");
+
+ buf[18] = 0x02;//change to msg2 after receive msg1
+
+ printf("Handshake MSG 2 Sent\n");
+ printf("\n====================================================\n");
+ }
+
+ else if(buf[18] == 0x03) //msg3 check
+ {
+ printf("Handshake MSG 3 Sent\n");
+ printf("\n====================================================\n");
+
+ buf[18] = 0x04;
+
+ printf("Handshake MSG 4 Sent\n");
+ printf("\n====================================================\n");
+ }
+ }
+ #endif
+ // Trigger start send DL packets
+ if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && SYMBOL == 0x09 && ANT_NUM == 0x00 && dl_start == 0){
+
+ printf("\nU-Plane Started\n");
+ printf("\n====================================================\n");
+
+ dl_start = 1;
+ }
+
+
+ if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00) {
+ p.frame = FRAME;
+ p.subframe = SUBFRAME >> 4;
+ p.slot = 0; /* unused */
+ p.symbol = SYMBOL;
+ p.antenna = 0;
+ memcpy(p.iq, IQ_ptr, 4800);
+ store_ul(bs, &p);
+ }
+
+ // U-PLANE UL ANT_0 PROCESSING
+ if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00 && dl_start == 1)
+ {
+ int tx_frame = FRAME;
+ int tx_subframe = SUBFRAME >> 4;
+ int tx_symbol = SYMBOL + 5;
+ if (tx_symbol > 13) {
+ tx_symbol -= 14;
+ tx_subframe++;
+ if (tx_subframe == 10) {
+ tx_subframe = 0;
+ tx_frame = (tx_frame + 1) & 255;
+ }
+ }
+
+// ANT_NUM = 0x00;
+// SYMBOL = (SYMBOL + 5) % 14;
+ PAYLOAD_2 = 0xc8;
+
+ FRAME = tx_frame;
+ SUBFRAME = tx_subframe << 4;
+ SYMBOL = tx_symbol;
+
+ /* antenna 0 - send actual DL data (if available) */
+ lock_dl_buffer(bs->buffers, tx_subframe);
+ if (!(bs->buffers->dl_busy[tx_subframe] & (1 << tx_symbol))) {
+ printf("%s: warning, DL underflow (sf.symbol %d.%d)\n", __FUNCTION__,
+ tx_subframe, tx_symbol);
+ memset(IQ_ptr, 0, 1200 * 4);
+ } else {
+ memcpy(IQ_ptr, bs->buffers->dl[tx_subframe] + tx_symbol * 1200*4,
+ 1200*4);
+ }
+ bs->buffers->dl_busy[tx_subframe] &= ~(1 << tx_symbol);
+ unlock_dl_buffer(bs->buffers, tx_subframe);
+
+ // fill DL Data for ant 0 with 0 value
+// memset(IQ_ptr, 0, 4800);
+ }
+
+ // U-PLANE UL ANT_1 PROCESSING
+ else if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x01 && dl_start == 1)
+ {
+
+// ANT_NUM = 0x01;
+ SYMBOL = (SYMBOL + 5) % 14;
+ PAYLOAD_2 = 0xc8;
+
+ // fill DL Data for ant 1 with 0 value
+ memset(IQ_ptr, 0, 4800);
+ }
+
+ // U-PLANE PRACH PROCESSING
+ else if(PAYLOAD_1 == 0x0d && PAYLOAD_2 == 0x28){
+ if (ANT_NUM == 0) {
+ store_prach(bs, FRAME, SUBFRAME>>4, IQ_ptr);
+ }
+
+ rte_pktmbuf_free(m);
+ return;
+ }
+
+ // Send Packets
+ buffer = tx_buffer[dst_port];
+
+ sent = rte_eth_tx_buffer(dst_port, 0, buffer, m);
+
+ if (sent)
+ port_statistics[dst_port].tx += sent;
+
+}
+/* main processing loop */
+static void
+l2fwd_main_loop(benetel_t *bs)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ struct rte_mbuf *m;
+ int sent;
+ unsigned lcore_id;
+ uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc;
+ unsigned i, j, portid, nb_rx;
+ struct lcore_queue_conf *qconf;
+ const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S *
+ BURST_TX_DRAIN_US;
+ struct rte_eth_dev_tx_buffer *buffer;
+ prev_tsc = 0;
+ timer_tsc = 0;
+ lcore_id = rte_lcore_id();
+ qconf = &lcore_queue_conf[lcore_id];
+ if (qconf->n_rx_port == 0) {
+ RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id);
+ return;
+ }
+ RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id);
+ for (i = 0; i < qconf->n_rx_port; i++) {
+ portid = qconf->rx_port_list[i];
+ RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id,
+ portid);
+ }
+ while (!force_quit) {
+ cur_tsc = rte_rdtsc();
+ /*
+ * TX burst queue drain
+ */
+ diff_tsc = cur_tsc - prev_tsc;
+ if (unlikely(diff_tsc > drain_tsc)) {
+ for (i = 0; i < qconf->n_rx_port; i++) {
+ portid = l2fwd_dst_ports[qconf->rx_port_list[i]];
+ buffer = tx_buffer[portid];
+ sent = rte_eth_tx_buffer_flush(portid, 0, buffer);
+ if (sent)
+ port_statistics[portid].tx += sent;
+ }
+ /* if timer is enabled */
+ if (timer_period > 0) {
+ /* advance the timer */
+ timer_tsc += diff_tsc;
+ /* if timer has reached its timeout */
+ if (unlikely(timer_tsc >= timer_period)) {
+ /* do this only on master core */
+ if (lcore_id == rte_get_master_lcore()) {
+ //print_stats();
+ /* reset the timer */
+ timer_tsc = 0;
+ }
+ }
+ }
+ prev_tsc = cur_tsc;
+ }
+ /*
+ * Read packet from RX queues
+ */
+ for (i = 0; i < qconf->n_rx_port; i++) {
+ portid = qconf->rx_port_list[i];
+ nb_rx = rte_eth_rx_burst(portid, 0,
+ pkts_burst, MAX_PKT_BURST);
+ port_statistics[portid].rx += nb_rx;
+ for (j = 0; j < nb_rx; j++) {
+ m = pkts_burst[j];
+ rte_prefetch0(rte_pktmbuf_mtod(m, void *));
+ l2fwd_simple_forward(m, portid, bs);
+ }
+ }
+ }
+}
+static int
+l2fwd_launch_one_lcore(void *bs)
+{
+ l2fwd_main_loop(bs);
+ return 0;
+}
+/* display usage */
+static void
+l2fwd_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n"
+ " -p PORTMASK: hexadecimal bitmask of ports to configure\n"
+ " -q NQ: number of queue (=ports) per lcore (default is 1)\n"
+ " -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n"
+ " --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\n"
+ " When enabled:\n"
+ " - The source MAC address is replaced by the TX port MAC address\n"
+ " - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\n",
+ prgname);
+}
+static int
+l2fwd_parse_portmask(const char *portmask)
+{
+ char *end = NULL;
+ unsigned long pm;
+ /* parse hexadecimal string */
+ pm = strtoul(portmask, &end, 16);
+ if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
+ return -1;
+ if (pm == 0)
+ return -1;
+ return pm;
+}
+static unsigned int
+l2fwd_parse_nqueue(const char *q_arg)
+{
+ char *end = NULL;
+ unsigned long n;
+ /* parse hexadecimal string */
+ n = strtoul(q_arg, &end, 10);
+ if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0'))
+ return 0;
+ if (n == 0)
+ return 0;
+ if (n >= MAX_RX_QUEUE_PER_LCORE)
+ return 0;
+ return n;
+}
+static int
+l2fwd_parse_timer_period(const char *q_arg)
+{
+ char *end = NULL;
+ int n;
+ /* parse number string */
+ n = strtol(q_arg, &end, 10);
+ if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0'))
+ return -1;
+ if (n >= MAX_TIMER_PERIOD)
+ return -1;
+ return n;
+}
+static const char short_options[] =
+ "p:" /* portmask */
+ "q:" /* number of queues */
+ "T:" /* timer period */
+ ;
+#define CMD_LINE_OPT_MAC_UPDATING "mac-updating"
+#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
+enum {
+ /* long options mapped to a short option */
+ /* first long only option value must be >= 256, so that we won't
+ * conflict with short options */
+ CMD_LINE_OPT_MIN_NUM = 256,
+};
+static const struct option lgopts[] = {
+ { CMD_LINE_OPT_MAC_UPDATING, no_argument, &mac_updating, 1},
+ { CMD_LINE_OPT_NO_MAC_UPDATING, no_argument, &mac_updating, 0},
+ {NULL, 0, 0, 0}
+};
+/* Parse the argument given in the command line of the application */
+static int
+l2fwd_parse_args(int argc, char **argv)
+{
+ int opt, ret, timer_secs;
+ char **argvopt;
+ int option_index;
+ char *prgname = argv[0];
+ argvopt = argv;
+ while ((opt = getopt_long(argc, argvopt, short_options,
+ lgopts, &option_index)) != EOF) {
+ switch (opt) {
+ /* portmask */
+ case 'p':
+ l2fwd_enabled_port_mask = l2fwd_parse_portmask(optarg);
+ if (l2fwd_enabled_port_mask == 0) {
+ printf("invalid portmask\n");
+ l2fwd_usage(prgname);
+ return -1;
+ }
+ break;
+ /* nqueue */
+ case 'q':
+ l2fwd_rx_queue_per_lcore = l2fwd_parse_nqueue(optarg);
+ if (l2fwd_rx_queue_per_lcore == 0) {
+ printf("invalid queue number\n");
+ l2fwd_usage(prgname);
+ return -1;
+ }
+ break;
+ /* timer period */
+ case 'T':
+ timer_secs = l2fwd_parse_timer_period(optarg);
+ if (timer_secs < 0) {
+ printf("invalid timer period\n");
+ l2fwd_usage(prgname);
+ return -1;
+ }
+ timer_period = timer_secs;
+ break;
+ /* long options */
+ case 0:
+ break;
+ default:
+ l2fwd_usage(prgname);
+ return -1;
+ }
+ }
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+/* Check the link status of all ports in up to 9s, and print them finally */
+static void
+check_all_ports_link_status(uint32_t port_mask)
+{
+#define CHECK_INTERVAL 100 /* 100ms */
+#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
+ uint16_t portid;
+ uint8_t count, all_ports_up, print_flag = 0;
+ struct rte_eth_link link;
+ printf("\nChecking link status");
+ fflush(stdout);
+ for (count = 0; count <= MAX_CHECK_TIME; count++) {
+ if (force_quit)
+ return;
+ all_ports_up = 1;
+ RTE_ETH_FOREACH_DEV(portid) {
+ if (force_quit)
+ return;
+ if ((port_mask & (1 << portid)) == 0)
+ continue;
+ memset(&link, 0, sizeof(link));
+ rte_eth_link_get_nowait(portid, &link);
+ /* print link status if flag set */
+ if (print_flag == 1) {
+ if (link.link_status)
+ printf(
+ "Port%d Link Up. Speed %u Mbps - %s\n",
+ portid, link.link_speed,
+ (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex\n"));
+ else
+ printf("Port %d Link Down\n", portid);
+ continue;
+ }
+ /* clear all_ports_up flag if any link down */
+ if (link.link_status == ETH_LINK_DOWN) {
+ all_ports_up = 0;
+ break;
+ }
+ }
+ /* after finally printing all link status, get out */
+ if (print_flag == 1)
+ break;
+ if (all_ports_up == 0) {
+ printf(".");
+ fflush(stdout);
+ rte_delay_ms(CHECK_INTERVAL);
+ }
+ /* set the print_flag if all ports up or timeout */
+ if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
+ print_flag = 1;
+ printf("done\n");
+ }
+ }
+}
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\n\nSignal %d received, preparing to exit...\n",
+ signum);
+ force_quit = true;
+ }
+}
+int
+dpdk_main(int argc, char **argv, benetel_t *bs)
+{
+ struct lcore_queue_conf *qconf;
+ int ret;
+ uint16_t nb_ports;
+ uint16_t nb_ports_available = 0;
+ uint16_t portid, last_port;
+ unsigned lcore_id, rx_lcore_id;
+ unsigned nb_ports_in_mask = 0;
+ unsigned int nb_lcores = 0;
+ unsigned int nb_mbufs;
+ /* init EAL */
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
+ argc -= ret;
+ argv += ret;
+ force_quit = false;
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+ /* parse application arguments (after the EAL ones) */
+ ret = l2fwd_parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n");
+ printf("MAC updating %s\n", mac_updating ? "enabled" : "disabled");
+ /* convert to number of cycles */
+ timer_period *= rte_get_timer_hz();
+ nb_ports = rte_eth_dev_count_avail();
+ if (nb_ports == 0)
+ rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n");
+ /* check port mask to possible port mask */
+ if (l2fwd_enabled_port_mask & ~((1 << nb_ports) - 1))
+ rte_exit(EXIT_FAILURE, "Invalid portmask; possible (0x%x)\n",
+ (1 << nb_ports) - 1);
+ /* reset l2fwd_dst_ports */
+ for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++)
+ l2fwd_dst_ports[portid] = 0;
+ last_port = 0;
+ /*
+ * Each logical core is assigned a dedicated TX queue on each port.
+ */
+ RTE_ETH_FOREACH_DEV(portid) {
+ /* skip ports that are not enabled */
+ if ((l2fwd_enabled_port_mask & (1 << portid)) == 0)
+ continue;
+ if (nb_ports_in_mask % 2) {
+ l2fwd_dst_ports[portid] = last_port;
+ l2fwd_dst_ports[last_port] = portid;
+ }
+ else
+ last_port = portid;
+ nb_ports_in_mask++;
+ }
+ if (nb_ports_in_mask % 2) {
+ printf("Notice: odd number of ports in portmask.\n");
+ l2fwd_dst_ports[last_port] = last_port;
+ }
+ rx_lcore_id = 0;
+ qconf = NULL;
+ /* Initialize the port/queue configuration of each logical core */
+ RTE_ETH_FOREACH_DEV(portid) {
+ /* skip ports that are not enabled */
+ if ((l2fwd_enabled_port_mask & (1 << portid)) == 0)
+ continue;
+ /* get the lcore_id for this port */
+ while (rte_lcore_is_enabled(rx_lcore_id) == 0 ||
+ lcore_queue_conf[rx_lcore_id].n_rx_port ==
+ l2fwd_rx_queue_per_lcore) {
+ rx_lcore_id++;
+ if (rx_lcore_id >= RTE_MAX_LCORE)
+ rte_exit(EXIT_FAILURE, "Not enough cores\n");
+ }
+ if (qconf != &lcore_queue_conf[rx_lcore_id]) {
+ /* Assigned a new logical core in the loop above. */
+ qconf = &lcore_queue_conf[rx_lcore_id];
+ nb_lcores++;
+ }
+ qconf->rx_port_list[qconf->n_rx_port] = portid;
+ qconf->n_rx_port++;
+ printf("Lcore %u: RX port %u\n", rx_lcore_id, portid);
+ }
+ nb_mbufs = RTE_MAX(nb_ports * (nb_rxd + nb_txd + MAX_PKT_BURST +
+ nb_lcores * MEMPOOL_CACHE_SIZE), 8192U);
+ /* create the mbuf pool */
+ l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", nb_mbufs,
+ MEMPOOL_CACHE_SIZE, 0, 9680,
+ rte_socket_id());
+ if (l2fwd_pktmbuf_pool == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");
+ /* Initialise each port */
+ RTE_ETH_FOREACH_DEV(portid) {
+ struct rte_eth_rxconf rxq_conf;
+ struct rte_eth_txconf txq_conf;
+ struct rte_eth_conf local_port_conf = port_conf;
+ struct rte_eth_dev_info dev_info;
+ /* skip ports that are not enabled */
+ if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) {
+ printf("Skipping disabled port %u\n", portid);
+ continue;
+ }
+ nb_ports_available++;
+ /* init port */
+ printf("Initializing port %u... ", portid);
+ fflush(stdout);
+ rte_eth_dev_info_get(portid, &dev_info);
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
+ local_port_conf.txmode.offloads |=
+ DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+ ret = rte_eth_dev_configure(portid, 1, 1, &local_port_conf);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n",
+ ret, portid);
+ ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd,
+ &nb_txd);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE,
+ "Cannot adjust number of descriptors: err=%d, port=%u\n",
+ ret, portid);
+ rte_eth_macaddr_get(portid,&l2fwd_ports_eth_addr[portid]);
+ /* init one RX queue */
+ fflush(stdout);
+ rxq_conf = dev_info.default_rxconf;
+ rxq_conf.offloads = local_port_conf.rxmode.offloads;
+ ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd,
+ rte_eth_dev_socket_id(portid),
+ &rxq_conf,
+ l2fwd_pktmbuf_pool);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%u\n",
+ ret, portid);
+ /* init one TX queue on each port */
+ fflush(stdout);
+ txq_conf = dev_info.default_txconf;
+ txq_conf.offloads = local_port_conf.txmode.offloads;
+ ret = rte_eth_tx_queue_setup(portid, 0, nb_txd,
+ rte_eth_dev_socket_id(portid),
+ &txq_conf);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:err=%d, port=%u\n",
+ ret, portid);
+ /* Initialize TX buffers */
+ tx_buffer[portid] = rte_zmalloc_socket("tx_buffer",
+ RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0,
+ rte_eth_dev_socket_id(portid));
+ if (tx_buffer[portid] == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot allocate buffer for tx on port %u\n",
+ portid);
+ rte_eth_tx_buffer_init(tx_buffer[portid], MAX_PKT_BURST);
+ ret = rte_eth_tx_buffer_set_err_callback(tx_buffer[portid],
+ rte_eth_tx_buffer_count_callback,
+ &port_statistics[portid].dropped);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE,
+ "Cannot set error callback for tx buffer on port %u\n",
+ portid);
+ /* Start device */
+ ret = rte_eth_dev_start(portid);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n",
+ ret, portid);
+ printf("done: \n");
+ rte_eth_promiscuous_enable(portid);
+ printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n",
+ portid,
+ l2fwd_ports_eth_addr[portid].addr_bytes[0],
+ l2fwd_ports_eth_addr[portid].addr_bytes[1],
+ l2fwd_ports_eth_addr[portid].addr_bytes[2],
+ l2fwd_ports_eth_addr[portid].addr_bytes[3],
+ l2fwd_ports_eth_addr[portid].addr_bytes[4],
+ l2fwd_ports_eth_addr[portid].addr_bytes[5]);
+ /* initialize port stats */
+ memset(&port_statistics, 0, sizeof(port_statistics));
+ }
+ if (!nb_ports_available) {
+ rte_exit(EXIT_FAILURE,
+ "All available ports are disabled. Please set portmask.\n");
+ }
+ check_all_ports_link_status(l2fwd_enabled_port_mask);
+ ret = 0;
+ /* launch per-lcore init on every lcore */
+ rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, bs, CALL_MASTER);
+ RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+ if (rte_eal_wait_lcore(lcore_id) < 0) {
+ ret = -1;
+ break;
+ }
+ }
+ RTE_ETH_FOREACH_DEV(portid) {
+ if ((l2fwd_enabled_port_mask & (1 << portid)) == 0)
+ continue;
+ printf("Closing port %d...", portid);
+ rte_eth_dev_stop(portid);
+ rte_eth_dev_close(portid);
+ printf(" Done\n");
+ }
+ printf("Bye...\n");
+ return ret;
+}
diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.c b/targets/ARCH/ETHERNET/benetel/4g/low.c
new file mode 100644
index 0000000000..038592d596
--- /dev/null
+++ b/targets/ARCH/ETHERNET/benetel/4g/low.c
@@ -0,0 +1,95 @@
+/*
+ * 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.1 (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 "low.h"
+
+#include
+#include
+#include
+
+void store_ul(benetel_t *bs, ul_packet_t *ul)
+{
+ /* only antenna 0 for the moment */
+ if (ul->antenna != 0)
+ return;
+
+ if (ul->subframe != bs->next_subframe ||
+ ul->symbol != bs->next_symbol) {
+ printf("%s: fatal, expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n",
+ __FUNCTION__,
+ bs->expected_benetel_frame, bs->next_subframe, bs->next_symbol,
+ ul->frame, ul->subframe, ul->symbol);
+ exit(1);
+ }
+
+ lock_ul_buffer(bs->buffers, bs->next_subframe);
+ if (bs->buffers->ul_busy[bs->next_subframe] & (1 << bs->next_symbol)) {
+ printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__,
+ bs->next_subframe, bs->next_symbol);
+ }
+ memcpy(bs->buffers->ul[bs->next_subframe] + bs->next_symbol * 1200*4,
+ ul->iq, 1200*4);
+ bs->buffers->ul_busy[bs->next_subframe] |= (1 << bs->next_symbol);
+ signal_ul_buffer(bs->buffers, bs->next_subframe);
+ unlock_ul_buffer(bs->buffers, bs->next_subframe);
+
+ bs->next_symbol++;
+ if (bs->next_symbol == 14) {
+ bs->next_symbol = 0;
+ bs->next_subframe = (bs->next_subframe + 1) % 10;
+ if (bs->next_subframe == 0) {
+ bs->expected_benetel_frame++;
+ bs->expected_benetel_frame &= 255;
+ }
+ }
+}
+
+void store_prach(benetel_t *bs, int frame, int subframe, void *data)
+{
+ static int last_frame = -1;
+ static int last_subframe = -1;
+ /* hack: antenna number is always 0, discard second packet with same f/sf */
+ if (frame == last_frame && subframe == last_subframe) return;
+ last_frame = frame;
+ last_subframe = subframe;
+
+ lock_ul_buffer(bs->buffers, subframe);
+ if (bs->buffers->prach_busy[subframe]) {
+ printf("store_prach: fatal: previous prach buffer not processed\n");
+ unlock_ul_buffer(bs->buffers, subframe);
+ return;
+ }
+ bs->buffers->prach_busy[subframe] = 1;
+ memcpy(bs->buffers->prach[subframe], data, 849*4);
+ signal_ul_buffer(bs->buffers, subframe);
+ unlock_ul_buffer(bs->buffers, subframe);
+
+}
+
+void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line);
+
+void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line)
+{
+ if (!strcmp(ifname, "dpdk"))
+ return benetel_start_dpdk(ifname, buffers, dpdk_main_command_line);
+ printf("benetel: fatal: interface %s not supported, only dpdpk is supported\n", ifname);
+ exit(1);
+}
diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.h b/targets/ARCH/ETHERNET/benetel/4g/low.h
new file mode 100644
index 0000000000..5e75d9181e
--- /dev/null
+++ b/targets/ARCH/ETHERNET/benetel/4g/low.h
@@ -0,0 +1,49 @@
+/*
+ * 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.1 (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 _BENETEL_4G_LOW_H_
+#define _BENETEL_4G_LOW_H_
+
+#include "shared_buffers.h"
+
+typedef struct {
+ shared_buffers *buffers;
+ int next_subframe;
+ int next_symbol;
+ int expected_benetel_frame;
+ char *dpdk_main_command_line;
+} benetel_t;
+
+typedef struct {
+ int frame;
+ int subframe;
+ int slot;
+ int symbol;
+ int antenna;
+ unsigned char iq[4800];
+} ul_packet_t;
+
+void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line);
+
+void store_ul(benetel_t *bs, ul_packet_t *ul);
+void store_prach(benetel_t *bs, int frame, int subframe, void *data);
+
+#endif /* _BENETEL_4G_LOW_H_ */
diff --git a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c
new file mode 100644
index 0000000000..ecff473010
--- /dev/null
+++ b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c
@@ -0,0 +1,118 @@
+/*
+ * 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.1 (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
+ */
+
+/* those 2 lines for CPU_SET */
+#define _GNU_SOURCE
+#include
+
+#include
+#include
+#include
+#include
+
+#include "low.h"
+
+int dpdk_main(int argc, char **argv, benetel_t *);
+
+void *dpdk_thread(void *_bs)
+{
+ benetel_t *bs = _bs;
+ int n = 0;
+ char **v = NULL; // { "softmodem", "-n", "2", "-l", "8", "--", "-p", "0x2" };
+ char *s = bs->dpdk_main_command_line;
+ char *tok;
+
+ while ((tok = strtok(s, " ")) != NULL) {
+ n++;
+ v = realloc(v, n * sizeof(char *));
+ if (v == NULL) {
+ printf("%s: out of memory\n", __FUNCTION__);
+ exit(1);
+ }
+ v[n-1] = tok;
+ s = NULL;
+ }
+
+ dpdk_main(n, v, bs);
+ exit(1);
+ return 0;
+}
+
+void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line)
+{
+ benetel_t *bs;
+
+ bs = calloc(1, sizeof(benetel_t));
+ if (bs == NULL) {
+ printf("%s: out of memory\n", __FUNCTION__);
+ exit(1);
+ }
+
+ bs->buffers = buffers;
+
+ bs->expected_benetel_frame = 255;
+
+ bs->dpdk_main_command_line = dpdk_main_command_line;
+
+ pthread_attr_t attr;
+
+ if (pthread_attr_init(&attr) != 0) {
+ printf("pthread_attr_init failed\n");
+ exit(1);
+ }
+
+ cpu_set_t cpuset;
+ CPU_ZERO(&cpuset);
+ CPU_SET(12,&cpuset);
+ if (pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset) != 0) {
+ printf("pthread_attr_setaffinity_np failed\n");
+ exit(1);
+ }
+
+ if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) != 0) {
+ printf("pthread_attr_setschedpolicy failed\n");
+ exit(1);
+ }
+
+ struct sched_param params;
+ params.sched_priority = sched_get_priority_max(SCHED_FIFO);
+ if (sched_get_priority_max(SCHED_FIFO) == -1) {
+ printf("sched_get_priority_max failed\n");
+ exit(1);
+ }
+ if (pthread_attr_setschedparam(&attr, ¶ms) != 0) {
+ printf("pthread_setschedparam failed\n");
+ exit(1);
+ }
+
+ pthread_t t;
+ if (pthread_create(&t, &attr, dpdk_thread, bs) != 0) {
+ printf("%s: thread creation failed\n", __FUNCTION__);
+ exit(1);
+ }
+
+ if (pthread_attr_destroy(&attr) != 0) {
+ printf("pthread_attr_init failed\n");
+ exit(1);
+ }
+
+ return bs;
+}
diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c
new file mode 100644
index 0000000000..492a15dfc3
--- /dev/null
+++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c
@@ -0,0 +1,114 @@
+/*
+ * 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.1 (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 "shared_buffers.h"
+
+#include
+#include
+#include
+
+void init_buffers(shared_buffers *s)
+{
+ int subframe;
+
+ memset(s, 0, sizeof(*s));
+
+ for (subframe = 0; subframe < 10; subframe++) {
+ if (pthread_mutex_init(&s->m_dl[subframe], NULL) != 0 ||
+ pthread_cond_init(&s->c_dl[subframe], NULL) != 0 ||
+ pthread_mutex_init(&s->m_ul[subframe], NULL) != 0 ||
+ pthread_cond_init(&s->c_ul[subframe], NULL) != 0) {
+ printf("%s: error initializing mutex/cond\n", __FUNCTION__);
+ exit(1);
+ }
+ }
+
+ /* in FDD the eNB's first transmitted DL subframe is 4 but the device
+ * needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready.
+ */
+ s->dl_busy[1] = 0x3fff;
+ s->dl_busy[2] = 0x3fff;
+ s->dl_busy[3] = 0x3fff;
+}
+
+void lock_dl_buffer(shared_buffers *s, int subframe)
+{
+ if (pthread_mutex_lock(&s->m_dl[subframe]) != 0) {
+ printf("%s: fatal: lock fails\n", __FUNCTION__);
+ exit(1);
+ }
+}
+
+void unlock_dl_buffer(shared_buffers *s, int subframe)
+{
+ if (pthread_mutex_unlock(&s->m_dl[subframe]) != 0) {
+ printf("%s: fatal: unlock fails\n", __FUNCTION__);
+ exit(1);
+ }
+}
+
+void wait_dl_buffer(shared_buffers *s, int subframe)
+{
+ if (pthread_cond_wait(&s->c_dl[subframe], &s->m_dl[subframe]) != 0) {
+ printf("%s: fatal: cond_wait fails\n", __FUNCTION__);
+ exit(1);
+ }
+}
+
+void signal_dl_buffer(shared_buffers *s, int subframe)
+{
+ if (pthread_cond_broadcast(&s->c_dl[subframe]) != 0) {
+ printf("%s: fatal: cond_broadcast fails\n", __FUNCTION__);
+ exit(1);
+ }
+}
+
+void lock_ul_buffer(shared_buffers *s, int subframe)
+{
+ if (pthread_mutex_lock(&s->m_ul[subframe]) != 0) {
+ printf("%s: fatal: lock fails\n", __FUNCTION__);
+ exit(1);
+ }
+}
+
+void unlock_ul_buffer(shared_buffers *s, int subframe)
+{
+ if (pthread_mutex_unlock(&s->m_ul[subframe]) != 0) {
+ printf("%s: fatal: unlock fails\n", __FUNCTION__);
+ exit(1);
+ }
+}
+
+void wait_ul_buffer(shared_buffers *s, int subframe)
+{
+ if (pthread_cond_wait(&s->c_ul[subframe], &s->m_ul[subframe]) != 0) {
+ printf("%s: fatal: cond_wait fails\n", __FUNCTION__);
+ exit(1);
+ }
+}
+
+void signal_ul_buffer(shared_buffers *s, int subframe)
+{
+ if (pthread_cond_broadcast(&s->c_ul[subframe]) != 0) {
+ printf("%s: fatal: cond_broadcast fails\n", __FUNCTION__);
+ exit(1);
+ }
+}
diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h
new file mode 100644
index 0000000000..1d5040b95b
--- /dev/null
+++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h
@@ -0,0 +1,60 @@
+/*
+ * 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.1 (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 _BENETEL_4G_SHARED_BUFFERS_H_
+#define _BENETEL_4G_SHARED_BUFFERS_H_
+
+#include
+#include
+
+typedef struct {
+ unsigned char dl[10][14*1200*4];
+ unsigned char ul[10][14*1200*4];
+ uint16_t dl_busy[10];
+ uint16_t ul_busy[10];
+
+ pthread_mutex_t m_ul[10];
+ pthread_cond_t c_ul[10];
+
+ pthread_mutex_t m_dl[10];
+ pthread_cond_t c_dl[10];
+
+ unsigned char prach[10][849*4];
+ unsigned char prach_busy[10];
+
+ /* statistics/error counting */
+ int ul_overflow;
+ int dl_underflow;
+} shared_buffers;
+
+void init_buffers(shared_buffers *s);
+
+void lock_dl_buffer(shared_buffers *s, int subframe);
+void unlock_dl_buffer(shared_buffers *s, int subframe);
+void wait_dl_buffer(shared_buffers *s, int subframe);
+void signal_dl_buffer(shared_buffers *s, int subframe);
+
+void lock_ul_buffer(shared_buffers *s, int subframe);
+void unlock_ul_buffer(shared_buffers *s, int subframe);
+void wait_ul_buffer(shared_buffers *s, int subframe);
+void signal_ul_buffer(shared_buffers *s, int subframe);
+
+#endif /* _BENETEL_4G_SHARED_BUFFERS_H_ */
diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c
new file mode 100644
index 0000000000..c1ae1afcc7
--- /dev/null
+++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c
@@ -0,0 +1,388 @@
+/*
+ * 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.1 (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
+
+#include "common_lib.h"
+#include "ethernet_lib.h"
+#include "shared_buffers.h"
+#include "low.h"
+#include "openair1/PHY/defs_gNB.h"
+
+typedef struct {
+ eth_state_t e;
+ shared_buffers buffers;
+ rru_config_msg_type_t last_msg;
+ int capabilities_sent;
+ void *benetel_priv;
+ char *dpdk_main_command_line;
+} benetel_eth_state_t;
+
+int trx_benetel_start(openair0_device *device)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return 0;
+}
+
+
+void trx_benetel_end(openair0_device *device)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+}
+
+
+int trx_benetel_stop(openair0_device *device)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return(0);
+}
+
+
+int trx_benetel_set_freq(openair0_device* device,
+ openair0_config_t *openair0_cfg,
+ int exmimo_dump_config)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return(0);
+}
+
+
+int trx_benetel_set_gains(openair0_device* device,
+ openair0_config_t *openair0_cfg)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return(0);
+}
+
+
+int trx_benetel_get_stats(openair0_device* device)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return(0);
+}
+
+
+int trx_benetel_reset_stats(openair0_device* device)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return(0);
+}
+
+
+int ethernet_tune(openair0_device *device,
+ unsigned int option,
+ int value)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return 0;
+}
+
+int trx_benetel_write_raw(openair0_device *device,
+ openair0_timestamp timestamp,
+ void **buff, int nsamps, int cc, int flags)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return nsamps*4;
+}
+
+int trx_benetel_read_raw(openair0_device *device,
+ openair0_timestamp *timestamp,
+ void **buff, int nsamps, int cc)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+ return nsamps*4;
+}
+
+char *msg_type(int t)
+{
+ static char *s[12] = {
+ "RAU_tick",
+ "RRU_capabilities",
+ "RRU_config",
+ "RRU_config_ok",
+ "RRU_start",
+ "RRU_stop",
+ "RRU_sync_ok",
+ "RRU_frame_resynch",
+ "RRU_MSG_max_num",
+ "RRU_check_sync",
+ "RRU_config_update",
+ "RRU_config_update_ok",
+ };
+
+ if (t < 0 || t > 11) return "UNKNOWN";
+ return s[t];
+}
+
+int trx_benetel_ctlsend(openair0_device *device, void *msg, ssize_t msg_len)
+{
+ RRU_CONFIG_msg_t *rru_config_msg = msg;
+ benetel_eth_state_t *s = device->priv;
+
+ printf("BENETEL: %s\n", __FUNCTION__);
+
+ printf(" rru_config_msg->type %d [%s]\n", rru_config_msg->type,
+ msg_type(rru_config_msg->type));
+
+ s->last_msg = rru_config_msg->type;
+
+ return msg_len;
+}
+
+int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len)
+{
+ RRU_CONFIG_msg_t *rru_config_msg = msg;
+ benetel_eth_state_t *s = device->priv;
+
+ printf("BENETEL: %s\n", __FUNCTION__);
+
+ if (s->last_msg == RAU_tick && s->capabilities_sent == 0) {
+ RRU_capabilities_t *cap;
+ rru_config_msg->type = RRU_capabilities;
+ rru_config_msg->len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t);
+ cap = (RRU_capabilities_t*)&rru_config_msg->msg[0];
+ cap->FH_fmt = OAI_IF4p5_only;
+ cap->num_bands = 1;
+ cap->band_list[0] = 78;
+ cap->nb_rx[0] = 1;
+ cap->nb_tx[0] = 1;
+ cap->max_pdschReferenceSignalPower[0] = -27;
+ cap->max_rxgain[0] = 90;
+
+ s->capabilities_sent = 1;
+
+ return rru_config_msg->len;
+ }
+#if 0
+ if (s->last_msg == RRU_config) {
+ rru_config_msg->type = RRU_config_ok;
+ return 0;
+ }
+ if (s->last_msg == RRU_start) {
+printf("***************** benetel start\n");
+ s->benetel_priv = benetel_start(s->e.if_name, &s->buffers, s->dpdk_main_command_line);
+ }
+#endif
+ if (s->last_msg == RRU_config) {
+ rru_config_msg->type = RRU_config_ok;
+ s->benetel_priv = benetel_start(s->e.if_name, &s->buffers, s->dpdk_main_command_line);
+ }
+ /* correct? */
+//printf("***************** benetel pause\n");
+// while (1) pause();
+
+ return 0;
+}
+
+void benetel_fh_if4p5_south_in(RU_t *ru,
+ int *frame,
+ int *slot)
+{
+//printf("XXX benetel_fh_if4p5_south_in %d %d\n", *frame, *slot);
+ benetel_eth_state_t *s = ru->ifdevice.priv;
+ NR_DL_FRAME_PARMS *fp;
+ int symbol;
+ int32_t *rxdata;
+ int antenna = 0;
+
+ lock_ul_buffer(&s->buffers, *slot);
+#if 1
+next:
+ while (!(s->buffers.ul_busy[*slot] == 0x3fff ||
+ s->buffers.prach_busy[*slot] == 1))
+ wait_ul_buffer(&s->buffers, *slot);
+ if (s->buffers.prach_busy[*slot] == 1) {
+ int i;
+ int antenna = 0;
+ uint16_t *in;
+ uint16_t *out;
+ in = (uint16_t *)s->buffers.prach[*slot];
+ out = (uint16_t *)ru->prach_rxsigF[antenna];
+ for (i = 0; i < 839*2; i++)
+ out[i] = ntohs(in[i]);
+ s->buffers.prach_busy[*slot] = 0;
+ //printf("prach for f.sl %d.%d\n", *frame, *slot);
+ //ru->wakeup_prach_gNB(ru->gNB_list[0], ru, *frame, *slot);
+ goto next;
+ }
+#endif
+
+ fp = ru->nr_frame_parms;
+ for (symbol = 0; symbol < 14; symbol++) {
+ int i;
+ uint16_t *p = (uint16_t *)(&s->buffers.ul[*slot][symbol*1272*4]);
+ for (i = 0; i < 1272*2; i++) {
+ p[i] = htons(p[i]);
+ }
+ rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size];
+#if 1
+ memcpy(rxdata + 2048 - 1272/2,
+ &s->buffers.ul[*slot][symbol*1272*4],
+ (1272/2) * 4);
+ memcpy(rxdata,
+ &s->buffers.ul[*slot][symbol*1272*4] + (1272/2)*4,
+ (1272/2) * 4);
+#endif
+ }
+
+ s->buffers.ul_busy[*slot] = 0;
+ signal_ul_buffer(&s->buffers, *slot);
+ unlock_ul_buffer(&s->buffers, *slot);
+
+ //printf("BENETEL: %s (f.sf %d.%d)\n", __FUNCTION__, *frame, *slot);
+
+ RU_proc_t *proc = &ru->proc;
+ extern uint16_t sl_ahead;
+ int f = *frame;
+ int sl = *slot;
+
+ //calculate timestamp_rx, timestamp_tx based on frame and slot
+ proc->tti_rx = sl;
+ proc->frame_rx = f;
+ /* TODO: be sure of samples_per_slot0
+ FK: should use get_samples_per_slot(slot)
+ but for mu=1 its ok
+ */
+ proc->timestamp_rx = ((proc->frame_rx * 20) + proc->tti_rx ) * fp->samples_per_slot0;
+
+ if (get_nprocs()<=4) {
+ // why? what if there are more?
+ proc->tti_tx = (sl+sl_ahead)%20;
+ proc->frame_tx = (sl>(19-sl_ahead)) ? (f+1)&1023 : f;
+ }
+}
+
+void benetel_fh_if4p5_south_out(RU_t *ru,
+ int frame,
+ int slot,
+ uint64_t timestamp)
+{
+//printf("XXX benetel_fh_if4p5_south_out %d %d %ld\n", frame, slot, timestamp);
+ benetel_eth_state_t *s = ru->ifdevice.priv;
+ NR_DL_FRAME_PARMS *fp;
+ int symbol;
+ int32_t *txdata;
+ int aa = 0;
+
+ //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, slot, timestamp);
+
+ lock_dl_buffer(&s->buffers, slot);
+ if (s->buffers.dl_busy[slot]) {
+ printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, slot);
+ unlock_dl_buffer(&s->buffers, slot);
+ return;
+ }
+
+ fp = ru->nr_frame_parms;
+ if (ru->num_gNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 ||
+ fp->Ncp != NORMAL || fp->symbols_per_slot != 14) {
+ printf("%s:%d:%s: unsupported configuration\n",
+ __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ for (symbol = 0; symbol < 14; symbol++) {
+ txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size];
+#if 1
+ memcpy(&s->buffers.dl[slot][symbol*1272*4],
+ txdata + 2048 - (1272/2),
+ (1272/2) * 4);
+ memcpy(&s->buffers.dl[slot][symbol*1272*4] + (1272/2)*4,
+ txdata,
+ (1272/2) * 4);
+#endif
+ int i;
+ uint16_t *p = (uint16_t *)(&s->buffers.dl[slot][symbol*1272*4]);
+ for (i = 0; i < 1272*2; i++) {
+ p[i] = htons(p[i]);
+ }
+ }
+
+ s->buffers.dl_busy[slot] = 0x3fff;
+ unlock_dl_buffer(&s->buffers, slot);
+}
+
+void *get_internal_parameter(char *name)
+{
+ printf("BENETEL: %s\n", __FUNCTION__);
+
+ if (!strcmp(name, "fh_if4p5_south_in"))
+ return benetel_fh_if4p5_south_in;
+ if (!strcmp(name, "fh_if4p5_south_out"))
+ return benetel_fh_if4p5_south_out;
+
+ return NULL;
+}
+
+__attribute__((__visibility__("default")))
+int transport_init(openair0_device *device,
+ openair0_config_t *openair0_cfg,
+ eth_params_t * eth_params )
+{
+ benetel_eth_state_t *eth;
+
+ printf("BENETEL: %s\n", __FUNCTION__);
+
+ device->Mod_id = 0;
+ device->transp_type = ETHERNET_TP;
+ device->trx_start_func = trx_benetel_start;
+ device->trx_get_stats_func = trx_benetel_get_stats;
+ device->trx_reset_stats_func = trx_benetel_reset_stats;
+ device->trx_end_func = trx_benetel_end;
+ device->trx_stop_func = trx_benetel_stop;
+ device->trx_set_freq_func = trx_benetel_set_freq;
+ device->trx_set_gains_func = trx_benetel_set_gains;
+
+ device->trx_write_func = trx_benetel_write_raw;
+ device->trx_read_func = trx_benetel_read_raw;
+
+ device->trx_ctlsend_func = trx_benetel_ctlsend;
+ device->trx_ctlrecv_func = trx_benetel_ctlrecv;
+
+ device->get_internal_parameter = get_internal_parameter;
+
+ eth = calloc(1, sizeof(benetel_eth_state_t));
+ if (eth == NULL) {
+ AssertFatal(0==1, "out of memory\n");
+ }
+
+ eth->e.flags = ETH_RAW_IF4p5_MODE;
+ eth->e.compression = NO_COMPRESS;
+ eth->e.if_name = eth_params->local_if_name;
+ device->priv = eth;
+ device->openair0_cfg=&openair0_cfg[0];
+
+ if (openair0_cfg->sdr_addrs == NULL) {
+ printf("benetel: fatal: sdr_addrs not set in configuration file\n");
+ exit(1);
+ }
+
+ eth->dpdk_main_command_line = strdup(openair0_cfg->sdr_addrs);
+ if (eth->dpdk_main_command_line == NULL) {
+ AssertFatal(0==1, "out of memory\n");
+ }
+
+ eth->last_msg = -1;
+
+ init_buffers(ð->buffers);
+
+ return 0;
+}
diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c
new file mode 100644
index 0000000000..b90702d331
--- /dev/null
+++ b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c
@@ -0,0 +1,856 @@
+/* license: to be defined */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include